@warlock.js/core 5.31.0 → 5.33.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 (1097) hide show
  1. package/CHANGELOG.md +61 -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 +9 -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 +22 -20
  11. package/esm/application/boot-signal.d.mts.map +1 -1
  12. package/esm/application/boot-signal.mjs +15 -9
  13. package/esm/application/boot-signal.mjs.map +1 -1
  14. package/esm/application/index.d.mts +2 -1
  15. package/esm/application/index.mjs +1 -1
  16. package/esm/application/public-url.d.mts +1 -2
  17. package/esm/application/public-url.d.mts.map +1 -1
  18. package/esm/application/roles.d.mts +10 -11
  19. package/esm/application/roles.d.mts.map +1 -1
  20. package/esm/benchmark/benchmark-snapshots.d.mts +1 -3
  21. package/esm/benchmark/benchmark-snapshots.d.mts.map +1 -1
  22. package/esm/benchmark/benchmark.d.mts +1 -3
  23. package/esm/benchmark/benchmark.d.mts.map +1 -1
  24. package/esm/benchmark/channels/console.channel.d.mts +1 -3
  25. package/esm/benchmark/channels/console.channel.d.mts.map +1 -1
  26. package/esm/benchmark/channels/noop.channel.d.mts +1 -3
  27. package/esm/benchmark/channels/noop.channel.d.mts.map +1 -1
  28. package/esm/benchmark/index.mjs +1 -1
  29. package/esm/benchmark/profiler.d.mts +1 -3
  30. package/esm/benchmark/profiler.d.mts.map +1 -1
  31. package/esm/benchmark/profiler.mjs +2 -1
  32. package/esm/benchmark/profiler.mjs.map +1 -1
  33. package/esm/benchmark/types.d.mts +22 -17
  34. package/esm/benchmark/types.d.mts.map +1 -1
  35. package/esm/bootstrap/setup.d.mts +1 -2
  36. package/esm/bootstrap/setup.d.mts.map +1 -1
  37. package/esm/bootstrap.d.mts +1 -2
  38. package/esm/bootstrap.d.mts.map +1 -1
  39. package/esm/cache/database-cache-driver.d.mts +3 -5
  40. package/esm/cache/database-cache-driver.d.mts.map +1 -1
  41. package/esm/cache/database-cache-driver.mjs +1 -1
  42. package/esm/cache/index.d.mts +2 -1
  43. package/esm/cache/index.mjs +1 -1
  44. package/esm/cli/cli-commands.manager.mjs +6 -3
  45. package/esm/cli/cli-commands.manager.mjs.map +1 -1
  46. package/esm/cli/commands/agents-md/agents-md-command.action.mjs +3 -2
  47. package/esm/cli/commands/agents-md/agents-md-command.action.mjs.map +1 -1
  48. package/esm/cli/commands/ai/ai-command.action.mjs +140 -0
  49. package/esm/cli/commands/ai/ai-command.action.mjs.map +1 -0
  50. package/esm/cli/commands/ai.command.mjs +50 -0
  51. package/esm/cli/commands/ai.command.mjs.map +1 -0
  52. package/esm/cli/commands/board/board-command.action.mjs +1 -1
  53. package/esm/cli/commands/check/check-command.action.mjs +4 -1
  54. package/esm/cli/commands/check/check-command.action.mjs.map +1 -1
  55. package/esm/cli/commands/check/child-typecheck.mjs +1 -1
  56. package/esm/cli/commands/check/child-typecheck.mjs.map +1 -1
  57. package/esm/cli/commands/check/format-problems.mjs +1 -1
  58. package/esm/cli/commands/check.command.mjs +6 -1
  59. package/esm/cli/commands/check.command.mjs.map +1 -1
  60. package/esm/cli/commands/dev-server.command.mjs +3 -2
  61. package/esm/cli/commands/dev-server.command.mjs.map +1 -1
  62. package/esm/cli/commands/doctor/check.types.d.mts +29 -16
  63. package/esm/cli/commands/doctor/check.types.d.mts.map +1 -1
  64. package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs +22 -27
  65. package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs.map +1 -1
  66. package/esm/cli/commands/doctor/doctor-command.action.mjs +2 -1
  67. package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
  68. package/esm/cli/commands/explain/explain-command.action.mjs +1 -1
  69. package/esm/cli/commands/generate/generators/controller.generator.mjs +5 -2
  70. package/esm/cli/commands/generate/generators/controller.generator.mjs.map +1 -1
  71. package/esm/cli/commands/generate/generators/endpoint.generator.mjs +5 -3
  72. package/esm/cli/commands/generate/generators/endpoint.generator.mjs.map +1 -1
  73. package/esm/cli/commands/generate/generators/model.generator.mjs +3 -2
  74. package/esm/cli/commands/generate/generators/model.generator.mjs.map +1 -1
  75. package/esm/cli/commands/generate/generators/repository.generator.mjs +3 -1
  76. package/esm/cli/commands/generate/generators/repository.generator.mjs.map +1 -1
  77. package/esm/cli/commands/generate/generators/resource.generator.mjs +3 -1
  78. package/esm/cli/commands/generate/generators/resource.generator.mjs.map +1 -1
  79. package/esm/cli/commands/generate/generators/service.generator.mjs +3 -1
  80. package/esm/cli/commands/generate/generators/service.generator.mjs.map +1 -1
  81. package/esm/cli/commands/generate/templates/endpoint-stubs.mjs +2 -2
  82. package/esm/cli/commands/generate/templates/endpoint-stubs.mjs.map +1 -1
  83. package/esm/cli/commands/generate/utils/endpoint-schema.mjs +1 -2
  84. package/esm/cli/commands/generate/utils/endpoint-schema.mjs.map +1 -1
  85. package/esm/cli/commands/generate/utils/name-parser.mjs +1 -1
  86. package/esm/cli/commands/generate/utils/path-resolver.mjs +1 -1
  87. package/esm/cli/commands/inspect/inspect-command.action.mjs +3 -2
  88. package/esm/cli/commands/inspect/inspect-command.action.mjs.map +1 -1
  89. package/esm/cli/commands/issue/collect-environment.mjs +187 -0
  90. package/esm/cli/commands/issue/collect-environment.mjs.map +1 -0
  91. package/esm/cli/commands/issue/issue-command.action.mjs +70 -0
  92. package/esm/cli/commands/issue/issue-command.action.mjs.map +1 -0
  93. package/esm/cli/commands/issue.command.mjs +31 -0
  94. package/esm/cli/commands/issue.command.mjs.map +1 -0
  95. package/esm/cli/commands/mcp/mcp-command.action.mjs +15 -14
  96. package/esm/cli/commands/mcp/mcp-command.action.mjs.map +1 -1
  97. package/esm/cli/commands/openapi-generator.action.mjs +1 -1
  98. package/esm/cli/commands/pm2/pm2-command.action.mjs +91 -0
  99. package/esm/cli/commands/pm2/pm2-command.action.mjs.map +1 -0
  100. package/esm/cli/commands/pm2/pm2-config.mjs +115 -0
  101. package/esm/cli/commands/pm2/pm2-config.mjs.map +1 -0
  102. package/esm/cli/commands/pm2.command.mjs +53 -0
  103. package/esm/cli/commands/pm2.command.mjs.map +1 -0
  104. package/esm/cli/commands/postman-generator.action.mjs +1 -1
  105. package/esm/cli/commands/routes/format-routes-table.mjs +1 -1
  106. package/esm/cli/commands/routes/route-row.mjs +1 -1
  107. package/esm/cli/commands/routes/routes-diff.action.mjs +2 -2
  108. package/esm/cli/commands/routes/routes-diff.action.mjs.map +1 -1
  109. package/esm/cli/commands/test.command.mjs +1 -1
  110. package/esm/cli/commands/trace/trace-command.action.mjs +1 -1
  111. package/esm/cli/commands-loader.mjs +1 -1
  112. package/esm/cli/framework-cli-commands.mjs +6 -0
  113. package/esm/cli/framework-cli-commands.mjs.map +1 -1
  114. package/esm/cli/parse-cli-args.mjs +2 -2
  115. package/esm/cli/parse-cli-args.mjs.map +1 -1
  116. package/esm/cli/start.d.mts +1 -1
  117. package/esm/cli/string-similarity.mjs +1 -1
  118. package/esm/commands/cli-command.d.mts +2 -4
  119. package/esm/commands/cli-command.d.mts.map +1 -1
  120. package/esm/commands/index.d.mts +2 -1
  121. package/esm/commands/index.mjs +1 -1
  122. package/esm/commands/types.d.mts +8 -8
  123. package/esm/commands/types.d.mts.map +1 -1
  124. package/esm/config/config-getter.d.mts +2 -3
  125. package/esm/config/config-getter.d.mts.map +1 -1
  126. package/esm/config/config-getter.mjs +5 -5
  127. package/esm/config/config-getter.mjs.map +1 -1
  128. package/esm/config/config-handlers.d.mts +1 -3
  129. package/esm/config/config-handlers.d.mts.map +1 -1
  130. package/esm/config/config-loader.d.mts +1 -2
  131. package/esm/config/config-loader.d.mts.map +1 -1
  132. package/esm/config/config-loader.mjs +3 -3
  133. package/esm/config/config-loader.mjs.map +1 -1
  134. package/esm/config/config-manager.mjs +1 -1
  135. package/esm/config/config-schema.d.mts +19 -16
  136. package/esm/config/config-schema.d.mts.map +1 -1
  137. package/esm/config/config-setter.d.mts +2 -4
  138. package/esm/config/config-setter.d.mts.map +1 -1
  139. package/esm/config/config-setter.mjs +2 -2
  140. package/esm/config/config-setter.mjs.map +1 -1
  141. package/esm/config/config-special-handlers.d.mts +2 -4
  142. package/esm/config/config-special-handlers.d.mts.map +1 -1
  143. package/esm/config/index.d.mts +2 -1
  144. package/esm/config/index.mjs +1 -1
  145. package/esm/config/types.d.mts +4 -5
  146. package/esm/config/types.d.mts.map +1 -1
  147. package/esm/connectors/access-connector.d.mts +1 -3
  148. package/esm/connectors/access-connector.d.mts.map +1 -1
  149. package/esm/connectors/access-connector.mjs +2 -2
  150. package/esm/connectors/access-connector.mjs.map +1 -1
  151. package/esm/connectors/ai-connector.d.mts +1 -3
  152. package/esm/connectors/ai-connector.d.mts.map +1 -1
  153. package/esm/connectors/ai-connector.mjs +2 -2
  154. package/esm/connectors/ai-connector.mjs.map +1 -1
  155. package/esm/connectors/assert-no-reserved-connector-names.d.mts +1 -3
  156. package/esm/connectors/assert-no-reserved-connector-names.d.mts.map +1 -1
  157. package/esm/connectors/assert-unique-connector-names.d.mts +1 -3
  158. package/esm/connectors/assert-unique-connector-names.d.mts.map +1 -1
  159. package/esm/connectors/assert-unique-connector-names.mjs +2 -1
  160. package/esm/connectors/assert-unique-connector-names.mjs.map +1 -1
  161. package/esm/connectors/base-connector.d.mts +1 -3
  162. package/esm/connectors/base-connector.d.mts.map +1 -1
  163. package/esm/connectors/cache-connector.d.mts +1 -3
  164. package/esm/connectors/cache-connector.d.mts.map +1 -1
  165. package/esm/connectors/cache-connector.mjs +3 -3
  166. package/esm/connectors/cache-connector.mjs.map +1 -1
  167. package/esm/connectors/connectors-manager.d.mts +2 -4
  168. package/esm/connectors/connectors-manager.d.mts.map +1 -1
  169. package/esm/connectors/connectors-manager.mjs +3 -6
  170. package/esm/connectors/connectors-manager.mjs.map +1 -1
  171. package/esm/connectors/database-connector.d.mts +1 -3
  172. package/esm/connectors/database-connector.d.mts.map +1 -1
  173. package/esm/connectors/database-connector.mjs +2 -2
  174. package/esm/connectors/database-connector.mjs.map +1 -1
  175. package/esm/connectors/describe-server-address.mjs +4 -4
  176. package/esm/connectors/describe-server-address.mjs.map +1 -1
  177. package/esm/connectors/herald-connector.d.mts +1 -3
  178. package/esm/connectors/herald-connector.d.mts.map +1 -1
  179. package/esm/connectors/herald-connector.mjs +2 -2
  180. package/esm/connectors/herald-connector.mjs.map +1 -1
  181. package/esm/connectors/http-connector.d.mts +1 -3
  182. package/esm/connectors/http-connector.d.mts.map +1 -1
  183. package/esm/connectors/http-connector.mjs +8 -7
  184. package/esm/connectors/http-connector.mjs.map +1 -1
  185. package/esm/connectors/index.d.mts +2 -1
  186. package/esm/connectors/index.mjs +1 -1
  187. package/esm/connectors/logger-connector.d.mts +1 -3
  188. package/esm/connectors/logger-connector.d.mts.map +1 -1
  189. package/esm/connectors/logger-connector.mjs +2 -2
  190. package/esm/connectors/logger-connector.mjs.map +1 -1
  191. package/esm/connectors/mail-connector.d.mts +1 -3
  192. package/esm/connectors/mail-connector.d.mts.map +1 -1
  193. package/esm/connectors/mail-connector.mjs +2 -2
  194. package/esm/connectors/mail-connector.mjs.map +1 -1
  195. package/esm/connectors/notifications-connector.d.mts +1 -3
  196. package/esm/connectors/notifications-connector.d.mts.map +1 -1
  197. package/esm/connectors/notifications-connector.mjs +2 -2
  198. package/esm/connectors/notifications-connector.mjs.map +1 -1
  199. package/esm/connectors/register-configured-connectors.d.mts +2 -4
  200. package/esm/connectors/register-configured-connectors.d.mts.map +1 -1
  201. package/esm/connectors/shutdown-timeout.mjs +7 -0
  202. package/esm/connectors/shutdown-timeout.mjs.map +1 -0
  203. package/esm/connectors/socket-connector.d.mts +1 -3
  204. package/esm/connectors/socket-connector.d.mts.map +1 -1
  205. package/esm/connectors/socket-connector.mjs +20 -11
  206. package/esm/connectors/socket-connector.mjs.map +1 -1
  207. package/esm/connectors/storage.connector.d.mts +1 -3
  208. package/esm/connectors/storage.connector.d.mts.map +1 -1
  209. package/esm/connectors/storage.connector.mjs +2 -2
  210. package/esm/connectors/storage.connector.mjs.map +1 -1
  211. package/esm/connectors/types.d.mts +17 -14
  212. package/esm/connectors/types.d.mts.map +1 -1
  213. package/esm/container/container-instance-registry.mjs.map +1 -1
  214. package/esm/container/development-app-modules.d.mts +7 -5
  215. package/esm/container/development-app-modules.d.mts.map +1 -1
  216. package/esm/container/development-model-modules.d.mts +6 -5
  217. package/esm/container/development-model-modules.d.mts.map +1 -1
  218. package/esm/container/index.d.mts +4 -4
  219. package/esm/container/index.d.mts.map +1 -1
  220. package/esm/database/index.d.mts +3 -1
  221. package/esm/database/index.mjs +1 -1
  222. package/esm/database/migrate-action.mjs +1 -1
  223. package/esm/database/models/database-log/database-log.d.mts +2 -3
  224. package/esm/database/models/database-log/database-log.d.mts.map +1 -1
  225. package/esm/database/models/database-log/index.d.mts +2 -1
  226. package/esm/database/models/database-log/index.mjs +1 -1
  227. package/esm/database/seed-command-action.mjs +1 -1
  228. package/esm/database/seeds/seeder.d.mts +2 -4
  229. package/esm/database/seeds/seeder.d.mts.map +1 -1
  230. package/esm/database/seeds/seeder.errors.d.mts +2 -3
  231. package/esm/database/seeds/seeder.errors.d.mts.map +1 -1
  232. package/esm/database/seeds/seeders.manager.mjs +2 -1
  233. package/esm/database/seeds/seeders.manager.mjs.map +1 -1
  234. package/esm/database/seeds/types.d.mts +7 -8
  235. package/esm/database/seeds/types.d.mts.map +1 -1
  236. package/esm/database/utils.d.mts +4 -5
  237. package/esm/database/utils.d.mts.map +1 -1
  238. package/esm/dev-server/app-module-registry.mjs +1 -1
  239. package/esm/dev-server/create-worker.mjs +5 -3
  240. package/esm/dev-server/create-worker.mjs.map +1 -1
  241. package/esm/dev-server/dependency-graph.d.mts +1 -3
  242. package/esm/dev-server/dependency-graph.d.mts.map +1 -1
  243. package/esm/dev-server/dependency-graph.mjs +1 -1
  244. package/esm/dev-server/dependency-graph.mjs.map +1 -1
  245. package/esm/dev-server/extract-translation-keys.mjs +16 -17
  246. package/esm/dev-server/extract-translation-keys.mjs.map +1 -1
  247. package/esm/dev-server/file-manager.d.mts +3 -7
  248. package/esm/dev-server/file-manager.d.mts.map +1 -1
  249. package/esm/dev-server/file-operations.d.mts +1 -3
  250. package/esm/dev-server/file-operations.d.mts.map +1 -1
  251. package/esm/dev-server/files-watcher.mjs +12 -11
  252. package/esm/dev-server/files-watcher.mjs.map +1 -1
  253. package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs +6 -8
  254. package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs.map +1 -1
  255. package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs +36 -115
  256. package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs.map +1 -1
  257. package/esm/dev-server/health-checker/default-health-checkers.mjs +6 -15
  258. package/esm/dev-server/health-checker/default-health-checkers.mjs.map +1 -1
  259. package/esm/dev-server/health-checker/eslint-support.mjs +27 -0
  260. package/esm/dev-server/health-checker/eslint-support.mjs.map +1 -0
  261. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +7 -6
  262. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
  263. package/esm/dev-server/health-checker/file-health-result.d.mts +2 -2
  264. package/esm/dev-server/health-checker/file-health-result.d.mts.map +1 -1
  265. package/esm/dev-server/health-checker/files-healthcare.manager.mjs +1 -0
  266. package/esm/dev-server/health-checker/files-healthcare.manager.mjs.map +1 -1
  267. package/esm/dev-server/health-checker/oxlint-runner.mjs +6 -5
  268. package/esm/dev-server/health-checker/oxlint-runner.mjs.map +1 -1
  269. package/esm/dev-server/health-checker/workers/eslint-health.worker.d.mts +1 -1
  270. package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs +2 -11
  271. package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs.map +1 -1
  272. package/esm/dev-server/health-checker/workers/oxlint-health.worker.d.mts +1 -1
  273. package/esm/dev-server/health-checker/workers/ts-health.worker.d.mts +1 -1
  274. package/esm/dev-server/health-checker/workers/ts-health.worker.mjs +40 -174
  275. package/esm/dev-server/health-checker/workers/ts-health.worker.mjs.map +1 -1
  276. package/esm/dev-server/loader/hook-thread.d.mts +4 -8
  277. package/esm/dev-server/loader/hook-thread.d.mts.map +1 -1
  278. package/esm/dev-server/loader/load-hook.d.mts +10 -6
  279. package/esm/dev-server/loader/load-hook.d.mts.map +1 -1
  280. package/esm/dev-server/loader/load-hook.mjs +4 -3
  281. package/esm/dev-server/loader/load-hook.mjs.map +1 -1
  282. package/esm/dev-server/loader/own-resolver.mjs +1 -1
  283. package/esm/dev-server/loader/register-loader.mjs +3 -2
  284. package/esm/dev-server/loader/register-loader.mjs.map +1 -1
  285. package/esm/dev-server/loader/resolve-hook.d.mts +2 -2
  286. package/esm/dev-server/loader/resolve-hook.d.mts.map +1 -1
  287. package/esm/dev-server/loader/resolve-hook.mjs +2 -1
  288. package/esm/dev-server/loader/resolve-hook.mjs.map +1 -1
  289. package/esm/dev-server/loader/transpile-cache.mjs +2 -1
  290. package/esm/dev-server/loader/transpile-cache.mjs.map +1 -1
  291. package/esm/dev-server/manifest-manager.d.mts +1 -3
  292. package/esm/dev-server/manifest-manager.d.mts.map +1 -1
  293. package/esm/dev-server/model-module-registry.mjs +3 -3
  294. package/esm/dev-server/model-module-registry.mjs.map +1 -1
  295. package/esm/dev-server/model-resource-typings.mjs +40 -47
  296. package/esm/dev-server/model-resource-typings.mjs.map +1 -1
  297. package/esm/dev-server/module-loader.mjs +2 -2
  298. package/esm/dev-server/module-loader.mjs.map +1 -1
  299. package/esm/dev-server/package-json-manager.mjs +1 -1
  300. package/esm/dev-server/parse-imports.mjs +6 -38
  301. package/esm/dev-server/parse-imports.mjs.map +1 -1
  302. package/esm/dev-server/read-config-ast.mjs +3 -33
  303. package/esm/dev-server/read-config-ast.mjs.map +1 -1
  304. package/esm/dev-server/ready-block.mjs +1 -1
  305. package/esm/dev-server/shortcuts.mjs +1 -1
  306. package/esm/dev-server/special-files-collector.d.mts +2 -4
  307. package/esm/dev-server/special-files-collector.d.mts.map +1 -1
  308. package/esm/dev-server/supervisor.mjs +1 -1
  309. package/esm/dev-server/tsconfig-manager.mjs +3 -3
  310. package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
  311. package/esm/dev-server/type-generator.mjs +28 -35
  312. package/esm/dev-server/type-generator.mjs.map +1 -1
  313. package/esm/dev-server/types.d.mts +3 -4
  314. package/esm/dev-server/types.d.mts.map +1 -1
  315. package/esm/dev-server/update-check-cache.mjs +2 -2
  316. package/esm/dev-server/update-check-cache.mjs.map +1 -1
  317. package/esm/encryption/encrypt.d.mts +2 -3
  318. package/esm/encryption/encrypt.d.mts.map +1 -1
  319. package/esm/encryption/hash.d.mts +1 -2
  320. package/esm/encryption/hash.d.mts.map +1 -1
  321. package/esm/encryption/index.mjs +1 -1
  322. package/esm/encryption/password.d.mts +2 -3
  323. package/esm/encryption/password.d.mts.map +1 -1
  324. package/esm/encryption/types.d.mts +2 -3
  325. package/esm/encryption/types.d.mts.map +1 -1
  326. package/esm/errors/error-codes.d.mts +29 -22
  327. package/esm/errors/error-codes.d.mts.map +1 -1
  328. package/esm/errors/warlock-error.d.mts +1 -3
  329. package/esm/errors/warlock-error.d.mts.map +1 -1
  330. package/esm/generations/add-command.action.mjs +3 -2
  331. package/esm/generations/add-command.action.mjs.map +1 -1
  332. package/esm/generations/features/bull-board.feature.mjs +2 -1
  333. package/esm/generations/features/bull-board.feature.mjs.map +1 -1
  334. package/esm/generations/features/index.mjs +2 -0
  335. package/esm/generations/features/index.mjs.map +1 -1
  336. package/esm/generations/features/notifications.feature.mjs +2 -1
  337. package/esm/generations/features/notifications.feature.mjs.map +1 -1
  338. package/esm/generations/features/process.feature.mjs +65 -0
  339. package/esm/generations/features/process.feature.mjs.map +1 -0
  340. package/esm/generations/features/shared/merge-web-sitemap-config.mjs +16 -23
  341. package/esm/generations/features/shared/merge-web-sitemap-config.mjs.map +1 -1
  342. package/esm/generations/features/shared/patch-tsconfig-include.mjs +1 -1
  343. package/esm/generations/features/shared/relocate-conflicting-home-route.mjs +1 -1
  344. package/esm/generations/features/sitemap.feature.mjs +2 -1
  345. package/esm/generations/features/sitemap.feature.mjs.map +1 -1
  346. package/esm/generations/generation-fs.mjs +1 -1
  347. package/esm/generations/generation-run.mjs +1 -1
  348. package/esm/generations/stubs.mjs +1 -1
  349. package/esm/generations/stubs.mjs.map +1 -1
  350. package/esm/http/boot-port-preflight.d.mts +4 -5
  351. package/esm/http/boot-port-preflight.d.mts.map +1 -1
  352. package/esm/http/boot-port-preflight.mjs +2 -2
  353. package/esm/http/boot-port-preflight.mjs.map +1 -1
  354. package/esm/http/bounded-stream-queue.d.mts +4 -4
  355. package/esm/http/bounded-stream-queue.d.mts.map +1 -1
  356. package/esm/http/bounded-stream-queue.mjs +1 -1
  357. package/esm/http/bounded-stream-queue.mjs.map +1 -1
  358. package/esm/http/build-cors-options.mjs +2 -2
  359. package/esm/http/build-cors-options.mjs.map +1 -1
  360. package/esm/http/build-rate-limit-options.d.mts +2 -3
  361. package/esm/http/build-rate-limit-options.d.mts.map +1 -1
  362. package/esm/http/build-rate-limit-options.mjs +1 -1
  363. package/esm/http/build-rate-limit-options.mjs.map +1 -1
  364. package/esm/http/conditional-request.d.mts +14 -13
  365. package/esm/http/conditional-request.d.mts.map +1 -1
  366. package/esm/http/config.d.mts +2 -4
  367. package/esm/http/config.d.mts.map +1 -1
  368. package/esm/http/config.mjs +2 -2
  369. package/esm/http/config.mjs.map +1 -1
  370. package/esm/http/context/request-context.d.mts +6 -7
  371. package/esm/http/context/request-context.d.mts.map +1 -1
  372. package/esm/http/context/request-memo.d.mts +1 -2
  373. package/esm/http/context/request-memo.d.mts.map +1 -1
  374. package/esm/http/createHttpApplication.d.mts +2 -3
  375. package/esm/http/createHttpApplication.d.mts.map +1 -1
  376. package/esm/http/createHttpApplication.mjs +2 -2
  377. package/esm/http/createHttpApplication.mjs.map +1 -1
  378. package/esm/http/csp.d.mts +10 -12
  379. package/esm/http/csp.d.mts.map +1 -1
  380. package/esm/http/csp.mjs +2 -2
  381. package/esm/http/csp.mjs.map +1 -1
  382. package/esm/http/csrf-default-guard.d.mts +2 -4
  383. package/esm/http/csrf-default-guard.d.mts.map +1 -1
  384. package/esm/http/csrf-default-guard.mjs +1 -1
  385. package/esm/http/csrf-default-guard.mjs.map +1 -1
  386. package/esm/http/csrf-origin-policy.d.mts +7 -9
  387. package/esm/http/csrf-origin-policy.d.mts.map +1 -1
  388. package/esm/http/csrf-origin-policy.mjs +2 -2
  389. package/esm/http/csrf-origin-policy.mjs.map +1 -1
  390. package/esm/http/database/RequestLog.d.mts +2 -3
  391. package/esm/http/database/RequestLog.d.mts.map +1 -1
  392. package/esm/http/error-codes.d.mts +1 -2
  393. package/esm/http/error-codes.d.mts.map +1 -1
  394. package/esm/http/error-mapper.d.mts +2 -4
  395. package/esm/http/error-mapper.d.mts.map +1 -1
  396. package/esm/http/error-mapper.mjs +2 -2
  397. package/esm/http/error-mapper.mjs.map +1 -1
  398. package/esm/http/errors/errors.d.mts +28 -29
  399. package/esm/http/errors/errors.d.mts.map +1 -1
  400. package/esm/http/escape-header-value.d.mts +1 -2
  401. package/esm/http/escape-header-value.d.mts.map +1 -1
  402. package/esm/http/events.d.mts +2 -4
  403. package/esm/http/events.d.mts.map +1 -1
  404. package/esm/http/health.d.mts +4 -4
  405. package/esm/http/health.d.mts.map +1 -1
  406. package/esm/http/index.d.mts +4 -1
  407. package/esm/http/index.mjs +1 -1
  408. package/esm/http/middleware/cache-response-middleware.d.mts +2 -4
  409. package/esm/http/middleware/cache-response-middleware.d.mts.map +1 -1
  410. package/esm/http/middleware/concurrency-limit.middleware.d.mts +3 -3
  411. package/esm/http/middleware/concurrency-limit.middleware.d.mts.map +1 -1
  412. package/esm/http/middleware/idempotency.middleware.d.mts +3 -3
  413. package/esm/http/middleware/idempotency.middleware.d.mts.map +1 -1
  414. package/esm/http/middleware/idempotency.middleware.mjs +6 -6
  415. package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
  416. package/esm/http/middleware/index.d.mts +3 -1
  417. package/esm/http/middleware/index.mjs +1 -1
  418. package/esm/http/middleware/inject-request-context.d.mts +2 -4
  419. package/esm/http/middleware/inject-request-context.d.mts.map +1 -1
  420. package/esm/http/middleware/inject-request-context.mjs +3 -3
  421. package/esm/http/middleware/inject-request-context.mjs.map +1 -1
  422. package/esm/http/middleware/ip-filter.middleware.d.mts +3 -3
  423. package/esm/http/middleware/ip-filter.middleware.d.mts.map +1 -1
  424. package/esm/http/middleware/maintenance.middleware.d.mts +3 -3
  425. package/esm/http/middleware/maintenance.middleware.d.mts.map +1 -1
  426. package/esm/http/middleware/maintenance.middleware.mjs +4 -4
  427. package/esm/http/middleware/maintenance.middleware.mjs.map +1 -1
  428. package/esm/http/middleware/max-body-size.middleware.d.mts +2 -2
  429. package/esm/http/middleware/max-body-size.middleware.d.mts.map +1 -1
  430. package/esm/http/middleware/middleware-list.d.mts +1 -3
  431. package/esm/http/middleware/middleware-list.d.mts.map +1 -1
  432. package/esm/http/middleware/rate-limit.middleware.d.mts +3 -3
  433. package/esm/http/middleware/rate-limit.middleware.d.mts.map +1 -1
  434. package/esm/http/middleware/rate-limit.middleware.mjs +2 -2
  435. package/esm/http/middleware/rate-limit.middleware.mjs.map +1 -1
  436. package/esm/http/middleware/utils/cidr-match.d.mts +2 -3
  437. package/esm/http/middleware/utils/cidr-match.d.mts.map +1 -1
  438. package/esm/http/middleware/utils/idempotency-key.d.mts +3 -5
  439. package/esm/http/middleware/utils/idempotency-key.d.mts.map +1 -1
  440. package/esm/http/middleware/utils/index.d.mts +2 -1
  441. package/esm/http/middleware/utils/parse-size.d.mts +1 -2
  442. package/esm/http/middleware/utils/parse-size.d.mts.map +1 -1
  443. package/esm/http/middleware/utils/parse-size.mjs +2 -2
  444. package/esm/http/middleware/utils/parse-size.mjs.map +1 -1
  445. package/esm/http/plugins.d.mts +2 -4
  446. package/esm/http/plugins.d.mts.map +1 -1
  447. package/esm/http/plugins.mjs +10 -10
  448. package/esm/http/plugins.mjs.map +1 -1
  449. package/esm/http/port-preflight.d.mts +3 -4
  450. package/esm/http/port-preflight.d.mts.map +1 -1
  451. package/esm/http/port-preflight.mjs +2 -0
  452. package/esm/http/port-preflight.mjs.map +1 -1
  453. package/esm/http/rate-limit-cache-store.mjs +4 -3
  454. package/esm/http/rate-limit-cache-store.mjs.map +1 -1
  455. package/esm/http/ready-report.d.mts +15 -10
  456. package/esm/http/ready-report.d.mts.map +1 -1
  457. package/esm/http/request-controller.d.mts +1 -3
  458. package/esm/http/request-controller.d.mts.map +1 -1
  459. package/esm/http/request-log-snapshot.d.mts +20 -16
  460. package/esm/http/request-log-snapshot.d.mts.map +1 -1
  461. package/esm/http/request-log-snapshot.mjs +3 -3
  462. package/esm/http/request-log-snapshot.mjs.map +1 -1
  463. package/esm/http/request.d.mts +8 -7
  464. package/esm/http/request.d.mts.map +1 -1
  465. package/esm/http/request.mjs +8 -7
  466. package/esm/http/request.mjs.map +1 -1
  467. package/esm/http/response.d.mts +12 -11
  468. package/esm/http/response.d.mts.map +1 -1
  469. package/esm/http/response.mjs +7 -7
  470. package/esm/http/response.mjs.map +1 -1
  471. package/esm/http/safe-redirect.d.mts +3 -4
  472. package/esm/http/safe-redirect.d.mts.map +1 -1
  473. package/esm/http/serialized.d.mts +12 -13
  474. package/esm/http/serialized.d.mts.map +1 -1
  475. package/esm/http/server-rebuilt.d.mts +3 -5
  476. package/esm/http/server-rebuilt.d.mts.map +1 -1
  477. package/esm/http/server.d.mts +9 -9
  478. package/esm/http/server.d.mts.map +1 -1
  479. package/esm/http/server.mjs +4 -4
  480. package/esm/http/server.mjs.map +1 -1
  481. package/esm/http/stream-react-response.d.mts +7 -7
  482. package/esm/http/stream-react-response.d.mts.map +1 -1
  483. package/esm/http/tracing/index.mjs +1 -1
  484. package/esm/http/tracing/trace-id.d.mts +2 -3
  485. package/esm/http/tracing/trace-id.d.mts.map +1 -1
  486. package/esm/http/tracing/tracing-dispatcher.d.mts +10 -11
  487. package/esm/http/tracing/tracing-dispatcher.d.mts.map +1 -1
  488. package/esm/http/tracing/tracing-dispatcher.mjs +2 -2
  489. package/esm/http/tracing/tracing-dispatcher.mjs.map +1 -1
  490. package/esm/http/tracing/tracing.type.d.mts +11 -9
  491. package/esm/http/tracing/tracing.type.d.mts.map +1 -1
  492. package/esm/http/types.d.mts +49 -43
  493. package/esm/http/types.d.mts.map +1 -1
  494. package/esm/http/uploaded-file.d.mts +6 -5
  495. package/esm/http/uploaded-file.d.mts.map +1 -1
  496. package/esm/http/uploads/generate-image-variants.d.mts +6 -6
  497. package/esm/http/uploads/generate-image-variants.d.mts.map +1 -1
  498. package/esm/http/uploads/generate-image-variants.mjs +1 -1
  499. package/esm/http/uploads/generate-image-variants.mjs.map +1 -1
  500. package/esm/http/uploads/image-variant-cache-entries.mjs +1 -1
  501. package/esm/http/uploads/image-variant-cache.mjs +8 -8
  502. package/esm/http/uploads/image-variant-cache.mjs.map +1 -1
  503. package/esm/http/uploads/image-variant-types.d.mts +7 -9
  504. package/esm/http/uploads/image-variant-types.d.mts.map +1 -1
  505. package/esm/http/uploads/image-variants-config-error.d.mts +1 -2
  506. package/esm/http/uploads/image-variants-config-error.d.mts.map +1 -1
  507. package/esm/http/uploads/index.d.mts +2 -1
  508. package/esm/http/uploads/index.mjs +1 -1
  509. package/esm/http/uploads/parse-uploaded-file-query.mjs +1 -1
  510. package/esm/http/uploads/parse-uploaded-file-query.mjs.map +1 -1
  511. package/esm/http/uploads/purge-image-variants.d.mts +2 -4
  512. package/esm/http/uploads/purge-image-variants.d.mts.map +1 -1
  513. package/esm/http/uploads/resolve-image-variant.d.mts +3 -5
  514. package/esm/http/uploads/resolve-image-variant.d.mts.map +1 -1
  515. package/esm/http/uploads/resolve-image-variants-config.mjs +4 -4
  516. package/esm/http/uploads/resolve-image-variants-config.mjs.map +1 -1
  517. package/esm/http/uploads/resolve-original-content-type.mjs +1 -1
  518. package/esm/http/uploads/resolve-original-content-type.mjs.map +1 -1
  519. package/esm/http/uploads/trim-image-variant-cache.mjs +3 -3
  520. package/esm/http/uploads/trim-image-variant-cache.mjs.map +1 -1
  521. package/esm/http/uploads/uploaded-file.controller.d.mts +6 -5
  522. package/esm/http/uploads/uploaded-file.controller.d.mts.map +1 -1
  523. package/esm/http/uploads/uploaded-file.controller.mjs +2 -1
  524. package/esm/http/uploads/uploaded-file.controller.mjs.map +1 -1
  525. package/esm/http/uploads/variant-cache-key.mjs +1 -1
  526. package/esm/http/uploads-config.d.mts +2 -4
  527. package/esm/http/uploads-config.d.mts.map +1 -1
  528. package/esm/http/uploads-types.d.mts +19 -17
  529. package/esm/http/uploads-types.d.mts.map +1 -1
  530. package/esm/http/xmlable.d.mts +1 -2
  531. package/esm/http/xmlable.d.mts.map +1 -1
  532. package/esm/image/image.d.mts +6 -7
  533. package/esm/image/image.d.mts.map +1 -1
  534. package/esm/image/image.mjs.map +1 -1
  535. package/esm/image/index.d.mts +2 -1
  536. package/esm/image/index.mjs +1 -1
  537. package/esm/index.d.mts +28 -2
  538. package/esm/index.mjs +7 -2
  539. package/esm/loader/app-module-importer.d.mts +1 -2
  540. package/esm/loader/app-module-importer.d.mts.map +1 -1
  541. package/esm/localization/index.mjs +1 -1
  542. package/esm/localization/parse-locale-dictionary.d.mts +4 -5
  543. package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
  544. package/esm/localization/parse-locale-dictionary.mjs +1 -1
  545. package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
  546. package/esm/localization/register-locale-dictionary.d.mts +3 -4
  547. package/esm/localization/register-locale-dictionary.d.mts.map +1 -1
  548. package/esm/localization/register-locale-dictionary.mjs +2 -2
  549. package/esm/localization/register-locale-dictionary.mjs.map +1 -1
  550. package/esm/logger/fatal-visibility.d.mts +1 -2
  551. package/esm/logger/fatal-visibility.d.mts.map +1 -1
  552. package/esm/logger/index.d.mts +2 -1
  553. package/esm/logger/index.mjs +1 -1
  554. package/esm/logger/logger.d.mts +1 -3
  555. package/esm/logger/logger.d.mts.map +1 -1
  556. package/esm/logger/types.d.mts +2 -3
  557. package/esm/logger/types.d.mts.map +1 -1
  558. package/esm/mail/config.d.mts +12 -14
  559. package/esm/mail/config.d.mts.map +1 -1
  560. package/esm/mail/events.d.mts +4 -6
  561. package/esm/mail/events.d.mts.map +1 -1
  562. package/esm/mail/index.d.mts +2 -1
  563. package/esm/mail/index.mjs +1 -1
  564. package/esm/mail/mail.d.mts +1 -3
  565. package/esm/mail/mail.d.mts.map +1 -1
  566. package/esm/mail/mailer-pool.d.mts +5 -7
  567. package/esm/mail/mailer-pool.d.mts.map +1 -1
  568. package/esm/mail/react-mail.d.mts +1 -3
  569. package/esm/mail/react-mail.d.mts.map +1 -1
  570. package/esm/mail/send-mail.d.mts +1 -3
  571. package/esm/mail/send-mail.d.mts.map +1 -1
  572. package/esm/mail/send-mail.mjs +2 -1
  573. package/esm/mail/send-mail.mjs.map +1 -1
  574. package/esm/mail/test-mailbox.d.mts +11 -13
  575. package/esm/mail/test-mailbox.d.mts.map +1 -1
  576. package/esm/mail/types.d.mts +17 -18
  577. package/esm/mail/types.d.mts.map +1 -1
  578. package/esm/manifest/manifest-manager.mjs +1 -1
  579. package/esm/openapi/build-openapi-document.d.mts +2 -4
  580. package/esm/openapi/build-openapi-document.d.mts.map +1 -1
  581. package/esm/openapi/cast-schema.mjs +1 -1
  582. package/esm/openapi/development-openapi-provider.d.mts +5 -6
  583. package/esm/openapi/development-openapi-provider.d.mts.map +1 -1
  584. package/esm/openapi/index.d.mts +3 -1
  585. package/esm/openapi/index.mjs +1 -1
  586. package/esm/openapi/openapi-child-output.mjs +2 -2
  587. package/esm/openapi/openapi-child-output.mjs.map +1 -1
  588. package/esm/openapi/postman/build-request-url.mjs +1 -1
  589. package/esm/openapi/postman/example-from-schema.d.mts +1 -3
  590. package/esm/openapi/postman/example-from-schema.d.mts.map +1 -1
  591. package/esm/openapi/postman/index.d.mts +2 -1
  592. package/esm/openapi/postman/openapi-to-postman-collection.d.mts +3 -5
  593. package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -1
  594. package/esm/openapi/postman/postman-types.d.mts +19 -18
  595. package/esm/openapi/postman/postman-types.d.mts.map +1 -1
  596. package/esm/openapi/postman/schema-refs.d.mts +1 -3
  597. package/esm/openapi/postman/schema-refs.d.mts.map +1 -1
  598. package/esm/openapi/postman/uuid-v5.mjs +1 -1
  599. package/esm/openapi/schema-registry.d.mts +1 -1
  600. package/esm/openapi/security.mjs +1 -1
  601. package/esm/openapi/types.d.mts +23 -21
  602. package/esm/openapi/types.d.mts.map +1 -1
  603. package/esm/production/assert-generated-imports.mjs +1 -1
  604. package/esm/production/build-contributions.mjs +1 -1
  605. package/esm/production/bundle-framework-dependencies.mjs +1 -1
  606. package/esm/production/dist-build-manifest.mjs +1 -1
  607. package/esm/production/esbuild-plugins.mjs.map +1 -1
  608. package/esm/production/esbuild-preflight.mjs +1 -1
  609. package/esm/production/production-builder.mjs +2 -1
  610. package/esm/production/production-builder.mjs.map +1 -1
  611. package/esm/production/production-supervisor.mjs +1 -1
  612. package/esm/production/registration-child-runner.mjs +4 -3
  613. package/esm/production/registration-child-runner.mjs.map +1 -1
  614. package/esm/production/resolve-build-config.d.mts +4 -4
  615. package/esm/production/resolve-build-config.d.mts.map +1 -1
  616. package/esm/production/resolve-build-config.mjs +1 -1
  617. package/esm/production/route-registration-child.d.mts +1 -1
  618. package/esm/production/route-registration-child.mjs +8 -7
  619. package/esm/production/route-registration-child.mjs.map +1 -1
  620. package/esm/production/tsconfig-path-aliases.mjs +1 -1
  621. package/esm/react/index.d.mts +1 -3
  622. package/esm/react/index.d.mts.map +1 -1
  623. package/esm/react/index.mjs.map +1 -1
  624. package/esm/repositories/adapters/cascade/cascade-adapter.d.mts +3 -4
  625. package/esm/repositories/adapters/cascade/cascade-adapter.d.mts.map +1 -1
  626. package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts +2 -3
  627. package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts.map +1 -1
  628. package/esm/repositories/adapters/cascade/filter-applicator.mjs +10 -9
  629. package/esm/repositories/adapters/cascade/filter-applicator.mjs.map +1 -1
  630. package/esm/repositories/adapters/cascade/index.d.mts +2 -1
  631. package/esm/repositories/adapters/cascade/index.mjs +1 -1
  632. package/esm/repositories/contracts/index.d.mts +2 -1
  633. package/esm/repositories/contracts/query-builder.contract.d.mts +4 -6
  634. package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
  635. package/esm/repositories/contracts/repository-adapter.contract.d.mts +1 -3
  636. package/esm/repositories/contracts/repository-adapter.contract.d.mts.map +1 -1
  637. package/esm/repositories/contracts/types.d.mts +23 -25
  638. package/esm/repositories/contracts/types.d.mts.map +1 -1
  639. package/esm/repositories/index.d.mts +4 -1
  640. package/esm/repositories/index.mjs +1 -1
  641. package/esm/repositories/repository.manager.d.mts +2 -3
  642. package/esm/repositories/repository.manager.d.mts.map +1 -1
  643. package/esm/repositories/repository.manager.mjs +2 -2
  644. package/esm/repositories/repository.manager.mjs.map +1 -1
  645. package/esm/resource/define-resource.d.mts +3 -5
  646. package/esm/resource/define-resource.d.mts.map +1 -1
  647. package/esm/resource/index.d.mts +2 -1
  648. package/esm/resource/index.mjs +1 -1
  649. package/esm/resource/nullable-resource.d.mts +5 -7
  650. package/esm/resource/nullable-resource.d.mts.map +1 -1
  651. package/esm/resource/register-resource.d.mts +1 -3
  652. package/esm/resource/register-resource.d.mts.map +1 -1
  653. package/esm/resource/resource-field-builder.d.mts +1 -3
  654. package/esm/resource/resource-field-builder.d.mts.map +1 -1
  655. package/esm/resource/resource.d.mts +3 -5
  656. package/esm/resource/resource.d.mts.map +1 -1
  657. package/esm/resource/resource.mjs +4 -2
  658. package/esm/resource/resource.mjs.map +1 -1
  659. package/esm/resource/types.d.mts +21 -21
  660. package/esm/resource/types.d.mts.map +1 -1
  661. package/esm/restful/index.d.mts +2 -1
  662. package/esm/restful/index.mjs +1 -1
  663. package/esm/restful/restful.d.mts +12 -32
  664. package/esm/restful/restful.d.mts.map +1 -1
  665. package/esm/router/index.d.mts +2 -1
  666. package/esm/router/index.mjs +1 -1
  667. package/esm/router/named-api-routes-with-responses.mjs +2 -1
  668. package/esm/router/named-api-routes-with-responses.mjs.map +1 -1
  669. package/esm/router/normalize-request-path.d.mts +1 -2
  670. package/esm/router/normalize-request-path.d.mts.map +1 -1
  671. package/esm/router/normalize-route-path.d.mts +1 -2
  672. package/esm/router/normalize-route-path.d.mts.map +1 -1
  673. package/esm/router/positional-handler-diagnostics.d.mts +15 -13
  674. package/esm/router/positional-handler-diagnostics.d.mts.map +1 -1
  675. package/esm/router/resolve-route-rate-limit.mjs +3 -3
  676. package/esm/router/resolve-route-rate-limit.mjs.map +1 -1
  677. package/esm/router/route-builder.d.mts +1 -3
  678. package/esm/router/route-builder.d.mts.map +1 -1
  679. package/esm/router/route-guard-names.mjs +1 -1
  680. package/esm/router/route-guard-names.mjs.map +1 -1
  681. package/esm/router/route-name-method-suffix.d.mts +2 -3
  682. package/esm/router/route-name-method-suffix.d.mts.map +1 -1
  683. package/esm/router/route-name-taken-error.d.mts +1 -3
  684. package/esm/router/route-name-taken-error.d.mts.map +1 -1
  685. package/esm/router/route-registry.d.mts +1 -3
  686. package/esm/router/route-registry.d.mts.map +1 -1
  687. package/esm/router/router.d.mts +2 -4
  688. package/esm/router/router.d.mts.map +1 -1
  689. package/esm/router/router.mjs +8 -6
  690. package/esm/router/router.mjs.map +1 -1
  691. package/esm/router/types.d.mts +25 -26
  692. package/esm/router/types.d.mts.map +1 -1
  693. package/esm/router/unguarded-route-diagnostics.d.mts +6 -8
  694. package/esm/router/unguarded-route-diagnostics.d.mts.map +1 -1
  695. package/esm/secrets/errors.d.mts +9 -0
  696. package/esm/secrets/errors.d.mts.map +1 -0
  697. package/esm/secrets/errors.mjs +22 -0
  698. package/esm/secrets/errors.mjs.map +1 -0
  699. package/esm/secrets/file-backend.mjs +167 -0
  700. package/esm/secrets/file-backend.mjs.map +1 -0
  701. package/esm/secrets/index.d.mts +6 -0
  702. package/esm/secrets/index.mjs +6 -0
  703. package/esm/secrets/keyring-backend.mjs +50 -0
  704. package/esm/secrets/keyring-backend.mjs.map +1 -0
  705. package/esm/secrets/memory-backend.d.mts +12 -0
  706. package/esm/secrets/memory-backend.d.mts.map +1 -0
  707. package/esm/secrets/memory-backend.mjs +28 -0
  708. package/esm/secrets/memory-backend.mjs.map +1 -0
  709. package/esm/secrets/secret-store.d.mts +25 -0
  710. package/esm/secrets/secret-store.d.mts.map +1 -0
  711. package/esm/secrets/secret-store.mjs +117 -0
  712. package/esm/secrets/secret-store.mjs.map +1 -0
  713. package/esm/secrets/secrets.d.mts +11 -0
  714. package/esm/secrets/secrets.d.mts.map +1 -0
  715. package/esm/secrets/secrets.mjs +63 -0
  716. package/esm/secrets/secrets.mjs.map +1 -0
  717. package/esm/secrets/types.d.mts +22 -0
  718. package/esm/secrets/types.d.mts.map +1 -0
  719. package/esm/socket/index.d.mts +2 -1
  720. package/esm/socket/index.mjs +2 -2
  721. package/esm/socket/types.d.mts +2 -4
  722. package/esm/socket/types.d.mts.map +1 -1
  723. package/esm/socket/utils.d.mts +8 -3
  724. package/esm/socket/utils.d.mts.map +1 -1
  725. package/esm/socket/utils.mjs +12 -1
  726. package/esm/socket/utils.mjs.map +1 -1
  727. package/esm/storage/config.d.mts +4 -6
  728. package/esm/storage/config.d.mts.map +1 -1
  729. package/esm/storage/context/storage-driver-context.d.mts +3 -4
  730. package/esm/storage/context/storage-driver-context.d.mts.map +1 -1
  731. package/esm/storage/drivers/cloud-driver.d.mts +2 -4
  732. package/esm/storage/drivers/cloud-driver.d.mts.map +1 -1
  733. package/esm/storage/drivers/cloud-driver.mjs.map +1 -1
  734. package/esm/storage/drivers/do-spaces-driver.d.mts +1 -3
  735. package/esm/storage/drivers/do-spaces-driver.d.mts.map +1 -1
  736. package/esm/storage/drivers/local-driver.d.mts +2 -3
  737. package/esm/storage/drivers/local-driver.d.mts.map +1 -1
  738. package/esm/storage/drivers/local-driver.mjs +8 -3
  739. package/esm/storage/drivers/local-driver.mjs.map +1 -1
  740. package/esm/storage/drivers/r2-driver.d.mts +1 -3
  741. package/esm/storage/drivers/r2-driver.d.mts.map +1 -1
  742. package/esm/storage/drivers/s3-driver.d.mts +1 -3
  743. package/esm/storage/drivers/s3-driver.d.mts.map +1 -1
  744. package/esm/storage/index.d.mts +2 -1
  745. package/esm/storage/index.mjs +1 -1
  746. package/esm/storage/local-disk-roots.mjs +2 -2
  747. package/esm/storage/local-disk-roots.mjs.map +1 -1
  748. package/esm/storage/scoped-storage.d.mts +2 -3
  749. package/esm/storage/scoped-storage.d.mts.map +1 -1
  750. package/esm/storage/storage-file.d.mts +1 -3
  751. package/esm/storage/storage-file.d.mts.map +1 -1
  752. package/esm/storage/storage.d.mts +3 -4
  753. package/esm/storage/storage.d.mts.map +1 -1
  754. package/esm/storage/types.d.mts +36 -36
  755. package/esm/storage/types.d.mts.map +1 -1
  756. package/esm/storage/utils/classify-ip-address.d.mts +1 -2
  757. package/esm/storage/utils/classify-ip-address.d.mts.map +1 -1
  758. package/esm/storage/utils/contain-path.d.mts +1 -2
  759. package/esm/storage/utils/contain-path.d.mts.map +1 -1
  760. package/esm/storage/utils/mime.d.mts +2 -3
  761. package/esm/storage/utils/mime.d.mts.map +1 -1
  762. package/esm/storage/utils/safe-fetch.d.mts +6 -6
  763. package/esm/storage/utils/safe-fetch.d.mts.map +1 -1
  764. package/esm/storage/utils/safe-fetch.mjs +3 -3
  765. package/esm/storage/utils/safe-fetch.mjs.map +1 -1
  766. package/esm/storage/utils/storage-capability-error.d.mts +1 -3
  767. package/esm/storage/utils/storage-capability-error.d.mts.map +1 -1
  768. package/esm/storage/utils/storage-error.d.mts +2 -3
  769. package/esm/storage/utils/storage-error.d.mts.map +1 -1
  770. package/esm/storage/utils/storage-not-initialized-error.d.mts +1 -2
  771. package/esm/storage/utils/storage-not-initialized-error.d.mts.map +1 -1
  772. package/esm/tests/authenticated-test-client.d.mts +5 -6
  773. package/esm/tests/authenticated-test-client.d.mts.map +1 -1
  774. package/esm/tests/factories.d.mts +38 -23
  775. package/esm/tests/factories.d.mts.map +1 -1
  776. package/esm/tests/fakes/cache-fake.d.mts +14 -9
  777. package/esm/tests/fakes/cache-fake.d.mts.map +1 -1
  778. package/esm/tests/fakes/clock-fake.d.mts +13 -8
  779. package/esm/tests/fakes/clock-fake.d.mts.map +1 -1
  780. package/esm/tests/fakes/fake-assertion-error.d.mts +2 -3
  781. package/esm/tests/fakes/fake-assertion-error.d.mts.map +1 -1
  782. package/esm/tests/fakes/ids-fake.d.mts +5 -4
  783. package/esm/tests/fakes/ids-fake.d.mts.map +1 -1
  784. package/esm/tests/fakes/index.d.mts +3 -1
  785. package/esm/tests/fakes/index.mjs +2 -1
  786. package/esm/tests/fakes/mail-fake.d.mts +21 -13
  787. package/esm/tests/fakes/mail-fake.d.mts.map +1 -1
  788. package/esm/tests/fakes/queue-fake.d.mts +21 -13
  789. package/esm/tests/fakes/queue-fake.d.mts.map +1 -1
  790. package/esm/tests/fakes/secrets-fake.d.mts +13 -0
  791. package/esm/tests/fakes/secrets-fake.d.mts.map +1 -0
  792. package/esm/tests/fakes/secrets-fake.mjs +50 -0
  793. package/esm/tests/fakes/secrets-fake.mjs.map +1 -0
  794. package/esm/tests/fakes/storage-fake.d.mts +12 -8
  795. package/esm/tests/fakes/storage-fake.d.mts.map +1 -1
  796. package/esm/tests/fakes/storage-fake.mjs +1 -1
  797. package/esm/tests/fakes/test-fakes.d.mts +9 -10
  798. package/esm/tests/fakes/test-fakes.d.mts.map +1 -1
  799. package/esm/tests/fakes/test-fakes.mjs +6 -3
  800. package/esm/tests/fakes/test-fakes.mjs.map +1 -1
  801. package/esm/tests/index.d.mts +3 -1
  802. package/esm/tests/index.mjs +2 -1
  803. package/esm/tests/snapshot-response.d.mts +4 -5
  804. package/esm/tests/snapshot-response.d.mts.map +1 -1
  805. package/esm/tests/start-http-development-server.d.mts +4 -6
  806. package/esm/tests/start-http-development-server.d.mts.map +1 -1
  807. package/esm/tests/start-http-development-server.mjs +5 -5
  808. package/esm/tests/start-http-development-server.mjs.map +1 -1
  809. package/esm/tests/test-connectors-selection.d.mts +2 -2
  810. package/esm/tests/test-connectors-selection.d.mts.map +1 -1
  811. package/esm/tests/test-connectors-selection.mjs +1 -1
  812. package/esm/tests/test-helpers.d.mts +11 -12
  813. package/esm/tests/test-helpers.d.mts.map +1 -1
  814. package/esm/tests/test-http-server.d.mts +14 -10
  815. package/esm/tests/test-http-server.d.mts.map +1 -1
  816. package/esm/tests/test-lifecycle-state.mjs +1 -1
  817. package/esm/tests/vitest-setup.d.mts +7 -8
  818. package/esm/tests/vitest-setup.d.mts.map +1 -1
  819. package/esm/tests/vitest-setup.mjs.map +1 -1
  820. package/esm/tooling/agents-md/agents-md-markers.d.mts +4 -5
  821. package/esm/tooling/agents-md/agents-md-markers.d.mts.map +1 -1
  822. package/esm/tooling/agents-md/agents-md-markers.mjs +2 -1
  823. package/esm/tooling/agents-md/agents-md-markers.mjs.map +1 -1
  824. package/esm/tooling/agents-md/agents-md-refresher.d.mts +19 -12
  825. package/esm/tooling/agents-md/agents-md-refresher.d.mts.map +1 -1
  826. package/esm/tooling/agents-md/installed-skills.d.mts +13 -9
  827. package/esm/tooling/agents-md/installed-skills.d.mts.map +1 -1
  828. package/esm/tooling/agents-md/render-agents-md.d.mts +8 -7
  829. package/esm/tooling/agents-md/render-agents-md.d.mts.map +1 -1
  830. package/esm/tooling/agents-md/render-agents-md.mjs +2 -2
  831. package/esm/tooling/agents-md/render-agents-md.mjs.map +1 -1
  832. package/esm/tooling/agents-md/write-agents-md.d.mts +17 -12
  833. package/esm/tooling/agents-md/write-agents-md.d.mts.map +1 -1
  834. package/esm/tooling/board/board-message.d.mts +4 -6
  835. package/esm/tooling/board/board-message.d.mts.map +1 -1
  836. package/esm/tooling/board/board.d.mts +50 -38
  837. package/esm/tooling/board/board.d.mts.map +1 -1
  838. package/esm/tooling/board/board.mjs +4 -3
  839. package/esm/tooling/board/board.mjs.map +1 -1
  840. package/esm/tooling/board/board.types.d.mts +32 -23
  841. package/esm/tooling/board/board.types.d.mts.map +1 -1
  842. package/esm/tooling/check/changed-files.d.mts +4 -6
  843. package/esm/tooling/check/changed-files.d.mts.map +1 -1
  844. package/esm/tooling/check/changed-files.mjs +2 -2
  845. package/esm/tooling/check/changed-files.mjs.map +1 -1
  846. package/esm/tooling/check/check-report.types.d.mts +22 -17
  847. package/esm/tooling/check/check-report.types.d.mts.map +1 -1
  848. package/esm/tooling/check/code-style-conventions.mjs +25 -25
  849. package/esm/tooling/check/code-style-conventions.mjs.map +1 -1
  850. package/esm/tooling/check/conventions-step.d.mts +4 -6
  851. package/esm/tooling/check/conventions-step.d.mts.map +1 -1
  852. package/esm/tooling/check/conventions-step.mjs +7 -18
  853. package/esm/tooling/check/conventions-step.mjs.map +1 -1
  854. package/esm/tooling/check/environment-step.d.mts +2 -4
  855. package/esm/tooling/check/environment-step.d.mts.map +1 -1
  856. package/esm/tooling/check/environment-step.mjs +1 -1
  857. package/esm/tooling/check/index.mjs +1 -1
  858. package/esm/tooling/check/lint-step.d.mts +5 -12
  859. package/esm/tooling/check/lint-step.d.mts.map +1 -1
  860. package/esm/tooling/check/lint-step.mjs +16 -12
  861. package/esm/tooling/check/lint-step.mjs.map +1 -1
  862. package/esm/tooling/check/request-input.mjs +15 -15
  863. package/esm/tooling/check/request-input.mjs.map +1 -1
  864. package/esm/tooling/check/run-check.d.mts +24 -14
  865. package/esm/tooling/check/run-check.d.mts.map +1 -1
  866. package/esm/tooling/check/run-check.mjs +2 -2
  867. package/esm/tooling/check/run-check.mjs.map +1 -1
  868. package/esm/tooling/check/run-tests.d.mts +22 -15
  869. package/esm/tooling/check/run-tests.d.mts.map +1 -1
  870. package/esm/tooling/check/security-conventions.mjs +133 -131
  871. package/esm/tooling/check/security-conventions.mjs.map +1 -1
  872. package/esm/tooling/check/source-ast.mjs +92 -132
  873. package/esm/tooling/check/source-ast.mjs.map +1 -1
  874. package/esm/tooling/check/tests-step.d.mts +7 -8
  875. package/esm/tooling/check/tests-step.d.mts.map +1 -1
  876. package/esm/tooling/check/tests-step.mjs +3 -3
  877. package/esm/tooling/check/tests-step.mjs.map +1 -1
  878. package/esm/tooling/dev-state/dev-server-state.d.mts +17 -13
  879. package/esm/tooling/dev-state/dev-server-state.d.mts.map +1 -1
  880. package/esm/tooling/devtools/devtools-client.d.mts +29 -20
  881. package/esm/tooling/devtools/devtools-client.d.mts.map +1 -1
  882. package/esm/tooling/generate/generation.d.mts +34 -22
  883. package/esm/tooling/generate/generation.d.mts.map +1 -1
  884. package/esm/tooling/generate/generation.mjs +9 -5
  885. package/esm/tooling/generate/generation.mjs.map +1 -1
  886. package/esm/tooling/generate/generator-spec.d.mts +9 -9
  887. package/esm/tooling/generate/generator-spec.d.mts.map +1 -1
  888. package/esm/tooling/generate/index.mjs +1 -1
  889. package/esm/tooling/generate/project-files.mjs +3 -3
  890. package/esm/tooling/generate/project-files.mjs.map +1 -1
  891. package/esm/tooling/generate/run-cli.d.mts +14 -11
  892. package/esm/tooling/generate/run-cli.d.mts.map +1 -1
  893. package/esm/tooling/generate/run-cli.mjs +2 -2
  894. package/esm/tooling/generate/run-cli.mjs.map +1 -1
  895. package/esm/tooling/generate/unified-diff.d.mts +10 -7
  896. package/esm/tooling/generate/unified-diff.d.mts.map +1 -1
  897. package/esm/tooling/index.d.mts +1 -0
  898. package/esm/tooling/inspect/boot-for-inspect.d.mts +7 -7
  899. package/esm/tooling/inspect/boot-for-inspect.d.mts.map +1 -1
  900. package/esm/tooling/inspect/collect-config.mjs +3 -3
  901. package/esm/tooling/inspect/collect-config.mjs.map +1 -1
  902. package/esm/tooling/inspect/collect-models.d.mts +4 -3
  903. package/esm/tooling/inspect/collect-models.d.mts.map +1 -1
  904. package/esm/tooling/inspect/collect-models.mjs +1 -1
  905. package/esm/tooling/inspect/collect-packages.d.mts +1 -2
  906. package/esm/tooling/inspect/collect-packages.d.mts.map +1 -1
  907. package/esm/tooling/inspect/collect-pages.mjs +10 -10
  908. package/esm/tooling/inspect/collect-pages.mjs.map +1 -1
  909. package/esm/tooling/inspect/collect-routes.mjs +1 -1
  910. package/esm/tooling/inspect/event-recorder.d.mts +7 -7
  911. package/esm/tooling/inspect/event-recorder.d.mts.map +1 -1
  912. package/esm/tooling/inspect/index.d.mts +2 -1
  913. package/esm/tooling/inspect/index.mjs +1 -1
  914. package/esm/tooling/inspect/inspect-app.d.mts +25 -16
  915. package/esm/tooling/inspect/inspect-app.d.mts.map +1 -1
  916. package/esm/tooling/inspect/inspect-report.schema.d.mts +1 -2
  917. package/esm/tooling/inspect/inspect-report.schema.d.mts.map +1 -1
  918. package/esm/tooling/inspect/inspect-report.types.d.mts +86 -54
  919. package/esm/tooling/inspect/inspect-report.types.d.mts.map +1 -1
  920. package/esm/tooling/mcp/create-mcp-context.d.mts +11 -8
  921. package/esm/tooling/mcp/create-mcp-context.d.mts.map +1 -1
  922. package/esm/tooling/mcp/db-schema.d.mts +10 -9
  923. package/esm/tooling/mcp/db-schema.d.mts.map +1 -1
  924. package/esm/tooling/mcp/docs-search.d.mts +20 -15
  925. package/esm/tooling/mcp/docs-search.d.mts.map +1 -1
  926. package/esm/tooling/mcp/index.mjs +1 -1
  927. package/esm/tooling/mcp/load-ai-tools.d.mts +7 -8
  928. package/esm/tooling/mcp/load-ai-tools.d.mts.map +1 -1
  929. package/esm/tooling/mcp/load-ai-tools.mjs +2 -1
  930. package/esm/tooling/mcp/load-ai-tools.mjs.map +1 -1
  931. package/esm/tooling/mcp/mcp-tools.d.mts +29 -19
  932. package/esm/tooling/mcp/mcp-tools.d.mts.map +1 -1
  933. package/esm/tooling/mcp/mcp-tools.mjs +3 -2
  934. package/esm/tooling/mcp/mcp-tools.mjs.map +1 -1
  935. package/esm/tooling/mcp/start-mcp-server.d.mts +24 -17
  936. package/esm/tooling/mcp/start-mcp-server.d.mts.map +1 -1
  937. package/esm/tooling/mcp/start-mcp-server.mjs +1 -1
  938. package/esm/tooling/mcp/start-mcp-server.mjs.map +1 -1
  939. package/esm/tooling/mcp/tool-input.d.mts +7 -7
  940. package/esm/tooling/mcp/tool-input.d.mts.map +1 -1
  941. package/esm/tooling/problem.d.mts +27 -17
  942. package/esm/tooling/problem.d.mts.map +1 -1
  943. package/esm/tooling/syntax/ast.mjs +230 -0
  944. package/esm/tooling/syntax/ast.mjs.map +1 -0
  945. package/esm/tooling/syntax/imports.mjs +34 -0
  946. package/esm/tooling/syntax/imports.mjs.map +1 -0
  947. package/esm/tooling/trace/trace-report.types.d.mts +36 -22
  948. package/esm/tooling/trace/trace-report.types.d.mts.map +1 -1
  949. package/esm/tooling/trace/trace-request.d.mts +27 -20
  950. package/esm/tooling/trace/trace-request.d.mts.map +1 -1
  951. package/esm/tooling/trace/trace-request.mjs +2 -2
  952. package/esm/tooling/trace/trace-request.mjs.map +1 -1
  953. package/esm/tooling/typecheck/index.mjs +1 -1
  954. package/esm/tooling/typecheck/run-typecheck.d.mts +15 -48
  955. package/esm/tooling/typecheck/run-typecheck.d.mts.map +1 -1
  956. package/esm/tooling/typecheck/run-typecheck.mjs +42 -105
  957. package/esm/tooling/typecheck/run-typecheck.mjs.map +1 -1
  958. package/esm/tooling/typescript/compiler.d.mts +31 -0
  959. package/esm/tooling/typescript/compiler.d.mts.map +1 -0
  960. package/esm/tooling/typescript/compiler.mjs +120 -0
  961. package/esm/tooling/typescript/compiler.mjs.map +1 -0
  962. package/esm/updater/update-warlock-packages.mjs +3 -2
  963. package/esm/updater/update-warlock-packages.mjs.map +1 -1
  964. package/esm/upgrade/codemods/index.mjs +3 -1
  965. package/esm/upgrade/codemods/index.mjs.map +1 -1
  966. package/esm/upgrade/codemods/logger-sync-calls.mjs +1 -1
  967. package/esm/upgrade/codemods/logger-sync-calls.mjs.map +1 -1
  968. package/esm/upgrade/codemods/oxc-toolchain.mjs +142 -0
  969. package/esm/upgrade/codemods/oxc-toolchain.mjs.map +1 -0
  970. package/esm/upgrade/codemods/request-log-snapshot.mjs +1 -1
  971. package/esm/upgrade/codemods/request-log-snapshot.mjs.map +1 -1
  972. package/esm/upgrade/codemods/toolchain-templates.mjs +244 -0
  973. package/esm/upgrade/codemods/toolchain-templates.mjs.map +1 -0
  974. package/esm/upgrade/diff.mjs +1 -1
  975. package/esm/upgrade/diff.mjs.map +1 -1
  976. package/esm/upgrade/load-ts-morph.mjs +3 -2
  977. package/esm/upgrade/load-ts-morph.mjs.map +1 -1
  978. package/esm/upgrade/run-upgrade.mjs +26 -7
  979. package/esm/upgrade/run-upgrade.mjs.map +1 -1
  980. package/esm/use-cases/index.d.mts +2 -1
  981. package/esm/use-cases/index.mjs +1 -1
  982. package/esm/use-cases/types.d.mts +116 -63
  983. package/esm/use-cases/types.d.mts.map +1 -1
  984. package/esm/use-cases/use-case-broadcast.d.mts +1 -3
  985. package/esm/use-cases/use-case-broadcast.d.mts.map +1 -1
  986. package/esm/use-cases/use-case-events.d.mts +3 -5
  987. package/esm/use-cases/use-case-events.d.mts.map +1 -1
  988. package/esm/use-cases/use-case-pipeline.d.mts +6 -6
  989. package/esm/use-cases/use-case-pipeline.d.mts.map +1 -1
  990. package/esm/use-cases/use-case.d.mts +2 -4
  991. package/esm/use-cases/use-case.d.mts.map +1 -1
  992. package/esm/use-cases/use-case.errors.d.mts +1 -3
  993. package/esm/use-cases/use-case.errors.d.mts.map +1 -1
  994. package/esm/use-cases/use-cases-registry.d.mts +8 -10
  995. package/esm/use-cases/use-cases-registry.d.mts.map +1 -1
  996. package/esm/utils/app-log.d.mts +1 -2
  997. package/esm/utils/app-log.d.mts.map +1 -1
  998. package/esm/utils/clock.d.mts +8 -6
  999. package/esm/utils/clock.d.mts.map +1 -1
  1000. package/esm/utils/database-log.d.mts +3 -4
  1001. package/esm/utils/database-log.d.mts.map +1 -1
  1002. package/esm/utils/environment.d.mts +4 -5
  1003. package/esm/utils/environment.d.mts.map +1 -1
  1004. package/esm/utils/framework-vesion.mjs.map +1 -1
  1005. package/esm/utils/get-localized.d.mts +2 -3
  1006. package/esm/utils/get-localized.d.mts.map +1 -1
  1007. package/esm/utils/ids.d.mts +9 -6
  1008. package/esm/utils/ids.d.mts.map +1 -1
  1009. package/esm/utils/index.d.mts +2 -1
  1010. package/esm/utils/index.mjs +1 -1
  1011. package/esm/utils/normalized-path.d.mts +1 -2
  1012. package/esm/utils/normalized-path.d.mts.map +1 -1
  1013. package/esm/utils/npm-registry.d.mts +1 -2
  1014. package/esm/utils/npm-registry.d.mts.map +1 -1
  1015. package/esm/utils/paths.d.mts +13 -14
  1016. package/esm/utils/paths.d.mts.map +1 -1
  1017. package/esm/utils/paths.mjs +2 -2
  1018. package/esm/utils/paths.mjs.map +1 -1
  1019. package/esm/utils/promise-all-object.d.mts +1 -2
  1020. package/esm/utils/promise-all-object.d.mts.map +1 -1
  1021. package/esm/utils/queue.d.mts +1 -2
  1022. package/esm/utils/queue.d.mts.map +1 -1
  1023. package/esm/utils/runtime.d.mts +11 -10
  1024. package/esm/utils/runtime.d.mts.map +1 -1
  1025. package/esm/utils/sleep.d.mts +1 -2
  1026. package/esm/utils/sleep.d.mts.map +1 -1
  1027. package/esm/utils/sluggable.d.mts +1 -3
  1028. package/esm/utils/sluggable.d.mts.map +1 -1
  1029. package/esm/utils/to-json.d.mts +1 -2
  1030. package/esm/utils/to-json.d.mts.map +1 -1
  1031. package/esm/utils/types.d.mts +1 -2
  1032. package/esm/utils/types.d.mts.map +1 -1
  1033. package/esm/utils/urls.d.mts +5 -6
  1034. package/esm/utils/urls.d.mts.map +1 -1
  1035. package/esm/utils/version-compare.d.mts +1 -2
  1036. package/esm/utils/version-compare.d.mts.map +1 -1
  1037. package/esm/validation/database/exists-except-current-id.d.mts +2 -3
  1038. package/esm/validation/database/exists-except-current-id.d.mts.map +1 -1
  1039. package/esm/validation/database/exists-except-current-user.d.mts +2 -3
  1040. package/esm/validation/database/exists-except-current-user.d.mts.map +1 -1
  1041. package/esm/validation/database/index.d.mts +2 -1
  1042. package/esm/validation/database/index.mjs +1 -1
  1043. package/esm/validation/database/types.d.mts +14 -10
  1044. package/esm/validation/database/types.d.mts.map +1 -1
  1045. package/esm/validation/database/unique-except-current-id.d.mts +2 -3
  1046. package/esm/validation/database/unique-except-current-id.d.mts.map +1 -1
  1047. package/esm/validation/database/unique-except-current-user.d.mts +2 -3
  1048. package/esm/validation/database/unique-except-current-user.d.mts.map +1 -1
  1049. package/esm/validation/file/file.d.mts +4 -6
  1050. package/esm/validation/file/file.d.mts.map +1 -1
  1051. package/esm/validation/file/index.d.mts +2 -1
  1052. package/esm/validation/file/index.mjs +1 -1
  1053. package/esm/validation/index.d.mts +5 -1
  1054. package/esm/validation/index.mjs +1 -1
  1055. package/esm/validation/plugins/index.mjs +1 -1
  1056. package/esm/validation/types.d.mts +6 -4
  1057. package/esm/validation/types.d.mts.map +1 -1
  1058. package/esm/validation/validateAll.mjs +2 -2
  1059. package/esm/validation/validateAll.mjs.map +1 -1
  1060. package/esm/validation/validation-failure-status.mjs +2 -2
  1061. package/esm/validation/validation-failure-status.mjs.map +1 -1
  1062. package/esm/validation/validators/file-validator.d.mts +2 -4
  1063. package/esm/validation/validators/file-validator.d.mts.map +1 -1
  1064. package/esm/validation/validators/index.d.mts +2 -1
  1065. package/esm/validation/validators/index.mjs +1 -1
  1066. package/esm/vite/lower-stage3-decorators.d.mts +2 -3
  1067. package/esm/vite/lower-stage3-decorators.d.mts.map +1 -1
  1068. package/esm/warlock-config/define-config.d.mts +1 -3
  1069. package/esm/warlock-config/define-config.d.mts.map +1 -1
  1070. package/esm/warlock-config/define-config.mjs +3 -2
  1071. package/esm/warlock-config/define-config.mjs.map +1 -1
  1072. package/esm/warlock-config/index.d.mts +2 -1
  1073. package/esm/warlock-config/index.mjs +1 -1
  1074. package/esm/warlock-config/types.d.mts +8 -6
  1075. package/esm/warlock-config/types.d.mts.map +1 -1
  1076. package/esm/warlock-config/warlock-config.manager.d.mts +5 -7
  1077. package/esm/warlock-config/warlock-config.manager.d.mts.map +1 -1
  1078. package/esm/warlock-config/warlock-config.manager.mjs +2 -1
  1079. package/esm/warlock-config/warlock-config.manager.mjs.map +1 -1
  1080. package/esm/warlock-config/warn-deprecated-config.mjs +1 -1
  1081. package/llms-full.txt +379 -22
  1082. package/llms.txt +3 -2
  1083. package/package.json +27 -15
  1084. package/skills/README.md +2 -1
  1085. package/skills/create-module/SKILL.md +7 -0
  1086. package/skills/index.md +3 -1
  1087. package/skills/report-framework-issue.md +154 -0
  1088. package/skills/run-app/SKILL.md +120 -10
  1089. package/skills/store-secrets/SKILL.md +102 -0
  1090. package/skills/test-fakes/SKILL.md +13 -11
  1091. package/skills/upgrade-from-5-29/SKILL.md +78 -0
  1092. package/skills/warlock-check/SKILL.md +6 -1
  1093. package/skills/warlock-doctor/SKILL.md +9 -0
  1094. package/skills/wire-socket/SKILL.md +19 -0
  1095. package/skills/write-cli-command/SKILL.md +21 -0
  1096. package/esm/tooling/check/index.d.mts +0 -8
  1097. package/esm/tooling/typecheck/index.d.mts +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"locales-ts-deprecated.check.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/doctor/checks/locales-ts-deprecated.check.ts"],"sourcesContent":["import { existsSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport ts from \"typescript\";\nimport { config } from \"../../../../config/config-getter\";\nimport {\n parseLocaleDictionary,\n type LocaleDictionaryEntries,\n} from \"../../../../localization/parse-locale-dictionary\";\nimport { appPath, rootPath } from \"../../../../utils/paths\";\nimport type { DoctorCheck } from \"../check.types\";\n\ntype LocaleSource = {\n file: string;\n module: string;\n};\n\nexport type LocaleInspection = LocaleSource & {\n convertible: boolean;\n reason: string;\n group?: string;\n dictionary?: Record<string, unknown>;\n entries?: LocaleDictionaryEntries;\n};\n\nfunction localeSources(): LocaleSource[] {\n const appDirectory = appPath();\n if (!existsSync(appDirectory)) return [];\n\n return readdirSync(appDirectory, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => ({\n file: path.join(appDirectory, entry.name, \"utils\", \"locales.ts\"),\n module: entry.name,\n }))\n .filter(({ file }) => existsSync(file));\n}\n\nfunction propertyName(property: ts.PropertyAssignment): string | undefined {\n if (ts.isIdentifier(property.name) || ts.isStringLiteral(property.name))\n return property.name.text;\n return undefined;\n}\n\nfunction literalObject(node: ts.Expression): Record<string, unknown> | undefined {\n if (!ts.isObjectLiteralExpression(node)) return undefined;\n const value: Record<string, unknown> = Object.create(null);\n for (const member of node.properties) {\n if (!ts.isPropertyAssignment(member)) return undefined;\n const key = propertyName(member);\n if (key === undefined) return undefined;\n if (ts.isStringLiteral(member.initializer) || ts.isNumericLiteral(member.initializer)) {\n value[key] = ts.isNumericLiteral(member.initializer)\n ? Number(member.initializer.text)\n : member.initializer.text;\n continue;\n }\n const nested = literalObject(member.initializer);\n if (nested === undefined) return undefined;\n value[key] = nested;\n }\n return value;\n}\n\nfunction flattenLiteral(\n value: Record<string, unknown>,\n group: string,\n entries: LocaleDictionaryEntries,\n): boolean {\n const values = Object.values(value);\n if (values.every((item) => typeof item === \"string\" || typeof item === \"number\")) {\n if (group === \"\") return false;\n if (!values.every((item) => typeof item === \"string\")) return false;\n entries[group] = value as Record<string, string>;\n return true;\n }\n if (!values.every((item) => item !== null && typeof item === \"object\" && !Array.isArray(item)))\n return false;\n return Object.entries(value).every(([key, nested]) =>\n flattenLiteral(\n nested as Record<string, unknown>,\n group === \"\" ? key : `${group}.${key}`,\n entries,\n ),\n );\n}\n\nfunction inspect(source: LocaleSource): LocaleInspection {\n const jsonFile = path.join(path.dirname(source.file), \"locales.json\");\n if (existsSync(jsonFile))\n return { ...source, convertible: false, reason: \"locales.json already exists\" };\n\n const text = readFileSync(source.file, \"utf8\");\n const program = ts.createSourceFile(source.file, text, ts.ScriptTarget.Latest, true);\n const syntaxDiagnostics = ts.transpileModule(text, {\n fileName: source.file,\n reportDiagnostics: true,\n }).diagnostics;\n if (syntaxDiagnostics !== undefined && syntaxDiagnostics.length > 0)\n return { ...source, convertible: false, reason: \"TypeScript syntax is invalid\" };\n const [importStatement, callStatement] = program.statements;\n if (\n !importStatement ||\n !ts.isImportDeclaration(importStatement) ||\n !ts.isStringLiteral(importStatement.moduleSpecifier) ||\n importStatement.moduleSpecifier.text !== \"@warlock.js/core\" ||\n !importStatement.importClause ||\n importStatement.importClause.isTypeOnly ||\n importStatement.importClause.name ||\n !importStatement.importClause.namedBindings ||\n !ts.isNamedImports(importStatement.importClause.namedBindings) ||\n importStatement.importClause.namedBindings.elements.length !== 1 ||\n importStatement.importClause.namedBindings.elements[0]?.name.text !== \"groupedTranslations\" ||\n importStatement.importClause.namedBindings.elements[0]?.propertyName\n )\n return {\n ...source,\n convertible: false,\n reason: \"must import only groupedTranslations from @warlock.js/core\",\n };\n\n if (program.statements.length !== 2)\n return {\n ...source,\n convertible: false,\n reason: \"must contain only the groupedTranslations import and one call\",\n };\n\n if (\n !callStatement ||\n !ts.isExpressionStatement(callStatement) ||\n !ts.isCallExpression(callStatement.expression)\n )\n return {\n ...source,\n convertible: false,\n reason: \"must contain one top-level groupedTranslations call\",\n };\n const call = callStatement.expression;\n if (\n !ts.isIdentifier(call.expression) ||\n call.expression.text !== \"groupedTranslations\" ||\n call.arguments.length !== 2 ||\n !ts.isStringLiteral(call.arguments[0]!)\n )\n return {\n ...source,\n convertible: false,\n reason: \"must call groupedTranslations with a string group and object\",\n };\n const dictionary = literalObject(call.arguments[1]!);\n if (!dictionary)\n return {\n ...source,\n convertible: false,\n reason: \"translation object must contain only literal keys, objects, strings, or numbers\",\n };\n const group = call.arguments[0].text;\n const entries: LocaleDictionaryEntries = Object.create(null);\n if (!flattenLiteral(dictionary, group, entries))\n return {\n ...source,\n convertible: false,\n reason: \"translation object has no valid literal locale entries\",\n };\n return {\n ...source,\n convertible: true,\n reason: \"pure groupedTranslations literal\",\n group,\n dictionary,\n entries,\n };\n}\n\nexport function inspectLocaleSources(): LocaleInspection[] {\n return localeSources().map(inspect);\n}\n\nfunction localeCodes(): readonly string[] | undefined {\n const configured = config.key<unknown>(\"app.localeCodes\");\n return Array.isArray(configured) && configured.every((code) => typeof code === \"string\")\n ? configured\n : undefined;\n}\n\nfunction sameEntries(left: LocaleDictionaryEntries, right: LocaleDictionaryEntries): boolean {\n return JSON.stringify(left) === JSON.stringify(right);\n}\n\n/** Convert safe legacy locale sources, retaining a TS file whenever verification cannot prove equivalence. */\nexport function fixLocaleSources(): LocaleInspection[] {\n return inspectLocaleSources().map((result) => {\n if (!result.convertible || !result.group || !result.dictionary || !result.entries)\n return result;\n const jsonFile = path.join(path.dirname(result.file), \"locales.json\");\n const document: Record<string, unknown> =\n result.group === result.module\n ? result.dictionary\n : { $group: result.group, ...result.dictionary };\n const json = `${JSON.stringify(document, null, 2)}\\n`;\n writeFileSync(jsonFile, json);\n try {\n const parsed = parseLocaleDictionary({\n sourceFile: rootPath(path.relative(process.cwd(), jsonFile)),\n source: json,\n defaultNamespace: result.module,\n localeCodes: localeCodes(),\n });\n if (!sameEntries(result.entries, parsed.entries)) throw new Error(\"flattened entries differ\");\n } catch (error) {\n unlinkSync(jsonFile);\n return {\n ...result,\n convertible: false,\n reason: `verification failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n unlinkSync(result.file);\n return {\n ...result,\n reason: \"converted (comments in the TypeScript source are not retained)\",\n };\n });\n}\n\nexport const localesTsDeprecatedCheck: DoctorCheck = {\n name: \"locales-ts-deprecated\",\n run: () => {\n const sources = inspectLocaleSources();\n if (sources.length === 0) return undefined;\n const details = sources.map((source) => {\n const label = path.relative(process.cwd(), source.file).replaceAll(\"\\\\\", \"/\");\n return `${label}: ${source.convertible ? \"auto-convertible\" : \"manual\"} (${source.reason})`;\n });\n return {\n name: \"locales-ts-deprecated\",\n status: \"warn\",\n code: \"WL9101\",\n detail:\n `${details.join(\"; \")}. Auto-loaded locales.ts goes away in v6; ` +\n \"run `warlock doctor --fix` to convert auto-convertible files.\",\n };\n },\n};\n"],"mappings":";;;;;;;;AAwBA,SAAS,gBAAgC;CACvC,MAAM,eAAe,QAAQ;CAC7B,IAAI,CAAC,WAAW,YAAY,GAAG,OAAO,CAAC;CAEvC,OAAO,YAAY,cAAc,EAAE,eAAe,KAAK,CAAC,CAAC,CACtD,QAAQ,UAAU,MAAM,YAAY,CAAC,CAAC,CACtC,KAAK,WAAW;EACf,MAAM,KAAK,KAAK,cAAc,MAAM,MAAM,SAAS,YAAY;EAC/D,QAAQ,MAAM;CAChB,EAAE,CAAC,CACF,QAAQ,EAAE,WAAW,WAAW,IAAI,CAAC;AAC1C;AAEA,SAAS,aAAa,UAAqD;CACzE,IAAI,GAAG,aAAa,SAAS,IAAI,KAAK,GAAG,gBAAgB,SAAS,IAAI,GACpE,OAAO,SAAS,KAAK;AAEzB;AAEA,SAAS,cAAc,MAA0D;CAC/E,IAAI,CAAC,GAAG,0BAA0B,IAAI,GAAG,OAAO;CAChD,MAAM,QAAiC,OAAO,OAAO,IAAI;CACzD,KAAK,MAAM,UAAU,KAAK,YAAY;EACpC,IAAI,CAAC,GAAG,qBAAqB,MAAM,GAAG,OAAO;EAC7C,MAAM,MAAM,aAAa,MAAM;EAC/B,IAAI,QAAQ,QAAW,OAAO;EAC9B,IAAI,GAAG,gBAAgB,OAAO,WAAW,KAAK,GAAG,iBAAiB,OAAO,WAAW,GAAG;GACrF,MAAM,OAAO,GAAG,iBAAiB,OAAO,WAAW,IAC/C,OAAO,OAAO,YAAY,IAAI,IAC9B,OAAO,YAAY;GACvB;EACF;EACA,MAAM,SAAS,cAAc,OAAO,WAAW;EAC/C,IAAI,WAAW,QAAW,OAAO;EACjC,MAAM,OAAO;CACf;CACA,OAAO;AACT;AAEA,SAAS,eACP,OACA,OACA,SACS;CACT,MAAM,SAAS,OAAO,OAAO,KAAK;CAClC,IAAI,OAAO,OAAO,SAAS,OAAO,SAAS,YAAY,OAAO,SAAS,QAAQ,GAAG;EAChF,IAAI,UAAU,IAAI,OAAO;EACzB,IAAI,CAAC,OAAO,OAAO,SAAS,OAAO,SAAS,QAAQ,GAAG,OAAO;EAC9D,QAAQ,SAAS;EACjB,OAAO;CACT;CACA,IAAI,CAAC,OAAO,OAAO,SAAS,SAAS,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,CAAC,GAC3F,OAAO;CACT,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,YACxC,eACE,QACA,UAAU,KAAK,MAAM,GAAG,MAAM,GAAG,OACjC,OACF,CACF;AACF;AAEA,SAAS,QAAQ,QAAwC;CAEvD,IAAI,WADa,KAAK,KAAK,KAAK,QAAQ,OAAO,IAAI,GAAG,cAChC,CAAC,GACrB,OAAO;EAAE,GAAG;EAAQ,aAAa;EAAO,QAAQ;CAA8B;CAEhF,MAAM,OAAO,aAAa,OAAO,MAAM,MAAM;CAC7C,MAAM,UAAU,GAAG,iBAAiB,OAAO,MAAM,MAAM,GAAG,aAAa,QAAQ,IAAI;CACnF,MAAM,oBAAoB,GAAG,gBAAgB,MAAM;EACjD,UAAU,OAAO;EACjB,mBAAmB;CACrB,CAAC,CAAC,CAAC;CACH,IAAI,sBAAsB,UAAa,kBAAkB,SAAS,GAChE,OAAO;EAAE,GAAG;EAAQ,aAAa;EAAO,QAAQ;CAA+B;CACjF,MAAM,CAAC,iBAAiB,iBAAiB,QAAQ;CACjD,IACE,CAAC,mBACD,CAAC,GAAG,oBAAoB,eAAe,KACvC,CAAC,GAAG,gBAAgB,gBAAgB,eAAe,KACnD,gBAAgB,gBAAgB,SAAS,sBACzC,CAAC,gBAAgB,gBACjB,gBAAgB,aAAa,cAC7B,gBAAgB,aAAa,QAC7B,CAAC,gBAAgB,aAAa,iBAC9B,CAAC,GAAG,eAAe,gBAAgB,aAAa,aAAa,KAC7D,gBAAgB,aAAa,cAAc,SAAS,WAAW,KAC/D,gBAAgB,aAAa,cAAc,SAAS,EAAE,EAAE,KAAK,SAAS,yBACtE,gBAAgB,aAAa,cAAc,SAAS,EAAE,EAAE,cAExD,OAAO;EACL,GAAG;EACH,aAAa;EACb,QAAQ;CACV;CAEF,IAAI,QAAQ,WAAW,WAAW,GAChC,OAAO;EACL,GAAG;EACH,aAAa;EACb,QAAQ;CACV;CAEF,IACE,CAAC,iBACD,CAAC,GAAG,sBAAsB,aAAa,KACvC,CAAC,GAAG,iBAAiB,cAAc,UAAU,GAE7C,OAAO;EACL,GAAG;EACH,aAAa;EACb,QAAQ;CACV;CACF,MAAM,OAAO,cAAc;CAC3B,IACE,CAAC,GAAG,aAAa,KAAK,UAAU,KAChC,KAAK,WAAW,SAAS,yBACzB,KAAK,UAAU,WAAW,KAC1B,CAAC,GAAG,gBAAgB,KAAK,UAAU,EAAG,GAEtC,OAAO;EACL,GAAG;EACH,aAAa;EACb,QAAQ;CACV;CACF,MAAM,aAAa,cAAc,KAAK,UAAU,EAAG;CACnD,IAAI,CAAC,YACH,OAAO;EACL,GAAG;EACH,aAAa;EACb,QAAQ;CACV;CACF,MAAM,QAAQ,KAAK,UAAU,EAAE,CAAC;CAChC,MAAM,UAAmC,OAAO,OAAO,IAAI;CAC3D,IAAI,CAAC,eAAe,YAAY,OAAO,OAAO,GAC5C,OAAO;EACL,GAAG;EACH,aAAa;EACb,QAAQ;CACV;CACF,OAAO;EACL,GAAG;EACH,aAAa;EACb,QAAQ;EACR;EACA;EACA;CACF;AACF;AAEA,SAAgB,uBAA2C;CACzD,OAAO,cAAc,CAAC,CAAC,IAAI,OAAO;AACpC;AAEA,SAAS,cAA6C;CACpD,MAAM,aAAa,OAAO,IAAa,iBAAiB;CACxD,OAAO,MAAM,QAAQ,UAAU,KAAK,WAAW,OAAO,SAAS,OAAO,SAAS,QAAQ,IACnF,aACA;AACN;AAEA,SAAS,YAAY,MAA+B,OAAyC;CAC3F,OAAO,KAAK,UAAU,IAAI,MAAM,KAAK,UAAU,KAAK;AACtD;;AAGA,SAAgB,mBAAuC;CACrD,OAAO,qBAAqB,CAAC,CAAC,KAAK,WAAW;EAC5C,IAAI,CAAC,OAAO,eAAe,CAAC,OAAO,SAAS,CAAC,OAAO,cAAc,CAAC,OAAO,SACxE,OAAO;EACT,MAAM,WAAW,KAAK,KAAK,KAAK,QAAQ,OAAO,IAAI,GAAG,cAAc;EACpE,MAAM,WACJ,OAAO,UAAU,OAAO,SACpB,OAAO,aACP;GAAE,QAAQ,OAAO;GAAO,GAAG,OAAO;EAAW;EACnD,MAAM,OAAO,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE;EAClD,cAAc,UAAU,IAAI;EAC5B,IAAI;GACF,MAAM,SAAS,sBAAsB;IACnC,YAAY,SAAS,KAAK,SAAS,QAAQ,IAAI,GAAG,QAAQ,CAAC;IAC3D,QAAQ;IACR,kBAAkB,OAAO;IACzB,aAAa,YAAY;GAC3B,CAAC;GACD,IAAI,CAAC,YAAY,OAAO,SAAS,OAAO,OAAO,GAAG,MAAM,IAAI,MAAM,0BAA0B;EAC9F,SAAS,OAAO;GACd,WAAW,QAAQ;GACnB,OAAO;IACL,GAAG;IACH,aAAa;IACb,QAAQ,wBAAwB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GACvF;EACF;EACA,WAAW,OAAO,IAAI;EACtB,OAAO;GACL,GAAG;GACH,QAAQ;EACV;CACF,CAAC;AACH;AAEA,MAAa,2BAAwC;CACnD,MAAM;CACN,WAAW;EACT,MAAM,UAAU,qBAAqB;EACrC,IAAI,QAAQ,WAAW,GAAG,OAAO;EAKjC,OAAO;GACL,MAAM;GACN,QAAQ;GACR,MAAM;GACN,QACE,GATY,QAAQ,KAAK,WAAW;IAEtC,OAAO,GADO,KAAK,SAAS,QAAQ,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC,WAAW,MAAM,GAC3D,EAAE,IAAI,OAAO,cAAc,qBAAqB,SAAS,IAAI,OAAO,OAAO;GAC3F,CAMa,CAAC,CAAC,KAAK,IAAI,EAAE;EAE1B;CACF;AACF"}
