@nextclaw/app-runtime 0.7.10 → 0.7.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/dist/bridge/host-bridge.service.d.ts +2 -1
  2. package/dist/bridge/host-bridge.service.d.ts.map +1 -0
  3. package/dist/bridge/host-bridge.service.js +2 -0
  4. package/dist/bridge/host-bridge.service.js.map +1 -0
  5. package/dist/bundle/app-bundle.service.d.ts +2 -1
  6. package/dist/bundle/app-bundle.service.d.ts.map +1 -0
  7. package/dist/bundle/app-bundle.service.js +2 -0
  8. package/dist/bundle/app-bundle.service.js.map +1 -0
  9. package/dist/bundle/app-bundle.types.d.ts +2 -1
  10. package/dist/bundle/app-bundle.types.d.ts.map +1 -0
  11. package/dist/cli/app-runtime-cli.service.d.ts +2 -1
  12. package/dist/cli/app-runtime-cli.service.d.ts.map +1 -0
  13. package/dist/cli/app-runtime-cli.service.js +2 -0
  14. package/dist/cli/app-runtime-cli.service.js.map +1 -0
  15. package/dist/cli/app-runtime-options.service.d.ts +2 -1
  16. package/dist/cli/app-runtime-options.service.d.ts.map +1 -0
  17. package/dist/cli/app-runtime-options.service.js +2 -0
  18. package/dist/cli/app-runtime-options.service.js.map +1 -0
  19. package/dist/commands/create.controller.d.ts +2 -1
  20. package/dist/commands/create.controller.d.ts.map +1 -0
  21. package/dist/commands/create.controller.js +2 -0
  22. package/dist/commands/create.controller.js.map +1 -0
  23. package/dist/commands/dev.controller.js +2 -0
  24. package/dist/commands/dev.controller.js.map +1 -0
  25. package/dist/commands/grant.controller.d.ts +2 -1
  26. package/dist/commands/grant.controller.d.ts.map +1 -0
  27. package/dist/commands/grant.controller.js +2 -0
  28. package/dist/commands/grant.controller.js.map +1 -0
  29. package/dist/commands/info.controller.d.ts +2 -1
  30. package/dist/commands/info.controller.d.ts.map +1 -0
  31. package/dist/commands/info.controller.js +2 -0
  32. package/dist/commands/info.controller.js.map +1 -0
  33. package/dist/commands/inspect.controller.js +2 -0
  34. package/dist/commands/inspect.controller.js.map +1 -0
  35. package/dist/commands/install.controller.d.ts +2 -1
  36. package/dist/commands/install.controller.d.ts.map +1 -0
  37. package/dist/commands/install.controller.js +2 -0
  38. package/dist/commands/install.controller.js.map +1 -0
  39. package/dist/commands/list.controller.d.ts +2 -1
  40. package/dist/commands/list.controller.d.ts.map +1 -0
  41. package/dist/commands/list.controller.js +2 -0
  42. package/dist/commands/list.controller.js.map +1 -0
  43. package/dist/commands/pack.controller.d.ts +2 -1
  44. package/dist/commands/pack.controller.d.ts.map +1 -0
  45. package/dist/commands/pack.controller.js +2 -0
  46. package/dist/commands/pack.controller.js.map +1 -0
  47. package/dist/commands/permissions.controller.d.ts +2 -1
  48. package/dist/commands/permissions.controller.d.ts.map +1 -0
  49. package/dist/commands/permissions.controller.js +2 -0
  50. package/dist/commands/permissions.controller.js.map +1 -0
  51. package/dist/commands/publish.controller.d.ts +2 -1
  52. package/dist/commands/publish.controller.d.ts.map +1 -0
  53. package/dist/commands/publish.controller.js +2 -0
  54. package/dist/commands/publish.controller.js.map +1 -0
  55. package/dist/commands/registry.controller.d.ts +2 -1
  56. package/dist/commands/registry.controller.d.ts.map +1 -0
  57. package/dist/commands/registry.controller.js +2 -0
  58. package/dist/commands/registry.controller.js.map +1 -0
  59. package/dist/commands/revoke.controller.d.ts +2 -1
  60. package/dist/commands/revoke.controller.d.ts.map +1 -0
  61. package/dist/commands/revoke.controller.js +2 -0
  62. package/dist/commands/revoke.controller.js.map +1 -0
  63. package/dist/commands/run.controller.js +2 -0
  64. package/dist/commands/run.controller.js.map +1 -0
  65. package/dist/commands/uninstall.controller.d.ts +2 -1
  66. package/dist/commands/uninstall.controller.d.ts.map +1 -0
  67. package/dist/commands/uninstall.controller.js +2 -0
  68. package/dist/commands/uninstall.controller.js.map +1 -0
  69. package/dist/commands/update.controller.d.ts +2 -1
  70. package/dist/commands/update.controller.d.ts.map +1 -0
  71. package/dist/commands/update.controller.js +2 -0
  72. package/dist/commands/update.controller.js.map +1 -0
  73. package/dist/commands/validate-publish.controller.d.ts +2 -1
  74. package/dist/commands/validate-publish.controller.d.ts.map +1 -0
  75. package/dist/commands/validate-publish.controller.js +2 -0
  76. package/dist/commands/validate-publish.controller.js.map +1 -0
  77. package/dist/host/app-host.service.d.ts +2 -1
  78. package/dist/host/app-host.service.d.ts.map +1 -0
  79. package/dist/host/app-host.service.js +2 -0
  80. package/dist/host/app-host.service.js.map +1 -0
  81. package/dist/host/app-instance.service.d.ts +2 -1
  82. package/dist/host/app-instance.service.d.ts.map +1 -0
  83. package/dist/host/app-instance.service.js +2 -0
  84. package/dist/host/app-instance.service.js.map +1 -0
  85. package/dist/install/app-installation.service.d.ts +2 -1
  86. package/dist/install/app-installation.service.d.ts.map +1 -0
  87. package/dist/install/app-installation.service.js +2 -0
  88. package/dist/install/app-installation.service.js.map +1 -0
  89. package/dist/install/app-installation.types.d.ts +2 -1
  90. package/dist/install/app-installation.types.d.ts.map +1 -0
  91. package/dist/main.js +2 -0
  92. package/dist/main.js.map +1 -0
  93. package/dist/manifest/app-manifest.service.d.ts +2 -1
  94. package/dist/manifest/app-manifest.service.d.ts.map +1 -0
  95. package/dist/manifest/app-manifest.service.js +2 -0
  96. package/dist/manifest/app-manifest.service.js.map +1 -0
  97. package/dist/manifest/app-manifest.types.d.ts +2 -1
  98. package/dist/manifest/app-manifest.types.d.ts.map +1 -0
  99. package/dist/package.js +3 -1
  100. package/dist/package.js.map +1 -0
  101. package/dist/paths/app-home.service.d.ts +2 -1
  102. package/dist/paths/app-home.service.d.ts.map +1 -0
  103. package/dist/paths/app-home.service.js +2 -0
  104. package/dist/paths/app-home.service.js.map +1 -0
  105. package/dist/permissions/app-grant.service.d.ts +2 -1
  106. package/dist/permissions/app-grant.service.d.ts.map +1 -0
  107. package/dist/permissions/app-grant.service.js +2 -0
  108. package/dist/permissions/app-grant.service.js.map +1 -0
  109. package/dist/permissions/app-permissions.service.d.ts +2 -1
  110. package/dist/permissions/app-permissions.service.d.ts.map +1 -0
  111. package/dist/permissions/app-permissions.service.js +2 -0
  112. package/dist/permissions/app-permissions.service.js.map +1 -0
  113. package/dist/permissions/app-permissions.types.d.ts +2 -1
  114. package/dist/permissions/app-permissions.types.d.ts.map +1 -0
  115. package/dist/publish/app-marketplace-client.service.d.ts +2 -1
  116. package/dist/publish/app-marketplace-client.service.d.ts.map +1 -0
  117. package/dist/publish/app-marketplace-client.service.js +2 -0
  118. package/dist/publish/app-marketplace-client.service.js.map +1 -0
  119. package/dist/publish/app-marketplace-metadata.service.d.ts +2 -1
  120. package/dist/publish/app-marketplace-metadata.service.d.ts.map +1 -0
  121. package/dist/publish/app-marketplace-metadata.service.js +2 -0
  122. package/dist/publish/app-marketplace-metadata.service.js.map +1 -0
  123. package/dist/publish/app-publish-validation.service.d.ts +2 -1
  124. package/dist/publish/app-publish-validation.service.d.ts.map +1 -0
  125. package/dist/publish/app-publish-validation.service.js +2 -0
  126. package/dist/publish/app-publish-validation.service.js.map +1 -0
  127. package/dist/publish/app-publish.service.d.ts +2 -1
  128. package/dist/publish/app-publish.service.d.ts.map +1 -0
  129. package/dist/publish/app-publish.service.js +2 -0
  130. package/dist/publish/app-publish.service.js.map +1 -0
  131. package/dist/publish/app-publish.types.d.ts +2 -1
  132. package/dist/publish/app-publish.types.d.ts.map +1 -0
  133. package/dist/publish/app-publish.types.js +2 -0
  134. package/dist/publish/app-publish.types.js.map +1 -0
  135. package/dist/publish/platform-auth-state.service.d.ts +2 -1
  136. package/dist/publish/platform-auth-state.service.d.ts.map +1 -0
  137. package/dist/publish/platform-auth-state.service.js +2 -0
  138. package/dist/publish/platform-auth-state.service.js.map +1 -0
  139. package/dist/registry/app-registry-config.service.d.ts +2 -1
  140. package/dist/registry/app-registry-config.service.d.ts.map +1 -0
  141. package/dist/registry/app-registry-config.service.js +2 -0
  142. package/dist/registry/app-registry-config.service.js.map +1 -0
  143. package/dist/registry/app-registry.service.d.ts +2 -1
  144. package/dist/registry/app-registry.service.d.ts.map +1 -0
  145. package/dist/registry/app-registry.service.js +2 -0
  146. package/dist/registry/app-registry.service.js.map +1 -0
  147. package/dist/registry/app-registry.types.d.ts +2 -1
  148. package/dist/registry/app-registry.types.d.ts.map +1 -0
  149. package/dist/registry/app-remote-registry-client.service.d.ts +2 -1
  150. package/dist/registry/app-remote-registry-client.service.d.ts.map +1 -0
  151. package/dist/registry/app-remote-registry-client.service.js +2 -0
  152. package/dist/registry/app-remote-registry-client.service.js.map +1 -0
  153. package/dist/registry/app-remote-registry.types.d.ts +2 -1
  154. package/dist/registry/app-remote-registry.types.d.ts.map +1 -0
  155. package/dist/registry/app-remote-registry.types.js +2 -0
  156. package/dist/registry/app-remote-registry.types.js.map +1 -0
  157. package/dist/runtime/app-build.service.d.ts +2 -1
  158. package/dist/runtime/app-build.service.d.ts.map +1 -0
  159. package/dist/runtime/app-build.service.js +2 -0
  160. package/dist/runtime/app-build.service.js.map +1 -0
  161. package/dist/runtime/app-runtime-toolchain.service.d.ts +2 -1
  162. package/dist/runtime/app-runtime-toolchain.service.d.ts.map +1 -0
  163. package/dist/runtime/app-runtime-toolchain.service.js +2 -0
  164. package/dist/runtime/app-runtime-toolchain.service.js.map +1 -0
  165. package/dist/runtime/main-runner.service.d.ts +2 -1
  166. package/dist/runtime/main-runner.service.d.ts.map +1 -0
  167. package/dist/runtime/main-runner.service.js +2 -0
  168. package/dist/runtime/main-runner.service.js.map +1 -0
  169. package/dist/runtime/main-runner.types.d.ts +2 -1
  170. package/dist/runtime/main-runner.types.d.ts.map +1 -0
  171. package/dist/runtime/wasm-main-runner.service.d.ts +2 -1
  172. package/dist/runtime/wasm-main-runner.service.d.ts.map +1 -0
  173. package/dist/runtime/wasm-main-runner.service.js +2 -0
  174. package/dist/runtime/wasm-main-runner.service.js.map +1 -0
  175. package/dist/runtime/wasmtime-wasi-http-component.service.d.ts +2 -1
  176. package/dist/runtime/wasmtime-wasi-http-component.service.d.ts.map +1 -0
  177. package/dist/runtime/wasmtime-wasi-http-component.service.js +2 -0
  178. package/dist/runtime/wasmtime-wasi-http-component.service.js.map +1 -0
  179. package/dist/scaffold/app-scaffold.service.d.ts +2 -1
  180. package/dist/scaffold/app-scaffold.service.d.ts.map +1 -0
  181. package/dist/scaffold/app-scaffold.service.js +2 -0
  182. package/dist/scaffold/app-scaffold.service.js.map +1 -0
  183. package/dist/scaffold/app-ts-http-lite-scaffold-template.service.d.ts +2 -1
  184. package/dist/scaffold/app-ts-http-lite-scaffold-template.service.d.ts.map +1 -0
  185. package/dist/scaffold/app-ts-http-lite-scaffold-template.service.js +2 -0
  186. package/dist/scaffold/app-ts-http-lite-scaffold-template.service.js.map +1 -0
  187. package/dist/scaffold/app-ts-http-scaffold-template.service.d.ts +2 -1
  188. package/dist/scaffold/app-ts-http-scaffold-template.service.d.ts.map +1 -0
  189. package/dist/scaffold/app-ts-http-scaffold-template.service.js +2 -0
  190. package/dist/scaffold/app-ts-http-scaffold-template.service.js.map +1 -0
  191. package/dist/sidecar/wasm-sidecar-client.service.d.ts +2 -1
  192. package/dist/sidecar/wasm-sidecar-client.service.d.ts.map +1 -0
  193. package/dist/sidecar/wasm-sidecar-client.service.js +2 -0
  194. package/dist/sidecar/wasm-sidecar-client.service.js.map +1 -0
  195. package/dist/ui/ui-server.service.d.ts +2 -1
  196. package/dist/ui/ui-server.service.d.ts.map +1 -0
  197. package/dist/ui/ui-server.service.js +2 -0
  198. package/dist/ui/ui-server.service.js.map +1 -0
  199. package/package.json +2 -2
