@aventara/client 1.0.0-rc.1 → 1.0.0-rc.11

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 (62) hide show
  1. package/CHANGELOG.md +247 -0
  2. package/README.md +147 -11
  3. package/dist/cli/command.parser.d.ts +4 -3
  4. package/dist/cli/command.parser.js +3 -3
  5. package/dist/cli/generation-failure.renderer.d.ts +2 -1
  6. package/dist/cli/generation-success.renderer.d.ts +2 -1
  7. package/dist/cli/step.reporter.d.ts +2 -1
  8. package/dist/cli/terminal.prompter.d.ts +2 -1
  9. package/dist/config/client-config.interface.d.ts +17 -0
  10. package/dist/config/config.loader.d.ts +8 -3
  11. package/dist/config/config.loader.js +20 -2
  12. package/dist/config/config.resolver.d.ts +10 -3
  13. package/dist/config/config.resolver.js +28 -0
  14. package/dist/config/env.cascade.d.ts +2 -6
  15. package/dist/config/env.cascade.js +3 -3
  16. package/dist/config/module-style.resolver.d.ts +3 -6
  17. package/dist/config/module-style.resolver.js +2 -2
  18. package/dist/config/tsconfig.locator.d.ts +2 -1
  19. package/dist/config/tsconfig.locator.js +14 -2
  20. package/dist/contract/contract.acceptance.d.ts +0 -1
  21. package/dist/contract/contract.acceptance.js +1 -1
  22. package/dist/contract/contract.fetcher.d.ts +2 -1
  23. package/dist/contract/contract.loader.d.ts +3 -2
  24. package/dist/emit/access.emitter.d.ts +12 -0
  25. package/dist/emit/access.emitter.js +263 -0
  26. package/dist/emit/banner.emitter.d.ts +6 -1
  27. package/dist/emit/banner.emitter.js +12 -8
  28. package/dist/emit/cached-read.emitter.d.ts +3 -0
  29. package/dist/emit/cached-read.emitter.js +158 -0
  30. package/dist/emit/client-surface.emitter.js +130 -13
  31. package/dist/emit/client-tree.emitter.d.ts +9 -2
  32. package/dist/emit/client-tree.emitter.js +51 -15
  33. package/dist/emit/derivation.emitter.d.ts +3 -3
  34. package/dist/emit/derivation.emitter.js +6 -3
  35. package/dist/emit/descriptor.emitter.d.ts +2 -0
  36. package/dist/emit/descriptor.emitter.js +28 -1
  37. package/dist/emit/emitted-tree.interface.d.ts +1 -1
  38. package/dist/emit/field-check.emitter.d.ts +2 -1
  39. package/dist/emit/field-check.emitter.js +2 -13
  40. package/dist/emit/module-specifier.scanner.d.ts +2 -1
  41. package/dist/emit/name.deriver.d.ts +2 -3
  42. package/dist/emit/name.deriver.js +6 -1
  43. package/dist/emit/named-type.emitter.js +12 -2
  44. package/dist/emit/operation-set.emitter.d.ts +3 -0
  45. package/dist/emit/operation-set.emitter.js +604 -0
  46. package/dist/emit/runtime.emitter.d.ts +5 -4
  47. package/dist/emit/runtime.emitter.js +484 -42
  48. package/dist/emit/scalar.codec.js +223 -6
  49. package/dist/emit/transaction.emitter.js +7 -3
  50. package/dist/generate.d.ts +3 -2
  51. package/dist/generate.js +1 -1
  52. package/dist/hydration/hydration-tag.format.d.ts +11 -0
  53. package/dist/hydration/hydration-tag.format.js +6 -0
  54. package/dist/init/client-init.planner.d.ts +3 -2
  55. package/dist/init/client-init.questions.d.ts +1 -12
  56. package/dist/init/client-init.questions.js +2 -2
  57. package/dist/internal.d.ts +25 -0
  58. package/dist/internal.js +11 -0
  59. package/dist/output/output.validator.d.ts +3 -4
  60. package/dist/output/output.validator.js +2 -2
  61. package/dist/output/output.writer.d.ts +3 -2
  62. package/package.json +9 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,252 @@
1
1
  # @aventara/client
2
2
 
