@undefineds.co/xpod 0.2.6 → 0.2.7
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/config/cloud.json +1 -1
- package/dist/api/chatkit/ai-provider.js +4 -3
- package/dist/api/chatkit/ai-provider.js.map +1 -1
- package/dist/api/chatkit/default-agent.js +8 -7
- package/dist/api/chatkit/default-agent.js.map +1 -1
- package/dist/api/chatkit/runtime/PtyThreadRuntime.js +2 -1
- package/dist/api/chatkit/runtime/PtyThreadRuntime.js.map +1 -1
- package/dist/api/handlers/AdminHandler.js +1 -1
- package/dist/api/handlers/AdminHandler.js.map +1 -1
- package/dist/api/service/VercelChatService.js +23 -23
- package/dist/api/service/VercelChatService.js.map +1 -1
- package/dist/api/service/platform-ai-config.d.ts +8 -0
- package/dist/api/service/platform-ai-config.js +64 -0
- package/dist/api/service/platform-ai-config.js.map +1 -0
- package/dist/cli/commands/start.js +1 -2
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/components/context.jsonld +3 -0
- package/dist/http/TracingHandler.js +2 -0
- package/dist/http/TracingHandler.js.map +1 -1
- package/dist/identity/drizzle/DrizzleIndexedStorage.d.ts +10 -1
- package/dist/identity/drizzle/DrizzleIndexedStorage.js +99 -6
- package/dist/identity/drizzle/DrizzleIndexedStorage.js.map +1 -1
- package/dist/identity/drizzle/DrizzleIndexedStorage.jsonld +36 -0
- package/dist/main.js +1 -2
- package/dist/main.js.map +1 -1
- package/dist/provision/ProvisionPodCreator.d.ts +1 -0
- package/dist/provision/ProvisionPodCreator.js +25 -2
- package/dist/provision/ProvisionPodCreator.js.map +1 -1
- package/dist/provision/ProvisionPodCreator.jsonld +4 -0
- package/dist/runtime/bootstrap.js +4 -4
- package/dist/runtime/bootstrap.js.map +1 -1
- package/dist/storage/MetadataRequestContext.d.ts +13 -0
- package/dist/storage/MetadataRequestContext.js +6 -0
- package/dist/storage/MetadataRequestContext.js.map +1 -0
- package/dist/storage/NodeSqliteDrizzle.js +19 -5
- package/dist/storage/NodeSqliteDrizzle.js.map +1 -1
- package/dist/storage/accessors/MinioDataAccessor.d.ts +1 -0
- package/dist/storage/accessors/MinioDataAccessor.js +25 -2
- package/dist/storage/accessors/MinioDataAccessor.js.map +1 -1
- package/dist/storage/accessors/MinioDataAccessor.jsonld +4 -0
- package/dist/storage/accessors/MixDataAccessor.d.ts +3 -1
- package/dist/storage/accessors/MixDataAccessor.js +61 -23
- package/dist/storage/accessors/MixDataAccessor.js.map +1 -1
- package/dist/storage/accessors/MixDataAccessor.jsonld +23 -0
- package/dist/supervisor/Supervisor.js +1 -1
- package/dist/supervisor/Supervisor.js.map +1 -1
- package/package.json +1 -1
- package/static/app/assets/index.css +1 -1
- package/static/app/assets/main.js +50 -10
- package/static/dashboard/assets/{dashboard-BfmT5Vc8.js → dashboard-CTk9cn1-.js} +8 -8
- package/static/dashboard/assets/dashboard-VQRsvXx9.css +1 -0
- package/static/dashboard/dashboard.html +2 -2
- package/static/dashboard/assets/dashboard-DkZOr7bV.css +0 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAiGatewayBaseUrl = getAiGatewayBaseUrl;
|
|
4
|
+
exports.getAiGatewayApiKey = getAiGatewayApiKey;
|
|
5
|
+
exports.getPlatformApiBaseUrl = getPlatformApiBaseUrl;
|
|
6
|
+
exports.getPlatformApiKey = getPlatformApiKey;
|
|
7
|
+
exports.hasPlatformApiConfig = hasPlatformApiConfig;
|
|
8
|
+
exports.getPlatformProviderId = getPlatformProviderId;
|
|
9
|
+
exports.getPlatformDefaultModel = getPlatformDefaultModel;
|
|
10
|
+
exports.getPlatformTimeoutMs = getPlatformTimeoutMs;
|
|
11
|
+
const provider_registry_1 = require("./provider-registry");
|
|
12
|
+
const DEFAULT_PLATFORM_PROVIDER = 'undefineds';
|
|
13
|
+
const DEFAULT_PLATFORM_MODEL = 'linx-lite';
|
|
14
|
+
const DEFAULT_PLATFORM_TIMEOUT_MS = 30_000;
|
|
15
|
+
function readTrimmedEnv(name) {
|
|
16
|
+
const value = process.env[name]?.trim();
|
|
17
|
+
return value ? value : undefined;
|
|
18
|
+
}
|
|
19
|
+
function getAiGatewayBaseUrl() {
|
|
20
|
+
const explicit = readTrimmedEnv('DEFAULT_API_BASE');
|
|
21
|
+
if (explicit) {
|
|
22
|
+
return explicit.replace(/\/$/, '');
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
function getAiGatewayApiKey() {
|
|
27
|
+
return readTrimmedEnv('DEFAULT_API_KEY');
|
|
28
|
+
}
|
|
29
|
+
function getPlatformApiBaseUrl() {
|
|
30
|
+
const explicit = readTrimmedEnv('DEFAULT_API_BASE');
|
|
31
|
+
if (explicit) {
|
|
32
|
+
return explicit.replace(/\/$/, '');
|
|
33
|
+
}
|
|
34
|
+
const aiGatewayBase = getAiGatewayBaseUrl();
|
|
35
|
+
if (!aiGatewayBase) {
|
|
36
|
+
const provider = getPlatformProviderId();
|
|
37
|
+
if (provider === DEFAULT_PLATFORM_PROVIDER) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
return (0, provider_registry_1.getDefaultBaseUrl)(provider);
|
|
41
|
+
}
|
|
42
|
+
return aiGatewayBase.endsWith('/v1') ? aiGatewayBase : `${aiGatewayBase}/v1`;
|
|
43
|
+
}
|
|
44
|
+
function getPlatformApiKey() {
|
|
45
|
+
return getAiGatewayApiKey() ?? '';
|
|
46
|
+
}
|
|
47
|
+
function hasPlatformApiConfig() {
|
|
48
|
+
return !!(getPlatformApiBaseUrl() || getPlatformApiKey());
|
|
49
|
+
}
|
|
50
|
+
function getPlatformProviderId() {
|
|
51
|
+
return readTrimmedEnv('DEFAULT_PROVIDER') ?? DEFAULT_PLATFORM_PROVIDER;
|
|
52
|
+
}
|
|
53
|
+
function getPlatformDefaultModel() {
|
|
54
|
+
return readTrimmedEnv('DEFAULT_MODEL') ?? DEFAULT_PLATFORM_MODEL;
|
|
55
|
+
}
|
|
56
|
+
function getPlatformTimeoutMs() {
|
|
57
|
+
const raw = readTrimmedEnv('DEFAULT_TIMEOUT_MS');
|
|
58
|
+
if (!raw) {
|
|
59
|
+
return DEFAULT_PLATFORM_TIMEOUT_MS;
|
|
60
|
+
}
|
|
61
|
+
const parsed = Number(raw);
|
|
62
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_PLATFORM_TIMEOUT_MS;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=platform-ai-config.js.map
|
|
@@ -0,0 +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"]}
|
|
@@ -98,8 +98,7 @@ exports.startCommand = {
|
|
|
98
98
|
}
|
|
99
99
|
const supervisor = new supervisor_1.Supervisor();
|
|
100
100
|
const cssBinary = require.resolve('@solid/community-server/bin/server.js');
|
|
101
|
-
const
|
|
102
|
-
const cssArgs = [cssBinary, '-c', configPath, '-m', cssModuleRoot, '-p', cssPort.toString(), '-b', baseUrl];
|
|
101
|
+
const cssArgs = [cssBinary, '-c', configPath, '-m', runtime_1.PACKAGE_ROOT, '-p', cssPort.toString(), '-b', baseUrl];
|
|
103
102
|
if (idpUrl) {
|
|
104
103
|
cssArgs.push('--idpUrl', idpUrl);
|
|
105
104
|
}
|
|
@@ -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 cssModuleRoot = path.dirname(require.resolve('@solid/community-server/package.json'));\n\n const cssArgs = [cssBinary, '-c', configPath, '-m', cssModuleRoot, '-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_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"]}
|
|
@@ -342,6 +342,9 @@
|
|
|
342
342
|
"presignedRedirectEnabled": {
|
|
343
343
|
"@id": "undefineds:dist/storage/accessors/MixDataAccessor.jsonld#MixDataAccessor_presignedRedirectEnabled"
|
|
344
344
|
},
|
|
345
|
+
"mirrorContainersToUnstructured": {
|
|
346
|
+
"@id": "undefineds:dist/storage/accessors/MixDataAccessor.jsonld#MixDataAccessor_mirrorContainersToUnstructured"
|
|
347
|
+
},
|
|
345
348
|
"structuredDataAccessor": {
|
|
346
349
|
"@id": "undefineds:dist/storage/accessors/MixDataAccessor.jsonld#MixDataAccessor_structuredDataAccessor"
|
|
347
350
|
},
|
|
@@ -8,6 +8,7 @@ const global_logger_factory_1 = require("global-logger-factory");
|
|
|
8
8
|
const community_server_1 = require("@solid/community-server");
|
|
9
9
|
const LogContext_1 = require("../logging/LogContext");
|
|
10
10
|
const LockContext_1 = require("../util/LockContext");
|
|
11
|
+
const MetadataRequestContext_1 = require("../storage/MetadataRequestContext");
|
|
11
12
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
12
13
|
/**
|
|
13
14
|
* HTTP Handler that provides request tracing capabilities.
|
|
@@ -39,6 +40,7 @@ class TracingHandler extends community_server_1.HttpHandler {
|
|
|
39
40
|
// Enter logging context for this request
|
|
40
41
|
LogContext_1.logContext.enterWith({ requestId });
|
|
41
42
|
LockContext_1.lockContext.enterWith(new Map());
|
|
43
|
+
MetadataRequestContext_1.metadataRequestContext.enterWith({ metadataCache: new Map() });
|
|
42
44
|
// Register finish listener to log completion
|
|
43
45
|
input.response.on('finish', () => {
|
|
44
46
|
const ms = Date.now() - startTime;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TracingHandler.js","sourceRoot":"","sources":["../../src/http/TracingHandler.ts"],"names":[],"mappings":";;;;;;AAAA,iEAAqD;AACrD,8DAA6E;AAC7E,sDAAmD;AACnD,qDAAkD;AAClD,8DAAiC;AAEjC;;;;;;;;;;;;GAYG;AACH,MAAa,cAAe,SAAQ,8BAAW;IAA/C;;QACqB,WAAM,GAAG,IAAA,oCAAY,EAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"TracingHandler.js","sourceRoot":"","sources":["../../src/http/TracingHandler.ts"],"names":[],"mappings":";;;;;;AAAA,iEAAqD;AACrD,8DAA6E;AAC7E,sDAAmD;AACnD,qDAAkD;AAClD,8EAA2E;AAC3E,8DAAiC;AAEjC;;;;;;;;;;;;GAYG;AACH,MAAa,cAAe,SAAQ,8BAAW;IAA/C;;QACqB,WAAM,GAAG,IAAA,oCAAY,EAAC,IAAI,CAAC,CAAC;IAoCjD,CAAC;IAlCiB,KAAK,CAAC,SAAS,CAAC,MAAwB;QACtD,sEAAsE;IACxE,CAAC;IAEe,KAAK,CAAC,MAAM,CAAC,KAAuB;QAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,qBAAM,CAAC,UAAU,EAAE,CAAC;QAC1F,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,sBAAsB;QACtB,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;QAEpD,yCAAyC;QACzC,uBAAU,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QACpC,yBAAW,CAAC,SAAS,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QACjC,+CAAsB,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;QAE/D,6CAA6C;QAC7C,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YAC/B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAClC,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,IAAI,GAAG,CAAC;YAEhD,+CAA+C;YAC/C,uBAAU,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE;gBACjC,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;oBACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,OAAO,MAAM,KAAK,EAAE,KAAK,CAAC,CAAC;gBAC1F,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,OAAO,MAAM,KAAK,EAAE,KAAK,CAAC,CAAC;gBAC1F,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,qEAAqE;IACvE,CAAC;CACF;AArCD,wCAqCC","sourcesContent":["import { getLoggerFor } from 'global-logger-factory';\nimport { HttpHandler, type HttpHandlerInput } from '@solid/community-server';\nimport { logContext } from '../logging/LogContext';\nimport { lockContext } from '../util/LockContext';\nimport { metadataRequestContext } from '../storage/MetadataRequestContext';\nimport crypto from 'node:crypto';\n\n/**\n * HTTP Handler that provides request tracing capabilities.\n * \n * This handler:\n * 1. Reads or generates a Request ID (from X-Request-ID header or new UUID)\n * 2. Sets the X-Request-ID in the response header\n * 3. Enters the logging context with the request ID\n * 4. Logs request completion with status code and duration via response 'finish' event\n * \n * Designed to be used as the first handler in a SequenceHandler chain.\n * It sets up the tracing context and returns immediately, allowing\n * the SequenceHandler to continue to subsequent handlers.\n */\nexport class TracingHandler extends HttpHandler {\n protected readonly logger = getLoggerFor(this);\n\n public override async canHandle(_input: HttpHandlerInput): Promise<void> {\n // Always can handle - we just set up tracing context and pass through\n }\n\n public override async handle(input: HttpHandlerInput): Promise<void> {\n const headerId = input.request.headers['x-request-id'];\n const requestId = Array.isArray(headerId) ? headerId[0] : headerId || crypto.randomUUID();\n const startTime = Date.now();\n \n // Set response header\n input.response.setHeader('X-Request-ID', requestId);\n \n // Enter logging context for this request\n logContext.enterWith({ requestId });\n lockContext.enterWith(new Map());\n metadataRequestContext.enterWith({ metadataCache: new Map() });\n\n // Register finish listener to log completion\n input.response.on('finish', () => {\n const ms = Date.now() - startTime;\n const status = input.response.statusCode || 200;\n \n // Re-enter log context for the finish callback\n logContext.run({ requestId }, () => {\n if (status < 400) {\n this.logger.info(`${input.request.method} ${input.request.url} -> ${status} (${ms}ms)`);\n } else {\n this.logger.warn(`${input.request.method} ${input.request.url} -> ${status} (${ms}ms)`);\n }\n });\n });\n\n // Return immediately - SequenceHandler will continue to next handler\n }\n}\n"]}
|
|
@@ -4,15 +4,17 @@ import type { IndexedStorage } from '@solid/community-server';
|
|
|
4
4
|
* Maps `type` (container) and `id` (key) to rows in the table.
|
|
5
5
|
*/
|
|
6
6
|
export declare class DrizzleIndexedStorage implements IndexedStorage<any> {
|
|
7
|
+
private readonly logger;
|
|
7
8
|
private readonly db;
|
|
8
9
|
private readonly tableName;
|
|
9
10
|
private readonly definitions;
|
|
11
|
+
private readonly createdIndexes;
|
|
10
12
|
private ready;
|
|
11
13
|
constructor(connectionString: string, tablePrefix?: string);
|
|
12
14
|
private toJsonSql;
|
|
13
15
|
private ensureTable;
|
|
14
16
|
defineType(type: string, description: any): Promise<void>;
|
|
15
|
-
createIndex(): Promise<void>;
|
|
17
|
+
createIndex(type: string, key: string): Promise<void>;
|
|
16
18
|
create(type: string, value: any): Promise<any>;
|
|
17
19
|
has(type: string, id: string): Promise<boolean>;
|
|
18
20
|
get(type: string, id: string): Promise<any | undefined>;
|
|
@@ -23,4 +25,11 @@ export declare class DrizzleIndexedStorage implements IndexedStorage<any> {
|
|
|
23
25
|
delete(type: string, id: string): Promise<void>;
|
|
24
26
|
entries(type: string): AsyncIterableIterator<any>;
|
|
25
27
|
private matchesQuery;
|
|
28
|
+
private canPushDownQuery;
|
|
29
|
+
private isSupportedQueryValue;
|
|
30
|
+
private buildWhereClause;
|
|
31
|
+
private buildIndexName;
|
|
32
|
+
private toSqliteJsonPath;
|
|
33
|
+
private escapeSqlLiteral;
|
|
34
|
+
private logDuration;
|
|
26
35
|
}
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.DrizzleIndexedStorage = void 0;
|
|
7
|
+
const global_logger_factory_1 = require("global-logger-factory");
|
|
7
8
|
const drizzle_orm_1 = require("drizzle-orm");
|
|
8
9
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
9
10
|
const db_1 = require("./db");
|
|
@@ -30,7 +31,9 @@ function parsePayload(value) {
|
|
|
30
31
|
*/
|
|
31
32
|
class DrizzleIndexedStorage {
|
|
32
33
|
constructor(connectionString, tablePrefix = 'identity_') {
|
|
34
|
+
this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
|
|
33
35
|
this.definitions = new Map();
|
|
36
|
+
this.createdIndexes = new Set();
|
|
34
37
|
this.ready = false;
|
|
35
38
|
this.db = (0, db_1.getIdentityDatabase)(connectionString);
|
|
36
39
|
this.tableName = `${tablePrefix}store`;
|
|
@@ -57,10 +60,29 @@ class DrizzleIndexedStorage {
|
|
|
57
60
|
this.definitions.set(type, description);
|
|
58
61
|
await this.ensureTable();
|
|
59
62
|
}
|
|
60
|
-
async createIndex() {
|
|
61
|
-
|
|
63
|
+
async createIndex(type, key) {
|
|
64
|
+
const started = Date.now();
|
|
65
|
+
await this.ensureTable();
|
|
66
|
+
if (key === 'id') {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const cacheKey = `${type}:${key}`;
|
|
70
|
+
if (this.createdIndexes.has(cacheKey)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if ((0, db_1.isDatabaseSqlite)(this.db)) {
|
|
74
|
+
const jsonPath = this.escapeSqlLiteral(this.toSqliteJsonPath(key));
|
|
75
|
+
await (0, db_1.executeStatement)(this.db, drizzle_orm_1.sql.raw(`CREATE INDEX IF NOT EXISTS "${this.buildIndexName(type, key)}" ON "${this.tableName}" (container, json_extract(payload, '${jsonPath}'))`));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const escapedKey = this.escapeSqlLiteral(key);
|
|
79
|
+
await (0, db_1.executeStatement)(this.db, drizzle_orm_1.sql.raw(`CREATE INDEX IF NOT EXISTS "${this.buildIndexName(type, key)}" ON "${this.tableName}" (container, (jsonb_extract_path_text(payload, '${escapedKey}')))`));
|
|
80
|
+
}
|
|
81
|
+
this.createdIndexes.add(cacheKey);
|
|
82
|
+
this.logDuration('createIndex', started, { type, key }, 50, 500);
|
|
62
83
|
}
|
|
63
84
|
async create(type, value) {
|
|
85
|
+
const started = Date.now();
|
|
64
86
|
await this.ensureTable();
|
|
65
87
|
const id = node_crypto_1.default.randomUUID();
|
|
66
88
|
const payload = serializePayload(value);
|
|
@@ -69,18 +91,23 @@ class DrizzleIndexedStorage {
|
|
|
69
91
|
INSERT INTO ${tableNameId} (container, id, payload)
|
|
70
92
|
VALUES (${type}, ${id}, ${this.toJsonSql(payload)})
|
|
71
93
|
`);
|
|
94
|
+
this.logDuration('create', started, { type, fields: Object.keys(value ?? {}) }, 50, 500);
|
|
72
95
|
return { id, ...value };
|
|
73
96
|
}
|
|
74
97
|
async has(type, id) {
|
|
98
|
+
const started = Date.now();
|
|
75
99
|
await this.ensureTable();
|
|
76
100
|
const tableNameId = drizzle_orm_1.sql.identifier([this.tableName]);
|
|
77
101
|
const result = await (0, db_1.executeQuery)(this.db, (0, drizzle_orm_1.sql) `SELECT 1 FROM ${tableNameId} WHERE container = ${type} AND id = ${id} LIMIT 1`);
|
|
102
|
+
this.logDuration('has', started, { type, id }, 50, 500);
|
|
78
103
|
return result.rows.length > 0;
|
|
79
104
|
}
|
|
80
105
|
async get(type, id) {
|
|
106
|
+
const started = Date.now();
|
|
81
107
|
await this.ensureTable();
|
|
82
108
|
const tableNameId = drizzle_orm_1.sql.identifier([this.tableName]);
|
|
83
109
|
const result = await (0, db_1.executeQuery)(this.db, (0, drizzle_orm_1.sql) `SELECT payload FROM ${tableNameId} WHERE container = ${type} AND id = ${id} LIMIT 1`);
|
|
110
|
+
this.logDuration('get', started, { type, id }, 50, 500);
|
|
84
111
|
if (result.rows.length === 0) {
|
|
85
112
|
return undefined;
|
|
86
113
|
}
|
|
@@ -88,21 +115,30 @@ class DrizzleIndexedStorage {
|
|
|
88
115
|
return { id, ...payload };
|
|
89
116
|
}
|
|
90
117
|
async find(type, query) {
|
|
118
|
+
const started = Date.now();
|
|
91
119
|
await this.ensureTable();
|
|
92
120
|
const tableNameId = drizzle_orm_1.sql.identifier([this.tableName]);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const result =
|
|
121
|
+
const normalizedQuery = (query ?? {});
|
|
122
|
+
const pushdown = this.canPushDownQuery(normalizedQuery);
|
|
123
|
+
const result = pushdown
|
|
124
|
+
? await (0, db_1.executeQuery)(this.db, (0, drizzle_orm_1.sql) `SELECT id, payload FROM ${tableNameId} WHERE ${this.buildWhereClause(type, normalizedQuery)}`)
|
|
125
|
+
: await (0, db_1.executeQuery)(this.db, (0, drizzle_orm_1.sql) `SELECT id, payload FROM ${tableNameId} WHERE container = ${type}`);
|
|
96
126
|
const matches = [];
|
|
97
127
|
for (const row of result.rows) {
|
|
98
128
|
const payload = {
|
|
99
129
|
id: row.id,
|
|
100
130
|
...parsePayload(row.payload),
|
|
101
131
|
};
|
|
102
|
-
if (this.matchesQuery(type, payload,
|
|
132
|
+
if (this.matchesQuery(type, payload, normalizedQuery)) {
|
|
103
133
|
matches.push(payload);
|
|
104
134
|
}
|
|
105
135
|
}
|
|
136
|
+
this.logDuration('find', started, {
|
|
137
|
+
type,
|
|
138
|
+
keys: Object.keys(normalizedQuery),
|
|
139
|
+
pushdown,
|
|
140
|
+
matched: matches.length,
|
|
141
|
+
}, 50, 500);
|
|
106
142
|
return matches;
|
|
107
143
|
}
|
|
108
144
|
async findIds(type, query) {
|
|
@@ -110,6 +146,7 @@ class DrizzleIndexedStorage {
|
|
|
110
146
|
return rows.map((row) => row.id);
|
|
111
147
|
}
|
|
112
148
|
async set(type, value) {
|
|
149
|
+
const started = Date.now();
|
|
113
150
|
await this.ensureTable();
|
|
114
151
|
const tableNameId = drizzle_orm_1.sql.identifier([this.tableName]);
|
|
115
152
|
const { id, ...rest } = value;
|
|
@@ -119,6 +156,7 @@ class DrizzleIndexedStorage {
|
|
|
119
156
|
SET payload = ${this.toJsonSql(payload)}
|
|
120
157
|
WHERE container = ${type} AND id = ${id}
|
|
121
158
|
`);
|
|
159
|
+
this.logDuration('set', started, { type, id, fields: Object.keys(rest) }, 50, 500);
|
|
122
160
|
}
|
|
123
161
|
async setField(type, id, key, value) {
|
|
124
162
|
const current = await this.get(type, id);
|
|
@@ -129,9 +167,11 @@ class DrizzleIndexedStorage {
|
|
|
129
167
|
await this.set(type, updated);
|
|
130
168
|
}
|
|
131
169
|
async delete(type, id) {
|
|
170
|
+
const started = Date.now();
|
|
132
171
|
await this.ensureTable();
|
|
133
172
|
const tableNameId = drizzle_orm_1.sql.identifier([this.tableName]);
|
|
134
173
|
await (0, db_1.executeStatement)(this.db, (0, drizzle_orm_1.sql) `DELETE FROM ${tableNameId} WHERE container = ${type} AND id = ${id}`);
|
|
174
|
+
this.logDuration('delete', started, { type, id }, 50, 500);
|
|
135
175
|
}
|
|
136
176
|
async *entries(type) {
|
|
137
177
|
await this.ensureTable();
|
|
@@ -154,6 +194,59 @@ class DrizzleIndexedStorage {
|
|
|
154
194
|
}
|
|
155
195
|
return true;
|
|
156
196
|
}
|
|
197
|
+
canPushDownQuery(query) {
|
|
198
|
+
return Object.values(query).every((value) => this.isSupportedQueryValue(value));
|
|
199
|
+
}
|
|
200
|
+
isSupportedQueryValue(value) {
|
|
201
|
+
return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
|
|
202
|
+
}
|
|
203
|
+
buildWhereClause(type, query) {
|
|
204
|
+
const clauses = [(0, drizzle_orm_1.sql) `container = ${type}`];
|
|
205
|
+
for (const [key, value] of Object.entries(query)) {
|
|
206
|
+
if (key === 'id') {
|
|
207
|
+
clauses.push((0, drizzle_orm_1.sql) `id = ${String(value)}`);
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if ((0, db_1.isDatabaseSqlite)(this.db)) {
|
|
211
|
+
const jsonPath = this.toSqliteJsonPath(key);
|
|
212
|
+
const wrappedValue = JSON.stringify({ value });
|
|
213
|
+
clauses.push((0, drizzle_orm_1.sql) `json_extract(payload, ${jsonPath}) = json_extract(${wrappedValue}, '$.value')`);
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
clauses.push((0, drizzle_orm_1.sql) `jsonb_extract_path_text(payload, ${key}) = ${String(value)}`);
|
|
217
|
+
}
|
|
218
|
+
return drizzle_orm_1.sql.join(clauses, (0, drizzle_orm_1.sql) ` AND `);
|
|
219
|
+
}
|
|
220
|
+
buildIndexName(type, key) {
|
|
221
|
+
const rawName = `${this.tableName}_${type}_${key}_idx`;
|
|
222
|
+
const normalized = rawName.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
223
|
+
if (normalized.length <= 63) {
|
|
224
|
+
return normalized;
|
|
225
|
+
}
|
|
226
|
+
return `${normalized.slice(0, 54)}_${node_crypto_1.default.createHash('sha1').update(rawName).digest('hex').slice(0, 8)}`;
|
|
227
|
+
}
|
|
228
|
+
toSqliteJsonPath(key) {
|
|
229
|
+
const escaped = key.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
230
|
+
return `$."${escaped}"`;
|
|
231
|
+
}
|
|
232
|
+
escapeSqlLiteral(value) {
|
|
233
|
+
return value.replace(/'/g, "''");
|
|
234
|
+
}
|
|
235
|
+
logDuration(operation, started, details, slowThresholdMs = 100, warnThresholdMs = 1000) {
|
|
236
|
+
const elapsedMs = Date.now() - started;
|
|
237
|
+
if (elapsedMs < slowThresholdMs) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const detailText = Object.entries(details)
|
|
241
|
+
.map(([key, value]) => `${key}=${Array.isArray(value) ? value.join(',') : String(value)}`)
|
|
242
|
+
.join(' ');
|
|
243
|
+
const message = `[timing] DrizzleIndexedStorage.${operation} ${detailText} took=${elapsedMs}ms`;
|
|
244
|
+
if (elapsedMs >= warnThresholdMs) {
|
|
245
|
+
this.logger.warn(message);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
this.logger.info(message);
|
|
249
|
+
}
|
|
157
250
|
}
|
|
158
251
|
exports.DrizzleIndexedStorage = DrizzleIndexedStorage;
|
|
159
252
|
//# sourceMappingURL=DrizzleIndexedStorage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DrizzleIndexedStorage.js","sourceRoot":"","sources":["../../../src/identity/drizzle/DrizzleIndexedStorage.ts"],"names":[],"mappings":"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","sourcesContent":["import { sql } from 'drizzle-orm';\nimport crypto from 'node:crypto';\nimport type {\n CreateTypeObject,\n IndexedQuery,\n IndexedStorage,\n IndexTypeCollection,\n StringKey,\n TypeObject,\n ValueTypeDescription,\n} from '@solid/community-server';\nimport { \n getIdentityDatabase, \n IdentityDatabase, \n executeQuery, \n executeStatement,\n isDatabaseSqlite \n} from './db';\n\nfunction serializePayload(value: Record<string, unknown>): string {\n return JSON.stringify(value ?? {});\n}\n\nfunction parsePayload<T>(value: unknown): T {\n if (value == null) {\n return {} as T;\n }\n if (typeof value === 'string') {\n try {\n return JSON.parse(value) as T;\n } catch {\n return {} as T;\n }\n }\n return value as T;\n}\n\n/**\n * A generic Key-Value storage backed by a single SQL table.\n * Maps `type` (container) and `id` (key) to rows in the table.\n */\nexport class DrizzleIndexedStorage implements IndexedStorage<any> {\n private readonly db: IdentityDatabase;\n private readonly tableName: string;\n private readonly definitions: Map<string, Record<string, ValueTypeDescription<string>>> = new Map();\n private ready: boolean = false;\n\n public constructor(connectionString: string, tablePrefix = 'identity_') {\n this.db = getIdentityDatabase(connectionString);\n this.tableName = `${tablePrefix}store`;\n }\n\n private toJsonSql(payload: string): any {\n return isDatabaseSqlite(this.db) ? sql`${payload}` : sql`${payload}::jsonb`;\n }\n\n private async ensureTable(): Promise<void> {\n if (this.ready) return;\n \n const jsonType = isDatabaseSqlite(this.db) ? sql.raw('TEXT') : sql.raw('JSONB');\n const tableNameId = sql.identifier([this.tableName]);\n \n await executeStatement(this.db, sql`\n CREATE TABLE IF NOT EXISTS ${tableNameId} (\n container TEXT NOT NULL,\n id TEXT NOT NULL,\n payload ${jsonType} NOT NULL,\n PRIMARY KEY (container, id)\n )\n `);\n this.ready = true;\n }\n\n public async defineType(type: string, description: any): Promise<void> {\n this.definitions.set(type, description as Record<string, ValueTypeDescription<string>>);\n await this.ensureTable();\n }\n\n public async createIndex(): Promise<void> {\n // Indexes are not required for the current usage.\n }\n\n public async create(type: string, value: any): Promise<any> {\n await this.ensureTable();\n const id = crypto.randomUUID();\n const payload = serializePayload(value as Record<string, unknown>);\n const tableNameId = sql.identifier([this.tableName]);\n\n await executeStatement(this.db, sql`\n INSERT INTO ${tableNameId} (container, id, payload)\n VALUES (${type}, ${id}, ${this.toJsonSql(payload)})\n `);\n return { id, ...(value as Record<string, unknown>) };\n }\n\n public async has(type: string, id: string): Promise<boolean> {\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n const result = await executeQuery(this.db, sql`SELECT 1 FROM ${tableNameId} WHERE container = ${type} AND id = ${id} LIMIT 1`);\n return result.rows.length > 0;\n }\n\n public async get(type: string, id: string): Promise<any | undefined> {\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n const result = await executeQuery(this.db, sql`SELECT payload FROM ${tableNameId} WHERE container = ${type} AND id = ${id} LIMIT 1`);\n if (result.rows.length === 0) {\n return undefined;\n }\n const payload = parsePayload<Record<string, unknown>>(result.rows[0].payload);\n return { id, ...payload };\n }\n\n public async find(type: string, query: any): Promise<any[]> {\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n // Note: This fetches all rows for the container and filters in memory. \n // For high volume types, this should be optimized with JSON path queries if possible.\n const result = await executeQuery(this.db, sql`SELECT id, payload FROM ${tableNameId} WHERE container = ${type}`);\n const matches: any[] = [];\n for (const row of result.rows) {\n const payload = {\n id: row.id as string,\n ...parsePayload<Record<string, unknown>>(row.payload),\n };\n if (this.matchesQuery(type, payload, query as Record<string, unknown>)) {\n matches.push(payload);\n }\n }\n return matches;\n }\n\n public async findIds(type: string, query: any): Promise<string[]> {\n const rows = await this.find(type, query);\n return rows.map((row) => row.id as string);\n }\n\n public async set(type: string, value: any): Promise<void> {\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n const { id, ...rest } = value as Record<string, unknown>;\n const payload = serializePayload(rest);\n \n await executeStatement(this.db, sql`\n UPDATE ${tableNameId}\n SET payload = ${this.toJsonSql(payload)}\n WHERE container = ${type} AND id = ${id}\n `);\n }\n\n public async setField(type: string, id: string, key: string, value: any): Promise<void> {\n const current = await this.get(type, id);\n if (!current) {\n return;\n }\n const updated = { ...current, [key]: value };\n await this.set(type, updated);\n }\n\n public async delete(type: string, id: string): Promise<void> {\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n await executeStatement(this.db, sql`DELETE FROM ${tableNameId} WHERE container = ${type} AND id = ${id}`);\n }\n\n public async *entries(type: string): AsyncIterableIterator<any> {\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n const result = await executeQuery(this.db, sql`SELECT id, payload FROM ${tableNameId} WHERE container = ${type}`);\n for (const row of result.rows) {\n yield {\n id: row.id as string,\n ...parsePayload<Record<string, unknown>>(row.payload),\n };\n }\n }\n\n private matchesQuery(type: string, payload: any, query: any): boolean {\n // Basic in-memory implementation of query matching\n // This mirrors MemoryIndexedStorage behavior for compatibility\n for (const key of Object.keys(query)) {\n if (payload[key] !== query[key]) {\n return false;\n }\n }\n return true;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DrizzleIndexedStorage.js","sourceRoot":"","sources":["../../../src/identity/drizzle/DrizzleIndexedStorage.ts"],"names":[],"mappings":"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","sourcesContent":["import { getLoggerFor } from 'global-logger-factory';\nimport { sql } from 'drizzle-orm';\nimport crypto from 'node:crypto';\nimport type {\n CreateTypeObject,\n IndexedQuery,\n IndexedStorage,\n IndexTypeCollection,\n StringKey,\n TypeObject,\n ValueTypeDescription,\n} from '@solid/community-server';\nimport { \n getIdentityDatabase, \n IdentityDatabase, \n executeQuery, \n executeStatement,\n isDatabaseSqlite \n} from './db';\n\nfunction serializePayload(value: Record<string, unknown>): string {\n return JSON.stringify(value ?? {});\n}\n\nfunction parsePayload<T>(value: unknown): T {\n if (value == null) {\n return {} as T;\n }\n if (typeof value === 'string') {\n try {\n return JSON.parse(value) as T;\n } catch {\n return {} as T;\n }\n }\n return value as T;\n}\n\n/**\n * A generic Key-Value storage backed by a single SQL table.\n * Maps `type` (container) and `id` (key) to rows in the table.\n */\nexport class DrizzleIndexedStorage implements IndexedStorage<any> {\n private readonly logger = getLoggerFor(this);\n private readonly db: IdentityDatabase;\n private readonly tableName: string;\n private readonly definitions: Map<string, Record<string, ValueTypeDescription<string>>> = new Map();\n private readonly createdIndexes: Set<string> = new Set();\n private ready: boolean = false;\n\n public constructor(connectionString: string, tablePrefix = 'identity_') {\n this.db = getIdentityDatabase(connectionString);\n this.tableName = `${tablePrefix}store`;\n }\n\n private toJsonSql(payload: string): any {\n return isDatabaseSqlite(this.db) ? sql`${payload}` : sql`${payload}::jsonb`;\n }\n\n private async ensureTable(): Promise<void> {\n if (this.ready) return;\n \n const jsonType = isDatabaseSqlite(this.db) ? sql.raw('TEXT') : sql.raw('JSONB');\n const tableNameId = sql.identifier([this.tableName]);\n \n await executeStatement(this.db, sql`\n CREATE TABLE IF NOT EXISTS ${tableNameId} (\n container TEXT NOT NULL,\n id TEXT NOT NULL,\n payload ${jsonType} NOT NULL,\n PRIMARY KEY (container, id)\n )\n `);\n this.ready = true;\n }\n\n public async defineType(type: string, description: any): Promise<void> {\n this.definitions.set(type, description as Record<string, ValueTypeDescription<string>>);\n await this.ensureTable();\n }\n\n public async createIndex(type: string, key: string): Promise<void> {\n const started = Date.now();\n await this.ensureTable();\n if (key === 'id') {\n return;\n }\n\n const cacheKey = `${type}:${key}`;\n if (this.createdIndexes.has(cacheKey)) {\n return;\n }\n\n if (isDatabaseSqlite(this.db)) {\n const jsonPath = this.escapeSqlLiteral(this.toSqliteJsonPath(key));\n await executeStatement(this.db, sql.raw(\n `CREATE INDEX IF NOT EXISTS \"${this.buildIndexName(type, key)}\" ON \"${this.tableName}\" (container, json_extract(payload, '${jsonPath}'))`,\n ));\n } else {\n const escapedKey = this.escapeSqlLiteral(key);\n await executeStatement(this.db, sql.raw(\n `CREATE INDEX IF NOT EXISTS \"${this.buildIndexName(type, key)}\" ON \"${this.tableName}\" (container, (jsonb_extract_path_text(payload, '${escapedKey}')))` ,\n ));\n }\n\n this.createdIndexes.add(cacheKey);\n this.logDuration('createIndex', started, { type, key }, 50, 500);\n }\n\n public async create(type: string, value: any): Promise<any> {\n const started = Date.now();\n await this.ensureTable();\n const id = crypto.randomUUID();\n const payload = serializePayload(value as Record<string, unknown>);\n const tableNameId = sql.identifier([this.tableName]);\n\n await executeStatement(this.db, sql`\n INSERT INTO ${tableNameId} (container, id, payload)\n VALUES (${type}, ${id}, ${this.toJsonSql(payload)})\n `);\n this.logDuration('create', started, { type, fields: Object.keys(value ?? {}) }, 50, 500);\n return { id, ...(value as Record<string, unknown>) };\n }\n\n public async has(type: string, id: string): Promise<boolean> {\n const started = Date.now();\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n const result = await executeQuery(this.db, sql`SELECT 1 FROM ${tableNameId} WHERE container = ${type} AND id = ${id} LIMIT 1`);\n this.logDuration('has', started, { type, id }, 50, 500);\n return result.rows.length > 0;\n }\n\n public async get(type: string, id: string): Promise<any | undefined> {\n const started = Date.now();\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n const result = await executeQuery(this.db, sql`SELECT payload FROM ${tableNameId} WHERE container = ${type} AND id = ${id} LIMIT 1`);\n this.logDuration('get', started, { type, id }, 50, 500);\n if (result.rows.length === 0) {\n return undefined;\n }\n const payload = parsePayload<Record<string, unknown>>(result.rows[0].payload);\n return { id, ...payload };\n }\n\n public async find(type: string, query: any): Promise<any[]> {\n const started = Date.now();\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n const normalizedQuery = (query ?? {}) as Record<string, unknown>;\n const pushdown = this.canPushDownQuery(normalizedQuery);\n const result = pushdown\n ? await executeQuery(this.db, sql`SELECT id, payload FROM ${tableNameId} WHERE ${this.buildWhereClause(type, normalizedQuery)}`)\n : await executeQuery(this.db, sql`SELECT id, payload FROM ${tableNameId} WHERE container = ${type}`);\n const matches: any[] = [];\n for (const row of result.rows) {\n const payload = {\n id: row.id as string,\n ...parsePayload<Record<string, unknown>>(row.payload),\n };\n if (this.matchesQuery(type, payload, normalizedQuery)) {\n matches.push(payload);\n }\n }\n this.logDuration('find', started, {\n type,\n keys: Object.keys(normalizedQuery),\n pushdown,\n matched: matches.length,\n }, 50, 500);\n return matches;\n }\n\n public async findIds(type: string, query: any): Promise<string[]> {\n const rows = await this.find(type, query);\n return rows.map((row) => row.id as string);\n }\n\n public async set(type: string, value: any): Promise<void> {\n const started = Date.now();\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n const { id, ...rest } = value as Record<string, unknown>;\n const payload = serializePayload(rest);\n \n await executeStatement(this.db, sql`\n UPDATE ${tableNameId}\n SET payload = ${this.toJsonSql(payload)}\n WHERE container = ${type} AND id = ${id}\n `);\n this.logDuration('set', started, { type, id, fields: Object.keys(rest) }, 50, 500);\n }\n\n public async setField(type: string, id: string, key: string, value: any): Promise<void> {\n const current = await this.get(type, id);\n if (!current) {\n return;\n }\n const updated = { ...current, [key]: value };\n await this.set(type, updated);\n }\n\n public async delete(type: string, id: string): Promise<void> {\n const started = Date.now();\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n await executeStatement(this.db, sql`DELETE FROM ${tableNameId} WHERE container = ${type} AND id = ${id}`);\n this.logDuration('delete', started, { type, id }, 50, 500);\n }\n\n public async *entries(type: string): AsyncIterableIterator<any> {\n await this.ensureTable();\n const tableNameId = sql.identifier([this.tableName]);\n const result = await executeQuery(this.db, sql`SELECT id, payload FROM ${tableNameId} WHERE container = ${type}`);\n for (const row of result.rows) {\n yield {\n id: row.id as string,\n ...parsePayload<Record<string, unknown>>(row.payload),\n };\n }\n }\n\n private matchesQuery(type: string, payload: any, query: any): boolean {\n // Basic in-memory implementation of query matching\n // This mirrors MemoryIndexedStorage behavior for compatibility\n for (const key of Object.keys(query)) {\n if (payload[key] !== query[key]) {\n return false;\n }\n }\n return true;\n }\n\n private canPushDownQuery(query: Record<string, unknown>): boolean {\n return Object.values(query).every((value) => this.isSupportedQueryValue(value));\n }\n\n private isSupportedQueryValue(value: unknown): value is string | number | boolean {\n return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';\n }\n\n private buildWhereClause(type: string, query: Record<string, unknown>): any {\n const clauses = [sql`container = ${type}`];\n\n for (const [key, value] of Object.entries(query)) {\n if (key === 'id') {\n clauses.push(sql`id = ${String(value)}`);\n continue;\n }\n\n if (isDatabaseSqlite(this.db)) {\n const jsonPath = this.toSqliteJsonPath(key);\n const wrappedValue = JSON.stringify({ value });\n clauses.push(sql`json_extract(payload, ${jsonPath}) = json_extract(${wrappedValue}, '$.value')`);\n continue;\n }\n\n clauses.push(sql`jsonb_extract_path_text(payload, ${key}) = ${String(value)}`);\n }\n\n return sql.join(clauses, sql` AND `);\n }\n\n private buildIndexName(type: string, key: string): string {\n const rawName = `${this.tableName}_${type}_${key}_idx`;\n const normalized = rawName.replace(/[^a-zA-Z0-9_]/g, '_');\n if (normalized.length <= 63) {\n return normalized;\n }\n\n return `${normalized.slice(0, 54)}_${crypto.createHash('sha1').update(rawName).digest('hex').slice(0, 8)}`;\n }\n\n private toSqliteJsonPath(key: string): string {\n const escaped = key.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n return `$.\"${escaped}\"`;\n }\n\n private escapeSqlLiteral(value: string): string {\n return value.replace(/'/g, \"''\");\n }\n\n private logDuration(\n operation: string,\n started: number,\n details: Record<string, unknown>,\n slowThresholdMs = 100,\n warnThresholdMs = 1000,\n ): void {\n const elapsedMs = Date.now() - started;\n if (elapsedMs < slowThresholdMs) {\n return;\n }\n\n const detailText = Object.entries(details)\n .map(([key, value]) => `${key}=${Array.isArray(value) ? value.join(',') : String(value)}`)\n .join(' ');\n const message = `[timing] DrizzleIndexedStorage.${operation} ${detailText} took=${elapsedMs}ms`;\n\n if (elapsedMs >= warnThresholdMs) {\n this.logger.warn(message);\n return;\n }\n\n this.logger.info(message);\n }\n}\n"]}
|
|
@@ -40,6 +40,10 @@
|
|
|
40
40
|
}
|
|
41
41
|
],
|
|
42
42
|
"memberFields": [
|
|
43
|
+
{
|
|
44
|
+
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_logger",
|
|
45
|
+
"memberFieldName": "logger"
|
|
46
|
+
},
|
|
43
47
|
{
|
|
44
48
|
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_db",
|
|
45
49
|
"memberFieldName": "db"
|
|
@@ -52,6 +56,10 @@
|
|
|
52
56
|
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_definitions",
|
|
53
57
|
"memberFieldName": "definitions"
|
|
54
58
|
},
|
|
59
|
+
{
|
|
60
|
+
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_createdIndexes",
|
|
61
|
+
"memberFieldName": "createdIndexes"
|
|
62
|
+
},
|
|
55
63
|
{
|
|
56
64
|
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_ready",
|
|
57
65
|
"memberFieldName": "ready"
|
|
@@ -115,6 +123,34 @@
|
|
|
115
123
|
{
|
|
116
124
|
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_matchesQuery",
|
|
117
125
|
"memberFieldName": "matchesQuery"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_canPushDownQuery",
|
|
129
|
+
"memberFieldName": "canPushDownQuery"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_isSupportedQueryValue",
|
|
133
|
+
"memberFieldName": "isSupportedQueryValue"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_buildWhereClause",
|
|
137
|
+
"memberFieldName": "buildWhereClause"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_buildIndexName",
|
|
141
|
+
"memberFieldName": "buildIndexName"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_toSqliteJsonPath",
|
|
145
|
+
"memberFieldName": "toSqliteJsonPath"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_escapeSqlLiteral",
|
|
149
|
+
"memberFieldName": "escapeSqlLiteral"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"@id": "undefineds:dist/identity/drizzle/DrizzleIndexedStorage.jsonld#DrizzleIndexedStorage__member_logDuration",
|
|
153
|
+
"memberFieldName": "logDuration"
|
|
118
154
|
}
|
|
119
155
|
],
|
|
120
156
|
"constructorArguments": [
|
package/dist/main.js
CHANGED
|
@@ -218,14 +218,13 @@ async function startRuntime(options) {
|
|
|
218
218
|
logger.info(` - API (internal): http://localhost:${apiPort}`);
|
|
219
219
|
const supervisor = new supervisor_1.Supervisor();
|
|
220
220
|
const cssBinary = require.resolve('@solid/community-server/bin/server.js');
|
|
221
|
-
const cssModuleRoot = path_1.default.dirname(require.resolve('@solid/community-server/package.json'));
|
|
222
221
|
supervisor.register({
|
|
223
222
|
name: 'css',
|
|
224
223
|
command: childJsRuntime,
|
|
225
224
|
args: [
|
|
226
225
|
cssBinary,
|
|
227
226
|
'-c', configPath,
|
|
228
|
-
'-m',
|
|
227
|
+
'-m', runtime_1.PACKAGE_ROOT,
|
|
229
228
|
'-p', cssPort.toString(),
|
|
230
229
|
'-b', baseUrl,
|
|
231
230
|
],
|