Compare commits
28 Commits
main
...
nadro/adho
Author | SHA1 | Date | |
---|---|---|---|
ac938e1f23 | |||
bf9dd893f1 | |||
03a13fd741 | |||
d567de1e5f | |||
66970d674d | |||
07d899e884 | |||
86e6590f4d | |||
340c503633 | |||
7abc119993 | |||
4102249bd8 | |||
3929f2e9fb | |||
bab98ab5c9 | |||
8dc1b156ff | |||
693fd8eb31 | |||
14a72344e2 | |||
e5d1cd847d | |||
01d294a8bb | |||
aa460d631d | |||
23e609443b | |||
d3aa09a20b | |||
eba91e85ea | |||
74f6e338f7 | |||
529c619fb5 | |||
195000b50c | |||
7993b5f4e8 | |||
fb8acbefe7 | |||
8f2a2391d1 | |||
e2247669f0 |
@ -6,6 +6,9 @@ URL STATUS
|
||||
000 https://${BASE_URL}
|
||||
405 https://api.dev.zoo.dev/oauth2/token/revoke
|
||||
401 https://api.dev.zoo.dev/users
|
||||
401 https://dev.zoo.dev
|
||||
401 https://dev.zoo.dev/docs
|
||||
401 https://dev.zoo.dev/docs/kcl-samples/car-wheel-assembly
|
||||
301 https://discord.gg/JQEpHR7Nt2
|
||||
404 https://github.com/KittyCAD/engine/issues/3528
|
||||
404 https://github.com/KittyCAD/modeling-app/commit/${ref}
|
||||
@ -19,5 +22,4 @@ URL STATUS
|
||||
302 https://stackoverflow.com/a/58436959/22753272
|
||||
303 https://text-to-cad.zoo.dev/dashboard
|
||||
307 https://zoo.dev/
|
||||
308 https://zoo.dev/docs/api/ml/generate-a-cad-model-from-text
|
||||
308 https://zoo.dev/docs/kcl
|
||||
|
@ -53,7 +53,6 @@ import {
|
||||
WASM_INIT_FAILED_TOAST_ID,
|
||||
} from '@src/lib/constants'
|
||||
import { isPlaywright } from '@src/lib/isPlaywright'
|
||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
||||
import { useNetworkHealthStatus } from '@src/components/NetworkHealthIndicator'
|
||||
import { useNetworkMachineStatus } from '@src/components/NetworkMachineIndicator'
|
||||
import {
|
||||
@ -65,6 +64,7 @@ import { useModelingContext } from '@src/hooks/useModelingContext'
|
||||
import { xStateValueToString } from '@src/lib/xStateValueToString'
|
||||
import { getSelectionTypeDisplayText } from '@src/lib/selections'
|
||||
import type { StatusBarItemType } from '@src/components/StatusBar/statusBarTypes'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
// CYCLIC REF
|
||||
sceneInfra.camControls.engineStreamActor = engineStreamActor
|
||||
@ -189,7 +189,8 @@ export function App() {
|
||||
() =>
|
||||
DownloadAppToast({
|
||||
onAccept: () => {
|
||||
openWindow(`${VITE_KC_SITE_BASE_URL}/${APP_DOWNLOAD_PATH}`)
|
||||
const url = withSiteBaseURL(`/${APP_DOWNLOAD_PATH}`)
|
||||
openWindow(url)
|
||||
.then(() => {
|
||||
toast.dismiss(DOWNLOAD_APP_TOAST_ID)
|
||||
})
|
||||
|
@ -5,8 +5,8 @@ import {
|
||||
BillingRemaining,
|
||||
BillingRemainingMode,
|
||||
} from '@src/components/BillingRemaining'
|
||||
|
||||
import { type BillingActor } from '@src/machines/billingMachine'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
export const BillingDialog = (props: { billingActor: BillingActor }) => {
|
||||
const billingContext = useSelector(
|
||||
@ -42,7 +42,7 @@ export const BillingDialog = (props: { billingActor: BillingActor }) => {
|
||||
{!hasUnlimited && (
|
||||
<a
|
||||
className="bg-ml-black text-ml-white rounded-lg text-center p-1 cursor-pointer"
|
||||
href="https://zoo.dev/design-studio-pricing"
|
||||
href={withSiteBaseURL('/design-studio-pricing')}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
data-testid="billing-upgrade-button"
|
||||
|
@ -15,6 +15,7 @@ import {
|
||||
import { onboardingStartPath } from '@src/lib/onboardingPaths'
|
||||
import { reportRejection } from '@src/lib/trap'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
const HelpMenuDivider = () => (
|
||||
<div className="h-[1px] bg-chalkboard-110 dark:bg-chalkboard-80" />
|
||||
@ -89,7 +90,7 @@ export function HelpMenu() {
|
||||
<HelpMenuDivider />
|
||||
<HelpMenuItem
|
||||
as="a"
|
||||
href="https://zoo.dev/docs/kcl-samples"
|
||||
href={withSiteBaseURL('/docs/kcl-samples')}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
@ -97,7 +98,7 @@ export function HelpMenu() {
|
||||
</HelpMenuItem>
|
||||
<HelpMenuItem
|
||||
as="a"
|
||||
href="https://zoo.dev/docs/kcl-lang"
|
||||
href={withSiteBaseURL('/docs/kcl-lang')}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
LanguageServerClient,
|
||||
LspWorkerEventType,
|
||||
} from '@kittycad/codemirror-lsp-client'
|
||||
import { TEST } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import React, { createContext, useContext, useMemo, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import type * as LSP from 'vscode-languageserver-protocol'
|
||||
@ -78,7 +78,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
// But the server happens async so we break this into two parts.
|
||||
// Below is the client and server promise.
|
||||
const { lspClient: kclLspClient } = useMemo(() => {
|
||||
if (!token || token === '' || TEST) {
|
||||
if (!token || token === '' || env().TEST) {
|
||||
return { lspClient: null }
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
// We do not want to restart the server, its just wasteful.
|
||||
const kclLSP = useMemo(() => {
|
||||
let plugin = null
|
||||
if (isKclLspReady && !TEST && kclLspClient) {
|
||||
if (isKclLspReady && !env().TEST && kclLspClient) {
|
||||
// Set up the lsp plugin.
|
||||
const lsp = kcl({
|
||||
documentUri: `file:///${PROJECT_ENTRYPOINT}`,
|
||||
@ -171,7 +171,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
}, [kclLspClient, isKclLspReady])
|
||||
|
||||
const { lspClient: copilotLspClient } = useMemo(() => {
|
||||
if (!token || token === '' || TEST) {
|
||||
if (!token || token === '' || env().TEST) {
|
||||
return { lspClient: null }
|
||||
}
|
||||
|
||||
@ -213,7 +213,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
// We do not want to restart the server, its just wasteful.
|
||||
const copilotLSP = useMemo(() => {
|
||||
let plugin = null
|
||||
if (isCopilotLspReady && !TEST && copilotLspClient) {
|
||||
if (isCopilotLspReady && !env().TEST && copilotLspClient) {
|
||||
// Set up the lsp plugin.
|
||||
const lsp = copilotPlugin({
|
||||
documentUri: `file:///${PROJECT_ENTRYPOINT}`,
|
||||
|
@ -12,6 +12,7 @@ import { reportRejection } from '@src/lib/trap'
|
||||
import { commandBarActor, settingsActor } from '@src/lib/singletons'
|
||||
|
||||
import styles from './KclEditorMenu.module.css'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
export const KclEditorMenu = ({ children }: PropsWithChildren) => {
|
||||
const { enable: convertToVarEnabled, handleClick: handleConvertToVarClick } =
|
||||
@ -67,7 +68,7 @@ export const KclEditorMenu = ({ children }: PropsWithChildren) => {
|
||||
<Menu.Item>
|
||||
<a
|
||||
className={styles.button}
|
||||
href="https://zoo.dev/docs/kcl-lang"
|
||||
href={withSiteBaseURL('/docs/kcl-lang')}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={openExternalBrowserIfDesktop()}
|
||||
@ -108,7 +109,7 @@ export const KclEditorMenu = ({ children }: PropsWithChildren) => {
|
||||
<Menu.Item>
|
||||
<a
|
||||
className={styles.button}
|
||||
href="https://zoo.dev/docs/kcl-samples"
|
||||
href={withSiteBaseURL('/docs/kcl-samples')}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={openExternalBrowserIfDesktop()}
|
||||
|
@ -35,7 +35,7 @@ import {
|
||||
rectangularSelection,
|
||||
} from '@codemirror/view'
|
||||
import interact from '@replit/codemirror-interact'
|
||||
import { TEST } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import { useSelector } from '@xstate/react'
|
||||
import { useEffect, useMemo, useRef } from 'react'
|
||||
|
||||
@ -149,7 +149,7 @@ export const KclEditorPane = () => {
|
||||
if (copilotLSP) extensions.push(copilotLSP)
|
||||
|
||||
// These extensions have proven to mess with vitest
|
||||
if (!TEST) {
|
||||
if (!env().TEST) {
|
||||
extensions.push(
|
||||
lintGutter(),
|
||||
lineNumbers(),
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Transition } from '@headlessui/react'
|
||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { base64ToString } from '@src/lib/base64'
|
||||
|
||||
@ -16,6 +15,7 @@ import { platform } from '@src/lib/utils'
|
||||
import { codeManager } from '@src/lib/singletons'
|
||||
import { Logo } from '@src/components/Logo'
|
||||
import { useEffect } from 'react'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
/**
|
||||
* This component is a handler that checks if a certain query parameter
|
||||
@ -98,7 +98,7 @@ export const OpenInDesktopAppHandler = (props: React.PropsWithChildren) => {
|
||||
>
|
||||
<Transition.Child
|
||||
as="div"
|
||||
className={`max-w-3xl py-6 px-10 flex flex-col items-center gap-12
|
||||
className={`max-w-3xl py-6 px-10 flex flex-col items-center gap-12
|
||||
mx-auto border rounded-lg shadow-lg bg-chalkboard-10 dark:bg-chalkboard-100`}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
@ -133,7 +133,7 @@ export const OpenInDesktopAppHandler = (props: React.PropsWithChildren) => {
|
||||
buttonClasses +
|
||||
' text-sm border-transparent justify-center dark:bg-transparent'
|
||||
}
|
||||
to={`${VITE_KC_SITE_BASE_URL}/${APP_DOWNLOAD_PATH}`}
|
||||
to={withSiteBaseURL(`/${APP_DOWNLOAD_PATH}`)}
|
||||
iconEnd={{ icon: 'link', bgClassName: '!bg-transparent' }}
|
||||
>
|
||||
Download desktop app
|
||||
|
@ -12,9 +12,9 @@ import { Popover } from '@headlessui/react'
|
||||
import Tooltip from '@src/components/Tooltip'
|
||||
import { HelpMenu } from '@src/components/HelpMenu'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
||||
import { APP_DOWNLOAD_PATH } from '@src/lib/constants'
|
||||
import { desktopAppPitchMessage } from '@src/components/DownloadAppToast'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
export const defaultGlobalStatusBarItems = ({
|
||||
location,
|
||||
@ -37,7 +37,7 @@ export const defaultGlobalStatusBarItems = ({
|
||||
id: 'download-desktop-app',
|
||||
element: 'externalLink',
|
||||
label: 'Download the app',
|
||||
href: `${VITE_KC_SITE_BASE_URL}/${APP_DOWNLOAD_PATH}`,
|
||||
href: withSiteBaseURL(`/${APP_DOWNLOAD_PATH}`),
|
||||
icon: 'download',
|
||||
toolTip: {
|
||||
children: desktopAppPitchMessage,
|
||||
|
@ -13,6 +13,7 @@ import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { PATHS } from '@src/lib/paths'
|
||||
import { authActor } from '@src/lib/singletons'
|
||||
import { reportRejection } from '@src/lib/trap'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
type User = Models['User_type']
|
||||
|
||||
@ -62,7 +63,7 @@ const UserSidebarMenu = ({ user }: { user?: User }) => {
|
||||
{
|
||||
id: 'account',
|
||||
Element: 'externalLink',
|
||||
to: 'https://zoo.dev/account',
|
||||
to: withSiteBaseURL('/account'),
|
||||
children: (
|
||||
<>
|
||||
<span className="flex-1">Manage account</span>
|
||||
|
126
src/env.test.ts
Normal file
126
src/env.test.ts
Normal file
@ -0,0 +1,126 @@
|
||||
import env from '@src/env'
|
||||
import { vi } from 'vitest'
|
||||
import { viteEnv, windowElectronProcessEnv, processEnv } from '@src/env'
|
||||
|
||||
describe('@src/env', () => {
|
||||
describe('default export', () => {
|
||||
it('should run the process.env workflow', () => {
|
||||
// vite > node.js
|
||||
const expected = {
|
||||
NODE_ENV: 'test',
|
||||
VITE_KC_API_WS_MODELING_URL:
|
||||
'wss://api.dev.zoo.dev/ws/modeling/commands',
|
||||
VITE_KITTYCAD_API_BASE_URL: 'https://api.dev.zoo.dev',
|
||||
VITE_KC_SITE_BASE_URL: 'https://dev.zoo.dev',
|
||||
VITE_KC_SITE_APP_URL: 'https://app.dev.zoo.dev',
|
||||
VITE_KC_CONNECTION_TIMEOUT_MS: '5000',
|
||||
VITE_KITTYCAD_API_TOKEN: 'redacted',
|
||||
PROD: undefined,
|
||||
TEST: 'true',
|
||||
DEV: '1',
|
||||
CI: 'true',
|
||||
}
|
||||
const actual = env()
|
||||
expect(typeof actual.VITE_KITTYCAD_API_TOKEN).toBe('string')
|
||||
//@ts-ignore I do not want this token in our logs for any reason.
|
||||
actual.VITE_KITTYCAD_API_TOKEN = 'redacted'
|
||||
//@ts-ignore need to hard code this for localhost and CI
|
||||
actual.CI = 'true'
|
||||
expect(actual).toStrictEqual(expected)
|
||||
})
|
||||
})
|
||||
describe('viteEnv', () => {
|
||||
it('should match the EnvironmentVariables key types*', () => {
|
||||
// Do not print entire object or compare, it contains a ton of ENV vars.
|
||||
// We only need to match against EnvironmentVariables
|
||||
const actual = viteEnv()
|
||||
expect(typeof actual.NODE_ENV).toBe('string')
|
||||
// Not passed in during tests?
|
||||
expect(typeof actual.VITE_KC_WS_MODELING_URL).toBe('undefined')
|
||||
expect(typeof actual.VITE_KITTYCAD_API_BASE_URL).toBe('string')
|
||||
expect(typeof actual.VITE_KC_SITE_BASE_URL).toBe('string')
|
||||
// Not passed in during tests?
|
||||
expect(typeof actual.VITE_KC_SITE_API_URL).toBe('undefined')
|
||||
expect(typeof actual.VITE_KC_CONNECTION_TIMEOUT_MS).toBe('string')
|
||||
expect(typeof actual.VITE_KITTYCAD_API_TOKEN).toBe('string')
|
||||
expect(typeof actual.PROD).toBe('boolean')
|
||||
expect(typeof actual.TEST).toBe('string')
|
||||
expect(typeof actual.DEV).toBe('boolean')
|
||||
// Don't check CI...
|
||||
})
|
||||
})
|
||||
describe('windowElectronProcessEnv', () => {
|
||||
it('should return undefined in vitest runtime', () => {
|
||||
const expected = undefined
|
||||
const actual = windowElectronProcessEnv()
|
||||
expect(actual).toBe(expected)
|
||||
})
|
||||
describe('When mocking window', () => {
|
||||
it('should match the EnvironmentVariable key types*', () => {
|
||||
vi.stubGlobal('electron', {
|
||||
process: {
|
||||
env: {
|
||||
NODE_ENV: 'test',
|
||||
VITE_KC_API_WS_MODELING_URL:
|
||||
'wss://api.dev.zoo.dev/ws/modeling/commands',
|
||||
VITE_KITTYCAD_API_BASE_URL: 'https://api.dev.zoo.dev',
|
||||
VITE_KC_SITE_BASE_URL: 'https://dev.zoo.dev',
|
||||
VITE_KC_SITE_APP_URL: 'https://app.dev.zoo.dev',
|
||||
VITE_KC_CONNECTION_TIMEOUT_MS: '5000',
|
||||
VITE_KITTYCAD_API_TOKEN: 'redacted',
|
||||
PROD: undefined,
|
||||
TEST: 'true',
|
||||
DEV: '1',
|
||||
CI: undefined,
|
||||
},
|
||||
},
|
||||
})
|
||||
const expected = {
|
||||
NODE_ENV: 'test',
|
||||
VITE_KC_API_WS_MODELING_URL:
|
||||
'wss://api.dev.zoo.dev/ws/modeling/commands',
|
||||
VITE_KITTYCAD_API_BASE_URL: 'https://api.dev.zoo.dev',
|
||||
VITE_KC_SITE_BASE_URL: 'https://dev.zoo.dev',
|
||||
VITE_KC_SITE_APP_URL: 'https://app.dev.zoo.dev',
|
||||
VITE_KC_CONNECTION_TIMEOUT_MS: '5000',
|
||||
VITE_KITTYCAD_API_TOKEN: 'redacted',
|
||||
PROD: undefined,
|
||||
TEST: 'true',
|
||||
DEV: '1',
|
||||
CI: undefined,
|
||||
}
|
||||
const actual = windowElectronProcessEnv()
|
||||
expect(actual).toStrictEqual(expected)
|
||||
vi.unstubAllGlobals()
|
||||
})
|
||||
})
|
||||
it('should fail on missing window.electron', () => {
|
||||
// someone didn't clean up their test if this fails!
|
||||
const expected = undefined
|
||||
const actual = windowElectronProcessEnv()
|
||||
expect(actual).toBe(expected)
|
||||
expect(window.electron).toBe(expected)
|
||||
})
|
||||
})
|
||||
describe('processEnv', () => {
|
||||
it('should match the EnvironmentVariables key types*', () => {
|
||||
// Do not print entire object or compare, it contains a ton of ENV vars.
|
||||
// We only need to match against EnvironmentVariables
|
||||
const actual = processEnv()
|
||||
expect(!!actual).toBe(true)
|
||||
expect(typeof actual?.NODE_ENV).toBe('string')
|
||||
// Not passed in during tests?
|
||||
expect(typeof actual?.VITE_KC_WS_MODELING_URL).toBe('undefined')
|
||||
expect(typeof actual?.VITE_KITTYCAD_API_BASE_URL).toBe('string')
|
||||
expect(typeof actual?.VITE_KC_SITE_BASE_URL).toBe('string')
|
||||
// Not passed in during tests?
|
||||
expect(typeof actual?.VITE_KC_SITE_API_URL).toBe('undefined')
|
||||
expect(typeof actual?.VITE_KC_CONNECTION_TIMEOUT_MS).toBe('string')
|
||||
expect(typeof actual?.VITE_KITTYCAD_API_TOKEN).toBe('string')
|
||||
expect(typeof actual?.PROD).toBe('string')
|
||||
expect(typeof actual?.TEST).toBe('string')
|
||||
expect(typeof actual?.DEV).toBe('string')
|
||||
// Don't check CI...
|
||||
})
|
||||
})
|
||||
})
|
108
src/env.ts
108
src/env.ts
@ -1,22 +1,88 @@
|
||||
// It turns out import.meta.env is a really fucky env var passing method.
|
||||
// It's purely generated by Vite and nothing else.
|
||||
// For Jest tests, we use babel to deal with it (it's a Syntax error otherwise)
|
||||
// @ts-ignore: TS1343
|
||||
const env = window.electron?.process.env ?? import.meta.env
|
||||
type EnvironmentVariables = {
|
||||
readonly NODE_ENV: string | undefined
|
||||
readonly VITE_KC_API_WS_MODELING_URL: string | undefined
|
||||
readonly VITE_KITTYCAD_API_BASE_URL: string | undefined
|
||||
readonly VITE_KC_SITE_BASE_URL: string | undefined
|
||||
readonly VITE_KC_SITE_APP_URL: string | undefined
|
||||
readonly VITE_KC_CONNECTION_TIMEOUT_MS: string | undefined
|
||||
readonly VITE_KITTYCAD_API_TOKEN: string | undefined
|
||||
readonly PROD: string | undefined
|
||||
readonly TEST: string | undefined
|
||||
readonly DEV: string | undefined
|
||||
readonly CI: string | undefined
|
||||
}
|
||||
|
||||
export const NODE_ENV = env.NODE_ENV as string | undefined
|
||||
export const VITE_KC_API_WS_MODELING_URL = env.VITE_KC_API_WS_MODELING_URL as
|
||||
| string
|
||||
| undefined
|
||||
export const VITE_KITTYCAD_API_BASE_URL = env.VITE_KITTYCAD_API_BASE_URL
|
||||
export const VITE_KC_SITE_BASE_URL = env.VITE_KC_SITE_BASE_URL
|
||||
export const VITE_KC_SITE_APP_URL = env.VITE_KC_SITE_APP_URL
|
||||
export const VITE_KC_CONNECTION_TIMEOUT_MS =
|
||||
env.VITE_KC_CONNECTION_TIMEOUT_MS as string | undefined
|
||||
export const VITE_KITTYCAD_API_TOKEN = env.VITE_KITTYCAD_API_TOKEN as
|
||||
| string
|
||||
| undefined
|
||||
export const PROD = env.PROD as string | undefined
|
||||
export const TEST = env.TEST as string | undefined
|
||||
export const DEV = env.DEV as string | undefined
|
||||
export const CI = env.CI as string | undefined
|
||||
export const viteEnv = () => {
|
||||
// It turns out import.meta.env is a really fucky env var passing method.
|
||||
// It's purely generated by Vite and nothing else.
|
||||
// For Jest tests, we use babel to deal with it (it's a Syntax error otherwise)
|
||||
// @ts-ignore: TS1343
|
||||
return import.meta.env
|
||||
}
|
||||
|
||||
export const windowElectronProcessEnv = () => {
|
||||
return typeof window !== 'undefined' && typeof window.electron !== 'undefined'
|
||||
? window?.electron?.process?.env
|
||||
: undefined
|
||||
}
|
||||
|
||||
export const processEnv = () => {
|
||||
if (typeof process === 'undefined') {
|
||||
// Web, no window.process or process
|
||||
return undefined
|
||||
} else if (
|
||||
typeof process !== 'undefined' &&
|
||||
typeof window !== 'undefined' &&
|
||||
process.env.TEST === 'false'
|
||||
) {
|
||||
// Web, you made window.process, why :(, need process.env.TEST to make sure the frontend gets evaluated.
|
||||
// The frontend can spoof this too :(
|
||||
return undefined
|
||||
}
|
||||
|
||||
return process.env
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will work in any runtime. Note that we shouldn't be using this for any values outside of the
|
||||
* EnvironmentVariables type. This is not going to replace process.env.
|
||||
*
|
||||
* Vite -> node.js -> bridge -> javascript
|
||||
* We want to have the node.js and javascript runtime share the same code for getting these important configurations.
|
||||
*/
|
||||
export default (): EnvironmentVariables => {
|
||||
// Compute the possible environment variables, order operation is important
|
||||
// runtime (TODO) > process.env > window.electron.process.env > import.meta.env
|
||||
|
||||
const viteOnly = viteEnv()
|
||||
const windowElectronProcessEnvOnly = windowElectronProcessEnv()
|
||||
const processEnvOnly = processEnv()
|
||||
const env = processEnvOnly || windowElectronProcessEnvOnly || viteOnly
|
||||
// Vite uses Booleans and process.env uses strings
|
||||
let PROD = env.PROD
|
||||
if (typeof PROD === 'boolean') {
|
||||
PROD = Number(PROD).toString()
|
||||
}
|
||||
let DEV = env.DEV
|
||||
if (typeof DEV === 'boolean') {
|
||||
DEV = Number(DEV).toString()
|
||||
}
|
||||
const environmentVariables: EnvironmentVariables = {
|
||||
NODE_ENV: (env.NODE_ENV as string) || undefined,
|
||||
VITE_KC_API_WS_MODELING_URL:
|
||||
(env.VITE_KC_API_WS_MODELING_URL as string) || undefined,
|
||||
VITE_KITTYCAD_API_BASE_URL:
|
||||
(env.VITE_KITTYCAD_API_BASE_URL as string) || undefined,
|
||||
VITE_KC_SITE_BASE_URL: (env.VITE_KC_SITE_BASE_URL as string) || undefined,
|
||||
VITE_KC_SITE_APP_URL: (env.VITE_KC_SITE_APP_URL as string) || undefined,
|
||||
VITE_KC_CONNECTION_TIMEOUT_MS:
|
||||
(env.VITE_KC_CONNECTION_TIMEOUT_MS as string) || undefined,
|
||||
VITE_KITTYCAD_API_TOKEN:
|
||||
(env.VITE_KITTYCAD_API_TOKEN as string) || undefined,
|
||||
PROD: PROD || undefined,
|
||||
TEST: (env.TEST as string) || undefined,
|
||||
DEV: DEV || undefined,
|
||||
CI: (env.CI as string) || undefined,
|
||||
}
|
||||
return environmentVariables
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { VITE_KITTYCAD_API_TOKEN } from '@src/env'
|
||||
import env from '@src/env'
|
||||
|
||||
import { createLiteral } from '@src/lang/create'
|
||||
import type {
|
||||
@ -42,7 +42,7 @@ beforeAll(async () => {
|
||||
|
||||
await new Promise((resolve) => {
|
||||
engineCommandManager.start({
|
||||
token: VITE_KITTYCAD_API_TOKEN,
|
||||
token: env().VITE_KITTYCAD_API_TOKEN,
|
||||
width: 256,
|
||||
height: 256,
|
||||
setMediaStream: () => {},
|
||||
|
@ -4,7 +4,7 @@ import { initPromise } from '@src/lang/wasmUtils'
|
||||
import { err } from '@src/lib/trap'
|
||||
import type { Selection } from '@src/lib/selections'
|
||||
import { engineCommandManager, kclManager } from '@src/lib/singletons'
|
||||
import { VITE_KITTYCAD_API_TOKEN } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import { modifyAstWithTagsForSelection } from '@src/lang/modifyAst/tagManagement'
|
||||
|
||||
beforeAll(async () => {
|
||||
@ -12,7 +12,7 @@ beforeAll(async () => {
|
||||
|
||||
await new Promise((resolve) => {
|
||||
engineCommandManager.start({
|
||||
token: VITE_KITTYCAD_API_TOKEN,
|
||||
token: env().VITE_KITTYCAD_API_TOKEN,
|
||||
width: 256,
|
||||
height: 256,
|
||||
setMediaStream: () => {},
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { Models } from '@kittycad/lib'
|
||||
import { VITE_KC_API_WS_MODELING_URL, VITE_KITTYCAD_API_TOKEN } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import { jsAppSettings } from '@src/lib/settings/settingsUtils'
|
||||
import { BSON } from 'bson'
|
||||
|
||||
@ -387,7 +387,7 @@ class EngineConnection extends EventTarget {
|
||||
|
||||
// SHOULD ONLY BE USED FOR VITESTS
|
||||
connectLite(callback: () => void) {
|
||||
const url = `${VITE_KC_API_WS_MODELING_URL}?video_res_width=${256}&video_res_height=${256}`
|
||||
const url = `${env().VITE_KC_API_WS_MODELING_URL}?video_res_width=${256}&video_res_height=${256}`
|
||||
|
||||
this.websocket = new WebSocket(url, [])
|
||||
this.websocket.binaryType = 'arraybuffer'
|
||||
@ -400,7 +400,7 @@ class EngineConnection extends EventTarget {
|
||||
this.send({
|
||||
type: 'headers',
|
||||
headers: {
|
||||
Authorization: `Bearer ${VITE_KITTYCAD_API_TOKEN}`,
|
||||
Authorization: `Bearer ${env().VITE_KITTYCAD_API_TOKEN}`,
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -1531,7 +1531,7 @@ export class EngineCommandManager extends EventTarget {
|
||||
additionalSettings +=
|
||||
'&show_grid=' + (this.settings.showScaleGrid ? 'true' : 'false')
|
||||
const pool = !this.settings.pool ? '' : `&pool=${this.settings.pool}`
|
||||
const url = `${VITE_KC_API_WS_MODELING_URL}?video_res_width=${width}&video_res_height=${height}${additionalSettings}${pool}`
|
||||
const url = `${env().VITE_KC_API_WS_MODELING_URL}?video_res_width=${width}&video_res_height=${height}${additionalSettings}${pool}`
|
||||
this.engineConnection = new EngineConnection({
|
||||
engineCommandManager: this,
|
||||
url,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DEV } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import type {
|
||||
Actor,
|
||||
AnyStateMachine,
|
||||
@ -89,7 +89,8 @@ export function createMachineCommand<
|
||||
} else if ('status' in commandConfig) {
|
||||
const { status } = commandConfig
|
||||
if (status === 'inactive') return null
|
||||
if (status === 'development' && !(DEV || IS_STAGING_OR_DEBUG)) return null
|
||||
if (status === 'development' && !(env().DEV || IS_STAGING_OR_DEBUG))
|
||||
return null
|
||||
}
|
||||
|
||||
const icon = ('icon' in commandConfig && commandConfig.icon) || undefined
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DEV } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import isomorphicFetch from 'isomorphic-fetch'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
|
||||
@ -28,7 +28,7 @@ export default async function crossPlatformFetch<T>(
|
||||
// Add credentials: 'include' to options
|
||||
// We send the token with the headers only in development mode, DO NOT
|
||||
// DO THIS IN PRODUCTION, as it is a security risk.
|
||||
opts.headers = headers(DEV ? token : undefined)
|
||||
opts.headers = headers(env().DEV ? token : undefined)
|
||||
opts.credentials = 'include'
|
||||
response = await fetch(url, opts)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { VITE_KC_SITE_APP_URL } from '@src/env'
|
||||
import env from '@src/env'
|
||||
|
||||
import { createCreateFileUrl } from '@src/lib/links'
|
||||
|
||||
@ -9,7 +9,7 @@ describe(`link creation tests`, () => {
|
||||
|
||||
// Converted with external online tools
|
||||
const expectedEncodedCode = `ZXh0cnVzaW9uRGlzdGFuY2UgPSAxMg%3D%3D`
|
||||
const expectedLink = `${VITE_KC_SITE_APP_URL}/?create-file=true&name=test&code=${expectedEncodedCode}&ask-open-desktop=true`
|
||||
const expectedLink = `${env().VITE_KC_SITE_APP_URL}/?create-file=true&name=test&code=${expectedEncodedCode}&ask-open-desktop=true`
|
||||
|
||||
const result = createCreateFileUrl({ code, name, isRestrictedToOrg: false })
|
||||
expect(result.toString()).toBe(expectedLink)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { VITE_KC_SITE_APP_URL } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import toast from 'react-hot-toast'
|
||||
|
||||
import { stringToBase64 } from '@src/lib/base64'
|
||||
@ -58,7 +58,7 @@ export async function copyFileShareLink(
|
||||
* open the URL in the desktop app.
|
||||
*/
|
||||
export function createCreateFileUrl({ code, name }: FileLinkParams) {
|
||||
let origin = VITE_KC_SITE_APP_URL
|
||||
let origin = env().VITE_KC_SITE_APP_URL
|
||||
const searchParams = new URLSearchParams({
|
||||
[CREATE_FILE_URL_PARAM]: String(true),
|
||||
name,
|
||||
|
@ -1,7 +1,6 @@
|
||||
import type { SelectionRange } from '@codemirror/state'
|
||||
import { EditorSelection, Transaction } from '@codemirror/state'
|
||||
import type { Models } from '@kittycad/lib'
|
||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
||||
import { diffLines } from 'diff'
|
||||
import toast from 'react-hot-toast'
|
||||
import type { TextToCadMultiFileIteration_type } from '@kittycad/lib/dist/types/src/models'
|
||||
@ -28,7 +27,8 @@ import { uuidv4 } from '@src/lib/utils'
|
||||
import type { File as KittyCadLibFile } from '@kittycad/lib/dist/types/src/models'
|
||||
import type { FileMeta } from '@src/lib/types'
|
||||
import type { RequestedKCLFile } from '@src/machines/systemIO/utils'
|
||||
import { withAPIBaseURL } from '@src/lib/withBaseURL'
|
||||
import { withAPIBaseURL, withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
import env from '@src/env'
|
||||
|
||||
type KclFileMetaMap = {
|
||||
[execStateFileNamesIndex: number]: Extract<FileMeta, { type: 'kcl' }>
|
||||
@ -439,7 +439,7 @@ export async function promptToEditFlow({
|
||||
return Promise.reject(result)
|
||||
}
|
||||
const oldCodeWebAppOnly = codeManager.code
|
||||
const downloadLink = `${VITE_KC_SITE_BASE_URL}/${APP_DOWNLOAD_PATH}`
|
||||
const downloadLink = withSiteBaseURL(`/${APP_DOWNLOAD_PATH}`)
|
||||
|
||||
if (!isDesktop() && Object.values(result.outputs).length > 1) {
|
||||
const toastId = uuidv4()
|
||||
|
@ -2,7 +2,7 @@ import type { Configuration } from '@rust/kcl-lib/bindings/Configuration'
|
||||
import type { NamedView } from '@rust/kcl-lib/bindings/NamedView'
|
||||
import type { ProjectConfiguration } from '@rust/kcl-lib/bindings/ProjectConfiguration'
|
||||
import { default_app_settings } from '@rust/kcl-wasm-lib/pkg/kcl_wasm_lib'
|
||||
import { TEST } from '@src/env'
|
||||
import env from '@src/env'
|
||||
|
||||
import {
|
||||
defaultAppSettings,
|
||||
@ -545,7 +545,7 @@ export function getSettingInputType(setting: Setting) {
|
||||
|
||||
export const jsAppSettings = async (): Promise<DeepPartial<Configuration>> => {
|
||||
let jsAppSettings = default_app_settings()
|
||||
if (!TEST) {
|
||||
if (!env().TEST) {
|
||||
// TODO: https://github.com/KittyCAD/modeling-app/issues/6445
|
||||
const settings = await import('@src/lib/singletons').then((module) =>
|
||||
module.getSettings()
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
pipeHasCircle,
|
||||
} from '@src/machines/modelingMachine'
|
||||
import { IS_ML_EXPERIMENTAL } from '@src/lib/constants'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
export type ToolbarModeName = 'modeling' | 'sketching'
|
||||
|
||||
@ -105,7 +106,9 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-sketch-startSketchOn',
|
||||
url: withSiteBaseURL(
|
||||
'/docs/kcl-std/functions/std-sketch-startSketchOn'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -125,7 +128,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-sketch-extrude',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-sketch-extrude'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -145,7 +148,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-sketch-sweep',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-sketch-sweep'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -165,7 +168,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-sketch-loft',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-sketch-loft'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -185,11 +188,11 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-sketch-revolve',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-sketch-revolve'),
|
||||
},
|
||||
{
|
||||
label: 'KCL example',
|
||||
url: 'https://zoo.dev/docs/kcl-samples/ball-bearing',
|
||||
url: withSiteBaseURL('/docs/kcl-samples/ball-bearing'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -209,7 +212,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-solid-fillet',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-solid-fillet'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -234,7 +237,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
},
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-solid-chamfer',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-solid-chamfer'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -253,7 +256,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-solid-shell',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-solid-shell'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -275,7 +278,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-solid-union',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-solid-union'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -293,7 +296,9 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-solid-subtract',
|
||||
url: withSiteBaseURL(
|
||||
'/docs/kcl-std/functions/std-solid-subtract'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -311,7 +316,9 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-solid-intersect',
|
||||
url: withSiteBaseURL(
|
||||
'/docs/kcl-std/functions/std-solid-intersect'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -337,7 +344,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-offsetPlane',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-offsetPlane'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -368,7 +375,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-helix',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-helix'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -389,7 +396,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'API docs',
|
||||
url: 'https://zoo.dev/docs/kcl-lang/modules',
|
||||
url: withSiteBaseURL('/docs/kcl-lang/modules'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -410,7 +417,9 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'API docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-transform-translate',
|
||||
url: withSiteBaseURL(
|
||||
'/docs/kcl-std/functions/std-transform-translate'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -428,7 +437,9 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'API docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-transform-rotate',
|
||||
url: withSiteBaseURL(
|
||||
'/docs/kcl-std/functions/std-transform-rotate'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -446,7 +457,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'API docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-clone',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-clone'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -482,7 +493,9 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'API docs',
|
||||
url: 'https://zoo.dev/docs/api/ml/generate-a-cad-model-from-text',
|
||||
url: withSiteBaseURL(
|
||||
'/docs/api/ml/generate-a-cad-model-from-text'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -739,7 +752,7 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-sketch-polygon',
|
||||
url: withSiteBaseURL('/docs/kcl-std/functions/std-sketch-polygon'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -755,7 +768,9 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [
|
||||
{
|
||||
label: 'KCL docs',
|
||||
url: 'https://zoo.dev/docs/kcl-std/functions/std-transform-mirror2d',
|
||||
url: withSiteBaseURL(
|
||||
'/docs/kcl-std/functions/std-transform-mirror2d'
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { withAPIBaseURL } from '@src/lib/withBaseURL'
|
||||
import { withAPIBaseURL, withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
describe('withBaseURL', () => {
|
||||
/**
|
||||
* running in the development environment
|
||||
* the .env.development should load
|
||||
*/
|
||||
describe('withAPIBaseUrl', () => {
|
||||
describe('withAPIBaseURL', () => {
|
||||
it('should return base url', () => {
|
||||
const expected = 'https://api.dev.zoo.dev'
|
||||
const actual = withAPIBaseURL('')
|
||||
@ -31,4 +31,31 @@ describe('withBaseURL', () => {
|
||||
expect(actualEndsWith).toBe(expectedEndsWith)
|
||||
})
|
||||
})
|
||||
|
||||
describe('withSiteBaseURL', () => {
|
||||
it('should return base url', () => {
|
||||
const expected = 'https://dev.zoo.dev'
|
||||
const actual = withSiteBaseURL('')
|
||||
expect(actual).toBe(expected)
|
||||
})
|
||||
it('should return base url with /docs', () => {
|
||||
const expected = 'https://dev.zoo.dev/docs'
|
||||
const actual = withSiteBaseURL('/docs')
|
||||
expect(actual).toBe(expected)
|
||||
})
|
||||
it('should return a longer base base url with /docs/kcl-samples/car-wheel-assembly', () => {
|
||||
const expected = 'https://dev.zoo.dev/docs/kcl-samples/car-wheel-assembly'
|
||||
const actual = withSiteBaseURL('/docs/kcl-samples/car-wheel-assembly')
|
||||
expect(actual).toBe(expected)
|
||||
})
|
||||
it('should ensure base url does not have ending slash', () => {
|
||||
const expected = 'https://dev.zoo.dev'
|
||||
const actual = withSiteBaseURL('')
|
||||
expect(actual).toBe(expected)
|
||||
const expectedEndsWith = expected[expected.length - 1]
|
||||
const actualEndsWith = actual[actual.length - 1]
|
||||
expect(actual).toBe(expected)
|
||||
expect(actualEndsWith).toBe(expectedEndsWith)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { VITE_KITTYCAD_API_BASE_URL } from '@src/env'
|
||||
import env from '@src/env'
|
||||
|
||||
export function withAPIBaseURL(path: string): string {
|
||||
return VITE_KITTYCAD_API_BASE_URL + path
|
||||
return env().VITE_KITTYCAD_API_BASE_URL + path
|
||||
}
|
||||
|
||||
export function withSiteBaseURL(path: string): string {
|
||||
return env().VITE_KC_SITE_BASE_URL + path
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { Models } from '@kittycad/lib'
|
||||
import { VITE_KITTYCAD_API_TOKEN } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import { assign, fromPromise, setup } from 'xstate'
|
||||
|
||||
import { COOKIE_NAME, OAUTH2_DEVICE_CLIENT_ID } from '@src/lib/constants'
|
||||
@ -34,7 +34,7 @@ export const TOKEN_PERSIST_KEY = 'TOKEN_PERSIST_KEY'
|
||||
*/
|
||||
const persistedCookie = getCookie(COOKIE_NAME)
|
||||
const persistedLocalStorage = localStorage?.getItem(TOKEN_PERSIST_KEY) || ''
|
||||
const persistedDevToken = VITE_KITTYCAD_API_TOKEN
|
||||
const persistedDevToken = env().VITE_KITTYCAD_API_TOKEN
|
||||
export const persistedToken =
|
||||
persistedDevToken || persistedCookie || persistedLocalStorage
|
||||
console.log('Initial persisted token')
|
||||
@ -197,6 +197,7 @@ async function getAndSyncStoredToken(input: {
|
||||
token?: string
|
||||
}): Promise<string> {
|
||||
// dev mode
|
||||
const VITE_KITTYCAD_API_TOKEN = env().VITE_KITTYCAD_API_TOKEN
|
||||
if (VITE_KITTYCAD_API_TOKEN) {
|
||||
console.log('Token used for authentication')
|
||||
console.table([['api token', !!VITE_KITTYCAD_API_TOKEN]])
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
engineCommandManager,
|
||||
kclManager,
|
||||
} from '@src/lib/singletons'
|
||||
import { VITE_KITTYCAD_API_TOKEN } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import { getConstraintInfoKw } from '@src/lang/std/sketch'
|
||||
import { getNodeFromPath } from '@src/lang/queryAst'
|
||||
import type { Node } from '@rust/kcl-lib/bindings/Node'
|
||||
@ -31,7 +31,7 @@ beforeAll(async () => {
|
||||
|
||||
await new Promise((resolve) => {
|
||||
engineCommandManager.start({
|
||||
token: VITE_KITTYCAD_API_TOKEN,
|
||||
token: env().VITE_KITTYCAD_API_TOKEN,
|
||||
width: 256,
|
||||
height: 256,
|
||||
setMediaStream: () => {},
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { engineCommandManager, kclManager } from '@src/lib/singletons'
|
||||
import { VITE_KITTYCAD_API_TOKEN } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import { getModuleIdByFileName, isArray } from '@src/lib/utils'
|
||||
import { vi, inject } from 'vitest'
|
||||
import { assertParse } from '@src/lang/wasm'
|
||||
@ -357,7 +357,7 @@ beforeAll(async () => {
|
||||
|
||||
await new Promise((resolve) => {
|
||||
engineCommandManager.start({
|
||||
token: VITE_KITTYCAD_API_TOKEN,
|
||||
token: env().VITE_KITTYCAD_API_TOKEN,
|
||||
width: 256,
|
||||
height: 256,
|
||||
setMediaStream: () => {},
|
||||
|
@ -5,6 +5,7 @@ import { reportRejection } from '@src/lib/trap'
|
||||
import { typeSafeWebContentsSend } from '@src/menu/channels'
|
||||
import type { ZooMenuItemConstructorOptions } from '@src/menu/roles'
|
||||
import { getAutoUpdater } from '@src/updater'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
export const helpRole = (
|
||||
mainWindow: BrowserWindow
|
||||
@ -26,14 +27,16 @@ export const helpRole = (
|
||||
id: 'Help.KCL code samples',
|
||||
click: () => {
|
||||
shell
|
||||
.openExternal('https://zoo.dev/docs/kcl-samples')
|
||||
.openExternal(withSiteBaseURL('/docs/kcl-samples'))
|
||||
.catch(reportRejection)
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'KCL Docs',
|
||||
click: () => {
|
||||
shell.openExternal('https://zoo.dev/docs/kcl').catch(reportRejection)
|
||||
shell
|
||||
.openExternal(withSiteBaseURL('/docs/kcl'))
|
||||
.catch(reportRejection)
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -116,7 +119,7 @@ export const helpRole = (
|
||||
{
|
||||
label: 'Manage Account',
|
||||
click: () => {
|
||||
shell.openExternal('https://zoo.dev/account').catch(reportRejection)
|
||||
shell.openExternal(withSiteBaseURL('/account')).catch(reportRejection)
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -67,6 +67,7 @@ import {
|
||||
defaultGlobalStatusBarItems,
|
||||
} from '@src/components/StatusBar/defaultStatusBarItems'
|
||||
import { useSelector } from '@xstate/react'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
type ReadWriteProjectState = {
|
||||
value: boolean
|
||||
@ -367,9 +368,9 @@ const Home = () => {
|
||||
<li className="contents">
|
||||
<ActionButton
|
||||
Element="externalLink"
|
||||
to="https://zoo.dev/docs"
|
||||
to={withSiteBaseURL('/account')}
|
||||
onClick={openExternalBrowserIfDesktop(
|
||||
'https://zoo.dev/account'
|
||||
withSiteBaseURL('/account')
|
||||
)}
|
||||
className={sidebarButtonClasses}
|
||||
iconStart={{
|
||||
@ -384,8 +385,8 @@ const Home = () => {
|
||||
<li className="contents">
|
||||
<ActionButton
|
||||
Element="externalLink"
|
||||
to="https://zoo.dev/blog"
|
||||
onClick={openExternalBrowserIfDesktop('https://zoo.dev/blog')}
|
||||
to={withSiteBaseURL('/blog')}
|
||||
onClick={openExternalBrowserIfDesktop(withSiteBaseURL('/blog'))}
|
||||
className={sidebarButtonClasses}
|
||||
iconStart={{
|
||||
icon: 'glasses',
|
||||
|
@ -25,12 +25,12 @@ import { systemIOActor, commandBarActor } from '@src/lib/singletons'
|
||||
import type { IndexLoaderData } from '@src/lib/types'
|
||||
import { SystemIOMachineEvents } from '@src/machines/systemIO/utils'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
||||
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
||||
import {
|
||||
browserAxialFan,
|
||||
browserAxialFanAfterTextToCad,
|
||||
} from '@src/lib/exampleKcl'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
type BrowserOnboaringRoute = RouteObject & {
|
||||
path: keyof typeof browserOnboardingPaths
|
||||
@ -461,7 +461,7 @@ function PromptToEditResult() {
|
||||
function OnboardingConclusion() {
|
||||
// Close the panes on mount, close on unmount
|
||||
useOnboardingPanes()
|
||||
const downloadLink = `${VITE_KC_SITE_BASE_URL}/${APP_DOWNLOAD_PATH}`
|
||||
const downloadLink = withSiteBaseURL(`/${APP_DOWNLOAD_PATH}`)
|
||||
|
||||
return (
|
||||
<div className="cursor-not-allowed fixed inset-0 z-50 p-16 grid justify-center items-center">
|
||||
|
@ -27,8 +27,8 @@ import {
|
||||
modifiedFanHousingBrowser,
|
||||
modifiedParametersDesktop,
|
||||
} from '@src/lib/exampleKcl'
|
||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
||||
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
type DesktopOnboardingRoute = RouteObject & {
|
||||
path: keyof typeof desktopOnboardingPaths
|
||||
@ -642,10 +642,8 @@ function OnboardingConclusion() {
|
||||
project, click the Zoo button in the top left. To learn more detailed
|
||||
and advanced techniques,{' '}
|
||||
<a
|
||||
onClick={openExternalBrowserIfDesktop(
|
||||
`${VITE_KC_SITE_BASE_URL}/docs`
|
||||
)}
|
||||
href={`${VITE_KC_SITE_BASE_URL}/docs`}
|
||||
onClick={openExternalBrowserIfDesktop(withSiteBaseURL('/docs'))}
|
||||
href={`${withSiteBaseURL('/docs')}`}
|
||||
>
|
||||
check out our docs
|
||||
</a>
|
||||
|
@ -6,7 +6,6 @@ import { Link } from 'react-router-dom'
|
||||
import { ActionButton } from '@src/components/ActionButton'
|
||||
import { CustomIcon } from '@src/components/CustomIcon'
|
||||
import { Logo } from '@src/components/Logo'
|
||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
||||
import { APP_NAME } from '@src/lib/constants'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
||||
@ -15,7 +14,7 @@ import { reportRejection } from '@src/lib/trap'
|
||||
import { toSync } from '@src/lib/utils'
|
||||
import { authActor, useSettings } from '@src/lib/singletons'
|
||||
import { APP_VERSION, generateSignInUrl } from '@src/routes/utils'
|
||||
import { withAPIBaseURL } from '@src/lib/withBaseURL'
|
||||
import { withAPIBaseURL, withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
const subtleBorder =
|
||||
'border border-solid border-chalkboard-30 dark:border-chalkboard-80'
|
||||
@ -37,7 +36,7 @@ const SignIn = () => {
|
||||
app: { theme },
|
||||
} = useSettings()
|
||||
const signInUrl = generateSignInUrl()
|
||||
const kclSampleUrl = `${VITE_KC_SITE_BASE_URL}/docs/kcl-samples/car-wheel-assembly`
|
||||
const kclSampleUrl = withSiteBaseURL('/docs/kcl-samples/car-wheel-assembly')
|
||||
|
||||
const getThemeText = useCallback(
|
||||
(shouldContrast = true) =>
|
||||
@ -261,7 +260,7 @@ const SignIn = () => {
|
||||
<div className="flex gap-4 flex-wrap items-center">
|
||||
<ActionButton
|
||||
Element="externalLink"
|
||||
to="https://zoo.dev/docs/kcl-samples/pillow-block-bearing"
|
||||
to={withSiteBaseURL('/docs/kcl-samples/pillow-block-bearing')}
|
||||
iconStart={{
|
||||
icon: 'settings',
|
||||
bgClassName: '!bg-transparent',
|
||||
@ -274,7 +273,7 @@ const SignIn = () => {
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="externalLink"
|
||||
to="https://zoo.dev/docs/zoo-design-studio/text-to-cad"
|
||||
to={withSiteBaseURL('/docs/zoo-design-studio/text-to-cad')}
|
||||
iconStart={{
|
||||
icon: 'sparkles',
|
||||
bgClassName: '!bg-transparent',
|
||||
@ -297,7 +296,7 @@ const SignIn = () => {
|
||||
<div className="flex gap-4 flex-wrap items-center">
|
||||
<ActionButton
|
||||
Element="externalLink"
|
||||
to="https://zoo.dev/design-api"
|
||||
to={withSiteBaseURL('/design-api')}
|
||||
iconStart={{ icon: 'sketch', bgClassName: '!bg-transparent' }}
|
||||
className="!bg-primary !text-chalkboard-10 !border-transarent"
|
||||
>
|
||||
@ -305,7 +304,7 @@ const SignIn = () => {
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
Element="externalLink"
|
||||
to="https://zoo.dev/machine-learning-api"
|
||||
to={withSiteBaseURL('/machine-learning-api')}
|
||||
iconStart={{
|
||||
icon: 'elephant',
|
||||
bgClassName: '!bg-transparent',
|
||||
|
@ -1,15 +1,16 @@
|
||||
import { NODE_ENV, VITE_KC_SITE_BASE_URL } from '@src/env'
|
||||
import env from '@src/env'
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import {
|
||||
IS_PLAYWRIGHT_KEY,
|
||||
IMMEDIATE_SIGN_IN_IF_NECESSARY_QUERY_PARAM,
|
||||
} from '@src/lib/constants'
|
||||
import { PATHS } from '@src/lib/paths'
|
||||
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||
|
||||
const isTestEnv = window?.localStorage.getItem(IS_PLAYWRIGHT_KEY) === 'true'
|
||||
|
||||
export const APP_VERSION =
|
||||
isTestEnv && NODE_ENV === 'development'
|
||||
isTestEnv && env().NODE_ENV === 'development'
|
||||
? '11.22.33'
|
||||
: isDesktop()
|
||||
? // @ts-ignore
|
||||
@ -54,7 +55,7 @@ export function generateSignInUrl() {
|
||||
'?'
|
||||
)
|
||||
|
||||
return `${VITE_KC_SITE_BASE_URL}${
|
||||
PATHS.SIGN_IN
|
||||
}?callbackUrl=${encodeURIComponent(finalURL)}`
|
||||
return withSiteBaseURL(
|
||||
`${PATHS.SIGN_IN}?callbackUrl=${encodeURIComponent(finalURL)}`
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user