@@ -13,4 +13,5 @@ declare class UpdateCommand {
13
13
  }) => Promise<void>;
14
14
  }
15
15
  //#endregion
16
- export { UpdateCommand };
16
+ export { UpdateCommand };
17
+ //# sourceMappingURL=update.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.controller.d.ts","names":[],"sources":["../../src/commands/update.controller.ts"],"mappings":";;;cAEa,aAAA;EAAA,iBAEQ,mBAAA;cAAA,mBAAA,GAAqB,sBAAA;EAGxC,GAAA,GAAa,MAAA;IACX,KAAA;IACA,OAAA;IACA,WAAA;IACA,IAAA;IACA,KAAA,GAAQ,IAAA;EAAA,MACN,OAAA;AAAA"}
@@ -27,3 +27,5 @@ var UpdateCommand = class {
27
27
  };
28
28
  //#endregion
29
29
  export { UpdateCommand };
30
+
31
+ //# sourceMappingURL=update.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.controller.js","names":[],"sources":["../../src/commands/update.controller.ts"],"sourcesContent":["import { AppInstallationService } from \"../install/app-installation.service.js\";\n\nexport class UpdateCommand {\n constructor(\n private readonly installationService: AppInstallationService = new AppInstallationService(),\n ) {}\n\n run = async (params: {\n appId: string;\n version?: string;\n registryUrl?: string;\n json: boolean;\n write: (text: string) => void;\n }): Promise<void> => {\n const { appId, version, registryUrl, json, write } = params;\n const result = await this.installationService.update(appId, {\n version,\n registryUrl,\n });\n if (json) {\n write(`${JSON.stringify({ ok: true, update: result }, null, 2)}\\n`);\n return;\n }\n if (!result.updated) {\n write(`Already up to date: ${result.appId} ${result.version}\\n`);\n return;\n }\n write(`Updated ${result.name} (${result.appId}) ${result.previousVersion} -> ${result.version}\\n`);\n write(`Code: ${result.installDirectory}\\n`);\n };\n}\n"],"mappings":";;AAEA,IAAa,gBAAb,MAA2B;CACzB,YACE,sBAA+D,IAAI,wBAAwB,EAC3F;AADiB,OAAA,sBAAA;;CAGnB,MAAM,OAAO,WAMQ;EACnB,MAAM,EAAE,OAAO,SAAS,aAAa,MAAM,UAAU;EACrD,MAAM,SAAS,MAAM,KAAK,oBAAoB,OAAO,OAAO;GAC1D;GACA;GACD,CAAC;AACF,MAAI,MAAM;AACR,SAAM,GAAG,KAAK,UAAU;IAAE,IAAI;IAAM,QAAQ;IAAQ,EAAE,MAAM,EAAE,CAAC,IAAI;AACnE;;AAEF,MAAI,CAAC,OAAO,SAAS;AACnB,SAAM,uBAAuB,OAAO,MAAM,GAAG,OAAO,QAAQ,IAAI;AAChE;;AAEF,QAAM,WAAW,OAAO,KAAK,IAAI,OAAO,MAAM,IAAI,OAAO,gBAAgB,MAAM,OAAO,QAAQ,IAAI;AAClG,QAAM,SAAS,OAAO,iBAAiB,IAAI"}
@@ -13,4 +13,5 @@ declare class ValidatePublishCommand {
13
13
  }) => Promise<void>;
14
14
  }
15
15
  //#endregion
16
- export { ValidatePublishCommand };
16
+ export { ValidatePublishCommand };
17
+ //# sourceMappingURL=validate-publish.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-publish.controller.d.ts","names":[],"sources":["../../src/commands/validate-publish.controller.ts"],"mappings":";;;cAEa,sBAAA;EAAA,iBAEQ,iBAAA;cAAA,iBAAA,GAAmB,2BAAA;EAGtC,GAAA,GAAa,MAAA;IACX,YAAA;IACA,YAAA;IACA,IAAA;IACA,IAAA;IACA,KAAA,GAAQ,IAAA;EAAA,MACN,OAAA;AAAA"}
@@ -31,3 +31,5 @@ var ValidatePublishCommand = class {
31
31
  };
32
32
  //#endregion
33
33
  export { ValidatePublishCommand };
34
+
35
+ //# sourceMappingURL=validate-publish.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-publish.controller.js","names":[],"sources":["../../src/commands/validate-publish.controller.ts"],"sourcesContent":["import { AppPublishValidationService } from \"../publish/app-publish-validation.service.js\";\n\nexport class ValidatePublishCommand {\n constructor(\n private readonly validationService: AppPublishValidationService = new AppPublishValidationService(),\n ) {}\n\n run = async (params: {\n appDirectory: string;\n metadataPath?: string;\n mode: \"source\" | \"bundle\";\n json: boolean;\n write: (text: string) => void;\n }): Promise<void> => {\n const { appDirectory, metadataPath, mode, json, write } = params;\n const result = await this.validationService.validate({\n appDirectory,\n metadataPath,\n mode,\n });\n if (json) {\n write(`${JSON.stringify({ ok: true, validation: result }, null, 2)}\\n`);\n return;\n }\n write(`Publish validation ok for ${result.appId}@${result.version}\\n`);\n write(`Distribution mode: ${result.distributionMode}\\n`);\n write(`Main kind: ${result.mainKind}\\n`);\n write(`Main: ${result.mainEntryPath}\\n`);\n write(`Metadata: ${result.metadataPath}\\n`);\n write(`Bundle size: ${result.bundleSizeBytes} bytes\\n`);\n write(`Main entry size: ${result.mainEntrySizeBytes} bytes\\n`);\n write(`Bundle files (${result.bundleFilePaths.length}): ${result.bundleFilePaths.join(\", \")}\\n`);\n if (result.warnings.length > 0) {\n for (const warning of result.warnings) {\n write(`Warning [${warning.code}]: ${warning.message}\\n`);\n }\n }\n };\n}\n"],"mappings":";;AAEA,IAAa,yBAAb,MAAoC;CAClC,YACE,oBAAkE,IAAI,6BAA6B,EACnG;AADiB,OAAA,oBAAA;;CAGnB,MAAM,OAAO,WAMQ;EACnB,MAAM,EAAE,cAAc,cAAc,MAAM,MAAM,UAAU;EAC1D,MAAM,SAAS,MAAM,KAAK,kBAAkB,SAAS;GACnD;GACA;GACA;GACD,CAAC;AACF,MAAI,MAAM;AACR,SAAM,GAAG,KAAK,UAAU;IAAE,IAAI;IAAM,YAAY;IAAQ,EAAE,MAAM,EAAE,CAAC,IAAI;AACvE;;AAEF,QAAM,6BAA6B,OAAO,MAAM,GAAG,OAAO,QAAQ,IAAI;AACtE,QAAM,sBAAsB,OAAO,iBAAiB,IAAI;AACxD,QAAM,cAAc,OAAO,SAAS,IAAI;AACxC,QAAM,SAAS,OAAO,cAAc,IAAI;AACxC,QAAM,aAAa,OAAO,aAAa,IAAI;AAC3C,QAAM,gBAAgB,OAAO,gBAAgB,UAAU;AACvD,QAAM,oBAAoB,OAAO,mBAAmB,UAAU;AAC9D,QAAM,iBAAiB,OAAO,gBAAgB,OAAO,KAAK,OAAO,gBAAgB,KAAK,KAAK,CAAC,IAAI;AAChG,MAAI,OAAO,SAAS,SAAS,EAC3B,MAAK,MAAM,WAAW,OAAO,SAC3B,OAAM,YAAY,QAAQ,KAAK,KAAK,QAAQ,QAAQ,IAAI"}
@@ -24,4 +24,5 @@ declare class AppHostService {
24
24
  private handleRequest;
25
25
  }
26
26
  //#endregion
