@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
@@ -1,57 +1,14 @@
1
- /**
2
- * The generator's output as a VALUE before it is a filesystem effect.
3
- * Byte-equality is therefore testable without touching disk, and temp → validate →
4
- * replace is a property of the writer alone rather than of every emitter.
5
- */
6
1
  import type { ClientModuleStyle } from "./module-style.interface.js";
7
- /**
8
- * The output layout: the consumer names a directory, `generateAt`, which is SHARED
9
- * — they may keep their own files there. The generator owns exactly two entries in
10
- * it:
11
- *
12
- * - `AvClient.ts`, the entry point a consumer imports;
13
- * - `generated/`, every other module, owned and replaced whole.
14
- *
15
- * The tree is TypeScript source that the developer's own toolchain compiles like
16
- * their own files — `tsc`, Next.js (Turbopack or webpack), Vite, `tsx`, Node's
17
- * type stripping. pilot.1's tree always spelled its internal imports NodeNext's
18
- * way (`./generated/client.js`), which a bundler that does not map `.js` back to
19
- * `.ts` (Turbopack) and plain Node could not follow. Now those specifiers are the
20
- * project's: extensionless, `.js` or `.ts`, as its `tsconfig.json` decides
21
- * (`module-style.interface.ts`, Prisma 7's rules). A consumer imports the entry as
22
- * they import their own files — `./api/AvClient`, `./api/AvClient.js` or
23
- * `./api/AvClient.ts`.
24
- */
25
2
  /** The entry point, at the root of `generateAt`. */
26
3
  export declare const CLIENT_ENTRY_FILE = "AvClient.ts";
27
- /** The files the generator owns at the root of `generateAt`. */
28
4
  export declare const CLIENT_ENTRY_FILES: readonly ["AvClient.ts"];
29
5
  /** One of the entry point's files. */
30
6
  export type ClientEntryFile = (typeof CLIENT_ENTRY_FILES)[number];
31
- /**
32
- * Entry files an unreleased build of this generator wrote — JavaScript beside
33
- * declarations, never published. Each is the generator's only while it carries
34
- * the ownership line: a generation removes it then, so no stale `AvClient.mjs`
35
- * is left beside the `AvClient.ts` it was replaced by. One without the line is
36
- * the developer's file, and nothing reads, refuses on or removes it. (pilot.0's
37
- * and pilot.1's entry is `AvClient.ts` itself, replaced in place.)
38
- */
39
7
  export declare const LEGACY_CLIENT_ENTRY_FILES: readonly string[];
40
8
  /** The directory holding every other emitted module, under `generateAt`. */
41
9
  export declare const GENERATED_DIRECTORY = "generated";
42
- /**
43
- * One of core's published declaration files, copied under `generated/derivation/`
44
- * at its path relative to core's `dist`.
45
- */
46
10
  export type DerivationModulePath = `derivation/${string}.d.ts`;
47
- /**
48
- * Relative to `generated/`, POSIX-separated.
49
- */
50
11
  export type GeneratedModulePath = DerivationModulePath | "client.ts" | "contract.ts" | "enums.ts" | "metadata.ts" | "runtime/codec.ts" | "runtime/decimal.ts" | "runtime/descriptor.ts" | "runtime/errors.ts" | "runtime/fingerprint.ts" | "runtime/transaction.ts" | "runtime/transport.ts" | "types.d.ts";
51
- /**
52
- * The carrier: the ClientContract the tree was generated against, under
53
- * `generated/` — the module a rerun reads back to ask for a `304`.
54
- */
55
12
  export declare const CONTRACT_CARRIER_MODULE = "contract.ts";
56
13
  /** A path in the emitted tree: relative to `generateAt`, POSIX-separated. */
57
14
  export type EmittedFilePath = typeof CLIENT_ENTRY_FILE | `${typeof GENERATED_DIRECTORY}/${GeneratedModulePath}`;
@@ -65,17 +22,7 @@ export interface EmittedFile {
65
22
  readonly path: EmittedFilePath;
66
23
  readonly bytes: Uint8Array;
67
24
  }
68
- /**
69
- * Every file one generation emits, in UTF-16 code-unit order of `path`, each path
70
- * once — `AvClient.ts` first, then `generated/**`. Replaced, never merged:
71
- * `generated/` whole, `AvClient.ts` as one file.
72
- */
73
25
  export type EmittedTree = readonly EmittedFile[];
