@aventara/cli 0.1.0-pilot.1 → 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 (44) hide show
  1. package/README.md +2 -2
  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.js +0 -17
  7. package/dist/apply/manifest.merger.d.ts +11 -13
  8. package/dist/apply/manifest.merger.js +0 -18
  9. package/dist/aventara.bin.js +0 -10
  10. package/dist/catalog/adapter.catalog.generated.js +0 -4
  11. package/dist/catalog/catalog-entry.interface.d.ts +16 -13
  12. package/dist/catalog/catalog.matcher.d.ts +7 -13
  13. package/dist/catalog/catalog.matcher.js +0 -3
  14. package/dist/catalog/range.reader.d.ts +4 -10
  15. package/dist/catalog/range.reader.js +0 -14
  16. package/dist/cli.d.ts +2 -3
  17. package/dist/cli.js +0 -6
  18. package/dist/command/command.parser.d.ts +7 -7
  19. package/dist/command/command.parser.js +2 -7
  20. package/dist/node-version.guard.js +0 -12
  21. package/dist/plan/project.planner.d.ts +7 -13
  22. package/dist/plan/project.planner.js +6 -32
  23. package/dist/project/package-manager.detector.d.ts +0 -7
  24. package/dist/project/package-manager.detector.js +0 -7
  25. package/dist/project/project.inspector.d.ts +3 -9
  26. package/dist/project/project.inspector.js +0 -10
  27. package/dist/project/service.detector.d.ts +5 -10
  28. package/dist/project/service.detector.js +0 -2
  29. package/dist/project/source.scanner.js +0 -13
  30. package/dist/run/command.runner.d.ts +4 -4
  31. package/dist/run/init.orchestrator.d.ts +4 -6
  32. package/dist/run/init.orchestrator.js +1 -12
  33. package/dist/run/new.orchestrator.d.ts +6 -9
  34. package/dist/run/new.orchestrator.js +0 -16
  35. package/dist/templates/prisma7/prisma7.templates.js +0 -27
  36. package/dist/templates/template.registry.d.ts +13 -17
  37. package/dist/templates/template.registry.js +0 -5
  38. package/dist/wizard/answer.resolver.d.ts +5 -7
  39. package/dist/wizard/answer.resolver.js +0 -10
  40. package/dist/wizard/readline.prompter.d.ts +5 -7
  41. package/dist/wizard/readline.prompter.js +0 -10
  42. package/dist/wizard/wizard.questions.d.ts +16 -23
  43. package/dist/wizard/wizard.questions.js +0 -29
  44. package/package.json +2 -2
@@ -3,18 +3,12 @@ import { type ProjectInspection } from "../project/project.inspector.js";
3
3
  import { type OrmScaffold } from "../templates/template.registry.js";
4
4
  import type { PackageManager } from "../wizard/wizard.questions.js";
5
5
  /**
6
- * §4.1's `plan`: everything `aventara init` will write, decided before anything
7
- * is written — the files, the anchored `app.module.ts` edit (or the printed
8
- * instructions), the merged manifests — and every **conflict**, computed both
9
- * ways so the confirmation can choose. Pure apart from reading the files it
10
- * would replace.
11
- *
12
- * What is Nest's (its default start scripts, `AventaraModule`'s import) and what
13
- * is Aventara's (its packages at this CLI's version, D1; the `aventara:prepare`
14
- * and `postinstall` scripts, Q16-22, D2) is decided here; what is the ORM's
15
- * comes from its templates (D7).
6
+ * Pure apart from reading the files it would replace.
7
+ */
8
+ /**
9
+ * The name of the script that regenerates the ORM client and the discovery
10
+ * artifact.
16
11
  */
17
- /** The name of the script that regenerates the ORM client and the discovery artifact (Q16-22). */
18
12
  export declare const PREPARE_SCRIPT = "aventara:prepare";