27
- export { AppHostHandle, AppHostService, AppHostStartOptions };
27
+ export { AppHostHandle, AppHostService, AppHostStartOptions };
28
+ //# sourceMappingURL=app-host.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-host.service.d.ts","names":[],"sources":["../../src/host/app-host.service.ts"],"mappings":";;;;KAMY,mBAAA;EACV,IAAA;EACA,IAAA;AAAA;AAAA,KAGU,aAAA;EACV,KAAA;EACA,GAAA;EACA,IAAA;EACA,IAAA;AAAA;AAAA,cAGW,cAAA;EAAA,iBAMQ,WAAA;EAAA,iBACA,wBAAA;EAAA,QANX,MAAA;EAAA,iBACS,YAAA;EAAA,iBACA,QAAA;cAGE,WAAA,EAAa,kBAAA,EACb,wBAAA,GAA2B,gCAAA;EAM9C,KAAA,GAAe,OAAA,EAAS,mBAAA,KAAsB,OAAA,CAAQ,aAAA;EA2BtD,IAAA,QAAiB,OAAA;EAAA,QAgBT,aAAA;AAAA"}
@@ -68,3 +68,5 @@ var AppHostService = class {
68
68
  };
69
69
  //#endregion
70
70
  export { AppHostService };
71
+
72
+ //# sourceMappingURL=app-host.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-host.service.js","names":[],"sources":["../../src/host/app-host.service.ts"],"sourcesContent":["import { createServer, type IncomingMessage, type Server, type ServerResponse } from \"node:http\";\nimport { HostBridgeServer } from \"../bridge/host-bridge.service.js\";\nimport type { AppInstanceService } from \"./app-instance.service.js\";\nimport { UiServerService } from \"../ui/ui-server.service.js\";\nimport type { WasmtimeWasiHttpComponentService } from \"../runtime/wasmtime-wasi-http-component.service.js\";\n\nexport type AppHostStartOptions = {\n host: string;\n port: number;\n};\n\nexport type AppHostHandle = {\n appId: string;\n url: string;\n host: string;\n port: number;\n};\n\nexport class AppHostService {\n private server?: Server;\n private readonly bridgeServer: HostBridgeServer;\n private readonly uiServer: UiServerService;\n\n constructor(\n private readonly appInstance: AppInstanceService,\n private readonly wasiHttpComponentService?: WasmtimeWasiHttpComponentService,\n ) {\n this.bridgeServer = new HostBridgeServer(appInstance);\n this.uiServer = new UiServerService(appInstance.bundle);\n }\n\n start = async (options: AppHostStartOptions): Promise<AppHostHandle> => {\n if (this.server) {\n throw new Error(\"应用宿主已经启动。\");\n }\n const server = createServer((request, response) => {\n void this.handleRequest(request, response);\n });\n this.server = server;\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(options.port, options.host, () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n const address = server.address();\n if (!address || typeof address === \"string\") {\n throw new Error(\"无法获取应用宿主监听地址。\");\n }\n return {\n appId: this.appInstance.bundle.manifest.id,\n url: `http://${address.address}:${address.port}`,\n host: address.address,\n port: address.port,\n };\n };\n\n stop = async (): Promise<void> => {\n if (!this.server) {\n return;\n }\n await new Promise<void>((resolve, reject) => {\n this.server?.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n this.server = undefined;\n };\n\n private handleRequest = async (\n request: IncomingMessage,\n response: ServerResponse,\n ): Promise<void> => {\n try {\n if (this.wasiHttpComponentService) {\n const backendHandled = await this.wasiHttpComponentService.handleRequest(request, response);\n if (backendHandled) {\n return;\n }\n }\n const bridgeHandled = await this.bridgeServer.handle(request, response);\n if (bridgeHandled) {\n return;\n }\n await this.uiServer.handle(request, response);\n } catch (error) {\n response.writeHead(500, {\n \"content-type\": \"application/json; charset=utf-8\",\n });\n response.end(\n JSON.stringify(\n {\n ok: false,\n error: {\n code: \"APP_HOST_ERROR\",\n message: error instanceof Error ? error.message : String(error),\n },\n },\n null,\n 2,\n ),\n );\n }\n };\n}\n"],"mappings":";;;;AAkBA,IAAa,iBAAb,MAA4B;CAC1B;CACA;CACA;CAEA,YACE,aACA,0BACA;AAFiB,OAAA,cAAA;AACA,OAAA,2BAAA;AAEjB,OAAK,eAAe,IAAI,iBAAiB,YAAY;AACrD,OAAK,WAAW,IAAI,gBAAgB,YAAY,OAAO;;CAGzD,QAAQ,OAAO,YAAyD;AACtE,MAAI,KAAK,OACP,OAAM,IAAI,MAAM,YAAY;EAE9B,MAAM,SAAS,cAAc,SAAS,aAAa;AAC5C,QAAK,cAAc,SAAS,SAAS;IAC1C;AACF,OAAK,SAAS;AACd,QAAM,IAAI,SAAe,SAAS,WAAW;AAC3C,UAAO,KAAK,SAAS,OAAO;AAC5B,UAAO,OAAO,QAAQ,MAAM,QAAQ,YAAY;AAC9C,WAAO,IAAI,SAAS,OAAO;AAC3B,aAAS;KACT;IACF;EACF,MAAM,UAAU,OAAO,SAAS;AAChC,MAAI,CAAC,WAAW,OAAO,YAAY,SACjC,OAAM,IAAI,MAAM,gBAAgB;AAElC,SAAO;GACL,OAAO,KAAK,YAAY,OAAO,SAAS;GACxC,KAAK,UAAU,QAAQ,QAAQ,GAAG,QAAQ;GAC1C,MAAM,QAAQ;GACd,MAAM,QAAQ;GACf;;CAGH,OAAO,YAA2B;AAChC,MAAI,CAAC,KAAK,OACR;AAEF,QAAM,IAAI,SAAe,SAAS,WAAW;AAC3C,QAAK,QAAQ,OAAO,UAAU;AAC5B,QAAI,OAAO;AACT,YAAO,MAAM;AACb;;AAEF,aAAS;KACT;IACF;AACF,OAAK,SAAS,KAAA;;CAGhB,gBAAwB,OACtB,SACA,aACkB;AAClB,MAAI;AACF,OAAI,KAAK;QACgB,MAAM,KAAK,yBAAyB,cAAc,SAAS,SAAS,CAEzF;;AAIJ,OADsB,MAAM,KAAK,aAAa,OAAO,SAAS,SAAS,CAErE;AAEF,SAAM,KAAK,SAAS,OAAO,SAAS,SAAS;WACtC,OAAO;AACd,YAAS,UAAU,KAAK,EACtB,gBAAgB,mCACjB,CAAC;AACF,YAAS,IACP,KAAK,UACH;IACE,IAAI;IACJ,OAAO;KACL,MAAM;KACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;KAChE;IACF,EACD,MACA,EACD,CACF"}
@@ -30,4 +30,5 @@ declare class AppInstanceService {
30
30
  private getPermissions;
31
31
  }
32
32
  //#endregion
33
- export { AppInstanceService, AppRunResult };
33
+ export { AppInstanceService, AppRunResult };
34
+ //# sourceMappingURL=app-instance.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-instance.service.d.ts","names":[],"sources":["../../src/host/app-instance.service.ts"],"mappings":";;;;;;;;KAaY,YAAA;EACV,MAAA;EACA,KAAA,EAAO,wBAAA;EACP,MAAA,EAAQ,aAAA;EACR,UAAA;AAAA;AAAA,cAGW,kBAAA;EAAA,SAIA,MAAA,EAAQ,iBAAA;EAAA,iBACA,kBAAA;EAAA,iBACA,UAAA;EAAA,iBACA,eAAA;EAAA,QANX,WAAA;cAGG,MAAA,EAAQ,iBAAA,EACA,kBAAA,GAAoB,qBAAA,EACpB,UAAA,GAAY,qBAAA,EACZ,eAAA,GAAiB,kBAAA;EAGpC,UAAA,GACE,gBAAA,EAAkB,mBAAA,EAClB,OAAA;IACE,KAAA;EAAA,MAED,OAAA;EAQH,iBAAA,QARU,kBAAA;EAYV,oBAAA,QAA2B,oBAAA;EAI3B,SAAA,GAAmB,MAAA,cAAkB,OAAA,CAAQ,YAAA;EAAA,QAuBrC,2BAAA;EAAA,QAiBA,uBAAA;EAAA,QA6BA,cAAA;AAAA"}
@@ -79,3 +79,5 @@ var AppInstanceService = class {
79
79
  };
80
80
  //#endregion
81
81
  export { AppInstanceService };
