@undefineds.co/xpod 0.3.6 → 0.3.14
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/cli.json +1 -1
- package/config/cloud.json +54 -22
- package/config/local.json +56 -12
- package/config/resolver.json +10 -2
- package/config/xpod.base.json +50 -0
- package/config/xpod.json +8 -8
- package/dist/agents/config/resolve.js +10 -10
- package/dist/agents/config/resolve.js.map +1 -1
- package/dist/api/chatkit/index.d.ts +1 -1
- package/dist/api/chatkit/index.js.map +1 -1
- package/dist/api/chatkit/pod-store.d.ts +14 -11
- package/dist/api/chatkit/pod-store.js +114 -78
- package/dist/api/chatkit/pod-store.js.map +1 -1
- package/dist/api/chatkit/runtime/AcpAgentRuntime.js +1 -1
- package/dist/api/chatkit/runtime/AcpAgentRuntime.js.map +1 -1
- package/dist/api/chatkit/service.js +1 -1
- package/dist/api/chatkit/service.js.map +1 -1
- package/dist/api/chatkit/types.d.ts +11 -11
- package/dist/api/chatkit/types.js +3 -3
- package/dist/api/chatkit/types.js.map +1 -1
- package/dist/api/container/cloud.js +0 -8
- package/dist/api/container/cloud.js.map +1 -1
- package/dist/api/container/index.js +2 -1
- package/dist/api/container/index.js.map +1 -1
- package/dist/api/container/local.js +0 -7
- package/dist/api/container/local.js.map +1 -1
- package/dist/api/container/routes.js +3 -17
- package/dist/api/container/routes.js.map +1 -1
- package/dist/api/container/types.d.ts +0 -2
- package/dist/api/container/types.js.map +1 -1
- package/dist/api/handlers/PodManagementHandler.d.ts +3 -0
- package/dist/api/handlers/PodManagementHandler.js +71 -1
- package/dist/api/handlers/PodManagementHandler.js.map +1 -1
- package/dist/api/handlers/RunHandler.js +5 -5
- package/dist/api/handlers/RunHandler.js.map +1 -1
- package/dist/api/runs/AgentRuntimeTypes.d.ts +7 -8
- package/dist/api/runs/AgentRuntimeTypes.js.map +1 -1
- package/dist/api/runs/InngestRunExecutionBackend.d.ts +2 -2
- package/dist/api/runs/ManagedRunWorker.d.ts +1 -1
- package/dist/api/runs/ManagedRunWorker.js +6 -6
- package/dist/api/runs/ManagedRunWorker.js.map +1 -1
- package/dist/api/runs/PiAgentRuntimeDriver.d.ts +16 -1
- package/dist/api/runs/PiAgentRuntimeDriver.js +182 -23
- package/dist/api/runs/PiAgentRuntimeDriver.js.map +1 -1
- package/dist/api/runs/RunStateCenter.d.ts +3 -3
- package/dist/api/runs/RunStateCenter.js +13 -13
- package/dist/api/runs/RunStateCenter.js.map +1 -1
- package/dist/api/runs/store.d.ts +4 -4
- package/dist/api/runs/store.js +2 -2
- package/dist/api/runs/store.js.map +1 -1
- package/dist/api/service/VectorStoreService.d.ts +1 -1
- package/dist/api/service/VectorStoreService.js +16 -16
- package/dist/api/service/VectorStoreService.js.map +1 -1
- package/dist/api/tasks/InngestTaskScheduler.d.ts +4 -4
- package/dist/api/tasks/TaskMaterializer.d.ts +3 -3
- package/dist/api/tasks/TaskMaterializer.js +11 -11
- package/dist/api/tasks/TaskMaterializer.js.map +1 -1
- package/dist/api/tasks/TaskService.d.ts +3 -3
- package/dist/api/tasks/TaskService.js +11 -7
- package/dist/api/tasks/TaskService.js.map +1 -1
- package/dist/api/tasks/store.d.ts +10 -4
- package/dist/api/tasks/store.js +14 -4
- package/dist/api/tasks/store.js.map +1 -1
- package/dist/api/workspace/types.d.ts +3 -3
- package/dist/api/workspace/types.js +6 -6
- package/dist/api/workspace/types.js.map +1 -1
- package/dist/cli/commands/config.js +2 -2
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/start.js +9 -3
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/components/components.jsonld +8 -2
- package/dist/components/context.jsonld +302 -51
- package/dist/http/search/SearchHttpHandler.js +8 -8
- package/dist/http/search/SearchHttpHandler.js.map +1 -1
- package/dist/identity/drizzle/PodLookupRepository.d.ts +11 -1
- package/dist/identity/drizzle/PodLookupRepository.js +95 -4
- package/dist/identity/drizzle/PodLookupRepository.js.map +1 -1
- package/dist/identity/drizzle/db.js +4 -43
- package/dist/identity/drizzle/db.js.map +1 -1
- package/dist/identity/drizzle/schema.pg.d.ts +0 -5
- package/dist/identity/drizzle/schema.pg.js +2 -16
- package/dist/identity/drizzle/schema.pg.js.map +1 -1
- package/dist/identity/drizzle/schema.sqlite.d.ts +19 -176
- package/dist/identity/drizzle/schema.sqlite.js +2 -16
- package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
- package/dist/identity/oidc/AutoDetectIdentityProviderHandler.d.ts +4 -4
- package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js +7 -7
- package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js.map +1 -1
- package/dist/identity/oidc/AutoDetectIdentityProviderHandler.jsonld +6 -6
- package/dist/identity/oidc/AutoDetectOidcHandler.d.ts +4 -4
- package/dist/identity/oidc/AutoDetectOidcHandler.js +6 -6
- package/dist/identity/oidc/AutoDetectOidcHandler.js.map +1 -1
- package/dist/identity/oidc/AutoDetectOidcHandler.jsonld +6 -6
- package/dist/identity/oidc/ScopedPickWebIdHandler.d.ts +37 -0
- package/dist/identity/oidc/ScopedPickWebIdHandler.js +211 -0
- package/dist/identity/oidc/ScopedPickWebIdHandler.js.map +1 -0
- package/dist/identity/oidc/ScopedPickWebIdHandler.jsonld +158 -0
- package/dist/index.d.ts +12 -2
- package/dist/index.js +16 -4
- package/dist/index.js.map +1 -1
- package/dist/main.js +8 -2
- package/dist/main.js.map +1 -1
- package/dist/provision/ProvisionPodCreator.d.ts +3 -4
- package/dist/provision/ProvisionPodCreator.js +8 -13
- package/dist/provision/ProvisionPodCreator.js.map +1 -1
- package/dist/provision/ProvisionPodCreator.jsonld +7 -7
- package/dist/runtime/Proxy.d.ts +0 -1
- package/dist/runtime/Proxy.js +0 -9
- package/dist/runtime/Proxy.js.map +1 -1
- package/dist/runtime/bootstrap.d.ts +1 -0
- package/dist/runtime/bootstrap.js +5 -2
- package/dist/runtime/bootstrap.js.map +1 -1
- package/dist/runtime/css-process.d.ts +12 -4
- package/dist/runtime/css-process.js +61 -14
- package/dist/runtime/css-process.js.map +1 -1
- package/dist/runtime/oidc-issuer.d.ts +3 -2
- package/dist/runtime/oidc-issuer.js +3 -2
- package/dist/runtime/oidc-issuer.js.map +1 -1
- package/dist/runtime/runtime-types.d.ts +1 -0
- package/dist/runtime/runtime-types.js.map +1 -1
- package/dist/solidfs/LocalFirstRdfRepresentationResolver.d.ts +21 -0
- package/dist/solidfs/LocalFirstRdfRepresentationResolver.js +38 -0
- package/dist/solidfs/LocalFirstRdfRepresentationResolver.js.map +1 -0
- package/dist/solidfs/LocalSolidFS.d.ts +18 -0
- package/dist/solidfs/LocalSolidFS.js +539 -0
- package/dist/solidfs/LocalSolidFS.js.map +1 -0
- package/dist/solidfs/PodSolidFsHttpClient.d.ts +16 -0
- package/dist/solidfs/PodSolidFsHttpClient.js +93 -0
- package/dist/solidfs/PodSolidFsHttpClient.js.map +1 -0
- package/dist/solidfs/PodSolidFsHydrator.d.ts +27 -0
- package/dist/solidfs/PodSolidFsHydrator.js +127 -0
- package/dist/solidfs/PodSolidFsHydrator.js.map +1 -0
- package/dist/solidfs/PodSolidFsSyncer.d.ts +21 -0
- package/dist/solidfs/PodSolidFsSyncer.js +78 -0
- package/dist/solidfs/PodSolidFsSyncer.js.map +1 -0
- package/dist/solidfs/RdfIndexSolidFsSyncer.d.ts +22 -0
- package/dist/solidfs/RdfIndexSolidFsSyncer.js +131 -0
- package/dist/solidfs/RdfIndexSolidFsSyncer.js.map +1 -0
- package/dist/solidfs/index.d.ts +7 -0
- package/dist/solidfs/index.js +24 -0
- package/dist/solidfs/index.js.map +1 -0
- package/dist/solidfs/types.d.ts +131 -0
- package/dist/solidfs/types.js +19 -0
- package/dist/solidfs/types.js.map +1 -0
- package/dist/storage/RepresentationPartialConvertingStore.js +6 -13
- package/dist/storage/RepresentationPartialConvertingStore.js.map +1 -1
- package/dist/storage/SparqlUpdateResourceStore.d.ts +4 -0
- package/dist/storage/SparqlUpdateResourceStore.js +13 -0
- package/dist/storage/SparqlUpdateResourceStore.js.map +1 -1
- package/dist/storage/SparqlUpdateResourceStore.jsonld +26 -0
- package/dist/storage/accessors/MixDataAccessor.d.ts +85 -4
- package/dist/storage/accessors/MixDataAccessor.js +511 -16
- package/dist/storage/accessors/MixDataAccessor.js.map +1 -1
- package/dist/storage/accessors/MixDataAccessor.jsonld +176 -1
- package/dist/storage/accessors/QuintStoreSparqlDataAccessor.d.ts +7 -0
- package/dist/storage/accessors/QuintStoreSparqlDataAccessor.js +72 -4
- package/dist/storage/accessors/QuintStoreSparqlDataAccessor.js.map +1 -1
- package/dist/storage/accessors/QuintStoreSparqlDataAccessor.jsonld +24 -0
- package/dist/storage/quint/BaseQuintStore.d.ts +3 -0
- package/dist/storage/quint/BaseQuintStore.js +51 -27
- package/dist/storage/quint/BaseQuintStore.js.map +1 -1
- package/dist/storage/quint/PgQuintStore.d.ts +1 -0
- package/dist/storage/quint/PgQuintStore.js +50 -32
- package/dist/storage/quint/PgQuintStore.js.map +1 -1
- package/dist/storage/quint/PgQuintStore.jsonld +4 -3
- package/dist/storage/quint/SqliteQuintStore.d.ts +5 -0
- package/dist/storage/quint/SqliteQuintStore.js +100 -0
- package/dist/storage/quint/SqliteQuintStore.js.map +1 -1
- package/dist/storage/quint/SqliteQuintStore.jsonld +20 -0
- package/dist/storage/quint/types.d.ts +16 -0
- package/dist/storage/quint/types.js.map +1 -1
- package/dist/storage/rdf/Rdf3xTripleIndex.d.ts +55 -0
- package/dist/storage/rdf/Rdf3xTripleIndex.js +1235 -0
- package/dist/storage/rdf/Rdf3xTripleIndex.js.map +1 -0
- package/dist/storage/rdf/RdfContentTypes.d.ts +9 -0
- package/dist/storage/rdf/RdfContentTypes.js +79 -0
- package/dist/storage/rdf/RdfContentTypes.js.map +1 -0
- package/dist/storage/rdf/RdfLocalQueryEngine.d.ts +76 -0
- package/dist/storage/rdf/RdfLocalQueryEngine.js +2636 -0
- package/dist/storage/rdf/RdfLocalQueryEngine.js.map +1 -0
- package/dist/storage/rdf/RdfQuadIndex.d.ts +98 -0
- package/dist/storage/rdf/RdfQuadIndex.js +1840 -0
- package/dist/storage/rdf/RdfQuadIndex.js.map +1 -0
- package/dist/storage/rdf/RdfQuadIndex.jsonld +416 -0
- package/dist/storage/rdf/RdfShadowComparator.d.ts +12 -0
- package/dist/storage/rdf/RdfShadowComparator.js +47 -0
- package/dist/storage/rdf/RdfShadowComparator.js.map +1 -0
- package/dist/storage/rdf/RdfSparqlAdapter.d.ts +147 -0
- package/dist/storage/rdf/RdfSparqlAdapter.js +2420 -0
- package/dist/storage/rdf/RdfSparqlAdapter.js.map +1 -0
- package/dist/storage/rdf/RdfSparqlAdapter.jsonld +414 -0
- package/dist/storage/rdf/RdfTermDictionary.d.ts +27 -0
- package/dist/storage/rdf/RdfTermDictionary.js +352 -0
- package/dist/storage/rdf/RdfTermDictionary.js.map +1 -0
- package/dist/storage/rdf/RdfTermDictionary.jsonld +114 -0
- package/dist/storage/rdf/RdfTermSemantics.d.ts +6 -0
- package/dist/storage/rdf/RdfTermSemantics.js +40 -0
- package/dist/storage/rdf/RdfTermSemantics.js.map +1 -0
- package/dist/storage/rdf/RdfTextIndex.d.ts +23 -0
- package/dist/storage/rdf/RdfTextIndex.js +569 -0
- package/dist/storage/rdf/RdfTextIndex.js.map +1 -0
- package/dist/storage/rdf/RdfVectorIndex.d.ts +22 -0
- package/dist/storage/rdf/RdfVectorIndex.js +631 -0
- package/dist/storage/rdf/RdfVectorIndex.js.map +1 -0
- package/dist/storage/rdf/RdfXmlSerializer.d.ts +2 -0
- package/dist/storage/rdf/RdfXmlSerializer.js +123 -0
- package/dist/storage/rdf/RdfXmlSerializer.js.map +1 -0
- package/dist/storage/rdf/ShadowRdfQuintStore.d.ts +58 -0
- package/dist/storage/rdf/ShadowRdfQuintStore.js +202 -0
- package/dist/storage/rdf/ShadowRdfQuintStore.js.map +1 -0
- package/dist/storage/rdf/ShadowRdfQuintStore.jsonld +308 -0
- package/dist/storage/rdf/SolidRdfEngine.d.ts +51 -0
- package/dist/storage/rdf/SolidRdfEngine.js +264 -0
- package/dist/storage/rdf/SolidRdfEngine.js.map +1 -0
- package/dist/storage/rdf/SolidRdfEngine.jsonld +338 -0
- package/dist/storage/rdf/SolidRdfSparqlEngine.d.ts +92 -0
- package/dist/storage/rdf/SolidRdfSparqlEngine.js +477 -0
- package/dist/storage/rdf/SolidRdfSparqlEngine.js.map +1 -0
- package/dist/storage/rdf/SolidRdfSparqlEngine.jsonld +257 -0
- package/dist/storage/rdf/index.d.ts +15 -0
- package/dist/storage/rdf/index.js +61 -0
- package/dist/storage/rdf/index.js.map +1 -0
- package/dist/storage/rdf/models-benchmark.d.ts +260 -0
- package/dist/storage/rdf/models-benchmark.js +1405 -0
- package/dist/storage/rdf/models-benchmark.js.map +1 -0
- package/dist/storage/rdf/types.d.ts +726 -0
- package/dist/storage/rdf/types.js +3 -0
- package/dist/storage/rdf/types.js.map +1 -0
- package/dist/storage/rdf/types.jsonld +316 -0
- package/dist/storage/vector/VectorIndexingListener.d.ts +5 -5
- package/dist/storage/vector/VectorIndexingListener.js +19 -19
- package/dist/storage/vector/VectorIndexingListener.js.map +1 -1
- package/package.json +3 -2
- package/templates/pod/acp/.acr.hbs +39 -0
- package/templates/pod/acp/README.acr +18 -0
- package/templates/pod/acp/profile/card.acr +22 -0
- package/templates/pod/base/README$.md.hbs +27 -0
- package/templates/pod/base/profile/card$.ttl.hbs +13 -0
- package/templates/pod/wac/.acl.hbs +26 -0
- package/templates/pod/wac/README.acl.hbs +14 -0
- package/templates/pod/wac/profile/card.acl.hbs +19 -0
- package/dist/api/handlers/WebIdProfileHandler.d.ts +0 -16
- package/dist/api/handlers/WebIdProfileHandler.js +0 -423
- package/dist/api/handlers/WebIdProfileHandler.js.map +0 -1
- package/dist/identity/drizzle/WebIdProfileRepository.d.ts +0 -63
- package/dist/identity/drizzle/WebIdProfileRepository.js +0 -168
- package/dist/identity/drizzle/WebIdProfileRepository.js.map +0 -1
- package/dist/identity/drizzle/WebIdProfileRepository.jsonld +0 -112
- package/dist/storage/quint/BaseQuintStore.jsonld +0 -257
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WebIdProfileHandler.js","sourceRoot":"","sources":["../../../src/api/handlers/WebIdProfileHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WebID Profile API Handler\n *\n * 提供 WebID Profile 托管服务的 HTTP API\n *\n * GET /{username}/profile/card - 获取 WebID Profile (Turtle 格式)\n * POST /api/v1/identity/{username}/storage - 更新 storage 指针 (需认证)\n */\n\nimport type { ServerResponse, IncomingMessage } from 'node:http';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { ApiServer } from '../ApiServer';\nimport type { WebIdProfileRepository } from '../../identity/drizzle/WebIdProfileRepository';\nimport type { PodLookupRepository, PodLookupResult } from '../../identity/drizzle/PodLookupRepository';\n\nconst logger = getLoggerFor('WebIdProfileHandler');\n\nexport interface WebIdProfileHandlerOptions {\n profileRepo: WebIdProfileRepository;\n podLookupRepo?: PodLookupRepository;\n}\n\ninterface IdentityProfileResponse {\n username: string;\n webidUrl: string;\n storageUrl?: string;\n storageMode: 'cloud' | 'local' | 'custom';\n oidcIssuer?: string;\n createdAt?: Date;\n updatedAt?: Date;\n}\n\nexport function registerWebIdProfileRoutes(\n server: ApiServer,\n options: WebIdProfileHandlerOptions,\n): void {\n const { profileRepo } = options;\n\n /**\n * GET /{username}/profile/card\n *\n * 获取 WebID Profile (Turtle 格式)\n * 这是 Solid 标准的 WebID 端点\n */\n server.get('/:username/profile/card', async (request, response, params) => {\n const username = decodeURIComponent(params.username);\n\n try {\n const profile = await resolveIdentityLookup(username, options, request);\n\n if (!profile) {\n sendError(response, 404, 'Profile not found');\n return;\n }\n\n // 返回 Turtle 格式\n const turtle = profileRepo.generateProfileTurtle(profile);\n\n response.statusCode = 200;\n response.setHeader('Content-Type', 'text/turtle');\n response.setHeader('Link', `<${profile.webidUrl}>; rel=\"describedby\"`);\n response.end(turtle);\n } catch (error) {\n logger.error(`Failed to get profile for ${username}: ${error}`);\n sendError(response, 500, 'Internal server error');\n }\n }, { public: true });\n\n /**\n * POST /api/v1/identity/{username}/storage\n *\n * 更新 storage 指针\n * 用于 Local 节点更新其 storage URL\n *\n * Request body:\n * {\n * \"storageUrl\": \"https://alice.undefineds.xyz/\"\n * }\n */\n server.post('/api/v1/identity/:username/storage', async (request, response, params) => {\n const username = decodeURIComponent(params.username);\n\n try {\n const body = await readJsonBody(request);\n const payload = body as { storageUrl?: string; storageMode?: string } | undefined;\n\n if (!payload?.storageUrl) {\n sendError(response, 400, 'storageUrl is required');\n return;\n }\n\n // 验证 URL 格式\n try {\n new URL(payload.storageUrl);\n } catch {\n sendError(response, 400, 'Invalid storageUrl format');\n return;\n }\n\n const profile = await profileRepo.updateStorage(username, {\n storageUrl: payload.storageUrl,\n storageMode: payload.storageMode as 'cloud' | 'local' | 'custom' | undefined,\n });\n\n if (!profile) {\n sendError(response, 404, 'Profile not found');\n return;\n }\n\n logger.info(`Updated storage for ${username}: ${payload.storageUrl}`);\n\n sendJson(response, 200, {\n success: true,\n username,\n storageUrl: profile.storageUrl,\n storageMode: profile.storageMode,\n updatedAt: profile.updatedAt.toISOString(),\n });\n } catch (error) {\n logger.error(`Failed to update storage for ${username}: ${error}`);\n sendError(response, 500, 'Internal server error');\n }\n });\n\n /**\n * GET /api/v1/identity/{username}\n *\n * 获取 WebID Profile 信息 (JSON 格式)\n */\n server.get('/api/v1/identity/:username', async (request, response, params) => {\n const username = decodeURIComponent(params.username);\n\n try {\n const profile = await resolveIdentityLookup(username, options, request);\n\n if (!profile) {\n sendError(response, 404, 'Profile not found');\n return;\n }\n\n const body: Record<string, unknown> = {\n username: profile.username,\n webidUrl: profile.webidUrl,\n storageUrl: profile.storageUrl,\n storageMode: profile.storageMode,\n oidcIssuer: profile.oidcIssuer,\n };\n if (profile.createdAt) {\n body.createdAt = profile.createdAt.toISOString();\n }\n if (profile.updatedAt) {\n body.updatedAt = profile.updatedAt.toISOString();\n }\n sendJson(response, 200, body);\n } catch (error) {\n logger.error(`Failed to get profile for ${username}: ${error}`);\n sendError(response, 500, 'Internal server error');\n }\n }, { public: true });\n\n /**\n * POST /api/v1/identity\n *\n * 创建 WebID Profile\n *\n * Request body:\n * {\n * \"username\": \"alice\",\n * \"storageMode\": \"local\", // optional, default: \"cloud\"\n * \"storageUrl\": \"https://alice.undefineds.xyz/\" // optional\n * }\n */\n server.post('/api/v1/identity', async (request, response, _params) => {\n try {\n const body = await readJsonBody(request);\n const payload = body as {\n username?: string;\n storageMode?: string;\n storageUrl?: string;\n accountId?: string;\n } | undefined;\n\n if (!payload?.username) {\n sendError(response, 400, 'username is required');\n return;\n }\n\n // 验证用户名格式\n if (!/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/.test(payload.username)) {\n sendError(response, 400, 'Invalid username format');\n return;\n }\n\n // 检查是否已存在\n const existing = await profileRepo.get(payload.username);\n if (existing) {\n sendError(response, 409, 'Username already taken');\n return;\n }\n\n const profile = await profileRepo.create({\n username: payload.username,\n storageMode: payload.storageMode as 'cloud' | 'local' | 'custom' | undefined,\n storageUrl: payload.storageUrl,\n accountId: payload.accountId,\n });\n\n logger.info(`Created profile for ${payload.username}`);\n\n sendJson(response, 201, {\n success: true,\n username: profile.username,\n webidUrl: profile.webidUrl,\n storageUrl: profile.storageUrl,\n storageMode: profile.storageMode,\n createdAt: profile.createdAt.toISOString(),\n });\n } catch (error) {\n logger.error(`Failed to create profile: ${error}`);\n sendError(response, 500, 'Internal server error');\n }\n });\n\n logger.info('WebID Profile routes registered');\n}\n\nasync function resolveIdentityLookup(\n username: string,\n options: WebIdProfileHandlerOptions,\n request?: IncomingMessage,\n): Promise<IdentityProfileResponse | null> {\n try {\n const profile = await resolveProfileWithStorageBackfill(username, options);\n if (profile) {\n return profile;\n }\n } catch (error) {\n logger.warn(`Profile lookup unavailable for ${username}, falling back to Pod index: ${error}`);\n }\n\n return resolveProfileFromPods(username, options, request);\n}\n\nasync function resolveProfileFromPods(\n username: string,\n options: WebIdProfileHandlerOptions,\n request?: IncomingMessage,\n): Promise<IdentityProfileResponse | null> {\n const { podLookupRepo } = options;\n const identityBaseUrl = getHostedIdentityBaseUrl(request);\n\n if (podLookupRepo) {\n const webidUrl = buildHostedWebIdUrl(username, identityBaseUrl);\n const webIdMatch = await tryFindPodByWebId(podLookupRepo, webidUrl, username);\n if (webIdMatch) {\n return profileFromPod(username, webidUrl, webIdMatch);\n }\n\n const match = await tryFindPodByStorageSlug(podLookupRepo, username);\n if (match) {\n return profileFromPod(username, buildStorageWebIdUrl(match.baseUrl), match);\n }\n }\n\n const hostedStorageUrl = new URL(`${encodeURIComponent(username)}/`, identityBaseUrl).toString();\n if (await probeHostedStorageRoot(hostedStorageUrl, username)) {\n return {\n username,\n webidUrl: buildHostedWebIdUrl(username, identityBaseUrl),\n storageUrl: hostedStorageUrl,\n storageMode: 'cloud',\n oidcIssuer: deriveOrigin(identityBaseUrl),\n };\n }\n\n return null;\n}\n\nasync function resolveProfileWithStorageBackfill(\n username: string,\n options: WebIdProfileHandlerOptions,\n) {\n const { profileRepo, podLookupRepo } = options;\n const profile = await profileRepo.get(username);\n if (!profile) {\n return null;\n }\n\n if (profile.storageUrl || !profile.accountId || !podLookupRepo) {\n return profile;\n }\n\n let pods: PodLookupResult[];\n try {\n pods = await podLookupRepo.listByAccountId(profile.accountId);\n } catch (error) {\n logger.warn(`Skipped storage backfill for ${username}: pod index unavailable for account ${profile.accountId}: ${error}`);\n return profile;\n }\n const storageUrl = selectStorageBackfillCandidate(username, pods);\n if (!storageUrl) {\n logger.warn(`Skipped storage backfill for ${username}: no unambiguous pod found for account ${profile.accountId}`);\n return profile;\n }\n\n try {\n const updated = await profileRepo.updateStorage(username, {\n storageUrl,\n storageMode: profile.storageMode,\n });\n if (updated) {\n logger.info(`Backfilled storage for ${username}: ${storageUrl}`);\n return updated;\n }\n } catch (error) {\n logger.warn(`Failed to backfill storage for ${username}: ${error}`);\n }\n\n return profile;\n}\n\nfunction selectStorageBackfillCandidate(\n username: string,\n pods: PodLookupResult[],\n): string | null {\n if (pods.length === 0) {\n return null;\n }\n\n const exactMatches = pods.filter((pod) => derivePodSlug(pod.baseUrl) === username);\n if (exactMatches.length === 1) {\n return ensureTrailingSlash(exactMatches[0].baseUrl);\n }\n\n if (exactMatches.length > 1) {\n return null;\n }\n\n if (pods.length === 1) {\n return ensureTrailingSlash(pods[0].baseUrl);\n }\n\n return null;\n}\n\nfunction derivePodSlug(baseUrl: string): string | null {\n try {\n const parsed = new URL(baseUrl);\n const [slug] = parsed.pathname.split('/').filter(Boolean);\n return slug || null;\n } catch {\n return null;\n }\n}\n\nasync function tryFindPodByWebId(\n podLookupRepo: PodLookupRepository,\n webidUrl: string,\n username: string,\n): Promise<PodLookupResult | undefined> {\n try {\n if (typeof podLookupRepo.findByWebId === 'function') {\n return await podLookupRepo.findByWebId(webidUrl);\n }\n } catch (error) {\n logger.warn(`WebID index lookup unavailable for ${username}: ${error}`);\n }\n return undefined;\n}\n\nasync function tryFindPodByStorageSlug(\n podLookupRepo: PodLookupRepository,\n username: string,\n): Promise<PodLookupResult | undefined> {\n try {\n const pods = await podLookupRepo.listAllPods();\n return pods.find((pod) => derivePodSlug(pod.baseUrl) === username);\n } catch (error) {\n logger.warn(`Pod index lookup unavailable for ${username}: ${error}`);\n return undefined;\n }\n}\n\nfunction profileFromPod(\n username: string,\n webidUrl: string,\n pod: PodLookupResult,\n): IdentityProfileResponse {\n const storageUrl = ensureTrailingSlash(pod.baseUrl);\n return {\n username,\n webidUrl,\n storageUrl,\n storageMode: 'cloud',\n oidcIssuer: deriveOrigin(webidUrl),\n };\n}\n\nfunction buildHostedWebIdUrl(username: string, identityBaseUrl = getHostedIdentityBaseUrl()): string {\n return new URL(`${encodeURIComponent(username)}/profile/card#me`, identityBaseUrl).toString();\n}\n\nfunction buildStorageWebIdUrl(storageUrl: string): string {\n return new URL('profile/card#me', ensureTrailingSlash(storageUrl)).toString();\n}\n\nfunction getHostedIdentityBaseUrl(request?: IncomingMessage): string {\n return ensureTrailingSlash(\n requestOrigin(request) ??\n absoluteHttpUrl(process.env.CSS_BASE_URL) ??\n absoluteHttpUrl(process.env.BASE_URL) ??\n 'http://localhost:3000/',\n );\n}\n\nfunction absoluteHttpUrl(value: string | undefined): string | undefined {\n if (!value) {\n return undefined;\n }\n try {\n const url = new URL(value);\n return url.protocol === 'http:' || url.protocol === 'https:' ? url.toString() : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction requestOrigin(request: IncomingMessage | undefined): string | undefined {\n if (!request?.headers) {\n return undefined;\n }\n const host = firstHeader(request.headers['x-forwarded-host']) ?? firstHeader(request.headers.host);\n if (!host) {\n return undefined;\n }\n const proto = firstHeader(request.headers['x-forwarded-proto']) ?? 'https';\n return absoluteHttpUrl(`${proto}://${host}`);\n}\n\nfunction firstHeader(value: string | string[] | undefined): string | undefined {\n if (Array.isArray(value)) {\n return value[0];\n }\n return value;\n}\n\nasync function probeHostedStorageRoot(storageUrl: string, username: string): Promise<boolean> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 2_000);\n try {\n const response = await fetch(storageUrl, {\n method: 'HEAD',\n signal: controller.signal,\n });\n if (isHostedStorageRootResponse(response)) {\n logger.info(`Resolved hosted WebID profile for ${username} from existing storage root: ${storageUrl}`);\n return true;\n }\n return false;\n } catch (error) {\n logger.warn(`Hosted storage root probe unavailable for ${username}: ${error}`);\n return false;\n } finally {\n clearTimeout(timer);\n }\n}\n\nfunction isHostedStorageRootResponse(response: Response): boolean {\n if (response.status < 200 || response.status >= 400) {\n return false;\n }\n\n const link = response.headers.get('link') ?? '';\n return /<http:\\/\\/www\\.w3\\.org\\/ns\\/pim\\/space#Storage>;\\s*rel=\"?type\"?/iu.test(link) ||\n /<http:\\/\\/www\\.w3\\.org\\/ns\\/ldp#(?:Basic)?Container>;\\s*rel=\"?type\"?/iu.test(link);\n}\n\nfunction ensureTrailingSlash(url: string): string {\n return url.replace(/\\/+$/, '') + '/';\n}\n\nfunction deriveOrigin(url: string): string | undefined {\n try {\n return ensureTrailingSlash(new URL(url).origin);\n } catch {\n return undefined;\n }\n}\n\nasync function readJsonBody(request: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let data = '';\n request.setEncoding('utf8');\n request.on('data', (chunk: string) => {\n data += chunk;\n });\n request.on('end', () => {\n if (!data) {\n resolve(undefined);\n return;\n }\n try {\n resolve(JSON.parse(data));\n } catch {\n resolve(undefined);\n }\n });\n request.on('error', reject);\n });\n}\n\nfunction sendJson(response: ServerResponse, status: number, data: unknown): void {\n response.statusCode = status;\n response.setHeader('Content-Type', 'application/json');\n response.end(JSON.stringify(data));\n}\n\nfunction sendError(response: ServerResponse, status: number, message: string): void {\n sendJson(response, status, { error: message });\n}\n"]}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebID Profile Repository
|
|
3
|
-
*
|
|
4
|
-
* 管理 WebID Profile 的托管,支持身份与存储分离架构
|
|
5
|
-
*/
|
|
6
|
-
import { type IdentityDatabase } from './db';
|
|
7
|
-
export interface WebIdProfile {
|
|
8
|
-
username: string;
|
|
9
|
-
webidUrl: string;
|
|
10
|
-
storageUrl?: string;
|
|
11
|
-
storageMode: 'cloud' | 'local' | 'custom';
|
|
12
|
-
oidcIssuer?: string;
|
|
13
|
-
profileData?: Record<string, unknown>;
|
|
14
|
-
accountId?: string;
|
|
15
|
-
createdAt: Date;
|
|
16
|
-
updatedAt: Date;
|
|
17
|
-
}
|
|
18
|
-
export interface CreateWebIdProfileInput {
|
|
19
|
-
username: string;
|
|
20
|
-
storageMode?: 'cloud' | 'local' | 'custom';
|
|
21
|
-
storageUrl?: string;
|
|
22
|
-
accountId?: string;
|
|
23
|
-
}
|
|
24
|
-
export interface UpdateStorageInput {
|
|
25
|
-
storageUrl: string;
|
|
26
|
-
storageMode?: 'cloud' | 'local' | 'custom';
|
|
27
|
-
}
|
|
28
|
-
export interface WebIdProfileRepositoryOptions {
|
|
29
|
-
baseUrl: string;
|
|
30
|
-
db?: IdentityDatabase;
|
|
31
|
-
identityDbUrl?: string;
|
|
32
|
-
}
|
|
33
|
-
export type WebIdProfileTurtleInput = Pick<WebIdProfile, 'webidUrl' | 'storageUrl' | 'oidcIssuer'>;
|
|
34
|
-
export declare class WebIdProfileRepository {
|
|
35
|
-
private readonly baseUrl;
|
|
36
|
-
private readonly db;
|
|
37
|
-
private readonly schema;
|
|
38
|
-
constructor(options: WebIdProfileRepositoryOptions);
|
|
39
|
-
/**
|
|
40
|
-
* 创建 WebID Profile
|
|
41
|
-
*/
|
|
42
|
-
create(input: CreateWebIdProfileInput): Promise<WebIdProfile>;
|
|
43
|
-
/**
|
|
44
|
-
* 获取 WebID Profile
|
|
45
|
-
*/
|
|
46
|
-
get(username: string): Promise<WebIdProfile | null>;
|
|
47
|
-
/**
|
|
48
|
-
* 更新 Storage URL(用于 Local 节点更新指针)
|
|
49
|
-
*/
|
|
50
|
-
updateStorage(username: string, input: UpdateStorageInput): Promise<WebIdProfile | null>;
|
|
51
|
-
/**
|
|
52
|
-
* 删除 WebID Profile
|
|
53
|
-
*/
|
|
54
|
-
delete(username: string): Promise<boolean>;
|
|
55
|
-
/**
|
|
56
|
-
* 生成 WebID Profile 的 Turtle 格式
|
|
57
|
-
*/
|
|
58
|
-
generateProfileTurtle(profile: WebIdProfileTurtleInput): string;
|
|
59
|
-
/**
|
|
60
|
-
* 生成默认的 Profile 数据(JSON-LD 格式)
|
|
61
|
-
*/
|
|
62
|
-
private generateDefaultProfile;
|
|
63
|
-
}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* WebID Profile Repository
|
|
4
|
-
*
|
|
5
|
-
* 管理 WebID Profile 的托管,支持身份与存储分离架构
|
|
6
|
-
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.WebIdProfileRepository = void 0;
|
|
9
|
-
const drizzle_orm_1 = require("drizzle-orm");
|
|
10
|
-
const db_1 = require("./db");
|
|
11
|
-
const global_logger_factory_1 = require("global-logger-factory");
|
|
12
|
-
const logger = (0, global_logger_factory_1.getLoggerFor)('WebIdProfileRepository');
|
|
13
|
-
class WebIdProfileRepository {
|
|
14
|
-
constructor(options) {
|
|
15
|
-
this.db = options.db ?? getIdentityDatabaseFromOptions(options);
|
|
16
|
-
this.schema = (0, db_1.getSchema)(this.db);
|
|
17
|
-
if (!options.baseUrl) {
|
|
18
|
-
throw new Error('WebIdProfileRepository requires baseUrl.');
|
|
19
|
-
}
|
|
20
|
-
this.baseUrl = options.baseUrl.replace(/\/$/, '');
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* 创建 WebID Profile
|
|
24
|
-
*/
|
|
25
|
-
async create(input) {
|
|
26
|
-
const { username, storageMode = 'cloud', storageUrl, accountId } = input;
|
|
27
|
-
// 生成 WebID URL
|
|
28
|
-
const webidUrl = `${this.baseUrl}/${username}/profile/card#me`;
|
|
29
|
-
// 默认 storage URL
|
|
30
|
-
const defaultStorageUrl = storageMode === 'cloud'
|
|
31
|
-
? `${this.baseUrl}/${username}/`
|
|
32
|
-
: storageUrl;
|
|
33
|
-
// 生成默认的 Profile 数据
|
|
34
|
-
const profileData = this.generateDefaultProfile(username, webidUrl, defaultStorageUrl);
|
|
35
|
-
const now = new Date();
|
|
36
|
-
await this.db.insert(this.schema.webidProfiles).values({
|
|
37
|
-
username,
|
|
38
|
-
webidUrl,
|
|
39
|
-
storageUrl: defaultStorageUrl,
|
|
40
|
-
storageMode,
|
|
41
|
-
oidcIssuer: this.baseUrl,
|
|
42
|
-
profileData,
|
|
43
|
-
accountId,
|
|
44
|
-
createdAt: now,
|
|
45
|
-
updatedAt: now,
|
|
46
|
-
});
|
|
47
|
-
logger.info(`Created WebID profile for ${username}: ${webidUrl}`);
|
|
48
|
-
return {
|
|
49
|
-
username,
|
|
50
|
-
webidUrl,
|
|
51
|
-
storageUrl: defaultStorageUrl,
|
|
52
|
-
storageMode,
|
|
53
|
-
oidcIssuer: this.baseUrl,
|
|
54
|
-
profileData,
|
|
55
|
-
accountId,
|
|
56
|
-
createdAt: now,
|
|
57
|
-
updatedAt: now,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* 获取 WebID Profile
|
|
62
|
-
*/
|
|
63
|
-
async get(username) {
|
|
64
|
-
const results = await this.db
|
|
65
|
-
.select()
|
|
66
|
-
.from(this.schema.webidProfiles)
|
|
67
|
-
.where((0, drizzle_orm_1.eq)(this.schema.webidProfiles.username, username))
|
|
68
|
-
.limit(1);
|
|
69
|
-
if (results.length === 0) {
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
const row = results[0];
|
|
73
|
-
return {
|
|
74
|
-
username: row.username,
|
|
75
|
-
webidUrl: row.webidUrl,
|
|
76
|
-
storageUrl: row.storageUrl ?? undefined,
|
|
77
|
-
storageMode: row.storageMode ?? 'cloud',
|
|
78
|
-
oidcIssuer: row.oidcIssuer ?? undefined,
|
|
79
|
-
profileData: row.profileData,
|
|
80
|
-
accountId: row.accountId ?? undefined,
|
|
81
|
-
createdAt: row.createdAt,
|
|
82
|
-
updatedAt: row.updatedAt,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* 更新 Storage URL(用于 Local 节点更新指针)
|
|
87
|
-
*/
|
|
88
|
-
async updateStorage(username, input) {
|
|
89
|
-
const { storageUrl, storageMode } = input;
|
|
90
|
-
const existing = await this.get(username);
|
|
91
|
-
if (!existing) {
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
// 更新 Profile 数据中的 storage
|
|
95
|
-
const profileData = {
|
|
96
|
-
...(existing.profileData ?? {}),
|
|
97
|
-
'solid:storage': { '@id': storageUrl },
|
|
98
|
-
};
|
|
99
|
-
const now = new Date();
|
|
100
|
-
await this.db
|
|
101
|
-
.update(this.schema.webidProfiles)
|
|
102
|
-
.set({
|
|
103
|
-
storageUrl,
|
|
104
|
-
storageMode: storageMode ?? existing.storageMode,
|
|
105
|
-
profileData,
|
|
106
|
-
updatedAt: now,
|
|
107
|
-
})
|
|
108
|
-
.where((0, drizzle_orm_1.eq)(this.schema.webidProfiles.username, username));
|
|
109
|
-
logger.info(`Updated storage for ${username}: ${storageUrl}`);
|
|
110
|
-
return {
|
|
111
|
-
...existing,
|
|
112
|
-
storageUrl,
|
|
113
|
-
storageMode: storageMode ?? existing.storageMode,
|
|
114
|
-
profileData,
|
|
115
|
-
updatedAt: now,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* 删除 WebID Profile
|
|
120
|
-
*/
|
|
121
|
-
async delete(username) {
|
|
122
|
-
const result = await this.db
|
|
123
|
-
.delete(this.schema.webidProfiles)
|
|
124
|
-
.where((0, drizzle_orm_1.eq)(this.schema.webidProfiles.username, username));
|
|
125
|
-
// drizzle 返回的结果格式因数据库而异
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* 生成 WebID Profile 的 Turtle 格式
|
|
130
|
-
*/
|
|
131
|
-
generateProfileTurtle(profile) {
|
|
132
|
-
const { webidUrl, storageUrl, oidcIssuer } = profile;
|
|
133
|
-
return `@prefix foaf: <http://xmlns.com/foaf/0.1/>.
|
|
134
|
-
@prefix solid: <http://www.w3.org/ns/solid/terms#>.
|
|
135
|
-
|
|
136
|
-
<${webidUrl}>
|
|
137
|
-
a foaf:Person;
|
|
138
|
-
solid:oidcIssuer <${oidcIssuer}>${storageUrl ? `;
|
|
139
|
-
solid:storage <${storageUrl}>` : ''}.
|
|
140
|
-
`;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* 生成默认的 Profile 数据(JSON-LD 格式)
|
|
144
|
-
*/
|
|
145
|
-
generateDefaultProfile(username, webidUrl, storageUrl) {
|
|
146
|
-
const profile = {
|
|
147
|
-
'@context': {
|
|
148
|
-
foaf: 'http://xmlns.com/foaf/0.1/',
|
|
149
|
-
solid: 'http://www.w3.org/ns/solid/terms#',
|
|
150
|
-
},
|
|
151
|
-
'@id': webidUrl,
|
|
152
|
-
'@type': 'foaf:Person',
|
|
153
|
-
'solid:oidcIssuer': { '@id': this.baseUrl },
|
|
154
|
-
};
|
|
155
|
-
if (storageUrl) {
|
|
156
|
-
profile['solid:storage'] = { '@id': storageUrl };
|
|
157
|
-
}
|
|
158
|
-
return profile;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
exports.WebIdProfileRepository = WebIdProfileRepository;
|
|
162
|
-
function getIdentityDatabaseFromOptions(options) {
|
|
163
|
-
if (options.identityDbUrl) {
|
|
164
|
-
return (0, db_1.getIdentityDatabase)(options.identityDbUrl);
|
|
165
|
-
}
|
|
166
|
-
throw new Error('WebIdProfileRepository requires db or identityDbUrl.');
|
|
167
|
-
}
|
|
168
|
-
//# sourceMappingURL=WebIdProfileRepository.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WebIdProfileRepository.js","sourceRoot":"","sources":["../../../src/identity/drizzle/WebIdProfileRepository.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WebID Profile Repository\n *\n * 管理 WebID Profile 的托管,支持身份与存储分离架构\n */\n\nimport { eq } from 'drizzle-orm';\nimport { getIdentityDatabase, getSchema, type IdentityDatabase, type IdentitySchema } from './db';\nimport { getLoggerFor } from 'global-logger-factory';\n\nconst logger = getLoggerFor('WebIdProfileRepository');\n\nexport interface WebIdProfile {\n username: string;\n webidUrl: string;\n storageUrl?: string;\n storageMode: 'cloud' | 'local' | 'custom';\n oidcIssuer?: string;\n profileData?: Record<string, unknown>;\n accountId?: string;\n createdAt: Date;\n updatedAt: Date;\n}\n\nexport interface CreateWebIdProfileInput {\n username: string;\n storageMode?: 'cloud' | 'local' | 'custom';\n storageUrl?: string;\n accountId?: string;\n}\n\nexport interface UpdateStorageInput {\n storageUrl: string;\n storageMode?: 'cloud' | 'local' | 'custom';\n}\n\nexport interface WebIdProfileRepositoryOptions {\n baseUrl: string;\n db?: IdentityDatabase;\n identityDbUrl?: string;\n}\n\nexport type WebIdProfileTurtleInput = Pick<WebIdProfile, 'webidUrl' | 'storageUrl' | 'oidcIssuer'>;\n\nexport class WebIdProfileRepository {\n private readonly baseUrl: string;\n private readonly db: IdentityDatabase;\n private readonly schema: IdentitySchema;\n\n public constructor(options: WebIdProfileRepositoryOptions) {\n this.db = options.db ?? getIdentityDatabaseFromOptions(options);\n this.schema = getSchema(this.db);\n if (!options.baseUrl) {\n throw new Error('WebIdProfileRepository requires baseUrl.');\n }\n this.baseUrl = options.baseUrl.replace(/\\/$/, '');\n }\n\n /**\n * 创建 WebID Profile\n */\n async create(input: CreateWebIdProfileInput): Promise<WebIdProfile> {\n const { username, storageMode = 'cloud', storageUrl, accountId } = input;\n\n // 生成 WebID URL\n const webidUrl = `${this.baseUrl}/${username}/profile/card#me`;\n\n // 默认 storage URL\n const defaultStorageUrl = storageMode === 'cloud'\n ? `${this.baseUrl}/${username}/`\n : storageUrl;\n\n // 生成默认的 Profile 数据\n const profileData = this.generateDefaultProfile(username, webidUrl, defaultStorageUrl);\n\n const now = new Date();\n\n await this.db.insert(this.schema.webidProfiles).values({\n username,\n webidUrl,\n storageUrl: defaultStorageUrl,\n storageMode,\n oidcIssuer: this.baseUrl,\n profileData,\n accountId,\n createdAt: now,\n updatedAt: now,\n });\n\n logger.info(`Created WebID profile for ${username}: ${webidUrl}`);\n\n return {\n username,\n webidUrl,\n storageUrl: defaultStorageUrl,\n storageMode,\n oidcIssuer: this.baseUrl,\n profileData,\n accountId,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n /**\n * 获取 WebID Profile\n */\n async get(username: string): Promise<WebIdProfile | null> {\n const results = await this.db\n .select()\n .from(this.schema.webidProfiles)\n .where(eq(this.schema.webidProfiles.username, username))\n .limit(1);\n\n if (results.length === 0) {\n return null;\n }\n\n const row = results[0];\n return {\n username: row.username,\n webidUrl: row.webidUrl,\n storageUrl: row.storageUrl ?? undefined,\n storageMode: (row.storageMode as 'cloud' | 'local' | 'custom') ?? 'cloud',\n oidcIssuer: row.oidcIssuer ?? undefined,\n profileData: row.profileData as Record<string, unknown> | undefined,\n accountId: row.accountId ?? undefined,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n };\n }\n\n /**\n * 更新 Storage URL(用于 Local 节点更新指针)\n */\n async updateStorage(username: string, input: UpdateStorageInput): Promise<WebIdProfile | null> {\n const { storageUrl, storageMode } = input;\n\n const existing = await this.get(username);\n if (!existing) {\n return null;\n }\n\n // 更新 Profile 数据中的 storage\n const profileData = {\n ...(existing.profileData ?? {}),\n 'solid:storage': { '@id': storageUrl },\n };\n\n const now = new Date();\n\n await this.db\n .update(this.schema.webidProfiles)\n .set({\n storageUrl,\n storageMode: storageMode ?? existing.storageMode,\n profileData,\n updatedAt: now,\n })\n .where(eq(this.schema.webidProfiles.username, username));\n\n logger.info(`Updated storage for ${username}: ${storageUrl}`);\n\n return {\n ...existing,\n storageUrl,\n storageMode: storageMode ?? existing.storageMode,\n profileData,\n updatedAt: now,\n };\n }\n\n /**\n * 删除 WebID Profile\n */\n async delete(username: string): Promise<boolean> {\n const result = await this.db\n .delete(this.schema.webidProfiles)\n .where(eq(this.schema.webidProfiles.username, username));\n\n // drizzle 返回的结果格式因数据库而异\n return true;\n }\n\n /**\n * 生成 WebID Profile 的 Turtle 格式\n */\n generateProfileTurtle(profile: WebIdProfileTurtleInput): string {\n const { webidUrl, storageUrl, oidcIssuer } = profile;\n\n return `@prefix foaf: <http://xmlns.com/foaf/0.1/>.\n@prefix solid: <http://www.w3.org/ns/solid/terms#>.\n\n<${webidUrl}>\n a foaf:Person;\n solid:oidcIssuer <${oidcIssuer}>${storageUrl ? `;\n solid:storage <${storageUrl}>` : ''}.\n`;\n }\n\n /**\n * 生成默认的 Profile 数据(JSON-LD 格式)\n */\n private generateDefaultProfile(\n username: string,\n webidUrl: string,\n storageUrl?: string,\n ): Record<string, unknown> {\n const profile: Record<string, unknown> = {\n '@context': {\n foaf: 'http://xmlns.com/foaf/0.1/',\n solid: 'http://www.w3.org/ns/solid/terms#',\n },\n '@id': webidUrl,\n '@type': 'foaf:Person',\n 'solid:oidcIssuer': { '@id': this.baseUrl },\n };\n\n if (storageUrl) {\n profile['solid:storage'] = { '@id': storageUrl };\n }\n\n return profile;\n }\n}\n\nfunction getIdentityDatabaseFromOptions(options: WebIdProfileRepositoryOptions): IdentityDatabase {\n if (options.identityDbUrl) {\n return getIdentityDatabase(options.identityDbUrl);\n }\n\n throw new Error('WebIdProfileRepository requires db or identityDbUrl.');\n}\n"]}
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"@context": [
|
|
3
|
-
"https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod/^0.0.0/components/context.jsonld"
|
|
4
|
-
],
|
|
5
|
-
"@id": "npmd:@undefineds.co/xpod",
|
|
6
|
-
"components": [
|
|
7
|
-
{
|
|
8
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository",
|
|
9
|
-
"@type": "Class",
|
|
10
|
-
"requireElement": "WebIdProfileRepository",
|
|
11
|
-
"parameters": [
|
|
12
|
-
{
|
|
13
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository_options_baseUrl",
|
|
14
|
-
"range": "xsd:string"
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository_options_db",
|
|
18
|
-
"range": {
|
|
19
|
-
"@type": "ParameterRangeUnion",
|
|
20
|
-
"parameterRangeElements": [
|
|
21
|
-
{
|
|
22
|
-
"@type": "ParameterRangeWildcard"
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"@type": "ParameterRangeUndefined"
|
|
26
|
-
}
|
|
27
|
-
]
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository_options_identityDbUrl",
|
|
32
|
-
"range": {
|
|
33
|
-
"@type": "ParameterRangeUnion",
|
|
34
|
-
"parameterRangeElements": [
|
|
35
|
-
"xsd:string",
|
|
36
|
-
{
|
|
37
|
-
"@type": "ParameterRangeUndefined"
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
],
|
|
43
|
-
"memberFields": [
|
|
44
|
-
{
|
|
45
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository__member_baseUrl",
|
|
46
|
-
"memberFieldName": "baseUrl"
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository__member_db",
|
|
50
|
-
"memberFieldName": "db"
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository__member_schema",
|
|
54
|
-
"memberFieldName": "schema"
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository__member_constructor",
|
|
58
|
-
"memberFieldName": "constructor"
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository__member_create",
|
|
62
|
-
"memberFieldName": "create"
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository__member_get",
|
|
66
|
-
"memberFieldName": "get"
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository__member_updateStorage",
|
|
70
|
-
"memberFieldName": "updateStorage"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository__member_delete",
|
|
74
|
-
"memberFieldName": "delete"
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository__member_generateProfileTurtle",
|
|
78
|
-
"memberFieldName": "generateProfileTurtle"
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository__member_generateDefaultProfile",
|
|
82
|
-
"memberFieldName": "generateDefaultProfile"
|
|
83
|
-
}
|
|
84
|
-
],
|
|
85
|
-
"constructorArguments": [
|
|
86
|
-
{
|
|
87
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository_options__constructorArgument",
|
|
88
|
-
"fields": [
|
|
89
|
-
{
|
|
90
|
-
"keyRaw": "baseUrl",
|
|
91
|
-
"value": {
|
|
92
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository_options_baseUrl"
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"keyRaw": "db",
|
|
97
|
-
"value": {
|
|
98
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository_options_db"
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
"keyRaw": "identityDbUrl",
|
|
103
|
-
"value": {
|
|
104
|
-
"@id": "undefineds:dist/identity/drizzle/WebIdProfileRepository.jsonld#WebIdProfileRepository_options_identityDbUrl"
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
]
|
|
108
|
-
}
|
|
109
|
-
]
|
|
110
|
-
}
|
|
111
|
-
]
|
|
112
|
-
}
|