1
+ {"version":3,"file":"locales-ts-deprecated.check.mjs","names":["ast.isPropertyAssignment","ast.keyName","ast.isStringLiteral","ast.isNumericLiteral","ast.parseSourceFile","ast.valueText","ast.isExpressionStatement","ast.isIdentifier"],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/doctor/checks/locales-ts-deprecated.check.ts"],"sourcesContent":["import { existsSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { parseSync } from \"oxc-parser\";\nimport * as ast from \"../../../../tooling/syntax/ast\";\nimport { config } from \"../../../../config/config-getter\";\nimport {\n parseLocaleDictionary,\n type LocaleDictionaryEntries,\n} from \"../../../../localization/parse-locale-dictionary\";\nimport { appPath, rootPath } from \"../../../../utils/paths\";\nimport type { DoctorCheck } from \"../check.types\";\n\ntype LocaleSource = {\n file: string;\n module: string;\n};\n\nexport type LocaleInspection = LocaleSource & {\n convertible: boolean;\n reason: string;\n group?: string;\n dictionary?: Record<string, unknown>;\n entries?: LocaleDictionaryEntries;\n};\n\nfunction localeSources(): LocaleSource[] {\n const appDirectory = appPath();\n if (!existsSync(appDirectory)) return [];\n\n return readdirSync(appDirectory, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => ({\n file: path.join(appDirectory, entry.name, \"utils\", \"locales.ts\"),\n module: entry.name,\n }))\n .filter(({ file }) => existsSync(file));\n}\n\nfunction literalObject(node: ast.Node | undefined): Record<string, unknown> | undefined {\n if (node?.type !== \"ObjectExpression\") return undefined;\n const value: Record<string, unknown> = Object.create(null);\n for (const member of node.properties) {\n if (!ast.isPropertyAssignment(member)) return undefined;\n const key = ast.keyName(member.key);\n if (key === undefined) return undefined;\n if (ast.isStringLiteral(member.value) || ast.isNumericLiteral(member.value))\n value[key] = member.value.value;\n else {\n const nested = literalObject(member.value);\n if (nested === undefined) return undefined;\n value[key] = nested;\n }\n }\n return value;\n}\n\nfunction flattenLiteral(\n value: Record<string, unknown>,\n group: string,\n entries: LocaleDictionaryEntries,\n): boolean {\n const values = Object.values(value);\n if (values.every((item) => typeof item === \"string\" || typeof item === \"number\")) {\n if (group === \"\") return false;\n if (!values.every((item) => typeof item === \"string\")) return false;\n entries[group] = value as Record<string, string>;\n return true;\n }\n if (!values.every((item) => item !== null && typeof item === \"object\" && !Array.isArray(item)))\n return false;\n return Object.entries(value).every(([key, nested]) =>\n flattenLiteral(\n nested as Record<string, unknown>,\n group === \"\" ? key : `${group}.${key}`,\n entries,\n ),\n );\n}\n\nfunction inspect(source: LocaleSource): LocaleInspection {\n const jsonFile = path.join(path.dirname(source.file), \"locales.json\");\n if (existsSync(jsonFile))\n return { ...source, convertible: false, reason: \"locales.json already exists\" };\n\n const text = readFileSync(source.file, \"utf8\");\n const program = ast.parseSourceFile(source.file, text);\n if (parseSync(source.file, text).errors.length > 0)\n return { ...source, convertible: false, reason: \"TypeScript syntax is invalid\" };\n const [importStatement, callStatement] = program.body;\n const binding =\n importStatement?.type === \"ImportDeclaration\" ? importStatement.specifiers[0] : undefined;\n if (\n importStatement?.type !== \"ImportDeclaration\" ||\n importStatement.source.value !== \"@warlock.js/core\" ||\n importStatement.importKind === \"type\" ||\n importStatement.specifiers.length !== 1 ||\n binding?.type !== \"ImportSpecifier\" ||\n binding.importKind === \"type\" ||\n binding.local.name !== \"groupedTranslations\" ||\n ast.valueText(binding.imported) !== \"groupedTranslations\"\n )\n return {\n ...source,\n convertible: false,\n reason: \"must import only groupedTranslations from @warlock.js/core\",\n };\n\n if (program.body.length !== 2)\n return {\n ...source,\n convertible: false,\n reason: \"must contain only the groupedTranslations import and one call\",\n };\n\n if (\n !callStatement ||\n !ast.isExpressionStatement(callStatement) ||\n callStatement.expression.type !== \"CallExpression\"\n )\n return {\n ...source,\n convertible: false,\n reason: \"must contain one top-level groupedTranslations call\",\n };\n const call = callStatement.expression;\n if (\n !ast.isIdentifier(call.callee) ||\n ast.valueText(call.callee) !== \"groupedTranslations\" ||\n call.arguments.length !== 2 ||\n !call.arguments[0] ||\n !ast.isStringLiteral(call.arguments[0])\n )\n return {\n ...source,\n convertible: false,\n reason: \"must call groupedTranslations with a string group and object\",\n };\n const dictionary = literalObject(call.arguments[1]);\n if (!dictionary)\n return {\n ...source,\n convertible: false,\n reason: \"translation object must contain only literal keys, objects, strings, or numbers\",\n };\n const group = call.arguments[0].value;\n const entries: LocaleDictionaryEntries = Object.create(null);\n if (!flattenLiteral(dictionary, group, entries))\n return {\n ...source,\n convertible: false,\n reason: \"translation object has no valid literal locale entries\",\n };\n return {\n ...source,\n convertible: true,\n reason: \"pure groupedTranslations literal\",\n group,\n dictionary,\n entries,\n };\n}\n\nexport function inspectLocaleSources(): LocaleInspection[] {\n return localeSources().map(inspect);\n}\n\nfunction localeCodes(): readonly string[] | undefined {\n const configured = config.key<unknown>(\"app.localeCodes\");\n return Array.isArray(configured) && configured.every((code) => typeof code === \"string\")\n ? configured\n : undefined;\n}\n\nfunction sameEntries(left: LocaleDictionaryEntries, right: LocaleDictionaryEntries): boolean {\n return JSON.stringify(left) === JSON.stringify(right);\n}\n\n/** Convert safe legacy locale sources, retaining a TS file whenever verification cannot prove equivalence. */\nexport function fixLocaleSources(): LocaleInspection[] {\n return inspectLocaleSources().map((result) => {\n if (!result.convertible || !result.group || !result.dictionary || !result.entries)\n return result;\n const jsonFile = path.join(path.dirname(result.file), \"locales.json\");\n const document: Record<string, unknown> =\n result.group === result.module\n ? result.dictionary\n : { $group: result.group, ...result.dictionary };\n const json = `${JSON.stringify(document, null, 2)}\\n`;\n writeFileSync(jsonFile, json);\n try {\n const parsed = parseLocaleDictionary({\n sourceFile: rootPath(path.relative(process.cwd(), jsonFile)),\n source: json,\n defaultNamespace: result.module,\n localeCodes: localeCodes(),\n });\n if (!sameEntries(result.entries, parsed.entries)) throw new Error(\"flattened entries differ\");\n } catch (error) {\n unlinkSync(jsonFile);\n return {\n ...result,\n convertible: false,\n reason: `verification failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n unlinkSync(result.file);\n return {\n ...result,\n reason: \"converted (comments in the TypeScript source are not retained)\",\n };\n });\n}\n\nexport const localesTsDeprecatedCheck: DoctorCheck = {\n name: \"locales-ts-deprecated\",\n run: () => {\n const sources = inspectLocaleSources();\n if (sources.length === 0) return undefined;\n const details = sources.map((source) => {\n const label = path.relative(process.cwd(), source.file).replaceAll(\"\\\\\", \"/\");\n return `${label}: ${source.convertible ? \"auto-convertible\" : \"manual\"} (${source.reason})`;\n });\n return {\n name: \"locales-ts-deprecated\",\n status: \"warn\",\n code: \"WL9101\",\n detail:\n `${details.join(\"; \")}. Auto-loaded locales.ts goes away in v6; ` +\n \"run `warlock doctor --fix` to convert auto-convertible files.\",\n };\n },\n};\n"],"mappings":"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"}
@@ -40,7 +40,8 @@ async function doctorCommandAction(data) {
40
40
  const file = result.file.replace(process.cwd(), ".").replaceAll("\\", "/");
41
41
  log(`${result.convertible ? "converted" : "manual"} ${file}: ${result.reason}`);
42
42
  }