82
+
83
+ //# sourceMappingURL=app-instance.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-instance.service.js","names":[],"sources":["../../src/host/app-instance.service.ts"],"sourcesContent":["import { readdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { AppManifestBundle } from \"../manifest/app-manifest.types.js\";\nimport { AppManifestService } from \"../manifest/app-manifest.service.js\";\nimport { AppPermissionsService } from \"../permissions/app-permissions.service.js\";\nimport type {\n AppDocumentGrantMap,\n AppPermissionSummary,\n ResolvedPermissions,\n} from \"../permissions/app-permissions.types.js\";\nimport { WasmMainRunnerService } from \"../runtime/wasm-main-runner.service.js\";\nimport type { MainRunResult, WasmDocumentSummaryInput } from \"../runtime/main-runner.types.js\";\n\nexport type AppRunResult = {\n action: string;\n input: WasmDocumentSummaryInput;\n output: MainRunResult;\n observedAt: string;\n};\n\nexport class AppInstanceService {\n private permissions?: ResolvedPermissions;\n\n constructor(\n readonly bundle: AppManifestBundle,\n private readonly permissionsService: AppPermissionsService = new AppPermissionsService(),\n private readonly mainRunner: WasmMainRunnerService = new WasmMainRunnerService(),\n private readonly manifestService: AppManifestService = new AppManifestService(),\n ) {}\n\n initialize = async (\n documentGrantMap: AppDocumentGrantMap,\n context?: {\n appId?: string;\n },\n ): Promise<void> => {\n this.permissions = await this.permissionsService.resolve(\n this.bundle,\n documentGrantMap,\n context,\n );\n };\n\n summarizeManifest = () => {\n return this.manifestService.summarize(this.bundle);\n };\n\n summarizePermissions = (): AppPermissionSummary => {\n return this.permissionsService.summarize(this.bundle, this.getPermissions());\n };\n\n runAction = async (action?: string): Promise<AppRunResult> => {\n if (this.bundle.manifest.main.kind !== \"wasm\") {\n throw new Error(\"当前应用不支持 __napp/run action,请通过 /api/* 调用 WASI HTTP 后端。\");\n }\n const expectedAction = this.bundle.manifest.main.action;\n if (action && action !== expectedAction) {\n throw new Error(`当前应用只支持动作 ${expectedAction}。`);\n }\n\n const input = await this.collectDocumentSummaryInput();\n const output = await this.mainRunner.runDocumentSummary({\n bundle: this.bundle,\n input,\n });\n\n return {\n action: expectedAction,\n input,\n output,\n observedAt: new Date().toISOString(),\n };\n };\n\n private collectDocumentSummaryInput = async (): Promise<WasmDocumentSummaryInput> => {\n const permissions = this.getPermissions();\n let documentCount = 0;\n let textBytes = 0;\n\n for (const grant of permissions.documentAccess) {\n const scopeSummary = await this.collectDirectorySummary(grant.path);\n documentCount += scopeSummary.documentCount;\n textBytes += scopeSummary.textBytes;\n }\n\n return {\n documentCount,\n textBytes,\n };\n };\n\n private collectDirectorySummary = async (\n directoryPath: string,\n ): Promise<WasmDocumentSummaryInput> => {\n const entries = await readdir(directoryPath, { withFileTypes: true });\n let documentCount = 0;\n let textBytes = 0;\n\n for (const entry of entries) {\n const entryPath = path.join(directoryPath, entry.name);\n if (entry.isDirectory()) {\n const childSummary = await this.collectDirectorySummary(entryPath);\n documentCount += childSummary.documentCount;\n textBytes += childSummary.textBytes;\n continue;\n }\n if (!entry.isFile()) {\n continue;\n }\n const content = await readFile(entryPath, \"utf-8\");\n documentCount += 1;\n textBytes += Buffer.byteLength(content, \"utf-8\");\n }\n\n return {\n documentCount,\n textBytes,\n };\n };\n\n private getPermissions = (): ResolvedPermissions => {\n if (!this.permissions) {\n throw new Error(\"应用实例尚未初始化权限。\");\n }\n return this.permissions;\n };\n}\n"],"mappings":";;;;;;AAoBA,IAAa,qBAAb,MAAgC;CAC9B;CAEA,YACE,QACA,qBAA6D,IAAI,uBAAuB,EACxF,aAAqD,IAAI,uBAAuB,EAChF,kBAAuD,IAAI,oBAAoB,EAC/E;AAJS,OAAA,SAAA;AACQ,OAAA,qBAAA;AACA,OAAA,aAAA;AACA,OAAA,kBAAA;;CAGnB,aAAa,OACX,kBACA,YAGkB;AAClB,OAAK,cAAc,MAAM,KAAK,mBAAmB,QAC/C,KAAK,QACL,kBACA,QACD;;CAGH,0BAA0B;AACxB,SAAO,KAAK,gBAAgB,UAAU,KAAK,OAAO;;CAGpD,6BAAmD;AACjD,SAAO,KAAK,mBAAmB,UAAU,KAAK,QAAQ,KAAK,gBAAgB,CAAC;;CAG9E,YAAY,OAAO,WAA2C;AAC5D,MAAI,KAAK,OAAO,SAAS,KAAK,SAAS,OACrC,OAAM,IAAI,MAAM,wDAAwD;EAE1E,MAAM,iBAAiB,KAAK,OAAO,SAAS,KAAK;AACjD,MAAI,UAAU,WAAW,eACvB,OAAM,IAAI,MAAM,aAAa,eAAe,GAAG;EAGjD,MAAM,QAAQ,MAAM,KAAK,6BAA6B;AAMtD,SAAO;GACL,QAAQ;GACR;GACA,QARa,MAAM,KAAK,WAAW,mBAAmB;IACtD,QAAQ,KAAK;IACb;IACD,CAAC;GAMA,6BAAY,IAAI,MAAM,EAAC,aAAa;GACrC;;CAGH,8BAAsC,YAA+C;EACnF,MAAM,cAAc,KAAK,gBAAgB;EACzC,IAAI,gBAAgB;EACpB,IAAI,YAAY;AAEhB,OAAK,MAAM,SAAS,YAAY,gBAAgB;GAC9C,MAAM,eAAe,MAAM,KAAK,wBAAwB,MAAM,KAAK;AACnE,oBAAiB,aAAa;AAC9B,gBAAa,aAAa;;AAG5B,SAAO;GACL;GACA;GACD;;CAGH,0BAAkC,OAChC,kBACsC;EACtC,MAAM,UAAU,MAAM,QAAQ,eAAe,EAAE,eAAe,MAAM,CAAC;EACrE,IAAI,gBAAgB;EACpB,IAAI,YAAY;AAEhB,OAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,YAAY,KAAK,KAAK,eAAe,MAAM,KAAK;AACtD,OAAI,MAAM,aAAa,EAAE;IACvB,MAAM,eAAe,MAAM,KAAK,wBAAwB,UAAU;AAClE,qBAAiB,aAAa;AAC9B,iBAAa,aAAa;AAC1B;;AAEF,OAAI,CAAC,MAAM,QAAQ,CACjB;GAEF,MAAM,UAAU,MAAM,SAAS,WAAW,QAAQ;AAClD,oBAAiB;AACjB,gBAAa,OAAO,WAAW,SAAS,QAAQ;;AAGlD,SAAO;GACL;GACA;GACD;;CAGH,uBAAoD;AAClD,MAAI,CAAC,KAAK,YACR,OAAM,IAAI,MAAM,eAAe;AAEjC,SAAO,KAAK"}
@@ -37,4 +37,5 @@ declare class AppInstallationService {
37
37
  private materializeDistribution;
38
38
  }
39
39
  //#endregion
40
- export { AppInstallationService };
40
+ export { AppInstallationService };
41
+ //# sourceMappingURL=app-installation.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-installation.service.d.ts","names":[],"sources":["../../src/install/app-installation.service.ts"],"mappings":";;;;;;;;;;;cAoBa,sBAAA;EAAA,iBAEQ,cAAA;EAAA,iBACA,aAAA;EAAA,iBACA,eAAA;EAAA,iBACA,YAAA;EAAA,iBACA,eAAA;EAAA,iBACA,qBAAA;EAAA,iBAGA,oBAAA;cARA,cAAA,GAAgB,cAAA,EAChB,aAAA,GAAe,gBAAA,EACf,eAAA,GAAiB,kBAAA,EACjB,YAAA,GAAc,eAAA,EACd,eAAA,GAAiB,kBAAA,EACjB,qBAAA,GAAuB,wBAAA,EAGvB,oBAAA,GAAsB,8BAAA;EAKzC,OAAA,GACE,SAAA,UACA,OAAA;IACE,WAAA;EAAA,MAED,OAAA,CAAQ,gBAAA;EA6FX,MAAA,GACE,KAAA,UACA,OAAA;IACE,OAAA;IACA,WAAA;EAAA,MAED,OAAA,CAAQ,eAAA;EA8CX,SAAA,GACE,KAAA,UACA,SAAA,cACC,OAAA,CAAQ,kBAAA;EAuBX,IAAA,QAAiB,OAAA,CAAQ,oBAAA;EAazB,IAAA,GAAc,KAAA,aAAgB,OAAA,CAAQ,aAAA;EA+BtC,aAAA,GACE,YAAA,UACA,wBAAA,EAA0B,mBAAA,KACzB,OAAA,CAAQ,mBAAA;EA2BX,aAAA,GACE,KAAA,sBACA,gBAAA,EAAkB,mBAAA,KACjB,OAAA;EAAA,QAOK,oBAAA;EAAA,QAsDA,qBAAA;EAAA,QAiDA,iBAAA;EAAA,QAkBA,aAAA;EAAA,QAQA,uBAAA;AAAA"}
@@ -272,3 +272,5 @@ var AppInstallationService = class {
272
272
  };
273
273
  //#endregion
274
274
  export { AppInstallationService };
