@aventara/client 1.0.0-rc.0 → 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 (56) hide show
  1. package/CHANGELOG.md +457 -0
  2. package/README.md +159 -141
  3. package/dist/cli/command.parser.d.ts +3 -3
  4. package/dist/cli/command.parser.js +10 -10
  5. package/dist/cli/generation-failure.renderer.js +24 -24
  6. package/dist/config/client-config.interface.d.ts +7 -7
  7. package/dist/config/config.loader.d.ts +4 -4
  8. package/dist/config/config.loader.js +7 -7
  9. package/dist/config/config.resolver.d.ts +7 -7
  10. package/dist/config/config.resolver.js +12 -12
  11. package/dist/config/env.cascade.d.ts +2 -2
  12. package/dist/config/env.cascade.js +4 -4
  13. package/dist/config/module-style.resolver.d.ts +1 -1
  14. package/dist/config/module-style.resolver.js +2 -2
  15. package/dist/config/tsconfig.locator.d.ts +1 -1
  16. package/dist/config/tsconfig.locator.js +2 -2
  17. package/dist/contract/contract.acceptance.d.ts +4 -4
  18. package/dist/contract/contract.acceptance.js +4 -4
  19. package/dist/contract/contract.fetcher.d.ts +3 -3
  20. package/dist/contract/contract.fetcher.js +6 -6
  21. package/dist/contract/contract.loader.d.ts +6 -6
  22. package/dist/contract/contract.loader.js +2 -2
  23. package/dist/emit/client-surface.emitter.d.ts +2 -2
  24. package/dist/emit/client-surface.emitter.js +63 -40
  25. package/dist/emit/client-tree.emitter.d.ts +3 -3
  26. package/dist/emit/client-tree.emitter.js +8 -5
  27. package/dist/emit/contract-carrier.emitter.d.ts +3 -3
  28. package/dist/emit/derivation.emitter.js +1 -0
  29. package/dist/emit/descriptor.emitter.d.ts +2 -2
  30. package/dist/emit/descriptor.emitter.js +1 -1
  31. package/dist/emit/emitted-tree.interface.d.ts +1 -1
  32. package/dist/emit/enum.emitter.d.ts +2 -2
  33. package/dist/emit/field-check.emitter.d.ts +21 -0
  34. package/dist/emit/field-check.emitter.js +603 -0
  35. package/dist/emit/json-shape.emitter.d.ts +2 -2
  36. package/dist/emit/name.deriver.d.ts +6 -6
  37. package/dist/emit/name.deriver.js +14 -14
  38. package/dist/emit/named-type.emitter.d.ts +2 -2
  39. package/dist/emit/runtime.emitter.d.ts +2 -2
  40. package/dist/emit/runtime.emitter.js +115 -110
  41. package/dist/emit/scalar.codec.d.ts +1 -1
  42. package/dist/emit/scalar.codec.js +24 -24
  43. package/dist/emit/transaction.emitter.js +26 -14
  44. package/dist/generate.d.ts +2 -2
  45. package/dist/generate.js +2 -2
  46. package/dist/index.d.ts +1 -1
  47. package/dist/init/client-init.errors.d.ts +4 -4
  48. package/dist/init/client-init.errors.js +4 -4
  49. package/dist/init/client-init.orchestrator.js +7 -7
  50. package/dist/init/client-init.questions.d.ts +5 -5
  51. package/dist/init/client-init.questions.js +10 -10
  52. package/dist/init/client-project.inspector.d.ts +2 -2
  53. package/dist/init/client-project.inspector.js +3 -3
  54. package/dist/output/output.writer.d.ts +5 -5
  55. package/dist/output/output.writer.js +12 -12
  56. package/package.json +3 -3
@@ -1,3 +1,4 @@
1
+ import { contractHasFieldChecks } from "./field-check.emitter.js";
1
2
  import { shapedContractType } from "./json-shape.emitter.js";
2
3
  import { importSpecifier, } from "./module-style.interface.js";
3
4
  import { ownPropertyKey } from "./name.deriver.js";
