@tulipes/cli 0.2.0 → 0.3.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 (110) hide show
  1. package/dist/config-check.js +1 -1
  2. package/dist/env-check.d.ts +5 -3
  3. package/dist/env-check.js +26 -19
  4. package/dist/env-check.js.map +1 -1
  5. package/dist/main.js +83 -19
  6. package/dist/main.js.map +1 -1
  7. package/dist/migrate-0.12-env.d.ts +36 -0
  8. package/dist/migrate-0.12-env.js +250 -0
  9. package/dist/migrate-0.12-env.js.map +1 -0
  10. package/dist/migrate-0.12-scaffold.d.ts +1 -0
  11. package/dist/migrate-0.12-scaffold.js +197 -0
  12. package/dist/migrate-0.12-scaffold.js.map +1 -0
  13. package/dist/migrate-0.12.d.ts +47 -0
  14. package/dist/migrate-0.12.js +210 -0
  15. package/dist/migrate-0.12.js.map +1 -0
  16. package/dist/migrate.d.ts +3 -1
  17. package/dist/migrate.js +11 -5
  18. package/dist/migrate.js.map +1 -1
  19. package/dist/new-module.d.ts +7 -0
  20. package/dist/new-module.js +35 -16
  21. package/dist/new-module.js.map +1 -1
  22. package/dist/roles.d.ts +15 -0
  23. package/dist/roles.js +54 -0
  24. package/dist/roles.js.map +1 -0
  25. package/dist/routes.d.ts +7 -2
  26. package/dist/routes.js +19 -10
  27. package/dist/routes.js.map +1 -1
  28. package/dist/spec.d.ts +2 -0
  29. package/dist/spec.js +13 -11
  30. package/dist/spec.js.map +1 -1
  31. package/dist/sync.js +66 -53
  32. package/dist/sync.js.map +1 -1
  33. package/package.json +4 -4
  34. package/templates/AGENTS.md +35 -23
  35. package/templates/app/.envs/.env.development +2 -1
  36. package/templates/app/.envs/.env.production +2 -2
  37. package/templates/app/.envs/.env.staging +2 -2
  38. package/templates/app/README.md +44 -29
  39. package/templates/app/config/app.config.ts +60 -7
  40. package/templates/app/docs/agent-manifest.json +8 -681
  41. package/templates/app/modules/agent/controllers/{agent.controllers.ts → web.agent.controllers.ts} +1 -1
  42. package/templates/app/modules/agent/routes/{agent.routes.ts → web.agent.routes.ts} +4 -4
  43. package/templates/app/modules/auth/bootstrap/credentials.bootstrap.ts +20 -12
  44. package/templates/app/modules/auth/bootstrap/seed-admin.bootstrap.ts +4 -2
  45. package/templates/app/modules/auth/controllers/{auth.controllers.ts → web.auth.controllers.ts} +1 -1
  46. package/templates/app/modules/auth/helpers/passport.ts +1 -1
  47. package/templates/app/modules/auth/helpers/session-cache.ts +3 -3
  48. package/templates/app/modules/auth/helpers/tokens.ts +3 -5
  49. package/templates/app/modules/auth/module.acl.ts +31 -9
  50. package/templates/app/modules/auth/module.config.ts +5 -3
  51. package/templates/app/modules/auth/package.json +10 -10
  52. package/templates/app/modules/auth/routes/{auth.routes.ts → web.auth.routes.ts} +15 -10
  53. package/templates/app/modules/auth/tests/auth.test.ts +1 -1
  54. package/templates/app/modules/config/controllers/{config.controllers.ts → bo.config.controllers.ts} +3 -2
  55. package/templates/app/modules/config/helpers/audit.ts +1 -1
  56. package/templates/app/modules/config/helpers/describe.ts +35 -26
  57. package/templates/app/modules/config/module.acl.ts +1 -1
  58. package/templates/app/modules/config/routes/{config.routes.ts → bo.config.routes.ts} +5 -5
  59. package/templates/app/modules/config/tests/config.test.ts +14 -6
  60. package/templates/app/modules/core/helpers/cache/index.ts +8 -7
  61. package/templates/app/modules/core/helpers/lazy.ts +3 -3
  62. package/templates/app/modules/core/helpers/logger/index.ts +24 -16
  63. package/templates/app/modules/core/module.config.ts +5 -3
  64. package/templates/app/modules/core/package.json +46 -19
  65. package/templates/app/modules/core/routes/core.routes.ts +4 -4
  66. package/templates/app/modules/hello/agent/hello.agent.ts +2 -2
  67. package/templates/app/modules/hello/controllers/{hello.controllers.ts → web/hello.controllers.ts} +1 -1
  68. package/templates/app/modules/hello/controllers/{greetings.controllers.ts → web/hello.greetings.controllers.ts} +2 -2
  69. package/templates/app/modules/hello/module.acl.ts +12 -7
  70. package/templates/app/modules/hello/queues/hello.queues.ts +1 -1
  71. package/templates/app/modules/hello/routes/{greetings.routes.ts → web/hello.greetings.routes.ts} +4 -4
  72. package/templates/app/modules/hello/routes/{hello.routes.ts → web/hello.routes.ts} +14 -8
  73. package/templates/app/modules/security/helpers/rate-limit.ts +3 -2
  74. package/templates/app/modules/security/routes/security.routes.ts +4 -4
  75. package/templates/app/modules/settings/bootstrap/log-streams.bootstrap.ts +2 -2
  76. package/templates/app/modules/settings/controllers/{settings.controllers.ts → bo.settings.controllers.ts} +7 -6
  77. package/templates/app/modules/settings/helpers/log-stream.ts +6 -5
  78. package/templates/app/modules/settings/routes/{settings.routes.ts → bo.settings.routes.ts} +3 -3
  79. package/templates/app/modules/settings/tests/settings.test.ts +21 -25
  80. package/templates/app/modules/users/controllers/{users.controllers.ts → bo.users.controllers.ts} +5 -55
  81. package/templates/{overlays/no-queues/modules/users/controllers/users.controllers.ts → app/modules/users/controllers/web.users.controllers.ts} +4 -42
  82. package/templates/app/modules/users/module.acl.ts +4 -4
  83. package/templates/app/modules/users/queues/users.queues.ts +1 -1
  84. package/templates/app/modules/users/routes/bo.users.routes.ts +39 -0
  85. package/templates/app/modules/users/routes/web.users.routes.ts +45 -0
  86. package/templates/app/nginx/production.conf +1 -1
  87. package/templates/app/scripts/deploy-nginx.ts +3 -2
  88. package/templates/app/tests/support.ts +4 -3
  89. package/templates/claude/skills/tulipes-agent-tool/SKILL.md +6 -4
  90. package/templates/claude/skills/tulipes-boot-errors/SKILL.md +13 -7
  91. package/templates/claude/skills/tulipes-config/SKILL.md +6 -4
  92. package/templates/claude/skills/tulipes-endpoint/SKILL.md +34 -15
  93. package/templates/claude/skills/tulipes-env-variable/SKILL.md +62 -37
  94. package/templates/claude/skills/tulipes-i18n/SKILL.md +20 -1
  95. package/templates/claude/skills/tulipes-module/SKILL.md +10 -5
  96. package/templates/claude/skills/tulipes-permissions/SKILL.md +123 -35
  97. package/templates/claude/skills/tulipes-queue/SKILL.md +3 -2
  98. package/templates/claude/skills/tulipes-settings/SKILL.md +9 -8
  99. package/templates/claude/skills/tulipes-spec/SKILL.md +12 -2
  100. package/templates/minimal/config/app.config.ts +13 -3
  101. package/templates/minimal/modules/agent/routes/{agent.routes.ts → web.agent.routes.ts} +2 -2
  102. package/templates/minimal/modules/core/module.acl.ts +7 -1
  103. package/templates/minimal/modules/core/package.json +4 -4
  104. package/templates/minimal/modules/hello/module.acl.ts +1 -1
  105. package/templates/minimal/modules/hello/routes/{health.routes.ts → web.hello.health.routes.ts} +1 -1
  106. package/templates/minimal/modules/hello/routes/{hello.routes.ts → web.hello.routes.ts} +1 -1
  107. package/templates/overlays/no-queues/modules/hello/controllers/{greetings.controllers.ts → web/hello.greetings.controllers.ts} +1 -1
  108. package/templates/overlays/no-queues/modules/users/controllers/bo.users.controllers.ts +57 -0
  109. package/templates/versions.json +8 -8
  110. package/templates/app/modules/users/routes/users.routes.ts +0 -60
