@nextclaw/app-runtime 0.9.12 → 0.9.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/README.md +2 -2
- package/dist/{main.js → app/main.js} +2 -2
- package/dist/app/main.js.map +1 -0
- package/dist/{commands → controllers}/create.controller.d.ts +2 -2
- package/dist/controllers/create.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/create.controller.js +2 -2
- package/dist/controllers/create.controller.js.map +1 -0
- package/dist/{commands → controllers}/dev.controller.js +1 -1
- package/dist/controllers/dev.controller.js.map +1 -0
- package/dist/{commands → controllers}/grant.controller.d.ts +3 -3
- package/dist/controllers/grant.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/grant.controller.js +2 -2
- package/dist/controllers/grant.controller.js.map +1 -0
- package/dist/{commands → controllers}/info.controller.d.ts +2 -2
- package/dist/controllers/info.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/info.controller.js +2 -2
- package/dist/controllers/info.controller.js.map +1 -0
- package/dist/{commands → controllers}/inspect.controller.js +8 -2
- package/dist/controllers/inspect.controller.js.map +1 -0
- package/dist/{commands → controllers}/install.controller.d.ts +2 -2
- package/dist/controllers/install.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/install.controller.js +2 -2
- package/dist/controllers/install.controller.js.map +1 -0
- package/dist/{commands → controllers}/list.controller.d.ts +2 -2
- package/dist/controllers/list.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/list.controller.js +2 -2
- package/dist/controllers/list.controller.js.map +1 -0
- package/dist/controllers/pack.controller.d.ts +19 -0
- package/dist/controllers/pack.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/pack.controller.js +8 -4
- package/dist/controllers/pack.controller.js.map +1 -0
- package/dist/{commands → controllers}/permissions.controller.d.ts +2 -2
- package/dist/controllers/permissions.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/permissions.controller.js +2 -2
- package/dist/controllers/permissions.controller.js.map +1 -0
- package/dist/{commands → controllers}/publish.controller.d.ts +3 -3
- package/dist/controllers/publish.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/publish.controller.js +2 -2
- package/dist/controllers/publish.controller.js.map +1 -0
- package/dist/{commands → controllers}/registry.controller.d.ts +2 -2
- package/dist/controllers/registry.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/registry.controller.js +2 -2
- package/dist/controllers/registry.controller.js.map +1 -0
- package/dist/{commands → controllers}/revoke.controller.d.ts +2 -2
- package/dist/controllers/revoke.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/revoke.controller.js +2 -2
- package/dist/controllers/revoke.controller.js.map +1 -0
- package/dist/{commands → controllers}/run.controller.js +8 -6
- package/dist/controllers/run.controller.js.map +1 -0
- package/dist/{commands → controllers}/uninstall.controller.d.ts +2 -2
- package/dist/controllers/uninstall.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/uninstall.controller.js +2 -2
- package/dist/controllers/uninstall.controller.js.map +1 -0
- package/dist/{commands → controllers}/update.controller.d.ts +2 -2
- package/dist/controllers/update.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/update.controller.js +2 -2
- package/dist/controllers/update.controller.js.map +1 -0
- package/dist/{commands → controllers}/validate-publish.controller.d.ts +3 -3
- package/dist/controllers/validate-publish.controller.d.ts.map +1 -0
- package/dist/{commands → controllers}/validate-publish.controller.js +9 -5
- package/dist/controllers/validate-publish.controller.js.map +1 -0
- package/dist/index.d.ts +51 -51
- package/dist/index.js +46 -45
- package/dist/package.js +1 -1
- package/dist/{runtime → services}/app-build.service.d.ts +2 -2
- package/dist/services/app-build.service.d.ts.map +1 -0
- package/dist/{runtime → services}/app-build.service.js +4 -2
- package/dist/services/app-build.service.js.map +1 -0
- package/dist/{bundle → services}/app-bundle.service.d.ts +18 -6
- package/dist/services/app-bundle.service.d.ts.map +1 -0
- package/dist/services/app-bundle.service.js +305 -0
- package/dist/services/app-bundle.service.js.map +1 -0
- package/dist/{permissions → services}/app-grant.service.d.ts +4 -4
- package/dist/services/app-grant.service.d.ts.map +1 -0
- package/dist/{permissions → services}/app-grant.service.js +7 -4
- package/dist/services/app-grant.service.js.map +1 -0
- package/dist/{paths → services}/app-home.service.d.ts +1 -1
- package/dist/services/app-home.service.d.ts.map +1 -0
- package/dist/{paths → services}/app-home.service.js +1 -1
- package/dist/services/app-home.service.js.map +1 -0
- package/dist/{host → services}/app-host.service.d.ts +2 -2
- package/dist/services/app-host.service.d.ts.map +1 -0
- package/dist/{host → services}/app-host.service.js +3 -3
- package/dist/services/app-host.service.js.map +1 -0
- package/dist/services/app-install-source.service.js +72 -0
- package/dist/services/app-install-source.service.js.map +1 -0
- package/dist/{install → services}/app-installation.service.d.ts +15 -14
- package/dist/services/app-installation.service.d.ts.map +1 -0
- package/dist/services/app-installation.service.js +332 -0
- package/dist/services/app-installation.service.js.map +1 -0
- package/dist/services/app-instance.service.d.ts +34 -0
- package/dist/services/app-instance.service.d.ts.map +1 -0
- package/dist/{host → services}/app-instance.service.js +4 -4
- package/dist/services/app-instance.service.js.map +1 -0
- package/dist/{manifest → services}/app-manifest.service.d.ts +12 -2
- package/dist/services/app-manifest.service.d.ts.map +1 -0
- package/dist/services/app-manifest.service.js +271 -0
- package/dist/services/app-manifest.service.js.map +1 -0
- package/dist/{publish → services}/app-marketplace-client.service.d.ts +2 -2
- package/dist/services/app-marketplace-client.service.d.ts.map +1 -0
- package/dist/{publish → services}/app-marketplace-client.service.js +2 -2
- package/dist/services/app-marketplace-client.service.js.map +1 -0
- package/dist/{publish → services}/app-marketplace-metadata.service.d.ts +3 -3
- package/dist/services/app-marketplace-metadata.service.d.ts.map +1 -0
- package/dist/{publish → services}/app-marketplace-metadata.service.js +1 -1
- package/dist/services/app-marketplace-metadata.service.js.map +1 -0
- package/dist/{permissions → services}/app-permissions.service.d.ts +3 -3
- package/dist/services/app-permissions.service.d.ts.map +1 -0
- package/dist/{permissions → services}/app-permissions.service.js +4 -1
- package/dist/services/app-permissions.service.js.map +1 -0
- package/dist/{publish → services}/app-publish-validation.service.d.ts +9 -7
- package/dist/services/app-publish-validation.service.d.ts.map +1 -0
- package/dist/{publish → services}/app-publish-validation.service.js +14 -10
- package/dist/services/app-publish-validation.service.js.map +1 -0
- package/dist/{publish → services}/app-publish.service.d.ts +5 -5
- package/dist/services/app-publish.service.d.ts.map +1 -0
- package/dist/{publish → services}/app-publish.service.js +6 -6
- package/dist/services/app-publish.service.js.map +1 -0
- package/dist/{registry → services}/app-registry-config.service.d.ts +3 -3
- package/dist/{registry → services}/app-registry-config.service.d.ts.map +1 -1
- package/dist/{registry → services}/app-registry-config.service.js +3 -3
- package/dist/services/app-registry-config.service.js.map +1 -0
- package/dist/{registry → services}/app-registry.service.d.ts +18 -5
- package/dist/services/app-registry.service.d.ts.map +1 -0
- package/dist/services/app-registry.service.js +210 -0
- package/dist/services/app-registry.service.js.map +1 -0
- package/dist/{registry → services}/app-remote-registry-client.service.d.ts +6 -2
- package/dist/services/app-remote-registry-client.service.d.ts.map +1 -0
- package/dist/{registry → services}/app-remote-registry-client.service.js +54 -8
- package/dist/services/app-remote-registry-client.service.js.map +1 -0
- package/dist/{cli → services}/app-runtime-cli.service.d.ts +1 -1
- package/dist/services/app-runtime-cli.service.d.ts.map +1 -0
- package/dist/{cli → services}/app-runtime-cli.service.js +19 -19
- package/dist/services/app-runtime-cli.service.js.map +1 -0
- package/dist/{cli → services}/app-runtime-options.service.d.ts +6 -6
- package/dist/services/app-runtime-options.service.d.ts.map +1 -0
- package/dist/{cli → services}/app-runtime-options.service.js +3 -9
- package/dist/services/app-runtime-options.service.js.map +1 -0
- package/dist/{runtime → services}/app-runtime-toolchain.service.d.ts +1 -1
- package/dist/services/app-runtime-toolchain.service.d.ts.map +1 -0
- package/dist/{runtime → services}/app-runtime-toolchain.service.js +1 -1
- package/dist/services/app-runtime-toolchain.service.js.map +1 -0
- package/dist/{scaffold → services}/app-scaffold.service.d.ts +1 -1
- package/dist/{scaffold → services}/app-scaffold.service.d.ts.map +1 -1
- package/dist/{scaffold → services}/app-scaffold.service.js +1 -1
- package/dist/{scaffold → services}/app-scaffold.service.js.map +1 -1
- package/dist/{scaffold → services}/app-ts-http-lite-scaffold-template.service.d.ts +1 -1
- package/dist/{scaffold → services}/app-ts-http-lite-scaffold-template.service.d.ts.map +1 -1
- package/dist/{scaffold → services}/app-ts-http-lite-scaffold-template.service.js +1 -1
- package/dist/{scaffold → services}/app-ts-http-lite-scaffold-template.service.js.map +1 -1
- package/dist/{scaffold → services}/app-ts-http-scaffold-template.service.d.ts +1 -1
- package/dist/{scaffold → services}/app-ts-http-scaffold-template.service.d.ts.map +1 -1
- package/dist/{scaffold → services}/app-ts-http-scaffold-template.service.js +1 -1
- package/dist/{scaffold → services}/app-ts-http-scaffold-template.service.js.map +1 -1
- package/dist/{bridge → services}/host-bridge.service.d.ts +2 -2
- package/dist/services/host-bridge.service.d.ts.map +1 -0
- package/dist/{bridge → services}/host-bridge.service.js +1 -1
- package/dist/services/host-bridge.service.js.map +1 -0
- package/dist/services/main-runner.service.d.ts +9 -0
- package/dist/services/main-runner.service.d.ts.map +1 -0
- package/dist/services/main-runner.service.js +6 -0
- package/dist/services/main-runner.service.js.map +1 -0
- package/dist/{publish → services}/platform-auth-state.service.d.ts +1 -1
- package/dist/services/platform-auth-state.service.d.ts.map +1 -0
- package/dist/{publish → services}/platform-auth-state.service.js +1 -1
- package/dist/services/platform-auth-state.service.js.map +1 -0
- package/dist/{ui → services}/ui-server.service.d.ts +3 -3
- package/dist/services/ui-server.service.d.ts.map +1 -0
- package/dist/{ui → services}/ui-server.service.js +1 -1
- package/dist/services/ui-server.service.js.map +1 -0
- package/dist/{runtime → services}/wasm-main-runner.service.d.ts +3 -3
- package/dist/services/wasm-main-runner.service.d.ts.map +1 -0
- package/dist/{runtime → services}/wasm-main-runner.service.js +2 -2
- package/dist/services/wasm-main-runner.service.js.map +1 -0
- package/dist/{sidecar → services}/wasm-sidecar-client.service.d.ts +1 -1
- package/dist/services/wasm-sidecar-client.service.d.ts.map +1 -0
- package/dist/{sidecar → services}/wasm-sidecar-client.service.js +1 -1
- package/dist/services/wasm-sidecar-client.service.js.map +1 -0
- package/dist/{runtime → services}/wasmtime-wasi-http-component.service.d.ts +1 -1
- package/dist/services/wasmtime-wasi-http-component.service.d.ts.map +1 -0
- package/dist/{runtime → services}/wasmtime-wasi-http-component.service.js +1 -1
- package/dist/services/wasmtime-wasi-http-component.service.js.map +1 -0
- package/dist/{bundle → types}/app-bundle.types.d.ts +1 -1
- package/dist/types/app-bundle.types.d.ts.map +1 -0
- package/dist/{install → types}/app-installation.types.d.ts +27 -7
- package/dist/types/app-installation.types.d.ts.map +1 -0
- package/dist/types/app-manifest.types.d.ts +119 -0
- package/dist/types/app-manifest.types.d.ts.map +1 -0
- package/dist/types/app-manifest.types.js +11 -0
- package/dist/types/app-manifest.types.js.map +1 -0
- package/dist/{permissions → types}/app-permissions.types.d.ts +2 -2
- package/dist/types/app-permissions.types.d.ts.map +1 -0
- package/dist/{publish → types}/app-publish.types.d.ts +4 -4
- package/dist/types/app-publish.types.d.ts.map +1 -0
- package/dist/{publish → types}/app-publish.types.js +1 -1
- package/dist/types/app-publish.types.js.map +1 -0
- package/dist/{registry → types}/app-registry.types.d.ts +8 -4
- package/dist/types/app-registry.types.d.ts.map +1 -0
- package/dist/{registry → types}/app-remote-registry.types.d.ts +3 -3
- package/dist/types/app-remote-registry.types.d.ts.map +1 -0
- package/dist/{registry → types}/app-remote-registry.types.js +1 -1
- package/dist/types/app-remote-registry.types.js.map +1 -0
- package/dist/{runtime → types}/main-runner.types.d.ts +3 -3
- package/dist/types/main-runner.types.d.ts.map +1 -0
- package/package.json +10 -3
- package/dist/bridge/host-bridge.service.d.ts.map +0 -1
- package/dist/bridge/host-bridge.service.js.map +0 -1
- package/dist/bundle/app-bundle.service.d.ts.map +0 -1
- package/dist/bundle/app-bundle.service.js +0 -196
- package/dist/bundle/app-bundle.service.js.map +0 -1
- package/dist/bundle/app-bundle.types.d.ts.map +0 -1
- package/dist/cli/app-runtime-cli.service.d.ts.map +0 -1
- package/dist/cli/app-runtime-cli.service.js.map +0 -1
- package/dist/cli/app-runtime-options.service.d.ts.map +0 -1
- package/dist/cli/app-runtime-options.service.js.map +0 -1
- package/dist/commands/create.controller.d.ts.map +0 -1
- package/dist/commands/create.controller.js.map +0 -1
- package/dist/commands/dev.controller.js.map +0 -1
- package/dist/commands/grant.controller.d.ts.map +0 -1
- package/dist/commands/grant.controller.js.map +0 -1
- package/dist/commands/info.controller.d.ts.map +0 -1
- package/dist/commands/info.controller.js.map +0 -1
- package/dist/commands/inspect.controller.js.map +0 -1
- package/dist/commands/install.controller.d.ts.map +0 -1
- package/dist/commands/install.controller.js.map +0 -1
- package/dist/commands/list.controller.d.ts.map +0 -1
- package/dist/commands/list.controller.js.map +0 -1
- package/dist/commands/pack.controller.d.ts +0 -17
- package/dist/commands/pack.controller.d.ts.map +0 -1
- package/dist/commands/pack.controller.js.map +0 -1
- package/dist/commands/permissions.controller.d.ts.map +0 -1
- package/dist/commands/permissions.controller.js.map +0 -1
- package/dist/commands/publish.controller.d.ts.map +0 -1
- package/dist/commands/publish.controller.js.map +0 -1
- package/dist/commands/registry.controller.d.ts.map +0 -1
- package/dist/commands/registry.controller.js.map +0 -1
- package/dist/commands/revoke.controller.d.ts.map +0 -1
- package/dist/commands/revoke.controller.js.map +0 -1
- package/dist/commands/run.controller.js.map +0 -1
- package/dist/commands/uninstall.controller.d.ts.map +0 -1
- package/dist/commands/uninstall.controller.js.map +0 -1
- package/dist/commands/update.controller.d.ts.map +0 -1
- package/dist/commands/update.controller.js.map +0 -1
- package/dist/commands/validate-publish.controller.d.ts.map +0 -1
- package/dist/commands/validate-publish.controller.js.map +0 -1
- package/dist/host/app-host.service.d.ts.map +0 -1
- package/dist/host/app-host.service.js.map +0 -1
- package/dist/host/app-instance.service.d.ts +0 -34
- package/dist/host/app-instance.service.d.ts.map +0 -1
- package/dist/host/app-instance.service.js.map +0 -1
- package/dist/install/app-installation.service.d.ts.map +0 -1
- package/dist/install/app-installation.service.js +0 -276
- package/dist/install/app-installation.service.js.map +0 -1
- package/dist/install/app-installation.types.d.ts.map +0 -1
- package/dist/main.js.map +0 -1
- package/dist/manifest/app-manifest.service.d.ts.map +0 -1
- package/dist/manifest/app-manifest.service.js +0 -147
- package/dist/manifest/app-manifest.service.js.map +0 -1
- package/dist/manifest/app-manifest.types.d.ts +0 -68
- package/dist/manifest/app-manifest.types.d.ts.map +0 -1
- package/dist/paths/app-home.service.d.ts.map +0 -1
- package/dist/paths/app-home.service.js.map +0 -1
- package/dist/permissions/app-grant.service.d.ts.map +0 -1
- package/dist/permissions/app-grant.service.js.map +0 -1
- package/dist/permissions/app-permissions.service.d.ts.map +0 -1
- package/dist/permissions/app-permissions.service.js.map +0 -1
- package/dist/permissions/app-permissions.types.d.ts.map +0 -1
- package/dist/publish/app-marketplace-client.service.d.ts.map +0 -1
- package/dist/publish/app-marketplace-client.service.js.map +0 -1
- package/dist/publish/app-marketplace-metadata.service.d.ts.map +0 -1
- package/dist/publish/app-marketplace-metadata.service.js.map +0 -1
- package/dist/publish/app-publish-validation.service.d.ts.map +0 -1
- package/dist/publish/app-publish-validation.service.js.map +0 -1
- package/dist/publish/app-publish.service.d.ts.map +0 -1
- package/dist/publish/app-publish.service.js.map +0 -1
- package/dist/publish/app-publish.types.d.ts.map +0 -1
- package/dist/publish/app-publish.types.js.map +0 -1
- package/dist/publish/platform-auth-state.service.d.ts.map +0 -1
- package/dist/publish/platform-auth-state.service.js.map +0 -1
- package/dist/registry/app-registry-config.service.js.map +0 -1
- package/dist/registry/app-registry.service.d.ts.map +0 -1
- package/dist/registry/app-registry.service.js +0 -118
- package/dist/registry/app-registry.service.js.map +0 -1
- package/dist/registry/app-registry.types.d.ts.map +0 -1
- package/dist/registry/app-remote-registry-client.service.d.ts.map +0 -1
- package/dist/registry/app-remote-registry-client.service.js.map +0 -1
- package/dist/registry/app-remote-registry.types.d.ts.map +0 -1
- package/dist/registry/app-remote-registry.types.js.map +0 -1
- package/dist/runtime/app-build.service.d.ts.map +0 -1
- package/dist/runtime/app-build.service.js.map +0 -1
- package/dist/runtime/app-runtime-toolchain.service.d.ts.map +0 -1
- package/dist/runtime/app-runtime-toolchain.service.js.map +0 -1
- package/dist/runtime/main-runner.service.d.ts +0 -9
- package/dist/runtime/main-runner.service.d.ts.map +0 -1
- package/dist/runtime/main-runner.service.js +0 -6
- package/dist/runtime/main-runner.service.js.map +0 -1
- package/dist/runtime/main-runner.types.d.ts.map +0 -1
- package/dist/runtime/wasm-main-runner.service.d.ts.map +0 -1
- package/dist/runtime/wasm-main-runner.service.js.map +0 -1
- package/dist/runtime/wasmtime-wasi-http-component.service.d.ts.map +0 -1
- package/dist/runtime/wasmtime-wasi-http-component.service.js.map +0 -1
- package/dist/sidecar/wasm-sidecar-client.service.d.ts.map +0 -1
- package/dist/sidecar/wasm-sidecar-client.service.js.map +0 -1
- package/dist/ui/ui-server.service.d.ts.map +0 -1
- package/dist/ui/ui-server.service.js.map +0 -1
- /package/dist/{main.d.ts → app/main.d.ts} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-permissions.service.js","names":[],"sources":["../../src/permissions/app-permissions.service.ts"],"sourcesContent":["import { access } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type {\n AppDocumentAccessScope,\n AppManifestBundle,\n} from \"../manifest/app-manifest.types.js\";\nimport type {\n AppDocumentGrantMap,\n AppPermissionSummary,\n ResolvedDocumentGrant,\n ResolvedPermissions,\n} from \"./app-permissions.types.js\";\n\nexport class AppPermissionsService {\n resolve = async (\n bundle: AppManifestBundle,\n documentGrantMap: AppDocumentGrantMap,\n context?: {\n appId?: string;\n },\n ): Promise<ResolvedPermissions> => {\n const requestedPermissions = bundle.manifest.permissions ?? {};\n const documentAccess =\n requestedPermissions.documentAccess === undefined\n ? []\n : await Promise.all(\n requestedPermissions.documentAccess.map((scope) =>\n this.resolveDocumentGrant(scope, documentGrantMap, context?.appId),\n ),\n );\n\n return {\n documentAccess,\n allowedDomains: requestedPermissions.allowedDomains ?? [],\n storage: {\n enabled: requestedPermissions.storage !== undefined && requestedPermissions.storage !== false,\n namespace:\n typeof requestedPermissions.storage === \"object\"\n ? requestedPermissions.storage.namespace\n : undefined,\n },\n capabilities: {\n hostBridge: requestedPermissions.capabilities?.hostBridge !== false,\n },\n };\n };\n\n summarize = (\n bundle: AppManifestBundle,\n permissions: ResolvedPermissions,\n ): AppPermissionSummary => {\n return {\n requested: bundle.manifest.permissions ?? {},\n documentAccess: permissions.documentAccess,\n allowedDomains: permissions.allowedDomains,\n storage: permissions.storage,\n capabilities: permissions.capabilities,\n };\n };\n\n private resolveDocumentGrant = async (\n scope: AppDocumentAccessScope,\n documentGrantMap: AppDocumentGrantMap,\n appId?: string,\n ): Promise<ResolvedDocumentGrant> => {\n const grantedPath = documentGrantMap[scope.id];\n if (!grantedPath) {\n if (appId) {\n throw new Error(\n `缺少 documentAccess 授权:${scope.id}。请先执行 napp grant ${appId} --document ${scope.id}=/absolute/path`,\n );\n }\n throw new Error(\n `缺少 documentAccess 授权:${scope.id}。请通过 --document ${scope.id}=/absolute/path 提供授权。`,\n );\n }\n const normalizedPath = path.resolve(grantedPath);\n try {\n await access(normalizedPath);\n } catch {\n throw new Error(`documentAccess 授权路径不存在:${scope.id} -> ${normalizedPath}`);\n }\n return {\n id: scope.id,\n mode: scope.mode,\n description: scope.description,\n path: normalizedPath,\n };\n };\n}\n"],"mappings":";;;AAaA,IAAa,wBAAb,MAAmC;CACjC,UAAU,OACR,QACA,kBACA,YAGiC;EACjC,MAAM,uBAAuB,OAAO,SAAS,eAAe,EAAE;AAU9D,SAAO;GACL,gBATA,qBAAqB,mBAAmB,KAAA,IACpC,EAAE,GACF,MAAM,QAAQ,IACZ,qBAAqB,eAAe,KAAK,UACvC,KAAK,qBAAqB,OAAO,kBAAkB,SAAS,MAAM,CACnE,CACF;GAIL,gBAAgB,qBAAqB,kBAAkB,EAAE;GACzD,SAAS;IACP,SAAS,qBAAqB,YAAY,KAAA,KAAa,qBAAqB,YAAY;IACxF,WACE,OAAO,qBAAqB,YAAY,WACpC,qBAAqB,QAAQ,YAC7B,KAAA;IACP;GACD,cAAc,EACZ,YAAY,qBAAqB,cAAc,eAAe,OAC/D;GACF;;CAGH,aACE,QACA,gBACyB;AACzB,SAAO;GACL,WAAW,OAAO,SAAS,eAAe,EAAE;GAC5C,gBAAgB,YAAY;GAC5B,gBAAgB,YAAY;GAC5B,SAAS,YAAY;GACrB,cAAc,YAAY;GAC3B;;CAGH,uBAA+B,OAC7B,OACA,kBACA,UACmC;EACnC,MAAM,cAAc,iBAAiB,MAAM;AAC3C,MAAI,CAAC,aAAa;AAChB,OAAI,MACF,OAAM,IAAI,MACR,wBAAwB,MAAM,GAAG,mBAAmB,MAAM,cAAc,MAAM,GAAG,iBAClF;AAEH,SAAM,IAAI,MACR,wBAAwB,MAAM,GAAG,kBAAkB,MAAM,GAAG,uBAC7D;;EAEH,MAAM,iBAAiB,KAAK,QAAQ,YAAY;AAChD,MAAI;AACF,SAAM,OAAO,eAAe;UACtB;AACN,SAAM,IAAI,MAAM,0BAA0B,MAAM,GAAG,MAAM,iBAAiB;;AAE5E,SAAO;GACL,IAAI,MAAM;GACV,MAAM,MAAM;GACZ,aAAa,MAAM;GACnB,MAAM;GACP"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-permissions.types.d.ts","names":[],"sources":["../../src/permissions/app-permissions.types.ts"],"mappings":";;;KAEY,mBAAA,GAAsB,MAAA;AAAA,KAEtB,qBAAA;EACV,EAAA;EACA,IAAA;EACA,WAAA;EACA,IAAA;AAAA;AAAA,KAGU,mBAAA;EACV,cAAA,EAAgB,qBAAA;EAChB,cAAA;EACA,OAAA;IACE,OAAA;IACA,SAAA;EAAA;EAEF,YAAA;IACE,UAAA;EAAA;AAAA;AAAA,KAIQ,oBAAA,GAAuB,IAAA,CACjC,mBAAA;EAGA,SAAA,EAAW,cAAA;AAAA;AAAA,KAGD,qBAAA;EACV,EAAA;EACA,IAAA;EACA,WAAA;EACA,OAAA;EACA,WAAA;AAAA;AAAA,KAGU,2BAAA;EACV,KAAA;EACA,IAAA;EACA,aAAA;EACA,cAAA,EAAgB,qBAAA;EAChB,cAAA;EACA,OAAA;IACE,OAAA;IACA,SAAA;EAAA;EAEF,YAAA;IACE,UAAA;EAAA;AAAA;AAAA,KAIQ,8BAAA;EACV,KAAA;EACA,OAAA;EACA,WAAA;EACA,OAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-marketplace-client.service.d.ts","names":[],"sources":["../../src/publish/app-marketplace-client.service.ts"],"mappings":";;;cAGa,2BAAA;EACX,OAAA,GAAiB,MAAA;IACf,OAAA,EAAS,iBAAA;IACT,UAAA;IACA,KAAA;EAAA,MACE,OAAA,CAAQ,gBAAA;EAAA,QAyCJ,gBAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-marketplace-client.service.js","names":[],"sources":["../../src/publish/app-marketplace-client.service.ts"],"sourcesContent":["import type { AppPublishPayload, AppPublishResult } from \"./app-publish.types.js\";\nimport { DEFAULT_APP_MARKETPLACE_API_BASE } from \"./app-publish.types.js\";\n\nexport class AppMarketplaceClientService {\n publish = async (params: {\n payload: AppPublishPayload;\n apiBaseUrl?: string;\n token?: string;\n }): Promise<AppPublishResult> => {\n const apiBaseUrl = this.normalizeApiBase(\n params.apiBaseUrl ?? DEFAULT_APP_MARKETPLACE_API_BASE,\n );\n const token = params.token?.trim();\n if (!token) {\n throw new Error(\"缺少 marketplace publish token。请先登录 NextClaw,或传入 --token。\");\n }\n const response = await fetch(`${apiBaseUrl}/api/v1/apps/publish`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${token}`,\n accept: \"application/json\",\n },\n body: JSON.stringify(params.payload),\n });\n const payload = await response.json().catch(() => null);\n if (!response.ok) {\n const message =\n typeof payload === \"object\" &&\n payload &&\n \"error\" in payload &&\n typeof (payload as { error?: { message?: unknown } }).error?.message === \"string\"\n ? (payload as { error: { message: string } }).error.message\n : `${response.status} ${response.statusText}`;\n throw new Error(`发布 app 失败:${message}`);\n }\n const data =\n typeof payload === \"object\" &&\n payload &&\n \"data\" in payload &&\n typeof (payload as { data?: unknown }).data === \"object\"\n ? (payload as { data: AppPublishResult }).data\n : null;\n if (!data) {\n throw new Error(\"marketplace publish 返回格式无效。\");\n }\n return data;\n };\n\n private normalizeApiBase = (apiBaseUrl: string): string => {\n const normalized = new URL(apiBaseUrl);\n return normalized.toString().replace(/\\/+$/, \"\");\n };\n}\n"],"mappings":";;AAGA,IAAa,8BAAb,MAAyC;CACvC,UAAU,OAAO,WAIgB;EAC/B,MAAM,aAAa,KAAK,iBACtB,OAAO,cAAA,oCACR;EACD,MAAM,QAAQ,OAAO,OAAO,MAAM;AAClC,MAAI,CAAC,MACH,OAAM,IAAI,MAAM,0DAA0D;EAE5E,MAAM,WAAW,MAAM,MAAM,GAAG,WAAW,uBAAuB;GAChE,QAAQ;GACR,SAAS;IACP,gBAAgB;IAChB,eAAe,UAAU;IACzB,QAAQ;IACT;GACD,MAAM,KAAK,UAAU,OAAO,QAAQ;GACrC,CAAC;EACF,MAAM,UAAU,MAAM,SAAS,MAAM,CAAC,YAAY,KAAK;AACvD,MAAI,CAAC,SAAS,IAAI;GAChB,MAAM,UACJ,OAAO,YAAY,YACnB,WACA,WAAW,WACX,OAAQ,QAA8C,OAAO,YAAY,WACpE,QAA2C,MAAM,UAClD,GAAG,SAAS,OAAO,GAAG,SAAS;AACrC,SAAM,IAAI,MAAM,aAAa,UAAU;;EAEzC,MAAM,OACJ,OAAO,YAAY,YACnB,WACA,UAAU,WACV,OAAQ,QAA+B,SAAS,WAC3C,QAAuC,OACxC;AACN,MAAI,CAAC,KACH,OAAM,IAAI,MAAM,8BAA8B;AAEhD,SAAO;;CAGT,oBAA4B,eAA+B;AAEzD,SADmB,IAAI,IAAI,WAAW,CACpB,UAAU,CAAC,QAAQ,QAAQ,GAAG"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-marketplace-metadata.service.d.ts","names":[],"sources":["../../src/publish/app-marketplace-metadata.service.ts"],"mappings":";;;;cAMa,6BAAA;EACX,IAAA,GAAc,MAAA;IACZ,YAAA;IACA,QAAA,EAAU,WAAA;IACV,YAAA;EAAA,MACE,OAAA,CAAQ,sBAAA;EASZ,mBAAA,GAA6B,MAAA;IAC3B,YAAA;IACA,YAAA;EAAA,MACE,OAAA,CAAQ,KAAA;IAAQ,IAAA;IAAc,KAAA,EAAO,MAAA;EAAA;EAAA,QAoBjC,aAAA;EAAA,QA+BA,cAAA;EAAA,QAiBA,kBAAA;EAAA,QAOA,kBAAA;EAAA,QAUA,eAAA;EAAA,QASA,mBAAA;EAAA,QAaA,oBAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-marketplace-metadata.service.js","names":[],"sources":["../../src/publish/app-marketplace-metadata.service.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { AppManifest } from \"../manifest/app-manifest.types.js\";\nimport type { AppMarketplaceMetadata } from \"./app-publish.types.js\";\n\nexport class AppMarketplaceMetadataService {\n load = async (params: {\n appDirectory: string;\n manifest: AppManifest;\n metadataPath?: string;\n }): Promise<AppMarketplaceMetadata> => {\n const { appDirectory, manifest, metadataPath: customMetadataPath } = params;\n const metadataPath = customMetadataPath\n ? path.resolve(customMetadataPath)\n : path.join(path.resolve(appDirectory), \"marketplace.json\");\n const raw = JSON.parse(await readFile(metadataPath, \"utf-8\")) as unknown;\n return this.parseMetadata(raw, manifest);\n };\n\n collectPublishFiles = async (params: {\n appDirectory: string;\n metadataPath?: string;\n }): Promise<Array<{ path: string; bytes: Buffer }>> => {\n const appDirectory = path.resolve(params.appDirectory);\n const publishFiles: Array<{ path: string; bytes: Buffer }> = [];\n const metadataPath = params.metadataPath\n ? path.resolve(params.metadataPath)\n : path.join(appDirectory, \"marketplace.json\");\n publishFiles.push({\n path: \"marketplace.json\",\n bytes: Buffer.from(await readFile(metadataPath)),\n });\n const readmePath = path.join(appDirectory, \"README.md\");\n if (existsSync(readmePath)) {\n publishFiles.push({\n path: \"README.md\",\n bytes: Buffer.from(await readFile(readmePath)),\n });\n }\n return publishFiles;\n };\n\n private parseMetadata = (\n rawMetadata: unknown,\n manifest: AppManifest,\n ): AppMarketplaceMetadata => {\n if (!rawMetadata || typeof rawMetadata !== \"object\" || Array.isArray(rawMetadata)) {\n throw new Error(\"marketplace.json 必须是对象。\");\n }\n const candidate = rawMetadata as Record<string, unknown>;\n const slug = this.readRequiredString(candidate.slug, \"slug\");\n const summary = this.readRequiredString(candidate.summary, \"summary\");\n const description = this.readOptionalString(candidate.description, \"description\");\n const author =\n this.readOptionalString(candidate.author, \"author\") ?? manifest.name;\n const publisher = this.parsePublisher(candidate.publisher);\n return {\n slug,\n summary,\n summaryI18n: this.readLocalizedTextMap(candidate.summaryI18n, \"summaryI18n\", summary),\n description,\n descriptionI18n: description\n ? this.readLocalizedTextMap(candidate.descriptionI18n, \"descriptionI18n\", description)\n : undefined,\n author,\n tags: this.readStringArray(candidate.tags, \"tags\"),\n sourceRepo: this.readOptionalString(candidate.sourceRepo, \"sourceRepo\"),\n homepage: this.readOptionalString(candidate.homepage, \"homepage\"),\n featured: this.readOptionalBoolean(candidate.featured, \"featured\") ?? false,\n publisher,\n };\n };\n\n private parsePublisher = (\n rawPublisher: unknown,\n ): AppMarketplaceMetadata[\"publisher\"] => {\n if (rawPublisher === undefined) {\n return undefined;\n }\n if (!rawPublisher || typeof rawPublisher !== \"object\" || Array.isArray(rawPublisher)) {\n throw new Error(\"publisher 必须是对象。\");\n }\n const candidate = rawPublisher as Record<string, unknown>;\n return {\n id: this.readRequiredString(candidate.id, \"publisher.id\"),\n name: this.readRequiredString(candidate.name, \"publisher.name\"),\n url: this.readOptionalString(candidate.url, \"publisher.url\"),\n };\n };\n\n private readRequiredString = (value: unknown, fieldName: string): string => {\n if (typeof value !== \"string\" || !value.trim()) {\n throw new Error(`${fieldName} 必须是非空字符串。`);\n }\n return value.trim();\n };\n\n private readOptionalString = (\n value: unknown,\n fieldName: string,\n ): string | undefined => {\n if (value === undefined) {\n return undefined;\n }\n return this.readRequiredString(value, fieldName);\n };\n\n private readStringArray = (value: unknown, fieldName: string): string[] => {\n if (!Array.isArray(value) || value.length === 0) {\n throw new Error(`${fieldName} 必须是非空字符串数组。`);\n }\n return value.map((item, index) =>\n this.readRequiredString(item, `${fieldName}[${index}]`),\n );\n };\n\n private readOptionalBoolean = (\n value: unknown,\n fieldName: string,\n ): boolean | undefined => {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value !== \"boolean\") {\n throw new Error(`${fieldName} 必须是布尔值。`);\n }\n return value;\n };\n\n private readLocalizedTextMap = (\n value: unknown,\n fieldName: string,\n fallbackEn: string,\n ): Record<string, string> => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`${fieldName} 必须是对象。`);\n }\n const candidate = value as Record<string, unknown>;\n const normalized = Object.fromEntries(\n Object.entries(candidate).map(([locale, localeValue]) => [\n locale,\n this.readRequiredString(localeValue, `${fieldName}.${locale}`),\n ]),\n );\n if (!normalized.en) {\n normalized.en = fallbackEn;\n }\n return normalized;\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-publish-validation.service.d.ts","names":[],"sources":["../../src/publish/app-publish-validation.service.ts"],"mappings":";;;;;;KAYY,+BAAA;AAAA,KAIA,2BAAA;EACV,IAAA,EAAM,+BAAA;EACN,OAAA;AAAA;AAAA,KAGU,0BAAA;EACV,EAAA;EACA,YAAA;EACA,YAAA;EACA,KAAA;EACA,OAAA;EACA,gBAAA,EAAkB,mBAAA;EAClB,QAAA;EACA,aAAA;EACA,kBAAA;EACA,eAAA;EACA,eAAA;EACA,QAAA,EAAU,2BAAA;AAAA;AAAA,cAGC,2BAAA;EAAA,iBAEQ,eAAA;EAAA,iBACA,eAAA;EAAA,iBACA,aAAA;cAFA,eAAA,GAAiB,kBAAA,EACjB,eAAA,GAAiB,6BAAA,EACjB,aAAA,GAAe,gBAAA;EAGlC,QAAA,GAAkB,MAAA;IAChB,YAAA;IACA,YAAA;IACA,IAAA,GAAO,mBAAA;EAAA,MACL,OAAA,CAAQ,0BAAA;EAAA,QAiDJ,aAAA;EAAA,QAqBA,WAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-publish-validation.service.js","names":[],"sources":["../../src/publish/app-publish-validation.service.ts"],"sourcesContent":["import { stat } from \"node:fs/promises\";\nimport { mkdtemp, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { AppBundleService } from \"../bundle/app-bundle.service.js\";\nimport type { AppDistributionMode } from \"../bundle/app-bundle.types.js\";\nimport { AppManifestService } from \"../manifest/app-manifest.service.js\";\nimport { AppMarketplaceMetadataService } from \"./app-marketplace-metadata.service.js\";\n\nconst MAIN_ENTRY_WARN_BYTES = 10 * 1024 * 1024;\nconst BUNDLE_WARN_BYTES = 5 * 1024 * 1024;\n\nexport type AppPublishValidationWarningCode =\n | \"main-entry-large\"\n | \"bundle-large\";\n\nexport type AppPublishValidationWarning = {\n code: AppPublishValidationWarningCode;\n message: string;\n};\n\nexport type AppPublishValidationResult = {\n ok: boolean;\n appDirectory: string;\n metadataPath: string;\n appId: string;\n version: string;\n distributionMode: AppDistributionMode;\n mainKind: string;\n mainEntryPath: string;\n mainEntrySizeBytes: number;\n bundleSizeBytes: number;\n bundleFilePaths: string[];\n warnings: AppPublishValidationWarning[];\n};\n\nexport class AppPublishValidationService {\n constructor(\n private readonly manifestService: AppManifestService = new AppManifestService(),\n private readonly metadataService: AppMarketplaceMetadataService = new AppMarketplaceMetadataService(),\n private readonly bundleService: AppBundleService = new AppBundleService(),\n ) {}\n\n validate = async (params: {\n appDirectory: string;\n metadataPath?: string;\n mode?: AppDistributionMode;\n }): Promise<AppPublishValidationResult> => {\n const {\n appDirectory: inputAppDirectory,\n metadataPath: inputMetadataPath,\n mode,\n } = params;\n const appDirectory = path.resolve(inputAppDirectory);\n const distributionMode = mode ?? \"source\";\n const bundle = await this.manifestService.load(appDirectory);\n const metadataPath = inputMetadataPath\n ? path.resolve(inputMetadataPath)\n : path.join(appDirectory, \"marketplace.json\");\n await this.metadataService.load({\n appDirectory,\n manifest: bundle.manifest,\n metadataPath,\n });\n\n const tempDirectory = await mkdtemp(path.join(tmpdir(), \"napp-validate-publish-\"));\n try {\n const packResult = await this.bundleService.packAppDirectory({\n appDirectory,\n outputPath: path.join(tempDirectory, `${bundle.manifest.id}-${bundle.manifest.version}.napp`),\n mode: distributionMode,\n });\n const mainEntryStats = await stat(bundle.mainEntryPath);\n const warnings = this.buildWarnings({\n mainEntrySizeBytes: mainEntryStats.size,\n bundleSizeBytes: packResult.sizeBytes,\n });\n return {\n ok: true,\n appDirectory,\n metadataPath,\n appId: bundle.manifest.id,\n version: bundle.manifest.version,\n distributionMode,\n mainKind: bundle.manifest.main.kind,\n mainEntryPath: bundle.mainEntryPath,\n mainEntrySizeBytes: mainEntryStats.size,\n bundleSizeBytes: packResult.sizeBytes,\n bundleFilePaths: packResult.filePaths,\n warnings,\n };\n } finally {\n await rm(tempDirectory, { recursive: true, force: true });\n }\n };\n\n private buildWarnings = (params: {\n mainEntrySizeBytes: number;\n bundleSizeBytes: number;\n }): AppPublishValidationWarning[] => {\n const { bundleSizeBytes, mainEntrySizeBytes } = params;\n const warnings: AppPublishValidationWarning[] = [];\n if (mainEntrySizeBytes > MAIN_ENTRY_WARN_BYTES) {\n warnings.push({\n code: \"main-entry-large\",\n message: `main entry is ${this.formatBytes(mainEntrySizeBytes)}, which is larger than the ${this.formatBytes(MAIN_ENTRY_WARN_BYTES)} warning threshold.`,\n });\n }\n if (bundleSizeBytes > BUNDLE_WARN_BYTES) {\n warnings.push({\n code: \"bundle-large\",\n message: `packed .napp is ${this.formatBytes(bundleSizeBytes)}, which is larger than the ${this.formatBytes(BUNDLE_WARN_BYTES)} warning threshold.`,\n });\n }\n return warnings;\n };\n\n private formatBytes = (value: number): string => {\n if (value < 1024) {\n return `${value} B`;\n }\n if (value < 1024 * 1024) {\n return `${(value / 1024).toFixed(1)} KB`;\n }\n return `${(value / (1024 * 1024)).toFixed(1)} MB`;\n };\n}\n"],"mappings":";;;;;;;AASA,MAAM,wBAAwB,KAAK,OAAO;AAC1C,MAAM,oBAAoB,IAAI,OAAO;AA0BrC,IAAa,8BAAb,MAAyC;CACvC,YACE,kBAAuD,IAAI,oBAAoB,EAC/E,kBAAkE,IAAI,+BAA+B,EACrG,gBAAmD,IAAI,kBAAkB,EACzE;AAHiB,OAAA,kBAAA;AACA,OAAA,kBAAA;AACA,OAAA,gBAAA;;CAGnB,WAAW,OAAO,WAIyB;EACzC,MAAM,EACJ,cAAc,mBACd,cAAc,mBACd,SACE;EACJ,MAAM,eAAe,KAAK,QAAQ,kBAAkB;EACpD,MAAM,mBAAmB,QAAQ;EACjC,MAAM,SAAS,MAAM,KAAK,gBAAgB,KAAK,aAAa;EAC5D,MAAM,eAAe,oBACjB,KAAK,QAAQ,kBAAkB,GAC/B,KAAK,KAAK,cAAc,mBAAmB;AAC/C,QAAM,KAAK,gBAAgB,KAAK;GAC9B;GACA,UAAU,OAAO;GACjB;GACD,CAAC;EAEF,MAAM,gBAAgB,MAAM,QAAQ,KAAK,KAAK,QAAQ,EAAE,yBAAyB,CAAC;AAClF,MAAI;GACF,MAAM,aAAa,MAAM,KAAK,cAAc,iBAAiB;IAC3D;IACA,YAAY,KAAK,KAAK,eAAe,GAAG,OAAO,SAAS,GAAG,GAAG,OAAO,SAAS,QAAQ,OAAO;IAC7F,MAAM;IACP,CAAC;GACF,MAAM,iBAAiB,MAAM,KAAK,OAAO,cAAc;GACvD,MAAM,WAAW,KAAK,cAAc;IAClC,oBAAoB,eAAe;IACnC,iBAAiB,WAAW;IAC7B,CAAC;AACF,UAAO;IACL,IAAI;IACJ;IACA;IACA,OAAO,OAAO,SAAS;IACvB,SAAS,OAAO,SAAS;IACzB;IACA,UAAU,OAAO,SAAS,KAAK;IAC/B,eAAe,OAAO;IACtB,oBAAoB,eAAe;IACnC,iBAAiB,WAAW;IAC5B,iBAAiB,WAAW;IAC5B;IACD;YACO;AACR,SAAM,GAAG,eAAe;IAAE,WAAW;IAAM,OAAO;IAAM,CAAC;;;CAI7D,iBAAyB,WAGY;EACnC,MAAM,EAAE,iBAAiB,uBAAuB;EAChD,MAAM,WAA0C,EAAE;AAClD,MAAI,qBAAqB,sBACvB,UAAS,KAAK;GACZ,MAAM;GACN,SAAS,iBAAiB,KAAK,YAAY,mBAAmB,CAAC,6BAA6B,KAAK,YAAY,sBAAsB,CAAC;GACrI,CAAC;AAEJ,MAAI,kBAAkB,kBACpB,UAAS,KAAK;GACZ,MAAM;GACN,SAAS,mBAAmB,KAAK,YAAY,gBAAgB,CAAC,6BAA6B,KAAK,YAAY,kBAAkB,CAAC;GAChI,CAAC;AAEJ,SAAO;;CAGT,eAAuB,UAA0B;AAC/C,MAAI,QAAQ,KACV,QAAO,GAAG,MAAM;AAElB,MAAI,QAAQ,OAAO,KACjB,QAAO,IAAI,QAAQ,MAAM,QAAQ,EAAE,CAAC;AAEtC,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,EAAE,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-publish.service.d.ts","names":[],"sources":["../../src/publish/app-publish.service.ts"],"mappings":";;;;;;;;;cAkBa,iBAAA;EAAA,iBAEQ,eAAA;EAAA,iBACA,aAAA;EAAA,iBACA,eAAA;EAAA,iBACA,iBAAA;EAAA,iBACA,gBAAA;cAJA,eAAA,GAAiB,kBAAA,EACjB,aAAA,GAAe,gBAAA,EACf,eAAA,GAAiB,6BAAA,EACjB,iBAAA,GAAmB,2BAAA,EACnB,gBAAA,GAAkB,wBAAA;EAGrC,OAAA,GAAiB,MAAA;IACf,YAAA;IACA,YAAA;IACA,UAAA;IACA,KAAA;IACA,IAAA,GAAO,mBAAA;EAAA,MACL,OAAA,CAAQ,gBAAA;EAAA,QAiEJ,mBAAA;EAAA,QA6CA,wBAAA;EAAA,QA6CA,sBAAA;EAAA,QAOA,kBAAA;EAAA,QAkBA,sBAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-publish.service.js","names":[],"sources":["../../src/publish/app-publish.service.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { AppBundleService } from \"../bundle/app-bundle.service.js\";\nimport type { AppDistributionMode } from \"../bundle/app-bundle.types.js\";\nimport { AppManifestService } from \"../manifest/app-manifest.service.js\";\nimport { AppMarketplaceClientService } from \"./app-marketplace-client.service.js\";\nimport { AppMarketplaceMetadataService } from \"./app-marketplace-metadata.service.js\";\nimport type { AppPublishPayload, AppPublishResult } from \"./app-publish.types.js\";\nimport { PlatformAuthStateService } from \"./platform-auth-state.service.js\";\n\nconst DEFAULT_PLATFORM_API_BASE = \"https://ai-gateway-api.nextclaw.io\";\n\ntype ResolvedPublishActor = {\n token: string;\n publisher: NonNullable<AppPublishPayload[\"publisher\"]>;\n};\n\nexport class AppPublishService {\n constructor(\n private readonly manifestService: AppManifestService = new AppManifestService(),\n private readonly bundleService: AppBundleService = new AppBundleService(),\n private readonly metadataService: AppMarketplaceMetadataService = new AppMarketplaceMetadataService(),\n private readonly marketplaceClient: AppMarketplaceClientService = new AppMarketplaceClientService(),\n private readonly authStateService: PlatformAuthStateService = new PlatformAuthStateService(),\n ) {}\n\n publish = async (params: {\n appDirectory: string;\n metadataPath?: string;\n apiBaseUrl?: string;\n token?: string;\n mode?: AppDistributionMode;\n }): Promise<AppPublishResult> => {\n const { appDirectory: inputAppDirectory, metadataPath, apiBaseUrl, token } = params;\n const distributionMode = params.mode ?? \"source\";\n const appDirectory = path.resolve(inputAppDirectory);\n const manifestBundle = await this.manifestService.load(appDirectory);\n const metadata = await this.metadataService.load({\n appDirectory,\n manifest: manifestBundle.manifest,\n metadataPath,\n });\n const actor = await this.resolvePublishActor({\n apiBaseUrl,\n explicitToken: token,\n appId: manifestBundle.manifest.id,\n });\n const bundle = await this.bundleService.packAppDirectory({\n appDirectory,\n mode: distributionMode,\n });\n const bundleBytes = Buffer.from(await readFile(bundle.bundlePath));\n const bundleSha256 = createHash(\"sha256\").update(bundleBytes).digest(\"hex\");\n const publishFiles = await this.metadataService.collectPublishFiles({\n appDirectory,\n metadataPath,\n });\n const payload: AppPublishPayload = {\n slug: metadata.slug,\n appId: manifestBundle.manifest.id,\n name: manifestBundle.manifest.name,\n version: manifestBundle.manifest.version,\n summary: metadata.summary,\n summaryI18n: metadata.summaryI18n,\n description: metadata.description ?? manifestBundle.manifest.description,\n descriptionI18n: metadata.descriptionI18n,\n author: metadata.author,\n tags: metadata.tags,\n sourceRepo: metadata.sourceRepo,\n homepage: metadata.homepage,\n featured: metadata.featured ?? false,\n publisher: actor.publisher,\n distributionMode,\n manifest: manifestBundle.manifest,\n permissions: manifestBundle.manifest.permissions ?? {},\n bundleBase64: bundleBytes.toString(\"base64\"),\n bundleSha256,\n files: publishFiles.map((file) => ({\n path: file.path,\n contentBase64: file.bytes.toString(\"base64\"),\n })),\n };\n const result = await this.marketplaceClient.publish({\n payload,\n apiBaseUrl,\n token: actor.token,\n });\n return {\n ...result,\n distribution: {\n path: bundle.bundlePath,\n sha256: bundleSha256,\n mode: distributionMode,\n },\n };\n };\n\n private resolvePublishActor = async (params: {\n apiBaseUrl?: string;\n explicitToken?: string;\n appId: string;\n }): Promise<ResolvedPublishActor> => {\n const explicitToken = params.explicitToken?.trim();\n const envAdminToken = process.env.NEXTCLAW_MARKETPLACE_ADMIN_TOKEN?.trim();\n if (explicitToken) {\n const token = explicitToken;\n if (!token) {\n throw new Error(\"缺少 publish token。\");\n }\n const me = await this.fetchCurrentPlatformUser({\n token,\n platformApiBase: this.resolvePlatformApiBase(),\n });\n return {\n token,\n publisher: this.buildUserPublisher(me, params.appId),\n };\n }\n\n const authState = this.authStateService.readCurrentAuthState();\n const platformToken = authState.token?.trim();\n if (platformToken) {\n const me = await this.fetchCurrentPlatformUser({\n token: platformToken,\n platformApiBase: this.resolvePlatformApiBase(authState.apiBaseUrl),\n });\n return {\n token: platformToken,\n publisher: this.buildUserPublisher(me, params.appId),\n };\n }\n\n if (envAdminToken) {\n return {\n token: envAdminToken,\n publisher: this.buildOfficialPublisher(),\n };\n }\n\n throw new Error(\"发布需要 NextClaw 平台登录态。请先运行 nextclaw login,或传入 --token。\");\n };\n\n private fetchCurrentPlatformUser = async (params: {\n token: string;\n platformApiBase: string;\n }): Promise<{\n id: string;\n username: string | null;\n role: \"admin\" | \"user\";\n }> => {\n const response = await fetch(`${params.platformApiBase}/platform/auth/me`, {\n headers: {\n authorization: `Bearer ${params.token}`,\n accept: \"application/json\",\n },\n });\n const payload = await response.json().catch(() => null);\n if (!response.ok) {\n const message =\n typeof payload === \"object\" &&\n payload &&\n \"error\" in payload &&\n typeof (payload as { error?: { message?: unknown } }).error?.message === \"string\"\n ? (payload as { error: { message: string } }).error.message\n : `${response.status} ${response.statusText}`;\n throw new Error(`读取 NextClaw 登录态失败:${message}`);\n }\n const user = typeof payload === \"object\" &&\n payload &&\n \"data\" in payload &&\n typeof (payload as { data?: { user?: unknown } }).data?.user === \"object\" &&\n (payload as { data: { user: Record<string, unknown> } }).data.user\n ? (payload as { data: { user: Record<string, unknown> } }).data.user\n : null;\n const id = typeof user?.id === \"string\" ? user.id.trim() : \"\";\n const username = typeof user?.username === \"string\" ? user.username.trim() : \"\";\n const role = user?.role === \"admin\" ? \"admin\" : \"user\";\n if (!id) {\n throw new Error(\"平台登录态缺少用户 id。\");\n }\n return {\n id,\n username: username || null,\n role,\n };\n };\n\n private resolvePlatformApiBase = (configuredApiBase?: string): string => {\n const source = configuredApiBase?.trim() || process.env.NEXTCLAW_PLATFORM_API_BASE?.trim() || DEFAULT_PLATFORM_API_BASE;\n const normalized = new URL(source);\n normalized.pathname = normalized.pathname.replace(/\\/v1\\/?$/, \"/\");\n return normalized.toString().replace(/\\/+$/, \"\");\n };\n\n private buildUserPublisher = (\n user: { id: string; username: string | null; role: \"admin\" | \"user\" },\n appId: string,\n ): NonNullable<AppPublishPayload[\"publisher\"]> => {\n const isOfficialScope = appId.startsWith(\"nextclaw.\");\n if (isOfficialScope && user.role === \"admin\") {\n return this.buildOfficialPublisher();\n }\n if (!user.username) {\n throw new Error(\"当前 NextClaw 账号还没有 username,无法发布个人 scope app。请先在平台账号页设置用户名。\");\n }\n return {\n id: user.username,\n name: user.username,\n url: `https://platform.nextclaw.io/account`,\n };\n };\n\n private buildOfficialPublisher = (): NonNullable<AppPublishPayload[\"publisher\"]> => {\n return {\n id: \"nextclaw\",\n name: \"NextClaw\",\n url: \"https://nextclaw.io\",\n };\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-publish.types.d.ts","names":[],"sources":["../../src/publish/app-publish.types.ts"],"mappings":";;;;;cAIa,gCAAA;AAAA,KAED,sBAAA;EACV,IAAA;EACA,OAAA;EACA,WAAA,EAAa,MAAA;EACb,WAAA;EACA,eAAA,GAAkB,MAAA;EAClB,MAAA;EACA,IAAA;EACA,UAAA;EACA,QAAA;EACA,QAAA;EACA,SAAA,GAAY,YAAA;AAAA;AAAA,KAGF,cAAA;EACV,IAAA;EACA,aAAA;AAAA;AAAA,KAGU,iBAAA;EACV,IAAA;EACA,KAAA;EACA,IAAA;EACA,OAAA;EACA,OAAA;EACA,WAAA,EAAa,MAAA;EACb,WAAA;EACA,eAAA,GAAkB,MAAA;EAClB,MAAA;EACA,IAAA;EACA,UAAA;EACA,QAAA;EACA,QAAA;EACA,SAAA,EAAW,YAAA;EACX,gBAAA,EAAkB,mBAAA;EAClB,QAAA,EAAU,WAAA;EACV,WAAA,EAAa,cAAA;EACb,YAAA;EACA,YAAA;EACA,KAAA,EAAO,cAAA;AAAA;AAAA,KAGG,gBAAA;EACV,OAAA;EACA,IAAA;IACE,IAAA;IACA,KAAA;IACA,IAAA;IACA,aAAA;IACA,MAAA;IACA,OAAA;MACE,IAAA;MACA,IAAA;MACA,OAAA;MACA,QAAA;IAAA;EAAA;EAGJ,YAAA;IACE,IAAA;IACA,MAAA;IACA,IAAA,EAAM,mBAAA;EAAA;EAER,SAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-publish.types.js","names":[],"sources":["../../src/publish/app-publish.types.ts"],"sourcesContent":["import type { AppDistributionMode } from \"../bundle/app-bundle.types.js\";\nimport type { AppManifest, AppPermissions } from \"../manifest/app-manifest.types.js\";\nimport type { AppPublisher } from \"../registry/app-remote-registry.types.js\";\n\nexport const DEFAULT_APP_MARKETPLACE_API_BASE = \"https://apps-registry.nextclaw.io\";\n\nexport type AppMarketplaceMetadata = {\n slug: string;\n summary: string;\n summaryI18n: Record<string, string>;\n description?: string;\n descriptionI18n?: Record<string, string>;\n author: string;\n tags: string[];\n sourceRepo?: string;\n homepage?: string;\n featured?: boolean;\n publisher?: AppPublisher;\n};\n\nexport type AppPublishFile = {\n path: string;\n contentBase64: string;\n};\n\nexport type AppPublishPayload = {\n slug: string;\n appId: string;\n name: string;\n version: string;\n summary: string;\n summaryI18n: Record<string, string>;\n description?: string;\n descriptionI18n?: Record<string, string>;\n author: string;\n tags: string[];\n sourceRepo?: string;\n homepage?: string;\n featured: boolean;\n publisher: AppPublisher;\n distributionMode: AppDistributionMode;\n manifest: AppManifest;\n permissions: AppPermissions;\n bundleBase64: string;\n bundleSha256: string;\n files: AppPublishFile[];\n};\n\nexport type AppPublishResult = {\n created: boolean;\n item: {\n slug: string;\n appId: string;\n name: string;\n latestVersion: string;\n webUrl?: string;\n install: {\n kind: \"registry\";\n spec: string;\n command: string;\n registry: string;\n };\n };\n distribution: {\n path: string;\n sha256: string;\n mode: AppDistributionMode;\n };\n fileCount: number;\n};\n"],"mappings":";AAIA,MAAa,mCAAmC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"platform-auth-state.service.d.ts","names":[],"sources":["../../src/publish/platform-auth-state.service.ts"],"mappings":";KAWY,wBAAA;EACV,KAAA;EACA,UAAA;AAAA;AAAA,cAMW,wBAAA;EACX,oBAAA,QAA2B,wBAAA;EAAA,QA4BnB,iBAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"platform-auth-state.service.js","names":[],"sources":["../../src/publish/platform-auth-state.service.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { homedir } from \"node:os\";\n\ntype NextclawConfig = {\n providers?: Record<string, {\n apiKey?: string;\n apiBase?: string | null;\n } | undefined>;\n};\n\nexport type PlatformPublishAuthState = {\n token: string | null;\n apiBaseUrl?: string;\n};\n\nconst NEXTCLAW_HOME_ENV_KEY = \"NEXTCLAW_HOME\";\nconst NEXTCLAW_DEFAULT_HOME_DIR = \".nextclaw\";\n\nexport class PlatformAuthStateService {\n readCurrentAuthState = (): PlatformPublishAuthState => {\n const configPath = this.resolveConfigPath();\n if (!existsSync(configPath)) {\n return {\n token: null,\n };\n }\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw) as NextclawConfig;\n const provider = parsed.providers?.nextclaw;\n const token = typeof provider?.apiKey === \"string\" && provider.apiKey.trim().length > 0\n ? provider.apiKey.trim()\n : null;\n const apiBase = typeof provider?.apiBase === \"string\" && provider.apiBase.trim().length > 0\n ? provider.apiBase.trim()\n : undefined;\n return {\n token,\n apiBaseUrl: apiBase,\n };\n } catch {\n return {\n token: null,\n };\n }\n };\n\n private resolveConfigPath = (): string => {\n const nextclawHome = process.env[NEXTCLAW_HOME_ENV_KEY]?.trim();\n const dataHome = nextclawHome && nextclawHome.length > 0\n ? resolve(nextclawHome)\n : resolve(homedir(), NEXTCLAW_DEFAULT_HOME_DIR);\n return resolve(dataHome, \"config.json\");\n };\n}\n"],"mappings":";;;;AAgBA,MAAM,wBAAwB;AAC9B,MAAM,4BAA4B;AAElC,IAAa,2BAAb,MAAsC;CACpC,6BAAuD;EACrD,MAAM,aAAa,KAAK,mBAAmB;AAC3C,MAAI,CAAC,WAAW,WAAW,CACzB,QAAO,EACL,OAAO,MACR;AAEH,MAAI;GACF,MAAM,MAAM,aAAa,YAAY,QAAQ;GAE7C,MAAM,WADS,KAAK,MAAM,IAAI,CACN,WAAW;AAOnC,UAAO;IACL,OAPY,OAAO,UAAU,WAAW,YAAY,SAAS,OAAO,MAAM,CAAC,SAAS,IAClF,SAAS,OAAO,MAAM,GACtB;IAMF,YALc,OAAO,UAAU,YAAY,YAAY,SAAS,QAAQ,MAAM,CAAC,SAAS,IACtF,SAAS,QAAQ,MAAM,GACvB,KAAA;IAIH;UACK;AACN,UAAO,EACL,OAAO,MACR;;;CAIL,0BAA0C;EACxC,MAAM,eAAe,QAAQ,IAAI,wBAAwB,MAAM;AAI/D,SAAO,QAHU,gBAAgB,aAAa,SAAS,IACnD,QAAQ,aAAa,GACrB,QAAQ,SAAS,EAAE,0BAA0B,EACxB,cAAc"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-registry-config.service.js","names":[],"sources":["../../src/registry/app-registry-config.service.ts"],"sourcesContent":["import { readFile, rm, writeFile } from \"node:fs/promises\";\nimport { AppHomeService } from \"../paths/app-home.service.js\";\nimport {\n DEFAULT_APP_REGISTRY_URL,\n type AppRegistryConfig,\n type AppRegistryConfigSnapshot,\n} from \"./app-remote-registry.types.js\";\n\nexport class AppRegistryConfigService {\n constructor(\n private readonly appHomeService: AppHomeService = new AppHomeService(),\n ) {}\n\n getSnapshot = async (): Promise<AppRegistryConfigSnapshot> => {\n const envUrl = process.env.NEXTCLAW_APP_REGISTRY?.trim();\n if (envUrl) {\n return {\n defaultUrl: DEFAULT_APP_REGISTRY_URL,\n currentUrl: this.normalizeRegistryUrl(envUrl),\n source: \"env\",\n };\n }\n const config = await this.loadOptionalConfig();\n if (config) {\n return {\n defaultUrl: DEFAULT_APP_REGISTRY_URL,\n currentUrl: this.normalizeRegistryUrl(config.registry.url),\n source: \"config\",\n };\n }\n return {\n defaultUrl: DEFAULT_APP_REGISTRY_URL,\n currentUrl: DEFAULT_APP_REGISTRY_URL,\n source: \"default\",\n };\n };\n\n setRegistryUrl = async (registryUrl: string): Promise<AppRegistryConfigSnapshot> => {\n const normalized = this.normalizeRegistryUrl(registryUrl);\n await this.appHomeService.ensureBaseDirectories();\n await writeFile(\n this.appHomeService.getConfigPath(),\n `${JSON.stringify(\n {\n schemaVersion: 1,\n registry: {\n url: normalized,\n },\n } satisfies AppRegistryConfig,\n null,\n 2,\n )}\\n`,\n \"utf-8\",\n );\n return {\n defaultUrl: DEFAULT_APP_REGISTRY_URL,\n currentUrl: normalized,\n source: \"config\",\n };\n };\n\n resetRegistryUrl = async (): Promise<AppRegistryConfigSnapshot> => {\n await rm(this.appHomeService.getConfigPath(), { force: true });\n return {\n defaultUrl: DEFAULT_APP_REGISTRY_URL,\n currentUrl: DEFAULT_APP_REGISTRY_URL,\n source: \"default\",\n };\n };\n\n private loadOptionalConfig = async (): Promise<AppRegistryConfig | undefined> => {\n try {\n const raw = await readFile(this.appHomeService.getConfigPath(), \"utf-8\");\n return this.parseConfig(JSON.parse(raw) as unknown);\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n };\n\n private parseConfig = (rawConfig: unknown): AppRegistryConfig => {\n if (!rawConfig || typeof rawConfig !== \"object\" || Array.isArray(rawConfig)) {\n throw new Error(\"config.json 必须是对象。\");\n }\n const candidate = rawConfig as Record<string, unknown>;\n if (candidate.schemaVersion !== 1) {\n throw new Error(\"当前只支持 config schemaVersion = 1。\");\n }\n const registry = candidate.registry;\n if (!registry || typeof registry !== \"object\" || Array.isArray(registry)) {\n throw new Error(\"config.registry 必须是对象。\");\n }\n const registryUrl = (registry as Record<string, unknown>).url;\n if (typeof registryUrl !== \"string\" || !registryUrl.trim()) {\n throw new Error(\"config.registry.url 必须是非空字符串。\");\n }\n return {\n schemaVersion: 1,\n registry: {\n url: this.normalizeRegistryUrl(registryUrl),\n },\n };\n };\n\n private normalizeRegistryUrl = (registryUrl: string): string => {\n let normalized: URL;\n try {\n normalized = new URL(registryUrl);\n } catch {\n throw new Error(`非法 registry URL:${registryUrl}`);\n }\n if (normalized.protocol !== \"http:\" && normalized.protocol !== \"https:\") {\n throw new Error(`registry URL 只支持 http/https:${registryUrl}`);\n }\n const text = normalized.toString();\n return text.endsWith(\"/\") ? text : `${text}/`;\n };\n}\n"],"mappings":";;;;AAQA,IAAa,2BAAb,MAAsC;CACpC,YACE,iBAAkD,IAAI,gBAAgB,EACtE;AADiB,OAAA,iBAAA;;CAGnB,cAAc,YAAgD;EAC5D,MAAM,SAAS,QAAQ,IAAI,uBAAuB,MAAM;AACxD,MAAI,OACF,QAAO;GACL,YAAY;GACZ,YAAY,KAAK,qBAAqB,OAAO;GAC7C,QAAQ;GACT;EAEH,MAAM,SAAS,MAAM,KAAK,oBAAoB;AAC9C,MAAI,OACF,QAAO;GACL,YAAY;GACZ,YAAY,KAAK,qBAAqB,OAAO,SAAS,IAAI;GAC1D,QAAQ;GACT;AAEH,SAAO;GACL,YAAY;GACZ,YAAY;GACZ,QAAQ;GACT;;CAGH,iBAAiB,OAAO,gBAA4D;EAClF,MAAM,aAAa,KAAK,qBAAqB,YAAY;AACzD,QAAM,KAAK,eAAe,uBAAuB;AACjD,QAAM,UACJ,KAAK,eAAe,eAAe,EACnC,GAAG,KAAK,UACN;GACE,eAAe;GACf,UAAU,EACR,KAAK,YACN;GACF,EACD,MACA,EACD,CAAC,KACF,QACD;AACD,SAAO;GACL,YAAY;GACZ,YAAY;GACZ,QAAQ;GACT;;CAGH,mBAAmB,YAAgD;AACjE,QAAM,GAAG,KAAK,eAAe,eAAe,EAAE,EAAE,OAAO,MAAM,CAAC;AAC9D,SAAO;GACL,YAAY;GACZ,YAAY;GACZ,QAAQ;GACT;;CAGH,qBAA6B,YAAoD;AAC/E,MAAI;GACF,MAAM,MAAM,MAAM,SAAS,KAAK,eAAe,eAAe,EAAE,QAAQ;AACxE,UAAO,KAAK,YAAY,KAAK,MAAM,IAAI,CAAY;WAC5C,OAAO;AACd,OACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,SAEf;AAEF,SAAM;;;CAIV,eAAuB,cAA0C;AAC/D,MAAI,CAAC,aAAa,OAAO,cAAc,YAAY,MAAM,QAAQ,UAAU,CACzE,OAAM,IAAI,MAAM,qBAAqB;EAEvC,MAAM,YAAY;AAClB,MAAI,UAAU,kBAAkB,EAC9B,OAAM,IAAI,MAAM,kCAAkC;EAEpD,MAAM,WAAW,UAAU;AAC3B,MAAI,CAAC,YAAY,OAAO,aAAa,YAAY,MAAM,QAAQ,SAAS,CACtE,OAAM,IAAI,MAAM,yBAAyB;EAE3C,MAAM,cAAe,SAAqC;AAC1D,MAAI,OAAO,gBAAgB,YAAY,CAAC,YAAY,MAAM,CACxD,OAAM,IAAI,MAAM,gCAAgC;AAElD,SAAO;GACL,eAAe;GACf,UAAU,EACR,KAAK,KAAK,qBAAqB,YAAY,EAC5C;GACF;;CAGH,wBAAgC,gBAAgC;EAC9D,IAAI;AACJ,MAAI;AACF,gBAAa,IAAI,IAAI,YAAY;UAC3B;AACN,SAAM,IAAI,MAAM,mBAAmB,cAAc;;AAEnD,MAAI,WAAW,aAAa,WAAW,WAAW,aAAa,SAC7D,OAAM,IAAI,MAAM,+BAA+B,cAAc;EAE/D,MAAM,OAAO,WAAW,UAAU;AAClC,SAAO,KAAK,SAAS,IAAI,GAAG,OAAO,GAAG,KAAK"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-registry.service.d.ts","names":[],"sources":["../../src/registry/app-registry.service.ts"],"mappings":";;;;;;cAWa,kBAAA;EAAA,iBACkB,cAAA;cAAA,cAAA,GAAgB,cAAA;EAE7C,IAAA,QAAiB,OAAA,CAAQ,WAAA;EAsBzB,IAAA,GAAc,QAAA,EAAU,WAAA,KAAc,OAAA;EAStC,QAAA,QAAqB,OAAA,CAAQ,oBAAA;EAK7B,MAAA,GAAgB,KAAA,aAAgB,OAAA,CAAQ,oBAAA;EAKxC,gBAAA,GACE,KAAA,aACC,OAAA,CAAQ,2BAAA;EAQX,kBAAA,GAA4B,MAAA;IAC1B,KAAA;IACA,IAAA;IACA,WAAA;IACA,OAAA;IACA,gBAAA;IACA,aAAA;IACA,UAAA,EAAY,oBAAA;IACZ,SAAA;IACA,WAAA;IACA,gBAAA,GAAmB,2BAAA;IACnB,WAAA,EAAa,cAAA;IACb,WAAA;IACA,SAAA;IACA,MAAA;IACA,SAAA,GAAY,2BAAA;EAAA,MACV,OAAA,CAAQ,oBAAA;EAiDZ,YAAA,GACE,KAAA,UACA,MAAA,EAAQ,mBAAA,KACP,OAAA,CAAQ,oBAAA;EAeX,gBAAA,GACE,KAAA,UACA,OAAA,UACA,aAAA,aACC,OAAA,CAAQ,oBAAA;EAMX,mBAAA,GACE,KAAA,UACA,OAAA,aACC,OAAA;EAeH,SAAA,GAAmB,KAAA,aAAgB,OAAA,CAAQ,oBAAA;EAAA,QAWnC,aAAA;AAAA"}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { AppHomeService } from "../paths/app-home.service.js";
|
|
2
|
-
import { readFile, writeFile } from "node:fs/promises";
|
|
3
|
-
//#region src/registry/app-registry.service.ts
|
|
4
|
-
var AppRegistryService = class {
|
|
5
|
-
constructor(appHomeService = new AppHomeService()) {
|
|
6
|
-
this.appHomeService = appHomeService;
|
|
7
|
-
}
|
|
8
|
-
load = async () => {
|
|
9
|
-
await this.appHomeService.ensureBaseDirectories();
|
|
10
|
-
const registryPath = this.appHomeService.getRegistryPath();
|
|
11
|
-
try {
|
|
12
|
-
const raw = await readFile(registryPath, "utf-8");
|
|
13
|
-
return this.parseRegistry(JSON.parse(raw));
|
|
14
|
-
} catch (error) {
|
|
15
|
-
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") return {
|
|
16
|
-
schemaVersion: 1,
|
|
17
|
-
apps: {}
|
|
18
|
-
};
|
|
19
|
-
throw error;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
save = async (registry) => {
|
|
23
|
-
await this.appHomeService.ensureBaseDirectories();
|
|
24
|
-
await writeFile(this.appHomeService.getRegistryPath(), `${JSON.stringify(registry, null, 2)}\n`, "utf-8");
|
|
25
|
-
};
|
|
26
|
-
listApps = async () => {
|
|
27
|
-
const registry = await this.load();
|
|
28
|
-
return Object.values(registry.apps).sort((left, right) => left.appId.localeCompare(right.appId));
|
|
29
|
-
};
|
|
30
|
-
getApp = async (appId) => {
|
|
31
|
-
return (await this.load()).apps[appId];
|
|
32
|
-
};
|
|
33
|
-
getActiveVersion = async (appId) => {
|
|
34
|
-
const appRecord = await this.getApp(appId);
|
|
35
|
-
if (!appRecord) return;
|
|
36
|
-
return appRecord.installedVersions[appRecord.activeVersion];
|
|
37
|
-
};
|
|
38
|
-
upsertInstallation = async (params) => {
|
|
39
|
-
const { appId, name, description, version, installDirectory, dataDirectory, sourceKind, sourceRef, installedAt, distributionMode, permissions, registryUrl, bundleUrl, sha256, publisher } = params;
|
|
40
|
-
const registry = await this.load();
|
|
41
|
-
const currentRecord = registry.apps[appId];
|
|
42
|
-
const nextRecord = {
|
|
43
|
-
appId,
|
|
44
|
-
name,
|
|
45
|
-
description,
|
|
46
|
-
activeVersion: version,
|
|
47
|
-
dataDirectory,
|
|
48
|
-
installedVersions: {
|
|
49
|
-
...currentRecord?.installedVersions ?? {},
|
|
50
|
-
[version]: {
|
|
51
|
-
version,
|
|
52
|
-
installDirectory,
|
|
53
|
-
sourceKind,
|
|
54
|
-
sourceRef,
|
|
55
|
-
installedAt,
|
|
56
|
-
distributionMode,
|
|
57
|
-
permissions,
|
|
58
|
-
registryUrl,
|
|
59
|
-
bundleUrl,
|
|
60
|
-
sha256,
|
|
61
|
-
publisher
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
grants: currentRecord?.grants ?? {}
|
|
65
|
-
};
|
|
66
|
-
registry.apps[appId] = nextRecord;
|
|
67
|
-
await this.save(registry);
|
|
68
|
-
return nextRecord;
|
|
69
|
-
};
|
|
70
|
-
updateGrants = async (appId, grants) => {
|
|
71
|
-
const registry = await this.load();
|
|
72
|
-
const appRecord = registry.apps[appId];
|
|
73
|
-
if (!appRecord) throw new Error(`未找到已安装应用:${appId}`);
|
|
74
|
-
appRecord.grants = {
|
|
75
|
-
...appRecord.grants,
|
|
76
|
-
...grants
|
|
77
|
-
};
|
|
78
|
-
registry.apps[appId] = appRecord;
|
|
79
|
-
await this.save(registry);
|
|
80
|
-
return appRecord;
|
|
81
|
-
};
|
|
82
|
-
setDocumentGrant = async (appId, scopeId, directoryPath) => {
|
|
83
|
-
return this.updateGrants(appId, { [scopeId]: directoryPath });
|
|
84
|
-
};
|
|
85
|
-
removeDocumentGrant = async (appId, scopeId) => {
|
|
86
|
-
const registry = await this.load();
|
|
87
|
-
const appRecord = registry.apps[appId];
|
|
88
|
-
if (!appRecord) throw new Error(`未找到已安装应用:${appId}`);
|
|
89
|
-
if (!(scopeId in appRecord.grants)) return false;
|
|
90
|
-
delete appRecord.grants[scopeId];
|
|
91
|
-
registry.apps[appId] = appRecord;
|
|
92
|
-
await this.save(registry);
|
|
93
|
-
return true;
|
|
94
|
-
};
|
|
95
|
-
removeApp = async (appId) => {
|
|
96
|
-
const registry = await this.load();
|
|
97
|
-
const appRecord = registry.apps[appId];
|
|
98
|
-
if (!appRecord) return;
|
|
99
|
-
delete registry.apps[appId];
|
|
100
|
-
await this.save(registry);
|
|
101
|
-
return appRecord;
|
|
102
|
-
};
|
|
103
|
-
parseRegistry = (rawRegistry) => {
|
|
104
|
-
if (!rawRegistry || typeof rawRegistry !== "object" || Array.isArray(rawRegistry)) throw new Error("registry.json 必须是对象。");
|
|
105
|
-
const candidate = rawRegistry;
|
|
106
|
-
if (candidate.schemaVersion !== 1) throw new Error("当前只支持 registry schemaVersion = 1。");
|
|
107
|
-
const apps = candidate.apps;
|
|
108
|
-
if (!apps || typeof apps !== "object" || Array.isArray(apps)) throw new Error("registry.apps 必须是对象。");
|
|
109
|
-
return {
|
|
110
|
-
schemaVersion: 1,
|
|
111
|
-
apps
|
|
112
|
-
};
|
|
113
|
-
};
|
|
114
|
-
};
|
|
115
|
-
//#endregion
|
|
116
|
-
export { AppRegistryService };
|
|
117
|
-
|
|
118
|
-
//# sourceMappingURL=app-registry.service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-registry.service.js","names":[],"sources":["../../src/registry/app-registry.service.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport type { AppPermissions } from \"../manifest/app-manifest.types.js\";\nimport type { AppDocumentGrantMap } from \"../permissions/app-permissions.types.js\";\nimport { AppHomeService } from \"../paths/app-home.service.js\";\nimport type {\n AppInstallSourceKind,\n AppRegistry,\n AppRegistryAppRecord,\n AppRegistryInstalledVersion,\n} from \"./app-registry.types.js\";\n\nexport class AppRegistryService {\n constructor(private readonly appHomeService: AppHomeService = new AppHomeService()) {}\n\n load = async (): Promise<AppRegistry> => {\n await this.appHomeService.ensureBaseDirectories();\n const registryPath = this.appHomeService.getRegistryPath();\n try {\n const raw = await readFile(registryPath, \"utf-8\");\n return this.parseRegistry(JSON.parse(raw) as unknown);\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return {\n schemaVersion: 1,\n apps: {},\n };\n }\n throw error;\n }\n };\n\n save = async (registry: AppRegistry): Promise<void> => {\n await this.appHomeService.ensureBaseDirectories();\n await writeFile(\n this.appHomeService.getRegistryPath(),\n `${JSON.stringify(registry, null, 2)}\\n`,\n \"utf-8\",\n );\n };\n\n listApps = async (): Promise<AppRegistryAppRecord[]> => {\n const registry = await this.load();\n return Object.values(registry.apps).sort((left, right) => left.appId.localeCompare(right.appId));\n };\n\n getApp = async (appId: string): Promise<AppRegistryAppRecord | undefined> => {\n const registry = await this.load();\n return registry.apps[appId];\n };\n\n getActiveVersion = async (\n appId: string,\n ): Promise<AppRegistryInstalledVersion | undefined> => {\n const appRecord = await this.getApp(appId);\n if (!appRecord) {\n return undefined;\n }\n return appRecord.installedVersions[appRecord.activeVersion];\n };\n\n upsertInstallation = async (params: {\n appId: string;\n name: string;\n description?: string;\n version: string;\n installDirectory: string;\n dataDirectory: string;\n sourceKind: AppInstallSourceKind;\n sourceRef: string;\n installedAt: string;\n distributionMode?: AppRegistryInstalledVersion[\"distributionMode\"];\n permissions: AppPermissions;\n registryUrl?: string;\n bundleUrl?: string;\n sha256?: string;\n publisher?: AppRegistryInstalledVersion[\"publisher\"];\n }): Promise<AppRegistryAppRecord> => {\n const {\n appId,\n name,\n description,\n version,\n installDirectory,\n dataDirectory,\n sourceKind,\n sourceRef,\n installedAt,\n distributionMode,\n permissions,\n registryUrl,\n bundleUrl,\n sha256,\n publisher,\n } = params;\n const registry = await this.load();\n const currentRecord = registry.apps[appId];\n const nextRecord: AppRegistryAppRecord = {\n appId,\n name,\n description,\n activeVersion: version,\n dataDirectory,\n installedVersions: {\n ...(currentRecord?.installedVersions ?? {}),\n [version]: {\n version,\n installDirectory,\n sourceKind,\n sourceRef,\n installedAt,\n distributionMode,\n permissions,\n registryUrl,\n bundleUrl,\n sha256,\n publisher,\n },\n },\n grants: currentRecord?.grants ?? {},\n };\n registry.apps[appId] = nextRecord;\n await this.save(registry);\n return nextRecord;\n };\n\n updateGrants = async (\n appId: string,\n grants: AppDocumentGrantMap,\n ): Promise<AppRegistryAppRecord> => {\n const registry = await this.load();\n const appRecord = registry.apps[appId];\n if (!appRecord) {\n throw new Error(`未找到已安装应用:${appId}`);\n }\n appRecord.grants = {\n ...appRecord.grants,\n ...grants,\n };\n registry.apps[appId] = appRecord;\n await this.save(registry);\n return appRecord;\n };\n\n setDocumentGrant = async (\n appId: string,\n scopeId: string,\n directoryPath: string,\n ): Promise<AppRegistryAppRecord> => {\n return this.updateGrants(appId, {\n [scopeId]: directoryPath,\n });\n };\n\n removeDocumentGrant = async (\n appId: string,\n scopeId: string,\n ): Promise<boolean> => {\n const registry = await this.load();\n const appRecord = registry.apps[appId];\n if (!appRecord) {\n throw new Error(`未找到已安装应用:${appId}`);\n }\n if (!(scopeId in appRecord.grants)) {\n return false;\n }\n delete appRecord.grants[scopeId];\n registry.apps[appId] = appRecord;\n await this.save(registry);\n return true;\n };\n\n removeApp = async (appId: string): Promise<AppRegistryAppRecord | undefined> => {\n const registry = await this.load();\n const appRecord = registry.apps[appId];\n if (!appRecord) {\n return undefined;\n }\n delete registry.apps[appId];\n await this.save(registry);\n return appRecord;\n };\n\n private parseRegistry = (rawRegistry: unknown): AppRegistry => {\n if (!rawRegistry || typeof rawRegistry !== \"object\" || Array.isArray(rawRegistry)) {\n throw new Error(\"registry.json 必须是对象。\");\n }\n const candidate = rawRegistry as Record<string, unknown>;\n if (candidate.schemaVersion !== 1) {\n throw new Error(\"当前只支持 registry schemaVersion = 1。\");\n }\n const apps = candidate.apps;\n if (!apps || typeof apps !== \"object\" || Array.isArray(apps)) {\n throw new Error(\"registry.apps 必须是对象。\");\n }\n return {\n schemaVersion: 1,\n apps: apps as Record<string, AppRegistryAppRecord>,\n };\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-registry.types.d.ts","names":[],"sources":["../../src/registry/app-registry.types.ts"],"mappings":";;;;;;KAKY,oBAAA;AAAA,KAEA,2BAAA;EACV,OAAA;EACA,gBAAA;EACA,UAAA,EAAY,oBAAA;EACZ,SAAA;EACA,WAAA;EACA,gBAAA,GAAmB,mBAAA;EACnB,WAAA,EAAa,cAAA;EACb,WAAA;EACA,SAAA;EACA,MAAA;EACA,SAAA,GAAY,YAAA;AAAA;AAAA,KAGF,oBAAA;EACV,KAAA;EACA,IAAA;EACA,WAAA;EACA,aAAA;EACA,aAAA;EACA,iBAAA,EAAmB,MAAA,SAAe,2BAAA;EAClC,MAAA,EAAQ,mBAAA;AAAA;AAAA,KAGE,WAAA;EACV,aAAA;EACA,IAAA,EAAM,MAAA,SAAe,oBAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-remote-registry-client.service.d.ts","names":[],"sources":["../../src/registry/app-remote-registry-client.service.ts"],"mappings":";;;;cAUa,8BAAA;EAAA,iBAEQ,aAAA;cAAA,aAAA,GAAe,wBAAA;EAGlC,OAAA,GAAiB,MAAA;IACf,KAAA;IACA,OAAA;IACA,WAAA;EAAA,MACE,OAAA,CAAQ,2BAAA;EAqCZ,cAAA,GAAwB,MAAA;IACtB,UAAA,EAAY,2BAAA;IACZ,eAAA;EAAA,MACE,OAAA;IACF,UAAA;EAAA;EAAA,QA0BM,aAAA;EAAA,QAsCA,YAAA;EAAA,QAwDA,cAAA;EAAA,QAkBA,kBAAA;EAAA,QAOA,kBAAA;EAAA,QAUA,uBAAA;EAAA,QAIA,oBAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-remote-registry-client.service.js","names":[],"sources":["../../src/registry/app-remote-registry-client.service.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { AppRegistryConfigService } from \"./app-registry-config.service.js\";\nimport type {\n AppRemoteRegistryDocument,\n AppRemoteRegistryResolution,\n AppRemoteRegistryVersion,\n} from \"./app-remote-registry.types.js\";\n\nexport class AppRemoteRegistryClientService {\n constructor(\n private readonly configService: AppRegistryConfigService = new AppRegistryConfigService(),\n ) {}\n\n resolve = async (params: {\n appId: string;\n version?: string;\n registryUrl?: string;\n }): Promise<AppRemoteRegistryResolution> => {\n const { appId, version: requestedVersion, registryUrl: overrideRegistryUrl } = params;\n const registryUrl = overrideRegistryUrl\n ? this.normalizeRegistryUrl(overrideRegistryUrl)\n : (await this.configService.getSnapshot()).currentUrl;\n const metadataUrl = new URL(encodeURIComponent(appId), registryUrl).toString();\n const response = await fetch(metadataUrl);\n if (!response.ok) {\n throw new Error(\n `无法从 registry 拉取 ${appId} metadata:${response.status} ${response.statusText}`,\n );\n }\n const document = this.parseDocument(await response.json(), appId);\n const version = requestedVersion ?? document[\"dist-tags\"].latest;\n const versionRecord = document.versions[version];\n if (!versionRecord) {\n throw new Error(`registry ${registryUrl} 未提供 ${appId}@${version}。`);\n }\n return {\n registryUrl,\n metadataUrl,\n appId,\n version,\n description: versionRecord.description ?? document.description,\n publisher: versionRecord.publisher,\n permissions: versionRecord.permissions,\n distributionMode: versionRecord.dist.kind === \"source\" ? \"source\" : \"bundle\",\n bundleUrl: new URL(\n versionRecord.dist.artifact ??\n versionRecord.dist.source ??\n versionRecord.dist.bundle,\n metadataUrl,\n ).toString(),\n sha256: versionRecord.dist.sha256,\n };\n };\n\n downloadBundle = async (params: {\n resolution: AppRemoteRegistryResolution;\n targetDirectory: string;\n }): Promise<{\n bundlePath: string;\n }> => {\n const { resolution, targetDirectory } = params;\n const response = await fetch(resolution.bundleUrl);\n if (!response.ok) {\n throw new Error(\n `无法下载 bundle:${resolution.bundleUrl} (${response.status} ${response.statusText})`,\n );\n }\n const bundleBytes = Buffer.from(await response.arrayBuffer());\n const actualSha256 = createHash(\"sha256\").update(bundleBytes).digest(\"hex\");\n if (actualSha256 !== resolution.sha256) {\n throw new Error(\n `bundle checksum 校验失败:期望 ${resolution.sha256},实际 ${actualSha256}`,\n );\n }\n const bundlePath = path.join(\n targetDirectory,\n `${this.normalizeBundleFileName(resolution.appId)}-${resolution.version}.napp`,\n );\n await writeFile(bundlePath, bundleBytes);\n return {\n bundlePath,\n };\n };\n\n private parseDocument = (\n rawDocument: unknown,\n appId: string,\n ): AppRemoteRegistryDocument => {\n if (!rawDocument || typeof rawDocument !== \"object\" || Array.isArray(rawDocument)) {\n throw new Error(`registry ${appId} metadata 必须是对象。`);\n }\n const candidate = rawDocument as Record<string, unknown>;\n const name = this.readRequiredString(candidate.name, \"name\");\n if (name !== appId) {\n throw new Error(`registry 返回的包名与请求不一致:请求 ${appId},收到 ${name}`);\n }\n const distTags = candidate[\"dist-tags\"];\n if (!distTags || typeof distTags !== \"object\" || Array.isArray(distTags)) {\n throw new Error(\"registry metadata 缺少 dist-tags。\");\n }\n const versions = candidate.versions;\n if (!versions || typeof versions !== \"object\" || Array.isArray(versions)) {\n throw new Error(\"registry metadata 缺少 versions。\");\n }\n return {\n name,\n description: this.readOptionalString(candidate.description, \"description\"),\n \"dist-tags\": {\n latest: this.readRequiredString(\n (distTags as Record<string, unknown>).latest,\n \"dist-tags.latest\",\n ),\n },\n versions: Object.fromEntries(\n Object.entries(versions).map(([version, rawVersion]) => [\n version,\n this.parseVersion(rawVersion, name, version),\n ]),\n ),\n };\n };\n\n private parseVersion = (\n rawVersion: unknown,\n appId: string,\n version: string,\n ): AppRemoteRegistryVersion => {\n if (!rawVersion || typeof rawVersion !== \"object\" || Array.isArray(rawVersion)) {\n throw new Error(`registry metadata 的 versions.${version} 必须是对象。`);\n }\n const candidate = rawVersion as Record<string, unknown>;\n const name = this.readRequiredString(candidate.name, `versions.${version}.name`);\n const parsedVersion = this.readRequiredString(\n candidate.version,\n `versions.${version}.version`,\n );\n if (name !== appId || parsedVersion !== version) {\n throw new Error(`registry metadata 的 versions.${version} 与 app id/version 不一致。`);\n }\n const dist = candidate.dist;\n if (!dist || typeof dist !== \"object\" || Array.isArray(dist)) {\n throw new Error(`registry metadata 的 versions.${version}.dist 必须是对象。`);\n }\n const distCandidate = dist as Record<string, unknown>;\n return {\n name,\n version: parsedVersion,\n description: this.readOptionalString(\n candidate.description,\n `versions.${version}.description`,\n ),\n publisher: this.parsePublisher(candidate.publisher, version),\n permissions: candidate.permissions as AppRemoteRegistryVersion[\"permissions\"],\n dist: {\n kind:\n distCandidate.kind === \"source\" || distCandidate.kind === \"bundle\"\n ? distCandidate.kind\n : undefined,\n artifact: this.readOptionalString(\n distCandidate.artifact,\n `versions.${version}.dist.artifact`,\n ),\n bundle: this.readRequiredString(\n distCandidate.bundle,\n `versions.${version}.dist.bundle`,\n ),\n source: this.readOptionalString(\n distCandidate.source,\n `versions.${version}.dist.source`,\n ),\n sha256: this.readRequiredString(\n distCandidate.sha256,\n `versions.${version}.dist.sha256`,\n ),\n },\n };\n };\n\n private parsePublisher = (\n rawPublisher: unknown,\n version: string,\n ): AppRemoteRegistryVersion[\"publisher\"] => {\n if (rawPublisher === undefined) {\n return undefined;\n }\n if (!rawPublisher || typeof rawPublisher !== \"object\" || Array.isArray(rawPublisher)) {\n throw new Error(`versions.${version}.publisher 必须是对象。`);\n }\n const candidate = rawPublisher as Record<string, unknown>;\n return {\n id: this.readRequiredString(candidate.id, `versions.${version}.publisher.id`),\n name: this.readRequiredString(candidate.name, `versions.${version}.publisher.name`),\n url: this.readOptionalString(candidate.url, `versions.${version}.publisher.url`),\n };\n };\n\n private readRequiredString = (value: unknown, fieldName: string): string => {\n if (typeof value !== \"string\" || !value.trim()) {\n throw new Error(`${fieldName} 必须是非空字符串。`);\n }\n return value.trim();\n };\n\n private readOptionalString = (\n value: unknown,\n fieldName: string,\n ): string | undefined => {\n if (value === undefined) {\n return undefined;\n }\n return this.readRequiredString(value, fieldName);\n };\n\n private normalizeBundleFileName = (appId: string): string => {\n return appId.replace(/[^a-zA-Z0-9._-]+/g, \"-\");\n };\n\n private normalizeRegistryUrl = (registryUrl: string): string => {\n let normalized: URL;\n try {\n normalized = new URL(registryUrl);\n } catch {\n throw new Error(`非法 registry URL:${registryUrl}`);\n }\n if (normalized.protocol !== \"http:\" && normalized.protocol !== \"https:\") {\n throw new Error(`registry URL 只支持 http/https:${registryUrl}`);\n }\n const text = normalized.toString();\n return text.endsWith(\"/\") ? text : `${text}/`;\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-remote-registry.types.d.ts","names":[],"sources":["../../src/registry/app-remote-registry.types.ts"],"mappings":";;;;cAGa,wBAAA;AAAA,KAGD,YAAA;EACV,EAAA;EACA,IAAA;EACA,GAAA;AAAA;AAAA,KAGU,iBAAA;EACV,aAAA;EACA,QAAA;IACE,GAAA;EAAA;AAAA;AAAA,KAIQ,yBAAA;EACV,UAAA;EACA,UAAA;EACA,MAAA;AAAA;AAAA,KAGU,wBAAA;EACV,IAAA;EACA,OAAA;EACA,WAAA;EACA,SAAA,GAAY,YAAA;EACZ,WAAA,GAAc,cAAA;EACd,IAAA;IACE,IAAA,GAAO,mBAAA;IACP,QAAA;IACA,MAAA;IACA,MAAA;IACA,MAAA;EAAA;AAAA;AAAA,KAIQ,yBAAA;EACV,IAAA;EACA,WAAA;EACA,WAAA;IACE,MAAA;EAAA;EAEF,QAAA,EAAU,MAAA,SAAe,wBAAA;AAAA;AAAA,KAGf,2BAAA;EACV,WAAA;EACA,WAAA;EACA,KAAA;EACA,OAAA;EACA,WAAA;EACA,SAAA,GAAY,YAAA;EACZ,WAAA,GAAc,cAAA;EACd,gBAAA,EAAkB,mBAAA;EAClB,SAAA;EACA,MAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-remote-registry.types.js","names":[],"sources":["../../src/registry/app-remote-registry.types.ts"],"sourcesContent":["import type { AppPermissions } from \"../manifest/app-manifest.types.js\";\nimport type { AppDistributionMode } from \"../bundle/app-bundle.types.js\";\n\nexport const DEFAULT_APP_REGISTRY_URL =\n \"https://apps-registry.nextclaw.io/api/v1/apps/registry/\";\n\nexport type AppPublisher = {\n id: string;\n name: string;\n url?: string;\n};\n\nexport type AppRegistryConfig = {\n schemaVersion: 1;\n registry: {\n url: string;\n };\n};\n\nexport type AppRegistryConfigSnapshot = {\n defaultUrl: string;\n currentUrl: string;\n source: \"default\" | \"config\" | \"env\";\n};\n\nexport type AppRemoteRegistryVersion = {\n name: string;\n version: string;\n description?: string;\n publisher?: AppPublisher;\n permissions?: AppPermissions;\n dist: {\n kind?: AppDistributionMode;\n artifact?: string;\n bundle: string;\n source?: string;\n sha256: string;\n };\n};\n\nexport type AppRemoteRegistryDocument = {\n name: string;\n description?: string;\n \"dist-tags\": {\n latest: string;\n };\n versions: Record<string, AppRemoteRegistryVersion>;\n};\n\nexport type AppRemoteRegistryResolution = {\n registryUrl: string;\n metadataUrl: string;\n appId: string;\n version: string;\n description?: string;\n publisher?: AppPublisher;\n permissions?: AppPermissions;\n distributionMode: AppDistributionMode;\n bundleUrl: string;\n sha256: string;\n};\n"],"mappings":";AAGA,MAAa,2BACX"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-build.service.d.ts","names":[],"sources":["../../src/runtime/app-build.service.ts"],"mappings":";;;;KAKY,cAAA;EACV,YAAA;EACA,QAAA;EACA,aAAA;EACA,qBAAA;EACA,KAAA;EACA,aAAA;AAAA;AAAA,cAGW,eAAA;EAAA,iBAEQ,eAAA;EAAA,iBACA,gBAAA;cADA,eAAA,GAAiB,kBAAA,EACjB,gBAAA,GAAkB,0BAAA;EAGrC,KAAA,GAAe,MAAA;IACb,YAAA;IACA,OAAA;EAAA,MACE,OAAA,CAAQ,cAAA;EAAA,QAwCJ,UAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-build.service.js","names":[],"sources":["../../src/runtime/app-build.service.ts"],"sourcesContent":["import { access } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { AppManifestService } from \"../manifest/app-manifest.service.js\";\nimport { AppRuntimeToolchainService } from \"./app-runtime-toolchain.service.js\";\n\nexport type AppBuildResult = {\n appDirectory: string;\n mainKind: string;\n mainEntryPath: string;\n installedDependencies: boolean;\n built: boolean;\n skippedReason?: string;\n};\n\nexport class AppBuildService {\n constructor(\n private readonly manifestService: AppManifestService = new AppManifestService(),\n private readonly toolchainService: AppRuntimeToolchainService = new AppRuntimeToolchainService(),\n ) {}\n\n build = async (params: {\n appDirectory: string;\n install: boolean;\n }): Promise<AppBuildResult> => {\n const appDirectory = path.resolve(params.appDirectory);\n const bundle = await this.manifestService.load(appDirectory);\n if (bundle.manifest.main.kind !== \"wasi-http-component\") {\n return {\n appDirectory,\n mainKind: bundle.manifest.main.kind,\n mainEntryPath: bundle.mainEntryPath,\n installedDependencies: false,\n built: false,\n skippedReason: \"main.kind=wasm 应用不需要 TS/WASI HTTP 构建。\",\n };\n }\n\n await this.toolchainService.assertReadyForWasiHttpBuild();\n const mainDirectory = path.join(appDirectory, \"main\");\n await access(path.join(mainDirectory, \"package.json\"));\n const shouldInstall = params.install || !(await this.pathExists(path.join(mainDirectory, \"node_modules\")));\n if (shouldInstall) {\n await this.toolchainService.runCommand({\n command: \"npm\",\n args: [\"install\"],\n cwd: mainDirectory,\n });\n }\n await this.toolchainService.runCommand({\n command: \"npm\",\n args: [\"run\", \"build\"],\n cwd: mainDirectory,\n });\n await access(bundle.mainEntryPath);\n return {\n appDirectory,\n mainKind: bundle.manifest.main.kind,\n mainEntryPath: bundle.mainEntryPath,\n installedDependencies: shouldInstall,\n built: true,\n };\n };\n\n private pathExists = async (targetPath: string): Promise<boolean> => {\n try {\n await access(targetPath);\n return true;\n } catch {\n return false;\n }\n };\n}\n"],"mappings":";;;;;AAcA,IAAa,kBAAb,MAA6B;CAC3B,YACE,kBAAuD,IAAI,oBAAoB,EAC/E,mBAAgE,IAAI,4BAA4B,EAChG;AAFiB,OAAA,kBAAA;AACA,OAAA,mBAAA;;CAGnB,QAAQ,OAAO,WAGgB;EAC7B,MAAM,eAAe,KAAK,QAAQ,OAAO,aAAa;EACtD,MAAM,SAAS,MAAM,KAAK,gBAAgB,KAAK,aAAa;AAC5D,MAAI,OAAO,SAAS,KAAK,SAAS,sBAChC,QAAO;GACL;GACA,UAAU,OAAO,SAAS,KAAK;GAC/B,eAAe,OAAO;GACtB,uBAAuB;GACvB,OAAO;GACP,eAAe;GAChB;AAGH,QAAM,KAAK,iBAAiB,6BAA6B;EACzD,MAAM,gBAAgB,KAAK,KAAK,cAAc,OAAO;AACrD,QAAM,OAAO,KAAK,KAAK,eAAe,eAAe,CAAC;EACtD,MAAM,gBAAgB,OAAO,WAAW,CAAE,MAAM,KAAK,WAAW,KAAK,KAAK,eAAe,eAAe,CAAC;AACzG,MAAI,cACF,OAAM,KAAK,iBAAiB,WAAW;GACrC,SAAS;GACT,MAAM,CAAC,UAAU;GACjB,KAAK;GACN,CAAC;AAEJ,QAAM,KAAK,iBAAiB,WAAW;GACrC,SAAS;GACT,MAAM,CAAC,OAAO,QAAQ;GACtB,KAAK;GACN,CAAC;AACF,QAAM,OAAO,OAAO,cAAc;AAClC,SAAO;GACL;GACA,UAAU,OAAO,SAAS,KAAK;GAC/B,eAAe,OAAO;GACtB,uBAAuB;GACvB,OAAO;GACR;;CAGH,aAAqB,OAAO,eAAyC;AACnE,MAAI;AACF,SAAM,OAAO,WAAW;AACxB,UAAO;UACD;AACN,UAAO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-runtime-toolchain.service.d.ts","names":[],"sources":["../../src/runtime/app-runtime-toolchain.service.ts"],"mappings":";KAGY,oBAAA;EACV,IAAA;EACA,OAAA;EACA,EAAA;EACA,OAAA;EACA,WAAA;EACA,KAAA;AAAA;AAAA,KAGU,sBAAA;EACV,EAAA;EACA,KAAA,EAAO,oBAAA;AAAA;AAAA,KAGG,uBAAA;EACV,MAAA;EACA,MAAA;AAAA;AAAA,cA+BW,0BAAA;EACX,MAAA,QAAmB,OAAA,CAAQ,sBAAA;EAQ3B,2BAAA,QAAwC,OAAA;EAcxC,UAAA,GAAoB,MAAA;IAClB,OAAA;IACA,IAAA;IACA,GAAA;EAAA,MACE,OAAA,CAAQ,uBAAA;EAAA,QASJ,SAAA;EAAA,QA0BA,cAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app-runtime-toolchain.service.js","names":[],"sources":["../../src/runtime/app-runtime-toolchain.service.ts"],"sourcesContent":["import { spawn, type ChildProcessByStdio } from \"node:child_process\";\nimport type { Readable } from \"node:stream\";\n\nexport type AppRuntimeToolStatus = {\n name: string;\n command: string;\n ok: boolean;\n version?: string;\n installHint: string;\n error?: string;\n};\n\nexport type AppRuntimeDoctorResult = {\n ok: boolean;\n tools: AppRuntimeToolStatus[];\n};\n\nexport type AppRuntimeCommandResult = {\n stdout: string;\n stderr: string;\n};\n\ntype RequiredTool = {\n name: string;\n command: string;\n args: string[];\n installHint: string;\n};\n\nconst REQUIRED_TOOLS: RequiredTool[] = [\n {\n name: \"npm\",\n command: \"npm\",\n args: [\"--version\"],\n installHint: \"请安装 Node.js,或使用 NextClaw 桌面版内置运行环境。\",\n },\n {\n name: \"wasmtime\",\n command: \"wasmtime\",\n args: [\"--version\"],\n installHint: \"请安装 Wasmtime,或使用后续内置 Wasmtime 的 NextClaw 发行包。\",\n },\n {\n name: \"wkg\",\n command: \"wkg\",\n args: [\"--version\"],\n installHint: \"请安装 Bytecode Alliance wkg;有 Rust/Cargo 时可执行:cargo install wkg --locked。\",\n },\n];\n\nexport class AppRuntimeToolchainService {\n doctor = async (): Promise<AppRuntimeDoctorResult> => {\n const tools = await Promise.all(REQUIRED_TOOLS.map((tool) => this.checkTool(tool)));\n return {\n ok: tools.every((tool) => tool.ok),\n tools,\n };\n };\n\n assertReadyForWasiHttpBuild = async (): Promise<void> => {\n const result = await this.doctor();\n const missing = result.tools.filter((tool) => !tool.ok);\n if (missing.length === 0) {\n return;\n }\n throw new Error(\n [\n \"NApp WASI HTTP 开发环境尚未就绪。\",\n ...missing.map((tool) => `- 缺少 ${tool.name}: ${tool.installHint}`),\n ].join(\"\\n\"),\n );\n };\n\n runCommand = async (params: {\n command: string;\n args: string[];\n cwd: string;\n }): Promise<AppRuntimeCommandResult> => {\n const { command, args, cwd } = params;\n const child = spawn(command, args, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n return await this.collectProcess(child, command);\n };\n\n private checkTool = async (tool: RequiredTool): Promise<AppRuntimeToolStatus> => {\n try {\n const result = await this.runCommand({\n command: tool.command,\n args: tool.args,\n cwd: process.cwd(),\n });\n const version = (result.stdout || result.stderr).trim().split(/\\r?\\n/)[0]?.trim();\n return {\n name: tool.name,\n command: tool.command,\n ok: true,\n version,\n installHint: tool.installHint,\n };\n } catch (error) {\n return {\n name: tool.name,\n command: tool.command,\n ok: false,\n installHint: tool.installHint,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n };\n\n private collectProcess = async (\n child: ChildProcessByStdio<null, Readable, Readable>,\n command: string,\n ): Promise<AppRuntimeCommandResult> => {\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n child.stdout.on(\"data\", (chunk: Buffer) => {\n stdoutChunks.push(chunk);\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n stderrChunks.push(chunk);\n });\n const exitCode = await new Promise<number | null>((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"exit\", resolve);\n });\n const stdout = Buffer.concat(stdoutChunks).toString(\"utf-8\");\n const stderr = Buffer.concat(stderrChunks).toString(\"utf-8\");\n if (exitCode !== 0) {\n throw new Error(`${command} exited with ${exitCode ?? \"unknown\"}\\n${stderr || stdout}`);\n }\n return {\n stdout,\n stderr,\n };\n };\n}\n"],"mappings":";;AA6BA,MAAM,iBAAiC;CACrC;EACE,MAAM;EACN,SAAS;EACT,MAAM,CAAC,YAAY;EACnB,aAAa;EACd;CACD;EACE,MAAM;EACN,SAAS;EACT,MAAM,CAAC,YAAY;EACnB,aAAa;EACd;CACD;EACE,MAAM;EACN,SAAS;EACT,MAAM,CAAC,YAAY;EACnB,aAAa;EACd;CACF;AAED,IAAa,6BAAb,MAAwC;CACtC,SAAS,YAA6C;EACpD,MAAM,QAAQ,MAAM,QAAQ,IAAI,eAAe,KAAK,SAAS,KAAK,UAAU,KAAK,CAAC,CAAC;AACnF,SAAO;GACL,IAAI,MAAM,OAAO,SAAS,KAAK,GAAG;GAClC;GACD;;CAGH,8BAA8B,YAA2B;EAEvD,MAAM,WADS,MAAM,KAAK,QAAQ,EACX,MAAM,QAAQ,SAAS,CAAC,KAAK,GAAG;AACvD,MAAI,QAAQ,WAAW,EACrB;AAEF,QAAM,IAAI,MACR,CACE,4BACA,GAAG,QAAQ,KAAK,SAAS,QAAQ,KAAK,KAAK,IAAI,KAAK,cAAc,CACnE,CAAC,KAAK,KAAK,CACb;;CAGH,aAAa,OAAO,WAIoB;EACtC,MAAM,EAAE,SAAS,MAAM,QAAQ;EAC/B,MAAM,QAAQ,MAAM,SAAS,MAAM;GACjC;GACA,OAAO;IAAC;IAAU;IAAQ;IAAO;GAClC,CAAC;AACF,SAAO,MAAM,KAAK,eAAe,OAAO,QAAQ;;CAGlD,YAAoB,OAAO,SAAsD;AAC/E,MAAI;GACF,MAAM,SAAS,MAAM,KAAK,WAAW;IACnC,SAAS,KAAK;IACd,MAAM,KAAK;IACX,KAAK,QAAQ,KAAK;IACnB,CAAC;GACF,MAAM,WAAW,OAAO,UAAU,OAAO,QAAQ,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,MAAM;AACjF,UAAO;IACL,MAAM,KAAK;IACX,SAAS,KAAK;IACd,IAAI;IACJ;IACA,aAAa,KAAK;IACnB;WACM,OAAO;AACd,UAAO;IACL,MAAM,KAAK;IACX,SAAS,KAAK;IACd,IAAI;IACJ,aAAa,KAAK;IAClB,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAC9D;;;CAIL,iBAAyB,OACvB,OACA,YACqC;EACrC,MAAM,eAAyB,EAAE;EACjC,MAAM,eAAyB,EAAE;AACjC,QAAM,OAAO,GAAG,SAAS,UAAkB;AACzC,gBAAa,KAAK,MAAM;IACxB;AACF,QAAM,OAAO,GAAG,SAAS,UAAkB;AACzC,gBAAa,KAAK,MAAM;IACxB;EACF,MAAM,WAAW,MAAM,IAAI,SAAwB,SAAS,WAAW;AACrE,SAAM,KAAK,SAAS,OAAO;AAC3B,SAAM,KAAK,QAAQ,QAAQ;IAC3B;EACF,MAAM,SAAS,OAAO,OAAO,aAAa,CAAC,SAAS,QAAQ;EAC5D,MAAM,SAAS,OAAO,OAAO,aAAa,CAAC,SAAS,QAAQ;AAC5D,MAAI,aAAa,EACf,OAAM,IAAI,MAAM,GAAG,QAAQ,eAAe,YAAY,UAAU,IAAI,UAAU,SAAS;AAEzF,SAAO;GACL;GACA;GACD"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { MainRunRequest, MainRunResult } from "./main-runner.types.js";
|
|
2
|
-
|
|
3
|
-
//#region src/runtime/main-runner.service.d.ts
|
|
4
|
-
declare abstract class MainRunnerService {
|
|
5
|
-
abstract runDocumentSummary(request: MainRunRequest): Promise<MainRunResult>;
|
|
6
|
-
}
|
|
7
|
-
//#endregion
|
|
8
|
-
export { MainRunnerService };
|
|
9
|
-
//# sourceMappingURL=main-runner.service.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"main-runner.service.d.ts","names":[],"sources":["../../src/runtime/main-runner.service.ts"],"mappings":";;;uBAEsB,iBAAA;EAAA,SACX,kBAAA,CAAmB,OAAA,EAAS,cAAA,GAAiB,OAAA,CAAQ,aAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"main-runner.service.js","names":[],"sources":["../../src/runtime/main-runner.service.ts"],"sourcesContent":["import type { MainRunRequest, MainRunResult } from \"./main-runner.types.js\";\n\nexport abstract class MainRunnerService {\n abstract runDocumentSummary(request: MainRunRequest): Promise<MainRunResult>;\n}\n"],"mappings":";AAEA,IAAsB,oBAAtB,MAAwC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"main-runner.types.d.ts","names":[],"sources":["../../src/runtime/main-runner.types.ts"],"mappings":";;;KAEY,wBAAA;EACV,aAAA;EACA,SAAA;AAAA;AAAA,KAGU,cAAA;EACV,MAAA,EAAQ,iBAAA;EACR,KAAA,EAAO,wBAAA;AAAA;AAAA,KAGG,aAAA;EACV,UAAA;EACA,MAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-main-runner.service.d.ts","names":[],"sources":["../../src/runtime/wasm-main-runner.service.ts"],"mappings":";;;;;cAIa,qBAAA,SAA8B,iBAAA;EAAA,iBAEtB,aAAA;cAAA,aAAA,GAAe,wBAAA;EAKlC,kBAAA,GAA4B,OAAA,EAAS,cAAA,KAAiB,OAAA,CAAQ,aAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-main-runner.service.js","names":[],"sources":["../../src/runtime/wasm-main-runner.service.ts"],"sourcesContent":["import { MainRunnerService } from \"./main-runner.service.js\";\nimport type { MainRunRequest, MainRunResult } from \"./main-runner.types.js\";\nimport { WasmSidecarClientService } from \"../sidecar/wasm-sidecar-client.service.js\";\n\nexport class WasmMainRunnerService extends MainRunnerService {\n constructor(\n private readonly sidecarClient: WasmSidecarClientService = new WasmSidecarClientService(),\n ) {\n super();\n }\n\n runDocumentSummary = async (request: MainRunRequest): Promise<MainRunResult> => {\n if (request.bundle.manifest.main.kind !== \"wasm\") {\n throw new Error(\"runDocumentSummary 只支持 main.kind=wasm。\");\n }\n const output = await this.sidecarClient.runExport({\n wasmPath: request.bundle.mainEntryPath,\n exportName: request.bundle.manifest.main.export,\n args: [request.input.documentCount, request.input.textBytes],\n });\n return {\n exportName: request.bundle.manifest.main.export,\n output,\n };\n };\n}\n"],"mappings":";;;AAIA,IAAa,wBAAb,cAA2C,kBAAkB;CAC3D,YACE,gBAA2D,IAAI,0BAA0B,EACzF;AACA,SAAO;AAFU,OAAA,gBAAA;;CAKnB,qBAAqB,OAAO,YAAoD;AAC9E,MAAI,QAAQ,OAAO,SAAS,KAAK,SAAS,OACxC,OAAM,IAAI,MAAM,yCAAyC;EAE3D,MAAM,SAAS,MAAM,KAAK,cAAc,UAAU;GAChD,UAAU,QAAQ,OAAO;GACzB,YAAY,QAAQ,OAAO,SAAS,KAAK;GACzC,MAAM,CAAC,QAAQ,MAAM,eAAe,QAAQ,MAAM,UAAU;GAC7D,CAAC;AACF,SAAO;GACL,YAAY,QAAQ,OAAO,SAAS,KAAK;GACzC;GACD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wasmtime-wasi-http-component.service.d.ts","names":[],"sources":["../../src/runtime/wasmtime-wasi-http-component.service.ts"],"mappings":";;;KAMY,qCAAA;EACV,QAAA;EACA,aAAA;AAAA;AAAA,KAGU,+BAAA;EACV,GAAA;EACA,IAAA;AAAA;AAAA,cAGW,gCAAA;EAAA,QACH,OAAA;EAAA,QACA,MAAA;EAER,KAAA,GACE,OAAA,EAAS,qCAAA,KACR,OAAA,CAAQ,+BAAA;EAqCX,IAAA,QAAiB,OAAA;EAqBjB,aAAA,GACE,OAAA,EAAS,eAAA,EACT,QAAA,EAAU,cAAA,KACT,OAAA;EAAA,QAiCK,QAAA;EAAA,QAQA,kBAAA;EAAA,QAIA,iBAAA;EAAA,QAyBA,cAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wasmtime-wasi-http-component.service.js","names":[],"sources":["../../src/runtime/wasmtime-wasi-http-component.service.ts"],"sourcesContent":["import { spawn, type ChildProcessByStdio } from \"node:child_process\";\nimport { mkdir } from \"node:fs/promises\";\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport path from \"node:path\";\nimport type { Readable } from \"node:stream\";\n\nexport type WasmtimeWasiHttpComponentStartOptions = {\n wasmPath: string;\n dataDirectory: string;\n};\n\nexport type WasmtimeWasiHttpComponentHandle = {\n url: string;\n port: number;\n};\n\nexport class WasmtimeWasiHttpComponentService {\n private process?: ChildProcessByStdio<null, Readable, Readable>;\n private handle?: WasmtimeWasiHttpComponentHandle;\n\n start = async (\n options: WasmtimeWasiHttpComponentStartOptions,\n ): Promise<WasmtimeWasiHttpComponentHandle> => {\n if (this.process) {\n throw new Error(\"WASI HTTP component 已经启动。\");\n }\n const dataDirectory = path.resolve(options.dataDirectory);\n await mkdir(dataDirectory, { recursive: true });\n const port = await this.findAvailablePort();\n const child = spawn(\n \"wasmtime\",\n [\n \"serve\",\n \"-S\",\n \"cli=y\",\n \"-S\",\n \"http=y\",\n \"-S\",\n \"inherit-network=y\",\n \"--addr\",\n `127.0.0.1:${port}`,\n \"--dir\",\n `${dataDirectory}::/data`,\n options.wasmPath,\n ],\n {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n },\n );\n this.process = child;\n const handle = {\n url: `http://127.0.0.1:${port}`,\n port,\n };\n this.handle = handle;\n await this.waitUntilReady(handle.url, child);\n return handle;\n };\n\n stop = async (): Promise<void> => {\n const child = this.process;\n if (!child) {\n return;\n }\n await new Promise<void>((resolve) => {\n child.once(\"exit\", () => {\n resolve();\n });\n child.kill(\"SIGTERM\");\n setTimeout(() => {\n if (!child.killed) {\n child.kill(\"SIGKILL\");\n }\n resolve();\n }, 1_000).unref();\n });\n this.process = undefined;\n this.handle = undefined;\n };\n\n handleRequest = async (\n request: IncomingMessage,\n response: ServerResponse,\n ): Promise<boolean> => {\n const handle = this.handle;\n if (!handle) {\n return false;\n }\n const requestUrl = new URL(request.url ?? \"/\", handle.url);\n if (!requestUrl.pathname.startsWith(\"/api/\")) {\n return false;\n }\n const headers = new Headers();\n for (const [key, value] of Object.entries(request.headers)) {\n if (value === undefined || key.toLowerCase() === \"host\") {\n continue;\n }\n if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(key, item);\n }\n continue;\n }\n headers.set(key, value);\n }\n const body = await this.readBody(request);\n const upstreamResponse = await fetch(requestUrl, {\n method: request.method,\n headers,\n body: this.methodSupportsBody(request.method) ? body : undefined,\n });\n response.writeHead(upstreamResponse.status, Object.fromEntries(upstreamResponse.headers));\n response.end(Buffer.from(await upstreamResponse.arrayBuffer()));\n return true;\n };\n\n private readBody = async (request: IncomingMessage): Promise<Buffer> => {\n const chunks: Buffer[] = [];\n for await (const chunk of request) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks);\n };\n\n private methodSupportsBody = (method: string | undefined): boolean => {\n return method !== undefined && method !== \"GET\" && method !== \"HEAD\";\n };\n\n private findAvailablePort = async (): Promise<number> => {\n const server = createServer();\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n const address = server.address();\n await new Promise<void>((resolve, reject) => {\n server.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n if (!address || typeof address === \"string\") {\n throw new Error(\"无法分配 WASI HTTP component 端口。\");\n }\n return address.port;\n };\n\n private waitUntilReady = async (\n url: string,\n child: ChildProcessByStdio<null, Readable, Readable>,\n ): Promise<void> => {\n const errors: string[] = [];\n child.stderr.on(\"data\", (chunk: Buffer) => {\n errors.push(chunk.toString(\"utf-8\"));\n });\n for (let attempt = 0; attempt < 50; attempt += 1) {\n if (child.exitCode !== null) {\n throw new Error(\n `WASI HTTP component 启动失败:${errors.join(\"\").trim() || `exit ${child.exitCode}`}`,\n );\n }\n try {\n await fetch(url);\n return;\n } catch {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n }\n throw new Error(`WASI HTTP component 启动超时:${errors.join(\"\").trim()}`);\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-sidecar-client.service.d.ts","names":[],"sources":["../../src/sidecar/wasm-sidecar-client.service.ts"],"mappings":";cAaa,wBAAA;EACX,SAAA,GAAmB,MAAA;IACjB,QAAA;IACA,UAAA;IACA,IAAA;EAAA,MACE,OAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-sidecar-client.service.js","names":[],"sources":["../../src/sidecar/wasm-sidecar-client.service.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\n\ntype WasmRuntime = {\n instantiate(\n wasmBytes: Buffer,\n imports: Record<string, unknown>,\n ): Promise<{\n instance: {\n exports: Record<string, unknown>;\n };\n }>;\n};\n\nexport class WasmSidecarClientService {\n runExport = async (params: {\n wasmPath: string;\n exportName: string;\n args: number[];\n }): Promise<number> => {\n const { wasmPath, exportName, args } = params;\n const wasmBytes = await readFile(wasmPath);\n const wasmRuntime = (globalThis as typeof globalThis & { WebAssembly?: WasmRuntime })\n .WebAssembly;\n if (!wasmRuntime) {\n throw new Error(\"当前 Node 运行时不支持 WebAssembly。\");\n }\n const instance = await wasmRuntime.instantiate(wasmBytes, {});\n const exported = instance.instance.exports[exportName];\n if (typeof exported !== \"function\") {\n throw new Error(`Wasm 导出不存在或不可调用:${exportName}`);\n }\n const result = exported(...args);\n if (typeof result !== \"number\") {\n throw new Error(`Wasm 导出 ${exportName} 必须返回 number。`);\n }\n return result;\n };\n}\n"],"mappings":";;AAaA,IAAa,2BAAb,MAAsC;CACpC,YAAY,OAAO,WAII;EACrB,MAAM,EAAE,UAAU,YAAY,SAAS;EACvC,MAAM,YAAY,MAAM,SAAS,SAAS;EAC1C,MAAM,cAAe,WAClB;AACH,MAAI,CAAC,YACH,OAAM,IAAI,MAAM,8BAA8B;EAGhD,MAAM,YADW,MAAM,YAAY,YAAY,WAAW,EAAE,CAAC,EACnC,SAAS,QAAQ;AAC3C,MAAI,OAAO,aAAa,WACtB,OAAM,IAAI,MAAM,mBAAmB,aAAa;EAElD,MAAM,SAAS,SAAS,GAAG,KAAK;AAChC,MAAI,OAAO,WAAW,SACpB,OAAM,IAAI,MAAM,WAAW,WAAW,eAAe;AAEvD,SAAO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui-server.service.d.ts","names":[],"sources":["../../src/ui/ui-server.service.ts"],"mappings":";;;;cAca,eAAA;EAAA,iBACkB,MAAA;cAAA,MAAA,EAAQ,iBAAA;EAErC,MAAA,GACE,OAAA,EAAS,eAAA,EACT,QAAA,EAAU,cAAA,KACT,OAAA;EAAA,QA8BK,kBAAA;EAAA,QAKA,MAAA;EAAA,QASA,wBAAA;AAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui-server.service.js","names":[],"sources":["../../src/ui/ui-server.service.ts"],"sourcesContent":["import { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { AppManifestBundle } from \"../manifest/app-manifest.types.js\";\n\nconst CONTENT_TYPE_BY_EXTENSION: Record<string, string> = {\n \".css\": \"text/css; charset=utf-8\",\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"text/javascript; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".png\": \"image/png\",\n \".svg\": \"image/svg+xml; charset=utf-8\",\n};\n\nexport class UiServerService {\n constructor(private readonly bundle: AppManifestBundle) {}\n\n handle = async (\n request: IncomingMessage,\n response: ServerResponse,\n ): Promise<boolean> => {\n const requestUrl = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n const requestPath = requestUrl.pathname === \"/\" ? \"/index.html\" : requestUrl.pathname;\n const candidatePaths = [\n path.join(this.bundle.uiDirectoryPath, requestPath.slice(1)),\n path.join(this.bundle.assetsDirectoryPath, requestPath.slice(1)),\n ];\n\n for (const candidatePath of candidatePaths) {\n if (!(await this.isInsideAllowedDirectory(candidatePath))) {\n continue;\n }\n if (!(await this.exists(candidatePath))) {\n continue;\n }\n const content = await readFile(candidatePath);\n response.writeHead(200, {\n \"content-type\": this.resolveContentType(candidatePath),\n });\n response.end(content);\n return true;\n }\n\n response.writeHead(404, {\n \"content-type\": \"text/plain; charset=utf-8\",\n });\n response.end(`Not found: ${requestPath}`);\n return true;\n };\n\n private resolveContentType = (filePath: string): string => {\n const extension = path.extname(filePath).toLowerCase();\n return CONTENT_TYPE_BY_EXTENSION[extension] ?? \"application/octet-stream\";\n };\n\n private exists = async (filePath: string): Promise<boolean> => {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n };\n\n private isInsideAllowedDirectory = async (candidatePath: string): Promise<boolean> => {\n const allowedDirectories = [this.bundle.uiDirectoryPath, this.bundle.assetsDirectoryPath];\n return allowedDirectories.some((directoryPath) => {\n const relative = path.relative(directoryPath, candidatePath);\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n });\n };\n}\n"],"mappings":";;;AAKA,MAAM,4BAAoD;CACxD,QAAQ;CACR,SAAS;CACT,OAAO;CACP,SAAS;CACT,QAAQ;CACR,QAAQ;CACT;AAED,IAAa,kBAAb,MAA6B;CAC3B,YAAY,QAA4C;AAA3B,OAAA,SAAA;;CAE7B,SAAS,OACP,SACA,aACqB;EACrB,MAAM,aAAa,IAAI,IAAI,QAAQ,OAAO,KAAK,mBAAmB;EAClE,MAAM,cAAc,WAAW,aAAa,MAAM,gBAAgB,WAAW;EAC7E,MAAM,iBAAiB,CACrB,KAAK,KAAK,KAAK,OAAO,iBAAiB,YAAY,MAAM,EAAE,CAAC,EAC5D,KAAK,KAAK,KAAK,OAAO,qBAAqB,YAAY,MAAM,EAAE,CAAC,CACjE;AAED,OAAK,MAAM,iBAAiB,gBAAgB;AAC1C,OAAI,CAAE,MAAM,KAAK,yBAAyB,cAAc,CACtD;AAEF,OAAI,CAAE,MAAM,KAAK,OAAO,cAAc,CACpC;GAEF,MAAM,UAAU,MAAM,SAAS,cAAc;AAC7C,YAAS,UAAU,KAAK,EACtB,gBAAgB,KAAK,mBAAmB,cAAc,EACvD,CAAC;AACF,YAAS,IAAI,QAAQ;AACrB,UAAO;;AAGT,WAAS,UAAU,KAAK,EACtB,gBAAgB,6BACjB,CAAC;AACF,WAAS,IAAI,cAAc,cAAc;AACzC,SAAO;;CAGT,sBAA8B,aAA6B;AAEzD,SAAO,0BADW,KAAK,QAAQ,SAAS,CAAC,aAAa,KACP;;CAGjD,SAAiB,OAAO,aAAuC;AAC7D,MAAI;AACF,SAAM,OAAO,SAAS;AACtB,UAAO;UACD;AACN,UAAO;;;CAIX,2BAAmC,OAAO,kBAA4C;AAEpF,SAD2B,CAAC,KAAK,OAAO,iBAAiB,KAAK,OAAO,oBAAoB,CAC/D,MAAM,kBAAkB;GAChD,MAAM,WAAW,KAAK,SAAS,eAAe,cAAc;AAC5D,UAAO,aAAa,MAAO,CAAC,SAAS,WAAW,KAAK,IAAI,CAAC,KAAK,WAAW,SAAS;IACnF"}
|
|
File without changes
|