diff --git a/.github/agents/spx-upgrader.md b/.github/agents/spx-upgrader.md index 8adeed544f..e02846de0e 100644 --- a/.github/agents/spx-upgrader.md +++ b/.github/agents/spx-upgrader.md @@ -8,7 +8,7 @@ You are a release specialist dedicated to upgrading spx across goplus/builder sa - Require the requester to specify the target spx version or pseudo-version, and stop immediately with an error message if it is missing - For released versions, verify they exist by running `gh release view --repo goplus/spx v` - For pseudo-versioned dev commits, verify the matching `ghcr.io/goplus/spx:web-zip-` package exists -- Update `spx-gui/.env` so `VITE_SPX_VERSION` matches the target +- Update `spx-gui/src/apps/xbuilder/.env` so `VITE_SPX_VERSION` matches the target - Refresh Go modules in `tools/ai/`, `tools/spxls/`, and `tools/ispx/` via `go get github.com/goplus/spx/v2@v` followed by `go mod tidy` in each directory - Execute `bash spx-gui/install-spx.sh` to download the matching runtime assets and remove any temporary archives - Execute `bash build-wasm.sh` in `spx-gui/` to build Wasm components diff --git a/.github/workflows/publish-docker-image.yml b/.github/workflows/publish-docker-image.yml index 56d6157ca1..d0ddbc9d0a 100644 --- a/.github/workflows/publish-docker-image.yml +++ b/.github/workflows/publish-docker-image.yml @@ -32,7 +32,7 @@ jobs: context: . file: ${{ matrix.dockerfile }} build-args: | - NODE_ENV=staging + VITE_MODE=staging provenance: false sbom: false push: ${{ github.event_name == 'push' && github.ref_name == 'dev' }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 11019643d0..460cc7974f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -47,7 +47,7 @@ jobs: - name: Build account frontend for mainland China deployment working-directory: spx-gui - run: NODE_ENV=production.cn npm run build:account + run: VITE_MODE=production-cn npm run build:account - name: Deploy builder_account_cn uses: ./.github/actions/deploy diff --git a/spx-gui/AGENTS.md b/spx-gui/AGENTS.md index cc80620c66..4ca447cbf9 100644 --- a/spx-gui/AGENTS.md +++ b/spx-gui/AGENTS.md @@ -54,6 +54,22 @@ Keep import statements in order: * Use the remainder of the key to identify the owning feature and stored state, for example `builder-user` or `builder-account-pending-authorization`. * Migrate existing keys gradually when changing their owning storage logic. Do not rename unrelated existing keys solely for consistency. +### App Env and Configuration + +* App env belongs to the app that owns it. Define app-specific env values under `src/apps//env.ts` and app-specific `.env*` files under `src/apps//`. + +* Code that does not clearly belong to a single app must not import a concrete app env module such as `@/apps/xbuilder/env` or `@/apps/account/env`. + Instead, the shared module should define the smallest configuration interface it needs, then expose an explicit configuration surface such as: + - a setter on an exported singleton, for example an API client `setBaseUrl(...)`; + - a `provide` / `inject` pair for Vue component trees; + - a function parameter when the dependency is local to one operation. + +* App entry and setup code under `src/apps//` is responsible for reading that app's env and passing only the required values into shared modules. + +* Code that is clearly app-owned, especially files under `src/apps//`, may import and consume that app's env directly when that is simpler. + +* Keep shared module configuration narrow. Avoid passing a whole app env object into shared business logic when the module only needs one or two values. + ### Identifier Resolution When working with backend unique string identifiers such as `username`, project owner, and project name, distinguish unresolved identifiers from canonical identifiers. diff --git a/spx-gui/build/Dockerfile b/spx-gui/build/Dockerfile index aaa3a71a59..fa0a955cf1 100644 --- a/spx-gui/build/Dockerfile +++ b/spx-gui/build/Dockerfile @@ -38,7 +38,7 @@ COPY tutorial ../tutorial # Copy assets (with wasm) COPY --from=go-builder /app/spx-gui/src/assets /app/spx-gui/src/assets -ARG NODE_ENV +ARG VITE_MODE ENV NODE_OPTIONS=--max-old-space-size=4096 RUN npm run build diff --git a/spx-gui/build/Dockerfile.account b/spx-gui/build/Dockerfile.account index ff45d0d57d..0b97060b6c 100644 --- a/spx-gui/build/Dockerfile.account +++ b/spx-gui/build/Dockerfile.account @@ -12,7 +12,7 @@ RUN npm install --ignore-scripts COPY spx-gui . -ARG NODE_ENV +ARG VITE_MODE ENV NODE_OPTIONS=--max-old-space-size=4096 RUN npm run build:account diff --git a/spx-gui/build/vite-plugins/app-html-entry-plugin.ts b/spx-gui/build/vite-plugins/app-html-entry-plugin.ts index 29e779af26..33763eff6b 100644 --- a/spx-gui/build/vite-plugins/app-html-entry-plugin.ts +++ b/spx-gui/build/vite-plugins/app-html-entry-plugin.ts @@ -11,7 +11,8 @@ export function createAppHtmlEntryPlugin(path: string): Plugin { name: 'app-html-entry', transformIndexHtml: { order: 'pre', - async handler() { + async handler(html, ctx) { + if (ctx.path !== '/' && ctx.path !== '/index.html') return html return await fs.promises.readFile(path, 'utf8') } } diff --git a/spx-gui/install-spx.sh b/spx-gui/install-spx.sh index 48cd208b0d..b382af6932 100755 --- a/spx-gui/install-spx.sh +++ b/spx-gui/install-spx.sh @@ -3,7 +3,7 @@ set -e cd "$(dirname "$0")" -# Keep this version in sync with `VITE_SPX_VERSION` in `.env`. +# Keep this version in sync with `VITE_SPX_VERSION` in `src/apps/xbuilder/.env`. SPX_VERSION="2.0.4" SPX_NAME="spx_${SPX_VERSION}" diff --git a/spx-gui/package.json b/spx-gui/package.json index f1ad5b68a2..2dd797f2a6 100644 --- a/spx-gui/package.json +++ b/spx-gui/package.json @@ -7,10 +7,10 @@ "postinstall": "./install-spx.sh", "predev": "./install-spx.sh && ./build-wasm.sh && ./build-tutorial-books.sh", "dev": "vite", - "build": "./build-tutorial-books.sh && vue-tsc --build --force && NODE_ENV=production vite build --mode ${NODE_ENV:-production}", + "build": "./build-tutorial-books.sh && vue-tsc --build --force && NODE_ENV=production vite build --mode ${VITE_MODE:-production}", "preview": "vite preview", "dev:account": "vite --config vite.config.account.ts --port 5174", - "build:account": "NODE_ENV=production vite build --config vite.config.account.ts --mode ${NODE_ENV:-production}", + "build:account": "NODE_ENV=production vite build --config vite.config.account.ts --mode ${VITE_MODE:-production}", "type-check": "vue-tsc --build --force", "format-check": "prettier --check ./src", "format": "prettier --write ./src", diff --git a/spx-gui/src/apis/account/oauth.ts b/spx-gui/src/apis/account/oauth.ts index a8b7657237..50d1aa5f87 100644 --- a/spx-gui/src/apis/account/oauth.ts +++ b/spx-gui/src/apis/account/oauth.ts @@ -1,5 +1,4 @@ import { Client } from '@/apis/common/client' -import { apiBaseUrl } from '@/utils/env' import type { OAuthAPIs } from '@/utils/oauth' import { accountClient } from './common' @@ -85,11 +84,9 @@ class AccountOAuthApis implements OAuthAPIs { } /** Account OAuth APIs for use by app xbuilder. */ -export const accountOAuthApisForXBuilder = new AccountOAuthApis( - new Client({ - baseUrl: apiBaseUrl + '/account' - }) -) +export const accountOAuthClientForXBuilder = new Client() + +export const accountOAuthApisForXBuilder = new AccountOAuthApis(accountOAuthClientForXBuilder) /** Account OAuth APIs for use by app account. */ export const accountOAuthApis = new AccountOAuthApis(accountClient) diff --git a/spx-gui/src/apis/common/client.ts b/spx-gui/src/apis/common/client.ts index 36b383db0e..9b4e1032ac 100644 --- a/spx-gui/src/apis/common/client.ts +++ b/spx-gui/src/apis/common/client.ts @@ -65,14 +65,14 @@ export type JSONSSEEvent = { } export type ClientOptions = { - baseUrl: string + baseUrl?: string fetchFn?: typeof fetch } export class Client { - constructor(options: ClientOptions) { - this.baseUrl = options.baseUrl - this.fetchFn = options.fetchFn ?? globalThis.fetch.bind(globalThis) + constructor(options?: ClientOptions) { + this.baseUrl = options?.baseUrl ?? null + this.fetchFn = options?.fetchFn ?? globalThis.fetch.bind(globalThis) } private tokenProvider: TokenProvider = async () => null @@ -80,13 +80,22 @@ export class Client { this.tokenProvider = provider } - private baseUrl: string + setBaseUrl(baseUrl: string) { + this.baseUrl = baseUrl + } + + private baseUrl: string | null private fetchFn: typeof fetch private defaultTimeout = 10 * 1000 // 10 seconds + private ensureBaseUrl() { + if (this.baseUrl == null) throw new Error('API client base URL is not set') + return this.baseUrl + } + /** Get full URL for a given API path */ urlFor(path: string) { - const concated = this.baseUrl + path + const concated = this.ensureBaseUrl() + path return new URL(concated, window.location.origin) } @@ -103,7 +112,7 @@ export class Client { const traceData = Sentry.getTraceData() const sentryTraceHeader = traceData['sentry-trace'] const sentryBaggageHeader = traceData['baggage'] - const url = this.baseUrl + path + const url = this.ensureBaseUrl() + path const method = options?.method ?? 'GET' const body = payload != null ? JSON.stringify(payload) : null const headers = options?.headers ?? new Headers() @@ -119,7 +128,7 @@ export class Client { const traceData = Sentry.getTraceData() const sentryTraceHeader = traceData['sentry-trace'] const sentryBaggageHeader = traceData['baggage'] - const url = this.baseUrl + path + const url = this.ensureBaseUrl() + path const method = options?.method ?? 'POST' const body = new URLSearchParams() Object.entries(payload).forEach(([key, value]) => { @@ -178,7 +187,7 @@ export class Client { const traceData = Sentry.getTraceData() const sentryTraceHeader = traceData['sentry-trace'] const sentryBaggageHeader = traceData['baggage'] - const url = this.baseUrl + path + const url = this.ensureBaseUrl() + path const method = options?.method ?? 'GET' const headers = options?.headers ?? new Headers() await this.injectAuthorization(headers, options?.signal) diff --git a/spx-gui/src/apis/common/index.ts b/spx-gui/src/apis/common/index.ts index c57b633df5..863f049dda 100644 --- a/spx-gui/src/apis/common/index.ts +++ b/spx-gui/src/apis/common/index.ts @@ -1,4 +1,3 @@ -import { apiBaseUrl } from '@/utils/env' import { Client } from './client' export type PaginationParams = { @@ -44,13 +43,9 @@ export function timeStringify(time: number) { /** * The default client instance for app XBuilder to make requests to spx-backend APIs. - * Requests made through this client will have the base URL set to `apiBaseUrl` from environment variables. - * The token provider is expected to be set separately on app initialization (see details in setup.ts) - * so credentials will be included in requests. + * The base URL and token provider are expected to be configured on app initialization. */ -export const client = new Client({ - baseUrl: apiBaseUrl -}) +export const client = new Client() /** Art style indicates the visual style or aesthetic approach used in the creation of graphics */ export const enum ArtStyle { diff --git a/spx-gui/src/apis/file.ts b/spx-gui/src/apis/file.ts index a3bf3b522b..80cdd299e4 100644 --- a/spx-gui/src/apis/file.ts +++ b/spx-gui/src/apis/file.ts @@ -2,7 +2,6 @@ * @desc File-related APIs of spx-backend */ -import { usercontentBaseUrl, usercontentBucket } from '@/utils/env' import { client, type UniversalUrl, type UniversalToWebUrlMap } from './common' import { UniversalUrlScheme, parseUniversalUrl } from '@/utils/universal-url' @@ -19,26 +18,34 @@ export type UploadSession = { region: string } +export type FileURLSignatureConfig = { + baseUrl: string + bucket: string +} + export function createUploadSession() { return client.post('/upload-sessions') as Promise } -export async function createFileURLSignatures(objects: UniversalUrl[]): Promise { +export async function createFileURLSignatures( + objects: UniversalUrl[], + config: FileURLSignatureConfig +): Promise { // TODO(#1598): Restore the `/file-url-signatures` call after signed file URLs are fixed. - return workAroundIssue1598(objects) + return workAroundIssue1598(objects, config) // const result = (await client.post('/file-url-signatures', { objects })) as { objectUrls: UniversalToWebUrlMap } // return result.objectUrls } /** Workaround for https://github.com/goplus/builder/issues/1598 */ -function workAroundIssue1598(objects: UniversalUrl[]): UniversalToWebUrlMap { +function workAroundIssue1598(objects: UniversalUrl[], config: FileURLSignatureConfig): UniversalToWebUrlMap { + const { baseUrl, bucket } = config return objects.reduce((map, universalUrl) => { const parsed = parseUniversalUrl(universalUrl) if (parsed.scheme === UniversalUrlScheme.Kodo) { - if (parsed.bucket !== usercontentBucket) - console.warn(`unexpected bucket ${parsed.bucket}, expected ${usercontentBucket}`) - map[universalUrl] = `${usercontentBaseUrl}/${parsed.key}` + if (parsed.bucket !== bucket) console.warn(`unexpected bucket ${parsed.bucket}, expected ${bucket}`) + map[universalUrl] = `${baseUrl}/${parsed.key}` } else { map[universalUrl] = universalUrl } diff --git a/spx-gui/src/apps/account/.env b/spx-gui/src/apps/account/.env new file mode 100644 index 0000000000..350cd04a0d --- /dev/null +++ b/spx-gui/src/apps/account/.env @@ -0,0 +1,32 @@ +# This file documents app account configuration. Most values are left empty, +# as actual values should be set in the corresponding `.env.[mode]` files. For +# options that require defaults, values are set here. + +# Target URL that the Account Vite dev server proxies `/api/*` requests to +# during local development. +# +# This controls where local `/api` requests are sent. It may point to the +# Account Web origin below, or to a local Account Backend. The prefix `/api` +# is stripped from the request path before forwarding. +VITE_API_PROXY_TARGET="" + +# Public Account Web origin used during local Account development. +# +# This should match the corresponding Account Backend's `ACCOUNT_WEB_BASE_URL` +# origin. +# +# This origin serves two related roles: +# - Browser Hijack Plugin redirects matching browser requests from this origin +# back to the local Account Vite dev server. +# - The local `/api` proxy presents requests as coming through this Account Web +# origin by setting `Origin`, `Host`, and forwarded host/proto headers +# accordingly. +VITE_WEB_ORIGIN="" + +# Sentry configuration for app account. +VITE_SENTRY_DSN="" +VITE_SENTRY_TRACES_SAMPLE_RATE="0.8" +VITE_SENTRY_LSP_SAMPLE_RATE="0.1" + +# Default language for app account, e.g. `en`, `zh`. +VITE_DEFAULT_LANG="en" diff --git a/spx-gui/.env.development b/spx-gui/src/apps/account/.env.development similarity index 100% rename from spx-gui/.env.development rename to spx-gui/src/apps/account/.env.development diff --git a/spx-gui/src/apps/account/.env.production b/spx-gui/src/apps/account/.env.production new file mode 100644 index 0000000000..f6f902cb2f --- /dev/null +++ b/spx-gui/src/apps/account/.env.production @@ -0,0 +1,3 @@ +# Config for env production + +VITE_SENTRY_DSN="https://0d463740215eb87f7e06f6572d64c93e@o4509472134987776.ingest.us.sentry.io/4509472136167424" diff --git a/spx-gui/src/apps/account/.env.production-cn b/spx-gui/src/apps/account/.env.production-cn new file mode 100644 index 0000000000..467dd715fe --- /dev/null +++ b/spx-gui/src/apps/account/.env.production-cn @@ -0,0 +1,4 @@ +# Config for env production-cn + +VITE_SENTRY_DSN="https://3b532e8d49bece95a4ad2d14c73c2e0b@o4509472134987776.ingest.us.sentry.io/4509868940263424" +VITE_DEFAULT_LANG="zh" diff --git a/spx-gui/src/apps/account/.env.staging b/spx-gui/src/apps/account/.env.staging new file mode 100644 index 0000000000..52fd5a847c --- /dev/null +++ b/spx-gui/src/apps/account/.env.staging @@ -0,0 +1,6 @@ +# Config for env staging + +VITE_API_PROXY_TARGET="https://goplus-builder-account.qiniu.io/api" +VITE_WEB_ORIGIN="https://goplus-builder-account.qiniu.io" + +VITE_SENTRY_DSN="https://0d463740215eb87f7e06f6572d64c93e@o4509472134987776.ingest.us.sentry.io/4509472136167424" diff --git a/spx-gui/src/apps/account/env.ts b/spx-gui/src/apps/account/env.ts new file mode 100644 index 0000000000..8f9c347f60 --- /dev/null +++ b/spx-gui/src/apps/account/env.ts @@ -0,0 +1,8 @@ +export const defaultLang = (import.meta.env.VITE_DEFAULT_LANG as string) || 'en' +const sentryTracesSampleRate = parseFloat(import.meta.env.VITE_SENTRY_TRACES_SAMPLE_RATE as string) +const sentryLSPSampleRate = parseFloat(import.meta.env.VITE_SENTRY_LSP_SAMPLE_RATE as string) +export const sentry = { + dsn: (import.meta.env.VITE_SENTRY_DSN as string) || '', + tracesSampleRate: Number.isNaN(sentryTracesSampleRate) ? 0.1 : sentryTracesSampleRate, + lspSampleRate: Number.isNaN(sentryLSPSampleRate) ? 0.1 : sentryLSPSampleRate +} diff --git a/spx-gui/src/apps/account/main.ts b/spx-gui/src/apps/account/main.ts index b3fd95195a..6ff2e679e5 100644 --- a/spx-gui/src/apps/account/main.ts +++ b/spx-gui/src/apps/account/main.ts @@ -6,6 +6,7 @@ import { initDayjs } from '@/setup/dayjs' import { initI18n } from '@/setup/i18n' import { initSentry } from '@/setup/sentry' +import * as env from './env' import App from './App.vue' import router from './router' @@ -15,7 +16,7 @@ import router from './router' initDayjs() const app = createApp(App) -initSentry(app, router) -initI18n(app) +initSentry(app, router, env.sentry) +initI18n(app, env.defaultLang) app.use(router) app.mount('#app') diff --git a/spx-gui/src/apps/account/pages/home.vue b/spx-gui/src/apps/account/pages/home.vue index 62370c12d7..5084d9f6e4 100644 --- a/spx-gui/src/apps/account/pages/home.vue +++ b/spx-gui/src/apps/account/pages/home.vue @@ -51,9 +51,8 @@ import { computed } from 'vue' import { getSession } from '@/apis/account' import { UIError, UILoading } from '@/components/ui' -import { useAvatarUrl } from '@/stores/user/avatar' import { useQuery } from '@/utils/query' -import { usePageTitle } from '@/utils/utils' +import { useExternalUrl, usePageTitle } from '@/utils/utils' const { isLoading, @@ -65,7 +64,7 @@ const { zh: '无法加载登录状态' }) -const avatarUrl = useAvatarUrl(() => session.value?.user.avatar ?? null) +const avatarUrl = useExternalUrl(() => session.value?.user.avatar ?? null) const initial = computed(() => session.value == null ? '?' : session.value.user.displayName.trim().charAt(0).toUpperCase() || '?' ) diff --git a/spx-gui/.env b/spx-gui/src/apps/xbuilder/.env similarity index 51% rename from spx-gui/.env rename to spx-gui/src/apps/xbuilder/.env index 9c7d55ff36..3c3fc31856 100644 --- a/spx-gui/.env +++ b/spx-gui/src/apps/xbuilder/.env @@ -1,7 +1,6 @@ -# This file serves primarily as a documentation for the available configuration -# options in the project. Most values are left empty, as actual values should be -# set in the corresponding `.env.[mode]` files. However, for the ones that -# require default values, such as feature flags, they are set here. +# This file documents app xbuilder configuration. Most values are left empty, +# as actual values should be set in the corresponding `.env.[mode]` files. For +# options that require defaults, such as feature flags, values are set here. # Base URL for the spx-backend API. # @@ -21,17 +20,17 @@ VITE_VERCEL_PROXIED_API_BASE_URL="" # Optional. Only used when running `npm run dev`. VITE_DEV_PROXIED_API_BASE_URL="" -# Base URL for user-generated content files (e.g., images, audio) used in projects. +# Base URL for user-generated content files (e.g. images, audio) used in projects. # # NOTE: Must be synchronized with `KODO_BASE_URL` in spx-backend `.env` file. VITE_USERCONTENT_BASE_URL="" -# Kodo (Qiniu Cloud Object Storage) bucket name for user-generated content files +# Kodo (Qiniu Cloud Object Storage) bucket name for user-generated content files. # # NOTE: Must be synchronized with `KODO_BUCKET` in spx-backend `.env` file. VITE_USERCONTENT_BUCKET="" -# Base URL for user-generated content files (e.g., images, audio) uploading. +# Base URL for user-generated content files (e.g. images, audio) uploading. # # NOTE: Must be synchronized with `KODO_BUCKET_REGION` in spx-backend `.env` file. VITE_USERCONTENT_UPLOAD_BASE_URL="" @@ -47,46 +46,26 @@ VITE_SPX_VERSION="2.0.4" # Whether to show the license information (including copyright) in the footer. VITE_SHOW_LICENSE="false" -# Sentry configuration for error and performance monitoring -# DSN is required if you want to use Sentry (leave empty to disable) +# Sentry configuration for error and performance monitoring. +# DSN is required if you want to use Sentry (leave empty to disable). VITE_SENTRY_DSN="" -# Sampling rate for Sentry performance monitoring (0.0 to 1.0) -# 0.0 means no transactions are sent, 1.0 means all transactions are sent +# Sampling rate for Sentry performance monitoring (0.0 to 1.0). +# 0.0 means no transactions are sent, 1.0 means all transactions are sent. VITE_SENTRY_TRACES_SAMPLE_RATE="0.8" -# Sampling rate for Sentry LSP (Language Server Protocol) monitoring -# 0.0 means no LSP events are sent, 1.0 means all LSP events are sent +# Sampling rate for Sentry LSP (Language Server Protocol) monitoring. +# 0.0 means no LSP events are sent, 1.0 means all LSP events are sent. VITE_SENTRY_LSP_SAMPLE_RATE="0.1" -# If tutorials entry should be shown in the Navbar +# If tutorials entry should be shown in the Navbar. VITE_SHOW_TUTORIALS_ENTRY="false" -# Default language, e.g. `en`, `zh` +# Default language, e.g. `en`, `zh`. VITE_DEFAULT_LANG="en" -# Target URL that the Account Vite dev server proxies `/api/*` requests to -# during local development. -# -# This controls where local `/api` requests are sent. It may point to the -# Account Web origin below, or to a local Account Backend. The prefix `/api` -# is stripped from the request path before forwarding. -VITE_ACCOUNT_API_PROXY_TARGET="" - -# Public Account Web origin used during local Account development. -# -# This should match the corresponding Account Backend's `ACCOUNT_WEB_BASE_URL` -# origin. -# -# This origin serves two related roles: -# - Browser Hijack Plugin redirects matching browser requests from this origin -# back to the local Account Vite dev server. -# - The local `/api` proxy presents requests as coming through this Account Web -# origin by setting `Origin`, `Host`, and forwarded host/proto headers -# accordingly. -VITE_ACCOUNT_WEB_ORIGIN="" - -# Account OAuth configuration for the main-site hosted sign-in flow. +# Account OAuth configuration used by app xbuilder for the main-site hosted +# sign-in flow. # # Required when enabling the new Account OAuth flow. VITE_ACCOUNT_OAUTH_CLIENT_ID="" diff --git a/spx-gui/src/apps/xbuilder/.env.development b/spx-gui/src/apps/xbuilder/.env.development new file mode 120000 index 0000000000..4cb6f9fc55 --- /dev/null +++ b/spx-gui/src/apps/xbuilder/.env.development @@ -0,0 +1 @@ +.env.staging \ No newline at end of file diff --git a/spx-gui/.env.production b/spx-gui/src/apps/xbuilder/.env.production similarity index 100% rename from spx-gui/.env.production rename to spx-gui/src/apps/xbuilder/.env.production diff --git a/spx-gui/.env.production.cn b/spx-gui/src/apps/xbuilder/.env.production-cn similarity index 100% rename from spx-gui/.env.production.cn rename to spx-gui/src/apps/xbuilder/.env.production-cn diff --git a/spx-gui/.env.staging b/spx-gui/src/apps/xbuilder/.env.staging similarity index 78% rename from spx-gui/.env.staging rename to spx-gui/src/apps/xbuilder/.env.staging index 6bc8b1eb9e..f23aa21eac 100644 --- a/spx-gui/.env.staging +++ b/spx-gui/src/apps/xbuilder/.env.staging @@ -11,6 +11,4 @@ VITE_SENTRY_DSN="https://0d463740215eb87f7e06f6572d64c93e@o4509472134987776.inge VITE_SHOW_TUTORIALS_ENTRY="true" -VITE_ACCOUNT_API_PROXY_TARGET="https://goplus-builder-account.qiniu.io/api" -VITE_ACCOUNT_WEB_ORIGIN="https://goplus-builder-account.qiniu.io" VITE_ACCOUNT_OAUTH_CLIENT_ID="1" diff --git a/spx-gui/src/apps/xbuilder/env.ts b/spx-gui/src/apps/xbuilder/env.ts new file mode 100644 index 0000000000..d852b0181b --- /dev/null +++ b/spx-gui/src/apps/xbuilder/env.ts @@ -0,0 +1,16 @@ +export const apiBaseUrl = import.meta.env.VITE_API_BASE_URL as string +export const usercontentBaseUrl = import.meta.env.VITE_USERCONTENT_BASE_URL as string +export const usercontentBucket = import.meta.env.VITE_USERCONTENT_BUCKET as string +export const disableAIGC = import.meta.env.VITE_DISABLE_AIGC === 'true' +export const spxVersion = import.meta.env.VITE_SPX_VERSION as string +export const showLicense = import.meta.env.VITE_SHOW_LICENSE === 'true' +export const showTutorialsEntry = import.meta.env.VITE_SHOW_TUTORIALS_ENTRY === 'true' +export const defaultLang = (import.meta.env.VITE_DEFAULT_LANG as string) || 'en' +export const accountOAuthClientId = import.meta.env.VITE_ACCOUNT_OAUTH_CLIENT_ID as string +const sentryTracesSampleRate = parseFloat(import.meta.env.VITE_SENTRY_TRACES_SAMPLE_RATE as string) +const sentryLSPSampleRate = parseFloat(import.meta.env.VITE_SENTRY_LSP_SAMPLE_RATE as string) +export const sentry = { + dsn: (import.meta.env.VITE_SENTRY_DSN as string) || '', + tracesSampleRate: Number.isNaN(sentryTracesSampleRate) ? 0.1 : sentryTracesSampleRate, + lspSampleRate: Number.isNaN(sentryLSPSampleRate) ? 0.1 : sentryLSPSampleRate +} diff --git a/spx-gui/src/apps/xbuilder/main.ts b/spx-gui/src/apps/xbuilder/main.ts index 26e7cce983..df854d81c8 100644 --- a/spx-gui/src/apps/xbuilder/main.ts +++ b/spx-gui/src/apps/xbuilder/main.ts @@ -1,12 +1,12 @@ import '@/polyfills' import '@/app.css' import { createApp } from 'vue' -import { setup, configureApp } from '@/setup' +import { setupXBuilder, configureXBuilderApp } from './setup' import { initRouter } from './router' import App from './App.vue' -setup() +setupXBuilder() const app = createApp(App) const router = initRouter(app) -configureApp(app, router) +configureXBuilderApp(app, router) app.mount('#app') diff --git a/spx-gui/src/apps/xbuilder/pages/admin/index.vue b/spx-gui/src/apps/xbuilder/pages/admin/index.vue index 8c2034d71a..8691bba74a 100644 --- a/spx-gui/src/apps/xbuilder/pages/admin/index.vue +++ b/spx-gui/src/apps/xbuilder/pages/admin/index.vue @@ -1,9 +1,9 @@