43
- const report = await runChecks(defaultDoctorChecks, json ? await withConsoleOnStderr(bootForDiagnostics) : await bootForDiagnostics());
43
+ const context = json ? await withConsoleOnStderr(bootForDiagnostics) : await bootForDiagnostics();
44
+ const report = await runChecks(defaultDoctorChecks, context);
44
45
  if (json) console.log(JSON.stringify(toDoctorJson(report), null, 2));
45
46
  else printReport(report);
46
47
  if (report.hasFailures) await flushAndExit(report.exitCode);
@@ -1 +1 @@
1
- {"version":3,"file":"doctor-command.action.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/cli/commands/doctor/doctor-command.action.ts"],"sourcesContent":["import type { CommandActionData } from \"../../../commands/types\";\nimport { bootForDiagnostics } from \"./boot-for-diagnostics\";\nimport { defaultDoctorChecks } from \"./checks\";\nimport { fixLocaleSources } from \"./checks/locales-ts-deprecated.check\";\nimport { flushAndExit } from \"../../flush-and-exit\";\nimport { withConsoleOnStderr } from \"../routes/with-console-on-stderr\";\nimport { printReport, toDoctorJson } from \"./format-report\";\nimport { runChecks } from \"./run-checks\";\n\n/**\n * Action behind `warlock doctor`.\n *\n * Two steps, in this order and for a reason: ONE boot pass, then every check\n * against what that pass observed. The checks never boot anything themselves,\n * so the report cannot contain two lines that inspected the app at different\n * moments and contradicted each other — which is exactly what it used to\n * contain (`routes: 0 registered` beside `health: /health + /ready\n * registered`, in the same run, on an app serving fourteen routes).\n *\n * The pass boots every connector and starts none, so no database, cache or\n * socket connection is opened and no port is bound. See\n * `boot-for-diagnostics.ts`.\n *\n * A failing check is REPORTED (a line in the report + a non-zero exit), never\n * thrown: the runner converts any thrown check into a `fail` result first.\n *\n * On success this simply returns; the CLI manager then prints its own success\n * banner and exits zero — which also disposes of the handles the boot pass\n * left open (a Fastify instance, a Vite dev server for `web` apps).\n *\n * With `--json` the report is printed as JSON (see `toDoctorJson`): every\n * finding carries its stable `WL` code, `hint`, `skill` and `docs`.\n *\n * @param data Parsed CLI args: the optional safe migration flag and `--json`.\n */\nexport async function doctorCommandAction(data: CommandActionData): Promise<void> {\n const json = data.options.json === true;\n\n // With `--json`, stdout carries the report alone: the fix log and the boot's\n // progress lines go to stderr.\n const log = json ? console.error : console.log;\n\n if (data.options.fix === true) {\n for (const result of fixLocaleSources()) {\n const file = result.file.replace(process.cwd(), \".\").replaceAll(\"\\\\\", \"/\");\n log(`${result.convertible ? \"converted\" : \"manual\"} ${file}: ${result.reason}`);\n }\n }\n\n const context = json ? await withConsoleOnStderr(bootForDiagnostics) : await bootForDiagnostics();\n\n const report = await runChecks(defaultDoctorChecks, context);\n\n if (json) {\n console.log(JSON.stringify(toDoctorJson(report), null, 2));\n } else {\n printReport(report);\n }\n\n if (report.hasFailures) {\n await flushAndExit(report.exitCode);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,eAAsB,oBAAoB,MAAwC;CAChF,MAAM,OAAO,KAAK,QAAQ,SAAS;CAInC,MAAM,MAAM,OAAO,QAAQ,QAAQ,QAAQ;CAE3C,IAAI,KAAK,QAAQ,QAAQ,MACvB,KAAK,MAAM,UAAU,iBAAiB,GAAG;EACvC,MAAM,OAAO,OAAO,KAAK,QAAQ,QAAQ,IAAI,GAAG,GAAG,CAAC,CAAC,WAAW,MAAM,GAAG;EACzE,IAAI,GAAG,OAAO,cAAc,cAAc,SAAS,GAAG,KAAK,IAAI,OAAO,QAAQ;CAChF;CAKF,MAAM,SAAS,MAAM,UAAU,qBAFf,OAAO,MAAM,oBAAoB,kBAAkB,IAAI,MAAM,mBAAmB,CAErC;CAE3D,IAAI,MACF,QAAQ,IAAI,KAAK,UAAU,aAAa,MAAM,GAAG,MAAM,CAAC,CAAC;MAEzD,YAAY,MAAM;CAGpB,IAAI,OAAO,aACT,MAAM,aAAa,OAAO,QAAQ;AAEtC"}
1
+ {"version":3,"file":"doctor-command.action.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/cli/commands/doctor/doctor-command.action.ts"],"sourcesContent":["import type { CommandActionData } from \"../../../commands/types\";\nimport { bootForDiagnostics } from \"./boot-for-diagnostics\";\nimport { defaultDoctorChecks } from \"./checks\";\nimport { fixLocaleSources } from \"./checks/locales-ts-deprecated.check\";\nimport { flushAndExit } from \"../../flush-and-exit\";\nimport { withConsoleOnStderr } from \"../routes/with-console-on-stderr\";\nimport { printReport, toDoctorJson } from \"./format-report\";\nimport { runChecks } from \"./run-checks\";\n\n/**\n * Action behind `warlock doctor`.\n *\n * Two steps, in this order and for a reason: ONE boot pass, then every check\n * against what that pass observed. The checks never boot anything themselves,\n * so the report cannot contain two lines that inspected the app at different\n * moments and contradicted each other — which is exactly what it used to\n * contain (`routes: 0 registered` beside `health: /health + /ready\n * registered`, in the same run, on an app serving fourteen routes).\n *\n * The pass boots every connector and starts none, so no database, cache or\n * socket connection is opened and no port is bound. See\n * `boot-for-diagnostics.ts`.\n *\n * A failing check is REPORTED (a line in the report + a non-zero exit), never\n * thrown: the runner converts any thrown check into a `fail` result first.\n *\n * On success this simply returns; the CLI manager then prints its own success\n * banner and exits zero — which also disposes of the handles the boot pass\n * left open (a Fastify instance, a Vite dev server for `web` apps).\n *\n * With `--json` the report is printed as JSON (see `toDoctorJson`): every\n * finding carries its stable `WL` code, `hint`, `skill` and `docs`.\n *\n * @param data Parsed CLI args: the optional safe migration flag and `--json`.\n */\nexport async function doctorCommandAction(data: CommandActionData): Promise<void> {\n const json = data.options.json === true;\n\n // With `--json`, stdout carries the report alone: the fix log and the boot's\n // progress lines go to stderr.\n const log = json ? console.error : console.log;\n\n if (data.options.fix === true) {\n for (const result of fixLocaleSources()) {\n const file = result.file.replace(process.cwd(), \".\").replaceAll(\"\\\\\", \"/\");\n log(`${result.convertible ? \"converted\" : \"manual\"} ${file}: ${result.reason}`);\n }\n }\n\n const context = json ? await withConsoleOnStderr(bootForDiagnostics) : await bootForDiagnostics();\n\n const report = await runChecks(defaultDoctorChecks, context);\n\n if (json) {\n console.log(JSON.stringify(toDoctorJson(report), null, 2));\n } else {\n printReport(report);\n }\n\n if (report.hasFailures) {\n await flushAndExit(report.exitCode);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,eAAsB,oBAAoB,MAAwC;CAChF,MAAM,OAAO,KAAK,QAAQ,SAAS;CAInC,MAAM,MAAM,OAAO,QAAQ,QAAQ,QAAQ;CAE3C,IAAI,KAAK,QAAQ,QAAQ,MACvB,KAAK,MAAM,UAAU,iBAAiB,GAAG;EACvC,MAAM,OAAO,OAAO,KAAK,QAAQ,QAAQ,IAAI,GAAG,GAAG,CAAC,CAAC,WAAW,MAAM,GAAG;EACzE,IAAI,GAAG,OAAO,cAAc,cAAc,SAAS,GAAG,KAAK,IAAI,OAAO,QAAQ;CAChF;CAGF,MAAM,UAAU,OAAO,MAAM,oBAAoB,kBAAkB,IAAI,MAAM,mBAAmB;CAEhG,MAAM,SAAS,MAAM,UAAU,qBAAqB,OAAO;CAE3D,IAAI,MACF,QAAQ,IAAI,KAAK,UAAU,aAAa,MAAM,GAAG,MAAM,CAAC,CAAC;MAEzD,YAAY,MAAM;CAGpB,IAAI,OAAO,aACT,MAAM,aAAa,OAAO,QAAQ;AAEtC"}
@@ -60,5 +60,5 @@ async function explainCommandAction({ args, options }) {
60
60
  }
