@soapjs/cli 1.0.0 → 1.0.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 (55) hide show
  1. package/README.md +3 -0
  2. package/build/cli.js +2 -3
  3. package/build/commands/add/add.command.js +1 -2
  4. package/build/commands/add/command-plan.js +7 -8
  5. package/build/commands/add/entity-plan.js +1 -2
  6. package/build/commands/add/event-plan.js +1 -2
  7. package/build/commands/add/query-plan.js +6 -7
  8. package/build/commands/add/repository-plan.js +8 -9
  9. package/build/commands/add/resource-plan.js +20 -21
  10. package/build/commands/add/route-plan.js +7 -7
  11. package/build/commands/add/socket-plan.js +2 -3
  12. package/build/commands/add/use-case-plan.js +2 -3
  13. package/build/commands/check/check.command.js +1 -2
  14. package/build/commands/create/create.command.js +2 -3
  15. package/build/commands/create/project-plan.js +272 -227
  16. package/build/commands/doctor/doctor.command.js +1 -2
  17. package/build/commands/generate/bruno-analysis.js +4 -5
  18. package/build/commands/generate/bruno-plan.js +1 -2
  19. package/build/commands/generate/generate.command.js +1 -2
  20. package/build/commands/info/info.command.js +1 -2
  21. package/build/commands/remove/remove.command.js +1 -2
  22. package/build/commands/shared/common-options.js +3 -4
  23. package/build/commands/update/update.command.js +1 -2
  24. package/build/config/auth-policy.js +3 -4
  25. package/build/config/find-soap-root.js +1 -2
  26. package/build/config/load-soap-config.js +1 -2
  27. package/build/config/schemas/types.d.ts +1 -1
  28. package/build/config/schemas/validation.js +5 -6
  29. package/build/config/write-soap-config.js +1 -2
  30. package/build/core/command-context.js +2 -3
  31. package/build/core/errors.js +2 -2
  32. package/build/core/output.js +1 -2
  33. package/build/core/result.js +2 -3
  34. package/build/dependencies/dependency-resolver.js +12 -17
  35. package/build/dependencies/package-manager.js +3 -4
  36. package/build/io/conflict-policy.js +3 -4
  37. package/build/io/file-writer.js +1 -2
  38. package/build/io/format-file.js +1 -2
  39. package/build/presets/create-presets.js +3 -3
  40. package/build/prompts/add-resource.prompt.js +1 -2
  41. package/build/prompts/add-route.prompt.js +1 -2
  42. package/build/prompts/create-project.prompt.js +3 -2
  43. package/build/prompts/generate-bruno.prompt.js +1 -2
  44. package/build/prompts/inquirer-prompt-adapter.js +14 -5
  45. package/build/registry/registry.service.js +5 -6
  46. package/build/summary/create-summary.js +1 -2
  47. package/build/templates/naming.js +2 -3
  48. package/build/templates/template-engine.js +1 -2
  49. package/build/templates/template-resolver.js +2 -3
  50. package/build/terminal/terminal-capabilities.js +2 -3
  51. package/docs/cli/create.md +4 -1
  52. package/docs/guides/auth.md +9 -1
  53. package/docs/guides/index.md +1 -0
  54. package/docs/plans/KAFKA_1_0_UPDATE.md +30 -0
  55. package/package.json +3 -3