@@ -25,7 +25,7 @@ export async function runConfigCheck(rootDir) {
25
25
  try {
26
26
  const { settings } = handle.ctx;
27
27
  const namespaces = settings.namespaces();
28
- console.log(`APP_ENV=${handle.env.appEnv} — ${namespaces.length} settings namespace(s) in ${settings.status().label}:`);
28
+ console.log(`APP_ENV=${handle.ctx.appEnv} — ${namespaces.length} settings namespace(s) in ${settings.status().label}:`);
29
29
  for (const namespace of namespaces) {
30
30
  const description = settings.describe(namespace);
31
31
  const { version, updated_at, updated_by } = description.stored;
@@ -1,6 +1,8 @@
1
1
  /**
2
- * `tulipes env:check` — boot phases 1–3 and nothing else: validate the
3
- * current environment against every module's declared contract, print the
4
- * verdict, exit accordingly. Built for CI gates and deploy preflights.
2
+ * `tulipes env:check` — boot phase 1 and nothing else: resolve every
3
+ * declared variable from the process, the env file and the defaults, print
4
+ * where each landed in the config and from which source, exit non-zero on
5
+ * any problem. Built for CI gates and deploy preflights; also the one place
6
+ * to *see* the values, since `ctx.config` keeps them out of every listing.
5
7
  */
6
8
  export declare function runEnvCheck(rootDir: string): Promise<void>;
package/dist/env-check.js CHANGED
@@ -1,28 +1,35 @@
1
- import { Environment } from "@tulipes/core/env";
2
- import { TulipesBootError } from "@tulipes/core/errors";
1
+ import { join } from "node:path";
2
+ import { resolveAppEnv, resolveEnv } from "@tulipes/core/boot";
3
+ import { BootReport, TulipesBootError } from "@tulipes/core/errors";
4
+ import { discoverModules } from "@tulipes/core/modules";
3
5
  /**
4
- * `tulipes env:check` — boot phases 1–3 and nothing else: validate the
5
- * current environment against every module's declared contract, print the
6
- * verdict, exit accordingly. Built for CI gates and deploy preflights.
6
+ * `tulipes env:check` — boot phase 1 and nothing else: resolve every
7
+ * declared variable from the process, the env file and the defaults, print
8
+ * where each landed in the config and from which source, exit non-zero on
9
+ * any problem. Built for CI gates and deploy preflights; also the one place
10
+ * to *see* the values, since `ctx.config` keeps them out of every listing.
7
11
  */
8
12
  export async function runEnvCheck(rootDir) {
9
- let env;
13
+ const report = new BootReport();
10
14
  try {
11
- env = Environment.load({ rootDir });
12
- }
13
- catch (error) {
14
- if (error instanceof TulipesBootError) {
15
- console.error(error.message);
16
- process.exitCode = 1;
17
- return;
15
+ const appEnv = resolveAppEnv(undefined, report);
16
+ report.throwIfAny("environment");
17
+ const manifests = discoverModules(join(rootDir, "modules"), report);
18
+ report.throwIfAny("module graph");
19
+ const resolved = resolveEnv(manifests, { appEnv, envsDir: join(rootDir, ".envs") }, report);
20
+ report.throwIfAny("environment");
21
+ const lines = resolved.snapshot();
22
+ console.log(`APP_ENV=${appEnv} — ${lines.length} variable(s) resolved:`);
23
+ for (const { module, name, key, value } of lines) {
24
+ const shown = value === undefined ? "(not set)" : String(value);
25
+ console.log(` ✔ config.${module}.${name} ← ${key}=${shown}`);
18
26
  }
19
- throw error;
20
27
  }
21
- const snapshot = env.store.snapshot(); // secrets redacted
22
- const names = Object.keys(snapshot);
23
- console.log(`APP_ENV=${env.appEnv} — ${names.length} variable(s) resolved:`);
24
- for (const name of names) {
25
- console.log(` ✔ ${name}=${String(snapshot[name])}`);
28
+ catch (error) {
29
+ if (!(error instanceof TulipesBootError))
30
+ throw error;
31
+ console.error(error.message);
32
+ process.exitCode = 1;
26
33
  }
27
34
  }
28
35
  //# sourceMappingURL=env-check.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"env-check.js","sourceRoot":"","sources":["../src/env-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe;IAC/C,IAAI,GAAG,CAAC;IACR,IAAI,CAAC;QACH,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;YACtC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,mBAAmB;IAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,CAAC,MAAM,MAAM,KAAK,CAAC,MAAM,wBAAwB,CAAC,CAAC;IAC7E,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"env-check.js","sourceRoot":"","sources":["../src/env-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe;IAC/C,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;QACpE,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC5F,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QAEjC,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,MAAM,KAAK,CAAC,MAAM,wBAAwB,CAAC,CAAC;QACzE,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,KAAK,EAAE,CAAC;YACjD,MAAM,KAAK,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChE,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,IAAI,IAAI,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,CAAC;YAAE,MAAM,KAAK,CAAC;QACtD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
package/dist/main.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { RAI_SEGMENT } from "@tulipes/core/acl";
1
2
  import { FULL_FEATURES, runInit } from "./init.js";
2
3
  import { runSync } from "./sync.js";
3
4
  import { runEnvCheck } from "./env-check.js";
@@ -5,10 +6,12 @@ import { runNewModule } from "./new-module.js";
5
6
  import { runDev } from "./dev.js";
6
7
  import { runUpdate } from "./update.js";
7
8
  import { runConfigCheck } from "./config-check.js";
9
+ import { runRoles } from "./roles.js";
8
10
  import { runRoutes } from "./routes.js";
9
11
  import { runSpec } from "./spec.js";
10
12
  import { runAgentManifest } from "./agent.js";
11
13
  import { runMigrate } from "./migrate.js";
14
+ import { runMigrate012 } from "./migrate-0.12.js";
12
15
  import { runConfigImport } from "./config-import.js";
13
16
  import { appCoreVersion, cliVersion, coreVersion } from "./package-info.js";
14
17
  /**
@@ -24,18 +27,26 @@ Usage:
24
27
  --no-queues | --no-sockets (production only) leave a provider out
25
28
  tulipes dev [entry] run the entrypoint with node --watch (default: app.ts), sync first
26
29
  tulipes sync regenerate types/tulipes.d.ts and .env.example
27
- tulipes env:check validate env against every module's tulipes.env (CI-friendly)
30
+ tulipes env:check resolve every module's tulipes.env and show where each value lands (CI-friendly)
28
31
  tulipes config:check load every settings namespace from the store and print it
29
32
  tulipes routes list every declared endpoint, with the roles that reach it
33
+ --scope <scope> only the endpoints of one scope (bo, web, …)
34
+ tulipes roles list every role: description, extras, who defined it, its grants
35
+ --role <role> only that role
30
36
  tulipes spec [options] write an OpenAPI document / Postman collection (needs @tulipes/spec)
31
37
  --openapi <file> --postman <file> --url <base>
32
- both inspect the app: no service, secret or .env is needed
38
+ --scope <scope> describe one client surface only
39
+ all three inspect the app: no service, secret or .env is needed
33
40
  tulipes migrate 0.11 rewrite an app generated on 0.10 to the 0.11 layout and contracts
41
+ tulipes migrate 0.12 give every RAI id a scope (users:read → users:web:read) and move the
42
+ environment into the config (tulipes.env keyed by name, ctx.config.<module>.<name>)
43
+ --scope <scope> the scope to insert (default: web)
34
44
  tulipes config:import carry .envs values that became settings into the store
35
45
  --env <APP_ENV> --from <file> --dry-run
36
46
  tulipes agent manifest print every tool the app exposes to agents, as JSON
37
47
  --out <file> write it instead --role <role> only what that role may call
38
48
  tulipes new module <name> scaffold a module under ./modules
49
+ --scope <scope> the surface its first endpoint serves (default: web)
39
50
  --model | --no-model force model/bootstrap files on or off
40
51
  --queues | --no-queues force the queues file on or off
41
52
  --sockets | --no-sockets force the sockets file on or off
@@ -72,20 +83,34 @@ export async function main(argv) {
72
83
  return;
73
84
  }
74
85
  }
75
- case "migrate":
76
- if (rest.length !== 1) {
77
- console.error("Usage: tulipes migrate 0.11");
86
+ case "migrate": {
87
+ const [target, flag, scope, ...extra] = rest;
88
+ const valid = target !== undefined && (flag === undefined || (flag === "--scope" && scope !== undefined && !scope.startsWith("-") && extra.length === 0));
89
+ if (!valid) {
90
+ console.error("Usage: tulipes migrate 0.11 | tulipes migrate 0.12 [--scope <scope>]");
78
91
  process.exitCode = 2;
79
92
  return;
80
93
  }
81
- return runMigrate(rootDir, rest[0]);
94
+ const options = scope === undefined ? {} : { scope };
95
+ return target === "0.12" ? runMigrate012(rootDir, options) : runMigrate(rootDir, target, options);
96
+ }
82
97
  case "env:check":
83
98
  return runEnvCheck(rootDir);
84
99
  case "routes":
85
100
  case "spec": {
86
101
  try {
87
102
  const options = inspectionArguments(rest, command);
88
- return command === "routes" ? await runRoutes(rootDir) : await runSpec(rootDir, options);
103
+ return command === "routes" ? await runRoutes(rootDir, options) : await runSpec(rootDir, options);
104
+ }
105
+ catch (error) {
106
+ console.error(error instanceof Error ? error.message : String(error));
107
+ process.exitCode = 2;
108
+ return;
109
+ }
110
+ }
111
+ case "roles": {
112
+ try {
113
+ return await runRoles(rootDir, rolesArguments(rest));
89
114
  }
90
115
  catch (error) {
91
116
  console.error(error instanceof Error ? error.message : String(error));
@@ -110,20 +135,15 @@ export async function main(argv) {
110
135
  }
111
136
  case "update":
112
137
  return runUpdate(rootDir);
113
- case "new":
114
- if (rest[0] !== "module" || !rest[1] || rest.slice(2).some((flag) => !["--model", "--no-model", "--queues", "--no-queues", "--sockets", "--no-sockets"].includes(flag))) {
115
- console.error('Usage: tulipes new module <name> [--model | --no-model] [--queues | --no-queues] [--sockets | --no-sockets]');
138
+ case "new": {
139
+ const parsed = rest[0] === "module" && rest[1] ? newModuleArguments(rest.slice(2)) : undefined;
140
+ if (!parsed) {
141
+ console.error('Usage: tulipes new module <name> [--scope <scope>] [--model | --no-model] [--queues | --no-queues] [--sockets | --no-sockets]');
116
142
  process.exitCode = 2;
117
143
  return;
118
144
  }
119
- return runNewModule(rootDir, rest[1], {
120
- ...(rest.includes("--model") && { models: true }),
121
- ...(rest.includes("--no-model") && { models: false }),
122
- ...(rest.includes("--queues") && { queues: true }),
123
- ...(rest.includes("--no-queues") && { queues: false }),
124
- ...(rest.includes("--sockets") && { sockets: true }),
125
- ...(rest.includes("--no-sockets") && { sockets: false }),
126
- });
145
+ return runNewModule(rootDir, rest[1], parsed);
146
+ }
127
147
  case "dev":
128
148
  return runDev(rootDir, rest[0] ?? "app.ts");
129
149
  case "-v":
@@ -154,13 +174,16 @@ function inspectionArguments(args, command) {
154
174
  if (arg === "--offline" || arg === "--runtime") {
155
175
  throw new Error(`${arg} was removed in 0.11: ${command} always inspects the app without services, secrets or a .env`);
156
176
  }
157
- else if (command === "spec" && (arg === "--openapi" || arg === "--postman" || arg === "--url")) {
177
+ else if (arg === "--scope" || (command === "spec" && (arg === "--openapi" || arg === "--postman" || arg === "--url"))) {
158
178
  const value = args[++index];
159
179
  if (!value || value.startsWith("-"))
160
180
  throw new Error(`${arg} requires a value`);
161
181
  const key = arg.slice(2);
162
182
  if (options[key])
163
183
  throw new Error(`Duplicate option: ${arg}`);
184
+ if (key === "scope" && !RAI_SEGMENT.test(value)) {
185
+ throw new Error(`--scope "${value}" is not a scope — lowercase, starting with a letter ([a-z][a-z0-9-]*)`);
186
+ }
164
187
  options[key] = value;
165
188
  }
166
189
  else
@@ -168,6 +191,47 @@ function inspectionArguments(args, command) {
168
191
  }
169
192
  return options;
170
193
  }
194
+ const NEW_MODULE_FLAGS = {
195
+ "--model": { models: true },
196
+ "--no-model": { models: false },
197
+ "--queues": { queues: true },
198
+ "--no-queues": { queues: false },
199
+ "--sockets": { sockets: true },
200
+ "--no-sockets": { sockets: false },
201
+ };
202
+ /** Undefined for anything the usage line does not allow. */
203
+ function newModuleArguments(args) {
204
+ let options = {};
205
+ for (let i = 0; i < args.length; i++) {
206
+ const flag = args[i];
207
+ if (flag === "--scope") {
208
+ const value = args[++i];
209
+ if (!value || value.startsWith("-") || options.scope !== undefined)
210
+ return undefined;
211
+ options.scope = value;
212
+ }
213
+ else if (NEW_MODULE_FLAGS[flag]) {
214
+ options = { ...options, ...NEW_MODULE_FLAGS[flag] };
215
+ }
216
+ else
217
+ return undefined;
218
+ }
219
+ return options;
220
+ }
221
+ function rolesArguments(args) {
222
+ const options = {};
223
+ for (let i = 0; i < args.length; i++) {
224
+ const flag = args[i];
225
+ const value = args[i + 1];
226
+ if (flag === "--role" && value && !value.startsWith("-") && options.role === undefined) {
227
+ options.role = value;
228
+ i++;
229
+ continue;
230
+ }
231
+ throw new Error(`unknown or incomplete option "${flag}" — usage: tulipes roles [--role <role>]`);
232
+ }
233
+ return options;
234
+ }
171
235
  /** Validate the complete init invocation before creating any files. */
172
236
  function initArguments(args) {
173
237
  let target;
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * `tulipes migrate 0.12`, the environment step — a 0.11 module's variables
3
+ * become its config values.
4
+ *
5
+ * In 0.11 a module declared `tulipes.env` as an array of `{ name, … }` and
6
+ * code read a value with `ctx.Environment.get("NAME")`. In 0.12 the
7
+ * declaration is an object keyed by the camelCase name the value is read
8
+ * under, `key` names the variable, and the value is `ctx.config.<module>.<name>`
9
+ * beside the module's settings. This step:
10
+ *
11
+ * 1. rewrites every module's declaration (`MONGO_URI` → `mongoUri`), and
12
+ * remembers which module owns which variable;
13
+ * 2. rewrites every read it can see — `x.Environment.get("K")`,
14
+ * `x.Environment.store.has("K")`, `x.Environment.appEnv`, the same
15
+ * through a destructured `Environment`, a parameter typed
16
+ * `Environment`, and `handle.env` — and passes a context where an
17
+ * `Environment` was passed as a value;
18
+ * 3. wires `config/app.config.ts`: `server.port`, `mongoose.uri` and
19
+ * `bullmq.redisUrl` from the variables the app declared for them.
20
+ *
21
+ * What it cannot read — a variable name built at runtime, a `store.set()`
22
+ * in a test, an `Environment` passed where no context is in scope — is a
23
+ * TODO naming the file and the replacement. Idempotent: an object-form
24
+ * declaration and a file with no `Environment` are left alone.
25
+ */
26
+ export interface EnvMigrationOutcome {
27
+ changed: string[];
28
+ todos: string[];
29
+ /** Per module: variable → the config name it is read under. */
30
+ env: Record<string, Record<string, string>>;
31
+ }
32
+ declare const UPPER_SNAKE: RegExp;
33
+ export declare function migrateEnv(rootDir: string): EnvMigrationOutcome;
34
+ /** `MONGO_URI` → `mongoUri`, `PORT` → `port`. */
35
+ export declare function configNameOf(variable: string): string;
36
+ export { UPPER_SNAKE };
@@ -0,0 +1,250 @@
1
+ import { existsSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
2
+ import { join, relative } from "node:path";
3
+ import { walkTs } from "./migrate.js";
4
+ const UPPER_SNAKE = /^[A-Z][A-Z0-9_]*$/;
5
+ const WELL_KNOWN_WIRING = {
6
+ PORT: { path: "server", line: (value) => `server: { port: ${value} },` },
7
+ MONGO_URI: { path: "mongoose", line: (value) => `mongoose: { uri: ${value} },` },
8
+ REDIS_URL: { path: "bullmq", line: (value) => `bullmq: { redisUrl: ${value} },` },
9
+ };
10
+ export function migrateEnv(rootDir) {
11
+ const outcome = { changed: [], todos: [], env: {} };
12
+ const owners = rewriteDeclarations(rootDir, outcome);
13
+ for (const file of walkTs(rootDir))
14
+ rewriteReads(rootDir, file, owners, outcome);
15
+ wireAppConfig(rootDir, owners, outcome);
16
+ return outcome;
17
+ }
18
+ /** `MONGO_URI` → `mongoUri`, `PORT` → `port`. */
19
+ export function configNameOf(variable) {
20
+ return variable
21
+ .toLowerCase()
22
+ .split("_")
23
+ .map((part, index) => (index === 0 ? part : part.charAt(0).toUpperCase() + part.slice(1)))
24
+ .join("");
25
+ }
26
+ // ── 1. declarations ──────────────────────────────────────────────────────
27
+ function rewriteDeclarations(rootDir, outcome) {
28
+ const owners = new Map();
29
+ const modulesDir = join(rootDir, "modules");
30
+ if (!existsSync(modulesDir))
31
+ return owners;
32
+ for (const entry of readdirSync(modulesDir, { withFileTypes: true })) {
33
+ if (!entry.isDirectory() || entry.name.startsWith("."))
34
+ continue;
35
+ const file = join(modulesDir, entry.name, "package.json");
36
+ if (!existsSync(file))
37
+ continue;
38
+ const manifest = JSON.parse(readFileSync(file, "utf8"));
39
+ const module = (manifest.name ?? entry.name).split("/").at(-1);
40
+ const declared = manifest.tulipes?.env;
41
+ if (!declared)
42
+ continue;
43
+ if (Array.isArray(declared)) {
44
+ const converted = {};
45
+ for (const { name, ...rest } of declared) {
46
+ // `key` first, so the manifest reads "this value, from that variable".
47
+ converted[configNameOf(name)] = { key: name, ...rest };
48
+ }
49
+ manifest.tulipes.env = converted;
50
+ writeFileSync(file, JSON.stringify(manifest, null, 2) + "\n");
51
+ outcome.changed.push(`modules/${entry.name}/package.json: ${declared.length} variable(s) keyed by config name`);
52
+ }
53
+ // Object form, converted just now or already: every entry has an owner.
54
+ for (const [name, spec] of Object.entries(manifest.tulipes.env)) {
55
+ owners.set(spec.key, { module, name });
56
+ (outcome.env[module] ??= {})[spec.key] = name;
57
+ }
58
+ }
59
+ return owners;
60
+ }
61
+ // ── 2. reads ─────────────────────────────────────────────────────────────
62
+ /** `ctx.config.core.port` for a variable with an owner, else undefined. */
63
+ function configPath(variable, receiver, owners) {
64
+ const owner = owners.get(variable);
65
+ // `!`: the namespace exists once the app boots; its type says it may not.
66
+ return owner ? `${receiver}.config.${owner.module}!.${owner.name}` : undefined;
67
+ }
68
+ function rewriteReads(rootDir, file, owners, outcome) {
69
+ const source = readFileSync(file, "utf8");
70
+ if (!/\bEnvironment\b|\.env\.(get|appEnv)\b|\} = \w+\.env;/.test(source))
71
+ return;
72
+ const label = relative(rootDir, file);
73
+ const todos = [];
74
+ const unknown = (variable) => todos.push(`${label}: reads "${variable}", which no module declares — declare it or read the owning module's config`);
75
+ let next = source;
76
+ const literalRead = (receiver, variable, original) => configPath(variable, receiver, owners) ?? (unknown(variable), original);
77
+ // `x.Environment.get("K")`, `x.Environment.store.has("K")`, `x.Environment.appEnv`,
78
+ // for any receiver chain: ctx, this.ctx, app.handle.ctx.
79
+ next = next.replace(/([\w$]+(?:\.[\w$]+)*)\.Environment\.get\(\s*(["'])([A-Z][A-Z0-9_]*)\2\s*\)/g, (match, receiver, _q, variable) => literalRead(receiver, variable, match));
80
+ next = next.replace(/([\w$]+(?:\.[\w$]+)*)\.Environment\.store\.has\(\s*(["'])([A-Z][A-Z0-9_]*)\2\s*\)/g, (match, receiver, _q, variable) => {
81
+ const path = configPath(variable, receiver, owners);
82
+ return path ? `(${path} !== undefined)` : (unknown(variable), match);
83
+ });
84
+ next = next.replace(/([\w$]+(?:\.[\w$]+)*)\.Environment\.appEnv\b/g, "$1.appEnv");
85
+ // `handle.env`: the boot handle no longer carries one; the context does.
86
+ next = next.replace(/([\w$]+)\.env\.get\(\s*(["'])([A-Z][A-Z0-9_]*)\2\s*\)/g, (match, handle, _q, variable) => literalRead(`${handle}.ctx`, variable, match));
87
+ next = next.replace(/([\w$]+)\.env\.appEnv\b/g, "$1.ctx.appEnv");
88
+ next = next.replace(/(\{\s*appEnv\s*\}\s*=\s*)([\w$]+)\.env;/g, "$1$2.ctx;");
89
+ next = rewriteDestructured(next, owners, label, todos);
90
+ next = rewriteTypedParameters(next, owners, label, todos);
91
+ // An `Environment` passed where a context is wanted: the receiver is the context.
92
+ next = next.replace(/([\w$]+(?:\.[\w$]+)*)\.Environment\b(?![\w$.])/g, "$1");
93
+ // What is left is what the rules could not read.
94
+ for (const dynamic of next.matchAll(/\.Environment\.get\(/g)) {
95
+ todos.push(`${label}:${lineOf(next, dynamic.index)}: a variable read by a name built at runtime — read ctx.config.<module>.<name> for each name instead`);
96
+ }
97
+ // The store's methods, through any name the engine was held under.
98
+ for (const store of next.matchAll(/([\w$]+)\.store\.(set|describe|snapshot|ownerOf|sourceOf)\(/g)) {
99
+ const [, holder, method] = store;
100
+ const hint = method === "describe" ? "ctx.settings.describeEnv(module) describes a module's values" : method === "set" ? "a value is read-only now; set the variable before the boot" : "the store is gone; ctx.settings.describeEnv(module) is what remains";
101
+ todos.push(`${label}:${lineOf(next, store.index)}: ${holder}.store.${method}() — ${hint}`);
102
+ }
103
+ next = next.replace(/^import\s+(?:type\s+)?\{[^}]*\bEnvironment\b[^}]*\}\s+from\s+["']@tulipes\/core\/env["'];?\n/gm, "");
104
+ // Prose may still say "Environment"; code may not.
105
+ if (/\bEnvironment\b/.test(withoutComments(next))) {
106
+ todos.push(`${label}: still mentions Environment — the engine is gone; a module reads ctx.config.<module>.<name>, a helper takes the context`);
107
+ }
108
+ if (next !== source) {
109
+ writeFileSync(file, next);
110
+ outcome.changed.push(`${label}: environment reads → ctx.config`);
111
+ }
112
+ outcome.todos.push(...todos);
113
+ }
114
+ /**
115
+ * A destructured `Environment` — `const { app, Environment } = ctx;` or a
116
+ * parameter `({ Environment, signal }: RuntimeCtx)` — read the values through
117
+ * the source it came from. A destructured parameter becomes a plain
118
+ * `ctx` with the other names destructured on the first line, so an
119
+ * `Environment` passed as a value has a context to become.
120
+ */
121
+ function rewriteDestructured(source, owners, label, todos) {
122
+ let next = source;
123
+ // Parameter form: `function f({ a, Environment }: T) {` or `({ a, Environment }: T) => {`.
124
+ next = next.replace(/(\bfunction\s+[\w$]*\s*|\(?)\(\s*\{([^}]*\bEnvironment\b[^}]*)\}(?:\s*:\s*([\w$<>, ]+))?\s*\)(\s*(?::\s*[\w$<>|, ]+)?\s*(?:=>\s*)?\{\n?)/g, (_match, head, names, type, tail) => {
125
+ const others = splitNames(names).filter((name) => name !== "Environment");
126
+ // The body's own indentation, for the destructuring line it gains.
127
+ const indent = /\n(\s*)/.exec(tail.slice(tail.indexOf("{") + 1) + "\n") ? (/^(\s*)/.exec(tail.split("\n").at(-1) ?? "")?.[1] ?? "") : "";
128
+ const destructure = others.length ? `${indent} const { ${others.join(", ")} } = ctx;\n` : "";
129
+ return `${head}(ctx${type ? `: ${type}` : ""})${tail}${destructure}`;
130
+ });
131
+ // Local form: the source is named.
132
+ const local = /const\s*\{([^}]*\bEnvironment\b[^}]*)\}\s*=\s*([\w$]+(?:\.[\w$]+)*);/.exec(next);
133
+ const sourceName = local ? local[2] : /\bEnvironment\b/.test(next) && /\(ctx: /.test(next) ? "ctx" : undefined;
134
+ if (local) {
135
+ const others = splitNames(local[1]).filter((name) => name !== "Environment");
136
+ next = next.replace(local[0], others.length ? `const { ${others.join(", ")} } = ${local[2]};` : "");
137
+ }
138
+ if (!sourceName)
139
+ return next;
140
+ const read = (variable, original) => configPath(variable, sourceName, owners) ?? (todos.push(`${label}: reads "${variable}", which no module declares`), original);
141
+ next = next.replace(/(?<![\w$.])Environment\.get\(\s*(["'])([A-Z][A-Z0-9_]*)\1\s*\)/g, (match, _q, variable) => read(variable, match));
142
+ next = next.replace(/(?<![\w$.])Environment\.store\.has\(\s*(["'])([A-Z][A-Z0-9_]*)\1\s*\)/g, (match, _q, variable) => {
143
+ const path = configPath(variable, sourceName, owners);
144
+ return path ? `(${path} !== undefined)` : match;
145
+ });
146
+ next = next.replace(/(?<![\w$.])Environment\.appEnv\b/g, `${sourceName}.appEnv`);
147
+ // Passed as a value: the context it came from.
148
+ next = next.replace(/(?<![\w$.])Environment\b(?![\w$.])/g, sourceName);
149
+ return next;
150
+ }
151
+ /**
152
+ * A helper that took the engine — `logger(environment: Environment, …)` —
153
+ * takes the part of the context it reads: `Pick<Ctx, "config">`, plus
154
+ * `"appEnv"` when it reads that, or the whole `Ctx` when it only keeps the
155
+ * object as a key. Its reads move with it, and `Ctx` is imported.
156
+ */
157
+ function rewriteTypedParameters(source, owners, label, todos) {
158
+ const parameters = [...source.matchAll(/\b([\w$]+)\s*:\s*Environment\b/g)].map((match) => match[1]);
159
+ if (parameters.length === 0 && !/\bEnvironment\b/.test(source))
160
+ return source;
161
+ let next = source;
162
+ for (const parameter of new Set(parameters)) {
163
+ const uses = { config: false, appEnv: false };
164
+ next = next.replace(new RegExp(`\\b${parameter}\\.get\\(\\s*(["'])([A-Z][A-Z0-9_]*)\\1\\s*\\)`, "g"), (match, _q, variable) => {
165
+ const path = configPath(variable, parameter, owners);
166
+ if (!path)
167
+ return (todos.push(`${label}: reads "${variable}", which no module declares`), match);
168
+ uses.config = true;
169
+ return path;
170
+ });
171
+ next = next.replace(new RegExp(`\\b${parameter}\\.store\\.has\\(\\s*(["'])([A-Z][A-Z0-9_]*)\\1\\s*\\)`, "g"), (match, _q, variable) => {
172
+ const path = configPath(variable, parameter, owners);
173
+ if (!path)
174
+ return match;
175
+ uses.config = true;
176
+ return `(${path} !== undefined)`;
177
+ });
178
+ if (new RegExp(`\\b${parameter}\\.appEnv\\b`).test(next))
179
+ uses.appEnv = true;
180
+ const type = uses.config || uses.appEnv ? `Pick<Ctx, ${[uses.config && '"config"', uses.appEnv && '"appEnv"'].filter(Boolean).join(" | ")}>` : "Ctx";
181
+ next = next.replace(new RegExp(`\\b${parameter}\\s*:\\s*Environment\\b`, "g"), `${parameter}: ${type}`);
182
+ }
183
+ // Any other type position — `WeakMap<Environment, X>` — is the context too.
184
+ next = next.replace(/(?<![\w$.])Environment\b(?=\s*[,>|])/g, "Ctx");
185
+ if (next !== source && /\bCtx\b/.test(next) && !/import\s+(?:type\s+)?\{[^}]*\bCtx\b[^}]*\}\s+from\s+["']@tulipes\/core\/boot["']/.test(next)) {
186
+ next = next.replace(/^(import\s+(?:type\s+)?\{[^}]*\}\s+from\s+["']@tulipes\/core\/env["'];?\n)/m, '$1import type { Ctx } from "@tulipes/core/boot";\n');
187
+ if (!/import type \{ Ctx \} from "@tulipes\/core\/boot"/.test(next)) {
188
+ next = `import type { Ctx } from "@tulipes/core/boot";\n` + next;
189
+ }
190
+ }
191
+ return next;
192
+ }
193
+ // ── 3. the app config ────────────────────────────────────────────────────
194
+ /**
195
+ * Core and the providers read `server.port`, `mongoose.uri` and
196
+ * `bullmq.redisUrl`, which 0.11 found by variable name. The seed receives
197
+ * every module's values now, so it wires the ones the app declared.
198
+ */
199
+ function wireAppConfig(rootDir, owners, outcome) {
200
+ const wiring = Object.entries(WELL_KNOWN_WIRING)
201
+ .filter(([variable]) => owners.has(variable))
202
+ .map(([variable, { path, line }]) => ({ path, line: line(`env.${owners.get(variable).module}.${owners.get(variable).name}`) }));
203
+ if (wiring.length === 0)
204
+ return;
205
+ const file = [".ts", ".js"].map((ext) => join(rootDir, "config", `app.config${ext}`)).find((candidate) => existsSync(candidate));
206
+ if (!file) {
207
+ const lines = ["import type { AppConfigFn } from \"@tulipes/core/boot\";", "", "/** The environment wired to what core and the providers read. */", "const appConfig = ((env) => ({", ...wiring.map((entry) => ` ${entry.line}`), "})) satisfies AppConfigFn;", "", "export default appConfig;", ""];
208
+ writeFileSync(join(rootDir, "config", "app.config.ts"), lines.join("\n"));
209
+ outcome.changed.push(`config/app.config.ts: created, wiring ${wiring.map((entry) => entry.path).join(", ")}`);
210
+ return;
211
+ }
212
+ const source = readFileSync(file, "utf8");
213
+ const label = relative(rootDir, file);
214
+ const missing = wiring.filter((entry) => !new RegExp(`^\\s*${entry.path}\\s*:`, "m").test(source));
215
+ if (missing.length === 0)
216
+ return;
217
+ // The scaffold's shape: a factory of no arguments returning an object literal.
218
+ const factory = /\(\s*\)\s*=>\s*\(\{\n/.exec(source);
219
+ if (!factory) {
220
+ outcome.todos.push(`${label}: give the default export an \`env\` parameter and add ${missing.map((entry) => entry.line.replace(/,$/, "")).join("; ")}`);
221
+ return;
222
+ }
223
+ const indent = /\n(\s+)\S/.exec(source.slice(factory.index + factory[0].length))?.[1] ?? " ";
224
+ // The wiring, then a blank line, then the app's own keys.
225
+ const block = [
226
+ `${indent}// The environment wired to what core and the providers read (0.12).`,
227
+ ...missing.map((entry) => `${indent}${entry.line}`),
228
+ "",
229
+ "",
230
+ ].join("\n");
231
+ let next = source.slice(0, factory.index) + "(env) => ({\n" + block + source.slice(factory.index + factory[0].length);
232
+ // Core and the providers type these keys; the seed's own augmentation leaves them out.
233
+ const keys = missing.map((entry) => JSON.stringify(entry.path)).join(" | ");
234
+ next = next.replace(/Partial<ReturnType<typeof (\w+)>>/, `Partial<Omit<ReturnType<typeof $1>, ${keys}>>`);
235
+ writeFileSync(file, next);
236
+ outcome.changed.push(`${label}: wires ${missing.map((entry) => entry.path).join(", ")} from the environment`);
237
+ }
238
+ // ── helpers ──────────────────────────────────────────────────────────────
239
+ /** The source with line and block comments blanked, for checks that look at code only. */
240
+ function withoutComments(source) {
241
+ return source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
242
+ }
243
+ function splitNames(pattern) {
244
+ return pattern.split(",").map((name) => name.trim()).filter(Boolean);
245
+ }
246
+ function lineOf(source, index) {
247
+ return source.slice(0, index ?? 0).split("\n").length;
248
+ }
249
+ export { UPPER_SNAKE };
250
+ //# sourceMappingURL=migrate-0.12-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-0.12-env.js","sourceRoot":"","sources":["../src/migrate-0.12-env.ts"],"names":[],"mappings":"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"}