61
61
 
62
62
  //#endregion
63
- export { explainCommandAction };
63
+ export { explainCommandAction, formatCodeList, formatExplanation };
64
64
  //# sourceMappingURL=explain-command.action.mjs.map
@@ -35,10 +35,13 @@ async function generateController(data) {
35
35
  process.exit(1);
36
36
  }
37
37
  await ensureComponentDirectory(module, "controllers");
38
- await putFileAsync(controllerPath, controllerStub(name, { withValidation: !!withValidation }));
38
+ const controllerContent = controllerStub(name, { withValidation: !!withValidation });
39
+ await putFileAsync(controllerPath, controllerContent);
39
40
  if (withValidation) {
40
41
  await ensureComponentDirectory(module, "schema");
41
- await putFileAsync(resolveComponentPath(module, "schema", `${name.kebab}.schema`), schemaStub(name));
42
+ const schemaPath = resolveComponentPath(module, "schema", `${name.kebab}.schema`);
43
+ const schemaContent = schemaStub(name);
44
+ await putFileAsync(schemaPath, schemaContent);
42
45
  }
43
46
  console.log(colors.cyan(`\nController "${name.camel}" generated successfully!`));
44
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"controller.generator.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/controller.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport { controllerStub, schemaStub } from \"../templates/stubs\";\nimport { parseModulePath, parseName } from \"../utils/name-parser\";\nimport {\n componentExists,\n ensureComponentDirectory,\n moduleExists,\n resolveComponentPath,\n} from \"../utils/path-resolver\";\nimport { putFileAsync, setDryRun } from \"../utils/writer\";\n\nexport async function generateController(data: CommandActionData): Promise<void> {\n const input = data.args[0];\n\n if (!input) {\n console.log(colors.red(\"Error: Controller name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.controller <module>/<name>\"));\n console.log(colors.yellow(\"Example: warlock generate.controller 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.controller <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 withValidation = data.options.withValidation || data.options.v;\n const force = data.options.force || data.options.f;\n setDryRun(Boolean(data.options.dryRun));\n\n // Check if controller already exists\n const controllerPath = resolveComponentPath(module, \"controllers\", `${name.kebab}.controller`);\n if ((await componentExists(module, \"controllers\", `${name.kebab}.controller`)) && !force) {\n console.log(colors.red(`Error: Controller \"${name.kebab}.controller.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, \"controllers\");\n\n // Generate controller\n const controllerContent = controllerStub(name, { withValidation: !!withValidation });\n await putFileAsync(controllerPath, controllerContent);\n\n // Generate the validation schema alongside the controller if requested.\n // The controller imports the schema's exported type + value directly —\n // there is no separate `requests/` alias file.\n if (withValidation) {\n await ensureComponentDirectory(module, \"schema\");\n\n const schemaPath = resolveComponentPath(module, \"schema\", `${name.kebab}.schema`);\n const schemaContent = schemaStub(name);\n\n await putFileAsync(schemaPath, schemaContent);\n }\n\n console.log(colors.cyan(`\\nController \"${name.camel}\" generated successfully!`));\n}\n"],"mappings":";;;;;;;AAYA,eAAsB,mBAAmB,MAAwC;CAC/E,MAAM,QAAQ,KAAK,KAAK;CAExB,IAAI,CAAC,OAAO;EACV,QAAQ,IAAI,OAAO,IAAI,oCAAoC,CAAC;EAC5D,QAAQ,IAAI,OAAO,OAAO,oDAAoD,CAAC;EAC/E,QAAQ,IAAI,OAAO,OAAO,wDAAwD,CAAC;EACnF,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,oDAAoD,CAAC;EAC/E,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,iBAAiB,KAAK,QAAQ,kBAAkB,KAAK,QAAQ;CACnE,MAAM,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ;CACjD,UAAU,QAAQ,KAAK,QAAQ,MAAM,CAAC;CAGtC,MAAM,iBAAiB,qBAAqB,QAAQ,eAAe,GAAG,KAAK,MAAM,YAAY;CAC7F,IAAK,MAAM,gBAAgB,QAAQ,eAAe,GAAG,KAAK,MAAM,YAAY,KAAM,CAAC,OAAO;EACxF,QAAQ,IAAI,OAAO,IAAI,sBAAsB,KAAK,MAAM,+BAA+B,CAAC;EACxF,QAAQ,IAAI,OAAO,OAAO,0BAA0B,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,yBAAyB,QAAQ,aAAa;CAIpD,MAAM,aAAa,gBADO,eAAe,MAAM,EAAE,gBAAgB,CAAC,CAAC,eAAe,CAC/B,CAAC;CAKpD,IAAI,gBAAgB;EAClB,MAAM,yBAAyB,QAAQ,QAAQ;EAK/C,MAAM,aAHa,qBAAqB,QAAQ,UAAU,GAAG,KAAK,MAAM,QAG5C,GAFN,WAAW,IAEU,CAAC;CAC9C;CAEA,QAAQ,IAAI,OAAO,KAAK,iBAAiB,KAAK,MAAM,0BAA0B,CAAC;AACjF"}
1
+ {"version":3,"file":"controller.generator.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/controller.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport { controllerStub, schemaStub } from \"../templates/stubs\";\nimport { parseModulePath, parseName } from \"../utils/name-parser\";\nimport {\n componentExists,\n ensureComponentDirectory,\n moduleExists,\n resolveComponentPath,\n} from \"../utils/path-resolver\";\nimport { putFileAsync, setDryRun } from \"../utils/writer\";\n\nexport async function generateController(data: CommandActionData): Promise<void> {\n const input = data.args[0];\n\n if (!input) {\n console.log(colors.red(\"Error: Controller name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.controller <module>/<name>\"));\n console.log(colors.yellow(\"Example: warlock generate.controller 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.controller <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 withValidation = data.options.withValidation || data.options.v;\n const force = data.options.force || data.options.f;\n setDryRun(Boolean(data.options.dryRun));\n\n // Check if controller already exists\n const controllerPath = resolveComponentPath(module, \"controllers\", `${name.kebab}.controller`);\n if ((await componentExists(module, \"controllers\", `${name.kebab}.controller`)) && !force) {\n console.log(colors.red(`Error: Controller \"${name.kebab}.controller.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, \"controllers\");\n\n // Generate controller\n const controllerContent = controllerStub(name, { withValidation: !!withValidation });\n await putFileAsync(controllerPath, controllerContent);\n\n // Generate the validation schema alongside the controller if requested.\n // The controller imports the schema's exported type + value directly —\n // there is no separate `requests/` alias file.\n if (withValidation) {\n await ensureComponentDirectory(module, \"schema\");\n\n const schemaPath = resolveComponentPath(module, \"schema\", `${name.kebab}.schema`);\n const schemaContent = schemaStub(name);\n\n await putFileAsync(schemaPath, schemaContent);\n }\n\n console.log(colors.cyan(`\\nController \"${name.camel}\" generated successfully!`));\n}\n"],"mappings":";;;;;;;AAYA,eAAsB,mBAAmB,MAAwC;CAC/E,MAAM,QAAQ,KAAK,KAAK;CAExB,IAAI,CAAC,OAAO;EACV,QAAQ,IAAI,OAAO,IAAI,oCAAoC,CAAC;EAC5D,QAAQ,IAAI,OAAO,OAAO,oDAAoD,CAAC;EAC/E,QAAQ,IAAI,OAAO,OAAO,wDAAwD,CAAC;EACnF,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,oDAAoD,CAAC;EAC/E,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,iBAAiB,KAAK,QAAQ,kBAAkB,KAAK,QAAQ;CACnE,MAAM,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ;CACjD,UAAU,QAAQ,KAAK,QAAQ,MAAM,CAAC;CAGtC,MAAM,iBAAiB,qBAAqB,QAAQ,eAAe,GAAG,KAAK,MAAM,YAAY;CAC7F,IAAK,MAAM,gBAAgB,QAAQ,eAAe,GAAG,KAAK,MAAM,YAAY,KAAM,CAAC,OAAO;EACxF,QAAQ,IAAI,OAAO,IAAI,sBAAsB,KAAK,MAAM,+BAA+B,CAAC;EACxF,QAAQ,IAAI,OAAO,OAAO,0BAA0B,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,yBAAyB,QAAQ,aAAa;CAGpD,MAAM,oBAAoB,eAAe,MAAM,EAAE,gBAAgB,CAAC,CAAC,eAAe,CAAC;CACnF,MAAM,aAAa,gBAAgB,iBAAiB;CAKpD,IAAI,gBAAgB;EAClB,MAAM,yBAAyB,QAAQ,QAAQ;EAE/C,MAAM,aAAa,qBAAqB,QAAQ,UAAU,GAAG,KAAK,MAAM,QAAQ;EAChF,MAAM,gBAAgB,WAAW,IAAI;EAErC,MAAM,aAAa,YAAY,aAAa;CAC9C;CAEA,QAAQ,IAAI,OAAO,KAAK,iBAAiB,KAAK,MAAM,0BAA0B,CAAC;AACjF"}
@@ -80,7 +80,8 @@ function schemaModuleFromFile(options) {
80
80
  return `${header}\n${exportName === "default" ? `import source from "${specifier}";` : `import { ${exportName} } from "${specifier}";`}\n\nexport const ${valueName} = ${local};\n\n${footer}`;
81
81
  }
