@nextclaw/app-runtime 0.9.13 → 0.9.15

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 (307) hide show
  1. package/README.md +2 -2
  2. package/dist/{main.js → app/main.js} +2 -2
  3. package/dist/app/main.js.map +1 -0
  4. package/dist/{commands → controllers}/create.controller.d.ts +2 -2
  5. package/dist/controllers/create.controller.d.ts.map +1 -0
  6. package/dist/{commands → controllers}/create.controller.js +2 -2
  7. package/dist/controllers/create.controller.js.map +1 -0
  8. package/dist/{commands → controllers}/dev.controller.js +1 -1
  9. package/dist/controllers/dev.controller.js.map +1 -0
  10. package/dist/{commands → controllers}/grant.controller.d.ts +3 -3
  11. package/dist/controllers/grant.controller.d.ts.map +1 -0
  12. package/dist/{commands → controllers}/grant.controller.js +2 -2
  13. package/dist/controllers/grant.controller.js.map +1 -0
  14. package/dist/{commands → controllers}/info.controller.d.ts +2 -2
  15. package/dist/controllers/info.controller.d.ts.map +1 -0
  16. package/dist/{commands → controllers}/info.controller.js +2 -2
  17. package/dist/controllers/info.controller.js.map +1 -0
  18. package/dist/{commands → controllers}/inspect.controller.js +8 -2
  19. package/dist/controllers/inspect.controller.js.map +1 -0
  20. package/dist/{commands → controllers}/install.controller.d.ts +2 -2
  21. package/dist/controllers/install.controller.d.ts.map +1 -0
  22. package/dist/{commands → controllers}/install.controller.js +2 -2
  23. package/dist/controllers/install.controller.js.map +1 -0
  24. package/dist/{commands → controllers}/list.controller.d.ts +2 -2
  25. package/dist/controllers/list.controller.d.ts.map +1 -0
  26. package/dist/{commands → controllers}/list.controller.js +2 -2
  27. package/dist/controllers/list.controller.js.map +1 -0
  28. package/dist/controllers/pack.controller.d.ts +19 -0
  29. package/dist/controllers/pack.controller.d.ts.map +1 -0
  30. package/dist/{commands → controllers}/pack.controller.js +8 -4
  31. package/dist/controllers/pack.controller.js.map +1 -0
  32. package/dist/{commands → controllers}/permissions.controller.d.ts +2 -2
  33. package/dist/controllers/permissions.controller.d.ts.map +1 -0
  34. package/dist/{commands → controllers}/permissions.controller.js +2 -2
  35. package/dist/controllers/permissions.controller.js.map +1 -0
  36. package/dist/{commands → controllers}/publish.controller.d.ts +3 -3
  37. package/dist/controllers/publish.controller.d.ts.map +1 -0
  38. package/dist/{commands → controllers}/publish.controller.js +2 -2
  39. package/dist/controllers/publish.controller.js.map +1 -0
  40. package/dist/{commands → controllers}/registry.controller.d.ts +2 -2
  41. package/dist/controllers/registry.controller.d.ts.map +1 -0
  42. package/dist/{commands → controllers}/registry.controller.js +2 -2
  43. package/dist/controllers/registry.controller.js.map +1 -0
  44. package/dist/{commands → controllers}/revoke.controller.d.ts +2 -2
  45. package/dist/controllers/revoke.controller.d.ts.map +1 -0
  46. package/dist/{commands → controllers}/revoke.controller.js +2 -2
  47. package/dist/controllers/revoke.controller.js.map +1 -0
  48. package/dist/{commands → controllers}/run.controller.js +8 -6
  49. package/dist/controllers/run.controller.js.map +1 -0
  50. package/dist/{commands → controllers}/uninstall.controller.d.ts +2 -2
  51. package/dist/controllers/uninstall.controller.d.ts.map +1 -0
  52. package/dist/{commands → controllers}/uninstall.controller.js +2 -2
  53. package/dist/controllers/uninstall.controller.js.map +1 -0
  54. package/dist/{commands → controllers}/update.controller.d.ts +2 -2
  55. package/dist/controllers/update.controller.d.ts.map +1 -0
  56. package/dist/{commands → controllers}/update.controller.js +2 -2
  57. package/dist/controllers/update.controller.js.map +1 -0
  58. package/dist/{commands → controllers}/validate-publish.controller.d.ts +3 -3
  59. package/dist/controllers/validate-publish.controller.d.ts.map +1 -0
  60. package/dist/{commands → controllers}/validate-publish.controller.js +9 -5
  61. package/dist/controllers/validate-publish.controller.js.map +1 -0
  62. package/dist/index.d.ts +51 -51
  63. package/dist/index.js +46 -45
  64. package/dist/package.js +1 -1
  65. package/dist/{runtime → services}/app-build.service.d.ts +2 -2
  66. package/dist/services/app-build.service.d.ts.map +1 -0
  67. package/dist/{runtime → services}/app-build.service.js +4 -2
  68. package/dist/services/app-build.service.js.map +1 -0
  69. package/dist/{bundle → services}/app-bundle.service.d.ts +18 -6
  70. package/dist/services/app-bundle.service.d.ts.map +1 -0
  71. package/dist/services/app-bundle.service.js +305 -0
  72. package/dist/services/app-bundle.service.js.map +1 -0
  73. package/dist/{permissions → services}/app-grant.service.d.ts +4 -4
  74. package/dist/services/app-grant.service.d.ts.map +1 -0
  75. package/dist/{permissions → services}/app-grant.service.js +7 -4
  76. package/dist/services/app-grant.service.js.map +1 -0
  77. package/dist/{paths → services}/app-home.service.d.ts +2 -1
  78. package/dist/services/app-home.service.d.ts.map +1 -0
  79. package/dist/{paths → services}/app-home.service.js +4 -1
  80. package/dist/services/app-home.service.js.map +1 -0
  81. package/dist/{host → services}/app-host.service.d.ts +2 -2
  82. package/dist/services/app-host.service.d.ts.map +1 -0
  83. package/dist/{host → services}/app-host.service.js +3 -3
  84. package/dist/services/app-host.service.js.map +1 -0
  85. package/dist/services/app-install-source.service.js +72 -0
  86. package/dist/services/app-install-source.service.js.map +1 -0
  87. package/dist/services/app-installation.service.d.ts +48 -0
  88. package/dist/services/app-installation.service.d.ts.map +1 -0
  89. package/dist/services/app-installation.service.js +411 -0
  90. package/dist/services/app-installation.service.js.map +1 -0
  91. package/dist/services/app-instance.service.d.ts +34 -0
  92. package/dist/services/app-instance.service.d.ts.map +1 -0
  93. package/dist/{host → services}/app-instance.service.js +4 -4
  94. package/dist/services/app-instance.service.js.map +1 -0
  95. package/dist/{manifest → services}/app-manifest.service.d.ts +12 -2
  96. package/dist/services/app-manifest.service.d.ts.map +1 -0
  97. package/dist/services/app-manifest.service.js +271 -0
  98. package/dist/services/app-manifest.service.js.map +1 -0
  99. package/dist/{publish → services}/app-marketplace-client.service.d.ts +2 -2
  100. package/dist/services/app-marketplace-client.service.d.ts.map +1 -0
  101. package/dist/{publish → services}/app-marketplace-client.service.js +2 -2
  102. package/dist/services/app-marketplace-client.service.js.map +1 -0
  103. package/dist/{publish → services}/app-marketplace-metadata.service.d.ts +7 -3
  104. package/dist/services/app-marketplace-metadata.service.d.ts.map +1 -0
  105. package/dist/{publish → services}/app-marketplace-metadata.service.js +45 -3
  106. package/dist/services/app-marketplace-metadata.service.js.map +1 -0
  107. package/dist/{permissions → services}/app-permissions.service.d.ts +3 -3
  108. package/dist/services/app-permissions.service.d.ts.map +1 -0
  109. package/dist/{permissions → services}/app-permissions.service.js +4 -1
  110. package/dist/services/app-permissions.service.js.map +1 -0
  111. package/dist/{publish → services}/app-publish-validation.service.d.ts +9 -7
  112. package/dist/services/app-publish-validation.service.d.ts.map +1 -0
  113. package/dist/{publish → services}/app-publish-validation.service.js +14 -10
  114. package/dist/services/app-publish-validation.service.js.map +1 -0
  115. package/dist/{publish → services}/app-publish.service.d.ts +5 -5
  116. package/dist/services/app-publish.service.d.ts.map +1 -0
  117. package/dist/{publish → services}/app-publish.service.js +10 -7
  118. package/dist/services/app-publish.service.js.map +1 -0
  119. package/dist/{registry → services}/app-registry-config.service.d.ts +3 -3
  120. package/dist/{registry → services}/app-registry-config.service.d.ts.map +1 -1
  121. package/dist/{registry → services}/app-registry-config.service.js +3 -3
  122. package/dist/services/app-registry-config.service.js.map +1 -0
  123. package/dist/{registry → services}/app-registry.service.d.ts +20 -5
  124. package/dist/services/app-registry.service.d.ts.map +1 -0
  125. package/dist/services/app-registry.service.js +228 -0
  126. package/dist/services/app-registry.service.js.map +1 -0
  127. package/dist/{registry → services}/app-remote-registry-client.service.d.ts +6 -2
  128. package/dist/services/app-remote-registry-client.service.d.ts.map +1 -0
  129. package/dist/{registry → services}/app-remote-registry-client.service.js +54 -8
  130. package/dist/services/app-remote-registry-client.service.js.map +1 -0
  131. package/dist/{cli → services}/app-runtime-cli.service.d.ts +1 -1
  132. package/dist/services/app-runtime-cli.service.d.ts.map +1 -0
  133. package/dist/{cli → services}/app-runtime-cli.service.js +19 -19
  134. package/dist/services/app-runtime-cli.service.js.map +1 -0
  135. package/dist/{cli → services}/app-runtime-options.service.d.ts +6 -6
  136. package/dist/services/app-runtime-options.service.d.ts.map +1 -0
  137. package/dist/{cli → services}/app-runtime-options.service.js +3 -9
  138. package/dist/services/app-runtime-options.service.js.map +1 -0
  139. package/dist/{runtime → services}/app-runtime-toolchain.service.d.ts +1 -1
  140. package/dist/services/app-runtime-toolchain.service.d.ts.map +1 -0
  141. package/dist/{runtime → services}/app-runtime-toolchain.service.js +1 -1
  142. package/dist/services/app-runtime-toolchain.service.js.map +1 -0
  143. package/dist/{scaffold → services}/app-scaffold.service.d.ts +1 -1
  144. package/dist/{scaffold → services}/app-scaffold.service.d.ts.map +1 -1
  145. package/dist/{scaffold → services}/app-scaffold.service.js +1 -1
  146. package/dist/{scaffold → services}/app-scaffold.service.js.map +1 -1
  147. package/dist/{scaffold → services}/app-ts-http-lite-scaffold-template.service.d.ts +1 -1
  148. package/dist/{scaffold → services}/app-ts-http-lite-scaffold-template.service.d.ts.map +1 -1
  149. package/dist/{scaffold → services}/app-ts-http-lite-scaffold-template.service.js +1 -1
  150. package/dist/{scaffold → services}/app-ts-http-lite-scaffold-template.service.js.map +1 -1
  151. package/dist/{scaffold → services}/app-ts-http-scaffold-template.service.d.ts +1 -1
  152. package/dist/{scaffold → services}/app-ts-http-scaffold-template.service.d.ts.map +1 -1
  153. package/dist/{scaffold → services}/app-ts-http-scaffold-template.service.js +1 -1
  154. package/dist/{scaffold → services}/app-ts-http-scaffold-template.service.js.map +1 -1
  155. package/dist/{bridge → services}/host-bridge.service.d.ts +2 -2
  156. package/dist/services/host-bridge.service.d.ts.map +1 -0
  157. package/dist/{bridge → services}/host-bridge.service.js +1 -1
  158. package/dist/services/host-bridge.service.js.map +1 -0
  159. package/dist/services/main-runner.service.d.ts +9 -0
  160. package/dist/services/main-runner.service.d.ts.map +1 -0
  161. package/dist/services/main-runner.service.js +6 -0
  162. package/dist/services/main-runner.service.js.map +1 -0
  163. package/dist/{publish → services}/platform-auth-state.service.d.ts +1 -1
  164. package/dist/services/platform-auth-state.service.d.ts.map +1 -0
  165. package/dist/{publish → services}/platform-auth-state.service.js +1 -1
  166. package/dist/services/platform-auth-state.service.js.map +1 -0
  167. package/dist/{ui → services}/ui-server.service.d.ts +3 -3
  168. package/dist/services/ui-server.service.d.ts.map +1 -0
  169. package/dist/{ui → services}/ui-server.service.js +1 -1
  170. package/dist/services/ui-server.service.js.map +1 -0
  171. package/dist/{runtime → services}/wasm-main-runner.service.d.ts +3 -3
  172. package/dist/services/wasm-main-runner.service.d.ts.map +1 -0
  173. package/dist/{runtime → services}/wasm-main-runner.service.js +2 -2
  174. package/dist/services/wasm-main-runner.service.js.map +1 -0
  175. package/dist/{sidecar → services}/wasm-sidecar-client.service.d.ts +1 -1
  176. package/dist/services/wasm-sidecar-client.service.d.ts.map +1 -0
  177. package/dist/{sidecar → services}/wasm-sidecar-client.service.js +1 -1
  178. package/dist/services/wasm-sidecar-client.service.js.map +1 -0
  179. package/dist/{runtime → services}/wasmtime-wasi-http-component.service.d.ts +1 -1
  180. package/dist/services/wasmtime-wasi-http-component.service.d.ts.map +1 -0
  181. package/dist/{runtime → services}/wasmtime-wasi-http-component.service.js +1 -1
  182. package/dist/services/wasmtime-wasi-http-component.service.js.map +1 -0
  183. package/dist/{bundle → types}/app-bundle.types.d.ts +1 -1
  184. package/dist/types/app-bundle.types.d.ts.map +1 -0
  185. package/dist/{install → types}/app-installation.types.d.ts +29 -7
  186. package/dist/types/app-installation.types.d.ts.map +1 -0
  187. package/dist/types/app-manifest.types.d.ts +119 -0
  188. package/dist/types/app-manifest.types.d.ts.map +1 -0
  189. package/dist/types/app-manifest.types.js +11 -0
  190. package/dist/types/app-manifest.types.js.map +1 -0
  191. package/dist/{permissions → types}/app-permissions.types.d.ts +2 -2
  192. package/dist/types/app-permissions.types.d.ts.map +1 -0
  193. package/dist/{publish → types}/app-publish.types.d.ts +11 -5
  194. package/dist/types/app-publish.types.d.ts.map +1 -0
  195. package/dist/{publish → types}/app-publish.types.js +1 -1
  196. package/dist/types/app-publish.types.js.map +1 -0
  197. package/dist/{registry → types}/app-registry.types.d.ts +11 -4
  198. package/dist/types/app-registry.types.d.ts.map +1 -0
  199. package/dist/{registry → types}/app-remote-registry.types.d.ts +3 -3
  200. package/dist/types/app-remote-registry.types.d.ts.map +1 -0
  201. package/dist/{registry → types}/app-remote-registry.types.js +1 -1
  202. package/dist/types/app-remote-registry.types.js.map +1 -0
  203. package/dist/{runtime → types}/main-runner.types.d.ts +3 -3
  204. package/dist/types/main-runner.types.d.ts.map +1 -0
  205. package/package.json +10 -3
  206. package/dist/bridge/host-bridge.service.d.ts.map +0 -1
  207. package/dist/bridge/host-bridge.service.js.map +0 -1
  208. package/dist/bundle/app-bundle.service.d.ts.map +0 -1
  209. package/dist/bundle/app-bundle.service.js +0 -196
  210. package/dist/bundle/app-bundle.service.js.map +0 -1
  211. package/dist/bundle/app-bundle.types.d.ts.map +0 -1
  212. package/dist/cli/app-runtime-cli.service.d.ts.map +0 -1
  213. package/dist/cli/app-runtime-cli.service.js.map +0 -1
  214. package/dist/cli/app-runtime-options.service.d.ts.map +0 -1
  215. package/dist/cli/app-runtime-options.service.js.map +0 -1
  216. package/dist/commands/create.controller.d.ts.map +0 -1
  217. package/dist/commands/create.controller.js.map +0 -1
  218. package/dist/commands/dev.controller.js.map +0 -1
  219. package/dist/commands/grant.controller.d.ts.map +0 -1
  220. package/dist/commands/grant.controller.js.map +0 -1
  221. package/dist/commands/info.controller.d.ts.map +0 -1
  222. package/dist/commands/info.controller.js.map +0 -1
  223. package/dist/commands/inspect.controller.js.map +0 -1
  224. package/dist/commands/install.controller.d.ts.map +0 -1
  225. package/dist/commands/install.controller.js.map +0 -1
  226. package/dist/commands/list.controller.d.ts.map +0 -1
  227. package/dist/commands/list.controller.js.map +0 -1
  228. package/dist/commands/pack.controller.d.ts +0 -17
  229. package/dist/commands/pack.controller.d.ts.map +0 -1
  230. package/dist/commands/pack.controller.js.map +0 -1
  231. package/dist/commands/permissions.controller.d.ts.map +0 -1
  232. package/dist/commands/permissions.controller.js.map +0 -1
  233. package/dist/commands/publish.controller.d.ts.map +0 -1
  234. package/dist/commands/publish.controller.js.map +0 -1
  235. package/dist/commands/registry.controller.d.ts.map +0 -1
  236. package/dist/commands/registry.controller.js.map +0 -1
  237. package/dist/commands/revoke.controller.d.ts.map +0 -1
  238. package/dist/commands/revoke.controller.js.map +0 -1
  239. package/dist/commands/run.controller.js.map +0 -1
  240. package/dist/commands/uninstall.controller.d.ts.map +0 -1
  241. package/dist/commands/uninstall.controller.js.map +0 -1
  242. package/dist/commands/update.controller.d.ts.map +0 -1
  243. package/dist/commands/update.controller.js.map +0 -1
  244. package/dist/commands/validate-publish.controller.d.ts.map +0 -1
  245. package/dist/commands/validate-publish.controller.js.map +0 -1
  246. package/dist/host/app-host.service.d.ts.map +0 -1
  247. package/dist/host/app-host.service.js.map +0 -1
  248. package/dist/host/app-instance.service.d.ts +0 -34
  249. package/dist/host/app-instance.service.d.ts.map +0 -1
  250. package/dist/host/app-instance.service.js.map +0 -1
  251. package/dist/install/app-installation.service.d.ts +0 -41
  252. package/dist/install/app-installation.service.d.ts.map +0 -1
  253. package/dist/install/app-installation.service.js +0 -276
  254. package/dist/install/app-installation.service.js.map +0 -1
  255. package/dist/install/app-installation.types.d.ts.map +0 -1
  256. package/dist/main.js.map +0 -1
  257. package/dist/manifest/app-manifest.service.d.ts.map +0 -1
  258. package/dist/manifest/app-manifest.service.js +0 -147
  259. package/dist/manifest/app-manifest.service.js.map +0 -1
  260. package/dist/manifest/app-manifest.types.d.ts +0 -68
  261. package/dist/manifest/app-manifest.types.d.ts.map +0 -1
  262. package/dist/paths/app-home.service.d.ts.map +0 -1
  263. package/dist/paths/app-home.service.js.map +0 -1
  264. package/dist/permissions/app-grant.service.d.ts.map +0 -1
  265. package/dist/permissions/app-grant.service.js.map +0 -1
  266. package/dist/permissions/app-permissions.service.d.ts.map +0 -1
  267. package/dist/permissions/app-permissions.service.js.map +0 -1
  268. package/dist/permissions/app-permissions.types.d.ts.map +0 -1
  269. package/dist/publish/app-marketplace-client.service.d.ts.map +0 -1
  270. package/dist/publish/app-marketplace-client.service.js.map +0 -1
  271. package/dist/publish/app-marketplace-metadata.service.d.ts.map +0 -1
  272. package/dist/publish/app-marketplace-metadata.service.js.map +0 -1
  273. package/dist/publish/app-publish-validation.service.d.ts.map +0 -1
  274. package/dist/publish/app-publish-validation.service.js.map +0 -1
  275. package/dist/publish/app-publish.service.d.ts.map +0 -1
  276. package/dist/publish/app-publish.service.js.map +0 -1
  277. package/dist/publish/app-publish.types.d.ts.map +0 -1
  278. package/dist/publish/app-publish.types.js.map +0 -1
  279. package/dist/publish/platform-auth-state.service.d.ts.map +0 -1
  280. package/dist/publish/platform-auth-state.service.js.map +0 -1
  281. package/dist/registry/app-registry-config.service.js.map +0 -1
  282. package/dist/registry/app-registry.service.d.ts.map +0 -1
  283. package/dist/registry/app-registry.service.js +0 -118
  284. package/dist/registry/app-registry.service.js.map +0 -1
  285. package/dist/registry/app-registry.types.d.ts.map +0 -1
  286. package/dist/registry/app-remote-registry-client.service.d.ts.map +0 -1
  287. package/dist/registry/app-remote-registry-client.service.js.map +0 -1
  288. package/dist/registry/app-remote-registry.types.d.ts.map +0 -1
  289. package/dist/registry/app-remote-registry.types.js.map +0 -1
  290. package/dist/runtime/app-build.service.d.ts.map +0 -1
  291. package/dist/runtime/app-build.service.js.map +0 -1
  292. package/dist/runtime/app-runtime-toolchain.service.d.ts.map +0 -1
  293. package/dist/runtime/app-runtime-toolchain.service.js.map +0 -1
  294. package/dist/runtime/main-runner.service.d.ts +0 -9
  295. package/dist/runtime/main-runner.service.d.ts.map +0 -1
  296. package/dist/runtime/main-runner.service.js +0 -6
  297. package/dist/runtime/main-runner.service.js.map +0 -1
  298. package/dist/runtime/main-runner.types.d.ts.map +0 -1
  299. package/dist/runtime/wasm-main-runner.service.d.ts.map +0 -1
  300. package/dist/runtime/wasm-main-runner.service.js.map +0 -1
  301. package/dist/runtime/wasmtime-wasi-http-component.service.d.ts.map +0 -1
  302. package/dist/runtime/wasmtime-wasi-http-component.service.js.map +0 -1
  303. package/dist/sidecar/wasm-sidecar-client.service.d.ts.map +0 -1
  304. package/dist/sidecar/wasm-sidecar-client.service.js.map +0 -1
  305. package/dist/ui/ui-server.service.d.ts.map +0 -1
  306. package/dist/ui/ui-server.service.js.map +0 -1
  307. /package/dist/{main.d.ts → app/main.d.ts} +0 -0