19
13
  export type PlannedWrite = {
20
14
  readonly path: string;
@@ -39,12 +33,12 @@ export type PlanInput = {
39
33
  readonly entry: CatalogEntry;
40
34
  readonly scaffold: OrmScaffold;
41
35
  readonly packageManager: PackageManager;
42
- /** This CLI's version: every Aventara package is pinned to it (D1). */
36
+ /** This CLI's version: every Aventara package is pinned to it. */
43
37
  readonly aventaraVersion: string;
44
38
  readonly skipInstall: boolean;
45
39
  /** The current text of a project file, or `undefined` when absent. */
46
40
  readonly read: (file: string) => string | undefined;
47
- /** The anchored edit is not attempted; the wiring is printed (a service holding its client, §4.4.4). */
41
+ /** The anchored edit is not attempted; the wiring is printed. */
48
42
  readonly wiringByHand?: string;
49
43
  /** Said before the write, beside the planner's own. */
50
44
  readonly warnings?: readonly string[];
@@ -3,21 +3,7 @@ import { E2E_SPEC, spliceContractTest } from "../apply/e2e-spec.anchor.js";
3
3
  import { mergeEnvFile, mergeGitignore, mergePackageManifest, mergePnpmWorkspace, } from "../apply/manifest.merger.js";
4
4
  import { APP_MODULE, } from "../project/project.inspector.js";
5
5
  import { SCAFFOLD_ENTRYPOINT, } from "../templates/template.registry.js";
6
- /**
7
- * §4.1's `plan`: everything `aventara init` will write, decided before anything
8
- * is written — the files, the anchored `app.module.ts` edit (or the printed
9
- * instructions), the merged manifests — and every **conflict**, computed both
10
- * ways so the confirmation can choose. Pure apart from reading the files it
11
- * would replace.
12
- *
13
- * What is Nest's (its default start scripts, `AventaraModule`'s import) and what
14
- * is Aventara's (its packages at this CLI's version, D1; the `aventara:prepare`
15
- * and `postinstall` scripts, Q16-22, D2) is decided here; what is the ORM's
16
- * comes from its templates (D7).
17
- */
18
- /** The name of the script that regenerates the ORM client and the discovery artifact (Q16-22). */
19
6
  export const PREPARE_SCRIPT = "aventara:prepare";
20
- /** D3: `nest new`'s start scripts (B1), and what each becomes so `.env` reaches the server. */
21
7
  const START_SCRIPTS = {
22
8
  start: { from: "nest start", to: "nest start --env-file .env" },
23
9
  "start:dev": {
@@ -33,11 +19,6 @@ const START_SCRIPTS = {
33
19
  to: "node --env-file-if-exists=.env dist/main",
34
20
  },
35
21
  };
36
- /**
37
- * F-853: `nest new`'s e2e script per module kind (B1, B28), and the same run with
38
- * the `.env` the start scripts load — the e2e spec boots `AppModule`, whose
39
- * service needs `DATABASE_URL`, and neither vitest nor jest loads `.env`.
40
- */
41
22
  const E2E_SCRIPTS = {
42
23
  esm: {
43
24
  from: "vitest run --config ./vitest.config.e2e.ts",
@@ -61,12 +42,6 @@ function writeOf(path, before, after) {
61
42
  },
62
43
  ];
63
44
  }
64
- /**
65
- * pilot.1 — the frontend's first command, as the developer can run it: the
66
- * package manager's own one-off runner (`npx` or `pnpm dlx`), and — while this
67
- * CLI is a prerelease — its dist-tag, so the client comes from the same release
68
- * (`0.1.0-pilot.1` → `@aventara/client@pilot`). A release has no tag to name.
69
- */
70
45
  export function frontendInitCommand(packageManager, cliVersion) {
71
46
  const tag = /^\d+\.\d+\.\d+-([0-9A-Za-z-]+)/.exec(cliVersion)?.[1];
72
47
  const runner = packageManager === "pnpm" ? "pnpm dlx" : "npx";
@@ -87,7 +62,6 @@ export function planInit(input) {
87
62
  keeping.push(...writeOf(path, before, kept.text));
88
63
  replacing.push(...writeOf(path, before, replaced.text));
89
64
  };
90
- // The ORM's new files: identical content is no change (P3), other content a conflict.
91
65
  for (const file of scaffold.files) {
92
66
  const before = input.read(file.path);
93
67
  if (before === undefined) {
@@ -111,7 +85,6 @@ export function planInit(input) {
111
85
  });
112
86
  }
113
87
  }
114
- // The one edit to developer code (R2).
115
88
  const wiring = {
116
89
  imports: [
117
90
  `import { AventaraModule } from '${NEST_HOST}';`,
@@ -132,8 +105,6 @@ export function planInit(input) {
132
105
  if (edit.kind === "edited") {
133
106
  keeping.push(...writeOf(APP_MODULE, appModule, edit.text));
134
107
  replacing.push(...writeOf(APP_MODULE, appModule, edit.text));
135
- // pilot.1: Nest's own e2e spec also asks for the contract — only when
136
- // AventaraModule was wired in, so the test proves what it claims.
137
108
  const spec = input.read(E2E_SPEC);
138
109
  const tested = spec === undefined
139
110
  ? undefined
@@ -157,7 +128,6 @@ export function planInit(input) {
157
128
  devDependencies: scaffold.devDependencies,
158
129
  scripts: {
159
130
  [PREPARE_SCRIPT]: scaffold.prepare,
160
- // D2: the generated trees are ignored and rebuilt on every install.
161
131
  postinstall: `${packageManager} run ${PREPARE_SCRIPT}`,
162
132
  },
163
133
  rewrites: inspection.usesNestConfig
@@ -168,11 +138,15 @@ export function planInit(input) {
168
138
  },
169
139
  }, replace));
170
140
  const env = input.read(".env");
171
- if (Object.keys(scaffold.env).length > 0) {
141
+ const writesEnv = Object.keys(scaffold.env).length > 0;
142
+ if (writesEnv) {
172
143
  both(".env", env, (replace) => mergeEnvFile(env, scaffold.env, replace));
173
144
  }
174
145
  const gitignore = input.read(".gitignore");
175
- both(".gitignore", gitignore, () => mergeGitignore(gitignore, scaffold.gitignore));
146
+ both(".gitignore", gitignore, () => mergeGitignore(gitignore, [
147
+ ...scaffold.gitignore,
148
+ ...(writesEnv ? [".env"] : []),
149
+ ]));
176
150
  if (packageManager === "pnpm" && scaffold.nativeBuilds.length > 0) {
177
151
  const workspace = input.read("pnpm-workspace.yaml");
178
152
  both("pnpm-workspace.yaml", workspace, () => mergePnpmWorkspace(workspace, scaffold.nativeBuilds));
@@ -1,11 +1,4 @@
1
1
  import type { PackageManager } from "../wizard/wizard.questions.js";
2
- /**
3
- * Q16-5's default package manager: a lockfile says what a project already uses
4
- * (`init`); otherwise the package manager that launched this CLI says what the
5
- * developer uses — `npm_config_user_agent` is `npm/…` under `npx` and
6
- * `npm exec`, `pnpm/…` under `pnpm dlx` and `pnpm exec`, and unset when the bin
7
- * runs directly (B11); otherwise npm.
8
- */
9
2
  export declare function detectPackageManager(signals: {
10
3
  readonly lockfile?: PackageManager | undefined;
11
4
  readonly userAgent?: string | undefined;
@@ -1,10 +1,3 @@
1
- /**
2
- * Q16-5's default package manager: a lockfile says what a project already uses
3
- * (`init`); otherwise the package manager that launched this CLI says what the
4
- * developer uses — `npm_config_user_agent` is `npm/…` under `npx` and
5
- * `npm exec`, `pnpm/…` under `pnpm dlx` and `pnpm exec`, and unset when the bin
6
- * runs directly (B11); otherwise npm.
7
- */
8
1
  export function detectPackageManager(signals) {
9
2
  if (signals.lockfile !== undefined) {
10
3
  return signals.lockfile;
@@ -2,17 +2,11 @@ import type { PackageManifest } from "../apply/manifest.merger.js";
2
2
  import type { AdapterCatalog, CatalogEntry } from "../catalog/catalog-entry.interface.js";
3
3
  import type { ModuleKind } from "../templates/template.registry.js";
4
4
  import type { PackageManager } from "../wizard/wizard.questions.js";
5
- /**
6
- * §4.1's `inspect`: what `aventara init` needs to know about the project in the
7
- * working directory, read before anything is asked or written — so every
8
- * refusal here leaves the directory exactly as it was (it is a property of the
9
- * order, not of a rollback).
10
- */
11
5
  /** The project is not one `aventara init` serves. A refusal: one sentence, nothing written. */
12
6
  export declare class ProjectRefusedError extends Error {
13
7
  readonly name = "ProjectRefusedError";
14
8
  }
15
- /** The ORM a project already has, by the catalog's family packages (R14, D10). */
9
+ /** The ORM a project already has, by the catalog's family packages. */
16
10
  export type OrmPresence = {
17
11
  readonly kind: "absent";
18
12
  } | {
@@ -30,9 +24,9 @@ export type ProjectInspection = {
30
24
  /** The package manager the lockfile names, if exactly one does. */
31
25
  readonly lockfile: PackageManager | undefined;
32
26
  readonly orm: OrmPresence;
33
- /** `@nestjs/config` loads `.env` itself, so the start scripts are left alone (P5). */
27
+ /** `@nestjs/config` loads `.env` itself, so the start scripts are left alone. */
34
28
  readonly usesNestConfig: boolean;
35
29
  };
36
- /** The file the anchored edit opens (R2). */
30
+ /** The file the anchored edit opens. */
37
31
  export declare const APP_MODULE = "src/app.module.ts";
38
32
  export declare function inspectProject(directory: string, catalog: AdapterCatalog): ProjectInspection;
@@ -1,21 +1,11 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { lowestMajorOf } from "../catalog/range.reader.js";
4
- /**
5
- * §4.1's `inspect`: what `aventara init` needs to know about the project in the
6
- * working directory, read before anything is asked or written — so every
7
- * refusal here leaves the directory exactly as it was (it is a property of the
8
- * order, not of a rollback).
9
- */
10
- /** The project is not one `aventara init` serves. A refusal: one sentence, nothing written. */
11
4
  export class ProjectRefusedError extends Error {
12
5
  name = "ProjectRefusedError";
13
6
  }
14
- /** Nest 12 only (Phase 11 Q16). */
15
7
  const NEST_MAJOR = 12;
16
- /** D4: TypeScript 7 has no classic compiler API. */
17
8
  const FIRST_UNSUPPORTED_TYPESCRIPT = 7;
18
- /** The file the anchored edit opens (R2). */
19
9
  export const APP_MODULE = "src/app.module.ts";
20
10
  const LOCKFILES = [
21
11
  ["package-lock.json", "npm"],
@@ -1,15 +1,10 @@
1
1
  /**
2
- * R6 — finding the developer's own ORM service, lexically, over `src/**\/*.ts`:
3
- * no compiler (`aventara init` may run before anything is installed).
4
- *
5
- * 1. **Candidates**: exported classes that `extends` the ORM's client class,
6
- * where the file imports that class from a specifier the ORM's templates
7
- * recognise (the generated client, or the ORM package).
8
- * 2. **Compositions**: exported classes that hold a client instead of extending
9
- * one (`client = new PrismaClient(…)`, Phase 11 S7's shape) — reported with
10
- * the member, never wired.
2
+ * 1. **Candidates**: exported classes that `extends` the ORM's client class, where
3
+ * the file imports that class from a specifier the ORM's templates recognise
4
+ * (the generated client, or the ORM package).
11
5
  * 3. **Modules**: each `@Module({…})`-decorated exported class with the
12
- * identifiers its `providers` and `exports` list, and whether it is `@Global()`.
6
+ * identifiers its `providers` and `exports` list, and whether it is
7
+ * `@Global()`.
13
8
  *
14
9
  * Which of them is *the* service is the caller's question (the wizard's).
15
10
  */
@@ -18,7 +18,6 @@ function sourceFiles(directory, root, skip) {
18
18
  : [];
19
19
  });
20
20
  }
21
- /** The identifiers the array under `key`, at `object`'s own level, names (`providers: [A, B]`). */
22
21
  function arrayNames(text, code, object, key) {
23
22
  const end = closing(text, code, object);
24
23
  let depth = 0;
@@ -99,7 +98,6 @@ export function scanServices(directory, shape) {
99
98
  }
100
99
  return { candidates, compositions, modules };
101
100
  }
102
- /** The modules that make `service` injectable elsewhere: providing and exporting it, or global. */
103
101
  export function modulesProviding(scan, service) {
104
102
  return scan.modules.filter((module) => module.providers.includes(service.exportName) &&
105
103
  (module.exports.includes(service.exportName) || module.global));
@@ -1,15 +1,5 @@
1
- /**
2
- * A lexical view of TypeScript source — enough to find decorators, classes,
3
- * imports and brackets **in code**, never inside a comment, a string or a
4
- * template literal's text — with no compiler: `aventara new` runs before
5
- * anything (TypeScript included) is installed in the project, and the CLI
6
- * carries no TypeScript of its own. Shared by the anchored `app.module.ts` edit
7
- * and the detection of a developer's ORM service.
8
- */
9
- /** For each character: is it code (not inside a comment, string or template text)? */
10
1
  export function codeMask(text) {
11
2
  const code = new Array(text.length).fill(true);
12
- /** Open template literals' brace depths: `${` re-enters code until its `}`. */
13
3
  const templates = [];
14
4
  let braces = 0;
15
5
  let index = 0;
@@ -19,7 +9,6 @@ export function codeMask(text) {
19
9
  }
20
10
  };
21
11
  const templateText = (from) => {
22
- // Scans template text from `from` until "`" (closes) or "${" (re-enters code).
23
12
  let at = from;
24
13
  while (at < text.length) {
25
14
  if (text[at] === "\\") {
@@ -88,7 +77,6 @@ export function codeMask(text) {
88
77
  }
89
78
  return code;
90
79
  }
91
- /** Every index where `token` starts in code. */
92
80
  export function codeIndexes(text, code, token) {
93
81
  const found = [];
94
82
  for (const match of text.matchAll(token)) {
@@ -103,7 +91,6 @@ export const OPENERS = {
103
91
  "[": "]",
104
92
  "{": "}",
105
93
  };
106
- /** The index of the bracket closing the one at `open`, counting code brackets only. */
107
94
  export function closing(text, code, open) {
108
95
  const stack = [];
109
96
  for (let at = open; at < text.length; at += 1) {
@@ -1,8 +1,8 @@
1
1
  /**
2
- * The one external process seam (§4.2): a command, its arguments, a working
3
- * directory. Its stdout is always **piped**, never inherited — `nest new` asks a
4
- * question it has no flag for when its stdout is a terminal (B25) — and both
5
- * streams are collected, so a failure can be reported with what it said.
2
+ * The one external process seam: a command, its arguments, a working directory.
3
+ * Its stdout is always **piped**, never inherited — `nest new` asks a question it
4
+ * has no flag for when its stdout is a terminal — and both streams are collected,
5
+ * so a failure can be reported with what it said.
6
6
  */
7
7
  export type CommandResult = {
8
8
  readonly code: number;
@@ -3,11 +3,9 @@ import type { ScaffoldCommand } from "../command/command.parser.js";
3
3
  import { type Prompter } from "../wizard/answer.resolver.js";
4
4
  import type { CommandRunner } from "./command.runner.js";
5
5
  /**
6
- * `aventara init` in §4.1's order — inspect, ask, plan, confirm, and only then
7
- * write and install. Every step before the write reads; so a refusal anywhere
8
- * before it leaves the project exactly as it was. A failure after it (the
9
- * install) names the command, its exit code and what to re-run; nothing is
10
- * rolled back.
6
+ * Every step before the write reads; so a refusal anywhere before it leaves the
7
+ * project exactly as it was. A failure after it (the install) names the command,
8
+ * its exit code and what to re-run; nothing is rolled back.
11
9
  */
12
10
  export type InitIo = {
13
11
  readonly directory: string;
@@ -17,7 +15,7 @@ export type InitIo = {
17
15
  readonly prompter: Prompter;
18
16
  readonly runner: CommandRunner;
19
17
  readonly catalog: AdapterCatalog;
20
- /** This CLI's own version (D1). */
18
+ /** This CLI's own version. */
21
19
  readonly aventaraVersion: string;
22
20
  /** Next steps that come before init's own (`new`'s `cd <name>`). */
23
21
  readonly firstSteps?: readonly string[];
@@ -9,7 +9,6 @@ import { scanServices } from "../project/service.detector.js";
9
9
  import { templatesFor, } from "../templates/template.registry.js";
10
10
  import { resolveAnswers } from "../wizard/answer.resolver.js";
11
11
  import { INIT_QUESTIONS, REUSE_QUESTIONS, } from "../wizard/wizard.questions.js";
12
- /** The install step failed after the files were written. Reported, exit 1. */
13
12
  export class InstallFailedError extends Error {
14
13
  name = "InstallFailedError";
15
14
  }
@@ -49,7 +48,6 @@ export async function runInit(command, io) {
49
48
  prompter: io.prompter,
50
49
  });
51
50
  const writes = plan.conflicts.length === 0 ? plan.keeping : plan.replacing;
52
- // The only file I/O (§4.1 `apply`).
53
51
  for (const write of writes) {
54
52
  const target = path.join(io.directory, write.path);
55
53
  mkdirSync(path.dirname(target), { recursive: true });
@@ -76,7 +74,6 @@ export async function runInit(command, io) {
76
74
  io.stdout(`Next:\n${[...(io.firstSteps ?? []), ...plan.nextSteps].map((step, index) => ` ${index + 1}. ${step}`).join("\n")}\n`);
77
75
  return 0;
78
76
  }
79
- /** S6 — no ORM: the ORM and database are asked, and the entry's templates write it all. */
80
77
  async function prepareFresh(command, io, inspection, detectedPackageManager) {
81
78
  const answers = await resolveAnswers(INIT_QUESTIONS, {
82
79
  given: command.given,
@@ -101,7 +98,6 @@ async function prepareFresh(command, io, inspection, detectedPackageManager) {
101
98
  warnings: [],
102
99
  };
103
100
  }
104
- /** The installed version of `name`, looked up the way Node resolves it: upward from the project. */
105
101
  function installedVersion(directory, name) {
106
102
  let current = directory;
107
103
  for (;;) {
@@ -117,11 +113,6 @@ function installedVersion(directory, name) {
117
113
  current = parent;
118
114
  }
119
115
  }
120
- /**
121
- * S7 — the ORM is already set up (R6, R7): the catalog entry is matched against
122
- * what is installed, the setup against what the entry declares, and the
123
- * developer's own service is found or asked for. Nothing of theirs is written.
124
- */
125
116
  async function prepareReuse(command, io, inspection, detectedPackageManager) {
126
117
  const dependencies = [
127
118
  ...Object.keys(inspection.manifest.dependencies ?? {}),
@@ -146,7 +137,6 @@ async function prepareReuse(command, io, inspection, detectedPackageManager) {
146
137
  if (facts.clientOutput === undefined) {
147
138
  throw new ProjectRefusedError(`this project's ${facts.generator} generator block in ${facts.schema} has no output, and the generate step reads the client from it; give it one, such as ../src/generated/${entry.orm.family}`);
148
139
  }
149
- // A flag naming the ORM or database must name what the project has.
150
140
  for (const [flag, given, found] of [
151
141
  ["--orm", command.given.orm, `${entry.orm.family}@${entry.orm.major}`],
152
142
  ["--db", command.given.db, provider],
@@ -181,7 +171,6 @@ async function prepareReuse(command, io, inspection, detectedPackageManager) {
181
171
  packageManager === undefined) {
182
172
  throw new Error("the reuse questions settled without a service, module and package manager");
183
173
  }
184
- // Q16-21: beside the client's output, unless that output contains it (the adapter refuses that).
185
174
  const preferred = "src/generated/aventara/discovery.artifact.ts";
186
175
  const artifact = `${preferred}/`.startsWith(`${facts.clientOutput}/`)
187
176
  ? "src/aventara/discovery.artifact.ts"
@@ -190,7 +179,7 @@ async function prepareReuse(command, io, inspection, detectedPackageManager) {
190
179
  ...(facts.clientOutput.startsWith("src/")
191
180
  ? []
192
181
  : [
193
- `the ${entry.orm.label} client is generated into ${facts.clientOutput}, outside src/, which nest build does not compile (B6); your build is your own, and init does not change it`,
182
+ `the ${entry.orm.label} client is generated into ${facts.clientOutput}, outside src/, which nest build does not compile; your build is your own, and init does not change it`,
194
183
  ]),
195
184
  ...(service.clientMember === undefined
196
185
  ? []
@@ -1,18 +1,15 @@
1
1
  import type { ScaffoldCommand } from "../command/command.parser.js";
2
2
  import { type InitIo } from "./init.orchestrator.js";
3
3
  /**
4
- * `aventara new <name>` (R2, D1): the pinned `nest new`, then **exactly**
5
- * `aventara init`'s pipeline over the fresh project, with the wizard's answers
6
- * carried in — so every `new` run exercises the anchored edit, the merges and
7
- * the templates `init` uses.
4
+ * `aventara new <name>`: the pinned `nest new`, then **exactly** `aventara init`'s
5
+ * pipeline over the fresh project, with the wizard's answers carried in — so every
6
+ * `new` run exercises the anchored edit, the merges and the templates `init` uses.
8
7
  *
9
- * Nest authors its own scaffold (D1): the CLI never writes Nest's files. Its
10
- * output is pinned by digest (B24), so a `@nestjs/cli` that writes something
11
- * else stops the run before anything of Aventara's is written over it.
8
+ * Nest authors its own scaffold: the CLI never writes Nest's files. Its output is
9
+ * pinned by digest, so a `@nestjs/cli` that writes something else stops the run
10
+ * before anything of Aventara's is written over it.
12
11
  */
13
- /** D1: the `nest new` this CLI was measured against (B1, B24). */
14
12
  export declare const NEST_CLI = "@nestjs/cli@12.0.8";
15
- /** B24: `src/app.module.ts` as `@nestjs/cli` 12.0.8 writes it — the anchored edit's file. */
16
13
  export declare const NEST_APP_MODULE_SHA256 = "fe98c4cd2552342272494652287c02e4ef58db3072fcb18513ea831c60f85778";
17
14
  export type NewIo = Omit<InitIo, "directory"> & {
18
15
  /** Where `new` creates the project directory. */
@@ -6,21 +6,8 @@ import { ProjectRefusedError } from "../project/project.inspector.js";
6
6
  import { resolveAnswers } from "../wizard/answer.resolver.js";
7
7
  import { NEW_QUESTIONS } from "../wizard/wizard.questions.js";
8
8
  import { InstallFailedError, runInit, } from "./init.orchestrator.js";
9
- /**
10
- * `aventara new <name>` (R2, D1): the pinned `nest new`, then **exactly**
11
- * `aventara init`'s pipeline over the fresh project, with the wizard's answers
12
- * carried in — so every `new` run exercises the anchored edit, the merges and
13
- * the templates `init` uses.
14
- *
15
- * Nest authors its own scaffold (D1): the CLI never writes Nest's files. Its
16
- * output is pinned by digest (B24), so a `@nestjs/cli` that writes something
17
- * else stops the run before anything of Aventara's is written over it.
18
- */
19
- /** D1: the `nest new` this CLI was measured against (B1, B24). */
20
9
  export const NEST_CLI = "@nestjs/cli@12.0.8";
21
- /** B24: `src/app.module.ts` as `@nestjs/cli` 12.0.8 writes it — the anchored edit's file. */
22
10
  export const NEST_APP_MODULE_SHA256 = "fe98c4cd2552342272494652287c02e4ef58db3072fcb18513ea831c60f85778";
23
- /** The command that runs a package from the registry once, per package manager (B11, B21). */
24
11
  function oneOff(packageManager) {
25
12
  return packageManager === "pnpm" ? ["pnpm", ["dlx"]] : ["npx", ["-y"]];
26
13
  }
@@ -47,8 +34,6 @@ export async function runNew(command, io) {
47
34
  if (existsSync(directory) && readdirSync(directory).length > 0) {
48
35
  throw new ProjectRefusedError(`aventara new creates ${directory}, which already exists and is not empty; choose another name, or run aventara init inside an existing project`);
49
36
  }
50
- // stdout piped by the runner (B25): on a terminal, nest new asks the module
51
- // system, with no flag to answer it; piped, it asks nothing and writes ESM.
52
37
  const [runner, prefix] = oneOff(packageManager);
53
38
  const args = [
54
39
  ...prefix,
@@ -82,7 +67,6 @@ export async function runNew(command, io) {
82
67
  },
83
68
  skipInstall: command.skipInstall,
84
69
  skipGit: false,
85
- // A fresh project: there is nothing of the developer's to confirm over.
86
70
  yes: true,
87
71
  }, { ...io, directory, firstSteps: [`Enter the project: cd ${name}`] });
88
72
  }
@@ -2,21 +2,8 @@ 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
4
  import { SCAFFOLD_ENTRYPOINT, } from "../template.registry.js";
5
- /**
6
- * The `prisma7` entry's templates (D7): Prisma 7 knowledge as text the CLI
7
- * writes and reads, keyed by the providers `@aventara/prisma7-adapter`
8
- * declares. Every value that is an adapter fact — the ORM package, the driver
9
- * per provider, the generator, the generate bin, the version floor — is read
10
- * from the catalog entry handed in, not restated here.
11
- *
12
- * The texts follow the Nest scaffold's formatting (prettier, `singleQuote`,
13
- * `trailingComma: "all"`, B1), so the project's own `format` script leaves them
14
- * as they are.
15
- */
16
- /** The generated client goes under `src`, where `nest build` compiles it (B6). */
17
5
  const CLIENT_OUTPUT = "src/generated/prisma";
18
6
  const SCHEMA = "prisma/schema.prisma";
19
- /** B5: the Prisma CLI loads either name, and `prisma7.config.ts` wins when both exist. */
20
7
  const CONFIG_FILES = ["prisma7.config.ts", "prisma.config.ts"];
21
8
  const DRIVER_PREFIX = "@prisma/adapter-";
22
9
  const NEW_SERVICE = {
@@ -33,19 +20,16 @@ const PROVIDERS = {
33
20
  driverOptions: "{ url }",
34
21
  databaseUrl: "file:./dev.db",
35
22
  gitignore: ["/dev.db*"],
36
- // B9: pnpm 12 refuses these install scripts until they are allowed.
37
23
  nativeBuilds: ["@prisma/engines", "better-sqlite3", "prisma"],
38
24
  },
39
25
  postgresql: {
40
26
  driverClass: "PrismaPg",
41
27
  driverOptions: "{ connectionString: url }",
42
- // `prisma init`'s own placeholder (B5); printed in the next steps, never asked (Q16-8).
43
28
  databaseUrl: "postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public",
44
29
  gitignore: [],
45
30
  nativeBuilds: ["@prisma/engines", "prisma"],
46
31
  },
47
32
  };
48
- /** A relative import specifier from `from` (a project file) to `to` (a project path, no extension). */
49
33
  function specifier(from, to, js) {
50
34
  const relative = path.posix.relative(path.posix.dirname(from), to);
51
35
  return `${relative.startsWith(".") ? relative : `./${relative}`}${js}`;
@@ -62,7 +46,6 @@ function schema(input) {
62
46
  ` provider = "${input.provider}"`,
63
47
  "}",
64
48
  "",
65
- // R12: Prisma's `--with-model` starter (B5).
66
49
  "model User {",
67
50
  " id Int @id @default(autoincrement())",
68
51
  " email String @unique",
@@ -71,7 +54,6 @@ function schema(input) {
71
54
  "",
72
55
  ].join("\n");
73
56
  }
74
- /** `prisma.config.ts` (Q16-19). Prisma does not load `.env` itself (B5). */
75
57
  function prismaConfig() {
76
58
  return [
77
59
  "import { existsSync } from 'node:fs';",
@@ -94,7 +76,6 @@ function prismaConfig() {
94
76
  "",
95
77
  ].join("\n");
96
78
  }
97
- /** The developer-owned service (P2: `extends PrismaClient`, so `client: prisma`). */
98
79
  function prismaService(input) {
99
80
  const provider = PROVIDERS[input.provider];
100
81
  const driver = input.entry.drivers[input.provider];
@@ -126,7 +107,6 @@ function prismaService(input) {
126
107
  "",
127
108
  ].join("\n");
128
109
  }
129
- /** `src/aventara.config.ts` (R8, Q16-17): the framework's configuration. */
130
110
  function aventaraConfig(input) {
131
111
  const file = "src/aventara.config.ts";
132
112
  const service = input.service.exportName;
@@ -222,7 +202,6 @@ function scaffold(input) {
222
202
  ],
223
203
  env: { DATABASE_URL: provider.databaseUrl },
224
204
  gitignore: ["/src/generated/", ...provider.gitignore],
225
- // D1, D9: exactly the version floor the adapter declares; never bare `prisma`.
226
205
  dependencies: { [input.entry.orm.package]: floor, [driver]: floor },
227
206
  devDependencies: { prisma: floor },
228
207
  prepare: prepare({
@@ -270,7 +249,6 @@ function reuse(input) {
270
249
  }),
271
250
  },
272
251
  ],
273
- // R6: the developer's Prisma files, `.env` key and versions are theirs.
274
252
  env: {},
275
253
  gitignore: [`/${path.posix.dirname(input.artifact)}/`],
276
254
  dependencies: {},
@@ -287,9 +265,6 @@ function reuse(input) {
287
265
  nextSteps: [],
288
266
  };
289
267
  }
290
- /* ------------------------------------------------------------------ *
291
- * Reading an existing Prisma 7 setup (R6) *
292
- * ------------------------------------------------------------------ */
293
268
  function schemaLocation(directory, manifest) {
294
269
  for (const config of CONFIG_FILES) {
295
270
  const file = path.join(directory, config);
@@ -305,7 +280,6 @@ function schemaLocation(directory, manifest) {
305
280
  ? path.posix.normalize(prisma.schema)
306
281
  : SCHEMA;
307
282
  }
308
- /** The `.prisma` files of a schema path: the file, or every file in a schema folder. */
309
283
  function schemaFiles(directory, schemaPath) {
310
284
  const full = path.join(directory, schemaPath);
311
285
  if (!existsSync(full)) {
@@ -343,7 +317,6 @@ function readProject(directory, manifest) {
343
317
  for (const block of blocks(text, "generator")) {
344
318
  const declared = setting(block, "provider");
345
319
  const output = setting(block, "output");
346
- // The client generator, not a second generator (a zod or docs one) beside it.
347
320
  if (generator === undefined || /^prisma-client/.test(declared ?? "")) {
348
321
  generator = declared;
349
322
  clientOutput =