82
82
  let content = source.replace(/(from\s+|import\s*\(\s*|import\s+)(["'])(\.{1,2}\/[^"']+)\2/g, (_match, prefix, quote, specifier) => {
83
- return `${prefix}${quote}${toImportSpecifier(targetDirectory, path.resolve(path.dirname(sourcePath), specifier))}${quote}`;
83
+ const resolved = path.resolve(path.dirname(sourcePath), specifier);
84
+ return `${prefix}${quote}${toImportSpecifier(targetDirectory, resolved)}${quote}`;
84
85
  });
85
86
  if (exportName === "default") content = content.replace(/export\s+default\s+/, `export const ${valueName} = `);
86
87
  else if (exportName !== valueName) content = `${content.trimEnd()}\n\nexport const ${valueName} = ${exportName};\n`;
@@ -174,7 +175,8 @@ async function registerRoute(spec, routesPath) {
174
175
  }
175
176
  }
176
177
  lines.splice(lastImport + 1, 0, ...imports);
177
- await putFileAsync(routesPath, `${lines.join("\n").trimEnd()}\n\n${endpointRouteRegistration(spec)}`);
178
+ const updated = `${lines.join("\n").trimEnd()}\n\n${endpointRouteRegistration(spec)}`;
179
+ await putFileAsync(routesPath, updated);
178
180
  logEdit(routesPath, "updated");
179
181
  }
