chore: env(). support
This commit is contained in:
@ -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}`,
|
||||||
|
@ -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(),
|
||||||
|
121
src/env.test.ts
Normal file
121
src/env.test.ts
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
import env from '@src/env'
|
||||||
|
import { vi } from 'vitest'
|
||||||
|
import { viteEnv, windowElectronProcessEnv, processEnv } from '@src/env'
|
||||||
|
|
||||||
|
describe('@src/env 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_KC_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_KC_DEV_TOKEN: 'redacted',
|
||||||
|
PROD: undefined,
|
||||||
|
TEST: 'true',
|
||||||
|
DEV: '1',
|
||||||
|
CI: undefined,
|
||||||
|
}
|
||||||
|
const actual = env()
|
||||||
|
expect(typeof actual.VITE_KC_DEV_TOKEN).toBe('string')
|
||||||
|
//@ts-ignore I do not want this token in our logs for any reason.
|
||||||
|
actual.VITE_KC_DEV_TOKEN = 'redacted'
|
||||||
|
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_KC_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_KC_DEV_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_KC_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_KC_DEV_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_KC_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_KC_DEV_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_KC_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_KC_DEV_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...
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
91
src/env.ts
91
src/env.ts
@ -1,20 +1,73 @@
|
|||||||
// 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_KC_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_KC_DEV_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_KC_API_BASE_URL = env.VITE_KC_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_KC_DEV_TOKEN = env.VITE_KC_DEV_TOKEN as string | undefined
|
return typeof window !== 'undefined' && typeof window.electron !== 'undefined'
|
||||||
export const PROD = env.PROD as string | undefined
|
? window?.electron?.process?.env
|
||||||
export const TEST = env.TEST as string | undefined
|
: undefined
|
||||||
export const DEV = env.DEV as string | undefined
|
}
|
||||||
export const CI = env.CI as string | undefined
|
|
||||||
|
export const processEnv = () => {
|
||||||
|
return typeof process === 'undefined' ? undefined : 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_KC_API_BASE_URL: (env.VITE_KC_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_KC_DEV_TOKEN: (env.VITE_KC_DEV_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_KC_DEV_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 {
|
||||||
@ -43,7 +43,7 @@ beforeAll(async () => {
|
|||||||
// THESE TEST WILL FAIL without VITE_KC_DEV_TOKEN set in .env.development.local
|
// THESE TEST WILL FAIL without VITE_KC_DEV_TOKEN set in .env.development.local
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
engineCommandManager.start({
|
engineCommandManager.start({
|
||||||
token: VITE_KC_DEV_TOKEN,
|
token: env().VITE_KC_DEV_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_KC_DEV_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 () => {
|
||||||
@ -13,7 +13,7 @@ beforeAll(async () => {
|
|||||||
// THESE TEST WILL FAIL without VITE_KC_DEV_TOKEN set in .env.development.local
|
// THESE TEST WILL FAIL without VITE_KC_DEV_TOKEN set in .env.development.local
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
engineCommandManager.start({
|
engineCommandManager.start({
|
||||||
token: VITE_KC_DEV_TOKEN,
|
token: env().VITE_KC_DEV_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_KC_DEV_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_KC_DEV_TOKEN}`,
|
Authorization: `Bearer ${env().VITE_KC_DEV_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,
|
||||||
|
@ -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()
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { VITE_KC_API_BASE_URL, VITE_KC_SITE_BASE_URL } from '@src/env'
|
import env from '@src/env'
|
||||||
|
|
||||||
export function withAPIBaseURL(path: string): string {
|
export function withAPIBaseURL(path: string): string {
|
||||||
return VITE_KC_API_BASE_URL + path
|
return env().VITE_KC_API_BASE_URL + path
|
||||||
}
|
}
|
||||||
|
|
||||||
export function withSiteBaseURL(path: string): string {
|
export function withSiteBaseURL(path: string): string {
|
||||||
return VITE_KC_SITE_BASE_URL + path
|
return env().VITE_KC_SITE_BASE_URL + path
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
import { withSiteBaseURLNode } from '@src/lib/withBaseURLNode'
|
|
||||||
|
|
||||||
describe('withBaseURL', () => {
|
|
||||||
describe('withSiteBaseURL', () => {
|
|
||||||
it('should return base url', () => {
|
|
||||||
const expected = 'https://dev.zoo.dev'
|
|
||||||
const actual = withSiteBaseURLNode('')
|
|
||||||
expect(actual).toBe(expected)
|
|
||||||
})
|
|
||||||
it('should return base url with /docs', () => {
|
|
||||||
const expected = 'https://dev.zoo.dev/docs'
|
|
||||||
const actual = withSiteBaseURLNode('/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 = withSiteBaseURLNode('/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 = withSiteBaseURLNode('')
|
|
||||||
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,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* This will not run in the browser, look at withBaseURL
|
|
||||||
*/
|
|
||||||
export function withSiteBaseURLNode(path: string): string {
|
|
||||||
return process.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_KC_DEV_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_KC_DEV_TOKEN
|
const persistedDevToken = env().VITE_KC_DEV_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_KC_DEV_TOKEN = env().VITE_KC_DEV_TOKEN
|
||||||
if (VITE_KC_DEV_TOKEN) {
|
if (VITE_KC_DEV_TOKEN) {
|
||||||
console.log('Token used for authentication')
|
console.log('Token used for authentication')
|
||||||
console.table([['api token', !!VITE_KC_DEV_TOKEN]])
|
console.table([['api token', !!VITE_KC_DEV_TOKEN]])
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
engineCommandManager,
|
engineCommandManager,
|
||||||
kclManager,
|
kclManager,
|
||||||
} from '@src/lib/singletons'
|
} from '@src/lib/singletons'
|
||||||
import { VITE_KC_DEV_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'
|
||||||
@ -32,7 +32,7 @@ beforeAll(async () => {
|
|||||||
// THESE TEST WILL FAIL without VITE_KC_DEV_TOKEN set in .env.development.local
|
// THESE TEST WILL FAIL without VITE_KC_DEV_TOKEN set in .env.development.local
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
engineCommandManager.start({
|
engineCommandManager.start({
|
||||||
token: VITE_KC_DEV_TOKEN,
|
token: env().VITE_KC_DEV_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_KC_DEV_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'
|
||||||
@ -358,7 +358,7 @@ beforeAll(async () => {
|
|||||||
// THESE TEST WILL FAIL without VITE_KC_DEV_TOKEN set in .env.development.local
|
// THESE TEST WILL FAIL without VITE_KC_DEV_TOKEN set in .env.development.local
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
engineCommandManager.start({
|
engineCommandManager.start({
|
||||||
token: VITE_KC_DEV_TOKEN,
|
token: env().VITE_KC_DEV_TOKEN,
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
setMediaStream: () => {},
|
setMediaStream: () => {},
|
||||||
|
@ -300,7 +300,7 @@ app.on('ready', (event, data) => {
|
|||||||
// Create the mainWindow
|
// Create the mainWindow
|
||||||
mainWindow = createWindow()
|
mainWindow = createWindow()
|
||||||
// Set menu application to null to avoid default electron menu
|
// Set menu application to null to avoid default electron menu
|
||||||
Menu.setApplicationMenu(null)
|
// Menu.setApplicationMenu(null)
|
||||||
})
|
})
|
||||||
|
|
||||||
// For now there is no good reason to separate these out to another file(s)
|
// For now there is no good reason to separate these out to another file(s)
|
||||||
|
@ -5,7 +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 { withSiteBaseURLNode } from '@src/lib/withBaseURLNode'
|
import { withSiteBaseURL } from '@src/lib/withBaseURL'
|
||||||
|
|
||||||
export const helpRole = (
|
export const helpRole = (
|
||||||
mainWindow: BrowserWindow
|
mainWindow: BrowserWindow
|
||||||
@ -27,7 +27,7 @@ export const helpRole = (
|
|||||||
id: 'Help.KCL code samples',
|
id: 'Help.KCL code samples',
|
||||||
click: () => {
|
click: () => {
|
||||||
shell
|
shell
|
||||||
.openExternal(withSiteBaseURLNode('/docs/kcl-samples'))
|
.openExternal(withSiteBaseURL('/docs/kcl-samples'))
|
||||||
.catch(reportRejection)
|
.catch(reportRejection)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -35,7 +35,7 @@ export const helpRole = (
|
|||||||
label: 'KCL Docs',
|
label: 'KCL Docs',
|
||||||
click: () => {
|
click: () => {
|
||||||
shell
|
shell
|
||||||
.openExternal(withSiteBaseURLNode('/docs/kcl'))
|
.openExternal(withSiteBaseURL('/docs/kcl'))
|
||||||
.catch(reportRejection)
|
.catch(reportRejection)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -119,9 +119,7 @@ export const helpRole = (
|
|||||||
{
|
{
|
||||||
label: 'Manage Account',
|
label: 'Manage Account',
|
||||||
click: () => {
|
click: () => {
|
||||||
shell
|
shell.openExternal(withSiteBaseURL('/account')).catch(reportRejection)
|
||||||
.openExternal(withSiteBaseURLNode('/account'))
|
|
||||||
.catch(reportRejection)
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { NODE_ENV } 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,
|
||||||
@ -10,7 +10,7 @@ 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
|
||||||
|
Reference in New Issue
Block a user