@aventara/client 0.1.0-pilot.2 → 0.1.0-pilot.4

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 +11 -13
  2. package/dist/cli/command.parser.d.ts +1 -13
  3. package/dist/cli/generation-success.renderer.d.ts +0 -4
  4. package/dist/cli/terminal.prompter.d.ts +0 -6
  5. package/dist/cli/warning.renderer.d.ts +0 -6
  6. package/dist/cli.d.ts +0 -16
  7. package/dist/config/client-config.interface.d.ts +10 -20
  8. package/dist/config/config.loader.d.ts +0 -21
  9. package/dist/config/config.resolver.d.ts +2 -17
  10. package/dist/config/env.cascade.d.ts +0 -30
  11. package/dist/config/module-style.resolver.d.ts +0 -25
  12. package/dist/config/tsconfig.locator.d.ts +0 -24
  13. package/dist/contract/contract.acceptance.d.ts +0 -39
  14. package/dist/contract/contract.fetcher.d.ts +0 -29
  15. package/dist/contract/contract.loader.d.ts +0 -7
  16. package/dist/emit/banner.emitter.d.ts +0 -18
  17. package/dist/emit/banner.emitter.js +1 -1
  18. package/dist/emit/client-surface.emitter.d.ts +0 -23
  19. package/dist/emit/client-tree.emitter.d.ts +0 -20
  20. package/dist/emit/contract-carrier.emitter.d.ts +0 -7
  21. package/dist/emit/derivation.emitter.d.ts +0 -28
  22. package/dist/emit/emitted-tree.interface.d.ts +0 -53
  23. package/dist/emit/enum.emitter.d.ts +0 -20
  24. package/dist/emit/module-specifier.scanner.d.ts +0 -15
  25. package/dist/emit/module-style.interface.d.ts +0 -15
  26. package/dist/emit/name.deriver.d.ts +0 -71
  27. package/dist/emit/named-type.emitter.d.ts +0 -20
  28. package/dist/emit/runtime.emitter.d.ts +0 -50
  29. package/dist/emit/runtime.emitter.js +12 -19
  30. package/dist/emit/scalar.codec.d.ts +0 -39
  31. package/dist/emit/transaction.emitter.d.ts +0 -6
  32. package/dist/emit/transaction.emitter.js +3 -5
  33. package/dist/generate.d.ts +0 -33
  34. package/dist/index.d.ts +1 -5
  35. package/dist/init/client-config.template.d.ts +0 -8
  36. package/dist/init/client-init.orchestrator.js +7 -0
  37. package/dist/init/client-init.planner.d.ts +0 -1
  38. package/dist/init/client-init.planner.js +10 -0
  39. package/dist/init/client-init.questions.d.ts +0 -8
  40. package/dist/output/output.validator.d.ts +16 -33
  41. package/dist/output/output.validator.js +68 -16
  42. package/dist/output/output.writer.d.ts +1 -107
  43. package/dist/output/output.writer.js +2 -2
  44. package/package.json +3 -3
package/README.md CHANGED
@@ -6,7 +6,7 @@ client is the product: it imports nothing from this package, or from `@aventara/
6
6
 
7
7
  Every argument and result type in the generated client is core's own derivation — `@aventara/core`'s published
8
8
  declarations, copied into the tree and instantiated over the deployment's ClientContract — so the client agrees with the
9
- server by construction, and that agreement is gated over both pilot schemas.
9
+ server by construction.
10
10
 
11
11
  ## Setting up a frontend: `avclient init`
12
12
 
@@ -91,8 +91,9 @@ supported yet.
91
91
  - **A failed run leaves the previous output exactly as it was.** The whole tree is written to a staging directory inside
92
92
  `generateAt`, validated there as one program, and only then moved into place. A run killed part-way is repaired by the
93
93
  next run that writes, before it writes anything. A first run that fails removes the directories it created.
94
- - **The validate step is a real type check** when the optional peer `typescript` (5.5 to 6) is installed, under a
95
- consumer's strictest plausible settings and with nothing outside the tree resolvable. Without it — or under
94
+ - **The validate step is a real type check** when your project has the optional peer `typescript` (5.5 to 6) — it is
95
+ resolved from your project, so `npx @aventara/client@pilot init` type-checks too — under a consumer's strictest plausible
96
+ settings and with nothing outside the tree resolvable. Without it — or under
96
97
  TypeScript 7, which has no classic compiler API to check with — the check degrades to a parse with Node's own
97
98
  TypeScript parser, and says so loudly in one warning; it is never skipped, and the client is still written. The peer
98
99
  range has no upper bound, so a frontend on TypeScript 7 installs it; your own `tsc` checks the tree when it compiles.
@@ -209,11 +210,9 @@ chose. The `.d.ts` files are core's copied declarations under `generated/derivat
209
210
  `UserUniqueWhere`, `UserOrderBy`, `UserCreateData`, `UserUpdateData`, `UserSelect`, `UserInclude`), each only when
210
211
  its operation is advertised.
211
212
 
