@warlock.js/core 5.31.0 → 5.32.0

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 (1018) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/esm/application/app.d.mts +3 -3
  3. package/esm/application/app.d.mts.map +1 -1
  4. package/esm/application/application-config-types.d.mts +1 -2
  5. package/esm/application/application-config-types.d.mts.map +1 -1
  6. package/esm/application/application.d.mts +5 -7
  7. package/esm/application/application.d.mts.map +1 -1
  8. package/esm/application/application.mjs +3 -1
  9. package/esm/application/application.mjs.map +1 -1
  10. package/esm/application/boot-signal.d.mts +14 -12
  11. package/esm/application/boot-signal.d.mts.map +1 -1
  12. package/esm/application/index.d.mts +2 -1
  13. package/esm/application/index.mjs +1 -1
  14. package/esm/application/public-url.d.mts +1 -2
  15. package/esm/application/public-url.d.mts.map +1 -1
  16. package/esm/application/roles.d.mts +10 -11
  17. package/esm/application/roles.d.mts.map +1 -1
  18. package/esm/benchmark/benchmark-snapshots.d.mts +1 -3
  19. package/esm/benchmark/benchmark-snapshots.d.mts.map +1 -1
  20. package/esm/benchmark/benchmark.d.mts +1 -3
  21. package/esm/benchmark/benchmark.d.mts.map +1 -1
  22. package/esm/benchmark/channels/console.channel.d.mts +1 -3
  23. package/esm/benchmark/channels/console.channel.d.mts.map +1 -1
  24. package/esm/benchmark/channels/noop.channel.d.mts +1 -3
  25. package/esm/benchmark/channels/noop.channel.d.mts.map +1 -1
  26. package/esm/benchmark/index.mjs +1 -1
  27. package/esm/benchmark/profiler.d.mts +1 -3
  28. package/esm/benchmark/profiler.d.mts.map +1 -1
  29. package/esm/benchmark/profiler.mjs +2 -1
  30. package/esm/benchmark/profiler.mjs.map +1 -1
  31. package/esm/benchmark/types.d.mts +22 -17
  32. package/esm/benchmark/types.d.mts.map +1 -1
  33. package/esm/bootstrap/setup.d.mts +1 -2
  34. package/esm/bootstrap/setup.d.mts.map +1 -1
  35. package/esm/bootstrap.d.mts +1 -2
  36. package/esm/bootstrap.d.mts.map +1 -1
  37. package/esm/cache/database-cache-driver.d.mts +3 -5
  38. package/esm/cache/database-cache-driver.d.mts.map +1 -1
  39. package/esm/cache/database-cache-driver.mjs +1 -1
  40. package/esm/cache/index.d.mts +2 -1
  41. package/esm/cache/index.mjs +1 -1
  42. package/esm/cli/cli-commands.manager.mjs +6 -3
  43. package/esm/cli/cli-commands.manager.mjs.map +1 -1
  44. package/esm/cli/commands/agents-md/agents-md-command.action.mjs +3 -2
  45. package/esm/cli/commands/agents-md/agents-md-command.action.mjs.map +1 -1
  46. package/esm/cli/commands/board/board-command.action.mjs +1 -1
  47. package/esm/cli/commands/check/check-command.action.mjs +1 -1
  48. package/esm/cli/commands/check/child-typecheck.mjs +1 -1
  49. package/esm/cli/commands/check/child-typecheck.mjs.map +1 -1
  50. package/esm/cli/commands/check/format-problems.mjs +1 -1
  51. package/esm/cli/commands/dev-server.command.mjs +3 -2
  52. package/esm/cli/commands/dev-server.command.mjs.map +1 -1
  53. package/esm/cli/commands/doctor/check.types.d.mts +29 -16
  54. package/esm/cli/commands/doctor/check.types.d.mts.map +1 -1
  55. package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs +22 -27
  56. package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs.map +1 -1
  57. package/esm/cli/commands/doctor/doctor-command.action.mjs +2 -1
  58. package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
  59. package/esm/cli/commands/explain/explain-command.action.mjs +1 -1
  60. package/esm/cli/commands/generate/generators/controller.generator.mjs +5 -2
  61. package/esm/cli/commands/generate/generators/controller.generator.mjs.map +1 -1
  62. package/esm/cli/commands/generate/generators/endpoint.generator.mjs +5 -3
  63. package/esm/cli/commands/generate/generators/endpoint.generator.mjs.map +1 -1
  64. package/esm/cli/commands/generate/generators/model.generator.mjs +3 -2
  65. package/esm/cli/commands/generate/generators/model.generator.mjs.map +1 -1
  66. package/esm/cli/commands/generate/generators/repository.generator.mjs +3 -1
  67. package/esm/cli/commands/generate/generators/repository.generator.mjs.map +1 -1
  68. package/esm/cli/commands/generate/generators/resource.generator.mjs +3 -1
  69. package/esm/cli/commands/generate/generators/resource.generator.mjs.map +1 -1
  70. package/esm/cli/commands/generate/generators/service.generator.mjs +3 -1
  71. package/esm/cli/commands/generate/generators/service.generator.mjs.map +1 -1
  72. package/esm/cli/commands/generate/templates/endpoint-stubs.mjs +2 -2
  73. package/esm/cli/commands/generate/templates/endpoint-stubs.mjs.map +1 -1
  74. package/esm/cli/commands/generate/utils/endpoint-schema.mjs +1 -2
  75. package/esm/cli/commands/generate/utils/endpoint-schema.mjs.map +1 -1
  76. package/esm/cli/commands/generate/utils/name-parser.mjs +1 -1
  77. package/esm/cli/commands/generate/utils/path-resolver.mjs +1 -1
  78. package/esm/cli/commands/inspect/inspect-command.action.mjs +3 -2
  79. package/esm/cli/commands/inspect/inspect-command.action.mjs.map +1 -1
  80. package/esm/cli/commands/issue/collect-environment.mjs +187 -0
  81. package/esm/cli/commands/issue/collect-environment.mjs.map +1 -0
  82. package/esm/cli/commands/issue/issue-command.action.mjs +70 -0
  83. package/esm/cli/commands/issue/issue-command.action.mjs.map +1 -0
  84. package/esm/cli/commands/issue.command.mjs +31 -0
  85. package/esm/cli/commands/issue.command.mjs.map +1 -0
  86. package/esm/cli/commands/mcp/mcp-command.action.mjs +15 -14
  87. package/esm/cli/commands/mcp/mcp-command.action.mjs.map +1 -1
  88. package/esm/cli/commands/openapi-generator.action.mjs +1 -1
  89. package/esm/cli/commands/postman-generator.action.mjs +1 -1
  90. package/esm/cli/commands/routes/format-routes-table.mjs +1 -1
  91. package/esm/cli/commands/routes/route-row.mjs +1 -1
  92. package/esm/cli/commands/routes/routes-diff.action.mjs +2 -2
  93. package/esm/cli/commands/routes/routes-diff.action.mjs.map +1 -1
  94. package/esm/cli/commands/test.command.mjs +1 -1
  95. package/esm/cli/commands/trace/trace-command.action.mjs +1 -1
  96. package/esm/cli/commands-loader.mjs +1 -1
  97. package/esm/cli/framework-cli-commands.mjs +2 -0
  98. package/esm/cli/framework-cli-commands.mjs.map +1 -1
  99. package/esm/cli/parse-cli-args.mjs +2 -2
  100. package/esm/cli/parse-cli-args.mjs.map +1 -1
  101. package/esm/cli/start.d.mts +1 -1
  102. package/esm/cli/string-similarity.mjs +1 -1
  103. package/esm/commands/cli-command.d.mts +2 -4
  104. package/esm/commands/cli-command.d.mts.map +1 -1
  105. package/esm/commands/index.d.mts +2 -1
  106. package/esm/commands/index.mjs +1 -1
  107. package/esm/commands/types.d.mts +8 -8
  108. package/esm/commands/types.d.mts.map +1 -1
  109. package/esm/config/config-getter.d.mts +2 -3
  110. package/esm/config/config-getter.d.mts.map +1 -1
  111. package/esm/config/config-getter.mjs +5 -5
  112. package/esm/config/config-getter.mjs.map +1 -1
  113. package/esm/config/config-handlers.d.mts +1 -3
  114. package/esm/config/config-handlers.d.mts.map +1 -1
  115. package/esm/config/config-loader.d.mts +1 -2
  116. package/esm/config/config-loader.d.mts.map +1 -1
  117. package/esm/config/config-loader.mjs +3 -3
  118. package/esm/config/config-loader.mjs.map +1 -1
  119. package/esm/config/config-manager.mjs +1 -1
  120. package/esm/config/config-schema.d.mts +19 -16
  121. package/esm/config/config-schema.d.mts.map +1 -1
  122. package/esm/config/config-setter.d.mts +2 -4
  123. package/esm/config/config-setter.d.mts.map +1 -1
  124. package/esm/config/config-setter.mjs +2 -2
  125. package/esm/config/config-setter.mjs.map +1 -1
  126. package/esm/config/config-special-handlers.d.mts +2 -4
  127. package/esm/config/config-special-handlers.d.mts.map +1 -1
  128. package/esm/config/index.d.mts +2 -1
  129. package/esm/config/index.mjs +1 -1
  130. package/esm/config/types.d.mts +4 -5
  131. package/esm/config/types.d.mts.map +1 -1
  132. package/esm/connectors/access-connector.d.mts +1 -3
  133. package/esm/connectors/access-connector.d.mts.map +1 -1
  134. package/esm/connectors/access-connector.mjs +2 -2
  135. package/esm/connectors/access-connector.mjs.map +1 -1
  136. package/esm/connectors/ai-connector.d.mts +1 -3
  137. package/esm/connectors/ai-connector.d.mts.map +1 -1
  138. package/esm/connectors/ai-connector.mjs +2 -2
  139. package/esm/connectors/ai-connector.mjs.map +1 -1
  140. package/esm/connectors/assert-no-reserved-connector-names.d.mts +1 -3
  141. package/esm/connectors/assert-no-reserved-connector-names.d.mts.map +1 -1
  142. package/esm/connectors/assert-unique-connector-names.d.mts +1 -3
  143. package/esm/connectors/assert-unique-connector-names.d.mts.map +1 -1
  144. package/esm/connectors/assert-unique-connector-names.mjs +2 -1
  145. package/esm/connectors/assert-unique-connector-names.mjs.map +1 -1
  146. package/esm/connectors/base-connector.d.mts +1 -3
  147. package/esm/connectors/base-connector.d.mts.map +1 -1
  148. package/esm/connectors/cache-connector.d.mts +1 -3
  149. package/esm/connectors/cache-connector.d.mts.map +1 -1
  150. package/esm/connectors/cache-connector.mjs +3 -3
  151. package/esm/connectors/cache-connector.mjs.map +1 -1
  152. package/esm/connectors/connectors-manager.d.mts +2 -4
  153. package/esm/connectors/connectors-manager.d.mts.map +1 -1
  154. package/esm/connectors/connectors-manager.mjs +2 -2
  155. package/esm/connectors/connectors-manager.mjs.map +1 -1
  156. package/esm/connectors/database-connector.d.mts +1 -3
  157. package/esm/connectors/database-connector.d.mts.map +1 -1
  158. package/esm/connectors/database-connector.mjs +2 -2
  159. package/esm/connectors/database-connector.mjs.map +1 -1
  160. package/esm/connectors/describe-server-address.mjs +4 -4
  161. package/esm/connectors/describe-server-address.mjs.map +1 -1
  162. package/esm/connectors/herald-connector.d.mts +1 -3
  163. package/esm/connectors/herald-connector.d.mts.map +1 -1
  164. package/esm/connectors/herald-connector.mjs +2 -2
  165. package/esm/connectors/herald-connector.mjs.map +1 -1
  166. package/esm/connectors/http-connector.d.mts +1 -3
  167. package/esm/connectors/http-connector.d.mts.map +1 -1
  168. package/esm/connectors/http-connector.mjs +8 -7
  169. package/esm/connectors/http-connector.mjs.map +1 -1
  170. package/esm/connectors/index.d.mts +2 -1
  171. package/esm/connectors/index.mjs +1 -1
  172. package/esm/connectors/logger-connector.d.mts +1 -3
  173. package/esm/connectors/logger-connector.d.mts.map +1 -1
  174. package/esm/connectors/logger-connector.mjs +2 -2
  175. package/esm/connectors/logger-connector.mjs.map +1 -1
  176. package/esm/connectors/mail-connector.d.mts +1 -3
  177. package/esm/connectors/mail-connector.d.mts.map +1 -1
  178. package/esm/connectors/mail-connector.mjs +2 -2
  179. package/esm/connectors/mail-connector.mjs.map +1 -1
  180. package/esm/connectors/notifications-connector.d.mts +1 -3
  181. package/esm/connectors/notifications-connector.d.mts.map +1 -1
  182. package/esm/connectors/notifications-connector.mjs +2 -2
  183. package/esm/connectors/notifications-connector.mjs.map +1 -1
  184. package/esm/connectors/register-configured-connectors.d.mts +2 -4
  185. package/esm/connectors/register-configured-connectors.d.mts.map +1 -1
  186. package/esm/connectors/socket-connector.d.mts +1 -3
  187. package/esm/connectors/socket-connector.d.mts.map +1 -1
  188. package/esm/connectors/socket-connector.mjs +12 -10
  189. package/esm/connectors/socket-connector.mjs.map +1 -1
  190. package/esm/connectors/storage.connector.d.mts +1 -3
  191. package/esm/connectors/storage.connector.d.mts.map +1 -1
  192. package/esm/connectors/storage.connector.mjs +2 -2
  193. package/esm/connectors/storage.connector.mjs.map +1 -1
  194. package/esm/connectors/types.d.mts +17 -14
  195. package/esm/connectors/types.d.mts.map +1 -1
  196. package/esm/container/container-instance-registry.mjs.map +1 -1
  197. package/esm/container/development-app-modules.d.mts +7 -5
  198. package/esm/container/development-app-modules.d.mts.map +1 -1
  199. package/esm/container/development-model-modules.d.mts +6 -5
  200. package/esm/container/development-model-modules.d.mts.map +1 -1
  201. package/esm/container/index.d.mts +4 -4
  202. package/esm/container/index.d.mts.map +1 -1
  203. package/esm/database/index.d.mts +3 -1
  204. package/esm/database/index.mjs +1 -1
  205. package/esm/database/migrate-action.mjs +1 -1
  206. package/esm/database/models/database-log/database-log.d.mts +2 -3
  207. package/esm/database/models/database-log/database-log.d.mts.map +1 -1
  208. package/esm/database/models/database-log/index.d.mts +2 -1
  209. package/esm/database/models/database-log/index.mjs +1 -1
  210. package/esm/database/seed-command-action.mjs +1 -1
  211. package/esm/database/seeds/seeder.d.mts +2 -4
  212. package/esm/database/seeds/seeder.d.mts.map +1 -1
  213. package/esm/database/seeds/seeder.errors.d.mts +2 -3
  214. package/esm/database/seeds/seeder.errors.d.mts.map +1 -1
  215. package/esm/database/seeds/seeders.manager.mjs +2 -1
  216. package/esm/database/seeds/seeders.manager.mjs.map +1 -1
  217. package/esm/database/seeds/types.d.mts +7 -8
  218. package/esm/database/seeds/types.d.mts.map +1 -1
  219. package/esm/database/utils.d.mts +4 -5
  220. package/esm/database/utils.d.mts.map +1 -1
  221. package/esm/dev-server/app-module-registry.mjs +1 -1
  222. package/esm/dev-server/create-worker.mjs +5 -3
  223. package/esm/dev-server/create-worker.mjs.map +1 -1
  224. package/esm/dev-server/dependency-graph.d.mts +1 -3
  225. package/esm/dev-server/dependency-graph.d.mts.map +1 -1
  226. package/esm/dev-server/dependency-graph.mjs +1 -1
  227. package/esm/dev-server/dependency-graph.mjs.map +1 -1
  228. package/esm/dev-server/extract-translation-keys.mjs +16 -17
  229. package/esm/dev-server/extract-translation-keys.mjs.map +1 -1
  230. package/esm/dev-server/file-manager.d.mts +3 -7
  231. package/esm/dev-server/file-manager.d.mts.map +1 -1
  232. package/esm/dev-server/file-operations.d.mts +1 -3
  233. package/esm/dev-server/file-operations.d.mts.map +1 -1
  234. package/esm/dev-server/files-watcher.mjs +12 -11
  235. package/esm/dev-server/files-watcher.mjs.map +1 -1
  236. package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs +36 -115
  237. package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs.map +1 -1
  238. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +5 -5
  239. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
  240. package/esm/dev-server/health-checker/file-health-result.d.mts +2 -2
  241. package/esm/dev-server/health-checker/file-health-result.d.mts.map +1 -1
  242. package/esm/dev-server/health-checker/files-healthcare.manager.mjs +1 -0
  243. package/esm/dev-server/health-checker/files-healthcare.manager.mjs.map +1 -1
  244. package/esm/dev-server/health-checker/oxlint-runner.mjs +6 -5
  245. package/esm/dev-server/health-checker/oxlint-runner.mjs.map +1 -1
  246. package/esm/dev-server/health-checker/workers/eslint-health.worker.d.mts +1 -1
  247. package/esm/dev-server/health-checker/workers/oxlint-health.worker.d.mts +1 -1
  248. package/esm/dev-server/health-checker/workers/ts-health.worker.d.mts +1 -1
  249. package/esm/dev-server/health-checker/workers/ts-health.worker.mjs +40 -174
  250. package/esm/dev-server/health-checker/workers/ts-health.worker.mjs.map +1 -1
  251. package/esm/dev-server/loader/hook-thread.d.mts +4 -8
  252. package/esm/dev-server/loader/hook-thread.d.mts.map +1 -1
  253. package/esm/dev-server/loader/load-hook.d.mts +10 -6
  254. package/esm/dev-server/loader/load-hook.d.mts.map +1 -1
  255. package/esm/dev-server/loader/load-hook.mjs +4 -3
  256. package/esm/dev-server/loader/load-hook.mjs.map +1 -1
  257. package/esm/dev-server/loader/own-resolver.mjs +1 -1
  258. package/esm/dev-server/loader/register-loader.mjs +3 -2
  259. package/esm/dev-server/loader/register-loader.mjs.map +1 -1
  260. package/esm/dev-server/loader/resolve-hook.d.mts +2 -2
  261. package/esm/dev-server/loader/resolve-hook.d.mts.map +1 -1
  262. package/esm/dev-server/loader/resolve-hook.mjs +2 -1
  263. package/esm/dev-server/loader/resolve-hook.mjs.map +1 -1
  264. package/esm/dev-server/loader/transpile-cache.mjs +2 -1
  265. package/esm/dev-server/loader/transpile-cache.mjs.map +1 -1
  266. package/esm/dev-server/manifest-manager.d.mts +1 -3
  267. package/esm/dev-server/manifest-manager.d.mts.map +1 -1
  268. package/esm/dev-server/model-module-registry.mjs +3 -3
  269. package/esm/dev-server/model-module-registry.mjs.map +1 -1
  270. package/esm/dev-server/model-resource-typings.mjs +40 -47
  271. package/esm/dev-server/model-resource-typings.mjs.map +1 -1
  272. package/esm/dev-server/module-loader.mjs +2 -2
  273. package/esm/dev-server/module-loader.mjs.map +1 -1
  274. package/esm/dev-server/package-json-manager.mjs +1 -1
  275. package/esm/dev-server/parse-imports.mjs +6 -38
  276. package/esm/dev-server/parse-imports.mjs.map +1 -1
  277. package/esm/dev-server/read-config-ast.mjs +3 -33
  278. package/esm/dev-server/read-config-ast.mjs.map +1 -1
  279. package/esm/dev-server/ready-block.mjs +1 -1
  280. package/esm/dev-server/shortcuts.mjs +1 -1
  281. package/esm/dev-server/special-files-collector.d.mts +2 -4
  282. package/esm/dev-server/special-files-collector.d.mts.map +1 -1
  283. package/esm/dev-server/supervisor.mjs +1 -1
  284. package/esm/dev-server/tsconfig-manager.mjs +3 -3
  285. package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
  286. package/esm/dev-server/type-generator.mjs +28 -35
  287. package/esm/dev-server/type-generator.mjs.map +1 -1
  288. package/esm/dev-server/types.d.mts +3 -4
  289. package/esm/dev-server/types.d.mts.map +1 -1
  290. package/esm/dev-server/update-check-cache.mjs +2 -2
  291. package/esm/dev-server/update-check-cache.mjs.map +1 -1
  292. package/esm/encryption/encrypt.d.mts +2 -3
  293. package/esm/encryption/encrypt.d.mts.map +1 -1
  294. package/esm/encryption/hash.d.mts +1 -2
  295. package/esm/encryption/hash.d.mts.map +1 -1
  296. package/esm/encryption/index.mjs +1 -1
  297. package/esm/encryption/password.d.mts +2 -3
  298. package/esm/encryption/password.d.mts.map +1 -1
  299. package/esm/encryption/types.d.mts +2 -3
  300. package/esm/encryption/types.d.mts.map +1 -1
  301. package/esm/errors/error-codes.d.mts +29 -22
  302. package/esm/errors/error-codes.d.mts.map +1 -1
  303. package/esm/errors/warlock-error.d.mts +1 -3
  304. package/esm/errors/warlock-error.d.mts.map +1 -1
  305. package/esm/generations/add-command.action.mjs +3 -2
  306. package/esm/generations/add-command.action.mjs.map +1 -1
  307. package/esm/generations/features/bull-board.feature.mjs +2 -1
  308. package/esm/generations/features/bull-board.feature.mjs.map +1 -1
  309. package/esm/generations/features/notifications.feature.mjs +2 -1
  310. package/esm/generations/features/notifications.feature.mjs.map +1 -1
  311. package/esm/generations/features/shared/merge-web-sitemap-config.mjs +16 -23
  312. package/esm/generations/features/shared/merge-web-sitemap-config.mjs.map +1 -1
  313. package/esm/generations/features/shared/patch-tsconfig-include.mjs +1 -1
  314. package/esm/generations/features/shared/relocate-conflicting-home-route.mjs +1 -1
  315. package/esm/generations/features/sitemap.feature.mjs +2 -1
  316. package/esm/generations/features/sitemap.feature.mjs.map +1 -1
  317. package/esm/generations/generation-fs.mjs +1 -1
  318. package/esm/generations/generation-run.mjs +1 -1
  319. package/esm/generations/stubs.mjs +1 -1
  320. package/esm/generations/stubs.mjs.map +1 -1
  321. package/esm/http/boot-port-preflight.d.mts +4 -5
  322. package/esm/http/boot-port-preflight.d.mts.map +1 -1
  323. package/esm/http/boot-port-preflight.mjs +2 -2
  324. package/esm/http/boot-port-preflight.mjs.map +1 -1
  325. package/esm/http/bounded-stream-queue.d.mts +4 -4
  326. package/esm/http/bounded-stream-queue.d.mts.map +1 -1
  327. package/esm/http/bounded-stream-queue.mjs +1 -1
  328. package/esm/http/bounded-stream-queue.mjs.map +1 -1
  329. package/esm/http/build-cors-options.mjs +2 -2
  330. package/esm/http/build-cors-options.mjs.map +1 -1
  331. package/esm/http/build-rate-limit-options.d.mts +2 -3
  332. package/esm/http/build-rate-limit-options.d.mts.map +1 -1
  333. package/esm/http/build-rate-limit-options.mjs +1 -1
  334. package/esm/http/build-rate-limit-options.mjs.map +1 -1
  335. package/esm/http/conditional-request.d.mts +14 -13
  336. package/esm/http/conditional-request.d.mts.map +1 -1
  337. package/esm/http/config.d.mts +2 -4
  338. package/esm/http/config.d.mts.map +1 -1
  339. package/esm/http/config.mjs +2 -2
  340. package/esm/http/config.mjs.map +1 -1
  341. package/esm/http/context/request-context.d.mts +6 -7
  342. package/esm/http/context/request-context.d.mts.map +1 -1
  343. package/esm/http/context/request-memo.d.mts +1 -2
  344. package/esm/http/context/request-memo.d.mts.map +1 -1
  345. package/esm/http/createHttpApplication.d.mts +2 -3
  346. package/esm/http/createHttpApplication.d.mts.map +1 -1
  347. package/esm/http/createHttpApplication.mjs +2 -2
  348. package/esm/http/createHttpApplication.mjs.map +1 -1
  349. package/esm/http/csp.d.mts +10 -12
  350. package/esm/http/csp.d.mts.map +1 -1
  351. package/esm/http/csp.mjs +2 -2
  352. package/esm/http/csp.mjs.map +1 -1
  353. package/esm/http/csrf-default-guard.d.mts +2 -4
  354. package/esm/http/csrf-default-guard.d.mts.map +1 -1
  355. package/esm/http/csrf-default-guard.mjs +1 -1
  356. package/esm/http/csrf-default-guard.mjs.map +1 -1
  357. package/esm/http/csrf-origin-policy.d.mts +7 -9
  358. package/esm/http/csrf-origin-policy.d.mts.map +1 -1
  359. package/esm/http/csrf-origin-policy.mjs +2 -2
  360. package/esm/http/csrf-origin-policy.mjs.map +1 -1
  361. package/esm/http/database/RequestLog.d.mts +2 -3
  362. package/esm/http/database/RequestLog.d.mts.map +1 -1
  363. package/esm/http/error-codes.d.mts +1 -2
  364. package/esm/http/error-codes.d.mts.map +1 -1
  365. package/esm/http/error-mapper.d.mts +2 -4
  366. package/esm/http/error-mapper.d.mts.map +1 -1
  367. package/esm/http/error-mapper.mjs +2 -2
  368. package/esm/http/error-mapper.mjs.map +1 -1
  369. package/esm/http/errors/errors.d.mts +28 -29
  370. package/esm/http/errors/errors.d.mts.map +1 -1
  371. package/esm/http/escape-header-value.d.mts +1 -2
  372. package/esm/http/escape-header-value.d.mts.map +1 -1
  373. package/esm/http/events.d.mts +2 -4
  374. package/esm/http/events.d.mts.map +1 -1
  375. package/esm/http/health.d.mts +4 -4
  376. package/esm/http/health.d.mts.map +1 -1
  377. package/esm/http/index.d.mts +4 -1
  378. package/esm/http/index.mjs +1 -1
  379. package/esm/http/middleware/cache-response-middleware.d.mts +2 -4
  380. package/esm/http/middleware/cache-response-middleware.d.mts.map +1 -1
  381. package/esm/http/middleware/concurrency-limit.middleware.d.mts +3 -3
  382. package/esm/http/middleware/concurrency-limit.middleware.d.mts.map +1 -1
  383. package/esm/http/middleware/idempotency.middleware.d.mts +3 -3
  384. package/esm/http/middleware/idempotency.middleware.d.mts.map +1 -1
  385. package/esm/http/middleware/idempotency.middleware.mjs +6 -6
  386. package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
  387. package/esm/http/middleware/index.d.mts +3 -1
  388. package/esm/http/middleware/index.mjs +1 -1
  389. package/esm/http/middleware/inject-request-context.d.mts +2 -4
  390. package/esm/http/middleware/inject-request-context.d.mts.map +1 -1
  391. package/esm/http/middleware/inject-request-context.mjs +3 -3
  392. package/esm/http/middleware/inject-request-context.mjs.map +1 -1
  393. package/esm/http/middleware/ip-filter.middleware.d.mts +3 -3
  394. package/esm/http/middleware/ip-filter.middleware.d.mts.map +1 -1
  395. package/esm/http/middleware/maintenance.middleware.d.mts +3 -3
  396. package/esm/http/middleware/maintenance.middleware.d.mts.map +1 -1
  397. package/esm/http/middleware/maintenance.middleware.mjs +4 -4
  398. package/esm/http/middleware/maintenance.middleware.mjs.map +1 -1
  399. package/esm/http/middleware/max-body-size.middleware.d.mts +2 -2
  400. package/esm/http/middleware/max-body-size.middleware.d.mts.map +1 -1
  401. package/esm/http/middleware/middleware-list.d.mts +1 -3
  402. package/esm/http/middleware/middleware-list.d.mts.map +1 -1
  403. package/esm/http/middleware/rate-limit.middleware.d.mts +3 -3
  404. package/esm/http/middleware/rate-limit.middleware.d.mts.map +1 -1
  405. package/esm/http/middleware/rate-limit.middleware.mjs +2 -2
  406. package/esm/http/middleware/rate-limit.middleware.mjs.map +1 -1
  407. package/esm/http/middleware/utils/cidr-match.d.mts +2 -3
  408. package/esm/http/middleware/utils/cidr-match.d.mts.map +1 -1
  409. package/esm/http/middleware/utils/idempotency-key.d.mts +3 -5
  410. package/esm/http/middleware/utils/idempotency-key.d.mts.map +1 -1
  411. package/esm/http/middleware/utils/index.d.mts +2 -1
  412. package/esm/http/middleware/utils/parse-size.d.mts +1 -2
  413. package/esm/http/middleware/utils/parse-size.d.mts.map +1 -1
  414. package/esm/http/middleware/utils/parse-size.mjs +2 -2
  415. package/esm/http/middleware/utils/parse-size.mjs.map +1 -1
  416. package/esm/http/plugins.d.mts +2 -4
  417. package/esm/http/plugins.d.mts.map +1 -1
  418. package/esm/http/plugins.mjs +10 -10
  419. package/esm/http/plugins.mjs.map +1 -1
  420. package/esm/http/port-preflight.d.mts +3 -4
  421. package/esm/http/port-preflight.d.mts.map +1 -1
  422. package/esm/http/rate-limit-cache-store.mjs +4 -3
  423. package/esm/http/rate-limit-cache-store.mjs.map +1 -1
  424. package/esm/http/ready-report.d.mts +15 -10
  425. package/esm/http/ready-report.d.mts.map +1 -1
  426. package/esm/http/request-controller.d.mts +1 -3
  427. package/esm/http/request-controller.d.mts.map +1 -1
  428. package/esm/http/request-log-snapshot.d.mts +20 -16
  429. package/esm/http/request-log-snapshot.d.mts.map +1 -1
  430. package/esm/http/request-log-snapshot.mjs +3 -3
  431. package/esm/http/request-log-snapshot.mjs.map +1 -1
  432. package/esm/http/request.d.mts +8 -7
  433. package/esm/http/request.d.mts.map +1 -1
  434. package/esm/http/request.mjs +8 -7
  435. package/esm/http/request.mjs.map +1 -1
  436. package/esm/http/response.d.mts +12 -11
  437. package/esm/http/response.d.mts.map +1 -1
  438. package/esm/http/response.mjs +7 -7
  439. package/esm/http/response.mjs.map +1 -1
  440. package/esm/http/safe-redirect.d.mts +3 -4
  441. package/esm/http/safe-redirect.d.mts.map +1 -1
  442. package/esm/http/serialized.d.mts +12 -13
  443. package/esm/http/serialized.d.mts.map +1 -1
  444. package/esm/http/server-rebuilt.d.mts +3 -5
  445. package/esm/http/server-rebuilt.d.mts.map +1 -1
  446. package/esm/http/server.d.mts +9 -9
  447. package/esm/http/server.d.mts.map +1 -1
  448. package/esm/http/server.mjs +4 -4
  449. package/esm/http/server.mjs.map +1 -1
  450. package/esm/http/stream-react-response.d.mts +7 -7
  451. package/esm/http/stream-react-response.d.mts.map +1 -1
  452. package/esm/http/tracing/index.mjs +1 -1
  453. package/esm/http/tracing/trace-id.d.mts +2 -3
  454. package/esm/http/tracing/trace-id.d.mts.map +1 -1
  455. package/esm/http/tracing/tracing-dispatcher.d.mts +10 -11
  456. package/esm/http/tracing/tracing-dispatcher.d.mts.map +1 -1
  457. package/esm/http/tracing/tracing-dispatcher.mjs +2 -2
  458. package/esm/http/tracing/tracing-dispatcher.mjs.map +1 -1
  459. package/esm/http/tracing/tracing.type.d.mts +11 -9
  460. package/esm/http/tracing/tracing.type.d.mts.map +1 -1
  461. package/esm/http/types.d.mts +49 -43
  462. package/esm/http/types.d.mts.map +1 -1
  463. package/esm/http/uploaded-file.d.mts +6 -5
  464. package/esm/http/uploaded-file.d.mts.map +1 -1
  465. package/esm/http/uploads/generate-image-variants.d.mts +6 -6
  466. package/esm/http/uploads/generate-image-variants.d.mts.map +1 -1
  467. package/esm/http/uploads/generate-image-variants.mjs +1 -1
  468. package/esm/http/uploads/generate-image-variants.mjs.map +1 -1
  469. package/esm/http/uploads/image-variant-cache-entries.mjs +1 -1
  470. package/esm/http/uploads/image-variant-cache.mjs +8 -8
  471. package/esm/http/uploads/image-variant-cache.mjs.map +1 -1
  472. package/esm/http/uploads/image-variant-types.d.mts +7 -9
  473. package/esm/http/uploads/image-variant-types.d.mts.map +1 -1
  474. package/esm/http/uploads/image-variants-config-error.d.mts +1 -2
  475. package/esm/http/uploads/image-variants-config-error.d.mts.map +1 -1
  476. package/esm/http/uploads/index.d.mts +2 -1
  477. package/esm/http/uploads/index.mjs +1 -1
  478. package/esm/http/uploads/parse-uploaded-file-query.mjs +1 -1
  479. package/esm/http/uploads/parse-uploaded-file-query.mjs.map +1 -1
  480. package/esm/http/uploads/purge-image-variants.d.mts +2 -4
  481. package/esm/http/uploads/purge-image-variants.d.mts.map +1 -1
  482. package/esm/http/uploads/resolve-image-variant.d.mts +3 -5
  483. package/esm/http/uploads/resolve-image-variant.d.mts.map +1 -1
  484. package/esm/http/uploads/resolve-image-variants-config.mjs +4 -4
  485. package/esm/http/uploads/resolve-image-variants-config.mjs.map +1 -1
  486. package/esm/http/uploads/resolve-original-content-type.mjs +1 -1
  487. package/esm/http/uploads/resolve-original-content-type.mjs.map +1 -1
  488. package/esm/http/uploads/trim-image-variant-cache.mjs +3 -3
  489. package/esm/http/uploads/trim-image-variant-cache.mjs.map +1 -1
  490. package/esm/http/uploads/uploaded-file.controller.d.mts +6 -5
  491. package/esm/http/uploads/uploaded-file.controller.d.mts.map +1 -1
  492. package/esm/http/uploads/uploaded-file.controller.mjs +2 -1
  493. package/esm/http/uploads/uploaded-file.controller.mjs.map +1 -1
  494. package/esm/http/uploads/variant-cache-key.mjs +1 -1
  495. package/esm/http/uploads-config.d.mts +2 -4
  496. package/esm/http/uploads-config.d.mts.map +1 -1
  497. package/esm/http/uploads-types.d.mts +19 -17
  498. package/esm/http/uploads-types.d.mts.map +1 -1
  499. package/esm/http/xmlable.d.mts +1 -2
  500. package/esm/http/xmlable.d.mts.map +1 -1
  501. package/esm/image/image.d.mts +6 -7
  502. package/esm/image/image.d.mts.map +1 -1
  503. package/esm/image/image.mjs.map +1 -1
  504. package/esm/image/index.d.mts +2 -1
  505. package/esm/image/index.mjs +1 -1
  506. package/esm/index.d.mts +21 -0
  507. package/esm/loader/app-module-importer.d.mts +1 -2
  508. package/esm/loader/app-module-importer.d.mts.map +1 -1
  509. package/esm/localization/index.mjs +1 -1
  510. package/esm/localization/parse-locale-dictionary.d.mts +4 -5
  511. package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
  512. package/esm/localization/parse-locale-dictionary.mjs +1 -1
  513. package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
  514. package/esm/localization/register-locale-dictionary.d.mts +3 -4
  515. package/esm/localization/register-locale-dictionary.d.mts.map +1 -1
  516. package/esm/localization/register-locale-dictionary.mjs +2 -2
  517. package/esm/localization/register-locale-dictionary.mjs.map +1 -1
  518. package/esm/logger/fatal-visibility.d.mts +1 -2
  519. package/esm/logger/fatal-visibility.d.mts.map +1 -1
  520. package/esm/logger/index.d.mts +2 -1
  521. package/esm/logger/index.mjs +1 -1
  522. package/esm/logger/logger.d.mts +1 -3
  523. package/esm/logger/logger.d.mts.map +1 -1
  524. package/esm/logger/types.d.mts +2 -3
  525. package/esm/logger/types.d.mts.map +1 -1
  526. package/esm/mail/config.d.mts +12 -14
  527. package/esm/mail/config.d.mts.map +1 -1
  528. package/esm/mail/events.d.mts +4 -6
  529. package/esm/mail/events.d.mts.map +1 -1
  530. package/esm/mail/index.d.mts +2 -1
  531. package/esm/mail/index.mjs +1 -1
  532. package/esm/mail/mail.d.mts +1 -3
  533. package/esm/mail/mail.d.mts.map +1 -1
  534. package/esm/mail/mailer-pool.d.mts +5 -7
  535. package/esm/mail/mailer-pool.d.mts.map +1 -1
  536. package/esm/mail/react-mail.d.mts +1 -3
  537. package/esm/mail/react-mail.d.mts.map +1 -1
  538. package/esm/mail/send-mail.d.mts +1 -3
  539. package/esm/mail/send-mail.d.mts.map +1 -1
  540. package/esm/mail/send-mail.mjs +2 -1
  541. package/esm/mail/send-mail.mjs.map +1 -1
  542. package/esm/mail/test-mailbox.d.mts +11 -13
  543. package/esm/mail/test-mailbox.d.mts.map +1 -1
  544. package/esm/mail/types.d.mts +17 -18
  545. package/esm/mail/types.d.mts.map +1 -1
  546. package/esm/manifest/manifest-manager.mjs +1 -1
  547. package/esm/openapi/build-openapi-document.d.mts +2 -4
  548. package/esm/openapi/build-openapi-document.d.mts.map +1 -1
  549. package/esm/openapi/cast-schema.mjs +1 -1
  550. package/esm/openapi/development-openapi-provider.d.mts +5 -6
  551. package/esm/openapi/development-openapi-provider.d.mts.map +1 -1
  552. package/esm/openapi/index.d.mts +3 -1
  553. package/esm/openapi/index.mjs +1 -1
  554. package/esm/openapi/openapi-child-output.mjs +2 -2
  555. package/esm/openapi/openapi-child-output.mjs.map +1 -1
  556. package/esm/openapi/postman/build-request-url.mjs +1 -1
  557. package/esm/openapi/postman/example-from-schema.d.mts +1 -3
  558. package/esm/openapi/postman/example-from-schema.d.mts.map +1 -1
  559. package/esm/openapi/postman/index.d.mts +2 -1
  560. package/esm/openapi/postman/openapi-to-postman-collection.d.mts +3 -5
  561. package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -1
  562. package/esm/openapi/postman/postman-types.d.mts +19 -18
  563. package/esm/openapi/postman/postman-types.d.mts.map +1 -1
  564. package/esm/openapi/postman/schema-refs.d.mts +1 -3
  565. package/esm/openapi/postman/schema-refs.d.mts.map +1 -1
  566. package/esm/openapi/postman/uuid-v5.mjs +1 -1
  567. package/esm/openapi/schema-registry.d.mts +1 -1
  568. package/esm/openapi/security.mjs +1 -1
  569. package/esm/openapi/types.d.mts +23 -21
  570. package/esm/openapi/types.d.mts.map +1 -1
  571. package/esm/production/assert-generated-imports.mjs +1 -1
  572. package/esm/production/build-contributions.mjs +1 -1
  573. package/esm/production/bundle-framework-dependencies.mjs +1 -1
  574. package/esm/production/dist-build-manifest.mjs +1 -1
  575. package/esm/production/esbuild-plugins.mjs.map +1 -1
  576. package/esm/production/esbuild-preflight.mjs +1 -1
  577. package/esm/production/production-builder.mjs +2 -1
  578. package/esm/production/production-builder.mjs.map +1 -1
  579. package/esm/production/production-supervisor.mjs +1 -1
  580. package/esm/production/registration-child-runner.mjs +4 -3
  581. package/esm/production/registration-child-runner.mjs.map +1 -1
  582. package/esm/production/resolve-build-config.d.mts +4 -4
  583. package/esm/production/resolve-build-config.d.mts.map +1 -1
  584. package/esm/production/resolve-build-config.mjs +1 -1
  585. package/esm/production/route-registration-child.d.mts +1 -1
  586. package/esm/production/route-registration-child.mjs +8 -7
  587. package/esm/production/route-registration-child.mjs.map +1 -1
  588. package/esm/production/tsconfig-path-aliases.mjs +1 -1
  589. package/esm/react/index.d.mts +1 -3
  590. package/esm/react/index.d.mts.map +1 -1
  591. package/esm/react/index.mjs.map +1 -1
  592. package/esm/repositories/adapters/cascade/cascade-adapter.d.mts +3 -4
  593. package/esm/repositories/adapters/cascade/cascade-adapter.d.mts.map +1 -1
  594. package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts +2 -3
  595. package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts.map +1 -1
  596. package/esm/repositories/adapters/cascade/filter-applicator.mjs +10 -9
  597. package/esm/repositories/adapters/cascade/filter-applicator.mjs.map +1 -1
  598. package/esm/repositories/adapters/cascade/index.d.mts +2 -1
  599. package/esm/repositories/adapters/cascade/index.mjs +1 -1
  600. package/esm/repositories/contracts/index.d.mts +2 -1
  601. package/esm/repositories/contracts/query-builder.contract.d.mts +4 -6
  602. package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
  603. package/esm/repositories/contracts/repository-adapter.contract.d.mts +1 -3
  604. package/esm/repositories/contracts/repository-adapter.contract.d.mts.map +1 -1
  605. package/esm/repositories/contracts/types.d.mts +23 -25
  606. package/esm/repositories/contracts/types.d.mts.map +1 -1
  607. package/esm/repositories/index.d.mts +4 -1
  608. package/esm/repositories/index.mjs +1 -1
  609. package/esm/repositories/repository.manager.d.mts +2 -3
  610. package/esm/repositories/repository.manager.d.mts.map +1 -1
  611. package/esm/repositories/repository.manager.mjs +2 -2
  612. package/esm/repositories/repository.manager.mjs.map +1 -1
  613. package/esm/resource/define-resource.d.mts +3 -5
  614. package/esm/resource/define-resource.d.mts.map +1 -1
  615. package/esm/resource/index.d.mts +2 -1
  616. package/esm/resource/index.mjs +1 -1
  617. package/esm/resource/nullable-resource.d.mts +5 -7
  618. package/esm/resource/nullable-resource.d.mts.map +1 -1
  619. package/esm/resource/register-resource.d.mts +1 -3
  620. package/esm/resource/register-resource.d.mts.map +1 -1
  621. package/esm/resource/resource-field-builder.d.mts +1 -3
  622. package/esm/resource/resource-field-builder.d.mts.map +1 -1
  623. package/esm/resource/resource.d.mts +3 -5
  624. package/esm/resource/resource.d.mts.map +1 -1
  625. package/esm/resource/resource.mjs +4 -2
  626. package/esm/resource/resource.mjs.map +1 -1
  627. package/esm/resource/types.d.mts +21 -21
  628. package/esm/resource/types.d.mts.map +1 -1
  629. package/esm/restful/index.d.mts +2 -1
  630. package/esm/restful/index.mjs +1 -1
  631. package/esm/restful/restful.d.mts +12 -32
  632. package/esm/restful/restful.d.mts.map +1 -1
  633. package/esm/router/index.d.mts +2 -1
  634. package/esm/router/index.mjs +1 -1
  635. package/esm/router/named-api-routes-with-responses.mjs +2 -1
  636. package/esm/router/named-api-routes-with-responses.mjs.map +1 -1
  637. package/esm/router/normalize-request-path.d.mts +1 -2
  638. package/esm/router/normalize-request-path.d.mts.map +1 -1
  639. package/esm/router/normalize-route-path.d.mts +1 -2
  640. package/esm/router/normalize-route-path.d.mts.map +1 -1
  641. package/esm/router/positional-handler-diagnostics.d.mts +15 -13
  642. package/esm/router/positional-handler-diagnostics.d.mts.map +1 -1
  643. package/esm/router/resolve-route-rate-limit.mjs +3 -3
  644. package/esm/router/resolve-route-rate-limit.mjs.map +1 -1
  645. package/esm/router/route-builder.d.mts +1 -3
  646. package/esm/router/route-builder.d.mts.map +1 -1
  647. package/esm/router/route-guard-names.mjs +1 -1
  648. package/esm/router/route-guard-names.mjs.map +1 -1
  649. package/esm/router/route-name-method-suffix.d.mts +2 -3
  650. package/esm/router/route-name-method-suffix.d.mts.map +1 -1
  651. package/esm/router/route-name-taken-error.d.mts +1 -3
  652. package/esm/router/route-name-taken-error.d.mts.map +1 -1
  653. package/esm/router/route-registry.d.mts +1 -3
  654. package/esm/router/route-registry.d.mts.map +1 -1
  655. package/esm/router/router.d.mts +2 -4
  656. package/esm/router/router.d.mts.map +1 -1
  657. package/esm/router/router.mjs +8 -6
  658. package/esm/router/router.mjs.map +1 -1
  659. package/esm/router/types.d.mts +25 -26
  660. package/esm/router/types.d.mts.map +1 -1
  661. package/esm/router/unguarded-route-diagnostics.d.mts +6 -8
  662. package/esm/router/unguarded-route-diagnostics.d.mts.map +1 -1
  663. package/esm/socket/index.d.mts +2 -1
  664. package/esm/socket/index.mjs +1 -1
  665. package/esm/socket/types.d.mts +2 -4
  666. package/esm/socket/types.d.mts.map +1 -1
  667. package/esm/socket/utils.d.mts +1 -3
  668. package/esm/socket/utils.d.mts.map +1 -1
  669. package/esm/storage/config.d.mts +4 -6
  670. package/esm/storage/config.d.mts.map +1 -1
  671. package/esm/storage/context/storage-driver-context.d.mts +3 -4
  672. package/esm/storage/context/storage-driver-context.d.mts.map +1 -1
  673. package/esm/storage/drivers/cloud-driver.d.mts +2 -4
  674. package/esm/storage/drivers/cloud-driver.d.mts.map +1 -1
  675. package/esm/storage/drivers/cloud-driver.mjs.map +1 -1
  676. package/esm/storage/drivers/do-spaces-driver.d.mts +1 -3
  677. package/esm/storage/drivers/do-spaces-driver.d.mts.map +1 -1
  678. package/esm/storage/drivers/local-driver.d.mts +2 -3
  679. package/esm/storage/drivers/local-driver.d.mts.map +1 -1
  680. package/esm/storage/drivers/local-driver.mjs +8 -3
  681. package/esm/storage/drivers/local-driver.mjs.map +1 -1
  682. package/esm/storage/drivers/r2-driver.d.mts +1 -3
  683. package/esm/storage/drivers/r2-driver.d.mts.map +1 -1
  684. package/esm/storage/drivers/s3-driver.d.mts +1 -3
  685. package/esm/storage/drivers/s3-driver.d.mts.map +1 -1
  686. package/esm/storage/index.d.mts +2 -1
  687. package/esm/storage/index.mjs +1 -1
  688. package/esm/storage/local-disk-roots.mjs +2 -2
  689. package/esm/storage/local-disk-roots.mjs.map +1 -1
  690. package/esm/storage/scoped-storage.d.mts +2 -3
  691. package/esm/storage/scoped-storage.d.mts.map +1 -1
  692. package/esm/storage/storage-file.d.mts +1 -3
  693. package/esm/storage/storage-file.d.mts.map +1 -1
  694. package/esm/storage/storage.d.mts +3 -4
  695. package/esm/storage/storage.d.mts.map +1 -1
  696. package/esm/storage/types.d.mts +36 -36
  697. package/esm/storage/types.d.mts.map +1 -1
  698. package/esm/storage/utils/classify-ip-address.d.mts +1 -2
  699. package/esm/storage/utils/classify-ip-address.d.mts.map +1 -1
  700. package/esm/storage/utils/contain-path.d.mts +1 -2
  701. package/esm/storage/utils/contain-path.d.mts.map +1 -1
  702. package/esm/storage/utils/mime.d.mts +2 -3
  703. package/esm/storage/utils/mime.d.mts.map +1 -1
  704. package/esm/storage/utils/safe-fetch.d.mts +6 -6
  705. package/esm/storage/utils/safe-fetch.d.mts.map +1 -1
  706. package/esm/storage/utils/safe-fetch.mjs +3 -3
  707. package/esm/storage/utils/safe-fetch.mjs.map +1 -1
  708. package/esm/storage/utils/storage-capability-error.d.mts +1 -3
  709. package/esm/storage/utils/storage-capability-error.d.mts.map +1 -1
  710. package/esm/storage/utils/storage-error.d.mts +2 -3
  711. package/esm/storage/utils/storage-error.d.mts.map +1 -1
  712. package/esm/storage/utils/storage-not-initialized-error.d.mts +1 -2
  713. package/esm/storage/utils/storage-not-initialized-error.d.mts.map +1 -1
  714. package/esm/tests/authenticated-test-client.d.mts +5 -6
  715. package/esm/tests/authenticated-test-client.d.mts.map +1 -1
  716. package/esm/tests/factories.d.mts +38 -23
  717. package/esm/tests/factories.d.mts.map +1 -1
  718. package/esm/tests/fakes/cache-fake.d.mts +14 -9
  719. package/esm/tests/fakes/cache-fake.d.mts.map +1 -1
  720. package/esm/tests/fakes/clock-fake.d.mts +13 -8
  721. package/esm/tests/fakes/clock-fake.d.mts.map +1 -1
  722. package/esm/tests/fakes/fake-assertion-error.d.mts +2 -3
  723. package/esm/tests/fakes/fake-assertion-error.d.mts.map +1 -1
  724. package/esm/tests/fakes/ids-fake.d.mts +5 -4
  725. package/esm/tests/fakes/ids-fake.d.mts.map +1 -1
  726. package/esm/tests/fakes/index.d.mts +2 -1
  727. package/esm/tests/fakes/index.mjs +1 -1
  728. package/esm/tests/fakes/mail-fake.d.mts +21 -13
  729. package/esm/tests/fakes/mail-fake.d.mts.map +1 -1
  730. package/esm/tests/fakes/queue-fake.d.mts +21 -13
  731. package/esm/tests/fakes/queue-fake.d.mts.map +1 -1
  732. package/esm/tests/fakes/storage-fake.d.mts +12 -8
  733. package/esm/tests/fakes/storage-fake.d.mts.map +1 -1
  734. package/esm/tests/fakes/storage-fake.mjs +1 -1
  735. package/esm/tests/fakes/test-fakes.d.mts +8 -9
  736. package/esm/tests/fakes/test-fakes.d.mts.map +1 -1
  737. package/esm/tests/fakes/test-fakes.mjs +1 -1
  738. package/esm/tests/fakes/test-fakes.mjs.map +1 -1
  739. package/esm/tests/index.d.mts +1 -0
  740. package/esm/tests/snapshot-response.d.mts +4 -5
  741. package/esm/tests/snapshot-response.d.mts.map +1 -1
  742. package/esm/tests/start-http-development-server.d.mts +4 -6
  743. package/esm/tests/start-http-development-server.d.mts.map +1 -1
  744. package/esm/tests/start-http-development-server.mjs +5 -5
  745. package/esm/tests/start-http-development-server.mjs.map +1 -1
  746. package/esm/tests/test-connectors-selection.d.mts +2 -2
  747. package/esm/tests/test-connectors-selection.d.mts.map +1 -1
  748. package/esm/tests/test-connectors-selection.mjs +1 -1
  749. package/esm/tests/test-helpers.d.mts +11 -12
  750. package/esm/tests/test-helpers.d.mts.map +1 -1
  751. package/esm/tests/test-http-server.d.mts +14 -10
  752. package/esm/tests/test-http-server.d.mts.map +1 -1
  753. package/esm/tests/test-lifecycle-state.mjs +1 -1
  754. package/esm/tests/vitest-setup.d.mts +6 -7
  755. package/esm/tests/vitest-setup.d.mts.map +1 -1
  756. package/esm/tooling/agents-md/agents-md-markers.d.mts +4 -5
  757. package/esm/tooling/agents-md/agents-md-markers.d.mts.map +1 -1
  758. package/esm/tooling/agents-md/agents-md-markers.mjs +2 -1
  759. package/esm/tooling/agents-md/agents-md-markers.mjs.map +1 -1
  760. package/esm/tooling/agents-md/agents-md-refresher.d.mts +19 -12
  761. package/esm/tooling/agents-md/agents-md-refresher.d.mts.map +1 -1
  762. package/esm/tooling/agents-md/installed-skills.d.mts +13 -9
  763. package/esm/tooling/agents-md/installed-skills.d.mts.map +1 -1
  764. package/esm/tooling/agents-md/render-agents-md.d.mts +8 -7
  765. package/esm/tooling/agents-md/render-agents-md.d.mts.map +1 -1
  766. package/esm/tooling/agents-md/render-agents-md.mjs +2 -2
  767. package/esm/tooling/agents-md/render-agents-md.mjs.map +1 -1
  768. package/esm/tooling/agents-md/write-agents-md.d.mts +17 -12
  769. package/esm/tooling/agents-md/write-agents-md.d.mts.map +1 -1
  770. package/esm/tooling/board/board-message.d.mts +4 -6
  771. package/esm/tooling/board/board-message.d.mts.map +1 -1
  772. package/esm/tooling/board/board.d.mts +50 -38
  773. package/esm/tooling/board/board.d.mts.map +1 -1
  774. package/esm/tooling/board/board.mjs +4 -3
  775. package/esm/tooling/board/board.mjs.map +1 -1
  776. package/esm/tooling/board/board.types.d.mts +32 -23
  777. package/esm/tooling/board/board.types.d.mts.map +1 -1
  778. package/esm/tooling/check/changed-files.d.mts +4 -6
  779. package/esm/tooling/check/changed-files.d.mts.map +1 -1
  780. package/esm/tooling/check/changed-files.mjs +2 -2
  781. package/esm/tooling/check/changed-files.mjs.map +1 -1
  782. package/esm/tooling/check/check-report.types.d.mts +22 -17
  783. package/esm/tooling/check/check-report.types.d.mts.map +1 -1
  784. package/esm/tooling/check/code-style-conventions.mjs +25 -25
  785. package/esm/tooling/check/code-style-conventions.mjs.map +1 -1
  786. package/esm/tooling/check/conventions-step.d.mts +4 -6
  787. package/esm/tooling/check/conventions-step.d.mts.map +1 -1
  788. package/esm/tooling/check/conventions-step.mjs +7 -18
  789. package/esm/tooling/check/conventions-step.mjs.map +1 -1
  790. package/esm/tooling/check/environment-step.d.mts +2 -4
  791. package/esm/tooling/check/environment-step.d.mts.map +1 -1
  792. package/esm/tooling/check/environment-step.mjs +1 -1
  793. package/esm/tooling/check/index.mjs +1 -1
  794. package/esm/tooling/check/lint-step.d.mts +4 -5
  795. package/esm/tooling/check/lint-step.d.mts.map +1 -1
  796. package/esm/tooling/check/lint-step.mjs +2 -1
  797. package/esm/tooling/check/lint-step.mjs.map +1 -1
  798. package/esm/tooling/check/request-input.mjs +15 -15
  799. package/esm/tooling/check/request-input.mjs.map +1 -1
  800. package/esm/tooling/check/run-check.d.mts +22 -14
  801. package/esm/tooling/check/run-check.d.mts.map +1 -1
  802. package/esm/tooling/check/run-tests.d.mts +22 -15
  803. package/esm/tooling/check/run-tests.d.mts.map +1 -1
  804. package/esm/tooling/check/security-conventions.mjs +133 -131
  805. package/esm/tooling/check/security-conventions.mjs.map +1 -1
  806. package/esm/tooling/check/source-ast.mjs +92 -132
  807. package/esm/tooling/check/source-ast.mjs.map +1 -1
  808. package/esm/tooling/check/tests-step.d.mts +7 -8
  809. package/esm/tooling/check/tests-step.d.mts.map +1 -1
  810. package/esm/tooling/check/tests-step.mjs +3 -3
  811. package/esm/tooling/check/tests-step.mjs.map +1 -1
  812. package/esm/tooling/dev-state/dev-server-state.d.mts +17 -13
  813. package/esm/tooling/dev-state/dev-server-state.d.mts.map +1 -1
  814. package/esm/tooling/devtools/devtools-client.d.mts +29 -20
  815. package/esm/tooling/devtools/devtools-client.d.mts.map +1 -1
  816. package/esm/tooling/generate/generation.d.mts +34 -22
  817. package/esm/tooling/generate/generation.d.mts.map +1 -1
  818. package/esm/tooling/generate/generation.mjs +9 -5
  819. package/esm/tooling/generate/generation.mjs.map +1 -1
  820. package/esm/tooling/generate/generator-spec.d.mts +9 -9
  821. package/esm/tooling/generate/generator-spec.d.mts.map +1 -1
  822. package/esm/tooling/generate/index.mjs +1 -1
  823. package/esm/tooling/generate/project-files.mjs +3 -3
  824. package/esm/tooling/generate/project-files.mjs.map +1 -1
  825. package/esm/tooling/generate/run-cli.d.mts +14 -11
  826. package/esm/tooling/generate/run-cli.d.mts.map +1 -1
  827. package/esm/tooling/generate/run-cli.mjs +2 -2
  828. package/esm/tooling/generate/run-cli.mjs.map +1 -1
  829. package/esm/tooling/generate/unified-diff.d.mts +10 -7
  830. package/esm/tooling/generate/unified-diff.d.mts.map +1 -1
  831. package/esm/tooling/index.d.mts +1 -0
  832. package/esm/tooling/inspect/boot-for-inspect.d.mts +7 -7
  833. package/esm/tooling/inspect/boot-for-inspect.d.mts.map +1 -1
  834. package/esm/tooling/inspect/collect-config.mjs +3 -3
  835. package/esm/tooling/inspect/collect-config.mjs.map +1 -1
  836. package/esm/tooling/inspect/collect-models.d.mts +4 -3
  837. package/esm/tooling/inspect/collect-models.d.mts.map +1 -1
  838. package/esm/tooling/inspect/collect-models.mjs +1 -1
  839. package/esm/tooling/inspect/collect-packages.d.mts +1 -2
  840. package/esm/tooling/inspect/collect-packages.d.mts.map +1 -1
  841. package/esm/tooling/inspect/collect-pages.mjs +10 -10
  842. package/esm/tooling/inspect/collect-pages.mjs.map +1 -1
  843. package/esm/tooling/inspect/collect-routes.mjs +1 -1
  844. package/esm/tooling/inspect/event-recorder.d.mts +7 -7
  845. package/esm/tooling/inspect/event-recorder.d.mts.map +1 -1
  846. package/esm/tooling/inspect/index.d.mts +2 -1
  847. package/esm/tooling/inspect/index.mjs +1 -1
  848. package/esm/tooling/inspect/inspect-app.d.mts +25 -16
  849. package/esm/tooling/inspect/inspect-app.d.mts.map +1 -1
  850. package/esm/tooling/inspect/inspect-report.schema.d.mts +1 -2
  851. package/esm/tooling/inspect/inspect-report.schema.d.mts.map +1 -1
  852. package/esm/tooling/inspect/inspect-report.types.d.mts +86 -54
  853. package/esm/tooling/inspect/inspect-report.types.d.mts.map +1 -1
  854. package/esm/tooling/mcp/create-mcp-context.d.mts +11 -8
  855. package/esm/tooling/mcp/create-mcp-context.d.mts.map +1 -1
  856. package/esm/tooling/mcp/db-schema.d.mts +10 -9
  857. package/esm/tooling/mcp/db-schema.d.mts.map +1 -1
  858. package/esm/tooling/mcp/docs-search.d.mts +20 -15
  859. package/esm/tooling/mcp/docs-search.d.mts.map +1 -1
  860. package/esm/tooling/mcp/index.mjs +1 -1
  861. package/esm/tooling/mcp/load-ai-tools.d.mts +7 -8
  862. package/esm/tooling/mcp/load-ai-tools.d.mts.map +1 -1
  863. package/esm/tooling/mcp/load-ai-tools.mjs +2 -1
  864. package/esm/tooling/mcp/load-ai-tools.mjs.map +1 -1
  865. package/esm/tooling/mcp/mcp-tools.d.mts +29 -19
  866. package/esm/tooling/mcp/mcp-tools.d.mts.map +1 -1
  867. package/esm/tooling/mcp/mcp-tools.mjs +3 -2
  868. package/esm/tooling/mcp/mcp-tools.mjs.map +1 -1
  869. package/esm/tooling/mcp/start-mcp-server.d.mts +24 -17
  870. package/esm/tooling/mcp/start-mcp-server.d.mts.map +1 -1
  871. package/esm/tooling/mcp/start-mcp-server.mjs +1 -1
  872. package/esm/tooling/mcp/start-mcp-server.mjs.map +1 -1
  873. package/esm/tooling/mcp/tool-input.d.mts +7 -7
  874. package/esm/tooling/mcp/tool-input.d.mts.map +1 -1
  875. package/esm/tooling/problem.d.mts +27 -17
  876. package/esm/tooling/problem.d.mts.map +1 -1
  877. package/esm/tooling/syntax/ast.mjs +230 -0
  878. package/esm/tooling/syntax/ast.mjs.map +1 -0
  879. package/esm/tooling/syntax/imports.mjs +34 -0
  880. package/esm/tooling/syntax/imports.mjs.map +1 -0
  881. package/esm/tooling/trace/trace-report.types.d.mts +36 -22
  882. package/esm/tooling/trace/trace-report.types.d.mts.map +1 -1
  883. package/esm/tooling/trace/trace-request.d.mts +27 -20
  884. package/esm/tooling/trace/trace-request.d.mts.map +1 -1
  885. package/esm/tooling/trace/trace-request.mjs +2 -2
  886. package/esm/tooling/trace/trace-request.mjs.map +1 -1
  887. package/esm/tooling/typecheck/index.mjs +1 -1
  888. package/esm/tooling/typecheck/run-typecheck.d.mts +15 -48
  889. package/esm/tooling/typecheck/run-typecheck.d.mts.map +1 -1
  890. package/esm/tooling/typecheck/run-typecheck.mjs +42 -105
  891. package/esm/tooling/typecheck/run-typecheck.mjs.map +1 -1
  892. package/esm/tooling/typescript/compiler.d.mts +31 -0
  893. package/esm/tooling/typescript/compiler.d.mts.map +1 -0
  894. package/esm/tooling/typescript/compiler.mjs +120 -0
  895. package/esm/tooling/typescript/compiler.mjs.map +1 -0
  896. package/esm/updater/update-warlock-packages.mjs +3 -2
  897. package/esm/updater/update-warlock-packages.mjs.map +1 -1
  898. package/esm/upgrade/codemods/index.mjs +1 -1
  899. package/esm/upgrade/codemods/logger-sync-calls.mjs +1 -1
  900. package/esm/upgrade/codemods/logger-sync-calls.mjs.map +1 -1
  901. package/esm/upgrade/codemods/request-log-snapshot.mjs +1 -1
  902. package/esm/upgrade/codemods/request-log-snapshot.mjs.map +1 -1
  903. package/esm/upgrade/diff.mjs +1 -1
  904. package/esm/upgrade/diff.mjs.map +1 -1
  905. package/esm/upgrade/load-ts-morph.mjs +3 -2
  906. package/esm/upgrade/load-ts-morph.mjs.map +1 -1
  907. package/esm/upgrade/run-upgrade.mjs +1 -1
  908. package/esm/use-cases/index.d.mts +2 -1
  909. package/esm/use-cases/index.mjs +1 -1
  910. package/esm/use-cases/types.d.mts +116 -63
  911. package/esm/use-cases/types.d.mts.map +1 -1
  912. package/esm/use-cases/use-case-broadcast.d.mts +1 -3
  913. package/esm/use-cases/use-case-broadcast.d.mts.map +1 -1
  914. package/esm/use-cases/use-case-events.d.mts +3 -5
  915. package/esm/use-cases/use-case-events.d.mts.map +1 -1
  916. package/esm/use-cases/use-case-pipeline.d.mts +6 -6
  917. package/esm/use-cases/use-case-pipeline.d.mts.map +1 -1
  918. package/esm/use-cases/use-case.d.mts +2 -4
  919. package/esm/use-cases/use-case.d.mts.map +1 -1
  920. package/esm/use-cases/use-case.errors.d.mts +1 -3
  921. package/esm/use-cases/use-case.errors.d.mts.map +1 -1
  922. package/esm/use-cases/use-cases-registry.d.mts +8 -10
  923. package/esm/use-cases/use-cases-registry.d.mts.map +1 -1
  924. package/esm/utils/app-log.d.mts +1 -2
  925. package/esm/utils/app-log.d.mts.map +1 -1
  926. package/esm/utils/clock.d.mts +8 -6
  927. package/esm/utils/clock.d.mts.map +1 -1
  928. package/esm/utils/database-log.d.mts +3 -4
  929. package/esm/utils/database-log.d.mts.map +1 -1
  930. package/esm/utils/environment.d.mts +4 -5
  931. package/esm/utils/environment.d.mts.map +1 -1
  932. package/esm/utils/framework-vesion.mjs.map +1 -1
  933. package/esm/utils/get-localized.d.mts +2 -3
  934. package/esm/utils/get-localized.d.mts.map +1 -1
  935. package/esm/utils/ids.d.mts +9 -6
  936. package/esm/utils/ids.d.mts.map +1 -1
  937. package/esm/utils/index.d.mts +2 -1
  938. package/esm/utils/index.mjs +1 -1
  939. package/esm/utils/normalized-path.d.mts +1 -2
  940. package/esm/utils/normalized-path.d.mts.map +1 -1
  941. package/esm/utils/npm-registry.d.mts +1 -2
  942. package/esm/utils/npm-registry.d.mts.map +1 -1
  943. package/esm/utils/paths.d.mts +13 -14
  944. package/esm/utils/paths.d.mts.map +1 -1
  945. package/esm/utils/paths.mjs +2 -2
  946. package/esm/utils/paths.mjs.map +1 -1
  947. package/esm/utils/promise-all-object.d.mts +1 -2
  948. package/esm/utils/promise-all-object.d.mts.map +1 -1
  949. package/esm/utils/queue.d.mts +1 -2
  950. package/esm/utils/queue.d.mts.map +1 -1
  951. package/esm/utils/runtime.d.mts +11 -10
  952. package/esm/utils/runtime.d.mts.map +1 -1
  953. package/esm/utils/sleep.d.mts +1 -2
  954. package/esm/utils/sleep.d.mts.map +1 -1
  955. package/esm/utils/sluggable.d.mts +1 -3
  956. package/esm/utils/sluggable.d.mts.map +1 -1
  957. package/esm/utils/to-json.d.mts +1 -2
  958. package/esm/utils/to-json.d.mts.map +1 -1
  959. package/esm/utils/types.d.mts +1 -2
  960. package/esm/utils/types.d.mts.map +1 -1
  961. package/esm/utils/urls.d.mts +5 -6
  962. package/esm/utils/urls.d.mts.map +1 -1
  963. package/esm/utils/version-compare.d.mts +1 -2
  964. package/esm/utils/version-compare.d.mts.map +1 -1
  965. package/esm/validation/database/exists-except-current-id.d.mts +2 -3
  966. package/esm/validation/database/exists-except-current-id.d.mts.map +1 -1
  967. package/esm/validation/database/exists-except-current-user.d.mts +2 -3
  968. package/esm/validation/database/exists-except-current-user.d.mts.map +1 -1
  969. package/esm/validation/database/index.d.mts +2 -1
  970. package/esm/validation/database/index.mjs +1 -1
  971. package/esm/validation/database/types.d.mts +14 -10
  972. package/esm/validation/database/types.d.mts.map +1 -1
  973. package/esm/validation/database/unique-except-current-id.d.mts +2 -3
  974. package/esm/validation/database/unique-except-current-id.d.mts.map +1 -1
  975. package/esm/validation/database/unique-except-current-user.d.mts +2 -3
  976. package/esm/validation/database/unique-except-current-user.d.mts.map +1 -1
  977. package/esm/validation/file/file.d.mts +4 -6
  978. package/esm/validation/file/file.d.mts.map +1 -1
  979. package/esm/validation/file/index.d.mts +2 -1
  980. package/esm/validation/file/index.mjs +1 -1
  981. package/esm/validation/index.d.mts +5 -1
  982. package/esm/validation/index.mjs +1 -1
  983. package/esm/validation/plugins/index.mjs +1 -1
  984. package/esm/validation/types.d.mts +6 -4
  985. package/esm/validation/types.d.mts.map +1 -1
  986. package/esm/validation/validateAll.mjs +2 -2
  987. package/esm/validation/validateAll.mjs.map +1 -1
  988. package/esm/validation/validation-failure-status.mjs +2 -2
  989. package/esm/validation/validation-failure-status.mjs.map +1 -1
  990. package/esm/validation/validators/file-validator.d.mts +2 -4
  991. package/esm/validation/validators/file-validator.d.mts.map +1 -1
  992. package/esm/validation/validators/index.d.mts +2 -1
  993. package/esm/validation/validators/index.mjs +1 -1
  994. package/esm/vite/lower-stage3-decorators.d.mts +2 -3
  995. package/esm/vite/lower-stage3-decorators.d.mts.map +1 -1
  996. package/esm/warlock-config/define-config.d.mts +1 -3
  997. package/esm/warlock-config/define-config.d.mts.map +1 -1
  998. package/esm/warlock-config/define-config.mjs +3 -2
  999. package/esm/warlock-config/define-config.mjs.map +1 -1
  1000. package/esm/warlock-config/index.d.mts +2 -1
  1001. package/esm/warlock-config/index.mjs +1 -1
  1002. package/esm/warlock-config/types.d.mts +6 -5
  1003. package/esm/warlock-config/types.d.mts.map +1 -1
  1004. package/esm/warlock-config/warlock-config.manager.d.mts +5 -7
  1005. package/esm/warlock-config/warlock-config.manager.d.mts.map +1 -1
  1006. package/esm/warlock-config/warlock-config.manager.mjs +2 -1
  1007. package/esm/warlock-config/warlock-config.manager.mjs.map +1 -1
  1008. package/esm/warlock-config/warn-deprecated-config.mjs +1 -1
  1009. package/llms-full.txt +55 -5
  1010. package/package.json +17 -15
  1011. package/skills/create-module/SKILL.md +7 -0
  1012. package/skills/index.md +2 -0
  1013. package/skills/report-framework-issue.md +154 -0
  1014. package/skills/run-app/SKILL.md +6 -5
  1015. package/skills/upgrade-from-5-29/SKILL.md +41 -0
  1016. package/skills/warlock-check/SKILL.md +1 -0
  1017. package/esm/tooling/check/index.d.mts +0 -8
  1018. package/esm/tooling/typecheck/index.d.mts +0 -1