275
+
276
+ //# sourceMappingURL=app-installation.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-installation.service.js","names":[],"sources":["../../src/install/app-installation.service.ts"],"sourcesContent":["import { access, cp, mkdir, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { AppBundleService } from \"../bundle/app-bundle.service.js\";\nimport { AppManifestService } from \"../manifest/app-manifest.service.js\";\nimport { AppHomeService } from \"../paths/app-home.service.js\";\nimport { AppBuildService } from \"../runtime/app-build.service.js\";\nimport type { AppDistributionMode } from \"../bundle/app-bundle.types.js\";\nimport type { AppDocumentGrantMap } from \"../permissions/app-permissions.types.js\";\nimport { AppRegistryConfigService } from \"../registry/app-registry-config.service.js\";\nimport { AppRemoteRegistryClientService } from \"../registry/app-remote-registry-client.service.js\";\nimport { AppRegistryService } from \"../registry/app-registry.service.js\";\nimport type {\n AppInfoResult,\n AppInstallResult,\n AppLaunchResolution,\n AppUpdateResult,\n AppUninstallResult,\n InstalledAppListItem,\n} from \"./app-installation.types.js\";\n\nexport class AppInstallationService {\n constructor(\n private readonly appHomeService: AppHomeService = new AppHomeService(),\n private readonly bundleService: AppBundleService = new AppBundleService(),\n private readonly manifestService: AppManifestService = new AppManifestService(),\n private readonly buildService: AppBuildService = new AppBuildService(),\n private readonly registryService: AppRegistryService = new AppRegistryService(appHomeService),\n private readonly registryConfigService: AppRegistryConfigService = new AppRegistryConfigService(\n appHomeService,\n ),\n private readonly remoteRegistryClient: AppRemoteRegistryClientService = new AppRemoteRegistryClientService(\n new AppRegistryConfigService(appHomeService),\n ),\n ) {}\n\n install = async (\n appSource: string,\n options?: {\n registryUrl?: string;\n },\n ): Promise<AppInstallResult> => {\n const source = await this.resolveInstallSource(appSource, options?.registryUrl);\n const tempDirectory = await this.appHomeService.createTemporaryDirectory(\"napp-install-\");\n try {\n const bundlePath =\n source.kind === \"directory\"\n ? (await this.bundleService.packAppDirectory({\n appDirectory: source.appDirectory,\n outputPath: path.join(tempDirectory, \"app.napp\"),\n })).bundlePath\n : source.kind === \"bundle\"\n ? source.bundlePath\n : (\n await this.remoteRegistryClient.downloadBundle({\n resolution: source.registryResolution,\n targetDirectory: tempDirectory,\n })\n ).bundlePath;\n const extractedDirectory = path.join(tempDirectory, \"bundle\");\n const extractedMetadata = await this.bundleService.extractBundle({\n bundlePath,\n targetDirectory: extractedDirectory,\n });\n await this.materializeDistribution({\n appDirectory: extractedDirectory,\n distributionMode: extractedMetadata.metadata.distributionMode,\n });\n const manifestBundle = await this.manifestService.load(extractedDirectory);\n const installDirectory = this.appHomeService.getInstallDirectory(\n manifestBundle.manifest.id,\n manifestBundle.manifest.version,\n );\n if (\n source.kind === \"registry\" &&\n manifestBundle.manifest.id !== source.registryResolution.appId\n ) {\n throw new Error(\n `bundle manifest.appId 与 registry 请求不一致:期望 ${source.registryResolution.appId},实际 ${manifestBundle.manifest.id}`,\n );\n }\n const dataDirectory = this.appHomeService.getAppDataDirectory(manifestBundle.manifest.id);\n await rm(installDirectory, { recursive: true, force: true });\n await mkdir(path.dirname(installDirectory), { recursive: true });\n await mkdir(dataDirectory, { recursive: true });\n await cp(extractedDirectory, installDirectory, { recursive: true });\n const registryRecord = await this.registryService.upsertInstallation({\n appId: manifestBundle.manifest.id,\n name: manifestBundle.manifest.name,\n description: manifestBundle.manifest.description,\n version: manifestBundle.manifest.version,\n installDirectory,\n dataDirectory,\n sourceKind: source.kind,\n distributionMode:\n source.kind === \"registry\"\n ? source.registryResolution.distributionMode\n : extractedMetadata.metadata.distributionMode,\n sourceRef: source.sourceRef,\n installedAt: new Date().toISOString(),\n permissions: manifestBundle.manifest.permissions ?? {},\n registryUrl:\n source.kind === \"registry\" ? source.registryResolution.registryUrl : undefined,\n bundleUrl:\n source.kind === \"registry\" ? source.registryResolution.bundleUrl : undefined,\n sha256: source.kind === \"registry\" ? source.registryResolution.sha256 : undefined,\n publisher:\n source.kind === \"registry\" ? source.registryResolution.publisher : undefined,\n });\n return {\n appId: registryRecord.appId,\n name: registryRecord.name,\n version: registryRecord.activeVersion,\n installDirectory,\n dataDirectory,\n sourceKind: source.kind,\n sourceRef: source.sourceRef,\n distributionMode:\n registryRecord.installedVersions[registryRecord.activeVersion]?.distributionMode,\n permissions:\n registryRecord.installedVersions[registryRecord.activeVersion]?.permissions ?? {},\n registryUrl:\n registryRecord.installedVersions[registryRecord.activeVersion]?.registryUrl,\n bundleUrl:\n registryRecord.installedVersions[registryRecord.activeVersion]?.bundleUrl,\n sha256: registryRecord.installedVersions[registryRecord.activeVersion]?.sha256,\n publisher:\n registryRecord.installedVersions[registryRecord.activeVersion]?.publisher,\n };\n } finally {\n await rm(tempDirectory, { recursive: true, force: true });\n }\n };\n\n update = async (\n appId: string,\n options?: {\n version?: string;\n registryUrl?: string;\n },\n ): Promise<AppUpdateResult> => {\n const appRecord = await this.registryService.getApp(appId);\n if (!appRecord) {\n throw new Error(`未找到已安装应用:${appId}`);\n }\n const activeVersionRecord = appRecord.installedVersions[appRecord.activeVersion];\n const registryUrl =\n options?.registryUrl ??\n activeVersionRecord?.registryUrl ??\n (await this.registryConfigService.getSnapshot()).currentUrl;\n const resolution = await this.remoteRegistryClient.resolve({\n appId,\n version: options?.version,\n registryUrl,\n });\n if (resolution.version === appRecord.activeVersion) {\n if (!activeVersionRecord) {\n throw new Error(`已安装应用缺少激活版本:${appId}`);\n }\n return {\n appId: appRecord.appId,\n name: appRecord.name,\n version: appRecord.activeVersion,\n previousVersion: appRecord.activeVersion,\n installDirectory: activeVersionRecord.installDirectory,\n dataDirectory: appRecord.dataDirectory,\n sourceKind: activeVersionRecord.sourceKind,\n sourceRef: activeVersionRecord.sourceRef,\n permissions: activeVersionRecord.permissions,\n registryUrl: activeVersionRecord.registryUrl,\n bundleUrl: activeVersionRecord.bundleUrl,\n sha256: activeVersionRecord.sha256,\n publisher: activeVersionRecord.publisher,\n updated: false,\n };\n }\n const installResult = await this.install(`${appId}@${resolution.version}`, {\n registryUrl,\n });\n return {\n ...installResult,\n previousVersion: appRecord.activeVersion,\n updated: true,\n };\n };\n\n uninstall = async (\n appId: string,\n purgeData: boolean,\n ): Promise<AppUninstallResult> => {\n const appRecord = await this.registryService.removeApp(appId);\n if (!appRecord) {\n throw new Error(`未找到已安装应用:${appId}`);\n }\n const removedVersions = Object.keys(appRecord.installedVersions).sort((left, right) =>\n left.localeCompare(right),\n );\n await Promise.all(\n Object.values(appRecord.installedVersions).map((versionRecord) =>\n rm(versionRecord.installDirectory, { recursive: true, force: true }),\n ),\n );\n if (purgeData) {\n await rm(appRecord.dataDirectory, { recursive: true, force: true });\n }\n return {\n appId,\n removedVersions,\n dataRemoved: purgeData,\n };\n };\n\n list = async (): Promise<InstalledAppListItem[]> => {\n const appRecords = await this.registryService.listApps();\n return appRecords.map((appRecord) => ({\n appId: appRecord.appId,\n name: appRecord.name,\n activeVersion: appRecord.activeVersion,\n sourceKind:\n appRecord.installedVersions[appRecord.activeVersion]?.sourceKind ?? \"directory\",\n distributionMode:\n appRecord.installedVersions[appRecord.activeVersion]?.distributionMode,\n }));\n };\n\n info = async (appId: string): Promise<AppInfoResult> => {\n const appRecord = await this.registryService.getApp(appId);\n if (!appRecord) {\n throw new Error(`未找到已安装应用:${appId}`);\n }\n const installedVersions = Object.values(appRecord.installedVersions).sort((left, right) =>\n left.version.localeCompare(right.version),\n );\n return {\n appId: appRecord.appId,\n name: appRecord.name,\n description: appRecord.description,\n activeVersion: appRecord.activeVersion,\n dataDirectory: appRecord.dataDirectory,\n installedVersions: installedVersions.map((versionRecord) => ({\n version: versionRecord.version,\n installDirectory: versionRecord.installDirectory,\n sourceKind: versionRecord.sourceKind,\n distributionMode: versionRecord.distributionMode,\n sourceRef: versionRecord.sourceRef,\n installedAt: versionRecord.installedAt,\n permissions: versionRecord.permissions,\n registryUrl: versionRecord.registryUrl,\n bundleUrl: versionRecord.bundleUrl,\n sha256: versionRecord.sha256,\n publisher: versionRecord.publisher,\n })),\n grants: appRecord.grants,\n };\n };\n\n resolveLaunch = async (\n appReference: string,\n explicitDocumentGrantMap: AppDocumentGrantMap,\n ): Promise<AppLaunchResolution> => {\n const sourceType = await this.detectLocalSourceType(appReference, false);\n if (sourceType.kind === \"directory\") {\n return {\n appDirectory: sourceType.appDirectory,\n documentGrantMap: explicitDocumentGrantMap,\n };\n }\n const appRecord = await this.registryService.getApp(appReference);\n if (!appRecord) {\n throw new Error(`未找到应用目录,也未找到已安装应用:${appReference}`);\n }\n const activeVersion = appRecord.installedVersions[appRecord.activeVersion];\n if (!activeVersion) {\n throw new Error(`已安装应用缺少激活版本:${appReference}`);\n }\n return {\n appDirectory: activeVersion.installDirectory,\n appId: appRecord.appId,\n dataDirectory: appRecord.dataDirectory,\n documentGrantMap: {\n ...appRecord.grants,\n ...explicitDocumentGrantMap,\n },\n };\n };\n\n persistGrants = async (\n appId: string | undefined,\n documentGrantMap: AppDocumentGrantMap,\n ): Promise<void> => {\n if (!appId || Object.keys(documentGrantMap).length === 0) {\n return;\n }\n await this.registryService.updateGrants(appId, documentGrantMap);\n };\n\n private resolveInstallSource = async (\n appSource: string,\n registryUrl?: string,\n ): Promise<\n | {\n kind: \"directory\";\n appDirectory: string;\n sourceRef: string;\n }\n | {\n kind: \"bundle\";\n bundlePath: string;\n sourceRef: string;\n }\n | {\n kind: \"registry\";\n sourceRef: string;\n registryResolution: Awaited<ReturnType<AppRemoteRegistryClientService[\"resolve\"]>>;\n }\n > => {\n const localSource = await this.detectLocalSourceType(appSource);\n if (localSource.kind === \"directory\") {\n return {\n kind: \"directory\",\n appDirectory: localSource.appDirectory,\n sourceRef: localSource.appDirectory,\n };\n }\n if (localSource.kind === \"bundle\") {\n return {\n kind: \"bundle\",\n bundlePath: localSource.bundlePath,\n sourceRef: localSource.bundlePath,\n };\n }\n const registrySpec = this.parseRegistrySpec(appSource);\n if (!registrySpec) {\n if (this.looksLikePath(appSource)) {\n throw new Error(`本地安装源不存在:${appSource}`);\n }\n throw new Error(`无法识别安装源:${appSource}`);\n }\n const registryResolution = await this.remoteRegistryClient.resolve({\n appId: registrySpec.appId,\n version: registrySpec.version,\n registryUrl,\n });\n return {\n kind: \"registry\",\n sourceRef: `${registryResolution.appId}@${registryResolution.version}`,\n registryResolution,\n };\n };\n\n private detectLocalSourceType = async (\n sourcePath: string,\n allowBundle: boolean = true,\n ): Promise<\n | {\n kind: \"directory\";\n appDirectory: string;\n }\n | {\n kind: \"bundle\";\n bundlePath: string;\n }\n | {\n kind: \"missing\";\n }\n > => {\n const normalizedSource = path.resolve(sourcePath);\n try {\n await access(normalizedSource);\n const manifestBundle = await this.manifestService.load(normalizedSource);\n if (manifestBundle.appDirectory) {\n return {\n kind: \"directory\",\n appDirectory: normalizedSource,\n };\n }\n } catch {\n if (allowBundle && normalizedSource.endsWith(\".napp\")) {\n try {\n await access(normalizedSource);\n return {\n kind: \"bundle\",\n bundlePath: normalizedSource,\n };\n } catch {\n return {\n kind: \"missing\",\n };\n }\n }\n return {\n kind: \"missing\",\n };\n }\n return {\n kind: \"missing\",\n };\n };\n\n private parseRegistrySpec = (\n appSource: string,\n ): {\n appId: string;\n version?: string;\n } | undefined => {\n const match = /^(?<appId>[a-z0-9][a-z0-9._-]*)(?:@(?<version>[A-Za-z0-9._+-]+))?$/i.exec(\n appSource.trim(),\n );\n if (!match?.groups?.appId) {\n return undefined;\n }\n return {\n appId: match.groups.appId,\n version: match.groups.version,\n };\n };\n\n private looksLikePath = (appSource: string): boolean => {\n return (\n appSource.startsWith(\".\") ||\n appSource.startsWith(\"/\") ||\n appSource.includes(path.sep)\n );\n };\n\n private materializeDistribution = async (params: {\n appDirectory: string;\n distributionMode: AppDistributionMode;\n }): Promise<void> => {\n if (params.distributionMode !== \"source\") {\n return;\n }\n const manifestBundle = await this.manifestService.load(params.appDirectory);\n if (manifestBundle.manifest.main.kind !== \"wasi-http-component\") {\n return;\n }\n await this.buildService.build({\n appDirectory: params.appDirectory,\n install: true,\n });\n };\n}\n"],"mappings":"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"}
@@ -64,4 +64,5 @@ type AppUpdateResult = AppInstallResult & {
64
64
  updated: boolean;
65
65
  };
