@tulipes/cli 0.1.1 → 0.2.0-rc.2

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 (211) hide show
  1. package/README.md +10 -7
  2. package/dist/agent.d.ts +12 -0
  3. package/dist/agent.js +29 -0
  4. package/dist/agent.js.map +1 -0
  5. package/dist/app-core.d.ts +8 -6
  6. package/dist/app-core.js +23 -14
  7. package/dist/app-core.js.map +1 -1
  8. package/dist/bin.js +3 -3
  9. package/dist/bin.js.map +1 -1
  10. package/dist/config-check.d.ts +8 -0
  11. package/dist/config-check.js +43 -0
  12. package/dist/config-check.js.map +1 -0
  13. package/dist/config-import.d.ts +20 -0
  14. package/dist/config-import.js +133 -0
  15. package/dist/config-import.js.map +1 -0
  16. package/dist/dev.d.ts +4 -4
  17. package/dist/dev.js +7 -10
  18. package/dist/dev.js.map +1 -1
  19. package/dist/init.d.ts +6 -11
  20. package/dist/init.js +11 -6422
  21. package/dist/init.js.map +1 -1
  22. package/dist/inspection.d.ts +9 -8
  23. package/dist/inspection.js +10 -11
  24. package/dist/inspection.js.map +1 -1
  25. package/dist/main.js +82 -11
  26. package/dist/main.js.map +1 -1
  27. package/dist/migrate.d.ts +30 -0
  28. package/dist/migrate.js +772 -0
  29. package/dist/migrate.js.map +1 -0
  30. package/dist/new-module.js +84 -43
  31. package/dist/new-module.js.map +1 -1
  32. package/dist/routes.d.ts +3 -5
  33. package/dist/routes.js +4 -6
  34. package/dist/routes.js.map +1 -1
  35. package/dist/spec.d.ts +2 -5
  36. package/dist/spec.js +13 -6
  37. package/dist/spec.js.map +1 -1
  38. package/dist/sync.d.ts +3 -11
  39. package/dist/sync.js +81 -20
  40. package/dist/sync.js.map +1 -1
  41. package/dist/template.d.ts +58 -0
  42. package/dist/template.js +244 -0
  43. package/dist/template.js.map +1 -0
  44. package/dist/update.d.ts +8 -3
  45. package/dist/update.js +111 -38
  46. package/dist/update.js.map +1 -1
  47. package/package.json +17 -16
  48. package/templates/AGENTS.md +68 -31
  49. package/templates/CLAUDE.md +5 -4
  50. package/templates/app/.envs/.env.development +18 -0
  51. package/templates/app/.envs/.env.production +19 -0
  52. package/templates/app/.envs/.env.staging +19 -0
  53. package/templates/app/README.md +327 -0
  54. package/templates/app/app.ts +3 -0
  55. package/templates/app/config/app.config.ts +73 -0
  56. package/templates/app/docs/agent-manifest.json +724 -0
  57. package/templates/app/ecosystem.config.cjs +60 -0
  58. package/templates/app/modules/agent/controllers/agent.controllers.ts +31 -0
  59. package/templates/app/modules/agent/i18n/en.json +5 -0
  60. package/templates/app/modules/agent/i18n/fr.json +5 -0
  61. package/templates/app/modules/agent/module.acl.ts +14 -0
  62. package/templates/app/modules/agent/package.json +21 -0
  63. package/templates/app/modules/agent/routes/agent.routes.ts +29 -0
  64. package/templates/app/modules/agent/schemas/agent.schemas.ts +9 -0
  65. package/templates/app/modules/auth/bootstrap/credentials.bootstrap.ts +26 -0
  66. package/templates/app/modules/auth/bootstrap/seed-admin.bootstrap.ts +44 -0
  67. package/templates/app/modules/auth/controllers/auth.controllers.ts +312 -0
  68. package/templates/app/modules/auth/helpers/access-check.ts +42 -0
  69. package/templates/app/modules/auth/helpers/auth.ts +48 -0
  70. package/templates/app/modules/auth/helpers/documents.ts +57 -0
  71. package/templates/app/modules/auth/helpers/passport.ts +180 -0
  72. package/templates/app/modules/auth/helpers/passwords.ts +58 -0
  73. package/templates/app/modules/auth/helpers/session-cache.ts +67 -0
  74. package/templates/app/modules/auth/helpers/tokens.ts +329 -0
  75. package/templates/app/modules/auth/i18n/en.json +19 -0
  76. package/templates/app/modules/auth/i18n/fr.json +19 -0
  77. package/templates/app/modules/auth/lib/index.ts +12 -0
  78. package/templates/app/modules/auth/models/credential.model.ts +31 -0
  79. package/templates/app/modules/auth/models/revoked-token.model.ts +20 -0
  80. package/templates/app/modules/auth/models/session.model.ts +42 -0
  81. package/templates/app/modules/auth/module.acl.ts +41 -0
  82. package/templates/app/modules/auth/module.config.ts +30 -0
  83. package/templates/app/modules/auth/package.json +61 -0
  84. package/templates/app/modules/auth/routes/auth.routes.ts +94 -0
  85. package/templates/app/modules/auth/schemas/auth.schemas.ts +37 -0
  86. package/templates/app/modules/auth/tests/auth.test.ts +1079 -0
  87. package/templates/app/modules/config/controllers/config.controllers.ts +89 -0
  88. package/templates/app/modules/config/helpers/audit.ts +41 -0
  89. package/templates/app/modules/config/helpers/describe.ts +72 -0
  90. package/templates/app/modules/config/i18n/en.json +6 -0
  91. package/templates/app/modules/config/i18n/fr.json +6 -0
  92. package/templates/app/modules/config/models/config-audit.model.ts +26 -0
  93. package/templates/app/modules/config/module.acl.ts +12 -0
  94. package/templates/app/modules/config/package.json +23 -0
  95. package/templates/app/modules/config/routes/config.routes.ts +37 -0
  96. package/templates/app/modules/config/schemas/config.schemas.ts +13 -0
  97. package/templates/app/modules/config/tests/config.test.ts +126 -0
  98. package/templates/app/modules/core/bootstrap/cache.bootstrap.ts +12 -0
  99. package/templates/app/modules/core/helpers/cache/index.ts +60 -0
  100. package/templates/app/modules/core/helpers/cache/memory-cache.ts +53 -0
  101. package/templates/app/modules/core/helpers/cache/redis-cache.ts +68 -0
  102. package/templates/app/modules/core/helpers/cache/types.ts +37 -0
  103. package/templates/app/modules/core/helpers/lazy.ts +13 -0
  104. package/templates/app/modules/core/helpers/logger/index.ts +115 -0
  105. package/templates/app/modules/core/helpers/mongoose/index.ts +27 -0
  106. package/templates/app/modules/core/helpers/mongoose/plugins/base.plugin.ts +14 -0
  107. package/templates/app/modules/core/helpers/mongoose/plugins/soft-delete.plugin.ts +124 -0
  108. package/templates/app/modules/core/helpers/mongoose/plugins/timestamps.plugin.ts +13 -0
  109. package/templates/app/modules/core/helpers/mongoose/plugins/types.ts +45 -0
  110. package/templates/app/modules/core/helpers/mongoose/register.ts +20 -0
  111. package/templates/app/modules/core/lib/index.ts +34 -0
  112. package/templates/app/modules/core/module.config.ts +24 -0
  113. package/templates/app/modules/core/package.json +80 -0
  114. package/templates/app/modules/core/routes/core.routes.ts +24 -0
  115. package/templates/app/modules/core/tests/core.test.ts +19 -0
  116. package/templates/app/modules/hello/agent/hello.agent.ts +33 -0
  117. package/templates/app/modules/hello/bootstrap/seed-greetings.bootstrap.ts +27 -0
  118. package/templates/app/modules/hello/controllers/greetings.controllers.ts +43 -0
  119. package/templates/app/modules/hello/controllers/hello.controllers.ts +50 -0
  120. package/templates/app/modules/hello/helpers/greeting.ts +8 -0
  121. package/templates/app/modules/hello/i18n/en.json +8 -0
  122. package/templates/app/modules/hello/i18n/fr.json +8 -0
  123. package/templates/app/modules/hello/models/greeting.model.ts +24 -0
  124. package/templates/app/modules/hello/module.acl.ts +16 -0
  125. package/templates/app/modules/hello/module.config.ts +14 -0
  126. package/templates/app/modules/hello/package.json +24 -0
  127. package/templates/app/modules/hello/queues/hello.queues.ts +38 -0
  128. package/templates/app/modules/hello/routes/greetings.routes.ts +25 -0
  129. package/templates/app/modules/hello/routes/hello.routes.ts +44 -0
  130. package/templates/app/modules/hello/sockets/hello.sockets.ts +21 -0
  131. package/templates/app/modules/hello/tests/hello.test.ts +19 -0
  132. package/templates/app/modules/security/bootstrap/rate-limit.bootstrap.ts +8 -0
  133. package/templates/app/modules/security/helpers/hardening.ts +65 -0
  134. package/templates/app/modules/security/helpers/proxy.ts +16 -0
  135. package/templates/app/modules/security/helpers/rate-limit.ts +150 -0
  136. package/templates/app/modules/security/module.config.ts +59 -0
  137. package/templates/app/modules/security/package.json +26 -0
  138. package/templates/app/modules/security/routes/security.routes.ts +42 -0
  139. package/templates/app/modules/security/tests/security.test.ts +174 -0
  140. package/templates/app/modules/settings/bootstrap/log-streams.bootstrap.ts +12 -0
  141. package/templates/app/modules/settings/controllers/settings.controllers.ts +58 -0
  142. package/templates/app/modules/settings/helpers/access-lease.ts +99 -0
  143. package/templates/app/modules/settings/helpers/log-stream.ts +272 -0
  144. package/templates/app/modules/settings/helpers/log-tail.ts +253 -0
  145. package/templates/app/modules/settings/i18n/en.json +3 -0
  146. package/templates/app/modules/settings/i18n/fr.json +3 -0
  147. package/templates/app/modules/settings/module.acl.ts +12 -0
  148. package/templates/app/modules/settings/package.json +21 -0
  149. package/templates/app/modules/settings/routes/settings.routes.ts +33 -0
  150. package/templates/app/modules/settings/schemas/settings.schemas.ts +8 -0
  151. package/templates/app/modules/settings/tests/settings.test.ts +409 -0
  152. package/templates/app/modules/users/controllers/users.controllers.ts +113 -0
  153. package/templates/app/modules/users/i18n/en.json +14 -0
  154. package/templates/app/modules/users/i18n/fr.json +14 -0
  155. package/templates/app/modules/users/models/user.model.ts +18 -0
  156. package/templates/app/modules/users/module.acl.ts +10 -0
  157. package/templates/app/modules/users/module.config.ts +11 -0
  158. package/templates/app/modules/users/package.json +24 -0
  159. package/templates/app/modules/users/queues/users.queues.ts +31 -0
  160. package/templates/app/modules/users/routes/users.routes.ts +60 -0
  161. package/templates/app/modules/users/schemas/users.schemas.ts +30 -0
  162. package/templates/app/modules/users/sockets/users.sockets.ts +18 -0
  163. package/templates/app/nginx/development.conf +44 -0
  164. package/templates/app/nginx/production.conf +75 -0
  165. package/templates/app/nginx/staging.conf +51 -0
  166. package/templates/app/package.json +58 -0
  167. package/templates/app/scripts/count-greetings.ts +29 -0
  168. package/templates/app/scripts/deploy-nginx.ts +143 -0
  169. package/templates/app/scripts/list-users.ts +34 -0
  170. package/templates/app/tests/app.test.ts +28 -0
  171. package/templates/app/tests/support.ts +36 -0
  172. package/templates/app/tsconfig.json +28 -0
  173. package/templates/app/vitest.config.ts +6 -0
  174. package/templates/app/worker.ts +6 -0
  175. package/templates/claude/skills/tulipes-agent-tool/SKILL.md +87 -0
  176. package/templates/claude/skills/tulipes-boot-errors/SKILL.md +11 -5
  177. package/templates/claude/skills/tulipes-config/SKILL.md +74 -0
  178. package/templates/claude/skills/tulipes-endpoint/SKILL.md +38 -25
  179. package/templates/claude/skills/tulipes-env-variable/SKILL.md +54 -26
  180. package/templates/claude/skills/tulipes-model/SKILL.md +11 -4
  181. package/templates/claude/skills/tulipes-module/SKILL.md +11 -10
  182. package/templates/claude/skills/tulipes-queue/SKILL.md +20 -6
  183. package/templates/claude/skills/tulipes-settings/SKILL.md +49 -100
  184. package/templates/claude/skills/tulipes-spec/SKILL.md +10 -12
  185. package/templates/minimal/README.md +21 -0
  186. package/templates/minimal/app.ts +3 -0
  187. package/templates/minimal/config/app.config.ts +16 -0
  188. package/templates/minimal/modules/agent/module.acl.ts +3 -0
  189. package/templates/minimal/modules/agent/package.json +14 -0
  190. package/templates/minimal/modules/agent/routes/agent.routes.ts +20 -0
  191. package/templates/minimal/modules/core/module.acl.ts +4 -0
  192. package/templates/minimal/modules/core/package.json +21 -0
  193. package/templates/minimal/modules/hello/i18n/en.json +3 -0
  194. package/templates/minimal/modules/hello/module.acl.ts +2 -0
  195. package/templates/minimal/modules/hello/package.json +11 -0
  196. package/templates/minimal/modules/hello/routes/health.routes.ts +9 -0
  197. package/templates/minimal/modules/hello/routes/hello.routes.ts +10 -0
  198. package/templates/minimal/modules/security/package.json +15 -0
  199. package/templates/minimal/modules/security/routes/security.routes.ts +8 -0
  200. package/templates/minimal/package.json +38 -0
  201. package/templates/minimal/tests/app.test.ts +52 -0
  202. package/templates/minimal/tsconfig.json +22 -0
  203. package/templates/minimal/vitest.config.ts +5 -0
  204. package/templates/overlays/no-queues/ecosystem.config.cjs +52 -0
  205. package/templates/overlays/no-queues/modules/hello/controllers/greetings.controllers.ts +41 -0
  206. package/templates/overlays/no-queues/modules/users/controllers/users.controllers.ts +107 -0
  207. package/templates/versions.json +11 -0
  208. package/dist/minimal.d.ts +0 -2
  209. package/dist/minimal.js +0 -2200
  210. package/dist/minimal.js.map +0 -1
  211. /package/templates/{browser-auth.md → app/docs/browser-auth.md} +0 -0