3
+ ## 1.0.0-rc.11
4
+
5
+ ### Patch Changes
6
+
7
+ - 6197c08: `@/aventara/universal`'s calls are the generated client's own calls again. The entry no longer wraps each one in
8
+ `io().then(call)`, so its own `signal`, `avClient.all`'s `signal` and strict abort, and `avLazy` all reach it, in the
9
+ browser and on the server. Next's `io()` is now awaited before the request is sent.
10
+
11
+ In the browser, the calls made in one tick are still grouped into one `/_all`. On the server, none is grouped: each
12
+ call has a client of its own with grouping off, and it is sent from the async context of the code that made it. Before,
13
+ one queue served every request. Calls from two concurrent requests, or a call inside `unstable_cache` and one outside
14
+ it, could share a flush and run with the first call's headers and `state`.
15
+
16
+ `avLazy` no longer keeps one answer for every request on a server:
17
+
18
+ - The generated client's `avLazy` keeps its answer in a page. On a server (no `location`) it keeps none, and each await
19
+ makes the call again.
20
+ - `@aventara/core`'s `avLazy` keeps none: each await makes the call again.
21
+ - `@/aventara/universal` now exports its own `avLazy`, which keeps one answer per request inside a React render
22
+ (React's `cache`, which the entry now imports) and none where React keeps no request.
23
+
24
+ Before, an `avLazy` made at module scope handed the first request's answer to every request after it.
25
+
26
+ `ready()`'s in-process path now splits a cached read's GET URL into its path and its `?q=&v=` query, with an empty
27
+ body, so the read reaches its GET route instead of being answered as absent.
28
+
29
+ - 5ac10f7: The generated client's calls are grouped. A call runs when it is made, like `fetch` (a call never awaited still runs;
30
+ a transaction too), and `avLazy(() => call)`, exported beside `avClient`, makes one only when it is first awaited. The
31
+ calls made in one tick go out as one `POST /_all` Operation Set,
32
+ split at `limits.maxAll`, each resolving or throwing on its own as its streamed (NDJSON) or plain JSON answer arrives; a
33
+ call made alone keeps its own route. A call with `headers` or a `requestId`, a transaction, and any call made with
34
+ `grouping: false` (per call, or `new AvClient({ grouping: false })`) is sent alone. A server without `/_all` gets the calls
35
+ again one by one. A call's `signal` aborts that call only, and is never sent if it aborts first. `avClient.all({ … })`
36
+ awaits an object of calls: strict by default, or `{ settle: true }` for one settled entry per key, with a `signal` that
37
+ aborts its calls. `all` joins the client's reserved member names: a Resource named `all` is reached as `allModel`.
38
+
39
+ A read the ClientContract marks `cache` (a `cache({ for, maxAge })` stage) is sent as
40
+ `GET /_resources/<R>/find/<variant>?q=<args>&v=<hash>`, alone and never grouped, with only the caller's own headers: `q`
41
+ is the arguments' canonical JSON, percent-encoded or deflate-raw and base64url when shorter (plain where there is no
42
+ `CompressionStream`), and a URL longer than 4096 characters is POSTed instead. A client with a cached read carries two
43
+ more runtime modules, `runtime/cached-read.ts` and `runtime/canonical-json.ts` (core's writer, copied).
44
+
45
+ - Updated dependencies [6197c08]
46
+ - Updated dependencies [e0e89c1]
47
+ - Updated dependencies [186bc29]
48
+ - Updated dependencies [33b5f83]
49
+ - Updated dependencies [6d8b589]
50
+ - Updated dependencies [11ece49]
51
+ - Updated dependencies [92fd093]
52
+ - Updated dependencies [e5e98e6]
53
+ - Updated dependencies [a05d970]
54
+ - @aventara/core@1.0.0-rc.11
55
+
56
+ ## 1.0.0-rc.10
57
+
58
+ ### Patch Changes
59
+
60
+ - 7ee547b: A ClientContract whose `access` section states Aventara Access's `kiosk` verbs gives the generated client
61
+ `$access.switchUser`, `lock`, `setPin`, `enrollDevice` and `revokeDevice`, each a `POST` to Access's own route with its
62
+ arguments typed from the section's schema and its answer projected onto the result schema (`lock`, `setPin` and
63
+ `revokeDevice` resolve nothing). A section without them emits no member for them.
64
+ - d7e7369: A ClientContract with the `access` section gives the generated client `$access`: `can(questions)` (one request to
65
+ `/_access/can`), and exactly the Aventara Access verbs the section states (`me` with `GET` and `cache: "no-store"`,
66
+ `signIn`, `signUp`, `signOut`, `resetPassword`), each result projected onto the section's schema. `AvAccessMe` is
67
+ `me`'s result type and `AvAccessError` what a non-2xx Access answer throws. A client without the section is emitted
68
+ byte for byte as before. A ClientContract whose Access URL is on another origin than the
69
+ entrypoint's is refused unless `framework.client.ts` lists that origin in the new `accessOrigins`.
70
+ - 9d423f9: `avclient generate`'s reference step (a solution-style `tsconfig.json`) matches `${configDir}` entries of `files`,
71
+ `include` and `exclude`. `get-tsconfig` 4.10.0 makes them absolute and its file matcher joined them under the config's
72
+ directory again, so a referenced project including the client through `${configDir}` was passed over.
73
+ - 04bb39a: `engines.node` is now `^22.23.4 || >=24.22.1`, the Node security releases of 2026-10-20 (CVE-2026-105481,
74
+ CVE-2026-105482, CVE-2026-105483, CVE-2026-106069, CVE-2026-106072, CVE-2026-106073, CVE-2026-106074,
75
+ CVE-2026-111497). The bins refuse an older Node in one sentence naming that range.
76
+ - 88263a1: A value projected onto an `access` verb's result schema is refused with the projector's own `TypeError` when the schema
77
+ is outside the forms a Client Contract states (a free-form object or list, a tuple read past its length), whatever the
78
+ value, an empty one included. A Client Contract that passed its structure check never holds such a schema.
79
+ - Updated dependencies [587dd01]
80
+ - Updated dependencies [d7e7369]
81
+ - Updated dependencies [7ee547b]
82
+ - Updated dependencies [f52c499]
83
+ - Updated dependencies [2907484]
84
+ - Updated dependencies [a6bbdf0]
85
+ - Updated dependencies [3e26549]
86
+ - Updated dependencies [a6bbdf0]
87
+ - Updated dependencies [6f3f6f6]
88
+ - Updated dependencies [04bb39a]
89
+ - Updated dependencies [3fb3333]
90
+ - Updated dependencies [827ccb6]
91
+ - Updated dependencies [7f5abc3]
92
+ - Updated dependencies [88263a1]
93
+ - Updated dependencies [10341d5]
94
+ - Updated dependencies [8129844]
95
+ - Updated dependencies [88263a1]
96
+ - Updated dependencies [3020b5c]
97
+ - Updated dependencies [88263a1]
98
+ - Updated dependencies [88263a1]
99
+ - @aventara/core@1.0.0-rc.10
100
+
101
+ ## 1.0.0-rc.9
102
+
103
+ ### Patch Changes
104
+
105
+ - 99278e4: `aventara-build` reads a Next.js project's files from `src/aventara/` and, with `--client`, writes its browser client.
106
+
107
+ - A project whose `package.json` depends on `@aventara/next` keeps its configuration and adapter in
108
+ `src/aventara/config.ts` and `src/aventara/adapter.ts`; the build runs them there, and a configuration that imports no
109
+ Resource tree has its generated files in `src/aventara/generated/`. Every other project keeps
110
+ `src/aventara.config.ts` and `src/aventara.adapter.ts`, unchanged. A missing file is named with where the project's
111
+ host keeps it, and a project depending on both `@aventara/nest` and `@aventara/next` is refused in one sentence.
112
+ - `aventara-build --client` also writes the browser client from the ClientContract it has just compiled, with no
113
+ running server: `src/aventara/client.ts` and the client's modules under `src/aventara/generated/`, the same modules
114
+ `avclient generate` writes for that ClientContract except that the entrypoint is the app's own `api` on the page's
115
+ origin (`/api`) and the regenerate instructions. Its imports are spelled as the project's `tsconfig.json` says, and nothing it writes imports
116
+ `@aventara/client`.
117
+ - `src/aventara/client.ts` exports `avClient` and `avHydrate`, and re-exports every name `avclient generate`'s
118
+ `AvClient.ts` exports besides its default (`AvClient`, the Resource types, the enums, `AvDecimal`, the error
119
+ classes), so `import { AvDecimal } from "@/aventara/client"` works. The generated files and the contract-mismatch
120
+ error say to regenerate with `aventara-build --client` (the project's `aventara:prepare` script). `avClient` calls the API from the browser; a call made
121
+ on the server (a Client Component rendering there) rejects with one sentence pointing to `@/aventara/server` and
122
+ `@/aventara/universal`, and sends nothing. `avHydrate` revives data `avDehydrate` sends from the server: tagged
123
+ dates, `bigint`s, byte arrays and decimals become `Date`, `bigint`, `Uint8Array` and the client's own `AvDecimal`,
124
+ for TanStack Query's `deserializeData` or an SWR `fallback`.
125
+ - `aventara-build --check --client` checks those files too: a missing or stale one, or one an earlier ClientContract's
126
+ client left, exits 1 naming it. `--client` is refused in a NestJS project, whose frontends keep using
127
+ `avclient generate`, which is unchanged.
128
+ - `@aventara/client` gains an `@aventara/client/internal` entry, which `@aventara/build` reads the generator through.
129
+ It is not public API.
130
+
131
+ - Updated dependencies [205a379]
132
+ - Updated dependencies [a0bb05e]
133
+ - Updated dependencies [86ab319]
134
+ - Updated dependencies [fdf52e6]
135
+ - @aventara/core@1.0.0-rc.9
136
+
137
+ ## 1.0.0-rc.8
138
+
139
+ 1.0.0-rc.5, rc.6 and rc.7 were tagged but never published; 1.0.0-rc.8 contains everything listed under them and the changes below.
140
+
141
+ ### Patch Changes
142
+
143
+ - A generated client's results read as their value types in an editor: `body: string | null`, `published: boolean`,
144
+ `publishedAt: Date | null`, where a nullable, enum or `boolean` field was shown as `AvScalarValueType<…>` with the
145
+ client's Contract as its argument, and a result as `ProjectedFields<…>`. Run `avclient generate` again to pick it up.
146
+ What the client accepts and returns is unchanged.
147
+ - Updated dependencies [1c8e4ee]
148
+ - @aventara/core@1.0.0-rc.8
149
+
150
+ ## 1.0.0-rc.7
151
+
152
+ 1.0.0-rc.5 and 1.0.0-rc.6 were tagged but never published; 1.0.0-rc.7 contains everything listed under them and the changes below.
153
+
154
+ ### Patch Changes
155
+
156
+ - Updated dependencies [f917c1c]
157
+ - @aventara/core@1.0.0-rc.7
158
+
159
+ ## 1.0.0-rc.6
160
+
161
+ 1.0.0-rc.5 was tagged but never published. 1.0.0-rc.6 contains everything listed under 1.0.0-rc.5 and the fix below.
162
+
163
+ ### Patch Changes
164
+
165
+ - Updated dependencies [1cf72e0]
166
+ - @aventara/core@1.0.0-rc.6
167
+
168
+ ## 1.0.0-rc.5
169
+
170
+ ### Patch Changes
171
+
172
+ - Updated dependencies [4795ff1]
173
+ - Updated dependencies [9e178ca]
174
+ - @aventara/core@1.0.0-rc.5
175
+
176
+ ## 1.0.0-rc.4
177
+
178
+ ### Patch Changes
179
+
180
+ - Updated dependencies [e3d03a7]
181
+ - Updated dependencies [d10639a]
182
+ - Updated dependencies [f67e68c]
183
+ - Updated dependencies [708556c]
184
+ - Updated dependencies [3a0dfca]
185
+ - Updated dependencies [99169d2]
186
+ - Updated dependencies [0fd2608]
187
+ - Updated dependencies [154e440]
188
+ - Updated dependencies [2fcffdb]
189
+ - @aventara/core@1.0.0-rc.4
190
+
191
+ ## 1.0.0-rc.3
192
+
193
+ ### Patch Changes
194
+
195
+ - Updated dependencies [b38034d]
196
+ - Updated dependencies [b38034d]
197
+ - Updated dependencies [b38034d]
198
+ - Updated dependencies [b38034d]
199
+ - Updated dependencies [b38034d]
200
+ - Updated dependencies [b38034d]
201
+ - @aventara/core@1.0.0-rc.3
202
+
203
+ ## 1.0.0-rc.2
204
+
205
+ ### Patch Changes
206
+
207
+ - The optional `typescript` peer range is `>=5.7.0` (it was `>=5.5.0`), the lowest TypeScript Aventara's types
208
+ compile under. `avclient generate` type-checks the client with TypeScript 5.7 or later; under an older one it parses
209
+ the output with Node's TypeScript parser (`checked: syntax`) and says so in one warning, as it did below 5.5.
210
+ - A generated client sends an `undefined` array element (or a hole) as `null`, as `JSON.stringify` writes it, and its
211
+ `json` codec leaves out a key holding `undefined` and writes such an element as `null`. A `json` value
212
+ `{ a: undefined, b: [undefined] }` is sent as `{"b":[null]}`, the value the server stores when an in-process caller
213
+ passes it. In rc.1 the client refused the array element with a `TypeError` before sending. Regenerate the client.
214
+ - A generated client's `json` values admit a key holding `undefined` in their type, as core's `AvJsonValue` now does,
215
+ so an object with optional properties can be passed where a `json` value is taken; the key is not sent. In rc.1 it
216
+ was a compile error. Regenerate the client.
217
+ - A generated client refuses at compile time a filter `mode` or `path` that qualifies no operator: one alone, or one
218
+ whose only neighbour is a `not` holding operators (`{ mode: "insensitive", not: { contains: "x" } }`). Write it
219
+ inside the `not`. The server refuses the same filters (`A2004`, `V1001`). Regenerate the client.
220
+ - A generated client types a filter's `mode` by the field: `"default"` always, and `"sensitive"` or `"insensitive"`
221
+ only where the ClientContract's `filterModes` lists them; any other mode is a compile error. On a `json` field an
222
+ operator object that names `path` takes the modes `pathFilterModes` lists instead, so on Postgres
223
+ `where: { meta: { stringContains: "x", mode: "insensitive" } }` is a compile error and
224
+ `where: { meta: { path: ["label"], stringContains: "x", mode: "insensitive" } }` compiles. `isEmpty` is typed as a boolean, `path` as an array of strings and a `json` field's `string*`
225
+ operand as a string. The server refuses the same values (`A2004`), so the client adds no runtime check of its own.
226
+ Regenerate the client: the Contract hash changes.
227
+ - The generated client refuses an `undefined` value in a filter before anything is sent. JSON drops `undefined`, so
228
+ `avClient.Post.update.many({ where: { id: undefined }, data })` reached the server as `where: {}` and updated every
229
+ row; the same went for `find`, `count`, `delete` and a transaction step. Now an `undefined` anywhere inside a
230
+ `where` (`AND`, `OR`, `NOT`, relation filters, operator objects such as `{ equals: undefined }` or
231
+ `{ isEmpty: undefined }`, `in` lists), a `cursor`, a unique selector, the `where` or `cursor` of a relation in
232
+ `select` or `include`, or a nested write's selectors (`$connect`, `$disconnect`, `$set`, `$delete`, the `where` of
233
+ `$update`, `$upsert` and `$connectOrCreate`) throws `AvValidationError` (`A2004`) with a `V1001` issue at the path
234
+ the server uses (`["arguments", "where", "id"]`, or `["operations", 0, "args", "where", "id"]` with the step's
235
+ `operation` for a transaction), and no request is made. A `where`, `cursor`, `limit` or `offset` that is itself
236
+ `undefined` is refused the same way, with the server's code (`V1001`; `V1007` for a unique selector, `V1009` for a
237
+ cursor), at the top level, in a relation under `select` or `include`, and in a nested write's `where`. Leave the
238
+ key out to mean no filter. Write data is unchanged: an `undefined` field there is not sent. Regenerate the client
239
+ to get the check.
240
+ - `avclient generate` in a directory with no config names the extensions it looks for as the docs list them:
241
+ `no framework.client.ts, .mts, .cts, .js, .mjs or .cjs in <directory>; …`. In rc.1 it read
242
+ `no framework.client.{js,ts,mjs,cjs,mts,cts} in <directory>`. `avclient --help` and `avclient generate --help` list
243
+ them in the same order: `framework.client.ts (or .mts, .cts, .js, .mjs, .cjs)`. Which files are read is unchanged.
244
+ - Updated dependencies [9366e16]
245
+ - Updated dependencies [9366e16]
246
+ - Updated dependencies [9366e16]
247
+ - Updated dependencies [9366e16]
248
+ - @aventara/core@1.0.0-rc.2
249
+
3
250
  ## 1.0.0-rc.1