66
66
  //#endregion
67
- export { AppInfoResult, AppInstallResult, AppLaunchResolution, AppUninstallResult, AppUpdateResult, InstalledAppListItem };
67
+ export { AppInfoResult, AppInstallResult, AppLaunchResolution, AppUninstallResult, AppUpdateResult, InstalledAppListItem };
68
+ //# sourceMappingURL=app-installation.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-installation.types.d.ts","names":[],"sources":["../../src/install/app-installation.types.ts"],"mappings":";;;;;;;KAMY,gBAAA;EACV,KAAA;EACA,IAAA;EACA,OAAA;EACA,gBAAA;EACA,aAAA;EACA,UAAA,EAAY,oBAAA;EACZ,gBAAA,GAAmB,mBAAA;EACnB,SAAA;EACA,WAAA,EAAa,cAAA;EACb,WAAA;EACA,SAAA;EACA,MAAA;EACA,SAAA,GAAY,YAAA;AAAA;AAAA,KAGF,aAAA;EACV,KAAA;EACA,IAAA;EACA,WAAA;EACA,aAAA;EACA,aAAA;EACA,iBAAA,EAAmB,KAAA;IACjB,OAAA;IACA,gBAAA;IACA,UAAA,EAAY,oBAAA;IACZ,gBAAA,GAAmB,mBAAA;IACnB,SAAA;IACA,WAAA;IACA,WAAA,EAAa,cAAA;IACb,WAAA;IACA,SAAA;IACA,MAAA;IACA,SAAA,GAAY,YAAA;EAAA;EAEd,MAAA,EAAQ,mBAAA;AAAA;AAAA,KAGE,oBAAA;EACV,KAAA;EACA,IAAA;EACA,aAAA;EACA,UAAA,EAAY,oBAAA;EACZ,gBAAA,GAAmB,mBAAA;AAAA;AAAA,KAGT,kBAAA;EACV,KAAA;EACA,eAAA;EACA,WAAA;AAAA;AAAA,KAGU,mBAAA;EACV,YAAA;EACA,KAAA;EACA,aAAA;EACA,gBAAA,EAAkB,mBAAA;AAAA;AAAA,KAGR,eAAA,GAAkB,gBAAA;EAC5B,eAAA;EACA,OAAA;AAAA"}
package/dist/main.js CHANGED
@@ -7,3 +7,5 @@ new AppRuntimeCliService().run().catch((error) => {
7
7
  });
8
8
  //#endregion
9
9
  export {};
10
+
11
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { AppRuntimeCliService } from \"./cli/app-runtime-cli.service.js\";\n\nvoid new AppRuntimeCliService().run().catch((error) => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exit(1);\n});\n"],"mappings":";;;AAIK,IAAI,sBAAsB,CAAC,KAAK,CAAC,OAAO,UAAU;AACrD,SAAQ,OAAO,MAAM,GAAG,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC,IAAI;AACnF,SAAQ,KAAK,EAAE;EACf"}
@@ -20,4 +20,5 @@ declare class AppManifestService {
20
20
  private readBoolean;
21
21
  }
22
22
  //#endregion
23
- export { AppManifestService };
23
+ export { AppManifestService };
24
+ //# sourceMappingURL=app-manifest.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-manifest.service.d.ts","names":[],"sources":["../../src/manifest/app-manifest.service.ts"],"mappings":";;;cAUa,kBAAA;EACX,IAAA,GAAc,YAAA,aAAuB,OAAA,CAAQ,iBAAA;EAiC7C,SAAA,GAAa,MAAA,EAAQ,iBAAA,KAAoB,kBAAA;EAAA,QAiBjC,aAAA;EAAA,QA0BA,SAAA;EAAA,QAoBA,OAAA;EAAA,QAOA,gBAAA;EAAA,QAaA,mBAAA;EAAA,QA+BA,gBAAA;EAAA,QAeA,YAAA;EAAA,QAeA,iBAAA;EAAA,QAeA,kBAAA;EAAA,QAiBA,YAAA;EAAA,QAOA,kBAAA;EAAA,QAOA,kBAAA;EAAA,QAOA,UAAA;EAAA,QAOA,WAAA;AAAA"}
@@ -143,3 +143,5 @@ var AppManifestService = class {
143
143
  };
144
144
  //#endregion
145
145
  export { AppManifestService };
146
+
147
+ //# sourceMappingURL=app-manifest.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-manifest.service.js","names":[],"sources":["../../src/manifest/app-manifest.service.ts"],"sourcesContent":["import { access, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type {\n AppDocumentAccessScope,\n AppManifest,\n AppManifestBundle,\n AppManifestSummary,\n AppPermissions,\n} from \"./app-manifest.types.js\";\n\nexport class AppManifestService {\n load = async (appDirectory: string): Promise<AppManifestBundle> => {\n const normalizedDirectory = path.resolve(appDirectory);\n const manifestPath = path.join(normalizedDirectory, \"manifest.json\");\n const rawManifest = JSON.parse(await readFile(manifestPath, \"utf-8\")) as unknown;\n const manifest = this.parseManifest(rawManifest);\n const mainEntryPath = await this.assertResolvedFile(\n normalizedDirectory,\n manifest.main.entry,\n \"main.entry\",\n );\n const uiEntryPath = await this.assertResolvedFile(\n normalizedDirectory,\n manifest.ui.entry,\n \"ui.entry\",\n );\n const uiDirectoryPath = path.dirname(uiEntryPath);\n const assetsDirectoryPath = path.join(normalizedDirectory, \"assets\");\n const iconPath = manifest.icon\n ? await this.assertResolvedFile(normalizedDirectory, manifest.icon, \"icon\")\n : undefined;\n\n return {\n appDirectory: normalizedDirectory,\n manifestPath,\n manifest,\n mainEntryPath,\n uiEntryPath,\n uiDirectoryPath,\n assetsDirectoryPath,\n iconPath,\n };\n };\n\n summarize = (bundle: AppManifestBundle): AppManifestSummary => {\n const permissions = bundle.manifest.permissions ?? {};\n return {\n id: bundle.manifest.id,\n name: bundle.manifest.name,\n version: bundle.manifest.version,\n description: bundle.manifest.description,\n mainKind: bundle.manifest.main.kind,\n action: bundle.manifest.main.kind === \"wasm\" ? bundle.manifest.main.action : undefined,\n manifestPath: bundle.manifestPath,\n mainEntryPath: bundle.mainEntryPath,\n uiEntryPath: bundle.uiEntryPath,\n iconPath: bundle.iconPath,\n permissions,\n };\n };\n\n private parseManifest = (rawManifest: unknown): AppManifest => {\n if (!rawManifest || typeof rawManifest !== \"object\" || Array.isArray(rawManifest)) {\n throw new Error(\"manifest.json 必须是一个对象。\");\n }\n\n const candidate = rawManifest as Record<string, unknown>;\n const schemaVersion = this.readNumber(candidate.schemaVersion, \"schemaVersion\");\n if (schemaVersion !== 1) {\n throw new Error(\"当前只支持 schemaVersion = 1。\");\n }\n\n const permissions = this.parsePermissions(candidate.permissions);\n\n return {\n schemaVersion: 1,\n id: this.readRequiredString(candidate.id, \"id\"),\n name: this.readRequiredString(candidate.name, \"name\"),\n version: this.readRequiredString(candidate.version, \"version\"),\n description: this.readOptionalString(candidate.description, \"description\"),\n icon: this.readOptionalString(candidate.icon, \"icon\"),\n main: this.parseMain(candidate.main),\n ui: this.parseUi(candidate.ui),\n permissions,\n };\n };\n\n private parseMain = (rawMain: unknown): AppManifest[\"main\"] => {\n const candidate = this.assertObject(rawMain, \"main\");\n const kind = this.readRequiredString(candidate.kind, \"main.kind\");\n if (kind === \"wasm\") {\n return {\n kind: \"wasm\",\n entry: this.readRequiredString(candidate.entry, \"main.entry\"),\n export: this.readRequiredString(candidate.export, \"main.export\"),\n action: this.readRequiredString(candidate.action, \"main.action\"),\n };\n }\n if (kind === \"wasi-http-component\") {\n return {\n kind: \"wasi-http-component\",\n entry: this.readRequiredString(candidate.entry, \"main.entry\"),\n };\n }\n throw new Error(\"当前 main.kind 只支持 wasm 或 wasi-http-component。\");\n };\n\n private parseUi = (rawUi: unknown): AppManifest[\"ui\"] => {\n const candidate = this.assertObject(rawUi, \"ui\");\n return {\n entry: this.readRequiredString(candidate.entry, \"ui.entry\"),\n };\n };\n\n private parsePermissions = (rawPermissions: unknown): AppPermissions | undefined => {\n if (rawPermissions === undefined) {\n return undefined;\n }\n const candidate = this.assertObject(rawPermissions, \"permissions\");\n return {\n documentAccess: this.parseDocumentAccess(candidate.documentAccess),\n allowedDomains: this.parseStringArray(candidate.allowedDomains, \"permissions.allowedDomains\"),\n storage: this.parseStorage(candidate.storage),\n capabilities: this.parseCapabilities(candidate.capabilities),\n };\n };\n\n private parseDocumentAccess = (\n rawDocumentAccess: unknown,\n ): AppDocumentAccessScope[] | undefined => {\n if (rawDocumentAccess === undefined) {\n return undefined;\n }\n if (!Array.isArray(rawDocumentAccess)) {\n throw new Error(\"permissions.documentAccess 必须是数组。\");\n }\n return rawDocumentAccess.map((scope, index) => {\n const candidate = this.assertObject(scope, `permissions.documentAccess[${index}]`);\n const mode = this.readRequiredString(\n candidate.mode,\n `permissions.documentAccess[${index}].mode`,\n );\n if (mode !== \"read\" && mode !== \"read-write\") {\n throw new Error(\n `permissions.documentAccess[${index}].mode 只支持 read 或 read-write。`,\n );\n }\n return {\n id: this.readRequiredString(candidate.id, `permissions.documentAccess[${index}].id`),\n mode,\n description: this.readOptionalString(\n candidate.description,\n `permissions.documentAccess[${index}].description`,\n ),\n };\n });\n };\n\n private parseStringArray = (\n rawValue: unknown,\n fieldName: string,\n ): string[] | undefined => {\n if (rawValue === undefined) {\n return undefined;\n }\n if (!Array.isArray(rawValue)) {\n throw new Error(`${fieldName} 必须是字符串数组。`);\n }\n return rawValue.map((item, index) =>\n this.readRequiredString(item, `${fieldName}[${index}]`),\n );\n };\n\n private parseStorage = (\n rawStorage: unknown,\n ): AppPermissions[\"storage\"] | undefined => {\n if (rawStorage === undefined) {\n return undefined;\n }\n if (typeof rawStorage === \"boolean\") {\n return rawStorage;\n }\n const candidate = this.assertObject(rawStorage, \"permissions.storage\");\n return {\n namespace: this.readOptionalString(candidate.namespace, \"permissions.storage.namespace\"),\n };\n };\n\n private parseCapabilities = (\n rawCapabilities: unknown,\n ): AppPermissions[\"capabilities\"] | undefined => {\n if (rawCapabilities === undefined) {\n return undefined;\n }\n const candidate = this.assertObject(rawCapabilities, \"permissions.capabilities\");\n return {\n hostBridge:\n candidate.hostBridge === undefined\n ? undefined\n : this.readBoolean(candidate.hostBridge, \"permissions.capabilities.hostBridge\"),\n };\n };\n\n private assertResolvedFile = async (\n appDirectory: string,\n relativePath: string,\n fieldName: string,\n ): Promise<string> => {\n if (path.isAbsolute(relativePath)) {\n throw new Error(`${fieldName} 必须使用应用目录内的相对路径。`);\n }\n const resolvedPath = path.resolve(appDirectory, relativePath);\n const relative = path.relative(appDirectory, resolvedPath);\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(`${fieldName} 不能指向应用目录之外。`);\n }\n await access(resolvedPath);\n return resolvedPath;\n };\n\n private assertObject = (value: unknown, fieldName: string): Record<string, unknown> => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`${fieldName} 必须是对象。`);\n }\n return value as Record<string, unknown>;\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 = (value: unknown, fieldName: string): string | undefined => {\n if (value === undefined) {\n return undefined;\n }\n return this.readRequiredString(value, fieldName);\n };\n\n private readNumber = (value: unknown, fieldName: string): number => {\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new Error(`${fieldName} 必须是数字。`);\n }\n return value;\n };\n\n private readBoolean = (value: unknown, fieldName: string): boolean => {\n if (typeof value !== \"boolean\") {\n throw new Error(`${fieldName} 必须是布尔值。`);\n }\n return value;\n };\n}\n"],"mappings":"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"}
@@ -64,4 +64,5 @@ type AppManifestSummary = {
64
64
  permissions: AppPermissions;
65
65
  };
