@nextclaw/app-runtime 0.9.12 → 0.9.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) 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 +1 -1
  78. package/dist/services/app-home.service.d.ts.map +1 -0
  79. package/dist/{paths → services}/app-home.service.js +1 -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/{install → services}/app-installation.service.d.ts +15 -14
  88. package/dist/services/app-installation.service.d.ts.map +1 -0
  89. package/dist/services/app-installation.service.js +332 -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 +3 -3
  104. package/dist/services/app-marketplace-metadata.service.d.ts.map +1 -0
  105. package/dist/{publish → services}/app-marketplace-metadata.service.js +1 -1
  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 +6 -6
  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 +18 -5
  124. package/dist/services/app-registry.service.d.ts.map +1 -0
  125. package/dist/services/app-registry.service.js +210 -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 +27 -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 +4 -4
  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 +8 -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.map +0 -1
  252. package/dist/install/app-installation.service.js +0 -276
  253. package/dist/install/app-installation.service.js.map +0 -1
  254. package/dist/install/app-installation.types.d.ts.map +0 -1
  255. package/dist/main.js.map +0 -1
  256. package/dist/manifest/app-manifest.service.d.ts.map +0 -1
  257. package/dist/manifest/app-manifest.service.js +0 -147
  258. package/dist/manifest/app-manifest.service.js.map +0 -1
  259. package/dist/manifest/app-manifest.types.d.ts +0 -68
  260. package/dist/manifest/app-manifest.types.d.ts.map +0 -1
  261. package/dist/paths/app-home.service.d.ts.map +0 -1
  262. package/dist/paths/app-home.service.js.map +0 -1
  263. package/dist/permissions/app-grant.service.d.ts.map +0 -1
  264. package/dist/permissions/app-grant.service.js.map +0 -1
  265. package/dist/permissions/app-permissions.service.d.ts.map +0 -1
  266. package/dist/permissions/app-permissions.service.js.map +0 -1
  267. package/dist/permissions/app-permissions.types.d.ts.map +0 -1
  268. package/dist/publish/app-marketplace-client.service.d.ts.map +0 -1
  269. package/dist/publish/app-marketplace-client.service.js.map +0 -1
  270. package/dist/publish/app-marketplace-metadata.service.d.ts.map +0 -1
  271. package/dist/publish/app-marketplace-metadata.service.js.map +0 -1
  272. package/dist/publish/app-publish-validation.service.d.ts.map +0 -1
  273. package/dist/publish/app-publish-validation.service.js.map +0 -1
  274. package/dist/publish/app-publish.service.d.ts.map +0 -1
  275. package/dist/publish/app-publish.service.js.map +0 -1
  276. package/dist/publish/app-publish.types.d.ts.map +0 -1
  277. package/dist/publish/app-publish.types.js.map +0 -1
  278. package/dist/publish/platform-auth-state.service.d.ts.map +0 -1
  279. package/dist/publish/platform-auth-state.service.js.map +0 -1
  280. package/dist/registry/app-registry-config.service.js.map +0 -1
  281. package/dist/registry/app-registry.service.d.ts.map +0 -1
  282. package/dist/registry/app-registry.service.js +0 -118
  283. package/dist/registry/app-registry.service.js.map +0 -1
  284. package/dist/registry/app-registry.types.d.ts.map +0 -1
  285. package/dist/registry/app-remote-registry-client.service.d.ts.map +0 -1
  286. package/dist/registry/app-remote-registry-client.service.js.map +0 -1
  287. package/dist/registry/app-remote-registry.types.d.ts.map +0 -1
  288. package/dist/registry/app-remote-registry.types.js.map +0 -1
  289. package/dist/runtime/app-build.service.d.ts.map +0 -1
  290. package/dist/runtime/app-build.service.js.map +0 -1
  291. package/dist/runtime/app-runtime-toolchain.service.d.ts.map +0 -1
  292. package/dist/runtime/app-runtime-toolchain.service.js.map +0 -1
  293. package/dist/runtime/main-runner.service.d.ts +0 -9
  294. package/dist/runtime/main-runner.service.d.ts.map +0 -1
  295. package/dist/runtime/main-runner.service.js +0 -6
  296. package/dist/runtime/main-runner.service.js.map +0 -1
  297. package/dist/runtime/main-runner.types.d.ts.map +0 -1
  298. package/dist/runtime/wasm-main-runner.service.d.ts.map +0 -1
  299. package/dist/runtime/wasm-main-runner.service.js.map +0 -1
  300. package/dist/runtime/wasmtime-wasi-http-component.service.d.ts.map +0 -1
  301. package/dist/runtime/wasmtime-wasi-http-component.service.js.map +0 -1
  302. package/dist/sidecar/wasm-sidecar-client.service.d.ts.map +0 -1
  303. package/dist/sidecar/wasm-sidecar-client.service.js.map +0 -1
  304. package/dist/ui/ui-server.service.d.ts.map +0 -1
  305. package/dist/ui/ui-server.service.js.map +0 -1
  306. /package/dist/{main.d.ts → app/main.d.ts} +0 -0