4
251
 
5
252
  ### Patch Changes
package/README.md CHANGED
@@ -96,7 +96,7 @@ A failed run leaves the previous output exactly as it was. The whole tree is wri
96
96
  `generateAt`, validated there as one program, and only then moved into place. A run killed part-way is repaired by the
97
97
  next run that writes, before it writes anything. A first run that fails removes the directories it created.
98
98
 
99
- The validate step is a real type check when your project has the optional peer `typescript` (5.5 to 6). It is resolved
99
+ The validate step is a real type check when your project has the optional peer `typescript` (5.7 to 6). It is resolved
100
100
  from your project, so `npx @aventara/client@rc init` type-checks too, under a consumer's strictest plausible settings
101
101
  and with nothing outside the tree resolvable. Without it, or under TypeScript 7 (which has no classic compiler API to
102
102
  check with), the check falls back to a parse with Node's own TypeScript parser and says so in one warning. It is never
@@ -125,20 +125,112 @@ const maybe = await avClient.User.find.first({ where }); // User | null — a mi
125
125
  ClientContract (tests, SSR), and `fetch` is for a custom fetch.
126
126
  - The client has one property per Resource, one per family under it, and one per advertised variant. Only what the
127
127
  ClientContract advertises exists, in the type and at runtime. A Resource named like one of the client's own members