180
182
  /** Merge the endpoint's message into `utils/locales.json`; existing keys win. */
@@ -307,5 +309,5 @@ function createEndpointGenerator(loadSchemaModule = loadSchemaModuleWithAppLoade
307
309
  const generateEndpoint = createEndpointGenerator();
308
310
 
309
311
  //#endregion
310
- export { generateEndpoint };
312
+ export { createEndpointGenerator, generateEndpoint, pickSchemaExport, readEndpointInput, schemaModuleFromFile };
311
313
  //# sourceMappingURL=endpoint.generator.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint.generator.mjs","names":["putFileAsync","putEditedFileAsync"],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/endpoint.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport {\n fileExistsAsync,\n getFileAsync,\n putFileAsync as putEditedFileAsync,\n} from \"../../../../generations/generation-fs\";\nimport { recordSkippedFile, setGenerationDetail } from \"../../../../generations/generation-run\";\nimport { importAppModule } from \"../../../../loader/app-module-importer\";\nimport { appPath, srcPath } from \"../../../../utils\";\nimport {\n type EndpointAccess,\n type EndpointMethod,\n type EndpointSpec,\n endpointControllerStub,\n endpointLabel,\n endpointLocaleEntries,\n endpointResourceStub,\n endpointRouteImports,\n endpointRouteRegistration,\n endpointRoutesFileStub,\n endpointSchemaStub,\n endpointServiceStub,\n endpointTestStub,\n} from \"../templates/endpoint-stubs\";\nimport { readEndpointFields } from \"../utils/endpoint-schema\";\nimport { parseModulePath, parseName, singularName } from \"../utils/name-parser\";\nimport { isDryRun, putFileAsync, setDryRun } from \"../utils/writer\";\n\nconst METHODS: readonly EndpointMethod[] = [\"get\", \"post\", \"put\", \"patch\", \"delete\"];\n\nconst USAGE =\n \"Usage: warlock make endpoint <module>/<name> [--method post] [--path /posts] [--schema ./schema.ts] [--resource Post] [--auth | --public]\";\n\n/** Loads the `--schema` file and returns its exports. Replaceable in tests. */\nexport type SchemaModuleLoader = (absolutePath: string) => Promise<Record<string, unknown>>;\n\n/**\n * Import an app TypeScript file from the CLI: register the framework's\n * loader (path aliases, TypeScript) first, as `warlock dev` does.\n */\nconst loadSchemaModuleWithAppLoader: SchemaModuleLoader = async (absolutePath) => {\n const { filesOrchestrator } = await import(\"../../../../dev-server/files-orchestrator\");\n const { warlockConfigManager } =\n await import(\"../../../../warlock-config/warlock-config.manager\");\n\n await warlockConfigManager.load();\n await filesOrchestrator.init();\n\n return (await importAppModule(pathToFileURL(absolutePath).href)) as Record<string, unknown>;\n};\n\n/** A seal object validator, recognised structurally so a second seal copy still counts. */\ntype SchemaLike = { toJsonSchema(target?: string): unknown; schema: unknown };\n\nfunction isSchemaLike(value: unknown): value is SchemaLike {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"toJsonSchema\" in value &&\n typeof value.toJsonSchema === \"function\" &&\n \"schema\" in value &&\n typeof value.schema === \"object\"\n );\n}\n\nclass EndpointInputError extends Error {}\n\nfunction fail(message: string): never {\n throw new EndpointInputError(message);\n}\n\n/** Pick the request schema out of the `--schema` module's exports. */\nexport function pickSchemaExport(\n exports: Record<string, unknown>,\n preferredName: string,\n): { exportName: string; schema: SchemaLike } {\n const preferred = exports[preferredName];\n\n if (isSchemaLike(preferred)) return { exportName: preferredName, schema: preferred };\n\n const candidates = Object.entries(exports).filter(\n (entry): entry is [string, SchemaLike] => entry[0] !== \"default\" && isSchemaLike(entry[1]),\n );\n\n if (candidates.length === 1 && candidates[0]) {\n return { exportName: candidates[0][0], schema: candidates[0][1] };\n }\n\n const fallback = exports.default;\n\n if (candidates.length === 0 && isSchemaLike(fallback)) {\n return { exportName: \"default\", schema: fallback };\n }\n\n const names = candidates.map(([name]) => name);\n\n return fail(\n names.length === 0\n ? `The schema file exports no seal object schema (v.object(...)). Export one, e.g. \\`export const ${preferredName} = v.object({ ... })\\`.`\n : `The schema file exports several object schemas (${names.join(\", \")}). Name the one for this endpoint \\`${preferredName}\\`.`,\n );\n}\n\n/**\n * The `schema/<name>.schema.ts` content for a `--schema` file.\n *\n * A file already under `src/` is imported where it lives (one source of\n * truth). A file outside `src/` — a scratch spec — is copied in, with its\n * relative imports re-pointed at the new location. Either way the module\n * exports `<name>Schema` and its `<Name>Schema` type, the names the\n * controller and service import.\n */\nexport function schemaModuleFromFile(options: {\n sourcePath: string;\n source: string;\n exportName: string;\n targetPath: string;\n valueName: string;\n typeName: string;\n}): string {\n const { sourcePath, source, exportName, targetPath, valueName, typeName } = options;\n const targetDirectory = path.dirname(targetPath);\n\n if (isInside(srcPath(), sourcePath)) {\n const specifier = toImportSpecifier(targetDirectory, sourcePath);\n const header = `import type { Infer } from \"@warlock.js/seal\";`;\n const footer = `export type ${typeName} = Infer<typeof ${valueName}>;\\n`;\n\n if (exportName === valueName) {\n return `${header}\\nimport { ${valueName} } from \"${specifier}\";\\n\\nexport { ${valueName} };\\n\\n${footer}`;\n }\n\n const local = exportName === \"default\" ? \"source\" : exportName;\n const importLine =\n exportName === \"default\"\n ? `import source from \"${specifier}\";`\n : `import { ${exportName} } from \"${specifier}\";`;\n\n return `${header}\\n${importLine}\\n\\nexport const ${valueName} = ${local};\\n\\n${footer}`;\n }\n\n let content = source.replace(\n /(from\\s+|import\\s*\\(\\s*|import\\s+)([\"'])(\\.{1,2}\\/[^\"']+)\\2/g,\n (_match, prefix: string, quote: string, specifier: string) => {\n const resolved = path.resolve(path.dirname(sourcePath), specifier);\n\n return `${prefix}${quote}${toImportSpecifier(targetDirectory, resolved)}${quote}`;\n },\n );\n\n if (exportName === \"default\") {\n content = content.replace(/export\\s+default\\s+/, `export const ${valueName} = `);\n } else if (exportName !== valueName) {\n content = `${content.trimEnd()}\\n\\nexport const ${valueName} = ${exportName};\\n`;\n }\n\n const hasType = new RegExp(`export\\\\s+type\\\\s+${typeName}\\\\b`).test(content);\n\n if (!hasType) {\n const importsInfer = /\\bInfer\\b/.test(\n content\n .split(\"\\n\")\n .filter((line) => line.startsWith(\"import\"))\n .join(\"\\n\"),\n );\n\n if (!importsInfer) content = `import type { Infer } from \"@warlock.js/seal\";\\n${content}`;\n\n content = `${content.trimEnd()}\\n\\nexport type ${typeName} = Infer<typeof ${valueName}>;\\n`;\n }\n\n return content;\n}\n\nfunction isInside(directory: string, file: string): boolean {\n const relative = path.relative(directory, file);\n\n return relative !== \"\" && !relative.startsWith(\"..\") && !path.isAbsolute(relative);\n}\n\n/** A relative, extensionless, `/`-separated import specifier from `fromDirectory` to `file`. */\nfunction toImportSpecifier(fromDirectory: string, file: string): string {\n const withoutExtension = file.replace(/\\.(?:ts|tsx|mts|js|mjs)$/, \"\");\n const relative = path.relative(fromDirectory, withoutExtension).split(path.sep).join(\"/\");\n\n return relative.startsWith(\".\") ? relative : `./${relative}`;\n}\n\n/** Parse and check the command input. Throws {@link EndpointInputError} with a fix. */\nexport function readEndpointInput(data: CommandActionData): {\n module: string;\n name: string;\n method: EndpointMethod;\n path: string;\n access: EndpointAccess;\n resource: string;\n schemaFile?: string;\n force: boolean;\n} {\n const input = data.args[0];\n\n if (!input) fail(`Endpoint name is required.\\n${USAGE}`);\n\n const { module, name } = parseModulePath(input);\n\n if (!module || !name)\n fail(`Write the endpoint as <module>/<name>, e.g. posts/create-post.\\n${USAGE}`);\n\n const moduleName = parseName(module).kebab;\n const rawMethod = String(data.options.method ?? \"post\").toLowerCase();\n const method = METHODS.find((candidate) => candidate === rawMethod);\n\n if (!method) fail(`Unknown --method \"${rawMethod}\". Use one of: ${METHODS.join(\", \")}.`);\n\n const wantsAuth = data.options.auth === true;\n const wantsPublic = data.options.public === true;\n\n if (wantsAuth && wantsPublic) fail(\"Pass either --auth or --public, not both.\");\n\n const rawPath = typeof data.options.path === \"string\" ? data.options.path : undefined;\n const defaultPath =\n method === \"get\" || method === \"post\" ? `/${moduleName}` : `/${moduleName}/:id`;\n const routePath = rawPath ? (rawPath.startsWith(\"/\") ? rawPath : `/${rawPath}`) : defaultPath;\n const resource =\n typeof data.options.resource === \"string\" && data.options.resource.trim() !== \"\"\n ? data.options.resource.trim()\n : singularName(moduleName).pascal;\n const schemaFile =\n typeof data.options.schema === \"string\" && data.options.schema.trim() !== \"\"\n ? data.options.schema.trim()\n : undefined;\n\n return {\n module: moduleName,\n name,\n method,\n path: routePath,\n // Guarded unless the caller says, in so many words, that it is public.\n access: wantsPublic ? \"public\" : \"guarded\",\n resource,\n schemaFile,\n force: data.options.force === true || data.options.f === true,\n };\n}\n\n/**\n * Write a whole generated file unless it exists. Without `--force` an\n * existing file is the app's own code: it is skipped and reported, never\n * overwritten.\n */\nasync function writeNewFile(target: string, content: string, force: boolean): Promise<void> {\n if (!force && (await fileExistsAsync(target))) {\n recordSkippedFile(target, \"exists (pass --force to overwrite)\");\n console.log(`${colors.yellow(\"-\")} skipped ${colors.gray(displayPath(target))} (exists)`);\n return;\n }\n\n await putFileAsync(target, content);\n}\n\nfunction displayPath(target: string): string {\n return path.relative(process.cwd(), target).split(path.sep).join(\"/\");\n}\n\n/** Append the endpoint to the module's `routes.ts`, creating the file if needed. */\nasync function registerRoute(spec: EndpointSpec, routesPath: string): Promise<void> {\n if (!existsSync(routesPath)) {\n await putEditedFileAsync(routesPath, endpointRoutesFileStub(spec));\n logEdit(routesPath, \"created\");\n return;\n }\n\n const current = await getFileAsync(routesPath);\n const controller = `${spec.name.camel}Controller`;\n\n if (new RegExp(`\\\\b${controller}\\\\b`).test(current)) {\n recordSkippedFile(routesPath, `${controller} is already registered`);\n console.log(\n `${colors.yellow(\"-\")} skipped ${colors.gray(displayPath(routesPath))} (${controller} is already registered)`,\n );\n return;\n }\n\n const imports = [...endpointRouteImports(spec)];\n\n if (!/import\\s*\\{[^}]*\\brouter\\b[^}]*\\}\\s*from\\s*[\"']@warlock\\.js\\/core[\"']/.test(current)) {\n imports.unshift(`import { router } from \"@warlock.js/core\";`);\n }\n\n if (spec.access === \"guarded\" && !/\\bguarded\\b/.test(current)) {\n imports.unshift(`import { guarded } from \"app/shared/utils/router\";`);\n }\n\n const lines = current.split(\"\\n\");\n let lastImport = -1;\n let inImport = false;\n\n // An import may span lines; new imports go after the last statement ends.\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index] ?? \"\";\n\n if (/^import\\s/.test(line)) inImport = true;\n\n if (inImport && (/;\\s*$/.test(line) || /from\\s+[\"'][^\"']+[\"']\\s*$/.test(line))) {\n lastImport = index;\n inImport = false;\n }\n }\n\n lines.splice(lastImport + 1, 0, ...imports);\n\n const updated = `${lines.join(\"\\n\").trimEnd()}\\n\\n${endpointRouteRegistration(spec)}`;\n\n await putEditedFileAsync(routesPath, updated);\n logEdit(routesPath, \"updated\");\n}\n\n/** Merge the endpoint's message into `utils/locales.json`; existing keys win. */\nasync function registerLocales(spec: EndpointSpec, localesPath: string): Promise<void> {\n const entries = endpointLocaleEntries(spec);\n\n if (!existsSync(localesPath)) {\n await putEditedFileAsync(localesPath, `${JSON.stringify(entries, null, 2)}\\n`);\n logEdit(localesPath, \"created\");\n return;\n }\n\n let dictionary: Record<string, unknown>;\n\n try {\n const parsed: unknown = JSON.parse(await getFileAsync(localesPath));\n\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) throw new Error();\n\n dictionary = parsed as Record<string, unknown>;\n } catch {\n recordSkippedFile(localesPath, \"not a JSON object; add the message key by hand\");\n console.log(\n colors.yellow(\n `! ${displayPath(localesPath)} is not a JSON object; add ${Object.keys(entries).join(\", \")} by hand.`,\n ),\n );\n return;\n }\n\n if (dictionary.$group !== undefined && dictionary.$group !== spec.module) {\n recordSkippedFile(localesPath, `declares $group \"${String(dictionary.$group)}\"`);\n console.log(\n colors.yellow(\n `! ${displayPath(localesPath)} declares another $group; add ${spec.module}.${Object.keys(entries).join(\", \")} by hand.`,\n ),\n );\n return;\n }\n\n const missing = Object.keys(entries).filter((key) => dictionary[key] === undefined);\n\n if (missing.length === 0) {\n recordSkippedFile(localesPath, \"message key already present\");\n return;\n }\n\n for (const key of missing) dictionary[key] = entries[key];\n\n await putEditedFileAsync(localesPath, `${JSON.stringify(dictionary, null, 2)}\\n`);\n logEdit(localesPath, \"updated\");\n}\n\nfunction logEdit(target: string, verb: \"created\" | \"updated\"): void {\n const prefix = isDryRun()\n ? `${colors.cyan(\"○\")} would ${verb === \"created\" ? \"create\" : \"update\"}`\n : `${colors.green(\"✓\")} ${verb}`;\n\n console.log(`${prefix} ${colors.gray(displayPath(target))}`);\n}\n\n/**\n * `warlock make endpoint <module>/<name>` — a spec-first endpoint.\n *\n * Writes, under `src/app/<module>/`: the request schema (from `--schema` or a\n * stub), a service, the resource (unless it exists), one controller with its\n * validation and OpenAPI `responseSchema`, the route (guarded, or\n * `public: true` with `--public`), the success message in `utils/locales.json`,\n * and `tests/<name>.test.ts`, which requests the endpoint over the real HTTP\n * stack. Existing files are skipped and reported unless `--force`.\n */\nexport function createEndpointGenerator(\n loadSchemaModule: SchemaModuleLoader = loadSchemaModuleWithAppLoader,\n): (data: CommandActionData) => Promise<void> {\n return async (data) => {\n let input: ReturnType<typeof readEndpointInput>;\n\n try {\n input = readEndpointInput(data);\n } catch (error) {\n if (!(error instanceof EndpointInputError)) throw error;\n\n console.log(colors.red(`Error: ${error.message}`));\n process.exit(1);\n }\n\n setDryRun(data.options.dryRun === true);\n\n const name = parseName(input.name);\n const modulePath = appPath(input.module);\n const schemaPath = path.join(modulePath, \"schema\", `${name.kebab}.schema.ts`);\n const valueName = `${name.camel}Schema`;\n const typeName = `${name.pascal}Schema`;\n\n let jsonSchema: unknown;\n let schemaContent: string | undefined;\n\n if (input.schemaFile) {\n const sourcePath = path.resolve(process.cwd(), input.schemaFile);\n\n if (!existsSync(sourcePath)) {\n console.log(colors.red(`Error: Schema file not found: ${input.schemaFile}`));\n process.exit(1);\n }\n\n let exports: Record<string, unknown>;\n\n try {\n exports = await loadSchemaModule(sourcePath);\n } catch (error) {\n console.log(\n colors.red(\n `Error: Could not load ${input.schemaFile} to read its fields: ${error instanceof Error ? error.message : String(error)}`,\n ),\n );\n process.exit(1);\n }\n\n let picked: ReturnType<typeof pickSchemaExport>;\n\n try {\n picked = pickSchemaExport(exports, valueName);\n } catch (error) {\n console.log(colors.red(`Error: ${error instanceof Error ? error.message : String(error)}`));\n process.exit(1);\n }\n\n jsonSchema = picked.schema.toJsonSchema(\"draft-2020-12\");\n\n if (path.resolve(sourcePath) !== path.resolve(schemaPath)) {\n schemaContent = schemaModuleFromFile({\n sourcePath,\n source: readFileSync(sourcePath, \"utf8\"),\n exportName: picked.exportName,\n targetPath: schemaPath,\n valueName,\n typeName,\n });\n }\n }\n\n const spec: EndpointSpec = {\n module: input.module,\n name,\n method: input.method,\n path: input.path,\n access: input.access,\n resource: parseName(input.resource),\n fields: readEndpointFields(jsonSchema),\n };\n\n const resourcePath = path.join(\n modulePath,\n \"resources\",\n `${spec.resource.singular.kebab}.resource.ts`,\n );\n const testPath = path.join(modulePath, \"tests\", `${name.kebab}.test.ts`);\n\n setGenerationDetail(\"endpoint\", {\n method: spec.method.toUpperCase(),\n path: spec.path,\n access: spec.access,\n controller: `${name.camel}Controller`,\n resource: `${spec.resource.pascal}Resource`,\n fields: spec.fields.map((field) => field.name),\n test: displayPath(testPath),\n });\n\n console.log(colors.cyan(`\\nGenerating ${endpointLabel(spec)} in src/app/${spec.module}\\n`));\n\n if (input.schemaFile === undefined) {\n await writeNewFile(schemaPath, endpointSchemaStub(spec), input.force);\n } else if (schemaContent !== undefined) {\n await writeNewFile(schemaPath, schemaContent, input.force);\n }\n\n await writeNewFile(\n path.join(modulePath, \"services\", `${name.kebab}.service.ts`),\n endpointServiceStub(spec),\n input.force,\n );\n await writeNewFile(resourcePath, endpointResourceStub(spec), input.force);\n await writeNewFile(\n path.join(modulePath, \"controllers\", `${name.kebab}.controller.ts`),\n endpointControllerStub(spec),\n input.force,\n );\n await registerRoute(spec, path.join(modulePath, \"routes.ts\"));\n await registerLocales(spec, path.join(modulePath, \"utils\", \"locales.json\"));\n await writeNewFile(testPath, endpointTestStub(spec), input.force);\n\n console.log(\n colors.cyan(\n `\\n${endpointLabel(spec)} ${isDryRun() ? \"previewed\" : \"generated\"} (${spec.access === \"public\" ? \"public: true\" : \"guarded\"}).`,\n ),\n );\n console.log(\n colors.gray(\n `Next: fill in services/${name.kebab}.service.ts, then run the test with \\`warlock test --related ${displayPath(testPath)}\\`.`,\n ),\n );\n };\n}\n\nexport const generateEndpoint = createEndpointGenerator();\n"],"mappings":"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"}
1
+ {"version":3,"file":"endpoint.generator.mjs","names":["putFileAsync","putEditedFileAsync"],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/endpoint.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport {\n fileExistsAsync,\n getFileAsync,\n putFileAsync as putEditedFileAsync,\n} from \"../../../../generations/generation-fs\";\nimport { recordSkippedFile, setGenerationDetail } from \"../../../../generations/generation-run\";\nimport { importAppModule } from \"../../../../loader/app-module-importer\";\nimport { appPath, srcPath } from \"../../../../utils\";\nimport {\n type EndpointAccess,\n type EndpointMethod,\n type EndpointSpec,\n endpointControllerStub,\n endpointLabel,\n endpointLocaleEntries,\n endpointResourceStub,\n endpointRouteImports,\n endpointRouteRegistration,\n endpointRoutesFileStub,\n endpointSchemaStub,\n endpointServiceStub,\n endpointTestStub,\n} from \"../templates/endpoint-stubs\";\nimport { readEndpointFields } from \"../utils/endpoint-schema\";\nimport { parseModulePath, parseName, singularName } from \"../utils/name-parser\";\nimport { isDryRun, putFileAsync, setDryRun } from \"../utils/writer\";\n\nconst METHODS: readonly EndpointMethod[] = [\"get\", \"post\", \"put\", \"patch\", \"delete\"];\n\nconst USAGE =\n \"Usage: warlock make endpoint <module>/<name> [--method post] [--path /posts] [--schema ./schema.ts] [--resource Post] [--auth | --public]\";\n\n/** Loads the `--schema` file and returns its exports. Replaceable in tests. */\nexport type SchemaModuleLoader = (absolutePath: string) => Promise<Record<string, unknown>>;\n\n/**\n * Import an app TypeScript file from the CLI: register the framework's\n * loader (path aliases, TypeScript) first, as `warlock dev` does.\n */\nconst loadSchemaModuleWithAppLoader: SchemaModuleLoader = async (absolutePath) => {\n const { filesOrchestrator } = await import(\"../../../../dev-server/files-orchestrator\");\n const { warlockConfigManager } =\n await import(\"../../../../warlock-config/warlock-config.manager\");\n\n await warlockConfigManager.load();\n await filesOrchestrator.init();\n\n return (await importAppModule(pathToFileURL(absolutePath).href)) as Record<string, unknown>;\n};\n\n/** A seal object validator, recognised structurally so a second seal copy still counts. */\ntype SchemaLike = { toJsonSchema(target?: string): unknown; schema: unknown };\n\nfunction isSchemaLike(value: unknown): value is SchemaLike {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"toJsonSchema\" in value &&\n typeof value.toJsonSchema === \"function\" &&\n \"schema\" in value &&\n typeof value.schema === \"object\"\n );\n}\n\nclass EndpointInputError extends Error {}\n\nfunction fail(message: string): never {\n throw new EndpointInputError(message);\n}\n\n/** Pick the request schema out of the `--schema` module's exports. */\nexport function pickSchemaExport(\n exports: Record<string, unknown>,\n preferredName: string,\n): { exportName: string; schema: SchemaLike } {\n const preferred = exports[preferredName];\n\n if (isSchemaLike(preferred)) return { exportName: preferredName, schema: preferred };\n\n const candidates = Object.entries(exports).filter(\n (entry): entry is [string, SchemaLike] => entry[0] !== \"default\" && isSchemaLike(entry[1]),\n );\n\n if (candidates.length === 1 && candidates[0]) {\n return { exportName: candidates[0][0], schema: candidates[0][1] };\n }\n\n const fallback = exports.default;\n\n if (candidates.length === 0 && isSchemaLike(fallback)) {\n return { exportName: \"default\", schema: fallback };\n }\n\n const names = candidates.map(([name]) => name);\n\n return fail(\n names.length === 0\n ? `The schema file exports no seal object schema (v.object(...)). Export one, e.g. \\`export const ${preferredName} = v.object({ ... })\\`.`\n : `The schema file exports several object schemas (${names.join(\", \")}). Name the one for this endpoint \\`${preferredName}\\`.`,\n );\n}\n\n/**\n * The `schema/<name>.schema.ts` content for a `--schema` file.\n *\n * A file already under `src/` is imported where it lives (one source of\n * truth). A file outside `src/` — a scratch spec — is copied in, with its\n * relative imports re-pointed at the new location. Either way the module\n * exports `<name>Schema` and its `<Name>Schema` type, the names the\n * controller and service import.\n */\nexport function schemaModuleFromFile(options: {\n sourcePath: string;\n source: string;\n exportName: string;\n targetPath: string;\n valueName: string;\n typeName: string;\n}): string {\n const { sourcePath, source, exportName, targetPath, valueName, typeName } = options;\n const targetDirectory = path.dirname(targetPath);\n\n if (isInside(srcPath(), sourcePath)) {\n const specifier = toImportSpecifier(targetDirectory, sourcePath);\n const header = `import type { Infer } from \"@warlock.js/seal\";`;\n const footer = `export type ${typeName} = Infer<typeof ${valueName}>;\\n`;\n\n if (exportName === valueName) {\n return `${header}\\nimport { ${valueName} } from \"${specifier}\";\\n\\nexport { ${valueName} };\\n\\n${footer}`;\n }\n\n const local = exportName === \"default\" ? \"source\" : exportName;\n const importLine =\n exportName === \"default\"\n ? `import source from \"${specifier}\";`\n : `import { ${exportName} } from \"${specifier}\";`;\n\n return `${header}\\n${importLine}\\n\\nexport const ${valueName} = ${local};\\n\\n${footer}`;\n }\n\n let content = source.replace(\n /(from\\s+|import\\s*\\(\\s*|import\\s+)([\"'])(\\.{1,2}\\/[^\"']+)\\2/g,\n (_match, prefix: string, quote: string, specifier: string) => {\n const resolved = path.resolve(path.dirname(sourcePath), specifier);\n\n return `${prefix}${quote}${toImportSpecifier(targetDirectory, resolved)}${quote}`;\n },\n );\n\n if (exportName === \"default\") {\n content = content.replace(/export\\s+default\\s+/, `export const ${valueName} = `);\n } else if (exportName !== valueName) {\n content = `${content.trimEnd()}\\n\\nexport const ${valueName} = ${exportName};\\n`;\n }\n\n const hasType = new RegExp(`export\\\\s+type\\\\s+${typeName}\\\\b`).test(content);\n\n if (!hasType) {\n const importsInfer = /\\bInfer\\b/.test(\n content\n .split(\"\\n\")\n .filter((line) => line.startsWith(\"import\"))\n .join(\"\\n\"),\n );\n\n if (!importsInfer) content = `import type { Infer } from \"@warlock.js/seal\";\\n${content}`;\n\n content = `${content.trimEnd()}\\n\\nexport type ${typeName} = Infer<typeof ${valueName}>;\\n`;\n }\n\n return content;\n}\n\nfunction isInside(directory: string, file: string): boolean {\n const relative = path.relative(directory, file);\n\n return relative !== \"\" && !relative.startsWith(\"..\") && !path.isAbsolute(relative);\n}\n\n/** A relative, extensionless, `/`-separated import specifier from `fromDirectory` to `file`. */\nfunction toImportSpecifier(fromDirectory: string, file: string): string {\n const withoutExtension = file.replace(/\\.(?:ts|tsx|mts|js|mjs)$/, \"\");\n const relative = path.relative(fromDirectory, withoutExtension).split(path.sep).join(\"/\");\n\n return relative.startsWith(\".\") ? relative : `./${relative}`;\n}\n\n/** Parse and check the command input. Throws {@link EndpointInputError} with a fix. */\nexport function readEndpointInput(data: CommandActionData): {\n module: string;\n name: string;\n method: EndpointMethod;\n path: string;\n access: EndpointAccess;\n resource: string;\n schemaFile?: string;\n force: boolean;\n} {\n const input = data.args[0];\n\n if (!input) fail(`Endpoint name is required.\\n${USAGE}`);\n\n const { module, name } = parseModulePath(input);\n\n if (!module || !name)\n fail(`Write the endpoint as <module>/<name>, e.g. posts/create-post.\\n${USAGE}`);\n\n const moduleName = parseName(module).kebab;\n const rawMethod = String(data.options.method ?? \"post\").toLowerCase();\n const method = METHODS.find((candidate) => candidate === rawMethod);\n\n if (!method) fail(`Unknown --method \"${rawMethod}\". Use one of: ${METHODS.join(\", \")}.`);\n\n const wantsAuth = data.options.auth === true;\n const wantsPublic = data.options.public === true;\n\n if (wantsAuth && wantsPublic) fail(\"Pass either --auth or --public, not both.\");\n\n const rawPath = typeof data.options.path === \"string\" ? data.options.path : undefined;\n const defaultPath =\n method === \"get\" || method === \"post\" ? `/${moduleName}` : `/${moduleName}/:id`;\n const routePath = rawPath ? (rawPath.startsWith(\"/\") ? rawPath : `/${rawPath}`) : defaultPath;\n const resource =\n typeof data.options.resource === \"string\" && data.options.resource.trim() !== \"\"\n ? data.options.resource.trim()\n : singularName(moduleName).pascal;\n const schemaFile =\n typeof data.options.schema === \"string\" && data.options.schema.trim() !== \"\"\n ? data.options.schema.trim()\n : undefined;\n\n return {\n module: moduleName,\n name,\n method,\n path: routePath,\n // Guarded unless the caller says, in so many words, that it is public.\n access: wantsPublic ? \"public\" : \"guarded\",\n resource,\n schemaFile,\n force: data.options.force === true || data.options.f === true,\n };\n}\n\n/**\n * Write a whole generated file unless it exists. Without `--force` an\n * existing file is the app's own code: it is skipped and reported, never\n * overwritten.\n */\nasync function writeNewFile(target: string, content: string, force: boolean): Promise<void> {\n if (!force && (await fileExistsAsync(target))) {\n recordSkippedFile(target, \"exists (pass --force to overwrite)\");\n console.log(`${colors.yellow(\"-\")} skipped ${colors.gray(displayPath(target))} (exists)`);\n return;\n }\n\n await putFileAsync(target, content);\n}\n\nfunction displayPath(target: string): string {\n return path.relative(process.cwd(), target).split(path.sep).join(\"/\");\n}\n\n/** Append the endpoint to the module's `routes.ts`, creating the file if needed. */\nasync function registerRoute(spec: EndpointSpec, routesPath: string): Promise<void> {\n if (!existsSync(routesPath)) {\n await putEditedFileAsync(routesPath, endpointRoutesFileStub(spec));\n logEdit(routesPath, \"created\");\n return;\n }\n\n const current = await getFileAsync(routesPath);\n const controller = `${spec.name.camel}Controller`;\n\n if (new RegExp(`\\\\b${controller}\\\\b`).test(current)) {\n recordSkippedFile(routesPath, `${controller} is already registered`);\n console.log(\n `${colors.yellow(\"-\")} skipped ${colors.gray(displayPath(routesPath))} (${controller} is already registered)`,\n );\n return;\n }\n\n const imports = [...endpointRouteImports(spec)];\n\n if (!/import\\s*\\{[^}]*\\brouter\\b[^}]*\\}\\s*from\\s*[\"']@warlock\\.js\\/core[\"']/.test(current)) {\n imports.unshift(`import { router } from \"@warlock.js/core\";`);\n }\n\n if (spec.access === \"guarded\" && !/\\bguarded\\b/.test(current)) {\n imports.unshift(`import { guarded } from \"app/shared/utils/router\";`);\n }\n\n const lines = current.split(\"\\n\");\n let lastImport = -1;\n let inImport = false;\n\n // An import may span lines; new imports go after the last statement ends.\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index] ?? \"\";\n\n if (/^import\\s/.test(line)) inImport = true;\n\n if (inImport && (/;\\s*$/.test(line) || /from\\s+[\"'][^\"']+[\"']\\s*$/.test(line))) {\n lastImport = index;\n inImport = false;\n }\n }\n\n lines.splice(lastImport + 1, 0, ...imports);\n\n const updated = `${lines.join(\"\\n\").trimEnd()}\\n\\n${endpointRouteRegistration(spec)}`;\n\n await putEditedFileAsync(routesPath, updated);\n logEdit(routesPath, \"updated\");\n}\n\n/** Merge the endpoint's message into `utils/locales.json`; existing keys win. */\nasync function registerLocales(spec: EndpointSpec, localesPath: string): Promise<void> {\n const entries = endpointLocaleEntries(spec);\n\n if (!existsSync(localesPath)) {\n await putEditedFileAsync(localesPath, `${JSON.stringify(entries, null, 2)}\\n`);\n logEdit(localesPath, \"created\");\n return;\n }\n\n let dictionary: Record<string, unknown>;\n\n try {\n const parsed: unknown = JSON.parse(await getFileAsync(localesPath));\n\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) throw new Error();\n\n dictionary = parsed as Record<string, unknown>;\n } catch {\n recordSkippedFile(localesPath, \"not a JSON object; add the message key by hand\");\n console.log(\n colors.yellow(\n `! ${displayPath(localesPath)} is not a JSON object; add ${Object.keys(entries).join(\", \")} by hand.`,\n ),\n );\n return;\n }\n\n if (dictionary.$group !== undefined && dictionary.$group !== spec.module) {\n recordSkippedFile(localesPath, `declares $group \"${String(dictionary.$group)}\"`);\n console.log(\n colors.yellow(\n `! ${displayPath(localesPath)} declares another $group; add ${spec.module}.${Object.keys(entries).join(\", \")} by hand.`,\n ),\n );\n return;\n }\n\n const missing = Object.keys(entries).filter((key) => dictionary[key] === undefined);\n\n if (missing.length === 0) {\n recordSkippedFile(localesPath, \"message key already present\");\n return;\n }\n\n for (const key of missing) dictionary[key] = entries[key];\n\n await putEditedFileAsync(localesPath, `${JSON.stringify(dictionary, null, 2)}\\n`);\n logEdit(localesPath, \"updated\");\n}\n\nfunction logEdit(target: string, verb: \"created\" | \"updated\"): void {\n const prefix = isDryRun()\n ? `${colors.cyan(\"○\")} would ${verb === \"created\" ? \"create\" : \"update\"}`\n : `${colors.green(\"✓\")} ${verb}`;\n\n console.log(`${prefix} ${colors.gray(displayPath(target))}`);\n}\n\n/**\n * `warlock make endpoint <module>/<name>` — a spec-first endpoint.\n *\n * Writes, under `src/app/<module>/`: the request schema (from `--schema` or a\n * stub), a service, the resource (unless it exists), one controller with its\n * validation and OpenAPI `responseSchema`, the route (guarded, or\n * `public: true` with `--public`), the success message in `utils/locales.json`,\n * and `tests/<name>.test.ts`, which requests the endpoint over the real HTTP\n * stack. Existing files are skipped and reported unless `--force`.\n */\nexport function createEndpointGenerator(\n loadSchemaModule: SchemaModuleLoader = loadSchemaModuleWithAppLoader,\n): (data: CommandActionData) => Promise<void> {\n return async (data) => {\n let input: ReturnType<typeof readEndpointInput>;\n\n try {\n input = readEndpointInput(data);\n } catch (error) {\n if (!(error instanceof EndpointInputError)) throw error;\n\n console.log(colors.red(`Error: ${error.message}`));\n process.exit(1);\n }\n\n setDryRun(data.options.dryRun === true);\n\n const name = parseName(input.name);\n const modulePath = appPath(input.module);\n const schemaPath = path.join(modulePath, \"schema\", `${name.kebab}.schema.ts`);\n const valueName = `${name.camel}Schema`;\n const typeName = `${name.pascal}Schema`;\n\n let jsonSchema: unknown;\n let schemaContent: string | undefined;\n\n if (input.schemaFile) {\n const sourcePath = path.resolve(process.cwd(), input.schemaFile);\n\n if (!existsSync(sourcePath)) {\n console.log(colors.red(`Error: Schema file not found: ${input.schemaFile}`));\n process.exit(1);\n }\n\n let exports: Record<string, unknown>;\n\n try {\n exports = await loadSchemaModule(sourcePath);\n } catch (error) {\n console.log(\n colors.red(\n `Error: Could not load ${input.schemaFile} to read its fields: ${error instanceof Error ? error.message : String(error)}`,\n ),\n );\n process.exit(1);\n }\n\n let picked: ReturnType<typeof pickSchemaExport>;\n\n try {\n picked = pickSchemaExport(exports, valueName);\n } catch (error) {\n console.log(colors.red(`Error: ${error instanceof Error ? error.message : String(error)}`));\n process.exit(1);\n }\n\n jsonSchema = picked.schema.toJsonSchema(\"draft-2020-12\");\n\n if (path.resolve(sourcePath) !== path.resolve(schemaPath)) {\n schemaContent = schemaModuleFromFile({\n sourcePath,\n source: readFileSync(sourcePath, \"utf8\"),\n exportName: picked.exportName,\n targetPath: schemaPath,\n valueName,\n typeName,\n });\n }\n }\n\n const spec: EndpointSpec = {\n module: input.module,\n name,\n method: input.method,\n path: input.path,\n access: input.access,\n resource: parseName(input.resource),\n fields: readEndpointFields(jsonSchema),\n };\n\n const resourcePath = path.join(\n modulePath,\n \"resources\",\n `${spec.resource.singular.kebab}.resource.ts`,\n );\n const testPath = path.join(modulePath, \"tests\", `${name.kebab}.test.ts`);\n\n setGenerationDetail(\"endpoint\", {\n method: spec.method.toUpperCase(),\n path: spec.path,\n access: spec.access,\n controller: `${name.camel}Controller`,\n resource: `${spec.resource.pascal}Resource`,\n fields: spec.fields.map((field) => field.name),\n test: displayPath(testPath),\n });\n\n console.log(colors.cyan(`\\nGenerating ${endpointLabel(spec)} in src/app/${spec.module}\\n`));\n\n if (input.schemaFile === undefined) {\n await writeNewFile(schemaPath, endpointSchemaStub(spec), input.force);\n } else if (schemaContent !== undefined) {\n await writeNewFile(schemaPath, schemaContent, input.force);\n }\n\n await writeNewFile(\n path.join(modulePath, \"services\", `${name.kebab}.service.ts`),\n endpointServiceStub(spec),\n input.force,\n );\n await writeNewFile(resourcePath, endpointResourceStub(spec), input.force);\n await writeNewFile(\n path.join(modulePath, \"controllers\", `${name.kebab}.controller.ts`),\n endpointControllerStub(spec),\n input.force,\n );\n await registerRoute(spec, path.join(modulePath, \"routes.ts\"));\n await registerLocales(spec, path.join(modulePath, \"utils\", \"locales.json\"));\n await writeNewFile(testPath, endpointTestStub(spec), input.force);\n\n console.log(\n colors.cyan(\n `\\n${endpointLabel(spec)} ${isDryRun() ? \"previewed\" : \"generated\"} (${spec.access === \"public\" ? \"public: true\" : \"guarded\"}).`,\n ),\n );\n console.log(\n colors.gray(\n `Next: fill in services/${name.kebab}.service.ts, then run the test with \\`warlock test --related ${displayPath(testPath)}\\`.`,\n ),\n );\n };\n}\n\nexport const generateEndpoint = createEndpointGenerator();\n"],"mappings":"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"}
@@ -42,10 +42,11 @@ async function generateModel(data) {
42
42
  }