@@ -1,8 +1,10 @@
1
1
  import { AppRegistryConfigService } from "./app-registry-config.service.js";
2
- import { writeFile } from "node:fs/promises";
3
2
  import { createHash } from "node:crypto";
3
+ import { writeFile } from "node:fs/promises";
4
4
  import path from "node:path";
5
- //#region src/registry/app-remote-registry-client.service.ts
5
+ //#region src/services/app-remote-registry-client.service.ts
6
+ const MAX_REMOTE_BUNDLE_BYTES = 25 * 1024 * 1024;
7
+ const MAX_REGISTRY_GET_ATTEMPTS = 3;
6
8
  var AppRemoteRegistryClientService = class {
7
9
  constructor(configService = new AppRegistryConfigService()) {
8
10
  this.configService = configService;
@@ -11,9 +13,8 @@ var AppRemoteRegistryClientService = class {
11
13
  const { appId, version: requestedVersion, registryUrl: overrideRegistryUrl } = params;
12
14
  const registryUrl = overrideRegistryUrl ? this.normalizeRegistryUrl(overrideRegistryUrl) : (await this.configService.getSnapshot()).currentUrl;
13
15
  const metadataUrl = new URL(encodeURIComponent(appId), registryUrl).toString();
14
- const response = await fetch(metadataUrl);
15
- if (!response.ok) throw new Error(`无法从 registry 拉取 ${appId} metadata:${response.status} ${response.statusText}`);
16
- const document = this.parseDocument(await response.json(), appId);
16
+ const rawDocument = await this.readGetResponse(metadataUrl, `无法从 registry 拉取 ${appId} metadata`, async (response) => await response.json());
17
+ const document = this.parseDocument(rawDocument, appId);
17
18
  const version = requestedVersion ?? document["dist-tags"].latest;
18
19
  const versionRecord = document.versions[version];
19
20
  if (!versionRecord) throw new Error(`registry ${registryUrl} 未提供 ${appId}@${version}。`);
@@ -32,9 +33,13 @@ var AppRemoteRegistryClientService = class {
32
33
  };
33
34
  downloadBundle = async (params) => {
34
35
  const { resolution, targetDirectory } = params;
35
- const response = await fetch(resolution.bundleUrl);
36
- if (!response.ok) throw new Error(`无法下载 bundle:${resolution.bundleUrl} (${response.status} ${response.statusText})`);
37
- const bundleBytes = Buffer.from(await response.arrayBuffer());
36
+ const bundleBytes = await this.readGetResponse(resolution.bundleUrl, `无法下载 bundle:${resolution.bundleUrl}`, async (response) => {
37
+ const contentLength = Number(response.headers.get("content-length"));
38
+ if (Number.isFinite(contentLength) && contentLength > MAX_REMOTE_BUNDLE_BYTES) throw new Error(`远程 bundle 超过 ${MAX_REMOTE_BUNDLE_BYTES} bytes 上限。`);
39
+ const bytes = Buffer.from(await response.arrayBuffer());
40
+ if (bytes.byteLength > MAX_REMOTE_BUNDLE_BYTES) throw new Error(`远程 bundle 超过 ${MAX_REMOTE_BUNDLE_BYTES} bytes 上限。`);
41
+ return bytes;
42
+ });
38
43
  const actualSha256 = createHash("sha256").update(bundleBytes).digest("hex");
39
44
  if (actualSha256 !== resolution.sha256) throw new Error(`bundle checksum 校验失败:期望 ${resolution.sha256},实际 ${actualSha256}`);
40
45
  const bundlePath = path.join(targetDirectory, `${this.normalizeBundleFileName(resolution.appId)}-${resolution.version}.napp`);
@@ -102,6 +107,47 @@ var AppRemoteRegistryClientService = class {
102
107
  normalizeBundleFileName = (appId) => {
103
108
  return appId.replace(/[^a-zA-Z0-9._-]+/g, "-");
104
109
  };
110
+ readGetResponse = async (url, operation, read) => {
111
+ let lastError;
112
+ for (let attempt = 1; attempt <= MAX_REGISTRY_GET_ATTEMPTS; attempt += 1) {
113
+ try {
114
+ const response = await fetch(url);
115
+ if (!response.ok) {
116
+ if (this.isTransientHttpStatus(response.status) && attempt < MAX_REGISTRY_GET_ATTEMPTS) {
117
+ await response.body?.cancel();
118
+ await this.waitBeforeRetry(attempt);
119
+ continue;
120
+ }
121
+ throw new Error(`${operation}:${response.status} ${response.statusText}`);
122
+ }
123
+ try {
124
+ return await read(response);
125
+ } catch (error) {
126
+ if (!this.isTransientNetworkError(error) || attempt === MAX_REGISTRY_GET_ATTEMPTS) throw error;
127
+ lastError = error;
128
+ }
129
+ } catch (error) {
130
+ if (!this.isTransientNetworkError(error) || attempt === MAX_REGISTRY_GET_ATTEMPTS) {
131
+ if (this.isTransientNetworkError(error)) throw new Error(`${operation}失败(已尝试 ${MAX_REGISTRY_GET_ATTEMPTS} 次)。`, { cause: error });
132
+ throw error;
133
+ }
134
+ lastError = error;
135
+ }
136
+ await this.waitBeforeRetry(attempt);
137
+ }
138
+ throw new Error(`${operation}失败(已尝试 ${MAX_REGISTRY_GET_ATTEMPTS} 次)。`, { cause: lastError });
139
+ };
140
+ isTransientHttpStatus = (status) => {
141
+ return status === 408 || status === 429 || status >= 500;
142
+ };
143
+ isTransientNetworkError = (error) => {
144
+ return error instanceof TypeError;
145
+ };
146
+ waitBeforeRetry = async (attempt) => {
147
+ await new Promise((resolve) => {
148
+ setTimeout(resolve, attempt * 100);
149
+ });
150
+ };
105
151
  normalizeRegistryUrl = (registryUrl) => {
106
152
  let normalized;
107
153
  try {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-remote-registry-client.service.js","names":[],"sources":["../../src/services/app-remote-registry-client.service.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { AppRegistryConfigService } from \"./app-registry-config.service.js\";\nimport type {\n AppRemoteRegistryDocument,\n AppRemoteRegistryResolution,\n AppRemoteRegistryVersion,\n} from \"#app-runtime/types/app-remote-registry.types.js\";\n\nconst MAX_REMOTE_BUNDLE_BYTES = 25 * 1024 * 1024;\nconst MAX_REGISTRY_GET_ATTEMPTS = 3;\n\nexport class AppRemoteRegistryClientService {\n constructor(\n private readonly configService: AppRegistryConfigService = new AppRegistryConfigService(),\n ) {}\n\n resolve = async (params: {\n appId: string;\n version?: string;\n registryUrl?: string;\n }): Promise<AppRemoteRegistryResolution> => {\n const { appId, version: requestedVersion, registryUrl: overrideRegistryUrl } = params;\n const registryUrl = overrideRegistryUrl\n ? this.normalizeRegistryUrl(overrideRegistryUrl)\n : (await this.configService.getSnapshot()).currentUrl;\n const metadataUrl = new URL(encodeURIComponent(appId), registryUrl).toString();\n const rawDocument = await this.readGetResponse(\n metadataUrl,\n `无法从 registry 拉取 ${appId} metadata`,\n async (response) => await response.json(),\n );\n const document = this.parseDocument(rawDocument, appId);\n const version = requestedVersion ?? document[\"dist-tags\"].latest;\n const versionRecord = document.versions[version];\n if (!versionRecord) {\n throw new Error(`registry ${registryUrl} 未提供 ${appId}@${version}。`);\n }\n return {\n registryUrl,\n metadataUrl,\n appId,\n version,\n description: versionRecord.description ?? document.description,\n publisher: versionRecord.publisher,\n permissions: versionRecord.permissions,\n distributionMode: versionRecord.dist.kind === \"source\" ? \"source\" : \"bundle\",\n bundleUrl: new URL(\n versionRecord.dist.artifact ??\n versionRecord.dist.source ??\n versionRecord.dist.bundle,\n metadataUrl,\n ).toString(),\n sha256: versionRecord.dist.sha256,\n };\n };\n\n downloadBundle = async (params: {\n resolution: AppRemoteRegistryResolution;\n targetDirectory: string;\n }): Promise<{\n bundlePath: string;\n }> => {\n const { resolution, targetDirectory } = params;\n const bundleBytes = await this.readGetResponse(\n resolution.bundleUrl,\n `无法下载 bundle:${resolution.bundleUrl}`,\n async (response) => {\n const contentLength = Number(response.headers.get(\"content-length\"));\n if (Number.isFinite(contentLength) && contentLength > MAX_REMOTE_BUNDLE_BYTES) {\n throw new Error(`远程 bundle 超过 ${MAX_REMOTE_BUNDLE_BYTES} bytes 上限。`);\n }\n const bytes = Buffer.from(await response.arrayBuffer());\n if (bytes.byteLength > MAX_REMOTE_BUNDLE_BYTES) {\n throw new Error(`远程 bundle 超过 ${MAX_REMOTE_BUNDLE_BYTES} bytes 上限。`);\n }\n return bytes;\n },\n );\n const actualSha256 = createHash(\"sha256\").update(bundleBytes).digest(\"hex\");\n if (actualSha256 !== resolution.sha256) {\n throw new Error(\n `bundle checksum 校验失败:期望 ${resolution.sha256},实际 ${actualSha256}`,\n );\n }\n const bundlePath = path.join(\n targetDirectory,\n `${this.normalizeBundleFileName(resolution.appId)}-${resolution.version}.napp`,\n );\n await writeFile(bundlePath, bundleBytes);\n return {\n bundlePath,\n };\n };\n\n private parseDocument = (\n rawDocument: unknown,\n appId: string,\n ): AppRemoteRegistryDocument => {\n if (!rawDocument || typeof rawDocument !== \"object\" || Array.isArray(rawDocument)) {\n throw new Error(`registry ${appId} metadata 必须是对象。`);\n }\n const candidate = rawDocument as Record<string, unknown>;\n const name = this.readRequiredString(candidate.name, \"name\");\n if (name !== appId) {\n throw new Error(`registry 返回的包名与请求不一致:请求 ${appId},收到 ${name}`);\n }\n const distTags = candidate[\"dist-tags\"];\n if (!distTags || typeof distTags !== \"object\" || Array.isArray(distTags)) {\n throw new Error(\"registry metadata 缺少 dist-tags。\");\n }\n const versions = candidate.versions;\n if (!versions || typeof versions !== \"object\" || Array.isArray(versions)) {\n throw new Error(\"registry metadata 缺少 versions。\");\n }\n return {\n name,\n description: this.readOptionalString(candidate.description, \"description\"),\n \"dist-tags\": {\n latest: this.readRequiredString(\n (distTags as Record<string, unknown>).latest,\n \"dist-tags.latest\",\n ),\n },\n versions: Object.fromEntries(\n Object.entries(versions).map(([version, rawVersion]) => [\n version,\n this.parseVersion(rawVersion, name, version),\n ]),\n ),\n };\n };\n\n private parseVersion = (\n rawVersion: unknown,\n appId: string,\n version: string,\n ): AppRemoteRegistryVersion => {\n if (!rawVersion || typeof rawVersion !== \"object\" || Array.isArray(rawVersion)) {\n throw new Error(`registry metadata 的 versions.${version} 必须是对象。`);\n }\n const candidate = rawVersion as Record<string, unknown>;\n const name = this.readRequiredString(candidate.name, `versions.${version}.name`);\n const parsedVersion = this.readRequiredString(\n candidate.version,\n `versions.${version}.version`,\n );\n if (name !== appId || parsedVersion !== version) {\n throw new Error(`registry metadata 的 versions.${version} 与 app id/version 不一致。`);\n }\n const dist = candidate.dist;\n if (!dist || typeof dist !== \"object\" || Array.isArray(dist)) {\n throw new Error(`registry metadata 的 versions.${version}.dist 必须是对象。`);\n }\n const distCandidate = dist as Record<string, unknown>;\n return {\n name,\n version: parsedVersion,\n description: this.readOptionalString(\n candidate.description,\n `versions.${version}.description`,\n ),\n publisher: this.parsePublisher(candidate.publisher, version),\n permissions: candidate.permissions as AppRemoteRegistryVersion[\"permissions\"],\n dist: {\n kind:\n distCandidate.kind === \"source\" || distCandidate.kind === \"bundle\"\n ? distCandidate.kind\n : undefined,\n artifact: this.readOptionalString(\n distCandidate.artifact,\n `versions.${version}.dist.artifact`,\n ),\n bundle: this.readRequiredString(\n distCandidate.bundle,\n `versions.${version}.dist.bundle`,\n ),\n source: this.readOptionalString(\n distCandidate.source,\n `versions.${version}.dist.source`,\n ),\n sha256: this.readRequiredString(\n distCandidate.sha256,\n `versions.${version}.dist.sha256`,\n ),\n },\n };\n };\n\n private parsePublisher = (\n rawPublisher: unknown,\n version: string,\n ): AppRemoteRegistryVersion[\"publisher\"] => {\n if (rawPublisher === undefined) {\n return undefined;\n }\n if (!rawPublisher || typeof rawPublisher !== \"object\" || Array.isArray(rawPublisher)) {\n throw new Error(`versions.${version}.publisher 必须是对象。`);\n }\n const candidate = rawPublisher as Record<string, unknown>;\n return {\n id: this.readRequiredString(candidate.id, `versions.${version}.publisher.id`),\n name: this.readRequiredString(candidate.name, `versions.${version}.publisher.name`),\n url: this.readOptionalString(candidate.url, `versions.${version}.publisher.url`),\n };\n };\n\n private readRequiredString = (value: unknown, fieldName: string): string => {\n if (typeof value !== \"string\" || !value.trim()) {\n throw new Error(`${fieldName} 必须是非空字符串。`);\n }\n return value.trim();\n };\n\n private readOptionalString = (\n value: unknown,\n fieldName: string,\n ): string | undefined => {\n if (value === undefined) {\n return undefined;\n }\n return this.readRequiredString(value, fieldName);\n };\n\n private normalizeBundleFileName = (appId: string): string => {\n return appId.replace(/[^a-zA-Z0-9._-]+/g, \"-\");\n };\n\n private readGetResponse = async <T>(\n url: string,\n operation: string,\n read: (response: Response) => Promise<T>,\n ): Promise<T> => {\n let lastError: unknown;\n for (let attempt = 1; attempt <= MAX_REGISTRY_GET_ATTEMPTS; attempt += 1) {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n if (this.isTransientHttpStatus(response.status) && attempt < MAX_REGISTRY_GET_ATTEMPTS) {\n await response.body?.cancel();\n await this.waitBeforeRetry(attempt);\n continue;\n }\n throw new Error(`${operation}:${response.status} ${response.statusText}`);\n }\n try {\n return await read(response);\n } catch (error) {\n if (!this.isTransientNetworkError(error) || attempt === MAX_REGISTRY_GET_ATTEMPTS) {\n throw error;\n }\n lastError = error;\n }\n } catch (error) {\n if (!this.isTransientNetworkError(error) || attempt === MAX_REGISTRY_GET_ATTEMPTS) {\n if (this.isTransientNetworkError(error)) {\n throw new Error(\n `${operation}失败(已尝试 ${MAX_REGISTRY_GET_ATTEMPTS} 次)。`,\n { cause: error },\n );\n }\n throw error;\n }\n lastError = error;\n }\n await this.waitBeforeRetry(attempt);\n }\n throw new Error(\n `${operation}失败(已尝试 ${MAX_REGISTRY_GET_ATTEMPTS} 次)。`,\n { cause: lastError },\n );\n };\n\n private isTransientHttpStatus = (status: number): boolean => {\n return status === 408 || status === 429 || status >= 500;\n };\n\n private isTransientNetworkError = (error: unknown): boolean => {\n return error instanceof TypeError;\n };\n\n private waitBeforeRetry = async (attempt: number): Promise<void> => {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, attempt * 100);\n });\n };\n\n private normalizeRegistryUrl = (registryUrl: string): string => {\n let normalized: URL;\n try {\n normalized = new URL(registryUrl);\n } catch {\n throw new Error(`非法 registry URL:${registryUrl}`);\n }\n if (normalized.protocol !== \"http:\" && normalized.protocol !== \"https:\") {\n throw new Error(`registry URL 只支持 http/https:${registryUrl}`);\n }\n const text = normalized.toString();\n return text.endsWith(\"/\") ? text : `${text}/`;\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { AppRuntimeOptionsService } from "./app-runtime-options.service.js";
2
2
 
3
- //#region src/cli/app-runtime-cli.service.d.ts
3
+ //#region src/services/app-runtime-cli.service.d.ts
4
4
  declare class AppRuntimeCliService {
5
5
  private readonly optionsService;
6
6
  constructor(optionsService?: AppRuntimeOptionsService);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-runtime-cli.service.d.ts","names":[],"sources":["../../src/services/app-runtime-cli.service.ts"],"mappings":";;;cAqBa,oBAAA;EAAA,iBAEQ,cAAA;cAAA,cAAA,GAAgB,wBAAA;EAGnC,GAAA,QAAgB,OAAA;EAAA,QAkBR,QAAA;EAAA,QA8DA,YAAA;EAAA,QAWA,aAAA;EAAA,QAUA,WAAA;EAAA,QAsBA,YAAA;EAAA,QAwBA,SAAA;EAAA,QAcA,SAAA;EAAA,QAcA,UAAA;EAAA,QAYA,aAAA;EAAA,QAcA,qBAAA;EAAA,QAYA,aAAA;EAAA,QAWA,YAAA;EAAA,QAYA,eAAA;EAAA,QAWA,UAAA;EAAA,QAQA,UAAA;EAAA,QAUA,cAAA;EAAA,QA8CA,iBAAA;EAAA,QAUA,WAAA;EAAA,QAWA,YAAA;EAAA,QAWA,UAAA;EAAA,QAwBA,KAAA;AAAA"}
@@ -1,24 +1,24 @@
1
1
  import { version } from "../package.js";
2
- import { CreateCommand } from "../commands/create.controller.js";
3
- import { AppRuntimeToolchainService } from "../runtime/app-runtime-toolchain.service.js";
4
- import { AppBuildService } from "../runtime/app-build.service.js";
5
- import { RunCommand } from "../commands/run.controller.js";
6
- import { DevCommand } from "../commands/dev.controller.js";
7
- import { GrantCommand } from "../commands/grant.controller.js";
8
- import { InfoCommand } from "../commands/info.controller.js";
9
- import { InspectCommand } from "../commands/inspect.controller.js";
10
- import { InstallCommand } from "../commands/install.controller.js";
11
- import { ListCommand } from "../commands/list.controller.js";
12
- import { PackCommand } from "../commands/pack.controller.js";
13
- import { PermissionsCommand } from "../commands/permissions.controller.js";
14
- import { PublishCommand } from "../commands/publish.controller.js";
15
- import { RegistryCommand } from "../commands/registry.controller.js";
16
- import { RevokeCommand } from "../commands/revoke.controller.js";
17
- import { UninstallCommand } from "../commands/uninstall.controller.js";
18
- import { UpdateCommand } from "../commands/update.controller.js";
19
- import { ValidatePublishCommand } from "../commands/validate-publish.controller.js";
2
+ import { CreateCommand } from "../controllers/create.controller.js";
3
+ import { AppRuntimeToolchainService } from "./app-runtime-toolchain.service.js";
4
+ import { AppBuildService } from "./app-build.service.js";
5
+ import { RunCommand } from "../controllers/run.controller.js";
6
+ import { DevCommand } from "../controllers/dev.controller.js";
7
+ import { GrantCommand } from "../controllers/grant.controller.js";
8
+ import { InfoCommand } from "../controllers/info.controller.js";
9
+ import { InspectCommand } from "../controllers/inspect.controller.js";
10
+ import { InstallCommand } from "../controllers/install.controller.js";
11
+ import { ListCommand } from "../controllers/list.controller.js";
12
+ import { PackCommand } from "../controllers/pack.controller.js";
13
+ import { PermissionsCommand } from "../controllers/permissions.controller.js";
14
+ import { PublishCommand } from "../controllers/publish.controller.js";
15
+ import { RegistryCommand } from "../controllers/registry.controller.js";
16
+ import { RevokeCommand } from "../controllers/revoke.controller.js";
17
+ import { UninstallCommand } from "../controllers/uninstall.controller.js";
18
+ import { UpdateCommand } from "../controllers/update.controller.js";
19
+ import { ValidatePublishCommand } from "../controllers/validate-publish.controller.js";
20
20
  import { AppRuntimeOptionsService } from "./app-runtime-options.service.js";
21
- //#region src/cli/app-runtime-cli.service.ts
21
+ //#region src/services/app-runtime-cli.service.ts
22
22
  var AppRuntimeCliService = class {
23
23
  constructor(optionsService = new AppRuntimeOptionsService()) {
24
24
  this.optionsService = optionsService;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-runtime-cli.service.js","names":["packageJson.version"],"sources":["../../src/services/app-runtime-cli.service.ts"],"sourcesContent":["import packageJson from \"../../package.json\" with { type: \"json\" };\nimport { CreateCommand } from \"#app-runtime/controllers/create.controller.js\";\nimport { DevCommand } from \"#app-runtime/controllers/dev.controller.js\";\nimport { GrantCommand } from \"#app-runtime/controllers/grant.controller.js\";\nimport { InfoCommand } from \"#app-runtime/controllers/info.controller.js\";\nimport { InspectCommand } from \"#app-runtime/controllers/inspect.controller.js\";\nimport { InstallCommand } from \"#app-runtime/controllers/install.controller.js\";\nimport { ListCommand } from \"#app-runtime/controllers/list.controller.js\";\nimport { PackCommand } from \"#app-runtime/controllers/pack.controller.js\";\nimport { PermissionsCommand } from \"#app-runtime/controllers/permissions.controller.js\";\nimport { PublishCommand } from \"#app-runtime/controllers/publish.controller.js\";\nimport { RegistryCommand } from \"#app-runtime/controllers/registry.controller.js\";\nimport { RevokeCommand } from \"#app-runtime/controllers/revoke.controller.js\";\nimport { RunCommand } from \"#app-runtime/controllers/run.controller.js\";\nimport { UninstallCommand } from \"#app-runtime/controllers/uninstall.controller.js\";\nimport { UpdateCommand } from \"#app-runtime/controllers/update.controller.js\";\nimport { ValidatePublishCommand } from \"#app-runtime/controllers/validate-publish.controller.js\";\nimport { AppBuildService } from \"#app-runtime/services/app-build.service.js\";\nimport { AppRuntimeToolchainService } from \"#app-runtime/services/app-runtime-toolchain.service.js\";\nimport { AppRuntimeOptionsService } from \"./app-runtime-options.service.js\";\n\nexport class AppRuntimeCliService {\n constructor(\n private readonly optionsService: AppRuntimeOptionsService = new AppRuntimeOptionsService(),\n ) {}\n\n run = async (): Promise<void> => {\n const args = process.argv.slice(2);\n const [command, ...restArgs] = args;\n if (command === \"--help\" || command === \"help\") {\n this.writeUsage();\n return;\n }\n if (command === \"--version\" || command === \"version\") {\n this.write(`${packageJson.version}\\n`);\n return;\n }\n if (!command) {\n this.writeUsage();\n process.exit(1);\n }\n await this.dispatch(command, restArgs);\n };\n\n private dispatch = async (command: string, restArgs: string[]): Promise<void> => {\n switch (command) {\n case \"create\":\n await this.handleCreate(restArgs);\n return;\n case \"inspect\":\n await this.handleInspect(restArgs);\n return;\n case \"build\":\n await this.handleBuild(restArgs);\n return;\n case \"doctor\":\n await this.handleDoctor(restArgs);\n return;\n case \"run\":\n await this.handleRun(restArgs);\n return;\n case \"dev\":\n await this.handleDev(restArgs);\n return;\n case \"pack\":\n await this.handlePack(restArgs);\n return;\n case \"publish\":\n await this.handlePublish(restArgs);\n return;\n case \"validate-publish\":\n await this.handleValidatePublish(restArgs);\n return;\n case \"install\":\n await this.handleInstall(restArgs);\n return;\n case \"update\":\n await this.handleUpdate(restArgs);\n return;\n case \"uninstall\":\n await this.handleUninstall(restArgs);\n return;\n case \"list\":\n await this.handleList(restArgs);\n return;\n case \"info\":\n await this.handleInfo(restArgs);\n return;\n case \"registry\":\n await this.handleRegistry(restArgs);\n return;\n case \"permissions\":\n await this.handlePermissions(restArgs);\n return;\n case \"grant\":\n await this.handleGrant(restArgs);\n return;\n case \"revoke\":\n await this.handleRevoke(restArgs);\n return;\n default:\n this.writeUsage();\n process.exit(1);\n }\n };\n\n private handleCreate = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"create\", restArgs);\n const options = this.optionsService.readCreateOptions(optionArgs);\n await new CreateCommand().run({\n appDirectory: target,\n template: options.template,\n json: options.json,\n write: this.write,\n });\n };\n\n private handleInspect = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"inspect\", restArgs);\n const options = this.optionsService.readJsonOnlyOptions(optionArgs);\n await new InspectCommand().run({\n appDirectory: target,\n json: options.json,\n write: this.write,\n });\n };\n\n private handleBuild = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"build\", restArgs);\n const options = this.optionsService.readBuildOptions(optionArgs);\n const result = await new AppBuildService().build({\n appDirectory: target,\n install: options.install,\n });\n if (options.json) {\n this.write(`${JSON.stringify({ ok: true, build: result }, null, 2)}\\n`);\n return;\n }\n if (!result.built) {\n this.write(`Build skipped: ${result.skippedReason ?? result.mainKind}\\n`);\n return;\n }\n this.write(`Built ${result.mainKind} app\\n`);\n this.write(`Main: ${result.mainEntryPath}\\n`);\n if (result.installedDependencies) {\n this.write(\"Dependencies: installed\\n\");\n }\n };\n\n private handleDoctor = async (restArgs: string[]): Promise<void> => {\n const options = this.optionsService.readJsonOnlyOptions(restArgs);\n const result = await new AppRuntimeToolchainService().doctor();\n if (options.json) {\n this.write(`${JSON.stringify({ ok: result.ok, doctor: result }, null, 2)}\\n`);\n if (!result.ok) {\n process.exitCode = 1;\n }\n return;\n }\n this.write(`NApp runtime doctor: ${result.ok ? \"ok\" : \"not ready\"}\\n`);\n for (const tool of result.tools) {\n this.write(\n `${tool.ok ? \"ok\" : \"missing\"} ${tool.name}${tool.version ? ` ${tool.version}` : \"\"}\\n`,\n );\n if (!tool.ok) {\n this.write(` ${tool.installHint}\\n`);\n }\n }\n if (!result.ok) {\n process.exitCode = 1;\n }\n };\n\n private handleRun = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"run\", restArgs);\n const options = this.optionsService.readRuntimeOptions(optionArgs);\n await new RunCommand().run({\n appReference: target,\n host: options.host,\n port: options.port,\n dataDirectory: options.dataDirectory,\n json: options.json,\n documentGrantMap: options.documentGrantMap,\n write: this.write,\n });\n };\n\n private handleDev = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"dev\", restArgs);\n const options = this.optionsService.readRuntimeOptions(optionArgs);\n await new DevCommand().run({\n appReference: target,\n host: options.host,\n port: options.port,\n dataDirectory: options.dataDirectory,\n json: options.json,\n documentGrantMap: options.documentGrantMap,\n write: this.write,\n });\n };\n\n private handlePack = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"pack\", restArgs);\n const options = this.optionsService.readPackOptions(optionArgs);\n await new PackCommand().run({\n appDirectory: target,\n outputPath: options.outputPath,\n mode: options.mode,\n json: options.json,\n write: this.write,\n });\n };\n\n private handlePublish = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"publish\", restArgs);\n const options = this.optionsService.readPublishOptions(optionArgs);\n await new PublishCommand().run({\n appDirectory: target,\n metadataPath: options.metadataPath,\n apiBaseUrl: options.apiBaseUrl,\n token: options.token,\n mode: options.mode,\n json: options.json,\n write: this.write,\n });\n };\n\n private handleValidatePublish = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"validate-publish\", restArgs);\n const options = this.optionsService.readPublishOptions(optionArgs);\n await new ValidatePublishCommand().run({\n appDirectory: target,\n metadataPath: options.metadataPath,\n mode: options.mode,\n json: options.json,\n write: this.write,\n });\n };\n\n private handleInstall = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"install\", restArgs);\n const options = this.optionsService.readInstallOptions(optionArgs);\n await new InstallCommand().run({\n appSource: target,\n registryUrl: options.registryUrl,\n json: options.json,\n write: this.write,\n });\n };\n\n private handleUpdate = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"update\", restArgs);\n const options = this.optionsService.readUpdateOptions(optionArgs);\n await new UpdateCommand().run({\n appId: target,\n version: options.version,\n registryUrl: options.registryUrl,\n json: options.json,\n write: this.write,\n });\n };\n\n private handleUninstall = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"uninstall\", restArgs);\n const options = this.optionsService.readUninstallOptions(optionArgs);\n await new UninstallCommand().run({\n appId: target,\n purgeData: options.purgeData,\n json: options.json,\n write: this.write,\n });\n };\n\n private handleList = async (restArgs: string[]): Promise<void> => {\n const options = this.optionsService.readJsonOnlyOptions(restArgs);\n await new ListCommand().run({\n json: options.json,\n write: this.write,\n });\n };\n\n private handleInfo = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"info\", restArgs);\n const options = this.optionsService.readJsonOnlyOptions(optionArgs);\n await new InfoCommand().run({\n appId: target,\n json: options.json,\n write: this.write,\n });\n };\n\n private handleRegistry = async (restArgs: string[]): Promise<void> => {\n const [actionOrUrl, ...optionArgs] = restArgs;\n if (!actionOrUrl || actionOrUrl === \"get\") {\n const options = this.optionsService.readJsonOnlyOptions(optionArgs);\n await new RegistryCommand().run({\n action: \"get\",\n json: options.json,\n write: this.write,\n });\n return;\n }\n if (actionOrUrl === \"--json\") {\n const options = this.optionsService.readJsonOnlyOptions([actionOrUrl, ...optionArgs]);\n await new RegistryCommand().run({\n action: \"get\",\n json: options.json,\n write: this.write,\n });\n return;\n }\n if (actionOrUrl === \"set\") {\n const { target, optionArgs: actionOptionArgs } = this.optionsService.readTarget(\n \"registry set\",\n optionArgs,\n );\n const options = this.optionsService.readJsonOnlyOptions(actionOptionArgs);\n await new RegistryCommand().run({\n action: \"set\",\n registryUrl: target,\n json: options.json,\n write: this.write,\n });\n return;\n }\n if (actionOrUrl === \"reset\") {\n const options = this.optionsService.readJsonOnlyOptions(optionArgs);\n await new RegistryCommand().run({\n action: \"reset\",\n json: options.json,\n write: this.write,\n });\n return;\n }\n throw new Error(`未知 registry 子命令:${actionOrUrl}`);\n };\n\n private handlePermissions = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"permissions\", restArgs);\n const options = this.optionsService.readJsonOnlyOptions(optionArgs);\n await new PermissionsCommand().run({\n appId: target,\n json: options.json,\n write: this.write,\n });\n };\n\n private handleGrant = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"grant\", restArgs);\n const options = this.optionsService.readGrantOptions(optionArgs);\n await new GrantCommand().run({\n appId: target,\n documentGrantMap: options.documentGrantMap,\n json: options.json,\n write: this.write,\n });\n };\n\n private handleRevoke = async (restArgs: string[]): Promise<void> => {\n const { target, optionArgs } = this.optionsService.readTarget(\"revoke\", restArgs);\n const options = this.optionsService.readRevokeOptions(optionArgs);\n await new RevokeCommand().run({\n appId: target,\n documentScopeIds: options.documentScopeIds,\n json: options.json,\n write: this.write,\n });\n };\n\n private writeUsage = (): void => {\n this.write(\"Usage: napp create <app-dir> [--template starter|ts-http|ts-http-lite] [--json]\\n\");\n this.write(\" napp inspect <app-dir> [--json]\\n\");\n this.write(\" napp build <app-dir> [--install] [--json]\\n\");\n this.write(\" napp doctor [--json]\\n\");\n this.write(\" napp <run|dev> <app-dir|app-id> [--host 127.0.0.1] [--port 3100] [--data /path] [--json] [--document scope=/path]\\n\");\n this.write(\" napp pack <app-dir> [--mode source|bundle] [--out bundle.napp] [--json]\\n\");\n this.write(\" napp publish <app-dir> [--mode source|bundle] [--meta marketplace.json] [--api-base <url>] [--token <token>] [--json]\\n\");\n this.write(\" napp validate-publish <app-dir> [--mode source|bundle] [--meta marketplace.json] [--json]\\n\");\n this.write(\" napp install <app-dir|bundle.napp|app-id[@version]> [--registry <url>] [--json]\\n\");\n this.write(\" napp update <app-id> [--version <version>] [--registry <url>] [--json]\\n\");\n this.write(\" napp uninstall <app-id> [--purge-data] [--json]\\n\");\n this.write(\" napp list [--json]\\n\");\n this.write(\" napp info <app-id> [--json]\\n\");\n this.write(\" napp registry [get] [--json]\\n\");\n this.write(\" napp registry set <url> [--json]\\n\");\n this.write(\" napp registry reset [--json]\\n\");\n this.write(\" napp permissions <app-id> [--json]\\n\");\n this.write(\" napp grant <app-id> --document scope=/path [--json]\\n\");\n this.write(\" napp revoke <app-id> --document scope [--json]\\n\");\n this.write(\" napp --help\\n\");\n this.write(\" napp --version\\n\");\n };\n\n private write = (text: string): void => {\n process.stdout.write(text);\n };\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import { AppDistributionMode } from "../bundle/app-bundle.types.js";
2
- import { AppDocumentGrantMap } from "../permissions/app-permissions.types.js";
3
- import { AppScaffoldTemplate } from "../scaffold/app-scaffold.service.js";
1
+ import { AppDistributionMode } from "../types/app-bundle.types.js";
2
+ import { AppDocumentGrantMap } from "../types/app-permissions.types.js";
3
+ import { AppScaffoldTemplate } from "./app-scaffold.service.js";
4
4
 
5
- //#region src/cli/app-runtime-options.service.d.ts
5
+ //#region src/services/app-runtime-options.service.d.ts
6
6
  type RuntimeCliOptions = {
7
7
  host: string;
8
8
  port: number;
@@ -17,7 +17,7 @@ type CreateCliOptions = {
17
17
  type PackCliOptions = {
18
18
  json: boolean;
19
19
  outputPath?: string;
20
- mode: AppDistributionMode;
20
+ mode?: AppDistributionMode;
21
21
  };
22
22
  type BuildCliOptions = {
23
23
  json: boolean;
@@ -52,7 +52,7 @@ type PublishCliOptions = {
52
52
  metadataPath?: string;
53
53
  apiBaseUrl?: string;
54
54
  token?: string;
55
- mode: AppDistributionMode;
55
+ mode?: AppDistributionMode;
56
56
  };
57
57
  declare class AppRuntimeOptionsService {
58
58
  readTarget: (command: string, rawArgs: string[]) => {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-runtime-options.service.d.ts","names":[],"sources":["../../src/services/app-runtime-options.service.ts"],"mappings":";;;;;KAIY,iBAAA;EACV,IAAA;EACA,IAAA;EACA,aAAA;EACA,IAAA;EACA,gBAAA,EAAkB,mBAAA;AAAA;AAAA,KAGR,gBAAA;EACV,IAAA;EACA,QAAA,EAAU,mBAAA;AAAA;AAAA,KAGA,cAAA;EACV,IAAA;EACA,UAAA;EACA,IAAA,GAAO,mBAAA;AAAA;AAAA,KAGG,eAAA;EACV,IAAA;EACA,OAAA;AAAA;AAAA,KAGU,kBAAA;EACV,IAAA;AAAA;AAAA,KAGU,iBAAA;EACV,IAAA;EACA,WAAA;AAAA;AAAA,KAGU,gBAAA;EACV,IAAA;EACA,WAAA;EACA,OAAA;AAAA;AAAA,KAGU,mBAAA;EACV,IAAA;EACA,SAAA;AAAA;AAAA,KAGU,eAAA;EACV,IAAA;EACA,gBAAA,EAAkB,mBAAA;AAAA;AAAA,KAGR,gBAAA;EACV,IAAA;EACA,gBAAA;AAAA;AAAA,KAGU,iBAAA;EACV,IAAA;EACA,YAAA;EACA,UAAA;EACA,KAAA;EACA,IAAA,GAAO,mBAAA;AAAA;AAAA,cAGI,wBAAA;EACX,UAAA,GACE,OAAA,UACA,OAAA;IAEA,MAAA;IACA,UAAA;EAAA;EAYF,iBAAA,GAAqB,OAAA,eAAoB,gBAAA;EAAA,QA4BjC,kBAAA;EAOR,eAAA,GAAmB,OAAA,eAAoB,cAAA;EA6BvC,gBAAA,GAAoB,OAAA,eAAoB,eAAA;EAuBxC,mBAAA,GAAuB,OAAA,eAAoB,kBAAA;EAmB3C,kBAAA,GAAsB,OAAA,eAAoB,iBAAA;EAyB1C,iBAAA,GAAqB,OAAA,eAAoB,gBAAA;EA6BzC,oBAAA,GAAwB,OAAA,eAAoB,mBAAA;EAuB5C,kBAAA,GAAsB,OAAA,eAAoB,iBAAA;EAiD1C,gBAAA,GAAoB,OAAA,eAAoB,eAAA;EAgCxC,iBAAA,GAAqB,OAAA,eAAoB,gBAAA;EA+BzC,kBAAA,GAAsB,OAAA,eAAoB,iBAAA;EAAA,QAqClC,oBAAA;EAAA,QAOA,mBAAA;EAAA,QAgBA,mBAAA;EAAA,QAQA,kBAAA;AAAA"}
@@ -1,4 +1,4 @@
1
- //#region src/cli/app-runtime-options.service.ts
1
+ //#region src/services/app-runtime-options.service.ts
2
2
  var AppRuntimeOptionsService = class {
3
3
  readTarget = (command, rawArgs) => {
4
4
  const [target, ...optionArgs] = rawArgs;
@@ -35,10 +35,7 @@ var AppRuntimeOptionsService = class {
35
35
  throw new Error("--template 只支持 starter、ts-http 或 ts-http-lite。");
36
36
  };
37
37
  readPackOptions = (rawArgs) => {
38
- const options = {
39
- json: false,
40
- mode: "source"
41
- };
38
+ const options = { json: false };
42
39
  for (let index = 0; index < rawArgs.length; index += 1) {
43
40
  const current = rawArgs[index];
44
41
  if (!current?.startsWith("--")) throw new Error(`未知参数:${current}`);
@@ -238,10 +235,7 @@ var AppRuntimeOptionsService = class {
238
235
  return options;
239
236
  };
240
237
  readPublishOptions = (rawArgs) => {
241
- const options = {
242
- json: false,
243
- mode: "source"
244
- };
238
+ const options = { json: false };
245
239
  for (let index = 0; index < rawArgs.length; index += 1) {
246
240
  const current = rawArgs[index];
247
241
  if (!current?.startsWith("--")) throw new Error(`未知参数:${current}`);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-runtime-options.service.js","names":[],"sources":["../../src/services/app-runtime-options.service.ts"],"sourcesContent":["import type { AppDocumentGrantMap } from \"#app-runtime/types/app-permissions.types.js\";\nimport type { AppDistributionMode } from \"#app-runtime/types/app-bundle.types.js\";\nimport type { AppScaffoldTemplate } from \"#app-runtime/services/app-scaffold.service.js\";\n\nexport type RuntimeCliOptions = {\n host: string;\n port: number;\n dataDirectory?: string;\n json: boolean;\n documentGrantMap: AppDocumentGrantMap;\n};\n\nexport type CreateCliOptions = {\n json: boolean;\n template: AppScaffoldTemplate;\n};\n\nexport type PackCliOptions = {\n json: boolean;\n outputPath?: string;\n mode?: AppDistributionMode;\n};\n\nexport type BuildCliOptions = {\n json: boolean;\n install: boolean;\n};\n\nexport type JsonOnlyCliOptions = {\n json: boolean;\n};\n\nexport type InstallCliOptions = {\n json: boolean;\n registryUrl?: string;\n};\n\nexport type UpdateCliOptions = {\n json: boolean;\n registryUrl?: string;\n version?: string;\n};\n\nexport type UninstallCliOptions = {\n json: boolean;\n purgeData: boolean;\n};\n\nexport type GrantCliOptions = {\n json: boolean;\n documentGrantMap: AppDocumentGrantMap;\n};\n\nexport type RevokeCliOptions = {\n json: boolean;\n documentScopeIds: string[];\n};\n\nexport type PublishCliOptions = {\n json: boolean;\n metadataPath?: string;\n apiBaseUrl?: string;\n token?: string;\n mode?: AppDistributionMode;\n};\n\nexport class AppRuntimeOptionsService {\n readTarget = (\n command: string,\n rawArgs: string[],\n ): {\n target: string;\n optionArgs: string[];\n } => {\n const [target, ...optionArgs] = rawArgs;\n if (!target || target.startsWith(\"--\")) {\n throw new Error(`${command} 缺少目标参数。`);\n }\n return {\n target,\n optionArgs,\n };\n };\n\n readCreateOptions = (rawArgs: string[]): CreateCliOptions => {\n const options: CreateCliOptions = {\n json: false,\n template: \"starter\",\n };\n\n for (let index = 0; index < rawArgs.length; index += 1) {\n const current = rawArgs[index];\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n const nextValue = rawArgs[index + 1];\n switch (current) {\n case \"--json\":\n options.json = true;\n break;\n case \"--template\":\n options.template = this.readCreateTemplate(this.requireOptionValue(current, nextValue));\n index += 1;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n\n return options;\n };\n\n private readCreateTemplate = (rawTemplate: string): AppScaffoldTemplate => {\n if (rawTemplate === \"starter\" || rawTemplate === \"ts-http\" || rawTemplate === \"ts-http-lite\") {\n return rawTemplate;\n }\n throw new Error(\"--template 只支持 starter、ts-http 或 ts-http-lite。\");\n };\n\n readPackOptions = (rawArgs: string[]): PackCliOptions => {\n const options: PackCliOptions = {\n json: false,\n };\n for (let index = 0; index < rawArgs.length; index += 1) {\n const current = rawArgs[index];\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n const nextValue = rawArgs[index + 1];\n switch (current) {\n case \"--json\":\n options.json = true;\n break;\n case \"--out\":\n options.outputPath = this.requireOptionValue(current, nextValue);\n index += 1;\n break;\n case \"--mode\":\n options.mode = this.readDistributionMode(this.requireOptionValue(current, nextValue));\n index += 1;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n return options;\n };\n\n readBuildOptions = (rawArgs: string[]): BuildCliOptions => {\n const options: BuildCliOptions = {\n json: false,\n install: false,\n };\n for (const current of rawArgs) {\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n switch (current) {\n case \"--json\":\n options.json = true;\n break;\n case \"--install\":\n options.install = true;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n return options;\n };\n\n readJsonOnlyOptions = (rawArgs: string[]): JsonOnlyCliOptions => {\n const options: JsonOnlyCliOptions = {\n json: false,\n };\n for (const current of rawArgs) {\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n switch (current) {\n case \"--json\":\n options.json = true;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n return options;\n };\n\n readInstallOptions = (rawArgs: string[]): InstallCliOptions => {\n const options: InstallCliOptions = {\n json: false,\n };\n for (let index = 0; index < rawArgs.length; index += 1) {\n const current = rawArgs[index];\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n const nextValue = rawArgs[index + 1];\n switch (current) {\n case \"--json\":\n options.json = true;\n break;\n case \"--registry\":\n options.registryUrl = this.requireOptionValue(current, nextValue);\n index += 1;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n return options;\n };\n\n readUpdateOptions = (rawArgs: string[]): UpdateCliOptions => {\n const options: UpdateCliOptions = {\n json: false,\n };\n for (let index = 0; index < rawArgs.length; index += 1) {\n const current = rawArgs[index];\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n const nextValue = rawArgs[index + 1];\n switch (current) {\n case \"--json\":\n options.json = true;\n break;\n case \"--registry\":\n options.registryUrl = this.requireOptionValue(current, nextValue);\n index += 1;\n break;\n case \"--version\":\n options.version = this.requireOptionValue(current, nextValue);\n index += 1;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n return options;\n };\n\n readUninstallOptions = (rawArgs: string[]): UninstallCliOptions => {\n const options: UninstallCliOptions = {\n json: false,\n purgeData: false,\n };\n for (const current of rawArgs) {\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n switch (current) {\n case \"--json\":\n options.json = true;\n break;\n case \"--purge-data\":\n options.purgeData = true;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n return options;\n };\n\n readRuntimeOptions = (rawArgs: string[]): RuntimeCliOptions => {\n const options: RuntimeCliOptions = {\n host: \"127.0.0.1\",\n port: 3100,\n dataDirectory: undefined,\n json: false,\n documentGrantMap: {},\n };\n\n for (let index = 0; index < rawArgs.length; index += 1) {\n const current = rawArgs[index];\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n const nextValue = rawArgs[index + 1];\n switch (current) {\n case \"--host\":\n options.host = this.requireOptionValue(current, nextValue);\n index += 1;\n break;\n case \"--port\":\n options.port = Number.parseInt(this.requireOptionValue(current, nextValue), 10);\n if (Number.isNaN(options.port) || options.port < 0) {\n throw new Error(\"--port 必须是非负整数。\");\n }\n index += 1;\n break;\n case \"--json\":\n options.json = true;\n break;\n case \"--data\":\n options.dataDirectory = this.requireOptionValue(current, nextValue);\n index += 1;\n break;\n case \"--document\":\n this.assignDocumentGrant(\n options.documentGrantMap,\n this.requireOptionValue(current, nextValue),\n );\n index += 1;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n\n return options;\n };\n\n readGrantOptions = (rawArgs: string[]): GrantCliOptions => {\n const options: GrantCliOptions = {\n json: false,\n documentGrantMap: {},\n };\n for (let index = 0; index < rawArgs.length; index += 1) {\n const current = rawArgs[index];\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n const nextValue = rawArgs[index + 1];\n switch (current) {\n case \"--json\":\n options.json = true;\n break;\n case \"--document\":\n this.assignDocumentGrant(\n options.documentGrantMap,\n this.requireOptionValue(current, nextValue),\n );\n index += 1;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n if (Object.keys(options.documentGrantMap).length === 0) {\n throw new Error(\"grant 至少需要一个 --document scope=/path。\");\n }\n return options;\n };\n\n readRevokeOptions = (rawArgs: string[]): RevokeCliOptions => {\n const options: RevokeCliOptions = {\n json: false,\n documentScopeIds: [],\n };\n for (let index = 0; index < rawArgs.length; index += 1) {\n const current = rawArgs[index];\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n const nextValue = rawArgs[index + 1];\n switch (current) {\n case \"--json\":\n options.json = true;\n break;\n case \"--document\":\n options.documentScopeIds.push(\n this.readDocumentScopeId(this.requireOptionValue(current, nextValue)),\n );\n index += 1;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n if (options.documentScopeIds.length === 0) {\n throw new Error(\"revoke 至少需要一个 --document scope。\");\n }\n return options;\n };\n\n readPublishOptions = (rawArgs: string[]): PublishCliOptions => {\n const options: PublishCliOptions = {\n json: false,\n };\n for (let index = 0; index < rawArgs.length; index += 1) {\n const current = rawArgs[index];\n if (!current?.startsWith(\"--\")) {\n throw new Error(`未知参数:${current}`);\n }\n const nextValue = rawArgs[index + 1];\n switch (current) {\n case \"--json\":\n options.json = true;\n break;\n case \"--meta\":\n options.metadataPath = this.requireOptionValue(current, nextValue);\n index += 1;\n break;\n case \"--api-base\":\n options.apiBaseUrl = this.requireOptionValue(current, nextValue);\n index += 1;\n break;\n case \"--token\":\n options.token = this.requireOptionValue(current, nextValue);\n index += 1;\n break;\n case \"--mode\":\n options.mode = this.readDistributionMode(this.requireOptionValue(current, nextValue));\n index += 1;\n break;\n default:\n throw new Error(`未知参数:${current}`);\n }\n }\n return options;\n };\n\n private readDistributionMode = (rawMode: string): AppDistributionMode => {\n if (rawMode === \"source\" || rawMode === \"bundle\") {\n return rawMode;\n }\n throw new Error(\"--mode 只支持 source 或 bundle。\");\n };\n\n private assignDocumentGrant = (\n documentGrantMap: AppDocumentGrantMap,\n rawGrant: string,\n ): void => {\n const delimiterIndex = rawGrant.indexOf(\"=\");\n if (delimiterIndex < 1) {\n throw new Error(\"--document 必须使用 scopeId=/absolute/or/relative/path 格式。\");\n }\n const scopeId = rawGrant.slice(0, delimiterIndex).trim();\n const directoryPath = rawGrant.slice(delimiterIndex + 1).trim();\n if (!scopeId || !directoryPath) {\n throw new Error(\"--document 缺少 scopeId 或 path。\");\n }\n documentGrantMap[scopeId] = directoryPath;\n };\n\n private readDocumentScopeId = (scopeId: string): string => {\n const normalized = scopeId.trim();\n if (!normalized || normalized.includes(\"=\")) {\n throw new Error(\"--document 必须使用 scopeId 格式。\");\n }\n return normalized;\n };\n\n private requireOptionValue = (flag: string, nextValue: string | undefined): string => {\n if (!nextValue || nextValue.startsWith(\"--\")) {\n throw new Error(`${flag} 缺少值。`);\n }\n return nextValue;\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- //#region src/runtime/app-runtime-toolchain.service.d.ts
1
+ //#region src/services/app-runtime-toolchain.service.d.ts
2
2
  type AppRuntimeToolStatus = {
3
3
  name: string;
4
4
  command: string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-runtime-toolchain.service.d.ts","names":[],"sources":["../../src/services/app-runtime-toolchain.service.ts"],"mappings":";KAGY,oBAAA;EACV,IAAA;EACA,OAAA;EACA,EAAA;EACA,OAAA;EACA,WAAA;EACA,KAAA;AAAA;AAAA,KAGU,sBAAA;EACV,EAAA;EACA,KAAA,EAAO,oBAAA;AAAA;AAAA,KAGG,uBAAA;EACV,MAAA;EACA,MAAA;AAAA;AAAA,cA+BW,0BAAA;EACX,MAAA,QAAmB,OAAA,CAAQ,sBAAA;EAQ3B,2BAAA,QAAwC,OAAA;EAcxC,UAAA,GAAoB,MAAA;IAClB,OAAA;IACA,IAAA;IACA,GAAA;EAAA,MACE,OAAA,CAAQ,uBAAA;EAAA,QASJ,SAAA;EAAA,QA0BA,cAAA;AAAA"}
@@ -1,5 +1,5 @@
1
1
  import { spawn } from "node:child_process";
2
- //#region src/runtime/app-runtime-toolchain.service.ts
2
+ //#region src/services/app-runtime-toolchain.service.ts
3
3
  const REQUIRED_TOOLS = [
4
4
  {
5
5
  name: "npm",
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-runtime-toolchain.service.js","names":[],"sources":["../../src/services/app-runtime-toolchain.service.ts"],"sourcesContent":["import { spawn, type ChildProcessByStdio } from \"node:child_process\";\nimport type { Readable } from \"node:stream\";\n\nexport type AppRuntimeToolStatus = {\n name: string;\n command: string;\n ok: boolean;\n version?: string;\n installHint: string;\n error?: string;\n};\n\nexport type AppRuntimeDoctorResult = {\n ok: boolean;\n tools: AppRuntimeToolStatus[];\n};\n\nexport type AppRuntimeCommandResult = {\n stdout: string;\n stderr: string;\n};\n\ntype RequiredTool = {\n name: string;\n command: string;\n args: string[];\n installHint: string;\n};\n\nconst REQUIRED_TOOLS: RequiredTool[] = [\n {\n name: \"npm\",\n command: \"npm\",\n args: [\"--version\"],\n installHint: \"请安装 Node.js,或使用 NextClaw 桌面版内置运行环境。\",\n },\n {\n name: \"wasmtime\",\n command: \"wasmtime\",\n args: [\"--version\"],\n installHint: \"请安装 Wasmtime,或使用后续内置 Wasmtime 的 NextClaw 发行包。\",\n },\n {\n name: \"wkg\",\n command: \"wkg\",\n args: [\"--version\"],\n installHint: \"请安装 Bytecode Alliance wkg;有 Rust/Cargo 时可执行:cargo install wkg --locked。\",\n },\n];\n\nexport class AppRuntimeToolchainService {\n doctor = async (): Promise<AppRuntimeDoctorResult> => {\n const tools = await Promise.all(REQUIRED_TOOLS.map((tool) => this.checkTool(tool)));\n return {\n ok: tools.every((tool) => tool.ok),\n tools,\n };\n };\n\n assertReadyForWasiHttpBuild = async (): Promise<void> => {\n const result = await this.doctor();\n const missing = result.tools.filter((tool) => !tool.ok);\n if (missing.length === 0) {\n return;\n }\n throw new Error(\n [\n \"NApp WASI HTTP 开发环境尚未就绪。\",\n ...missing.map((tool) => `- 缺少 ${tool.name}: ${tool.installHint}`),\n ].join(\"\\n\"),\n );\n };\n\n runCommand = async (params: {\n command: string;\n args: string[];\n cwd: string;\n }): Promise<AppRuntimeCommandResult> => {\n const { command, args, cwd } = params;\n const child = spawn(command, args, {\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n return await this.collectProcess(child, command);\n };\n\n private checkTool = async (tool: RequiredTool): Promise<AppRuntimeToolStatus> => {\n try {\n const result = await this.runCommand({\n command: tool.command,\n args: tool.args,\n cwd: process.cwd(),\n });\n const version = (result.stdout || result.stderr).trim().split(/\\r?\\n/)[0]?.trim();\n return {\n name: tool.name,\n command: tool.command,\n ok: true,\n version,\n installHint: tool.installHint,\n };\n } catch (error) {\n return {\n name: tool.name,\n command: tool.command,\n ok: false,\n installHint: tool.installHint,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n };\n\n private collectProcess = async (\n child: ChildProcessByStdio<null, Readable, Readable>,\n command: string,\n ): Promise<AppRuntimeCommandResult> => {\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n child.stdout.on(\"data\", (chunk: Buffer) => {\n stdoutChunks.push(chunk);\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n stderrChunks.push(chunk);\n });\n const exitCode = await new Promise<number | null>((resolve, reject) => {\n child.once(\"error\", reject);\n child.once(\"exit\", resolve);\n });\n const stdout = Buffer.concat(stdoutChunks).toString(\"utf-8\");\n const stderr = Buffer.concat(stderrChunks).toString(\"utf-8\");\n if (exitCode !== 0) {\n throw new Error(`${command} exited with ${exitCode ?? \"unknown\"}\\n${stderr || stdout}`);\n }\n return {\n stdout,\n stderr,\n };\n };\n}\n"],"mappings":";;AA6BA,MAAM,iBAAiC;CACrC;EACE,MAAM;EACN,SAAS;EACT,MAAM,CAAC,YAAY;EACnB,aAAa;EACd;CACD;EACE,MAAM;EACN,SAAS;EACT,MAAM,CAAC,YAAY;EACnB,aAAa;EACd;CACD;EACE,MAAM;EACN,SAAS;EACT,MAAM,CAAC,YAAY;EACnB,aAAa;EACd;CACF;AAED,IAAa,6BAAb,MAAwC;CACtC,SAAS,YAA6C;EACpD,MAAM,QAAQ,MAAM,QAAQ,IAAI,eAAe,KAAK,SAAS,KAAK,UAAU,KAAK,CAAC,CAAC;AACnF,SAAO;GACL,IAAI,MAAM,OAAO,SAAS,KAAK,GAAG;GAClC;GACD;;CAGH,8BAA8B,YAA2B;EAEvD,MAAM,WADS,MAAM,KAAK,QAAQ,EACX,MAAM,QAAQ,SAAS,CAAC,KAAK,GAAG;AACvD,MAAI,QAAQ,WAAW,EACrB;AAEF,QAAM,IAAI,MACR,CACE,4BACA,GAAG,QAAQ,KAAK,SAAS,QAAQ,KAAK,KAAK,IAAI,KAAK,cAAc,CACnE,CAAC,KAAK,KAAK,CACb;;CAGH,aAAa,OAAO,WAIoB;EACtC,MAAM,EAAE,SAAS,MAAM,QAAQ;EAC/B,MAAM,QAAQ,MAAM,SAAS,MAAM;GACjC;GACA,OAAO;IAAC;IAAU;IAAQ;IAAO;GAClC,CAAC;AACF,SAAO,MAAM,KAAK,eAAe,OAAO,QAAQ;;CAGlD,YAAoB,OAAO,SAAsD;AAC/E,MAAI;GACF,MAAM,SAAS,MAAM,KAAK,WAAW;IACnC,SAAS,KAAK;IACd,MAAM,KAAK;IACX,KAAK,QAAQ,KAAK;IACnB,CAAC;GACF,MAAM,WAAW,OAAO,UAAU,OAAO,QAAQ,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,MAAM;AACjF,UAAO;IACL,MAAM,KAAK;IACX,SAAS,KAAK;IACd,IAAI;IACJ;IACA,aAAa,KAAK;IACnB;WACM,OAAO;AACd,UAAO;IACL,MAAM,KAAK;IACX,SAAS,KAAK;IACd,IAAI;IACJ,aAAa,KAAK;IAClB,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAC9D;;;CAIL,iBAAyB,OACvB,OACA,YACqC;EACrC,MAAM,eAAyB,EAAE;EACjC,MAAM,eAAyB,EAAE;AACjC,QAAM,OAAO,GAAG,SAAS,UAAkB;AACzC,gBAAa,KAAK,MAAM;IACxB;AACF,QAAM,OAAO,GAAG,SAAS,UAAkB;AACzC,gBAAa,KAAK,MAAM;IACxB;EACF,MAAM,WAAW,MAAM,IAAI,SAAwB,SAAS,WAAW;AACrE,SAAM,KAAK,SAAS,OAAO;AAC3B,SAAM,KAAK,QAAQ,QAAQ;IAC3B;EACF,MAAM,SAAS,OAAO,OAAO,aAAa,CAAC,SAAS,QAAQ;EAC5D,MAAM,SAAS,OAAO,OAAO,aAAa,CAAC,SAAS,QAAQ;AAC5D,MAAI,aAAa,EACf,OAAM,IAAI,MAAM,GAAG,QAAQ,eAAe,YAAY,UAAU,IAAI,UAAU,SAAS;AAEzF,SAAO;GACL;GACA;GACD"}
@@ -1,7 +1,7 @@
1
1
  import { AppTsHttpScaffoldTemplateService } from "./app-ts-http-scaffold-template.service.js";
2
2
  import { AppTsHttpLiteScaffoldTemplateService } from "./app-ts-http-lite-scaffold-template.service.js";
3
3
 
4
- //#region src/scaffold/app-scaffold.service.d.ts
4
+ //#region src/services/app-scaffold.service.d.ts
5
5
  type AppScaffoldTemplate = "starter" | "ts-http" | "ts-http-lite";
6
6
  type AppScaffoldResult = {
7
7
  appDirectory: string;
@@ -1 +1 @@
1
- {"version":3,"file":"app-scaffold.service.d.ts","names":[],"sources":["../../src/scaffold/app-scaffold.service.ts"],"mappings":";;;;KAKY,mBAAA;AAAA,KAEA,iBAAA;EACV,YAAA;EACA,YAAA;EACA,QAAA,EAAU,mBAAA;AAAA;AAAA,cAGC,kBAAA;EAAA,iBAEQ,qBAAA;EAAA,iBACA,yBAAA;cADA,qBAAA,GAAuB,gCAAA,EACvB,yBAAA,GAA2B,oCAAA;EAG9C,QAAA,GACE,eAAA,UACA,OAAA;IACE,QAAA,GAAW,mBAAA;EAAA,MAEZ,OAAA,CAAQ,iBAAA;EAAA,QAyEH,kBAAA;EAAA,QAaA,wBAAA;EAAA,QASA,UAAA;EAAA,QAKA,YAAA;EAAA,QAKA,aAAA;EAAA,QAYA,aAAA;EAAA,QA4BA,cAAA;EAAA,QAUA,WAAA;EAAA,QAyHA,wBAAA;EAAA,QAqBA,WAAA;EAAA,QAwBA,iBAAA;EAAA,QAqDA,YAAA;AAAA"}
1
+ {"version":3,"file":"app-scaffold.service.d.ts","names":[],"sources":["../../src/services/app-scaffold.service.ts"],"mappings":";;;;KAKY,mBAAA;AAAA,KAEA,iBAAA;EACV,YAAA;EACA,YAAA;EACA,QAAA,EAAU,mBAAA;AAAA;AAAA,cAGC,kBAAA;EAAA,iBAEQ,qBAAA;EAAA,iBACA,yBAAA;cADA,qBAAA,GAAuB,gCAAA,EACvB,yBAAA,GAA2B,oCAAA;EAG9C,QAAA,GACE,eAAA,UACA,OAAA;IACE,QAAA,GAAW,mBAAA;EAAA,MAEZ,OAAA,CAAQ,iBAAA;EAAA,QAyEH,kBAAA;EAAA,QAaA,wBAAA;EAAA,QASA,UAAA;EAAA,QAKA,YAAA;EAAA,QAKA,aAAA;EAAA,QAYA,aAAA;EAAA,QA4BA,cAAA;EAAA,QAUA,WAAA;EAAA,QAyHA,wBAAA;EAAA,QAqBA,WAAA;EAAA,QAwBA,iBAAA;EAAA,QAqDA,YAAA;AAAA"}
@@ -2,7 +2,7 @@ import { AppTsHttpScaffoldTemplateService } from "./app-ts-http-scaffold-templat
2
2
  import { AppTsHttpLiteScaffoldTemplateService } from "./app-ts-http-lite-scaffold-template.service.js";
3
3
  import { access, mkdir, writeFile } from "node:fs/promises";
4
4
  import path from "node:path";
5
- //#region src/scaffold/app-scaffold.service.ts
5
+ //#region src/services/app-scaffold.service.ts
6
6
  var AppScaffoldService = class {
7
7
  constructor(tsHttpTemplateService = new AppTsHttpScaffoldTemplateService(), tsHttpLiteTemplateService = new AppTsHttpLiteScaffoldTemplateService()) {
8
8
  this.tsHttpTemplateService = tsHttpTemplateService;
@@ -1 +1 @@
1
- {"version":3,"file":"app-scaffold.service.js","names":[],"sources":["../../src/scaffold/app-scaffold.service.ts"],"sourcesContent":["import { access, mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { AppTsHttpLiteScaffoldTemplateService } from \"./app-ts-http-lite-scaffold-template.service.js\";\nimport { AppTsHttpScaffoldTemplateService } from \"./app-ts-http-scaffold-template.service.js\";\n\nexport type AppScaffoldTemplate = \"starter\" | \"ts-http\" | \"ts-http-lite\";\n\nexport type AppScaffoldResult = {\n appDirectory: string;\n manifestPath: string;\n template: AppScaffoldTemplate;\n};\n\nexport class AppScaffoldService {\n constructor(\n private readonly tsHttpTemplateService: AppTsHttpScaffoldTemplateService = new AppTsHttpScaffoldTemplateService(),\n private readonly tsHttpLiteTemplateService: AppTsHttpLiteScaffoldTemplateService = new AppTsHttpLiteScaffoldTemplateService(),\n ) {}\n\n scaffold = async (\n targetDirectory: string,\n options?: {\n template?: AppScaffoldTemplate;\n },\n ): Promise<AppScaffoldResult> => {\n const appDirectory = path.resolve(targetDirectory);\n const template = options?.template ?? \"starter\";\n await this.assertTargetDoesNotExist(appDirectory);\n await mkdir(path.join(appDirectory, \"main\"), { recursive: true });\n await mkdir(path.join(appDirectory, \"ui\"), { recursive: true });\n await mkdir(path.join(appDirectory, \"assets\"), { recursive: true });\n\n const appName = this.buildAppName(appDirectory);\n const appId = this.buildAppId(appDirectory);\n const manifestPath = path.join(appDirectory, \"manifest.json\");\n if (template === \"ts-http\") {\n await this.writeTemplateFiles(\n appDirectory,\n this.tsHttpTemplateService.buildFiles({\n appId,\n appName,\n }),\n );\n return {\n appDirectory,\n manifestPath,\n template,\n };\n }\n if (template === \"ts-http-lite\") {\n await this.writeTemplateFiles(\n appDirectory,\n this.tsHttpLiteTemplateService.buildFiles({\n appId,\n appName,\n }),\n );\n return {\n appDirectory,\n manifestPath,\n template,\n };\n }\n\n await Promise.all([\n writeFile(\n manifestPath,\n `${JSON.stringify(this.buildManifest(appId, appName), null, 2)}\\n`,\n \"utf-8\",\n ),\n writeFile(\n path.join(appDirectory, \"marketplace.json\"),\n `${JSON.stringify(this.buildMarketplaceMetadata(appName), null, 2)}\\n`,\n \"utf-8\",\n ),\n writeFile(path.join(appDirectory, \"README.md\"), this.buildReadme(appName, appId), \"utf-8\"),\n writeFile(\n path.join(appDirectory, \"main\", \"app.wasm\"),\n Buffer.from(APP_WASM_BASE64, \"base64\"),\n ),\n writeFile(path.join(appDirectory, \"main\", \"app.wat\"), this.buildWatSource(), \"utf-8\"),\n writeFile(path.join(appDirectory, \"ui\", \"index.html\"), this.buildUiHtml(appName), \"utf-8\"),\n writeFile(\n path.join(appDirectory, \"ui\", \"app.controller.js\"),\n this.buildUiController(),\n \"utf-8\",\n ),\n writeFile(path.join(appDirectory, \"assets\", \"icon.svg\"), this.buildIconSvg(), \"utf-8\"),\n ]);\n\n return {\n appDirectory,\n manifestPath,\n template,\n };\n };\n\n private writeTemplateFiles = async (\n appDirectory: string,\n files: Array<{ relativePath: string; content: string | Buffer }>,\n ): Promise<void> => {\n await Promise.all(\n files.map(async (file) => {\n const filePath = path.join(appDirectory, file.relativePath);\n await mkdir(path.dirname(filePath), { recursive: true });\n await writeFile(filePath, file.content);\n }),\n );\n };\n\n private assertTargetDoesNotExist = async (targetDirectory: string): Promise<void> => {\n try {\n await access(targetDirectory);\n } catch {\n return;\n }\n throw new Error(`目标目录已存在:${targetDirectory}`);\n };\n\n private buildAppId = (targetDirectory: string): string => {\n const slug = this.normalizeSlug(path.basename(targetDirectory));\n return `nextclaw.${slug}`;\n };\n\n private buildAppName = (targetDirectory: string): string => {\n const parts = this.normalizeSlug(path.basename(targetDirectory)).split(\"-\");\n return parts.map((part) => `${part[0]?.toUpperCase() ?? \"\"}${part.slice(1)}`).join(\" \");\n };\n\n private normalizeSlug = (value: string): string => {\n const normalized = value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n if (!normalized) {\n throw new Error(\"应用目录名无法生成合法的应用标识。\");\n }\n return normalized;\n };\n\n private buildManifest = (appId: string, appName: string) => {\n return {\n schemaVersion: 1,\n id: appId,\n name: appName,\n version: \"0.1.0\",\n description: \"A minimal NextClaw micro app scaffold created by napp.\",\n icon: \"assets/icon.svg\",\n main: {\n kind: \"wasm\",\n entry: \"main/app.wasm\",\n export: \"summarize_notes\",\n action: \"runStarterDemo\",\n },\n ui: {\n entry: \"ui/index.html\",\n },\n permissions: {\n storage: {\n namespace: appId.replace(/\\./g, \"-\"),\n },\n capabilities: {\n hostBridge: true,\n },\n },\n };\n };\n\n private buildWatSource = (): string => {\n return `(module\n (func (export \"summarize_notes\") (param i32 i32) (result i32)\n local.get 0\n local.get 1\n i32.add\n i32.const 200\n i32.add))\\n`;\n };\n\n private buildUiHtml = (appName: string): string => {\n return `<!doctype html>\n<html lang=\"zh-CN\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>${appName}</title>\n <style>\n :root {\n color-scheme: light;\n font-family: \"IBM Plex Sans\", \"Helvetica Neue\", sans-serif;\n background:\n radial-gradient(circle at top left, rgba(255, 206, 134, 0.24), transparent 30%),\n linear-gradient(165deg, #f7f1e7 0%, #fcfcfe 48%, #e1ebf5 100%);\n color: #11233a;\n }\n\n body {\n margin: 0;\n min-height: 100vh;\n }\n\n main {\n box-sizing: border-box;\n max-width: 760px;\n margin: 0 auto;\n padding: 48px 20px 72px;\n }\n\n .panel {\n background: rgba(255, 255, 255, 0.78);\n border: 1px solid rgba(17, 35, 58, 0.08);\n border-radius: 24px;\n box-shadow: 0 18px 42px rgba(17, 35, 58, 0.12);\n padding: 28px;\n backdrop-filter: blur(18px);\n }\n\n h1 {\n margin: 0 0 12px;\n font-size: clamp(30px, 6vw, 54px);\n line-height: 1;\n }\n\n p {\n line-height: 1.6;\n }\n\n button {\n border: 0;\n border-radius: 999px;\n background: #11233a;\n color: #fff;\n padding: 12px 18px;\n font-size: 15px;\n cursor: pointer;\n }\n\n dl {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 12px;\n margin: 24px 0 0;\n }\n\n dt {\n font-size: 12px;\n color: #556881;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n }\n\n dd {\n margin: 6px 0 0;\n font-size: 24px;\n font-weight: 600;\n }\n\n pre {\n margin-top: 20px;\n padding: 14px;\n border-radius: 16px;\n background: rgba(17, 35, 58, 0.07);\n overflow: auto;\n }\n </style>\n </head>\n <body>\n <main>\n <section class=\"panel\">\n <p>NextClaw Micro App</p>\n <h1 id=\"title\">Loading...</h1>\n <p id=\"description\">A starter scaffold created by napp create.</p>\n <button id=\"run-button\" type=\"button\">Run Starter Demo</button>\n <dl>\n <div>\n <dt>Action</dt>\n <dd id=\"action\">-</dd>\n </div>\n <div>\n <dt>Documents</dt>\n <dd id=\"document-count\">-</dd>\n </div>\n <div>\n <dt>Text Bytes</dt>\n <dd id=\"text-bytes\">-</dd>\n </div>\n <div>\n <dt>Wasm Score</dt>\n <dd id=\"wasm-score\">-</dd>\n </div>\n </dl>\n <pre id=\"details\"></pre>\n </section>\n </main>\n <script type=\"module\" src=\"./app.controller.js\"></script>\n </body>\n</html>\n`;\n };\n\n private buildMarketplaceMetadata = (appName: string) => {\n return {\n slug: this.normalizeSlug(appName),\n summary: `A minimal ${appName} app scaffold created by napp.`,\n summaryI18n: {\n en: `A minimal ${appName} app scaffold created by napp.`,\n zh: `一个由 napp 创建的最小 ${appName} 应用骨架。`,\n },\n description: `A minimal NextClaw app scaffold for ${appName}, ready for local run and marketplace publish.`,\n descriptionI18n: {\n en: `A minimal NextClaw app scaffold for ${appName}, ready for local run and marketplace publish.`,\n zh: `一个面向 ${appName} 的最小 NextClaw 应用骨架,可直接本地运行并发布到 marketplace。`,\n },\n author: \"NextClaw\",\n tags: [\"starter\", \"official\", \"local\"],\n sourceRepo: \"https://github.com/Peiiii/nextclaw\",\n homepage: \"https://nextclaw.io\",\n featured: false,\n };\n };\n\n private buildReadme = (appName: string, appId: string): string => {\n return `# ${appName}\n\nThis starter app was created by \\`napp create\\`.\n\n## Local workflow\n\n\\`\\`\\`bash\nnapp inspect .\nnapp run .\n\\`\\`\\`\n\n## Publish workflow\n\n\\`\\`\\`bash\nnapp publish .\n\\`\\`\\`\n\n## App ID\n\n\\`${appId}\\`\n`;\n };\n\n private buildUiController = (): string => {\n return `const titleNode = document.getElementById(\"title\");\nconst descriptionNode = document.getElementById(\"description\");\nconst actionNode = document.getElementById(\"action\");\nconst documentCountNode = document.getElementById(\"document-count\");\nconst textBytesNode = document.getElementById(\"text-bytes\");\nconst wasmScoreNode = document.getElementById(\"wasm-score\");\nconst detailsNode = document.getElementById(\"details\");\nconst runButton = document.getElementById(\"run-button\");\n\nconst setDetails = (value) => {\n detailsNode.textContent = JSON.stringify(value, null, 2);\n};\n\nconst loadManifest = async () => {\n const response = await fetch(\"/__napp/manifest\");\n const payload = await response.json();\n titleNode.textContent = payload.manifest.name;\n descriptionNode.textContent = payload.manifest.description;\n actionNode.textContent = payload.manifest.main.action;\n setDetails(payload);\n};\n\nconst runDemo = async () => {\n runButton.disabled = true;\n try {\n const response = await fetch(\"/__napp/run\", {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n action: actionNode.textContent,\n }),\n });\n const payload = await response.json();\n documentCountNode.textContent = String(payload.result.input.documentCount);\n textBytesNode.textContent = String(payload.result.input.textBytes);\n wasmScoreNode.textContent = String(payload.result.output.output);\n setDetails(payload);\n } finally {\n runButton.disabled = false;\n }\n};\n\nrunButton.addEventListener(\"click\", () => {\n void runDemo();\n});\n\nawait loadManifest();\n`;\n };\n\n private buildIconSvg = (): string => {\n return `<svg width=\"160\" height=\"160\" viewBox=\"0 0 160 160\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"160\" height=\"160\" rx=\"40\" fill=\"#11233A\" />\n <path d=\"M42 45H118V58H74V115H58V58H42V45Z\" fill=\"#F8C97E\" />\n <path d=\"M92 74H118V87H92V74Z\" fill=\"#FFFFFF\" fill-opacity=\"0.92\" />\n <path d=\"M92 95H118V108H92V95Z\" fill=\"#FFFFFF\" fill-opacity=\"0.72\" />\n</svg>\n`;\n };\n}\n\nconst APP_WASM_BASE64 =\n \"AGFzbQEAAAABBwFgAn9/AX8DAgEABxMBD3N1bW1hcml6ZV9ub3RlcwAACg0BCwAgACABakHIAWoL\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-scaffold.service.js","names":[],"sources":["../../src/services/app-scaffold.service.ts"],"sourcesContent":["import { access, mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { AppTsHttpLiteScaffoldTemplateService } from \"./app-ts-http-lite-scaffold-template.service.js\";\nimport { AppTsHttpScaffoldTemplateService } from \"./app-ts-http-scaffold-template.service.js\";\n\nexport type AppScaffoldTemplate = \"starter\" | \"ts-http\" | \"ts-http-lite\";\n\nexport type AppScaffoldResult = {\n appDirectory: string;\n manifestPath: string;\n template: AppScaffoldTemplate;\n};\n\nexport class AppScaffoldService {\n constructor(\n private readonly tsHttpTemplateService: AppTsHttpScaffoldTemplateService = new AppTsHttpScaffoldTemplateService(),\n private readonly tsHttpLiteTemplateService: AppTsHttpLiteScaffoldTemplateService = new AppTsHttpLiteScaffoldTemplateService(),\n ) {}\n\n scaffold = async (\n targetDirectory: string,\n options?: {\n template?: AppScaffoldTemplate;\n },\n ): Promise<AppScaffoldResult> => {\n const appDirectory = path.resolve(targetDirectory);\n const template = options?.template ?? \"starter\";\n await this.assertTargetDoesNotExist(appDirectory);\n await mkdir(path.join(appDirectory, \"main\"), { recursive: true });\n await mkdir(path.join(appDirectory, \"ui\"), { recursive: true });\n await mkdir(path.join(appDirectory, \"assets\"), { recursive: true });\n\n const appName = this.buildAppName(appDirectory);\n const appId = this.buildAppId(appDirectory);\n const manifestPath = path.join(appDirectory, \"manifest.json\");\n if (template === \"ts-http\") {\n await this.writeTemplateFiles(\n appDirectory,\n this.tsHttpTemplateService.buildFiles({\n appId,\n appName,\n }),\n );\n return {\n appDirectory,\n manifestPath,\n template,\n };\n }\n if (template === \"ts-http-lite\") {\n await this.writeTemplateFiles(\n appDirectory,\n this.tsHttpLiteTemplateService.buildFiles({\n appId,\n appName,\n }),\n );\n return {\n appDirectory,\n manifestPath,\n template,\n };\n }\n\n await Promise.all([\n writeFile(\n manifestPath,\n `${JSON.stringify(this.buildManifest(appId, appName), null, 2)}\\n`,\n \"utf-8\",\n ),\n writeFile(\n path.join(appDirectory, \"marketplace.json\"),\n `${JSON.stringify(this.buildMarketplaceMetadata(appName), null, 2)}\\n`,\n \"utf-8\",\n ),\n writeFile(path.join(appDirectory, \"README.md\"), this.buildReadme(appName, appId), \"utf-8\"),\n writeFile(\n path.join(appDirectory, \"main\", \"app.wasm\"),\n Buffer.from(APP_WASM_BASE64, \"base64\"),\n ),\n writeFile(path.join(appDirectory, \"main\", \"app.wat\"), this.buildWatSource(), \"utf-8\"),\n writeFile(path.join(appDirectory, \"ui\", \"index.html\"), this.buildUiHtml(appName), \"utf-8\"),\n writeFile(\n path.join(appDirectory, \"ui\", \"app.controller.js\"),\n this.buildUiController(),\n \"utf-8\",\n ),\n writeFile(path.join(appDirectory, \"assets\", \"icon.svg\"), this.buildIconSvg(), \"utf-8\"),\n ]);\n\n return {\n appDirectory,\n manifestPath,\n template,\n };\n };\n\n private writeTemplateFiles = async (\n appDirectory: string,\n files: Array<{ relativePath: string; content: string | Buffer }>,\n ): Promise<void> => {\n await Promise.all(\n files.map(async (file) => {\n const filePath = path.join(appDirectory, file.relativePath);\n await mkdir(path.dirname(filePath), { recursive: true });\n await writeFile(filePath, file.content);\n }),\n );\n };\n\n private assertTargetDoesNotExist = async (targetDirectory: string): Promise<void> => {\n try {\n await access(targetDirectory);\n } catch {\n return;\n }\n throw new Error(`目标目录已存在:${targetDirectory}`);\n };\n\n private buildAppId = (targetDirectory: string): string => {\n const slug = this.normalizeSlug(path.basename(targetDirectory));\n return `nextclaw.${slug}`;\n };\n\n private buildAppName = (targetDirectory: string): string => {\n const parts = this.normalizeSlug(path.basename(targetDirectory)).split(\"-\");\n return parts.map((part) => `${part[0]?.toUpperCase() ?? \"\"}${part.slice(1)}`).join(\" \");\n };\n\n private normalizeSlug = (value: string): string => {\n const normalized = value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n if (!normalized) {\n throw new Error(\"应用目录名无法生成合法的应用标识。\");\n }\n return normalized;\n };\n\n private buildManifest = (appId: string, appName: string) => {\n return {\n schemaVersion: 1,\n id: appId,\n name: appName,\n version: \"0.1.0\",\n description: \"A minimal NextClaw micro app scaffold created by napp.\",\n icon: \"assets/icon.svg\",\n main: {\n kind: \"wasm\",\n entry: \"main/app.wasm\",\n export: \"summarize_notes\",\n action: \"runStarterDemo\",\n },\n ui: {\n entry: \"ui/index.html\",\n },\n permissions: {\n storage: {\n namespace: appId.replace(/\\./g, \"-\"),\n },\n capabilities: {\n hostBridge: true,\n },\n },\n };\n };\n\n private buildWatSource = (): string => {\n return `(module\n (func (export \"summarize_notes\") (param i32 i32) (result i32)\n local.get 0\n local.get 1\n i32.add\n i32.const 200\n i32.add))\\n`;\n };\n\n private buildUiHtml = (appName: string): string => {\n return `<!doctype html>\n<html lang=\"zh-CN\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>${appName}</title>\n <style>\n :root {\n color-scheme: light;\n font-family: \"IBM Plex Sans\", \"Helvetica Neue\", sans-serif;\n background:\n radial-gradient(circle at top left, rgba(255, 206, 134, 0.24), transparent 30%),\n linear-gradient(165deg, #f7f1e7 0%, #fcfcfe 48%, #e1ebf5 100%);\n color: #11233a;\n }\n\n body {\n margin: 0;\n min-height: 100vh;\n }\n\n main {\n box-sizing: border-box;\n max-width: 760px;\n margin: 0 auto;\n padding: 48px 20px 72px;\n }\n\n .panel {\n background: rgba(255, 255, 255, 0.78);\n border: 1px solid rgba(17, 35, 58, 0.08);\n border-radius: 24px;\n box-shadow: 0 18px 42px rgba(17, 35, 58, 0.12);\n padding: 28px;\n backdrop-filter: blur(18px);\n }\n\n h1 {\n margin: 0 0 12px;\n font-size: clamp(30px, 6vw, 54px);\n line-height: 1;\n }\n\n p {\n line-height: 1.6;\n }\n\n button {\n border: 0;\n border-radius: 999px;\n background: #11233a;\n color: #fff;\n padding: 12px 18px;\n font-size: 15px;\n cursor: pointer;\n }\n\n dl {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 12px;\n margin: 24px 0 0;\n }\n\n dt {\n font-size: 12px;\n color: #556881;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n }\n\n dd {\n margin: 6px 0 0;\n font-size: 24px;\n font-weight: 600;\n }\n\n pre {\n margin-top: 20px;\n padding: 14px;\n border-radius: 16px;\n background: rgba(17, 35, 58, 0.07);\n overflow: auto;\n }\n </style>\n </head>\n <body>\n <main>\n <section class=\"panel\">\n <p>NextClaw Micro App</p>\n <h1 id=\"title\">Loading...</h1>\n <p id=\"description\">A starter scaffold created by napp create.</p>\n <button id=\"run-button\" type=\"button\">Run Starter Demo</button>\n <dl>\n <div>\n <dt>Action</dt>\n <dd id=\"action\">-</dd>\n </div>\n <div>\n <dt>Documents</dt>\n <dd id=\"document-count\">-</dd>\n </div>\n <div>\n <dt>Text Bytes</dt>\n <dd id=\"text-bytes\">-</dd>\n </div>\n <div>\n <dt>Wasm Score</dt>\n <dd id=\"wasm-score\">-</dd>\n </div>\n </dl>\n <pre id=\"details\"></pre>\n </section>\n </main>\n <script type=\"module\" src=\"./app.controller.js\"></script>\n </body>\n</html>\n`;\n };\n\n private buildMarketplaceMetadata = (appName: string) => {\n return {\n slug: this.normalizeSlug(appName),\n summary: `A minimal ${appName} app scaffold created by napp.`,\n summaryI18n: {\n en: `A minimal ${appName} app scaffold created by napp.`,\n zh: `一个由 napp 创建的最小 ${appName} 应用骨架。`,\n },\n description: `A minimal NextClaw app scaffold for ${appName}, ready for local run and marketplace publish.`,\n descriptionI18n: {\n en: `A minimal NextClaw app scaffold for ${appName}, ready for local run and marketplace publish.`,\n zh: `一个面向 ${appName} 的最小 NextClaw 应用骨架,可直接本地运行并发布到 marketplace。`,\n },\n author: \"NextClaw\",\n tags: [\"starter\", \"official\", \"local\"],\n sourceRepo: \"https://github.com/Peiiii/nextclaw\",\n homepage: \"https://nextclaw.io\",\n featured: false,\n };\n };\n\n private buildReadme = (appName: string, appId: string): string => {\n return `# ${appName}\n\nThis starter app was created by \\`napp create\\`.\n\n## Local workflow\n\n\\`\\`\\`bash\nnapp inspect .\nnapp run .\n\\`\\`\\`\n\n## Publish workflow\n\n\\`\\`\\`bash\nnapp publish .\n\\`\\`\\`\n\n## App ID\n\n\\`${appId}\\`\n`;\n };\n\n private buildUiController = (): string => {\n return `const titleNode = document.getElementById(\"title\");\nconst descriptionNode = document.getElementById(\"description\");\nconst actionNode = document.getElementById(\"action\");\nconst documentCountNode = document.getElementById(\"document-count\");\nconst textBytesNode = document.getElementById(\"text-bytes\");\nconst wasmScoreNode = document.getElementById(\"wasm-score\");\nconst detailsNode = document.getElementById(\"details\");\nconst runButton = document.getElementById(\"run-button\");\n\nconst setDetails = (value) => {\n detailsNode.textContent = JSON.stringify(value, null, 2);\n};\n\nconst loadManifest = async () => {\n const response = await fetch(\"/__napp/manifest\");\n const payload = await response.json();\n titleNode.textContent = payload.manifest.name;\n descriptionNode.textContent = payload.manifest.description;\n actionNode.textContent = payload.manifest.main.action;\n setDetails(payload);\n};\n\nconst runDemo = async () => {\n runButton.disabled = true;\n try {\n const response = await fetch(\"/__napp/run\", {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n action: actionNode.textContent,\n }),\n });\n const payload = await response.json();\n documentCountNode.textContent = String(payload.result.input.documentCount);\n textBytesNode.textContent = String(payload.result.input.textBytes);\n wasmScoreNode.textContent = String(payload.result.output.output);\n setDetails(payload);\n } finally {\n runButton.disabled = false;\n }\n};\n\nrunButton.addEventListener(\"click\", () => {\n void runDemo();\n});\n\nawait loadManifest();\n`;\n };\n\n private buildIconSvg = (): string => {\n return `<svg width=\"160\" height=\"160\" viewBox=\"0 0 160 160\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"160\" height=\"160\" rx=\"40\" fill=\"#11233A\" />\n <path d=\"M42 45H118V58H74V115H58V58H42V45Z\" fill=\"#F8C97E\" />\n <path d=\"M92 74H118V87H92V74Z\" fill=\"#FFFFFF\" fill-opacity=\"0.92\" />\n <path d=\"M92 95H118V108H92V95Z\" fill=\"#FFFFFF\" fill-opacity=\"0.72\" />\n</svg>\n`;\n };\n}\n\nconst APP_WASM_BASE64 =\n \"AGFzbQEAAAABBwFgAn9/AX8DAgEABxMBD3N1bW1hcml6ZV9ub3RlcwAACg0BCwAgACABakHIAWoL\";\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { AppScaffoldFile, AppTsHttpScaffoldTemplateService } from "./app-ts-http-scaffold-template.service.js";
2
2
 
3
- //#region src/scaffold/app-ts-http-lite-scaffold-template.service.d.ts
3
+ //#region src/services/app-ts-http-lite-scaffold-template.service.d.ts
4
4
  declare class AppTsHttpLiteScaffoldTemplateService {
5
5
  private readonly standardTemplateService;
6
6
  constructor(standardTemplateService?: AppTsHttpScaffoldTemplateService);
@@ -1 +1 @@
1
- {"version":3,"file":"app-ts-http-lite-scaffold-template.service.d.ts","names":[],"sources":["../../src/scaffold/app-ts-http-lite-scaffold-template.service.ts"],"mappings":";;;cAGa,oCAAA;EAAA,iBAEQ,uBAAA;cAAA,uBAAA,GAAyB,gCAAA;EAG5C,UAAA,GAAc,MAAA;IACZ,KAAA;IACA,OAAA;EAAA,MACE,eAAA;EAAA,QA8BI,oBAAA;EAAA,QA0BA,wBAAA;EAAA,QAqBA,WAAA;EAAA,QAuDA,oBAAA;EAAA,QAkIA,aAAA;AAAA"}
1
+ {"version":3,"file":"app-ts-http-lite-scaffold-template.service.d.ts","names":[],"sources":["../../src/services/app-ts-http-lite-scaffold-template.service.ts"],"mappings":";;;cAGa,oCAAA;EAAA,iBAEQ,uBAAA;cAAA,uBAAA,GAAyB,gCAAA;EAG5C,UAAA,GAAc,MAAA;IACZ,KAAA;IACA,OAAA;EAAA,MACE,eAAA;EAAA,QA8BI,oBAAA;EAAA,QA0BA,wBAAA;EAAA,QAqBA,WAAA;EAAA,QAuDA,oBAAA;EAAA,QAkIA,aAAA;AAAA"}
@@ -1,5 +1,5 @@
1
1
  import { AppTsHttpScaffoldTemplateService } from "./app-ts-http-scaffold-template.service.js";
2
- //#region src/scaffold/app-ts-http-lite-scaffold-template.service.ts
2
+ //#region src/services/app-ts-http-lite-scaffold-template.service.ts
3
3
  var AppTsHttpLiteScaffoldTemplateService = class {
4
4
  constructor(standardTemplateService = new AppTsHttpScaffoldTemplateService()) {
5
5
  this.standardTemplateService = standardTemplateService;
@@ -1 +1 @@
1
- {"version":3,"file":"app-ts-http-lite-scaffold-template.service.js","names":[],"sources":["../../src/scaffold/app-ts-http-lite-scaffold-template.service.ts"],"sourcesContent":["import type { AppScaffoldFile } from \"./app-ts-http-scaffold-template.service.js\";\nimport { AppTsHttpScaffoldTemplateService } from \"./app-ts-http-scaffold-template.service.js\";\n\nexport class AppTsHttpLiteScaffoldTemplateService {\n constructor(\n private readonly standardTemplateService: AppTsHttpScaffoldTemplateService = new AppTsHttpScaffoldTemplateService(),\n ) {}\n\n buildFiles = (params: {\n appId: string;\n appName: string;\n }): AppScaffoldFile[] => {\n const standardFiles = this.standardTemplateService.buildFiles(params);\n return standardFiles.map((file) => {\n switch (file.relativePath) {\n case \"marketplace.json\":\n return {\n relativePath: file.relativePath,\n content: `${JSON.stringify(this.buildMarketplaceMetadata(params.appName), null, 2)}\\n`,\n };\n case \"README.md\":\n return {\n relativePath: file.relativePath,\n content: this.buildReadme(params.appName, params.appId),\n };\n case \"main/package.json\":\n return {\n relativePath: file.relativePath,\n content: `${JSON.stringify(this.buildMainPackageJson(params.appId), null, 2)}\\n`,\n };\n case \"main/src/component.ts\":\n return {\n relativePath: file.relativePath,\n content: this.buildComponentSource(),\n };\n default:\n return file;\n }\n });\n };\n\n private buildMainPackageJson = (appId: string) => {\n return {\n name: `${appId.replace(/\\./g, \"-\")}-main`,\n version: \"0.1.0\",\n private: true,\n type: \"module\",\n scripts: {\n build: \"npm run prepare-wit && npm run guest-types && npm run typecheck && npm run bundle && npm run componentize\",\n \"prepare-wit\": \"wkg wit fetch\",\n \"guest-types\": \"jco guest-types wit --world-name napp-http --out-dir generated/types\",\n typecheck: \"tsc --noEmit\",\n bundle: \"rolldown -c\",\n componentize: \"jco componentize -w wit -n napp-http -o app.wasm dist/component.js\",\n },\n dependencies: {\n \"@bytecodealliance/jco-std\": \"^0.1.3\",\n },\n devDependencies: {\n \"@bytecodealliance/componentize-js\": \"^0.20.0\",\n \"@bytecodealliance/jco\": \"^1.19.0\",\n rolldown: \"^1.0.0-rc.17\",\n typescript: \"^5.6.3\",\n },\n };\n };\n\n private buildMarketplaceMetadata = (appName: string) => {\n return {\n slug: this.normalizeSlug(appName),\n summary: `A lightweight TypeScript WASI HTTP ${appName} scaffold created by napp.`,\n summaryI18n: {\n en: `A lightweight TypeScript WASI HTTP ${appName} scaffold created by napp.`,\n zh: `一个由 napp 创建的轻量 TypeScript WASI HTTP ${appName} 应用骨架。`,\n },\n description: `A lightweight TypeScript NApp scaffold for ${appName}, designed to keep the WASI HTTP backend smaller than the default Hono-based template.`,\n descriptionI18n: {\n en: `A lightweight TypeScript NApp scaffold for ${appName}, designed to keep the WASI HTTP backend smaller than the default Hono-based template.`,\n zh: `一个面向 ${appName} 的轻量 TypeScript NApp 应用骨架,用更薄的 WASI HTTP handler 替代默认的 Hono 模板,优先追求更小包体。`,\n },\n author: \"NextClaw\",\n tags: [\"starter\", \"typescript\", \"wasi-http\", \"official\", \"lite\"],\n sourceRepo: \"https://github.com/Peiiii/nextclaw\",\n homepage: \"https://nextclaw.io\",\n featured: false,\n };\n };\n\n private buildReadme = (appName: string, appId: string): string => {\n return `# ${appName}\n\nThis app was created by \\`napp create --template ts-http-lite\\`.\n\nIt keeps the existing NApp directory contract, while making \\`main/app.wasm\\` a lighter WASI HTTP component without the default Hono routing layer.\n\n## App ID\n\n\\`${appId}\\`\n\n## Build the TypeScript backend\n\nRecommended:\n\n\\`\\`\\`bash\nnapp build . --install\n\\`\\`\\`\n\nManual equivalent:\n\n\\`\\`\\`bash\ncd main\nnpm install\nnpm run build\n\\`\\`\\`\n\nThe build writes the backend component to:\n\n\\`\\`\\`text\nmain/app.wasm\n\\`\\`\\`\n\n## Local workflow\n\n\\`\\`\\`bash\nnapp inspect .\nnapp validate-publish .\nnapp run . --data ./data\n\\`\\`\\`\n\nThe runtime mounts the host data directory to guest \\`/data\\`. This example stores todos in:\n\n\\`\\`\\`text\n./data/todos.json\n\\`\\`\\`\n\nThe frontend still uses ordinary same-origin HTTP:\n\n\\`\\`\\`js\nawait fetch(\"/api/todos\");\n\\`\\`\\`\n`;\n };\n\n private buildComponentSource = (): string => {\n return `import { fire, incomingHandler } from \"@bytecodealliance/jco-std/wasi/0.2.6/http/adapters/hono/server\";\nimport { getDirectories } from \"wasi:filesystem/preopens@0.2.2\";\n\ntype Todo = {\n id: string;\n title: string;\n completed: boolean;\n};\n\ntype TodoInput = {\n title?: string;\n};\n\nconst TODOS_FILE = \"todos.json\";\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\nconst app = {\n fetch: (request: Request): Promise<Response> => routeRequest(request),\n};\n\nfire(app as never);\n\nexport { incomingHandler };\n\nasync function routeRequest(request: Request): Promise<Response> {\n const url = new URL(request.url);\n const pathname = url.pathname;\n\n if (request.method === \"GET\" && pathname === \"/api/todos\") {\n return json(loadTodos());\n }\n\n if (request.method === \"POST\" && pathname === \"/api/todos\") {\n const input = await request.json() as TodoInput;\n if (!input.title?.trim()) {\n return json({ error: \"title is required\" }, 400);\n }\n const todos = loadTodos();\n todos.push({\n id: crypto.randomUUID(),\n title: input.title.trim(),\n completed: false,\n });\n saveTodos(todos);\n return json(todos);\n }\n\n if (request.method === \"PATCH\" && pathname.startsWith(\"/api/todos/\")) {\n const todoId = pathname.slice(\"/api/todos/\".length);\n const input = await request.json() as Partial<Todo>;\n const todos = loadTodos();\n const todo = todos.find((entry) => entry.id === todoId);\n if (!todo) {\n return json({ error: \"todo not found\" }, 404);\n }\n if (typeof input.title === \"string\") {\n todo.title = input.title;\n }\n if (typeof input.completed === \"boolean\") {\n todo.completed = input.completed;\n }\n saveTodos(todos);\n return json(todos);\n }\n\n if (request.method === \"DELETE\" && pathname.startsWith(\"/api/todos/\")) {\n const todoId = pathname.slice(\"/api/todos/\".length);\n const nextTodos = loadTodos().filter((entry) => entry.id !== todoId);\n saveTodos(nextTodos);\n return json(nextTodos);\n }\n\n return text(\"Not found\", 404);\n}\n\nfunction json(value: unknown, status = 200): Response {\n return new Response(JSON.stringify(value), {\n status,\n headers: {\n \"content-type\": \"application/json; charset=utf-8\",\n },\n });\n}\n\nfunction text(value: string, status = 200): Response {\n return new Response(value, { status });\n}\n\nfunction loadTodos(): Todo[] {\n const file = openTodosFile({ read: true });\n if (!file) {\n return [];\n }\n const [bytes] = file.read(BigInt(1024 * 1024), BigInt(0));\n if (bytes.length === 0) {\n return [];\n }\n return JSON.parse(decoder.decode(bytes)) as Todo[];\n}\n\nfunction saveTodos(todos: Todo[]): void {\n const file = getDataDirectory().openAt(\n { symlinkFollow: true },\n TODOS_FILE,\n { create: true, truncate: true },\n { write: true },\n );\n file.write(encoder.encode(JSON.stringify(todos, null, 2)), BigInt(0));\n}\n\nfunction openTodosFile(flags: { read?: boolean; write?: boolean }) {\n try {\n return getDataDirectory().openAt({ symlinkFollow: true }, TODOS_FILE, {}, flags);\n } catch {\n return undefined;\n }\n}\n\nfunction getDataDirectory() {\n for (const [descriptor, guestPath] of getDirectories()) {\n if (guestPath === \"/data\") {\n return descriptor;\n }\n }\n throw new Error(\"Missing /data preopen. NApp runtime must mount the app data directory at /data.\");\n}\n`;\n };\n\n private normalizeSlug = (value: string): string => {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n };\n}\n"],"mappings":";;AAGA,IAAa,uCAAb,MAAkD;CAChD,YACE,0BAA6E,IAAI,kCAAkC,EACnH;AADiB,OAAA,0BAAA;;CAGnB,cAAc,WAGW;AAEvB,SADsB,KAAK,wBAAwB,WAAW,OAAO,CAChD,KAAK,SAAS;AACjC,WAAQ,KAAK,cAAb;IACE,KAAK,mBACH,QAAO;KACL,cAAc,KAAK;KACnB,SAAS,GAAG,KAAK,UAAU,KAAK,yBAAyB,OAAO,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpF;IACH,KAAK,YACH,QAAO;KACL,cAAc,KAAK;KACnB,SAAS,KAAK,YAAY,OAAO,SAAS,OAAO,MAAM;KACxD;IACH,KAAK,oBACH,QAAO;KACL,cAAc,KAAK;KACnB,SAAS,GAAG,KAAK,UAAU,KAAK,qBAAqB,OAAO,MAAM,EAAE,MAAM,EAAE,CAAC;KAC9E;IACH,KAAK,wBACH,QAAO;KACL,cAAc,KAAK;KACnB,SAAS,KAAK,sBAAsB;KACrC;IACH,QACE,QAAO;;IAEX;;CAGJ,wBAAgC,UAAkB;AAChD,SAAO;GACL,MAAM,GAAG,MAAM,QAAQ,OAAO,IAAI,CAAC;GACnC,SAAS;GACT,SAAS;GACT,MAAM;GACN,SAAS;IACP,OAAO;IACP,eAAe;IACf,eAAe;IACf,WAAW;IACX,QAAQ;IACR,cAAc;IACf;GACD,cAAc,EACZ,6BAA6B,UAC9B;GACD,iBAAiB;IACf,qCAAqC;IACrC,yBAAyB;IACzB,UAAU;IACV,YAAY;IACb;GACF;;CAGH,4BAAoC,YAAoB;AACtD,SAAO;GACL,MAAM,KAAK,cAAc,QAAQ;GACjC,SAAS,sCAAsC,QAAQ;GACvD,aAAa;IACX,IAAI,sCAAsC,QAAQ;IAClD,IAAI,uCAAuC,QAAQ;IACpD;GACD,aAAa,8CAA8C,QAAQ;GACnE,iBAAiB;IACf,IAAI,8CAA8C,QAAQ;IAC1D,IAAI,QAAQ,QAAQ;IACrB;GACD,QAAQ;GACR,MAAM;IAAC;IAAW;IAAc;IAAa;IAAY;IAAO;GAChE,YAAY;GACZ,UAAU;GACV,UAAU;GACX;;CAGH,eAAuB,SAAiB,UAA0B;AAChE,SAAO,KAAK,QAAQ;;;;;;;;IAQpB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CR,6BAA6C;AAC3C,SAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiIT,iBAAyB,UAA0B;AACjD,SAAO,MACJ,MAAM,CACN,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,YAAY,GAAG"}
1
+ {"version":3,"file":"app-ts-http-lite-scaffold-template.service.js","names":[],"sources":["../../src/services/app-ts-http-lite-scaffold-template.service.ts"],"sourcesContent":["import type { AppScaffoldFile } from \"./app-ts-http-scaffold-template.service.js\";\nimport { AppTsHttpScaffoldTemplateService } from \"./app-ts-http-scaffold-template.service.js\";\n\nexport class AppTsHttpLiteScaffoldTemplateService {\n constructor(\n private readonly standardTemplateService: AppTsHttpScaffoldTemplateService = new AppTsHttpScaffoldTemplateService(),\n ) {}\n\n buildFiles = (params: {\n appId: string;\n appName: string;\n }): AppScaffoldFile[] => {\n const standardFiles = this.standardTemplateService.buildFiles(params);\n return standardFiles.map((file) => {\n switch (file.relativePath) {\n case \"marketplace.json\":\n return {\n relativePath: file.relativePath,\n content: `${JSON.stringify(this.buildMarketplaceMetadata(params.appName), null, 2)}\\n`,\n };\n case \"README.md\":\n return {\n relativePath: file.relativePath,\n content: this.buildReadme(params.appName, params.appId),\n };\n case \"main/package.json\":\n return {\n relativePath: file.relativePath,\n content: `${JSON.stringify(this.buildMainPackageJson(params.appId), null, 2)}\\n`,\n };\n case \"main/src/component.ts\":\n return {\n relativePath: file.relativePath,\n content: this.buildComponentSource(),\n };\n default:\n return file;\n }\n });\n };\n\n private buildMainPackageJson = (appId: string) => {\n return {\n name: `${appId.replace(/\\./g, \"-\")}-main`,\n version: \"0.1.0\",\n private: true,\n type: \"module\",\n scripts: {\n build: \"npm run prepare-wit && npm run guest-types && npm run typecheck && npm run bundle && npm run componentize\",\n \"prepare-wit\": \"wkg wit fetch\",\n \"guest-types\": \"jco guest-types wit --world-name napp-http --out-dir generated/types\",\n typecheck: \"tsc --noEmit\",\n bundle: \"rolldown -c\",\n componentize: \"jco componentize -w wit -n napp-http -o app.wasm dist/component.js\",\n },\n dependencies: {\n \"@bytecodealliance/jco-std\": \"^0.1.3\",\n },\n devDependencies: {\n \"@bytecodealliance/componentize-js\": \"^0.20.0\",\n \"@bytecodealliance/jco\": \"^1.19.0\",\n rolldown: \"^1.0.0-rc.17\",\n typescript: \"^5.6.3\",\n },\n };\n };\n\n private buildMarketplaceMetadata = (appName: string) => {\n return {\n slug: this.normalizeSlug(appName),\n summary: `A lightweight TypeScript WASI HTTP ${appName} scaffold created by napp.`,\n summaryI18n: {\n en: `A lightweight TypeScript WASI HTTP ${appName} scaffold created by napp.`,\n zh: `一个由 napp 创建的轻量 TypeScript WASI HTTP ${appName} 应用骨架。`,\n },\n description: `A lightweight TypeScript NApp scaffold for ${appName}, designed to keep the WASI HTTP backend smaller than the default Hono-based template.`,\n descriptionI18n: {\n en: `A lightweight TypeScript NApp scaffold for ${appName}, designed to keep the WASI HTTP backend smaller than the default Hono-based template.`,\n zh: `一个面向 ${appName} 的轻量 TypeScript NApp 应用骨架,用更薄的 WASI HTTP handler 替代默认的 Hono 模板,优先追求更小包体。`,\n },\n author: \"NextClaw\",\n tags: [\"starter\", \"typescript\", \"wasi-http\", \"official\", \"lite\"],\n sourceRepo: \"https://github.com/Peiiii/nextclaw\",\n homepage: \"https://nextclaw.io\",\n featured: false,\n };\n };\n\n private buildReadme = (appName: string, appId: string): string => {\n return `# ${appName}\n\nThis app was created by \\`napp create --template ts-http-lite\\`.\n\nIt keeps the existing NApp directory contract, while making \\`main/app.wasm\\` a lighter WASI HTTP component without the default Hono routing layer.\n\n## App ID\n\n\\`${appId}\\`\n\n## Build the TypeScript backend\n\nRecommended:\n\n\\`\\`\\`bash\nnapp build . --install\n\\`\\`\\`\n\nManual equivalent:\n\n\\`\\`\\`bash\ncd main\nnpm install\nnpm run build\n\\`\\`\\`\n\nThe build writes the backend component to:\n\n\\`\\`\\`text\nmain/app.wasm\n\\`\\`\\`\n\n## Local workflow\n\n\\`\\`\\`bash\nnapp inspect .\nnapp validate-publish .\nnapp run . --data ./data\n\\`\\`\\`\n\nThe runtime mounts the host data directory to guest \\`/data\\`. This example stores todos in:\n\n\\`\\`\\`text\n./data/todos.json\n\\`\\`\\`\n\nThe frontend still uses ordinary same-origin HTTP:\n\n\\`\\`\\`js\nawait fetch(\"/api/todos\");\n\\`\\`\\`\n`;\n };\n\n private buildComponentSource = (): string => {\n return `import { fire, incomingHandler } from \"@bytecodealliance/jco-std/wasi/0.2.6/http/adapters/hono/server\";\nimport { getDirectories } from \"wasi:filesystem/preopens@0.2.2\";\n\ntype Todo = {\n id: string;\n title: string;\n completed: boolean;\n};\n\ntype TodoInput = {\n title?: string;\n};\n\nconst TODOS_FILE = \"todos.json\";\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\nconst app = {\n fetch: (request: Request): Promise<Response> => routeRequest(request),\n};\n\nfire(app as never);\n\nexport { incomingHandler };\n\nasync function routeRequest(request: Request): Promise<Response> {\n const url = new URL(request.url);\n const pathname = url.pathname;\n\n if (request.method === \"GET\" && pathname === \"/api/todos\") {\n return json(loadTodos());\n }\n\n if (request.method === \"POST\" && pathname === \"/api/todos\") {\n const input = await request.json() as TodoInput;\n if (!input.title?.trim()) {\n return json({ error: \"title is required\" }, 400);\n }\n const todos = loadTodos();\n todos.push({\n id: crypto.randomUUID(),\n title: input.title.trim(),\n completed: false,\n });\n saveTodos(todos);\n return json(todos);\n }\n\n if (request.method === \"PATCH\" && pathname.startsWith(\"/api/todos/\")) {\n const todoId = pathname.slice(\"/api/todos/\".length);\n const input = await request.json() as Partial<Todo>;\n const todos = loadTodos();\n const todo = todos.find((entry) => entry.id === todoId);\n if (!todo) {\n return json({ error: \"todo not found\" }, 404);\n }\n if (typeof input.title === \"string\") {\n todo.title = input.title;\n }\n if (typeof input.completed === \"boolean\") {\n todo.completed = input.completed;\n }\n saveTodos(todos);\n return json(todos);\n }\n\n if (request.method === \"DELETE\" && pathname.startsWith(\"/api/todos/\")) {\n const todoId = pathname.slice(\"/api/todos/\".length);\n const nextTodos = loadTodos().filter((entry) => entry.id !== todoId);\n saveTodos(nextTodos);\n return json(nextTodos);\n }\n\n return text(\"Not found\", 404);\n}\n\nfunction json(value: unknown, status = 200): Response {\n return new Response(JSON.stringify(value), {\n status,\n headers: {\n \"content-type\": \"application/json; charset=utf-8\",\n },\n });\n}\n\nfunction text(value: string, status = 200): Response {\n return new Response(value, { status });\n}\n\nfunction loadTodos(): Todo[] {\n const file = openTodosFile({ read: true });\n if (!file) {\n return [];\n }\n const [bytes] = file.read(BigInt(1024 * 1024), BigInt(0));\n if (bytes.length === 0) {\n return [];\n }\n return JSON.parse(decoder.decode(bytes)) as Todo[];\n}\n\nfunction saveTodos(todos: Todo[]): void {\n const file = getDataDirectory().openAt(\n { symlinkFollow: true },\n TODOS_FILE,\n { create: true, truncate: true },\n { write: true },\n );\n file.write(encoder.encode(JSON.stringify(todos, null, 2)), BigInt(0));\n}\n\nfunction openTodosFile(flags: { read?: boolean; write?: boolean }) {\n try {\n return getDataDirectory().openAt({ symlinkFollow: true }, TODOS_FILE, {}, flags);\n } catch {\n return undefined;\n }\n}\n\nfunction getDataDirectory() {\n for (const [descriptor, guestPath] of getDirectories()) {\n if (guestPath === \"/data\") {\n return descriptor;\n }\n }\n throw new Error(\"Missing /data preopen. NApp runtime must mount the app data directory at /data.\");\n}\n`;\n };\n\n private normalizeSlug = (value: string): string => {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n };\n}\n"],"mappings":";;AAGA,IAAa,uCAAb,MAAkD;CAChD,YACE,0BAA6E,IAAI,kCAAkC,EACnH;AADiB,OAAA,0BAAA;;CAGnB,cAAc,WAGW;AAEvB,SADsB,KAAK,wBAAwB,WAAW,OAAO,CAChD,KAAK,SAAS;AACjC,WAAQ,KAAK,cAAb;IACE,KAAK,mBACH,QAAO;KACL,cAAc,KAAK;KACnB,SAAS,GAAG,KAAK,UAAU,KAAK,yBAAyB,OAAO,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpF;IACH,KAAK,YACH,QAAO;KACL,cAAc,KAAK;KACnB,SAAS,KAAK,YAAY,OAAO,SAAS,OAAO,MAAM;KACxD;IACH,KAAK,oBACH,QAAO;KACL,cAAc,KAAK;KACnB,SAAS,GAAG,KAAK,UAAU,KAAK,qBAAqB,OAAO,MAAM,EAAE,MAAM,EAAE,CAAC;KAC9E;IACH,KAAK,wBACH,QAAO;KACL,cAAc,KAAK;KACnB,SAAS,KAAK,sBAAsB;KACrC;IACH,QACE,QAAO;;IAEX;;CAGJ,wBAAgC,UAAkB;AAChD,SAAO;GACL,MAAM,GAAG,MAAM,QAAQ,OAAO,IAAI,CAAC;GACnC,SAAS;GACT,SAAS;GACT,MAAM;GACN,SAAS;IACP,OAAO;IACP,eAAe;IACf,eAAe;IACf,WAAW;IACX,QAAQ;IACR,cAAc;IACf;GACD,cAAc,EACZ,6BAA6B,UAC9B;GACD,iBAAiB;IACf,qCAAqC;IACrC,yBAAyB;IACzB,UAAU;IACV,YAAY;IACb;GACF;;CAGH,4BAAoC,YAAoB;AACtD,SAAO;GACL,MAAM,KAAK,cAAc,QAAQ;GACjC,SAAS,sCAAsC,QAAQ;GACvD,aAAa;IACX,IAAI,sCAAsC,QAAQ;IAClD,IAAI,uCAAuC,QAAQ;IACpD;GACD,aAAa,8CAA8C,QAAQ;GACnE,iBAAiB;IACf,IAAI,8CAA8C,QAAQ;IAC1D,IAAI,QAAQ,QAAQ;IACrB;GACD,QAAQ;GACR,MAAM;IAAC;IAAW;IAAc;IAAa;IAAY;IAAO;GAChE,YAAY;GACZ,UAAU;GACV,UAAU;GACX;;CAGH,eAAuB,SAAiB,UAA0B;AAChE,SAAO,KAAK,QAAQ;;;;;;;;IAQpB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CR,6BAA6C;AAC3C,SAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiIT,iBAAyB,UAA0B;AACjD,SAAO,MACJ,MAAM,CACN,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,YAAY,GAAG"}
@@ -1,4 +1,4 @@
1
- //#region src/scaffold/app-ts-http-scaffold-template.service.d.ts
1
+ //#region src/services/app-ts-http-scaffold-template.service.d.ts
2
2
  type AppScaffoldFile = {
3
3
  relativePath: string;
4
4
  content: string | Buffer;
@@ -1 +1 @@
1
- {"version":3,"file":"app-ts-http-scaffold-template.service.d.ts","names":[],"sources":["../../src/scaffold/app-ts-http-scaffold-template.service.ts"],"mappings":";KAAY,eAAA;EACV,YAAA;EACA,OAAA,WAAkB,MAAA;AAAA;AAAA,cAGP,gCAAA;EACX,UAAA,GAAc,MAAA;IACZ,KAAA;IACA,OAAA;EAAA,MACE,eAAA;EAAA,QAsDI,aAAA;EAAA,QAkBA,oBAAA;EAAA,QA2BA,aAAA;EAAA,QAeA,wBAAA;EAAA,QAqBA,WAAA;EAAA,QA4DA,mBAAA;EAAA,QAYA,aAAA;EAAA,QAYA,oBAAA;EAAA,QA+GA,WAAA;EAAA,QA4FA,aAAA;EAAA,QAgEA,YAAA;EAAA,QAUA,aAAA;AAAA"}
1
+ {"version":3,"file":"app-ts-http-scaffold-template.service.d.ts","names":[],"sources":["../../src/services/app-ts-http-scaffold-template.service.ts"],"mappings":";KAAY,eAAA;EACV,YAAA;EACA,OAAA,WAAkB,MAAA;AAAA;AAAA,cAGP,gCAAA;EACX,UAAA,GAAc,MAAA;IACZ,KAAA;IACA,OAAA;EAAA,MACE,eAAA;EAAA,QAsDI,aAAA;EAAA,QAkBA,oBAAA;EAAA,QA2BA,aAAA;EAAA,QAeA,wBAAA;EAAA,QAqBA,WAAA;EAAA,QA4DA,mBAAA;EAAA,QAYA,aAAA;EAAA,QAYA,oBAAA;EAAA,QA+GA,WAAA;EAAA,QA4FA,aAAA;EAAA,QAgEA,YAAA;EAAA,QAUA,aAAA;AAAA"}