@@ -0,0 +1,107 @@
1
+ import { forgetUser } from "@app/auth";
2
+ import type { Request, RequestHandler, Response } from "express";
3
+ import type { Ctx } from "@tulipes/core/boot";
4
+ import { HttpError } from "@tulipes/core/http";
5
+
6
+ /**
7
+ * One class per controller, holding the context. Each method returns a
8
+ * handler, so the routes file stays a table of contents.
9
+ *
10
+ * Every response goes through `res.respond`, which wraps the payload in
11
+ * the app's envelope. Failures are thrown rather than responded — the
12
+ * framework's terminal handler builds the same envelope from them — so a
13
+ * handler only ever writes the happy path.
14
+ *
15
+ * Thrown messages are i18n KEYS: the handler translates them in this
16
+ * module's namespace and derives the error code from the key, so
17
+ * "notFound" becomes NOT_FOUND with a translated message.
18
+ */
19
+ export class UsersController {
20
+ readonly #ctx: Ctx;
21
+
22
+ constructor(ctx: Ctx) {
23
+ this.#ctx = ctx;
24
+ }
25
+
26
+ list(): RequestHandler {
27
+ return async (req: Request, res: Response) => {
28
+ // ?page and ?per_page, already clamped by config.pagination.
29
+ const { per_page, skip } = req.page;
30
+ const User = this.#ctx.models!.get("User");
31
+
32
+ const [users, total_items] = await Promise.all([
33
+ User.find().select("email role -_id").skip(skip).limit(per_page).lean(),
34
+ User.countDocuments(),
35
+ ]);
36
+
37
+ // Passing total_items is what marks this a page: respond fills in
38
+ // page, per_page and total_pages from the request and the count.
39
+ res.respond({ data: users, meta: { total_items } });
40
+ };
41
+ }
42
+
43
+ /** Soft delete: the row stays in mongo but leaves every ordinary query. */
44
+ softDelete(): RequestHandler {
45
+ return async (req: Request, res: Response) => {
46
+ const user = await this.#ctx.models!.get("User").findOne({ email: req.params.email });
47
+ if (!user) throw new HttpError(404, "notFound");
48
+
49
+ // The account leaves every query, so its sessions resolve to nobody on
50
+ // the cold path; the cached identities would not know, so they go too.
51
+ await forgetUser(this.#ctx, String(user._id));
52
+ await (user as unknown as { softDelete(): Promise<unknown> }).softDelete();
53
+ res.respond({ data: { email: req.params.email, soft_deleted: true } });
54
+ };
55
+ }
56
+
57
+ listDeleted(): RequestHandler {
58
+ return async (_req: Request, res: Response) => {
59
+ const deleted = await this.#ctx.models!
60
+ .get("User")
61
+ .find({ is_deleted: true })
62
+ .setOptions({ withDeleted: true } as Record<string, unknown>)
63
+ .select("email role -_id")
64
+ .lean();
65
+
66
+ res.respond({ data: deleted });
67
+ };
68
+ }
69
+
70
+ create(): RequestHandler {
71
+ return async (req: Request, res: Response) => {
72
+ const { email } = (req.body ?? {}) as { email?: string };
73
+ // `field` is what puts this against the input in the envelope.
74
+ if (!email) throw new HttpError(422, "emailRequired", { field: "email" });
75
+
76
+ await this.#ctx.models!.get("User").create({ email });
77
+
78
+ res.respond({ status: 201, data: { email } });
79
+ };
80
+ }
81
+
82
+ ping(): RequestHandler {
83
+ return (req: Request, res: Response) => {
84
+ res.respond({
85
+ data: {
86
+ module: "users",
87
+ locale: req.locale,
88
+ max_sessions: this.#ctx.config.users?.maxSessions,
89
+ },
90
+ });
91
+ };
92
+ }
93
+
94
+ /** Demonstrates HttpError — the framework renders it into the envelope. */
95
+ demoMissing(): RequestHandler {
96
+ return async () => {
97
+ throw new HttpError(404, "notFound", { details: { hint: "demo endpoint" } });
98
+ };
99
+ }
100
+
101
+ /** Demonstrates an unexpected error: anonymous 500 outside development. */
102
+ demoBoom(): RequestHandler {
103
+ return async () => {
104
+ throw new Error("secret internals that must not leak in production");
105
+ };
106
+ }
107
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "pnpm": "10.28.0",
3
+ "@tulipes/core": "0.11.0-rc.2",
4
+ "@tulipes/cli": "0.2.0-rc.2",
5
+ "@tulipes/spec": "0.3.2-rc.2",
6
+ "@tulipes/mongoose": "0.2.0-rc.2",
7
+ "@tulipes/bullmq": "0.2.0-rc.2",
8
+ "@tulipes/socket.io": "0.1.2-rc.2",
9
+ "@tulipes/testing": "0.1.0-rc.2",
10
+ "@tulipes/mcp": "0.1.0-rc.2"
11
+ }
package/dist/minimal.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare function starterTests(production: boolean): string;
2
- export declare function renderMinimalProject(name: string, coreVersion: string, cliVersion: string): [string, string][];