43
43
  await ensureDirectoryAsync(modelDir);
44
44
  await ensureDirectoryAsync(path.join(modelDir, "migrations"));
45
- await putFileAsync(modelPath, modelStub(name, {
45
+ const modelContent = modelStub(name, {
46
46
  tableName,
47
47
  withResource: !!withResource
48
- }));
48
+ });
49
+ await putFileAsync(modelPath, modelContent);
49
50
  if (withResource) {
50
51
  const resourceFile = `${name.singular.kebab}.resource`;
51
52
  if (force || !await componentExists(module, "resources", resourceFile)) {
@@ -1 +1 @@
1
- {"version":3,"file":"model.generator.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/model.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport { migrationTimestamp } from \"../../../../generations/features/shared/migration-timestamp\";\nimport { migrationStub, modelStub, resourceStub } from \"../templates/stubs\";\nimport { parseModulePath, singularName } from \"../utils/name-parser\";\nimport {\n componentExists,\n ensureComponentDirectory,\n moduleExists,\n resolveComponentPath,\n resolveModulePath,\n} from \"../utils/path-resolver\";\nimport {\n ensureDirectoryAsync,\n putFileAsync,\n reportSkippedFiles,\n setDryRun,\n setSkipExisting,\n} from \"../utils/writer\";\n\nexport async function generateModel(data: CommandActionData): Promise<void> {\n const input = data.args[0];\n\n if (!input) {\n console.log(colors.red(\"Error: Model name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.model <module>/<name>\"));\n console.log(colors.yellow(\"Example: warlock generate.model 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.model <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 = singularName(componentName);\n const force = data.options.force || data.options.f;\n setDryRun(Boolean(data.options.dryRun));\n // --force only creates what is missing; replacing edited files needs --overwrite too\n setSkipExisting(!data.options.overwrite);\n const withResource = data.options.withResource || data.options.rs;\n const tableName = (data.options.table as string) || name.plural.snake;\n\n // Check if model already exists\n const modelDir = path.join(resolveModulePath(module), \"models\", name.kebab);\n const modelPath = path.join(modelDir, `${name.kebab}.model.ts`);\n\n if ((await componentExists(module, `models/${name.kebab}`, `${name.kebab}.model`)) && !force) {\n console.log(colors.red(`Error: Model \"${name.kebab}\" already exists`));\n console.log(colors.yellow(\"Use --force to overwrite\"));\n process.exit(1);\n }\n\n // Ensure directories exist\n await ensureDirectoryAsync(modelDir);\n await ensureDirectoryAsync(path.join(modelDir, \"migrations\"));\n\n // Generate model\n const modelContent = modelStub(name, { tableName, withResource: !!withResource });\n await putFileAsync(modelPath, modelContent);\n\n // The model imports ../../resources/<name>.resource, so that file must exist\n if (withResource) {\n const resourceFile = `${name.singular.kebab}.resource`;\n\n if (force || !(await componentExists(module, \"resources\", resourceFile))) {\n await ensureComponentDirectory(module, \"resources\");\n await putFileAsync(\n resolveComponentPath(module, \"resources\", resourceFile),\n resourceStub(name),\n );\n }\n }\n\n // Generate index.ts\n const indexContent = `export * from \"./${name.kebab}.model\";\n`;\n await putFileAsync(path.join(modelDir, \"index.ts\"), indexContent);\n\n // Generate migration (skip when one already exists, e.g. on --force)\n const migrationsDir = path.join(modelDir, \"migrations\");\n const hasMigration =\n existsSync(migrationsDir) &&\n readdirSync(migrationsDir).some((file) => file.endsWith(\".migration.ts\"));\n const timestamp = migrationTimestamp();\n const migrationPath = path.join(\n modelDir,\n \"migrations\",\n `${timestamp}-${name.kebab}.migration.ts`,\n );\n\n const migrationContent = migrationStub(name, {\n timestamps:\n data.options.timestamps !== \"false\" &&\n data.options.timestamps !== false &&\n !data.options.noTimestamps,\n });\n\n if (!hasMigration) {\n await putFileAsync(migrationPath, migrationContent);\n }\n\n reportSkippedFiles();\n\n console.log(colors.cyan(`\\n✨ Model \"${name.pascal}\" generated successfully!`));\n console.log(colors.gray(`\\nNext steps:`));\n console.log(colors.gray(` 1. Update model schema in ${name.kebab}.model.ts`));\n console.log(\n colors.gray(\n hasMigration\n ? ` 2. Existing migration kept; add changes with: warlock gen.migration ${module}/${name.kebab} --add ...`\n : ` 2. Update migration in migrations/${timestamp}-${name.kebab}.migration.ts`,\n ),\n );\n console.log(colors.gray(` 3. Run migration: warlock migrate`));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"model.generator.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/model.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport { migrationTimestamp } from \"../../../../generations/features/shared/migration-timestamp\";\nimport { migrationStub, modelStub, resourceStub } from \"../templates/stubs\";\nimport { parseModulePath, singularName } from \"../utils/name-parser\";\nimport {\n componentExists,\n ensureComponentDirectory,\n moduleExists,\n resolveComponentPath,\n resolveModulePath,\n} from \"../utils/path-resolver\";\nimport {\n ensureDirectoryAsync,\n putFileAsync,\n reportSkippedFiles,\n setDryRun,\n setSkipExisting,\n} from \"../utils/writer\";\n\nexport async function generateModel(data: CommandActionData): Promise<void> {\n const input = data.args[0];\n\n if (!input) {\n console.log(colors.red(\"Error: Model name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.model <module>/<name>\"));\n console.log(colors.yellow(\"Example: warlock generate.model 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.model <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 = singularName(componentName);\n const force = data.options.force || data.options.f;\n setDryRun(Boolean(data.options.dryRun));\n // --force only creates what is missing; replacing edited files needs --overwrite too\n setSkipExisting(!data.options.overwrite);\n const withResource = data.options.withResource || data.options.rs;\n const tableName = (data.options.table as string) || name.plural.snake;\n\n // Check if model already exists\n const modelDir = path.join(resolveModulePath(module), \"models\", name.kebab);\n const modelPath = path.join(modelDir, `${name.kebab}.model.ts`);\n\n if ((await componentExists(module, `models/${name.kebab}`, `${name.kebab}.model`)) && !force) {\n console.log(colors.red(`Error: Model \"${name.kebab}\" already exists`));\n console.log(colors.yellow(\"Use --force to overwrite\"));\n process.exit(1);\n }\n\n // Ensure directories exist\n await ensureDirectoryAsync(modelDir);\n await ensureDirectoryAsync(path.join(modelDir, \"migrations\"));\n\n // Generate model\n const modelContent = modelStub(name, { tableName, withResource: !!withResource });\n await putFileAsync(modelPath, modelContent);\n\n // The model imports ../../resources/<name>.resource, so that file must exist\n if (withResource) {\n const resourceFile = `${name.singular.kebab}.resource`;\n\n if (force || !(await componentExists(module, \"resources\", resourceFile))) {\n await ensureComponentDirectory(module, \"resources\");\n await putFileAsync(\n resolveComponentPath(module, \"resources\", resourceFile),\n resourceStub(name),\n );\n }\n }\n\n // Generate index.ts\n const indexContent = `export * from \"./${name.kebab}.model\";\n`;\n await putFileAsync(path.join(modelDir, \"index.ts\"), indexContent);\n\n // Generate migration (skip when one already exists, e.g. on --force)\n const migrationsDir = path.join(modelDir, \"migrations\");\n const hasMigration =\n existsSync(migrationsDir) &&\n readdirSync(migrationsDir).some((file) => file.endsWith(\".migration.ts\"));\n const timestamp = migrationTimestamp();\n const migrationPath = path.join(\n modelDir,\n \"migrations\",\n `${timestamp}-${name.kebab}.migration.ts`,\n );\n\n const migrationContent = migrationStub(name, {\n timestamps:\n data.options.timestamps !== \"false\" &&\n data.options.timestamps !== false &&\n !data.options.noTimestamps,\n });\n\n if (!hasMigration) {\n await putFileAsync(migrationPath, migrationContent);\n }\n\n reportSkippedFiles();\n\n console.log(colors.cyan(`\\n✨ Model \"${name.pascal}\" generated successfully!`));\n console.log(colors.gray(`\\nNext steps:`));\n console.log(colors.gray(` 1. Update model schema in ${name.kebab}.model.ts`));\n console.log(\n colors.gray(\n hasMigration\n ? ` 2. Existing migration kept; add changes with: warlock gen.migration ${module}/${name.kebab} --add ...`\n : ` 2. Update migration in migrations/${timestamp}-${name.kebab}.migration.ts`,\n ),\n );\n console.log(colors.gray(` 3. Run migration: warlock migrate`));\n}\n"],"mappings":";;;;;;;;;;AAsBA,eAAsB,cAAc,MAAwC;CAC1E,MAAM,QAAQ,KAAK,KAAK;CAExB,IAAI,CAAC,OAAO;EACV,QAAQ,IAAI,OAAO,IAAI,+BAA+B,CAAC;EACvD,QAAQ,IAAI,OAAO,OAAO,+CAA+C,CAAC;EAC1E,QAAQ,IAAI,OAAO,OAAO,4CAA4C,CAAC;EACvE,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,+CAA+C,CAAC;EAC1E,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,aAAa,aAAa;CACvC,MAAM,QAAQ,KAAK,QAAQ,SAAS,KAAK,QAAQ;CACjD,UAAU,QAAQ,KAAK,QAAQ,MAAM,CAAC;CAEtC,gBAAgB,CAAC,KAAK,QAAQ,SAAS;CACvC,MAAM,eAAe,KAAK,QAAQ,gBAAgB,KAAK,QAAQ;CAC/D,MAAM,YAAa,KAAK,QAAQ,SAAoB,KAAK,OAAO;CAGhE,MAAM,WAAW,KAAK,KAAK,kBAAkB,MAAM,GAAG,UAAU,KAAK,KAAK;CAC1E,MAAM,YAAY,KAAK,KAAK,UAAU,GAAG,KAAK,MAAM,UAAU;CAE9D,IAAK,MAAM,gBAAgB,QAAQ,UAAU,KAAK,SAAS,GAAG,KAAK,MAAM,OAAO,KAAM,CAAC,OAAO;EAC5F,QAAQ,IAAI,OAAO,IAAI,iBAAiB,KAAK,MAAM,iBAAiB,CAAC;EACrE,QAAQ,IAAI,OAAO,OAAO,0BAA0B,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,qBAAqB,QAAQ;CACnC,MAAM,qBAAqB,KAAK,KAAK,UAAU,YAAY,CAAC;CAG5D,MAAM,eAAe,UAAU,MAAM;EAAE;EAAW,cAAc,CAAC,CAAC;CAAa,CAAC;CAChF,MAAM,aAAa,WAAW,YAAY;CAG1C,IAAI,cAAc;EAChB,MAAM,eAAe,GAAG,KAAK,SAAS,MAAM;EAE5C,IAAI,SAAS,CAAE,MAAM,gBAAgB,QAAQ,aAAa,YAAY,GAAI;GACxE,MAAM,yBAAyB,QAAQ,WAAW;GAClD,MAAM,aACJ,qBAAqB,QAAQ,aAAa,YAAY,GACtD,aAAa,IAAI,CACnB;EACF;CACF;CAGA,MAAM,eAAe,oBAAoB,KAAK,MAAM;;CAEpD,MAAM,aAAa,KAAK,KAAK,UAAU,UAAU,GAAG,YAAY;CAGhE,MAAM,gBAAgB,KAAK,KAAK,UAAU,YAAY;CACtD,MAAM,eACJ,WAAW,aAAa,KACxB,YAAY,aAAa,CAAC,CAAC,MAAM,SAAS,KAAK,SAAS,eAAe,CAAC;CAC1E,MAAM,YAAY,mBAAmB;CACrC,MAAM,gBAAgB,KAAK,KACzB,UACA,cACA,GAAG,UAAU,GAAG,KAAK,MAAM,cAC7B;CAEA,MAAM,mBAAmB,cAAc,MAAM,EAC3C,YACE,KAAK,QAAQ,eAAe,WAC5B,KAAK,QAAQ,eAAe,SAC5B,CAAC,KAAK,QAAQ,aAClB,CAAC;CAED,IAAI,CAAC,cACH,MAAM,aAAa,eAAe,gBAAgB;CAGpD,mBAAmB;CAEnB,QAAQ,IAAI,OAAO,KAAK,cAAc,KAAK,OAAO,0BAA0B,CAAC;CAC7E,QAAQ,IAAI,OAAO,KAAK,eAAe,CAAC;CACxC,QAAQ,IAAI,OAAO,KAAK,+BAA+B,KAAK,MAAM,UAAU,CAAC;CAC7E,QAAQ,IACN,OAAO,KACL,eACI,yEAAyE,OAAO,GAAG,KAAK,MAAM,cAC9F,uCAAuC,UAAU,GAAG,KAAK,MAAM,cACrE,CACF;CACA,QAAQ,IAAI,OAAO,KAAK,qCAAqC,CAAC;AAChE"}
@@ -33,7 +33,9 @@ async function generateRepository(data) {
33
33
  process.exit(1);
34
34
  }
35
35
  await ensureComponentDirectory(module, "repositories");
36
- await putFileAsync(resolveComponentPath(module, "repositories", `${name.kebab}.repository`), repositoryStub(name));
36
+ const repositoryPath = resolveComponentPath(module, "repositories", `${name.kebab}.repository`);
37
+ const repositoryContent = repositoryStub(name);
38
+ await putFileAsync(repositoryPath, repositoryContent);
37
39
  console.log(colors.cyan(`\nRepository "${name.pascal}Repository" generated successfully!`));
38
40
  }
