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}
|
000 https://${BASE_URL}
|
||||||
405 https://api.dev.zoo.dev/oauth2/token/revoke
|
405 https://api.dev.zoo.dev/oauth2/token/revoke
|
||||||
401 https://api.dev.zoo.dev/users
|
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
|
301 https://discord.gg/JQEpHR7Nt2
|
||||||
404 https://github.com/KittyCAD/engine/issues/3528
|
404 https://github.com/KittyCAD/engine/issues/3528
|
||||||
404 https://github.com/KittyCAD/modeling-app/commit/${ref}
|
404 https://github.com/KittyCAD/modeling-app/commit/${ref}
|
||||||
@ -19,5 +22,4 @@ URL STATUS
|
|||||||
302 https://stackoverflow.com/a/58436959/22753272
|
302 https://stackoverflow.com/a/58436959/22753272
|
||||||
303 https://text-to-cad.zoo.dev/dashboard
|
303 https://text-to-cad.zoo.dev/dashboard
|
||||||
307 https://zoo.dev/
|
307 https://zoo.dev/
|
||||||
308 https://zoo.dev/docs/api/ml/generate-a-cad-model-from-text
|
|
||||||
308 https://zoo.dev/docs/kcl
|
308 https://zoo.dev/docs/kcl
|
||||||
|
@ -53,7 +53,6 @@ import {
|
|||||||
WASM_INIT_FAILED_TOAST_ID,
|
WASM_INIT_FAILED_TOAST_ID,
|
||||||
} from '@src/lib/constants'
|
} from '@src/lib/constants'
|
||||||
import { isPlaywright } from '@src/lib/isPlaywright'
|
import { isPlaywright } from '@src/lib/isPlaywright'
|
||||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
|
||||||
import { useNetworkHealthStatus } from '@src/components/NetworkHealthIndicator'
|
import { useNetworkHealthStatus } from '@src/components/NetworkHealthIndicator'
|
||||||
import { useNetworkMachineStatus } from '@src/components/NetworkMachineIndicator'
|
import { useNetworkMachineStatus } from '@src/components/NetworkMachineIndicator'
|
||||||
import {
|
import {
|
||||||
@ -65,6 +64,7 @@ import { useModelingContext } from '@src/hooks/useModelingContext'
|
|||||||
import { xStateValueToString } from '@src/lib/xStateValueToString'
|
import { xStateValueToString } from '@src/lib/xStateValueToString'
|
||||||
import { getSelectionTypeDisplayText } from '@src/lib/selections'
|
import { getSelectionTypeDisplayText } from '@src/lib/selections'
|
||||||
import type { StatusBarItemType } from '@src/components/StatusBar/statusBarTypes'
|
import type { StatusBarItemType } from '@src/components/StatusBar/statusBarTypes'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
// CYCLIC REF
|
// CYCLIC REF
|
||||||
sceneInfra.camControls.engineStreamActor = engineStreamActor
|
sceneInfra.camControls.engineStreamActor = engineStreamActor
|
||||||
@ -189,7 +189,8 @@ export function App() {
|
|||||||
() =>
|
() =>
|
||||||
DownloadAppToast({
|
DownloadAppToast({
|
||||||
onAccept: () => {
|
onAccept: () => {
|
||||||
openWindow(`${VITE_KC_SITE_BASE_URL}/${APP_DOWNLOAD_PATH}`)
|
const url = withSiteBaseURL(`/${APP_DOWNLOAD_PATH}`)
|
||||||
|
openWindow(url)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.dismiss(DOWNLOAD_APP_TOAST_ID)
|
toast.dismiss(DOWNLOAD_APP_TOAST_ID)
|
||||||
})
|
})
|
||||||
|
@ -5,8 +5,8 @@ import {
|
|||||||
BillingRemaining,
|
BillingRemaining,
|
||||||
BillingRemainingMode,
|
BillingRemainingMode,
|
||||||
} from '@src/components/BillingRemaining'
|
} from '@src/components/BillingRemaining'
|
||||||
|
|
||||||
import { type BillingActor } from '@src/machines/billingMachine'
|
import { type BillingActor } from '@src/machines/billingMachine'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
export const BillingDialog = (props: { billingActor: BillingActor }) => {
|
export const BillingDialog = (props: { billingActor: BillingActor }) => {
|
||||||
const billingContext = useSelector(
|
const billingContext = useSelector(
|
||||||
@ -42,7 +42,7 @@ export const BillingDialog = (props: { billingActor: BillingActor }) => {
|
|||||||
{!hasUnlimited && (
|
{!hasUnlimited && (
|
||||||
<a
|
<a
|
||||||
className="bg-ml-black text-ml-white rounded-lg text-center p-1 cursor-pointer"
|
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"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
data-testid="billing-upgrade-button"
|
data-testid="billing-upgrade-button"
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
import { onboardingStartPath } from '@src/lib/onboardingPaths'
|
import { onboardingStartPath } from '@src/lib/onboardingPaths'
|
||||||
import { reportRejection } from '@src/lib/trap'
|
import { reportRejection } from '@src/lib/trap'
|
||||||
import { isDesktop } from '@src/lib/isDesktop'
|
import { isDesktop } from '@src/lib/isDesktop'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
const HelpMenuDivider = () => (
|
const HelpMenuDivider = () => (
|
||||||
<div className="h-[1px] bg-chalkboard-110 dark:bg-chalkboard-80" />
|
<div className="h-[1px] bg-chalkboard-110 dark:bg-chalkboard-80" />
|
||||||
@ -89,7 +90,7 @@ export function HelpMenu() {
|
|||||||
<HelpMenuDivider />
|
<HelpMenuDivider />
|
||||||
<HelpMenuItem
|
<HelpMenuItem
|
||||||
as="a"
|
as="a"
|
||||||
href="https://zoo.dev/docs/kcl-samples"
|
href={withSiteBaseURL('/docs/kcl-samples')}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
@ -97,7 +98,7 @@ export function HelpMenu() {
|
|||||||
</HelpMenuItem>
|
</HelpMenuItem>
|
||||||
<HelpMenuItem
|
<HelpMenuItem
|
||||||
as="a"
|
as="a"
|
||||||
href="https://zoo.dev/docs/kcl-lang"
|
href={withSiteBaseURL('/docs/kcl-lang')}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
LanguageServerClient,
|
LanguageServerClient,
|
||||||
LspWorkerEventType,
|
LspWorkerEventType,
|
||||||
} from '@kittycad/codemirror-lsp-client'
|
} from '@kittycad/codemirror-lsp-client'
|
||||||
import { TEST } from '@src/env'
|
import env from '@src/env'
|
||||||
import React, { createContext, useContext, useMemo, useState } from 'react'
|
import React, { createContext, useContext, useMemo, useState } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import type * as LSP from 'vscode-languageserver-protocol'
|
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.
|
// But the server happens async so we break this into two parts.
|
||||||
// Below is the client and server promise.
|
// Below is the client and server promise.
|
||||||
const { lspClient: kclLspClient } = useMemo(() => {
|
const { lspClient: kclLspClient } = useMemo(() => {
|
||||||
if (!token || token === '' || TEST) {
|
if (!token || token === '' || env().TEST) {
|
||||||
return { lspClient: null }
|
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.
|
// We do not want to restart the server, its just wasteful.
|
||||||
const kclLSP = useMemo(() => {
|
const kclLSP = useMemo(() => {
|
||||||
let plugin = null
|
let plugin = null
|
||||||
if (isKclLspReady && !TEST && kclLspClient) {
|
if (isKclLspReady && !env().TEST && kclLspClient) {
|
||||||
// Set up the lsp plugin.
|
// Set up the lsp plugin.
|
||||||
const lsp = kcl({
|
const lsp = kcl({
|
||||||
documentUri: `file:///${PROJECT_ENTRYPOINT}`,
|
documentUri: `file:///${PROJECT_ENTRYPOINT}`,
|
||||||
@ -171,7 +171,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
}, [kclLspClient, isKclLspReady])
|
}, [kclLspClient, isKclLspReady])
|
||||||
|
|
||||||
const { lspClient: copilotLspClient } = useMemo(() => {
|
const { lspClient: copilotLspClient } = useMemo(() => {
|
||||||
if (!token || token === '' || TEST) {
|
if (!token || token === '' || env().TEST) {
|
||||||
return { lspClient: null }
|
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.
|
// We do not want to restart the server, its just wasteful.
|
||||||
const copilotLSP = useMemo(() => {
|
const copilotLSP = useMemo(() => {
|
||||||
let plugin = null
|
let plugin = null
|
||||||
if (isCopilotLspReady && !TEST && copilotLspClient) {
|
if (isCopilotLspReady && !env().TEST && copilotLspClient) {
|
||||||
// Set up the lsp plugin.
|
// Set up the lsp plugin.
|
||||||
const lsp = copilotPlugin({
|
const lsp = copilotPlugin({
|
||||||
documentUri: `file:///${PROJECT_ENTRYPOINT}`,
|
documentUri: `file:///${PROJECT_ENTRYPOINT}`,
|
||||||
|
@ -12,6 +12,7 @@ import { reportRejection } from '@src/lib/trap'
|
|||||||
import { commandBarActor, settingsActor } from '@src/lib/singletons'
|
import { commandBarActor, settingsActor } from '@src/lib/singletons'
|
||||||
|
|
||||||
import styles from './KclEditorMenu.module.css'
|
import styles from './KclEditorMenu.module.css'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
export const KclEditorMenu = ({ children }: PropsWithChildren) => {
|
export const KclEditorMenu = ({ children }: PropsWithChildren) => {
|
||||||
const { enable: convertToVarEnabled, handleClick: handleConvertToVarClick } =
|
const { enable: convertToVarEnabled, handleClick: handleConvertToVarClick } =
|
||||||
@ -67,7 +68,7 @@ export const KclEditorMenu = ({ children }: PropsWithChildren) => {
|
|||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
<a
|
<a
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
href="https://zoo.dev/docs/kcl-lang"
|
href={withSiteBaseURL('/docs/kcl-lang')}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
onClick={openExternalBrowserIfDesktop()}
|
onClick={openExternalBrowserIfDesktop()}
|
||||||
@ -108,7 +109,7 @@ export const KclEditorMenu = ({ children }: PropsWithChildren) => {
|
|||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
<a
|
<a
|
||||||
className={styles.button}
|
className={styles.button}
|
||||||
href="https://zoo.dev/docs/kcl-samples"
|
href={withSiteBaseURL('/docs/kcl-samples')}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
onClick={openExternalBrowserIfDesktop()}
|
onClick={openExternalBrowserIfDesktop()}
|
||||||
|
@ -35,7 +35,7 @@ import {
|
|||||||
rectangularSelection,
|
rectangularSelection,
|
||||||
} from '@codemirror/view'
|
} from '@codemirror/view'
|
||||||
import interact from '@replit/codemirror-interact'
|
import interact from '@replit/codemirror-interact'
|
||||||
import { TEST } from '@src/env'
|
import env from '@src/env'
|
||||||
import { useSelector } from '@xstate/react'
|
import { useSelector } from '@xstate/react'
|
||||||
import { useEffect, useMemo, useRef } from 'react'
|
import { useEffect, useMemo, useRef } from 'react'
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ export const KclEditorPane = () => {
|
|||||||
if (copilotLSP) extensions.push(copilotLSP)
|
if (copilotLSP) extensions.push(copilotLSP)
|
||||||
|
|
||||||
// These extensions have proven to mess with vitest
|
// These extensions have proven to mess with vitest
|
||||||
if (!TEST) {
|
if (!env().TEST) {
|
||||||
extensions.push(
|
extensions.push(
|
||||||
lintGutter(),
|
lintGutter(),
|
||||||
lineNumbers(),
|
lineNumbers(),
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { Transition } from '@headlessui/react'
|
import { Transition } from '@headlessui/react'
|
||||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
|
||||||
import { useSearchParams } from 'react-router-dom'
|
import { useSearchParams } from 'react-router-dom'
|
||||||
import { base64ToString } from '@src/lib/base64'
|
import { base64ToString } from '@src/lib/base64'
|
||||||
|
|
||||||
@ -16,6 +15,7 @@ import { platform } from '@src/lib/utils'
|
|||||||
import { codeManager } from '@src/lib/singletons'
|
import { codeManager } from '@src/lib/singletons'
|
||||||
import { Logo } from '@src/components/Logo'
|
import { Logo } from '@src/components/Logo'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component is a handler that checks if a certain query parameter
|
* This component is a handler that checks if a certain query parameter
|
||||||
@ -98,7 +98,7 @@ export const OpenInDesktopAppHandler = (props: React.PropsWithChildren) => {
|
|||||||
>
|
>
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
as="div"
|
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`}
|
mx-auto border rounded-lg shadow-lg bg-chalkboard-10 dark:bg-chalkboard-100`}
|
||||||
enter="ease-out duration-300"
|
enter="ease-out duration-300"
|
||||||
enterFrom="opacity-0 scale-95"
|
enterFrom="opacity-0 scale-95"
|
||||||
@ -133,7 +133,7 @@ export const OpenInDesktopAppHandler = (props: React.PropsWithChildren) => {
|
|||||||
buttonClasses +
|
buttonClasses +
|
||||||
' text-sm border-transparent justify-center dark:bg-transparent'
|
' 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' }}
|
iconEnd={{ icon: 'link', bgClassName: '!bg-transparent' }}
|
||||||
>
|
>
|
||||||
Download desktop app
|
Download desktop app
|
||||||
|
@ -12,9 +12,9 @@ import { Popover } from '@headlessui/react'
|
|||||||
import Tooltip from '@src/components/Tooltip'
|
import Tooltip from '@src/components/Tooltip'
|
||||||
import { HelpMenu } from '@src/components/HelpMenu'
|
import { HelpMenu } from '@src/components/HelpMenu'
|
||||||
import { isDesktop } from '@src/lib/isDesktop'
|
import { isDesktop } from '@src/lib/isDesktop'
|
||||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
|
||||||
import { APP_DOWNLOAD_PATH } from '@src/lib/constants'
|
import { APP_DOWNLOAD_PATH } from '@src/lib/constants'
|
||||||
import { desktopAppPitchMessage } from '@src/components/DownloadAppToast'
|
import { desktopAppPitchMessage } from '@src/components/DownloadAppToast'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
export const defaultGlobalStatusBarItems = ({
|
export const defaultGlobalStatusBarItems = ({
|
||||||
location,
|
location,
|
||||||
@ -37,7 +37,7 @@ export const defaultGlobalStatusBarItems = ({
|
|||||||
id: 'download-desktop-app',
|
id: 'download-desktop-app',
|
||||||
element: 'externalLink',
|
element: 'externalLink',
|
||||||
label: 'Download the app',
|
label: 'Download the app',
|
||||||
href: `${VITE_KC_SITE_BASE_URL}/${APP_DOWNLOAD_PATH}`,
|
href: withSiteBaseURL(`/${APP_DOWNLOAD_PATH}`),
|
||||||
icon: 'download',
|
icon: 'download',
|
||||||
toolTip: {
|
toolTip: {
|
||||||
children: desktopAppPitchMessage,
|
children: desktopAppPitchMessage,
|
||||||
|
@ -13,6 +13,7 @@ import { isDesktop } from '@src/lib/isDesktop'
|
|||||||
import { PATHS } from '@src/lib/paths'
|
import { PATHS } from '@src/lib/paths'
|
||||||
import { authActor } from '@src/lib/singletons'
|
import { authActor } from '@src/lib/singletons'
|
||||||
import { reportRejection } from '@src/lib/trap'
|
import { reportRejection } from '@src/lib/trap'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
type User = Models['User_type']
|
type User = Models['User_type']
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ const UserSidebarMenu = ({ user }: { user?: User }) => {
|
|||||||
{
|
{
|
||||||
id: 'account',
|
id: 'account',
|
||||||
Element: 'externalLink',
|
Element: 'externalLink',
|
||||||
to: 'https://zoo.dev/account',
|
to: withSiteBaseURL('/account'),
|
||||||
children: (
|
children: (
|
||||||
<>
|
<>
|
||||||
<span className="flex-1">Manage account</span>
|
<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.
|
type EnvironmentVariables = {
|
||||||
// It's purely generated by Vite and nothing else.
|
readonly NODE_ENV: string | undefined
|
||||||
// For Jest tests, we use babel to deal with it (it's a Syntax error otherwise)
|
readonly VITE_KC_API_WS_MODELING_URL: string | undefined
|
||||||
// @ts-ignore: TS1343
|
readonly VITE_KITTYCAD_API_BASE_URL: string | undefined
|
||||||
const env = window.electron?.process.env ?? import.meta.env
|
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 viteEnv = () => {
|
||||||
export const VITE_KC_API_WS_MODELING_URL = env.VITE_KC_API_WS_MODELING_URL as
|
// It turns out import.meta.env is a really fucky env var passing method.
|
||||||
| string
|
// It's purely generated by Vite and nothing else.
|
||||||
| undefined
|
// For Jest tests, we use babel to deal with it (it's a Syntax error otherwise)
|
||||||
export const VITE_KITTYCAD_API_BASE_URL = env.VITE_KITTYCAD_API_BASE_URL
|
// @ts-ignore: TS1343
|
||||||
export const VITE_KC_SITE_BASE_URL = env.VITE_KC_SITE_BASE_URL
|
return import.meta.env
|
||||||
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 windowElectronProcessEnv = () => {
|
||||||
export const VITE_KITTYCAD_API_TOKEN = env.VITE_KITTYCAD_API_TOKEN as
|
return typeof window !== 'undefined' && typeof window.electron !== 'undefined'
|
||||||
| string
|
? window?.electron?.process?.env
|
||||||
| undefined
|
: 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 processEnv = () => {
|
||||||
export const CI = env.CI as string | undefined
|
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 { createLiteral } from '@src/lang/create'
|
||||||
import type {
|
import type {
|
||||||
@ -42,7 +42,7 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
engineCommandManager.start({
|
engineCommandManager.start({
|
||||||
token: VITE_KITTYCAD_API_TOKEN,
|
token: env().VITE_KITTYCAD_API_TOKEN,
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
setMediaStream: () => {},
|
setMediaStream: () => {},
|
||||||
|
@ -4,7 +4,7 @@ import { initPromise } from '@src/lang/wasmUtils'
|
|||||||
import { err } from '@src/lib/trap'
|
import { err } from '@src/lib/trap'
|
||||||
import type { Selection } from '@src/lib/selections'
|
import type { Selection } from '@src/lib/selections'
|
||||||
import { engineCommandManager, kclManager } from '@src/lib/singletons'
|
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'
|
import { modifyAstWithTagsForSelection } from '@src/lang/modifyAst/tagManagement'
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
@ -12,7 +12,7 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
engineCommandManager.start({
|
engineCommandManager.start({
|
||||||
token: VITE_KITTYCAD_API_TOKEN,
|
token: env().VITE_KITTYCAD_API_TOKEN,
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
setMediaStream: () => {},
|
setMediaStream: () => {},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { Models } from '@kittycad/lib'
|
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 { jsAppSettings } from '@src/lib/settings/settingsUtils'
|
||||||
import { BSON } from 'bson'
|
import { BSON } from 'bson'
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ class EngineConnection extends EventTarget {
|
|||||||
|
|
||||||
// SHOULD ONLY BE USED FOR VITESTS
|
// SHOULD ONLY BE USED FOR VITESTS
|
||||||
connectLite(callback: () => void) {
|
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 = new WebSocket(url, [])
|
||||||
this.websocket.binaryType = 'arraybuffer'
|
this.websocket.binaryType = 'arraybuffer'
|
||||||
@ -400,7 +400,7 @@ class EngineConnection extends EventTarget {
|
|||||||
this.send({
|
this.send({
|
||||||
type: 'headers',
|
type: 'headers',
|
||||||
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 +=
|
additionalSettings +=
|
||||||
'&show_grid=' + (this.settings.showScaleGrid ? 'true' : 'false')
|
'&show_grid=' + (this.settings.showScaleGrid ? 'true' : 'false')
|
||||||
const pool = !this.settings.pool ? '' : `&pool=${this.settings.pool}`
|
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({
|
this.engineConnection = new EngineConnection({
|
||||||
engineCommandManager: this,
|
engineCommandManager: this,
|
||||||
url,
|
url,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DEV } from '@src/env'
|
import env from '@src/env'
|
||||||
import type {
|
import type {
|
||||||
Actor,
|
Actor,
|
||||||
AnyStateMachine,
|
AnyStateMachine,
|
||||||
@ -89,7 +89,8 @@ export function createMachineCommand<
|
|||||||
} else if ('status' in commandConfig) {
|
} else if ('status' in commandConfig) {
|
||||||
const { status } = commandConfig
|
const { status } = commandConfig
|
||||||
if (status === 'inactive') return null
|
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
|
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 isomorphicFetch from 'isomorphic-fetch'
|
||||||
import { isDesktop } from '@src/lib/isDesktop'
|
import { isDesktop } from '@src/lib/isDesktop'
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ export default async function crossPlatformFetch<T>(
|
|||||||
// Add credentials: 'include' to options
|
// Add credentials: 'include' to options
|
||||||
// We send the token with the headers only in development mode, DO NOT
|
// We send the token with the headers only in development mode, DO NOT
|
||||||
// DO THIS IN PRODUCTION, as it is a security risk.
|
// 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'
|
opts.credentials = 'include'
|
||||||
response = await fetch(url, opts)
|
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'
|
import { createCreateFileUrl } from '@src/lib/links'
|
||||||
|
|
||||||
@ -9,7 +9,7 @@ describe(`link creation tests`, () => {
|
|||||||
|
|
||||||
// Converted with external online tools
|
// Converted with external online tools
|
||||||
const expectedEncodedCode = `ZXh0cnVzaW9uRGlzdGFuY2UgPSAxMg%3D%3D`
|
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 })
|
const result = createCreateFileUrl({ code, name, isRestrictedToOrg: false })
|
||||||
expect(result.toString()).toBe(expectedLink)
|
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 toast from 'react-hot-toast'
|
||||||
|
|
||||||
import { stringToBase64 } from '@src/lib/base64'
|
import { stringToBase64 } from '@src/lib/base64'
|
||||||
@ -58,7 +58,7 @@ export async function copyFileShareLink(
|
|||||||
* open the URL in the desktop app.
|
* open the URL in the desktop app.
|
||||||
*/
|
*/
|
||||||
export function createCreateFileUrl({ code, name }: FileLinkParams) {
|
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({
|
const searchParams = new URLSearchParams({
|
||||||
[CREATE_FILE_URL_PARAM]: String(true),
|
[CREATE_FILE_URL_PARAM]: String(true),
|
||||||
name,
|
name,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import type { SelectionRange } from '@codemirror/state'
|
import type { SelectionRange } from '@codemirror/state'
|
||||||
import { EditorSelection, Transaction } from '@codemirror/state'
|
import { EditorSelection, Transaction } from '@codemirror/state'
|
||||||
import type { Models } from '@kittycad/lib'
|
import type { Models } from '@kittycad/lib'
|
||||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
|
||||||
import { diffLines } from 'diff'
|
import { diffLines } from 'diff'
|
||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
import type { TextToCadMultiFileIteration_type } from '@kittycad/lib/dist/types/src/models'
|
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 { File as KittyCadLibFile } from '@kittycad/lib/dist/types/src/models'
|
||||||
import type { FileMeta } from '@src/lib/types'
|
import type { FileMeta } from '@src/lib/types'
|
||||||
import type { RequestedKCLFile } from '@src/machines/systemIO/utils'
|
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 = {
|
type KclFileMetaMap = {
|
||||||
[execStateFileNamesIndex: number]: Extract<FileMeta, { type: 'kcl' }>
|
[execStateFileNamesIndex: number]: Extract<FileMeta, { type: 'kcl' }>
|
||||||
@ -439,7 +439,7 @@ export async function promptToEditFlow({
|
|||||||
return Promise.reject(result)
|
return Promise.reject(result)
|
||||||
}
|
}
|
||||||
const oldCodeWebAppOnly = codeManager.code
|
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) {
|
if (!isDesktop() && Object.values(result.outputs).length > 1) {
|
||||||
const toastId = uuidv4()
|
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 { NamedView } from '@rust/kcl-lib/bindings/NamedView'
|
||||||
import type { ProjectConfiguration } from '@rust/kcl-lib/bindings/ProjectConfiguration'
|
import type { ProjectConfiguration } from '@rust/kcl-lib/bindings/ProjectConfiguration'
|
||||||
import { default_app_settings } from '@rust/kcl-wasm-lib/pkg/kcl_wasm_lib'
|
import { default_app_settings } from '@rust/kcl-wasm-lib/pkg/kcl_wasm_lib'
|
||||||
import { TEST } from '@src/env'
|
import env from '@src/env'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
defaultAppSettings,
|
defaultAppSettings,
|
||||||
@ -545,7 +545,7 @@ export function getSettingInputType(setting: Setting) {
|
|||||||
|
|
||||||
export const jsAppSettings = async (): Promise<DeepPartial<Configuration>> => {
|
export const jsAppSettings = async (): Promise<DeepPartial<Configuration>> => {
|
||||||
let jsAppSettings = default_app_settings()
|
let jsAppSettings = default_app_settings()
|
||||||
if (!TEST) {
|
if (!env().TEST) {
|
||||||
// TODO: https://github.com/KittyCAD/modeling-app/issues/6445
|
// TODO: https://github.com/KittyCAD/modeling-app/issues/6445
|
||||||
const settings = await import('@src/lib/singletons').then((module) =>
|
const settings = await import('@src/lib/singletons').then((module) =>
|
||||||
module.getSettings()
|
module.getSettings()
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
pipeHasCircle,
|
pipeHasCircle,
|
||||||
} from '@src/machines/modelingMachine'
|
} from '@src/machines/modelingMachine'
|
||||||
import { IS_ML_EXPERIMENTAL } from '@src/lib/constants'
|
import { IS_ML_EXPERIMENTAL } from '@src/lib/constants'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
export type ToolbarModeName = 'modeling' | 'sketching'
|
export type ToolbarModeName = 'modeling' | 'sketching'
|
||||||
|
|
||||||
@ -105,7 +106,9 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
|||||||
links: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'API docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'API docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'API docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'API docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'API docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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: [
|
links: [
|
||||||
{
|
{
|
||||||
label: 'KCL docs',
|
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', () => {
|
describe('withBaseURL', () => {
|
||||||
/**
|
/**
|
||||||
* running in the development environment
|
* running in the development environment
|
||||||
* the .env.development should load
|
* the .env.development should load
|
||||||
*/
|
*/
|
||||||
describe('withAPIBaseUrl', () => {
|
describe('withAPIBaseURL', () => {
|
||||||
it('should return base url', () => {
|
it('should return base url', () => {
|
||||||
const expected = 'https://api.dev.zoo.dev'
|
const expected = 'https://api.dev.zoo.dev'
|
||||||
const actual = withAPIBaseURL('')
|
const actual = withAPIBaseURL('')
|
||||||
@ -31,4 +31,31 @@ describe('withBaseURL', () => {
|
|||||||
expect(actualEndsWith).toBe(expectedEndsWith)
|
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 {
|
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 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 { assign, fromPromise, setup } from 'xstate'
|
||||||
|
|
||||||
import { COOKIE_NAME, OAUTH2_DEVICE_CLIENT_ID } from '@src/lib/constants'
|
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 persistedCookie = getCookie(COOKIE_NAME)
|
||||||
const persistedLocalStorage = localStorage?.getItem(TOKEN_PERSIST_KEY) || ''
|
const persistedLocalStorage = localStorage?.getItem(TOKEN_PERSIST_KEY) || ''
|
||||||
const persistedDevToken = VITE_KITTYCAD_API_TOKEN
|
const persistedDevToken = env().VITE_KITTYCAD_API_TOKEN
|
||||||
export const persistedToken =
|
export const persistedToken =
|
||||||
persistedDevToken || persistedCookie || persistedLocalStorage
|
persistedDevToken || persistedCookie || persistedLocalStorage
|
||||||
console.log('Initial persisted token')
|
console.log('Initial persisted token')
|
||||||
@ -197,6 +197,7 @@ async function getAndSyncStoredToken(input: {
|
|||||||
token?: string
|
token?: string
|
||||||
}): Promise<string> {
|
}): Promise<string> {
|
||||||
// dev mode
|
// dev mode
|
||||||
|
const VITE_KITTYCAD_API_TOKEN = env().VITE_KITTYCAD_API_TOKEN
|
||||||
if (VITE_KITTYCAD_API_TOKEN) {
|
if (VITE_KITTYCAD_API_TOKEN) {
|
||||||
console.log('Token used for authentication')
|
console.log('Token used for authentication')
|
||||||
console.table([['api token', !!VITE_KITTYCAD_API_TOKEN]])
|
console.table([['api token', !!VITE_KITTYCAD_API_TOKEN]])
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
engineCommandManager,
|
engineCommandManager,
|
||||||
kclManager,
|
kclManager,
|
||||||
} from '@src/lib/singletons'
|
} 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 { getConstraintInfoKw } from '@src/lang/std/sketch'
|
||||||
import { getNodeFromPath } from '@src/lang/queryAst'
|
import { getNodeFromPath } from '@src/lang/queryAst'
|
||||||
import type { Node } from '@rust/kcl-lib/bindings/Node'
|
import type { Node } from '@rust/kcl-lib/bindings/Node'
|
||||||
@ -31,7 +31,7 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
engineCommandManager.start({
|
engineCommandManager.start({
|
||||||
token: VITE_KITTYCAD_API_TOKEN,
|
token: env().VITE_KITTYCAD_API_TOKEN,
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
setMediaStream: () => {},
|
setMediaStream: () => {},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { engineCommandManager, kclManager } from '@src/lib/singletons'
|
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 { getModuleIdByFileName, isArray } from '@src/lib/utils'
|
||||||
import { vi, inject } from 'vitest'
|
import { vi, inject } from 'vitest'
|
||||||
import { assertParse } from '@src/lang/wasm'
|
import { assertParse } from '@src/lang/wasm'
|
||||||
@ -357,7 +357,7 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
engineCommandManager.start({
|
engineCommandManager.start({
|
||||||
token: VITE_KITTYCAD_API_TOKEN,
|
token: env().VITE_KITTYCAD_API_TOKEN,
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
setMediaStream: () => {},
|
setMediaStream: () => {},
|
||||||
|
@ -5,6 +5,7 @@ import { reportRejection } from '@src/lib/trap'
|
|||||||
import { typeSafeWebContentsSend } from '@src/menu/channels'
|
import { typeSafeWebContentsSend } from '@src/menu/channels'
|
||||||
import type { ZooMenuItemConstructorOptions } from '@src/menu/roles'
|
import type { ZooMenuItemConstructorOptions } from '@src/menu/roles'
|
||||||
import { getAutoUpdater } from '@src/updater'
|
import { getAutoUpdater } from '@src/updater'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
export const helpRole = (
|
export const helpRole = (
|
||||||
mainWindow: BrowserWindow
|
mainWindow: BrowserWindow
|
||||||
@ -26,14 +27,16 @@ export const helpRole = (
|
|||||||
id: 'Help.KCL code samples',
|
id: 'Help.KCL code samples',
|
||||||
click: () => {
|
click: () => {
|
||||||
shell
|
shell
|
||||||
.openExternal('https://zoo.dev/docs/kcl-samples')
|
.openExternal(withSiteBaseURL('/docs/kcl-samples'))
|
||||||
.catch(reportRejection)
|
.catch(reportRejection)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'KCL Docs',
|
label: 'KCL Docs',
|
||||||
click: () => {
|
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',
|
label: 'Manage Account',
|
||||||
click: () => {
|
click: () => {
|
||||||
shell.openExternal('https://zoo.dev/account').catch(reportRejection)
|
shell.openExternal(withSiteBaseURL('/account')).catch(reportRejection)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -67,6 +67,7 @@ import {
|
|||||||
defaultGlobalStatusBarItems,
|
defaultGlobalStatusBarItems,
|
||||||
} from '@src/components/StatusBar/defaultStatusBarItems'
|
} from '@src/components/StatusBar/defaultStatusBarItems'
|
||||||
import { useSelector } from '@xstate/react'
|
import { useSelector } from '@xstate/react'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
type ReadWriteProjectState = {
|
type ReadWriteProjectState = {
|
||||||
value: boolean
|
value: boolean
|
||||||
@ -367,9 +368,9 @@ const Home = () => {
|
|||||||
<li className="contents">
|
<li className="contents">
|
||||||
<ActionButton
|
<ActionButton
|
||||||
Element="externalLink"
|
Element="externalLink"
|
||||||
to="https://zoo.dev/docs"
|
to={withSiteBaseURL('/account')}
|
||||||
onClick={openExternalBrowserIfDesktop(
|
onClick={openExternalBrowserIfDesktop(
|
||||||
'https://zoo.dev/account'
|
withSiteBaseURL('/account')
|
||||||
)}
|
)}
|
||||||
className={sidebarButtonClasses}
|
className={sidebarButtonClasses}
|
||||||
iconStart={{
|
iconStart={{
|
||||||
@ -384,8 +385,8 @@ const Home = () => {
|
|||||||
<li className="contents">
|
<li className="contents">
|
||||||
<ActionButton
|
<ActionButton
|
||||||
Element="externalLink"
|
Element="externalLink"
|
||||||
to="https://zoo.dev/blog"
|
to={withSiteBaseURL('/blog')}
|
||||||
onClick={openExternalBrowserIfDesktop('https://zoo.dev/blog')}
|
onClick={openExternalBrowserIfDesktop(withSiteBaseURL('/blog'))}
|
||||||
className={sidebarButtonClasses}
|
className={sidebarButtonClasses}
|
||||||
iconStart={{
|
iconStart={{
|
||||||
icon: 'glasses',
|
icon: 'glasses',
|
||||||
|
@ -25,12 +25,12 @@ import { systemIOActor, commandBarActor } from '@src/lib/singletons'
|
|||||||
import type { IndexLoaderData } from '@src/lib/types'
|
import type { IndexLoaderData } from '@src/lib/types'
|
||||||
import { SystemIOMachineEvents } from '@src/machines/systemIO/utils'
|
import { SystemIOMachineEvents } from '@src/machines/systemIO/utils'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
|
||||||
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
||||||
import {
|
import {
|
||||||
browserAxialFan,
|
browserAxialFan,
|
||||||
browserAxialFanAfterTextToCad,
|
browserAxialFanAfterTextToCad,
|
||||||
} from '@src/lib/exampleKcl'
|
} from '@src/lib/exampleKcl'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
type BrowserOnboaringRoute = RouteObject & {
|
type BrowserOnboaringRoute = RouteObject & {
|
||||||
path: keyof typeof browserOnboardingPaths
|
path: keyof typeof browserOnboardingPaths
|
||||||
@ -461,7 +461,7 @@ function PromptToEditResult() {
|
|||||||
function OnboardingConclusion() {
|
function OnboardingConclusion() {
|
||||||
// Close the panes on mount, close on unmount
|
// Close the panes on mount, close on unmount
|
||||||
useOnboardingPanes()
|
useOnboardingPanes()
|
||||||
const downloadLink = `${VITE_KC_SITE_BASE_URL}/${APP_DOWNLOAD_PATH}`
|
const downloadLink = withSiteBaseURL(`/${APP_DOWNLOAD_PATH}`)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="cursor-not-allowed fixed inset-0 z-50 p-16 grid justify-center items-center">
|
<div className="cursor-not-allowed fixed inset-0 z-50 p-16 grid justify-center items-center">
|
||||||
|
@ -27,8 +27,8 @@ import {
|
|||||||
modifiedFanHousingBrowser,
|
modifiedFanHousingBrowser,
|
||||||
modifiedParametersDesktop,
|
modifiedParametersDesktop,
|
||||||
} from '@src/lib/exampleKcl'
|
} from '@src/lib/exampleKcl'
|
||||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
|
||||||
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
type DesktopOnboardingRoute = RouteObject & {
|
type DesktopOnboardingRoute = RouteObject & {
|
||||||
path: keyof typeof desktopOnboardingPaths
|
path: keyof typeof desktopOnboardingPaths
|
||||||
@ -642,10 +642,8 @@ function OnboardingConclusion() {
|
|||||||
project, click the Zoo button in the top left. To learn more detailed
|
project, click the Zoo button in the top left. To learn more detailed
|
||||||
and advanced techniques,{' '}
|
and advanced techniques,{' '}
|
||||||
<a
|
<a
|
||||||
onClick={openExternalBrowserIfDesktop(
|
onClick={openExternalBrowserIfDesktop(withSiteBaseURL('/docs'))}
|
||||||
`${VITE_KC_SITE_BASE_URL}/docs`
|
href={`${withSiteBaseURL('/docs')}`}
|
||||||
)}
|
|
||||||
href={`${VITE_KC_SITE_BASE_URL}/docs`}
|
|
||||||
>
|
>
|
||||||
check out our docs
|
check out our docs
|
||||||
</a>
|
</a>
|
||||||
|
@ -6,7 +6,6 @@ import { Link } from 'react-router-dom'
|
|||||||
import { ActionButton } from '@src/components/ActionButton'
|
import { ActionButton } from '@src/components/ActionButton'
|
||||||
import { CustomIcon } from '@src/components/CustomIcon'
|
import { CustomIcon } from '@src/components/CustomIcon'
|
||||||
import { Logo } from '@src/components/Logo'
|
import { Logo } from '@src/components/Logo'
|
||||||
import { VITE_KC_SITE_BASE_URL } from '@src/env'
|
|
||||||
import { APP_NAME } from '@src/lib/constants'
|
import { APP_NAME } from '@src/lib/constants'
|
||||||
import { isDesktop } from '@src/lib/isDesktop'
|
import { isDesktop } from '@src/lib/isDesktop'
|
||||||
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
|
||||||
@ -15,7 +14,7 @@ import { reportRejection } from '@src/lib/trap'
|
|||||||
import { toSync } from '@src/lib/utils'
|
import { toSync } from '@src/lib/utils'
|
||||||
import { authActor, useSettings } from '@src/lib/singletons'
|
import { authActor, useSettings } from '@src/lib/singletons'
|
||||||
import { APP_VERSION, generateSignInUrl } from '@src/routes/utils'
|
import { APP_VERSION, generateSignInUrl } from '@src/routes/utils'
|
||||||
import { withAPIBaseURL } from '@src/lib/withBaseURL'
|
import { withAPIBaseURL, withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
const subtleBorder =
|
const subtleBorder =
|
||||||
'border border-solid border-chalkboard-30 dark:border-chalkboard-80'
|
'border border-solid border-chalkboard-30 dark:border-chalkboard-80'
|
||||||
@ -37,7 +36,7 @@ const SignIn = () => {
|
|||||||
app: { theme },
|
app: { theme },
|
||||||
} = useSettings()
|
} = useSettings()
|
||||||
const signInUrl = generateSignInUrl()
|
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(
|
const getThemeText = useCallback(
|
||||||
(shouldContrast = true) =>
|
(shouldContrast = true) =>
|
||||||
@ -261,7 +260,7 @@ const SignIn = () => {
|
|||||||
<div className="flex gap-4 flex-wrap items-center">
|
<div className="flex gap-4 flex-wrap items-center">
|
||||||
<ActionButton
|
<ActionButton
|
||||||
Element="externalLink"
|
Element="externalLink"
|
||||||
to="https://zoo.dev/docs/kcl-samples/pillow-block-bearing"
|
to={withSiteBaseURL('/docs/kcl-samples/pillow-block-bearing')}
|
||||||
iconStart={{
|
iconStart={{
|
||||||
icon: 'settings',
|
icon: 'settings',
|
||||||
bgClassName: '!bg-transparent',
|
bgClassName: '!bg-transparent',
|
||||||
@ -274,7 +273,7 @@ const SignIn = () => {
|
|||||||
</ActionButton>
|
</ActionButton>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
Element="externalLink"
|
Element="externalLink"
|
||||||
to="https://zoo.dev/docs/zoo-design-studio/text-to-cad"
|
to={withSiteBaseURL('/docs/zoo-design-studio/text-to-cad')}
|
||||||
iconStart={{
|
iconStart={{
|
||||||
icon: 'sparkles',
|
icon: 'sparkles',
|
||||||
bgClassName: '!bg-transparent',
|
bgClassName: '!bg-transparent',
|
||||||
@ -297,7 +296,7 @@ const SignIn = () => {
|
|||||||
<div className="flex gap-4 flex-wrap items-center">
|
<div className="flex gap-4 flex-wrap items-center">
|
||||||
<ActionButton
|
<ActionButton
|
||||||
Element="externalLink"
|
Element="externalLink"
|
||||||
to="https://zoo.dev/design-api"
|
to={withSiteBaseURL('/design-api')}
|
||||||
iconStart={{ icon: 'sketch', bgClassName: '!bg-transparent' }}
|
iconStart={{ icon: 'sketch', bgClassName: '!bg-transparent' }}
|
||||||
className="!bg-primary !text-chalkboard-10 !border-transarent"
|
className="!bg-primary !text-chalkboard-10 !border-transarent"
|
||||||
>
|
>
|
||||||
@ -305,7 +304,7 @@ const SignIn = () => {
|
|||||||
</ActionButton>
|
</ActionButton>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
Element="externalLink"
|
Element="externalLink"
|
||||||
to="https://zoo.dev/machine-learning-api"
|
to={withSiteBaseURL('/machine-learning-api')}
|
||||||
iconStart={{
|
iconStart={{
|
||||||
icon: 'elephant',
|
icon: 'elephant',
|
||||||
bgClassName: '!bg-transparent',
|
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 { isDesktop } from '@src/lib/isDesktop'
|
||||||
import {
|
import {
|
||||||
IS_PLAYWRIGHT_KEY,
|
IS_PLAYWRIGHT_KEY,
|
||||||
IMMEDIATE_SIGN_IN_IF_NECESSARY_QUERY_PARAM,
|
IMMEDIATE_SIGN_IN_IF_NECESSARY_QUERY_PARAM,
|
||||||
} from '@src/lib/constants'
|
} from '@src/lib/constants'
|
||||||
import { PATHS } from '@src/lib/paths'
|
import { PATHS } from '@src/lib/paths'
|
||||||
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
const isTestEnv = window?.localStorage.getItem(IS_PLAYWRIGHT_KEY) === 'true'
|
const isTestEnv = window?.localStorage.getItem(IS_PLAYWRIGHT_KEY) === 'true'
|
||||||
|
|
||||||
export const APP_VERSION =
|
export const APP_VERSION =
|
||||||
isTestEnv && NODE_ENV === 'development'
|
isTestEnv && env().NODE_ENV === 'development'
|
||||||
? '11.22.33'
|
? '11.22.33'
|
||||||
: isDesktop()
|
: isDesktop()
|
||||||
? // @ts-ignore
|
? // @ts-ignore
|
||||||
@ -54,7 +55,7 @@ export function generateSignInUrl() {
|
|||||||
'?'
|
'?'
|
||||||
)
|
)
|
||||||
|
|
||||||
return `${VITE_KC_SITE_BASE_URL}${
|
return withSiteBaseURL(
|
||||||
PATHS.SIGN_IN
|
`${PATHS.SIGN_IN}?callbackUrl=${encodeURIComponent(finalURL)}`
|
||||||
}?callbackUrl=${encodeURIComponent(finalURL)}`
|
)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user