@aventara/cli 0.1.0-pilot.0 → 0.1.0-pilot.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 (46) hide show
  1. package/README.md +39 -7
  2. package/dist/apply/app-module.anchor.d.ts +5 -11
  3. package/dist/apply/app-module.anchor.js +0 -23
  4. package/dist/apply/conflict.confirmer.d.ts +0 -9
  5. package/dist/apply/conflict.confirmer.js +0 -15
  6. package/dist/apply/e2e-spec.anchor.d.ts +18 -0
  7. package/dist/apply/e2e-spec.anchor.js +23 -0
  8. package/dist/apply/manifest.merger.d.ts +11 -13
  9. package/dist/apply/manifest.merger.js +0 -18
  10. package/dist/aventara.bin.js +0 -10
  11. package/dist/catalog/adapter.catalog.generated.js +0 -4
  12. package/dist/catalog/catalog-entry.interface.d.ts +16 -13
  13. package/dist/catalog/catalog.matcher.d.ts +7 -13
  14. package/dist/catalog/catalog.matcher.js +0 -3
  15. package/dist/catalog/range.reader.d.ts +4 -10
  16. package/dist/catalog/range.reader.js +0 -14
  17. package/dist/cli.d.ts +2 -3
  18. package/dist/cli.js +2 -8
  19. package/dist/command/command.parser.d.ts +13 -8
  20. package/dist/command/command.parser.js +30 -10
  21. package/dist/node-version.guard.js +0 -12
  22. package/dist/plan/project.planner.d.ts +15 -14
  23. package/dist/plan/project.planner.js +22 -25
  24. package/dist/project/package-manager.detector.d.ts +0 -7
  25. package/dist/project/package-manager.detector.js +0 -7
  26. package/dist/project/project.inspector.d.ts +3 -9
  27. package/dist/project/project.inspector.js +0 -10
  28. package/dist/project/service.detector.d.ts +5 -10
  29. package/dist/project/service.detector.js +0 -2
  30. package/dist/project/source.scanner.js +0 -13
  31. package/dist/run/command.runner.d.ts +4 -4
  32. package/dist/run/init.orchestrator.d.ts +4 -6
  33. package/dist/run/init.orchestrator.js +1 -12
  34. package/dist/run/new.orchestrator.d.ts +6 -9
  35. package/dist/run/new.orchestrator.js +0 -16
  36. package/dist/templates/prisma7/prisma7.templates.d.ts +1 -1
  37. package/dist/templates/prisma7/prisma7.templates.js +2 -28
  38. package/dist/templates/template.registry.d.ts +18 -17
  39. package/dist/templates/template.registry.js +1 -1
  40. package/dist/wizard/answer.resolver.d.ts +5 -7
  41. package/dist/wizard/answer.resolver.js +0 -10
  42. package/dist/wizard/readline.prompter.d.ts +5 -7
  43. package/dist/wizard/readline.prompter.js +0 -10
  44. package/dist/wizard/wizard.questions.d.ts +16 -23
  45. package/dist/wizard/wizard.questions.js +0 -29
  46. package/package.json +2 -2
@@ -1,21 +1,9 @@
1
1
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { lowestVersionOf } from "../../catalog/range.reader.js";
4
- /**
5
- * The `prisma7` entry's templates (D7): Prisma 7 knowledge as text the CLI
6
- * writes and reads, keyed by the providers `@aventara/prisma7-adapter`
7
- * declares. Every value that is an adapter fact — the ORM package, the driver
8
- * per provider, the generator, the generate bin, the version floor — is read
9
- * from the catalog entry handed in, not restated here.
10
- *
11
- * The texts follow the Nest scaffold's formatting (prettier, `singleQuote`,
12
- * `trailingComma: "all"`, B1), so the project's own `format` script leaves them
13
- * as they are.
14
- */
15
- /** The generated client goes under `src`, where `nest build` compiles it (B6). */
4
+ import { SCAFFOLD_ENTRYPOINT, } from "../template.registry.js";
16
5
  const CLIENT_OUTPUT = "src/generated/prisma";
17
6
  const SCHEMA = "prisma/schema.prisma";
18
- /** B5: the Prisma CLI loads either name, and `prisma7.config.ts` wins when both exist. */
19
7
  const CONFIG_FILES = ["prisma7.config.ts", "prisma.config.ts"];
