everything-dev 2.0.0-rc.1 → 2.0.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-contract.cjs +3 -6
- package/dist/api-contract.cjs.map +1 -1
- package/dist/api-contract.mjs +3 -6
- package/dist/api-contract.mjs.map +1 -1
- package/dist/apps/upload/src/client.cjs +188 -0
- package/dist/apps/upload/src/client.cjs.map +1 -0
- package/dist/apps/upload/src/client.mjs +180 -0
- package/dist/apps/upload/src/client.mjs.map +1 -0
- package/dist/auth-login.cjs +1 -1
- package/dist/auth-login.mjs +1 -1
- package/dist/build.cjs +2 -2
- package/dist/build.mjs +2 -2
- package/dist/bundle-fs-resolve.cjs +9 -17
- package/dist/bundle-fs-resolve.cjs.map +1 -1
- package/dist/bundle-fs-resolve.d.cts +6 -0
- package/dist/bundle-fs-resolve.d.mts +6 -0
- package/dist/bundle-fs-resolve.mjs +9 -17
- package/dist/bundle-fs-resolve.mjs.map +1 -1
- package/dist/bundle-path.cjs +48 -0
- package/dist/bundle-path.cjs.map +1 -0
- package/dist/bundle-path.mjs +45 -0
- package/dist/bundle-path.mjs.map +1 -0
- package/dist/cdn-deploy.cjs +29 -11
- package/dist/cdn-deploy.cjs.map +1 -1
- package/dist/cdn-deploy.mjs +29 -11
- package/dist/cdn-deploy.mjs.map +1 -1
- package/dist/cli/init.cjs +4 -6
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +1 -1
- package/dist/cli/init.d.mts +1 -1
- package/dist/cli/init.mjs +4 -6
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/status.cjs +69 -3
- package/dist/cli/status.cjs.map +1 -1
- package/dist/cli/status.mjs +67 -4
- package/dist/cli/status.mjs.map +1 -1
- package/dist/cli/sync.cjs +1 -2
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +1 -2
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/upgrade.cjs +2 -2
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +2 -2
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/cli.cjs +5 -7
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +5 -7
- package/dist/cli.mjs.map +1 -1
- package/dist/commands/deploy.cjs +26 -18
- package/dist/commands/deploy.cjs.map +1 -1
- package/dist/commands/deploy.mjs +26 -18
- package/dist/commands/deploy.mjs.map +1 -1
- package/dist/commands/init.cjs +1 -1
- package/dist/commands/init.cjs.map +1 -1
- package/dist/commands/init.mjs +1 -1
- package/dist/commands/init.mjs.map +1 -1
- package/dist/commands/plugins.cjs +2 -2
- package/dist/commands/plugins.cjs.map +1 -1
- package/dist/commands/plugins.mjs +2 -2
- package/dist/commands/plugins.mjs.map +1 -1
- package/dist/commands/upgrade.cjs +31 -8
- package/dist/commands/upgrade.cjs.map +1 -1
- package/dist/commands/upgrade.mjs +31 -8
- package/dist/commands/upgrade.mjs.map +1 -1
- package/dist/components/dev-render.cjs +1 -1
- package/dist/components/dev-render.mjs +1 -1
- package/dist/config.cjs +3 -3
- package/dist/config.cjs.map +1 -1
- package/dist/config.mjs +3 -3
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs +2 -0
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +3 -0
- package/dist/contract.d.mts +3 -0
- package/dist/contract.meta.cjs +2 -1
- package/dist/contract.meta.cjs.map +1 -1
- package/dist/contract.meta.d.cts +4 -1
- package/dist/contract.meta.d.mts +4 -1
- package/dist/contract.meta.mjs +2 -1
- package/dist/contract.meta.mjs.map +1 -1
- package/dist/contract.mjs +2 -0
- package/dist/contract.mjs.map +1 -1
- package/dist/db/driver.cjs +22 -2
- package/dist/db/driver.cjs.map +1 -1
- package/dist/db/driver.d.cts +13 -2
- package/dist/db/driver.d.mts +13 -2
- package/dist/db/driver.mjs +22 -3
- package/dist/db/driver.mjs.map +1 -1
- package/dist/db/index.cjs +1 -0
- package/dist/db/index.d.cts +2 -2
- package/dist/db/index.d.mts +2 -2
- package/dist/db/index.mjs +2 -2
- package/dist/deploy-diff.cjs +1 -1
- package/dist/deploy-diff.cjs.map +1 -1
- package/dist/deploy-diff.mjs +1 -1
- package/dist/deploy-diff.mjs.map +1 -1
- package/dist/dev-program.cjs +11 -2
- package/dist/dev-program.cjs.map +1 -1
- package/dist/dev-program.mjs +11 -3
- package/dist/dev-program.mjs.map +1 -1
- package/dist/image-deploy.cjs +103 -31
- package/dist/image-deploy.cjs.map +1 -1
- package/dist/image-deploy.mjs +103 -33
- package/dist/image-deploy.mjs.map +1 -1
- package/dist/internal/manifest-normalizer.cjs.map +1 -1
- package/dist/internal/manifest-normalizer.mjs.map +1 -1
- package/dist/plugin.d.cts +902 -1
- package/dist/plugin.d.mts +902 -1
- package/dist/publish.cjs +51 -2
- package/dist/publish.cjs.map +1 -1
- package/dist/publish.mjs +51 -4
- package/dist/publish.mjs.map +1 -1
- package/dist/resolution/session.cjs.map +1 -1
- package/dist/resolution/session.d.cts +5 -5
- package/dist/resolution/session.d.mts +5 -5
- package/dist/resolution/session.mjs.map +1 -1
- package/dist/storage-upload.cjs +7 -68
- package/dist/storage-upload.cjs.map +1 -1
- package/dist/storage-upload.mjs +7 -68
- package/dist/storage-upload.mjs.map +1 -1
- package/dist/types.d.cts +31 -1
- package/dist/types.d.mts +31 -1
- package/dist/ui/api.cjs +11 -69
- package/dist/ui/api.cjs.map +1 -1
- package/dist/ui/api.d.cts +2 -4
- package/dist/ui/api.d.mts +2 -4
- package/dist/ui/api.mjs +11 -69
- package/dist/ui/api.mjs.map +1 -1
- package/dist/ui/auth-guards.d.cts +78 -2
- package/dist/ui/auth-guards.d.mts +78 -2
- package/dist/ui/auth.cjs.map +1 -1
- package/dist/ui/auth.d.cts +4133 -7
- package/dist/ui/auth.d.mts +4133 -7
- package/dist/ui/auth.mjs.map +1 -1
- package/dist/ui/hydrate.cjs +2 -2
- package/dist/ui/hydrate.cjs.map +1 -1
- package/dist/ui/hydrate.mjs +2 -2
- package/dist/ui/hydrate.mjs.map +1 -1
- package/dist/utils/theme.cjs +2 -2
- package/dist/utils/theme.cjs.map +1 -1
- package/dist/utils/theme.mjs +2 -2
- package/dist/utils/theme.mjs.map +1 -1
- package/dist/version-manifest-resolve.cjs +55 -10
- package/dist/version-manifest-resolve.cjs.map +1 -1
- package/dist/version-manifest-resolve.mjs +53 -10
- package/dist/version-manifest-resolve.mjs.map +1 -1
- package/dist/workspace.cjs +26 -13
- package/dist/workspace.cjs.map +1 -1
- package/dist/workspace.mjs +26 -14
- package/dist/workspace.mjs.map +1 -1
- package/package.json +12 -10
package/dist/deploy-diff.cjs
CHANGED
|
@@ -49,7 +49,7 @@ function upsertDeployStatePins(configDir, account, gateway, pins) {
|
|
|
49
49
|
const state = readDeployState(configDir);
|
|
50
50
|
const appKey = `${account}/${gateway}`;
|
|
51
51
|
state.apps[appKey] = {
|
|
52
|
-
...state.apps[appKey]
|
|
52
|
+
...state.apps[appKey],
|
|
53
53
|
...pins
|
|
54
54
|
};
|
|
55
55
|
writeDeployState(configDir, state);
|
package/dist/deploy-diff.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-diff.cjs","names":["createHash","join","existsSync","readFileSync","dirname","collectSlotPinRefs"],"sources":["../src/deploy-diff.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { collectSlotPinRefs } from \"./rollback\";\nimport type { DistFile } from \"./storage-upload\";\nimport type { BosConfigInput } from \"./types\";\n\n/**\n * Differential bundle uploads (skip-unchanged): the previous deploy's version\n * manifest carries the dist's full per-file SRI map (`files`), so the next\n * deploy hashes its local dist, diffs against that map, and re-uploads only\n * new or changed files. Content-hashed dist filenames make an unchanged chunk\n * byte-identical, so a typical redeploy ships a handful of files instead of\n * the whole tree.\n *\n * Correctness: a skip requires (path, sha384) to match the previous\n * **server-computed** SRI map — client hashes decide only what to skip; the\n * published manifest keeps carrying the server-computed values. Any failure\n * to resolve the previous map (no pointer, fetch failed, SRI mismatch, manifest\n * predates `files`) degrades to a full upload.\n */\n\nexport interface PreviousPin {\n manifest: string;\n integrity: string;\n}\n\nexport interface DeployStateFile {\n version: 1;\n /** key: `<account>/<gateway>`, then workspace key → pin */\n apps: Record<string, Record<string, PreviousPin>>;\n}\n\nexport const BUNDLE_BASE_PATTERN = /\\/bundles\\/([^/]+)\\/([^/]+)\\/([^/]+)\\/$/;\n\nexport function workspaceKeyOfBase(base: string): string | null {\n const match = BUNDLE_BASE_PATTERN.exec(`${base.replace(/\\/$/, \"\")}/`);\n return match ? match[3]! : null;\n}\n\n/** The sha384 SRI the storage route would compute for these bytes. */\nexport function localObjectIntegrity(bytes: Uint8Array): string {\n return `sha384-${createHash(\"sha384\").update(bytes).digest(\"base64\")}`;\n}\n\nexport function localSriMap(files: DistFile[]): Record<string, string> {\n return Object.fromEntries(files.map((file) => [file.path, localObjectIntegrity(file.bytes)]));\n}\n\nconst deployStatePath = (configDir: string) => join(configDir, \".bos\", \"deploy-state.json\");\n\nexport function readDeployState(configDir: string): DeployStateFile {\n const path = deployStatePath(configDir);\n if (!existsSync(path)) return { version: 1, apps: {} };\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as Partial<DeployStateFile>;\n if (parsed.version !== 1 || typeof parsed.apps !== \"object\" || parsed.apps === null) {\n return { version: 1, apps: {} };\n }\n return { version: 1, apps: parsed.apps as DeployStateFile[\"apps\"] };\n } catch {\n return { version: 1, apps: {} };\n }\n}\n\nexport function writeDeployState(configDir: string, state: DeployStateFile): void {\n const path = deployStatePath(configDir);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(state, null, 2)}\\n`);\n}\n\nexport function upsertDeployStatePins(\n configDir: string,\n account: string,\n gateway: string,\n pins: Record<string, PreviousPin>,\n): void {\n const state = readDeployState(configDir);\n const appKey = `${account}/${gateway}`;\n state.apps[appKey] = { ...
|
|
1
|
+
{"version":3,"file":"deploy-diff.cjs","names":["createHash","join","existsSync","readFileSync","dirname","collectSlotPinRefs"],"sources":["../src/deploy-diff.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { collectSlotPinRefs } from \"./rollback\";\nimport type { DistFile } from \"./storage-upload\";\nimport type { BosConfigInput } from \"./types\";\n\n/**\n * Differential bundle uploads (skip-unchanged): the previous deploy's version\n * manifest carries the dist's full per-file SRI map (`files`), so the next\n * deploy hashes its local dist, diffs against that map, and re-uploads only\n * new or changed files. Content-hashed dist filenames make an unchanged chunk\n * byte-identical, so a typical redeploy ships a handful of files instead of\n * the whole tree.\n *\n * Correctness: a skip requires (path, sha384) to match the previous\n * **server-computed** SRI map — client hashes decide only what to skip; the\n * published manifest keeps carrying the server-computed values. Any failure\n * to resolve the previous map (no pointer, fetch failed, SRI mismatch, manifest\n * predates `files`) degrades to a full upload.\n */\n\nexport interface PreviousPin {\n manifest: string;\n integrity: string;\n}\n\nexport interface DeployStateFile {\n version: 1;\n /** key: `<account>/<gateway>`, then workspace key → pin */\n apps: Record<string, Record<string, PreviousPin>>;\n}\n\nexport const BUNDLE_BASE_PATTERN = /\\/bundles\\/([^/]+)\\/([^/]+)\\/([^/]+)\\/$/;\n\nexport function workspaceKeyOfBase(base: string): string | null {\n const match = BUNDLE_BASE_PATTERN.exec(`${base.replace(/\\/$/, \"\")}/`);\n return match ? match[3]! : null;\n}\n\n/** The sha384 SRI the storage route would compute for these bytes. */\nexport function localObjectIntegrity(bytes: Uint8Array): string {\n return `sha384-${createHash(\"sha384\").update(bytes).digest(\"base64\")}`;\n}\n\nexport function localSriMap(files: DistFile[]): Record<string, string> {\n return Object.fromEntries(files.map((file) => [file.path, localObjectIntegrity(file.bytes)]));\n}\n\nconst deployStatePath = (configDir: string) => join(configDir, \".bos\", \"deploy-state.json\");\n\nexport function readDeployState(configDir: string): DeployStateFile {\n const path = deployStatePath(configDir);\n if (!existsSync(path)) return { version: 1, apps: {} };\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as Partial<DeployStateFile>;\n if (parsed.version !== 1 || typeof parsed.apps !== \"object\" || parsed.apps === null) {\n return { version: 1, apps: {} };\n }\n return { version: 1, apps: parsed.apps as DeployStateFile[\"apps\"] };\n } catch {\n return { version: 1, apps: {} };\n }\n}\n\nexport function writeDeployState(configDir: string, state: DeployStateFile): void {\n const path = deployStatePath(configDir);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(state, null, 2)}\\n`);\n}\n\nexport function upsertDeployStatePins(\n configDir: string,\n account: string,\n gateway: string,\n pins: Record<string, PreviousPin>,\n): void {\n const state = readDeployState(configDir);\n const appKey = `${account}/${gateway}`;\n state.apps[appKey] = { ...state.apps[appKey], ...pins };\n writeDeployState(configDir, state);\n}\n\n/** Previous pins by workspace key, from the local deploy-state pointer. */\nexport function pinsFromDeployState(\n configDir: string,\n account: string,\n gateway: string,\n): Record<string, PreviousPin> {\n return readDeployState(configDir).apps[`${account}/${gateway}`] ?? {};\n}\n\n/** Previous pins by workspace key, from the published config's slot pins. */\nexport function pinsFromPublishedConfig(\n config: BosConfigInput,\n account: string,\n gateway: string,\n): Record<string, PreviousPin> {\n const pins: Record<string, PreviousPin> = {};\n for (const ref of collectSlotPinRefs(config)) {\n const workspace = workspaceKeyOfBase(ref.base);\n const nsMatch = BUNDLE_BASE_PATTERN.exec(`${ref.base.replace(/\\/$/, \"\")}/`);\n if (!workspace || !nsMatch || nsMatch[1] !== account || nsMatch[2] !== gateway) continue;\n pins[workspace] = ref.pin;\n }\n return pins;\n}\n\nexport interface WorkspaceDiff {\n /** files that must be uploaded (new or changed) */\n upload: DistFile[];\n /** number of files skipped because the previous manifest holds identical bytes */\n skipped: number;\n}\n\nexport function diffWorkspaceFiles(\n files: DistFile[],\n localSri: Record<string, string>,\n prevFiles: Record<string, string>,\n): WorkspaceDiff {\n const upload: DistFile[] = [];\n let skipped = 0;\n for (const file of files) {\n if (prevFiles[file.path] !== undefined && prevFiles[file.path] === localSri[file.path]) {\n skipped += 1;\n continue;\n }\n upload.push(file);\n }\n return { upload, skipped };\n}\n\n/**\n * The manifest's merged per-file map for this deploy: uploaded files carry the\n * server-computed SRI from the upload response; skipped files carry the\n * previous manifest's server-computed SRI (byte-identical to the local hash by\n * the skip decision). Files that left the dist carry nothing.\n */\nexport function mergedFileIntegrity(\n files: DistFile[],\n uploadedIntegrity: Record<string, string>,\n prevFiles: Record<string, string> | undefined,\n): Record<string, string> {\n const merged: Record<string, string> = {};\n for (const file of files) {\n const uploaded = uploadedIntegrity[file.path];\n if (uploaded) {\n merged[file.path] = uploaded;\n continue;\n }\n const carried = prevFiles?.[file.path];\n if (carried) merged[file.path] = carried;\n }\n return merged;\n}\n"],"mappings":"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"}
|
package/dist/deploy-diff.mjs
CHANGED
|
@@ -49,7 +49,7 @@ function upsertDeployStatePins(configDir, account, gateway, pins) {
|
|
|
49
49
|
const state = readDeployState(configDir);
|
|
50
50
|
const appKey = `${account}/${gateway}`;
|
|
51
51
|
state.apps[appKey] = {
|
|
52
|
-
...state.apps[appKey]
|
|
52
|
+
...state.apps[appKey],
|
|
53
53
|
...pins
|
|
54
54
|
};
|
|
55
55
|
writeDeployState(configDir, state);
|
package/dist/deploy-diff.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-diff.mjs","names":[],"sources":["../src/deploy-diff.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { collectSlotPinRefs } from \"./rollback\";\nimport type { DistFile } from \"./storage-upload\";\nimport type { BosConfigInput } from \"./types\";\n\n/**\n * Differential bundle uploads (skip-unchanged): the previous deploy's version\n * manifest carries the dist's full per-file SRI map (`files`), so the next\n * deploy hashes its local dist, diffs against that map, and re-uploads only\n * new or changed files. Content-hashed dist filenames make an unchanged chunk\n * byte-identical, so a typical redeploy ships a handful of files instead of\n * the whole tree.\n *\n * Correctness: a skip requires (path, sha384) to match the previous\n * **server-computed** SRI map — client hashes decide only what to skip; the\n * published manifest keeps carrying the server-computed values. Any failure\n * to resolve the previous map (no pointer, fetch failed, SRI mismatch, manifest\n * predates `files`) degrades to a full upload.\n */\n\nexport interface PreviousPin {\n manifest: string;\n integrity: string;\n}\n\nexport interface DeployStateFile {\n version: 1;\n /** key: `<account>/<gateway>`, then workspace key → pin */\n apps: Record<string, Record<string, PreviousPin>>;\n}\n\nexport const BUNDLE_BASE_PATTERN = /\\/bundles\\/([^/]+)\\/([^/]+)\\/([^/]+)\\/$/;\n\nexport function workspaceKeyOfBase(base: string): string | null {\n const match = BUNDLE_BASE_PATTERN.exec(`${base.replace(/\\/$/, \"\")}/`);\n return match ? match[3]! : null;\n}\n\n/** The sha384 SRI the storage route would compute for these bytes. */\nexport function localObjectIntegrity(bytes: Uint8Array): string {\n return `sha384-${createHash(\"sha384\").update(bytes).digest(\"base64\")}`;\n}\n\nexport function localSriMap(files: DistFile[]): Record<string, string> {\n return Object.fromEntries(files.map((file) => [file.path, localObjectIntegrity(file.bytes)]));\n}\n\nconst deployStatePath = (configDir: string) => join(configDir, \".bos\", \"deploy-state.json\");\n\nexport function readDeployState(configDir: string): DeployStateFile {\n const path = deployStatePath(configDir);\n if (!existsSync(path)) return { version: 1, apps: {} };\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as Partial<DeployStateFile>;\n if (parsed.version !== 1 || typeof parsed.apps !== \"object\" || parsed.apps === null) {\n return { version: 1, apps: {} };\n }\n return { version: 1, apps: parsed.apps as DeployStateFile[\"apps\"] };\n } catch {\n return { version: 1, apps: {} };\n }\n}\n\nexport function writeDeployState(configDir: string, state: DeployStateFile): void {\n const path = deployStatePath(configDir);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(state, null, 2)}\\n`);\n}\n\nexport function upsertDeployStatePins(\n configDir: string,\n account: string,\n gateway: string,\n pins: Record<string, PreviousPin>,\n): void {\n const state = readDeployState(configDir);\n const appKey = `${account}/${gateway}`;\n state.apps[appKey] = { ...
|
|
1
|
+
{"version":3,"file":"deploy-diff.mjs","names":[],"sources":["../src/deploy-diff.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { collectSlotPinRefs } from \"./rollback\";\nimport type { DistFile } from \"./storage-upload\";\nimport type { BosConfigInput } from \"./types\";\n\n/**\n * Differential bundle uploads (skip-unchanged): the previous deploy's version\n * manifest carries the dist's full per-file SRI map (`files`), so the next\n * deploy hashes its local dist, diffs against that map, and re-uploads only\n * new or changed files. Content-hashed dist filenames make an unchanged chunk\n * byte-identical, so a typical redeploy ships a handful of files instead of\n * the whole tree.\n *\n * Correctness: a skip requires (path, sha384) to match the previous\n * **server-computed** SRI map — client hashes decide only what to skip; the\n * published manifest keeps carrying the server-computed values. Any failure\n * to resolve the previous map (no pointer, fetch failed, SRI mismatch, manifest\n * predates `files`) degrades to a full upload.\n */\n\nexport interface PreviousPin {\n manifest: string;\n integrity: string;\n}\n\nexport interface DeployStateFile {\n version: 1;\n /** key: `<account>/<gateway>`, then workspace key → pin */\n apps: Record<string, Record<string, PreviousPin>>;\n}\n\nexport const BUNDLE_BASE_PATTERN = /\\/bundles\\/([^/]+)\\/([^/]+)\\/([^/]+)\\/$/;\n\nexport function workspaceKeyOfBase(base: string): string | null {\n const match = BUNDLE_BASE_PATTERN.exec(`${base.replace(/\\/$/, \"\")}/`);\n return match ? match[3]! : null;\n}\n\n/** The sha384 SRI the storage route would compute for these bytes. */\nexport function localObjectIntegrity(bytes: Uint8Array): string {\n return `sha384-${createHash(\"sha384\").update(bytes).digest(\"base64\")}`;\n}\n\nexport function localSriMap(files: DistFile[]): Record<string, string> {\n return Object.fromEntries(files.map((file) => [file.path, localObjectIntegrity(file.bytes)]));\n}\n\nconst deployStatePath = (configDir: string) => join(configDir, \".bos\", \"deploy-state.json\");\n\nexport function readDeployState(configDir: string): DeployStateFile {\n const path = deployStatePath(configDir);\n if (!existsSync(path)) return { version: 1, apps: {} };\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as Partial<DeployStateFile>;\n if (parsed.version !== 1 || typeof parsed.apps !== \"object\" || parsed.apps === null) {\n return { version: 1, apps: {} };\n }\n return { version: 1, apps: parsed.apps as DeployStateFile[\"apps\"] };\n } catch {\n return { version: 1, apps: {} };\n }\n}\n\nexport function writeDeployState(configDir: string, state: DeployStateFile): void {\n const path = deployStatePath(configDir);\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(state, null, 2)}\\n`);\n}\n\nexport function upsertDeployStatePins(\n configDir: string,\n account: string,\n gateway: string,\n pins: Record<string, PreviousPin>,\n): void {\n const state = readDeployState(configDir);\n const appKey = `${account}/${gateway}`;\n state.apps[appKey] = { ...state.apps[appKey], ...pins };\n writeDeployState(configDir, state);\n}\n\n/** Previous pins by workspace key, from the local deploy-state pointer. */\nexport function pinsFromDeployState(\n configDir: string,\n account: string,\n gateway: string,\n): Record<string, PreviousPin> {\n return readDeployState(configDir).apps[`${account}/${gateway}`] ?? {};\n}\n\n/** Previous pins by workspace key, from the published config's slot pins. */\nexport function pinsFromPublishedConfig(\n config: BosConfigInput,\n account: string,\n gateway: string,\n): Record<string, PreviousPin> {\n const pins: Record<string, PreviousPin> = {};\n for (const ref of collectSlotPinRefs(config)) {\n const workspace = workspaceKeyOfBase(ref.base);\n const nsMatch = BUNDLE_BASE_PATTERN.exec(`${ref.base.replace(/\\/$/, \"\")}/`);\n if (!workspace || !nsMatch || nsMatch[1] !== account || nsMatch[2] !== gateway) continue;\n pins[workspace] = ref.pin;\n }\n return pins;\n}\n\nexport interface WorkspaceDiff {\n /** files that must be uploaded (new or changed) */\n upload: DistFile[];\n /** number of files skipped because the previous manifest holds identical bytes */\n skipped: number;\n}\n\nexport function diffWorkspaceFiles(\n files: DistFile[],\n localSri: Record<string, string>,\n prevFiles: Record<string, string>,\n): WorkspaceDiff {\n const upload: DistFile[] = [];\n let skipped = 0;\n for (const file of files) {\n if (prevFiles[file.path] !== undefined && prevFiles[file.path] === localSri[file.path]) {\n skipped += 1;\n continue;\n }\n upload.push(file);\n }\n return { upload, skipped };\n}\n\n/**\n * The manifest's merged per-file map for this deploy: uploaded files carry the\n * server-computed SRI from the upload response; skipped files carry the\n * previous manifest's server-computed SRI (byte-identical to the local hash by\n * the skip decision). Files that left the dist carry nothing.\n */\nexport function mergedFileIntegrity(\n files: DistFile[],\n uploadedIntegrity: Record<string, string>,\n prevFiles: Record<string, string> | undefined,\n): Record<string, string> {\n const merged: Record<string, string> = {};\n for (const file of files) {\n const uploaded = uploadedIntegrity[file.path];\n if (uploaded) {\n merged[file.path] = uploaded;\n continue;\n }\n const carried = prevFiles?.[file.path];\n if (carried) merged[file.path] = carried;\n }\n return merged;\n}\n"],"mappings":";;;;;;AAiCA,MAAa,sBAAsB;AAEnC,SAAgB,mBAAmB,MAA6B;CAC9D,MAAM,QAAQ,oBAAoB,KAAK,GAAG,KAAK,QAAQ,OAAO,EAAE,EAAE,EAAE;CACpE,OAAO,QAAQ,MAAM,KAAM;AAC7B;;AAGA,SAAgB,qBAAqB,OAA2B;CAC9D,OAAO,UAAU,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,QAAQ;AACrE;AAEA,SAAgB,YAAY,OAA2C;CACrE,OAAO,OAAO,YAAY,MAAM,KAAK,SAAS,CAAC,KAAK,MAAM,qBAAqB,KAAK,KAAK,CAAC,CAAC,CAAC;AAC9F;AAEA,MAAM,mBAAmB,cAAsB,KAAK,WAAW,QAAQ,mBAAmB;AAE1F,SAAgB,gBAAgB,WAAoC;CAClE,MAAM,OAAO,gBAAgB,SAAS;CACtC,IAAI,CAAC,WAAW,IAAI,GAAG,OAAO;EAAE,SAAS;EAAG,MAAM,CAAC;CAAE;CACrD,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC;EACpD,IAAI,OAAO,YAAY,KAAK,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS,MAC7E,OAAO;GAAE,SAAS;GAAG,MAAM,CAAC;EAAE;EAEhC,OAAO;GAAE,SAAS;GAAG,MAAM,OAAO;EAAgC;CACpE,QAAQ;EACN,OAAO;GAAE,SAAS;GAAG,MAAM,CAAC;EAAE;CAChC;AACF;AAEA,SAAgB,iBAAiB,WAAmB,OAA8B;CAChF,MAAM,OAAO,gBAAgB,SAAS;CACtC,UAAU,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;CAC5C,cAAc,MAAM,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,GAAG;AAC3D;AAEA,SAAgB,sBACd,WACA,SACA,SACA,MACM;CACN,MAAM,QAAQ,gBAAgB,SAAS;CACvC,MAAM,SAAS,GAAG,QAAQ,GAAG;CAC7B,MAAM,KAAK,UAAU;EAAE,GAAG,MAAM,KAAK;EAAS,GAAG;CAAK;CACtD,iBAAiB,WAAW,KAAK;AACnC;;AAGA,SAAgB,oBACd,WACA,SACA,SAC6B;CAC7B,OAAO,gBAAgB,SAAS,CAAC,CAAC,KAAK,GAAG,QAAQ,GAAG,cAAc,CAAC;AACtE;;AAGA,SAAgB,wBACd,QACA,SACA,SAC6B;CAC7B,MAAM,OAAoC,CAAC;CAC3C,KAAK,MAAM,OAAO,mBAAmB,MAAM,GAAG;EAC5C,MAAM,YAAY,mBAAmB,IAAI,IAAI;EAC7C,MAAM,UAAU,oBAAoB,KAAK,GAAG,IAAI,KAAK,QAAQ,OAAO,EAAE,EAAE,EAAE;EAC1E,IAAI,CAAC,aAAa,CAAC,WAAW,QAAQ,OAAO,WAAW,QAAQ,OAAO,SAAS;EAChF,KAAK,aAAa,IAAI;CACxB;CACA,OAAO;AACT;AASA,SAAgB,mBACd,OACA,UACA,WACe;CACf,MAAM,SAAqB,CAAC;CAC5B,IAAI,UAAU;CACd,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,UAAU,KAAK,UAAU,UAAa,UAAU,KAAK,UAAU,SAAS,KAAK,OAAO;GACtF,WAAW;GACX;EACF;EACA,OAAO,KAAK,IAAI;CAClB;CACA,OAAO;EAAE;EAAQ;CAAQ;AAC3B;;;;;;;AAQA,SAAgB,oBACd,OACA,mBACA,WACwB;CACxB,MAAM,SAAiC,CAAC;CACxC,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,WAAW,kBAAkB,KAAK;EACxC,IAAI,UAAU;GACZ,OAAO,KAAK,QAAQ;GACpB;EACF;EACA,MAAM,UAAU,YAAY,KAAK;EACjC,IAAI,SAAS,OAAO,KAAK,QAAQ;CACnC;CACA,OAAO;AACT"}
|
package/dist/dev-program.cjs
CHANGED
|
@@ -3,11 +3,12 @@ const require_service_descriptor = require('./service-descriptor.cjs');
|
|
|
3
3
|
const require_types = require('./types.cjs');
|
|
4
4
|
const require_fastkv = require('./fastkv.cjs');
|
|
5
5
|
const require_config = require('./config.cjs');
|
|
6
|
+
const require_run = require('./utils/run.cjs');
|
|
6
7
|
const require_start_config_source = require('./start-config-source.cjs');
|
|
7
8
|
const require_dev_log_pipeline = require('./dev-log-pipeline.cjs');
|
|
8
9
|
const require_docker = require('./infra/docker.cjs');
|
|
9
10
|
const require_resolution_session = require('./resolution/session.cjs');
|
|
10
|
-
const
|
|
11
|
+
const require_driver = require('./db/driver.cjs');
|
|
11
12
|
const require_workspace = require('./workspace.cjs');
|
|
12
13
|
const require_shared_deps = require('./shared-deps.cjs');
|
|
13
14
|
const require_code_artifacts = require('./code-artifacts.cjs');
|
|
@@ -172,7 +173,7 @@ const devBootstrap = (deps, input, timings) => effect.Effect.gen(function* () {
|
|
|
172
173
|
});
|
|
173
174
|
yield* ensureEnvStep(projectEnv, session.root);
|
|
174
175
|
yield* loadEnvStep(projectEnv, session.root);
|
|
175
|
-
yield* projectEnv.sync(session.root, plan.envGenerated, shell).pipe(effect.Effect.catchTag("EnvSyncError", (error) => effect.Effect.logWarning(`[env] failed to refresh .env from resolved ports: ${error.cause}`)));
|
|
176
|
+
yield* projectEnv.sync(session.root, plan.envGenerated, shell).pipe(effect.Effect.catchTag("EnvSyncError", (error) => effect.Effect.logWarning(`[env] failed to refresh .env from resolved ports: ${String(error.cause)}`)));
|
|
176
177
|
const mergedEnv = yield* effect.Effect.sync(() => require_orchestrator.mergeGeneratedOverFileEnv(plan.envGenerated, require_process_env.processEnvRecord(), shell));
|
|
177
178
|
yield* effect.Effect.sync(() => {
|
|
178
179
|
for (const [key, value] of Object.entries(mergedEnv)) if (key === "BASE_URL" || key === "CORS_ORIGIN") require_process_env.setProcessEnv(key, value);
|
|
@@ -330,6 +331,13 @@ const startBootstrap = (deps, input) => effect.Effect.gen(function* () {
|
|
|
330
331
|
if (!value || value.length === 0) missingSecrets.push(secret);
|
|
331
332
|
}
|
|
332
333
|
if (missingSecrets.length > 0) warnings.push(`Missing ${missingSecrets.length} secret(s): ${missingSecrets.join(", ")}`);
|
|
334
|
+
for (const [secret, value] of Object.entries(require_process_env.processEnvRecord())) {
|
|
335
|
+
if (!value || !secret.endsWith("_DATABASE_URL")) continue;
|
|
336
|
+
if (require_driver.isRailwayPublicProxyUrl(value)) {
|
|
337
|
+
const host = new URL(value).hostname;
|
|
338
|
+
warnings.push(`${secret} points at Railway's public proxy (${host}) — its TLS certificate is self-signed, so connections use unverified TLS. Prefer the private *.railway.internal URL when the database runs in the same Railway project.`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
333
341
|
const stagingEnvVars = isStaging ? { BOS_GATEWAY: baseConfig.staging?.domain ?? baseConfig.domain ?? "" } : {};
|
|
334
342
|
const plan = yield* require_planner.planInfra({
|
|
335
343
|
configDir: sessionRoot,
|
|
@@ -401,5 +409,6 @@ exports.StartRemoteConfigMissing = StartRemoteConfigMissing;
|
|
|
401
409
|
exports.bootstrapLayers = bootstrapLayers;
|
|
402
410
|
exports.devBootstrap = devBootstrap;
|
|
403
411
|
exports.resolveProxyUrl = resolveProxyUrl;
|
|
412
|
+
exports.resolvePublishedConfig = resolvePublishedConfig;
|
|
404
413
|
exports.startBootstrap = startBootstrap;
|
|
405
414
|
//# sourceMappingURL=dev-program.cjs.map
|
package/dist/dev-program.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-program.cjs","names":["Data","walkExtendsChain","resolveConfigComposableEntries","BosConfigSchema","timedPhase","Effect","captureShellEnv","ProjectEnv","detectLocalPackages","syncResolvedSharedDeps","run","findWorkspaceRoot","ensureFreshDeps","openResolution","planInfra","materializeViaLayer","mergeGeneratedOverFileEnv","processEnvRecord","preflightLocalInfra","shouldAutoStartDocker","detectAutoStartContext","isDockerAvailable","runDockerComposeUp","buildServiceDescriptorMapFromPlan","isDebug","getProcessEnv","generateCodeArtifacts","buildDescription","emitProgress","resolveStartConfigSource","buildRegistryConfigUrl","getHostDevelopmentPort","buildRuntimePluginsForConfig","buildRuntimeConfig","isRegistryStart","buildServiceDescriptorMap","findConfigPath","Layer","ProjectEnvLive","PortAllocatorLive"],"sources":["../src/dev-program.ts"],"sourcesContent":["import { Data, Effect, Layer } from \"effect\";\nimport { detectLocalPackages, PortAllocatorLive } from \"./app\";\nimport { generateCodeArtifacts } from \"./code-artifacts\";\nimport {\n buildRuntimeConfig,\n buildRuntimePluginsForConfig,\n findConfigPath,\n getHostDevelopmentPort,\n resolveConfigComposableEntries,\n} from \"./config\";\nimport type { DevOptions, PhaseTiming, StartOptions } from \"./contract\";\nimport { isDebug } from \"./dev-log-pipeline\";\nimport type { DevSessionData, StartSummary } from \"./dev-session-data\";\nimport {\n deleteProcessEnv,\n getProcessEnv,\n processEnvRecord,\n setProcessEnv,\n} from \"./env/process-env\";\nimport {\n captureShellEnv,\n type EnvEnsureError,\n type EnvLoadError,\n ProjectEnv,\n ProjectEnvLive,\n type ProjectEnvService,\n} from \"./env/project-env\";\nimport { buildRegistryConfigUrl } from \"./fastkv\";\nimport {\n detectAutoStartContext,\n isDockerAvailable,\n runDockerComposeUp,\n shouldAutoStartDocker,\n} from \"./infra/docker\";\nimport { materializeViaLayer } from \"./infra/materializer\";\nimport { planInfra } from \"./infra/planner\";\nimport { preflightLocalInfra } from \"./infra/preflight\";\nimport type { InfraPlan } from \"./infra/types\";\nimport { mergeGeneratedOverFileEnv } from \"./orchestrator\";\nimport { emitProgress, timedPhase } from \"./progress\";\nimport { openResolution, type ResolutionSession, walkExtendsChain } from \"./resolution/session\";\nimport {\n type AppOrchestrator,\n buildDescription,\n buildServiceDescriptorMap,\n buildServiceDescriptorMapFromPlan,\n} from \"./service-descriptor\";\nimport { syncResolvedSharedDeps } from \"./shared-deps\";\nimport { isRegistryStart, resolveStartConfigSource } from \"./start-config-source\";\nimport type { BosConfig, SourceMode } from \"./types\";\nimport { BosConfigSchema } from \"./types\";\nimport { run } from \"./utils/run\";\nimport { ensureFreshDeps, findWorkspaceRoot } from \"./workspace\";\n\nexport type { DevSessionData, StartSummary } from \"./dev-session-data\";\n\nexport interface BootstrapDeps {\n readonly session: ResolutionSession | null;\n}\n\nexport class DevStepError extends Data.TaggedError(\"DevStepError\")<{\n phase: string;\n cause: unknown;\n}> {}\n\nexport class DevConfigMissing extends Data.TaggedError(\"DevConfigMissing\")<Record<string, never>> {}\n\nexport class DevProxyMissing extends Data.TaggedError(\"DevProxyMissing\")<Record<string, never>> {}\n\nexport class DevPreflightFailed extends Data.TaggedError(\"DevPreflightFailed\")<{\n messages: string[];\n}> {}\n\nexport class StartFetchFailed extends Data.TaggedError(\"StartFetchFailed\")<{ message: string }> {}\n\nexport class StartRemoteConfigMissing extends Data.TaggedError(\"StartRemoteConfigMissing\")<{\n message: string;\n}> {}\n\nexport class StartConfigMissing extends Data.TaggedError(\"StartConfigMissing\")<\n Record<string, never>\n> {}\n\nfunction parseSourceMode(value: string | undefined, defaultValue: SourceMode): SourceMode {\n if (value === \"local\" || value === \"remote\") return value;\n return defaultValue;\n}\n\nasync function resolvePublishedConfig(\n account: string,\n gateway: string,\n registry?: string,\n): Promise<BosConfig | null> {\n try {\n const { config: merged } = await walkExtendsChain(`bos://${account}/${gateway}`, {\n env: \"production\",\n registry,\n visit: async () => {},\n });\n return resolveConfigComposableEntries(\n BosConfigSchema.parse(merged),\n process.cwd(),\n \"production\",\n );\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"No config found\")) {\n return null;\n }\n throw error;\n }\n}\n\nfunction isValidProxyUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nexport function resolveProxyUrl(bosConfig: BosConfig | null): string | null {\n if (!bosConfig) return null;\n const apiConfig = bosConfig.app.api;\n if (!apiConfig) return null;\n if (apiConfig.proxy && isValidProxyUrl(apiConfig.proxy)) return apiConfig.proxy;\n if (apiConfig.production && isValidProxyUrl(apiConfig.production)) return apiConfig.production;\n return null;\n}\n\nconst step = <A>(timings: PhaseTiming[], name: string, fn: () => Promise<A>) =>\n timedPhase(\n timings,\n name,\n Effect.tryPromise({\n try: fn,\n catch: (cause) => new DevStepError({ phase: name, cause }),\n }),\n );\n\nconst ensureEnvStep = (projectEnv: ProjectEnvService, configDir: string) =>\n projectEnv\n .ensureFile(configDir)\n .pipe(\n Effect.mapError((cause: EnvEnsureError) => new DevStepError({ phase: \"ensure env\", cause })),\n );\n\nconst loadEnvStep = (projectEnv: ProjectEnvService, configDir: string) =>\n projectEnv\n .load(configDir)\n .pipe(Effect.mapError((cause: EnvLoadError) => new DevStepError({ phase: \"load env\", cause })));\n\nexport const devBootstrap = (deps: BootstrapDeps, input: DevOptions, timings: PhaseTiming[]) =>\n Effect.gen(function* () {\n const shell = yield* captureShellEnv;\n const projectEnv = yield* ProjectEnv;\n\n if (!deps.session) {\n return yield* new DevConfigMissing({});\n }\n let session: ResolutionSession = deps.session;\n\n yield* ensureEnvStep(projectEnv, session.root);\n yield* loadEnvStep(projectEnv, session.root);\n\n const localPackages = detectLocalPackages(\n session.config ?? undefined,\n session.runtime ?? undefined,\n session.root,\n );\n const localPackageNames = new Set(localPackages.map((entry) => entry.name));\n const localDirs = localPackages.map((entry) => entry.dir);\n\n const hostSource: SourceMode = localPackageNames.has(\"host\")\n ? parseSourceMode(input.host, \"local\")\n : \"remote\";\n const uiSource: SourceMode = localPackageNames.has(\"ui\")\n ? parseSourceMode(input.ui, \"local\")\n : \"remote\";\n const apiSource: SourceMode = localPackageNames.has(\"api\")\n ? parseSourceMode(input.api, \"local\")\n : \"remote\";\n const authSource: SourceMode = localPackageNames.has(\"auth\")\n ? parseSourceMode(input.auth, \"local\")\n : \"remote\";\n const ssr = input.ssr ?? false;\n const proxy = input.proxy ?? false;\n\n if (input.logLevel) {\n yield* Effect.sync(() => {\n setProcessEnv(\"BOS_LOG_LEVEL\", input.logLevel!);\n });\n }\n\n if (ssr) {\n yield* Effect.sync(() => {\n setProcessEnv(\"BOS_SSR\", \"1\");\n });\n }\n\n const sharedSync = yield* step(timings, \"shared deps\", () =>\n syncResolvedSharedDeps({\n configDir: session.root,\n hostMode: hostSource,\n bosConfig: session.config ?? undefined,\n extendsChain: [],\n }),\n );\n let configMayHaveChanged = false;\n if (sharedSync.catalogChanged) {\n yield* step(timings, \"install\", () =>\n run(\"pnpm\", [\"install\"], { cwd: findWorkspaceRoot(session.root)?.dir ?? session.root }),\n );\n configMayHaveChanged = true;\n }\n\n yield* step(timings, \"build\", async () => {\n const report = await ensureFreshDeps(session.root, localDirs);\n if (report.rebuilt.some((member) => member.name === \"everything-dev\")) {\n // Only the bos process itself runs the everything-dev dist (plugin\n // children spawn after this step and load the fresh build). A source\n // run (node --import tsx src/cli.ts) never imported dist, so nothing\n // is stale for it — warn only where the previously imported build\n // matters.\n const runningFromDist = import.meta.url.includes(\"/dist/\");\n if (runningFromDist) {\n console.log(\n \"[dev] everything-dev was rebuilt — this session still runs the previous \" +\n \"orchestrator build. Restart `bos dev` once to pick it up.\",\n );\n }\n }\n });\n\n let devExtendsChain: string[] | undefined;\n if (configMayHaveChanged || input.remotePlugins !== undefined) {\n yield* step(timings, \"resolve config\", async () => {\n const opened = await openResolution({\n cwd: session.root,\n remotePlugins: input.remotePlugins,\n });\n if (opened) {\n session = opened;\n devExtendsChain = [...opened.chain];\n }\n });\n }\n\n if (!session.config) {\n return yield* new DevConfigMissing({});\n }\n const bosConfig: BosConfig = session.config;\n\n if (proxy && !resolveProxyUrl(bosConfig)) {\n return yield* new DevProxyMissing({});\n }\n\n const developmentRuntime = yield* Effect.tryPromise({\n try: async () => {\n return session.buildRuntime({\n uiSource,\n apiSource,\n authSource,\n hostSource,\n env: \"development\",\n plugins: session.runtime?.plugins,\n });\n },\n catch: (cause) => new DevStepError({ phase: \"build runtime config\", cause }),\n });\n for (const message of session.warnings) {\n yield* Effect.logWarning(message);\n }\n\n const plan: InfraPlan = yield* timedPhase(\n timings,\n \"ports\",\n planInfra({\n configDir: session.root,\n bosConfig: developmentRuntime,\n cli: {\n port: input.port,\n apiPort: input.apiPort,\n authPort: input.authPort,\n uiPort: input.uiPort,\n pluginPortStart: input.pluginPortStart,\n ssr,\n proxy,\n hostSource,\n uiSource,\n apiSource,\n authSource,\n interactive: input.interactive,\n },\n }),\n );\n\n yield* Effect.tryPromise({\n try: () => materializeViaLayer(session.root, plan.runtimeConfig),\n catch: (cause) => new DevStepError({ phase: \"materialize infra\", cause }),\n });\n yield* ensureEnvStep(projectEnv, session.root);\n yield* loadEnvStep(projectEnv, session.root);\n\n yield* projectEnv\n .sync(session.root, plan.envGenerated, shell)\n .pipe(\n Effect.catchTag(\"EnvSyncError\", (error) =>\n Effect.logWarning(`[env] failed to refresh .env from resolved ports: ${error.cause}`),\n ),\n );\n\n const mergedEnv = yield* Effect.sync(() =>\n mergeGeneratedOverFileEnv(\n plan.envGenerated,\n processEnvRecord() as Record<string, string>,\n shell,\n ),\n );\n yield* Effect.sync(() => {\n for (const [key, value] of Object.entries(mergedEnv)) {\n if (key === \"BASE_URL\" || key === \"CORS_ORIGIN\") setProcessEnv(key, value);\n }\n });\n let preflightFailures = yield* preflightLocalInfra(plan.envGenerated, mergedEnv);\n if (\n preflightFailures.length > 0 &&\n shouldAutoStartDocker(preflightFailures, {\n ...detectAutoStartContext(session.root),\n dockerAvailable: yield* Effect.promise(isDockerAvailable),\n })\n ) {\n const compose = yield* step(timings, \"docker compose up\", () =>\n runDockerComposeUp(session.root),\n );\n if (compose.ok) {\n preflightFailures = yield* preflightLocalInfra(plan.envGenerated, mergedEnv);\n } else {\n preflightFailures = [\n ...preflightFailures,\n {\n secret: \"docker-compose\",\n host: \"localhost\",\n port: 0,\n error: `docker compose up -d --wait failed${compose.tail ? `:\\n${compose.tail}` : \"\"}`,\n tcpReachable: false,\n },\n ];\n }\n }\n if (preflightFailures.length > 0) {\n return yield* new DevPreflightFailed({ messages: preflightFailures.map((f) => f.error) });\n }\n\n const services = buildServiceDescriptorMapFromPlan(plan, { ssr, proxy });\n\n const packages = [...plan.serviceDescriptors.keys()];\n if (isDebug(getProcessEnv(\"DEBUG\"))) {\n yield* Effect.logError(`[DEBUG dev] services keys: ${packages.join(\", \")}`);\n }\n const apiSvc = services.get(\"api\");\n if (apiSvc?.proxy) {\n const proxyUrl = resolveProxyUrl(bosConfig);\n if (proxyUrl) plan.orchestrator.env.API_PROXY = proxyUrl;\n }\n\n yield* step(timings, \"generate artifacts\", () =>\n generateCodeArtifacts(session.root, bosConfig, {\n env: \"development\",\n extendsChain: devExtendsChain,\n runtimeConfig: plan.runtimeConfig,\n }),\n );\n\n return {\n session: {\n orchestrator: plan.orchestrator,\n services,\n runtimeConfig: plan.runtimeConfig,\n envGenerated: plan.envGenerated,\n shellEnv: shell,\n } satisfies DevSessionData,\n description: buildDescription(services) || plan.description,\n processes: packages,\n };\n });\n\nexport const startBootstrap = (deps: BootstrapDeps, input: StartOptions) =>\n Effect.gen(function* () {\n const shell = yield* captureShellEnv;\n const projectEnv = yield* ProjectEnv;\n\n const sessionRoot = deps.session?.root ?? process.cwd();\n\n yield* loadEnvStep(projectEnv, sessionRoot);\n\n yield* emitProgress({ phase: \"config\", status: \"running\" });\n\n const bosEnv = input.env ?? (getProcessEnv(\"BOS_ENV\") === \"staging\" ? \"staging\" : \"production\");\n const explicitConfig = resolveStartConfigSource(input, {\n BOS_ACCOUNT: getProcessEnv(\"BOS_ACCOUNT\"),\n BOS_GATEWAY: getProcessEnv(\"BOS_GATEWAY\"),\n });\n\n let config: BosConfig | null = null;\n let remoteConfig: BosConfig | null = null;\n\n if (explicitConfig.configPath) {\n config = deps.session?.config ?? null;\n } else if (explicitConfig.registry) {\n const { account, domain } = explicitConfig.registry;\n const expectedUrl = buildRegistryConfigUrl(account, domain, input.registry);\n remoteConfig = yield* Effect.tryPromise({\n try: () => resolvePublishedConfig(account, domain, input.registry),\n catch: (error) =>\n new StartFetchFailed({\n message: `Failed to fetch config for bos://${account}/${domain}: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }\\nExpected URL: ${expectedUrl}`,\n }),\n });\n if (remoteConfig) {\n config = remoteConfig;\n } else {\n return yield* new StartRemoteConfigMissing({\n message: `No config found at bos://${account}/${domain}. Verify the account and gateway are correct and the config has been published.\\nExpected URL: ${expectedUrl}`,\n });\n }\n } else {\n config = deps.session?.config ?? null;\n }\n\n if (!config) {\n return yield* new StartConfigMissing({});\n }\n\n if (!explicitConfig.configPath) {\n if (explicitConfig.registry?.account) {\n config = { ...config, account: explicitConfig.registry.account };\n }\n if (explicitConfig.registry?.domain) {\n config = { ...config, domain: explicitConfig.registry.domain };\n }\n }\n const baseConfig: BosConfig = config;\n\n const port = input.port ?? getHostDevelopmentPort(baseConfig.app.host.development);\n const isStaging = bosEnv === \"staging\";\n const runtimePlugins = yield* Effect.tryPromise({\n try: () => buildRuntimePluginsForConfig(baseConfig, sessionRoot, \"production\"),\n catch: (cause) => new DevStepError({ phase: \"resolve runtime plugins\", cause }),\n });\n const runtimeConfig = yield* Effect.tryPromise({\n try: () =>\n buildRuntimeConfig(baseConfig, sessionRoot, \"production\", {\n uiSource: \"remote\",\n apiSource: \"remote\",\n authSource: \"remote\",\n hostSource: \"remote\",\n plugins: runtimePlugins,\n }),\n catch: (cause) => new DevStepError({ phase: \"build runtime config\", cause }),\n });\n\n if (isStaging && baseConfig.staging?.domain) {\n runtimeConfig.domain = baseConfig.staging.domain;\n }\n\n if (isStaging) {\n runtimeConfig.env = \"staging\";\n }\n\n yield* emitProgress({ phase: \"generate artifacts\", status: \"running\" });\n yield* Effect.tryPromise({\n try: () =>\n generateCodeArtifacts(sessionRoot, baseConfig, {\n env: \"production\",\n runtimeConfig,\n }),\n catch: (cause) => new DevStepError({ phase: \"generate artifacts\", cause }),\n });\n yield* emitProgress({ phase: \"generate artifacts\", status: \"done\" });\n\n const productionEnv: Record<string, string> = {};\n const warnings: string[] = [];\n\n const localhostOrigin = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/i;\n const corsOrigin = getProcessEnv(\"CORS_ORIGIN\");\n const isLocalhostProductionOrigin =\n corsOrigin !== undefined && localhostOrigin.test(corsOrigin);\n if (isLocalhostProductionOrigin && isRegistryStart(explicitConfig)) {\n warnings.push(\n `CORS_ORIGIN is a localhost origin (${corsOrigin}) in a registry production start — overriding with the configured domain`,\n );\n deleteProcessEnv(\"CORS_ORIGIN\");\n deleteProcessEnv(\"BASE_URL\");\n }\n\n if (!getProcessEnv(\"CORS_ORIGIN\") && baseConfig.domain) {\n const effectiveDomain = isStaging\n ? (baseConfig.staging?.domain ?? baseConfig.domain)\n : baseConfig.domain;\n const defaultOrigin = `https://${effectiveDomain}`;\n productionEnv.CORS_ORIGIN = defaultOrigin;\n productionEnv.BASE_URL = defaultOrigin;\n warnings.push(`CORS_ORIGIN defaulting to ${defaultOrigin}`);\n }\n\n const requiredSecrets = new Set<string>();\n const missingSecrets: string[] = [];\n\n if (runtimeConfig.host.secrets) {\n for (const s of runtimeConfig.host.secrets) requiredSecrets.add(s);\n }\n if (runtimeConfig.auth?.secrets) {\n for (const s of runtimeConfig.auth.secrets) requiredSecrets.add(s);\n }\n if (runtimeConfig.api?.secrets) {\n for (const s of runtimeConfig.api.secrets) requiredSecrets.add(s);\n }\n for (const plugin of Object.values(runtimeConfig.plugins ?? {})) {\n if (plugin.secrets) {\n for (const s of plugin.secrets) {\n if (s.endsWith(\"_DATABASE_URL\")) continue;\n requiredSecrets.add(s);\n }\n }\n }\n\n for (const secret of requiredSecrets) {\n const value = getProcessEnv(secret);\n if (!value || value.length === 0) {\n missingSecrets.push(secret);\n }\n }\n\n if (missingSecrets.length > 0) {\n warnings.push(`Missing ${missingSecrets.length} secret(s): ${missingSecrets.join(\", \")}`);\n }\n\n const stagingEnvVars: Record<string, string> = isStaging\n ? { BOS_GATEWAY: baseConfig.staging?.domain ?? baseConfig.domain ?? \"\" }\n : {};\n\n const plan: InfraPlan = yield* planInfra({\n configDir: sessionRoot,\n bosConfig: runtimeConfig,\n cli: {\n port: input.port,\n ssr: false,\n proxy: false,\n hostSource: \"remote\",\n uiSource: \"remote\",\n apiSource: \"remote\",\n authSource: \"remote\",\n interactive: input.interactive,\n },\n });\n\n const services = buildServiceDescriptorMap(plan.runtimeConfig);\n\n const configSource = explicitConfig.configPath\n ? explicitConfig.configPath\n : remoteConfig\n ? `bos://${explicitConfig.registry?.account}/${explicitConfig.registry?.domain}`\n : (findConfigPath() ?? \"bos.config.json\");\n\n const configSourceHttp =\n remoteConfig && explicitConfig.registry\n ? buildRegistryConfigUrl(\n explicitConfig.registry.account,\n explicitConfig.registry.domain,\n input.registry,\n )\n : undefined;\n\n const summary: StartSummary = {\n configSource,\n configSourceHttp,\n account: baseConfig.account,\n domain: baseConfig.domain ?? undefined,\n modules: {\n host: plan.runtimeConfig.host.remoteUrl ?? plan.runtimeConfig.host.url ?? \"local\",\n ui: plan.runtimeConfig.ui.url ?? \"local\",\n api: plan.runtimeConfig.api.url ?? \"local\",\n auth: plan.runtimeConfig.auth?.url ?? undefined,\n },\n warnings,\n };\n\n const orchestrator: AppOrchestrator = {\n packages: [\"host\"],\n env: {\n NODE_ENV: \"production\",\n ...productionEnv,\n ...stagingEnvVars,\n ...plan.launch.env,\n },\n description: `${isStaging ? \"Staging\" : \"Production\"} Mode (${baseConfig.account})`,\n port: plan.resolvedPorts.host ?? port,\n interactive: input.interactive,\n noLogs: true,\n };\n\n yield* emitProgress({ phase: \"config\", status: \"done\" });\n\n return {\n session: {\n orchestrator,\n services,\n runtimeConfig: plan.runtimeConfig,\n envGenerated: plan.envGenerated,\n shellEnv: shell,\n } satisfies DevSessionData,\n summary,\n url: plan.launch.hostUrl ?? `http://localhost:${plan.resolvedPorts.host ?? port}`,\n };\n });\n\nexport const bootstrapLayers = Layer.mergeAll(ProjectEnvLive, PortAllocatorLive);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dev-program.cjs","names":["Data","walkExtendsChain","resolveConfigComposableEntries","BosConfigSchema","timedPhase","Effect","captureShellEnv","ProjectEnv","detectLocalPackages","syncResolvedSharedDeps","run","findWorkspaceRoot","ensureFreshDeps","openResolution","planInfra","materializeViaLayer","mergeGeneratedOverFileEnv","processEnvRecord","preflightLocalInfra","shouldAutoStartDocker","detectAutoStartContext","isDockerAvailable","runDockerComposeUp","buildServiceDescriptorMapFromPlan","isDebug","getProcessEnv","generateCodeArtifacts","buildDescription","emitProgress","resolveStartConfigSource","buildRegistryConfigUrl","getHostDevelopmentPort","buildRuntimePluginsForConfig","buildRuntimeConfig","isRegistryStart","isRailwayPublicProxyUrl","buildServiceDescriptorMap","findConfigPath","Layer","ProjectEnvLive","PortAllocatorLive"],"sources":["../src/dev-program.ts"],"sourcesContent":["import { Data, Effect, Layer } from \"effect\";\nimport { detectLocalPackages, PortAllocatorLive } from \"./app\";\nimport { generateCodeArtifacts } from \"./code-artifacts\";\nimport {\n buildRuntimeConfig,\n buildRuntimePluginsForConfig,\n findConfigPath,\n getHostDevelopmentPort,\n resolveConfigComposableEntries,\n} from \"./config\";\nimport type { DevOptions, PhaseTiming, StartOptions } from \"./contract\";\nimport { isRailwayPublicProxyUrl } from \"./db/driver\";\nimport { isDebug } from \"./dev-log-pipeline\";\nimport type { DevSessionData, StartSummary } from \"./dev-session-data\";\nimport {\n deleteProcessEnv,\n getProcessEnv,\n processEnvRecord,\n setProcessEnv,\n} from \"./env/process-env\";\nimport {\n captureShellEnv,\n type EnvEnsureError,\n type EnvLoadError,\n ProjectEnv,\n ProjectEnvLive,\n type ProjectEnvService,\n} from \"./env/project-env\";\nimport { buildRegistryConfigUrl } from \"./fastkv\";\nimport {\n detectAutoStartContext,\n isDockerAvailable,\n runDockerComposeUp,\n shouldAutoStartDocker,\n} from \"./infra/docker\";\nimport { materializeViaLayer } from \"./infra/materializer\";\nimport { planInfra } from \"./infra/planner\";\nimport { preflightLocalInfra } from \"./infra/preflight\";\nimport type { InfraPlan } from \"./infra/types\";\nimport { mergeGeneratedOverFileEnv } from \"./orchestrator\";\nimport { emitProgress, timedPhase } from \"./progress\";\nimport { openResolution, type ResolutionSession, walkExtendsChain } from \"./resolution/session\";\nimport {\n type AppOrchestrator,\n buildDescription,\n buildServiceDescriptorMap,\n buildServiceDescriptorMapFromPlan,\n} from \"./service-descriptor\";\nimport { syncResolvedSharedDeps } from \"./shared-deps\";\nimport { isRegistryStart, resolveStartConfigSource } from \"./start-config-source\";\nimport type { BosConfig, SourceMode } from \"./types\";\nimport { BosConfigSchema } from \"./types\";\nimport { run } from \"./utils/run\";\nimport { ensureFreshDeps, findWorkspaceRoot } from \"./workspace\";\n\nexport type { DevSessionData, StartSummary } from \"./dev-session-data\";\n\nexport interface BootstrapDeps {\n readonly session: ResolutionSession | null;\n}\n\nexport class DevStepError extends Data.TaggedError(\"DevStepError\")<{\n phase: string;\n cause: unknown;\n}> {}\n\nexport class DevConfigMissing extends Data.TaggedError(\"DevConfigMissing\")<Record<string, never>> {}\n\nexport class DevProxyMissing extends Data.TaggedError(\"DevProxyMissing\")<Record<string, never>> {}\n\nexport class DevPreflightFailed extends Data.TaggedError(\"DevPreflightFailed\")<{\n messages: string[];\n}> {}\n\nexport class StartFetchFailed extends Data.TaggedError(\"StartFetchFailed\")<{ message: string }> {}\n\nexport class StartRemoteConfigMissing extends Data.TaggedError(\"StartRemoteConfigMissing\")<{\n message: string;\n}> {}\n\nexport class StartConfigMissing extends Data.TaggedError(\"StartConfigMissing\")<\n Record<string, never>\n> {}\n\nfunction parseSourceMode(value: string | undefined, defaultValue: SourceMode): SourceMode {\n if (value === \"local\" || value === \"remote\") return value;\n return defaultValue;\n}\n\nexport async function resolvePublishedConfig(\n account: string,\n gateway: string,\n registry?: string,\n): Promise<BosConfig | null> {\n try {\n const { config: merged } = await walkExtendsChain(`bos://${account}/${gateway}`, {\n env: \"production\",\n registry,\n visit: async () => {},\n });\n return resolveConfigComposableEntries(\n BosConfigSchema.parse(merged),\n process.cwd(),\n \"production\",\n );\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"No config found\")) {\n return null;\n }\n throw error;\n }\n}\n\nfunction isValidProxyUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nexport function resolveProxyUrl(bosConfig: BosConfig | null): string | null {\n if (!bosConfig) return null;\n const apiConfig = bosConfig.app.api;\n if (!apiConfig) return null;\n if (apiConfig.proxy && isValidProxyUrl(apiConfig.proxy)) return apiConfig.proxy;\n if (apiConfig.production && isValidProxyUrl(apiConfig.production)) return apiConfig.production;\n return null;\n}\n\nconst step = <A>(timings: PhaseTiming[], name: string, fn: () => Promise<A>) =>\n timedPhase(\n timings,\n name,\n Effect.tryPromise({\n try: fn,\n catch: (cause) => new DevStepError({ phase: name, cause }),\n }),\n );\n\nconst ensureEnvStep = (projectEnv: ProjectEnvService, configDir: string) =>\n projectEnv\n .ensureFile(configDir)\n .pipe(\n Effect.mapError((cause: EnvEnsureError) => new DevStepError({ phase: \"ensure env\", cause })),\n );\n\nconst loadEnvStep = (projectEnv: ProjectEnvService, configDir: string) =>\n projectEnv\n .load(configDir)\n .pipe(Effect.mapError((cause: EnvLoadError) => new DevStepError({ phase: \"load env\", cause })));\n\nexport const devBootstrap = (deps: BootstrapDeps, input: DevOptions, timings: PhaseTiming[]) =>\n Effect.gen(function* () {\n const shell = yield* captureShellEnv;\n const projectEnv = yield* ProjectEnv;\n\n if (!deps.session) {\n return yield* new DevConfigMissing({});\n }\n let session: ResolutionSession = deps.session;\n\n yield* ensureEnvStep(projectEnv, session.root);\n yield* loadEnvStep(projectEnv, session.root);\n\n const localPackages = detectLocalPackages(\n session.config ?? undefined,\n session.runtime ?? undefined,\n session.root,\n );\n const localPackageNames = new Set(localPackages.map((entry) => entry.name));\n const localDirs = localPackages.map((entry) => entry.dir);\n\n const hostSource: SourceMode = localPackageNames.has(\"host\")\n ? parseSourceMode(input.host, \"local\")\n : \"remote\";\n const uiSource: SourceMode = localPackageNames.has(\"ui\")\n ? parseSourceMode(input.ui, \"local\")\n : \"remote\";\n const apiSource: SourceMode = localPackageNames.has(\"api\")\n ? parseSourceMode(input.api, \"local\")\n : \"remote\";\n const authSource: SourceMode = localPackageNames.has(\"auth\")\n ? parseSourceMode(input.auth, \"local\")\n : \"remote\";\n const ssr = input.ssr ?? false;\n const proxy = input.proxy ?? false;\n\n if (input.logLevel) {\n yield* Effect.sync(() => {\n setProcessEnv(\"BOS_LOG_LEVEL\", input.logLevel!);\n });\n }\n\n if (ssr) {\n yield* Effect.sync(() => {\n setProcessEnv(\"BOS_SSR\", \"1\");\n });\n }\n\n const sharedSync = yield* step(timings, \"shared deps\", () =>\n syncResolvedSharedDeps({\n configDir: session.root,\n hostMode: hostSource,\n bosConfig: session.config ?? undefined,\n extendsChain: [],\n }),\n );\n let configMayHaveChanged = false;\n if (sharedSync.catalogChanged) {\n yield* step(timings, \"install\", () =>\n run(\"pnpm\", [\"install\"], { cwd: findWorkspaceRoot(session.root)?.dir ?? session.root }),\n );\n configMayHaveChanged = true;\n }\n\n yield* step(timings, \"build\", async () => {\n const report = await ensureFreshDeps(session.root, localDirs);\n if (report.rebuilt.some((member) => member.name === \"everything-dev\")) {\n // Only the bos process itself runs the everything-dev dist (plugin\n // children spawn after this step and load the fresh build). A source\n // run (node --import tsx src/cli.ts) never imported dist, so nothing\n // is stale for it — warn only where the previously imported build\n // matters.\n const runningFromDist = import.meta.url.includes(\"/dist/\");\n if (runningFromDist) {\n console.log(\n \"[dev] everything-dev was rebuilt — this session still runs the previous \" +\n \"orchestrator build. Restart `bos dev` once to pick it up.\",\n );\n }\n }\n });\n\n let devExtendsChain: string[] | undefined;\n if (configMayHaveChanged || input.remotePlugins !== undefined) {\n yield* step(timings, \"resolve config\", async () => {\n const opened = await openResolution({\n cwd: session.root,\n remotePlugins: input.remotePlugins,\n });\n if (opened) {\n session = opened;\n devExtendsChain = [...opened.chain];\n }\n });\n }\n\n if (!session.config) {\n return yield* new DevConfigMissing({});\n }\n const bosConfig: BosConfig = session.config;\n\n if (proxy && !resolveProxyUrl(bosConfig)) {\n return yield* new DevProxyMissing({});\n }\n\n const developmentRuntime = yield* Effect.tryPromise({\n try: async () => {\n return session.buildRuntime({\n uiSource,\n apiSource,\n authSource,\n hostSource,\n env: \"development\",\n plugins: session.runtime?.plugins,\n });\n },\n catch: (cause) => new DevStepError({ phase: \"build runtime config\", cause }),\n });\n for (const message of session.warnings) {\n yield* Effect.logWarning(message);\n }\n\n const plan: InfraPlan = yield* timedPhase(\n timings,\n \"ports\",\n planInfra({\n configDir: session.root,\n bosConfig: developmentRuntime,\n cli: {\n port: input.port,\n apiPort: input.apiPort,\n authPort: input.authPort,\n uiPort: input.uiPort,\n pluginPortStart: input.pluginPortStart,\n ssr,\n proxy,\n hostSource,\n uiSource,\n apiSource,\n authSource,\n interactive: input.interactive,\n },\n }),\n );\n\n yield* Effect.tryPromise({\n try: () => materializeViaLayer(session.root, plan.runtimeConfig),\n catch: (cause) => new DevStepError({ phase: \"materialize infra\", cause }),\n });\n yield* ensureEnvStep(projectEnv, session.root);\n yield* loadEnvStep(projectEnv, session.root);\n\n yield* projectEnv\n .sync(session.root, plan.envGenerated, shell)\n .pipe(\n Effect.catchTag(\"EnvSyncError\", (error) =>\n Effect.logWarning(\n `[env] failed to refresh .env from resolved ports: ${String(error.cause)}`,\n ),\n ),\n );\n\n const mergedEnv = yield* Effect.sync(() =>\n mergeGeneratedOverFileEnv(\n plan.envGenerated,\n processEnvRecord() as Record<string, string>,\n shell,\n ),\n );\n yield* Effect.sync(() => {\n for (const [key, value] of Object.entries(mergedEnv)) {\n if (key === \"BASE_URL\" || key === \"CORS_ORIGIN\") setProcessEnv(key, value);\n }\n });\n let preflightFailures = yield* preflightLocalInfra(plan.envGenerated, mergedEnv);\n if (\n preflightFailures.length > 0 &&\n shouldAutoStartDocker(preflightFailures, {\n ...detectAutoStartContext(session.root),\n dockerAvailable: yield* Effect.promise(isDockerAvailable),\n })\n ) {\n const compose = yield* step(timings, \"docker compose up\", () =>\n runDockerComposeUp(session.root),\n );\n if (compose.ok) {\n preflightFailures = yield* preflightLocalInfra(plan.envGenerated, mergedEnv);\n } else {\n preflightFailures = [\n ...preflightFailures,\n {\n secret: \"docker-compose\",\n host: \"localhost\",\n port: 0,\n error: `docker compose up -d --wait failed${compose.tail ? `:\\n${compose.tail}` : \"\"}`,\n tcpReachable: false,\n },\n ];\n }\n }\n if (preflightFailures.length > 0) {\n return yield* new DevPreflightFailed({ messages: preflightFailures.map((f) => f.error) });\n }\n\n const services = buildServiceDescriptorMapFromPlan(plan, { ssr, proxy });\n\n const packages = [...plan.serviceDescriptors.keys()];\n if (isDebug(getProcessEnv(\"DEBUG\"))) {\n yield* Effect.logError(`[DEBUG dev] services keys: ${packages.join(\", \")}`);\n }\n const apiSvc = services.get(\"api\");\n if (apiSvc?.proxy) {\n const proxyUrl = resolveProxyUrl(bosConfig);\n if (proxyUrl) plan.orchestrator.env.API_PROXY = proxyUrl;\n }\n\n yield* step(timings, \"generate artifacts\", () =>\n generateCodeArtifacts(session.root, bosConfig, {\n env: \"development\",\n extendsChain: devExtendsChain,\n runtimeConfig: plan.runtimeConfig,\n }),\n );\n\n return {\n session: {\n orchestrator: plan.orchestrator,\n services,\n runtimeConfig: plan.runtimeConfig,\n envGenerated: plan.envGenerated,\n shellEnv: shell,\n } satisfies DevSessionData,\n description: buildDescription(services) || plan.description,\n processes: packages,\n };\n });\n\nexport const startBootstrap = (deps: BootstrapDeps, input: StartOptions) =>\n Effect.gen(function* () {\n const shell = yield* captureShellEnv;\n const projectEnv = yield* ProjectEnv;\n\n const sessionRoot = deps.session?.root ?? process.cwd();\n\n yield* loadEnvStep(projectEnv, sessionRoot);\n\n yield* emitProgress({ phase: \"config\", status: \"running\" });\n\n const bosEnv = input.env ?? (getProcessEnv(\"BOS_ENV\") === \"staging\" ? \"staging\" : \"production\");\n const explicitConfig = resolveStartConfigSource(input, {\n BOS_ACCOUNT: getProcessEnv(\"BOS_ACCOUNT\"),\n BOS_GATEWAY: getProcessEnv(\"BOS_GATEWAY\"),\n });\n\n let config: BosConfig | null = null;\n let remoteConfig: BosConfig | null = null;\n\n if (explicitConfig.configPath) {\n config = deps.session?.config ?? null;\n } else if (explicitConfig.registry) {\n const { account, domain } = explicitConfig.registry;\n const expectedUrl = buildRegistryConfigUrl(account, domain, input.registry);\n remoteConfig = yield* Effect.tryPromise({\n try: () => resolvePublishedConfig(account, domain, input.registry),\n catch: (error) =>\n new StartFetchFailed({\n message: `Failed to fetch config for bos://${account}/${domain}: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }\\nExpected URL: ${expectedUrl}`,\n }),\n });\n if (remoteConfig) {\n config = remoteConfig;\n } else {\n return yield* new StartRemoteConfigMissing({\n message: `No config found at bos://${account}/${domain}. Verify the account and gateway are correct and the config has been published.\\nExpected URL: ${expectedUrl}`,\n });\n }\n } else {\n config = deps.session?.config ?? null;\n }\n\n if (!config) {\n return yield* new StartConfigMissing({});\n }\n\n if (!explicitConfig.configPath) {\n if (explicitConfig.registry?.account) {\n config = { ...config, account: explicitConfig.registry.account };\n }\n if (explicitConfig.registry?.domain) {\n config = { ...config, domain: explicitConfig.registry.domain };\n }\n }\n const baseConfig: BosConfig = config;\n\n const port = input.port ?? getHostDevelopmentPort(baseConfig.app.host.development);\n const isStaging = bosEnv === \"staging\";\n const runtimePlugins = yield* Effect.tryPromise({\n try: () => buildRuntimePluginsForConfig(baseConfig, sessionRoot, \"production\"),\n catch: (cause) => new DevStepError({ phase: \"resolve runtime plugins\", cause }),\n });\n const runtimeConfig = yield* Effect.tryPromise({\n try: () =>\n buildRuntimeConfig(baseConfig, sessionRoot, \"production\", {\n uiSource: \"remote\",\n apiSource: \"remote\",\n authSource: \"remote\",\n hostSource: \"remote\",\n plugins: runtimePlugins,\n }),\n catch: (cause) => new DevStepError({ phase: \"build runtime config\", cause }),\n });\n\n if (isStaging && baseConfig.staging?.domain) {\n runtimeConfig.domain = baseConfig.staging.domain;\n }\n\n if (isStaging) {\n runtimeConfig.env = \"staging\";\n }\n\n yield* emitProgress({ phase: \"generate artifacts\", status: \"running\" });\n yield* Effect.tryPromise({\n try: () =>\n generateCodeArtifacts(sessionRoot, baseConfig, {\n env: \"production\",\n runtimeConfig,\n }),\n catch: (cause) => new DevStepError({ phase: \"generate artifacts\", cause }),\n });\n yield* emitProgress({ phase: \"generate artifacts\", status: \"done\" });\n\n const productionEnv: Record<string, string> = {};\n const warnings: string[] = [];\n\n const localhostOrigin = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/i;\n const corsOrigin = getProcessEnv(\"CORS_ORIGIN\");\n const isLocalhostProductionOrigin =\n corsOrigin !== undefined && localhostOrigin.test(corsOrigin);\n if (isLocalhostProductionOrigin && isRegistryStart(explicitConfig)) {\n warnings.push(\n `CORS_ORIGIN is a localhost origin (${corsOrigin}) in a registry production start — overriding with the configured domain`,\n );\n deleteProcessEnv(\"CORS_ORIGIN\");\n deleteProcessEnv(\"BASE_URL\");\n }\n\n if (!getProcessEnv(\"CORS_ORIGIN\") && baseConfig.domain) {\n const effectiveDomain = isStaging\n ? (baseConfig.staging?.domain ?? baseConfig.domain)\n : baseConfig.domain;\n const defaultOrigin = `https://${effectiveDomain}`;\n productionEnv.CORS_ORIGIN = defaultOrigin;\n productionEnv.BASE_URL = defaultOrigin;\n warnings.push(`CORS_ORIGIN defaulting to ${defaultOrigin}`);\n }\n\n const requiredSecrets = new Set<string>();\n const missingSecrets: string[] = [];\n\n if (runtimeConfig.host.secrets) {\n for (const s of runtimeConfig.host.secrets) requiredSecrets.add(s);\n }\n if (runtimeConfig.auth?.secrets) {\n for (const s of runtimeConfig.auth.secrets) requiredSecrets.add(s);\n }\n if (runtimeConfig.api?.secrets) {\n for (const s of runtimeConfig.api.secrets) requiredSecrets.add(s);\n }\n for (const plugin of Object.values(runtimeConfig.plugins ?? {})) {\n if (plugin.secrets) {\n for (const s of plugin.secrets) {\n if (s.endsWith(\"_DATABASE_URL\")) continue;\n requiredSecrets.add(s);\n }\n }\n }\n\n for (const secret of requiredSecrets) {\n const value = getProcessEnv(secret);\n if (!value || value.length === 0) {\n missingSecrets.push(secret);\n }\n }\n\n if (missingSecrets.length > 0) {\n warnings.push(`Missing ${missingSecrets.length} secret(s): ${missingSecrets.join(\", \")}`);\n }\n\n for (const [secret, value] of Object.entries(processEnvRecord())) {\n if (!value || !secret.endsWith(\"_DATABASE_URL\")) continue;\n if (isRailwayPublicProxyUrl(value)) {\n const host = new URL(value).hostname;\n warnings.push(\n `${secret} points at Railway's public proxy (${host}) — its TLS certificate is self-signed, ` +\n `so connections use unverified TLS. Prefer the private *.railway.internal URL when the ` +\n `database runs in the same Railway project.`,\n );\n }\n }\n\n const stagingEnvVars: Record<string, string> = isStaging\n ? { BOS_GATEWAY: baseConfig.staging?.domain ?? baseConfig.domain ?? \"\" }\n : {};\n\n const plan: InfraPlan = yield* planInfra({\n configDir: sessionRoot,\n bosConfig: runtimeConfig,\n cli: {\n port: input.port,\n ssr: false,\n proxy: false,\n hostSource: \"remote\",\n uiSource: \"remote\",\n apiSource: \"remote\",\n authSource: \"remote\",\n interactive: input.interactive,\n },\n });\n\n const services = buildServiceDescriptorMap(plan.runtimeConfig);\n\n const configSource = explicitConfig.configPath\n ? explicitConfig.configPath\n : remoteConfig\n ? `bos://${explicitConfig.registry?.account}/${explicitConfig.registry?.domain}`\n : (findConfigPath() ?? \"bos.config.json\");\n\n const configSourceHttp =\n remoteConfig && explicitConfig.registry\n ? buildRegistryConfigUrl(\n explicitConfig.registry.account,\n explicitConfig.registry.domain,\n input.registry,\n )\n : undefined;\n\n const summary: StartSummary = {\n configSource,\n configSourceHttp,\n account: baseConfig.account,\n domain: baseConfig.domain ?? undefined,\n modules: {\n host: plan.runtimeConfig.host.remoteUrl ?? plan.runtimeConfig.host.url ?? \"local\",\n ui: plan.runtimeConfig.ui.url ?? \"local\",\n api: plan.runtimeConfig.api.url ?? \"local\",\n auth: plan.runtimeConfig.auth?.url ?? undefined,\n },\n warnings,\n };\n\n const orchestrator: AppOrchestrator = {\n packages: [\"host\"],\n env: {\n NODE_ENV: \"production\",\n ...productionEnv,\n ...stagingEnvVars,\n ...plan.launch.env,\n },\n description: `${isStaging ? \"Staging\" : \"Production\"} Mode (${baseConfig.account})`,\n port: plan.resolvedPorts.host ?? port,\n interactive: input.interactive,\n noLogs: true,\n };\n\n yield* emitProgress({ phase: \"config\", status: \"done\" });\n\n return {\n session: {\n orchestrator,\n services,\n runtimeConfig: plan.runtimeConfig,\n envGenerated: plan.envGenerated,\n shellEnv: shell,\n } satisfies DevSessionData,\n summary,\n url: plan.launch.hostUrl ?? `http://localhost:${plan.resolvedPorts.host ?? port}`,\n };\n });\n\nexport const bootstrapLayers = Layer.mergeAll(ProjectEnvLive, PortAllocatorLive);\n"],"mappings":"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"}
|
package/dist/dev-program.mjs
CHANGED
|
@@ -3,11 +3,12 @@ import { buildDescription, buildServiceDescriptorMap, buildServiceDescriptorMapF
|
|
|
3
3
|
import { BosConfigSchema } from "./types.mjs";
|
|
4
4
|
import { buildRegistryConfigUrl } from "./fastkv.mjs";
|
|
5
5
|
import { buildRuntimeConfig, buildRuntimePluginsForConfig, findConfigPath, getHostDevelopmentPort, resolveConfigComposableEntries } from "./config.mjs";
|
|
6
|
+
import { run } from "./utils/run.mjs";
|
|
6
7
|
import { isRegistryStart, resolveStartConfigSource } from "./start-config-source.mjs";
|
|
7
8
|
import { isDebug } from "./dev-log-pipeline.mjs";
|
|
8
9
|
import { detectAutoStartContext, isDockerAvailable, runDockerComposeUp, shouldAutoStartDocker } from "./infra/docker.mjs";
|
|
9
10
|
import { openResolution, walkExtendsChain } from "./resolution/session.mjs";
|
|
10
|
-
import {
|
|
11
|
+
import { isRailwayPublicProxyUrl } from "./db/driver.mjs";
|
|
11
12
|
import { ensureFreshDeps, findWorkspaceRoot } from "./workspace.mjs";
|
|
12
13
|
import { syncResolvedSharedDeps } from "./shared-deps.mjs";
|
|
13
14
|
import { generateCodeArtifacts } from "./code-artifacts.mjs";
|
|
@@ -172,7 +173,7 @@ const devBootstrap = (deps, input, timings) => Effect.gen(function* () {
|
|
|
172
173
|
});
|
|
173
174
|
yield* ensureEnvStep(projectEnv, session.root);
|
|
174
175
|
yield* loadEnvStep(projectEnv, session.root);
|
|
175
|
-
yield* projectEnv.sync(session.root, plan.envGenerated, shell).pipe(Effect.catchTag("EnvSyncError", (error) => Effect.logWarning(`[env] failed to refresh .env from resolved ports: ${error.cause}`)));
|
|
176
|
+
yield* projectEnv.sync(session.root, plan.envGenerated, shell).pipe(Effect.catchTag("EnvSyncError", (error) => Effect.logWarning(`[env] failed to refresh .env from resolved ports: ${String(error.cause)}`)));
|
|
176
177
|
const mergedEnv = yield* Effect.sync(() => mergeGeneratedOverFileEnv(plan.envGenerated, processEnvRecord(), shell));
|
|
177
178
|
yield* Effect.sync(() => {
|
|
178
179
|
for (const [key, value] of Object.entries(mergedEnv)) if (key === "BASE_URL" || key === "CORS_ORIGIN") setProcessEnv(key, value);
|
|
@@ -330,6 +331,13 @@ const startBootstrap = (deps, input) => Effect.gen(function* () {
|
|
|
330
331
|
if (!value || value.length === 0) missingSecrets.push(secret);
|
|
331
332
|
}
|
|
332
333
|
if (missingSecrets.length > 0) warnings.push(`Missing ${missingSecrets.length} secret(s): ${missingSecrets.join(", ")}`);
|
|
334
|
+
for (const [secret, value] of Object.entries(processEnvRecord())) {
|
|
335
|
+
if (!value || !secret.endsWith("_DATABASE_URL")) continue;
|
|
336
|
+
if (isRailwayPublicProxyUrl(value)) {
|
|
337
|
+
const host = new URL(value).hostname;
|
|
338
|
+
warnings.push(`${secret} points at Railway's public proxy (${host}) — its TLS certificate is self-signed, so connections use unverified TLS. Prefer the private *.railway.internal URL when the database runs in the same Railway project.`);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
333
341
|
const stagingEnvVars = isStaging ? { BOS_GATEWAY: baseConfig.staging?.domain ?? baseConfig.domain ?? "" } : {};
|
|
334
342
|
const plan = yield* planInfra({
|
|
335
343
|
configDir: sessionRoot,
|
|
@@ -391,5 +399,5 @@ const startBootstrap = (deps, input) => Effect.gen(function* () {
|
|
|
391
399
|
const bootstrapLayers = Layer.mergeAll(ProjectEnvLive, PortAllocatorLive);
|
|
392
400
|
|
|
393
401
|
//#endregion
|
|
394
|
-
export { DevConfigMissing, DevPreflightFailed, DevProxyMissing, DevStepError, StartConfigMissing, StartFetchFailed, StartRemoteConfigMissing, bootstrapLayers, devBootstrap, resolveProxyUrl, startBootstrap };
|
|
402
|
+
export { DevConfigMissing, DevPreflightFailed, DevProxyMissing, DevStepError, StartConfigMissing, StartFetchFailed, StartRemoteConfigMissing, bootstrapLayers, devBootstrap, resolveProxyUrl, resolvePublishedConfig, startBootstrap };
|
|
395
403
|
//# sourceMappingURL=dev-program.mjs.map
|
package/dist/dev-program.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-program.mjs","names":[],"sources":["../src/dev-program.ts"],"sourcesContent":["import { Data, Effect, Layer } from \"effect\";\nimport { detectLocalPackages, PortAllocatorLive } from \"./app\";\nimport { generateCodeArtifacts } from \"./code-artifacts\";\nimport {\n buildRuntimeConfig,\n buildRuntimePluginsForConfig,\n findConfigPath,\n getHostDevelopmentPort,\n resolveConfigComposableEntries,\n} from \"./config\";\nimport type { DevOptions, PhaseTiming, StartOptions } from \"./contract\";\nimport { isDebug } from \"./dev-log-pipeline\";\nimport type { DevSessionData, StartSummary } from \"./dev-session-data\";\nimport {\n deleteProcessEnv,\n getProcessEnv,\n processEnvRecord,\n setProcessEnv,\n} from \"./env/process-env\";\nimport {\n captureShellEnv,\n type EnvEnsureError,\n type EnvLoadError,\n ProjectEnv,\n ProjectEnvLive,\n type ProjectEnvService,\n} from \"./env/project-env\";\nimport { buildRegistryConfigUrl } from \"./fastkv\";\nimport {\n detectAutoStartContext,\n isDockerAvailable,\n runDockerComposeUp,\n shouldAutoStartDocker,\n} from \"./infra/docker\";\nimport { materializeViaLayer } from \"./infra/materializer\";\nimport { planInfra } from \"./infra/planner\";\nimport { preflightLocalInfra } from \"./infra/preflight\";\nimport type { InfraPlan } from \"./infra/types\";\nimport { mergeGeneratedOverFileEnv } from \"./orchestrator\";\nimport { emitProgress, timedPhase } from \"./progress\";\nimport { openResolution, type ResolutionSession, walkExtendsChain } from \"./resolution/session\";\nimport {\n type AppOrchestrator,\n buildDescription,\n buildServiceDescriptorMap,\n buildServiceDescriptorMapFromPlan,\n} from \"./service-descriptor\";\nimport { syncResolvedSharedDeps } from \"./shared-deps\";\nimport { isRegistryStart, resolveStartConfigSource } from \"./start-config-source\";\nimport type { BosConfig, SourceMode } from \"./types\";\nimport { BosConfigSchema } from \"./types\";\nimport { run } from \"./utils/run\";\nimport { ensureFreshDeps, findWorkspaceRoot } from \"./workspace\";\n\nexport type { DevSessionData, StartSummary } from \"./dev-session-data\";\n\nexport interface BootstrapDeps {\n readonly session: ResolutionSession | null;\n}\n\nexport class DevStepError extends Data.TaggedError(\"DevStepError\")<{\n phase: string;\n cause: unknown;\n}> {}\n\nexport class DevConfigMissing extends Data.TaggedError(\"DevConfigMissing\")<Record<string, never>> {}\n\nexport class DevProxyMissing extends Data.TaggedError(\"DevProxyMissing\")<Record<string, never>> {}\n\nexport class DevPreflightFailed extends Data.TaggedError(\"DevPreflightFailed\")<{\n messages: string[];\n}> {}\n\nexport class StartFetchFailed extends Data.TaggedError(\"StartFetchFailed\")<{ message: string }> {}\n\nexport class StartRemoteConfigMissing extends Data.TaggedError(\"StartRemoteConfigMissing\")<{\n message: string;\n}> {}\n\nexport class StartConfigMissing extends Data.TaggedError(\"StartConfigMissing\")<\n Record<string, never>\n> {}\n\nfunction parseSourceMode(value: string | undefined, defaultValue: SourceMode): SourceMode {\n if (value === \"local\" || value === \"remote\") return value;\n return defaultValue;\n}\n\nasync function resolvePublishedConfig(\n account: string,\n gateway: string,\n registry?: string,\n): Promise<BosConfig | null> {\n try {\n const { config: merged } = await walkExtendsChain(`bos://${account}/${gateway}`, {\n env: \"production\",\n registry,\n visit: async () => {},\n });\n return resolveConfigComposableEntries(\n BosConfigSchema.parse(merged),\n process.cwd(),\n \"production\",\n );\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"No config found\")) {\n return null;\n }\n throw error;\n }\n}\n\nfunction isValidProxyUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nexport function resolveProxyUrl(bosConfig: BosConfig | null): string | null {\n if (!bosConfig) return null;\n const apiConfig = bosConfig.app.api;\n if (!apiConfig) return null;\n if (apiConfig.proxy && isValidProxyUrl(apiConfig.proxy)) return apiConfig.proxy;\n if (apiConfig.production && isValidProxyUrl(apiConfig.production)) return apiConfig.production;\n return null;\n}\n\nconst step = <A>(timings: PhaseTiming[], name: string, fn: () => Promise<A>) =>\n timedPhase(\n timings,\n name,\n Effect.tryPromise({\n try: fn,\n catch: (cause) => new DevStepError({ phase: name, cause }),\n }),\n );\n\nconst ensureEnvStep = (projectEnv: ProjectEnvService, configDir: string) =>\n projectEnv\n .ensureFile(configDir)\n .pipe(\n Effect.mapError((cause: EnvEnsureError) => new DevStepError({ phase: \"ensure env\", cause })),\n );\n\nconst loadEnvStep = (projectEnv: ProjectEnvService, configDir: string) =>\n projectEnv\n .load(configDir)\n .pipe(Effect.mapError((cause: EnvLoadError) => new DevStepError({ phase: \"load env\", cause })));\n\nexport const devBootstrap = (deps: BootstrapDeps, input: DevOptions, timings: PhaseTiming[]) =>\n Effect.gen(function* () {\n const shell = yield* captureShellEnv;\n const projectEnv = yield* ProjectEnv;\n\n if (!deps.session) {\n return yield* new DevConfigMissing({});\n }\n let session: ResolutionSession = deps.session;\n\n yield* ensureEnvStep(projectEnv, session.root);\n yield* loadEnvStep(projectEnv, session.root);\n\n const localPackages = detectLocalPackages(\n session.config ?? undefined,\n session.runtime ?? undefined,\n session.root,\n );\n const localPackageNames = new Set(localPackages.map((entry) => entry.name));\n const localDirs = localPackages.map((entry) => entry.dir);\n\n const hostSource: SourceMode = localPackageNames.has(\"host\")\n ? parseSourceMode(input.host, \"local\")\n : \"remote\";\n const uiSource: SourceMode = localPackageNames.has(\"ui\")\n ? parseSourceMode(input.ui, \"local\")\n : \"remote\";\n const apiSource: SourceMode = localPackageNames.has(\"api\")\n ? parseSourceMode(input.api, \"local\")\n : \"remote\";\n const authSource: SourceMode = localPackageNames.has(\"auth\")\n ? parseSourceMode(input.auth, \"local\")\n : \"remote\";\n const ssr = input.ssr ?? false;\n const proxy = input.proxy ?? false;\n\n if (input.logLevel) {\n yield* Effect.sync(() => {\n setProcessEnv(\"BOS_LOG_LEVEL\", input.logLevel!);\n });\n }\n\n if (ssr) {\n yield* Effect.sync(() => {\n setProcessEnv(\"BOS_SSR\", \"1\");\n });\n }\n\n const sharedSync = yield* step(timings, \"shared deps\", () =>\n syncResolvedSharedDeps({\n configDir: session.root,\n hostMode: hostSource,\n bosConfig: session.config ?? undefined,\n extendsChain: [],\n }),\n );\n let configMayHaveChanged = false;\n if (sharedSync.catalogChanged) {\n yield* step(timings, \"install\", () =>\n run(\"pnpm\", [\"install\"], { cwd: findWorkspaceRoot(session.root)?.dir ?? session.root }),\n );\n configMayHaveChanged = true;\n }\n\n yield* step(timings, \"build\", async () => {\n const report = await ensureFreshDeps(session.root, localDirs);\n if (report.rebuilt.some((member) => member.name === \"everything-dev\")) {\n // Only the bos process itself runs the everything-dev dist (plugin\n // children spawn after this step and load the fresh build). A source\n // run (node --import tsx src/cli.ts) never imported dist, so nothing\n // is stale for it — warn only where the previously imported build\n // matters.\n const runningFromDist = import.meta.url.includes(\"/dist/\");\n if (runningFromDist) {\n console.log(\n \"[dev] everything-dev was rebuilt — this session still runs the previous \" +\n \"orchestrator build. Restart `bos dev` once to pick it up.\",\n );\n }\n }\n });\n\n let devExtendsChain: string[] | undefined;\n if (configMayHaveChanged || input.remotePlugins !== undefined) {\n yield* step(timings, \"resolve config\", async () => {\n const opened = await openResolution({\n cwd: session.root,\n remotePlugins: input.remotePlugins,\n });\n if (opened) {\n session = opened;\n devExtendsChain = [...opened.chain];\n }\n });\n }\n\n if (!session.config) {\n return yield* new DevConfigMissing({});\n }\n const bosConfig: BosConfig = session.config;\n\n if (proxy && !resolveProxyUrl(bosConfig)) {\n return yield* new DevProxyMissing({});\n }\n\n const developmentRuntime = yield* Effect.tryPromise({\n try: async () => {\n return session.buildRuntime({\n uiSource,\n apiSource,\n authSource,\n hostSource,\n env: \"development\",\n plugins: session.runtime?.plugins,\n });\n },\n catch: (cause) => new DevStepError({ phase: \"build runtime config\", cause }),\n });\n for (const message of session.warnings) {\n yield* Effect.logWarning(message);\n }\n\n const plan: InfraPlan = yield* timedPhase(\n timings,\n \"ports\",\n planInfra({\n configDir: session.root,\n bosConfig: developmentRuntime,\n cli: {\n port: input.port,\n apiPort: input.apiPort,\n authPort: input.authPort,\n uiPort: input.uiPort,\n pluginPortStart: input.pluginPortStart,\n ssr,\n proxy,\n hostSource,\n uiSource,\n apiSource,\n authSource,\n interactive: input.interactive,\n },\n }),\n );\n\n yield* Effect.tryPromise({\n try: () => materializeViaLayer(session.root, plan.runtimeConfig),\n catch: (cause) => new DevStepError({ phase: \"materialize infra\", cause }),\n });\n yield* ensureEnvStep(projectEnv, session.root);\n yield* loadEnvStep(projectEnv, session.root);\n\n yield* projectEnv\n .sync(session.root, plan.envGenerated, shell)\n .pipe(\n Effect.catchTag(\"EnvSyncError\", (error) =>\n Effect.logWarning(`[env] failed to refresh .env from resolved ports: ${error.cause}`),\n ),\n );\n\n const mergedEnv = yield* Effect.sync(() =>\n mergeGeneratedOverFileEnv(\n plan.envGenerated,\n processEnvRecord() as Record<string, string>,\n shell,\n ),\n );\n yield* Effect.sync(() => {\n for (const [key, value] of Object.entries(mergedEnv)) {\n if (key === \"BASE_URL\" || key === \"CORS_ORIGIN\") setProcessEnv(key, value);\n }\n });\n let preflightFailures = yield* preflightLocalInfra(plan.envGenerated, mergedEnv);\n if (\n preflightFailures.length > 0 &&\n shouldAutoStartDocker(preflightFailures, {\n ...detectAutoStartContext(session.root),\n dockerAvailable: yield* Effect.promise(isDockerAvailable),\n })\n ) {\n const compose = yield* step(timings, \"docker compose up\", () =>\n runDockerComposeUp(session.root),\n );\n if (compose.ok) {\n preflightFailures = yield* preflightLocalInfra(plan.envGenerated, mergedEnv);\n } else {\n preflightFailures = [\n ...preflightFailures,\n {\n secret: \"docker-compose\",\n host: \"localhost\",\n port: 0,\n error: `docker compose up -d --wait failed${compose.tail ? `:\\n${compose.tail}` : \"\"}`,\n tcpReachable: false,\n },\n ];\n }\n }\n if (preflightFailures.length > 0) {\n return yield* new DevPreflightFailed({ messages: preflightFailures.map((f) => f.error) });\n }\n\n const services = buildServiceDescriptorMapFromPlan(plan, { ssr, proxy });\n\n const packages = [...plan.serviceDescriptors.keys()];\n if (isDebug(getProcessEnv(\"DEBUG\"))) {\n yield* Effect.logError(`[DEBUG dev] services keys: ${packages.join(\", \")}`);\n }\n const apiSvc = services.get(\"api\");\n if (apiSvc?.proxy) {\n const proxyUrl = resolveProxyUrl(bosConfig);\n if (proxyUrl) plan.orchestrator.env.API_PROXY = proxyUrl;\n }\n\n yield* step(timings, \"generate artifacts\", () =>\n generateCodeArtifacts(session.root, bosConfig, {\n env: \"development\",\n extendsChain: devExtendsChain,\n runtimeConfig: plan.runtimeConfig,\n }),\n );\n\n return {\n session: {\n orchestrator: plan.orchestrator,\n services,\n runtimeConfig: plan.runtimeConfig,\n envGenerated: plan.envGenerated,\n shellEnv: shell,\n } satisfies DevSessionData,\n description: buildDescription(services) || plan.description,\n processes: packages,\n };\n });\n\nexport const startBootstrap = (deps: BootstrapDeps, input: StartOptions) =>\n Effect.gen(function* () {\n const shell = yield* captureShellEnv;\n const projectEnv = yield* ProjectEnv;\n\n const sessionRoot = deps.session?.root ?? process.cwd();\n\n yield* loadEnvStep(projectEnv, sessionRoot);\n\n yield* emitProgress({ phase: \"config\", status: \"running\" });\n\n const bosEnv = input.env ?? (getProcessEnv(\"BOS_ENV\") === \"staging\" ? \"staging\" : \"production\");\n const explicitConfig = resolveStartConfigSource(input, {\n BOS_ACCOUNT: getProcessEnv(\"BOS_ACCOUNT\"),\n BOS_GATEWAY: getProcessEnv(\"BOS_GATEWAY\"),\n });\n\n let config: BosConfig | null = null;\n let remoteConfig: BosConfig | null = null;\n\n if (explicitConfig.configPath) {\n config = deps.session?.config ?? null;\n } else if (explicitConfig.registry) {\n const { account, domain } = explicitConfig.registry;\n const expectedUrl = buildRegistryConfigUrl(account, domain, input.registry);\n remoteConfig = yield* Effect.tryPromise({\n try: () => resolvePublishedConfig(account, domain, input.registry),\n catch: (error) =>\n new StartFetchFailed({\n message: `Failed to fetch config for bos://${account}/${domain}: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }\\nExpected URL: ${expectedUrl}`,\n }),\n });\n if (remoteConfig) {\n config = remoteConfig;\n } else {\n return yield* new StartRemoteConfigMissing({\n message: `No config found at bos://${account}/${domain}. Verify the account and gateway are correct and the config has been published.\\nExpected URL: ${expectedUrl}`,\n });\n }\n } else {\n config = deps.session?.config ?? null;\n }\n\n if (!config) {\n return yield* new StartConfigMissing({});\n }\n\n if (!explicitConfig.configPath) {\n if (explicitConfig.registry?.account) {\n config = { ...config, account: explicitConfig.registry.account };\n }\n if (explicitConfig.registry?.domain) {\n config = { ...config, domain: explicitConfig.registry.domain };\n }\n }\n const baseConfig: BosConfig = config;\n\n const port = input.port ?? getHostDevelopmentPort(baseConfig.app.host.development);\n const isStaging = bosEnv === \"staging\";\n const runtimePlugins = yield* Effect.tryPromise({\n try: () => buildRuntimePluginsForConfig(baseConfig, sessionRoot, \"production\"),\n catch: (cause) => new DevStepError({ phase: \"resolve runtime plugins\", cause }),\n });\n const runtimeConfig = yield* Effect.tryPromise({\n try: () =>\n buildRuntimeConfig(baseConfig, sessionRoot, \"production\", {\n uiSource: \"remote\",\n apiSource: \"remote\",\n authSource: \"remote\",\n hostSource: \"remote\",\n plugins: runtimePlugins,\n }),\n catch: (cause) => new DevStepError({ phase: \"build runtime config\", cause }),\n });\n\n if (isStaging && baseConfig.staging?.domain) {\n runtimeConfig.domain = baseConfig.staging.domain;\n }\n\n if (isStaging) {\n runtimeConfig.env = \"staging\";\n }\n\n yield* emitProgress({ phase: \"generate artifacts\", status: \"running\" });\n yield* Effect.tryPromise({\n try: () =>\n generateCodeArtifacts(sessionRoot, baseConfig, {\n env: \"production\",\n runtimeConfig,\n }),\n catch: (cause) => new DevStepError({ phase: \"generate artifacts\", cause }),\n });\n yield* emitProgress({ phase: \"generate artifacts\", status: \"done\" });\n\n const productionEnv: Record<string, string> = {};\n const warnings: string[] = [];\n\n const localhostOrigin = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/i;\n const corsOrigin = getProcessEnv(\"CORS_ORIGIN\");\n const isLocalhostProductionOrigin =\n corsOrigin !== undefined && localhostOrigin.test(corsOrigin);\n if (isLocalhostProductionOrigin && isRegistryStart(explicitConfig)) {\n warnings.push(\n `CORS_ORIGIN is a localhost origin (${corsOrigin}) in a registry production start — overriding with the configured domain`,\n );\n deleteProcessEnv(\"CORS_ORIGIN\");\n deleteProcessEnv(\"BASE_URL\");\n }\n\n if (!getProcessEnv(\"CORS_ORIGIN\") && baseConfig.domain) {\n const effectiveDomain = isStaging\n ? (baseConfig.staging?.domain ?? baseConfig.domain)\n : baseConfig.domain;\n const defaultOrigin = `https://${effectiveDomain}`;\n productionEnv.CORS_ORIGIN = defaultOrigin;\n productionEnv.BASE_URL = defaultOrigin;\n warnings.push(`CORS_ORIGIN defaulting to ${defaultOrigin}`);\n }\n\n const requiredSecrets = new Set<string>();\n const missingSecrets: string[] = [];\n\n if (runtimeConfig.host.secrets) {\n for (const s of runtimeConfig.host.secrets) requiredSecrets.add(s);\n }\n if (runtimeConfig.auth?.secrets) {\n for (const s of runtimeConfig.auth.secrets) requiredSecrets.add(s);\n }\n if (runtimeConfig.api?.secrets) {\n for (const s of runtimeConfig.api.secrets) requiredSecrets.add(s);\n }\n for (const plugin of Object.values(runtimeConfig.plugins ?? {})) {\n if (plugin.secrets) {\n for (const s of plugin.secrets) {\n if (s.endsWith(\"_DATABASE_URL\")) continue;\n requiredSecrets.add(s);\n }\n }\n }\n\n for (const secret of requiredSecrets) {\n const value = getProcessEnv(secret);\n if (!value || value.length === 0) {\n missingSecrets.push(secret);\n }\n }\n\n if (missingSecrets.length > 0) {\n warnings.push(`Missing ${missingSecrets.length} secret(s): ${missingSecrets.join(\", \")}`);\n }\n\n const stagingEnvVars: Record<string, string> = isStaging\n ? { BOS_GATEWAY: baseConfig.staging?.domain ?? baseConfig.domain ?? \"\" }\n : {};\n\n const plan: InfraPlan = yield* planInfra({\n configDir: sessionRoot,\n bosConfig: runtimeConfig,\n cli: {\n port: input.port,\n ssr: false,\n proxy: false,\n hostSource: \"remote\",\n uiSource: \"remote\",\n apiSource: \"remote\",\n authSource: \"remote\",\n interactive: input.interactive,\n },\n });\n\n const services = buildServiceDescriptorMap(plan.runtimeConfig);\n\n const configSource = explicitConfig.configPath\n ? explicitConfig.configPath\n : remoteConfig\n ? `bos://${explicitConfig.registry?.account}/${explicitConfig.registry?.domain}`\n : (findConfigPath() ?? \"bos.config.json\");\n\n const configSourceHttp =\n remoteConfig && explicitConfig.registry\n ? buildRegistryConfigUrl(\n explicitConfig.registry.account,\n explicitConfig.registry.domain,\n input.registry,\n )\n : undefined;\n\n const summary: StartSummary = {\n configSource,\n configSourceHttp,\n account: baseConfig.account,\n domain: baseConfig.domain ?? undefined,\n modules: {\n host: plan.runtimeConfig.host.remoteUrl ?? plan.runtimeConfig.host.url ?? \"local\",\n ui: plan.runtimeConfig.ui.url ?? \"local\",\n api: plan.runtimeConfig.api.url ?? \"local\",\n auth: plan.runtimeConfig.auth?.url ?? undefined,\n },\n warnings,\n };\n\n const orchestrator: AppOrchestrator = {\n packages: [\"host\"],\n env: {\n NODE_ENV: \"production\",\n ...productionEnv,\n ...stagingEnvVars,\n ...plan.launch.env,\n },\n description: `${isStaging ? \"Staging\" : \"Production\"} Mode (${baseConfig.account})`,\n port: plan.resolvedPorts.host ?? port,\n interactive: input.interactive,\n noLogs: true,\n };\n\n yield* emitProgress({ phase: \"config\", status: \"done\" });\n\n return {\n session: {\n orchestrator,\n services,\n runtimeConfig: plan.runtimeConfig,\n envGenerated: plan.envGenerated,\n shellEnv: shell,\n } satisfies DevSessionData,\n summary,\n url: plan.launch.hostUrl ?? `http://localhost:${plan.resolvedPorts.host ?? port}`,\n };\n });\n\nexport const bootstrapLayers = Layer.mergeAll(ProjectEnvLive, PortAllocatorLive);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dev-program.mjs","names":[],"sources":["../src/dev-program.ts"],"sourcesContent":["import { Data, Effect, Layer } from \"effect\";\nimport { detectLocalPackages, PortAllocatorLive } from \"./app\";\nimport { generateCodeArtifacts } from \"./code-artifacts\";\nimport {\n buildRuntimeConfig,\n buildRuntimePluginsForConfig,\n findConfigPath,\n getHostDevelopmentPort,\n resolveConfigComposableEntries,\n} from \"./config\";\nimport type { DevOptions, PhaseTiming, StartOptions } from \"./contract\";\nimport { isRailwayPublicProxyUrl } from \"./db/driver\";\nimport { isDebug } from \"./dev-log-pipeline\";\nimport type { DevSessionData, StartSummary } from \"./dev-session-data\";\nimport {\n deleteProcessEnv,\n getProcessEnv,\n processEnvRecord,\n setProcessEnv,\n} from \"./env/process-env\";\nimport {\n captureShellEnv,\n type EnvEnsureError,\n type EnvLoadError,\n ProjectEnv,\n ProjectEnvLive,\n type ProjectEnvService,\n} from \"./env/project-env\";\nimport { buildRegistryConfigUrl } from \"./fastkv\";\nimport {\n detectAutoStartContext,\n isDockerAvailable,\n runDockerComposeUp,\n shouldAutoStartDocker,\n} from \"./infra/docker\";\nimport { materializeViaLayer } from \"./infra/materializer\";\nimport { planInfra } from \"./infra/planner\";\nimport { preflightLocalInfra } from \"./infra/preflight\";\nimport type { InfraPlan } from \"./infra/types\";\nimport { mergeGeneratedOverFileEnv } from \"./orchestrator\";\nimport { emitProgress, timedPhase } from \"./progress\";\nimport { openResolution, type ResolutionSession, walkExtendsChain } from \"./resolution/session\";\nimport {\n type AppOrchestrator,\n buildDescription,\n buildServiceDescriptorMap,\n buildServiceDescriptorMapFromPlan,\n} from \"./service-descriptor\";\nimport { syncResolvedSharedDeps } from \"./shared-deps\";\nimport { isRegistryStart, resolveStartConfigSource } from \"./start-config-source\";\nimport type { BosConfig, SourceMode } from \"./types\";\nimport { BosConfigSchema } from \"./types\";\nimport { run } from \"./utils/run\";\nimport { ensureFreshDeps, findWorkspaceRoot } from \"./workspace\";\n\nexport type { DevSessionData, StartSummary } from \"./dev-session-data\";\n\nexport interface BootstrapDeps {\n readonly session: ResolutionSession | null;\n}\n\nexport class DevStepError extends Data.TaggedError(\"DevStepError\")<{\n phase: string;\n cause: unknown;\n}> {}\n\nexport class DevConfigMissing extends Data.TaggedError(\"DevConfigMissing\")<Record<string, never>> {}\n\nexport class DevProxyMissing extends Data.TaggedError(\"DevProxyMissing\")<Record<string, never>> {}\n\nexport class DevPreflightFailed extends Data.TaggedError(\"DevPreflightFailed\")<{\n messages: string[];\n}> {}\n\nexport class StartFetchFailed extends Data.TaggedError(\"StartFetchFailed\")<{ message: string }> {}\n\nexport class StartRemoteConfigMissing extends Data.TaggedError(\"StartRemoteConfigMissing\")<{\n message: string;\n}> {}\n\nexport class StartConfigMissing extends Data.TaggedError(\"StartConfigMissing\")<\n Record<string, never>\n> {}\n\nfunction parseSourceMode(value: string | undefined, defaultValue: SourceMode): SourceMode {\n if (value === \"local\" || value === \"remote\") return value;\n return defaultValue;\n}\n\nexport async function resolvePublishedConfig(\n account: string,\n gateway: string,\n registry?: string,\n): Promise<BosConfig | null> {\n try {\n const { config: merged } = await walkExtendsChain(`bos://${account}/${gateway}`, {\n env: \"production\",\n registry,\n visit: async () => {},\n });\n return resolveConfigComposableEntries(\n BosConfigSchema.parse(merged),\n process.cwd(),\n \"production\",\n );\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"No config found\")) {\n return null;\n }\n throw error;\n }\n}\n\nfunction isValidProxyUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\nexport function resolveProxyUrl(bosConfig: BosConfig | null): string | null {\n if (!bosConfig) return null;\n const apiConfig = bosConfig.app.api;\n if (!apiConfig) return null;\n if (apiConfig.proxy && isValidProxyUrl(apiConfig.proxy)) return apiConfig.proxy;\n if (apiConfig.production && isValidProxyUrl(apiConfig.production)) return apiConfig.production;\n return null;\n}\n\nconst step = <A>(timings: PhaseTiming[], name: string, fn: () => Promise<A>) =>\n timedPhase(\n timings,\n name,\n Effect.tryPromise({\n try: fn,\n catch: (cause) => new DevStepError({ phase: name, cause }),\n }),\n );\n\nconst ensureEnvStep = (projectEnv: ProjectEnvService, configDir: string) =>\n projectEnv\n .ensureFile(configDir)\n .pipe(\n Effect.mapError((cause: EnvEnsureError) => new DevStepError({ phase: \"ensure env\", cause })),\n );\n\nconst loadEnvStep = (projectEnv: ProjectEnvService, configDir: string) =>\n projectEnv\n .load(configDir)\n .pipe(Effect.mapError((cause: EnvLoadError) => new DevStepError({ phase: \"load env\", cause })));\n\nexport const devBootstrap = (deps: BootstrapDeps, input: DevOptions, timings: PhaseTiming[]) =>\n Effect.gen(function* () {\n const shell = yield* captureShellEnv;\n const projectEnv = yield* ProjectEnv;\n\n if (!deps.session) {\n return yield* new DevConfigMissing({});\n }\n let session: ResolutionSession = deps.session;\n\n yield* ensureEnvStep(projectEnv, session.root);\n yield* loadEnvStep(projectEnv, session.root);\n\n const localPackages = detectLocalPackages(\n session.config ?? undefined,\n session.runtime ?? undefined,\n session.root,\n );\n const localPackageNames = new Set(localPackages.map((entry) => entry.name));\n const localDirs = localPackages.map((entry) => entry.dir);\n\n const hostSource: SourceMode = localPackageNames.has(\"host\")\n ? parseSourceMode(input.host, \"local\")\n : \"remote\";\n const uiSource: SourceMode = localPackageNames.has(\"ui\")\n ? parseSourceMode(input.ui, \"local\")\n : \"remote\";\n const apiSource: SourceMode = localPackageNames.has(\"api\")\n ? parseSourceMode(input.api, \"local\")\n : \"remote\";\n const authSource: SourceMode = localPackageNames.has(\"auth\")\n ? parseSourceMode(input.auth, \"local\")\n : \"remote\";\n const ssr = input.ssr ?? false;\n const proxy = input.proxy ?? false;\n\n if (input.logLevel) {\n yield* Effect.sync(() => {\n setProcessEnv(\"BOS_LOG_LEVEL\", input.logLevel!);\n });\n }\n\n if (ssr) {\n yield* Effect.sync(() => {\n setProcessEnv(\"BOS_SSR\", \"1\");\n });\n }\n\n const sharedSync = yield* step(timings, \"shared deps\", () =>\n syncResolvedSharedDeps({\n configDir: session.root,\n hostMode: hostSource,\n bosConfig: session.config ?? undefined,\n extendsChain: [],\n }),\n );\n let configMayHaveChanged = false;\n if (sharedSync.catalogChanged) {\n yield* step(timings, \"install\", () =>\n run(\"pnpm\", [\"install\"], { cwd: findWorkspaceRoot(session.root)?.dir ?? session.root }),\n );\n configMayHaveChanged = true;\n }\n\n yield* step(timings, \"build\", async () => {\n const report = await ensureFreshDeps(session.root, localDirs);\n if (report.rebuilt.some((member) => member.name === \"everything-dev\")) {\n // Only the bos process itself runs the everything-dev dist (plugin\n // children spawn after this step and load the fresh build). A source\n // run (node --import tsx src/cli.ts) never imported dist, so nothing\n // is stale for it — warn only where the previously imported build\n // matters.\n const runningFromDist = import.meta.url.includes(\"/dist/\");\n if (runningFromDist) {\n console.log(\n \"[dev] everything-dev was rebuilt — this session still runs the previous \" +\n \"orchestrator build. Restart `bos dev` once to pick it up.\",\n );\n }\n }\n });\n\n let devExtendsChain: string[] | undefined;\n if (configMayHaveChanged || input.remotePlugins !== undefined) {\n yield* step(timings, \"resolve config\", async () => {\n const opened = await openResolution({\n cwd: session.root,\n remotePlugins: input.remotePlugins,\n });\n if (opened) {\n session = opened;\n devExtendsChain = [...opened.chain];\n }\n });\n }\n\n if (!session.config) {\n return yield* new DevConfigMissing({});\n }\n const bosConfig: BosConfig = session.config;\n\n if (proxy && !resolveProxyUrl(bosConfig)) {\n return yield* new DevProxyMissing({});\n }\n\n const developmentRuntime = yield* Effect.tryPromise({\n try: async () => {\n return session.buildRuntime({\n uiSource,\n apiSource,\n authSource,\n hostSource,\n env: \"development\",\n plugins: session.runtime?.plugins,\n });\n },\n catch: (cause) => new DevStepError({ phase: \"build runtime config\", cause }),\n });\n for (const message of session.warnings) {\n yield* Effect.logWarning(message);\n }\n\n const plan: InfraPlan = yield* timedPhase(\n timings,\n \"ports\",\n planInfra({\n configDir: session.root,\n bosConfig: developmentRuntime,\n cli: {\n port: input.port,\n apiPort: input.apiPort,\n authPort: input.authPort,\n uiPort: input.uiPort,\n pluginPortStart: input.pluginPortStart,\n ssr,\n proxy,\n hostSource,\n uiSource,\n apiSource,\n authSource,\n interactive: input.interactive,\n },\n }),\n );\n\n yield* Effect.tryPromise({\n try: () => materializeViaLayer(session.root, plan.runtimeConfig),\n catch: (cause) => new DevStepError({ phase: \"materialize infra\", cause }),\n });\n yield* ensureEnvStep(projectEnv, session.root);\n yield* loadEnvStep(projectEnv, session.root);\n\n yield* projectEnv\n .sync(session.root, plan.envGenerated, shell)\n .pipe(\n Effect.catchTag(\"EnvSyncError\", (error) =>\n Effect.logWarning(\n `[env] failed to refresh .env from resolved ports: ${String(error.cause)}`,\n ),\n ),\n );\n\n const mergedEnv = yield* Effect.sync(() =>\n mergeGeneratedOverFileEnv(\n plan.envGenerated,\n processEnvRecord() as Record<string, string>,\n shell,\n ),\n );\n yield* Effect.sync(() => {\n for (const [key, value] of Object.entries(mergedEnv)) {\n if (key === \"BASE_URL\" || key === \"CORS_ORIGIN\") setProcessEnv(key, value);\n }\n });\n let preflightFailures = yield* preflightLocalInfra(plan.envGenerated, mergedEnv);\n if (\n preflightFailures.length > 0 &&\n shouldAutoStartDocker(preflightFailures, {\n ...detectAutoStartContext(session.root),\n dockerAvailable: yield* Effect.promise(isDockerAvailable),\n })\n ) {\n const compose = yield* step(timings, \"docker compose up\", () =>\n runDockerComposeUp(session.root),\n );\n if (compose.ok) {\n preflightFailures = yield* preflightLocalInfra(plan.envGenerated, mergedEnv);\n } else {\n preflightFailures = [\n ...preflightFailures,\n {\n secret: \"docker-compose\",\n host: \"localhost\",\n port: 0,\n error: `docker compose up -d --wait failed${compose.tail ? `:\\n${compose.tail}` : \"\"}`,\n tcpReachable: false,\n },\n ];\n }\n }\n if (preflightFailures.length > 0) {\n return yield* new DevPreflightFailed({ messages: preflightFailures.map((f) => f.error) });\n }\n\n const services = buildServiceDescriptorMapFromPlan(plan, { ssr, proxy });\n\n const packages = [...plan.serviceDescriptors.keys()];\n if (isDebug(getProcessEnv(\"DEBUG\"))) {\n yield* Effect.logError(`[DEBUG dev] services keys: ${packages.join(\", \")}`);\n }\n const apiSvc = services.get(\"api\");\n if (apiSvc?.proxy) {\n const proxyUrl = resolveProxyUrl(bosConfig);\n if (proxyUrl) plan.orchestrator.env.API_PROXY = proxyUrl;\n }\n\n yield* step(timings, \"generate artifacts\", () =>\n generateCodeArtifacts(session.root, bosConfig, {\n env: \"development\",\n extendsChain: devExtendsChain,\n runtimeConfig: plan.runtimeConfig,\n }),\n );\n\n return {\n session: {\n orchestrator: plan.orchestrator,\n services,\n runtimeConfig: plan.runtimeConfig,\n envGenerated: plan.envGenerated,\n shellEnv: shell,\n } satisfies DevSessionData,\n description: buildDescription(services) || plan.description,\n processes: packages,\n };\n });\n\nexport const startBootstrap = (deps: BootstrapDeps, input: StartOptions) =>\n Effect.gen(function* () {\n const shell = yield* captureShellEnv;\n const projectEnv = yield* ProjectEnv;\n\n const sessionRoot = deps.session?.root ?? process.cwd();\n\n yield* loadEnvStep(projectEnv, sessionRoot);\n\n yield* emitProgress({ phase: \"config\", status: \"running\" });\n\n const bosEnv = input.env ?? (getProcessEnv(\"BOS_ENV\") === \"staging\" ? \"staging\" : \"production\");\n const explicitConfig = resolveStartConfigSource(input, {\n BOS_ACCOUNT: getProcessEnv(\"BOS_ACCOUNT\"),\n BOS_GATEWAY: getProcessEnv(\"BOS_GATEWAY\"),\n });\n\n let config: BosConfig | null = null;\n let remoteConfig: BosConfig | null = null;\n\n if (explicitConfig.configPath) {\n config = deps.session?.config ?? null;\n } else if (explicitConfig.registry) {\n const { account, domain } = explicitConfig.registry;\n const expectedUrl = buildRegistryConfigUrl(account, domain, input.registry);\n remoteConfig = yield* Effect.tryPromise({\n try: () => resolvePublishedConfig(account, domain, input.registry),\n catch: (error) =>\n new StartFetchFailed({\n message: `Failed to fetch config for bos://${account}/${domain}: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }\\nExpected URL: ${expectedUrl}`,\n }),\n });\n if (remoteConfig) {\n config = remoteConfig;\n } else {\n return yield* new StartRemoteConfigMissing({\n message: `No config found at bos://${account}/${domain}. Verify the account and gateway are correct and the config has been published.\\nExpected URL: ${expectedUrl}`,\n });\n }\n } else {\n config = deps.session?.config ?? null;\n }\n\n if (!config) {\n return yield* new StartConfigMissing({});\n }\n\n if (!explicitConfig.configPath) {\n if (explicitConfig.registry?.account) {\n config = { ...config, account: explicitConfig.registry.account };\n }\n if (explicitConfig.registry?.domain) {\n config = { ...config, domain: explicitConfig.registry.domain };\n }\n }\n const baseConfig: BosConfig = config;\n\n const port = input.port ?? getHostDevelopmentPort(baseConfig.app.host.development);\n const isStaging = bosEnv === \"staging\";\n const runtimePlugins = yield* Effect.tryPromise({\n try: () => buildRuntimePluginsForConfig(baseConfig, sessionRoot, \"production\"),\n catch: (cause) => new DevStepError({ phase: \"resolve runtime plugins\", cause }),\n });\n const runtimeConfig = yield* Effect.tryPromise({\n try: () =>\n buildRuntimeConfig(baseConfig, sessionRoot, \"production\", {\n uiSource: \"remote\",\n apiSource: \"remote\",\n authSource: \"remote\",\n hostSource: \"remote\",\n plugins: runtimePlugins,\n }),\n catch: (cause) => new DevStepError({ phase: \"build runtime config\", cause }),\n });\n\n if (isStaging && baseConfig.staging?.domain) {\n runtimeConfig.domain = baseConfig.staging.domain;\n }\n\n if (isStaging) {\n runtimeConfig.env = \"staging\";\n }\n\n yield* emitProgress({ phase: \"generate artifacts\", status: \"running\" });\n yield* Effect.tryPromise({\n try: () =>\n generateCodeArtifacts(sessionRoot, baseConfig, {\n env: \"production\",\n runtimeConfig,\n }),\n catch: (cause) => new DevStepError({ phase: \"generate artifacts\", cause }),\n });\n yield* emitProgress({ phase: \"generate artifacts\", status: \"done\" });\n\n const productionEnv: Record<string, string> = {};\n const warnings: string[] = [];\n\n const localhostOrigin = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/i;\n const corsOrigin = getProcessEnv(\"CORS_ORIGIN\");\n const isLocalhostProductionOrigin =\n corsOrigin !== undefined && localhostOrigin.test(corsOrigin);\n if (isLocalhostProductionOrigin && isRegistryStart(explicitConfig)) {\n warnings.push(\n `CORS_ORIGIN is a localhost origin (${corsOrigin}) in a registry production start — overriding with the configured domain`,\n );\n deleteProcessEnv(\"CORS_ORIGIN\");\n deleteProcessEnv(\"BASE_URL\");\n }\n\n if (!getProcessEnv(\"CORS_ORIGIN\") && baseConfig.domain) {\n const effectiveDomain = isStaging\n ? (baseConfig.staging?.domain ?? baseConfig.domain)\n : baseConfig.domain;\n const defaultOrigin = `https://${effectiveDomain}`;\n productionEnv.CORS_ORIGIN = defaultOrigin;\n productionEnv.BASE_URL = defaultOrigin;\n warnings.push(`CORS_ORIGIN defaulting to ${defaultOrigin}`);\n }\n\n const requiredSecrets = new Set<string>();\n const missingSecrets: string[] = [];\n\n if (runtimeConfig.host.secrets) {\n for (const s of runtimeConfig.host.secrets) requiredSecrets.add(s);\n }\n if (runtimeConfig.auth?.secrets) {\n for (const s of runtimeConfig.auth.secrets) requiredSecrets.add(s);\n }\n if (runtimeConfig.api?.secrets) {\n for (const s of runtimeConfig.api.secrets) requiredSecrets.add(s);\n }\n for (const plugin of Object.values(runtimeConfig.plugins ?? {})) {\n if (plugin.secrets) {\n for (const s of plugin.secrets) {\n if (s.endsWith(\"_DATABASE_URL\")) continue;\n requiredSecrets.add(s);\n }\n }\n }\n\n for (const secret of requiredSecrets) {\n const value = getProcessEnv(secret);\n if (!value || value.length === 0) {\n missingSecrets.push(secret);\n }\n }\n\n if (missingSecrets.length > 0) {\n warnings.push(`Missing ${missingSecrets.length} secret(s): ${missingSecrets.join(\", \")}`);\n }\n\n for (const [secret, value] of Object.entries(processEnvRecord())) {\n if (!value || !secret.endsWith(\"_DATABASE_URL\")) continue;\n if (isRailwayPublicProxyUrl(value)) {\n const host = new URL(value).hostname;\n warnings.push(\n `${secret} points at Railway's public proxy (${host}) — its TLS certificate is self-signed, ` +\n `so connections use unverified TLS. Prefer the private *.railway.internal URL when the ` +\n `database runs in the same Railway project.`,\n );\n }\n }\n\n const stagingEnvVars: Record<string, string> = isStaging\n ? { BOS_GATEWAY: baseConfig.staging?.domain ?? baseConfig.domain ?? \"\" }\n : {};\n\n const plan: InfraPlan = yield* planInfra({\n configDir: sessionRoot,\n bosConfig: runtimeConfig,\n cli: {\n port: input.port,\n ssr: false,\n proxy: false,\n hostSource: \"remote\",\n uiSource: \"remote\",\n apiSource: \"remote\",\n authSource: \"remote\",\n interactive: input.interactive,\n },\n });\n\n const services = buildServiceDescriptorMap(plan.runtimeConfig);\n\n const configSource = explicitConfig.configPath\n ? explicitConfig.configPath\n : remoteConfig\n ? `bos://${explicitConfig.registry?.account}/${explicitConfig.registry?.domain}`\n : (findConfigPath() ?? \"bos.config.json\");\n\n const configSourceHttp =\n remoteConfig && explicitConfig.registry\n ? buildRegistryConfigUrl(\n explicitConfig.registry.account,\n explicitConfig.registry.domain,\n input.registry,\n )\n : undefined;\n\n const summary: StartSummary = {\n configSource,\n configSourceHttp,\n account: baseConfig.account,\n domain: baseConfig.domain ?? undefined,\n modules: {\n host: plan.runtimeConfig.host.remoteUrl ?? plan.runtimeConfig.host.url ?? \"local\",\n ui: plan.runtimeConfig.ui.url ?? \"local\",\n api: plan.runtimeConfig.api.url ?? \"local\",\n auth: plan.runtimeConfig.auth?.url ?? undefined,\n },\n warnings,\n };\n\n const orchestrator: AppOrchestrator = {\n packages: [\"host\"],\n env: {\n NODE_ENV: \"production\",\n ...productionEnv,\n ...stagingEnvVars,\n ...plan.launch.env,\n },\n description: `${isStaging ? \"Staging\" : \"Production\"} Mode (${baseConfig.account})`,\n port: plan.resolvedPorts.host ?? port,\n interactive: input.interactive,\n noLogs: true,\n };\n\n yield* emitProgress({ phase: \"config\", status: \"done\" });\n\n return {\n session: {\n orchestrator,\n services,\n runtimeConfig: plan.runtimeConfig,\n envGenerated: plan.envGenerated,\n shellEnv: shell,\n } satisfies DevSessionData,\n summary,\n url: plan.launch.hostUrl ?? `http://localhost:${plan.resolvedPorts.host ?? port}`,\n };\n });\n\nexport const bootstrapLayers = Layer.mergeAll(ProjectEnvLive, PortAllocatorLive);\n"],"mappings":"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"}
|