128
- (`tx`, `transaction`, `then`, `constructor`, `Object.prototype`'s names) is reached as `<name>Model`, with one
128
+ (`all`, `tx`, `transaction`, `then`, `constructor`, `Object.prototype`'s names) is reached as `<name>Model`, with one
129
129
  warning; its wire name is unchanged.
130
130
  - A call resolves to the data: the record, a list, a count. A first-style miss (`A1001`) is `null`. Every other
131
131
  outcome throws the `AvError` subclass of its code (`AvNotFoundError` for a strict-unique miss,
132
132
  `AvContractMismatchError` for a stale client, …), or `AvTransportError` when no framework answer arrived.
133
133
  - Values are application values: `bigint`, `Date`, `Uint8Array`, the client's `AvDecimal`, JSON values as they are.
134
134
  Arguments are encoded and results revived for you; a value that cannot be read throws `AvTransportError`.
135
- - Per-call options (`AvCallOptions`) are never sent in the body: `signal` (an abort rejects with what `fetch` rejected
136
- with), `headers` (the framework's own identity headers are refused), and `requestId`, sent as `Aventara-Request-Id`
137
- and winning over that header in `headers`.
135
+ - Per-call options (`AvCallOptions`) are never sent in the body: `signal` (aborts this call only, see below),
136
+ `headers` (the framework's own identity headers are refused), `requestId`, sent as `Aventara-Request-Id` and winning
137
+ over that header in `headers`, and `grouping: false` (see below).
138
138
  - The named types (`User`, `UserWhere`, `UserUniqueWhere`, `UserOrderBy`, `UserCreateData`, `UserUpdateData`,
139
139
  `UserSelect`, `UserInclude`) are named exports, each only when the operation it reads is advertised. A name that would
140
140
  clash walks the rename ladder (`User` beside a Resource `UserWhere` becomes `UserModel`), one warning each.
141
141
 
142
+ ## Calls run when made, together
143
+
144
+ A call runs when you make it, as `fetch` does: it checks and encodes its arguments and is queued at once, and a call
145
+ you never await still runs. A transaction too. Awaiting a call again does not send it again.
146
+
147
+ The calls made in one tick go out as one request, `POST /_all` (an Operation Set):
148
+
149
+ ```ts
150
+ const [campaigns, unread, me] = await Promise.all([
151
+ avClient.Campaign.find.many({ where: { ownerId } }),
152
+ avClient.Message.find.count({ where: { toId: ownerId, readAt: null } }),
153
+ avClient.User.find.unique({ where: { id: ownerId } }),
154
+ ]); // one request
155
+ ```
156
+
157
+ - Each call runs on the server exactly as it would alone (validation, exposure, policy, limits, pipelines), concurrently
158
+ with the others and not atomically: a write that ran stays written whatever the others answered. Each call resolves
159
+ or throws on its own, as soon as its own answer arrives (the client asks for a streamed answer,
160
+ `Accept: application/x-ndjson`, where the runtime can read one, and reads a plain JSON answer otherwise, as on React
161
+ Native).
162
+ - Together means made before the microtask queue settles: one `Promise.all`, several async functions run together,
163
+ `avClient.all`. No timer is involved, and a call made on its own goes to its own route as before.
164
+ - A group larger than the ClientContract's `limits.maxAll` (or `limits.maxRequestBytes`) is split into several
165
+ requests.
166
+ - Sent alone, never grouped: a call with `headers` or a `requestId` (they belong to one request), a call made with
167
+ `{ grouping: false }`, every call of a client made with `new AvClient({ grouping: false })`, and a transaction.
168
+ - A server without `/_all` (it answers `A2002`) gets the calls again one by one, and that client stops grouping.
169
+
170
+ ### Aborting a call
171
+
172
+ A call's `signal` aborts that call and nothing else. Aborted before it is sent, it is never sent. Aborted while its
173
+ group is in flight, it rejects at once with the signal's reason (an `AbortError`), and the others in the request go on;
174
+ the request itself is aborted once no call in it still waits for an answer. Sent alone, the abort aborts its request,
175
+ as before. The server still finishes an operation it has already started: there is no way to cancel a database query
176
+ once it runs.
177
+
178
+ Nothing is aborted for you: there is no default timeout and no abort on navigation. Pass the signal your data library
179
+ gives you (React Query and SWR pass one per query), or your own.
180
+
181
+ ### `avClient.all`
182
+
183
+ ```ts
184
+ const { campaigns, unread } = await avClient.all({
185
+ campaigns: avClient.Campaign.find.many({ where: { ownerId } }),
186
+ unread: avClient.Message.find.count({ where: { toId: ownerId, readAt: null } }),
187
+ });
188
+ ```
189
+
190
+ `all` takes an object of calls and resolves one value per key, typed per key. It is strict: the first failure rejects
191
+ it with that call's error and aborts its other calls. That is fail-fast, not atomic: a write that already ran stays
192
+ written. With `{ settle: true }` every key settles on its own, as `{ status: "fulfilled", value }` or
193
+ `{ status: "rejected", reason }`, and `all` never rejects for one key:
194
+
195
+ ```ts
196
+ const panels = await avClient.all({ campaigns, unread }, { settle: true });
197
+ if (panels.unread.status === "rejected") { /* show that panel's error */ }
198
+ ```
199
+
200
+ `{ signal }` aborts every call of that `all`; a call inside it is aborted by its own signal or by the `all`'s. Calls
201
+ grouped beside it but not in it are never touched. The keys are yours and are never sent.
202
+
203
+ ### `avLazy`: describe now, run later
204
+
205
+ ```ts
206
+ import avClient, { avLazy } from "./api/AvClient";
207
+
208
+ const posts = avLazy(() => avClient.Post.find.many({ where: { published: true } })); // nothing sent yet
209
+ const list = await posts; // sent now (once, in a page)
210
+ ```
211
+
212
+ `avLazy(() => call)` makes the call on its first `then`, `catch` or `finally`, and settles as that call does. In a
213
+ page it makes the call once and keeps the answer. On a server, where one module serves every request, it keeps nothing:
214
+ each await makes the call again. `avClient.all` accepts it as it accepts a call (its `signal` aborts that call too).
215
+
216
+ ## Cached reads are GETs
217
+
218
+ A read the deployment caches (a `cache({ for, maxAge })` stage on it, which its ClientContract marks) is sent as a GET,
219
+ so the browser, or a CDN when the stage allows one, may keep its answer:
220
+
221
+ ```
222
+ GET <entrypoint>/_resources/Product/find/many?q=<arguments>&v=<ClientContract hash>
223
+ ```
224
+
225
+ - `q` is the arguments' canonical JSON (keys sorted, so the same read is the same URL), percent-encoded, or that JSON
226
+ deflate-raw'd and base64url'd when that is shorter. Where the runtime has no `CompressionStream` the plain form is sent.
227
+ - A cached read is never grouped into `/_all`: each keeps its own URL, its own cache entry. Your `headers` and
228
+ `requestId` go with the GET; it sends no header of its own, so a cross-origin read needs no CORS preflight. Its
229
+ `signal` aborts it as any call's does.
230
+ - A URL longer than 4096 characters (the whole URL) is POSTed to the same route instead, uncached, as are arguments
231
+ canonical JSON cannot write.
232
+ - The URL holds the arguments, so it lands in server and proxy logs and in browser history.
233
+
142
234
  ## Transactions
143
235
 
144
236
  When the ClientContract advertises `interactive` transactions, the client has `avClient.tx` and `avClient.transaction`
@@ -170,7 +262,7 @@ Its source field must have the same type as where it is written:
170
262
 
171
263
  A mismatch is a type error, and the server refuses it before anything runs (`A2007`/`V1011`).
172
264
 
173
- `avClient.tx.…` builds a handle and sends nothing. `avClient.transaction([...])` sends the plan once and resolves one
265
+ `avClient.tx.…` builds a handle and sends nothing. `avClient.transaction([...])` sends the plan once, when made, and resolves one
174
266
  result per handle, typed, in order; a failing step throws its error with `cause.operation` naming the step. `$ref` binds
175
267
  to the handle's position in the list it runs with. Two mistakes are refused before anything is sent, as core refuses
176
268
  them in process: one handle twice (`AvValidationError`, `A2004`/`V1001`), and a `$ref` to a handle not in the list
@@ -192,6 +284,42 @@ The platform `fetch` is read when a call is made, not when the client is importe
192
284
  where there is no `fetch`; a call does, saying why. An entrypoint carrying credentials is refused when the config is
193
285
  resolved.
194
286
 
287
+ ## Aventara Access: `$access`
288
+
289
+ When the deployment's ClientContract has the `access` section (the framework is configured with `access`), the client
290
+ has `$access`:
291
+
292
+ ```ts
293
+ const answers = await avClient.$access.can([
294
+ { resource: "Order", action: "update", where: { id: 41 } },
295
+ { resource: "Refund", action: "create" },
296
+ ]); // [boolean, boolean], one request to /_access/can
297
+ await avClient.$access.signIn({ email, password }); // Access's own route
298
+ const me = await avClient.$access.me(); // AvAccessMe | null
299
+ ```
300
+
301
+ `can` is always there; `me`, `signIn`, `signUp`, `signOut` and `resetPassword`, and on Access's `kiosk` profile
302
+ `switchUser`, `lock`, `setPin`, `enrollDevice` and `revokeDevice`, exactly when the section states them.
303
+ Each verb calls Access's own route (`me` with `GET` and `cache: "no-store"`), and resolves its result projected onto the
304
+ section's schema: members the schema does not declare are dropped. `AvAccessMe` is `me`'s result type. A non-2xx answer
305
+ from Access throws `AvAccessError` (`status`, `code`, `message`); `can`'s refusals are `AvError`s, as every call's.
306
+ Without the section there is no `$access`.
307
+
308
+ Where Access lives decides where a sign-in's credentials go, so the generator emits an absolute Access URL only when it
309
+ is on the entrypoint's origin, or on an origin `framework.client.ts` lists:
310
+
311
+ ```ts
312
+ export default defineClientConfig({
313
+ entrypoint: env("AVENTARA_API_URL"),
314
+ generateAt: "./src/api",
315
+ accessOrigins: ["https://auth.example.com"],
316
+ });
317
+ ```
318
+
319
+ A verb on another origin carries cookies only when your `fetch` sends them: pass one that does
320
+ (`new AvClient({ fetch: (url, init) => fetch(url, { ...init, credentials: "include" }) })`), and have Access allow
321
+ that origin with credentials (CORS).
322
+
195
323
  ## Up to date
196
324
 
197
325
  A rerun asks the deployment conditionally (`If-None-Match`, the ClientContract hash of the output it finds), but only
@@ -208,7 +336,7 @@ repository uses. The `.d.ts` files are core's copied declarations under `generat
208
336
  and the named types in `generated/types.d.ts`; the `.ts` sources carry their own types.
209
337
 
210
338
  - `AvClient.ts`: the entry point you import: `avClient` (the default export), `AvClient`, `AvClientOptions`,
211
- `AvCallOptions`, `AvFetch`, `AvOperation`, the named Resource types, the enums, `AvDecimal`, `AvError` and its
339
+ `AvCallOptions`, `AvFetch`, `AvOperation`, `avLazy`, the named Resource types, the enums, `AvDecimal`, `AvError` and its
212
340
  subclasses, `AvTransportError`, and the types `AvCause`, `AvValidationIssue`, `AvOperationCode` and `AvValidationCode`.
213
341
  - `generated/client.ts`: the typed client: the class `AvClient`, `AvClientOptions`, `AvCallOptions` and the ready
214
342
  instance `avClient`. Every argument and result type is an instantiation of core's own derivation.
@@ -219,6 +347,10 @@ and the named types in `generated/types.d.ts`; the `.ts` sources carry their own
219
347
  - `generated/enums.ts`: each enum as a union type and a same-named `as const` object.
220
348
  - `generated/metadata.ts`: the ClientContract hash and protocol version the client is bound to, and the entrypoint it
221
349
  was generated from, which is its default deployment (an entrypoint carrying credentials is refused at resolution).
350
+ - `generated/runtime/cached-read.ts`: a cached read's GET: its `q` (canonical JSON, plain or deflate-raw), its
351
+ `v`, and the POST past 4096 characters. Emitted only when the ClientContract caches a read.
352
+ - `generated/runtime/canonical-json.ts`: `@aventara/core`'s canonical JSON writer, its compiled source copied as it is
353
+ (unchecked: `// @ts-nocheck`). Emitted only when the ClientContract caches a read.
222
354
  - `generated/runtime/codec.ts`: the nine scalars' wire codecs, and the request-body serializer.
223
355
  - `generated/runtime/decimal.ts`: the framework's `AvDecimal`, with a constructor, `toString` and `toJSON`.
224
356
  - `generated/runtime/descriptor.ts`: what the runtime reads of the contract: the result fields it revives and the
@@ -235,12 +367,16 @@ and the named types in `generated/types.d.ts`; the `.ts` sources carry their own
235
367
  carries a check.
236
368
  - `generated/runtime/fingerprint.ts`: the operation fingerprint (RFC 8785 canonical JSON, SHA-256, base64url),
237
369
  dependency-free and pinned to core's. Emitted only when transactions are `interactive`.
370
+ - `generated/runtime/operation-set.ts`: the calls, queued when made, the grouping of the calls made together into
371
+ Operation Sets
372
+ (`POST /_all`), per-call abort, and `avClient.all`.
238
373
  - `generated/runtime/transaction.ts`: `avClient.tx`'s deferred handles and `avClient.transaction`'s plan assembly,
239
374
  refusals and one POST to `/_transactions`. Emitted only when transactions are `interactive`.
240
- - `generated/runtime/transport.ts`: one POST per operation with the identity headers, and the response read by the
241
- protocol's rule. Arguments are encoded by value, results revived by the decode table, and the platform's own `fetch`
242
- type is accepted. Its `execute` primitive is module-private: no public file re-exports it, and `AvClient`'s methods
243
- wrap it.
375
+ - `generated/runtime/transport.ts`: one POST per operation, or one `POST /_all` per Operation Set (its answer read
376
+ streamed or whole), with the identity headers, and the response read by the protocol's rule. Arguments are encoded
377
+ by value, results revived by the decode table, and the platform's own `fetch` type is accepted. Its primitives are
378
+ module-private: no public file re-exports them, and `AvClient`'s methods reach them through
379
+ `generated/runtime/operation-set.ts`.
244
380
  - `generated/types.d.ts`: the named Resource types, as a declaration file (`User`, `UserWhere`, `UserUniqueWhere`,
245
381
  `UserOrderBy`, `UserCreateData`, `UserUpdateData`, `UserSelect`, `UserInclude`), each only when its operation is
246
382
  advertised.
@@ -1,5 +1,5 @@
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";
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";
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 .mts, .cts, .js, .mjs,\n .cjs) 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";
2
+ export declare const GENERATE_USAGE = "Usage: avclient generate [--yes]\n\nRead framework.client.ts (or .mts, .cts, .js, .mjs, .cjs) 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";
3
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 --verbose Show the install's output as it runs.\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";
4
4
  export type ClientInitCommand = {
5
5
  readonly command: "init";
@@ -12,7 +12,7 @@ export type ClientInitCommand = {
12
12
  readonly verbose?: boolean;
13
13
  };
14
14
  /** What the command line asked for. */
15
- export type CliCommand = {
15
+ type CliCommand = {
16
16
  readonly command: "help";
17
17
  readonly topic?: "generate" | "init";
18
18
  } | {
@@ -30,3 +30,4 @@ export declare class AvCliCommandError extends Error {
30
30
  * `--help`/`-h` or `--version`/`-v`.
31
31
  */
32
32
  export declare function parseCliCommand(argv: readonly string[]): CliCommand;
33
+ export {};
@@ -2,8 +2,8 @@ import { CLIENT_CONFIG_FILE } from "../config/config.loader.js";
2
2
  export const USAGE = `avclient — generate a typed Aventara client from a deployed ClientContract.
3
3
 
4
4
  Usage:
5
- avclient generate [--yes] Read ${CLIENT_CONFIG_FILE} (or .js, .mjs, .cjs, .mts,
6
- .cts) in the current directory, fetch
5
+ avclient generate [--yes] Read ${CLIENT_CONFIG_FILE} (or .mts, .cts, .js, .mjs,
6
+ .cjs) in the current directory, fetch
7
7
  <entrypoint>/_contract, and write AvClient.ts and
8
8
  generated/ into its generateAt directory, its imports
9
9
  spelled as the project's tsconfig.json says.
@@ -39,7 +39,7 @@ current directory, highest precedence first: the process environment,
39
39
  `;
40
40
  export const GENERATE_USAGE = `Usage: avclient generate [--yes]
41
41
 
42
- Read ${CLIENT_CONFIG_FILE} (or .js, .mjs, .cjs, .mts, .cts) in the current directory,
42
+ Read ${CLIENT_CONFIG_FILE} (or .mts, .cts, .js, .mjs, .cjs) in the current directory,
43
43
  fetch <entrypoint>/_contract, and write AvClient.ts and generated/ into its
44
44
  generateAt directory, its imports spelled as the project's tsconfig.json says.
45
45
 
@@ -1,6 +1,7 @@
1
- export interface GenerationFailureReport {
1
+ interface GenerationFailureReport {
2
2
  readonly exitCode: number;
3
3
  /** What goes to stderr, newline-terminated: the warnings carried, then the sentence. */
4
4
  readonly text: string;
5
5
  }
6
6
  export declare function renderGenerationFailure(error: unknown): GenerationFailureReport;
7
+ export {};
@@ -6,7 +6,7 @@ import type { ClientGenerated, ClientUpToDate, ForeignOutputContent } from "../g
6
6
  * them — renames, the degraded check, crash recovery — so the same run prints the
7
7
  * same lines.
8
8
  */
9
- export interface GenerationSuccessReport {
9
+ interface GenerationSuccessReport {
10
10
  /** What goes to stdout, newline-terminated. */
11
11
  readonly stdout: string;
12
12
  /** What goes to stderr: one line per warning, or nothing. */
@@ -29,3 +29,4 @@ export declare const FOREIGN_CONTENT_QUESTION = "avclient: overwrite them and ge
29
29
  * are reported as a refused one's are.
30
30
  */
31
31
  export declare function renderForeignContentCancellation(found: ForeignOutputContent, asked: boolean): string;
32
+ export {};
@@ -1,7 +1,7 @@
1
1
  export type ProgressMode = "live" | "plain" | "off";
2
2
  /** `live` only on a terminal that is not CI and accepts control sequences. */
3
3
  export declare function progressModeOf(isTTY: boolean | undefined, env: Readonly<Record<string, string | undefined>>): Exclude<ProgressMode, "off">;
4
- export type StepReporterOptions = {
4
+ type StepReporterOptions = {
5
5
  /** Where the lines go: the tool's stderr, so its stdout stays its result. */
6
6
  readonly write: (text: string) => void;
7
7
  readonly mode: ProgressMode;
@@ -29,3 +29,4 @@ export type StepReporter = {
29
29
  /** `12.4s`, or `1m 02s` from a minute. */
30
30
  export declare function formatElapsed(milliseconds: number): string;
31
31
  export declare function createStepReporter(options: StepReporterOptions): StepReporter;
32
+ export {};
@@ -1,6 +1,7 @@
1
- export type TerminalPrompter = {
1
+ type TerminalPrompter = {
2
2
  readonly ask: (prompt: string) => Promise<string>;
3
3
  readonly confirm: (question: string) => Promise<boolean>;
4
4
  readonly close: () => void;
5
5
  };
6
6
  export declare function createTerminalPrompter(): TerminalPrompter;
7
+ export {};
@@ -28,6 +28,13 @@ export interface AvClientConfigInput {
28
28
  * `generateAt` is used.
29
29
  */
30
30
  readonly tsconfigFile?: string;
31
+ /**
32
+ * The origins other than the entrypoint's that `$access` may send a
33
+ * sign-in to (`"https://auth.example.com"`): where the deployment mounted
34
+ * Aventara Access, when that is another origin. Absent, the generator
35
+ * refuses a ClientContract whose Access URL is on another origin.
36
+ */
37
+ readonly accessOrigins?: readonly AvClientConfigValue[];
31
38
  }
32
39
  /** A filesystem path known to be absolute. */
33
40
  export type AbsolutePath = string & {
@@ -44,11 +51,21 @@ export interface ClientEntrypoint {
44
51
  readonly deployment: URL;
45
52
  readonly path: EntrypointPath;
46
53
  }
54
+ /** An entrypoint on the page's own origin: its mount path alone, such as `/api`. */
55
+ export interface SameOriginEntrypoint {
56
+ /** Absent: the deployment is whichever origin served the page. */
57
+ readonly deployment?: undefined;
58
+ readonly path: EntrypointPath;
59
+ }
60
+ /** The entrypoint a generated client embeds as its default: a deployment's, or the page's own origin. */
61
+ export type EmittedEntrypoint = ClientEntrypoint | SameOriginEntrypoint;
47
62
  export interface ResolvedClientConfig {
48
63
  readonly entrypoint: ClientEntrypoint;
49
64
  /** `generateAt`, made absolute. */
50
65
  readonly generateAt: AbsolutePath;
51
66
  /** `tsconfigFile`, made absolute; absent when the config names none. */
52
67
  readonly tsconfigFile?: AbsolutePath;
68
+ /** `accessOrigins`, each an http(s) origin (`scheme://host[:port]`); empty when the config names none. */
69
+ readonly accessOrigins: readonly string[];
53
70
  readonly mode: string;
54
71
  }
@@ -1,11 +1,15 @@
1
1
  import type { AvClientConfigInput } from "./client-config.interface.js";
2
2
  /** Prisma's `SUPPORTED_EXTENSIONS`, in its order. */
3
3
  export declare const CLIENT_CONFIG_FILE_EXTENSIONS: readonly [".js", ".ts", ".mjs", ".cjs", ".mts", ".cts"];
4
- /** The config's name, before its extension. */
5
- export declare const CLIENT_CONFIG_BASENAME = "framework.client";
4
+ /**
5
+ * The same extensions as the docs and `avclient --help` list them, TypeScript
6
+ * first: the order a sentence to the developer names them in. Lookup keeps
7
+ * {@link CLIENT_CONFIG_FILE_EXTENSIONS}' order, Prisma's.
8
+ */
9
+ export declare const CLIENT_CONFIG_FILE_EXTENSIONS_AS_LISTED: readonly [".ts", ".mts", ".cts", ".js", ".mjs", ".cjs"];
6
10
  /** The config file `avclient init` writes when the project has none. */
7
11
  export declare const CLIENT_CONFIG_FILE = "framework.client.ts";
8
- export interface LoadedClientConfig {
12
+ interface LoadedClientConfig {
9
13
  /** The config file's absolute path; `generateAt` resolves against its directory. */
10
14
  readonly file: string;
11
15
  readonly config: AvClientConfigInput;
@@ -30,3 +34,4 @@ export declare function findClientConfigFile(directory: string): string | undefi
30
34
  * or the file does not evaluate, or does not default-export a client config.
31
35
  */
32
36
  export declare function loadClientConfigFile(directory: string): Promise<LoadedClientConfig>;
37
+ export {};