74
- /**
75
- * What emission yields: the tree, and the diagnostics a run raised without
76
- * failing — today, one line per renamed name (`name.deriver.ts`). Returned rather
77
- * than printed, so the code that owns the terminal decides where they go.
78
- */
79
26
  export interface ClientEmission {
80
27
  readonly tree: EmittedTree;
81
28
  /** The project's spelling the tree was emitted in, and is validated in. */
@@ -1,24 +1,4 @@
1
1
  import type { ClientContract } from "@aventara/core";
2
2
  import type { EmittedModule } from "./emitted-tree.interface.js";
3
3
  import { type EmittedNames } from "./name.deriver.js";
4
- /**
5
- * `enums.ts`: per enum, a string-literal union type and a same-named `as const`
6
- * object:
7
- *
8
- * ```ts
9
- * export type Role = "ADMIN" | "USER";
10
- * export const Role = { ADMIN: "ADMIN", USER: "USER" } as const;
11
- * ```
12
- *
13
- * The type is what every later emitter references; the object gives a consumer a
14
- * value to name a member by and to enumerate. Both are declared under the enum's
15
- * emitted identifier, which differs from its contract name only when the name was
16
- * renamed (`name.deriver.ts`). The values are the wire values and are never
17
- * renamed.
18
- *
19
- * Enums come in the order `names` gives them — UTF-16 code units of the contract
20
- * name — so the key order a contract arrives in never reaches the bytes. An enum's
21
- * VALUES keep their declared order, in the type and in the object: that order is
22
- * meaning, and canonical form keeps it too.
23
- */
24
4
  export declare function emitEnumsModule(contract: Pick<ClientContract, "enums">, names: EmittedNames): EmittedModule;
@@ -1,9 +1,3 @@
1
- /**
2
- * Which modules a file names, read without `typescript`: the derivation's copy
3
- * walks core's declaration closure by it (`derivation.emitter.ts`), and the output
4
- * validator checks by it that every module the emitted tree names is a file of the
5
- * tree, spelled the project's way — with or without a compiler.
6
- */
7
1
  export interface ScannedModule {
8
2
  /**
9
3
  * Every module specifier: a `from` clause's, a side-effect `import`'s, and an
@@ -13,13 +7,4 @@ export interface ScannedModule {
13
7
  /** Whether the file carries a `/// <reference …/>` directive. */
14
8
  readonly references: boolean;
15
9
  }
16
- /**
17
- * The specifiers one module names — a declaration file or JavaScript — read by a
18
- * small lexer rather than by `typescript` (an optional peer, absent from a
19
- * consumer's install): comments, string literals, template literals and
20
- * regular-expression literals are skipped as units, so text inside them is never
21
- * mistaken for an import. Agrees with TypeScript's own pre-processor over core's
22
- * closure (`derivation.emitter.spec.ts`) and over every emitted file
23
- * (`module-specifier.scanner.spec.ts`).
24
- */
25
10
  export declare function scanModuleSpecifiers(text: string): ScannedModule;
@@ -1,12 +1,3 @@
1
- /**
2
- * How the generated client's modules are spelled for the project that compiles
3
- * them. The client is TypeScript source — `.ts` files — and the developer's own
4
- * toolchain compiles it like their own files, so the relative specifiers by which
5
- * its modules name each other, and the module format they are checked in, follow
6
- * that project's rules. The names and the rules are Prisma 7's `prisma-client`
7
- * generator's (`importFileExtension`, `moduleFormat`), inferred from the project's
8
- * `tsconfig.json` (`config/module-style.resolver.ts`).
9
- */
10
1
  /**
11
2
  * The extension a relative import inside the generated client is written with:
12
3
  *
@@ -42,12 +33,6 @@ export interface ClientModuleStyle {
42
33
  * the module it imports.
43
34
  */
44
35
  export type ExtensionlessModulePath = `./${string}` | `../${string}`;
45
- /**
46
- * The specifier a generated module imports `module` by, in this style. One rule
47
- * for every target, `.ts` source and `.d.ts` declaration alike: TypeScript
48
- * resolves an extensionless, a `.js` and a `.ts` specifier to either (measured
49
- * under `nodenext` and `bundler`, TypeScript 5.9, 6 and 7).
50
- */
51
36
  export declare function importSpecifier(module: ExtensionlessModulePath, style: Pick<ClientModuleStyle, "importFileExtension">): string;
52
37
  /**
53
38
  * Writes the quoted specifier an emitted `import`/`export … from` names a
@@ -1,56 +1,6 @@
1
1
  import { type ClientContract, type OperationFamily } from "@aventara/core";
2
2
  /**
3
3
  * Name derivation and the rename ladder for the emitted tree.
4
- *
5
- * The name the server uses — the wire name a Resource is addressed by — is kept
6
- * beside it unchanged (`EmittedName.contractName`), so a later emitter that sends
7
- * a request reads that, never the identifier. Every rename is one warning line on
8
- * the result; generation does not print.
9
- *
10
- * A name is unusable as-is when it is not an identifier, is a reserved word, is a
11
- * predefined type's name, is a name the generated runtime owns, or — an enum only
12
- * — is also a Resource's name. Its ladder is tried in order and the first rung
13
- * that is usable AND free of every other emitted name (verbatim or renamed) wins:
14
- *
15
- * - Resource `X`: `XModel` → `ResourceX` → `X_` → `_X` → `_X_` → refused;
16
- * - enum `X`: `XEnum` → `EnumX` → `X_` → refused.
17
- *
18
- * Only a name whose whole ladder is unusable or taken is refused, in one sentence
19
- * — and a name no rename can repair, which is refused without trying a rung: the
20
- * empty name. Every rung of its ladder is a bare affix (`Model`, `Enum`, `_`) that
21
- * names nothing on the server, so "renaming" it would invent an identifier rather
22
- * than repair one.
23
- *
24
- * # Determinism
25
- *
26
- * The same Contract always yields the same names, whatever order its keys arrive
27
- * in: every name usable as-is is claimed first (so a usable name is never
28
- * displaced by another's rename), then Resources are renamed, then enums, each
29
- * registry in UTF-16 code-unit order of its contract names. An enum sharing a
30
- * Resource's name walks its ladder and the Resource keeps the name.
31
- *
32
- * # One namespace
33
- *
34
- * Names are case-sensitive.
35
- *
36
- * A Resource's base name is taken at the first rung — its own name first, when
37
- * usable — where the base AND every name derived from it are free of every other
38
- * emitted name: `User` beside a Resource `UserWhere` walks to `UserModel`, one
39
- * warning. Derived names a Resource claims are claimed for good, so a later
40
- * Resource or enum never takes one. The generated modules that declare these names
41
- * use no global type a Resource could shadow (`types.d.ts` imports two helpers,
42
- * which are reserved).
43
- *
44
- * A Resource is reached as a property of the client, named by its contract name. A
45
- * contract name equal to one of the client's own members ({@link
46
- * CLIENT_MEMBER_NAMES}) walks the Resource ladder for its PROPERTY only, one
47
- * warning; the wire name, and the TypeScript type names, are unaffected.
48
- *
49
- * Reads registry KEYS and which operations are advertised. No capability member.
50
- */
51
- /**
52
- * A Contract name equal to one of them walks its rename ladder. In UTF-16
53
- * code-unit order.
54
4
  */
55
5
  export declare const RESERVED_EMITTED_NAMES: readonly string[];
56
6
  export interface ResourceNamedType {
@@ -63,15 +13,6 @@ export interface ResourceNamedType {
63
13
  export declare const RESOURCE_NAMED_TYPES: readonly ResourceNamedType[];
64
14
  /** The named types a Resource with `operations` gets: those whose operation it advertises. */
65
15
  export declare function namedTypesOf(operations: unknown): readonly ResourceNamedType[];
66
- /**
67
- * The client's own members, which a Resource property must not shadow: `tx` and
68
- * `transaction` (reserved whether or not the contract advertises transactions, so
69
- * a property never moves with `transactions`), `then` — a client with a `then` is
70
- * a thenable, and `await` would call it — and every name `Object.prototype`
71
- * carries in ES2022, `constructor` among them. Fixed here, not read from the
72
- * running Node, so the output never moves with the generator's runtime. In UTF-16
73
- * code-unit order.
74
- */
75
16
  export declare const CLIENT_MEMBER_NAMES: readonly string[];
76
17
  /** One Contract name and the TypeScript identifier the tree declares it under. */
77
18
  export interface EmittedName {
@@ -80,7 +21,6 @@ export interface EmittedName {
80
21
  /** The identifier the emitted TypeScript declares; `contractName` unless renamed. */
81
22
  readonly identifier: string;
82
23
  }
83
- /** A Resource's property on the client: its contract name unless a member owns it. */
84
24
  export interface EmittedProperty {
85
25
  /** The name the server uses. Never renamed. */
86
26
  readonly contractName: string;
@@ -95,11 +35,6 @@ export interface EmittedNames {
95
35
  readonly resources: readonly EmittedName[];
96
36
  /** Each Resource's client property, in UTF-16 code-unit order of `contractName`. */
97
37
  readonly properties: readonly EmittedProperty[];
98
- /**
99
- * One line per renamed name, in UTF-16 code-unit order of the contract name, a
100
- * Resource before an enum of the same name. Returned, never printed: the caller
101
- * that owns the terminal decides where diagnostics go.
102
- */
103
38
  readonly warnings: readonly string[];
104
39
  }
105
40
  /** Whether `text` is an IdentifierName — the rule above, for every emitter. */
@@ -116,10 +51,4 @@ export declare class GeneratedNameError extends Error {
116
51
  readonly name = "GeneratedNameError";
117
52
  constructor(problems: readonly string[]);
118
53
  }
119
- /**
120
- * `value` as an object-literal key that makes it an OWN property: bare when it is
121
- * an IdentifierName (reserved words included — a property name may be one), a
122
- * string literal otherwise — except `__proto__`, which bare or quoted sets the
123
- * prototype instead (measured on Node 24), so it is computed.
124
- */
125
54
  export declare function ownPropertyKey(value: string): string;
@@ -2,24 +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
- * Each is an ALIAS over the copied derivation — `ResourceRecord` /
7
- * `ResourceArgument`, declared in `client.ts` — never a walked-out literal type:
8
- * the derivation stays one. A Resource is addressed by its contract name, a string
9
- * literal type, so nothing here depends on how it was renamed.
10
- *
11
- * The module declares no name but these, and uses no global type a Resource named
12
- * like one could shadow.
13
- *
14
- * TypeScript resolves a type alias where it is DECLARED, so a consumer pays for
15
- * every Resource's named types whether it uses them or not — measured ≈2,800
16
- * instantiations per Resource. Emitted as `types.d.ts`, they cost nothing under
17
- * `skipLibCheck: true` (the common default) until used, and the same as a `.ts`
18
- * under `skipLibCheck: false`. It is live, not a dead declaration: nothing else
19
- * declares these names, and no `types.ts` sits beside it to shadow it
20
- * (`client-tree.emitter.spec.ts`). Only types are declared here, so nothing a
21
- * bundler needs lives in it; `AvClient.ts` re-exports it by `export type *`
22
- * (TypeScript 5.0, inside the 5.5 peer floor) — an `export *` would survive to the
23
- * JavaScript and import a `types.js` that does not exist.
24
- */
25
5
  export declare function emitNamedTypesModule(contract: ClientContract, names: EmittedNames, style: ClientModuleStyle): EmittedModule;
@@ -2,59 +2,9 @@ import { type ClientContract } from "@aventara/core";
2
2
  import type { ClientEntrypoint } from "../config/client-config.interface.js";
3
3
  import type { EmittedModule } from "./emitted-tree.interface.js";
4
4
  import { type ClientModuleStyle } from "./module-style.interface.js";
5
- /**
6
- * The runtime modules the generated client carries: `metadata.ts`, the
7
- * framework `Decimal`, the outcome codes and error classes, and the transport
8
- * here; the scalar codec in `scalar.codec.ts`.
9
- */
10
- /**
11
- * Bundled with the client and imported from nothing: its public type is its own,
12
- * never an ORM's.
13
- *
14
- * It holds the decimal string it was made from, digit for digit, and does no
15
- * arithmetic — the surface is core's `Decimal` (a string constructor and
16
- * `toString`) plus `toJSON`, so a value means the same on both sides of the wire.
17
- * A proven decimal library may later sit behind it; none is needed to carry
18
- * digits.
19
- *
20
- * No `equals`, no arithmetic. The request body never relies on it:
21
- * `serializeWireBody` refuses an unencoded Decimal regardless, so a value the
22
- * codec did not encode cannot slip onto the wire through `toJSON`.
23
- *
24
- * The grammar is core's `Decimal` grammar, read from `AvProtocol.scalarFormats`
25
- * and emitted by value. Unlike core's, the constructor refuses a non-string
26
- * outright: a pattern test coerces its argument, so `5` would otherwise pass as
27
- * `"5"` and be kept as a number.
28
- */
29
5
  export declare function emitDecimalModule(): EmittedModule;
30
- /**
31
- * `metadata.ts` — what this client was generated against: the ClientContract hash
32
- * and the protocol version, and the resolved entrypoint as the client's default.
33
- * Nothing else: no driver, no timestamp, no generator version, no host path —
34
- * anything a re-run over the same inputs could change breaks byte-equality. The
35
- * entrypoint is an input like the contract: changing it regenerates different
36
- * bytes and leaves the hash alone, and it never carries credentials.
37
- *
38
- * The hash and the version are what every operation request sends, from
39
- * `runtime/transport.ts`; all three are internal — `AvClient.ts` exports none.
40
- */
41
6
  export declare function emitMetadataModule(protocol: ClientContract["protocol"], entrypoint: ClientEntrypoint): EmittedModule;
42
- /**
43
- * The `FrameworkError` subclasses the generated runtime declares, in UTF-16
44
- * code-unit order — names the root namespace reserves (`name.deriver.ts`).
45
- */
46
7
  export declare const FRAMEWORK_ERROR_CLASS_NAMES: readonly string[];
47
8
  export declare function errorsModuleExports(): readonly string[];
48
- /**
49
- * Exported beyond what `AvClient.ts` re-exports: the two arrays,
50
- * `OperationErrorCode` and `frameworkErrorOf`, which `runtime/transport.ts` reads.
51
- */
52
9
  export declare function emitErrorsModule(): EmittedModule;
53
- /**
54
- * It reads no capability and no operation descriptor; the caller names the
55
- * operation.
56
- *
57
- * Fetch and AbortSignal are the platform's, reached through the structural types
58
- * below so the module compiles with neither DOM nor Node types.
59
- */
60
10
  export declare function emitTransportModule(style: ClientModuleStyle): EmittedModule;
@@ -54,7 +54,7 @@ export function emitMetadataModule(protocol, entrypoint) {
54
54
  const FRAMEWORK_ERROR_CLASSES = {
55
55
  AuthError: "The caller is not authenticated, or is not permitted to run the operation.",
56
56
  ConflictError: "The operation conflicted with stored state, and nothing was written. A2008 fails the same way if sent again; A2013 and A2014 may succeed if sent again, and no retry is automatic.",
57
- ContractMismatchError: "This client was generated against a ClientContract other than the one the server serves (invariant 15). Regenerate it with `avclient generate`.",
57
+ ContractMismatchError: "This client was generated against a ClientContract other than the one the server serves. Regenerate it with `avclient generate`.",
58
58
  InternalError: "The server failed. Nothing in its cause is actionable; the diagnostics are in the server's logs.",
59
59
  NotFoundError: "A strict unique target does not exist.",
60
60
  ProtocolError: "The request was not one the server could route or interpret: an unknown Resource or operation, a protocol version it does not speak, or a body, media type, size or method it refuses.",
@@ -250,18 +250,17 @@ import {
250
250
  *
251
251
  * # A stale client
252
252
  *
253
- * A client generated against an older ClientContract must fail hard and say to
254
- * regenerate (cross-phase invariant 15). The server is what knows: it checks the
255
- * identity this transport sends BEFORE it routes, so a request
256
- * under a stale hash — to an operation the deployment still advertises, or to
257
- * one it no longer does — is answered 409 A2005, which throws
258
- * ContractMismatchError naming the remedy. Nothing here guesses: a response that
259
- * is not a framework envelope — a host's own 404 for a path it does not mount —
260
- * is a TransportError, and names no remedy, because nothing in it says this
261
- * client is stale.
253
+ * A client generated against an older ClientContract fails hard and says to
254
+ * regenerate. The server checks the identity this transport sends before it
255
+ * routes, so a request under a stale hash, to an operation the deployment still
256
+ * advertises or to one it no longer does, is answered 409 A2005, which throws
257
+ * ContractMismatchError naming the remedy. A response that is not a framework
258
+ * envelope, such as a host's own 404 for a path it does not mount, is a
259
+ * TransportError and names no remedy, because nothing in it says this client is
260
+ * stale.
262
261
  */
263
262
 
264
- /** The wire prefix of the identity headers, in one place: its freeze is a one-line change. */
263
+ /** The wire prefix of the identity headers, in one place. */
265
264
  const WIRE_PREFIX = ${JSON.stringify(IDENTITY_HEADERS.prefix)};
266
265
 
267
266
  /** The headers the framework owns on every operation request. */
@@ -333,12 +332,7 @@ export interface CallOptions {
333
332
 
334
333
  type SuccessCode = Exclude<OperationCode, OperationErrorCode>;
335
334
 
336
- /**
337
- * A framework envelope, read and checked — told apart by \`outcome\`, a string
338
- * discriminant, rather than by \`cause\` being null: without \`strictNullChecks\`
339
- * (\`strict: false\`, which Next.js writes into a tsconfig it creates) null
340
- * narrows nothing, and the client must type-check under the consumer's settings.
341
- */
335
+ /** A framework envelope, read and checked, told apart by \`outcome\`. */
342
336
  type Envelope =
343
337
  | { readonly outcome: "data"; readonly code: SuccessCode; readonly data: unknown }
344
338
  | { readonly outcome: "failure"; readonly code: OperationErrorCode; readonly cause: Cause };
@@ -453,8 +447,7 @@ function decoded<T>(operation: string, status: number, decode: () => T): T {
453
447
 
454
448
  /**
455
449
  * Settles one response by the protocol's rule: the envelope's data, still in wire form,
456
- * which the caller decodes by the decode table. A decode failure's mode is
457
- * decided:
450
+ * which the caller decodes by the decode table.
458
451
  * A scalar in \`data\` that fails to decode, inside an otherwise valid envelope, throws TransportError
459
452
  * — not a FrameworkError, because the server reported no failure; the response is
460
453
  * one this client cannot read, which is what TransportError means.
@@ -1,45 +1,6 @@
1
1
  import { AvProtocol } from "@aventara/core/protocol";
2
2
  import type { EmittedModule } from "./emitted-tree.interface.js";
3
3
  import { type ClientModuleStyle } from "./module-style.interface.js";
4
- /**
5
- * # Keyed on `BuiltInScalar` alone
6
- *
7
- * So the codec reads no field, no capability and no operation descriptor — the
8
- * caller names the scalar, and the codec converts one value.
9
- *
10
- * One source for the scalar set: the emitted `BuiltInScalar` union and the emitted
11
- * table both come from core's `BUILT_IN_SCALARS`, in its order, and {@link
12
- * SCALAR_CODEC_SOURCES} is a mapped type over core's `BuiltInScalar` — a scalar
13
- * the protocol adds is a compile error here until its codec is written.
14
- *
15
- * # Untyped on purpose
16
- *
17
- * Every codec is `unknown → unknown`, checked at runtime. When the boundary lifts,
18
- * the methods that call these codecs carry the types.
19
- *
20
- * # What the emitted codec promises
21
- *
22
- * - `null` passes through both: it is explicit, and whether a field admits it is
23
- * the field's nullability, which the server validates.
24
- * - `undefined` is never a value: an optional property is omitted, and
25
- * `serializeWireBody` strips every `undefined` property before transport.
26
- * - A value outside a scalar's runtime or wire form is refused with a `TypeError`
27
- * naming the scalar — never coerced. A `json` value carrying a `BigInt`, `Date`,
28
- * `Uint8Array`, `Decimal`, function, symbol or `undefined` is refused, with the
29
- * path to the offending member.
30
- * - Wire grammars are the server's, read from core — `AvProtocol.scalarFormats` —
31
- * and emitted by value as regular-expression literals ({@link
32
- * wireGrammarLiteral}): bigint `-?(0|[1-9]\d*)`, datetime exactly
33
- * `toISOString()`'s form, bytes RFC 4648 base64 with the standard alphabet and
34
- * padding, canonical. Base64 is written out rather than delegated to
35
- * `atob`/`btoa`, so the module needs neither a DOM nor a Node global.
36
- */
37
- /**
38
- * The regular-expression literal of one of core's wire grammars, as emitted
39
- * source: `/<source>/`, the grammar's own text. The sources are anchored,
40
- * flagless and carry a `/` only inside a character class, which core's
41
- * `av-protocol.spec.ts` pins, so the literal is the grammar itself.
42
- */
43
4
  export declare function wireGrammarLiteral(scalar: keyof typeof AvProtocol.scalarFormats): string;
44
5
  /**
45
6
  * `runtime/codec.ts`: the `BuiltInScalar` union and the codec table in core's
@@ -1,9 +1,3 @@
1
1
  import type { EmittedModule } from "./emitted-tree.interface.js";
2
2
  import { type ClientModuleStyle } from "./module-style.interface.js";
3
- /**
4
- * The transaction builder and runner: `runtime/fingerprint.ts` and
5
- * `runtime/transaction.ts`, emitted iff the ClientContract advertises
6
- * `interactive` transactions — `client.ts` wires them to `avClient.tx` and
7
- * `avClient.transaction`.
8
- */
9
3
  export declare function emitTransactionModules(style: ClientModuleStyle): readonly EmittedModule[];
@@ -12,8 +12,7 @@ const FINGERPRINT_MODULE = `/**
12
12
  * The v1 operation fingerprint: RFC 8785 canonical JSON of
13
13
  * { resource, family, variant, args } over the WIRE-form arguments, its UTF-8
14
14
  * bytes hashed with SHA-256, the first 16 bytes in base64url, prefixed "fp1:".
15
- * Dependency-free, and pinned byte for byte to core's
16
- * computeOperationFingerprint.
15
+ * Dependency-free; the same bytes the server computes.
17
16
  */
18
17
 
19
18
  /** One plan node, its arguments already in wire form. */
@@ -216,8 +215,7 @@ import { fingerprintOf } from ${from("./fingerprint")};
216
215
  import { type CallOptions, executePlan, type TransportConnection } from ${from("./transport")};
217
216
 
218
217
  /**
219
- * The deferred transaction builder and runner, as core assembles a plan
220
- * in process (transaction-plan-assembler.ts): \`avClient.tx\` defers an operation
218
+ * The deferred transaction builder and runner: \`avClient.tx\` defers an operation
221
219
  * into a handle — pure data, no request — and \`avClient.transaction\` binds a
222
220
  * list of handles into one transaction plan, sends it once, and resolves one
223
221
  * result per handle in list order. A handle has no connection, so any client of
@@ -386,7 +384,7 @@ export async function runTransaction(
386
384
  }
387
385
  }
388
386
 
389
- // Bound lazily, as core binds them: a node's references need their source's
387
+ // Bound lazily: a node's references need their source's
390
388
  // fingerprint, so each node is built once, on first need, wherever its source
391
389
  // stands in the list — the server, not this client, refuses a later one.
392
390
  const nodes = new Map<number, PlanNode>();
@@ -3,21 +3,6 @@ import { type ProcessEnvInput } from "./config/env.cascade.js";
3
3
  import type { ContractFetch } from "./contract/contract.fetcher.js";
4
4
  import { type EmittedFilePath } from "./emit/emitted-tree.interface.js";
5
5
  import type { OutputCheck, TypeScriptResolver } from "./output/output.validator.js";
6
- /**
7
- * The cascade is a returned record, never written into `process.env`: the config
8
- * reaches it through `env("NAME")`.
9
- *
10
- * Output goes to `generateAt`: `AvClient.ts` and `generated/`, nothing else there
11
- * touched. Content in those two the generator did not produce is never overwritten
12
- * unasked: the run returns `ForeignOutputContent` instead, and the caller decides.
13
- *
14
- * Every failure is thrown, every diagnostic that is not a failure is returned:
15
- * this function prints nothing and asks nothing. `cli.ts` owns the terminal. A
16
- * refusal raised after a warning (`OutputWriteError`) carries the warnings raised
17
- * before it, and so does `ForeignOutputContent`; a defect is rethrown as itself,
18
- * its warnings kept beside it (`warningsRaisedBeforeDefect`). No run's warnings
19
- * are lost because it stopped.
20
- */
21
6
  export interface ClientGenerationInput {
22
7
  /** The project directory: where `framework.client.ts` and the `.env` files are. */
23
8
  readonly directory: string;
@@ -30,9 +15,7 @@ export interface ClientGenerationInput {
30
15
  * written.
31
16
  */
32
17
  readonly overrideForeign?: boolean;
33
- /** Injected for tests; the platform `fetch` otherwise. */
34
18
  readonly fetch?: ContractFetch;
35
- /** The `typescript` optional peer; the installed one by default. */
36
19
  readonly resolveTypeScript?: TypeScriptResolver;
37
20
  }
38
21
  export interface ClientGenerated {
@@ -43,11 +26,6 @@ export interface ClientGenerated {
43
26
  readonly files: readonly EmittedFilePath[];
44
27
  /** How deeply the output was validated before it replaced the previous one. */
45
28
  readonly checked: OutputCheck;
46
- /**
47
- * The deployment answered `304` — the ClientContract is the one the previous
48
- * output was generated against — and the output was still replaced, because this
49
- * generator or this entrypoint emits other bytes.
50
- */
51
29
  readonly contractUnchanged: boolean;
52
30
  /**
53
31
  * Everything the run has to say without failing, in a fixed order: the
@@ -56,12 +34,6 @@ export interface ClientGenerated {
56
34
  */
57
35
  readonly warnings: readonly string[];
58
36
  }
59
- /**
60
- * The run found content in `AvClient.ts` or `generated/` the generator did not
61
- * produce, and stopped before writing anything. Whoever owns the terminal asks;
62
- * `proceed` writes the emission already made — no second fetch — overwriting or
63
- * removing exactly `foreign`, through the same temp → validate → replace path.
64
- */
65
37
  export interface ForeignOutputContent {
66
38
  readonly kind: "foreign-content";
67
39
  readonly generateAt: AbsolutePath;
@@ -79,11 +51,6 @@ export interface ForeignOutputContent {
79
51
  readonly warnings: readonly string[];
80
52
  proceed(): Promise<ClientGenerated>;
81
53
  }
82
- /**
83
- * The deployment serves the ClientContract the output was generated against, and
84
- * this generator, with this entrypoint, emits exactly the bytes already there:
85
- * nothing was written.
86
- */
87
54
  export interface ClientUpToDate {
88
55
  readonly kind: "up-to-date";
89
56
  readonly generateAt: AbsolutePath;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,4 @@
1
- /**
2
- * This package's version, read from its own manifest — the `package.json` every
3
- * tarball carries beside `dist/` — so a release's `changeset version` is the one
4
- * statement of it.
5
- */
1
+ /** The version of `@aventara/client`. */
6
2
  export declare const AVENTARA_CLIENT_GENERATOR_VERSION: string;
7
3
  export type { ClientConfigInput, ConfigValue, EnvReference, } from "./config/client-config.interface.js";
8
4
  export { defineClientConfig, env } from "./config/config.resolver.js";
@@ -1,11 +1,3 @@
1
- /**
2
- * `file` names it in its own comment line: the `framework.client.ts` it writes, or
3
- * the project's own config of another extension, which init reuses rather than add
4
- * a second (two configs make `avclient generate` refuse). A `.cjs` one is written
5
- * in CommonJS — `require` and `module.exports` — the syntax its extension
6
- * promises; every other one in ES module syntax, which the loader reads in any of
7
- * them.
8
- */
9
1
  export declare function clientConfigSource(input: {
10
2
  readonly entrypoint: string;
11
3
  readonly envVar: string | undefined;
@@ -2,7 +2,9 @@ import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { runGenerate } from "../cli/generate.command.js";
4
4
  import { CLIENT_CONFIG_FILE } from "../config/config.loader.js";
5
+ import { resolveModuleStyle } from "../config/module-style.resolver.js";
5
6
  import { ContractTransportError } from "../contract/contract.fetcher.js";
7
+ import { CLIENT_ENTRY_FILE } from "../emit/emitted-tree.interface.js";
6
8
  import { ClientInitNotConfirmedError, ClientInitStepError, } from "./client-init.errors.js";
7
9
  import { GENERATE_SCRIPT, planClientInit } from "./client-init.planner.js";
8
10
  import { resolveClientInitAnswers } from "./client-init.questions.js";
@@ -26,6 +28,11 @@ export async function runClientInit(command, io) {
26
28
  detectedPackageManager: project.lockfile ??
27
29
  (userAgent?.split("/")[0] === "pnpm" ? "pnpm" : "npm"),
28
30
  });
31
+ const generateAt = path.resolve(io.cwd, answers.generateAt);
32
+ resolveModuleStyle({
33
+ generateAt,
34
+ entryFile: path.join(generateAt, CLIENT_ENTRY_FILE),
35
+ });
29
36
  const clientVersion = ownVersion();
30
37
  const plan = planClientInit({ project, answers, clientVersion });
31
38
  if (plan.conflicts.length > 0 && !command.yes) {
@@ -14,6 +14,5 @@ export type ClientInitPlan = {
14
14
  export declare function planClientInit(input: {
15
15
  readonly project: ClientProject;
16
16
  readonly answers: ClientInitAnswers;
17
- /** This package's own version: the devDependency is pinned to it exactly. */
18
17
  readonly clientVersion: string;
19
18
  }): ClientInitPlan;
@@ -47,6 +47,16 @@ export function planClientInit(input) {
47
47
  replaced[at] = line;
48
48
  }
49
49
  add(".env", before, `${kept.join("\n")}\n`, `${replaced.join("\n")}\n`);
50
+ const ignore = project.read(".gitignore");
51
+ const ignored = (ignore ?? "")
52
+ .split("\n")
53
+ .some((line) => line.trim() === ".env");
54
+ if (!ignored) {
55
+ const appended = ignore === undefined || ignore === ""
56
+ ? ".env\n"
57
+ : `${ignore.endsWith("\n") ? ignore : `${ignore}\n`}.env\n`;
58
+ add(".gitignore", ignore, appended, appended);
59
+ }
50
60
  }
51
61
  const manifest = (replace) => {
52
62
  const parsed = JSON.parse(project.manifestText);