66
66
  //#endregion
67
- export { AppCoreWasmMainManifest, AppDocumentAccessMode, AppDocumentAccessScope, AppMainManifest, AppManifest, AppManifestBundle, AppManifestSummary, AppPermissions, AppUiManifest, AppWasiHttpComponentMainManifest };
67
+ export { AppCoreWasmMainManifest, AppDocumentAccessMode, AppDocumentAccessScope, AppMainManifest, AppManifest, AppManifestBundle, AppManifestSummary, AppPermissions, AppUiManifest, AppWasiHttpComponentMainManifest };
68
+ //# sourceMappingURL=app-manifest.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-manifest.types.d.ts","names":[],"sources":["../../src/manifest/app-manifest.types.ts"],"mappings":";KAAY,qBAAA;AAAA,KAEA,sBAAA;EACV,EAAA;EACA,IAAA,EAAM,qBAAA;EACN,WAAA;AAAA;AAAA,KAGU,cAAA;EACV,cAAA,GAAiB,sBAAA;EACjB,cAAA;EACA,OAAA;IAAsB,SAAA;EAAA;EACtB,YAAA;IACE,UAAA;EAAA;AAAA;AAAA,KAIQ,uBAAA;EACV,IAAA;EACA,KAAA;EACA,MAAA;EACA,MAAA;AAAA;AAAA,KAGU,gCAAA;EACV,IAAA;EACA,KAAA;AAAA;AAAA,KAGU,eAAA,GAAkB,uBAAA,GAA0B,gCAAA;AAAA,KAE5C,aAAA;EACV,KAAA;AAAA;AAAA,KAGU,WAAA;EACV,aAAA;EACA,EAAA;EACA,IAAA;EACA,OAAA;EACA,WAAA;EACA,IAAA;EACA,IAAA,EAAM,eAAA;EACN,EAAA,EAAI,aAAA;EACJ,WAAA,GAAc,cAAA;AAAA;AAAA,KAGJ,iBAAA;EACV,YAAA;EACA,YAAA;EACA,QAAA,EAAU,WAAA;EACV,aAAA;EACA,WAAA;EACA,eAAA;EACA,mBAAA;EACA,QAAA;AAAA;AAAA,KAGU,kBAAA;EACV,EAAA;EACA,IAAA;EACA,OAAA;EACA,WAAA;EACA,QAAA,EAAU,eAAA;EACV,MAAA;EACA,YAAA;EACA,aAAA;EACA,WAAA;EACA,QAAA;EACA,WAAA,EAAa,cAAA;AAAA"}
package/dist/package.js CHANGED
@@ -1,4 +1,6 @@
1
1
  //#region package.json
2
- var version = "0.7.10";
2
+ var version = "0.7.12";
3
3
  //#endregion
4
4
  export { version };
5
+
6
+ //# sourceMappingURL=package.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package.js","names":[],"sources":["../package.json"],"sourcesContent":[""],"mappings":""}
@@ -13,4 +13,5 @@ declare class AppHomeService {
13
13
  createTemporaryDirectory: (prefix: string) => Promise<string>;
14
14
  }
15
15
  //#endregion
16
- export { AppHomeService };
16
+ export { AppHomeService };
17
+ //# sourceMappingURL=app-home.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-home.service.d.ts","names":[],"sources":["../../src/paths/app-home.service.ts"],"mappings":";cAIa,cAAA;EAAA,iBAEQ,gBAAA;cAAA,gBAAA;EAKnB,mBAAA;EAIA,oBAAA;EAIA,gBAAA;EAIA,eAAA;EAIA,aAAA;EAIA,mBAAA,GAAuB,KAAA,UAAe,OAAA;EAItC,mBAAA,GAAuB,KAAA;EAIvB,qBAAA,QAAkC,OAAA;EAQlC,wBAAA,GAAkC,MAAA,aAAiB,OAAA;AAAA"}
@@ -40,3 +40,5 @@ var AppHomeService = class {
40
40
  };
41
41
  //#endregion
42
42
  export { AppHomeService };
43
+
44
+ //# sourceMappingURL=app-home.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-home.service.js","names":[],"sources":["../../src/paths/app-home.service.ts"],"sourcesContent":["import { mkdir, mkdtemp } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\n\nexport class AppHomeService {\n constructor(\n private readonly appHomeDirectory: string = process.env.NEXTCLAW_APP_HOME\n ? path.resolve(process.env.NEXTCLAW_APP_HOME)\n : path.join(process.env.HOME ?? process.cwd(), \".nextclaw\", \"apps\"),\n ) {}\n\n getAppHomeDirectory = (): string => {\n return this.appHomeDirectory;\n };\n\n getPackagesDirectory = (): string => {\n return path.join(this.appHomeDirectory, \"packages\");\n };\n\n getDataDirectory = (): string => {\n return path.join(this.appHomeDirectory, \"data\");\n };\n\n getRegistryPath = (): string => {\n return path.join(this.appHomeDirectory, \"registry.json\");\n };\n\n getConfigPath = (): string => {\n return path.join(this.appHomeDirectory, \"config.json\");\n };\n\n getInstallDirectory = (appId: string, version: string): string => {\n return path.join(this.getPackagesDirectory(), appId, version);\n };\n\n getAppDataDirectory = (appId: string): string => {\n return path.join(this.getDataDirectory(), appId);\n };\n\n ensureBaseDirectories = async (): Promise<void> => {\n await Promise.all([\n mkdir(this.appHomeDirectory, { recursive: true }),\n mkdir(this.getPackagesDirectory(), { recursive: true }),\n mkdir(this.getDataDirectory(), { recursive: true }),\n ]);\n };\n\n createTemporaryDirectory = async (prefix: string): Promise<string> => {\n return mkdtemp(path.join(tmpdir(), prefix));\n };\n}\n"],"mappings":";;;;AAIA,IAAa,iBAAb,MAA4B;CAC1B,YACE,mBAA4C,QAAQ,IAAI,oBACpD,KAAK,QAAQ,QAAQ,IAAI,kBAAkB,GAC3C,KAAK,KAAK,QAAQ,IAAI,QAAQ,QAAQ,KAAK,EAAE,aAAa,OAAO,EACrE;AAHiB,OAAA,mBAAA;;CAKnB,4BAAoC;AAClC,SAAO,KAAK;;CAGd,6BAAqC;AACnC,SAAO,KAAK,KAAK,KAAK,kBAAkB,WAAW;;CAGrD,yBAAiC;AAC/B,SAAO,KAAK,KAAK,KAAK,kBAAkB,OAAO;;CAGjD,wBAAgC;AAC9B,SAAO,KAAK,KAAK,KAAK,kBAAkB,gBAAgB;;CAG1D,sBAA8B;AAC5B,SAAO,KAAK,KAAK,KAAK,kBAAkB,cAAc;;CAGxD,uBAAuB,OAAe,YAA4B;AAChE,SAAO,KAAK,KAAK,KAAK,sBAAsB,EAAE,OAAO,QAAQ;;CAG/D,uBAAuB,UAA0B;AAC/C,SAAO,KAAK,KAAK,KAAK,kBAAkB,EAAE,MAAM;;CAGlD,wBAAwB,YAA2B;AACjD,QAAM,QAAQ,IAAI;GAChB,MAAM,KAAK,kBAAkB,EAAE,WAAW,MAAM,CAAC;GACjD,MAAM,KAAK,sBAAsB,EAAE,EAAE,WAAW,MAAM,CAAC;GACvD,MAAM,KAAK,kBAAkB,EAAE,EAAE,WAAW,MAAM,CAAC;GACpD,CAAC;;CAGJ,2BAA2B,OAAO,WAAoC;AACpE,SAAO,QAAQ,KAAK,KAAK,QAAQ,EAAE,OAAO,CAAC"}
@@ -19,4 +19,5 @@ declare class AppGrantService {
19
19
  }) => Promise<AppDocumentGrantMutationResult>;
20
20
  }
21
21
  //#endregion
22
- export { AppGrantService };
22
+ export { AppGrantService };
23
+ //# sourceMappingURL=app-grant.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-grant.service.d.ts","names":[],"sources":["../../src/permissions/app-grant.service.ts"],"mappings":";;;;;cASa,eAAA;EAAA,iBAEQ,eAAA;EAAA,iBACA,eAAA;cADA,eAAA,GAAiB,kBAAA,EACjB,eAAA,GAAiB,kBAAA;EAGpC,SAAA,GAAmB,KAAA,aAAgB,OAAA,CAAQ,2BAAA;EAsC3C,kBAAA,GAA4B,MAAA;IAC1B,KAAA;IACA,OAAA;IACA,aAAA;EAAA,MACE,OAAA,CAAQ,8BAAA;EA2BZ,mBAAA,GAA6B,MAAA;IAC3B,KAAA;IACA,OAAA;EAAA,MACE,OAAA,CAAQ,8BAAA;AAAA"}
@@ -61,3 +61,5 @@ var AppGrantService = class {
61
61
  };
62
62
  //#endregion
63
63
  export { AppGrantService };