@@ -33,7 +33,9 @@ async function generateResource(data) {
33
33
  process.exit(1);
34
34
  }
35
35
  await ensureComponentDirectory(module, "resources");
36
- await putFileAsync(resolveComponentPath(module, "resources", `${name.kebab}.resource`), resourceStub(name));
36
+ const resourcePath = resolveComponentPath(module, "resources", `${name.kebab}.resource`);
37
+ const resourceContent = resourceStub(name);
38
+ await putFileAsync(resourcePath, resourceContent);
37
39
  console.log(colors.cyan(`\nResource "${name.pascal}Resource" generated successfully!`));
38
40
  }
39
41
 
@@ -1 +1 @@
1
- {"version":3,"file":"resource.generator.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/resource.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport { resourceStub } from \"../templates/stubs\";\nimport { putFileAsync, setDryRun } from \"../utils/writer\";\nimport { parseModulePath, parseName } from \"../utils/name-parser\";\nimport {\n componentExists,\n ensureComponentDirectory,\n moduleExists,\n resolveComponentPath,\n} from \"../utils/path-resolver\";\n\nexport async function generateResource(data: CommandActionData): Promise<void> {\n const input = data.args[0];\n\n if (!input) {\n console.log(colors.red(\"Error: Resource name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.resource <module>/<name>\"));\n console.log(colors.yellow(\"Example: warlock generate.resource users/user\"));\n process.exit(1);\n }\n\n const { module, name: componentName } = parseModulePath(input);\n\n if (!module) {\n console.log(colors.red(\"Error: Module name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.resource <module>/<name>\"));\n process.exit(1);\n }\n\n // Check if module exists\n if (!(await moduleExists(module))) {\n console.log(colors.red(`Error: Module \"${module}\" does not exist`));\n console.log(colors.yellow(`Run: warlock generate.module ${module}`));\n process.exit(1);\n }\n\n const name = parseName(componentName);\n const force = data.options.force || data.options.f;\n setDryRun(Boolean(data.options.dryRun));\n\n // Check if resource already exists\n if ((await componentExists(module, \"resources\", `${name.kebab}.resource`)) && !force) {\n console.log(colors.red(`Error: Resource \"${name.kebab}.resource.ts\" already exists`));\n console.log(colors.yellow(\"Use --force to overwrite\"));\n process.exit(1);\n }\n\n // Ensure directories exist\n await ensureComponentDirectory(module, \"resources\");\n\n // Generate resource\n const resourcePath = resolveComponentPath(module, \"resources\", `${name.kebab}.resource`);\n const resourceContent = resourceStub(name);\n\n await putFileAsync(resourcePath, resourceContent);\n\n console.log(colors.cyan(`\\nResource \"${name.pascal}Resource\" generated successfully!`));\n}\n"],"mappings":";;;;;;;AAYA,eAAsB,iBAAiB,MAAwC;CAC7E,MAAM,QAAQ,KAAK,KAAK;CAExB,IAAI,CAAC,OAAO;EACV,QAAQ,IAAI,OAAO,IAAI,kCAAkC,CAAC;EAC1D,QAAQ,IAAI,OAAO,OAAO,kDAAkD,CAAC;EAC7E,QAAQ,IAAI,OAAO,OAAO,+CAA+C,CAAC;EAC1E,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,EAAE,QAAQ,MAAM,kBAAkB,gBAAgB,KAAK;CAE7D,IAAI,CAAC,QAAQ;EACX,QAAQ,IAAI,OAAO,IAAI,gCAAgC,CAAC;EACxD,QAAQ,IAAI,OAAO,OAAO,kDAAkD,CAAC;EAC7E,QAAQ,KAAK,CAAC;CAChB;CAGA,IAAI,CAAE,MAAM,aAAa,MAAM,GAAI;EACjC,QAAQ,IAAI,OAAO,IAAI,kBAAkB,OAAO,iBAAiB,CAAC;EAClE,QAAQ,IAAI,OAAO,OAAO,gCAAgC,QAAQ,CAAC;EACnE,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,OAAO,UAAU,aAAa;CACpC,MAAM,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ;CACjD,UAAU,QAAQ,KAAK,QAAQ,MAAM,CAAC;CAGtC,IAAK,MAAM,gBAAgB,QAAQ,aAAa,GAAG,KAAK,MAAM,UAAU,KAAM,CAAC,OAAO;EACpF,QAAQ,IAAI,OAAO,IAAI,oBAAoB,KAAK,MAAM,6BAA6B,CAAC;EACpF,QAAQ,IAAI,OAAO,OAAO,0BAA0B,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,yBAAyB,QAAQ,WAAW;CAMlD,MAAM,aAHe,qBAAqB,QAAQ,aAAa,GAAG,KAAK,MAAM,UAG/C,GAFN,aAAa,IAEU,CAAC;CAEhD,QAAQ,IAAI,OAAO,KAAK,eAAe,KAAK,OAAO,kCAAkC,CAAC;AACxF"}
1
+ {"version":3,"file":"resource.generator.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/resource.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport { resourceStub } from \"../templates/stubs\";\nimport { putFileAsync, setDryRun } from \"../utils/writer\";\nimport { parseModulePath, parseName } from \"../utils/name-parser\";\nimport {\n componentExists,\n ensureComponentDirectory,\n moduleExists,\n resolveComponentPath,\n} from \"../utils/path-resolver\";\n\nexport async function generateResource(data: CommandActionData): Promise<void> {\n const input = data.args[0];\n\n if (!input) {\n console.log(colors.red(\"Error: Resource name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.resource <module>/<name>\"));\n console.log(colors.yellow(\"Example: warlock generate.resource users/user\"));\n process.exit(1);\n }\n\n const { module, name: componentName } = parseModulePath(input);\n\n if (!module) {\n console.log(colors.red(\"Error: Module name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.resource <module>/<name>\"));\n process.exit(1);\n }\n\n // Check if module exists\n if (!(await moduleExists(module))) {\n console.log(colors.red(`Error: Module \"${module}\" does not exist`));\n console.log(colors.yellow(`Run: warlock generate.module ${module}`));\n process.exit(1);\n }\n\n const name = parseName(componentName);\n const force = data.options.force || data.options.f;\n setDryRun(Boolean(data.options.dryRun));\n\n // Check if resource already exists\n if ((await componentExists(module, \"resources\", `${name.kebab}.resource`)) && !force) {\n console.log(colors.red(`Error: Resource \"${name.kebab}.resource.ts\" already exists`));\n console.log(colors.yellow(\"Use --force to overwrite\"));\n process.exit(1);\n }\n\n // Ensure directories exist\n await ensureComponentDirectory(module, \"resources\");\n\n // Generate resource\n const resourcePath = resolveComponentPath(module, \"resources\", `${name.kebab}.resource`);\n const resourceContent = resourceStub(name);\n\n await putFileAsync(resourcePath, resourceContent);\n\n console.log(colors.cyan(`\\nResource \"${name.pascal}Resource\" generated successfully!`));\n}\n"],"mappings":";;;;;;;AAYA,eAAsB,iBAAiB,MAAwC;CAC7E,MAAM,QAAQ,KAAK,KAAK;CAExB,IAAI,CAAC,OAAO;EACV,QAAQ,IAAI,OAAO,IAAI,kCAAkC,CAAC;EAC1D,QAAQ,IAAI,OAAO,OAAO,kDAAkD,CAAC;EAC7E,QAAQ,IAAI,OAAO,OAAO,+CAA+C,CAAC;EAC1E,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,EAAE,QAAQ,MAAM,kBAAkB,gBAAgB,KAAK;CAE7D,IAAI,CAAC,QAAQ;EACX,QAAQ,IAAI,OAAO,IAAI,gCAAgC,CAAC;EACxD,QAAQ,IAAI,OAAO,OAAO,kDAAkD,CAAC;EAC7E,QAAQ,KAAK,CAAC;CAChB;CAGA,IAAI,CAAE,MAAM,aAAa,MAAM,GAAI;EACjC,QAAQ,IAAI,OAAO,IAAI,kBAAkB,OAAO,iBAAiB,CAAC;EAClE,QAAQ,IAAI,OAAO,OAAO,gCAAgC,QAAQ,CAAC;EACnE,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,OAAO,UAAU,aAAa;CACpC,MAAM,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ;CACjD,UAAU,QAAQ,KAAK,QAAQ,MAAM,CAAC;CAGtC,IAAK,MAAM,gBAAgB,QAAQ,aAAa,GAAG,KAAK,MAAM,UAAU,KAAM,CAAC,OAAO;EACpF,QAAQ,IAAI,OAAO,IAAI,oBAAoB,KAAK,MAAM,6BAA6B,CAAC;EACpF,QAAQ,IAAI,OAAO,OAAO,0BAA0B,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,yBAAyB,QAAQ,WAAW;CAGlD,MAAM,eAAe,qBAAqB,QAAQ,aAAa,GAAG,KAAK,MAAM,UAAU;CACvF,MAAM,kBAAkB,aAAa,IAAI;CAEzC,MAAM,aAAa,cAAc,eAAe;CAEhD,QAAQ,IAAI,OAAO,KAAK,eAAe,KAAK,OAAO,kCAAkC,CAAC;AACxF"}
@@ -33,7 +33,9 @@ async function generateService(data) {
33
33
  process.exit(1);
34
34
  }