@@ -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"}
@@ -1,4 +1,4 @@
1
- //#region src/scaffold/app-ts-http-scaffold-template.service.ts
1
+ //#region src/services/app-ts-http-scaffold-template.service.ts
2
2
  var AppTsHttpScaffoldTemplateService = class {
3
3
  buildFiles = (params) => {
4
4
  const { appId, appName } = params;
@@ -1 +1 @@
1
- {"version":3,"file":"app-ts-http-scaffold-template.service.js","names":[],"sources":["../../src/scaffold/app-ts-http-scaffold-template.service.ts"],"sourcesContent":["export type AppScaffoldFile = {\n relativePath: string;\n content: string | Buffer;\n};\n\nexport class AppTsHttpScaffoldTemplateService {\n buildFiles = (params: {\n appId: string;\n appName: string;\n }): AppScaffoldFile[] => {\n const { appId, appName } = params;\n return [\n {\n relativePath: \"manifest.json\",\n content: `${JSON.stringify(this.buildManifest(appId, appName), null, 2)}\\n`,\n },\n {\n relativePath: \"marketplace.json\",\n content: `${JSON.stringify(this.buildMarketplaceMetadata(appName), null, 2)}\\n`,\n },\n {\n relativePath: \"README.md\",\n content: this.buildReadme(appName, appId),\n },\n {\n relativePath: \"main/package.json\",\n content: `${JSON.stringify(this.buildMainPackageJson(appId), null, 2)}\\n`,\n },\n {\n relativePath: \"main/tsconfig.json\",\n content: `${JSON.stringify(this.buildTsconfig(), null, 2)}\\n`,\n },\n {\n relativePath: \"main/rolldown.config.mjs\",\n content: this.buildRolldownConfig(),\n },\n {\n relativePath: \"main/wit/world.wit\",\n content: this.buildWitWorld(),\n },\n {\n relativePath: \"main/src/component.ts\",\n content: this.buildComponentSource(),\n },\n {\n relativePath: \"main/app.wasm\",\n content: Buffer.from(APP_WASM_PLACEHOLDER_BASE64, \"base64\"),\n },\n {\n relativePath: \"ui/index.html\",\n content: this.buildUiHtml(appName),\n },\n {\n relativePath: \"ui/app.js\",\n content: this.buildUiScript(),\n },\n {\n relativePath: \"assets/icon.svg\",\n content: this.buildIconSvg(),\n },\n ];\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 TypeScript WASI HTTP NApp scaffold created by napp.\",\n icon: \"assets/icon.svg\",\n main: {\n kind: \"wasi-http-component\",\n entry: \"main/app.wasm\",\n },\n ui: {\n entry: \"ui/index.html\",\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 hono: \"^4.10.0\",\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 buildTsconfig = () => {\n return {\n compilerOptions: {\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"Bundler\",\n strict: true,\n skipLibCheck: true,\n lib: [\"ES2022\", \"DOM\"],\n types: [\"./generated/types/interfaces/wasi-filesystem-preopens\", \"./generated/types/interfaces/wasi-filesystem-types\"],\n },\n include: [\"src/**/*.ts\"],\n };\n };\n\n private buildMarketplaceMetadata = (appName: string) => {\n return {\n slug: this.normalizeSlug(appName),\n summary: `A TypeScript WASI HTTP ${appName} scaffold created by napp.`,\n summaryI18n: {\n en: `A TypeScript WASI HTTP ${appName} scaffold created by napp.`,\n zh: `一个由 napp 创建的 TypeScript WASI HTTP ${appName} 应用骨架。`,\n },\n description: `A TypeScript NApp scaffold for ${appName}, designed for ordinary frontend-to-backend HTTP development on WASI components.`,\n descriptionI18n: {\n en: `A TypeScript NApp scaffold for ${appName}, designed for ordinary frontend-to-backend HTTP development on WASI components.`,\n zh: `一个面向 ${appName} 的 TypeScript NApp 应用骨架,用 WASI component 承载普通前后端 HTTP 开发心智。`,\n },\n author: \"NextClaw\",\n tags: [\"starter\", \"typescript\", \"wasi-http\", \"official\"],\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\\`.\n\nIt keeps the existing NApp directory contract, while making \\`main/app.wasm\\` a WASI HTTP component.\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\nThe build uses the official Bytecode Alliance toolchain and expects \\`wkg\\` to be available for fetching WIT dependencies:\n\n\\`\\`\\`bash\ncargo install wkg\n\\`\\`\\`\n\n## Local workflow\n\n\\`\\`\\`bash\nnapp inspect .\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 can call the backend as ordinary same-origin HTTP:\n\n\\`\\`\\`js\nawait fetch(\"/api/todos\");\n\\`\\`\\`\n`;\n };\n\n private buildRolldownConfig = (): string => {\n return `export default {\n input: \"src/component.ts\",\n output: {\n file: \"dist/component.js\",\n format: \"esm\"\n },\n external: [/^wasi:/]\n};\n`;\n };\n\n private buildWitWorld = (): string => {\n return `package nextclaw:napp;\n\nworld napp-http {\n import wasi:filesystem/types@0.2.2;\n import wasi:filesystem/preopens@0.2.2;\n\n export wasi:http/incoming-handler@0.2.6;\n}\n`;\n };\n\n private buildComponentSource = (): string => {\n return `import { Hono } from \"hono\";\nimport { fire } 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 = new Hono();\n\napp.get(\"/api/todos\", (context) => {\n return context.json(loadTodos());\n});\n\napp.post(\"/api/todos\", async (context) => {\n const input = await context.req.json<TodoInput>();\n if (!input.title?.trim()) {\n return context.json({ error: \"title is required\" }, 400);\n }\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 context.json(todos);\n});\n\napp.patch(\"/api/todos/:id\", async (context) => {\n const input = await context.req.json<Partial<Todo>>();\n const todos = loadTodos();\n const todo = todos.find((entry) => entry.id === context.req.param(\"id\"));\n if (!todo) {\n return context.json({ error: \"todo not found\" }, 404);\n }\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 context.json(todos);\n});\n\napp.delete(\"/api/todos/:id\", (context) => {\n const nextTodos = loadTodos().filter((entry) => entry.id !== context.req.param(\"id\"));\n saveTodos(nextTodos);\n return context.json(nextTodos);\n});\n\napp.notFound((context) => context.text(\"Not found\", 404));\n\nfire(app);\n\nexport { incomingHandler } from \"@bytecodealliance/jco-std/wasi/0.2.6/http/adapters/hono/server\";\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 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: linear-gradient(135deg, #f4efe6 0%, #eff6f9 50%, #f8fafc 100%);\n color: #13212f;\n }\n\n body {\n margin: 0;\n min-height: 100vh;\n }\n\n main {\n box-sizing: border-box;\n max-width: 720px;\n margin: 0 auto;\n padding: 48px 20px;\n }\n\n .panel {\n border: 1px solid rgba(19, 33, 47, 0.1);\n border-radius: 24px;\n background: rgba(255, 255, 255, 0.82);\n box-shadow: 0 24px 70px rgba(19, 33, 47, 0.14);\n padding: 28px;\n }\n\n h1 {\n margin: 0 0 10px;\n font-size: clamp(32px, 7vw, 58px);\n letter-spacing: -0.06em;\n }\n\n form {\n display: flex;\n gap: 10px;\n margin: 24px 0;\n }\n\n input {\n flex: 1;\n border: 1px solid rgba(19, 33, 47, 0.18);\n border-radius: 999px;\n padding: 12px 14px;\n font-size: 15px;\n }\n\n button {\n border: 0;\n border-radius: 999px;\n background: #13212f;\n color: white;\n padding: 12px 18px;\n cursor: pointer;\n }\n\n li {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 0;\n border-top: 1px solid rgba(19, 33, 47, 0.1);\n }\n </style>\n </head>\n <body>\n <main>\n <section class=\"panel\">\n <p>TypeScript WASI HTTP NApp</p>\n <h1>${appName}</h1>\n <form id=\"todo-form\">\n <input id=\"todo-title\" type=\"text\" placeholder=\"Add a todo\" />\n <button type=\"submit\">Add</button>\n </form>\n <ul id=\"todos\"></ul>\n </section>\n </main>\n <script type=\"module\" src=\"./app.js\"></script>\n </body>\n</html>\n`;\n };\n\n private buildUiScript = (): string => {\n return `const form = document.getElementById(\"todo-form\");\nconst input = document.getElementById(\"todo-title\");\nconst list = document.getElementById(\"todos\");\n\nasync function loadTodos() {\n const response = await fetch(\"/api/todos\");\n render(await response.json());\n}\n\nasync function addTodo(title) {\n const response = await fetch(\"/api/todos\", {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({ title })\n });\n render(await response.json());\n}\n\nasync function toggleTodo(todo) {\n const response = await fetch(\\`/api/todos/\\${todo.id}\\`, {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({ completed: !todo.completed })\n });\n render(await response.json());\n}\n\nfunction render(todos) {\n list.replaceChildren(\n ...todos.map((todo) => {\n const item = document.createElement(\"li\");\n const label = document.createElement(\"span\");\n label.textContent = todo.completed ? \\`✓ \\${todo.title}\\` : todo.title;\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.textContent = todo.completed ? \"Reopen\" : \"Done\";\n button.addEventListener(\"click\", () => {\n void toggleTodo(todo);\n });\n item.append(label, button);\n return item;\n })\n );\n}\n\nform.addEventListener(\"submit\", (event) => {\n event.preventDefault();\n const title = input.value.trim();\n if (!title) {\n return;\n }\n input.value = \"\";\n void addTodo(title);\n});\n\nvoid loadTodos();\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=\"38\" fill=\"#13212F\" />\n <path d=\"M44 49H116V63H44V49Z\" fill=\"#F2C879\" />\n <path d=\"M44 76H116V90H44V76Z\" fill=\"#F7F4EC\" />\n <path d=\"M44 103H92V117H44V103Z\" fill=\"#8FD3C7\" />\n</svg>\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\nconst APP_WASM_PLACEHOLDER_BASE64 =\n \"AGFzbQEAAAABBwFgAn9/AX8DAgEABxMBD3N1bW1hcml6ZV9ub3RlcwAACg0BCwAgACABakHIAWoL\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-ts-http-scaffold-template.service.js","names":[],"sources":["../../src/services/app-ts-http-scaffold-template.service.ts"],"sourcesContent":["export type AppScaffoldFile = {\n relativePath: string;\n content: string | Buffer;\n};\n\nexport class AppTsHttpScaffoldTemplateService {\n buildFiles = (params: {\n appId: string;\n appName: string;\n }): AppScaffoldFile[] => {\n const { appId, appName } = params;\n return [\n {\n relativePath: \"manifest.json\",\n content: `${JSON.stringify(this.buildManifest(appId, appName), null, 2)}\\n`,\n },\n {\n relativePath: \"marketplace.json\",\n content: `${JSON.stringify(this.buildMarketplaceMetadata(appName), null, 2)}\\n`,\n },\n {\n relativePath: \"README.md\",\n content: this.buildReadme(appName, appId),\n },\n {\n relativePath: \"main/package.json\",\n content: `${JSON.stringify(this.buildMainPackageJson(appId), null, 2)}\\n`,\n },\n {\n relativePath: \"main/tsconfig.json\",\n content: `${JSON.stringify(this.buildTsconfig(), null, 2)}\\n`,\n },\n {\n relativePath: \"main/rolldown.config.mjs\",\n content: this.buildRolldownConfig(),\n },\n {\n relativePath: \"main/wit/world.wit\",\n content: this.buildWitWorld(),\n },\n {\n relativePath: \"main/src/component.ts\",\n content: this.buildComponentSource(),\n },\n {\n relativePath: \"main/app.wasm\",\n content: Buffer.from(APP_WASM_PLACEHOLDER_BASE64, \"base64\"),\n },\n {\n relativePath: \"ui/index.html\",\n content: this.buildUiHtml(appName),\n },\n {\n relativePath: \"ui/app.js\",\n content: this.buildUiScript(),\n },\n {\n relativePath: \"assets/icon.svg\",\n content: this.buildIconSvg(),\n },\n ];\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 TypeScript WASI HTTP NApp scaffold created by napp.\",\n icon: \"assets/icon.svg\",\n main: {\n kind: \"wasi-http-component\",\n entry: \"main/app.wasm\",\n },\n ui: {\n entry: \"ui/index.html\",\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 hono: \"^4.10.0\",\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 buildTsconfig = () => {\n return {\n compilerOptions: {\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"Bundler\",\n strict: true,\n skipLibCheck: true,\n lib: [\"ES2022\", \"DOM\"],\n types: [\"./generated/types/interfaces/wasi-filesystem-preopens\", \"./generated/types/interfaces/wasi-filesystem-types\"],\n },\n include: [\"src/**/*.ts\"],\n };\n };\n\n private buildMarketplaceMetadata = (appName: string) => {\n return {\n slug: this.normalizeSlug(appName),\n summary: `A TypeScript WASI HTTP ${appName} scaffold created by napp.`,\n summaryI18n: {\n en: `A TypeScript WASI HTTP ${appName} scaffold created by napp.`,\n zh: `一个由 napp 创建的 TypeScript WASI HTTP ${appName} 应用骨架。`,\n },\n description: `A TypeScript NApp scaffold for ${appName}, designed for ordinary frontend-to-backend HTTP development on WASI components.`,\n descriptionI18n: {\n en: `A TypeScript NApp scaffold for ${appName}, designed for ordinary frontend-to-backend HTTP development on WASI components.`,\n zh: `一个面向 ${appName} 的 TypeScript NApp 应用骨架,用 WASI component 承载普通前后端 HTTP 开发心智。`,\n },\n author: \"NextClaw\",\n tags: [\"starter\", \"typescript\", \"wasi-http\", \"official\"],\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\\`.\n\nIt keeps the existing NApp directory contract, while making \\`main/app.wasm\\` a WASI HTTP component.\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\nThe build uses the official Bytecode Alliance toolchain and expects \\`wkg\\` to be available for fetching WIT dependencies:\n\n\\`\\`\\`bash\ncargo install wkg\n\\`\\`\\`\n\n## Local workflow\n\n\\`\\`\\`bash\nnapp inspect .\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 can call the backend as ordinary same-origin HTTP:\n\n\\`\\`\\`js\nawait fetch(\"/api/todos\");\n\\`\\`\\`\n`;\n };\n\n private buildRolldownConfig = (): string => {\n return `export default {\n input: \"src/component.ts\",\n output: {\n file: \"dist/component.js\",\n format: \"esm\"\n },\n external: [/^wasi:/]\n};\n`;\n };\n\n private buildWitWorld = (): string => {\n return `package nextclaw:napp;\n\nworld napp-http {\n import wasi:filesystem/types@0.2.2;\n import wasi:filesystem/preopens@0.2.2;\n\n export wasi:http/incoming-handler@0.2.6;\n}\n`;\n };\n\n private buildComponentSource = (): string => {\n return `import { Hono } from \"hono\";\nimport { fire } 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 = new Hono();\n\napp.get(\"/api/todos\", (context) => {\n return context.json(loadTodos());\n});\n\napp.post(\"/api/todos\", async (context) => {\n const input = await context.req.json<TodoInput>();\n if (!input.title?.trim()) {\n return context.json({ error: \"title is required\" }, 400);\n }\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 context.json(todos);\n});\n\napp.patch(\"/api/todos/:id\", async (context) => {\n const input = await context.req.json<Partial<Todo>>();\n const todos = loadTodos();\n const todo = todos.find((entry) => entry.id === context.req.param(\"id\"));\n if (!todo) {\n return context.json({ error: \"todo not found\" }, 404);\n }\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 context.json(todos);\n});\n\napp.delete(\"/api/todos/:id\", (context) => {\n const nextTodos = loadTodos().filter((entry) => entry.id !== context.req.param(\"id\"));\n saveTodos(nextTodos);\n return context.json(nextTodos);\n});\n\napp.notFound((context) => context.text(\"Not found\", 404));\n\nfire(app);\n\nexport { incomingHandler } from \"@bytecodealliance/jco-std/wasi/0.2.6/http/adapters/hono/server\";\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 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: linear-gradient(135deg, #f4efe6 0%, #eff6f9 50%, #f8fafc 100%);\n color: #13212f;\n }\n\n body {\n margin: 0;\n min-height: 100vh;\n }\n\n main {\n box-sizing: border-box;\n max-width: 720px;\n margin: 0 auto;\n padding: 48px 20px;\n }\n\n .panel {\n border: 1px solid rgba(19, 33, 47, 0.1);\n border-radius: 24px;\n background: rgba(255, 255, 255, 0.82);\n box-shadow: 0 24px 70px rgba(19, 33, 47, 0.14);\n padding: 28px;\n }\n\n h1 {\n margin: 0 0 10px;\n font-size: clamp(32px, 7vw, 58px);\n letter-spacing: -0.06em;\n }\n\n form {\n display: flex;\n gap: 10px;\n margin: 24px 0;\n }\n\n input {\n flex: 1;\n border: 1px solid rgba(19, 33, 47, 0.18);\n border-radius: 999px;\n padding: 12px 14px;\n font-size: 15px;\n }\n\n button {\n border: 0;\n border-radius: 999px;\n background: #13212f;\n color: white;\n padding: 12px 18px;\n cursor: pointer;\n }\n\n li {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 0;\n border-top: 1px solid rgba(19, 33, 47, 0.1);\n }\n </style>\n </head>\n <body>\n <main>\n <section class=\"panel\">\n <p>TypeScript WASI HTTP NApp</p>\n <h1>${appName}</h1>\n <form id=\"todo-form\">\n <input id=\"todo-title\" type=\"text\" placeholder=\"Add a todo\" />\n <button type=\"submit\">Add</button>\n </form>\n <ul id=\"todos\"></ul>\n </section>\n </main>\n <script type=\"module\" src=\"./app.js\"></script>\n </body>\n</html>\n`;\n };\n\n private buildUiScript = (): string => {\n return `const form = document.getElementById(\"todo-form\");\nconst input = document.getElementById(\"todo-title\");\nconst list = document.getElementById(\"todos\");\n\nasync function loadTodos() {\n const response = await fetch(\"/api/todos\");\n render(await response.json());\n}\n\nasync function addTodo(title) {\n const response = await fetch(\"/api/todos\", {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({ title })\n });\n render(await response.json());\n}\n\nasync function toggleTodo(todo) {\n const response = await fetch(\\`/api/todos/\\${todo.id}\\`, {\n method: \"PATCH\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({ completed: !todo.completed })\n });\n render(await response.json());\n}\n\nfunction render(todos) {\n list.replaceChildren(\n ...todos.map((todo) => {\n const item = document.createElement(\"li\");\n const label = document.createElement(\"span\");\n label.textContent = todo.completed ? \\`✓ \\${todo.title}\\` : todo.title;\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.textContent = todo.completed ? \"Reopen\" : \"Done\";\n button.addEventListener(\"click\", () => {\n void toggleTodo(todo);\n });\n item.append(label, button);\n return item;\n })\n );\n}\n\nform.addEventListener(\"submit\", (event) => {\n event.preventDefault();\n const title = input.value.trim();\n if (!title) {\n return;\n }\n input.value = \"\";\n void addTodo(title);\n});\n\nvoid loadTodos();\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=\"38\" fill=\"#13212F\" />\n <path d=\"M44 49H116V63H44V49Z\" fill=\"#F2C879\" />\n <path d=\"M44 76H116V90H44V76Z\" fill=\"#F7F4EC\" />\n <path d=\"M44 103H92V117H44V103Z\" fill=\"#8FD3C7\" />\n</svg>\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\nconst APP_WASM_PLACEHOLDER_BASE64 =\n \"AGFzbQEAAAABBwFgAn9/AX8DAgEABxMBD3N1bW1hcml6ZV9ub3RlcwAACg0BCwAgACABakHIAWoL\";\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { AppInstanceService } from "../host/app-instance.service.js";
1
+ import { AppInstanceService } from "./app-instance.service.js";
2
2
  import { IncomingMessage, ServerResponse } from "node:http";
3
3
 
4
- //#region src/bridge/host-bridge.service.d.ts
4
+ //#region src/services/host-bridge.service.d.ts
5
5
  declare class HostBridgeServer {
6
6
  private readonly appInstance;
7
7
  constructor(appInstance: AppInstanceService);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-bridge.service.d.ts","names":[],"sources":["../../src/services/host-bridge.service.ts"],"mappings":";;;;cAGa,gBAAA;EAAA,iBACkB,WAAA;cAAA,WAAA,EAAa,kBAAA;EAE1C,MAAA,GACE,OAAA,EAAS,eAAA,EACT,QAAA,EAAU,cAAA,KACT,OAAA;EAAA,QA4CK,YAAA;EAAA,QAYA,SAAA;AAAA"}
@@ -1,4 +1,4 @@
1
- //#region src/bridge/host-bridge.service.ts
1
+ //#region src/services/host-bridge.service.ts
2
2
  var HostBridgeServer = class {
3
3
  constructor(appInstance) {
4
4
  this.appInstance = appInstance;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-bridge.service.js","names":[],"sources":["../../src/services/host-bridge.service.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { AppInstanceService } from \"#app-runtime/services/app-instance.service.js\";\n\nexport class HostBridgeServer {\n constructor(private readonly appInstance: AppInstanceService) {}\n\n handle = async (\n request: IncomingMessage,\n response: ServerResponse,\n ): Promise<boolean> => {\n const requestUrl = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n if (!requestUrl.pathname.startsWith(\"/__napp\")) {\n return false;\n }\n\n if (request.method === \"GET\" && requestUrl.pathname === \"/__napp/health\") {\n this.writeJson(response, 200, { ok: true });\n return true;\n }\n\n if (request.method === \"GET\" && requestUrl.pathname === \"/__napp/manifest\") {\n this.writeJson(response, 200, {\n ok: true,\n manifest: this.appInstance.summarizeManifest(),\n });\n return true;\n }\n\n if (request.method === \"GET\" && requestUrl.pathname === \"/__napp/permissions\") {\n this.writeJson(response, 200, {\n ok: true,\n permissions: this.appInstance.summarizePermissions(),\n });\n return true;\n }\n\n if (request.method === \"POST\" && requestUrl.pathname === \"/__napp/run\") {\n const body = await this.readJsonBody<{ action?: string }>(request);\n const result = await this.appInstance.runAction(body.action);\n this.writeJson(response, 200, { ok: true, result });\n return true;\n }\n\n this.writeJson(response, 404, {\n ok: false,\n error: {\n code: \"NOT_FOUND\",\n message: `Unknown bridge path: ${requestUrl.pathname}`,\n },\n });\n return true;\n };\n\n private readJsonBody = async <T>(request: IncomingMessage): Promise<T> => {\n const chunks: Buffer[] = [];\n for await (const chunk of request) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const rawBody = Buffer.concat(chunks).toString(\"utf-8\").trim();\n if (!rawBody) {\n return {} as T;\n }\n return JSON.parse(rawBody) as T;\n };\n\n private writeJson = (\n response: ServerResponse,\n statusCode: number,\n payload: unknown,\n ): void => {\n response.writeHead(statusCode, {\n \"content-type\": \"application/json; charset=utf-8\",\n \"cache-control\": \"no-store\",\n });\n response.end(JSON.stringify(payload, null, 2));\n };\n}\n"],"mappings":";AAGA,IAAa,mBAAb,MAA8B;CAC5B,YAAY,aAAkD;AAAjC,OAAA,cAAA;;CAE7B,SAAS,OACP,SACA,aACqB;EACrB,MAAM,aAAa,IAAI,IAAI,QAAQ,OAAO,KAAK,mBAAmB;AAClE,MAAI,CAAC,WAAW,SAAS,WAAW,UAAU,CAC5C,QAAO;AAGT,MAAI,QAAQ,WAAW,SAAS,WAAW,aAAa,kBAAkB;AACxE,QAAK,UAAU,UAAU,KAAK,EAAE,IAAI,MAAM,CAAC;AAC3C,UAAO;;AAGT,MAAI,QAAQ,WAAW,SAAS,WAAW,aAAa,oBAAoB;AAC1E,QAAK,UAAU,UAAU,KAAK;IAC5B,IAAI;IACJ,UAAU,KAAK,YAAY,mBAAmB;IAC/C,CAAC;AACF,UAAO;;AAGT,MAAI,QAAQ,WAAW,SAAS,WAAW,aAAa,uBAAuB;AAC7E,QAAK,UAAU,UAAU,KAAK;IAC5B,IAAI;IACJ,aAAa,KAAK,YAAY,sBAAsB;IACrD,CAAC;AACF,UAAO;;AAGT,MAAI,QAAQ,WAAW,UAAU,WAAW,aAAa,eAAe;GACtE,MAAM,OAAO,MAAM,KAAK,aAAkC,QAAQ;GAClE,MAAM,SAAS,MAAM,KAAK,YAAY,UAAU,KAAK,OAAO;AAC5D,QAAK,UAAU,UAAU,KAAK;IAAE,IAAI;IAAM;IAAQ,CAAC;AACnD,UAAO;;AAGT,OAAK,UAAU,UAAU,KAAK;GAC5B,IAAI;GACJ,OAAO;IACL,MAAM;IACN,SAAS,wBAAwB,WAAW;IAC7C;GACF,CAAC;AACF,SAAO;;CAGT,eAAuB,OAAU,YAAyC;EACxE,MAAM,SAAmB,EAAE;AAC3B,aAAW,MAAM,SAAS,QACxB,QAAO,KAAK,OAAO,SAAS,MAAM,GAAG,QAAQ,OAAO,KAAK,MAAM,CAAC;EAElE,MAAM,UAAU,OAAO,OAAO,OAAO,CAAC,SAAS,QAAQ,CAAC,MAAM;AAC9D,MAAI,CAAC,QACH,QAAO,EAAE;AAEX,SAAO,KAAK,MAAM,QAAQ;;CAG5B,aACE,UACA,YACA,YACS;AACT,WAAS,UAAU,YAAY;GAC7B,gBAAgB;GAChB,iBAAiB;GAClB,CAAC;AACF,WAAS,IAAI,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { MainRunRequest, MainRunResult } from "../types/main-runner.types.js";
2
+
3
+ //#region src/services/main-runner.service.d.ts
4
+ declare abstract class MainRunnerService {
5
+ abstract runDocumentSummary(request: MainRunRequest): Promise<MainRunResult>;
6
+ }
7
+ //#endregion
8
+ export { MainRunnerService };
9
+ //# sourceMappingURL=main-runner.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-runner.service.d.ts","names":[],"sources":["../../src/services/main-runner.service.ts"],"mappings":";;;uBAEsB,iBAAA;EAAA,SACX,kBAAA,CAAmB,OAAA,EAAS,cAAA,GAAiB,OAAA,CAAQ,aAAA;AAAA"}
@@ -0,0 +1,6 @@
1
+ //#region src/services/main-runner.service.ts
2
+ var MainRunnerService = class {};
3
+ //#endregion
4
+ export { MainRunnerService };
5
+
6
+ //# sourceMappingURL=main-runner.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-runner.service.js","names":[],"sources":["../../src/services/main-runner.service.ts"],"sourcesContent":["import type { MainRunRequest, MainRunResult } from \"#app-runtime/types/main-runner.types.js\";\n\nexport abstract class MainRunnerService {\n abstract runDocumentSummary(request: MainRunRequest): Promise<MainRunResult>;\n}\n"],"mappings":";AAEA,IAAsB,oBAAtB,MAAwC"}
@@ -1,4 +1,4 @@
1
- //#region src/publish/platform-auth-state.service.d.ts
1
+ //#region src/services/platform-auth-state.service.d.ts
2
2
  type PlatformPublishAuthState = {
3
3
  token: string | null;
4
4
  apiBaseUrl?: string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-auth-state.service.d.ts","names":[],"sources":["../../src/services/platform-auth-state.service.ts"],"mappings":";KAWY,wBAAA;EACV,KAAA;EACA,UAAA;AAAA;AAAA,cAMW,wBAAA;EACX,oBAAA,QAA2B,wBAAA;EAAA,QA4BnB,iBAAA;AAAA"}
@@ -1,7 +1,7 @@
1
1
  import { resolve } from "node:path";
2
2
  import { homedir } from "node:os";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
- //#region src/publish/platform-auth-state.service.ts
4
+ //#region src/services/platform-auth-state.service.ts
5
5
  const NEXTCLAW_HOME_ENV_KEY = "NEXTCLAW_HOME";
6
6
  const NEXTCLAW_DEFAULT_HOME_DIR = ".nextclaw";
7
7
  var PlatformAuthStateService = class {