@aventara/cli 0.1.0-pilot.4 → 1.0.0-rc.1

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/CHANGELOG.md +345 -0
  2. package/README.md +55 -42
  3. package/dist/apply/conflict.confirmer.js +4 -4
  4. package/dist/cli.js +18 -14
  5. package/dist/command/command.parser.js +17 -10
  6. package/dist/plan/project.planner.js +2 -4
  7. package/dist/project/project.inspector.js +8 -8
  8. package/dist/run/command.runner.js +2 -0
  9. package/dist/run/init.orchestrator.js +40 -20
  10. package/dist/run/new.orchestrator.js +32 -14
  11. package/dist/run/step.reporter.js +87 -0
  12. package/dist/templates/docs.links.js +2 -1
  13. package/dist/templates/prisma7/prisma7.templates.js +26 -5
  14. package/dist/templates/template.registry.js +1 -1
  15. package/dist/wizard/answer.resolver.js +5 -5
  16. package/dist/wizard/readline.prompter.js +3 -3
  17. package/dist/wizard/wizard.questions.js +9 -9
  18. package/package.json +4 -3
  19. package/dist/apply/app-module.anchor.d.ts +0 -24
  20. package/dist/apply/conflict.confirmer.d.ts +0 -15
  21. package/dist/apply/e2e-spec.anchor.d.ts +0 -18
  22. package/dist/apply/main-cors.anchor.d.ts +0 -50
  23. package/dist/apply/manifest.merger.d.ts +0 -51
  24. package/dist/aventara.bin.d.ts +0 -2
  25. package/dist/catalog/adapter.catalog.generated.d.ts +0 -20
  26. package/dist/catalog/catalog-entry.interface.d.ts +0 -54
  27. package/dist/catalog/catalog.matcher.d.ts +0 -40
  28. package/dist/catalog/range.reader.d.ts +0 -11
  29. package/dist/cli.d.ts +0 -29
  30. package/dist/command/command.parser.d.ts +0 -38
  31. package/dist/node-version.guard.d.ts +0 -8
  32. package/dist/plan/project.planner.d.ts +0 -53
  33. package/dist/project/package-manager.detector.d.ts +0 -5
  34. package/dist/project/project.inspector.d.ts +0 -32
  35. package/dist/project/service.detector.d.ts +0 -40
  36. package/dist/project/source.scanner.d.ts +0 -16
  37. package/dist/run/command.runner.d.ts +0 -15
  38. package/dist/run/init.orchestrator.d.ts +0 -27
  39. package/dist/run/new.orchestrator.d.ts +0 -20
  40. package/dist/run/scaffold.committer.d.ts +0 -28
  41. package/dist/templates/docs.links.d.ts +0 -8
  42. package/dist/templates/prisma7/prisma7.templates.d.ts +0 -34
  43. package/dist/templates/template.registry.d.ts +0 -152
  44. package/dist/wizard/answer.resolver.d.ts +0 -47
  45. package/dist/wizard/readline.prompter.d.ts +0 -22
  46. package/dist/wizard/wizard.questions.d.ts +0 -120
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aventara/cli",
3
- "version": "0.1.0-pilot.4",
3
+ "version": "1.0.0-rc.1",
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",
@@ -12,7 +12,8 @@
12
12
  },
13
13
  "files": [
14
14
  "dist",
15
- "LICENSE-ADDITIONAL-PERMISSION.md"
15
+ "LICENSE-ADDITIONAL-PERMISSION.md",
16
+ "CHANGELOG.md"
16
17
  ],
17
18
  "publishConfig": {
18
19
  "access": "public"
@@ -23,7 +24,7 @@
23
24
  },
