@undefineds.co/xpod 0.2.28 → 0.2.30

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.
Files changed (29) hide show
  1. package/config/cli.json +1 -1
  2. package/config/local.json +8 -8
  3. package/config/resolver.json +2 -2
  4. package/config/xpod.json +8 -8
  5. package/dist/api/container/index.js +1 -1
  6. package/dist/api/container/index.js.map +1 -1
  7. package/dist/api/service/VercelChatService.d.ts +2 -1
  8. package/dist/api/service/VercelChatService.js +7 -3
  9. package/dist/api/service/VercelChatService.js.map +1 -1
  10. package/dist/api/service/ai-gateway-transport.d.ts +3 -1
  11. package/dist/api/service/ai-gateway-transport.js +12 -7
  12. package/dist/api/service/ai-gateway-transport.js.map +1 -1
  13. package/dist/api/service/platform-ai-config.d.ts +2 -0
  14. package/dist/api/service/platform-ai-config.js +17 -5
  15. package/dist/api/service/platform-ai-config.js.map +1 -1
  16. package/dist/cli/commands/start.js +8 -8
  17. package/dist/cli/commands/start.js.map +1 -1
  18. package/dist/components/context.jsonld +8 -8
  19. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.d.ts +4 -4
  20. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js +7 -7
  21. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js.map +1 -1
  22. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld +6 -6
  23. package/dist/identity/oidc/AutoDetectOidcHandler.d.ts +4 -4
  24. package/dist/identity/oidc/AutoDetectOidcHandler.js +6 -6
  25. package/dist/identity/oidc/AutoDetectOidcHandler.js.map +1 -1
  26. package/dist/identity/oidc/AutoDetectOidcHandler.jsonld +6 -6
  27. package/dist/runtime/bootstrap.js +1 -1
  28. package/dist/runtime/bootstrap.js.map +1 -1
  29. package/package.json +1 -1
@@ -7,11 +7,14 @@ exports.getPlatformApiKey = getPlatformApiKey;
7
7
  exports.hasPlatformApiConfig = hasPlatformApiConfig;
8
8
  exports.getPlatformProviderId = getPlatformProviderId;
9
9
  exports.getPlatformDefaultModel = getPlatformDefaultModel;
10
+ exports.getPlatformQueryTimeoutMs = getPlatformQueryTimeoutMs;
11
+ exports.getPlatformGenerationTimeoutMs = getPlatformGenerationTimeoutMs;
10
12
  exports.getPlatformTimeoutMs = getPlatformTimeoutMs;
11
13
  const provider_registry_1 = require("./provider-registry");
12
14
  const DEFAULT_PLATFORM_PROVIDER = 'undefineds';
13
15
  const DEFAULT_PLATFORM_MODEL = 'linx-lite';