20
8
  const DRIVER_PREFIX = "@prisma/adapter-";
21
9
  const NEW_SERVICE = {
@@ -32,19 +20,16 @@ const PROVIDERS = {
32
20
  driverOptions: "{ url }",
33
21
  databaseUrl: "file:./dev.db",
34
22
  gitignore: ["/dev.db*"],
35
- // B9: pnpm 12 refuses these install scripts until they are allowed.
36
23
  nativeBuilds: ["@prisma/engines", "better-sqlite3", "prisma"],
37
24
  },
38
25
  postgresql: {
39
26
  driverClass: "PrismaPg",
40
27
  driverOptions: "{ connectionString: url }",
41
- // `prisma init`'s own placeholder (B5); printed in the next steps, never asked (Q16-8).
42
28
  databaseUrl: "postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public",
43
29
  gitignore: [],
44
30
  nativeBuilds: ["@prisma/engines", "prisma"],
45
31
  },
46
32
  };
47
- /** A relative import specifier from `from` (a project file) to `to` (a project path, no extension). */
48
33
  function specifier(from, to, js) {
49
34
  const relative = path.posix.relative(path.posix.dirname(from), to);
50
35
  return `${relative.startsWith(".") ? relative : `./${relative}`}${js}`;
@@ -61,7 +46,6 @@ function schema(input) {
61
46
  ` provider = "${input.provider}"`,
62
47
  "}",
63
48
  "",
64
- // R12: Prisma's `--with-model` starter (B5).
65
49
  "model User {",
66
50
  " id Int @id @default(autoincrement())",
67
51
  " email String @unique",
@@ -70,7 +54,6 @@ function schema(input) {
70
54
  "",
71
55
  ].join("\n");
72
56
  }
73
- /** `prisma.config.ts` (Q16-19). Prisma does not load `.env` itself (B5). */
74
57
  function prismaConfig() {
75
58
  return [
76
59
  "import { existsSync } from 'node:fs';",
@@ -93,7 +76,6 @@ function prismaConfig() {
93
76
  "",
94
77
  ].join("\n");
95
78
  }
96
- /** The developer-owned service (P2: `extends PrismaClient`, so `client: prisma`). */
97
79
  function prismaService(input) {
98
80
  const provider = PROVIDERS[input.provider];
99
81
  const driver = input.entry.drivers[input.provider];
@@ -125,7 +107,6 @@ function prismaService(input) {
125
107
  "",
126
108
  ].join("\n");
127
109
  }
128
- /** `src/aventara.config.ts` (R8, Q16-17): the framework's configuration. */
129
110
  function aventaraConfig(input) {
130
111
  const file = "src/aventara.config.ts";
131
112
  const service = input.service.exportName;
@@ -141,7 +122,7 @@ function aventaraConfig(input) {
141
122
  " */",
142
123
  `export async function aventaraConfig(prisma: ${service}) {`,
143
124
  " return {",
144
- " entrypoint: '/api',",
125
+ ` entrypoint: '${SCAFFOLD_ENTRYPOINT}',`,
145
126
  " adapter: await createPrismaAdapter({",
146
127
  input.service.clientMember === undefined
147
128
  ? " client: prisma,"
@@ -221,7 +202,6 @@ function scaffold(input) {
221
202
  ],
222
203
  env: { DATABASE_URL: provider.databaseUrl },
223
204
  gitignore: ["/src/generated/", ...provider.gitignore],
224
- // D1, D9: exactly the version floor the adapter declares; never bare `prisma`.
225
205
  dependencies: { [input.entry.orm.package]: floor, [driver]: floor },
226
206
  devDependencies: { prisma: floor },
227
207
  prepare: prepare({
@@ -269,7 +249,6 @@ function reuse(input) {
269
249
  }),
270
250
  },
271
251
  ],
272
- // R6: the developer's Prisma files, `.env` key and versions are theirs.
273
252
  env: {},
274
253
  gitignore: [`/${path.posix.dirname(input.artifact)}/`],
275
254
  dependencies: {},
@@ -286,9 +265,6 @@ function reuse(input) {
286
265
  nextSteps: [],
287
266
  };
288
267
  }
289
- /* ------------------------------------------------------------------ *
290
- * Reading an existing Prisma 7 setup (R6) *
291
- * ------------------------------------------------------------------ */
292
268
  function schemaLocation(directory, manifest) {
293
269
  for (const config of CONFIG_FILES) {
294
270
  const file = path.join(directory, config);
@@ -304,7 +280,6 @@ function schemaLocation(directory, manifest) {
304
280
  ? path.posix.normalize(prisma.schema)
305
281
  : SCHEMA;
306
282
  }
307
- /** The `.prisma` files of a schema path: the file, or every file in a schema folder. */
308
283
  function schemaFiles(directory, schemaPath) {
309
284
  const full = path.join(directory, schemaPath);
310
285
  if (!existsSync(full)) {
@@ -342,7 +317,6 @@ function readProject(directory, manifest) {
342
317
  for (const block of blocks(text, "generator")) {
343
318
  const declared = setting(block, "provider");
344
319
  const output = setting(block, "output");
345
- // The client generator, not a second generator (a zod or docs one) beside it.
346
320
  if (generator === undefined || /^prisma-client/.test(declared ?? "")) {
347
321
  generator = declared;
348
322
  clientOutput =
@@ -3,14 +3,11 @@ import type { CatalogEntry, EntryId, ProviderOf } from "../catalog/catalog-entry
3
3
  import type { ClientShape, ExportReference } from "../project/service.detector.js";
4
4
  import type { PackageManager } from "../wizard/wizard.questions.js";
5
5
  /**
6
- * D7 — what the CLI writes for an ORM lives here as text, keyed by catalog id;
7
- * the adapter itself runs only through its bin.
8
- *
9
6
  * The registry is **total** in both directions, and both are checked before a
10
7
  * project is ever scaffolded:
11
- * - at compile time, over the generated catalog's literal type: an entry with
12
- * no template set, or a template set missing a provider its adapter declares,
13
- * does not type-check;
8
+ * - at compile time, over the generated catalog's literal type: an entry with no
9
+ * template set, or a template set missing a provider its adapter declares, does
10
+ * not type-check;
14
11
  * - at build time, by the catalog generator: a templates directory with no
15
12
  * adapter, or an adapter with no templates directory, fails the build.
16
13
  */
@@ -20,14 +17,19 @@ export type ProviderTemplate = {
20
17
  readonly driverClass: string;
21
18
  /** The driver class's constructor argument, given the connection string as `url`. */
22
19
  readonly driverOptions: string;
23
- /** The `DATABASE_URL` line's value; a placeholder where it cannot be known (Q16-8). */
20
+ /** The `DATABASE_URL` line's value; a placeholder where it cannot be known. */
24
21
  readonly databaseUrl: string;
25
22
  /** `.gitignore` lines this provider's files need (a SQLite database file). */
26
23
  readonly gitignore: readonly string[];
27
- /** Packages whose install scripts pnpm must be allowed to run (B9). */
24
+ /** Packages whose install scripts pnpm must be allowed to run. */
28
25
  readonly nativeBuilds: readonly string[];
29
26
  };
30
27
  export type ModuleKind = "esm" | "cjs";
28
+ /**
29
+ * The entrypoint every scaffold mounts the protocol at: written into
30
+ * `src/aventara.config.ts`, and tested by the e2e spec (pilot.1).
31
+ */
32
+ export declare const SCAFFOLD_ENTRYPOINT = "/api";
31
33
  /** What a template set is asked to scaffold. */
32
34
  export type ScaffoldInput = {
33
35
  readonly entry: CatalogEntry;
@@ -43,7 +45,7 @@ export type ScaffoldInput = {
43
45
  * `aventara:prepare` and `postinstall` script names) is the planner's.
44
46
  */
45
47
  export type OrmScaffold = {
46
- /** New, developer-owned files (§4.3). */
48
+ /** New, developer-owned files. */
47
49
  readonly files: readonly {
48
50
  readonly path: string;
49
51
  readonly content: string;
@@ -53,7 +55,7 @@ export type OrmScaffold = {
53
55
  readonly gitignore: readonly string[];
54
56
  readonly dependencies: Readonly<Record<string, string>>;
55
57
  readonly devDependencies: Readonly<Record<string, string>>;
56
- /** The command `aventara:prepare` runs (D7: the adapter only through its bin). */
58
+ /** The command `aventara:prepare` runs. */
57
59
  readonly prepare: string;
58
60
  /** What the anchored `app.module.ts` edit adds: import lines, and `imports:` entries. */
59
61
  readonly appModule: {
@@ -61,13 +63,13 @@ export type OrmScaffold = {
61
63
  readonly entries: readonly string[];
62
64
  };
63
65
  readonly nativeBuilds: readonly string[];
64
- /** The ORM's next steps, after the install and before the server starts (R11). */
66
+ /** The ORM's next steps, after the install and before the server starts. */
65
67
  readonly nextSteps: readonly string[];
66
68
  };
67
69
  /**
68
- * What a project's existing ORM setup states, read by the entry's templates
69
- * (R6) — the ORM's own file layout is template knowledge (D7); judging it
70
- * against the catalog is the matcher's (`catalog.matcher.ts`).
70
+ * What a project's existing ORM setup states, read by the entry's templates — the
71
+ * ORM's own file layout is template knowledge; judging it against the catalog is
72
+ * the matcher's (`catalog.matcher.ts`).
71
73
  */
72
74
  export type OrmProjectFacts = {
73
75
  /** The schema the generate step reads, relative to the project root. */
@@ -79,7 +81,7 @@ export type OrmProjectFacts = {
79
81
  /** The driver-adapter packages the project depends on. */
80
82
  readonly drivers: readonly string[];
81
83
  };
82
- /** Reusing a project's ORM setup (R6): its schema, its output, its service. */
84
+ /** Reusing a project's ORM setup: its schema, its output, its service. */
83
85
  export type ReuseInput = {
84
86
  readonly entry: CatalogEntry;
85
87
  readonly facts: OrmProjectFacts & {
@@ -102,7 +104,6 @@ export type TemplateSet<I extends EntryId> = {
102
104
  readonly providers: {
103
105
  readonly [P in ProviderOf<I>]: ProviderTemplate;
104
106
  };
105
- /** A project with no ORM: everything §4.3 lists. */
106
107
  readonly scaffold: (input: ScaffoldInput) => OrmScaffold;
107
108
  /** Reads an existing setup's facts; `undefined` when there is none to read. */
108
109
  readonly readProject: (directory: string, manifest: PackageManifest) => OrmProjectFacts;
@@ -113,7 +114,7 @@ export type TemplateSet<I extends EntryId> = {
113
114
  readonly service: ExportReference;
114
115
  readonly module: ExportReference;
115
116
  };
116
- /** A project with the ORM already set up: no ORM file written or edited (R6). */
117
+ /** A project with the ORM already set up: no ORM file written or edited. */
117
118
  readonly reuse: (input: ReuseInput) => OrmScaffold;
118
119
  };
119
120
  export type TemplateRegistry = {
@@ -1,8 +1,8 @@
1
1
  import { PRISMA7_TEMPLATES } from "./prisma7/prisma7.templates.js";
2
+ export const SCAFFOLD_ENTRYPOINT = "/api";
2
3
  export const TEMPLATE_REGISTRY = {
3
4
  prisma7: PRISMA7_TEMPLATES,
4
5
  };
5
- /** The template set for `entry` — every catalog entry has one (checked at build). */
6
6
  export function templatesFor(entry) {
7
7
  const set = TEMPLATE_REGISTRY[entry.id];
8
8
  if (set === undefined) {
@@ -1,26 +1,24 @@
1
1
  import type { AnyWizardQuestion, QuestionId, WizardAnswers, WizardContext } from "./wizard.questions.js";
2
2
  /**
3
- * R5 — how each question gets its answer, in this order:
4
- *
5
3
  * 1. **its flag**, validated by the question (a bad value is refused, never
6
4
  * re-asked);
7
- * 2. **the only choice there is** (N3): shown on a terminal with no keypress;
5
+ * 2. **the only choice there is**: shown on a terminal with no keypress;
8
6
  * 3. **`--yes`**: the question's default, when it has one;
9
7
  * 4. **the prompt**, when someone can answer (stdin is a terminal);
10
8
  * 5. otherwise the question is **unanswered**, and once every question has been
11
9
  * tried the run refuses in one sentence naming exactly those flags.
12
10
  *
13
11
  * `--yes` comes before the prompt because it means "accept each unanswered
14
- * question's default" (R5 + R2), on a terminal as much as anywhere; a question
15
- * with no default (`new`'s `<name>`) is still asked on a terminal.
12
+ * question's default", on a terminal as much as anywhere; a question with no
13
+ * default (`new`'s `<name>`) is still asked on a terminal.
16
14
  */
17
- /** The seam to a person (B26): `node:readline/promises` on a terminal, a script in specs. */
15
+ /** The seam to a person: `node:readline/promises` on a terminal, a script in specs. */
18
16
  export type Prompter = {
19
17
  /** Whether someone can answer: stdin is a terminal. */
20
18
  readonly interactive: boolean;
21
19
  /** Asks once; resolves with what was typed, `""` for Enter alone. */
22
20
  readonly ask: (request: PromptRequest) => Promise<string>;
23
- /** Says one line without asking (N3, and why an answer was not accepted). */
21
+ /** Says one line without asking. */
24
22
  readonly say: (line: string) => void;
25
23
  };
26
24
  export type PromptRequest = {
@@ -1,9 +1,7 @@
1
1
  import { WizardAnswerError } from "./wizard.questions.js";
2
- /** Nobody can answer and some questions are unanswered. A refusal: one sentence. */
3
2
  export class UnansweredQuestionsError extends Error {
4
3
  name = "UnansweredQuestionsError";
5
4
  }
6
- /** `--db <sqlite|postgresql>`, or `<name>` for the positional. */
7
5
  function flagSpelling(question, context) {
8
6
  if (!question.flag.startsWith("--")) {
9
7
  return question.flag;
@@ -18,7 +16,6 @@ function listed(items) {
18
16
  ? items.join("")
19
17
  : `${items.slice(0, -1).join(", ")} and ${items[items.length - 1]}`;
20
18
  }
21
- /** The refusal sentence: the unanswered flags, exactly, and `--yes` for those with a default. */
22
19
  function unansweredSentence(missing, yes) {
23
20
  const defaulted = missing.filter((item) => item.defaulted);
24
21
  const yesClause = !yes && defaulted.length > 0
@@ -51,12 +48,6 @@ async function prompt(question, context, prompter) {
51
48
  }
52
49
  }
53
50
  }
54
- /**
55
- * Settles `questions` in order, each later question seeing the earlier answers.
56
- *
57
- * @throws WizardAnswerError when a flag's value is not an answer.
58
- * @throws UnansweredQuestionsError when nobody can answer and something is unanswered.
59
- */
60
51
  export async function resolveAnswers(questions, sources) {
61
52
  const answered = {};
62
53
  const missing = [];
@@ -65,7 +56,6 @@ export async function resolveAnswers(questions, sources) {
65
56
  ...sources.context,
66
57
  answered: answered,
67
58
  };
68
- // A question that depends on one left unanswered cannot be asked yet.
69
59
  if (question.after !== undefined &&
70
60
  answered[question.after] === undefined) {
71
61
  missing.push({ spelling: question.flag, defaulted: false });
@@ -1,13 +1,11 @@
1
1
  import type { Readable, Writable } from "node:stream";
2
2
  import type { Prompter } from "./answer.resolver.js";
3
3
  /**
4
- * P6, B26 — the {@link Prompter} over `node:readline`: no prompt dependency.
5
- *
6
- * Lines are **queued** as they arrive and handed to questions in order. A
7
- * terminal delivers whatever was typed ahead of a question — and a script piping
8
- * answers into a pseudo-terminal delivers them all at once — and readline drops
9
- * a line nobody is waiting for. Measured: with `readline/promises`' `question`,
10
- * three answers piped into `script(1)` reached the first question only.
4
+ * Lines are **queued** as they arrive and handed to questions in order. A terminal
5
+ * delivers whatever was typed ahead of a question — and a script piping answers
6
+ * into a pseudo-terminal delivers them all at once — and readline drops a line
7
+ * nobody is waiting for. Measured: with `readline/promises`' `question`, three
8
+ * answers piped into `script(1)` reached the first question only.
11
9
  */
12
10
  /** Input ended while a question was open: the person closed the wizard. A refusal. */
13
11
  export declare class WizardCancelledError extends Error {
@@ -1,14 +1,4 @@
1
1
  import { createInterface } from "node:readline";
2
- /**
3
- * P6, B26 — the {@link Prompter} over `node:readline`: no prompt dependency.
4
- *
5
- * Lines are **queued** as they arrive and handed to questions in order. A
6
- * terminal delivers whatever was typed ahead of a question — and a script piping
7
- * answers into a pseudo-terminal delivers them all at once — and readline drops
8
- * a line nobody is waiting for. Measured: with `readline/promises`' `question`,
9
- * three answers piped into `script(1)` reached the first question only.
10
- */
11
- /** Input ended while a question was open: the person closed the wizard. A refusal. */
12
2
  export class WizardCancelledError extends Error {
13
3
  name = "WizardCancelledError";
14
4
  }
@@ -1,29 +1,27 @@
1
1
  import type { AdapterCatalog, CatalogEntry } from "../catalog/catalog-entry.interface.js";
2
2
  import { type ExportReference, type ServiceScan } from "../project/service.detector.js";
3
3
  /**
4
- * R5 — every question the two commands ask, in **one table**: its flag, its
5
- * label, its choices and its default. The command-line grammar, the TTY prompt,
6
- * the `--yes` defaults and the non-interactive refusal sentence are all derived
7
- * from it, so a question cannot have a flag the parser does not know or a
8
- * default the refusal does not mention.
4
+ * The command-line grammar, the TTY prompt, the `--yes` defaults and the
5
+ * non-interactive refusal sentence are all derived from it, so a question cannot
6
+ * have a flag the parser does not know or a default the refusal does not mention.
9
7
  *
10
8
  * Choices that are an adapter's facts — which ORMs and majors exist, which
11
- * databases one supports — come from the generated catalog (R14), never from a
12
- * literal here.
9
+ * databases one supports — come from the generated catalog, never from a literal
10
+ * here.
13
11
  */
14
- /** Q16-5 (a). Yarn is not supported (U1). */
12
+ /** Yarn is not supported. */
15
13
  export declare const PACKAGE_MANAGERS: readonly ["npm", "pnpm"];
16
14
  export type PackageManager = (typeof PACKAGE_MANAGERS)[number];
17
15
  /** What the wizard settles. */
18
16
  export type WizardAnswers = {
19
- /** `new`'s project directory (Q16-3). */
17
+ /** `new`'s project directory. */
20
18
  readonly name: string;
21
- /** The ORM and major, as the catalog entry that serves it (R14). */
19
+ /** The ORM and major, as the catalog entry that serves it. */
22
20
  readonly orm: CatalogEntry;
23
- /** One of `orm`'s providers (R10). */
21
+ /** One of `orm`'s providers. */
24
22
  readonly db: string;
25
23
  readonly packageManager: PackageManager;
26
- /** `init` over an existing ORM setup: the developer's service (R6). */
24
+ /** `init` over an existing ORM setup: the developer's service. */
27
25
  readonly service: ServiceChoice;
28
26
  /** The Nest module that provides and exports it. */
29
27
  readonly module: ExportReference;
@@ -36,7 +34,7 @@ export type ServiceChoice = ExportReference & {
36
34
  readonly isNew: boolean;
37
35
  };
38
36
  export type QuestionId = keyof WizardAnswers;
39
- /** What the scan of the developer's source found, for the service questions (R6). */
37
+ /** What the scan of the developer's source found, for the service questions. */
40
38
  export type ServiceContext = {
41
39
  readonly scan: ServiceScan;
42
40
  /** The ORM's client class, as the scan looked for it. */
@@ -52,7 +50,6 @@ export type ServiceContext = {
52
50
  /** What a question may consult: the catalog, what was detected, what is already answered. */
53
51
  export type WizardContext = {
54
52
  readonly catalog: AdapterCatalog;
55
- /** Q16-5's default: the lockfile, else the launching package manager (B11), else npm. */
56
53
  readonly detectedPackageManager: PackageManager;
57
54
  readonly answered: Partial<WizardAnswers>;
58
55
  /** Present for `init` over an existing ORM setup. */
@@ -91,24 +88,20 @@ export type AnyWizardQuestion = {
91
88
  readonly [K in QuestionId]: WizardQuestion<K>;
92
89
  }[QuestionId];
93
90
  export declare const NAME_QUESTION: WizardQuestion<"name">;
94
- /**
95
- * R14 — the ORM, from the catalog: `--orm <family>@<major>`, or `--orm <family>`
96
- * for the family's highest major (Q16-31).
97
- */
98
91
  export declare const ORM_QUESTION: WizardQuestion<"orm">;
99
- /** R10 — the database, from the chosen entry's providers; the first is the default. */
100
92
  export declare const DB_QUESTION: WizardQuestion<"db">;
101
- /** Q16-5 — npm or pnpm; the default is detected. */
102
93
  export declare const PACKAGE_MANAGER_QUESTION: WizardQuestion<"packageManager">;
103
- /** R6, Q16-11 — the developer's service; a new one is written only when there is none. */
104
94
  export declare const SERVICE_QUESTION: WizardQuestion<"service">;
105
95
  /** The module that provides and exports the chosen service (or is @Global). */
106
96
  export declare const MODULE_QUESTION: WizardQuestion<"module">;
107
97
  /** `aventara new`'s questions, in the order they are asked. */
108
98
  export declare const NEW_QUESTIONS: readonly [WizardQuestion<"name">, WizardQuestion<"orm">, WizardQuestion<"db">, WizardQuestion<"packageManager">];
109
- /** `aventara init`'s questions when the project has no ORM (S6), in order. */
99
+ /** `aventara init`'s questions when the project has no ORM, in order. */
110
100
  export declare const INIT_QUESTIONS: readonly [WizardQuestion<"orm">, WizardQuestion<"db">, WizardQuestion<"packageManager">];
111
- /** `aventara init`'s questions over an existing ORM setup (S7): the ORM and database are read, not asked. */
101
+ /**
102
+ * `aventara init`'s questions over an existing ORM setup: the ORM and database are
103
+ * read, not asked.
104
+ */
112
105
  export declare const REUSE_QUESTIONS: readonly [WizardQuestion<"service">, WizardQuestion<"module">, WizardQuestion<"packageManager">];
113
106
  /** Every flag `aventara init` takes for a question, either way. */
114
107
  export declare const INIT_FLAG_QUESTIONS: readonly [WizardQuestion<"orm">, WizardQuestion<"db">, WizardQuestion<"service">, WizardQuestion<"module">, WizardQuestion<"packageManager">];
@@ -1,18 +1,5 @@
1
1
  import { modulesProviding, } from "../project/service.detector.js";
2
- /**
3
- * R5 — every question the two commands ask, in **one table**: its flag, its
4
- * label, its choices and its default. The command-line grammar, the TTY prompt,
5
- * the `--yes` defaults and the non-interactive refusal sentence are all derived
6
- * from it, so a question cannot have a flag the parser does not know or a
7
- * default the refusal does not mention.
8
- *
9
- * Choices that are an adapter's facts — which ORMs and majors exist, which
10
- * databases one supports — come from the generated catalog (R14), never from a
11
- * literal here.
12
- */
13
- /** Q16-5 (a). Yarn is not supported (U1). */
14
2
  export const PACKAGE_MANAGERS = ["npm", "pnpm"];
15
- /** An answer the question cannot accept. A refusal: one sentence. */
16
3
  export class WizardAnswerError extends Error {
17
4
  name = "WizardAnswerError";
18
5
  }
@@ -24,7 +11,6 @@ function available(catalog) {
24
11
  .map((entry) => `${ormLabel(entry)} (${entry.adapterPackage})`)
25
12
  .join(", ");
26
13
  }
27
- /** Ordered for the wizard: by family as the catalog lists them, majors newest first. */
28
14
  function ormChoices(catalog) {
29
15
  const families = [...new Set(catalog.map((entry) => entry.orm.family))];
30
16
  return families.flatMap((family) => catalog
@@ -47,10 +33,6 @@ export const NAME_QUESTION = {
47
33
  },
48
34
  describe: (name) => name,
49
35
  };
50
- /**
51
- * R14 — the ORM, from the catalog: `--orm <family>@<major>`, or `--orm <family>`
52
- * for the family's highest major (Q16-31).
53
- */
54
36
  export const ORM_QUESTION = {
55
37
  id: "orm",
56
38
  flag: "--orm",
@@ -86,7 +68,6 @@ function requireOrm(context) {
86
68
  }
87
69
  return orm;
88
70
  }
89
- /** R10 — the database, from the chosen entry's providers; the first is the default. */
90
71
  export const DB_QUESTION = {
91
72
  id: "db",
92
73
  flag: "--db",
@@ -107,7 +88,6 @@ export const DB_QUESTION = {
107
88
  },
108
89
  describe: (db) => db,
109
90
  };
110
- /** Q16-5 — npm or pnpm; the default is detected. */
111
91
  export const PACKAGE_MANAGER_QUESTION = {
112
92
  id: "packageManager",
113
93
  flag: "--package-manager",
@@ -139,7 +119,6 @@ function requireServices(context) {
139
119
  }
140
120
  return context.services;
141
121
  }
142
- /** The services on offer: what the scan found, or — when it found none — the template's new file. */
143
122
  function serviceOptions(services) {
144
123
  const found = [
145
124
  ...services.scan.candidates.map((candidate) => ({
@@ -156,14 +135,11 @@ function serviceOptions(services) {
156
135
  ? found
157
136
  : [{ ...services.newService, isNew: true }];
158
137
  }
159
- /** R6, Q16-11 — the developer's service; a new one is written only when there is none. */
160
138
  export const SERVICE_QUESTION = {
161
139
  id: "service",
162
140
  flag: "--prisma-service",
163
141
  placeholder: "<path#Export>",
164
142
  label: "Service to give Aventara (file#Export)",
165
- // With no service found, the offer to write one is a question with a default
166
- // (asked on a terminal, taken by --yes), not a single choice taken silently.
167
143
  choices: (context) => {
168
144
  const options = serviceOptions(requireServices(context));
169
145
  return options.every((option) => option.isNew)
@@ -198,7 +174,6 @@ export const SERVICE_QUESTION = {
198
174
  },
199
175
  describe: spelled,
200
176
  };
201
- /** The module that provides and exports the chosen service (or is @Global). */
202
177
  export const MODULE_QUESTION = {
203
178
  id: "module",
204
179
  flag: "--prisma-module",
@@ -232,26 +207,22 @@ export const MODULE_QUESTION = {
232
207
  },
233
208
  describe: spelled,
234
209
  };
235
- /** `aventara new`'s questions, in the order they are asked. */
236
210
  export const NEW_QUESTIONS = [
237
211
  NAME_QUESTION,
238
212
  ORM_QUESTION,
239
213
  DB_QUESTION,
240
214
  PACKAGE_MANAGER_QUESTION,
241
215
  ];
242
- /** `aventara init`'s questions when the project has no ORM (S6), in order. */
243
216
  export const INIT_QUESTIONS = [
244
217
  ORM_QUESTION,
245
218
  DB_QUESTION,
246
219
  PACKAGE_MANAGER_QUESTION,
247
220
  ];
248
- /** `aventara init`'s questions over an existing ORM setup (S7): the ORM and database are read, not asked. */
249
221
  export const REUSE_QUESTIONS = [
250
222
  SERVICE_QUESTION,
251
223
  MODULE_QUESTION,
252
224
  PACKAGE_MANAGER_QUESTION,
253
225
  ];
254
- /** Every flag `aventara init` takes for a question, either way. */
255
226
  export const INIT_FLAG_QUESTIONS = [
256
227
  ORM_QUESTION,
257
228
  DB_QUESTION,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aventara/cli",
3
- "version": "0.1.0-pilot.0",
3
+ "version": "0.1.0-pilot.2",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "description": "Scaffolds an Aventara server: `aventara new` for a new NestJS project, `aventara init` for an existing one.",
6
6
  "type": "module",
@@ -23,7 +23,7 @@
23
23
  },
24
24
  "scripts": {
25
25
  "prebuild": "node scripts/adapter-catalog.generator.ts",
26
- "build": "tsc -p tsconfig.json",
26
+ "build": "tsc -p tsconfig.json --removeComments --declaration false && tsc -p tsconfig.json --emitDeclarationOnly && node ../../scripts/build/declaration-comments.sanitizer.ts dist",
27
27
  "typecheck": "tsc -p tsconfig.typecheck.json --noEmit",
28
28
  "test": "vitest run --typecheck --config ../../vitest.config.mts --root .",
29
29
  "lint": "biome lint src scripts"