212
- The tree is self-contained: every import in it names a file in it. That is gated twice in this package's tests — once
213
- lexically, once by compiling the tree alone where nothing outside it can resolve — and each gate catches a planted
214
- import of `@aventara/core` or `@aventara/client` on its own. Names a TypeScript declaration cannot carry as-is (a
215
- reserved word, a name the runtime owns, an enum sharing a Resource's name) are renamed, with one warning each; the wire
216
- name is kept.
213
+ The tree is self-contained: every import in it names a file in it, so it compiles with nothing else installed. Names a TypeScript
214
+ declaration cannot carry as-is (a reserved word, a name the runtime owns, an enum sharing a Resource's name) are
215
+ renamed, with one warning each; the wire name is kept.
217
216
 
218
217
  ## What a generated client is bound to
219
218
 
@@ -236,11 +235,10 @@ doing so re-binds nothing — the ClientContract hash still decides whether that
236
235
 
237
236
  ## Type-checking cost in a consumer
238
237
 
239
- A consumer pays for the calls it type-checks, not for the schema — under `skipLibCheck: true` (the common default),
240
- where the named types (`generated/types.d.ts`) and core's derivation are declaration files checked only where read:
241
- about 33,000 instantiations for a 50-Resource schema and seven typed calls. Under `skipLibCheck: false` every named type
242
- is resolved where it is declared, about 2,900 instantiations per Resource: about 204,000 for the same
243
- program, the 500,000 line near 150 Resources.
238
+ A consumer pays for the calls it type-checks, not for the schema, under `skipLibCheck: true` (the common default):
239
+ the named types (`generated/types.d.ts`) and core's derivation are declaration files checked only where read. Under
240
+ `skipLibCheck: false` every named type is resolved where it is declared, so the cost grows with the number of
241
+ Resources.
244
242
 
245
243
  ## Before 1.0
246
244
 
@@ -1,16 +1,6 @@
1
- /**
2
- * The `avclient` command line: one command, its one flag, and help. Everything the
3
- * generator needs is in `framework.client.ts` and the `.env` cascade, so
4
- * `generate` takes no flag that would duplicate a config member — a second source
5
- * of the same fact. `--yes` is not one: it answers the one question the generator
6
- * asks.
7
- */
8
1
  export declare const USAGE = "avclient \u2014 generate a typed Aventara client from a deployed ClientContract.\n\nUsage:\n avclient generate [--yes] Read framework.client.ts (or .js, .mjs, .cjs, .mts,\n .cts) in the current directory, fetch\n <entrypoint>/_contract, and write AvClient.ts and\n generated/ into its generateAt directory, its imports\n spelled as the project's tsconfig.json says.\n avclient init [options] Set up this frontend: write framework.client.ts, the\n .env entry, the avclient:generate script and the\n @aventara/client devDependency; install; generate.\n --entrypoint <url> The server's entrypoint [http://localhost:3000/api].\n --env-var <NAME> Read it from this variable [AVENTARA_API_URL].\n --no-env-var Write it into framework.client.ts as a literal.\n --generate-at <dir> Where the client goes [./src/api].\n --package-manager <npm|pnpm> [the lockfile's, else the launching one, else npm]\n --skip-install Print the install instead of running it.\n --skip-generate Do not generate now.\n -y, --yes Accept every default, and replace differing content.\n avclient --help Print this and exit 0.\n avclient <command> --help Print that command's usage and exit 0.\n avclient --version, -v Print this generator's version and exit 0.\n\nOptions:\n -y, --yes Overwrite or remove content in AvClient.ts and generated/ that the\n generator did not produce, without asking. Without it, such content\n is listed and you are asked; where nobody can answer (stdin is not a\n terminal, as in CI), the run is refused and nothing is touched.\n\nThe generator owns AvClient.ts and generated/ in generateAt, and nothing else\nthere: your own files beside them are never read, moved or removed. Generated\nfiles are replaced on every run; do not edit them.\n\nBefore framework.client.ts is evaluated, the .env cascade is read from the\ncurrent directory, highest precedence first: the process environment,\n.env.<mode>.local, .env.<mode>, .env.local, .env \u2014 where mode is NODE_ENV, or\n\"development\".\n";
9
- /** `avclient generate --help` (pilot.1): that command's usage alone. */
10
2
  export declare const GENERATE_USAGE = "Usage: avclient generate [--yes]\n\nRead framework.client.ts (or .js, .mjs, .cjs, .mts, .cts) in the current directory,\nfetch <entrypoint>/_contract, and write AvClient.ts and generated/ into its\ngenerateAt directory, its imports spelled as the project's tsconfig.json says.\n\nOptions:\n -y, --yes Overwrite or remove content in AvClient.ts and generated/ that the\n generator did not produce, without asking. Without it, such content\n is listed and you are asked; where nobody can answer (stdin is not a\n terminal, as in CI), the run is refused and nothing is touched.\n\nThe generator owns AvClient.ts and generated/ in generateAt, and nothing else\nthere: your own files beside them are never read, moved or removed.\n\nBefore the config is evaluated, the .env cascade is read from the current\ndirectory, highest precedence first: the process environment, .env.<mode>.local,\n.env.<mode>, .env.local, .env \u2014 where mode is NODE_ENV, or \"development\".\n";
11
- /** `avclient init --help` (pilot.1): that command's usage alone. */
12
3
  export declare const INIT_USAGE = "Usage: avclient init [options]\n\nSet up this frontend: write framework.client.ts, the .env entry, the avclient:generate\nscript and the @aventara/client devDependency; install; generate.\n\nOptions:\n --entrypoint <url> The server's entrypoint [http://localhost:3000/api].\n --env-var <NAME> Read it from this variable [AVENTARA_API_URL].\n --no-env-var Write it into framework.client.ts as a literal.\n --generate-at <dir> Where the client goes [./src/api].\n --package-manager <npm|pnpm> [the lockfile's, else the launching one, else npm]\n --skip-install Print the install instead of running it.\n --skip-generate Do not generate now.\n -y, --yes Accept every default, and replace differing content.\n\nOn a terminal every unanswered question is asked; anywhere else, pass its flag\nor --yes, or the run stops before writing anything.\n";
13
- /** `avclient init`'s command line. */
14
4
  export type ClientInitCommand = {
15
5
  readonly command: "init";
16
6
  readonly given: Readonly<Partial<Record<"entrypoint" | "envVar" | "generateAt" | "packageManager", string>>>;
@@ -20,9 +10,7 @@ export type ClientInitCommand = {
20
10
  readonly yes: boolean;
21
11
  };
22
12
  /** What the command line asked for. */
23
- export type CliCommand =
24
- /** `--help`; with `topic`, `avclient <topic> --help` (pilot.1). */
25
- {
13
+ export type CliCommand = {
26
14
  readonly command: "help";
27
15
  readonly topic?: "generate" | "init";
28
16
  } | {
@@ -13,10 +13,6 @@ export interface GenerationSuccessReport {
13
13
  readonly stderr: string;
14
14
  }
15
15
  export declare function renderGenerationSuccess(result: ClientGenerated): GenerationSuccessReport;
16
- /**
17
- * Nothing written: the deployment's ClientContract and these bytes are what is
18
- * there.
19
- */
20
16
  export declare function renderUpToDate(result: ClientUpToDate): GenerationSuccessReport;
21
17
  /**
22
18
  * What the person running the generator is told before being asked: every path
@@ -1,9 +1,3 @@
1
- /**
2
- * The terminal's questions — `generate`'s yes/no and `init`'s wizard — over one
3
- * `node:readline` interface whose lines are **queued**: a line typed (or piped
4
- * into a pseudo-terminal) before its question is kept for it, where a fresh
5
- * interface per question, or `readline/promises`' `question`, drops it.
6
- */
7
1
  export type TerminalPrompter = {
8
2
  readonly ask: (prompt: string) => Promise<string>;
9
3
  readonly confirm: (question: string) => Promise<boolean>;
@@ -1,9 +1,3 @@
1
- /**
2
- * How one warning reaches the person running the generator: its own stderr line,
3
- * under the CLI's one prefix. Warnings carry no prefix of their own, so the line
4
- * says "warning" once. Shared by a success and a refusal, so a warning reads the
5
- * same either way.
6
- */
7
1
  /** The prefix every warning line opens with. */
8
2
  export declare const WARNING_LINE_PREFIX = "avclient: warning: ";
9
3
  /** One newline-terminated line per warning, in the order given; empty for none. */
package/dist/cli.d.ts CHANGED
@@ -1,21 +1,5 @@
1
1
  import { type CliIo } from "./cli/generate.command.js";
2
2
  export type { CliIo } from "./cli/generate.command.js";
3
- /**
4
- * It is also the one place that ASKS: when content the generator did not produce
5
- * stands in `AvClient.ts` or `generated/`, the paths are listed and the person is
6
- * asked whether to overwrite them. `--yes` answers for them. Where nobody can
7
- * answer — stdin is not a terminal — it never asks and never overrides: it
8
- * refuses, naming `--yes`. Cancelled or refused, nothing was touched, the run's
9
- * warnings are printed before the sentence, and the exit code is 1. A killed run's
10
- * leftovers are looked at before the question, so the answer — and `--yes` —
11
- * covers what it hid as well.
12
- */
13
3
  /** Runs one command line; resolves to the exit code. Never throws. */
14
4
  export declare function runCli(argv: readonly string[], io: CliIo): Promise<number>;
15
- /**
16
- * Runs `avclient` over this process — its arguments, its terminal, its exit
17
- * code. Called by the bin's entry (`avclient.bin.ts`) once the Node guard has
18
- * admitted this Node; importing this module runs nothing, which is what lets
19
- * `runCli` be tested in process.
20
- */
21
5
  export declare function runFromProcess(): Promise<void>;
@@ -1,33 +1,31 @@
1
- /**
2
- * The generator's configuration, in its two states.
3
- *
4
- * `ClientConfigInput` is what a `framework.client.ts` default-exports through
5
- * `defineClientConfig`. It is passive data: an environment variable appears as an
6
- * `EnvReference`, a NAME to look up, so the file can be evaluated without the
7
- * environment having been loaded into the global and resolution stays a pure
8
- * function of the input and an `EnvRecord`.
9
- */
10
1
  /** A deferred read of one environment variable from the resolved cascade. */
11
2
  export interface EnvReference {
3
+ /** Always `"env"`. */
12
4
  readonly kind: "env";
5
+ /** The environment variable's name. */
13
6
  readonly name: string;
14
7
  }
15
8
  /** A value written literally, or read from the resolved environment. */
16
9
  export type ConfigValue = string | EnvReference;
10
+ /**
11
+ * What a `framework.client.ts` default-exports through `defineClientConfig`.
12
+ * Plain data: an environment variable appears as an `EnvReference` (`env("NAME")`),
13
+ * a name to look up, so the file can be evaluated before the environment is loaded.
14
+ */
17
15
  export interface ClientConfigInput {
18
16
  /** The full deployed framework entrypoint: origin plus mount path. */
19
17
  readonly entrypoint: ConfigValue;
20
18
  /**
21
19
  * The directory the client is generated into, relative to the config file's
22
- * directory. It is SHARED: the generator owns only `AvClient.ts` and `generated/`
23
- * in it, and never touches anything else there.
20
+ * directory. It is shared: the generator writes only `AvClient.ts` and
21
+ * `generated/` in it, and never touches anything else there.
24
22
  */
25
23
  readonly generateAt: ConfigValue;
26
24
  /**
27
25
  * The `tsconfig.json` the generated client is written for, relative to the
28
26
  * config file's directory — only for a layout the discovery gets wrong (a
29
27
  * monorepo, a non-standard name). Absent, the nearest `tsconfig.json` above
30
- * `generateAt` (`tsconfig.locator.ts`).
28
+ * `generateAt` is used.
31
29
  */
32
30
  readonly tsconfigFile?: string;
33
31
  }
@@ -35,17 +33,9 @@ export interface ClientConfigInput {
35
33
  export type AbsolutePath = string & {
36
34
  readonly __absolutePath: true;
37
35
  };
38
- /**
39
- * Root is the empty string, not `"/"`, so every route is `path + "/<route>"` with
40
- * no special case. Only resolution makes one.
41
- */
42
36
  export type EntrypointPath = ("" | `/${string}`) & {
43
37
  readonly __entrypointPath: true;
44
38
  };
45
- /**
46
- * The deployed entrypoint, normalised once at resolution so every consumer reads
47
- * one canonical form. Joining a route onto it is concatenation.
48
- */
49
39
  export interface ClientEntrypoint {
50
40
  /**
51
41
  * The deployment the entrypoint addresses: scheme, credentials, host and port.
@@ -1,25 +1,4 @@
1
1
  import type { ClientConfigInput } from "./client-config.interface.js";
2
- /**
3
- * Finds and evaluates the client config, `framework.client.<ext>`, the way
4
- * Prisma 7 loads `prisma.config.ts` (`@prisma/config` 7.10's
5
- * `loadConfigFromFile`): through `c12`, which evaluates it with `jiti`
6
- * (`interopDefault`, no module cache), with no `.env` loading, no rc file, no
7
- * remote or `extends` layers and no `package.json` key. So any of
8
- * {@link CLIENT_CONFIG_FILE_EXTENSIONS} — Prisma's own list — in ES module or
9
- * CommonJS syntax, whatever the project's `"type"`, TypeScript included, with
10
- * no compiler of the project's needed (pilot.1's `.mts` rule is gone: jiti, not
11
- * Node, decides how the file is read).
12
- *
13
- * One file, looked up in one directory — no search up the tree — and when more
14
- * than one is present the run refuses rather than choose: two files would be
15
- * two sources of the same fact. What the file imports — `@aventara/client` for
16
- * `defineClientConfig` and `env` — resolves from the consumer's project, as any
17
- * import of theirs would.
18
- *
19
- * The evaluated value is checked against `ClientConfigInput`'s shape before it
20
- * is trusted: the config is the consumer's code, and a typo there should be a
21
- * sentence naming the member, not a `TypeError` from deep inside resolution.
22
- */
23
2
  /** Prisma's `SUPPORTED_EXTENSIONS`, in its order. */
24
3
  export declare const CLIENT_CONFIG_FILE_EXTENSIONS: readonly [".js", ".ts", ".mjs", ".cjs", ".mts", ".cts"];
25
4
  /** The config's name, before its extension. */
@@ -1,8 +1,8 @@
1
1
  import type { ClientConfigInput, ClientEntrypoint, EnvReference, ResolvedClientConfig } from "./client-config.interface.js";
2
2
  import type { EnvCascadeResolution } from "./env.cascade.js";
3
- /** The identity function that gives a `framework.client.ts` its type. */
3
+ /** Gives a `framework.client.ts` its type: returns `config` unchanged. */
4
4
  export declare function defineClientConfig(config: ClientConfigInput): ClientConfigInput;
5
- /** Names an environment variable to be read from the resolved cascade. */
5
+ /** Names an environment variable to be read from the resolved environment. */
6
6
  export declare function env(name: string): EnvReference;
7
7
  /**
8
8
  * The configuration cannot be resolved. The message is the whole diagnosis — the
@@ -23,22 +23,7 @@ export interface ClientConfigResolutionInput {
23
23
  */
24
24
  export declare function resolveClientConfig(input: ClientConfigResolutionInput): ResolvedClientConfig;
25
25
  /**
26
- * An entrypoint value resolved to its canonical form. The URL half is this
27
- * function's: whitespace (which the URL parser would trim or drop unseen), a value
28
- * that is not an absolute URL, a scheme other than http(s), credentials, a query
29
- * or fragment (even an empty one, which the parser forgets), and a `..` segment
30
- * (which the parser would resolve away) are refused here, reading the value as
31
- * written.
32
- *
33
- * Only its slash spelling is coerced — `api`, `/api/` and `//api//` are one
34
- * intent, `/api` — and root is `""`.
35
- *
36
26
  * @throws ClientConfigError in one sentence that does not echo the value.
37
27
  */
38
28
  export declare function resolveEntrypoint(value: string): ClientEntrypoint;
39
- /**
40
- * The entrypoint as one absolute URL with no trailing slash — the form the emitted
41
- * transport joins its routes to, and the default a generated client embeds. Root
42
- * is the bare origin.
43
- */
44
29
  export declare function entrypointHref(entrypoint: ClientEntrypoint): string;
@@ -1,39 +1,9 @@
1
- /**
2
- * Precedence, highest first: the existing process environment >
3
- * `.env.<mode>.local` > `.env.<mode>` > `.env.local` > `.env`.
4
- *
5
- * # Why a returned record, and not `process.loadEnvFile`
6
- *
7
- * Measured on Node v24.20.0, `process.loadEnvFile` is first-write-wins and never
8
- * overrides an existing value — the right semantics — but it is the wrong
9
- * mechanism here, for three reasons that were measured rather than argued:
10
- *
11
- * 1. It writes into the live `process.env`. A resolution that mutates the global
12
- * leaks across tests and across invocations in one process; a suite that passes
13
- * alone and fails in sequence is exactly that leak.
14
- * 2. It reports an unreadable file (`EACCES`) as `ENOENT`. Catching `ENOENT` from
15
- * it would treat a `.env` the user cannot read as a `.env` that is not there —
16
- * a silent wrong answer.
17
- * 3. It silently drops lines that are not assignments. So does `util.parseEnv`;
18
- * neither has a notion of a malformed file.
19
- *
20
- * So each file is read with `readFileSync` (whose error code is the truth), parsed
21
- * with `util.parseEnv` (the same parser `loadEnvFile` uses — pinned by a parity
22
- * test), checked for lines the parser would discard, and folded first-write-wins
23
- * over the candidates in priority order. Nothing global is read or written: the
24
- * process environment is an INPUT.
25
- */
26
1
  /** A resolved environment: names to values, never `undefined`. */
27
2
  export type EnvRecord = Readonly<Record<string, string>>;
28
3
  /** The process environment as Node types it: values may be `undefined`. */
29
4
  export type ProcessEnvInput = Readonly<Record<string, string | undefined>>;
30
5
  /** The mode used when neither an explicit mode nor `NODE_ENV` supplies one. */
31
6
  export declare const DEFAULT_ENV_MODE = "development";
32
- /**
33
- * Reads one candidate file. Returns `undefined` only when the file does not
34
- * exist; any other failure throws. The seam exists so resolution can be tested
35
- * without a filesystem — the default reads from disk.
36
- */
37
7
  export type EnvFileReader = (filePath: string) => string | undefined;
38
8
  export interface EnvCascadeInput {
39
9
  /** The directory the five candidates are looked up in. */
@@ -1,31 +1,6 @@
1
1
  import type { TsConfigJsonResolved } from "get-tsconfig";
2
2
  import type { ClientModuleStyle, ImportFileExtension, ModuleFormat } from "../emit/module-style.interface.js";
3
3
  import { type LocatedTsconfig } from "./tsconfig.locator.js";
4
- /**
5
- * How the generated client is spelled for the project that compiles it: inferred
6
- * from the project's `tsconfig.json` (`tsconfig.locator.ts`) and, under
7
- * `node16`/`nodenext`, the nearest `package.json`, by Prisma 7.10's
8
- * `prisma-client` rules, mirrored from its CLI with the generated extension fixed
9
- * at `ts`:
10
- *
11
- * importFileExtension
12
- * 1. `allowImportingTsExtensions` or `rewriteRelativeImportExtensions` → `ts`;
13
- * 2. `module` is `commonjs`, or `moduleResolution` is `bundler` (either case) →
14
- * `""`;
15
- * 3. otherwise → `js` (Prisma's `ts → js`).
16
- *
17
- * moduleFormat
18
- * 1. `module` is `commonjs` → `cjs`;
19
- * 2. `module` is `node16` or `nodenext` → the nearest `package.json` above
20
- * `generateAt`: `"type": "module"` → `esm`; no `package.json`, an unparseable
21
- * one, or any other `type` → `cjs`;
22
- * 3. any other `module` → `esm`; no `module` → `esm` (Prisma's fallback, whose
23
- * `cjs` arm needs a generated `.cts`).
24
- *
25
- * Prisma falls back to the generated extension when there is no tsconfig; this
26
- * generator refuses instead: its client is TypeScript, and a project without a
27
- * tsconfig is a JavaScript project, not supported yet.
28
- */
29
4
  /** What the run follows, and where it read it from. */
30
5
  export interface ResolvedModuleStyle extends ClientModuleStyle {
31
6
  /** The tsconfig the style was inferred from. */
@@ -1,28 +1,4 @@
1
1
  import { type TsConfigJsonResolved } from "get-tsconfig";
2
- /**
3
- * Which `tsconfig.json` the generated client is spelled for
4
- * (`module-style.resolver.ts`): the project's own, found the way Prisma 7's
5
- * `prisma-client` generator finds it — `get-tsconfig`'s `getTsconfig`, the very
6
- * library and version Prisma 7.10 bundles, searching from the output directory
7
- * up, `extends` chains merged — with one step Prisma does not take.
8
- *
9
- * # A solution-style root (Vite's layout)
10
- *
11
- * `npm create vite` writes a `tsconfig.json` that compiles nothing — `"files":
12
- * []` and `references` to `tsconfig.app.json` and `tsconfig.node.json` — so the
13
- * nearest config names no compiler option at all. When the config found does
14
- * not include the generated entry file and has `references`, the referenced
15
- * project that does include it is the one used, the first in `references`
16
- * order — how TypeScript's own language service picks a file's project. With
17
- * none including it, the root stays the answer, as it is Prisma's.
18
- *
19
- * # `tsconfigFile`
20
- *
21
- * The escape hatch for a layout this discovery gets wrong (a monorepo, a
22
- * non-standard name): the config's `tsconfigFile`, resolved against the config
23
- * file's directory, used as named — no search, no reference step. A missing or
24
- * unreadable one is refused, naming the path it resolved to.
25
- */
26
2
  /** The tsconfig a run follows: its path and its resolved content (`extends` merged). */
27
3
  export interface LocatedTsconfig {
28
4
  readonly path: string;
@@ -1,47 +1,8 @@
1
1
  import { type ClientContract } from "@aventara/core";
2
- /**
3
- * # The structure check is core's, never a second implementation
4
- *
5
- * What a ClientContract IS belongs to core, so the structure step is core's
6
- * `validateClientContractStructure` and nothing here restates a member, a kind or
7
- * a vocabulary. Before it, a body with a valid envelope and a malformed member —
8
- * `resources: { Spell: 5 }` — reached core's canonicalizer, which reads members
9
- * without validating them, and escaped as a plain `TypeError` and a stack.
10
- *
11
- * # Protocol support is judged first, from a read rather than a rule
12
- *
13
- * A body from a protocol this generator does not speak may have a different
14
- * structure, and "unsupported" is then the true and useful answer. So the
15
- * advertised version is READ — leniently, never judged — and judged against the
16
- * supported set before any structure is. A body whose version cannot be read at
17
- * all goes on to the structure step, which names what is wrong with it.
18
- *
19
- * # A value, not a throw site
20
- *
21
- * # The hash is core's, never a second implementation
22
- *
23
- * The advertised `protocol.hash` is recomputed with `computeClientContractHash` —
24
- * the function the compiler stamps it with — and compared. A hash computed here
25
- * would be a second source of the Contract's identity.
26
- *
27
- * The ClientContract type admits values RFC 8785 cannot encode, and a valid JSON
28
- * body produces two of them: `1e999` parses to `Infinity`, and `"\ud800"` parses
29
- * to a lone surrogate. Core rejects both with `CanonicalJsonError`. No server can
30
- * have stamped a hash over such a body — its own canonicalizer would have refused
31
- * — so it is refused at THIS step, as `hash-mismatch` with its own sentence and
32
- * core's path, never let escape as a stack. ONLY that class is caught: anything
33
- * else thrown while hashing is not a known property of the input, and keeps its
34
- * stack as a defect.
35
- */
36
- /** The protocol versions this generator speaks. */
37
2
  export declare const SUPPORTED_PROTOCOL_VERSIONS: ReadonlySet<number>;
38
3
  export type ContractRejectionReason = "protocol-unsupported" | "hash-mismatch" | "structure-invalid";
39
4
  export type ContractAccepted = {
40
5
  readonly accepted: true;
41
- /**
42
- * Trusted to the depth this step checks: core's structure check and the hash. It
43
- * is the erased ClientContract: no capability is interpreted here.
44
- */
45
6
  readonly contract: ClientContract;
46
7
  };
47
8
  export type ContractRejected = {
@@ -1,18 +1,4 @@
1
1
  import type { ClientEntrypoint } from "../config/client-config.interface.js";
2
- /**
3
- * # Transport, and only transport
4
- *
5
- * This file's success is "a JSON value arrived". It does not judge the value: a
6
- * body that is a JSON array is still a successful fetch, and refusing it is
7
- * `contract.acceptance.ts`'s job. Every way of failing to produce a JSON value is
8
- * a `ContractTransportError`, a different class from `ContractProtocolError`,
9
- * because the two have different remedies — reach the deployment, versus
10
- * regenerate or upgrade against what it served — and a message that blurs them
11
- * sends the developer to the wrong one.
12
- *
13
- * `fetch` is injected, so the transport is tested without a server; the default is
14
- * the platform's.
15
- */
16
2
  /** The part of a `Response` the fetcher reads. */
17
3
  export type ContractResponse = Pick<Response, "ok" | "status" | "text">;
18
4
  /** The `fetch` the fetcher calls. `globalThis.fetch` satisfies it. */
@@ -20,10 +6,6 @@ export type ContractFetch = (url: URL, init: {
20
6
  readonly method: "GET";
21
7
  readonly headers?: Readonly<Record<string, string>>;
22
8
  }) => Promise<ContractResponse>;
23
- /**
24
- * What a conditional GET answers when the served ClientContract is the one named:
25
- * no body, nothing to judge.
26
- */
27
9
  export declare const CONTRACT_NOT_MODIFIED: unique symbol;
28
10
  export type ContractTransportFailureReason =
29
11
  /** No response at all: DNS, refused connection, TLS, abort. */
@@ -39,21 +21,10 @@ export declare class ContractTransportError extends Error {
39
21
  readonly name = "ContractTransportError";
40
22
  constructor(reason: ContractTransportFailureReason, message: string, options?: ErrorOptions);
41
23
  }
42
- /**
43
- * `<entrypoint>/_contract`: the canonical mount path and the route, concatenated.
44
- * The path's canonical form is resolution's — root is `""` — so the join repairs
45
- * nothing and special-cases nothing. URL resolution would be wrong here: `new
46
- * URL("_contract", "https://h/api")` replaces `api`.
47
- */
48
24
  export declare function contractUrlOf(entrypoint: ClientEntrypoint): URL;
49
25
  /** The URL as it may be printed: credentials in the entrypoint never are. */
50
26
  export declare function displayUrl(url: URL): string;
51
27
  /**
52
- * GETs the ClientContract and returns the parsed body, unjudged — or, when
53
- * `ifNoneMatch` (a quoted contract hash, the deployment's entity tag) is sent and
54
- * the deployment answers `304`, {@link CONTRACT_NOT_MODIFIED}. A `304` to a
55
- * request that sent none is no answer, like any other non-2xx.
56
- *
57
28
  * @throws ContractTransportError when no JSON value arrives.
58
29
  */
59
30
  export declare function fetchClientContractBody(entrypoint: ClientEntrypoint, fetch?: ContractFetch, ifNoneMatch?: string): Promise<unknown>;
@@ -1,14 +1,8 @@
1
1
  import type { ClientContract } from "@aventara/core";
2
2
  import type { ClientEntrypoint } from "../config/client-config.interface.js";
3
3
  import { type ContractFetch } from "./contract.fetcher.js";
4
- /**
5
- * Where the pipeline stops on a rejection, so it is where the `ContractRejected`
6
- * value becomes a thrown `ContractProtocolError`.
7
- */
8
4
  export interface ClientContractLoadInput {
9
- /** The client config's resolved entrypoint. */
10
5
  readonly entrypoint: ClientEntrypoint;
11
- /** Injected for tests; the platform `fetch` otherwise. */
12
6
  readonly fetch?: ContractFetch;
13
7
  }
14
8
  /**
@@ -16,7 +10,6 @@ export interface ClientContractLoadInput {
16
10
  * @throws ContractProtocolError when what arrived is refused.
17
11
  */
18
12
  export declare function loadClientContract(input: ClientContractLoadInput): Promise<ClientContract>;
19
- /** A ClientContract loaded against one the caller already holds. */
20
13
  export interface ClientContractSince {
21
14
  readonly contract: ClientContract;
22
15
  /** The deployment answered `304`: `contract` is the one the caller held. */
@@ -1,22 +1,4 @@
1
- /**
2
- * The banner line that says who owns a file. It is what the output writer reads to
3
- * decide that a directory is a previous generation it may replace whole rather
4
- * than someone's files it would delete — so it is its own constant, and must not
5
- * change between generator versions: an output written by an older generator has
6
- * to stay recognisable to a newer one.
7
- */
8
1
  export declare const GENERATED_OWNERSHIP_LINE = "/* !!! Generated by @aventara/client. Do not edit. !!! */";
9
- /**
10
- * The ownership banner every emitted file opens with.
11
- *
12
- * The Biome suppressions are EMITTED rather than configured, so the output stays
13
- * correct wherever a consumer drops it, including a repository whose formatter
14
- * nobody here chose.
15
- *
16
- * Nothing in it can change between two runs over one contract: no timestamp, no
17
- * generator version, no host, no path — any of them would break the exit gate's
18
- * byte-equality on the first re-run. And no driver prose.
19
- */
20
2
  export declare const GENERATED_BANNER: readonly string[];
21
3
  /** `source` with the banner before it and one blank line between. */
22
4
  export declare function withGeneratedBanner(source: string): string;
@@ -1,6 +1,6 @@
1
1
  export const GENERATED_OWNERSHIP_LINE = "/* !!! Generated by @aventara/client. Do not edit. !!! */";
2
2
  export const GENERATED_BANNER = [
3
- "// biome-ignore-all format: generated output; these bytes are the artifact",
3
+ "// biome-ignore-all format: generated output",
4
4
  "// biome-ignore-all lint: generated output",
5
5
  GENERATED_OWNERSHIP_LINE,
6
6
  "/* Regenerate with `avclient generate`. */",
@@ -2,27 +2,4 @@ import type { ClientContract } from "@aventara/core";
2
2
  import type { EmittedModule } from "./emitted-tree.interface.js";
3
3
  import { type ClientModuleStyle } from "./module-style.interface.js";
4
4
  import { type EmittedNames } from "./name.deriver.js";
5
- /**
6
- * `generated/client.ts` — the typed surface: the class `AvClient`, its options
7
- * `AvClientOptions` and the per-call `CallOptions`, and the ready instance
8
- * `avClient`, this module's default export.
9
- *
10
- * Every argument and result type is an instantiation of core's own derivation,
11
- * copied under `generated/derivation/`: the call grammar over the carrier's
12
- * contract, in the client's forms. Nothing here re-spells a rule. A call resolves
13
- * to the data, a first-style miss to `null`.
14
- *
15
- * Each surface is one mapped alias over the one contract. A Resource is reached by
16
- * its contract name, except where that name is one of the client's own members,
17
- * which renames the property only. `tx` and `transaction` exist iff the contract
18
- * advertises `interactive` transactions, in the type as in the runtime.
19
- *
20
- * Also declared here, for `types.d.ts` alone, the two helpers the named types are
21
- * aliases of: `ResourceRecord` and `ResourceArgument`.
22
- *
23
- * At runtime the class builds one frozen object per Resource from the advertised
24
- * operations — each variant a function that runs the operation through the
25
- * transport, reading the fetch when it is called — and the default entrypoint is
26
- * the generated one unless the options name another.
27
- */
28
5
  export declare function emitClientSurfaceModule(contract: ClientContract, names: EmittedNames, style: ClientModuleStyle): EmittedModule;
@@ -3,26 +3,6 @@ import type { ClientEntrypoint } from "../config/client-config.interface.js";
3
3
  import { type ClientEmission } from "./emitted-tree.interface.js";
4
4
  import { type ClientModuleStyle } from "./module-style.interface.js";
5
5
  /**
6
- * The banner, the encoding and the file order are applied HERE, once, over every
7
- * module — so no emitter can forget the banner, and byte-equality is a property of
8
- * this function rather than of each emitter's care:
9
- *
10
- * - every module opens with the generated banner;
11
- * - every file is UTF-8;
12
- * - files come in UTF-16 code-unit order of their path, each path once.
13
- *
14
- * The name derivation's rename warnings ride on the result beside the tree; this
15
- * function prints nothing.
16
- *
17
- * The names and enums read the enum registry, registry NAMES and `protocol`.
18
- * Core's derivation is copied under `generated/derivation/` as its published
19
- * declarations: read from the installed `@aventara/core`, never from the Contract.
20
- * The contract itself reaches the tree as three projections of the one accepted
21
- * contract: the carrier `generated/contract.ts`, the runtime's decode table and
22
- * advertised operations `generated/runtime/descriptor.ts`, and `metadata.ts`'s
23
- * hash, version and default entrypoint — the entrypoint being the run's other
24
- * input.
25
- *
26
6
  * @throws GeneratedNameError when a name cannot be emitted, even renamed.
27
7
  */
28
8
  export declare function emitClientTree(contract: ClientContract, entrypoint: ClientEntrypoint, style: ClientModuleStyle): ClientEmission;
@@ -2,11 +2,4 @@ import { type ClientContract } from "@aventara/core";
2
2
  import type { EmittedModule } from "./emitted-tree.interface.js";
3
3
  /** `generated/contract.ts`, before the banner. */
4
4
  export declare function emitContractCarrierModule(contract: ClientContract): EmittedModule;
5
- /**
6
- * The ClientContract a carrier file holds — its whole text, banner included — or
7
- * `undefined` when it is not one this generator wrote over a contract that still
8
- * verifies: a foreign prefix or suffix, bytes that are not JSON, a body that is
9
- * not a ClientContract or whose hash does not re-verify, or bytes that are not
10
- * that contract's canonical form. Never trusted otherwise.
11
- */
12
5
  export declare function parseContractCarrier(text: string): Promise<ClientContract | undefined>;
@@ -1,32 +1,4 @@
1
1
  import type { EmittedModule } from "./emitted-tree.interface.js";
2
- /**
3
- * The derivation, transported. A generated client's argument and result types are
4
- * core's own `OperationArgumentsFor`, `OperationResultFor` and the call grammar
5
- * (`OperationCall`, …) — never a second spelling. They reach the emitted tree as
6
- * core's PUBLISHED DECLARATIONS, copied under `generated/derivation/` at their
7
- * path relative to core's `dist`:
8
- *
9
- * - declarations, not sources: the sources' closure carries value imports (the
10
- * canonicaliser, the wire grammars), the declarations' carries none; a `.d.ts`
11
- * cannot carry runtime, so a bundler never sees one;
12
- * - under their own directory, so core's `runtime/decimal.d.ts` cannot shadow the
13
- * emitted `generated/runtime/decimal.ts`;
14
- * - byte for byte, except the trailing `//# sourceMappingURL=…` line, which names
15
- * a map the tree does not hold.
16
- *
17
- * The closure is walked here, at generation time, from {@link DERIVATION_ROOTS}
18
- * over whichever `@aventara/core` this package resolves — so the output is a
19
- * function of the core version the generator depends on, as the rest of it is a
20
- * function of the generator. A closure that names a package, carries a
21
- * triple-slash reference, or leaves core's declarations is refused: it cannot be
22
- * transported, and core's own gate (`emittable-closure.gate.spec.ts`) exists so
23
- * that it never is.
24
- */
25
- /**
26
- * The modules whose declarations the generated client copies — the roots of core's
27
- * `emittable-closure.gate.spec.ts`, mirrored (core cannot export a test constant,
28
- * and this package cannot read core's tests).
29
- */
30
2
  export declare const DERIVATION_ROOTS: readonly string[];
31
3
  /**
32
4
  * Reads one declaration file by its path relative to core's `dist`