24
25
  "scripts": {
25
26
  "prebuild": "node scripts/adapter-catalog.generator.ts",
26
- "build": "tsc -p tsconfig.json --removeComments --declaration false",
27
+ "build": "node ../../scripts/build/build-output.cleaner.ts dist && tsc -p tsconfig.json --removeComments",
27
28
  "typecheck": "tsc -p tsconfig.typecheck.json --noEmit",
28
29
  "test": "vitest run --typecheck --config ../../vitest.config.mts --root .",
29
30
  "lint": "biome lint src scripts"
@@ -1,24 +0,0 @@
1
- /**
2
- * The scan is string- and comment-aware (a `@Module(` or an `imports: [` inside a
3
- * comment, a string or a template literal is not code), and it never reformats:
4
- * everything outside the two insertion points keeps its bytes. When the anchor is
5
- * not found exactly once — two `@Module`s, a computed `imports`, no `imports` at
6
- * all — nothing is edited and the caller prints the lines to add instead.
7
- */
8
- export type AppModuleWiring = {
9
- /** Complete import declarations, one per line. */
10
- readonly imports: readonly string[];
11
- /** `imports:` entries, each possibly multi-line, each ending with a comma. */
12
- readonly entries: readonly string[];
13
- };
14
- export type AppModuleEdit = {
15
- readonly kind: "edited";
16
- readonly text: string;
17
- } | {
18
- readonly kind: "not-anchored";
19
- readonly reason: string;
20
- };
21
- /** Splices `wiring` into `text` at the anchor, or says why there is no anchor. */
22
- export declare function spliceAppModule(text: string, wiring: AppModuleWiring): AppModuleEdit;
23
- /** What to add by hand when there is no anchor. */
24
- export declare function wiringInstructions(wiring: AppModuleWiring): string;
@@ -1,15 +0,0 @@
1
- import type { Prompter } from "../wizard/answer.resolver.js";
2
- /** Nobody confirmed replacing existing content. A refusal: nothing was touched. */
3
- export declare class ConflictsNotConfirmedError extends Error {
4
- readonly name = "ConflictsNotConfirmedError";
5
- }
6
- export declare function conflictWarning(conflicts: readonly string[]): string;
7
- /**
8
- * Resolves when `conflicts` may be replaced; throws when they may not.
9
- *
10
- * @throws ConflictsNotConfirmedError
11
- */
12
- export declare function confirmConflicts(conflicts: readonly string[], consent: {
13
- readonly yes: boolean;
14
- readonly prompter: Prompter;
15
- }): Promise<void>;
@@ -1,18 +0,0 @@
1
- /**
2
- * pilot.1 — the scaffold's own e2e spec also proves the protocol is mounted.
3
- *
4
- * `nest new`'s `test/app.e2e-spec.ts` (`@nestjs/schematics` 12's template, ESM
5
- * and CommonJS alike) tests `GET /` and nothing else. Like the `app.module.ts`
6
- * edit, this one is anchored on Nest's exact text: the `/ (GET)` test is found
7
- * exactly once, and a `GET <entrypoint>/_contract` test is added right after
8
- * it, through the spec's own `app` and `request`. A spec that is not Nest's —
9
- * the developer's own — is left as it is, and nothing is said: the test is a
10
- * convenience, and the developer's tests are theirs.
11
- */
12
- /** The e2e spec `nest new` writes. */
13
- export declare const E2E_SPEC = "test/app.e2e-spec.ts";
14
- /**
15
- * `spec` with the contract test after Nest's `GET /` test, or `undefined` when
16
- * the anchor is not there exactly once, or the contract test already is.
17
- */
18
- export declare function spliceContractTest(spec: string, entrypoint: string): string | undefined;
@@ -1,50 +0,0 @@
1
- /**
2
- * pilot.3 — the scaffold turns CORS on in `src/main.ts` for the origins listed in
3
- * `CORS_ORIGINS`, so a browser frontend on another port (Vite's 5173, a Next.js
4
- * dev server on 3001) can call the protocol:
5
- *
6
- * const corsOrigins = (process.env.CORS_ORIGINS ?? '')…filter(Boolean);
7
- * app.enableCors({ origin: corsOrigins.length > 0 ? corsOrigins : false });
8
- *
9
- * followed by a commented-out platform-level rate limiter.
10
- *
11
- * **Unset or empty is OFF, never open.** The `cors` package Nest's Express
12
- * platform uses — and `@fastify/cors` — answer `Access-Control-Allow-Origin: *`
13
- * when given no origin, so the list is never passed through as it is: no origin is
14
- * `false`, CORS disabled.
15
- *
16
- * Like the `app.module.ts` edit, this one is anchored and never reformats: the
17
- * lines are inserted after the one statement that creates the application — `const
18
- * app = await NestFactory.create(…);`, found in code exactly once — through its
19
- * own variable. A `main.ts` that already configures CORS (`enableCors`, or a
20
- * `cors` option given to `NestFactory.create`) is the developer's decision and is
21
- * left as it is; one with no such statement is not edited, and the lines are
22
- * printed instead.
23
- */
24
- /** The variable the inserted lines read. */
25
- export declare const CORS_ORIGINS_VARIABLE = "CORS_ORIGINS";
26
- /** What the scaffold's `.env` lists: Vite's dev server, and a Next.js one beside Nest's 3000. */
27
- export declare const SCAFFOLD_CORS_ORIGINS = "http://localhost:5173,http://localhost:3001";
28
- /** The main file `nest new` writes. */
29
- export declare const MAIN_FILE = "src/main.ts";
30
- export type MainCorsEdit =
31
- /** The lines were inserted. */
32
- {
33
- readonly kind: "edited";
34
- readonly text: string;
35
- }
36
- /** The lines are already there: a previous run's edit. */
37
- | {
38
- readonly kind: "present";
39
- }
40
- /** The developer configures CORS: nothing is changed. */
41
- | {
42
- readonly kind: "configured";
43
- } | {
44
- readonly kind: "not-anchored";
45
- readonly reason: string;
46
- };
47
- /** Splices the CORS lines into `text`, or says why they are not. */
48
- export declare function spliceMainCors(text: string): MainCorsEdit;
49
- /** What to add by hand when there is no anchor. */
50
- export declare function mainCorsInstructions(): string;
@@ -1,51 +0,0 @@
1
- /**
2
- * The merges `aventara init` makes into files a project already has —
3
- * `package.json`, `.env`, `.gitignore`, `pnpm-workspace.yaml` — each answering the
4
- * merged text and the **conflicts**: values already there that differ from what
5
- * would be written (the `generateAt` rule's "content the tool did not produce"). A
6
- * value already equal to what would be written is no change; a conflict is
7
- * replaced only once confirmed (`conflict.confirmer.ts`), so each merge is
8
- * computed with conflicts both kept and replaced.
9
- */
10
- export type Merge = {
11
- readonly text: string;
12
- /** What differs, named for the person asked: `package.json's scripts["postinstall"]`. */
13
- readonly conflicts: readonly string[];
14
- };
15
- export type PackageManifest = {
16
- readonly [key: string]: unknown;
17
- readonly dependencies?: Readonly<Record<string, string>>;
18
- readonly devDependencies?: Readonly<Record<string, string>>;
19
- readonly scripts?: Readonly<Record<string, string>>;
20
- };
21
- export type ManifestChanges = {
22
- readonly dependencies: Readonly<Record<string, string>>;
23
- readonly devDependencies: Readonly<Record<string, string>>;
24
- /** Scripts to set; a different existing value is a conflict. */
25
- readonly scripts: Readonly<Record<string, string>>;
26
- /**
27
- * Scripts to rewrite only from a known value: `from` → `to`. Any other existing
28
- * value is a conflict; an absent script is left absent.
29
- */
30
- readonly rewrites: Readonly<Record<string, {
31
- readonly from: string;
32
- readonly to: string;
33
- }>>;
34
- };
35
- /** `package.json`, in npm's own layout: two-space JSON, dependencies sorted. */
36
- export declare function mergePackageManifest(text: string, changes: ManifestChanges, replaceConflicts: boolean): Merge;
37
- /** `.env`: a missing key is appended as `KEY="value"`, after a final newline. */
38
- export declare function mergeEnvFile(text: string | undefined, entries: Readonly<Record<string, string>>, replaceConflicts: boolean): Merge;
39
- /**
40
- * pilot.3 — `.env`: `KEY="value"` appended after a final newline when no line sets
41
- * `key`; a line that does is the developer's, never a conflict, and nothing else
42
- * is reordered or rewritten.
43
- */
44
- export declare function appendEnvEntryIfAbsent(text: string | undefined, key: string, value: string): string;
45
- /** `.gitignore`: missing lines appended, nothing else touched. */
46
- export declare function mergeGitignore(text: string | undefined, additions: readonly string[]): Merge;
47
- /**
48
- * Keys missing under an existing `allowBuilds:` are added there; otherwise the
49
- * block is appended.
50
- */
51
- export declare function mergePnpmWorkspace(text: string | undefined, packages: readonly string[]): Merge;
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
@@ -1,20 +0,0 @@
1
- export declare const ADAPTER_CATALOG: readonly [{
2
- readonly id: "prisma7";
3
- readonly alias: "prisma7";
4
- readonly adapterPackage: "@aventara/prisma7-adapter";
5
- readonly orm: {
6
- readonly family: "prisma";
7
- readonly label: "Prisma";
8
- readonly package: "@prisma/client";
9
- readonly major: 7;
10
- };
11
- readonly range: "^7.10.0";
12
- readonly familyPackages: readonly ["prisma", "@prisma/client", "@prisma/prisma7", "@prisma/orm-*"];
13
- readonly providers: readonly ["sqlite", "postgresql"];
14
- readonly drivers: {
15
- readonly sqlite: "@prisma/adapter-better-sqlite3";
16
- readonly postgresql: "@prisma/adapter-pg";
17
- };
18
- readonly generators: readonly ["prisma-client"];
19
- readonly bin: "aventara-prisma7-generate";
20
- }];
@@ -1,54 +0,0 @@
1
- import type { ADAPTER_CATALOG } from "./adapter.catalog.generated.js";
2
- /**
3
- * One entry per Aventara adapter package that exists: what the CLI may offer and
4
- * what it must refuse, every value traced to that adapter's own manifest — its
5
- * `aventara.adapter` declaration, its `peerDependencies` and its `bin`. The
6
- * entries are **generated** at this package's build by
7
- * `scripts/adapter-catalog.generator.ts` into `adapter.catalog.generated.ts` and
8
- * never edited. The CLI holds no list of ORMs, majors, providers or drivers of its
9
- * own.
10
- */
11
- export type CatalogEntry = {
12
- /**
13
- * The adapter package's ORM stem, e.g. `prisma7`: the wizard's value and the
14
- * templates' key.
15
- */
16
- readonly id: string;
17
- /**
18
- * `aventara.adapter.alias`, e.g. `prisma7`: what `--orm` takes. Always
19
- * `<orm><major>`, the generator refuses any other.
20
- */
21
- readonly alias: string;
22
- /** The adapter package a project installs, e.g. `@aventara/prisma7-adapter`. */
23
- readonly adapterPackage: string;
24
- readonly orm: {
25
- /** `aventara.adapter.orm`, e.g. `prisma`: the family the wizard groups majors under. */
26
- readonly family: string;
27
- /** `aventara.adapter.ormLabel`, e.g. `Prisma`: how the wizard names the family. */
28
- readonly label: string;
29
- /** `aventara.adapter.ormPackage`, e.g. `@prisma/client`: whose installed version selects the entry. */
30
- readonly package: string;
31
- /** The one major `range` admits. */
32
- readonly major: number;
33
- };
34
- /** `peerDependencies[orm.package]`: the ORM versions the adapter supports. */
35
- readonly range: string;
36
- /** Packages that identify the ORM family in a project. */
37
- readonly familyPackages: readonly string[];
38
- /** Database providers, in the adapter's order; the first is the default. */
39
- readonly providers: readonly string[];
40
- /** Provider → the driver adapter package for it. */
41
- readonly drivers: Readonly<Record<string, string>>;
42
- /** The ORM generators whose output the adapter reads. */
43
- readonly generators: readonly string[];
44
- /** The adapter's generate step: its one `bin`. */
45
- readonly bin: string;
46
- };
47
- export type AdapterCatalog = readonly CatalogEntry[];
48
- /** The generated catalog's literal type: what the template registry is checked against. */
49
- export type Catalog = typeof ADAPTER_CATALOG;
50
- export type EntryId = Catalog[number]["id"];
51
- /** The providers one entry declares, as literals. */
52
- export type ProviderOf<I extends EntryId> = Extract<Catalog[number], {
53
- readonly id: I;
54
- }>["providers"][number];
@@ -1,40 +0,0 @@
1
- import type { AdapterCatalog, CatalogEntry } from "./catalog-entry.interface.js";
2
- /**
3
- * 1. The ORM family: the catalog entries whose family packages the project depends
4
- * on (a pattern ending in `*` is a prefix).
5
- * 2. Every other family package installed must be of that same major — a Prisma 8
6
- * CLI or an `@prisma/orm-*` beside a Prisma 7 client is a project
7
- * mid-migration, refused.
8
- * 3. The entry for that major, or a refusal naming what exists.
9
- * 4. The installed version inside the entry's declared range.
10
- * 5. Then what the project's ORM setup declares — provider, driver, generator —
11
- * against the entry's providers, drivers and generators.
12
- *
13
- * Every refusal is one sentence naming what was found and what the catalog offers.
14
- * Nothing has been written when one is raised.
15
- */
16
- export type MatchVerdict = {
17
- readonly kind: "matched";
18
- readonly entry: CatalogEntry;
19
- } | {
20
- readonly kind: "refused";
21
- readonly sentence: string;
22
- };
23
- export type InstalledOrm = {
24
- /** The project's dependency names (dependencies and devDependencies). */
25
- readonly dependencies: readonly string[];
26
- /** The installed version of a package, or `undefined` when it is not installed. */
27
- readonly installedVersion: (name: string) => string | undefined;
28
- /** The command that installs the project's dependencies. */
29
- readonly installCommand: string;
30
- };
31
- /** What the project's ORM setup states, read by the entry's templates. */
32
- export type OrmSetup = {
33
- readonly provider: string | undefined;
34
- readonly generator: string | undefined;
35
- /** The driver-adapter packages the project depends on. */
36
- readonly drivers: readonly string[];
37
- };
38
- export declare function matchInstalledOrm(catalog: AdapterCatalog, project: InstalledOrm): MatchVerdict;
39
- /** Step 5: the project's provider, driver and generator against what `entry` declares. */
40
- export declare function matchOrmSetup(entry: CatalogEntry, setup: OrmSetup): string | undefined;
@@ -1,11 +0,0 @@
1
- /** `^7.10.0` → `7.10.0`; `>=7.10.0 <8` → `7.10.0`. */
2
- export declare function lowestVersionOf(range: string): string;
3
- /** `^12.0.1` → 12; `~6.0.2` → 6; a range with no number (`latest`, `*`) → `undefined`. */
4
- export declare function lowestMajorOf(range: string): number | undefined;
5
- /**
6
- * Whether an installed `version` is in a declared `range`. Reads the comparator
7
- * forms an adapter's peer range uses; a pre-release never satisfies (semver's rule
8
- * for a range whose comparators carry none). Any other form is refused rather than
9
- * guessed.
10
- */
11
- export declare function satisfiesRange(version: string, range: string): boolean;
package/dist/cli.d.ts DELETED
@@ -1,29 +0,0 @@
1
- import type { AdapterCatalog } from "./catalog/catalog-entry.interface.js";
2
- import { type CommandRunner } from "./run/command.runner.js";
3
- import { type Prompter } from "./wizard/answer.resolver.js";
4
- /**
5
- * `aventara` — the bin: `new` and `init`. A refusal is one sentence on stderr and
6
- * exit 1, never a stack; anything else is a defect and keeps its stack.
7
- *
8
- * `init` initializes the project in the working directory
9
- * (`run/init.orchestrator.ts`); `new` creates one with the pinned `nest new` and
10
- * then runs the same pipeline over it (`run/new.orchestrator.ts`).
11
- */
12
- export type CliIo = {
13
- /** The working directory: where `init` initializes and `new` creates. */
14
- readonly cwd: string;
15
- readonly env: Readonly<Record<string, string | undefined>>;
16
- readonly stdout: (text: string) => void;
17
- readonly stderr: (text: string) => void;
18
- readonly prompter: Prompter;
19
- readonly runner?: CommandRunner;
20
- readonly catalog?: AdapterCatalog;
21
- };
22
- export declare function runCli(argv: readonly string[], io: CliIo): Promise<number>;
23
- /**
24
- * Runs `aventara` over this process — its arguments, its terminal, its exit
25
- * code. Called by the bin's entry (`aventara.bin.ts`) once the Node guard has
26
- * admitted this Node; importing this module runs nothing, which lets `runCli`
27
- * be tested in process.
28
- */
29
- export declare function runFromProcess(): Promise<void>;
@@ -1,38 +0,0 @@
1
- import type { AdapterCatalog } from "../catalog/catalog-entry.interface.js";
2
- import { type QuestionId } from "../wizard/wizard.questions.js";
3
- /**
4
- * The `aventara` command line: `new <name>` and `init`, each question's flag from
5
- * the wizard's table, and the options that are not questions. Unknown, misplaced
6
- * or repeated arguments are refused in one sentence; a flag's VALUE is the
7
- * question's to judge, because what is valid (`--db`'s providers) depends on the
8
- * catalog and on earlier answers.
9
- */
10
- export type ScaffoldCommandName = "new" | "init";
11
- export type ScaffoldCommand = {
12
- readonly command: ScaffoldCommandName;
13
- /** Raw answers by question, from flags and `new`'s positional `<name>`. */
14
- readonly given: Readonly<Partial<Record<QuestionId, string>>>;
15
- readonly skipInstall: boolean;
16
- /** `new` only: passed through to `nest new`. */
17
- readonly skipGit: boolean;
18
- /** Accepts each unanswered question's default and confirms overwrites. */
19
- readonly yes: boolean;
20
- };
21
- export type CliCommand =
22
- /** `--help`; with `topic`, `aventara <topic> --help` (pilot.1). */
23
- {
24
- readonly command: "help";
25
- readonly topic?: ScaffoldCommandName;
26
- } | {
27
- readonly command: "version";
28
- } | ScaffoldCommand;
29
- /** The command line cannot be understood. A refusal: one sentence, exit 1. */
30
- export declare class CliCommandError extends Error {
31
- readonly name = "CliCommandError";
32
- }
33
- /** `aventara <command> --help` (pilot.1): that command's usage alone. */
34
- export declare function commandUsage(command: ScaffoldCommandName, catalog: AdapterCatalog): string;
35
- /** `aventara --help`: both commands, each flag with the values `catalog` offers. */
36
- export declare function usage(catalog: AdapterCatalog): string;
37
- /** @throws CliCommandError when `argv` is not a command this CLI has. */
38
- export declare function parseCliCommand(argv: readonly string[]): CliCommand;
@@ -1,8 +0,0 @@
1
- /** The sentence a bin answers on `version`, or `undefined` when `range` admits it. */
2
- export declare function nodeVersionRefusal(bin: string, packageName: string, range: string, version: string): string | undefined;
3
- /**
4
- * Reads the manifest at `manifestUrl`; on a Node its `engines.node` does not
5
- * admit, writes the sentence to stderr, sets exit code 1 and answers `true` —
6
- * the bin then loads nothing else.
7
- */
8
- export declare function refuseUnsupportedNode(bin: string, manifestUrl: URL): boolean;
@@ -1,53 +0,0 @@
1
- import type { CatalogEntry } from "../catalog/catalog-entry.interface.js";
2
- import { type ProjectInspection } from "../project/project.inspector.js";
3
- import { type OrmScaffold } from "../templates/template.registry.js";
4
- import type { PackageManager } from "../wizard/wizard.questions.js";
5
- /**
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.
11
- */
12
- export declare const PREPARE_SCRIPT = "aventara:prepare";
13
- export type PlannedWrite = {
14
- readonly path: string;
15
- readonly content: string;
16
- /** `create` a new file, or `replace` one whose content changes. */
17
- readonly change: "create" | "replace";
18
- };
19
- export type ProjectPlan = {
20
- /** What is written when the conflicts are kept as they are. */
21
- readonly keeping: readonly PlannedWrite[];
22
- /** What is written once the conflicts are confirmed (`--yes`, or a yes). */
23
- readonly replacing: readonly PlannedWrite[];
24
- /** Existing content that differs from what would be written. */
25
- readonly conflicts: readonly string[];
26
- readonly warnings: readonly string[];
27
- /** Printed when the anchored edit could not be made. */
28
- readonly instructions: string | undefined;
29
- readonly nextSteps: readonly string[];
30
- };
31
- export type PlanInput = {
32
- readonly inspection: ProjectInspection;
33
- readonly entry: CatalogEntry;
34
- readonly scaffold: OrmScaffold;
35
- readonly packageManager: PackageManager;
36
- /** This CLI's version: every Aventara package is pinned to it. */
37
- readonly aventaraVersion: string;
38
- readonly skipInstall: boolean;
39
- /** The current text of a project file, or `undefined` when absent. */
40
- readonly read: (file: string) => string | undefined;
41
- /** The anchored edit is not attempted; the wiring is printed. */
42
- readonly wiringByHand?: string;
43
- /** Said before the write, beside the planner's own. */
44
- readonly warnings?: readonly string[];
45
- };
46
- /**
47
- * pilot.1 — the frontend's first command, as the developer can run it: the
48
- * package manager's own one-off runner (`npx` or `pnpm dlx`), and — while this
49
- * CLI is a prerelease — its dist-tag, so the client comes from the same release
50
- * (`0.1.0-pilot.1` → `@aventara/client@pilot`). A release has no tag to name.
51
- */
52
- export declare function frontendInitCommand(packageManager: PackageManager, cliVersion: string): string;
53
- export declare function planInit(input: PlanInput): ProjectPlan;
@@ -1,5 +0,0 @@
1
- import type { PackageManager } from "../wizard/wizard.questions.js";
2
- export declare function detectPackageManager(signals: {
3
- readonly lockfile?: PackageManager | undefined;
4
- readonly userAgent?: string | undefined;
5
- }): PackageManager;
@@ -1,32 +0,0 @@
1
- import type { PackageManifest } from "../apply/manifest.merger.js";
2
- import type { AdapterCatalog, CatalogEntry } from "../catalog/catalog-entry.interface.js";
3
- import type { ModuleKind } from "../templates/template.registry.js";
4
- import type { PackageManager } from "../wizard/wizard.questions.js";
5
- /** The project is not one `aventara init` serves. A refusal: one sentence, nothing written. */
6
- export declare class ProjectRefusedError extends Error {
7
- readonly name = "ProjectRefusedError";
8
- }
9
- /** The ORM a project already has, by the catalog's family packages. */
10
- export type OrmPresence = {
11
- readonly kind: "absent";
12
- } | {
13
- readonly kind: "present";
14
- /** The family packages found among its dependencies. */
15
- readonly packages: readonly string[];
16
- /** The catalog entries whose family they belong to. */
17
- readonly families: readonly CatalogEntry["orm"]["label"][];
18
- };
19
- export type ProjectInspection = {
20
- readonly directory: string;
21
- readonly manifest: PackageManifest;
22
- readonly manifestText: string;
23
- readonly moduleKind: ModuleKind;
24
- /** The package manager the lockfile names, if exactly one does. */
25
- readonly lockfile: PackageManager | undefined;
26
- readonly orm: OrmPresence;
27
- /** `@nestjs/config` loads `.env` itself, so the start scripts are left alone. */
28
- readonly usesNestConfig: boolean;
29
- };
30
- /** The file the anchored edit opens. */
31
- export declare const APP_MODULE = "src/app.module.ts";
32
- export declare function inspectProject(directory: string, catalog: AdapterCatalog): ProjectInspection;
@@ -1,40 +0,0 @@
1
- /**
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).
5
- * 3. **Modules**: each `@Module({…})`-decorated exported class with the
6
- * identifiers its `providers` and `exports` list, and whether it is
7
- * `@Global()`.
8
- *
9
- * Which of them is *the* service is the caller's question (the wizard's).
10
- */
11
- export type ExportReference = {
12
- /** Relative to the project root, POSIX separators. */
13
- readonly file: string;
14
- readonly exportName: string;
15
- };
16
- export type ServiceComposition = ExportReference & {
17
- /** The member that holds the client. */
18
- readonly member: string;
19
- };
20
- export type ModuleDeclaration = ExportReference & {
21
- readonly providers: readonly string[];
22
- readonly exports: readonly string[];
23
- readonly global: boolean;
24
- };
25
- export type ServiceScan = {
26
- readonly candidates: readonly ExportReference[];
27
- readonly compositions: readonly ServiceComposition[];
28
- readonly modules: readonly ModuleDeclaration[];
29
- };
30
- export type ClientShape = {
31
- /** The client class a service extends, e.g. the ORM's generated client. */
32
- readonly clientClass: string;
33
- /** Whether `specifier`, imported by `file` (project-relative), is the client's module. */
34
- readonly importsClient: (specifier: string, file: string) => boolean;
35
- /** Directories under `src/` that hold generated code, skipped. */
36
- readonly skip: readonly string[];
37
- };
38
- export declare function scanServices(directory: string, shape: ClientShape): ServiceScan;
39
- /** The modules that make `service` injectable elsewhere: providing and exporting it, or global. */
40
- export declare function modulesProviding(scan: ServiceScan, service: ExportReference): readonly ModuleDeclaration[];
@@ -1,16 +0,0 @@
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
- export declare function codeMask(text: string): boolean[];
11
- /** Every index where `token` starts in code. */
12
- export declare function codeIndexes(text: string, code: boolean[], token: RegExp): number[];
13
- export declare const OPENERS: Readonly<Record<string, string>>;
14
- /** The index of the bracket closing the one at `open`, counting code brackets only. */
15
- export declare function closing(text: string, code: boolean[], open: number): number;
16
- export declare function nextCode(text: string, code: boolean[], from: number): number;
@@ -1,15 +0,0 @@
1
- /**
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
- */
7
- export type CommandResult = {
8
- readonly code: number;
9
- readonly stdout: string;
10
- readonly stderr: string;
11
- };
12
- export type CommandRunner = (command: string, args: readonly string[], options: {
13
- readonly cwd: string;
14
- }) => Promise<CommandResult>;
15
- export declare const runCommand: CommandRunner;
@@ -1,27 +0,0 @@
1
- import type { AdapterCatalog } from "../catalog/catalog-entry.interface.js";
2
- import type { ScaffoldCommand } from "../command/command.parser.js";
3
- import { type Prompter } from "../wizard/answer.resolver.js";
4
- import type { CommandRunner } from "./command.runner.js";
5
- /**
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.
9
- */
10
- export type InitIo = {
11
- readonly directory: string;
12
- readonly env: Readonly<Record<string, string | undefined>>;
13
- readonly stdout: (text: string) => void;
14
- readonly stderr: (text: string) => void;
15
- readonly prompter: Prompter;
16
- readonly runner: CommandRunner;
17
- readonly catalog: AdapterCatalog;
18
- /** This CLI's own version. */
19
- readonly aventaraVersion: string;
20
- /** Next steps that come before init's own (`new`'s `cd <name>`). */
21
- readonly firstSteps?: readonly string[];
22
- };
23
- /** The install step failed after the files were written. Reported, exit 1. */
24
- export declare class InstallFailedError extends Error {
25
- readonly name = "InstallFailedError";
26
- }
27
- export declare function runInit(command: ScaffoldCommand, io: InitIo): Promise<number>;
@@ -1,20 +0,0 @@
1
- import type { ScaffoldCommand } from "../command/command.parser.js";
2
- import { type InitIo } from "./init.orchestrator.js";
3
- /**
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
7
- * — and, after the install, the project's first commit (`scaffold.committer.ts`,
8
- * pilot.3).
9
- *
10
- * Nest authors its own scaffold: the CLI never writes Nest's files. Its output is
11
- * pinned by digest, so a `@nestjs/cli` that writes something else stops the run
12
- * before anything of Aventara's is written over it.
13
- */
14
- export declare const NEST_CLI = "@nestjs/cli@12.0.8";
15
- export declare const NEST_APP_MODULE_SHA256 = "fe98c4cd2552342272494652287c02e4ef58db3072fcb18513ea831c60f85778";
16
- export type NewIo = Omit<InitIo, "directory"> & {
17
- /** Where `new` creates the project directory. */
18
- readonly cwd: string;
19
- };
20
- export declare function runNew(command: ScaffoldCommand, io: NewIo): Promise<number>;