39
41
 
@@ -1 +1 @@
1
- {"version":3,"file":"repository.generator.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/repository.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport { repositoryStub } 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 generateRepository(data: CommandActionData): Promise<void> {\n const input = data.args[0];\n\n if (!input) {\n console.log(colors.red(\"Error: Repository name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.repository <module>/<name>\"));\n console.log(colors.yellow(\"Example: warlock generate.repository 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.repository <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 repository already exists\n if ((await componentExists(module, \"repositories\", `${name.kebab}.repository`)) && !force) {\n console.log(colors.red(`Error: Repository \"${name.kebab}.repository.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, \"repositories\");\n\n // Generate repository\n const repositoryPath = resolveComponentPath(module, \"repositories\", `${name.kebab}.repository`);\n const repositoryContent = repositoryStub(name);\n\n await putFileAsync(repositoryPath, repositoryContent);\n\n console.log(colors.cyan(`\\nRepository \"${name.pascal}Repository\" generated successfully!`));\n}\n"],"mappings":";;;;;;;AAYA,eAAsB,mBAAmB,MAAwC;CAC/E,MAAM,QAAQ,KAAK,KAAK;CAExB,IAAI,CAAC,OAAO;EACV,QAAQ,IAAI,OAAO,IAAI,oCAAoC,CAAC;EAC5D,QAAQ,IAAI,OAAO,OAAO,oDAAoD,CAAC;EAC/E,QAAQ,IAAI,OAAO,OAAO,iDAAiD,CAAC;EAC5E,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,oDAAoD,CAAC;EAC/E,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,gBAAgB,GAAG,KAAK,MAAM,YAAY,KAAM,CAAC,OAAO;EACzF,QAAQ,IAAI,OAAO,IAAI,sBAAsB,KAAK,MAAM,+BAA+B,CAAC;EACxF,QAAQ,IAAI,OAAO,OAAO,0BAA0B,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,yBAAyB,QAAQ,cAAc;CAMrD,MAAM,aAHiB,qBAAqB,QAAQ,gBAAgB,GAAG,KAAK,MAAM,YAGlD,GAFN,eAAe,IAEU,CAAC;CAEpD,QAAQ,IAAI,OAAO,KAAK,iBAAiB,KAAK,OAAO,oCAAoC,CAAC;AAC5F"}
1
+ {"version":3,"file":"repository.generator.mjs","names":[],"sources":["../../../../../../../../../../../packages/core/src/cli/commands/generate/generators/repository.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { CommandActionData } from \"../../../../commands/types\";\nimport { repositoryStub } 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 generateRepository(data: CommandActionData): Promise<void> {\n const input = data.args[0];\n\n if (!input) {\n console.log(colors.red(\"Error: Repository name is required\"));\n console.log(colors.yellow(\"Usage: warlock generate.repository <module>/<name>\"));\n console.log(colors.yellow(\"Example: warlock generate.repository 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.repository <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 repository already exists\n if ((await componentExists(module, \"repositories\", `${name.kebab}.repository`)) && !force) {\n console.log(colors.red(`Error: Repository \"${name.kebab}.repository.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, \"repositories\");\n\n // Generate repository\n const repositoryPath = resolveComponentPath(module, \"repositories\", `${name.kebab}.repository`);\n const repositoryContent = repositoryStub(name);\n\n await putFileAsync(repositoryPath, repositoryContent);\n\n console.log(colors.cyan(`\\nRepository \"${name.pascal}Repository\" generated successfully!`));\n}\n"],"mappings":";;;;;;;AAYA,eAAsB,mBAAmB,MAAwC;CAC/E,MAAM,QAAQ,KAAK,KAAK;CAExB,IAAI,CAAC,OAAO;EACV,QAAQ,IAAI,OAAO,IAAI,oCAAoC,CAAC;EAC5D,QAAQ,IAAI,OAAO,OAAO,oDAAoD,CAAC;EAC/E,QAAQ,IAAI,OAAO,OAAO,iDAAiD,CAAC;EAC5E,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,oDAAoD,CAAC;EAC/E,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,gBAAgB,GAAG,KAAK,MAAM,YAAY,KAAM,CAAC,OAAO;EACzF,QAAQ,IAAI,OAAO,IAAI,sBAAsB,KAAK,MAAM,+BAA+B,CAAC;EACxF,QAAQ,IAAI,OAAO,OAAO,0BAA0B,CAAC;EACrD,QAAQ,KAAK,CAAC;CAChB;CAGA,MAAM,yBAAyB,QAAQ,cAAc;CAGrD,MAAM,iBAAiB,qBAAqB,QAAQ,gBAAgB,GAAG,KAAK,MAAM,YAAY;CAC9F,MAAM,oBAAoB,eAAe,IAAI;CAE7C,MAAM,aAAa,gBAAgB,iBAAiB;CAEpD,QAAQ,IAAI,OAAO,KAAK,iBAAiB,KAAK,OAAO,oCAAoC,CAAC;AAC5F"}
@@ -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