14
- const DEFAULT_PLATFORM_TIMEOUT_MS = 30_000;
16
+ const DEFAULT_PLATFORM_QUERY_TIMEOUT_MS = 30_000;
17
+ const DEFAULT_PLATFORM_GENERATION_TIMEOUT_MS = 120_000;
15
18
  function readTrimmedEnv(name) {
16
19
  const value = process.env[name]?.trim();
17
20
  return value ? value : undefined;
@@ -53,12 +56,21 @@ function getPlatformProviderId() {
53
56
  function getPlatformDefaultModel() {
54
57
  return readTrimmedEnv('DEFAULT_MODEL') ?? DEFAULT_PLATFORM_MODEL;
55
58
  }
56
- function getPlatformTimeoutMs() {
57
- const raw = readTrimmedEnv('DEFAULT_TIMEOUT_MS');
59
+ function readPositiveIntegerEnv(name, fallback) {
60
+ const raw = readTrimmedEnv(name);
58
61
  if (!raw) {
59
- return DEFAULT_PLATFORM_TIMEOUT_MS;
62
+ return fallback;
60
63
  }
61
64
  const parsed = Number(raw);
62
- return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_PLATFORM_TIMEOUT_MS;
65
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
66
+ }
67
+ function getPlatformQueryTimeoutMs() {
68
+ return readPositiveIntegerEnv('DEFAULT_TIMEOUT_MS', DEFAULT_PLATFORM_QUERY_TIMEOUT_MS);
69
+ }
70
+ function getPlatformGenerationTimeoutMs() {
71
+ return readPositiveIntegerEnv('DEFAULT_GENERATION_TIMEOUT_MS', DEFAULT_PLATFORM_GENERATION_TIMEOUT_MS);
72
+ }
73
+ function getPlatformTimeoutMs() {
74
+ return getPlatformQueryTimeoutMs();
63
75
  }
64
76
  //# sourceMappingURL=platform-ai-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"platform-ai-config.js","sourceRoot":"","sources":["../../../src/api/service/platform-ai-config.ts"],"names":[],"mappings":";;AAWA,kDAMC;AAED,gDAEC;AAED,sDAgBC;AAED,8CAEC;AAED,oDAEC;AAED,sDAEC;AAED,0DAEC;AAED,oDAQC;AAjED,2DAAwD;AAExD,MAAM,yBAAyB,GAAG,YAAY,CAAC;AAC/C,MAAM,sBAAsB,GAAG,WAAW,CAAC;AAC3C,MAAM,2BAA2B,GAAG,MAAM,CAAC;AAE3C,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;IACxC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACnC,CAAC;AAED,SAAgB,mBAAmB;IACjC,MAAM,QAAQ,GAAG,cAAc,CAAC,kBAAkB,CAAC,CAAC;IACpD,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,kBAAkB;IAChC,OAAO,cAAc,CAAC,iBAAiB,CAAC,CAAC;AAC3C,CAAC;AAED,SAAgB,qBAAqB;IACnC,MAAM,QAAQ,GAAG,cAAc,CAAC,kBAAkB,CAAC,CAAC;IACpD,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,aAAa,GAAG,mBAAmB,EAAE,CAAC;IAC5C,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;QACzC,IAAI,QAAQ,KAAK,yBAAyB,EAAE,CAAC;YAC3C,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,IAAA,qCAAiB,EAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,aAAa,KAAK,CAAC;AAC/E,CAAC;AAED,SAAgB,iBAAiB;IAC/B,OAAO,kBAAkB,EAAE,IAAI,EAAE,CAAC;AACpC,CAAC;AAED,SAAgB,oBAAoB;IAClC,OAAO,CAAC,CAAC,CAAC,qBAAqB,EAAE,IAAI,iBAAiB,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,SAAgB,qBAAqB;IACnC,OAAO,cAAc,CAAC,kBAAkB,CAAC,IAAI,yBAAyB,CAAC;AACzE,CAAC;AAED,SAAgB,uBAAuB;IACrC,OAAO,cAAc,CAAC,eAAe,CAAC,IAAI,sBAAsB,CAAC;AACnE,CAAC;AAED,SAAgB,oBAAoB;IAClC,MAAM,GAAG,GAAG,cAAc,CAAC,oBAAoB,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,2BAA2B,CAAC;IACrC,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,2BAA2B,CAAC;AACtF,CAAC","sourcesContent":["import { getDefaultBaseUrl } from './provider-registry';\n\nconst DEFAULT_PLATFORM_PROVIDER = 'undefineds';\nconst DEFAULT_PLATFORM_MODEL = 'linx-lite';\nconst DEFAULT_PLATFORM_TIMEOUT_MS = 30_000;\n\nfunction readTrimmedEnv(name: string): string | undefined {\n const value = process.env[name]?.trim();\n return value ? value : undefined;\n}\n\nexport function getAiGatewayBaseUrl(): string | undefined {\n const explicit = readTrimmedEnv('DEFAULT_API_BASE');\n if (explicit) {\n return explicit.replace(/\\/$/, '');\n }\n return undefined;\n}\n\nexport function getAiGatewayApiKey(): string | undefined {\n return readTrimmedEnv('DEFAULT_API_KEY');\n}\n\nexport function getPlatformApiBaseUrl(): string | undefined {\n const explicit = readTrimmedEnv('DEFAULT_API_BASE');\n if (explicit) {\n return explicit.replace(/\\/$/, '');\n }\n\n const aiGatewayBase = getAiGatewayBaseUrl();\n if (!aiGatewayBase) {\n const provider = getPlatformProviderId();\n if (provider === DEFAULT_PLATFORM_PROVIDER) {\n return undefined;\n }\n return getDefaultBaseUrl(provider);\n }\n\n return aiGatewayBase.endsWith('/v1') ? aiGatewayBase : `${aiGatewayBase}/v1`;\n}\n\nexport function getPlatformApiKey(): string {\n return getAiGatewayApiKey() ?? '';\n}\n\nexport function hasPlatformApiConfig(): boolean {\n return !!(getPlatformApiBaseUrl() || getPlatformApiKey());\n}\n\nexport function getPlatformProviderId(): string {\n return readTrimmedEnv('DEFAULT_PROVIDER') ?? DEFAULT_PLATFORM_PROVIDER;\n}\n\nexport function getPlatformDefaultModel(): string {\n return readTrimmedEnv('DEFAULT_MODEL') ?? DEFAULT_PLATFORM_MODEL;\n}\n\nexport function getPlatformTimeoutMs(): number {\n const raw = readTrimmedEnv('DEFAULT_TIMEOUT_MS');\n if (!raw) {\n return DEFAULT_PLATFORM_TIMEOUT_MS;\n }\n\n const parsed = Number(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_PLATFORM_TIMEOUT_MS;\n}\n"]}
1
+ {"version":3,"file":"platform-ai-config.js","sourceRoot":"","sources":["../../../src/api/service/platform-ai-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { getDefaultBaseUrl } from './provider-registry';\n\nconst DEFAULT_PLATFORM_PROVIDER = 'undefineds';\nconst DEFAULT_PLATFORM_MODEL = 'linx-lite';\nconst DEFAULT_PLATFORM_QUERY_TIMEOUT_MS = 30_000;\nconst DEFAULT_PLATFORM_GENERATION_TIMEOUT_MS = 120_000;\n\nfunction readTrimmedEnv(name: string): string | undefined {\n const value = process.env[name]?.trim();\n return value ? value : undefined;\n}\n\nexport function getAiGatewayBaseUrl(): string | undefined {\n const explicit = readTrimmedEnv('DEFAULT_API_BASE');\n if (explicit) {\n return explicit.replace(/\\/$/, '');\n }\n return undefined;\n}\n\nexport function getAiGatewayApiKey(): string | undefined {\n return readTrimmedEnv('DEFAULT_API_KEY');\n}\n\nexport function getPlatformApiBaseUrl(): string | undefined {\n const explicit = readTrimmedEnv('DEFAULT_API_BASE');\n if (explicit) {\n return explicit.replace(/\\/$/, '');\n }\n\n const aiGatewayBase = getAiGatewayBaseUrl();\n if (!aiGatewayBase) {\n const provider = getPlatformProviderId();\n if (provider === DEFAULT_PLATFORM_PROVIDER) {\n return undefined;\n }\n return getDefaultBaseUrl(provider);\n }\n\n return aiGatewayBase.endsWith('/v1') ? aiGatewayBase : `${aiGatewayBase}/v1`;\n}\n\nexport function getPlatformApiKey(): string {\n return getAiGatewayApiKey() ?? '';\n}\n\nexport function hasPlatformApiConfig(): boolean {\n return !!(getPlatformApiBaseUrl() || getPlatformApiKey());\n}\n\nexport function getPlatformProviderId(): string {\n return readTrimmedEnv('DEFAULT_PROVIDER') ?? DEFAULT_PLATFORM_PROVIDER;\n}\n\nexport function getPlatformDefaultModel(): string {\n return readTrimmedEnv('DEFAULT_MODEL') ?? DEFAULT_PLATFORM_MODEL;\n}\n\nfunction readPositiveIntegerEnv(name: string, fallback: number): number {\n const raw = readTrimmedEnv(name);\n if (!raw) {\n return fallback;\n }\n\n const parsed = Number(raw);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\nexport function getPlatformQueryTimeoutMs(): number {\n return readPositiveIntegerEnv('DEFAULT_TIMEOUT_MS', DEFAULT_PLATFORM_QUERY_TIMEOUT_MS);\n}\n\nexport function getPlatformGenerationTimeoutMs(): number {\n return readPositiveIntegerEnv('DEFAULT_GENERATION_TIMEOUT_MS', DEFAULT_PLATFORM_GENERATION_TIMEOUT_MS);\n}\n\nexport function getPlatformTimeoutMs(): number {\n return getPlatformQueryTimeoutMs();\n}\n"]}
@@ -87,20 +87,20 @@ exports.startCommand = {
87
87
  const apiPort = await (0, runtime_1.getFreePort)(cssPort + 1, argv.host);
88
88
  const baseUrl = process.env.CSS_BASE_URL || `http://${argv.host}:${mainPort}/`;
89
89
  // SP 模式:全部通过环境变量配置(.env.local 或 --env 参数)
90
- // XPOD_SERVICE_TOKEN, XPOD_NODE_ID, XPOD_NODE_TOKEN, XPOD_CLOUD_API_ENDPOINT, CSS_IDP_URL
91
- const idpUrl = process.env.CSS_IDP_URL || process.env.XPOD_CLOUD_API_ENDPOINT;
90
+ // XPOD_SERVICE_TOKEN, XPOD_NODE_ID, XPOD_NODE_TOKEN, XPOD_CLOUD_API_ENDPOINT, CSS_OIDC_ISSUER
91
+ const oidcIssuer = process.env.CSS_OIDC_ISSUER;
92
92
  console.log('Starting xpod...');
93
93
  console.log(` Gateway: ${baseUrl} (${argv.host}:${mainPort})`);
94
94
  console.log(` CSS (internal): http://localhost:${cssPort}`);
95
95
  console.log(` API (internal): http://localhost:${apiPort}`);
96
- if (idpUrl) {
97
- console.log(` SP mode: Cloud IdP = ${idpUrl}`);
96
+ if (oidcIssuer) {
97
+ console.log(` SP mode: Cloud IdP = ${oidcIssuer}`);
98
98
  }
99
99
  const supervisor = new supervisor_1.Supervisor();
100
100
  const cssBinary = require.resolve('@solid/community-server/bin/server.js');
101
101
  const cssArgs = [cssBinary, '-c', configPath, '-m', runtime_1.PACKAGE_ROOT, '-p', cssPort.toString(), '-b', baseUrl];
102
- if (idpUrl) {
103
- cssArgs.push('--idpUrl', idpUrl);
102
+ if (oidcIssuer) {
103
+ cssArgs.push('--oidcIssuer', oidcIssuer);
104
104
  }
105
105
  supervisor.register({
106
106
  name: 'css',
@@ -130,8 +130,8 @@ exports.startCommand = {
130
130
  XPOD_MAIN_PORT: mainPort.toString(),
131
131
  CSS_INTERNAL_URL: `http://localhost:${cssPort}`,
132
132
  CSS_BASE_URL: baseUrl,
133
- CSS_TOKEN_ENDPOINT: idpUrl
134
- ? `${idpUrl.replace(/\/$/, '')}/.oidc/token`
133
+ CSS_TOKEN_ENDPOINT: oidcIssuer
134
+ ? `${oidcIssuer.replace(/\/$/, '')}/.oidc/token`
135
135
  : `${baseUrl}.oidc/token`,
136
136
  },
137
137
  });
@@ -1 +1 @@
1
- {"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CommandModule } from 'yargs';\nimport path from 'path';\nimport fs from 'fs';\nimport { Supervisor } from '../../supervisor';\nimport { GatewayProxy, getFreePort, PACKAGE_ROOT } from '../../runtime';\n\ninterface StartArgs {\n mode?: string;\n config?: string;\n env?: string;\n port: number;\n host: string;\n}\n\nconst childJsRuntime = typeof (globalThis as { Bun?: unknown }).Bun !== 'undefined'\n ? (process.env.XPOD_NODE_BINARY ?? 'node')\n : process.execPath;\n\nfunction loadEnvFile(envPath: string): void {\n if (!fs.existsSync(envPath)) {\n console.warn(`Env file not found: ${envPath}`);\n return;\n }\n const content = fs.readFileSync(envPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n if (!process.env[key]) {\n process.env[key] = value;\n }\n }\n}\n\nexport const startCommand: CommandModule<object, StartArgs> = {\n command: 'start',\n describe: 'Start xpod services',\n builder: (yargs) =>\n yargs\n .option('mode', {\n alias: 'm',\n type: 'string',\n choices: ['local', 'cloud'],\n description: 'Run mode',\n })\n .option('config', {\n alias: 'c',\n type: 'string',\n description: 'Path to config file (overrides --mode)',\n })\n .option('env', {\n alias: 'e',\n type: 'string',\n description: 'Path to .env file',\n })\n .option('port', {\n alias: 'p',\n type: 'number',\n description: 'Gateway port',\n default: 3000,\n })\n .option('host', {\n type: 'string',\n description: 'Gateway host',\n default: 'localhost',\n }),\n handler: async (argv) => {\n if (argv.env) {\n loadEnvFile(argv.env);\n }\n\n const mainPort =\n argv.port !== 3000\n ? argv.port\n : parseInt(process.env.XPOD_PORT ?? process.env.PORT ?? '3000', 10);\n\n let configPath: string;\n if (argv.config) {\n configPath = argv.config;\n } else if (argv.mode) {\n configPath = path.join(PACKAGE_ROOT, `config/${argv.mode}.json`);\n } else {\n configPath = path.join(PACKAGE_ROOT, 'config/local.json');\n }\n\n const cssPort = await getFreePort(mainPort + 1, argv.host);\n const apiPort = await getFreePort(cssPort + 1, argv.host);\n\n const baseUrl = process.env.CSS_BASE_URL || `http://${argv.host}:${mainPort}/`;\n\n // SP 模式:全部通过环境变量配置(.env.local 或 --env 参数)\n // XPOD_SERVICE_TOKEN, XPOD_NODE_ID, XPOD_NODE_TOKEN, XPOD_CLOUD_API_ENDPOINT, CSS_IDP_URL\n const idpUrl = process.env.CSS_IDP_URL || process.env.XPOD_CLOUD_API_ENDPOINT;\n\n console.log('Starting xpod...');\n console.log(` Gateway: ${baseUrl} (${argv.host}:${mainPort})`);\n console.log(` CSS (internal): http://localhost:${cssPort}`);\n console.log(` API (internal): http://localhost:${apiPort}`);\n if (idpUrl) {\n console.log(` SP mode: Cloud IdP = ${idpUrl}`);\n }\n\n const supervisor = new Supervisor();\n const cssBinary = require.resolve('@solid/community-server/bin/server.js');\n const cssArgs = [cssBinary, '-c', configPath, '-m', PACKAGE_ROOT, '-p', cssPort.toString(), '-b', baseUrl];\n if (idpUrl) {\n cssArgs.push('--idpUrl', idpUrl);\n }\n\n supervisor.register({\n name: 'css',\n command: childJsRuntime,\n args: cssArgs,\n env: {\n ...process.env as Record<string, string>,\n CSS_PORT: cssPort.toString(),\n CSS_BASE_URL: baseUrl,\n },\n });\n\n const isDevMode = __filename.endsWith('.ts');\n const apiArgs = isDevMode\n ? [\n '-r',\n require.resolve('ts-node/register/transpile-only'),\n path.resolve(__dirname, '..', '..', 'api', 'main.ts'),\n ]\n : [path.resolve(__dirname, '..', '..', 'api', 'main.js')];\n\n supervisor.register({\n name: 'api',\n command: childJsRuntime,\n args: apiArgs,\n env: {\n ...process.env as Record<string, string>,\n API_PORT: apiPort.toString(),\n XPOD_MAIN_PORT: mainPort.toString(),\n CSS_INTERNAL_URL: `http://localhost:${cssPort}`,\n CSS_BASE_URL: baseUrl,\n CSS_TOKEN_ENDPOINT: idpUrl\n ? `${idpUrl.replace(/\\/$/, '')}/.oidc/token`\n : `${baseUrl}.oidc/token`,\n },\n });\n\n const proxy = new GatewayProxy(mainPort, supervisor, '0.0.0.0', {\n exitOnStop: true,\n baseUrl,\n });\n proxy.setTargets({\n css: `http://localhost:${cssPort}`,\n api: `http://localhost:${apiPort}`,\n });\n\n await supervisor.startAll();\n await proxy.start();\n\n const shutdown = async (signal: string): Promise<void> => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n await supervisor.stopAll();\n process.exit(0);\n };\n\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('SIGINT', () => shutdown('SIGINT'));\n },\n};\n"]}
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CommandModule } from 'yargs';\nimport path from 'path';\nimport fs from 'fs';\nimport { Supervisor } from '../../supervisor';\nimport { GatewayProxy, getFreePort, PACKAGE_ROOT } from '../../runtime';\n\ninterface StartArgs {\n mode?: string;\n config?: string;\n env?: string;\n port: number;\n host: string;\n}\n\nconst childJsRuntime = typeof (globalThis as { Bun?: unknown }).Bun !== 'undefined'\n ? (process.env.XPOD_NODE_BINARY ?? 'node')\n : process.execPath;\n\nfunction loadEnvFile(envPath: string): void {\n if (!fs.existsSync(envPath)) {\n console.warn(`Env file not found: ${envPath}`);\n return;\n }\n const content = fs.readFileSync(envPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n let value = trimmed.slice(eqIndex + 1).trim();\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n if (!process.env[key]) {\n process.env[key] = value;\n }\n }\n}\n\nexport const startCommand: CommandModule<object, StartArgs> = {\n command: 'start',\n describe: 'Start xpod services',\n builder: (yargs) =>\n yargs\n .option('mode', {\n alias: 'm',\n type: 'string',\n choices: ['local', 'cloud'],\n description: 'Run mode',\n })\n .option('config', {\n alias: 'c',\n type: 'string',\n description: 'Path to config file (overrides --mode)',\n })\n .option('env', {\n alias: 'e',\n type: 'string',\n description: 'Path to .env file',\n })\n .option('port', {\n alias: 'p',\n type: 'number',\n description: 'Gateway port',\n default: 3000,\n })\n .option('host', {\n type: 'string',\n description: 'Gateway host',\n default: 'localhost',\n }),\n handler: async (argv) => {\n if (argv.env) {\n loadEnvFile(argv.env);\n }\n\n const mainPort =\n argv.port !== 3000\n ? argv.port\n : parseInt(process.env.XPOD_PORT ?? process.env.PORT ?? '3000', 10);\n\n let configPath: string;\n if (argv.config) {\n configPath = argv.config;\n } else if (argv.mode) {\n configPath = path.join(PACKAGE_ROOT, `config/${argv.mode}.json`);\n } else {\n configPath = path.join(PACKAGE_ROOT, 'config/local.json');\n }\n\n const cssPort = await getFreePort(mainPort + 1, argv.host);\n const apiPort = await getFreePort(cssPort + 1, argv.host);\n\n const baseUrl = process.env.CSS_BASE_URL || `http://${argv.host}:${mainPort}/`;\n\n // SP 模式:全部通过环境变量配置(.env.local 或 --env 参数)\n // XPOD_SERVICE_TOKEN, XPOD_NODE_ID, XPOD_NODE_TOKEN, XPOD_CLOUD_API_ENDPOINT, CSS_OIDC_ISSUER\n const oidcIssuer = process.env.CSS_OIDC_ISSUER;\n\n console.log('Starting xpod...');\n console.log(` Gateway: ${baseUrl} (${argv.host}:${mainPort})`);\n console.log(` CSS (internal): http://localhost:${cssPort}`);\n console.log(` API (internal): http://localhost:${apiPort}`);\n if (oidcIssuer) {\n console.log(` SP mode: Cloud IdP = ${oidcIssuer}`);\n }\n\n const supervisor = new Supervisor();\n const cssBinary = require.resolve('@solid/community-server/bin/server.js');\n const cssArgs = [cssBinary, '-c', configPath, '-m', PACKAGE_ROOT, '-p', cssPort.toString(), '-b', baseUrl];\n if (oidcIssuer) {\n cssArgs.push('--oidcIssuer', oidcIssuer);\n }\n\n supervisor.register({\n name: 'css',\n command: childJsRuntime,\n args: cssArgs,\n env: {\n ...process.env as Record<string, string>,\n CSS_PORT: cssPort.toString(),\n CSS_BASE_URL: baseUrl,\n },\n });\n\n const isDevMode = __filename.endsWith('.ts');\n const apiArgs = isDevMode\n ? [\n '-r',\n require.resolve('ts-node/register/transpile-only'),\n path.resolve(__dirname, '..', '..', 'api', 'main.ts'),\n ]\n : [path.resolve(__dirname, '..', '..', 'api', 'main.js')];\n\n supervisor.register({\n name: 'api',\n command: childJsRuntime,\n args: apiArgs,\n env: {\n ...process.env as Record<string, string>,\n API_PORT: apiPort.toString(),\n XPOD_MAIN_PORT: mainPort.toString(),\n CSS_INTERNAL_URL: `http://localhost:${cssPort}`,\n CSS_BASE_URL: baseUrl,\n CSS_TOKEN_ENDPOINT: oidcIssuer\n ? `${oidcIssuer.replace(/\\/$/, '')}/.oidc/token`\n : `${baseUrl}.oidc/token`,\n },\n });\n\n const proxy = new GatewayProxy(mainPort, supervisor, '0.0.0.0', {\n exitOnStop: true,\n baseUrl,\n });\n proxy.setTargets({\n css: `http://localhost:${cssPort}`,\n api: `http://localhost:${apiPort}`,\n });\n\n await supervisor.startAll();\n await proxy.start();\n\n const shutdown = async (signal: string): Promise<void> => {\n console.log(`\\nReceived ${signal}, shutting down...`);\n await supervisor.stopAll();\n process.exit(0);\n };\n\n process.on('SIGTERM', () => shutdown('SIGTERM'));\n process.on('SIGINT', () => shutdown('SIGINT'));\n },\n};\n"]}
@@ -1762,8 +1762,8 @@
1762
1762
  "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler",
1763
1763
  "@prefix": true,
1764
1764
  "@context": {
1765
- "options_idpUrl": {
1766
- "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_idpUrl"
1765
+ "options_oidcIssuer": {
1766
+ "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_oidcIssuer"
1767
1767
  },
1768
1768
  "options_message": {
1769
1769
  "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_message"
@@ -1771,8 +1771,8 @@
1771
1771
  "options_cacheMs": {
1772
1772
  "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_cacheMs"
1773
1773
  },
1774
- "idpUrl": {
1775
- "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_idpUrl"
1774
+ "oidcIssuer": {
1775
+ "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_oidcIssuer"
1776
1776
  },
1777
1777
  "message": {
1778
1778
  "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_message"
@@ -1786,8 +1786,8 @@
1786
1786
  "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler",
1787
1787
  "@prefix": true,
1788
1788
  "@context": {
1789
- "options_idpUrl": {
1790
- "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_idpUrl"
1789
+ "options_oidcIssuer": {
1790
+ "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_oidcIssuer"
1791
1791
  },
1792
1792
  "options_message": {
1793
1793
  "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_message"
@@ -1795,8 +1795,8 @@
1795
1795
  "options_source": {
1796
1796
  "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_source"
1797
1797
  },
1798
- "idpUrl": {
1799
- "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_idpUrl"
1798
+ "oidcIssuer": {
1799
+ "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_oidcIssuer"
1800
1800
  },
1801
1801
  "message": {
1802
1802
  "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_message"
@@ -1,7 +1,7 @@
1
1
  import { HttpHandler, type HttpHandlerInput } from '@solid/community-server';
2
2
  export interface AutoDetectIdentityProviderHandlerOptions {
3
3
  /** 外部 IdP 的基础 URL,如果提供则启用 SP 模式 */
4
- idpUrl?: string;
4
+ oidcIssuer?: string;
5
5
  /** 禁用时的消息 */
6
6
  message?: string;
7
7
  /** CSS 默认的 IdentityProviderHandler,标准模式下委托给它 */
@@ -11,12 +11,12 @@ export interface AutoDetectIdentityProviderHandlerOptions {
11
11
  * Auto-detect Identity Provider Handler
12
12
  *
13
13
  * 自动检测运行模式:
14
- * - 如果配置了 idpUrl -> SP 模式:禁用本地账户管理
15
- * - 如果没有配置 idpUrl -> 标准模式:委托给 CSS 默认 Handler
14
+ * - 如果配置了 oidcIssuer -> SP 模式:禁用本地账户管理
15
+ * - 如果没有配置 oidcIssuer -> 标准模式:委托给 CSS 默认 Handler
16
16
  */
17
17
  export declare class AutoDetectIdentityProviderHandler extends HttpHandler {
18
18
  private readonly logger;
19
- private readonly idpUrl?;
19
+ private readonly oidcIssuer?;
20
20
  private readonly message;
21
21
  private readonly source?;
22
22
  constructor(options?: AutoDetectIdentityProviderHandlerOptions);
@@ -7,18 +7,18 @@ const community_server_1 = require("@solid/community-server");
7
7
  * Auto-detect Identity Provider Handler
8
8
  *
9
9
  * 自动检测运行模式:
10
- * - 如果配置了 idpUrl -> SP 模式:禁用本地账户管理
11
- * - 如果没有配置 idpUrl -> 标准模式:委托给 CSS 默认 Handler
10
+ * - 如果配置了 oidcIssuer -> SP 模式:禁用本地账户管理
11
+ * - 如果没有配置 oidcIssuer -> 标准模式:委托给 CSS 默认 Handler
12
12
  */
13
13
  class AutoDetectIdentityProviderHandler extends community_server_1.HttpHandler {
14
14
  constructor(options = {}) {
15
15
  super();
16
16
  this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
17
- this.idpUrl = options.idpUrl;
17
+ this.oidcIssuer = options.oidcIssuer;
18
18
  this.message = options.message ?? 'Account management handled by external IdP';
19
19
  this.source = options.source;
20
- if (this.idpUrl) {
21
- this.logger.info(`SP mode enabled: ${this.message}, external IdP: ${this.idpUrl}`);
20
+ if (this.oidcIssuer) {
21
+ this.logger.info(`SP mode enabled: ${this.message}, external IdP: ${this.oidcIssuer}`);
22
22
  }
23
23
  else {
24
24
  this.logger.info('Standard mode enabled, delegating to source IdentityProviderHandler');
@@ -36,7 +36,7 @@ class AutoDetectIdentityProviderHandler extends community_server_1.HttpHandler {
36
36
  throw new community_server_1.NotImplementedHttpError('Not an IdP request');
37
37
  }
38
38
  // SP 模式:接受 IdP 路径请求,在 handle 中返回 404
39
- if (this.idpUrl) {
39
+ if (this.oidcIssuer) {
40
40
  return;
41
41
  }
42
42
  // 标准模式:委托给 source Handler
@@ -53,7 +53,7 @@ class AutoDetectIdentityProviderHandler extends community_server_1.HttpHandler {
53
53
  * - 标准模式:委托给 source Handler
54
54
  */
55
55
  async handle(input) {
56
- if (this.idpUrl) {
56
+ if (this.oidcIssuer) {
57
57
  const { response } = input;
58
58
  response.writeHead(404, { 'Content-Type': 'application/json' });
59
59
  response.end(JSON.stringify({ error: this.message }));
@@ -1 +1 @@
1
- {"version":3,"file":"AutoDetectIdentityProviderHandler.js","sourceRoot":"","sources":["../../../src/identity/oidc/AutoDetectIdentityProviderHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { getLoggerFor } from 'global-logger-factory';\nimport {\n HttpHandler,\n type HttpHandlerInput,\n NotImplementedHttpError,\n} from '@solid/community-server';\n\nexport interface AutoDetectIdentityProviderHandlerOptions {\n /** 外部 IdP 的基础 URL,如果提供则启用 SP 模式 */\n idpUrl?: string;\n /** 禁用时的消息 */\n message?: string;\n /** CSS 默认的 IdentityProviderHandler,标准模式下委托给它 */\n source?: HttpHandler;\n}\n\n/**\n * Auto-detect Identity Provider Handler\n *\n * 自动检测运行模式:\n * - 如果配置了 idpUrl -> SP 模式:禁用本地账户管理\n * - 如果没有配置 idpUrl -> 标准模式:委托给 CSS 默认 Handler\n */\nexport class AutoDetectIdentityProviderHandler extends HttpHandler {\n private readonly logger = getLoggerFor(this);\n private readonly idpUrl?: string;\n private readonly message: string;\n private readonly source?: HttpHandler;\n\n constructor(options: AutoDetectIdentityProviderHandlerOptions = {}) {\n super();\n this.idpUrl = options.idpUrl;\n this.message = options.message ?? 'Account management handled by external IdP';\n this.source = options.source;\n\n if (this.idpUrl) {\n this.logger.info(`SP mode enabled: ${this.message}, external IdP: ${this.idpUrl}`);\n } else {\n this.logger.info('Standard mode enabled, delegating to source IdentityProviderHandler');\n }\n }\n\n /**\n * 判断是否处理请求\n * - SP 模式:拒绝所有 IdP 请求\n * - 标准模式:委托给 source Handler\n */\n public override async canHandle(input: HttpHandlerInput): Promise<void> {\n const url = input.request.url ?? '';\n\n // 检查是否是 IdP 路径\n if (!this.isIdpPath(url)) {\n throw new NotImplementedHttpError('Not an IdP request');\n }\n\n // SP 模式:接受 IdP 路径请求,在 handle 中返回 404\n if (this.idpUrl) {\n return;\n }\n\n // 标准模式:委托给 source Handler\n if (this.source) {\n await this.source.canHandle(input);\n } else {\n throw new NotImplementedHttpError('No source IdentityProviderHandler configured');\n }\n }\n\n /**\n * 处理请求\n * - SP 模式:不应该到达这里\n * - 标准模式:委托给 source Handler\n */\n public override async handle(input: HttpHandlerInput): Promise<void> {\n if (this.idpUrl) {\n const { response } = input;\n response.writeHead(404, { 'Content-Type': 'application/json' });\n response.end(JSON.stringify({ error: this.message }));\n return;\n }\n\n // 标准模式:委托给 source Handler\n if (this.source) {\n await this.source.handle(input);\n } else {\n throw new NotImplementedHttpError('No source IdentityProviderHandler configured');\n }\n }\n\n /**\n * 检查是否是 IdP 路径\n */\n private isIdpPath(url: string): boolean {\n const pathname = this.getPathname(url);\n return (\n pathname.startsWith('/idp/') ||\n pathname.startsWith('/.account/') ||\n pathname === '/register' ||\n pathname === '/login' ||\n pathname === '/logout'\n );\n }\n\n /**\n * 从 URL 提取 pathname\n */\n private getPathname(url: string): string {\n try {\n return new URL(url, 'http://localhost').pathname;\n } catch {\n return url.split('?')[0];\n }\n }\n}\n"]}
1
+ {"version":3,"file":"AutoDetectIdentityProviderHandler.js","sourceRoot":"","sources":["../../../src/identity/oidc/AutoDetectIdentityProviderHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { getLoggerFor } from 'global-logger-factory';\nimport {\n HttpHandler,\n type HttpHandlerInput,\n NotImplementedHttpError,\n} from '@solid/community-server';\n\nexport interface AutoDetectIdentityProviderHandlerOptions {\n /** 外部 IdP 的基础 URL,如果提供则启用 SP 模式 */\n oidcIssuer?: string;\n /** 禁用时的消息 */\n message?: string;\n /** CSS 默认的 IdentityProviderHandler,标准模式下委托给它 */\n source?: HttpHandler;\n}\n\n/**\n * Auto-detect Identity Provider Handler\n *\n * 自动检测运行模式:\n * - 如果配置了 oidcIssuer -> SP 模式:禁用本地账户管理\n * - 如果没有配置 oidcIssuer -> 标准模式:委托给 CSS 默认 Handler\n */\nexport class AutoDetectIdentityProviderHandler extends HttpHandler {\n private readonly logger = getLoggerFor(this);\n private readonly oidcIssuer?: string;\n private readonly message: string;\n private readonly source?: HttpHandler;\n\n constructor(options: AutoDetectIdentityProviderHandlerOptions = {}) {\n super();\n this.oidcIssuer = options.oidcIssuer;\n this.message = options.message ?? 'Account management handled by external IdP';\n this.source = options.source;\n\n if (this.oidcIssuer) {\n this.logger.info(`SP mode enabled: ${this.message}, external IdP: ${this.oidcIssuer}`);\n } else {\n this.logger.info('Standard mode enabled, delegating to source IdentityProviderHandler');\n }\n }\n\n /**\n * 判断是否处理请求\n * - SP 模式:拒绝所有 IdP 请求\n * - 标准模式:委托给 source Handler\n */\n public override async canHandle(input: HttpHandlerInput): Promise<void> {\n const url = input.request.url ?? '';\n\n // 检查是否是 IdP 路径\n if (!this.isIdpPath(url)) {\n throw new NotImplementedHttpError('Not an IdP request');\n }\n\n // SP 模式:接受 IdP 路径请求,在 handle 中返回 404\n if (this.oidcIssuer) {\n return;\n }\n\n // 标准模式:委托给 source Handler\n if (this.source) {\n await this.source.canHandle(input);\n } else {\n throw new NotImplementedHttpError('No source IdentityProviderHandler configured');\n }\n }\n\n /**\n * 处理请求\n * - SP 模式:不应该到达这里\n * - 标准模式:委托给 source Handler\n */\n public override async handle(input: HttpHandlerInput): Promise<void> {\n if (this.oidcIssuer) {\n const { response } = input;\n response.writeHead(404, { 'Content-Type': 'application/json' });\n response.end(JSON.stringify({ error: this.message }));\n return;\n }\n\n // 标准模式:委托给 source Handler\n if (this.source) {\n await this.source.handle(input);\n } else {\n throw new NotImplementedHttpError('No source IdentityProviderHandler configured');\n }\n }\n\n /**\n * 检查是否是 IdP 路径\n */\n private isIdpPath(url: string): boolean {\n const pathname = this.getPathname(url);\n return (\n pathname.startsWith('/idp/') ||\n pathname.startsWith('/.account/') ||\n pathname === '/register' ||\n pathname === '/login' ||\n pathname === '/logout'\n );\n }\n\n /**\n * 从 URL 提取 pathname\n */\n private getPathname(url: string): string {\n try {\n return new URL(url, 'http://localhost').pathname;\n } catch {\n return url.split('?')[0];\n }\n }\n}\n"]}
@@ -12,10 +12,10 @@
12
12
  "extends": [
13
13
  "css:dist/server/HttpHandler.jsonld#HttpHandler"
14
14
  ],
15
- "comment": "Auto-detect Identity Provider Handler 自动检测运行模式: - 如果配置了 idpUrl -> SP 模式:禁用本地账户管理 - 如果没有配置 idpUrl -> 标准模式:委托给 CSS 默认 Handler",
15
+ "comment": "Auto-detect Identity Provider Handler 自动检测运行模式: - 如果配置了 oidcIssuer -> SP 模式:禁用本地账户管理 - 如果没有配置 oidcIssuer -> 标准模式:委托给 CSS 默认 Handler",
16
16
  "parameters": [
17
17
  {
18
- "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_idpUrl",
18
+ "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_oidcIssuer",
19
19
  "range": {
20
20
  "@type": "ParameterRangeUnion",
21
21
  "parameterRangeElements": [
@@ -60,8 +60,8 @@
60
60
  "memberFieldName": "logger"
61
61
  },
62
62
  {
63
- "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler__member_idpUrl",
64
- "memberFieldName": "idpUrl"
63
+ "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler__member_oidcIssuer",
64
+ "memberFieldName": "oidcIssuer"
65
65
  },
66
66
  {
67
67
  "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler__member_message",
@@ -97,9 +97,9 @@
97
97
  "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options__constructorArgument",
98
98
  "fields": [
99
99
  {
100
- "keyRaw": "idpUrl",
100
+ "keyRaw": "oidcIssuer",
101
101
  "value": {
102
- "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_idpUrl"
102
+ "@id": "undefineds:dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld#AutoDetectIdentityProviderHandler_options_oidcIssuer"
103
103
  }
104
104
  },
105
105
  {
@@ -1,7 +1,7 @@
1
1
  import { HttpHandler, type HttpHandlerInput } from '@solid/community-server';
2
2
  export interface AutoDetectOidcHandlerOptions {
3
3
  /** 外部 IdP 的基础 URL,如果提供则启用 SP 模式 */
4
- idpUrl?: string;
4
+ oidcIssuer?: string;
5
5
  /** 禁用原因说明 */
6
6
  message?: string;
7
7
  /** JWKS 缓存时间 (ms) */
@@ -11,14 +11,14 @@ export interface AutoDetectOidcHandlerOptions {
11
11
  * Auto-detect OIDC Handler
12
12
  *
13
13
  * 自动检测运行模式:
14
- * - 如果配置了 idpUrl -> SP 模式:禁用本地 OIDC,代理外部 IdP 的 JWKS
15
- * - 如果没有配置 idpUrl -> 标准模式:所有 OIDC 请求透传(由 CSS 默认 Handler 处理)
14
+ * - 如果配置了 oidcIssuer -> SP 模式:禁用本地 OIDC,代理外部 IdP 的 JWKS
15
+ * - 如果没有配置 oidcIssuer -> 标准模式:所有 OIDC 请求透传(由 CSS 默认 Handler 处理)
16
16
  *
17
17
  * 使用方式:在 HTTP pipeline 中替换默认的 OidcHandler
18
18
  */
19
19
  export declare class AutoDetectOidcHandler extends HttpHandler {
20
20
  private readonly logger;
21
- private readonly idpUrl?;
21
+ private readonly oidcIssuer?;
22
22
  private readonly jwksUrl?;
23
23
  private readonly message;
24
24
  private readonly cacheMs;
@@ -8,8 +8,8 @@ const community_server_1 = require("@solid/community-server");
8
8
  * Auto-detect OIDC Handler
9
9
  *
10
10
  * 自动检测运行模式:
11
- * - 如果配置了 idpUrl -> SP 模式:禁用本地 OIDC,代理外部 IdP 的 JWKS
12
- * - 如果没有配置 idpUrl -> 标准模式:所有 OIDC 请求透传(由 CSS 默认 Handler 处理)
11
+ * - 如果配置了 oidcIssuer -> SP 模式:禁用本地 OIDC,代理外部 IdP 的 JWKS
12
+ * - 如果没有配置 oidcIssuer -> 标准模式:所有 OIDC 请求透传(由 CSS 默认 Handler 处理)
13
13
  *
14
14
  * 使用方式:在 HTTP pipeline 中替换默认的 OidcHandler
15
15
  */
@@ -17,12 +17,12 @@ class AutoDetectOidcHandler extends community_server_1.HttpHandler {
17
17
  constructor(options = {}) {
18
18
  super();
19
19
  this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
20
- this.idpUrl = options.idpUrl;
21
- this.jwksUrl = this.idpUrl ? `${this.idpUrl.replace(/\/$/, '')}/.oidc/jwks` : undefined;
20
+ this.oidcIssuer = options.oidcIssuer;
21
+ this.jwksUrl = this.oidcIssuer ? `${this.oidcIssuer.replace(/\/$/, '')}/.oidc/jwks` : undefined;
22
22
  this.message = options.message ?? 'OIDC disabled in storage provider mode';
23
23
  this.cacheMs = options.cacheMs ?? 300000; // 默认 5 分钟
24
- if (this.idpUrl) {
25
- this.logger.info(`SP mode enabled, external IdP: ${this.idpUrl}, JWKS: ${this.jwksUrl}`);
24
+ if (this.oidcIssuer) {
25
+ this.logger.info(`SP mode enabled, external IdP: ${this.oidcIssuer}, JWKS: ${this.jwksUrl}`);
26
26
  }
27
27
  else {
28
28
  this.logger.info('Standard mode enabled, OIDC requests will pass through');
@@ -1 +1 @@
1
- {"version":3,"file":"AutoDetectOidcHandler.js","sourceRoot":"","sources":["../../../src/identity/oidc/AutoDetectOidcHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { URL } from 'node:url';\nimport { getLoggerFor } from 'global-logger-factory';\nimport {\n HttpHandler,\n type HttpHandlerInput,\n NotImplementedHttpError,\n InternalServerError,\n} from '@solid/community-server';\n\nexport interface AutoDetectOidcHandlerOptions {\n /** 外部 IdP 的基础 URL,如果提供则启用 SP 模式 */\n idpUrl?: string;\n /** 禁用原因说明 */\n message?: string;\n /** JWKS 缓存时间 (ms) */\n cacheMs?: number;\n}\n\ninterface JwksCache {\n keys: unknown[];\n expiresAt: number;\n}\n\n/**\n * Auto-detect OIDC Handler\n *\n * 自动检测运行模式:\n * - 如果配置了 idpUrl -> SP 模式:禁用本地 OIDC,代理外部 IdP 的 JWKS\n * - 如果没有配置 idpUrl -> 标准模式:所有 OIDC 请求透传(由 CSS 默认 Handler 处理)\n *\n * 使用方式:在 HTTP pipeline 中替换默认的 OidcHandler\n */\nexport class AutoDetectOidcHandler extends HttpHandler {\n private readonly logger = getLoggerFor(this);\n private readonly idpUrl?: string;\n private readonly jwksUrl?: string;\n private readonly message: string;\n private readonly cacheMs: number;\n private jwksCache?: JwksCache;\n\n constructor(options: AutoDetectOidcHandlerOptions = {}) {\n super();\n this.idpUrl = options.idpUrl;\n this.jwksUrl = this.idpUrl ? `${this.idpUrl.replace(/\\/$/, '')}/.oidc/jwks` : undefined;\n this.message = options.message ?? 'OIDC disabled in storage provider mode';\n this.cacheMs = options.cacheMs ?? 300000; // 默认 5 分钟\n\n if (this.idpUrl) {\n this.logger.info(`SP mode enabled, external IdP: ${this.idpUrl}, JWKS: ${this.jwksUrl}`);\n } else {\n this.logger.info('Standard mode enabled, OIDC requests will pass through');\n }\n }\n\n /**\n * 判断是否处理请求\n * - SP 模式:只处理 JWKS 请求,其他 OIDC 请求返回 501\n * - 标准模式:不处理任何请求(透传给 CSS 默认 Handler)\n */\n public override async canHandle({ request }: HttpHandlerInput): Promise<void> {\n const url = request.url ?? '';\n\n // 检查是否是 OIDC 路径\n if (!this.isOidcPath(url)) {\n throw new NotImplementedHttpError('Not an OIDC request');\n }\n\n // 标准模式:不处理,透传给 CSS 默认 Handler\n if (!this.jwksUrl) {\n throw new NotImplementedHttpError('Pass through to default OIDC handler');\n }\n\n // SP 模式:只有 JWKS 请求可以处理\n if (!this.isJwksPath(url)) {\n throw new NotImplementedHttpError(\n `External IdP mode: ${this.message}. Authentication handled by external IdP.`\n );\n }\n }\n\n /**\n * 处理请求\n * - SP 模式:代理 JWKS\n * - 标准模式:不应该到达这里\n */\n public override async handle({ response }: HttpHandlerInput): Promise<void> {\n // 标准模式:不应该到达这里\n if (!this.jwksUrl) {\n throw new InternalServerError('AutoDetectOidcHandler should not handle requests in standard mode');\n }\n\n try {\n const jwks = await this.fetchJwks();\n\n response.statusCode = 200;\n response.setHeader('Content-Type', 'application/json');\n response.setHeader('Cache-Control', `public, max-age=${Math.floor(this.cacheMs / 1000)}`);\n response.end(JSON.stringify(jwks));\n\n this.logger.debug('JWKS proxy successful');\n } catch (error) {\n this.logger.error(`JWKS proxy failed: ${(error as Error).message}`);\n throw new InternalServerError('Failed to proxy JWKS request', { cause: error });\n }\n }\n\n /**\n * 获取并缓存 JWKS\n */\n private async fetchJwks(): Promise<{ keys: unknown[] }> {\n // 检查缓存\n if (this.jwksCache && this.jwksCache.expiresAt > Date.now()) {\n this.logger.debug('Returning cached JWKS');\n return { keys: this.jwksCache.keys };\n }\n\n if (!this.jwksUrl) {\n throw new Error('External JWKS URL not configured');\n }\n\n this.logger.debug(`Fetching JWKS from ${this.jwksUrl}`);\n\n const res = await fetch(this.jwksUrl, {\n headers: { Accept: 'application/json' },\n });\n\n if (!res.ok) {\n throw new Error(`Failed to fetch JWKS: ${res.status} ${res.statusText}`);\n }\n\n const jwks = await res.json() as { keys: unknown[] };\n\n // 验证 JWKS 格式\n if (!Array.isArray(jwks.keys)) {\n throw new Error('Invalid JWKS format: missing keys array');\n }\n\n // 更新缓存\n this.jwksCache = {\n keys: jwks.keys,\n expiresAt: Date.now() + this.cacheMs,\n };\n\n this.logger.debug(`JWKS cached with ${jwks.keys.length} keys`);\n return jwks;\n }\n\n /**\n * 检查是否是 OIDC 路径\n */\n private isOidcPath(url: string): boolean {\n const pathname = this.getPathname(url);\n return (\n pathname.startsWith('/.oidc/') ||\n pathname === '/.well-known/openid-configuration' ||\n pathname === '/.well-known/oauth-authorization-server' ||\n pathname.startsWith('/idp/')\n );\n }\n\n /**\n * 检查是否是 JWKS 路径\n */\n private isJwksPath(url: string): boolean {\n const pathname = this.getPathname(url);\n return pathname === '/.oidc/jwks' || pathname === '/.oidc/jwks.json';\n }\n\n /**\n * 从 URL 提取 pathname\n */\n private getPathname(url: string): string {\n try {\n return new URL(url, 'http://localhost').pathname;\n } catch {\n // 如果解析失败,直接返回 url(可能是相对路径)\n return url.split('?')[0];\n }\n }\n}\n"]}
1
+ {"version":3,"file":"AutoDetectOidcHandler.js","sourceRoot":"","sources":["../../../src/identity/oidc/AutoDetectOidcHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { URL } from 'node:url';\nimport { getLoggerFor } from 'global-logger-factory';\nimport {\n HttpHandler,\n type HttpHandlerInput,\n NotImplementedHttpError,\n InternalServerError,\n} from '@solid/community-server';\n\nexport interface AutoDetectOidcHandlerOptions {\n /** 外部 IdP 的基础 URL,如果提供则启用 SP 模式 */\n oidcIssuer?: string;\n /** 禁用原因说明 */\n message?: string;\n /** JWKS 缓存时间 (ms) */\n cacheMs?: number;\n}\n\ninterface JwksCache {\n keys: unknown[];\n expiresAt: number;\n}\n\n/**\n * Auto-detect OIDC Handler\n *\n * 自动检测运行模式:\n * - 如果配置了 oidcIssuer -> SP 模式:禁用本地 OIDC,代理外部 IdP 的 JWKS\n * - 如果没有配置 oidcIssuer -> 标准模式:所有 OIDC 请求透传(由 CSS 默认 Handler 处理)\n *\n * 使用方式:在 HTTP pipeline 中替换默认的 OidcHandler\n */\nexport class AutoDetectOidcHandler extends HttpHandler {\n private readonly logger = getLoggerFor(this);\n private readonly oidcIssuer?: string;\n private readonly jwksUrl?: string;\n private readonly message: string;\n private readonly cacheMs: number;\n private jwksCache?: JwksCache;\n\n constructor(options: AutoDetectOidcHandlerOptions = {}) {\n super();\n this.oidcIssuer = options.oidcIssuer;\n this.jwksUrl = this.oidcIssuer ? `${this.oidcIssuer.replace(/\\/$/, '')}/.oidc/jwks` : undefined;\n this.message = options.message ?? 'OIDC disabled in storage provider mode';\n this.cacheMs = options.cacheMs ?? 300000; // 默认 5 分钟\n\n if (this.oidcIssuer) {\n this.logger.info(`SP mode enabled, external IdP: ${this.oidcIssuer}, JWKS: ${this.jwksUrl}`);\n } else {\n this.logger.info('Standard mode enabled, OIDC requests will pass through');\n }\n }\n\n /**\n * 判断是否处理请求\n * - SP 模式:只处理 JWKS 请求,其他 OIDC 请求返回 501\n * - 标准模式:不处理任何请求(透传给 CSS 默认 Handler)\n */\n public override async canHandle({ request }: HttpHandlerInput): Promise<void> {\n const url = request.url ?? '';\n\n // 检查是否是 OIDC 路径\n if (!this.isOidcPath(url)) {\n throw new NotImplementedHttpError('Not an OIDC request');\n }\n\n // 标准模式:不处理,透传给 CSS 默认 Handler\n if (!this.jwksUrl) {\n throw new NotImplementedHttpError('Pass through to default OIDC handler');\n }\n\n // SP 模式:只有 JWKS 请求可以处理\n if (!this.isJwksPath(url)) {\n throw new NotImplementedHttpError(\n `External IdP mode: ${this.message}. Authentication handled by external IdP.`\n );\n }\n }\n\n /**\n * 处理请求\n * - SP 模式:代理 JWKS\n * - 标准模式:不应该到达这里\n */\n public override async handle({ response }: HttpHandlerInput): Promise<void> {\n // 标准模式:不应该到达这里\n if (!this.jwksUrl) {\n throw new InternalServerError('AutoDetectOidcHandler should not handle requests in standard mode');\n }\n\n try {\n const jwks = await this.fetchJwks();\n\n response.statusCode = 200;\n response.setHeader('Content-Type', 'application/json');\n response.setHeader('Cache-Control', `public, max-age=${Math.floor(this.cacheMs / 1000)}`);\n response.end(JSON.stringify(jwks));\n\n this.logger.debug('JWKS proxy successful');\n } catch (error) {\n this.logger.error(`JWKS proxy failed: ${(error as Error).message}`);\n throw new InternalServerError('Failed to proxy JWKS request', { cause: error });\n }\n }\n\n /**\n * 获取并缓存 JWKS\n */\n private async fetchJwks(): Promise<{ keys: unknown[] }> {\n // 检查缓存\n if (this.jwksCache && this.jwksCache.expiresAt > Date.now()) {\n this.logger.debug('Returning cached JWKS');\n return { keys: this.jwksCache.keys };\n }\n\n if (!this.jwksUrl) {\n throw new Error('External JWKS URL not configured');\n }\n\n this.logger.debug(`Fetching JWKS from ${this.jwksUrl}`);\n\n const res = await fetch(this.jwksUrl, {\n headers: { Accept: 'application/json' },\n });\n\n if (!res.ok) {\n throw new Error(`Failed to fetch JWKS: ${res.status} ${res.statusText}`);\n }\n\n const jwks = await res.json() as { keys: unknown[] };\n\n // 验证 JWKS 格式\n if (!Array.isArray(jwks.keys)) {\n throw new Error('Invalid JWKS format: missing keys array');\n }\n\n // 更新缓存\n this.jwksCache = {\n keys: jwks.keys,\n expiresAt: Date.now() + this.cacheMs,\n };\n\n this.logger.debug(`JWKS cached with ${jwks.keys.length} keys`);\n return jwks;\n }\n\n /**\n * 检查是否是 OIDC 路径\n */\n private isOidcPath(url: string): boolean {\n const pathname = this.getPathname(url);\n return (\n pathname.startsWith('/.oidc/') ||\n pathname === '/.well-known/openid-configuration' ||\n pathname === '/.well-known/oauth-authorization-server' ||\n pathname.startsWith('/idp/')\n );\n }\n\n /**\n * 检查是否是 JWKS 路径\n */\n private isJwksPath(url: string): boolean {\n const pathname = this.getPathname(url);\n return pathname === '/.oidc/jwks' || pathname === '/.oidc/jwks.json';\n }\n\n /**\n * 从 URL 提取 pathname\n */\n private getPathname(url: string): string {\n try {\n return new URL(url, 'http://localhost').pathname;\n } catch {\n // 如果解析失败,直接返回 url(可能是相对路径)\n return url.split('?')[0];\n }\n }\n}\n"]}
@@ -12,10 +12,10 @@
12
12
  "extends": [
13
13
  "css:dist/server/HttpHandler.jsonld#HttpHandler"
14
14
  ],
15
- "comment": "Auto-detect OIDC Handler 自动检测运行模式: - 如果配置了 idpUrl -> SP 模式:禁用本地 OIDC,代理外部 IdP 的 JWKS - 如果没有配置 idpUrl -> 标准模式:所有 OIDC 请求透传(由 CSS 默认 Handler 处理) 使用方式:在 HTTP pipeline 中替换默认的 OidcHandler",
15
+ "comment": "Auto-detect OIDC Handler 自动检测运行模式: - 如果配置了 oidcIssuer -> SP 模式:禁用本地 OIDC,代理外部 IdP 的 JWKS - 如果没有配置 oidcIssuer -> 标准模式:所有 OIDC 请求透传(由 CSS 默认 Handler 处理) 使用方式:在 HTTP pipeline 中替换默认的 OidcHandler",
16
16
  "parameters": [
17
17
  {
18
- "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_idpUrl",
18
+ "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_oidcIssuer",
19
19
  "range": {
20
20
  "@type": "ParameterRangeUnion",
21
21
  "parameterRangeElements": [
@@ -60,8 +60,8 @@
60
60
  "memberFieldName": "logger"
61
61
  },
62
62
  {
63
- "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler__member_idpUrl",
64
- "memberFieldName": "idpUrl"
63
+ "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler__member_oidcIssuer",
64
+ "memberFieldName": "oidcIssuer"
65
65
  },
66
66
  {
67
67
  "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler__member_jwksUrl",
@@ -113,9 +113,9 @@
113
113
  "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options__constructorArgument",
114
114
  "fields": [
115
115
  {
116
- "keyRaw": "idpUrl",
116
+ "keyRaw": "oidcIssuer",
117
117
  "value": {
118
- "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_idpUrl"
118
+ "@id": "undefineds:dist/identity/oidc/AutoDetectOidcHandler.jsonld#AutoDetectOidcHandler_options_oidcIssuer"
119
119
  }
120
120
  },
121
121
  {
@@ -160,7 +160,7 @@ function buildRuntimeShorthand(runtimeEnv, options, state, baseEnv = NodeRuntime
160
160
  ['emailConfigPort', envValue('CSS_EMAIL_CONFIG_PORT') ?? '587'],
161
161
  ['emailConfigAuthUser', envValue('CSS_EMAIL_CONFIG_AUTH_USER') ?? ''],
162
162
  ['emailConfigAuthPass', envValue('CSS_EMAIL_CONFIG_AUTH_PASS') ?? ''],
163
- ['idpUrl', envValue('CSS_IDP_URL') ?? envValue('XPOD_CLOUD_API_ENDPOINT')],
163
+ ['oidcIssuer', envValue('CSS_OIDC_ISSUER')],
164
164
  ['allowedHosts', envValue('CSS_ALLOWED_HOSTS')],
165
165
  ['nodeId', envValue('XPOD_NODE_ID')],
166
166
  ['nodeToken', envValue('XPOD_NODE_TOKEN')],
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["import { setGlobalLoggerFactory } from 'global-logger-factory';\nimport path from 'node:path';\nimport { ConfigurableLoggerFactory } from '../logging/ConfigurableLoggerFactory';\nimport { PACKAGE_ROOT } from './package-root';\nimport type { RuntimeHost } from './host/types';\nimport { nodeRuntimePlatform } from './platform/node/NodeRuntimePlatform';\nimport type { RuntimePlatform } from './platform/types';\nimport type { XpodRuntimeOptions, XpodRuntimePorts, XpodRuntimeSockets } from './runtime-types';\n\nexport interface RuntimeBootstrapState {\n id: string;\n host: RuntimeHost;\n mode: 'local' | 'cloud';\n transport: 'socket' | 'port';\n bindHost: string;\n runtimeRoot: string;\n rootFilePath: string;\n sparqlEndpoint: string;\n identityDbUrl: string;\n usageDbUrl: string;\n cssAuthMode: 'acp' | 'acl' | 'allow-all';\n apiOpen: boolean;\n logLevel: string;\n baseUrl: string;\n envFilePath?: string;\n ports: XpodRuntimePorts;\n sockets: XpodRuntimeSockets;\n}\n\nfunction ensureTrailingSlash(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\nfunction normalizeWindowsAbsolutePath(filePath: string): string {\n return filePath.replace(/^[\\\\/]+(?=[A-Za-z]:[\\\\/])/, '');\n}\n\nfunction isWindowsAbsolutePath(filePath: string): boolean {\n return /^[A-Za-z]:[\\\\/]/.test(normalizeWindowsAbsolutePath(filePath));\n}\n\nfunction getWindowsDriveRoot(filePath: string): string | undefined {\n const normalizedPath = normalizeWindowsAbsolutePath(filePath);\n return isWindowsAbsolutePath(normalizedPath) ? path.win32.parse(normalizedPath).root.toLowerCase() : undefined;\n}\n\nfunction arePathsOnDifferentWindowsDrives(firstPath: string, secondPath: string): boolean {\n const firstRoot = getWindowsDriveRoot(firstPath);\n const secondRoot = getWindowsDriveRoot(secondPath);\n return Boolean(firstRoot && secondRoot && firstRoot !== secondRoot);\n}\n\nfunction toWindowsFileUrl(filePath: string): string {\n const normalizedPath = normalizeWindowsAbsolutePath(filePath).replace(/\\\\/g, '/');\n return new URL(`file:///${normalizedPath}`).href;\n}\n\nfunction toConfigImportSpecifier(fromFilePath: string, toFilePath: string): string {\n const normalizedFromPath = normalizeWindowsAbsolutePath(fromFilePath);\n const normalizedToPath = normalizeWindowsAbsolutePath(toFilePath);\n const useWindowsPaths = isWindowsAbsolutePath(normalizedFromPath) || isWindowsAbsolutePath(normalizedToPath);\n const pathApi = useWindowsPaths ? path.win32 : path.posix;\n const fromDirectoryPath = pathApi.dirname(useWindowsPaths ? normalizedFromPath : fromFilePath);\n const targetPath = useWindowsPaths ? normalizedToPath : toFilePath;\n\n if (useWindowsPaths && arePathsOnDifferentWindowsDrives(fromDirectoryPath, targetPath)) {\n return toWindowsFileUrl(targetPath);\n }\n\n const relativePath = pathApi.relative(fromDirectoryPath, targetPath).replace(/\\\\/g, '/');\n if (relativePath.startsWith('./') || relativePath.startsWith('../')) {\n return relativePath;\n }\n return `./${relativePath}`;\n}\n\nfunction withDefinedEntries(entries: Array<[string, string | number | boolean | undefined]>): Record<string, string | number | boolean> {\n const result: Record<string, string | number | boolean> = {};\n for (const [key, value] of entries) {\n if (value !== undefined) {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction normalizeDatabaseUrl(\n value: string,\n platform: Pick<RuntimePlatform, 'resolvePath'> = nodeRuntimePlatform,\n): string {\n if (\n value.startsWith('sqlite:') ||\n value.startsWith('postgres://') ||\n value.startsWith('postgresql://') ||\n value.startsWith('mysql://')\n ) {\n return value;\n }\n return `sqlite:${platform.resolvePath(value)}`;\n}\n\nexport async function resolveRuntimeBootstrap(\n id: string,\n options: XpodRuntimeOptions,\n host: RuntimeHost,\n platform: RuntimePlatform = nodeRuntimePlatform,\n): Promise<RuntimeBootstrapState> {\n const mode = options.mode ?? 'local';\n const transport = host.resolveTransport(options.transport);\n const bindHost = options.bindHost ?? '127.0.0.1';\n const runtimeRoot = platform.resolvePath(options.runtimeRoot ?? platform.joinPath(platform.cwd(), '.test-data', 'xpod-runtime', id));\n const rootFilePath = platform.resolvePath(options.rootFilePath ?? platform.joinPath(runtimeRoot, 'data'));\n const sparqlEndpoint = normalizeDatabaseUrl(options.sparqlEndpoint ?? platform.joinPath(runtimeRoot, 'quadstore.sqlite'), platform);\n const identityDbUrl = normalizeDatabaseUrl(options.identityDbUrl ?? platform.joinPath(runtimeRoot, 'identity.sqlite'), platform);\n const usageDbUrl = normalizeDatabaseUrl(options.usageDbUrl ?? platform.joinPath(runtimeRoot, 'usage.sqlite'), platform);\n const cssAuthMode = options.authMode ?? (options.open ? 'allow-all' : 'acp');\n const apiOpen = options.apiOpen ?? options.open ?? false;\n const logLevel = options.logLevel ?? platform.getEnv('CSS_LOGGING_LEVEL') ?? 'warn';\n\n platform.ensureDir(runtimeRoot);\n platform.ensureDir(rootFilePath);\n\n const socketsRoot = platform.joinPath(runtimeRoot, 'sockets');\n if (transport === 'socket') {\n platform.ensureDir(socketsRoot);\n }\n const ports: XpodRuntimePorts = transport === 'port'\n ? await host.allocatePorts({\n gatewayPort: options.gatewayPort,\n cssPort: options.cssPort,\n apiPort: options.apiPort,\n basePort: 5600,\n })\n : {};\n const sockets: XpodRuntimeSockets = {};\n\n if (transport === 'socket') {\n sockets.gateway = platform.resolvePath(options.gatewaySocketPath ?? platform.joinPath(socketsRoot, 'gateway.sock'));\n sockets.css = platform.resolvePath(options.cssSocketPath ?? platform.joinPath(socketsRoot, 'css.sock'));\n sockets.api = platform.resolvePath(options.apiSocketPath ?? platform.joinPath(socketsRoot, 'api.sock'));\n }\n\n const baseUrl = ensureTrailingSlash(\n options.baseUrl ?? (transport === 'socket'\n ? 'http://localhost'\n : `http://${bindHost}:${ports.gateway}`),\n );\n\n return {\n id,\n host,\n mode,\n transport,\n bindHost,\n runtimeRoot,\n rootFilePath,\n sparqlEndpoint,\n identityDbUrl,\n usageDbUrl,\n cssAuthMode,\n apiOpen,\n logLevel,\n baseUrl,\n envFilePath: options.envFile ? platform.resolvePath(options.envFile) : undefined,\n ports,\n sockets,\n };\n}\n\nexport function buildRuntimeEnv(\n state: RuntimeBootstrapState,\n options: XpodRuntimeOptions,\n envFromFile: Record<string, string | undefined> = {},\n): Record<string, string | undefined> {\n return {\n ...envFromFile,\n ...options.env,\n XPOD_ENV_PATH: state.envFilePath,\n XPOD_EDITION: state.mode,\n CSS_BASE_URL: state.baseUrl,\n CSS_TOKEN_ENDPOINT: `${state.baseUrl}.oidc/token`,\n CSS_ROOT_FILE_PATH: state.rootFilePath,\n CSS_IDENTITY_DB_URL: state.identityDbUrl,\n DATABASE_URL: state.identityDbUrl,\n CSS_PORT: state.ports.css !== undefined ? String(state.ports.css) : undefined,\n API_PORT: state.ports.api !== undefined ? String(state.ports.api) : undefined,\n API_HOST: state.bindHost,\n API_SOCKET_PATH: state.sockets.api,\n XPOD_MAIN_PORT: state.ports.gateway !== undefined ? String(state.ports.gateway) : undefined,\n CORS_ORIGINS: new URL(state.baseUrl).origin,\n CSS_LOGGING_LEVEL: state.logLevel,\n };\n}\n\nexport function buildRuntimeShorthand(\n runtimeEnv: Record<string, string | undefined>,\n options: XpodRuntimeOptions,\n state: RuntimeBootstrapState,\n baseEnv: Record<string, string | undefined> = nodeRuntimePlatform.baseEnv,\n): Record<string, string | number | boolean> {\n const envValue = (key: string): string | undefined => runtimeEnv[key] ?? baseEnv[key];\n\n return {\n ...withDefinedEntries([\n ['baseStorageDomain', envValue('CSS_BASE_STORAGE_DOMAIN')],\n ['minioAccessKey', envValue('CSS_MINIO_ACCESS_KEY')],\n ['minioSecretKey', envValue('CSS_MINIO_SECRET_KEY')],\n ['minioEndpoint', envValue('CSS_MINIO_ENDPOINT')],\n ['minioBucketName', envValue('CSS_MINIO_BUCKET_NAME')],\n ['redisClient', envValue('CSS_REDIS_CLIENT')],\n ['redisUsername', envValue('CSS_REDIS_USERNAME')],\n ['redisPassword', envValue('CSS_REDIS_PASSWORD')],\n ['emailConfigHost', envValue('CSS_EMAIL_CONFIG_HOST') ?? ''],\n ['emailConfigPort', envValue('CSS_EMAIL_CONFIG_PORT') ?? '587'],\n ['emailConfigAuthUser', envValue('CSS_EMAIL_CONFIG_AUTH_USER') ?? ''],\n ['emailConfigAuthPass', envValue('CSS_EMAIL_CONFIG_AUTH_PASS') ?? ''],\n ['idpUrl', envValue('CSS_IDP_URL') ?? envValue('XPOD_CLOUD_API_ENDPOINT')],\n ['allowedHosts', envValue('CSS_ALLOWED_HOSTS')],\n ['nodeId', envValue('XPOD_NODE_ID')],\n ['nodeToken', envValue('XPOD_NODE_TOKEN')],\n ['serviceToken', envValue('XPOD_SERVICE_TOKEN')],\n ]),\n baseUrl: state.baseUrl,\n rootFilePath: state.rootFilePath,\n sparqlEndpoint: state.sparqlEndpoint,\n identityDbUrl: state.identityDbUrl,\n usageDbUrl: state.usageDbUrl,\n logLevel: state.logLevel,\n authMode: state.cssAuthMode,\n edition: state.mode === 'cloud' ? 'server' : 'local',\n edgeNodesEnabled: options.edgeNodesEnabled ?? false,\n centerRegistrationEnabled: options.centerRegistrationEnabled ?? false,\n ...(options.shorthand ?? {}),\n };\n}\n\nexport function createCssRuntimeConfig(\n state: RuntimeBootstrapState,\n open: boolean,\n platform: Pick<RuntimePlatform, 'dirname' | 'ensureDir' | 'joinPath' | 'writeTextFile'> = nodeRuntimePlatform,\n): string {\n const configPath = normalizeWindowsAbsolutePath(platform.joinPath(PACKAGE_ROOT, `config/${state.mode}.json`));\n if (!open) {\n return configPath;\n }\n\n const runtimeRoot = normalizeWindowsAbsolutePath(state.runtimeRoot);\n const runtimeConfigPath = arePathsOnDifferentWindowsDrives(runtimeRoot, configPath)\n ? (() => {\n const runtimeConfigDir = normalizeWindowsAbsolutePath(platform.joinPath(\n platform.dirname(configPath),\n '..',\n '.xpod-runtime',\n state.id,\n ));\n platform.ensureDir(runtimeConfigDir);\n return normalizeWindowsAbsolutePath(platform.joinPath(runtimeConfigDir, 'css-runtime.config.json'));\n })()\n : normalizeWindowsAbsolutePath(platform.joinPath(runtimeRoot, 'css-runtime.config.json'));\n const openConfigPath = normalizeWindowsAbsolutePath(platform.joinPath(PACKAGE_ROOT, 'config/runtime-open.json'));\n platform.writeTextFile(runtimeConfigPath, JSON.stringify({\n '@context': [\n 'https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^8.0.0/components/context.jsonld',\n 'https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld',\n ],\n import: [\n toConfigImportSpecifier(runtimeConfigPath, configPath),\n toConfigImportSpecifier(runtimeConfigPath, openConfigPath),\n ],\n }, null, 2));\n\n return runtimeConfigPath;\n}\n\nexport function initRuntimeLogger(\n level: string,\n platform: Pick<RuntimePlatform, 'cwd' | 'joinPath'> = nodeRuntimePlatform,\n): void {\n const loggerFactory = new ConfigurableLoggerFactory(level, {\n fileName: platform.joinPath(platform.cwd(), 'logs/xpod-%DATE%.log'),\n showLocation: true,\n });\n setGlobalLoggerFactory(loggerFactory);\n}\n"]}
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["import { setGlobalLoggerFactory } from 'global-logger-factory';\nimport path from 'node:path';\nimport { ConfigurableLoggerFactory } from '../logging/ConfigurableLoggerFactory';\nimport { PACKAGE_ROOT } from './package-root';\nimport type { RuntimeHost } from './host/types';\nimport { nodeRuntimePlatform } from './platform/node/NodeRuntimePlatform';\nimport type { RuntimePlatform } from './platform/types';\nimport type { XpodRuntimeOptions, XpodRuntimePorts, XpodRuntimeSockets } from './runtime-types';\n\nexport interface RuntimeBootstrapState {\n id: string;\n host: RuntimeHost;\n mode: 'local' | 'cloud';\n transport: 'socket' | 'port';\n bindHost: string;\n runtimeRoot: string;\n rootFilePath: string;\n sparqlEndpoint: string;\n identityDbUrl: string;\n usageDbUrl: string;\n cssAuthMode: 'acp' | 'acl' | 'allow-all';\n apiOpen: boolean;\n logLevel: string;\n baseUrl: string;\n envFilePath?: string;\n ports: XpodRuntimePorts;\n sockets: XpodRuntimeSockets;\n}\n\nfunction ensureTrailingSlash(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\nfunction normalizeWindowsAbsolutePath(filePath: string): string {\n return filePath.replace(/^[\\\\/]+(?=[A-Za-z]:[\\\\/])/, '');\n}\n\nfunction isWindowsAbsolutePath(filePath: string): boolean {\n return /^[A-Za-z]:[\\\\/]/.test(normalizeWindowsAbsolutePath(filePath));\n}\n\nfunction getWindowsDriveRoot(filePath: string): string | undefined {\n const normalizedPath = normalizeWindowsAbsolutePath(filePath);\n return isWindowsAbsolutePath(normalizedPath) ? path.win32.parse(normalizedPath).root.toLowerCase() : undefined;\n}\n\nfunction arePathsOnDifferentWindowsDrives(firstPath: string, secondPath: string): boolean {\n const firstRoot = getWindowsDriveRoot(firstPath);\n const secondRoot = getWindowsDriveRoot(secondPath);\n return Boolean(firstRoot && secondRoot && firstRoot !== secondRoot);\n}\n\nfunction toWindowsFileUrl(filePath: string): string {\n const normalizedPath = normalizeWindowsAbsolutePath(filePath).replace(/\\\\/g, '/');\n return new URL(`file:///${normalizedPath}`).href;\n}\n\nfunction toConfigImportSpecifier(fromFilePath: string, toFilePath: string): string {\n const normalizedFromPath = normalizeWindowsAbsolutePath(fromFilePath);\n const normalizedToPath = normalizeWindowsAbsolutePath(toFilePath);\n const useWindowsPaths = isWindowsAbsolutePath(normalizedFromPath) || isWindowsAbsolutePath(normalizedToPath);\n const pathApi = useWindowsPaths ? path.win32 : path.posix;\n const fromDirectoryPath = pathApi.dirname(useWindowsPaths ? normalizedFromPath : fromFilePath);\n const targetPath = useWindowsPaths ? normalizedToPath : toFilePath;\n\n if (useWindowsPaths && arePathsOnDifferentWindowsDrives(fromDirectoryPath, targetPath)) {\n return toWindowsFileUrl(targetPath);\n }\n\n const relativePath = pathApi.relative(fromDirectoryPath, targetPath).replace(/\\\\/g, '/');\n if (relativePath.startsWith('./') || relativePath.startsWith('../')) {\n return relativePath;\n }\n return `./${relativePath}`;\n}\n\nfunction withDefinedEntries(entries: Array<[string, string | number | boolean | undefined]>): Record<string, string | number | boolean> {\n const result: Record<string, string | number | boolean> = {};\n for (const [key, value] of entries) {\n if (value !== undefined) {\n result[key] = value;\n }\n }\n return result;\n}\n\nfunction normalizeDatabaseUrl(\n value: string,\n platform: Pick<RuntimePlatform, 'resolvePath'> = nodeRuntimePlatform,\n): string {\n if (\n value.startsWith('sqlite:') ||\n value.startsWith('postgres://') ||\n value.startsWith('postgresql://') ||\n value.startsWith('mysql://')\n ) {\n return value;\n }\n return `sqlite:${platform.resolvePath(value)}`;\n}\n\nexport async function resolveRuntimeBootstrap(\n id: string,\n options: XpodRuntimeOptions,\n host: RuntimeHost,\n platform: RuntimePlatform = nodeRuntimePlatform,\n): Promise<RuntimeBootstrapState> {\n const mode = options.mode ?? 'local';\n const transport = host.resolveTransport(options.transport);\n const bindHost = options.bindHost ?? '127.0.0.1';\n const runtimeRoot = platform.resolvePath(options.runtimeRoot ?? platform.joinPath(platform.cwd(), '.test-data', 'xpod-runtime', id));\n const rootFilePath = platform.resolvePath(options.rootFilePath ?? platform.joinPath(runtimeRoot, 'data'));\n const sparqlEndpoint = normalizeDatabaseUrl(options.sparqlEndpoint ?? platform.joinPath(runtimeRoot, 'quadstore.sqlite'), platform);\n const identityDbUrl = normalizeDatabaseUrl(options.identityDbUrl ?? platform.joinPath(runtimeRoot, 'identity.sqlite'), platform);\n const usageDbUrl = normalizeDatabaseUrl(options.usageDbUrl ?? platform.joinPath(runtimeRoot, 'usage.sqlite'), platform);\n const cssAuthMode = options.authMode ?? (options.open ? 'allow-all' : 'acp');\n const apiOpen = options.apiOpen ?? options.open ?? false;\n const logLevel = options.logLevel ?? platform.getEnv('CSS_LOGGING_LEVEL') ?? 'warn';\n\n platform.ensureDir(runtimeRoot);\n platform.ensureDir(rootFilePath);\n\n const socketsRoot = platform.joinPath(runtimeRoot, 'sockets');\n if (transport === 'socket') {\n platform.ensureDir(socketsRoot);\n }\n const ports: XpodRuntimePorts = transport === 'port'\n ? await host.allocatePorts({\n gatewayPort: options.gatewayPort,\n cssPort: options.cssPort,\n apiPort: options.apiPort,\n basePort: 5600,\n })\n : {};\n const sockets: XpodRuntimeSockets = {};\n\n if (transport === 'socket') {\n sockets.gateway = platform.resolvePath(options.gatewaySocketPath ?? platform.joinPath(socketsRoot, 'gateway.sock'));\n sockets.css = platform.resolvePath(options.cssSocketPath ?? platform.joinPath(socketsRoot, 'css.sock'));\n sockets.api = platform.resolvePath(options.apiSocketPath ?? platform.joinPath(socketsRoot, 'api.sock'));\n }\n\n const baseUrl = ensureTrailingSlash(\n options.baseUrl ?? (transport === 'socket'\n ? 'http://localhost'\n : `http://${bindHost}:${ports.gateway}`),\n );\n\n return {\n id,\n host,\n mode,\n transport,\n bindHost,\n runtimeRoot,\n rootFilePath,\n sparqlEndpoint,\n identityDbUrl,\n usageDbUrl,\n cssAuthMode,\n apiOpen,\n logLevel,\n baseUrl,\n envFilePath: options.envFile ? platform.resolvePath(options.envFile) : undefined,\n ports,\n sockets,\n };\n}\n\nexport function buildRuntimeEnv(\n state: RuntimeBootstrapState,\n options: XpodRuntimeOptions,\n envFromFile: Record<string, string | undefined> = {},\n): Record<string, string | undefined> {\n return {\n ...envFromFile,\n ...options.env,\n XPOD_ENV_PATH: state.envFilePath,\n XPOD_EDITION: state.mode,\n CSS_BASE_URL: state.baseUrl,\n CSS_TOKEN_ENDPOINT: `${state.baseUrl}.oidc/token`,\n CSS_ROOT_FILE_PATH: state.rootFilePath,\n CSS_IDENTITY_DB_URL: state.identityDbUrl,\n DATABASE_URL: state.identityDbUrl,\n CSS_PORT: state.ports.css !== undefined ? String(state.ports.css) : undefined,\n API_PORT: state.ports.api !== undefined ? String(state.ports.api) : undefined,\n API_HOST: state.bindHost,\n API_SOCKET_PATH: state.sockets.api,\n XPOD_MAIN_PORT: state.ports.gateway !== undefined ? String(state.ports.gateway) : undefined,\n CORS_ORIGINS: new URL(state.baseUrl).origin,\n CSS_LOGGING_LEVEL: state.logLevel,\n };\n}\n\nexport function buildRuntimeShorthand(\n runtimeEnv: Record<string, string | undefined>,\n options: XpodRuntimeOptions,\n state: RuntimeBootstrapState,\n baseEnv: Record<string, string | undefined> = nodeRuntimePlatform.baseEnv,\n): Record<string, string | number | boolean> {\n const envValue = (key: string): string | undefined => runtimeEnv[key] ?? baseEnv[key];\n\n return {\n ...withDefinedEntries([\n ['baseStorageDomain', envValue('CSS_BASE_STORAGE_DOMAIN')],\n ['minioAccessKey', envValue('CSS_MINIO_ACCESS_KEY')],\n ['minioSecretKey', envValue('CSS_MINIO_SECRET_KEY')],\n ['minioEndpoint', envValue('CSS_MINIO_ENDPOINT')],\n ['minioBucketName', envValue('CSS_MINIO_BUCKET_NAME')],\n ['redisClient', envValue('CSS_REDIS_CLIENT')],\n ['redisUsername', envValue('CSS_REDIS_USERNAME')],\n ['redisPassword', envValue('CSS_REDIS_PASSWORD')],\n ['emailConfigHost', envValue('CSS_EMAIL_CONFIG_HOST') ?? ''],\n ['emailConfigPort', envValue('CSS_EMAIL_CONFIG_PORT') ?? '587'],\n ['emailConfigAuthUser', envValue('CSS_EMAIL_CONFIG_AUTH_USER') ?? ''],\n ['emailConfigAuthPass', envValue('CSS_EMAIL_CONFIG_AUTH_PASS') ?? ''],\n ['oidcIssuer', envValue('CSS_OIDC_ISSUER')],\n ['allowedHosts', envValue('CSS_ALLOWED_HOSTS')],\n ['nodeId', envValue('XPOD_NODE_ID')],\n ['nodeToken', envValue('XPOD_NODE_TOKEN')],\n ['serviceToken', envValue('XPOD_SERVICE_TOKEN')],\n ]),\n baseUrl: state.baseUrl,\n rootFilePath: state.rootFilePath,\n sparqlEndpoint: state.sparqlEndpoint,\n identityDbUrl: state.identityDbUrl,\n usageDbUrl: state.usageDbUrl,\n logLevel: state.logLevel,\n authMode: state.cssAuthMode,\n edition: state.mode === 'cloud' ? 'server' : 'local',\n edgeNodesEnabled: options.edgeNodesEnabled ?? false,\n centerRegistrationEnabled: options.centerRegistrationEnabled ?? false,\n ...(options.shorthand ?? {}),\n };\n}\n\nexport function createCssRuntimeConfig(\n state: RuntimeBootstrapState,\n open: boolean,\n platform: Pick<RuntimePlatform, 'dirname' | 'ensureDir' | 'joinPath' | 'writeTextFile'> = nodeRuntimePlatform,\n): string {\n const configPath = normalizeWindowsAbsolutePath(platform.joinPath(PACKAGE_ROOT, `config/${state.mode}.json`));\n if (!open) {\n return configPath;\n }\n\n const runtimeRoot = normalizeWindowsAbsolutePath(state.runtimeRoot);\n const runtimeConfigPath = arePathsOnDifferentWindowsDrives(runtimeRoot, configPath)\n ? (() => {\n const runtimeConfigDir = normalizeWindowsAbsolutePath(platform.joinPath(\n platform.dirname(configPath),\n '..',\n '.xpod-runtime',\n state.id,\n ));\n platform.ensureDir(runtimeConfigDir);\n return normalizeWindowsAbsolutePath(platform.joinPath(runtimeConfigDir, 'css-runtime.config.json'));\n })()\n : normalizeWindowsAbsolutePath(platform.joinPath(runtimeRoot, 'css-runtime.config.json'));\n const openConfigPath = normalizeWindowsAbsolutePath(platform.joinPath(PACKAGE_ROOT, 'config/runtime-open.json'));\n platform.writeTextFile(runtimeConfigPath, JSON.stringify({\n '@context': [\n 'https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^8.0.0/components/context.jsonld',\n 'https://linkedsoftwaredependencies.org/bundles/npm/asynchronous-handlers/^1.0.0/components/context.jsonld',\n ],\n import: [\n toConfigImportSpecifier(runtimeConfigPath, configPath),\n toConfigImportSpecifier(runtimeConfigPath, openConfigPath),\n ],\n }, null, 2));\n\n return runtimeConfigPath;\n}\n\nexport function initRuntimeLogger(\n level: string,\n platform: Pick<RuntimePlatform, 'cwd' | 'joinPath'> = nodeRuntimePlatform,\n): void {\n const loggerFactory = new ConfigurableLoggerFactory(level, {\n fileName: platform.joinPath(platform.cwd(), 'logs/xpod-%DATE%.log'),\n showLocation: true,\n });\n setGlobalLoggerFactory(loggerFactory);\n}\n"]}