35
35
  await ensureComponentDirectory(module, "services");
36
- await putFileAsync(resolveComponentPath(module, "services", `${name.kebab}.service`), serviceStub(name));
36
+ const servicePath = resolveComponentPath(module, "services", `${name.kebab}.service`);
37
+ const serviceContent = serviceStub(name);
38
+ await putFileAsync(servicePath, serviceContent);
37
39
  console.log(colors.cyan(`\n✨ Service "${name.camel}" generated successfully!`));
38
40
  }
39
41
 
@@ -1 +1 @@
1
- {"version":3,"file":"service.generator.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/service.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport { serviceStub } from \"../templates/stubs\";\nimport { putFileAsync, setDryRun } from \"../utils/writer\";\nimport { parseModulePath, parseName } from \"../utils/name-parser\";\nimport {\n componentExists,\n ensureComponentDirectory,\n moduleExists,\n resolveComponentPath,\n} from \"../utils/path-resolver\";\n\nexport async function generateService(data: CommandActionData): Promise<void> {\n const input = data.args[0];\n\n if (!input) {\n console.log(colors.red(\"Error: Service name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.service <module>/<name>\"));\n console.log(colors.yellow(\"Example: warlock generate.service users/create-user\"));\n process.exit(1);\n }\n\n const { module, name: componentName } = parseModulePath(input);\n\n if (!module) {\n console.log(colors.red(\"Error: Module name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.service <module>/<name>\"));\n process.exit(1);\n }\n\n // Check if module exists\n if (!(await moduleExists(module))) {\n console.log(colors.red(`Error: Module \"${module}\" does not exist`));\n console.log(colors.yellow(`Run: warlock generate.module ${module}`));\n process.exit(1);\n }\n\n const name = parseName(componentName);\n const force = data.options.force || data.options.f;\n setDryRun(Boolean(data.options.dryRun));\n\n // Check if service already exists\n if ((await componentExists(module, \"services\", `${name.kebab}.service`)) && !force) {\n console.log(colors.red(`Error: Service \"${name.kebab}.service.ts\" already exists`));\n console.log(colors.yellow(\"Use --force to overwrite\"));\n process.exit(1);\n }\n\n // Ensure directories exist\n await ensureComponentDirectory(module, \"services\");\n\n // Generate service\n const servicePath = resolveComponentPath(module, \"services\", `${name.kebab}.service`);\n const serviceContent = serviceStub(name);\n\n await putFileAsync(servicePath, serviceContent);\n\n console.log(colors.cyan(`\\n✨ Service \"${name.camel}\" generated successfully!`));\n}\n"],"mappings":";;;;;;;AAYA,eAAsB,gBAAgB,MAAwC;CAC5E,MAAM,QAAQ,KAAK,KAAK;CAExB,IAAI,CAAC,OAAO;EACV,QAAQ,IAAI,OAAO,IAAI,iCAAiC,CAAC;EACzD,QAAQ,IAAI,OAAO,OAAO,iDAAiD,CAAC;EAC5E,QAAQ,IAAI,OAAO,OAAO,qDAAqD,CAAC;EAChF,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,EAAE,QAAQ,MAAM,kBAAkB,gBAAgB,KAAK;CAE7D,IAAI,CAAC,QAAQ;EACX,QAAQ,IAAI,OAAO,IAAI,gCAAgC,CAAC;EACxD,QAAQ,IAAI,OAAO,OAAO,iDAAiD,CAAC;EAC5E,QAAQ,KAAK,CAAC;CAChB;CAGA,IAAI,CAAE,MAAM,aAAa,MAAM,GAAI;EACjC,QAAQ,IAAI,OAAO,IAAI,kBAAkB,OAAO,iBAAiB,CAAC;EAClE,QAAQ,IAAI,OAAO,OAAO,gCAAgC,QAAQ,CAAC;EACnE,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,OAAO,UAAU,aAAa;CACpC,MAAM,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ;CACjD,UAAU,QAAQ,KAAK,QAAQ,MAAM,CAAC;CAGtC,IAAK,MAAM,gBAAgB,QAAQ,YAAY,GAAG,KAAK,MAAM,SAAS,KAAM,CAAC,OAAO;EAClF,QAAQ,IAAI,OAAO,IAAI,mBAAmB,KAAK,MAAM,4BAA4B,CAAC;EAClF,QAAQ,IAAI,OAAO,OAAO,0BAA0B,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,yBAAyB,QAAQ,UAAU;CAMjD,MAAM,aAHc,qBAAqB,QAAQ,YAAY,GAAG,KAAK,MAAM,SAG9C,GAFN,YAAY,IAEU,CAAC;CAE9C,QAAQ,IAAI,OAAO,KAAK,gBAAgB,KAAK,MAAM,0BAA0B,CAAC;AAChF"}
1
+ {"version":3,"file":"service.generator.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/service.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport { serviceStub } from \"../templates/stubs\";\nimport { putFileAsync, setDryRun } from \"../utils/writer\";\nimport { parseModulePath, parseName } from \"../utils/name-parser\";\nimport {\n componentExists,\n ensureComponentDirectory,\n moduleExists,\n resolveComponentPath,\n} from \"../utils/path-resolver\";\n\nexport async function generateService(data: CommandActionData): Promise<void> {\n const input = data.args[0];\n\n if (!input) {\n console.log(colors.red(\"Error: Service name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.service <module>/<name>\"));\n console.log(colors.yellow(\"Example: warlock generate.service users/create-user\"));\n process.exit(1);\n }\n\n const { module, name: componentName } = parseModulePath(input);\n\n if (!module) {\n console.log(colors.red(\"Error: Module name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.service <module>/<name>\"));\n process.exit(1);\n }\n\n // Check if module exists\n if (!(await moduleExists(module))) {\n console.log(colors.red(`Error: Module \"${module}\" does not exist`));\n console.log(colors.yellow(`Run: warlock generate.module ${module}`));\n process.exit(1);\n }\n\n const name = parseName(componentName);\n const force = data.options.force || data.options.f;\n setDryRun(Boolean(data.options.dryRun));\n\n // Check if service already exists\n if ((await componentExists(module, \"services\", `${name.kebab}.service`)) && !force) {\n console.log(colors.red(`Error: Service \"${name.kebab}.service.ts\" already exists`));\n console.log(colors.yellow(\"Use --force to overwrite\"));\n process.exit(1);\n }\n\n // Ensure directories exist\n await ensureComponentDirectory(module, \"services\");\n\n // Generate service\n const servicePath = resolveComponentPath(module, \"services\", `${name.kebab}.service`);\n const serviceContent = serviceStub(name);\n\n await putFileAsync(servicePath, serviceContent);\n\n console.log(colors.cyan(`\\n✨ Service \"${name.camel}\" generated successfully!`));\n}\n"],"mappings":";;;;;;;AAYA,eAAsB,gBAAgB,MAAwC;CAC5E,MAAM,QAAQ,KAAK,KAAK;CAExB,IAAI,CAAC,OAAO;EACV,QAAQ,IAAI,OAAO,IAAI,iCAAiC,CAAC;EACzD,QAAQ,IAAI,OAAO,OAAO,iDAAiD,CAAC;EAC5E,QAAQ,IAAI,OAAO,OAAO,qDAAqD,CAAC;EAChF,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,EAAE,QAAQ,MAAM,kBAAkB,gBAAgB,KAAK;CAE7D,IAAI,CAAC,QAAQ;EACX,QAAQ,IAAI,OAAO,IAAI,gCAAgC,CAAC;EACxD,QAAQ,IAAI,OAAO,OAAO,iDAAiD,CAAC;EAC5E,QAAQ,KAAK,CAAC;CAChB;CAGA,IAAI,CAAE,MAAM,aAAa,MAAM,GAAI;EACjC,QAAQ,IAAI,OAAO,IAAI,kBAAkB,OAAO,iBAAiB,CAAC;EAClE,QAAQ,IAAI,OAAO,OAAO,gCAAgC,QAAQ,CAAC;EACnE,QAAQ,KAAK,CAAC;CAChB;CAEA,MAAM,OAAO,UAAU,aAAa;CACpC,MAAM,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ;CACjD,UAAU,QAAQ,KAAK,QAAQ,MAAM,CAAC;CAGtC,IAAK,MAAM,gBAAgB,QAAQ,YAAY,GAAG,KAAK,MAAM,SAAS,KAAM,CAAC,OAAO;EAClF,QAAQ,IAAI,OAAO,IAAI,mBAAmB,KAAK,MAAM,4BAA4B,CAAC;EAClF,QAAQ,IAAI,OAAO,OAAO,0BAA0B,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,yBAAyB,QAAQ,UAAU;CAGjD,MAAM,cAAc,qBAAqB,QAAQ,YAAY,GAAG,KAAK,MAAM,SAAS;CACpF,MAAM,iBAAiB,YAAY,IAAI;CAEvC,MAAM,aAAa,aAAa,cAAc;CAE9C,QAAQ,IAAI,OAAO,KAAK,gBAAgB,KAAK,MAAM,0BAA0B,CAAC;AAChF"}
@@ -215,7 +215,7 @@ function endpointTestStub(spec) {
215
215
  const uncarriable = uncarriableRequiredFields(spec);
216
216
  const guarded = spec.access === "guarded";
217
217
  const needsQuery = spec.method === "get";
218
- const helpers = new Set(["expectJson", ...anonymousHelpers(spec)]);
218
+ const helpers = /* @__PURE__ */ new Set(["expectJson", ...anonymousHelpers(spec)]);
219
219
  if (guarded) helpers.add("actingAs");
220
220
  const lines = [];
221
221
  if (guarded) {
@@ -337,5 +337,5 @@ function endpointLocaleEntries(spec) {
337
337
  }
338
338
 
339
339
  //#endregion
340
- export { endpointControllerStub, endpointLabel, endpointLocaleEntries, endpointResourceStub, endpointRouteImports, endpointRouteRegistration, endpointRoutesFileStub, endpointSchemaStub, endpointServiceStub, endpointTestStub };
340
+ export { endpointControllerStub, endpointLabel, endpointLocaleEntries, endpointResourceStub, endpointRouteImports, endpointRouteRegistration, endpointRoutesFileStub, endpointSampleInput, endpointSchemaStub, endpointServiceStub, endpointStatus, endpointTestPath, endpointTestStub, resourceResponseKey, successMessage, successMessageKey };
341
341
  //# sourceMappingURL=endpoint-stubs.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-stubs.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/templates/endpoint-stubs.ts"],"sourcesContent":["import type { Name } from \"../utils/name-parser\";\nimport type { EndpointField } from \"../utils/endpoint-schema\";\n\n/**\n * Stubs for `warlock make endpoint`.\n *\n * Every stub follows the conventions `warlock check` enforces:\n * one controller per file, input read through `request.validated()` only,\n * the work done in a service that never sees the request, a resource for the\n * output, the response documented through `responseSchema` (OpenAPI), and a\n * mutating route that is either guarded or explicitly `public: true`.\n */\n\nexport type EndpointMethod = \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\";\n\nexport type EndpointAccess = \"guarded\" | \"public\";\n\nexport type EndpointSpec = {\n /** Module folder name, e.g. `posts`. */\n module: string;\n /** The endpoint's name, e.g. `create-post`. */\n name: Name;\n method: EndpointMethod;\n /** Route path, e.g. `/posts` or `/posts/:id`. */\n path: string;\n access: EndpointAccess;\n /** The resource the endpoint answers with, e.g. `Post`. */\n resource: Name;\n /** Top-level request fields, read from the schema (empty without `--schema`). */\n fields: EndpointField[];\n};\n\n/** `POST /posts` — used in comments, test names and descriptions. */\nexport function endpointLabel(spec: EndpointSpec): string {\n return `${spec.method.toUpperCase()} ${spec.path}`;\n}\n\n/** The success status the controller answers with. */\nexport function endpointStatus(spec: EndpointSpec): 200 | 201 {\n return spec.method === \"post\" ? 201 : 200;\n}\n\n/** `createPostSuccess` — the locale key of the success message. */\nexport function successMessageKey(spec: EndpointSpec): string {\n return `${spec.name.camel}Success`;\n}\n\n/** `Create post completed successfully.` — the English success message. */\nexport function successMessage(spec: EndpointSpec): string {\n const words = spec.name.kebab.split(\"-\").join(\" \");\n\n return `${words.charAt(0).toUpperCase()}${words.slice(1)} completed successfully.`;\n}\n\n/** The key the resource sits under in the response body, e.g. `post`. */\nexport function resourceResponseKey(spec: EndpointSpec): string {\n return spec.resource.singular.camel;\n}\n\n/** `schema/<name>.schema.ts` when no `--schema` file was given. */\nexport function endpointSchemaStub(spec: EndpointSpec): string {\n return `import { type Infer, v } from \"@warlock.js/seal\";\n\n/** Request input for ${endpointLabel(spec)}. */\nexport const ${spec.name.camel}Schema = v.object({\n // TODO: describe the request input, then run make endpoint again with --force\n // to regenerate the resource and test from it.\n});\n\nexport type ${spec.name.pascal}Schema = Infer<typeof ${spec.name.camel}Schema>;\n`;\n}\n\n/** `services/<name>.service.ts`. */\nexport function endpointServiceStub(spec: EndpointSpec): string {\n return `import type { ${spec.name.pascal}Schema } from \"../schema/${spec.name.kebab}.schema\";\n\n/**\n * The work behind ${endpointLabel(spec)}. It takes validated input, never the\n * request, so a job, a command or another service can call it too.\n */\nexport async function ${spec.name.camel}Service(input: ${spec.name.pascal}Schema) {\n // TODO: persist or act on the input, then return what the endpoint answers with.\n return input;\n}\n`;\n}\n\n/** `resources/<resource>.resource.ts`, shaped from the request fields. */\nexport function endpointResourceStub(spec: EndpointSpec): string {\n const fields = spec.fields.filter((field) => field.cast !== undefined);\n const body =\n fields.length === 0\n ? ' // TODO: list the fields this resource outputs, e.g. id: \"number\"'\n : fields.map((field) => ` ${propertyKey(field.name)}: \"${field.cast}\",`).join(\"\\n\");\n\n return `import { defineResource } from \"@warlock.js/core\";\n\n/** What ${spec.resource.pascal} looks like in a response. */\nexport const ${spec.resource.pascal}Resource = defineResource({\n schema: {\n${body}\n },\n});\n`;\n}\n\n/** `controllers/<name>.controller.ts` — one handler per file. */\nexport function endpointControllerStub(spec: EndpointSpec): string {\n const resource = `${spec.resource.pascal}Resource`;\n const key = resourceResponseKey(spec);\n const status = endpointStatus(spec);\n const respond = status === 201 ? \"successCreate\" : \"success\";\n const controller = `${spec.name.camel}Controller`;\n const schemaType = `${spec.name.pascal}Schema`;\n const handlerType =\n spec.access === \"guarded\"\n ? `GuardedRequestHandler<${schemaType}>`\n : `RequestHandler<Request<${schemaType}>>`;\n const coreImport =\n spec.access === \"guarded\"\n ? `import { t } from \"@warlock.js/core\";\nimport { type GuardedRequestHandler } from \"app/auth/requests/guarded.request\";`\n : `import { type Request, type RequestHandler, t } from \"@warlock.js/core\";`;\n\n return `${coreImport}\nimport { ${resource} } from \"../resources/${spec.resource.singular.kebab}.resource\";\nimport { type ${schemaType}, ${spec.name.camel}Schema } from \"../schema/${spec.name.kebab}.schema\";\nimport { ${spec.name.camel}Service } from \"../services/${spec.name.kebab}.service\";\n\n/** ${endpointLabel(spec)} */\nexport const ${controller}: ${handlerType} = async ({\n request,\n response,\n}) => {\n const ${key} = await ${spec.name.camel}Service(request.validated());\n\n return response.${respond}({\n message: t(\"${spec.module}.${successMessageKey(spec)}\"),\n ${key}: new ${resource}(${key}),\n });\n};\n\n${controller}.description = \"${successMessage(spec).replace(\" completed successfully.\", \"\")}\";\n\n${controller}.validation = {\n schema: ${spec.name.camel}Schema,\n};\n\n// Documents the success response for \\`warlock generate.openapi\\` and the typed route map.\n${controller}.responseSchema = {\n ${status}: {\n body: {\n message: \"string\",\n ${key}: ${resource},\n },\n },\n};\n`;\n}\n\n/** The import lines a module `routes.ts` needs for this endpoint. */\nexport function endpointRouteImports(spec: EndpointSpec): string[] {\n const imports = [\n `import { ${spec.name.camel}Controller } from \"./controllers/${spec.name.kebab}.controller\";`,\n ];\n\n return imports;\n}\n\n/** The registration block appended to the module's `routes.ts`. */\nexport function endpointRouteRegistration(spec: EndpointSpec): string {\n const controller = `${spec.name.camel}Controller`;\n\n if (spec.access === \"public\") {\n return `// ${endpointLabel(spec)} — public on purpose: no auth guard.\nrouter.${spec.method}(\"${spec.path}\", ${controller}, { public: true });\n`;\n }\n\n return `guarded(() => {\n router.${spec.method}(\"${spec.path}\", ${controller});\n});\n`;\n}\n\n/** A fresh module `routes.ts` holding only this endpoint. */\nexport function endpointRoutesFileStub(spec: EndpointSpec): string {\n const imports = [`import { router } from \"@warlock.js/core\";`];\n\n if (spec.access === \"guarded\") {\n imports.push(`import { guarded } from \"app/shared/utils/router\";`);\n }\n\n imports.push(...endpointRouteImports(spec));\n\n return `${imports.join(\"\\n\")}\n\n${endpointRouteRegistration(spec)}`;\n}\n\n/** The path the generated test requests: route params get a placeholder. */\nexport function endpointTestPath(spec: EndpointSpec): string {\n return spec.path.replace(/:[A-Za-z0-9_]+\\??/g, \"1\");\n}\n\n/** The request input the generated test sends: every field JSON can carry. */\nexport function endpointSampleInput(spec: EndpointSpec): Record<string, unknown> {\n const input: Record<string, unknown> = {};\n\n for (const field of spec.fields) {\n if (field.sample !== undefined) input[field.name] = field.sample;\n }\n\n return input;\n}\n\n/** The part of the input the response echoes unchanged. */\nfunction comparableInput(spec: EndpointSpec): Record<string, unknown> {\n const input: Record<string, unknown> = {};\n\n for (const field of spec.fields) {\n if (field.comparable) input[field.name] = field.sample;\n }\n\n return input;\n}\n\n/** A required field the test can drop to prove validation runs, if any. */\nfunction droppableRequiredField(spec: EndpointSpec) {\n return spec.fields.find((field) => field.required && field.sample !== undefined);\n}\n\n/** Fields JSON cannot carry (files): the happy path needs multipart instead. */\nfunction uncarriableRequiredFields(spec: EndpointSpec): string[] {\n return spec.fields\n .filter((field) => field.required && field.sample === undefined)\n .map((field) => field.name);\n}\n\nfunction propertyKey(name: string): string {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\n/** A TypeScript literal for a JSON value: unquoted identifier keys, trailing commas. */\nfunction toLiteral(value: unknown, indent: string): string {\n if (Array.isArray(value)) {\n if (value.length === 0) return \"[]\";\n\n return `[\\n${value.map((item) => `${indent} ${toLiteral(item, `${indent} `)},`).join(\"\\n\")}\\n${indent}]`;\n }\n\n if (typeof value === \"object\" && value !== null) {\n const entries = Object.entries(value);\n\n if (entries.length === 0) return \"{}\";\n\n return `{\\n${entries\n .map(([key, item]) => `${indent} ${propertyKey(key)}: ${toLiteral(item, `${indent} `)},`)\n .join(\"\\n\")}\\n${indent}}`;\n }\n\n return JSON.stringify(value);\n}\n\nfunction indentJson(value: unknown, indent: string): string {\n return toLiteral(value, indent);\n}\n\n/**\n * The statement that sends `inputExpression` to the endpoint, through\n * `client` (`testRequest`-shaped helpers or an `actingAs()` client).\n */\nfunction sendRequest(spec: EndpointSpec, client: string, inputExpression: string): string {\n const path = JSON.stringify(endpointTestPath(spec));\n\n switch (spec.method) {\n case \"get\":\n return `${client === \"\" ? \"testGet\" : `${client}.get`}(${path} + \"?\" + new URLSearchParams(toQuery(${inputExpression})).toString())`;\n case \"delete\":\n return `${client === \"\" ? \"testRequest\" : `${client}.request`}(${path}, {\n method: \"DELETE\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(${inputExpression}),\n })`;\n default: {\n const helper = `test${spec.method.charAt(0).toUpperCase()}${spec.method.slice(1)}`;\n\n return `${client === \"\" ? helper : `${client}.${spec.method}`}(${path}, ${inputExpression})`;\n }\n }\n}\n\n/** The `@warlock.js/core/tests` helpers a test sends anonymous requests with. */\nfunction anonymousHelpers(spec: EndpointSpec): string[] {\n switch (spec.method) {\n case \"get\":\n return [\"testGet\"];\n case \"delete\":\n return [\"testRequest\"];\n default:\n return [`test${spec.method.charAt(0).toUpperCase()}${spec.method.slice(1)}`];\n }\n}\n\n/**\n * `tests/<name>.test.ts` — requests the endpoint over the real HTTP stack\n * (the test server `warlock add test` wires up): routing, middleware,\n * validation, controller, resource and serialization all run.\n */\nexport function endpointTestStub(spec: EndpointSpec): string {\n const label = endpointLabel(spec);\n const key = resourceResponseKey(spec);\n const status = endpointStatus(spec);\n const input = endpointSampleInput(spec);\n const expected = comparableInput(spec);\n const dropped = droppableRequiredField(spec);\n const uncarriable = uncarriableRequiredFields(spec);\n const guarded = spec.access === \"guarded\";\n const needsQuery = spec.method === \"get\";\n const helpers = new Set<string>([\"expectJson\", ...anonymousHelpers(spec)]);\n\n if (guarded) helpers.add(\"actingAs\");\n\n const lines: string[] = [];\n\n if (guarded) {\n lines.push(`import type { Auth } from \"@warlock.js/auth\";`);\n lines.push(`import type { ChildModel } from \"@warlock.js/cascade\";`);\n lines.push(`import { config } from \"@warlock.js/core\";`);\n }\n\n lines.push(`import { ${[...helpers].sort().join(\", \")} } from \"@warlock.js/core/tests\";`);\n\n if (guarded) lines.push(`import { randomUUID } from \"node:crypto\";`);\n\n lines.push(\n `import { ${guarded ? \"afterAll, describe, expect, it\" : \"describe, expect, it\"} } from \"vitest\";`,\n );\n\n const header = `${lines.join(\"\\n\")}\n\n/** A valid request for ${label}, derived from its schema. */\nconst validInput: Record<string, unknown> = ${indentJson(input, \"\")};\n${\n needsQuery\n ? `\n/** Query values travel as strings; numeric schema fields need \\`.coerce()\\`. */\nfunction toQuery(input: Record<string, unknown>): Record<string, string> {\n return Object.fromEntries(Object.entries(input).map(([key, value]) => [key, String(value)]));\n}\n`\n : \"\"\n}`;\n\n const happyAssertions = (indent: string) =>\n [\n `const body = await expectJson<{ message: string; ${key}: Record<string, unknown> }>(`,\n ` response,`,\n ` ${status},`,\n `);`,\n ``,\n `expect(typeof body.message).toBe(\"string\");`,\n `expect(body.${key}).toMatchObject(${indentJson(expected, indent)});`,\n ]\n .map((line, index) => (index === 0 || line === \"\" ? line : `${indent}${line}`))\n .join(\"\\n\");\n\n const dropStatement = dropped\n ? `const input = { ...validInput };\n\n delete input[${JSON.stringify(dropped.name)}];\n`\n : \"\";\n\n const validationCase = dropped\n ? `\n it(\"rejects a request without ${dropped.name}\", async () => {\n ${dropStatement}\n const response = await ${sendRequest(spec, \"\", \"input\")};\n\n expect(response.status).toBeGreaterThanOrEqual(400);\n expect(response.status).toBeLessThan(500);\n });\n`\n : \"\";\n\n if (!guarded) {\n const happy =\n uncarriable.length > 0\n ? ` it.todo(\"answers a valid request — send ${uncarriable.join(\", \")} as multipart form data (JSON cannot carry files)\");\\n`\n : ` it(\"answers a valid request with the ${spec.resource.singular.pascal} resource\", async () => {\n const response = await ${sendRequest(spec, \"\", \"validInput\")};\n\n ${happyAssertions(\" \")}\n });\n`;\n\n return `${header}\ndescribe(\"${label}\", () => {\n${happy}${validationCase}});\n`;\n }\n\n const signedInHappy =\n uncarriable.length > 0\n ? ` it.todo(\"answers a signed-in user — send ${uncarriable.join(\", \")} as multipart form data (JSON cannot carry files)\");\\n`\n : ` it(\"answers a signed-in user with the ${spec.resource.singular.pascal} resource\", async () => {\n const client = await signIn();\n\n try {\n const response = await ${sendRequest(spec, \"client\", \"validInput\")};\n\n ${happyAssertions(\" \")}\n } finally {\n await client.dispose();\n }\n });\n`;\n\n const guardedValidation = dropped\n ? `\n it(\"rejects a request without ${dropped.name}\", async () => {\n const client = await signIn();\n\n try {\n const input = { ...validInput };\n\n delete input[${JSON.stringify(dropped.name)}];\n\n const response = await ${sendRequest(spec, \"client\", \"input\")};\n\n expect(response.status).toBeGreaterThanOrEqual(400);\n expect(response.status).toBeLessThan(500);\n } finally {\n await client.dispose();\n }\n });\n`\n : \"\";\n\n return `${header}\ndescribe(\"${label}\", () => {\n const users: Auth[] = [];\n\n /** A real user and a real access token; adjust the fields if your user model requires more. */\n async function signIn() {\n const User = config.key<ChildModel<Auth>>(\"auth.userType.user\");\n\n if (!User) throw new Error(\"This test needs the configured auth.userType.user model.\");\n\n const user = await User.create({\n name: \"Endpoint test user\",\n email: \"endpoint-\" + randomUUID() + \"@example.test\",\n password: \"test-password\",\n });\n\n users.push(user);\n\n return actingAs(user);\n }\n\n afterAll(async () => {\n await Promise.all(users.splice(0).map((user) => user.destroy({ strategy: \"permanent\" })));\n });\n\n it(\"rejects an anonymous request\", async () => {\n const response = await ${sendRequest(spec, \"\", \"validInput\")};\n\n expect(response.status).toBe(401);\n });\n\n${signedInHappy}${guardedValidation}});\n`;\n}\n\n/** The locale entry merged into the module's `utils/locales.json`. */\nexport function endpointLocaleEntries(spec: EndpointSpec): Record<string, Record<string, string>> {\n return { [successMessageKey(spec)]: { en: successMessage(spec) } };\n}\n"],"mappings":";;AAiCA,SAAgB,cAAc,MAA4B;CACxD,OAAO,GAAG,KAAK,OAAO,YAAY,EAAE,GAAG,KAAK;AAC9C;;AAGA,SAAgB,eAAe,MAA+B;CAC5D,OAAO,KAAK,WAAW,SAAS,MAAM;AACxC;;AAGA,SAAgB,kBAAkB,MAA4B;CAC5D,OAAO,GAAG,KAAK,KAAK,MAAM;AAC5B;;AAGA,SAAgB,eAAe,MAA4B;CACzD,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG;CAEjD,OAAO,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,MAAM,MAAM,CAAC,EAAE;AAC3D;;AAGA,SAAgB,oBAAoB,MAA4B;CAC9D,OAAO,KAAK,SAAS,SAAS;AAChC;;AAGA,SAAgB,mBAAmB,MAA4B;CAC7D,OAAO;;wBAEe,cAAc,IAAI,EAAE;eAC7B,KAAK,KAAK,MAAM;;;;;cAKjB,KAAK,KAAK,OAAO,wBAAwB,KAAK,KAAK,MAAM;;AAEvE;;AAGA,SAAgB,oBAAoB,MAA4B;CAC9D,OAAO,iBAAiB,KAAK,KAAK,OAAO,2BAA2B,KAAK,KAAK,MAAM;;;qBAGjE,cAAc,IAAI,EAAE;;;wBAGjB,KAAK,KAAK,MAAM,iBAAiB,KAAK,KAAK,OAAO;;;;;AAK1E;;AAGA,SAAgB,qBAAqB,MAA4B;CAC/D,MAAM,SAAS,KAAK,OAAO,QAAQ,UAAU,MAAM,SAAS,MAAS;CACrE,MAAM,OACJ,OAAO,WAAW,IACd,4EACA,OAAO,KAAK,UAAU,OAAO,YAAY,MAAM,IAAI,EAAE,KAAK,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI;CAEzF,OAAO;;WAEE,KAAK,SAAS,OAAO;eACjB,KAAK,SAAS,OAAO;;EAElC,KAAK;;;;AAIP;;AAGA,SAAgB,uBAAuB,MAA4B;CACjE,MAAM,WAAW,GAAG,KAAK,SAAS,OAAO;CACzC,MAAM,MAAM,oBAAoB,IAAI;CACpC,MAAM,SAAS,eAAe,IAAI;CAClC,MAAM,UAAU,WAAW,MAAM,kBAAkB;CACnD,MAAM,aAAa,GAAG,KAAK,KAAK,MAAM;CACtC,MAAM,aAAa,GAAG,KAAK,KAAK,OAAO;CACvC,MAAM,cACJ,KAAK,WAAW,YACZ,yBAAyB,WAAW,KACpC,0BAA0B,WAAW;CAO3C,OAAO,GALL,KAAK,WAAW,YACZ;mFAEA,2EAEe;WACZ,SAAS,wBAAwB,KAAK,SAAS,SAAS,MAAM;gBACzD,WAAW,IAAI,KAAK,KAAK,MAAM,2BAA2B,KAAK,KAAK,MAAM;WAC/E,KAAK,KAAK,MAAM,8BAA8B,KAAK,KAAK,MAAM;;MAEnE,cAAc,IAAI,EAAE;eACX,WAAW,IAAI,YAAY;;;;UAIhC,IAAI,WAAW,KAAK,KAAK,MAAM;;oBAErB,QAAQ;kBACV,KAAK,OAAO,GAAG,kBAAkB,IAAI,EAAE;MACnD,IAAI,QAAQ,SAAS,GAAG,IAAI;;;;EAIhC,WAAW,kBAAkB,eAAe,IAAI,CAAC,CAAC,QAAQ,4BAA4B,EAAE,EAAE;;EAE1F,WAAW;YACD,KAAK,KAAK,MAAM;;;;EAI1B,WAAW;IACT,OAAO;;;QAGH,IAAI,IAAI,SAAS;;;;;AAKzB;;AAGA,SAAgB,qBAAqB,MAA8B;CAKjE,OAAO,CAHL,YAAY,KAAK,KAAK,MAAM,mCAAmC,KAAK,KAAK,MAAM,cAGpE;AACf;;AAGA,SAAgB,0BAA0B,MAA4B;CACpE,MAAM,aAAa,GAAG,KAAK,KAAK,MAAM;CAEtC,IAAI,KAAK,WAAW,UAClB,OAAO,MAAM,cAAc,IAAI,EAAE;SAC5B,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,WAAW;;CAIjD,OAAO;WACE,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,WAAW;;;AAGrD;;AAGA,SAAgB,uBAAuB,MAA4B;CACjE,MAAM,UAAU,CAAC,4CAA4C;CAE7D,IAAI,KAAK,WAAW,WAClB,QAAQ,KAAK,oDAAoD;CAGnE,QAAQ,KAAK,GAAG,qBAAqB,IAAI,CAAC;CAE1C,OAAO,GAAG,QAAQ,KAAK,IAAI,EAAE;;EAE7B,0BAA0B,IAAI;AAChC;;AAGA,SAAgB,iBAAiB,MAA4B;CAC3D,OAAO,KAAK,KAAK,QAAQ,sBAAsB,GAAG;AACpD;;AAGA,SAAgB,oBAAoB,MAA6C;CAC/E,MAAM,QAAiC,CAAC;CAExC,KAAK,MAAM,SAAS,KAAK,QACvB,IAAI,MAAM,WAAW,QAAW,MAAM,MAAM,QAAQ,MAAM;CAG5D,OAAO;AACT;;AAGA,SAAS,gBAAgB,MAA6C;CACpE,MAAM,QAAiC,CAAC;CAExC,KAAK,MAAM,SAAS,KAAK,QACvB,IAAI,MAAM,YAAY,MAAM,MAAM,QAAQ,MAAM;CAGlD,OAAO;AACT;;AAGA,SAAS,uBAAuB,MAAoB;CAClD,OAAO,KAAK,OAAO,MAAM,UAAU,MAAM,YAAY,MAAM,WAAW,MAAS;AACjF;;AAGA,SAAS,0BAA0B,MAA8B;CAC/D,OAAO,KAAK,OACT,QAAQ,UAAU,MAAM,YAAY,MAAM,WAAW,MAAS,CAAC,CAC/D,KAAK,UAAU,MAAM,IAAI;AAC9B;AAEA,SAAS,YAAY,MAAsB;CACzC,OAAO,6BAA6B,KAAK,IAAI,IAAI,OAAO,KAAK,UAAU,IAAI;AAC7E;;AAGA,SAAS,UAAU,OAAgB,QAAwB;CACzD,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,IAAI,MAAM,WAAW,GAAG,OAAO;EAE/B,OAAO,MAAM,MAAM,KAAK,SAAS,GAAG,OAAO,IAAI,UAAU,MAAM,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI,OAAO;CAC1G;CAEA,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;EAC/C,MAAM,UAAU,OAAO,QAAQ,KAAK;EAEpC,IAAI,QAAQ,WAAW,GAAG,OAAO;EAEjC,OAAO,MAAM,QACV,KAAK,CAAC,KAAK,UAAU,GAAG,OAAO,IAAI,YAAY,GAAG,EAAE,IAAI,UAAU,MAAM,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC,CAC1F,KAAK,IAAI,EAAE,IAAI,OAAO;CAC3B;CAEA,OAAO,KAAK,UAAU,KAAK;AAC7B;AAEA,SAAS,WAAW,OAAgB,QAAwB;CAC1D,OAAO,UAAU,OAAO,MAAM;AAChC;;;;;AAMA,SAAS,YAAY,MAAoB,QAAgB,iBAAiC;CACxF,MAAM,OAAO,KAAK,UAAU,iBAAiB,IAAI,CAAC;CAElD,QAAQ,KAAK,QAAb;EACE,KAAK,OACH,OAAO,GAAG,WAAW,KAAK,YAAY,GAAG,OAAO,MAAM,GAAG,KAAK,uCAAuC,gBAAgB;EACvH,KAAK,UACH,OAAO,GAAG,WAAW,KAAK,gBAAgB,GAAG,OAAO,UAAU,GAAG,KAAK;;;6BAG/C,gBAAgB;;EAEzC,SAAS;GACP,MAAM,SAAS,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,OAAO,MAAM,CAAC;GAE/E,OAAO,GAAG,WAAW,KAAK,SAAS,GAAG,OAAO,GAAG,KAAK,SAAS,GAAG,KAAK,IAAI,gBAAgB;EAC5F;CACF;AACF;;AAGA,SAAS,iBAAiB,MAA8B;CACtD,QAAQ,KAAK,QAAb;EACE,KAAK,OACH,OAAO,CAAC,SAAS;EACnB,KAAK,UACH,OAAO,CAAC,aAAa;EACvB,SACE,OAAO,CAAC,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,OAAO,MAAM,CAAC,GAAG;CAC/E;AACF;;;;;;AAOA,SAAgB,iBAAiB,MAA4B;CAC3D,MAAM,QAAQ,cAAc,IAAI;CAChC,MAAM,MAAM,oBAAoB,IAAI;CACpC,MAAM,SAAS,eAAe,IAAI;CAClC,MAAM,QAAQ,oBAAoB,IAAI;CACtC,MAAM,WAAW,gBAAgB,IAAI;CACrC,MAAM,UAAU,uBAAuB,IAAI;CAC3C,MAAM,cAAc,0BAA0B,IAAI;CAClD,MAAM,UAAU,KAAK,WAAW;CAChC,MAAM,aAAa,KAAK,WAAW;CACnC,MAAM,UAAU,IAAI,IAAY,CAAC,cAAc,GAAG,iBAAiB,IAAI,CAAC,CAAC;CAEzE,IAAI,SAAS,QAAQ,IAAI,UAAU;CAEnC,MAAM,QAAkB,CAAC;CAEzB,IAAI,SAAS;EACX,MAAM,KAAK,+CAA+C;EAC1D,MAAM,KAAK,wDAAwD;EACnE,MAAM,KAAK,4CAA4C;CACzD;CAEA,MAAM,KAAK,YAAY,CAAC,GAAG,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,kCAAkC;CAExF,IAAI,SAAS,MAAM,KAAK,2CAA2C;CAEnE,MAAM,KACJ,YAAY,UAAU,mCAAmC,uBAAuB,kBAClF;CAEA,MAAM,SAAS,GAAG,MAAM,KAAK,IAAI,EAAE;;0BAEX,MAAM;8CACc,WAAW,OAAO,EAAE,EAAE;EAElE,aACI;;;;;IAMA;CAGJ,MAAM,mBAAmB,WACvB;EACE,oDAAoD,IAAI;EACxD;EACA,KAAK,OAAO;EACZ;EACA;EACA;EACA,eAAe,IAAI,kBAAkB,WAAW,UAAU,MAAM,EAAE;CACpE,CAAC,CACE,KAAK,MAAM,UAAW,UAAU,KAAK,SAAS,KAAK,OAAO,GAAG,SAAS,MAAO,CAAC,CAC9E,KAAK,IAAI;CAEd,MAAM,gBAAgB,UAClB;;mBAEa,KAAK,UAAU,QAAQ,IAAI,EAAE;IAE1C;CAEJ,MAAM,iBAAiB,UACnB;kCAC4B,QAAQ,KAAK;MACzC,cAAc;6BACS,YAAY,MAAM,IAAI,OAAO,EAAE;;;;;IAMtD;CAEJ,IAAI,CAAC,SAWH,OAAO,GAAG,OAAO;YACT,MAAM;EAVZ,YAAY,SAAS,IACjB,6CAA6C,YAAY,KAAK,IAAI,EAAE,0DACpE,0CAA0C,KAAK,SAAS,SAAS,OAAO;6BACrD,YAAY,MAAM,IAAI,YAAY,EAAE;;MAE3D,gBAAgB,MAAM,EAAE;;IAMpB,eAAe;;CAIvB,MAAM,gBACJ,YAAY,SAAS,IACjB,8CAA8C,YAAY,KAAK,IAAI,EAAE,0DACrE,2CAA2C,KAAK,SAAS,SAAS,OAAO;;;;+BAIlD,YAAY,MAAM,UAAU,YAAY,EAAE;;QAEjE,gBAAgB,QAAQ,EAAE;;;;;;CAOhC,MAAM,oBAAoB,UACtB;kCAC4B,QAAQ,KAAK;;;;;;qBAM1B,KAAK,UAAU,QAAQ,IAAI,EAAE;;+BAEnB,YAAY,MAAM,UAAU,OAAO,EAAE;;;;;;;;IAS9D;CAEJ,OAAO,GAAG,OAAO;YACP,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;6BAyBW,YAAY,MAAM,IAAI,YAAY,EAAE;;;;;EAK/D,gBAAgB,kBAAkB;;AAEpC;;AAGA,SAAgB,sBAAsB,MAA4D;CAChG,OAAO,GAAG,kBAAkB,IAAI,IAAI,EAAE,IAAI,eAAe,IAAI,EAAE,EAAE;AACnE"}
1
+ {"version":3,"file":"endpoint-stubs.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/templates/endpoint-stubs.ts"],"sourcesContent":["import type { Name } from \"../utils/name-parser\";\nimport type { EndpointField } from \"../utils/endpoint-schema\";\n\n/**\n * Stubs for `warlock make endpoint`.\n *\n * Every stub follows the conventions `warlock check` enforces:\n * one controller per file, input read through `request.validated()` only,\n * the work done in a service that never sees the request, a resource for the\n * output, the response documented through `responseSchema` (OpenAPI), and a\n * mutating route that is either guarded or explicitly `public: true`.\n */\n\nexport type EndpointMethod = \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\";\n\nexport type EndpointAccess = \"guarded\" | \"public\";\n\nexport type EndpointSpec = {\n /** Module folder name, e.g. `posts`. */\n module: string;\n /** The endpoint's name, e.g. `create-post`. */\n name: Name;\n method: EndpointMethod;\n /** Route path, e.g. `/posts` or `/posts/:id`. */\n path: string;\n access: EndpointAccess;\n /** The resource the endpoint answers with, e.g. `Post`. */\n resource: Name;\n /** Top-level request fields, read from the schema (empty without `--schema`). */\n fields: EndpointField[];\n};\n\n/** `POST /posts` — used in comments, test names and descriptions. */\nexport function endpointLabel(spec: EndpointSpec): string {\n return `${spec.method.toUpperCase()} ${spec.path}`;\n}\n\n/** The success status the controller answers with. */\nexport function endpointStatus(spec: EndpointSpec): 200 | 201 {\n return spec.method === \"post\" ? 201 : 200;\n}\n\n/** `createPostSuccess` — the locale key of the success message. */\nexport function successMessageKey(spec: EndpointSpec): string {\n return `${spec.name.camel}Success`;\n}\n\n/** `Create post completed successfully.` — the English success message. */\nexport function successMessage(spec: EndpointSpec): string {\n const words = spec.name.kebab.split(\"-\").join(\" \");\n\n return `${words.charAt(0).toUpperCase()}${words.slice(1)} completed successfully.`;\n}\n\n/** The key the resource sits under in the response body, e.g. `post`. */\nexport function resourceResponseKey(spec: EndpointSpec): string {\n return spec.resource.singular.camel;\n}\n\n/** `schema/<name>.schema.ts` when no `--schema` file was given. */\nexport function endpointSchemaStub(spec: EndpointSpec): string {\n return `import { type Infer, v } from \"@warlock.js/seal\";\n\n/** Request input for ${endpointLabel(spec)}. */\nexport const ${spec.name.camel}Schema = v.object({\n // TODO: describe the request input, then run make endpoint again with --force\n // to regenerate the resource and test from it.\n});\n\nexport type ${spec.name.pascal}Schema = Infer<typeof ${spec.name.camel}Schema>;\n`;\n}\n\n/** `services/<name>.service.ts`. */\nexport function endpointServiceStub(spec: EndpointSpec): string {\n return `import type { ${spec.name.pascal}Schema } from \"../schema/${spec.name.kebab}.schema\";\n\n/**\n * The work behind ${endpointLabel(spec)}. It takes validated input, never the\n * request, so a job, a command or another service can call it too.\n */\nexport async function ${spec.name.camel}Service(input: ${spec.name.pascal}Schema) {\n // TODO: persist or act on the input, then return what the endpoint answers with.\n return input;\n}\n`;\n}\n\n/** `resources/<resource>.resource.ts`, shaped from the request fields. */\nexport function endpointResourceStub(spec: EndpointSpec): string {\n const fields = spec.fields.filter((field) => field.cast !== undefined);\n const body =\n fields.length === 0\n ? ' // TODO: list the fields this resource outputs, e.g. id: \"number\"'\n : fields.map((field) => ` ${propertyKey(field.name)}: \"${field.cast}\",`).join(\"\\n\");\n\n return `import { defineResource } from \"@warlock.js/core\";\n\n/** What ${spec.resource.pascal} looks like in a response. */\nexport const ${spec.resource.pascal}Resource = defineResource({\n schema: {\n${body}\n },\n});\n`;\n}\n\n/** `controllers/<name>.controller.ts` — one handler per file. */\nexport function endpointControllerStub(spec: EndpointSpec): string {\n const resource = `${spec.resource.pascal}Resource`;\n const key = resourceResponseKey(spec);\n const status = endpointStatus(spec);\n const respond = status === 201 ? \"successCreate\" : \"success\";\n const controller = `${spec.name.camel}Controller`;\n const schemaType = `${spec.name.pascal}Schema`;\n const handlerType =\n spec.access === \"guarded\"\n ? `GuardedRequestHandler<${schemaType}>`\n : `RequestHandler<Request<${schemaType}>>`;\n const coreImport =\n spec.access === \"guarded\"\n ? `import { t } from \"@warlock.js/core\";\nimport { type GuardedRequestHandler } from \"app/auth/requests/guarded.request\";`\n : `import { type Request, type RequestHandler, t } from \"@warlock.js/core\";`;\n\n return `${coreImport}\nimport { ${resource} } from \"../resources/${spec.resource.singular.kebab}.resource\";\nimport { type ${schemaType}, ${spec.name.camel}Schema } from \"../schema/${spec.name.kebab}.schema\";\nimport { ${spec.name.camel}Service } from \"../services/${spec.name.kebab}.service\";\n\n/** ${endpointLabel(spec)} */\nexport const ${controller}: ${handlerType} = async ({\n request,\n response,\n}) => {\n const ${key} = await ${spec.name.camel}Service(request.validated());\n\n return response.${respond}({\n message: t(\"${spec.module}.${successMessageKey(spec)}\"),\n ${key}: new ${resource}(${key}),\n });\n};\n\n${controller}.description = \"${successMessage(spec).replace(\" completed successfully.\", \"\")}\";\n\n${controller}.validation = {\n schema: ${spec.name.camel}Schema,\n};\n\n// Documents the success response for \\`warlock generate.openapi\\` and the typed route map.\n${controller}.responseSchema = {\n ${status}: {\n body: {\n message: \"string\",\n ${key}: ${resource},\n },\n },\n};\n`;\n}\n\n/** The import lines a module `routes.ts` needs for this endpoint. */\nexport function endpointRouteImports(spec: EndpointSpec): string[] {\n const imports = [\n `import { ${spec.name.camel}Controller } from \"./controllers/${spec.name.kebab}.controller\";`,\n ];\n\n return imports;\n}\n\n/** The registration block appended to the module's `routes.ts`. */\nexport function endpointRouteRegistration(spec: EndpointSpec): string {\n const controller = `${spec.name.camel}Controller`;\n\n if (spec.access === \"public\") {\n return `// ${endpointLabel(spec)} — public on purpose: no auth guard.\nrouter.${spec.method}(\"${spec.path}\", ${controller}, { public: true });\n`;\n }\n\n return `guarded(() => {\n router.${spec.method}(\"${spec.path}\", ${controller});\n});\n`;\n}\n\n/** A fresh module `routes.ts` holding only this endpoint. */\nexport function endpointRoutesFileStub(spec: EndpointSpec): string {\n const imports = [`import { router } from \"@warlock.js/core\";`];\n\n if (spec.access === \"guarded\") {\n imports.push(`import { guarded } from \"app/shared/utils/router\";`);\n }\n\n imports.push(...endpointRouteImports(spec));\n\n return `${imports.join(\"\\n\")}\n\n${endpointRouteRegistration(spec)}`;\n}\n\n/** The path the generated test requests: route params get a placeholder. */\nexport function endpointTestPath(spec: EndpointSpec): string {\n return spec.path.replace(/:[A-Za-z0-9_]+\\??/g, \"1\");\n}\n\n/** The request input the generated test sends: every field JSON can carry. */\nexport function endpointSampleInput(spec: EndpointSpec): Record<string, unknown> {\n const input: Record<string, unknown> = {};\n\n for (const field of spec.fields) {\n if (field.sample !== undefined) input[field.name] = field.sample;\n }\n\n return input;\n}\n\n/** The part of the input the response echoes unchanged. */\nfunction comparableInput(spec: EndpointSpec): Record<string, unknown> {\n const input: Record<string, unknown> = {};\n\n for (const field of spec.fields) {\n if (field.comparable) input[field.name] = field.sample;\n }\n\n return input;\n}\n\n/** A required field the test can drop to prove validation runs, if any. */\nfunction droppableRequiredField(spec: EndpointSpec) {\n return spec.fields.find((field) => field.required && field.sample !== undefined);\n}\n\n/** Fields JSON cannot carry (files): the happy path needs multipart instead. */\nfunction uncarriableRequiredFields(spec: EndpointSpec): string[] {\n return spec.fields\n .filter((field) => field.required && field.sample === undefined)\n .map((field) => field.name);\n}\n\nfunction propertyKey(name: string): string {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\n/** A TypeScript literal for a JSON value: unquoted identifier keys, trailing commas. */\nfunction toLiteral(value: unknown, indent: string): string {\n if (Array.isArray(value)) {\n if (value.length === 0) return \"[]\";\n\n return `[\\n${value.map((item) => `${indent} ${toLiteral(item, `${indent} `)},`).join(\"\\n\")}\\n${indent}]`;\n }\n\n if (typeof value === \"object\" && value !== null) {\n const entries = Object.entries(value);\n\n if (entries.length === 0) return \"{}\";\n\n return `{\\n${entries\n .map(([key, item]) => `${indent} ${propertyKey(key)}: ${toLiteral(item, `${indent} `)},`)\n .join(\"\\n\")}\\n${indent}}`;\n }\n\n return JSON.stringify(value);\n}\n\nfunction indentJson(value: unknown, indent: string): string {\n return toLiteral(value, indent);\n}\n\n/**\n * The statement that sends `inputExpression` to the endpoint, through\n * `client` (`testRequest`-shaped helpers or an `actingAs()` client).\n */\nfunction sendRequest(spec: EndpointSpec, client: string, inputExpression: string): string {\n const path = JSON.stringify(endpointTestPath(spec));\n\n switch (spec.method) {\n case \"get\":\n return `${client === \"\" ? \"testGet\" : `${client}.get`}(${path} + \"?\" + new URLSearchParams(toQuery(${inputExpression})).toString())`;\n case \"delete\":\n return `${client === \"\" ? \"testRequest\" : `${client}.request`}(${path}, {\n method: \"DELETE\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(${inputExpression}),\n })`;\n default: {\n const helper = `test${spec.method.charAt(0).toUpperCase()}${spec.method.slice(1)}`;\n\n return `${client === \"\" ? helper : `${client}.${spec.method}`}(${path}, ${inputExpression})`;\n }\n }\n}\n\n/** The `@warlock.js/core/tests` helpers a test sends anonymous requests with. */\nfunction anonymousHelpers(spec: EndpointSpec): string[] {\n switch (spec.method) {\n case \"get\":\n return [\"testGet\"];\n case \"delete\":\n return [\"testRequest\"];\n default:\n return [`test${spec.method.charAt(0).toUpperCase()}${spec.method.slice(1)}`];\n }\n}\n\n/**\n * `tests/<name>.test.ts` — requests the endpoint over the real HTTP stack\n * (the test server `warlock add test` wires up): routing, middleware,\n * validation, controller, resource and serialization all run.\n */\nexport function endpointTestStub(spec: EndpointSpec): string {\n const label = endpointLabel(spec);\n const key = resourceResponseKey(spec);\n const status = endpointStatus(spec);\n const input = endpointSampleInput(spec);\n const expected = comparableInput(spec);\n const dropped = droppableRequiredField(spec);\n const uncarriable = uncarriableRequiredFields(spec);\n const guarded = spec.access === \"guarded\";\n const needsQuery = spec.method === \"get\";\n const helpers = new Set<string>([\"expectJson\", ...anonymousHelpers(spec)]);\n\n if (guarded) helpers.add(\"actingAs\");\n\n const lines: string[] = [];\n\n if (guarded) {\n lines.push(`import type { Auth } from \"@warlock.js/auth\";`);\n lines.push(`import type { ChildModel } from \"@warlock.js/cascade\";`);\n lines.push(`import { config } from \"@warlock.js/core\";`);\n }\n\n lines.push(`import { ${[...helpers].sort().join(\", \")} } from \"@warlock.js/core/tests\";`);\n\n if (guarded) lines.push(`import { randomUUID } from \"node:crypto\";`);\n\n lines.push(\n `import { ${guarded ? \"afterAll, describe, expect, it\" : \"describe, expect, it\"} } from \"vitest\";`,\n );\n\n const header = `${lines.join(\"\\n\")}\n\n/** A valid request for ${label}, derived from its schema. */\nconst validInput: Record<string, unknown> = ${indentJson(input, \"\")};\n${\n needsQuery\n ? `\n/** Query values travel as strings; numeric schema fields need \\`.coerce()\\`. */\nfunction toQuery(input: Record<string, unknown>): Record<string, string> {\n return Object.fromEntries(Object.entries(input).map(([key, value]) => [key, String(value)]));\n}\n`\n : \"\"\n}`;\n\n const happyAssertions = (indent: string) =>\n [\n `const body = await expectJson<{ message: string; ${key}: Record<string, unknown> }>(`,\n ` response,`,\n ` ${status},`,\n `);`,\n ``,\n `expect(typeof body.message).toBe(\"string\");`,\n `expect(body.${key}).toMatchObject(${indentJson(expected, indent)});`,\n ]\n .map((line, index) => (index === 0 || line === \"\" ? line : `${indent}${line}`))\n .join(\"\\n\");\n\n const dropStatement = dropped\n ? `const input = { ...validInput };\n\n delete input[${JSON.stringify(dropped.name)}];\n`\n : \"\";\n\n const validationCase = dropped\n ? `\n it(\"rejects a request without ${dropped.name}\", async () => {\n ${dropStatement}\n const response = await ${sendRequest(spec, \"\", \"input\")};\n\n expect(response.status).toBeGreaterThanOrEqual(400);\n expect(response.status).toBeLessThan(500);\n });\n`\n : \"\";\n\n if (!guarded) {\n const happy =\n uncarriable.length > 0\n ? ` it.todo(\"answers a valid request — send ${uncarriable.join(\", \")} as multipart form data (JSON cannot carry files)\");\\n`\n : ` it(\"answers a valid request with the ${spec.resource.singular.pascal} resource\", async () => {\n const response = await ${sendRequest(spec, \"\", \"validInput\")};\n\n ${happyAssertions(\" \")}\n });\n`;\n\n return `${header}\ndescribe(\"${label}\", () => {\n${happy}${validationCase}});\n`;\n }\n\n const signedInHappy =\n uncarriable.length > 0\n ? ` it.todo(\"answers a signed-in user — send ${uncarriable.join(\", \")} as multipart form data (JSON cannot carry files)\");\\n`\n : ` it(\"answers a signed-in user with the ${spec.resource.singular.pascal} resource\", async () => {\n const client = await signIn();\n\n try {\n const response = await ${sendRequest(spec, \"client\", \"validInput\")};\n\n ${happyAssertions(\" \")}\n } finally {\n await client.dispose();\n }\n });\n`;\n\n const guardedValidation = dropped\n ? `\n it(\"rejects a request without ${dropped.name}\", async () => {\n const client = await signIn();\n\n try {\n const input = { ...validInput };\n\n delete input[${JSON.stringify(dropped.name)}];\n\n const response = await ${sendRequest(spec, \"client\", \"input\")};\n\n expect(response.status).toBeGreaterThanOrEqual(400);\n expect(response.status).toBeLessThan(500);\n } finally {\n await client.dispose();\n }\n });\n`\n : \"\";\n\n return `${header}\ndescribe(\"${label}\", () => {\n const users: Auth[] = [];\n\n /** A real user and a real access token; adjust the fields if your user model requires more. */\n async function signIn() {\n const User = config.key<ChildModel<Auth>>(\"auth.userType.user\");\n\n if (!User) throw new Error(\"This test needs the configured auth.userType.user model.\");\n\n const user = await User.create({\n name: \"Endpoint test user\",\n email: \"endpoint-\" + randomUUID() + \"@example.test\",\n password: \"test-password\",\n });\n\n users.push(user);\n\n return actingAs(user);\n }\n\n afterAll(async () => {\n await Promise.all(users.splice(0).map((user) => user.destroy({ strategy: \"permanent\" })));\n });\n\n it(\"rejects an anonymous request\", async () => {\n const response = await ${sendRequest(spec, \"\", \"validInput\")};\n\n expect(response.status).toBe(401);\n });\n\n${signedInHappy}${guardedValidation}});\n`;\n}\n\n/** The locale entry merged into the module's `utils/locales.json`. */\nexport function endpointLocaleEntries(spec: EndpointSpec): Record<string, Record<string, string>> {\n return { [successMessageKey(spec)]: { en: successMessage(spec) } };\n}\n"],"mappings":";;AAiCA,SAAgB,cAAc,MAA4B;CACxD,OAAO,GAAG,KAAK,OAAO,YAAY,EAAE,GAAG,KAAK;AAC9C;;AAGA,SAAgB,eAAe,MAA+B;CAC5D,OAAO,KAAK,WAAW,SAAS,MAAM;AACxC;;AAGA,SAAgB,kBAAkB,MAA4B;CAC5D,OAAO,GAAG,KAAK,KAAK,MAAM;AAC5B;;AAGA,SAAgB,eAAe,MAA4B;CACzD,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG;CAEjD,OAAO,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,MAAM,MAAM,CAAC,EAAE;AAC3D;;AAGA,SAAgB,oBAAoB,MAA4B;CAC9D,OAAO,KAAK,SAAS,SAAS;AAChC;;AAGA,SAAgB,mBAAmB,MAA4B;CAC7D,OAAO;;wBAEe,cAAc,IAAI,EAAE;eAC7B,KAAK,KAAK,MAAM;;;;;cAKjB,KAAK,KAAK,OAAO,wBAAwB,KAAK,KAAK,MAAM;;AAEvE;;AAGA,SAAgB,oBAAoB,MAA4B;CAC9D,OAAO,iBAAiB,KAAK,KAAK,OAAO,2BAA2B,KAAK,KAAK,MAAM;;;qBAGjE,cAAc,IAAI,EAAE;;;wBAGjB,KAAK,KAAK,MAAM,iBAAiB,KAAK,KAAK,OAAO;;;;;AAK1E;;AAGA,SAAgB,qBAAqB,MAA4B;CAC/D,MAAM,SAAS,KAAK,OAAO,QAAQ,UAAU,MAAM,SAAS,MAAS;CACrE,MAAM,OACJ,OAAO,WAAW,IACd,4EACA,OAAO,KAAK,UAAU,OAAO,YAAY,MAAM,IAAI,EAAE,KAAK,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI;CAEzF,OAAO;;WAEE,KAAK,SAAS,OAAO;eACjB,KAAK,SAAS,OAAO;;EAElC,KAAK;;;;AAIP;;AAGA,SAAgB,uBAAuB,MAA4B;CACjE,MAAM,WAAW,GAAG,KAAK,SAAS,OAAO;CACzC,MAAM,MAAM,oBAAoB,IAAI;CACpC,MAAM,SAAS,eAAe,IAAI;CAClC,MAAM,UAAU,WAAW,MAAM,kBAAkB;CACnD,MAAM,aAAa,GAAG,KAAK,KAAK,MAAM;CACtC,MAAM,aAAa,GAAG,KAAK,KAAK,OAAO;CACvC,MAAM,cACJ,KAAK,WAAW,YACZ,yBAAyB,WAAW,KACpC,0BAA0B,WAAW;CAO3C,OAAO,GALL,KAAK,WAAW,YACZ;mFAEA,2EAEe;WACZ,SAAS,wBAAwB,KAAK,SAAS,SAAS,MAAM;gBACzD,WAAW,IAAI,KAAK,KAAK,MAAM,2BAA2B,KAAK,KAAK,MAAM;WAC/E,KAAK,KAAK,MAAM,8BAA8B,KAAK,KAAK,MAAM;;MAEnE,cAAc,IAAI,EAAE;eACX,WAAW,IAAI,YAAY;;;;UAIhC,IAAI,WAAW,KAAK,KAAK,MAAM;;oBAErB,QAAQ;kBACV,KAAK,OAAO,GAAG,kBAAkB,IAAI,EAAE;MACnD,IAAI,QAAQ,SAAS,GAAG,IAAI;;;;EAIhC,WAAW,kBAAkB,eAAe,IAAI,CAAC,CAAC,QAAQ,4BAA4B,EAAE,EAAE;;EAE1F,WAAW;YACD,KAAK,KAAK,MAAM;;;;EAI1B,WAAW;IACT,OAAO;;;QAGH,IAAI,IAAI,SAAS;;;;;AAKzB;;AAGA,SAAgB,qBAAqB,MAA8B;CAKjE,OAAO,CAHL,YAAY,KAAK,KAAK,MAAM,mCAAmC,KAAK,KAAK,MAAM,cAGpE;AACf;;AAGA,SAAgB,0BAA0B,MAA4B;CACpE,MAAM,aAAa,GAAG,KAAK,KAAK,MAAM;CAEtC,IAAI,KAAK,WAAW,UAClB,OAAO,MAAM,cAAc,IAAI,EAAE;SAC5B,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,WAAW;;CAIjD,OAAO;WACE,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,WAAW;;;AAGrD;;AAGA,SAAgB,uBAAuB,MAA4B;CACjE,MAAM,UAAU,CAAC,4CAA4C;CAE7D,IAAI,KAAK,WAAW,WAClB,QAAQ,KAAK,oDAAoD;CAGnE,QAAQ,KAAK,GAAG,qBAAqB,IAAI,CAAC;CAE1C,OAAO,GAAG,QAAQ,KAAK,IAAI,EAAE;;EAE7B,0BAA0B,IAAI;AAChC;;AAGA,SAAgB,iBAAiB,MAA4B;CAC3D,OAAO,KAAK,KAAK,QAAQ,sBAAsB,GAAG;AACpD;;AAGA,SAAgB,oBAAoB,MAA6C;CAC/E,MAAM,QAAiC,CAAC;CAExC,KAAK,MAAM,SAAS,KAAK,QACvB,IAAI,MAAM,WAAW,QAAW,MAAM,MAAM,QAAQ,MAAM;CAG5D,OAAO;AACT;;AAGA,SAAS,gBAAgB,MAA6C;CACpE,MAAM,QAAiC,CAAC;CAExC,KAAK,MAAM,SAAS,KAAK,QACvB,IAAI,MAAM,YAAY,MAAM,MAAM,QAAQ,MAAM;CAGlD,OAAO;AACT;;AAGA,SAAS,uBAAuB,MAAoB;CAClD,OAAO,KAAK,OAAO,MAAM,UAAU,MAAM,YAAY,MAAM,WAAW,MAAS;AACjF;;AAGA,SAAS,0BAA0B,MAA8B;CAC/D,OAAO,KAAK,OACT,QAAQ,UAAU,MAAM,YAAY,MAAM,WAAW,MAAS,CAAC,CAC/D,KAAK,UAAU,MAAM,IAAI;AAC9B;AAEA,SAAS,YAAY,MAAsB;CACzC,OAAO,6BAA6B,KAAK,IAAI,IAAI,OAAO,KAAK,UAAU,IAAI;AAC7E;;AAGA,SAAS,UAAU,OAAgB,QAAwB;CACzD,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,IAAI,MAAM,WAAW,GAAG,OAAO;EAE/B,OAAO,MAAM,MAAM,KAAK,SAAS,GAAG,OAAO,IAAI,UAAU,MAAM,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI,OAAO;CAC1G;CAEA,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;EAC/C,MAAM,UAAU,OAAO,QAAQ,KAAK;EAEpC,IAAI,QAAQ,WAAW,GAAG,OAAO;EAEjC,OAAO,MAAM,QACV,KAAK,CAAC,KAAK,UAAU,GAAG,OAAO,IAAI,YAAY,GAAG,EAAE,IAAI,UAAU,MAAM,GAAG,OAAO,GAAG,EAAE,EAAE,CAAC,CAC1F,KAAK,IAAI,EAAE,IAAI,OAAO;CAC3B;CAEA,OAAO,KAAK,UAAU,KAAK;AAC7B;AAEA,SAAS,WAAW,OAAgB,QAAwB;CAC1D,OAAO,UAAU,OAAO,MAAM;AAChC;;;;;AAMA,SAAS,YAAY,MAAoB,QAAgB,iBAAiC;CACxF,MAAM,OAAO,KAAK,UAAU,iBAAiB,IAAI,CAAC;CAElD,QAAQ,KAAK,QAAb;EACE,KAAK,OACH,OAAO,GAAG,WAAW,KAAK,YAAY,GAAG,OAAO,MAAM,GAAG,KAAK,uCAAuC,gBAAgB;EACvH,KAAK,UACH,OAAO,GAAG,WAAW,KAAK,gBAAgB,GAAG,OAAO,UAAU,GAAG,KAAK;;;6BAG/C,gBAAgB;;EAEzC,SAAS;GACP,MAAM,SAAS,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,OAAO,MAAM,CAAC;GAE/E,OAAO,GAAG,WAAW,KAAK,SAAS,GAAG,OAAO,GAAG,KAAK,SAAS,GAAG,KAAK,IAAI,gBAAgB;EAC5F;CACF;AACF;;AAGA,SAAS,iBAAiB,MAA8B;CACtD,QAAQ,KAAK,QAAb;EACE,KAAK,OACH,OAAO,CAAC,SAAS;EACnB,KAAK,UACH,OAAO,CAAC,aAAa;EACvB,SACE,OAAO,CAAC,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,OAAO,MAAM,CAAC,GAAG;CAC/E;AACF;;;;;;AAOA,SAAgB,iBAAiB,MAA4B;CAC3D,MAAM,QAAQ,cAAc,IAAI;CAChC,MAAM,MAAM,oBAAoB,IAAI;CACpC,MAAM,SAAS,eAAe,IAAI;CAClC,MAAM,QAAQ,oBAAoB,IAAI;CACtC,MAAM,WAAW,gBAAgB,IAAI;CACrC,MAAM,UAAU,uBAAuB,IAAI;CAC3C,MAAM,cAAc,0BAA0B,IAAI;CAClD,MAAM,UAAU,KAAK,WAAW;CAChC,MAAM,aAAa,KAAK,WAAW;CACnC,MAAM,0BAAU,IAAI,IAAY,CAAC,cAAc,GAAG,iBAAiB,IAAI,CAAC,CAAC;CAEzE,IAAI,SAAS,QAAQ,IAAI,UAAU;CAEnC,MAAM,QAAkB,CAAC;CAEzB,IAAI,SAAS;EACX,MAAM,KAAK,+CAA+C;EAC1D,MAAM,KAAK,wDAAwD;EACnE,MAAM,KAAK,4CAA4C;CACzD;CAEA,MAAM,KAAK,YAAY,CAAC,GAAG,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,kCAAkC;CAExF,IAAI,SAAS,MAAM,KAAK,2CAA2C;CAEnE,MAAM,KACJ,YAAY,UAAU,mCAAmC,uBAAuB,kBAClF;CAEA,MAAM,SAAS,GAAG,MAAM,KAAK,IAAI,EAAE;;0BAEX,MAAM;8CACc,WAAW,OAAO,EAAE,EAAE;EAElE,aACI;;;;;IAMA;CAGJ,MAAM,mBAAmB,WACvB;EACE,oDAAoD,IAAI;EACxD;EACA,KAAK,OAAO;EACZ;EACA;EACA;EACA,eAAe,IAAI,kBAAkB,WAAW,UAAU,MAAM,EAAE;CACpE,CAAC,CACE,KAAK,MAAM,UAAW,UAAU,KAAK,SAAS,KAAK,OAAO,GAAG,SAAS,MAAO,CAAC,CAC9E,KAAK,IAAI;CAEd,MAAM,gBAAgB,UAClB;;mBAEa,KAAK,UAAU,QAAQ,IAAI,EAAE;IAE1C;CAEJ,MAAM,iBAAiB,UACnB;kCAC4B,QAAQ,KAAK;MACzC,cAAc;6BACS,YAAY,MAAM,IAAI,OAAO,EAAE;;;;;IAMtD;CAEJ,IAAI,CAAC,SAWH,OAAO,GAAG,OAAO;YACT,MAAM;EAVZ,YAAY,SAAS,IACjB,6CAA6C,YAAY,KAAK,IAAI,EAAE,0DACpE,0CAA0C,KAAK,SAAS,SAAS,OAAO;6BACrD,YAAY,MAAM,IAAI,YAAY,EAAE;;MAE3D,gBAAgB,MAAM,EAAE;;IAMpB,eAAe;;CAIvB,MAAM,gBACJ,YAAY,SAAS,IACjB,8CAA8C,YAAY,KAAK,IAAI,EAAE,0DACrE,2CAA2C,KAAK,SAAS,SAAS,OAAO;;;;+BAIlD,YAAY,MAAM,UAAU,YAAY,EAAE;;QAEjE,gBAAgB,QAAQ,EAAE;;;;;;CAOhC,MAAM,oBAAoB,UACtB;kCAC4B,QAAQ,KAAK;;;;;;qBAM1B,KAAK,UAAU,QAAQ,IAAI,EAAE;;+BAEnB,YAAY,MAAM,UAAU,OAAO,EAAE;;;;;;;;IAS9D;CAEJ,OAAO,GAAG,OAAO;YACP,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;6BAyBW,YAAY,MAAM,IAAI,YAAY,EAAE;;;;;EAK/D,gBAAgB,kBAAkB;;AAEpC;;AAGA,SAAgB,sBAAsB,MAA4D;CAChG,OAAO,GAAG,kBAAkB,IAAI,IAAI,EAAE,IAAI,eAAe,IAAI,EAAE,EAAE;AACnE"}
@@ -92,7 +92,6 @@ function sampleString(node, seed) {
92
92
  case "uuid": return "00000000-0000-4000-8000-000000000001";
93
93
  case "date-time": return "2026-01-01T00:00:00.000Z";
94
94
  case "date": return "2026-01-01";
95
- default: break;
96
95
  }
97
96
  const minLength = node.minLength ?? 1;
98
97
  let value = `${seed} sample`;
@@ -133,5 +132,5 @@ function readEndpointFields(jsonSchema) {
133
132
  }
134
133
 
135
134
  //#endregion
136
- export { readEndpointFields };
135
+ export { castForNode, readEndpointFields, sampleForNode };
137
136
  //# sourceMappingURL=endpoint-schema.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-schema.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/utils/endpoint-schema.ts"],"sourcesContent":["/**\n * What the endpoint generator needs to know about a request schema, read\n * from the JSON Schema seal produces (`validator.toJsonSchema()`).\n *\n * Kept free of seal imports: it works on the plain JSON Schema object, so it\n * is unit-testable and survives seal's internals changing.\n */\n\n/** The JSON Schema subset this module reads. */\nexport type JsonSchemaNode = {\n type?: string | string[];\n format?: string;\n enum?: unknown[];\n const?: unknown;\n minimum?: number;\n exclusiveMinimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n minItems?: number;\n items?: JsonSchemaNode;\n properties?: Record<string, JsonSchemaNode>;\n required?: string[];\n anyOf?: JsonSchemaNode[];\n oneOf?: JsonSchemaNode[];\n contentMediaType?: string;\n contentEncoding?: string;\n};\n\n/** One top-level field of the request schema. */\nexport type EndpointField = {\n name: string;\n required: boolean;\n /** The resource cast for this field, or `undefined` when it has no plain JSON shape (a file). */\n cast?: string;\n /** A deterministic valid value, or `undefined` when JSON cannot carry one (a file). */\n sample?: unknown;\n /**\n * Whether the response echoes the sample unchanged, so a generated test can\n * compare it. Dates are parsed and re-cast, so they are not comparable.\n */\n comparable: boolean;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** The non-null JSON types a node allows, and whether `null` is one of them. */\nfunction typesOf(node: JsonSchemaNode): { types: string[]; nullable: boolean } {\n const variants = node.anyOf ?? node.oneOf;\n\n if (variants) {\n const all = variants.map(typesOf);\n\n return {\n types: all.flatMap((entry) => entry.types),\n nullable: all.some((entry) => entry.nullable),\n };\n }\n\n const raw = node.type === undefined ? [] : Array.isArray(node.type) ? node.type : [node.type];\n\n return { types: raw.filter((type) => type !== \"null\"), nullable: raw.includes(\"null\") };\n}\n\nfunction primaryNode(node: JsonSchemaNode): JsonSchemaNode {\n const variants = node.anyOf ?? node.oneOf;\n\n if (!variants) return node;\n\n return (\n variants.find((variant) => !typesOf(variant).types.every((type) => type === \"null\")) ?? node\n );\n}\n\n/** A file upload: JSON cannot carry it, so it has no sample and no cast. */\nfunction isFileNode(node: JsonSchemaNode): boolean {\n return (\n node.format === \"binary\" ||\n node.contentEncoding === \"binary\" ||\n node.contentMediaType !== undefined\n );\n}\n\nconst CASTS: Record<string, string> = {\n string: \"string\",\n integer: \"int\",\n number: \"number\",\n boolean: \"boolean\",\n array: \"array\",\n object: \"object\",\n};\n\n/** `\"string\"` or `\"number\"` when every enum value has that type. */\nfunction enumValuesType(node: JsonSchemaNode): string | undefined {\n if (!node.enum || node.enum.length === 0) return undefined;\n if (node.enum.every((value) => typeof value === \"string\")) return \"string\";\n if (node.enum.every((value) => typeof value === \"number\")) return \"number\";\n\n return undefined;\n}\n\n/** The resource cast for a field, with `?` when the value may be null or absent. */\nexport function castForNode(node: JsonSchemaNode, required: boolean): string | undefined {\n const primary = primaryNode(node);\n\n if (isFileNode(primary)) return undefined;\n\n const { types, nullable } = typesOf(node);\n const enumType = enumValuesType(primary);\n const only = types.length === 1 ? types[0] : undefined;\n const base = enumType ?? (only === undefined ? undefined : CASTS[only]);\n\n if (base === undefined) return undefined;\n\n if (base === \"string\" && (primary.format === \"date-time\" || primary.format === \"date\")) {\n return nullable || !required ? \"date?\" : \"date\";\n }\n\n return nullable || !required ? `${base}?` : base;\n}\n\n/**\n * A deterministic value that satisfies `node`, or `undefined` when JSON cannot\n * express one. `seed` keeps values readable and stable between runs.\n */\nexport function sampleForNode(node: JsonSchemaNode, seed: string): unknown {\n const primary = primaryNode(node);\n\n if (isFileNode(primary)) return undefined;\n if (primary.const !== undefined) return primary.const;\n if (primary.enum && primary.enum.length > 0) return primary.enum[0];\n\n const { types } = typesOf(node);\n const type = types[0];\n\n switch (type) {\n case \"string\":\n return sampleString(primary, seed);\n case \"integer\":\n return sampleNumber(primary, true);\n case \"number\":\n return sampleNumber(primary, false);\n case \"boolean\":\n return true;\n case \"array\": {\n const count = primary.minItems ?? 0;\n const item = primary.items ? sampleForNode(primary.items, `${seed}-item`) : undefined;\n\n if (count > 0 && item === undefined) return undefined;\n\n return Array.from({ length: count }, () => item);\n }\n case \"object\":\n return sampleObject(primary, seed);\n default:\n return undefined;\n }\n}\n\nfunction sampleNumber(node: JsonSchemaNode, integer: boolean): number {\n const lower =\n node.minimum ?? (node.exclusiveMinimum !== undefined ? node.exclusiveMinimum + 1 : 1);\n let value = integer ? Math.ceil(lower) : lower;\n\n if (node.maximum !== undefined && value > node.maximum) value = node.maximum;\n\n return value;\n}\n\nfunction sampleString(node: JsonSchemaNode, seed: string): string {\n switch (node.format) {\n case \"email\":\n return `${seed.replace(/[^a-z0-9]/gi, \"\").toLowerCase() || \"user\"}@example.test`;\n case \"uri\":\n case \"url\":\n return `https://example.test/${seed}`;\n case \"uuid\":\n return \"00000000-0000-4000-8000-000000000001\";\n case \"date-time\":\n return \"2026-01-01T00:00:00.000Z\";\n case \"date\":\n return \"2026-01-01\";\n default:\n break;\n }\n\n const minLength = node.minLength ?? 1;\n let value = `${seed} sample`;\n\n while (value.length < minLength) value += \" sample\";\n\n return node.maxLength !== undefined ? value.slice(0, Math.max(node.maxLength, minLength)) : value;\n}\n\nfunction sampleObject(node: JsonSchemaNode, seed: string): Record<string, unknown> | undefined {\n const required = new Set(node.required ?? []);\n const result: Record<string, unknown> = {};\n\n for (const [key, child] of Object.entries(node.properties ?? {})) {\n const value = sampleForNode(child, key);\n\n if (value === undefined) {\n if (required.has(key)) return undefined;\n continue;\n }\n\n result[key] = value;\n }\n\n void seed;\n\n return result;\n}\n\n/** Read the top-level fields of a request schema's JSON Schema. */\nexport function readEndpointFields(jsonSchema: unknown): EndpointField[] {\n if (!isRecord(jsonSchema)) return [];\n\n const node = jsonSchema as JsonSchemaNode;\n const required = new Set(node.required ?? []);\n\n return Object.entries(node.properties ?? {}).map(([name, child]) => {\n const isRequired = required.has(name);\n const cast = castForNode(child, isRequired);\n const sample = sampleForNode(child, name);\n const field: EndpointField = {\n name,\n required: isRequired,\n comparable:\n sample !== undefined &&\n cast !== undefined &&\n !cast.startsWith(\"date\") &&\n !cast.startsWith(\"object\"),\n };\n\n if (cast !== undefined) field.cast = cast;\n if (sample !== undefined) field.sample = sample;\n\n return field;\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"endpoint-schema.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/utils/endpoint-schema.ts"],"sourcesContent":["/**\n * What the endpoint generator needs to know about a request schema, read\n * from the JSON Schema seal produces (`validator.toJsonSchema()`).\n *\n * Kept free of seal imports: it works on the plain JSON Schema object, so it\n * is unit-testable and survives seal's internals changing.\n */\n\n/** The JSON Schema subset this module reads. */\nexport type JsonSchemaNode = {\n type?: string | string[];\n format?: string;\n enum?: unknown[];\n const?: unknown;\n minimum?: number;\n exclusiveMinimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n minItems?: number;\n items?: JsonSchemaNode;\n properties?: Record<string, JsonSchemaNode>;\n required?: string[];\n anyOf?: JsonSchemaNode[];\n oneOf?: JsonSchemaNode[];\n contentMediaType?: string;\n contentEncoding?: string;\n};\n\n/** One top-level field of the request schema. */\nexport type EndpointField = {\n name: string;\n required: boolean;\n /** The resource cast for this field, or `undefined` when it has no plain JSON shape (a file). */\n cast?: string;\n /** A deterministic valid value, or `undefined` when JSON cannot carry one (a file). */\n sample?: unknown;\n /**\n * Whether the response echoes the sample unchanged, so a generated test can\n * compare it. Dates are parsed and re-cast, so they are not comparable.\n */\n comparable: boolean;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** The non-null JSON types a node allows, and whether `null` is one of them. */\nfunction typesOf(node: JsonSchemaNode): { types: string[]; nullable: boolean } {\n const variants = node.anyOf ?? node.oneOf;\n\n if (variants) {\n const all = variants.map(typesOf);\n\n return {\n types: all.flatMap((entry) => entry.types),\n nullable: all.some((entry) => entry.nullable),\n };\n }\n\n const raw = node.type === undefined ? [] : Array.isArray(node.type) ? node.type : [node.type];\n\n return { types: raw.filter((type) => type !== \"null\"), nullable: raw.includes(\"null\") };\n}\n\nfunction primaryNode(node: JsonSchemaNode): JsonSchemaNode {\n const variants = node.anyOf ?? node.oneOf;\n\n if (!variants) return node;\n\n return (\n variants.find((variant) => !typesOf(variant).types.every((type) => type === \"null\")) ?? node\n );\n}\n\n/** A file upload: JSON cannot carry it, so it has no sample and no cast. */\nfunction isFileNode(node: JsonSchemaNode): boolean {\n return (\n node.format === \"binary\" ||\n node.contentEncoding === \"binary\" ||\n node.contentMediaType !== undefined\n );\n}\n\nconst CASTS: Record<string, string> = {\n string: \"string\",\n integer: \"int\",\n number: \"number\",\n boolean: \"boolean\",\n array: \"array\",\n object: \"object\",\n};\n\n/** `\"string\"` or `\"number\"` when every enum value has that type. */\nfunction enumValuesType(node: JsonSchemaNode): string | undefined {\n if (!node.enum || node.enum.length === 0) return undefined;\n if (node.enum.every((value) => typeof value === \"string\")) return \"string\";\n if (node.enum.every((value) => typeof value === \"number\")) return \"number\";\n\n return undefined;\n}\n\n/** The resource cast for a field, with `?` when the value may be null or absent. */\nexport function castForNode(node: JsonSchemaNode, required: boolean): string | undefined {\n const primary = primaryNode(node);\n\n if (isFileNode(primary)) return undefined;\n\n const { types, nullable } = typesOf(node);\n const enumType = enumValuesType(primary);\n const only = types.length === 1 ? types[0] : undefined;\n const base = enumType ?? (only === undefined ? undefined : CASTS[only]);\n\n if (base === undefined) return undefined;\n\n if (base === \"string\" && (primary.format === \"date-time\" || primary.format === \"date\")) {\n return nullable || !required ? \"date?\" : \"date\";\n }\n\n return nullable || !required ? `${base}?` : base;\n}\n\n/**\n * A deterministic value that satisfies `node`, or `undefined` when JSON cannot\n * express one. `seed` keeps values readable and stable between runs.\n */\nexport function sampleForNode(node: JsonSchemaNode, seed: string): unknown {\n const primary = primaryNode(node);\n\n if (isFileNode(primary)) return undefined;\n if (primary.const !== undefined) return primary.const;\n if (primary.enum && primary.enum.length > 0) return primary.enum[0];\n\n const { types } = typesOf(node);\n const type = types[0];\n\n switch (type) {\n case \"string\":\n return sampleString(primary, seed);\n case \"integer\":\n return sampleNumber(primary, true);\n case \"number\":\n return sampleNumber(primary, false);\n case \"boolean\":\n return true;\n case \"array\": {\n const count = primary.minItems ?? 0;\n const item = primary.items ? sampleForNode(primary.items, `${seed}-item`) : undefined;\n\n if (count > 0 && item === undefined) return undefined;\n\n return Array.from({ length: count }, () => item);\n }\n case \"object\":\n return sampleObject(primary, seed);\n default:\n return undefined;\n }\n}\n\nfunction sampleNumber(node: JsonSchemaNode, integer: boolean): number {\n const lower =\n node.minimum ?? (node.exclusiveMinimum !== undefined ? node.exclusiveMinimum + 1 : 1);\n let value = integer ? Math.ceil(lower) : lower;\n\n if (node.maximum !== undefined && value > node.maximum) value = node.maximum;\n\n return value;\n}\n\nfunction sampleString(node: JsonSchemaNode, seed: string): string {\n switch (node.format) {\n case \"email\":\n return `${seed.replace(/[^a-z0-9]/gi, \"\").toLowerCase() || \"user\"}@example.test`;\n case \"uri\":\n case \"url\":\n return `https://example.test/${seed}`;\n case \"uuid\":\n return \"00000000-0000-4000-8000-000000000001\";\n case \"date-time\":\n return \"2026-01-01T00:00:00.000Z\";\n case \"date\":\n return \"2026-01-01\";\n default:\n break;\n }\n\n const minLength = node.minLength ?? 1;\n let value = `${seed} sample`;\n\n while (value.length < minLength) value += \" sample\";\n\n return node.maxLength !== undefined ? value.slice(0, Math.max(node.maxLength, minLength)) : value;\n}\n\nfunction sampleObject(node: JsonSchemaNode, seed: string): Record<string, unknown> | undefined {\n const required = new Set(node.required ?? []);\n const result: Record<string, unknown> = {};\n\n for (const [key, child] of Object.entries(node.properties ?? {})) {\n const value = sampleForNode(child, key);\n\n if (value === undefined) {\n if (required.has(key)) return undefined;\n continue;\n }\n\n result[key] = value;\n }\n\n void seed;\n\n return result;\n}\n\n/** Read the top-level fields of a request schema's JSON Schema. */\nexport function readEndpointFields(jsonSchema: unknown): EndpointField[] {\n if (!isRecord(jsonSchema)) return [];\n\n const node = jsonSchema as JsonSchemaNode;\n const required = new Set(node.required ?? []);\n\n return Object.entries(node.properties ?? {}).map(([name, child]) => {\n const isRequired = required.has(name);\n const cast = castForNode(child, isRequired);\n const sample = sampleForNode(child, name);\n const field: EndpointField = {\n name,\n required: isRequired,\n comparable:\n sample !== undefined &&\n cast !== undefined &&\n !cast.startsWith(\"date\") &&\n !cast.startsWith(\"object\"),\n };\n\n if (cast !== undefined) field.cast = cast;\n if (sample !== undefined) field.sample = sample;\n\n return field;\n });\n}\n"],"mappings":"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"}
@@ -65,5 +65,5 @@ var Name = class Name {
65
65
  };
66
66
 
67
67
  //#endregion
68
- export { parseModulePath, parseName, pluralName, singularName };
68
+ export { Name, parseModulePath, parseName, pluralName, singularName };
69
69
  //# sourceMappingURL=name-parser.mjs.map
@@ -52,5 +52,5 @@ async function ensureComponentDirectory(module, type) {
52
52
  }
53
53
 
54
54
  //#endregion
55
- export { componentExists, ensureComponentDirectory, moduleExists, resolveComponentPath, resolveModulePath };
55
+ export { componentExists, ensureComponentDirectory, ensureDirectory, moduleExists, resolveComponentPath, resolveModulePath };
56
56
  //# sourceMappingURL=path-resolver.mjs.map
@@ -54,8 +54,9 @@ function formatInspectSummary(report) {
54
54
  async function inspectCommandAction({ options }) {
55
55
  const sections = parseInspectSections(stringOption(options.section));
56
56
  const json = options.json === true;
57
+ const boot = json ? await withConsoleOnStderr(() => bootForInspect()) : await bootForInspect();
57
58
  const report = await inspectApp({
58
- ...inspectOptionsFromBoot(json ? await withConsoleOnStderr(() => bootForInspect()) : await bootForInspect()),
59
+ ...inspectOptionsFromBoot(boot),
59
60
  sections
60
61
  });
61
62
  if (json) {
@@ -68,5 +69,5 @@ async function inspectCommandAction({ options }) {
68
69
  }
69
70
 
70
71
  //#endregion
71
- export { inspectCommandAction };
72
+ export { formatInspectSummary, inspectCommandAction };
72
73
  //# sourceMappingURL=inspect-command.action.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"inspect-command.action.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/cli/commands/inspect/inspect-command.action.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandActionData } from \"../../../commands/types\";\nimport { bootForInspect, inspectOptionsFromBoot } from \"../../../tooling/inspect/boot-for-inspect\";\nimport { inspectApp, parseInspectSections } from \"../../../tooling/inspect/inspect-app\";\nimport type { InspectReport } from \"../../../tooling/inspect/inspect-report.types\";\nimport { withConsoleOnStderr } from \"../routes/with-console-on-stderr\";\n\nfunction stringOption(value: string | number | boolean | undefined): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : undefined;\n}\n\n/**\n * The human summary `warlock inspect` prints without `--json`: one count per\n * section, the routes as `METHOD path [auth] name`, and the warnings.\n * Returned as lines so it is testable.\n */\nexport function formatInspectSummary(report: InspectReport): string[] {\n const lines: string[] = [\n `${report.app.name ?? \"app\"}${report.app.version ? `@${report.app.version}` : \"\"} (${report.app.runtimeStrategy}, Node ${report.app.node})`,\n \"\",\n ];\n\n const counts: [string, number | undefined][] = [\n [\"routes\", report.routes?.length],\n [\"models\", report.models?.length],\n [\"resources\", report.resources?.length],\n [\"config keys\", report.config?.length],\n [\"events\", report.events?.length],\n [\"pages\", report.pages?.length],\n [\"jobs\", report.jobs?.length],\n [\"schedules\", report.schedules?.length],\n [\"packages\", report.packages?.length],\n ];\n\n for (const [label, count] of counts) {\n if (count !== undefined) lines.push(` ${label.padEnd(12)} ${count}`);\n }\n\n if (report.routes && report.routes.length > 0) {\n lines.push(\"\", \"Routes:\");\n\n for (const route of report.routes) {\n const guard = route.auth.required ? \" [auth]\" : \"\";\n const name = route.name ? ` ${route.name}` : \"\";\n\n lines.push(` ${route.method.padEnd(7)} ${route.path}${guard}${name}`);\n }\n }\n\n if (report.warnings.length > 0) {\n lines.push(\"\", `${report.warnings.length} warning(s):`);\n\n for (const warning of report.warnings) {\n lines.push(` - ${warning.code ? `${warning.code} ` : \"\"}${warning.message}`);\n }\n }\n\n lines.push(\"\", \"Run `warlock inspect --json` for the full report.\");\n\n return lines;\n}\n\n/**\n * Action behind `warlock inspect`.\n *\n * Boots the app read-only (the `warlock doctor` boot pass: connectors booted,\n * none started, no connection, no port), then describes it with\n * `inspectApp()`. With `--json`, stdout carries exactly the report and the\n * boot's progress lines go to stderr.\n *\n * @param data Parsed CLI args: `options.json`, `options.section`.\n */\nexport async function inspectCommandAction({ options }: CommandActionData): Promise<void> {\n // Parsed first, so a typo fails before the app boots.\n const sections = parseInspectSections(stringOption(options.section));\n const json = options.json === true;\n const boot = json ? await withConsoleOnStderr(() => bootForInspect()) : await bootForInspect();\n const report = await inspectApp({ ...inspectOptionsFromBoot(boot), sections });\n\n if (json) {\n console.log(JSON.stringify(report, null, 2));\n return;\n }\n\n const [heading, ...rest] = formatInspectSummary(report);\n\n console.log(colors.bold(heading ?? \"\"));\n\n for (const line of rest) {\n console.log(line);\n }\n}\n"],"mappings":";;;;;;AAOA,SAAS,aAAa,OAAkE;CACtF,OAAO,OAAO,UAAU,YAAY,MAAM,KAAK,CAAC,CAAC,SAAS,IAAI,MAAM,KAAK,IAAI;AAC/E;;;;;;AAOA,SAAgB,qBAAqB,QAAiC;CACpE,MAAM,QAAkB,CACtB,GAAG,OAAO,IAAI,QAAQ,QAAQ,OAAO,IAAI,UAAU,IAAI,OAAO,IAAI,YAAY,GAAG,IAAI,OAAO,IAAI,gBAAgB,SAAS,OAAO,IAAI,KAAK,IACzI,EACF;CAEA,MAAM,SAAyC;EAC7C,CAAC,UAAU,OAAO,QAAQ,MAAM;EAChC,CAAC,UAAU,OAAO,QAAQ,MAAM;EAChC,CAAC,aAAa,OAAO,WAAW,MAAM;EACtC,CAAC,eAAe,OAAO,QAAQ,MAAM;EACrC,CAAC,UAAU,OAAO,QAAQ,MAAM;EAChC,CAAC,SAAS,OAAO,OAAO,MAAM;EAC9B,CAAC,QAAQ,OAAO,MAAM,MAAM;EAC5B,CAAC,aAAa,OAAO,WAAW,MAAM;EACtC,CAAC,YAAY,OAAO,UAAU,MAAM;CACtC;CAEA,KAAK,MAAM,CAAC,OAAO,UAAU,QAC3B,IAAI,UAAU,QAAW,MAAM,KAAK,KAAK,MAAM,OAAO,EAAE,EAAE,GAAG,OAAO;CAGtE,IAAI,OAAO,UAAU,OAAO,OAAO,SAAS,GAAG;EAC7C,MAAM,KAAK,IAAI,SAAS;EAExB,KAAK,MAAM,SAAS,OAAO,QAAQ;GACjC,MAAM,QAAQ,MAAM,KAAK,WAAW,YAAY;GAChD,MAAM,OAAO,MAAM,OAAO,KAAK,MAAM,SAAS;GAE9C,MAAM,KAAK,KAAK,MAAM,OAAO,OAAO,CAAC,EAAE,GAAG,MAAM,OAAO,QAAQ,MAAM;EACvE;CACF;CAEA,IAAI,OAAO,SAAS,SAAS,GAAG;EAC9B,MAAM,KAAK,IAAI,GAAG,OAAO,SAAS,OAAO,aAAa;EAEtD,KAAK,MAAM,WAAW,OAAO,UAC3B,MAAM,KAAK,OAAO,QAAQ,OAAO,GAAG,QAAQ,KAAK,KAAK,KAAK,QAAQ,SAAS;CAEhF;CAEA,MAAM,KAAK,IAAI,mDAAmD;CAElE,OAAO;AACT;;;;;;;;;;;AAYA,eAAsB,qBAAqB,EAAE,WAA6C;CAExF,MAAM,WAAW,qBAAqB,aAAa,QAAQ,OAAO,CAAC;CACnE,MAAM,OAAO,QAAQ,SAAS;CAE9B,MAAM,SAAS,MAAM,WAAW;EAAE,GAAG,uBADxB,OAAO,MAAM,0BAA0B,eAAe,CAAC,IAAI,MAAM,eAAe,CAC7B;EAAG;CAAS,CAAC;CAE7E,IAAI,MAAM;EACR,QAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;EAC3C;CACF;CAEA,MAAM,CAAC,SAAS,GAAG,QAAQ,qBAAqB,MAAM;CAEtD,QAAQ,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;CAEtC,KAAK,MAAM,QAAQ,MACjB,QAAQ,IAAI,IAAI;AAEpB"}
1
+ {"version":3,"file":"inspect-command.action.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/cli/commands/inspect/inspect-command.action.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandActionData } from \"../../../commands/types\";\nimport { bootForInspect, inspectOptionsFromBoot } from \"../../../tooling/inspect/boot-for-inspect\";\nimport { inspectApp, parseInspectSections } from \"../../../tooling/inspect/inspect-app\";\nimport type { InspectReport } from \"../../../tooling/inspect/inspect-report.types\";\nimport { withConsoleOnStderr } from \"../routes/with-console-on-stderr\";\n\nfunction stringOption(value: string | number | boolean | undefined): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : undefined;\n}\n\n/**\n * The human summary `warlock inspect` prints without `--json`: one count per\n * section, the routes as `METHOD path [auth] name`, and the warnings.\n * Returned as lines so it is testable.\n */\nexport function formatInspectSummary(report: InspectReport): string[] {\n const lines: string[] = [\n `${report.app.name ?? \"app\"}${report.app.version ? `@${report.app.version}` : \"\"} (${report.app.runtimeStrategy}, Node ${report.app.node})`,\n \"\",\n ];\n\n const counts: [string, number | undefined][] = [\n [\"routes\", report.routes?.length],\n [\"models\", report.models?.length],\n [\"resources\", report.resources?.length],\n [\"config keys\", report.config?.length],\n [\"events\", report.events?.length],\n [\"pages\", report.pages?.length],\n [\"jobs\", report.jobs?.length],\n [\"schedules\", report.schedules?.length],\n [\"packages\", report.packages?.length],\n ];\n\n for (const [label, count] of counts) {\n if (count !== undefined) lines.push(` ${label.padEnd(12)} ${count}`);\n }\n\n if (report.routes && report.routes.length > 0) {\n lines.push(\"\", \"Routes:\");\n\n for (const route of report.routes) {\n const guard = route.auth.required ? \" [auth]\" : \"\";\n const name = route.name ? ` ${route.name}` : \"\";\n\n lines.push(` ${route.method.padEnd(7)} ${route.path}${guard}${name}`);\n }\n }\n\n if (report.warnings.length > 0) {\n lines.push(\"\", `${report.warnings.length} warning(s):`);\n\n for (const warning of report.warnings) {\n lines.push(` - ${warning.code ? `${warning.code} ` : \"\"}${warning.message}`);\n }\n }\n\n lines.push(\"\", \"Run `warlock inspect --json` for the full report.\");\n\n return lines;\n}\n\n/**\n * Action behind `warlock inspect`.\n *\n * Boots the app read-only (the `warlock doctor` boot pass: connectors booted,\n * none started, no connection, no port), then describes it with\n * `inspectApp()`. With `--json`, stdout carries exactly the report and the\n * boot's progress lines go to stderr.\n *\n * @param data Parsed CLI args: `options.json`, `options.section`.\n */\nexport async function inspectCommandAction({ options }: CommandActionData): Promise<void> {\n // Parsed first, so a typo fails before the app boots.\n const sections = parseInspectSections(stringOption(options.section));\n const json = options.json === true;\n const boot = json ? await withConsoleOnStderr(() => bootForInspect()) : await bootForInspect();\n const report = await inspectApp({ ...inspectOptionsFromBoot(boot), sections });\n\n if (json) {\n console.log(JSON.stringify(report, null, 2));\n return;\n }\n\n const [heading, ...rest] = formatInspectSummary(report);\n\n console.log(colors.bold(heading ?? \"\"));\n\n for (const line of rest) {\n console.log(line);\n }\n}\n"],"mappings":";;;;;;AAOA,SAAS,aAAa,OAAkE;CACtF,OAAO,OAAO,UAAU,YAAY,MAAM,KAAK,CAAC,CAAC,SAAS,IAAI,MAAM,KAAK,IAAI;AAC/E;;;;;;AAOA,SAAgB,qBAAqB,QAAiC;CACpE,MAAM,QAAkB,CACtB,GAAG,OAAO,IAAI,QAAQ,QAAQ,OAAO,IAAI,UAAU,IAAI,OAAO,IAAI,YAAY,GAAG,IAAI,OAAO,IAAI,gBAAgB,SAAS,OAAO,IAAI,KAAK,IACzI,EACF;CAEA,MAAM,SAAyC;EAC7C,CAAC,UAAU,OAAO,QAAQ,MAAM;EAChC,CAAC,UAAU,OAAO,QAAQ,MAAM;EAChC,CAAC,aAAa,OAAO,WAAW,MAAM;EACtC,CAAC,eAAe,OAAO,QAAQ,MAAM;EACrC,CAAC,UAAU,OAAO,QAAQ,MAAM;EAChC,CAAC,SAAS,OAAO,OAAO,MAAM;EAC9B,CAAC,QAAQ,OAAO,MAAM,MAAM;EAC5B,CAAC,aAAa,OAAO,WAAW,MAAM;EACtC,CAAC,YAAY,OAAO,UAAU,MAAM;CACtC;CAEA,KAAK,MAAM,CAAC,OAAO,UAAU,QAC3B,IAAI,UAAU,QAAW,MAAM,KAAK,KAAK,MAAM,OAAO,EAAE,EAAE,GAAG,OAAO;CAGtE,IAAI,OAAO,UAAU,OAAO,OAAO,SAAS,GAAG;EAC7C,MAAM,KAAK,IAAI,SAAS;EAExB,KAAK,MAAM,SAAS,OAAO,QAAQ;GACjC,MAAM,QAAQ,MAAM,KAAK,WAAW,YAAY;GAChD,MAAM,OAAO,MAAM,OAAO,KAAK,MAAM,SAAS;GAE9C,MAAM,KAAK,KAAK,MAAM,OAAO,OAAO,CAAC,EAAE,GAAG,MAAM,OAAO,QAAQ,MAAM;EACvE;CACF;CAEA,IAAI,OAAO,SAAS,SAAS,GAAG;EAC9B,MAAM,KAAK,IAAI,GAAG,OAAO,SAAS,OAAO,aAAa;EAEtD,KAAK,MAAM,WAAW,OAAO,UAC3B,MAAM,KAAK,OAAO,QAAQ,OAAO,GAAG,QAAQ,KAAK,KAAK,KAAK,QAAQ,SAAS;CAEhF;CAEA,MAAM,KAAK,IAAI,mDAAmD;CAElE,OAAO;AACT;;;;;;;;;;;AAYA,eAAsB,qBAAqB,EAAE,WAA6C;CAExF,MAAM,WAAW,qBAAqB,aAAa,QAAQ,OAAO,CAAC;CACnE,MAAM,OAAO,QAAQ,SAAS;CAC9B,MAAM,OAAO,OAAO,MAAM,0BAA0B,eAAe,CAAC,IAAI,MAAM,eAAe;CAC7F,MAAM,SAAS,MAAM,WAAW;EAAE,GAAG,uBAAuB,IAAI;EAAG;CAAS,CAAC;CAE7E,IAAI,MAAM;EACR,QAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;EAC3C;CACF;CAEA,MAAM,CAAC,SAAS,GAAG,QAAQ,qBAAqB,MAAM;CAEtD,QAAQ,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;CAEtC,KAAK,MAAM,QAAQ,MACjB,QAAQ,IAAI,IAAI;AAEpB"}
@@ -0,0 +1,187 @@
1
+ import path from "node:path";
2
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
3
+ import { parseSync } from "oxc-parser";
4
+ import { spawnSync } from "node:child_process";
5
+ import os from "node:os";
6
+
7
+ //#region ../../packages/core/src/cli/commands/issue/collect-environment.ts
8
+ function readJson(file) {
9
+ try {
10
+ return JSON.parse(readFileSync(file, "utf8"));
11
+ } catch {
12
+ return;
13
+ }
14
+ }
15
+ function field(value, key) {
16
+ return typeof value === "object" && value !== null ? Reflect.get(value, key) : void 0;
17
+ }
18
+ function versionOf(value) {
19
+ return typeof value === "string" && /^\d+\.\d+\.\d+(?:[-+][\w.+-]+)?$/.test(value) ? value : null;
20
+ }
21
+ function moduleDirectories(cwd) {
22
+ const directories = [];
23
+ for (let current = path.resolve(cwd);; current = path.dirname(current)) {
24
+ directories.push(path.join(current, "node_modules"));
25
+ if (path.dirname(current) === current) return directories;
26
+ }
27
+ }
28
+ function installedVersion(directories, name) {
29
+ for (const directory of directories) {
30
+ const file = path.join(directory, name, "package.json");
31
+ if (existsSync(file)) return versionOf(field(readJson(file), "version"));
32
+ }
33
+ return null;
34
+ }
35
+ function installedPackages(directories) {
36
+ const names = /* @__PURE__ */ new Set();
37
+ for (const directory of directories) try {
38
+ for (const name of readdirSync(path.join(directory, "@warlock.js"))) if (/^[a-z0-9][a-z0-9-]*$/.test(name)) names.add(`@warlock.js/${name}`);
39
+ } catch {}
40
+ const packages = {};
41
+ for (const name of [...names].sort()) {
42
+ const version = installedVersion(directories, name);
43
+ if (version) packages[name] = version;
44
+ }
45
+ return packages;
46
+ }
47
+ function packageManager(cwd, userAgent) {
48
+ const agent = /^(npm|pnpm|yarn|bun)\/(\d+\.\d+\.\d+(?:[-+][\w.+-]+)?)(?:\s|$)/.exec(userAgent ?? "");
49
+ if (agent?.[1] && agent[2]) return {
50
+ name: agent[1],
51
+ version: agent[2]
52
+ };
53
+ const declared = field(readJson(path.join(cwd, "package.json")), "packageManager");
54
+ const detected = (typeof declared === "string" ? /^(npm|pnpm|yarn|bun)@/.exec(declared)?.[1] : void 0) ?? [
55
+ ["pnpm-lock.yaml", "pnpm"],
56
+ ["yarn.lock", "yarn"],
57
+ ["bun.lock", "bun"],
58
+ ["bun.lockb", "bun"],
59
+ ["package-lock.json", "npm"]
60
+ ].find(([file]) => existsSync(path.join(cwd, file)))?.[1];
61
+ if (!detected) return null;
62
+ const child = spawnSync(detected, ["--version"], {
63
+ cwd: path.parse(path.resolve(cwd)).root,
64
+ encoding: "utf8",
65
+ timeout: 3e3,
66
+ maxBuffer: 4096,
67
+ env: {
68
+ ...process.env,
69
+ COREPACK_ENABLE_NETWORK: "0",
70
+ COREPACK_ENABLE_AUTO_PIN: "0"
71
+ },
72
+ stdio: [
73
+ "ignore",
74
+ "pipe",
75
+ "pipe"
76
+ ],
77
+ windowsHide: true
78
+ });
79
+ return {
80
+ name: detected,
81
+ version: child.status === 0 ? versionOf(child.stdout.trim()) : null
82
+ };
83
+ }
84
+ function unwrap(node) {
85
+ if (node.type === "TSAsExpression" || node.type === "TSSatisfiesExpression" || node.type === "ParenthesizedExpression" || node.type === "TSTypeAssertion") return unwrap(node.expression);
86
+ return node;
87
+ }
88
+ function property(object, name) {
89
+ for (const item of [...object.properties].reverse()) {
90
+ if (item.type !== "Property" || item.computed || item.method) continue;
91
+ if ((item.key.type === "Identifier" ? item.key.name : item.key.type === "Literal" ? item.key.value : void 0) === name) return unwrap(item.value);
92
+ }
93
+ }
94
+ /** Parse syntax only; never import config, .env, connectors or app modules. */
95
+ function collectIssueConfig(cwd) {
96
+ const summary = {
97
+ status: "missing",
98
+ sections: [],
99
+ buildFlags: {},
100
+ connectors: null,
101
+ customCommands: null,
102
+ dynamic: false
103
+ };
104
+ const file = path.join(cwd, "warlock.config.ts");
105
+ if (!existsSync(file)) return summary;
106
+ let source;
107
+ try {
108
+ source = readFileSync(file, "utf8");
109
+ } catch {
110
+ return {
111
+ ...summary,
112
+ status: "unreadable"
113
+ };
114
+ }
115
+ try {
116
+ const parsed = parseSync("warlock.config.ts", source);
117
+ if (parsed.errors.length) return {
118
+ ...summary,
119
+ status: "unparsed",
120
+ dynamic: true
121
+ };
122
+ const exported = parsed.program.body.find((node) => node.type === "ExportDefaultDeclaration");
123
+ let value = exported ? unwrap(exported.declaration) : void 0;
124
+ if (value?.type === "CallExpression" && value.callee.type === "Identifier" && value.callee.name === "defineConfig") value = value.arguments[0];
125
+ if (value) value = unwrap(value);
126
+ if (value?.type !== "ObjectExpression") return {
127
+ ...summary,
128
+ status: "unparsed",
129
+ dynamic: true
130
+ };
131
+ const object = value;
132
+ summary.status = "static";
133
+ summary.sections = [
134
+ "server",
135
+ "build",
136
+ "connectors",
137
+ "cli",
138
+ "devServer",
139
+ "database",
140
+ "testing"
141
+ ].filter((name) => property(object, name) !== void 0);
142
+ summary.dynamic = object.properties.some((item) => item.type === "SpreadElement" || item.computed);
143
+ const build = property(object, "build");
144
+ if (build?.type === "ObjectExpression") for (const key of [
145
+ "minify",
146
+ "sourcemap",
147
+ "singleBundle",
148
+ "esmShim",
149
+ "splitting"
150
+ ]) {
151
+ const flag = property(build, key);
152
+ if (flag?.type === "Literal" && typeof flag.value === "boolean") summary.buildFlags[key] = flag.value;
153
+ }
154
+ const connectors = property(object, "connectors");
155
+ if (connectors?.type === "ArrayExpression" && !connectors.elements.some((item) => item?.type === "SpreadElement")) summary.connectors = connectors.elements.length;
156
+ const cli = property(object, "cli");
157
+ const commands = cli?.type === "ObjectExpression" ? property(cli, "commands") : void 0;
158
+ if (commands?.type === "ArrayExpression" && !commands.elements.some((item) => item?.type === "SpreadElement")) summary.customCommands = commands.elements.length;
159
+ return summary;
160
+ } catch {
161
+ return {
162
+ ...summary,
163
+ status: "unparsed",
164
+ dynamic: true
165
+ };
166
+ }
167
+ }
168
+ /** Collect installed metadata without starting the app or reading private values. */
169
+ function collectIssueEnvironment(cwd = process.cwd(), userAgent = process.env.npm_config_user_agent) {
170
+ const directories = moduleDirectories(cwd);
171
+ return {
172
+ packages: installedPackages(directories),
173
+ node: process.version,
174
+ packageManager: packageManager(cwd, userAgent),
175
+ os: {
176
+ platform: os.platform(),
177
+ release: os.release(),
178
+ arch: os.arch()
179
+ },
180
+ typescript: installedVersion(directories, "typescript"),
181
+ config: collectIssueConfig(cwd)
182
+ };
183
+ }
184
+
185
+ //#endregion
186
+ export { collectIssueConfig, collectIssueEnvironment };
187
+ //# sourceMappingURL=collect-environment.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collect-environment.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/cli/commands/issue/collect-environment.ts"],"sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { parseSync, type Node, type ObjectExpression } from \"oxc-parser\";\n\nexport type IssueConfigSummary = {\n status: \"missing\" | \"unreadable\" | \"unparsed\" | \"static\";\n sections: string[];\n buildFlags: Record<string, boolean>;\n connectors: number | null;\n customCommands: number | null;\n dynamic: boolean;\n};\n\nexport type IssueEnvironment = {\n packages: Record<string, string>;\n node: string;\n packageManager: { name: string; version: string | null } | null;\n os: { platform: string; release: string; arch: string };\n typescript: string | null;\n config: IssueConfigSummary;\n};\n\nfunction readJson(file: string): unknown {\n try {\n return JSON.parse(readFileSync(file, \"utf8\"));\n } catch {\n return undefined;\n }\n}\n\nfunction field(value: unknown, key: string): unknown {\n return typeof value === \"object\" && value !== null ? Reflect.get(value, key) : undefined;\n}\n\n// Version metadata only: never copy arbitrary manifest strings into a public report.\nfunction versionOf(value: unknown): string | null {\n return typeof value === \"string\" && /^\\d+\\.\\d+\\.\\d+(?:[-+][\\w.+-]+)?$/.test(value) ? value : null;\n}\n\nfunction moduleDirectories(cwd: string): string[] {\n const directories: string[] = [];\n for (let current = path.resolve(cwd); ; current = path.dirname(current)) {\n directories.push(path.join(current, \"node_modules\"));\n if (path.dirname(current) === current) return directories;\n }\n}\n\nfunction installedVersion(directories: string[], name: string): string | null {\n for (const directory of directories) {\n const file = path.join(directory, name, \"package.json\");\n if (existsSync(file)) return versionOf(field(readJson(file), \"version\"));\n }\n return null;\n}\n\nfunction installedPackages(directories: string[]): Record<string, string> {\n const names = new Set<string>();\n for (const directory of directories) {\n try {\n for (const name of readdirSync(path.join(directory, \"@warlock.js\"))) {\n if (/^[a-z0-9][a-z0-9-]*$/.test(name)) names.add(`@warlock.js/${name}`);\n }\n } catch {\n // Missing node_modules is useful information, not a reason to require a boot.\n }\n }\n const packages: Record<string, string> = {};\n for (const name of [...names].sort()) {\n const version = installedVersion(directories, name);\n if (version) packages[name] = version;\n }\n return packages;\n}\n\nfunction packageManager(\n cwd: string,\n userAgent: string | undefined,\n): IssueEnvironment[\"packageManager\"] {\n const agent = /^(npm|pnpm|yarn|bun)\\/(\\d+\\.\\d+\\.\\d+(?:[-+][\\w.+-]+)?)(?:\\s|$)/.exec(\n userAgent ?? \"\",\n );\n if (agent?.[1] && agent[2]) return { name: agent[1], version: agent[2] };\n\n const declared = field(readJson(path.join(cwd, \"package.json\")), \"packageManager\");\n const name =\n typeof declared === \"string\" ? /^(npm|pnpm|yarn|bun)@/.exec(declared)?.[1] : undefined;\n const detected =\n name ??\n (\n [\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"bun.lock\", \"bun\"],\n [\"bun.lockb\", \"bun\"],\n [\"package-lock.json\", \"npm\"],\n ] as const\n ).find(([file]) => existsSync(path.join(cwd, file)))?.[1];\n if (!detected) return null;\n\n // Only a known executable and --version, never app scripts or npm_execpath.\n // Probe outside the app so manager shims cannot select/install an app-pinned\n // version or load project plugins. The result records our child's PID;\n // timeout targets only that child.\n const child = spawnSync(detected, [\"--version\"], {\n cwd: path.parse(path.resolve(cwd)).root,\n encoding: \"utf8\",\n timeout: 3_000,\n maxBuffer: 4_096,\n env: { ...process.env, COREPACK_ENABLE_NETWORK: \"0\", COREPACK_ENABLE_AUTO_PIN: \"0\" },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n windowsHide: true,\n });\n return { name: detected, version: child.status === 0 ? versionOf(child.stdout.trim()) : null };\n}\n\nfunction unwrap(node: Node): Node {\n if (\n node.type === \"TSAsExpression\" ||\n node.type === \"TSSatisfiesExpression\" ||\n node.type === \"ParenthesizedExpression\" ||\n node.type === \"TSTypeAssertion\"\n )\n return unwrap(node.expression);\n return node;\n}\n\nfunction property(object: ObjectExpression, name: string): Node | undefined {\n for (const item of [...object.properties].reverse()) {\n if (item.type !== \"Property\" || item.computed || item.method) continue;\n const key =\n item.key.type === \"Identifier\"\n ? item.key.name\n : item.key.type === \"Literal\"\n ? item.key.value\n : undefined;\n if (key === name) return unwrap(item.value);\n }\n return undefined;\n}\n\n/** Parse syntax only; never import config, .env, connectors or app modules. */\nexport function collectIssueConfig(cwd: string): IssueConfigSummary {\n const summary: IssueConfigSummary = {\n status: \"missing\",\n sections: [],\n buildFlags: {},\n connectors: null,\n customCommands: null,\n dynamic: false,\n };\n const file = path.join(cwd, \"warlock.config.ts\");\n if (!existsSync(file)) return summary;\n let source: string;\n try {\n source = readFileSync(file, \"utf8\");\n } catch {\n return { ...summary, status: \"unreadable\" };\n }\n try {\n const parsed = parseSync(\"warlock.config.ts\", source);\n if (parsed.errors.length) return { ...summary, status: \"unparsed\", dynamic: true };\n const exported = parsed.program.body.find((node) => node.type === \"ExportDefaultDeclaration\");\n let value: Node | undefined = exported ? unwrap(exported.declaration) : undefined;\n if (\n value?.type === \"CallExpression\" &&\n value.callee.type === \"Identifier\" &&\n value.callee.name === \"defineConfig\"\n ) {\n value = value.arguments[0];\n }\n if (value) value = unwrap(value);\n if (value?.type !== \"ObjectExpression\")\n return { ...summary, status: \"unparsed\", dynamic: true };\n\n const object = value;\n summary.status = \"static\";\n // Fixed allowlist excludes custom keys, paths, names and all string values.\n summary.sections = [\n \"server\",\n \"build\",\n \"connectors\",\n \"cli\",\n \"devServer\",\n \"database\",\n \"testing\",\n ].filter((name) => property(object, name) !== undefined);\n summary.dynamic = object.properties.some(\n (item) => item.type === \"SpreadElement\" || item.computed,\n );\n const build = property(object, \"build\");\n if (build?.type === \"ObjectExpression\") {\n for (const key of [\"minify\", \"sourcemap\", \"singleBundle\", \"esmShim\", \"splitting\"]) {\n const flag = property(build, key);\n if (flag?.type === \"Literal\" && typeof flag.value === \"boolean\")\n summary.buildFlags[key] = flag.value;\n }\n }\n const connectors = property(object, \"connectors\");\n if (\n connectors?.type === \"ArrayExpression\" &&\n !connectors.elements.some((item) => item?.type === \"SpreadElement\")\n ) {\n summary.connectors = connectors.elements.length;\n }\n const cli = property(object, \"cli\");\n const commands = cli?.type === \"ObjectExpression\" ? property(cli, \"commands\") : undefined;\n if (\n commands?.type === \"ArrayExpression\" &&\n !commands.elements.some((item) => item?.type === \"SpreadElement\")\n ) {\n summary.customCommands = commands.elements.length;\n }\n return summary;\n } catch {\n return { ...summary, status: \"unparsed\", dynamic: true };\n }\n}\n\n/** Collect installed metadata without starting the app or reading private values. */\nexport function collectIssueEnvironment(\n cwd = process.cwd(),\n userAgent = process.env.npm_config_user_agent,\n): IssueEnvironment {\n const directories = moduleDirectories(cwd);\n return {\n packages: installedPackages(directories),\n node: process.version,\n packageManager: packageManager(cwd, userAgent),\n os: { platform: os.platform(), release: os.release(), arch: os.arch() },\n typescript: installedVersion(directories, \"typescript\"),\n config: collectIssueConfig(cwd),\n };\n}\n"],"mappings":"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"}