@@ -11,6 +12,7 @@ export function emitClientSurfaceModule(contract, names, style) {
11
12
  .join("")}R`;
12
13
  const resourceKey = renamed.length === 0 ? "R in Resource" : `R in Resource as ${propertyOf}`;
13
14
  const interactive = contract.transactions === "interactive";
15
+ const checked = contractHasFieldChecks(contract);
14
16
  const shaped = shapedContractType(contract);
15
17
  const C = shaped === undefined ? "ClientContractShape" : "ShapedContract";
16
18
  const renamedEntries = renamed.length === 0
@@ -29,38 +31,41 @@ export function emitClientSurfaceModule(contract, names, style) {
29
31
  (shaped === undefined
30
32
  ? ""
31
33
  : `import type { JsonFieldType } from ${from("./derivation/contracts/json-shape")};\n`) +
32
- `import type { ApplicationScalarForms } from ${from("./derivation/contracts/scalar-value-type")};\n` +
33
- `import type { OperationArgumentsFor, ResourceKey } from ${from("./derivation/operations/operation-arguments")};\n` +
34
- `import type { ${interactive ? "DeferredOperationCall, " : ""}OperationCall, OperationGrammar } from ${from("./derivation/operations/operation-call")};\n` +
35
- `import type { OperationFamily, OperationIdentity } from ${from("./derivation/operations/operation-identity")};\n` +
34
+ `import type { AvApplicationScalarForms } from ${from("./derivation/contracts/scalar-value-type")};\n` +
35
+ `import type { AvOperationArgumentsFor, AvResourceKey } from ${from("./derivation/operations/operation-arguments")};\n` +
36
+ `import type { ${interactive ? "AvDeferredOperationCall, " : ""}AvOperationCall, AvOperationGrammar } from ${from("./derivation/operations/operation-call")};\n` +
37
+ `import type { AvOperationFamily, AvOperationIdentity } from ${from("./derivation/operations/operation-identity")};\n` +
36
38
  `import type { AdmittedOperationResult } from ${from("./derivation/operations/operation-result")};\n` +
37
39
  (interactive
38
- ? `import type { Operation, TransactionResults } from ${from("./derivation/transactions/deferred-operation")};\n`
40
+ ? `import type { AvOperation, AvTransactionResults } from ${from("./derivation/transactions/deferred-operation")};\n`
39
41
  : "") +
40
42
  `import { DEFAULT_ENTRYPOINT } from ${from("./metadata")};\n` +
41
- `import type { Decimal } from ${from("./runtime/decimal")};\n` +
43
+ `import type { AvDecimal } from ${from("./runtime/decimal")};\n` +
42
44
  `import { ADVERTISED_OPERATIONS } from ${from("./runtime/descriptor")};\n` +
45
+ (checked
46
+ ? `import { ${interactive ? "checkOperation, checkPlan" : "checkOperation"} } from ${from("./runtime/field-validators")};\n`
47
+ : "") +
43
48
  (interactive
44
49
  ? `import { deferOperation, runTransaction } from ${from("./runtime/transaction")};\n`
45
50
  : "") +
46
- `import { type CallOptions, execute, type Fetch, type TransportConnection } from ${from("./runtime/transport")};\n` +
51
+ `import { type AvCallOptions, execute, type AvFetch, type TransportConnection } from ${from("./runtime/transport")};\n` +
47
52
  "\n" +
48
- `export type { CallOptions } from ${from("./runtime/transport")};\n` +
53
+ `export type { AvCallOptions } from ${from("./runtime/transport")};\n` +
49
54
  "\n" +
50
55
  "/**\n" +
51
- " * The forms this client reads and writes: core's application forms —\n" +
52
- " * `bigint`, `Date`, `Uint8Array` — with this client's own `Decimal`.\n" +
56
+ " * The forms this client reads and writes: core's application forms\n" +
57
+ " * (`bigint`, `Date`, `Uint8Array`) with this client's own `AvDecimal`.\n" +
53
58
  " */\n" +
54
- 'export type ClientScalarForms = Omit<ApplicationScalarForms, "decimal"> & {\n' +
55
- "\treadonly decimal: Decimal;\n" +
59
+ 'export type ClientScalarForms = Omit<AvApplicationScalarForms, "decimal"> & {\n' +
60
+ "\treadonly decimal: AvDecimal;\n" +
56
61
  "};\n" +
57
62
  "\n" +
58
63
  "/** How an `AvClient` reaches its deployment. */\n" +
59
64
  "export interface AvClientOptions {\n" +
60
65
  "\t/** Another deployment serving exactly the same ClientContract; the generated default otherwise. */\n" +
61
66
  "\treadonly entrypoint?: string;\n" +
62
- "\t/** A custom fetch — authentication, tests; the platform's otherwise. */\n" +
63
- "\treadonly fetch?: Fetch;\n" +
67
+ "\t/** A custom fetch, for authentication or tests; the platform's otherwise. */\n" +
68
+ "\treadonly fetch?: AvFetch;\n" +
64
69
  "}\n" +
65
70
  "\n" +
66
71
  (shaped === undefined
@@ -68,41 +73,52 @@ export function emitClientSurfaceModule(contract, names, style) {
68
73
  : "/** The ClientContract, with each shaped Json field's own type. */\n" +
69
74
  `type ShapedContract = ${shaped};\n` +
70
75
  "\n") +
71
- `type Grammar = OperationGrammar<${C}>;\n` +
72
- `type Resource = ResourceKey<${C}>;\n` +
76
+ `type Grammar = AvOperationGrammar<${C}>;\n` +
77
+ `type Resource = AvResourceKey<${C}>;\n` +
73
78
  "\n" +
74
79
  "/** `avClient.<resource>.<family>.<variant>(args, options?)`: one call per advertised operation. */\n" +
75
- surface("AvClientSurface", "OperationCall<\n" +
80
+ surface("AvClientSurface", "AvOperationCall<\n" +
76
81
  `\t\t\t\t${C},\n` +
77
82
  "\t\t\t\tR,\n" +
78
- "\t\t\t\tGrammar[R][F][V] & OperationIdentity,\n" +
83
+ "\t\t\t\tGrammar[R][F][V] & AvOperationIdentity,\n" +
79
84
  "\t\t\t\tClientScalarForms,\n" +
80
85
  "\t\t\t\tClientScalarForms,\n" +
81
- '\t\t\t\t"data",\n' +
82
- "\t\t\t\tCallOptions\n" +
86
+ "\t\t\t\tAvCallOptions\n" +
83
87
  "\t\t\t>") +
84
88
  (interactive
85
89
  ? "\n" +
86
90
  "/** `avClient.tx.<resource>.<family>.<variant>(args)`: a deferred handle; no request. */\n" +
87
- surface("AvTxSurface", "DeferredOperationCall<\n" +
91
+ surface("AvTxSurface", "AvDeferredOperationCall<\n" +
88
92
  `\t\t\t\t${C},\n` +
89
93
  "\t\t\t\tR,\n" +
90
- "\t\t\t\tGrammar[R][F][V] & OperationIdentity,\n" +
94
+ "\t\t\t\tGrammar[R][F][V] & AvOperationIdentity,\n" +
91
95
  "\t\t\t\tClientScalarForms,\n" +
92
96
  "\t\t\t\tClientScalarForms\n" +
93
97
  "\t\t\t>") +
94
98
  "\n" +
95
99
  "/** Sends the handles as one plan and resolves their results as a typed tuple. */\n" +
96
- "type TransactionCall = <const Steps extends readonly Operation<unknown>[]>(\n" +
100
+ "type TransactionCall = <const Steps extends readonly AvOperation<unknown>[]>(\n" +
97
101
  "\tsteps: Steps,\n" +
98
- "\toptions?: CallOptions,\n" +
99
- ") => Promise<TransactionResults<Steps>>;\n"
102
+ "\toptions?: AvCallOptions,\n" +
103
+ ") => Promise<AvTransactionResults<Steps>>;\n"
100
104
  : "") +
101
105
  "\n" +
102
106
  "/** The generated client: one property per Resource this deployment's ClientContract advertises. */\n" +
103
107
  "export interface AvClient extends AvClientSurface {}\n" +
104
108
  "\n" +
105
- "/** The generated client. */\n" +
109
+ (checked
110
+ ? "/**\n" +
111
+ " * The generated client.\n" +
112
+ " *\n" +
113
+ " * A call runs the ClientContract's field validators before it is sent: one\n" +
114
+ " * whose values break a validator, or a check of a shaped Json field, is\n" +
115
+ " * refused with the AvValidationError the server would answer (A2004, with\n" +
116
+ " * the same issues), and nothing is sent. The client checks each value as\n" +
117
+ " * written; the server checks it again after its field pipes, so a field pipe\n" +
118
+ " * that normalizes a value must not turn one the client accepted into one the\n" +
119
+ " * server refuses. A $ref value in a transaction is the server's to check.\n" +
120
+ " */\n"
121
+ : "/** The generated client. */\n") +
106
122
  "export class AvClient {\n" +
107
123
  (interactive
108
124
  ? "\t/** Deferred operations, for `transaction`. */\n" +
@@ -117,8 +133,13 @@ export function emitClientSurfaceModule(contract, names, style) {
117
133
  "\t\tconst connect = (): TransportConnection => ({ entrypoint, fetch: platformFetch(given) });\n" +
118
134
  "\t\tfor (const [resource, families] of operationTree(\n" +
119
135
  "\t\t\t(resource, family, variant): OperationMethod =>\n" +
120
- "\t\t\t\tasync (args = {}, callOptions = {}) =>\n" +
121
- "\t\t\t\t\texecute(connect(), resource, family, variant, args, callOptions),\n" +
136
+ (checked
137
+ ? "\t\t\t\tasync (args = {}, callOptions = {}) => {\n" +
138
+ "\t\t\t\t\tcheckOperation(resource, family, args);\n" +
139
+ "\t\t\t\t\treturn execute(connect(), resource, family, variant, args, callOptions);\n" +
140
+ "\t\t\t\t},\n"
141
+ : "\t\t\t\tasync (args = {}, callOptions = {}) =>\n" +
142
+ "\t\t\t\t\texecute(connect(), resource, family, variant, args, callOptions),\n") +
122
143
  "\t\t)) {\n" +
123
144
  "\t\t\tObject.defineProperty(this, propertyOf(resource), { value: families, enumerable: true });\n" +
124
145
  "\t\t}\n" +
@@ -133,8 +154,10 @@ export function emitClientSurfaceModule(contract, names, style) {
133
154
  "\t\t}\n" +
134
155
  '\t\tObject.defineProperty(this, "tx", { value: Object.freeze(deferred) });\n' +
135
156
  '\t\tObject.defineProperty(this, "transaction", {\n' +
136
- "\t\t\tvalue: async (steps: unknown, callOptions: CallOptions = {}) =>\n" +
137
- "\t\t\t\trunTransaction(connect(), steps, callOptions),\n" +
157
+ "\t\t\tvalue: async (steps: unknown, callOptions: AvCallOptions = {}) =>\n" +
158
+ (checked
159
+ ? "\t\t\t\trunTransaction(connect(), steps, callOptions, checkPlan),\n"
160
+ : "\t\t\t\trunTransaction(connect(), steps, callOptions),\n") +
138
161
  "\t\t});\n"
139
162
  : "") +
140
163
  "\t}\n" +
@@ -142,7 +165,7 @@ export function emitClientSurfaceModule(contract, names, style) {
142
165
  "\n" +
143
166
  "/**\n" +
144
167
  " * One frozen object per Resource, one per family under it, one member per\n" +
145
- " * advertised variant — by wire name; the caller places each Resource.\n" +
168
+ " * advertised variant, by wire name; the caller places each Resource.\n" +
146
169
  " */\n" +
147
170
  "function operationTree<M>(member: (resource: string, family: string, variant: string) => M): Map<string, object> {\n" +
148
171
  "\tconst resources = new Map<string, Map<string, Record<string, M>>>();\n" +
@@ -162,7 +185,7 @@ export function emitClientSurfaceModule(contract, names, style) {
162
185
  "}\n" +
163
186
  "\n" +
164
187
  "/** One advertised operation, as the runtime calls it: the types are the surface's. */\n" +
165
- "type OperationMethod = (args?: Readonly<Record<string, unknown>>, options?: CallOptions) => Promise<unknown>;\n" +
188
+ "type OperationMethod = (args?: Readonly<Record<string, unknown>>, options?: AvCallOptions) => Promise<unknown>;\n" +
166
189
  "\n" +
167
190
  "/** The Resources reached by a property other than their wire name. */\n" +
168
191
  `const RENAMED_PROPERTIES: Readonly<Record<string, string>> = {${renamedEntries}};\n` +
@@ -174,11 +197,11 @@ export function emitClientSurfaceModule(contract, names, style) {
174
197
  "\n" +
175
198
  "/**\n" +
176
199
  " * The fetch a call uses: the one the client was given, else the\n" +
177
- " * platform's, read when the call is made — so importing the client never\n" +
200
+ " * platform's, read when the call is made. Importing the client never\n" +
178
201
  " * fails where there is no fetch, and a call does, saying why.\n" +
179
202
  " */\n" +
180
- "function platformFetch(given: Fetch | undefined): Fetch {\n" +
181
- "\tconst found = given ?? (globalThis as { readonly fetch?: Fetch }).fetch;\n" +
203
+ "function platformFetch(given: AvFetch | undefined): AvFetch {\n" +
204
+ "\tconst found = given ?? (globalThis as { readonly fetch?: AvFetch }).fetch;\n" +
182
205
  '\tif (typeof found !== "function") {\n' +
183
206
  '\t\tthrow new TypeError("No fetch is available here; pass one: new AvClient({ fetch }).");\n' +
184
207
  "\t}\n" +
@@ -189,12 +212,12 @@ export function emitClientSurfaceModule(contract, names, style) {
189
212
  "const avClient: AvClient = new AvClient();\n" +
190
213
  "export default avClient;\n" +
191
214
  "\n" +
192
- "type Identity<F extends OperationFamily, V extends string> = Extract<\n" +
193
- "\tOperationIdentity,\n" +
215
+ "type Identity<F extends AvOperationFamily, V extends string> = Extract<\n" +
216
+ "\tAvOperationIdentity,\n" +
194
217
  "\t{ readonly family: F; readonly variant: V }\n" +
195
218
  ">;\n" +
196
219
  "\n" +
197
- "/** A Resource's default record — `find.unique` with no projection. */\n" +
220
+ "/** A Resource's default record: `find.unique` with no projection. */\n" +
198
221
  "export type ResourceRecord<R extends Resource> = AdmittedOperationResult<\n" +
199
222
  `\t${C},\n` +
200
223
  "\tR,\n" +
@@ -206,11 +229,11 @@ export function emitClientSurfaceModule(contract, names, style) {
206
229
  "/** One argument of one of a Resource's operations, present. */\n" +
207
230
  "export type ResourceArgument<\n" +
208
231
  "\tR extends Resource,\n" +
209
- "\tF extends OperationFamily,\n" +
232
+ "\tF extends AvOperationFamily,\n" +
210
233
  "\tV extends string,\n" +
211
234
  "\tK extends string,\n" +
212
235
  "> = ArgumentOf<\n" +
213
- `\tOperationArgumentsFor<${C}, R, Identity<F, V>, ClientScalarForms>,\n` +
236
+ `\tAvOperationArgumentsFor<${C}, R, Identity<F, V>, ClientScalarForms>,\n` +
214
237
  "\tK\n" +
215
238
  ">;\n" +
216
239
  "\n" +
@@ -1,8 +1,8 @@
1
- import type { ClientContract } from "@aventara/core";
1
+ import type { AvContractClient } from "@aventara/core";
2
2
  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
- * @throws GeneratedNameError when a name cannot be emitted, even renamed.
6
+ * @throws AvGeneratedNameError when a name cannot be emitted, even renamed.
7
7
  */
8
- export declare function emitClientTree(contract: ClientContract, entrypoint: ClientEntrypoint, style: ClientModuleStyle): ClientEmission;
8
+ export declare function emitClientTree(contract: AvContractClient, entrypoint: ClientEntrypoint, style: ClientModuleStyle): ClientEmission;
@@ -5,6 +5,7 @@ import { emitDerivationModules } from "./derivation.emitter.js";
5
5
  import { emitDescriptorModule } from "./descriptor.emitter.js";
6
6
  import { CLIENT_ENTRY_FILE, GENERATED_DIRECTORY, } from "./emitted-tree.interface.js";
7
7
  import { emitEnumsModule } from "./enum.emitter.js";
8
+ import { emitFieldCheckModules } from "./field-check.emitter.js";
8
9
  import { moduleSpecifierWriter, } from "./module-style.interface.js";
9
10
  import { deriveEmittedNames } from "./name.deriver.js";
10
11
  import { emitNamedTypesModule } from "./named-type.emitter.js";
@@ -13,8 +14,9 @@ import { emitScalarCodecModule } from "./scalar.codec.js";
13
14
  import { emitTransactionModules } from "./transaction.emitter.js";
14
15
  export function emitClientTree(contract, entrypoint, style) {
15
16
  const names = deriveEmittedNames(contract);
17
+ const derivation = emitDerivationModules();
16
18
  const generated = [
17
- ...emitDerivationModules(),
19
+ ...derivation,
18
20
  emitClientSurfaceModule(contract, names, style),
19
21
  emitContractCarrierModule(contract),
20
22
  emitDescriptorModule(contract),
@@ -28,6 +30,7 @@ export function emitClientTree(contract, entrypoint, style) {
28
30
  ...(contract.transactions === "interactive"
29
31
  ? emitTransactionModules(style)
30
32
  : []),
33
+ ...emitFieldCheckModules(contract, style, new Set(derivation.map((module) => module.path))),
31
34
  ];
32
35
  const files = [
33
36
  { path: CLIENT_ENTRY_FILE, source: clientEntrySource(style) },
@@ -49,12 +52,12 @@ function clientEntrySource(style) {
49
52
  const specifier = moduleSpecifierWriter(style);
50
53
  const from = (module) => specifier(`./${GENERATED_DIRECTORY}/${module.replace(/\.d\.ts$|\.ts$/, "")}`);
51
54
  return (`export { default } from ${from("client.ts")};\n` +
52
- `export {\n\tAvClient,\n\ttype AvClientOptions,\n\ttype CallOptions,\n} from ${from("client.ts")};\n` +
53
- `export type { Fetch } from ${from("runtime/transport.ts")};\n` +
54
- `export type { Operation } from ${from("derivation/transactions/deferred-operation.d.ts")};\n` +
55
+ `export {\n\tAvClient,\n\ttype AvClientOptions,\n\ttype AvCallOptions,\n} from ${from("client.ts")};\n` +
56
+ `export type { AvFetch } from ${from("runtime/transport.ts")};\n` +
57
+ `export type { AvOperation } from ${from("derivation/transactions/deferred-operation.d.ts")};\n` +
55
58
  `export type * from ${from("types.d.ts")};\n` +
56
59
  `export * from ${from("enums.ts")};\n` +
57
- `export { Decimal } from ${from("runtime/decimal.ts")};\n` +
60
+ `export { AvDecimal } from ${from("runtime/decimal.ts")};\n` +
58
61
  `export {\n${errorsModuleExports()
59
62
  .map((name) => `\t${name},\n`)
60
63
  .join("")}} from ${from("runtime/errors.ts")};\n`);
@@ -1,5 +1,5 @@
1
- import type { ClientContract } from "@aventara/core";
1
+ import type { AvContractClient } from "@aventara/core";
2
2
  import type { EmittedModule } from "./emitted-tree.interface.js";
3
3
  /** `generated/contract.ts`, before the banner. */
4
- export declare function emitContractCarrierModule(contract: ClientContract): EmittedModule;
5
- export declare function parseContractCarrier(text: string): Promise<ClientContract | undefined>;
4
+ export declare function emitContractCarrierModule(contract: AvContractClient): EmittedModule;
5
+ export declare function parseContractCarrier(text: string): Promise<AvContractClient | undefined>;
@@ -9,6 +9,7 @@ export const DERIVATION_ROOTS = [
9
9
  "operations/operation-call",
10
10
  "operations/operation-identity",
11
11
  "operations/operation-result",
12
+ "operations/validation-code",
12
13
  "transactions/deferred-operation",
13
14
  "transactions/transaction-reference",
14
15
  ];
@@ -1,4 +1,4 @@
1
- import type { ClientContract } from "@aventara/core";
1
+ import type { AvContractClient } from "@aventara/core";
2
2
  import type { EmittedModule } from "./emitted-tree.interface.js";
3
3
  /** `generated/runtime/descriptor.ts`, before the banner. */
4
- export declare function emitDescriptorModule(contract: ClientContract): EmittedModule;
4
+ export declare function emitDescriptorModule(contract: AvContractClient): EmittedModule;
@@ -31,7 +31,7 @@ export function emitDescriptorModule(contract) {
31
31
  path: "runtime/descriptor.ts",
32
32
  source: "/**\n" +
33
33
  " * A result field the decoder revives from its wire string, or a relation\n" +
34
- " * it recurses into, read as the relation's target Resource — `many` saying the\n" +
34
+ " * it recurses into, read as the relation's target Resource; `many` says the\n" +
35
35
  " * value is a list, `{ data, count }` or `{ count }` rather than one record.\n" +
36
36
  " */\n" +
37
37
  "export type FieldDecoding =\n" +
@@ -8,7 +8,7 @@ export declare const LEGACY_CLIENT_ENTRY_FILES: readonly string[];
8
8
  /** The directory holding every other emitted module, under `generateAt`. */
9
9
  export declare const GENERATED_DIRECTORY = "generated";
10
10
  export type DerivationModulePath = `derivation/${string}.d.ts`;
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";
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/field-check.evaluator.ts" | "runtime/field-validators.ts" | "runtime/fingerprint.ts" | "runtime/transaction.ts" | "runtime/transport.ts" | "types.d.ts";
12
12
  export declare const CONTRACT_CARRIER_MODULE = "contract.ts";
13
13
  /** A path in the emitted tree: relative to `generateAt`, POSIX-separated. */
14
14
  export type EmittedFilePath = typeof CLIENT_ENTRY_FILE | `${typeof GENERATED_DIRECTORY}/${GeneratedModulePath}`;
@@ -1,4 +1,4 @@
1
- import type { ClientContract } from "@aventara/core";
1
+ import type { AvContractClient } from "@aventara/core";
2
2
  import type { EmittedModule } from "./emitted-tree.interface.js";
3
3
  import { type EmittedNames } from "./name.deriver.js";
4
- export declare function emitEnumsModule(contract: Pick<ClientContract, "enums">, names: EmittedNames): EmittedModule;
4
+ export declare function emitEnumsModule(contract: Pick<AvContractClient, "enums">, names: EmittedNames): EmittedModule;
@@ -0,0 +1,21 @@
1
+ import type { AvContractClient } from "@aventara/core";
2
+ import type { EmittedModule } from "./emitted-tree.interface.js";
3
+ import { type ClientModuleStyle } from "./module-style.interface.js";
4
+ /** Where `@aventara/core` publishes the evaluator's source, relative to its package root. */
5
+ export declare const EVALUATOR_SOURCE = "src/runtime/field-check.evaluator.ts";
6
+ /** Reads the evaluator's published source; `undefined` when core publishes none. */
7
+ export type EvaluatorSourceReader = () => string | undefined;
8
+ /** The evaluator's source as the `@aventara/core` this package resolves publishes it. */
9
+ export declare function publishedCoreEvaluator(): EvaluatorSourceReader;
10
+ /** Whether the ClientContract carries any check: a field's validators or a Json Shape node's. */
11
+ export declare function contractHasFieldChecks(contract: AvContractClient): boolean;
12
+ /**
13
+ * The two field check modules, or none when the contract carries no check.
14
+ *
15
+ * @param derivation the declaration paths the tree copies under `derivation/`
16
+ * (`derivation/contracts/field-check.d.ts`, …): the evaluator's type imports
17
+ * must name one of them.
18
+ * @throws Error when the evaluator cannot be copied — a defect of the installed
19
+ * `@aventara/core`, never of the consumer's input.
20
+ */
21
+ export declare function emitFieldCheckModules(contract: AvContractClient, style: ClientModuleStyle, derivation: ReadonlySet<string>, read?: EvaluatorSourceReader): readonly EmittedModule[];