64
+
65
+ //# sourceMappingURL=app-grant.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-grant.service.js","names":[],"sources":["../../src/permissions/app-grant.service.ts"],"sourcesContent":["import { access } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { AppManifestService } from \"../manifest/app-manifest.service.js\";\nimport { AppRegistryService } from \"../registry/app-registry.service.js\";\nimport type {\n AppDocumentGrantMutationResult,\n AppInstalledPermissionState,\n} from \"./app-permissions.types.js\";\n\nexport class AppGrantService {\n constructor(\n private readonly registryService: AppRegistryService = new AppRegistryService(),\n private readonly manifestService: AppManifestService = new AppManifestService(),\n ) {}\n\n summarize = async (appId: string): Promise<AppInstalledPermissionState> => {\n const appRecord = await this.registryService.getApp(appId);\n if (!appRecord) {\n throw new Error(`未找到已安装应用:${appId}`);\n }\n const activeVersion = appRecord.installedVersions[appRecord.activeVersion];\n if (!activeVersion) {\n throw new Error(`已安装应用缺少激活版本:${appId}`);\n }\n const bundle = await this.manifestService.load(activeVersion.installDirectory);\n const requestedPermissions = bundle.manifest.permissions ?? {};\n return {\n appId: appRecord.appId,\n name: appRecord.name,\n activeVersion: appRecord.activeVersion,\n documentAccess: (requestedPermissions.documentAccess ?? []).map((scope) => ({\n id: scope.id,\n mode: scope.mode,\n description: scope.description,\n granted: Boolean(appRecord.grants[scope.id]),\n grantedPath: appRecord.grants[scope.id],\n })),\n allowedDomains: requestedPermissions.allowedDomains ?? [],\n storage: {\n enabled:\n requestedPermissions.storage !== undefined &&\n 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 grantDocumentScope = async (params: {\n appId: string;\n scopeId: string;\n directoryPath: string;\n }): Promise<AppDocumentGrantMutationResult> => {\n const { appId, scopeId, directoryPath } = params;\n const permissionState = await this.summarize(appId);\n const requestedScope = permissionState.documentAccess.find(\n (scope) => scope.id === scopeId,\n );\n if (!requestedScope) {\n throw new Error(`应用 ${appId} 未声明 documentAccess scope:${scopeId}`);\n }\n const normalizedDirectory = path.resolve(directoryPath);\n try {\n await access(normalizedDirectory);\n } catch {\n throw new Error(`授权目录不存在:${normalizedDirectory}`);\n }\n await this.registryService.setDocumentGrant(\n appId,\n scopeId,\n normalizedDirectory,\n );\n return {\n appId,\n scopeId,\n grantedPath: normalizedDirectory,\n };\n };\n\n revokeDocumentScope = async (params: {\n appId: string;\n scopeId: string;\n }): Promise<AppDocumentGrantMutationResult> => {\n const { appId, scopeId } = params;\n await this.summarize(appId);\n const removed = await this.registryService.removeDocumentGrant(\n appId,\n scopeId,\n );\n return {\n appId,\n scopeId,\n removed,\n };\n };\n}\n"],"mappings":";;;;;AASA,IAAa,kBAAb,MAA6B;CAC3B,YACE,kBAAuD,IAAI,oBAAoB,EAC/E,kBAAuD,IAAI,oBAAoB,EAC/E;AAFiB,OAAA,kBAAA;AACA,OAAA,kBAAA;;CAGnB,YAAY,OAAO,UAAwD;EACzE,MAAM,YAAY,MAAM,KAAK,gBAAgB,OAAO,MAAM;AAC1D,MAAI,CAAC,UACH,OAAM,IAAI,MAAM,YAAY,QAAQ;EAEtC,MAAM,gBAAgB,UAAU,kBAAkB,UAAU;AAC5D,MAAI,CAAC,cACH,OAAM,IAAI,MAAM,eAAe,QAAQ;EAGzC,MAAM,wBADS,MAAM,KAAK,gBAAgB,KAAK,cAAc,iBAAiB,EAC1C,SAAS,eAAe,EAAE;AAC9D,SAAO;GACL,OAAO,UAAU;GACjB,MAAM,UAAU;GAChB,eAAe,UAAU;GACzB,iBAAiB,qBAAqB,kBAAkB,EAAE,EAAE,KAAK,WAAW;IAC1E,IAAI,MAAM;IACV,MAAM,MAAM;IACZ,aAAa,MAAM;IACnB,SAAS,QAAQ,UAAU,OAAO,MAAM,IAAI;IAC5C,aAAa,UAAU,OAAO,MAAM;IACrC,EAAE;GACH,gBAAgB,qBAAqB,kBAAkB,EAAE;GACzD,SAAS;IACP,SACE,qBAAqB,YAAY,KAAA,KACjC,qBAAqB,YAAY;IACnC,WACE,OAAO,qBAAqB,YAAY,WACpC,qBAAqB,QAAQ,YAC7B,KAAA;IACP;GACD,cAAc,EACZ,YAAY,qBAAqB,cAAc,eAAe,OAC/D;GACF;;CAGH,qBAAqB,OAAO,WAImB;EAC7C,MAAM,EAAE,OAAO,SAAS,kBAAkB;AAK1C,MAAI,EAJoB,MAAM,KAAK,UAAU,MAAM,EACZ,eAAe,MACnD,UAAU,MAAM,OAAO,QACzB,CAEC,OAAM,IAAI,MAAM,MAAM,MAAM,4BAA4B,UAAU;EAEpE,MAAM,sBAAsB,KAAK,QAAQ,cAAc;AACvD,MAAI;AACF,SAAM,OAAO,oBAAoB;UAC3B;AACN,SAAM,IAAI,MAAM,WAAW,sBAAsB;;AAEnD,QAAM,KAAK,gBAAgB,iBACzB,OACA,SACA,oBACD;AACD,SAAO;GACL;GACA;GACA,aAAa;GACd;;CAGH,sBAAsB,OAAO,WAGkB;EAC7C,MAAM,EAAE,OAAO,YAAY;AAC3B,QAAM,KAAK,UAAU,MAAM;AAK3B,SAAO;GACL;GACA;GACA,SAPc,MAAM,KAAK,gBAAgB,oBACzC,OACA,QACD;GAKA"}
@@ -10,4 +10,5 @@ declare class AppPermissionsService {
10
10
  private resolveDocumentGrant;
11
11
  }
12
12
  //#endregion
13
- export { AppPermissionsService };
13
+ export { AppPermissionsService };
14
+ //# sourceMappingURL=app-permissions.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-permissions.service.d.ts","names":[],"sources":["../../src/permissions/app-permissions.service.ts"],"mappings":";;;;cAaa,qBAAA;EACX,OAAA,GACE,MAAA,EAAQ,iBAAA,EACR,gBAAA,EAAkB,mBAAA,EAClB,OAAA;IACE,KAAA;EAAA,MAED,OAAA,CAAQ,mBAAA;EA2BX,SAAA,GACE,MAAA,EAAQ,iBAAA,EACR,WAAA,EAAa,mBAAA,KACZ,oBAAA;EAAA,QAUK,oBAAA;AAAA"}
@@ -45,3 +45,5 @@ var AppPermissionsService = class {
45
45
  };
46
46
  //#endregion
47
47
  export { AppPermissionsService };
48
+
49
+ //# sourceMappingURL=app-permissions.service.js.map
@@ -0,0 +1 @@
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"}
@@ -50,4 +50,5 @@ type AppDocumentGrantMutationResult = {
50
50
  removed?: boolean;
51
51
  };
52
52
  //#endregion
53
- export { AppDocumentGrantMap, AppDocumentGrantMutationResult, AppDocumentGrantState, AppInstalledPermissionState, AppPermissionSummary, ResolvedDocumentGrant, ResolvedPermissions };
53
+ export { AppDocumentGrantMap, AppDocumentGrantMutationResult, AppDocumentGrantState, AppInstalledPermissionState, AppPermissionSummary, ResolvedDocumentGrant, ResolvedPermissions };
54
+ //# sourceMappingURL=app-permissions.types.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -10,4 +10,5 @@ declare class AppMarketplaceClientService {
10
10
  private normalizeApiBase;
11
11
  }
12
12
  //#endregion
13
- export { AppMarketplaceClientService };
13
+ export { AppMarketplaceClientService };
14
+ //# sourceMappingURL=app-marketplace-client.service.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -29,3 +29,5 @@ var AppMarketplaceClientService = class {
29
29
  };
30
30
  //#endregion
31
31
  export { AppMarketplaceClientService };
32
+
33
+ //# sourceMappingURL=app-marketplace-client.service.js.map
@@ -0,0 +1 @@
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"}
@@ -24,4 +24,5 @@ declare class AppMarketplaceMetadataService {
24
24
  private readLocalizedTextMap;
25
25
  }
26
26
  //#endregion
27
- export { AppMarketplaceMetadataService };
27
+ export { AppMarketplaceMetadataService };
28
+ //# sourceMappingURL=app-marketplace-metadata.service.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -82,3 +82,5 @@ var AppMarketplaceMetadataService = class {
82
82
  };
83
83
  //#endregion
84
84
  export { AppMarketplaceMetadataService };
85
+
86
+ //# sourceMappingURL=app-marketplace-metadata.service.js.map
@@ -0,0 +1 @@
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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"}
@@ -37,4 +37,5 @@ declare class AppPublishValidationService {
37
37
  private formatBytes;
38
38
  }
39
39
  //#endregion
40
- export { AppPublishValidationResult, AppPublishValidationService, AppPublishValidationWarning, AppPublishValidationWarningCode };
40
+ export { AppPublishValidationResult, AppPublishValidationService, AppPublishValidationWarning, AppPublishValidationWarningCode };
41
+ //# sourceMappingURL=app-publish-validation.service.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -78,3 +78,5 @@ var AppPublishValidationService = class {
78
78
  };
79
79
  //#endregion
80
80
  export { AppPublishValidationService };
81
+
82
+ //# sourceMappingURL=app-publish-validation.service.js.map
@@ -0,0 +1 @@
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"}
@@ -28,4 +28,5 @@ declare class AppPublishService {
28
28
  private buildOfficialPublisher;
29
29
  }
30
30
  //#endregion
31
- export { AppPublishService };
31
+ export { AppPublishService };
32
+ //# sourceMappingURL=app-publish.service.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -158,3 +158,5 @@ var AppPublishService = class {
158
158
  };
159
159
  //#endregion
160
160
  export { AppPublishService };
161
+
162
+ //# sourceMappingURL=app-publish.service.js.map
@@ -0,0 +1 @@
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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"}
@@ -66,4 +66,5 @@ type AppPublishResult = {
66
66
  fileCount: number;
67
67
  };
68
68
  //#endregion
69
- export { AppMarketplaceMetadata, AppPublishFile, AppPublishPayload, AppPublishResult, DEFAULT_APP_MARKETPLACE_API_BASE };
69
+ export { AppMarketplaceMetadata, AppPublishFile, AppPublishPayload, AppPublishResult, DEFAULT_APP_MARKETPLACE_API_BASE };
70
+ //# sourceMappingURL=app-publish.types.d.ts.map
@@ -0,0 +1 @@
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"}