everything-dev 1.51.2 → 1.51.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/fastkv.cjs +1 -1
- package/dist/fastkv.cjs.map +1 -1
- package/dist/fastkv.d.cts.map +1 -1
- package/dist/fastkv.d.mts.map +1 -1
- package/dist/fastkv.mjs +1 -1
- package/dist/fastkv.mjs.map +1 -1
- package/dist/infra/planner.cjs +1 -1
- package/dist/infra/planner.cjs.map +1 -1
- package/dist/infra/planner.mjs +1 -1
- package/dist/infra/planner.mjs.map +1 -1
- package/dist/ui/head.cjs +12 -7
- package/dist/ui/head.cjs.map +1 -1
- package/dist/ui/head.d.cts.map +1 -1
- package/dist/ui/head.d.mts.map +1 -1
- package/dist/ui/head.mjs +12 -7
- package/dist/ui/head.mjs.map +1 -1
- package/package.json +2 -2
package/dist/fastkv.cjs
CHANGED
|
@@ -33,7 +33,7 @@ function getRegistryConfigKey(accountId, gatewayId, pathSegments = []) {
|
|
|
33
33
|
return `apps/${accountId}/${gatewayId}${pathSegments.length > 0 ? `/${pathSegments.map((segment) => encodeURIComponent(segment)).join("/")}` : ""}/bos.config.json`;
|
|
34
34
|
}
|
|
35
35
|
function parseBosUrl(bosUrl) {
|
|
36
|
-
const match = bosUrl.match(/^bos:\/\/([^/]+)\/(.+)$/);
|
|
36
|
+
const match = bosUrl.split("#")[0].match(/^bos:\/\/([^/]+)\/(.+)$/);
|
|
37
37
|
if (!match?.[1] || !match[2]) throw new Error(`Invalid BOS URL: ${bosUrl}`);
|
|
38
38
|
const pathSegments = match[2].split("/").filter(Boolean).map((segment) => decodeURIComponent(segment));
|
|
39
39
|
if (pathSegments.length === 0) throw new Error(`Invalid BOS URL: ${bosUrl}`);
|
package/dist/fastkv.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fastkv.cjs","names":["fetchJsonOrNull"],"sources":["../src/fastkv.ts"],"sourcesContent":["export type NetworkId = \"mainnet\" | \"testnet\";\n\ninterface FastKvEntry {\n value: unknown;\n}\n\ninterface FastKvListResponse {\n entries?: Array<FastKvEntry | null>;\n}\n\nimport { fetchJsonOrNull } from \"./http-client\";\n\nfunction getNetworkIdForAccount(accountId: string): NetworkId {\n return accountId.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n\nexport function getFastKvBaseUrlForNetwork(network: NetworkId): string {\n return network === \"testnet\"\n ? process.env.REGISTRY_FASTKV_TESTNET_URL || \"https://kv.test.fastnear.com\"\n : process.env.REGISTRY_FASTKV_MAINNET_URL || \"https://kv.main.fastnear.com\";\n}\n\nfunction getFastKvBaseUrlForAccount(accountId: string): string {\n return getNetworkIdForAccount(accountId) === \"testnet\"\n ? getFastKvBaseUrlForNetwork(\"testnet\")\n : getFastKvBaseUrlForNetwork(\"mainnet\");\n}\n\nexport function buildRegistryConfigUrl(accountId: string, gatewayId: string): string {\n const baseUrl = getFastKvBaseUrlForAccount(accountId);\n const namespace = getRegistryNamespaceForAccount(accountId);\n const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function buildRegistryConfigUrlForNetwork(\n network: NetworkId,\n accountId: string,\n gatewayId: string,\n): string {\n const baseUrl = getFastKvBaseUrlForNetwork(network);\n const namespace = getRegistryNamespaceForNetwork(network);\n const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function getRegistryNamespaceForAccount(accountId: string): string {\n return accountId.endsWith(\".testnet\")\n ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nexport function getRegistryNamespaceForNetwork(network: NetworkId): string {\n return network === \"testnet\"\n ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nfunction getRegistryConfigKey(\n accountId: string,\n gatewayId: string,\n pathSegments: string[] = [],\n): string {\n const suffix =\n pathSegments.length > 0\n ? `/${pathSegments.map((segment) => encodeURIComponent(segment)).join(\"/\")}`\n : \"\";\n return `apps/${accountId}/${gatewayId}${suffix}/bos.config.json`;\n}\n\nexport function parseBosUrl(bosUrl: string): {\n accountId: string;\n gatewayId: string;\n pathSegments: string[];\n} {\n const
|
|
1
|
+
{"version":3,"file":"fastkv.cjs","names":["fetchJsonOrNull"],"sources":["../src/fastkv.ts"],"sourcesContent":["export type NetworkId = \"mainnet\" | \"testnet\";\n\ninterface FastKvEntry {\n value: unknown;\n}\n\ninterface FastKvListResponse {\n entries?: Array<FastKvEntry | null>;\n}\n\nimport { fetchJsonOrNull } from \"./http-client\";\n\nfunction getNetworkIdForAccount(accountId: string): NetworkId {\n return accountId.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n\nexport function getFastKvBaseUrlForNetwork(network: NetworkId): string {\n return network === \"testnet\"\n ? process.env.REGISTRY_FASTKV_TESTNET_URL || \"https://kv.test.fastnear.com\"\n : process.env.REGISTRY_FASTKV_MAINNET_URL || \"https://kv.main.fastnear.com\";\n}\n\nfunction getFastKvBaseUrlForAccount(accountId: string): string {\n return getNetworkIdForAccount(accountId) === \"testnet\"\n ? getFastKvBaseUrlForNetwork(\"testnet\")\n : getFastKvBaseUrlForNetwork(\"mainnet\");\n}\n\nexport function buildRegistryConfigUrl(accountId: string, gatewayId: string): string {\n const baseUrl = getFastKvBaseUrlForAccount(accountId);\n const namespace = getRegistryNamespaceForAccount(accountId);\n const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function buildRegistryConfigUrlForNetwork(\n network: NetworkId,\n accountId: string,\n gatewayId: string,\n): string {\n const baseUrl = getFastKvBaseUrlForNetwork(network);\n const namespace = getRegistryNamespaceForNetwork(network);\n const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function getRegistryNamespaceForAccount(accountId: string): string {\n return accountId.endsWith(\".testnet\")\n ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nexport function getRegistryNamespaceForNetwork(network: NetworkId): string {\n return network === \"testnet\"\n ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nfunction getRegistryConfigKey(\n accountId: string,\n gatewayId: string,\n pathSegments: string[] = [],\n): string {\n const suffix =\n pathSegments.length > 0\n ? `/${pathSegments.map((segment) => encodeURIComponent(segment)).join(\"/\")}`\n : \"\";\n return `apps/${accountId}/${gatewayId}${suffix}/bos.config.json`;\n}\n\nexport function parseBosUrl(bosUrl: string): {\n accountId: string;\n gatewayId: string;\n pathSegments: string[];\n} {\n const strippedUrl = bosUrl.split(\"#\")[0];\n const match = strippedUrl.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!match?.[1] || !match[2]) {\n throw new Error(`Invalid BOS URL: ${bosUrl}`);\n }\n\n const pathSegments = match[2]\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => decodeURIComponent(segment));\n if (pathSegments.length === 0) {\n throw new Error(`Invalid BOS URL: ${bosUrl}`);\n }\n\n const [gatewayId, ...pathSegmentsTail] = pathSegments;\n if (!gatewayId) {\n throw new Error(`Invalid BOS URL: ${bosUrl}`);\n }\n\n return {\n accountId: match[1],\n gatewayId,\n pathSegments: pathSegmentsTail,\n };\n}\n\nexport async function fetchBosConfigFromFastKv<T>(bosUrl: string): Promise<T> {\n const { accountId, gatewayId, pathSegments } = parseBosUrl(bosUrl);\n const payload = await fetchJson<FastKvListResponse>(\n `${getFastKvBaseUrlForAccount(accountId)}/v0/latest/${encodeURIComponent(getRegistryNamespaceForAccount(accountId))}/${encodeURIComponent(accountId)}`,\n {\n method: \"POST\",\n body: JSON.stringify({\n key: getRegistryConfigKey(accountId, gatewayId, pathSegments),\n limit: 1,\n }),\n },\n );\n const value = payload?.entries?.find(Boolean)?.value;\n\n if (!value) {\n throw new Error(`No config found for ${bosUrl}`);\n }\n\n if (typeof value === \"string\") {\n return JSON.parse(value) as T;\n }\n\n if (typeof value !== \"object\") {\n throw new Error(`Invalid config value for ${bosUrl}`);\n }\n\n return value as T;\n}\n\nexport interface PluginManifest {\n schemaVersion: number;\n kind: string;\n plugin: { name: string; version: string };\n runtime: { remoteEntry: string };\n contract: {\n kind: string;\n types: { path: string; exportName: string; typeName: string; sha256: string };\n };\n additionalExports?: Array<{ path: string; exports: string[]; sha256: string }>;\n}\n\nexport async function fetchRemotePluginManifest(cdnUrl: string): Promise<PluginManifest | null> {\n const baseUrl = cdnUrl.replace(/\\/$/, \"\");\n return fetchJsonOrNull<PluginManifest>(`${baseUrl}/plugin.manifest.json`, { retries: 0 });\n}\n\nasync function fetchJson<T>(url: string, init?: RequestInit): Promise<T | null> {\n const headers: Record<string, string> = {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n ...(init?.headers as Record<string, string> | undefined),\n };\n return fetchJsonOrNull<T>(url, {\n method: init?.method,\n headers,\n body: init?.body ?? undefined,\n retries: 3,\n });\n}\n"],"mappings":"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"}
|
package/dist/fastkv.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fastkv.d.cts","names":[],"sources":["../src/fastkv.ts"],"mappings":";KAAY,SAAA;AAAA,iBAgBI,0BAAA,CAA2B,OAAA,EAAS,SAAA;AAAA,iBAYpC,sBAAA,CAAuB,SAAA,UAAmB,SAAA;AAAA,iBAO1C,gCAAA,CACd,OAAA,EAAS,SAAA,EACT,SAAA,UACA,SAAA;AAAA,iBAQc,8BAAA,CAA+B,SAAA;AAAA,iBAM/B,8BAAA,CAA+B,OAAA,EAAS,SAAA;AAAA,iBAkBxC,WAAA,CAAY,MAAA;EAC1B,SAAA;EACA,SAAA;EACA,YAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"fastkv.d.cts","names":[],"sources":["../src/fastkv.ts"],"mappings":";KAAY,SAAA;AAAA,iBAgBI,0BAAA,CAA2B,OAAA,EAAS,SAAA;AAAA,iBAYpC,sBAAA,CAAuB,SAAA,UAAmB,SAAA;AAAA,iBAO1C,gCAAA,CACd,OAAA,EAAS,SAAA,EACT,SAAA,UACA,SAAA;AAAA,iBAQc,8BAAA,CAA+B,SAAA;AAAA,iBAM/B,8BAAA,CAA+B,OAAA,EAAS,SAAA;AAAA,iBAkBxC,WAAA,CAAY,MAAA;EAC1B,SAAA;EACA,SAAA;EACA,YAAA;AAAA;AAAA,iBA4BoB,wBAAA,GAAA,CAA4B,MAAA,WAAiB,OAAA,CAAQ,CAAA;AAAA,UA6B1D,cAAA;EACf,aAAA;EACA,IAAA;EACA,MAAA;IAAU,IAAA;IAAc,OAAA;EAAA;EACxB,OAAA;IAAW,WAAA;EAAA;EACX,QAAA;IACE,IAAA;IACA,KAAA;MAAS,IAAA;MAAc,UAAA;MAAoB,QAAA;MAAkB,MAAA;IAAA;EAAA;EAE/D,iBAAA,GAAoB,KAAA;IAAQ,IAAA;IAAc,OAAA;IAAmB,MAAA;EAAA;AAAA;AAAA,iBAGzC,yBAAA,CAA0B,MAAA,WAAiB,OAAA,CAAQ,cAAA"}
|
package/dist/fastkv.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fastkv.d.mts","names":[],"sources":["../src/fastkv.ts"],"mappings":";KAAY,SAAA;AAAA,iBAgBI,0BAAA,CAA2B,OAAA,EAAS,SAAA;AAAA,iBAYpC,sBAAA,CAAuB,SAAA,UAAmB,SAAA;AAAA,iBAO1C,gCAAA,CACd,OAAA,EAAS,SAAA,EACT,SAAA,UACA,SAAA;AAAA,iBAQc,8BAAA,CAA+B,SAAA;AAAA,iBAM/B,8BAAA,CAA+B,OAAA,EAAS,SAAA;AAAA,iBAkBxC,WAAA,CAAY,MAAA;EAC1B,SAAA;EACA,SAAA;EACA,YAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"fastkv.d.mts","names":[],"sources":["../src/fastkv.ts"],"mappings":";KAAY,SAAA;AAAA,iBAgBI,0BAAA,CAA2B,OAAA,EAAS,SAAA;AAAA,iBAYpC,sBAAA,CAAuB,SAAA,UAAmB,SAAA;AAAA,iBAO1C,gCAAA,CACd,OAAA,EAAS,SAAA,EACT,SAAA,UACA,SAAA;AAAA,iBAQc,8BAAA,CAA+B,SAAA;AAAA,iBAM/B,8BAAA,CAA+B,OAAA,EAAS,SAAA;AAAA,iBAkBxC,WAAA,CAAY,MAAA;EAC1B,SAAA;EACA,SAAA;EACA,YAAA;AAAA;AAAA,iBA4BoB,wBAAA,GAAA,CAA4B,MAAA,WAAiB,OAAA,CAAQ,CAAA;AAAA,UA6B1D,cAAA;EACf,aAAA;EACA,IAAA;EACA,MAAA;IAAU,IAAA;IAAc,OAAA;EAAA;EACxB,OAAA;IAAW,WAAA;EAAA;EACX,QAAA;IACE,IAAA;IACA,KAAA;MAAS,IAAA;MAAc,UAAA;MAAoB,QAAA;MAAkB,MAAA;IAAA;EAAA;EAE/D,iBAAA,GAAoB,KAAA;IAAQ,IAAA;IAAc,OAAA;IAAmB,MAAA;EAAA;AAAA;AAAA,iBAGzC,yBAAA,CAA0B,MAAA,WAAiB,OAAA,CAAQ,cAAA"}
|
package/dist/fastkv.mjs
CHANGED
|
@@ -32,7 +32,7 @@ function getRegistryConfigKey(accountId, gatewayId, pathSegments = []) {
|
|
|
32
32
|
return `apps/${accountId}/${gatewayId}${pathSegments.length > 0 ? `/${pathSegments.map((segment) => encodeURIComponent(segment)).join("/")}` : ""}/bos.config.json`;
|
|
33
33
|
}
|
|
34
34
|
function parseBosUrl(bosUrl) {
|
|
35
|
-
const match = bosUrl.match(/^bos:\/\/([^/]+)\/(.+)$/);
|
|
35
|
+
const match = bosUrl.split("#")[0].match(/^bos:\/\/([^/]+)\/(.+)$/);
|
|
36
36
|
if (!match?.[1] || !match[2]) throw new Error(`Invalid BOS URL: ${bosUrl}`);
|
|
37
37
|
const pathSegments = match[2].split("/").filter(Boolean).map((segment) => decodeURIComponent(segment));
|
|
38
38
|
if (pathSegments.length === 0) throw new Error(`Invalid BOS URL: ${bosUrl}`);
|
package/dist/fastkv.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fastkv.mjs","names":[],"sources":["../src/fastkv.ts"],"sourcesContent":["export type NetworkId = \"mainnet\" | \"testnet\";\n\ninterface FastKvEntry {\n value: unknown;\n}\n\ninterface FastKvListResponse {\n entries?: Array<FastKvEntry | null>;\n}\n\nimport { fetchJsonOrNull } from \"./http-client\";\n\nfunction getNetworkIdForAccount(accountId: string): NetworkId {\n return accountId.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n\nexport function getFastKvBaseUrlForNetwork(network: NetworkId): string {\n return network === \"testnet\"\n ? process.env.REGISTRY_FASTKV_TESTNET_URL || \"https://kv.test.fastnear.com\"\n : process.env.REGISTRY_FASTKV_MAINNET_URL || \"https://kv.main.fastnear.com\";\n}\n\nfunction getFastKvBaseUrlForAccount(accountId: string): string {\n return getNetworkIdForAccount(accountId) === \"testnet\"\n ? getFastKvBaseUrlForNetwork(\"testnet\")\n : getFastKvBaseUrlForNetwork(\"mainnet\");\n}\n\nexport function buildRegistryConfigUrl(accountId: string, gatewayId: string): string {\n const baseUrl = getFastKvBaseUrlForAccount(accountId);\n const namespace = getRegistryNamespaceForAccount(accountId);\n const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function buildRegistryConfigUrlForNetwork(\n network: NetworkId,\n accountId: string,\n gatewayId: string,\n): string {\n const baseUrl = getFastKvBaseUrlForNetwork(network);\n const namespace = getRegistryNamespaceForNetwork(network);\n const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function getRegistryNamespaceForAccount(accountId: string): string {\n return accountId.endsWith(\".testnet\")\n ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nexport function getRegistryNamespaceForNetwork(network: NetworkId): string {\n return network === \"testnet\"\n ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nfunction getRegistryConfigKey(\n accountId: string,\n gatewayId: string,\n pathSegments: string[] = [],\n): string {\n const suffix =\n pathSegments.length > 0\n ? `/${pathSegments.map((segment) => encodeURIComponent(segment)).join(\"/\")}`\n : \"\";\n return `apps/${accountId}/${gatewayId}${suffix}/bos.config.json`;\n}\n\nexport function parseBosUrl(bosUrl: string): {\n accountId: string;\n gatewayId: string;\n pathSegments: string[];\n} {\n const
|
|
1
|
+
{"version":3,"file":"fastkv.mjs","names":[],"sources":["../src/fastkv.ts"],"sourcesContent":["export type NetworkId = \"mainnet\" | \"testnet\";\n\ninterface FastKvEntry {\n value: unknown;\n}\n\ninterface FastKvListResponse {\n entries?: Array<FastKvEntry | null>;\n}\n\nimport { fetchJsonOrNull } from \"./http-client\";\n\nfunction getNetworkIdForAccount(accountId: string): NetworkId {\n return accountId.endsWith(\".testnet\") ? \"testnet\" : \"mainnet\";\n}\n\nexport function getFastKvBaseUrlForNetwork(network: NetworkId): string {\n return network === \"testnet\"\n ? process.env.REGISTRY_FASTKV_TESTNET_URL || \"https://kv.test.fastnear.com\"\n : process.env.REGISTRY_FASTKV_MAINNET_URL || \"https://kv.main.fastnear.com\";\n}\n\nfunction getFastKvBaseUrlForAccount(accountId: string): string {\n return getNetworkIdForAccount(accountId) === \"testnet\"\n ? getFastKvBaseUrlForNetwork(\"testnet\")\n : getFastKvBaseUrlForNetwork(\"mainnet\");\n}\n\nexport function buildRegistryConfigUrl(accountId: string, gatewayId: string): string {\n const baseUrl = getFastKvBaseUrlForAccount(accountId);\n const namespace = getRegistryNamespaceForAccount(accountId);\n const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function buildRegistryConfigUrlForNetwork(\n network: NetworkId,\n accountId: string,\n gatewayId: string,\n): string {\n const baseUrl = getFastKvBaseUrlForNetwork(network);\n const namespace = getRegistryNamespaceForNetwork(network);\n const key = encodeURIComponent(getRegistryConfigKey(accountId, gatewayId));\n return `${baseUrl}/v0/latest/${encodeURIComponent(namespace)}/${encodeURIComponent(accountId)}/${key}`;\n}\n\nexport function getRegistryNamespaceForAccount(accountId: string): string {\n return accountId.endsWith(\".testnet\")\n ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nexport function getRegistryNamespaceForNetwork(network: NetworkId): string {\n return network === \"testnet\"\n ? process.env.REGISTRY_FASTKV_TESTNET_NAMESPACE || \"dev.everything.near\"\n : process.env.REGISTRY_FASTKV_MAINNET_NAMESPACE || \"dev.everything.near\";\n}\n\nfunction getRegistryConfigKey(\n accountId: string,\n gatewayId: string,\n pathSegments: string[] = [],\n): string {\n const suffix =\n pathSegments.length > 0\n ? `/${pathSegments.map((segment) => encodeURIComponent(segment)).join(\"/\")}`\n : \"\";\n return `apps/${accountId}/${gatewayId}${suffix}/bos.config.json`;\n}\n\nexport function parseBosUrl(bosUrl: string): {\n accountId: string;\n gatewayId: string;\n pathSegments: string[];\n} {\n const strippedUrl = bosUrl.split(\"#\")[0];\n const match = strippedUrl.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!match?.[1] || !match[2]) {\n throw new Error(`Invalid BOS URL: ${bosUrl}`);\n }\n\n const pathSegments = match[2]\n .split(\"/\")\n .filter(Boolean)\n .map((segment) => decodeURIComponent(segment));\n if (pathSegments.length === 0) {\n throw new Error(`Invalid BOS URL: ${bosUrl}`);\n }\n\n const [gatewayId, ...pathSegmentsTail] = pathSegments;\n if (!gatewayId) {\n throw new Error(`Invalid BOS URL: ${bosUrl}`);\n }\n\n return {\n accountId: match[1],\n gatewayId,\n pathSegments: pathSegmentsTail,\n };\n}\n\nexport async function fetchBosConfigFromFastKv<T>(bosUrl: string): Promise<T> {\n const { accountId, gatewayId, pathSegments } = parseBosUrl(bosUrl);\n const payload = await fetchJson<FastKvListResponse>(\n `${getFastKvBaseUrlForAccount(accountId)}/v0/latest/${encodeURIComponent(getRegistryNamespaceForAccount(accountId))}/${encodeURIComponent(accountId)}`,\n {\n method: \"POST\",\n body: JSON.stringify({\n key: getRegistryConfigKey(accountId, gatewayId, pathSegments),\n limit: 1,\n }),\n },\n );\n const value = payload?.entries?.find(Boolean)?.value;\n\n if (!value) {\n throw new Error(`No config found for ${bosUrl}`);\n }\n\n if (typeof value === \"string\") {\n return JSON.parse(value) as T;\n }\n\n if (typeof value !== \"object\") {\n throw new Error(`Invalid config value for ${bosUrl}`);\n }\n\n return value as T;\n}\n\nexport interface PluginManifest {\n schemaVersion: number;\n kind: string;\n plugin: { name: string; version: string };\n runtime: { remoteEntry: string };\n contract: {\n kind: string;\n types: { path: string; exportName: string; typeName: string; sha256: string };\n };\n additionalExports?: Array<{ path: string; exports: string[]; sha256: string }>;\n}\n\nexport async function fetchRemotePluginManifest(cdnUrl: string): Promise<PluginManifest | null> {\n const baseUrl = cdnUrl.replace(/\\/$/, \"\");\n return fetchJsonOrNull<PluginManifest>(`${baseUrl}/plugin.manifest.json`, { retries: 0 });\n}\n\nasync function fetchJson<T>(url: string, init?: RequestInit): Promise<T | null> {\n const headers: Record<string, string> = {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n ...(init?.headers as Record<string, string> | undefined),\n };\n return fetchJsonOrNull<T>(url, {\n method: init?.method,\n headers,\n body: init?.body ?? undefined,\n retries: 3,\n });\n}\n"],"mappings":";;;AAYA,SAAS,uBAAuB,WAA8B;AAC5D,QAAO,UAAU,SAAS,WAAW,GAAG,YAAY;;AAGtD,SAAgB,2BAA2B,SAA4B;AACrE,QAAO,YAAY,YACf,QAAQ,IAAI,+BAA+B,iCAC3C,QAAQ,IAAI,+BAA+B;;AAGjD,SAAS,2BAA2B,WAA2B;AAC7D,QAAO,uBAAuB,UAAU,KAAK,YACzC,2BAA2B,UAAU,GACrC,2BAA2B,UAAU;;AAG3C,SAAgB,uBAAuB,WAAmB,WAA2B;CACnF,MAAM,UAAU,2BAA2B,UAAU;CACrD,MAAM,YAAY,+BAA+B,UAAU;CAC3D,MAAM,MAAM,mBAAmB,qBAAqB,WAAW,UAAU,CAAC;AAC1E,QAAO,GAAG,QAAQ,aAAa,mBAAmB,UAAU,CAAC,GAAG,mBAAmB,UAAU,CAAC,GAAG;;AAGnG,SAAgB,iCACd,SACA,WACA,WACQ;CACR,MAAM,UAAU,2BAA2B,QAAQ;CACnD,MAAM,YAAY,+BAA+B,QAAQ;CACzD,MAAM,MAAM,mBAAmB,qBAAqB,WAAW,UAAU,CAAC;AAC1E,QAAO,GAAG,QAAQ,aAAa,mBAAmB,UAAU,CAAC,GAAG,mBAAmB,UAAU,CAAC,GAAG;;AAGnG,SAAgB,+BAA+B,WAA2B;AACxE,QAAO,UAAU,SAAS,WAAW,GACjC,QAAQ,IAAI,qCAAqC,wBACjD,QAAQ,IAAI,qCAAqC;;AAGvD,SAAgB,+BAA+B,SAA4B;AACzE,QAAO,YAAY,YACf,QAAQ,IAAI,qCAAqC,wBACjD,QAAQ,IAAI,qCAAqC;;AAGvD,SAAS,qBACP,WACA,WACA,eAAyB,EAAE,EACnB;AAKR,QAAO,QAAQ,UAAU,GAAG,YAH1B,aAAa,SAAS,IAClB,IAAI,aAAa,KAAK,YAAY,mBAAmB,QAAQ,CAAC,CAAC,KAAK,IAAI,KACxE,GACyC;;AAGjD,SAAgB,YAAY,QAI1B;CAEA,MAAM,QADc,OAAO,MAAM,IAAI,CAAC,GACZ,MAAM,0BAA0B;AAC1D,KAAI,CAAC,QAAQ,MAAM,CAAC,MAAM,GACxB,OAAM,IAAI,MAAM,oBAAoB,SAAS;CAG/C,MAAM,eAAe,MAAM,GACxB,MAAM,IAAI,CACV,OAAO,QAAQ,CACf,KAAK,YAAY,mBAAmB,QAAQ,CAAC;AAChD,KAAI,aAAa,WAAW,EAC1B,OAAM,IAAI,MAAM,oBAAoB,SAAS;CAG/C,MAAM,CAAC,WAAW,GAAG,oBAAoB;AACzC,KAAI,CAAC,UACH,OAAM,IAAI,MAAM,oBAAoB,SAAS;AAG/C,QAAO;EACL,WAAW,MAAM;EACjB;EACA,cAAc;EACf;;AAGH,eAAsB,yBAA4B,QAA4B;CAC5E,MAAM,EAAE,WAAW,WAAW,iBAAiB,YAAY,OAAO;CAWlE,MAAM,SAAQ,MAVQ,UACpB,GAAG,2BAA2B,UAAU,CAAC,aAAa,mBAAmB,+BAA+B,UAAU,CAAC,CAAC,GAAG,mBAAmB,UAAU,IACpJ;EACE,QAAQ;EACR,MAAM,KAAK,UAAU;GACnB,KAAK,qBAAqB,WAAW,WAAW,aAAa;GAC7D,OAAO;GACR,CAAC;EACH,CACF,GACsB,SAAS,KAAK,QAAQ,EAAE;AAE/C,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,uBAAuB,SAAS;AAGlD,KAAI,OAAO,UAAU,SACnB,QAAO,KAAK,MAAM,MAAM;AAG1B,KAAI,OAAO,UAAU,SACnB,OAAM,IAAI,MAAM,4BAA4B,SAAS;AAGvD,QAAO;;AAeT,eAAsB,0BAA0B,QAAgD;AAE9F,QAAO,gBAAgC,GADvB,OAAO,QAAQ,OAAO,GACW,CAAC,wBAAwB,EAAE,SAAS,GAAG,CAAC;;AAG3F,eAAe,UAAa,KAAa,MAAuC;CAC9E,MAAM,UAAkC;EACtC,QAAQ;EACR,gBAAgB;EAChB,GAAI,MAAM;EACX;AACD,QAAO,gBAAmB,KAAK;EAC7B,QAAQ,MAAM;EACd;EACA,MAAM,MAAM,QAAQ;EACpB,SAAS;EACV,CAAC"}
|
package/dist/infra/planner.cjs
CHANGED
|
@@ -268,7 +268,7 @@ function planInfra(input) {
|
|
|
268
268
|
postgres: pgPorts,
|
|
269
269
|
redis: rdPorts
|
|
270
270
|
};
|
|
271
|
-
require_infra.savePortState(input.configDir, {
|
|
271
|
+
if (process.env.BOS_NO_PERSIST_PORTS !== "1") require_infra.savePortState(input.configDir, {
|
|
272
272
|
postgresPorts: pgPorts,
|
|
273
273
|
redisPorts: rdPorts,
|
|
274
274
|
devPorts: devPortsState
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner.cjs","names":["Effect","loadPortState","PortAllocator","InfraError","getSecretGroups","buildOriginMap","buildDatabaseConfigs","buildRedisConfigs","buildDescription"],"sources":["../../src/infra/planner.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { Effect } from \"effect\";\nimport { PortAllocator } from \"../app\";\nimport {\n buildDatabaseConfigs,\n buildOriginMap,\n buildRedisConfigs,\n type DatabaseSecretConfig,\n getSecretGroups,\n loadPortState,\n type RedisSecretConfig,\n savePortState,\n} from \"../cli/infra\";\nimport { buildDescription } from \"../service-descriptor\";\nimport type { RuntimeConfig } from \"../types\";\nimport type {\n ClaimRecord,\n CliPorts,\n ComposeModelPlan,\n DatabasePlan,\n InfraInput,\n InfraPlan,\n RedisPlan,\n ResolvedPorts,\n RuntimeLaunchSpec,\n ServiceDescriptorPlan,\n} from \"./types\";\nimport { InfraError } from \"./types\";\n\nconst DEFAULT_HOST_PORT = 3000;\nconst DEFAULT_API_PORT = 3001;\nconst DEFAULT_AUTH_PORT = 3002;\nconst DEFAULT_UI_PORT = 3003;\nconst DEFAULT_PLUGIN_PORT_START = 3010;\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\n\nexport function workspaceKey(configDir: string): string {\n const hash = createHash(\"sha256\").update(resolve(configDir)).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\nfunction normalizeCliPorts(input: InfraInput[\"cli\"]): CliPorts {\n return {\n host: input.port,\n api: input.apiPort,\n auth: input.authPort,\n ui: input.uiPort,\n uiSsr: undefined,\n pluginsStart: input.pluginPortStart,\n plugins: input.plugins,\n };\n}\n\ninterface AllocateServicesResult {\n ports: ResolvedPorts;\n claims: ClaimRecord[];\n devPortsState: { host: number; api: number; auth: number; ui: number; pluginPortStart: number };\n}\n\nfunction allocateServices(\n cliPorts: CliPorts,\n plugins: Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >,\n configDir: string,\n): Effect.Effect<AllocateServicesResult, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const wKey = workspaceKey(configDir);\n const persisted = loadPortState(configDir).devPorts;\n const allocator = yield* PortAllocator;\n\n const hostPort = yield* allocator.pickAvailable(\n cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT,\n );\n\n const apiPort = yield* allocator.pickAvailable(\n cliPorts.api ?? persisted?.api ?? DEFAULT_API_PORT,\n );\n\n const authPort = yield* allocator.pickAvailable(\n cliPorts.auth ?? persisted?.auth ?? DEFAULT_AUTH_PORT,\n );\n\n const uiPort = yield* allocator.pickAvailable(cliPorts.ui ?? persisted?.ui ?? DEFAULT_UI_PORT);\n\n const uiSsrPort = yield* allocator.pickAvailable(cliPorts.uiSsr ?? uiPort + 1);\n\n const pluginApiPorts: Record<string, number> = {};\n const pluginUiPorts: Record<string, number> = {};\n\n const pluginKeys = Object.keys(plugins).sort();\n const pluginStart =\n cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? DEFAULT_PLUGIN_PORT_START;\n let nextPluginPort = pluginStart;\n for (const pluginId of pluginKeys) {\n const pluginCfg = plugins[pluginId];\n const preferred = cliPorts.plugins?.[pluginId]?.api ?? nextPluginPort;\n const pluginPort = yield* allocator.pickAvailable(preferred);\n pluginApiPorts[pluginId] = pluginPort;\n nextPluginPort = pluginPort + 1;\n\n if (\n pluginCfg?.source === \"local\" &&\n pluginCfg?.localPath &&\n pluginCfg?.ui?.source === \"local\"\n ) {\n const uiPreferred = cliPorts.plugins?.[pluginId]?.ui ?? nextPluginPort;\n const pluginUiPort = yield* allocator.pickAvailable(uiPreferred);\n pluginUiPorts[pluginId] = pluginUiPort;\n nextPluginPort = pluginUiPort + 1;\n }\n }\n\n const resolved: ResolvedPorts = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n uiSsr: uiSsrPort,\n plugins: Object.fromEntries(\n Object.entries(pluginApiPorts).map(([k, v]) => [k, { api: v, ui: pluginUiPorts[k] }]),\n ),\n postgres: {},\n redis: {},\n };\n\n const devPortsState = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n pluginPortStart: pluginStart,\n };\n\n const claimPorts: Record<string, number> = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n uiSsr: uiSsrPort,\n };\n for (const [id, port] of Object.entries(pluginApiPorts)) {\n claimPorts[`plugin:${id}`] = port;\n }\n for (const [id, port] of Object.entries(pluginUiPorts)) {\n claimPorts[`plugin-ui:${id}`] = port;\n }\n\n const claim: ClaimRecord = {\n resourceKey: `workspace:${wKey}`,\n pid: process.pid,\n configDir,\n ports: claimPorts,\n startedAt: Date.now(),\n };\n\n return { ports: resolved, claims: [claim], devPortsState };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-services\",\n message: `Port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nfunction allocateDatabases(\n runtimeConfig: RuntimeConfig,\n configDir: string,\n): Effect.Effect<\n {\n postgres: Record<string, number>;\n redis: Record<string, number>;\n dbs: DatabasePlan[];\n redisPlans: RedisPlan[];\n },\n InfraError,\n PortAllocator\n> {\n return Effect.gen(function* () {\n const persisted = loadPortState(configDir);\n const groups = getSecretGroups(runtimeConfig);\n const allSecrets = groups.flatMap((group) => group.secrets);\n const originMap = buildOriginMap(configDir, runtimeConfig);\n const allocator = yield* PortAllocator;\n\n const infraDatabases: DatabaseSecretConfig[] = yield* Effect.sync(() =>\n buildDatabaseConfigs(allSecrets, originMap, { ...persisted.postgresPorts }),\n );\n const infraRedis: RedisSecretConfig[] = yield* Effect.sync(() =>\n buildRedisConfigs(allSecrets, originMap, { ...persisted.redisPorts }),\n );\n\n const postgres: Record<string, number> = {};\n const dbs: DatabasePlan[] = [];\n for (const db of infraDatabases) {\n const port = yield* allocator.pickAvailable(db.port);\n postgres[db.slug] = port;\n dbs.push({\n secret: db.secret,\n slug: db.slug,\n port,\n dbName: db.databaseName,\n containerName: db.containerName,\n volumeName: db.volumeName,\n url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.slug}_db`,\n });\n }\n\n const redis: Record<string, number> = {};\n const redisPlans: RedisPlan[] = [];\n for (const r of infraRedis) {\n const port = yield* allocator.pickAvailable(r.port);\n redis[r.slug] = port;\n redisPlans.push({\n secret: r.secret,\n slug: r.slug,\n port,\n containerName: r.containerName,\n volumeName: r.volumeName,\n url: `redis://localhost:${port}`,\n });\n }\n\n return { postgres, redis, dbs, redisPlans };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-databases\",\n message: `Database port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nexport function buildServiceDescriptors(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): ServiceDescriptorPlan[] {\n const descriptors: ServiceDescriptorPlan[] = [];\n\n if (runtimeConfig.host) {\n const isLocal = runtimeConfig.host.source === \"local\";\n descriptors.push({\n key: \"host\",\n source: runtimeConfig.host.source,\n url: isLocal ? `http://localhost:${resolvedPorts.host}` : runtimeConfig.host.url,\n port: isLocal ? resolvedPorts.host : undefined,\n localPath: isLocal ? runtimeConfig.host.localPath : undefined,\n });\n }\n\n if (runtimeConfig.api) {\n const isLocal = runtimeConfig.api.source === \"local\";\n descriptors.push({\n key: \"api\",\n source: runtimeConfig.api.source,\n url: isLocal ? `http://localhost:${resolvedPorts.api}` : runtimeConfig.api.url,\n port: isLocal ? resolvedPorts.api : undefined,\n localPath: isLocal ? runtimeConfig.api.localPath : undefined,\n });\n }\n\n if (runtimeConfig.auth) {\n const isLocal = runtimeConfig.auth.source === \"local\";\n descriptors.push({\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: isLocal ? `http://localhost:${resolvedPorts.auth}` : runtimeConfig.auth.url,\n port: isLocal ? resolvedPorts.auth : undefined,\n localPath: isLocal ? runtimeConfig.auth.localPath : undefined,\n });\n }\n\n if (runtimeConfig.ui) {\n const isLocal = runtimeConfig.ui.source === \"local\";\n descriptors.push({\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: isLocal ? `http://localhost:${resolvedPorts.ui}` : runtimeConfig.ui.url,\n port: isLocal ? resolvedPorts.ui : undefined,\n localPath: isLocal ? runtimeConfig.ui.localPath : undefined,\n });\n if (isLocal && resolvedPorts.uiSsr) {\n descriptors.push({\n key: \"ui-ssr\",\n source: \"local\",\n url: `http://localhost:${resolvedPorts.uiSsr}`,\n port: resolvedPorts.uiSsr,\n localPath: runtimeConfig.ui.localPath,\n });\n }\n }\n\n if (runtimeConfig.plugins) {\n for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {\n const pluginIsLocal = pluginCfg.source === \"local\";\n const p = resolvedPorts.plugins[pluginId];\n if (pluginIsLocal && p?.api) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.api}`,\n port: p.api,\n localPath: pluginCfg.localPath,\n });\n }\n if (!pluginIsLocal && pluginCfg.url) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"remote\",\n url: pluginCfg.url,\n port: undefined,\n localPath: undefined,\n });\n }\n if (pluginIsLocal && p?.ui && pluginCfg.ui?.source === \"local\") {\n descriptors.push({\n key: `plugin-ui:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.ui}`,\n port: p.ui,\n localPath: pluginCfg.ui?.localPath,\n });\n }\n }\n }\n\n return descriptors;\n}\n\nexport function buildLaunchSpec(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): RuntimeLaunchSpec {\n const hostPort =\n runtimeConfig.host?.source === \"local\" ? resolvedPorts.host : runtimeConfig.host?.port;\n const corsOrigin = hostPort ? `http://localhost:${hostPort}` : `http://localhost:3000`;\n\n return {\n port: resolvedPorts.host,\n hostUrl: runtimeConfig.host?.url,\n corsOrigin,\n env: {\n ...(resolvedPorts.host ? { PORT: String(resolvedPorts.host) } : {}),\n ...(resolvedPorts.api ? { API_PORT: String(resolvedPorts.api) } : {}),\n ...(resolvedPorts.ui ? { UI_PORT: String(resolvedPorts.ui) } : {}),\n ...(resolvedPorts.auth ? { AUTH_PORT: String(resolvedPorts.auth) } : {}),\n },\n runtimeConfig,\n };\n}\n\nexport function buildComposeModel(dbs: DatabasePlan[], redisPlans: RedisPlan[]): ComposeModelPlan {\n return { databases: dbs, redis: redisPlans };\n}\n\nexport function buildEnvGenerated(\n resolvedPorts: ResolvedPorts,\n dbs: DatabasePlan[],\n redisPlans: RedisPlan[],\n): Record<string, string> {\n const env: Record<string, string> = {};\n\n if (resolvedPorts.host) {\n env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;\n }\n\n for (const db of dbs) {\n env[db.secret] = db.url;\n }\n for (const r of redisPlans) {\n env[r.secret] = r.url;\n }\n\n return env;\n}\n\nexport function planInfra(input: InfraInput): Effect.Effect<InfraPlan, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const cliPorts = normalizeCliPorts(input.cli);\n const wKey = workspaceKey(input.configDir);\n\n const plugins = (input.bosConfig.plugins ?? {}) as Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >;\n\n const {\n ports: svcPorts,\n claims,\n devPortsState,\n } = yield* allocateServices(cliPorts, plugins, input.configDir);\n\n const {\n dbs,\n redisPlans,\n postgres: pgPorts,\n redis: rdPorts,\n } = yield* allocateDatabases(input.bosConfig, input.configDir);\n\n const resolvedPorts: ResolvedPorts = {\n ...svcPorts,\n postgres: pgPorts,\n redis: rdPorts,\n };\n\n // Write merged state once after all allocations succeed\n savePortState(input.configDir, {\n postgresPorts: pgPorts,\n redisPorts: rdPorts,\n devPorts: devPortsState,\n });\n\n const hostIsLocal = input.bosConfig.host?.source === \"local\";\n const apiIsLocal = input.bosConfig.api?.source === \"local\";\n const uiIsLocal = input.bosConfig.ui?.source === \"local\";\n const authIsLocal = input.bosConfig.auth?.source === \"local\";\n const assignedRuntimeConfig: RuntimeConfig = {\n ...input.bosConfig,\n host: resolvedPorts.host\n ? {\n ...input.bosConfig.host,\n port: resolvedPorts.host,\n url: `http://localhost:${resolvedPorts.host}`,\n remoteUrl: !hostIsLocal\n ? (input.bosConfig.host.remoteUrl ?? input.bosConfig.host.url)\n : undefined,\n }\n : input.bosConfig.host,\n api:\n apiIsLocal && resolvedPorts.api\n ? {\n ...input.bosConfig.api,\n port: resolvedPorts.api,\n url: `http://localhost:${resolvedPorts.api}`,\n }\n : input.bosConfig.api,\n ui:\n uiIsLocal && resolvedPorts.ui\n ? {\n ...input.bosConfig.ui,\n port: resolvedPorts.ui,\n url: `http://localhost:${resolvedPorts.ui}`,\n }\n : input.bosConfig.ui,\n auth:\n authIsLocal && resolvedPorts.auth && input.bosConfig.auth\n ? {\n ...input.bosConfig.auth,\n port: resolvedPorts.auth,\n url: `http://localhost:${resolvedPorts.auth}`,\n }\n : input.bosConfig.auth,\n plugins: input.bosConfig.plugins\n ? Object.fromEntries(\n Object.entries(input.bosConfig.plugins).map(([id, p]) => {\n const pluginPort = resolvedPorts.plugins[id];\n if (p.source === \"local\" && pluginPort?.api) {\n return [\n id,\n { ...p, port: pluginPort.api, url: `http://localhost:${pluginPort.api}` },\n ];\n }\n return [id, p];\n }),\n )\n : undefined,\n };\n\n const serviceDescriptors = buildServiceDescriptors(input.bosConfig, resolvedPorts);\n\n const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);\n const composeModel = buildComposeModel(dbs, redisPlans);\n const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);\n\n const packages = serviceDescriptors.map((d) => d.key);\n const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));\n const description = buildDescription(descriptionMap);\n\n const orchestrator = {\n packages,\n env: {},\n description,\n port: resolvedPorts.host,\n interactive: input.cli.interactive,\n };\n\n return {\n workspaceKey: wKey,\n cliPorts,\n resolvedPorts,\n runtimeConfig: assignedRuntimeConfig,\n launch,\n description,\n serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),\n envGenerated,\n composeModel,\n claims,\n orchestrator,\n };\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"planner.cjs","names":["Effect","loadPortState","PortAllocator","InfraError","getSecretGroups","buildOriginMap","buildDatabaseConfigs","buildRedisConfigs","buildDescription"],"sources":["../../src/infra/planner.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { Effect } from \"effect\";\nimport { PortAllocator } from \"../app\";\nimport {\n buildDatabaseConfigs,\n buildOriginMap,\n buildRedisConfigs,\n type DatabaseSecretConfig,\n getSecretGroups,\n loadPortState,\n type RedisSecretConfig,\n savePortState,\n} from \"../cli/infra\";\nimport { buildDescription } from \"../service-descriptor\";\nimport type { RuntimeConfig } from \"../types\";\nimport type {\n ClaimRecord,\n CliPorts,\n ComposeModelPlan,\n DatabasePlan,\n InfraInput,\n InfraPlan,\n RedisPlan,\n ResolvedPorts,\n RuntimeLaunchSpec,\n ServiceDescriptorPlan,\n} from \"./types\";\nimport { InfraError } from \"./types\";\n\nconst DEFAULT_HOST_PORT = 3000;\nconst DEFAULT_API_PORT = 3001;\nconst DEFAULT_AUTH_PORT = 3002;\nconst DEFAULT_UI_PORT = 3003;\nconst DEFAULT_PLUGIN_PORT_START = 3010;\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\n\nexport function workspaceKey(configDir: string): string {\n const hash = createHash(\"sha256\").update(resolve(configDir)).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\nfunction normalizeCliPorts(input: InfraInput[\"cli\"]): CliPorts {\n return {\n host: input.port,\n api: input.apiPort,\n auth: input.authPort,\n ui: input.uiPort,\n uiSsr: undefined,\n pluginsStart: input.pluginPortStart,\n plugins: input.plugins,\n };\n}\n\ninterface AllocateServicesResult {\n ports: ResolvedPorts;\n claims: ClaimRecord[];\n devPortsState: { host: number; api: number; auth: number; ui: number; pluginPortStart: number };\n}\n\nfunction allocateServices(\n cliPorts: CliPorts,\n plugins: Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >,\n configDir: string,\n): Effect.Effect<AllocateServicesResult, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const wKey = workspaceKey(configDir);\n const persisted = loadPortState(configDir).devPorts;\n const allocator = yield* PortAllocator;\n\n const hostPort = yield* allocator.pickAvailable(\n cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT,\n );\n\n const apiPort = yield* allocator.pickAvailable(\n cliPorts.api ?? persisted?.api ?? DEFAULT_API_PORT,\n );\n\n const authPort = yield* allocator.pickAvailable(\n cliPorts.auth ?? persisted?.auth ?? DEFAULT_AUTH_PORT,\n );\n\n const uiPort = yield* allocator.pickAvailable(cliPorts.ui ?? persisted?.ui ?? DEFAULT_UI_PORT);\n\n const uiSsrPort = yield* allocator.pickAvailable(cliPorts.uiSsr ?? uiPort + 1);\n\n const pluginApiPorts: Record<string, number> = {};\n const pluginUiPorts: Record<string, number> = {};\n\n const pluginKeys = Object.keys(plugins).sort();\n const pluginStart =\n cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? DEFAULT_PLUGIN_PORT_START;\n let nextPluginPort = pluginStart;\n for (const pluginId of pluginKeys) {\n const pluginCfg = plugins[pluginId];\n const preferred = cliPorts.plugins?.[pluginId]?.api ?? nextPluginPort;\n const pluginPort = yield* allocator.pickAvailable(preferred);\n pluginApiPorts[pluginId] = pluginPort;\n nextPluginPort = pluginPort + 1;\n\n if (\n pluginCfg?.source === \"local\" &&\n pluginCfg?.localPath &&\n pluginCfg?.ui?.source === \"local\"\n ) {\n const uiPreferred = cliPorts.plugins?.[pluginId]?.ui ?? nextPluginPort;\n const pluginUiPort = yield* allocator.pickAvailable(uiPreferred);\n pluginUiPorts[pluginId] = pluginUiPort;\n nextPluginPort = pluginUiPort + 1;\n }\n }\n\n const resolved: ResolvedPorts = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n uiSsr: uiSsrPort,\n plugins: Object.fromEntries(\n Object.entries(pluginApiPorts).map(([k, v]) => [k, { api: v, ui: pluginUiPorts[k] }]),\n ),\n postgres: {},\n redis: {},\n };\n\n const devPortsState = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n pluginPortStart: pluginStart,\n };\n\n const claimPorts: Record<string, number> = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n uiSsr: uiSsrPort,\n };\n for (const [id, port] of Object.entries(pluginApiPorts)) {\n claimPorts[`plugin:${id}`] = port;\n }\n for (const [id, port] of Object.entries(pluginUiPorts)) {\n claimPorts[`plugin-ui:${id}`] = port;\n }\n\n const claim: ClaimRecord = {\n resourceKey: `workspace:${wKey}`,\n pid: process.pid,\n configDir,\n ports: claimPorts,\n startedAt: Date.now(),\n };\n\n return { ports: resolved, claims: [claim], devPortsState };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-services\",\n message: `Port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nfunction allocateDatabases(\n runtimeConfig: RuntimeConfig,\n configDir: string,\n): Effect.Effect<\n {\n postgres: Record<string, number>;\n redis: Record<string, number>;\n dbs: DatabasePlan[];\n redisPlans: RedisPlan[];\n },\n InfraError,\n PortAllocator\n> {\n return Effect.gen(function* () {\n const persisted = loadPortState(configDir);\n const groups = getSecretGroups(runtimeConfig);\n const allSecrets = groups.flatMap((group) => group.secrets);\n const originMap = buildOriginMap(configDir, runtimeConfig);\n const allocator = yield* PortAllocator;\n\n const infraDatabases: DatabaseSecretConfig[] = yield* Effect.sync(() =>\n buildDatabaseConfigs(allSecrets, originMap, { ...persisted.postgresPorts }),\n );\n const infraRedis: RedisSecretConfig[] = yield* Effect.sync(() =>\n buildRedisConfigs(allSecrets, originMap, { ...persisted.redisPorts }),\n );\n\n const postgres: Record<string, number> = {};\n const dbs: DatabasePlan[] = [];\n for (const db of infraDatabases) {\n const port = yield* allocator.pickAvailable(db.port);\n postgres[db.slug] = port;\n dbs.push({\n secret: db.secret,\n slug: db.slug,\n port,\n dbName: db.databaseName,\n containerName: db.containerName,\n volumeName: db.volumeName,\n url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.slug}_db`,\n });\n }\n\n const redis: Record<string, number> = {};\n const redisPlans: RedisPlan[] = [];\n for (const r of infraRedis) {\n const port = yield* allocator.pickAvailable(r.port);\n redis[r.slug] = port;\n redisPlans.push({\n secret: r.secret,\n slug: r.slug,\n port,\n containerName: r.containerName,\n volumeName: r.volumeName,\n url: `redis://localhost:${port}`,\n });\n }\n\n return { postgres, redis, dbs, redisPlans };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-databases\",\n message: `Database port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nexport function buildServiceDescriptors(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): ServiceDescriptorPlan[] {\n const descriptors: ServiceDescriptorPlan[] = [];\n\n if (runtimeConfig.host) {\n const isLocal = runtimeConfig.host.source === \"local\";\n descriptors.push({\n key: \"host\",\n source: runtimeConfig.host.source,\n url: isLocal ? `http://localhost:${resolvedPorts.host}` : runtimeConfig.host.url,\n port: isLocal ? resolvedPorts.host : undefined,\n localPath: isLocal ? runtimeConfig.host.localPath : undefined,\n });\n }\n\n if (runtimeConfig.api) {\n const isLocal = runtimeConfig.api.source === \"local\";\n descriptors.push({\n key: \"api\",\n source: runtimeConfig.api.source,\n url: isLocal ? `http://localhost:${resolvedPorts.api}` : runtimeConfig.api.url,\n port: isLocal ? resolvedPorts.api : undefined,\n localPath: isLocal ? runtimeConfig.api.localPath : undefined,\n });\n }\n\n if (runtimeConfig.auth) {\n const isLocal = runtimeConfig.auth.source === \"local\";\n descriptors.push({\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: isLocal ? `http://localhost:${resolvedPorts.auth}` : runtimeConfig.auth.url,\n port: isLocal ? resolvedPorts.auth : undefined,\n localPath: isLocal ? runtimeConfig.auth.localPath : undefined,\n });\n }\n\n if (runtimeConfig.ui) {\n const isLocal = runtimeConfig.ui.source === \"local\";\n descriptors.push({\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: isLocal ? `http://localhost:${resolvedPorts.ui}` : runtimeConfig.ui.url,\n port: isLocal ? resolvedPorts.ui : undefined,\n localPath: isLocal ? runtimeConfig.ui.localPath : undefined,\n });\n if (isLocal && resolvedPorts.uiSsr) {\n descriptors.push({\n key: \"ui-ssr\",\n source: \"local\",\n url: `http://localhost:${resolvedPorts.uiSsr}`,\n port: resolvedPorts.uiSsr,\n localPath: runtimeConfig.ui.localPath,\n });\n }\n }\n\n if (runtimeConfig.plugins) {\n for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {\n const pluginIsLocal = pluginCfg.source === \"local\";\n const p = resolvedPorts.plugins[pluginId];\n if (pluginIsLocal && p?.api) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.api}`,\n port: p.api,\n localPath: pluginCfg.localPath,\n });\n }\n if (!pluginIsLocal && pluginCfg.url) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"remote\",\n url: pluginCfg.url,\n port: undefined,\n localPath: undefined,\n });\n }\n if (pluginIsLocal && p?.ui && pluginCfg.ui?.source === \"local\") {\n descriptors.push({\n key: `plugin-ui:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.ui}`,\n port: p.ui,\n localPath: pluginCfg.ui?.localPath,\n });\n }\n }\n }\n\n return descriptors;\n}\n\nexport function buildLaunchSpec(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): RuntimeLaunchSpec {\n const hostPort =\n runtimeConfig.host?.source === \"local\" ? resolvedPorts.host : runtimeConfig.host?.port;\n const corsOrigin = hostPort ? `http://localhost:${hostPort}` : `http://localhost:3000`;\n\n return {\n port: resolvedPorts.host,\n hostUrl: runtimeConfig.host?.url,\n corsOrigin,\n env: {\n ...(resolvedPorts.host ? { PORT: String(resolvedPorts.host) } : {}),\n ...(resolvedPorts.api ? { API_PORT: String(resolvedPorts.api) } : {}),\n ...(resolvedPorts.ui ? { UI_PORT: String(resolvedPorts.ui) } : {}),\n ...(resolvedPorts.auth ? { AUTH_PORT: String(resolvedPorts.auth) } : {}),\n },\n runtimeConfig,\n };\n}\n\nexport function buildComposeModel(dbs: DatabasePlan[], redisPlans: RedisPlan[]): ComposeModelPlan {\n return { databases: dbs, redis: redisPlans };\n}\n\nexport function buildEnvGenerated(\n resolvedPorts: ResolvedPorts,\n dbs: DatabasePlan[],\n redisPlans: RedisPlan[],\n): Record<string, string> {\n const env: Record<string, string> = {};\n\n if (resolvedPorts.host) {\n env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;\n }\n\n for (const db of dbs) {\n env[db.secret] = db.url;\n }\n for (const r of redisPlans) {\n env[r.secret] = r.url;\n }\n\n return env;\n}\n\nexport function planInfra(input: InfraInput): Effect.Effect<InfraPlan, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const cliPorts = normalizeCliPorts(input.cli);\n const wKey = workspaceKey(input.configDir);\n\n const plugins = (input.bosConfig.plugins ?? {}) as Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >;\n\n const {\n ports: svcPorts,\n claims,\n devPortsState,\n } = yield* allocateServices(cliPorts, plugins, input.configDir);\n\n const {\n dbs,\n redisPlans,\n postgres: pgPorts,\n redis: rdPorts,\n } = yield* allocateDatabases(input.bosConfig, input.configDir);\n\n const resolvedPorts: ResolvedPorts = {\n ...svcPorts,\n postgres: pgPorts,\n redis: rdPorts,\n };\n\n // Write merged state once after all allocations succeed\n // Skip persistence for regression tests / ephemeral runs\n if (process.env.BOS_NO_PERSIST_PORTS !== \"1\") {\n savePortState(input.configDir, {\n postgresPorts: pgPorts,\n redisPorts: rdPorts,\n devPorts: devPortsState,\n });\n }\n\n const hostIsLocal = input.bosConfig.host?.source === \"local\";\n const apiIsLocal = input.bosConfig.api?.source === \"local\";\n const uiIsLocal = input.bosConfig.ui?.source === \"local\";\n const authIsLocal = input.bosConfig.auth?.source === \"local\";\n const assignedRuntimeConfig: RuntimeConfig = {\n ...input.bosConfig,\n host: resolvedPorts.host\n ? {\n ...input.bosConfig.host,\n port: resolvedPorts.host,\n url: `http://localhost:${resolvedPorts.host}`,\n remoteUrl: !hostIsLocal\n ? (input.bosConfig.host.remoteUrl ?? input.bosConfig.host.url)\n : undefined,\n }\n : input.bosConfig.host,\n api:\n apiIsLocal && resolvedPorts.api\n ? {\n ...input.bosConfig.api,\n port: resolvedPorts.api,\n url: `http://localhost:${resolvedPorts.api}`,\n }\n : input.bosConfig.api,\n ui:\n uiIsLocal && resolvedPorts.ui\n ? {\n ...input.bosConfig.ui,\n port: resolvedPorts.ui,\n url: `http://localhost:${resolvedPorts.ui}`,\n }\n : input.bosConfig.ui,\n auth:\n authIsLocal && resolvedPorts.auth && input.bosConfig.auth\n ? {\n ...input.bosConfig.auth,\n port: resolvedPorts.auth,\n url: `http://localhost:${resolvedPorts.auth}`,\n }\n : input.bosConfig.auth,\n plugins: input.bosConfig.plugins\n ? Object.fromEntries(\n Object.entries(input.bosConfig.plugins).map(([id, p]) => {\n const pluginPort = resolvedPorts.plugins[id];\n if (p.source === \"local\" && pluginPort?.api) {\n return [\n id,\n { ...p, port: pluginPort.api, url: `http://localhost:${pluginPort.api}` },\n ];\n }\n return [id, p];\n }),\n )\n : undefined,\n };\n\n const serviceDescriptors = buildServiceDescriptors(input.bosConfig, resolvedPorts);\n\n const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);\n const composeModel = buildComposeModel(dbs, redisPlans);\n const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);\n\n const packages = serviceDescriptors.map((d) => d.key);\n const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));\n const description = buildDescription(descriptionMap);\n\n const orchestrator = {\n packages,\n env: {},\n description,\n port: resolvedPorts.host,\n interactive: input.cli.interactive,\n };\n\n return {\n workspaceKey: wKey,\n cliPorts,\n resolvedPorts,\n runtimeConfig: assignedRuntimeConfig,\n launch,\n description,\n serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),\n envGenerated,\n composeModel,\n claims,\n orchestrator,\n };\n });\n}\n"],"mappings":"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"}
|
package/dist/infra/planner.mjs
CHANGED
|
@@ -267,7 +267,7 @@ function planInfra(input) {
|
|
|
267
267
|
postgres: pgPorts,
|
|
268
268
|
redis: rdPorts
|
|
269
269
|
};
|
|
270
|
-
savePortState(input.configDir, {
|
|
270
|
+
if (process.env.BOS_NO_PERSIST_PORTS !== "1") savePortState(input.configDir, {
|
|
271
271
|
postgresPorts: pgPorts,
|
|
272
272
|
redisPorts: rdPorts,
|
|
273
273
|
devPorts: devPortsState
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner.mjs","names":[],"sources":["../../src/infra/planner.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { Effect } from \"effect\";\nimport { PortAllocator } from \"../app\";\nimport {\n buildDatabaseConfigs,\n buildOriginMap,\n buildRedisConfigs,\n type DatabaseSecretConfig,\n getSecretGroups,\n loadPortState,\n type RedisSecretConfig,\n savePortState,\n} from \"../cli/infra\";\nimport { buildDescription } from \"../service-descriptor\";\nimport type { RuntimeConfig } from \"../types\";\nimport type {\n ClaimRecord,\n CliPorts,\n ComposeModelPlan,\n DatabasePlan,\n InfraInput,\n InfraPlan,\n RedisPlan,\n ResolvedPorts,\n RuntimeLaunchSpec,\n ServiceDescriptorPlan,\n} from \"./types\";\nimport { InfraError } from \"./types\";\n\nconst DEFAULT_HOST_PORT = 3000;\nconst DEFAULT_API_PORT = 3001;\nconst DEFAULT_AUTH_PORT = 3002;\nconst DEFAULT_UI_PORT = 3003;\nconst DEFAULT_PLUGIN_PORT_START = 3010;\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\n\nexport function workspaceKey(configDir: string): string {\n const hash = createHash(\"sha256\").update(resolve(configDir)).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\nfunction normalizeCliPorts(input: InfraInput[\"cli\"]): CliPorts {\n return {\n host: input.port,\n api: input.apiPort,\n auth: input.authPort,\n ui: input.uiPort,\n uiSsr: undefined,\n pluginsStart: input.pluginPortStart,\n plugins: input.plugins,\n };\n}\n\ninterface AllocateServicesResult {\n ports: ResolvedPorts;\n claims: ClaimRecord[];\n devPortsState: { host: number; api: number; auth: number; ui: number; pluginPortStart: number };\n}\n\nfunction allocateServices(\n cliPorts: CliPorts,\n plugins: Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >,\n configDir: string,\n): Effect.Effect<AllocateServicesResult, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const wKey = workspaceKey(configDir);\n const persisted = loadPortState(configDir).devPorts;\n const allocator = yield* PortAllocator;\n\n const hostPort = yield* allocator.pickAvailable(\n cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT,\n );\n\n const apiPort = yield* allocator.pickAvailable(\n cliPorts.api ?? persisted?.api ?? DEFAULT_API_PORT,\n );\n\n const authPort = yield* allocator.pickAvailable(\n cliPorts.auth ?? persisted?.auth ?? DEFAULT_AUTH_PORT,\n );\n\n const uiPort = yield* allocator.pickAvailable(cliPorts.ui ?? persisted?.ui ?? DEFAULT_UI_PORT);\n\n const uiSsrPort = yield* allocator.pickAvailable(cliPorts.uiSsr ?? uiPort + 1);\n\n const pluginApiPorts: Record<string, number> = {};\n const pluginUiPorts: Record<string, number> = {};\n\n const pluginKeys = Object.keys(plugins).sort();\n const pluginStart =\n cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? DEFAULT_PLUGIN_PORT_START;\n let nextPluginPort = pluginStart;\n for (const pluginId of pluginKeys) {\n const pluginCfg = plugins[pluginId];\n const preferred = cliPorts.plugins?.[pluginId]?.api ?? nextPluginPort;\n const pluginPort = yield* allocator.pickAvailable(preferred);\n pluginApiPorts[pluginId] = pluginPort;\n nextPluginPort = pluginPort + 1;\n\n if (\n pluginCfg?.source === \"local\" &&\n pluginCfg?.localPath &&\n pluginCfg?.ui?.source === \"local\"\n ) {\n const uiPreferred = cliPorts.plugins?.[pluginId]?.ui ?? nextPluginPort;\n const pluginUiPort = yield* allocator.pickAvailable(uiPreferred);\n pluginUiPorts[pluginId] = pluginUiPort;\n nextPluginPort = pluginUiPort + 1;\n }\n }\n\n const resolved: ResolvedPorts = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n uiSsr: uiSsrPort,\n plugins: Object.fromEntries(\n Object.entries(pluginApiPorts).map(([k, v]) => [k, { api: v, ui: pluginUiPorts[k] }]),\n ),\n postgres: {},\n redis: {},\n };\n\n const devPortsState = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n pluginPortStart: pluginStart,\n };\n\n const claimPorts: Record<string, number> = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n uiSsr: uiSsrPort,\n };\n for (const [id, port] of Object.entries(pluginApiPorts)) {\n claimPorts[`plugin:${id}`] = port;\n }\n for (const [id, port] of Object.entries(pluginUiPorts)) {\n claimPorts[`plugin-ui:${id}`] = port;\n }\n\n const claim: ClaimRecord = {\n resourceKey: `workspace:${wKey}`,\n pid: process.pid,\n configDir,\n ports: claimPorts,\n startedAt: Date.now(),\n };\n\n return { ports: resolved, claims: [claim], devPortsState };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-services\",\n message: `Port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nfunction allocateDatabases(\n runtimeConfig: RuntimeConfig,\n configDir: string,\n): Effect.Effect<\n {\n postgres: Record<string, number>;\n redis: Record<string, number>;\n dbs: DatabasePlan[];\n redisPlans: RedisPlan[];\n },\n InfraError,\n PortAllocator\n> {\n return Effect.gen(function* () {\n const persisted = loadPortState(configDir);\n const groups = getSecretGroups(runtimeConfig);\n const allSecrets = groups.flatMap((group) => group.secrets);\n const originMap = buildOriginMap(configDir, runtimeConfig);\n const allocator = yield* PortAllocator;\n\n const infraDatabases: DatabaseSecretConfig[] = yield* Effect.sync(() =>\n buildDatabaseConfigs(allSecrets, originMap, { ...persisted.postgresPorts }),\n );\n const infraRedis: RedisSecretConfig[] = yield* Effect.sync(() =>\n buildRedisConfigs(allSecrets, originMap, { ...persisted.redisPorts }),\n );\n\n const postgres: Record<string, number> = {};\n const dbs: DatabasePlan[] = [];\n for (const db of infraDatabases) {\n const port = yield* allocator.pickAvailable(db.port);\n postgres[db.slug] = port;\n dbs.push({\n secret: db.secret,\n slug: db.slug,\n port,\n dbName: db.databaseName,\n containerName: db.containerName,\n volumeName: db.volumeName,\n url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.slug}_db`,\n });\n }\n\n const redis: Record<string, number> = {};\n const redisPlans: RedisPlan[] = [];\n for (const r of infraRedis) {\n const port = yield* allocator.pickAvailable(r.port);\n redis[r.slug] = port;\n redisPlans.push({\n secret: r.secret,\n slug: r.slug,\n port,\n containerName: r.containerName,\n volumeName: r.volumeName,\n url: `redis://localhost:${port}`,\n });\n }\n\n return { postgres, redis, dbs, redisPlans };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-databases\",\n message: `Database port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nexport function buildServiceDescriptors(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): ServiceDescriptorPlan[] {\n const descriptors: ServiceDescriptorPlan[] = [];\n\n if (runtimeConfig.host) {\n const isLocal = runtimeConfig.host.source === \"local\";\n descriptors.push({\n key: \"host\",\n source: runtimeConfig.host.source,\n url: isLocal ? `http://localhost:${resolvedPorts.host}` : runtimeConfig.host.url,\n port: isLocal ? resolvedPorts.host : undefined,\n localPath: isLocal ? runtimeConfig.host.localPath : undefined,\n });\n }\n\n if (runtimeConfig.api) {\n const isLocal = runtimeConfig.api.source === \"local\";\n descriptors.push({\n key: \"api\",\n source: runtimeConfig.api.source,\n url: isLocal ? `http://localhost:${resolvedPorts.api}` : runtimeConfig.api.url,\n port: isLocal ? resolvedPorts.api : undefined,\n localPath: isLocal ? runtimeConfig.api.localPath : undefined,\n });\n }\n\n if (runtimeConfig.auth) {\n const isLocal = runtimeConfig.auth.source === \"local\";\n descriptors.push({\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: isLocal ? `http://localhost:${resolvedPorts.auth}` : runtimeConfig.auth.url,\n port: isLocal ? resolvedPorts.auth : undefined,\n localPath: isLocal ? runtimeConfig.auth.localPath : undefined,\n });\n }\n\n if (runtimeConfig.ui) {\n const isLocal = runtimeConfig.ui.source === \"local\";\n descriptors.push({\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: isLocal ? `http://localhost:${resolvedPorts.ui}` : runtimeConfig.ui.url,\n port: isLocal ? resolvedPorts.ui : undefined,\n localPath: isLocal ? runtimeConfig.ui.localPath : undefined,\n });\n if (isLocal && resolvedPorts.uiSsr) {\n descriptors.push({\n key: \"ui-ssr\",\n source: \"local\",\n url: `http://localhost:${resolvedPorts.uiSsr}`,\n port: resolvedPorts.uiSsr,\n localPath: runtimeConfig.ui.localPath,\n });\n }\n }\n\n if (runtimeConfig.plugins) {\n for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {\n const pluginIsLocal = pluginCfg.source === \"local\";\n const p = resolvedPorts.plugins[pluginId];\n if (pluginIsLocal && p?.api) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.api}`,\n port: p.api,\n localPath: pluginCfg.localPath,\n });\n }\n if (!pluginIsLocal && pluginCfg.url) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"remote\",\n url: pluginCfg.url,\n port: undefined,\n localPath: undefined,\n });\n }\n if (pluginIsLocal && p?.ui && pluginCfg.ui?.source === \"local\") {\n descriptors.push({\n key: `plugin-ui:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.ui}`,\n port: p.ui,\n localPath: pluginCfg.ui?.localPath,\n });\n }\n }\n }\n\n return descriptors;\n}\n\nexport function buildLaunchSpec(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): RuntimeLaunchSpec {\n const hostPort =\n runtimeConfig.host?.source === \"local\" ? resolvedPorts.host : runtimeConfig.host?.port;\n const corsOrigin = hostPort ? `http://localhost:${hostPort}` : `http://localhost:3000`;\n\n return {\n port: resolvedPorts.host,\n hostUrl: runtimeConfig.host?.url,\n corsOrigin,\n env: {\n ...(resolvedPorts.host ? { PORT: String(resolvedPorts.host) } : {}),\n ...(resolvedPorts.api ? { API_PORT: String(resolvedPorts.api) } : {}),\n ...(resolvedPorts.ui ? { UI_PORT: String(resolvedPorts.ui) } : {}),\n ...(resolvedPorts.auth ? { AUTH_PORT: String(resolvedPorts.auth) } : {}),\n },\n runtimeConfig,\n };\n}\n\nexport function buildComposeModel(dbs: DatabasePlan[], redisPlans: RedisPlan[]): ComposeModelPlan {\n return { databases: dbs, redis: redisPlans };\n}\n\nexport function buildEnvGenerated(\n resolvedPorts: ResolvedPorts,\n dbs: DatabasePlan[],\n redisPlans: RedisPlan[],\n): Record<string, string> {\n const env: Record<string, string> = {};\n\n if (resolvedPorts.host) {\n env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;\n }\n\n for (const db of dbs) {\n env[db.secret] = db.url;\n }\n for (const r of redisPlans) {\n env[r.secret] = r.url;\n }\n\n return env;\n}\n\nexport function planInfra(input: InfraInput): Effect.Effect<InfraPlan, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const cliPorts = normalizeCliPorts(input.cli);\n const wKey = workspaceKey(input.configDir);\n\n const plugins = (input.bosConfig.plugins ?? {}) as Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >;\n\n const {\n ports: svcPorts,\n claims,\n devPortsState,\n } = yield* allocateServices(cliPorts, plugins, input.configDir);\n\n const {\n dbs,\n redisPlans,\n postgres: pgPorts,\n redis: rdPorts,\n } = yield* allocateDatabases(input.bosConfig, input.configDir);\n\n const resolvedPorts: ResolvedPorts = {\n ...svcPorts,\n postgres: pgPorts,\n redis: rdPorts,\n };\n\n // Write merged state once after all allocations succeed\n savePortState(input.configDir, {\n postgresPorts: pgPorts,\n redisPorts: rdPorts,\n devPorts: devPortsState,\n });\n\n const hostIsLocal = input.bosConfig.host?.source === \"local\";\n const apiIsLocal = input.bosConfig.api?.source === \"local\";\n const uiIsLocal = input.bosConfig.ui?.source === \"local\";\n const authIsLocal = input.bosConfig.auth?.source === \"local\";\n const assignedRuntimeConfig: RuntimeConfig = {\n ...input.bosConfig,\n host: resolvedPorts.host\n ? {\n ...input.bosConfig.host,\n port: resolvedPorts.host,\n url: `http://localhost:${resolvedPorts.host}`,\n remoteUrl: !hostIsLocal\n ? (input.bosConfig.host.remoteUrl ?? input.bosConfig.host.url)\n : undefined,\n }\n : input.bosConfig.host,\n api:\n apiIsLocal && resolvedPorts.api\n ? {\n ...input.bosConfig.api,\n port: resolvedPorts.api,\n url: `http://localhost:${resolvedPorts.api}`,\n }\n : input.bosConfig.api,\n ui:\n uiIsLocal && resolvedPorts.ui\n ? {\n ...input.bosConfig.ui,\n port: resolvedPorts.ui,\n url: `http://localhost:${resolvedPorts.ui}`,\n }\n : input.bosConfig.ui,\n auth:\n authIsLocal && resolvedPorts.auth && input.bosConfig.auth\n ? {\n ...input.bosConfig.auth,\n port: resolvedPorts.auth,\n url: `http://localhost:${resolvedPorts.auth}`,\n }\n : input.bosConfig.auth,\n plugins: input.bosConfig.plugins\n ? Object.fromEntries(\n Object.entries(input.bosConfig.plugins).map(([id, p]) => {\n const pluginPort = resolvedPorts.plugins[id];\n if (p.source === \"local\" && pluginPort?.api) {\n return [\n id,\n { ...p, port: pluginPort.api, url: `http://localhost:${pluginPort.api}` },\n ];\n }\n return [id, p];\n }),\n )\n : undefined,\n };\n\n const serviceDescriptors = buildServiceDescriptors(input.bosConfig, resolvedPorts);\n\n const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);\n const composeModel = buildComposeModel(dbs, redisPlans);\n const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);\n\n const packages = serviceDescriptors.map((d) => d.key);\n const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));\n const description = buildDescription(descriptionMap);\n\n const orchestrator = {\n packages,\n env: {},\n description,\n port: resolvedPorts.host,\n interactive: input.cli.interactive,\n };\n\n return {\n workspaceKey: wKey,\n cliPorts,\n resolvedPorts,\n runtimeConfig: assignedRuntimeConfig,\n launch,\n description,\n serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),\n envGenerated,\n composeModel,\n claims,\n orchestrator,\n };\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"planner.mjs","names":[],"sources":["../../src/infra/planner.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport { Effect } from \"effect\";\nimport { PortAllocator } from \"../app\";\nimport {\n buildDatabaseConfigs,\n buildOriginMap,\n buildRedisConfigs,\n type DatabaseSecretConfig,\n getSecretGroups,\n loadPortState,\n type RedisSecretConfig,\n savePortState,\n} from \"../cli/infra\";\nimport { buildDescription } from \"../service-descriptor\";\nimport type { RuntimeConfig } from \"../types\";\nimport type {\n ClaimRecord,\n CliPorts,\n ComposeModelPlan,\n DatabasePlan,\n InfraInput,\n InfraPlan,\n RedisPlan,\n ResolvedPorts,\n RuntimeLaunchSpec,\n ServiceDescriptorPlan,\n} from \"./types\";\nimport { InfraError } from \"./types\";\n\nconst DEFAULT_HOST_PORT = 3000;\nconst DEFAULT_API_PORT = 3001;\nconst DEFAULT_AUTH_PORT = 3002;\nconst DEFAULT_UI_PORT = 3003;\nconst DEFAULT_PLUGIN_PORT_START = 3010;\nconst POSTGRES_USER = \"everythingdev\";\nconst POSTGRES_PASSWORD = \"everythingdev\";\n\nexport function workspaceKey(configDir: string): string {\n const hash = createHash(\"sha256\").update(resolve(configDir)).digest(\"hex\");\n return hash.slice(0, 12);\n}\n\nfunction normalizeCliPorts(input: InfraInput[\"cli\"]): CliPorts {\n return {\n host: input.port,\n api: input.apiPort,\n auth: input.authPort,\n ui: input.uiPort,\n uiSsr: undefined,\n pluginsStart: input.pluginPortStart,\n plugins: input.plugins,\n };\n}\n\ninterface AllocateServicesResult {\n ports: ResolvedPorts;\n claims: ClaimRecord[];\n devPortsState: { host: number; api: number; auth: number; ui: number; pluginPortStart: number };\n}\n\nfunction allocateServices(\n cliPorts: CliPorts,\n plugins: Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >,\n configDir: string,\n): Effect.Effect<AllocateServicesResult, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const wKey = workspaceKey(configDir);\n const persisted = loadPortState(configDir).devPorts;\n const allocator = yield* PortAllocator;\n\n const hostPort = yield* allocator.pickAvailable(\n cliPorts.host ?? persisted?.host ?? DEFAULT_HOST_PORT,\n );\n\n const apiPort = yield* allocator.pickAvailable(\n cliPorts.api ?? persisted?.api ?? DEFAULT_API_PORT,\n );\n\n const authPort = yield* allocator.pickAvailable(\n cliPorts.auth ?? persisted?.auth ?? DEFAULT_AUTH_PORT,\n );\n\n const uiPort = yield* allocator.pickAvailable(cliPorts.ui ?? persisted?.ui ?? DEFAULT_UI_PORT);\n\n const uiSsrPort = yield* allocator.pickAvailable(cliPorts.uiSsr ?? uiPort + 1);\n\n const pluginApiPorts: Record<string, number> = {};\n const pluginUiPorts: Record<string, number> = {};\n\n const pluginKeys = Object.keys(plugins).sort();\n const pluginStart =\n cliPorts.pluginsStart ?? persisted?.pluginPortStart ?? DEFAULT_PLUGIN_PORT_START;\n let nextPluginPort = pluginStart;\n for (const pluginId of pluginKeys) {\n const pluginCfg = plugins[pluginId];\n const preferred = cliPorts.plugins?.[pluginId]?.api ?? nextPluginPort;\n const pluginPort = yield* allocator.pickAvailable(preferred);\n pluginApiPorts[pluginId] = pluginPort;\n nextPluginPort = pluginPort + 1;\n\n if (\n pluginCfg?.source === \"local\" &&\n pluginCfg?.localPath &&\n pluginCfg?.ui?.source === \"local\"\n ) {\n const uiPreferred = cliPorts.plugins?.[pluginId]?.ui ?? nextPluginPort;\n const pluginUiPort = yield* allocator.pickAvailable(uiPreferred);\n pluginUiPorts[pluginId] = pluginUiPort;\n nextPluginPort = pluginUiPort + 1;\n }\n }\n\n const resolved: ResolvedPorts = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n uiSsr: uiSsrPort,\n plugins: Object.fromEntries(\n Object.entries(pluginApiPorts).map(([k, v]) => [k, { api: v, ui: pluginUiPorts[k] }]),\n ),\n postgres: {},\n redis: {},\n };\n\n const devPortsState = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n pluginPortStart: pluginStart,\n };\n\n const claimPorts: Record<string, number> = {\n host: hostPort,\n api: apiPort,\n auth: authPort,\n ui: uiPort,\n uiSsr: uiSsrPort,\n };\n for (const [id, port] of Object.entries(pluginApiPorts)) {\n claimPorts[`plugin:${id}`] = port;\n }\n for (const [id, port] of Object.entries(pluginUiPorts)) {\n claimPorts[`plugin-ui:${id}`] = port;\n }\n\n const claim: ClaimRecord = {\n resourceKey: `workspace:${wKey}`,\n pid: process.pid,\n configDir,\n ports: claimPorts,\n startedAt: Date.now(),\n };\n\n return { ports: resolved, claims: [claim], devPortsState };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-services\",\n message: `Port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nfunction allocateDatabases(\n runtimeConfig: RuntimeConfig,\n configDir: string,\n): Effect.Effect<\n {\n postgres: Record<string, number>;\n redis: Record<string, number>;\n dbs: DatabasePlan[];\n redisPlans: RedisPlan[];\n },\n InfraError,\n PortAllocator\n> {\n return Effect.gen(function* () {\n const persisted = loadPortState(configDir);\n const groups = getSecretGroups(runtimeConfig);\n const allSecrets = groups.flatMap((group) => group.secrets);\n const originMap = buildOriginMap(configDir, runtimeConfig);\n const allocator = yield* PortAllocator;\n\n const infraDatabases: DatabaseSecretConfig[] = yield* Effect.sync(() =>\n buildDatabaseConfigs(allSecrets, originMap, { ...persisted.postgresPorts }),\n );\n const infraRedis: RedisSecretConfig[] = yield* Effect.sync(() =>\n buildRedisConfigs(allSecrets, originMap, { ...persisted.redisPorts }),\n );\n\n const postgres: Record<string, number> = {};\n const dbs: DatabasePlan[] = [];\n for (const db of infraDatabases) {\n const port = yield* allocator.pickAvailable(db.port);\n postgres[db.slug] = port;\n dbs.push({\n secret: db.secret,\n slug: db.slug,\n port,\n dbName: db.databaseName,\n containerName: db.containerName,\n volumeName: db.volumeName,\n url: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${port}/${db.slug}_db`,\n });\n }\n\n const redis: Record<string, number> = {};\n const redisPlans: RedisPlan[] = [];\n for (const r of infraRedis) {\n const port = yield* allocator.pickAvailable(r.port);\n redis[r.slug] = port;\n redisPlans.push({\n secret: r.secret,\n slug: r.slug,\n port,\n containerName: r.containerName,\n volumeName: r.volumeName,\n url: `redis://localhost:${port}`,\n });\n }\n\n return { postgres, redis, dbs, redisPlans };\n }).pipe(\n Effect.mapError(\n (portErr) =>\n new InfraError({\n phase: \"allocate-databases\",\n message: `Database port allocation failed: ${String(portErr)}`,\n cause: portErr,\n }),\n ),\n );\n}\n\nexport function buildServiceDescriptors(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): ServiceDescriptorPlan[] {\n const descriptors: ServiceDescriptorPlan[] = [];\n\n if (runtimeConfig.host) {\n const isLocal = runtimeConfig.host.source === \"local\";\n descriptors.push({\n key: \"host\",\n source: runtimeConfig.host.source,\n url: isLocal ? `http://localhost:${resolvedPorts.host}` : runtimeConfig.host.url,\n port: isLocal ? resolvedPorts.host : undefined,\n localPath: isLocal ? runtimeConfig.host.localPath : undefined,\n });\n }\n\n if (runtimeConfig.api) {\n const isLocal = runtimeConfig.api.source === \"local\";\n descriptors.push({\n key: \"api\",\n source: runtimeConfig.api.source,\n url: isLocal ? `http://localhost:${resolvedPorts.api}` : runtimeConfig.api.url,\n port: isLocal ? resolvedPorts.api : undefined,\n localPath: isLocal ? runtimeConfig.api.localPath : undefined,\n });\n }\n\n if (runtimeConfig.auth) {\n const isLocal = runtimeConfig.auth.source === \"local\";\n descriptors.push({\n key: \"auth\",\n source: runtimeConfig.auth.source,\n url: isLocal ? `http://localhost:${resolvedPorts.auth}` : runtimeConfig.auth.url,\n port: isLocal ? resolvedPorts.auth : undefined,\n localPath: isLocal ? runtimeConfig.auth.localPath : undefined,\n });\n }\n\n if (runtimeConfig.ui) {\n const isLocal = runtimeConfig.ui.source === \"local\";\n descriptors.push({\n key: \"ui\",\n source: runtimeConfig.ui.source,\n url: isLocal ? `http://localhost:${resolvedPorts.ui}` : runtimeConfig.ui.url,\n port: isLocal ? resolvedPorts.ui : undefined,\n localPath: isLocal ? runtimeConfig.ui.localPath : undefined,\n });\n if (isLocal && resolvedPorts.uiSsr) {\n descriptors.push({\n key: \"ui-ssr\",\n source: \"local\",\n url: `http://localhost:${resolvedPorts.uiSsr}`,\n port: resolvedPorts.uiSsr,\n localPath: runtimeConfig.ui.localPath,\n });\n }\n }\n\n if (runtimeConfig.plugins) {\n for (const [pluginId, pluginCfg] of Object.entries(runtimeConfig.plugins)) {\n const pluginIsLocal = pluginCfg.source === \"local\";\n const p = resolvedPorts.plugins[pluginId];\n if (pluginIsLocal && p?.api) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.api}`,\n port: p.api,\n localPath: pluginCfg.localPath,\n });\n }\n if (!pluginIsLocal && pluginCfg.url) {\n descriptors.push({\n key: `plugin:${pluginId}`,\n source: \"remote\",\n url: pluginCfg.url,\n port: undefined,\n localPath: undefined,\n });\n }\n if (pluginIsLocal && p?.ui && pluginCfg.ui?.source === \"local\") {\n descriptors.push({\n key: `plugin-ui:${pluginId}`,\n source: \"local\",\n url: `http://localhost:${p.ui}`,\n port: p.ui,\n localPath: pluginCfg.ui?.localPath,\n });\n }\n }\n }\n\n return descriptors;\n}\n\nexport function buildLaunchSpec(\n runtimeConfig: RuntimeConfig,\n resolvedPorts: ResolvedPorts,\n): RuntimeLaunchSpec {\n const hostPort =\n runtimeConfig.host?.source === \"local\" ? resolvedPorts.host : runtimeConfig.host?.port;\n const corsOrigin = hostPort ? `http://localhost:${hostPort}` : `http://localhost:3000`;\n\n return {\n port: resolvedPorts.host,\n hostUrl: runtimeConfig.host?.url,\n corsOrigin,\n env: {\n ...(resolvedPorts.host ? { PORT: String(resolvedPorts.host) } : {}),\n ...(resolvedPorts.api ? { API_PORT: String(resolvedPorts.api) } : {}),\n ...(resolvedPorts.ui ? { UI_PORT: String(resolvedPorts.ui) } : {}),\n ...(resolvedPorts.auth ? { AUTH_PORT: String(resolvedPorts.auth) } : {}),\n },\n runtimeConfig,\n };\n}\n\nexport function buildComposeModel(dbs: DatabasePlan[], redisPlans: RedisPlan[]): ComposeModelPlan {\n return { databases: dbs, redis: redisPlans };\n}\n\nexport function buildEnvGenerated(\n resolvedPorts: ResolvedPorts,\n dbs: DatabasePlan[],\n redisPlans: RedisPlan[],\n): Record<string, string> {\n const env: Record<string, string> = {};\n\n if (resolvedPorts.host) {\n env.CORS_ORIGIN = `http://localhost:${resolvedPorts.host}`;\n }\n\n for (const db of dbs) {\n env[db.secret] = db.url;\n }\n for (const r of redisPlans) {\n env[r.secret] = r.url;\n }\n\n return env;\n}\n\nexport function planInfra(input: InfraInput): Effect.Effect<InfraPlan, InfraError, PortAllocator> {\n return Effect.gen(function* () {\n const cliPorts = normalizeCliPorts(input.cli);\n const wKey = workspaceKey(input.configDir);\n\n const plugins = (input.bosConfig.plugins ?? {}) as Record<\n string,\n { source: string; localPath?: string; ui?: { source: string; localPath?: string } }\n >;\n\n const {\n ports: svcPorts,\n claims,\n devPortsState,\n } = yield* allocateServices(cliPorts, plugins, input.configDir);\n\n const {\n dbs,\n redisPlans,\n postgres: pgPorts,\n redis: rdPorts,\n } = yield* allocateDatabases(input.bosConfig, input.configDir);\n\n const resolvedPorts: ResolvedPorts = {\n ...svcPorts,\n postgres: pgPorts,\n redis: rdPorts,\n };\n\n // Write merged state once after all allocations succeed\n // Skip persistence for regression tests / ephemeral runs\n if (process.env.BOS_NO_PERSIST_PORTS !== \"1\") {\n savePortState(input.configDir, {\n postgresPorts: pgPorts,\n redisPorts: rdPorts,\n devPorts: devPortsState,\n });\n }\n\n const hostIsLocal = input.bosConfig.host?.source === \"local\";\n const apiIsLocal = input.bosConfig.api?.source === \"local\";\n const uiIsLocal = input.bosConfig.ui?.source === \"local\";\n const authIsLocal = input.bosConfig.auth?.source === \"local\";\n const assignedRuntimeConfig: RuntimeConfig = {\n ...input.bosConfig,\n host: resolvedPorts.host\n ? {\n ...input.bosConfig.host,\n port: resolvedPorts.host,\n url: `http://localhost:${resolvedPorts.host}`,\n remoteUrl: !hostIsLocal\n ? (input.bosConfig.host.remoteUrl ?? input.bosConfig.host.url)\n : undefined,\n }\n : input.bosConfig.host,\n api:\n apiIsLocal && resolvedPorts.api\n ? {\n ...input.bosConfig.api,\n port: resolvedPorts.api,\n url: `http://localhost:${resolvedPorts.api}`,\n }\n : input.bosConfig.api,\n ui:\n uiIsLocal && resolvedPorts.ui\n ? {\n ...input.bosConfig.ui,\n port: resolvedPorts.ui,\n url: `http://localhost:${resolvedPorts.ui}`,\n }\n : input.bosConfig.ui,\n auth:\n authIsLocal && resolvedPorts.auth && input.bosConfig.auth\n ? {\n ...input.bosConfig.auth,\n port: resolvedPorts.auth,\n url: `http://localhost:${resolvedPorts.auth}`,\n }\n : input.bosConfig.auth,\n plugins: input.bosConfig.plugins\n ? Object.fromEntries(\n Object.entries(input.bosConfig.plugins).map(([id, p]) => {\n const pluginPort = resolvedPorts.plugins[id];\n if (p.source === \"local\" && pluginPort?.api) {\n return [\n id,\n { ...p, port: pluginPort.api, url: `http://localhost:${pluginPort.api}` },\n ];\n }\n return [id, p];\n }),\n )\n : undefined,\n };\n\n const serviceDescriptors = buildServiceDescriptors(input.bosConfig, resolvedPorts);\n\n const launch = buildLaunchSpec(input.bosConfig, resolvedPorts);\n const composeModel = buildComposeModel(dbs, redisPlans);\n const envGenerated = buildEnvGenerated(resolvedPorts, dbs, redisPlans);\n\n const packages = serviceDescriptors.map((d) => d.key);\n const descriptionMap = new Map(serviceDescriptors.map((d) => [d.key, d]));\n const description = buildDescription(descriptionMap);\n\n const orchestrator = {\n packages,\n env: {},\n description,\n port: resolvedPorts.host,\n interactive: input.cli.interactive,\n };\n\n return {\n workspaceKey: wKey,\n cliPorts,\n resolvedPorts,\n runtimeConfig: assignedRuntimeConfig,\n launch,\n description,\n serviceDescriptors: new Map(serviceDescriptors.map((d) => [d.key, d])),\n envGenerated,\n composeModel,\n claims,\n orchestrator,\n };\n });\n}\n"],"mappings":"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"}
|
package/dist/ui/head.cjs
CHANGED
|
@@ -4,14 +4,18 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
4
4
|
function getThemeInitScript() {
|
|
5
5
|
return { children: "(function(){var t=localStorage.getItem('theme');if(t==='dark'||(!t&&window.matchMedia('(prefers-color-scheme: dark)').matches)){document.documentElement.classList.add('dark');}})();" };
|
|
6
6
|
}
|
|
7
|
+
function escapeJsonForScript(value) {
|
|
8
|
+
return JSON.stringify(value).replace(/<\/script/gi, "<\\/script").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
9
|
+
}
|
|
7
10
|
function getHydrateScript(runtimeConfig, containerName = "ui", hydratePath = "./Hydrate", cspNonce) {
|
|
8
11
|
return { children: `
|
|
9
|
-
window.__CSP_NONCE__=${
|
|
10
|
-
window.__RUNTIME_CONFIG__=${
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
window.__CSP_NONCE__=${cspNonce != null ? escapeJsonForScript(cspNonce) : null};
|
|
13
|
+
window.__RUNTIME_CONFIG__=${escapeJsonForScript(runtimeConfig)};
|
|
14
|
+
function __hydrate(){
|
|
15
|
+
if (window.__EVERYTHING_DEV_HYDRATE_PROMISE__) {
|
|
16
|
+
console.warn('[Hydrate] Already in progress, skipping duplicate call');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
15
19
|
var container = window['${containerName}'];
|
|
16
20
|
if (!container) {
|
|
17
21
|
console.warn('[Hydrate] Container not ready yet, waiting...');
|
|
@@ -31,8 +35,9 @@ function getHydrateScript(runtimeConfig, containerName = "ui", hydratePath = "./
|
|
|
31
35
|
return mod().hydrate();
|
|
32
36
|
}).catch(function(e){
|
|
33
37
|
console.error('[Hydrate] Failed:', e);
|
|
38
|
+
window.__EVERYTHING_DEV_HYDRATE_PROMISE__ = undefined;
|
|
34
39
|
});
|
|
35
|
-
|
|
40
|
+
}
|
|
36
41
|
if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',__hydrate);}else{__hydrate();}
|
|
37
42
|
`.trim() };
|
|
38
43
|
}
|
package/dist/ui/head.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"head.cjs","names":[],"sources":["../../src/ui/head.ts"],"sourcesContent":["import type { ClientRuntimeConfig } from \"../types\";\nimport type { HeadScript } from \"./types\";\n\nexport interface RemoteScriptsOptions {\n runtimeConfig?: Partial<ClientRuntimeConfig>;\n containerName?: string;\n hydratePath?: string;\n integrity?: string;\n cspNonce?: string;\n}\n\nexport function getThemeInitScript(): HeadScript {\n return {\n children:\n \"(function(){var t=localStorage.getItem('theme');if(t==='dark'||(!t&&window.matchMedia('(prefers-color-scheme: dark)').matches)){document.documentElement.classList.add('dark');}})();\",\n };\n}\n\nexport function getHydrateScript(\n runtimeConfig: Partial<ClientRuntimeConfig> | undefined,\n containerName = \"ui\",\n hydratePath = \"./Hydrate\",\n cspNonce?: string,\n): HeadScript {\n return {\n children: `\n window.__CSP_NONCE__=${
|
|
1
|
+
{"version":3,"file":"head.cjs","names":[],"sources":["../../src/ui/head.ts"],"sourcesContent":["import type { ClientRuntimeConfig } from \"../types\";\nimport type { HeadScript } from \"./types\";\n\nexport interface RemoteScriptsOptions {\n runtimeConfig?: Partial<ClientRuntimeConfig>;\n containerName?: string;\n hydratePath?: string;\n integrity?: string;\n cspNonce?: string;\n}\n\nexport function getThemeInitScript(): HeadScript {\n return {\n children:\n \"(function(){var t=localStorage.getItem('theme');if(t==='dark'||(!t&&window.matchMedia('(prefers-color-scheme: dark)').matches)){document.documentElement.classList.add('dark');}})();\",\n };\n}\n\nfunction escapeJsonForScript(value: unknown): string {\n return JSON.stringify(value)\n .replace(/<\\/script/gi, \"<\\\\/script\")\n .replace(/\\u2028/g, \"\\\\u2028\")\n .replace(/\\u2029/g, \"\\\\u2029\");\n}\n\nexport function getHydrateScript(\n runtimeConfig: Partial<ClientRuntimeConfig> | undefined,\n containerName = \"ui\",\n hydratePath = \"./Hydrate\",\n cspNonce?: string,\n): HeadScript {\n return {\n children: `\n window.__CSP_NONCE__=${cspNonce != null ? escapeJsonForScript(cspNonce) : null};\n window.__RUNTIME_CONFIG__=${escapeJsonForScript(runtimeConfig)};\n function __hydrate(){\n if (window.__EVERYTHING_DEV_HYDRATE_PROMISE__) {\n console.warn('[Hydrate] Already in progress, skipping duplicate call');\n return;\n }\n var container = window['${containerName}'];\n if (!container) {\n console.warn('[Hydrate] Container not ready yet, waiting...');\n window.__hydrateRetry = window.__hydrateRetry || 0;\n if (window.__hydrateRetry < 10) {\n window.__hydrateRetry++;\n setTimeout(__hydrate, 100);\n return;\n }\n console.error('[Hydrate] Container not found after 10 retries');\n return;\n }\n console.log('[Hydrate] Container available, starting init...');\n container.init({}).then(function(){\n return container.get('${hydratePath}');\n }).then(function(mod){\n return mod().hydrate();\n }).catch(function(e){\n console.error('[Hydrate] Failed:', e);\n window.__EVERYTHING_DEV_HYDRATE_PROMISE__ = undefined;\n });\n }\n if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',__hydrate);}else{__hydrate();}\n \t\t`.trim(),\n };\n}\n\nexport function getRemoteScripts(options: RemoteScriptsOptions): HeadScript[] {\n const { runtimeConfig, containerName, hydratePath, integrity, cspNonce } = options;\n const assetsUrl = runtimeConfig?.assetsUrl?.replace(/\\/$/, \"\");\n const entryScript: HeadScript = {\n src: `${assetsUrl ?? \"\"}/remoteEntry.js${integrity ? `?v=${encodeURIComponent(integrity)}` : \"\"}`,\n };\n if (integrity) {\n entryScript.integrity = integrity;\n entryScript.crossOrigin = \"anonymous\";\n }\n return [entryScript, getHydrateScript(runtimeConfig, containerName, hydratePath, cspNonce)];\n}\n\nexport function getBaseStyles(): string {\n return `\n*, *::before, *::after { box-sizing: border-box; }\nhtml { height: 100%; height: 100dvh; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; color-scheme: light dark; }\nbody { min-height: 100%; min-height: 100dvh; margin: 0; background-color: var(--background); color: var(--foreground); -webkit-tap-highlight-color: transparent; touch-action: manipulation; }\n#root { min-height: 100vh; }\n@supports (min-height: 100dvh) { #root { min-height: 100dvh; } }\n `.trim();\n}\n"],"mappings":";;;AAWA,SAAgB,qBAAiC;AAC/C,QAAO,EACL,UACE,yLACH;;AAGH,SAAS,oBAAoB,OAAwB;AACnD,QAAO,KAAK,UAAU,MAAM,CACzB,QAAQ,eAAe,aAAa,CACpC,QAAQ,WAAW,UAAU,CAC7B,QAAQ,WAAW,UAAU;;AAGlC,SAAgB,iBACd,eACA,gBAAgB,MAChB,cAAc,aACd,UACY;AACZ,QAAO,EACL,UAAU;wBACU,YAAY,OAAO,oBAAoB,SAAS,GAAG,KAAK;6BACnD,oBAAoB,cAAc,CAAC;;;;;;6BAMnC,cAAc;;;;;;;;;;;;;;4BAcf,YAAY;;;;;;;;;KASnC,MAAM,EACR;;AAGH,SAAgB,iBAAiB,SAA6C;CAC5E,MAAM,EAAE,eAAe,eAAe,aAAa,WAAW,aAAa;CAE3E,MAAM,cAA0B,EAC9B,KAAK,GAFW,eAAe,WAAW,QAAQ,OAAO,GAAG,IAEvC,GAAG,iBAAiB,YAAY,MAAM,mBAAmB,UAAU,KAAK,MAC9F;AACD,KAAI,WAAW;AACb,cAAY,YAAY;AACxB,cAAY,cAAc;;AAE5B,QAAO,CAAC,aAAa,iBAAiB,eAAe,eAAe,aAAa,SAAS,CAAC;;AAG7F,SAAgB,gBAAwB;AACtC,QAAO;;;;;;IAML,MAAM"}
|
package/dist/ui/head.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"head.d.cts","names":[],"sources":["../../src/ui/head.ts"],"mappings":";;;;UAGiB,oBAAA;EACf,aAAA,GAAgB,OAAA,CAAQ,mBAAA;EACxB,aAAA;EACA,WAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,iBAGc,kBAAA,CAAA,GAAsB,UAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"head.d.cts","names":[],"sources":["../../src/ui/head.ts"],"mappings":";;;;UAGiB,oBAAA;EACf,aAAA,GAAgB,OAAA,CAAQ,mBAAA;EACxB,aAAA;EACA,WAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,iBAGc,kBAAA,CAAA,GAAsB,UAAA;AAAA,iBActB,gBAAA,CACd,aAAA,EAAe,OAAA,CAAQ,mBAAA,eACvB,aAAA,WACA,WAAA,WACA,QAAA,YACC,UAAA;AAAA,iBAqCa,gBAAA,CAAiB,OAAA,EAAS,oBAAA,GAAuB,UAAA;AAAA,iBAajD,aAAA,CAAA"}
|
package/dist/ui/head.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"head.d.mts","names":[],"sources":["../../src/ui/head.ts"],"mappings":";;;;UAGiB,oBAAA;EACf,aAAA,GAAgB,OAAA,CAAQ,mBAAA;EACxB,aAAA;EACA,WAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,iBAGc,kBAAA,CAAA,GAAsB,UAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"head.d.mts","names":[],"sources":["../../src/ui/head.ts"],"mappings":";;;;UAGiB,oBAAA;EACf,aAAA,GAAgB,OAAA,CAAQ,mBAAA;EACxB,aAAA;EACA,WAAA;EACA,SAAA;EACA,QAAA;AAAA;AAAA,iBAGc,kBAAA,CAAA,GAAsB,UAAA;AAAA,iBActB,gBAAA,CACd,aAAA,EAAe,OAAA,CAAQ,mBAAA,eACvB,aAAA,WACA,WAAA,WACA,QAAA,YACC,UAAA;AAAA,iBAqCa,gBAAA,CAAiB,OAAA,EAAS,oBAAA,GAAuB,UAAA;AAAA,iBAajD,aAAA,CAAA"}
|
package/dist/ui/head.mjs
CHANGED
|
@@ -2,14 +2,18 @@
|
|
|
2
2
|
function getThemeInitScript() {
|
|
3
3
|
return { children: "(function(){var t=localStorage.getItem('theme');if(t==='dark'||(!t&&window.matchMedia('(prefers-color-scheme: dark)').matches)){document.documentElement.classList.add('dark');}})();" };
|
|
4
4
|
}
|
|
5
|
+
function escapeJsonForScript(value) {
|
|
6
|
+
return JSON.stringify(value).replace(/<\/script/gi, "<\\/script").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
7
|
+
}
|
|
5
8
|
function getHydrateScript(runtimeConfig, containerName = "ui", hydratePath = "./Hydrate", cspNonce) {
|
|
6
9
|
return { children: `
|
|
7
|
-
window.__CSP_NONCE__=${
|
|
8
|
-
window.__RUNTIME_CONFIG__=${
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
window.__CSP_NONCE__=${cspNonce != null ? escapeJsonForScript(cspNonce) : null};
|
|
11
|
+
window.__RUNTIME_CONFIG__=${escapeJsonForScript(runtimeConfig)};
|
|
12
|
+
function __hydrate(){
|
|
13
|
+
if (window.__EVERYTHING_DEV_HYDRATE_PROMISE__) {
|
|
14
|
+
console.warn('[Hydrate] Already in progress, skipping duplicate call');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
13
17
|
var container = window['${containerName}'];
|
|
14
18
|
if (!container) {
|
|
15
19
|
console.warn('[Hydrate] Container not ready yet, waiting...');
|
|
@@ -29,8 +33,9 @@ function getHydrateScript(runtimeConfig, containerName = "ui", hydratePath = "./
|
|
|
29
33
|
return mod().hydrate();
|
|
30
34
|
}).catch(function(e){
|
|
31
35
|
console.error('[Hydrate] Failed:', e);
|
|
36
|
+
window.__EVERYTHING_DEV_HYDRATE_PROMISE__ = undefined;
|
|
32
37
|
});
|
|
33
|
-
|
|
38
|
+
}
|
|
34
39
|
if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',__hydrate);}else{__hydrate();}
|
|
35
40
|
`.trim() };
|
|
36
41
|
}
|
package/dist/ui/head.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"head.mjs","names":[],"sources":["../../src/ui/head.ts"],"sourcesContent":["import type { ClientRuntimeConfig } from \"../types\";\nimport type { HeadScript } from \"./types\";\n\nexport interface RemoteScriptsOptions {\n runtimeConfig?: Partial<ClientRuntimeConfig>;\n containerName?: string;\n hydratePath?: string;\n integrity?: string;\n cspNonce?: string;\n}\n\nexport function getThemeInitScript(): HeadScript {\n return {\n children:\n \"(function(){var t=localStorage.getItem('theme');if(t==='dark'||(!t&&window.matchMedia('(prefers-color-scheme: dark)').matches)){document.documentElement.classList.add('dark');}})();\",\n };\n}\n\nexport function getHydrateScript(\n runtimeConfig: Partial<ClientRuntimeConfig> | undefined,\n containerName = \"ui\",\n hydratePath = \"./Hydrate\",\n cspNonce?: string,\n): HeadScript {\n return {\n children: `\n window.__CSP_NONCE__=${
|
|
1
|
+
{"version":3,"file":"head.mjs","names":[],"sources":["../../src/ui/head.ts"],"sourcesContent":["import type { ClientRuntimeConfig } from \"../types\";\nimport type { HeadScript } from \"./types\";\n\nexport interface RemoteScriptsOptions {\n runtimeConfig?: Partial<ClientRuntimeConfig>;\n containerName?: string;\n hydratePath?: string;\n integrity?: string;\n cspNonce?: string;\n}\n\nexport function getThemeInitScript(): HeadScript {\n return {\n children:\n \"(function(){var t=localStorage.getItem('theme');if(t==='dark'||(!t&&window.matchMedia('(prefers-color-scheme: dark)').matches)){document.documentElement.classList.add('dark');}})();\",\n };\n}\n\nfunction escapeJsonForScript(value: unknown): string {\n return JSON.stringify(value)\n .replace(/<\\/script/gi, \"<\\\\/script\")\n .replace(/\\u2028/g, \"\\\\u2028\")\n .replace(/\\u2029/g, \"\\\\u2029\");\n}\n\nexport function getHydrateScript(\n runtimeConfig: Partial<ClientRuntimeConfig> | undefined,\n containerName = \"ui\",\n hydratePath = \"./Hydrate\",\n cspNonce?: string,\n): HeadScript {\n return {\n children: `\n window.__CSP_NONCE__=${cspNonce != null ? escapeJsonForScript(cspNonce) : null};\n window.__RUNTIME_CONFIG__=${escapeJsonForScript(runtimeConfig)};\n function __hydrate(){\n if (window.__EVERYTHING_DEV_HYDRATE_PROMISE__) {\n console.warn('[Hydrate] Already in progress, skipping duplicate call');\n return;\n }\n var container = window['${containerName}'];\n if (!container) {\n console.warn('[Hydrate] Container not ready yet, waiting...');\n window.__hydrateRetry = window.__hydrateRetry || 0;\n if (window.__hydrateRetry < 10) {\n window.__hydrateRetry++;\n setTimeout(__hydrate, 100);\n return;\n }\n console.error('[Hydrate] Container not found after 10 retries');\n return;\n }\n console.log('[Hydrate] Container available, starting init...');\n container.init({}).then(function(){\n return container.get('${hydratePath}');\n }).then(function(mod){\n return mod().hydrate();\n }).catch(function(e){\n console.error('[Hydrate] Failed:', e);\n window.__EVERYTHING_DEV_HYDRATE_PROMISE__ = undefined;\n });\n }\n if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',__hydrate);}else{__hydrate();}\n \t\t`.trim(),\n };\n}\n\nexport function getRemoteScripts(options: RemoteScriptsOptions): HeadScript[] {\n const { runtimeConfig, containerName, hydratePath, integrity, cspNonce } = options;\n const assetsUrl = runtimeConfig?.assetsUrl?.replace(/\\/$/, \"\");\n const entryScript: HeadScript = {\n src: `${assetsUrl ?? \"\"}/remoteEntry.js${integrity ? `?v=${encodeURIComponent(integrity)}` : \"\"}`,\n };\n if (integrity) {\n entryScript.integrity = integrity;\n entryScript.crossOrigin = \"anonymous\";\n }\n return [entryScript, getHydrateScript(runtimeConfig, containerName, hydratePath, cspNonce)];\n}\n\nexport function getBaseStyles(): string {\n return `\n*, *::before, *::after { box-sizing: border-box; }\nhtml { height: 100%; height: 100dvh; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; color-scheme: light dark; }\nbody { min-height: 100%; min-height: 100dvh; margin: 0; background-color: var(--background); color: var(--foreground); -webkit-tap-highlight-color: transparent; touch-action: manipulation; }\n#root { min-height: 100vh; }\n@supports (min-height: 100dvh) { #root { min-height: 100dvh; } }\n `.trim();\n}\n"],"mappings":";AAWA,SAAgB,qBAAiC;AAC/C,QAAO,EACL,UACE,yLACH;;AAGH,SAAS,oBAAoB,OAAwB;AACnD,QAAO,KAAK,UAAU,MAAM,CACzB,QAAQ,eAAe,aAAa,CACpC,QAAQ,WAAW,UAAU,CAC7B,QAAQ,WAAW,UAAU;;AAGlC,SAAgB,iBACd,eACA,gBAAgB,MAChB,cAAc,aACd,UACY;AACZ,QAAO,EACL,UAAU;wBACU,YAAY,OAAO,oBAAoB,SAAS,GAAG,KAAK;6BACnD,oBAAoB,cAAc,CAAC;;;;;;6BAMnC,cAAc;;;;;;;;;;;;;;4BAcf,YAAY;;;;;;;;;KASnC,MAAM,EACR;;AAGH,SAAgB,iBAAiB,SAA6C;CAC5E,MAAM,EAAE,eAAe,eAAe,aAAa,WAAW,aAAa;CAE3E,MAAM,cAA0B,EAC9B,KAAK,GAFW,eAAe,WAAW,QAAQ,OAAO,GAAG,IAEvC,GAAG,iBAAiB,YAAY,MAAM,mBAAmB,UAAU,KAAK,MAC9F;AACD,KAAI,WAAW;AACb,cAAY,YAAY;AACxB,cAAY,cAAc;;AAE5B,QAAO,CAAC,aAAa,iBAAiB,eAAe,eAAe,aAAa,SAAS,CAAC;;AAG7F,SAAgB,gBAAwB;AACtC,QAAO;;;;;;IAML,MAAM"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "everything-dev",
|
|
3
|
-
"version": "1.51.
|
|
3
|
+
"version": "1.51.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.11"
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
"dotenv": "^17.3.1",
|
|
141
141
|
"effect": "^3.21.0",
|
|
142
142
|
"execa": "^9.5.2",
|
|
143
|
-
"every-plugin": "^2.9.
|
|
143
|
+
"every-plugin": "^2.9.6",
|
|
144
144
|
"glob": "^13.0.6",
|
|
145
145
|
"gradient-string": "^3.0.0",
|
|
146
146
|
"ink": "^6.8.0",
|