@@ -1,30 +1,39 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InquirerPromptAdapter = void 0;
4
- const prompts_1 = require("@inquirer/prompts");
4
+ const importModule = new Function("specifier", "return import(specifier)");
5
+ let prompts;
6
+ function loadPrompts() {
7
+ prompts ??= importModule("@inquirer/prompts");
8
+ return prompts;
9
+ }
5
10
  class InquirerPromptAdapter {
6
11
  async input(question) {
7
- return (0, prompts_1.input)({
12
+ const { input } = await loadPrompts();
13
+ return input({
8
14
  message: question.message,
9
15
  default: question.defaultValue,
10
16
  validate: question.required ? (value) => value.trim().length > 0 || "Value is required." : undefined,
11
17
  });
12
18
  }
13
19
  async confirm(question) {
14
- return (0, prompts_1.confirm)({
20
+ const { confirm } = await loadPrompts();
21
+ return confirm({
15
22
  message: question.message,
16
23
  default: question.defaultValue,
17
24
  });
18
25
  }
19
26
  async select(question) {
20
- return (0, prompts_1.select)({
27
+ const { select } = await loadPrompts();
28
+ return select({
21
29
  message: question.message,
22
30
  choices: question.choices.map(toInquirerChoice),
23
31
  default: question.defaultValue,
24
32
  });
25
33
  }
26
34
  async multiSelect(question) {
27
- const selected = await (0, prompts_1.checkbox)({
35
+ const { checkbox } = await loadPrompts();
36
+ const selected = await checkbox({
28
37
  message: question.message,
29
38
  choices: question.choices.map((choice) => ({
30
39
  ...toInquirerChoice(choice),
@@ -3,7 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.registerGeneratedFile = exports.assertCanWriteGeneratedFile = exports.upsertGeneratedFile = exports.readFileHash = exports.hashContent = void 0;
6
+ exports.hashContent = hashContent;
7
+ exports.readFileHash = readFileHash;
8
+ exports.upsertGeneratedFile = upsertGeneratedFile;
9
+ exports.assertCanWriteGeneratedFile = assertCanWriteGeneratedFile;
10
+ exports.registerGeneratedFile = registerGeneratedFile;
7
11
  const crypto_1 = __importDefault(require("crypto"));
8
12
  const promises_1 = __importDefault(require("fs/promises"));
9
13
  const path_1 = __importDefault(require("path"));
@@ -11,7 +15,6 @@ const errors_1 = require("../core/errors");
11
15
  function hashContent(content) {
12
16
  return crypto_1.default.createHash("sha256").update(content).digest("hex");
13
17
  }
14
- exports.hashContent = hashContent;
15
18
  async function readFileHash(filePath) {
16
19
  try {
17
20
  return hashContent(await promises_1.default.readFile(filePath, "utf8"));
@@ -23,7 +26,6 @@ async function readFileHash(filePath) {
23
26
  throw error;
24
27
  }
25
28
  }
26
- exports.readFileHash = readFileHash;
27
29
  function upsertGeneratedFile(registry, entry) {
28
30
  const index = registry.generatedFiles.findIndex((item) => item.path === entry.path);
29
31
  const next = {
@@ -37,7 +39,6 @@ function upsertGeneratedFile(registry, entry) {
37
39
  registry.generatedFiles.push(next);
38
40
  }
39
41
  }
40
- exports.upsertGeneratedFile = upsertGeneratedFile;
41
42
  async function assertCanWriteGeneratedFile(root, relativePath, registry, options = {}) {
42
43
  const targetPath = path_1.default.join(root, relativePath);
43
44
  const entry = registry.generatedFiles.find((item) => item.path === relativePath);
@@ -53,7 +54,6 @@ async function assertCanWriteGeneratedFile(root, relativePath, registry, options
53
54
  }
54
55
  throw new errors_1.CliError(`Refusing to overwrite modified file ${relativePath}. Use --force to overwrite or --write-new to write ${relativePath}.new.`);
55
56
  }
56
- exports.assertCanWriteGeneratedFile = assertCanWriteGeneratedFile;
57
57
  async function registerGeneratedFile(options, content, context) {
58
58
  upsertGeneratedFile(options.registry, {
59
59
  path: options.relativePath,
@@ -65,4 +65,3 @@ async function registerGeneratedFile(options, content, context) {
65
65
  context.output.info(`[dry-run] register ${options.relativePath}`);
66
66
  }
67
67
  }
68
- exports.registerGeneratedFile = registerGeneratedFile;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatCreateSummary = void 0;
3
+ exports.formatCreateSummary = formatCreateSummary;
4
4
  function formatCreateSummary(plan) {
5
5
  return [
6
6
  `Project: ${plan.name}`,
@@ -18,7 +18,6 @@ function formatCreateSummary(plan) {
18
18
  `Package manager: ${plan.packageManager}`,
19
19
  ].join("\n");
20
20
  }
21
- exports.formatCreateSummary = formatCreateSummary;
22
21
  function formatList(values) {
23
22
  return values.length > 0 ? values.join(", ") : "none";
24
23
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createNameVariants = exports.pluralize = void 0;
3
+ exports.pluralize = pluralize;
4
+ exports.createNameVariants = createNameVariants;
4
5
  const change_case_1 = require("change-case");
5
6
  function pluralize(value) {
6
7
  if (value.endsWith("s")) {
@@ -14,7 +15,6 @@ function pluralize(value) {
14
15
  }
15
16
  return `${value}s`;
16
17
  }
17
- exports.pluralize = pluralize;
18
18
  function createNameVariants(name) {
19
19
  const kebabName = (0, change_case_1.paramCase)(name);
20
20
  return {
@@ -27,4 +27,3 @@ function createNameVariants(name) {
27
27
  pluralName: pluralize(kebabName),
28
28
  };
29
29
  }
30
- exports.createNameVariants = createNameVariants;
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.renderTemplate = void 0;
3
+ exports.renderTemplate = renderTemplate;
4
4
  function renderTemplate(template, values) {
5
5
  return template.replace(/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g, (_, key) => {
6
6
  const value = values[key];
7
7
  return value === undefined ? "" : String(value);
8
8
  });
9
9
  }
10
- exports.renderTemplate = renderTemplate;
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveTemplate = exports.registerTemplate = void 0;
3
+ exports.registerTemplate = registerTemplate;
4
+ exports.resolveTemplate = resolveTemplate;
4
5
  const errors_1 = require("../core/errors");
5
6
  const templates = new Map();
6
7
  function registerTemplate(name, content) {
7
8
  templates.set(name, content);
8
9
  }
9
- exports.registerTemplate = registerTemplate;
10
10
  function resolveTemplate(name) {
11
11
  const content = templates.get(name);
12
12
  if (!content) {
@@ -14,4 +14,3 @@ function resolveTemplate(name) {
14
14
  }
15
15
  return content;
16
16
  }
17
- exports.resolveTemplate = resolveTemplate;
@@ -1,14 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.canRunInteractiveMode = exports.getTerminalCapabilities = void 0;
3
+ exports.getTerminalCapabilities = getTerminalCapabilities;
4
+ exports.canRunInteractiveMode = canRunInteractiveMode;
4
5
  function getTerminalCapabilities() {
5
6
  return {
6
7
  stdinIsTty: Boolean(process.stdin.isTTY),
7
8
  stdoutIsTty: Boolean(process.stdout.isTTY),
8
9
  };
9
10
  }
10
- exports.getTerminalCapabilities = getTerminalCapabilities;
11
11
  function canRunInteractiveMode(capabilities = getTerminalCapabilities()) {
12
12
  return capabilities.stdinIsTty && capabilities.stdoutIsTty;
13
13
  }
14
- exports.canRunInteractiveMode = canRunInteractiveMode;
@@ -28,7 +28,7 @@ Prompts cover the supported MVP capabilities:
28
28
  - auth
29
29
  - messaging
30
30
  - realtime
31
- - telemetry
31
+ - telemetry (`logs`, `otel-noop`, `metrics`, `memory`)
32
32
  - OpenAPI docs
33
33
  - contracts
34
34
  - Bruno API client
@@ -67,6 +67,9 @@ In interactive mode, preset values become prompt defaults. Explicit CLI flags st
67
67
 
68
68
  - Only `express` is currently supported.
69
69
  - `--contracts zod` enables generated contracts backed by Zod.
70
+ - Auth projects use `@soapjs/soap-auth` 1.x recipe configs and the `@soapjs/soap-express/auth` router/middleware helpers.
71
+ - Security defaults are generated through soap-express security config. Auth projects include route-specific throttling for login, refresh, and OAuth callbacks.
72
+ - `--telemetry metrics` exposes `/metrics`; `--telemetry memory` exposes `/memory`. Minimal projects keep these monitoring endpoints disabled.
70
73
  - Database capabilities include `mongo`, `postgres`, `mysql`, `sqlite`, and `redis`. Resource repositories are generated for Mongo and SQL adapters; Redis is infrastructure-only for now.
71
74
  - `--install` runs the selected package manager after files are written. `--skip-install` always skips installation.
72
75
  - `--git-init` runs `git init` after files are written. It does not commit or push.
@@ -1,6 +1,7 @@
1
1
  # Guide: Auth And Route Policies
2
2
 
3
3
  SoapJS CLI supports project-level auth capabilities and route-level policies.
4
+ Generated auth bootstrap is based on `@soapjs/soap-auth` 1.x recipe configs and `@soapjs/soap-express/auth` helpers. The CLI registers `SoapAuth.create(...)` with the Express app and exposes generated auth routes through `createAuthRouter(...)`.
4
5
 
5
6
  ## Enable Auth
6
7
 
@@ -25,6 +26,14 @@ Supported auth capabilities:
25
26
 
26
27
  For routes, `local` is normalized to `jwt`.
27
28
 
29
+ JWT projects include a local development login strategy so `/auth/login` can issue JWT access and refresh tokens. API key projects use `createApiKeyAuthConfig(...)` with a development `retrieveUserByApiKey` implementation. Generated `.env.example` includes `JWT_ACCESS_SECRET`, `JWT_REFRESH_SECRET`, and API key variables when relevant.
30
+
31
+ Auth projects also enable route-specific throttling for:
32
+
33
+ - `POST /auth/login`
34
+ - `POST /auth/refresh`
35
+ - `GET /auth/oauth/:provider/callback`
36
+
28
37
  ## Add Protected CRUD Routes
29
38
 
30
39
  ```bash
@@ -87,4 +96,3 @@ soap check routes
87
96
  ```
88
97
 
89
98
  This checks unknown auth strategies, disabled auth capabilities, invalid zones, policy-without-auth, contracts, and Bruno files.
90
-
@@ -4,6 +4,7 @@ Use these guides when building a service with SoapJS CLI.
4
4
 
5
5
  SoapJS CLI and generated projects require Node.js `>=24.17.0` (Node 24 LTS or newer).
6
6
  Generated projects include `.nvmrc` with `24.17.0`.
7
+ Generated auth projects use `@soapjs/soap-auth` 1.x with the soap-express auth router and middleware helpers. Security defaults are emitted through soap-express security config, and metrics/memory endpoints are opt-in telemetry capabilities.
7
8
 
8
9
  ## Start Here
9
10
 
@@ -0,0 +1,30 @@
1
+ # Kafka Adapter 1.0 Update
2
+
3
+ This checklist tracks the changes needed in `soap-cli` after the Kafka adapter release as `@soapjs/soap-kafka@1.0.0`.
4
+
5
+ ## Required Changes
6
+
7
+ - Replace generated Kafka dependency:
8
+ - from `@soapjs/soap-node-kafka: ^0.1.3`
9
+ - to `@soapjs/soap-kafka: ^1.0.0`
10
+ - file: `src/dependencies/dependency-resolver.ts`
11
+
12
+ - Replace generated Kafka imports:
13
+ - from `@soapjs/soap-node-kafka`
14
+ - to `@soapjs/soap-kafka`
15
+ - file: `src/commands/create/project-plan.ts`
16
+
17
+ - Verify generated project templates still compile when `messaging.kafka` is selected:
18
+ - generated `src/common/events/kafka/kafka.client.ts`
19
+ - generated `src/common/events/kafka/kafka-event-bus.ts`
20
+ - generated `package.json`
21
+
22
+ ## Compatibility Notes
23
+
24
+ - `KafkaEventBus` and `KafkaDomainEventBus` are still exported by the new package.
25
+ - The adapter peer dependency is now `@soapjs/soap@^0.14.0`.
26
+ - If CLI templates ever generate `EventProcessor` options with a custom strategy, use `processingStrategy`, not the old `strategy` property.
27
+
28
+ ## Out Of Scope
29
+
30
+ - `test-cli/*` fixtures can be ignored for this migration unless they are intentionally refreshed later.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soapjs/cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Deterministic project and code generator for SoapJS services.",
5
5
  "homepage": "https://docs.soapjs.com",
6
6
  "repository": "https://github.com/soapjs/soap-cli",
@@ -33,12 +33,12 @@
33
33
  "prepublish": "npm run clean && tsc --project tsconfig.build.json"
34
34
  },
35
35
  "dependencies": {
36
- "@inquirer/prompts": "^3.3.2",
36
+ "@inquirer/prompts": "^8.5.2",
37
37
  "change-case": "^4.1.2",
38
38
  "commander": "^10.0.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "^24.0.0",
42
- "typescript": "^4.5.4"
42
+ "typescript": "^5.9.3"
43
43
  }
44
44
  }