@foir/sdk 0.5.0 → 0.8.0

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 (107) hide show
  1. package/CHANGELOG.md +1126 -0
  2. package/README.md +94 -0
  3. package/dist/auth/auth.d.ts +243 -0
  4. package/dist/auth/hosted.d.ts +40 -0
  5. package/dist/auth/index.d.ts +21 -0
  6. package/dist/auth/operations.d.ts +144 -0
  7. package/dist/auth/ops.d.ts +99 -0
  8. package/dist/auth/session-client.d.ts +76 -0
  9. package/dist/auth-session.js +137 -0
  10. package/dist/auth.js +973 -92
  11. package/dist/chunk-IGNLWT3H.js +35 -0
  12. package/dist/chunk-OHYVKTGB.js +45 -0
  13. package/dist/chunk-TAL5H6VA.js +39 -0
  14. package/dist/client/platform-client.d.ts +29 -0
  15. package/dist/client.js +275 -37
  16. package/dist/codegen/block-registry.d.ts +13 -23
  17. package/dist/codegen/block-registry.js +3 -31
  18. package/dist/codegen/block-scaffold.d.ts +12 -25
  19. package/dist/codegen/block-scaffold.js +3 -41
  20. package/dist/codegen/index.d.ts +12 -61
  21. package/dist/codegen/index.js +7 -11
  22. package/dist/codegen/item-registry.d.ts +28 -0
  23. package/dist/codegen/item-registry.js +7 -0
  24. package/dist/codegen/item-scaffold.d.ts +29 -0
  25. package/dist/codegen/item-scaffold.js +7 -0
  26. package/dist/codegen/preset.d.ts +67 -0
  27. package/dist/codegen/shared.d.ts +36 -0
  28. package/dist/components/EditorProvider.d.ts +36 -0
  29. package/dist/content/content-renderer.d.ts +113 -0
  30. package/dist/content/index.d.ts +18 -0
  31. package/dist/content/richtext.d.ts +118 -0
  32. package/dist/content.js +227 -80
  33. package/dist/data/builtins.d.ts +506 -0
  34. package/dist/data/client.d.ts +166 -0
  35. package/dist/data/document.d.ts +251 -0
  36. package/dist/data/index.d.ts +73 -0
  37. package/dist/data/manifest.d.ts +424 -0
  38. package/dist/data/schema.d.ts +313 -0
  39. package/dist/data/selection.d.ts +524 -0
  40. package/dist/data/subjects.d.ts +221 -0
  41. package/dist/data/subscription-document.d.ts +75 -0
  42. package/dist/data/subscriptions.d.ts +181 -0
  43. package/dist/data/transport.d.ts +325 -0
  44. package/dist/data/ws-transport.d.ts +197 -0
  45. package/dist/data.js +1683 -0
  46. package/dist/graphql/cdn-route.d.ts +26 -0
  47. package/dist/graphql/client.d.ts +30 -0
  48. package/dist/graphql/content-client.d.ts +66 -0
  49. package/dist/graphql/foir-request.d.ts +47 -0
  50. package/dist/hooks/useAutoResize.d.ts +22 -0
  51. package/dist/hooks/useEditor.d.ts +16 -0
  52. package/dist/index.d.ts +10 -394
  53. package/dist/media/BlurhashCanvas.d.ts +10 -0
  54. package/dist/media/ProgressiveMedia.d.ts +56 -0
  55. package/dist/media/index.d.ts +18 -0
  56. package/dist/media/media.d.ts +139 -0
  57. package/dist/media/screen-capture.d.ts +81 -0
  58. package/dist/media/useProgressiveLoad.d.ts +23 -0
  59. package/dist/media.js +102 -0
  60. package/dist/next/cookieAdapter.d.ts +26 -0
  61. package/dist/next/index.d.ts +15 -0
  62. package/dist/next/middleware.d.ts +49 -0
  63. package/dist/next/session.d.ts +53 -0
  64. package/dist/next.js +763 -78
  65. package/dist/protocol/constants.d.ts +6 -0
  66. package/dist/protocol/messages.d.ts +155 -0
  67. package/dist/protocol/validation.d.ts +8 -0
  68. package/dist/push/index.d.ts +14 -0
  69. package/dist/push/operations.d.ts +22 -0
  70. package/dist/push/web-push.d.ts +39 -0
  71. package/dist/push.js +892 -78
  72. package/dist/react/FoirFeedback.d.ts +62 -0
  73. package/dist/react/FoirProvider.d.ts +116 -0
  74. package/dist/react/OAuthButtons.d.ts +20 -0
  75. package/dist/react/SignIn.d.ts +22 -0
  76. package/dist/react/UserButton.d.ts +13 -0
  77. package/dist/react/feedback-notes.d.ts +101 -0
  78. package/dist/react/index.d.ts +25 -0
  79. package/dist/react/localStorageAdapter.d.ts +10 -0
  80. package/dist/react.js +1373 -91
  81. package/dist/{realtime.d.ts → realtime/index.d.ts} +35 -16
  82. package/dist/realtime.js +1 -1
  83. package/dist/server/callback-client.d.ts +92 -0
  84. package/dist/server/events-client.d.ts +279 -0
  85. package/dist/server/index.d.ts +12 -0
  86. package/dist/server/operation-types.d.ts +134 -0
  87. package/dist/server/require-scoped-token.d.ts +76 -0
  88. package/dist/server/server-client.d.ts +34 -0
  89. package/dist/server/types.d.ts +54 -0
  90. package/dist/server/verify-scoped-token.d.ts +100 -0
  91. package/dist/server/webhook-helpers.d.ts +36 -0
  92. package/dist/server.js +298 -0
  93. package/dist/transport/foir-http.d.ts +234 -0
  94. package/dist/transport/persisted-query.d.ts +68 -0
  95. package/dist/transport/retry.d.ts +61 -0
  96. package/dist/types/index.d.ts +124 -0
  97. package/package.json +35 -13
  98. package/dist/auth.d.ts +0 -382
  99. package/dist/chunk-ADO5FJNM.js +0 -30
  100. package/dist/client.d.ts +0 -135
  101. package/dist/content.d.ts +0 -96
  102. package/dist/media.d.ts +0 -234
  103. package/dist/next.d.ts +0 -178
  104. package/dist/push.d.ts +0 -109
  105. package/dist/react.d.ts +0 -319
  106. package/dist/server.d.ts +0 -534
  107. package/dist/shared-DkWlEd2Z.d.ts +0 -18
@@ -0,0 +1,424 @@
1
+ /**
2
+ * `GET /v1/manifest` — the per-caller surface descriptor, as a runtime type.
3
+ *
4
+ * This is the *runtime* mirror of `schema.ts`'s compile-time contract: what the
5
+ * server actually sends, verbatim, so `foir types` (TTS-875) has a typed thing
6
+ * to read and the drift check has a version to compare. The manifest is already
7
+ * the projection of `CachedSchema.SchemaForCaller(scopes)`, so what it lists is
8
+ * exactly what this credential may do — no client-side filtering anywhere.
9
+ *
10
+ * Shape verified against deployed dev on 2026-07-28, against two live keys
11
+ * (an unnarrowed one over 7 models, and one narrowed to a single model whose
12
+ * `tilly_page.blocks` union carries 29 members). The buckets below are the
13
+ * platform's `Manifest` struct
14
+ * (`api-public/internal/schema/manifest.go`) field for field; where the two
15
+ * disagree the platform is right and this file is the bug.
16
+ */
17
+ import { type FoirClientConfig } from './transport';
18
+ export interface FoirManifestScalar {
19
+ key: string;
20
+ /**
21
+ * GraphQL named type: a scalar (`String`, `Float`, `Boolean`, `ID`,
22
+ * `DateTime`, `JSON`), a generated enum (then `enumValues` is set), or one of
23
+ * the closed set of platform-owned value objects (`Image`, `Video`,
24
+ * `FileValue`, `MediaValue`, `Richtext`, `GeoPoint`,
25
+ * `Reference`, `CollabInfo`) — see `builtins.ts`.
26
+ */
27
+ type: string;
28
+ /**
29
+ * Mirrors the EXECUTABLE schema, NOT the model's `required` flag. The schema
30
+ * generator deliberately never emits NonNull for a user field, so a
31
+ * `required: true` field still reports `nullable: true`. Reporting otherwise
32
+ * would be the lie a consumer's generated types cannot recover from.
33
+ */
34
+ nullable: boolean;
35
+ list: boolean;
36
+ /** Enum value NAMES (what the wire carries). Set only when `type` names an enum. */
37
+ enumValues?: string[];
38
+ /**
39
+ * A soft-deleted field, still in the executable schema for its 30-day grace
40
+ * window and always resolving null. Reported rather than dropped so an
41
+ * in-flight client query still type-checks.
42
+ */
43
+ deprecated?: boolean;
44
+ }
45
+ export interface FoirManifestRelation {
46
+ key: string;
47
+ /** Model key of the relation's target. Absent for a polymorphic reference. */
48
+ target?: string;
49
+ /** Member model keys, for a polymorphic reference (a `Ref` union over ≥2 models). */
50
+ targets?: string[];
51
+ list: boolean;
52
+ /** A Relay connection (the association-inverse shape) rather than a plain list. */
53
+ connection?: boolean;
54
+ nullable: boolean;
55
+ deprecated?: boolean;
56
+ }
57
+ /**
58
+ * An embedded (inline) model field: `seo`, `page_content`, `section`.
59
+ *
60
+ * Its own bucket because neither of the other two fits — always returned like
61
+ * a scalar, structurally nested like a relation, and never `include`-able.
62
+ */
63
+ export interface FoirManifestComposite {
64
+ key: string;
65
+ /** The embedded model's key. Its shape is in `models`. */
66
+ target: string;
67
+ list: boolean;
68
+ nullable: boolean;
69
+ deprecated?: boolean;
70
+ }
71
+ export interface FoirManifestOp {
72
+ /** GraphQL root field this op compiles to, e.g. `tillyBlocks`. */
73
+ field: string;
74
+ args?: string[];
75
+ /**
76
+ * Each name in `args` mapped to the GraphQL type the root field declares for
77
+ * it — `'String!'`, `'[PageOrderByInput]'`, `'SortDirection'` — spelled
78
+ * exactly as a variable definition needs it.
79
+ *
80
+ * This is what lets the printer emit `query FoirQuery($orderBy: [PageOrderByInput])`
81
+ * and put the value in `variables`, where the executor coerces it. Without
82
+ * the type a printer has to infer a LITERAL from the JavaScript value, which
83
+ * is exact for strings, numbers, booleans and objects and ambiguous for
84
+ * enums — the client holds the string `'DESC'` and `orderBy: { createdAt: DESC }`
85
+ * needs it unquoted.
86
+ *
87
+ * An argument named in `args` with no entry here has no type this projection
88
+ * could read. The printer REFUSES such a call: inferring the literal form
89
+ * from the value is the defect this field exists to remove, so falling back
90
+ * to it would reintroduce it under a condition nobody can see.
91
+ */
92
+ argTypes?: Record<string, string>;
93
+ /** True when the field lives on the Mutation root. */
94
+ mutation?: boolean;
95
+ /**
96
+ * The resolved shape of this op's RESULT.
97
+ *
98
+ * The model's own `selection` answers for `findUnique` and for nothing else:
99
+ * `findMany` returns a connection OVER the model, `search` returns a wrapper
100
+ * CARRYING it, `delete` returns `Boolean!`, and `myAccess` returns a payload
101
+ * that is not the model in any sense. A consumer that bridged that gap by
102
+ * knowing from the OP NAME which shape to print was carrying a schema under
103
+ * another name.
104
+ *
105
+ * Absent is not "no selection". A consumer must refuse the op rather than
106
+ * synthesise a shape for it.
107
+ */
108
+ payload?: FoirManifestOpPayload;
109
+ }
110
+ /**
111
+ * The resolved shape of one op's result — four kinds, and the printer handles
112
+ * all four rather than defaulting.
113
+ */
114
+ export interface FoirManifestOpPayload {
115
+ /**
116
+ * - `record` — the payload IS the model named by `model`; print that model's
117
+ * published `selection` as the root field's selection set.
118
+ * - `object` — `fields` is the resolved selection set. A field carrying
119
+ * `model` expands to that model's `selection`, which is how the connection
120
+ * and search-result wrappers keep the record's tree in one place instead of
121
+ * copying it per op.
122
+ * - `union` — print one inline fragment per member of `selectionUnions[union]`.
123
+ * - `leaf` — `Boolean!`, `Int`, an enum. NO selection set: emitting `{}` is a
124
+ * parse error, which is why this is a stated kind rather than empty `fields`.
125
+ */
126
+ kind: 'record' | 'object' | 'union' | 'leaf';
127
+ /** Model key, for kind `record`. */
128
+ model?: string;
129
+ /** `selectionUnions` key, for kind `union`. */
130
+ union?: string;
131
+ /** The resolved selection, for kind `object`. */
132
+ fields?: FoirManifestSelectionField[];
133
+ /** What this payload emits when printed whole, in `FoirManifestSelection.cost`'s unit. */
134
+ cost?: number;
135
+ /**
136
+ * Why this payload could not be resolved. Set INSTEAD of the shape fields,
137
+ * never beside them — an op carrying an error has no printable shape and a
138
+ * consumer must refuse it.
139
+ */
140
+ error?: string;
141
+ }
142
+ /** A built field the projection has no bucket for. Reported rather than dropped. */
143
+ export interface FoirManifestUnclassifiedField {
144
+ key: string;
145
+ type: string;
146
+ list: boolean;
147
+ }
148
+ export interface FoirManifestModel {
149
+ typeName: string;
150
+ /**
151
+ * `record` for a record-bearing model, `embedded` for an inline model.
152
+ * Embedded models never carry `ops` — they exist in the payload only because
153
+ * a composite or a block union names them.
154
+ */
155
+ kind: string;
156
+ /**
157
+ * Present ⇔ the corresponding root field is in this caller's variant.
158
+ * ABSENT ENTIRELY on an embedded model, and on a record model no op of which
159
+ * survived pruning — hence optional, not `{}`.
160
+ */
161
+ ops?: Record<string, FoirManifestOp>;
162
+ /**
163
+ * The resolved complete-by-default selection for this model. Present on a
164
+ * server that publishes selection trees; absent otherwise.
165
+ *
166
+ * It hangs off the MODEL rather than each op because every op whose payload
167
+ * is this model shares one selection root.
168
+ */
169
+ selection?: FoirManifestSelection;
170
+ /** Why `selection` is absent, when the server could not resolve one. */
171
+ selectionError?: string;
172
+ scalars: FoirManifestScalar[];
173
+ relations: FoirManifestRelation[];
174
+ composites: FoirManifestComposite[];
175
+ /**
176
+ * Block-union field key → member model keys. Members that are built-in block
177
+ * primitives appear under their lowercase token (`text`, `image`, `video`,
178
+ * `file`, `richtext`, `media`, `reference`, `flexible`) and have NO entry in
179
+ * `models` — they are platform-owned, identical in every project, and typed
180
+ * statically by `builtins.ts`.
181
+ */
182
+ unions?: Record<string, string[]>;
183
+ /** Op names of this model's typed lookups. Each also appears in `ops`. */
184
+ lookups?: string[];
185
+ /**
186
+ * The model's `<Type>OrderByInput`, projected — the vocabulary of the
187
+ * `orderBy` argument.
188
+ *
189
+ * `fields` are the entry keys a sort element may carry; `directions` are the
190
+ * value names of the enum those entries are typed as (`ASC` / `DESC`). Both
191
+ * are read off the built input object server-side, so neither can disagree
192
+ * with what the executor coerces a caller's `orderBy` against.
193
+ *
194
+ * IT IS PUBLISHED BECAUSE NOTHING ELSE HERE ANSWERS FOR IT, and `scalars` —
195
+ * the field that looks like it should — is wrong in both directions at once:
196
+ *
197
+ * - wrong SET: `hero` (`Image`), `body` (`Richtext`), `_segments`
198
+ * (`JSON`) and every soft-deleted field are scalars and none is sortable;
199
+ * - wrong NAMES: the platform-managed columns are `_id` / `_createdAt` /
200
+ * `_updatedAt` / `_naturalKey` on the record type and `id` / `createdAt` /
201
+ * `updatedAt` / `naturalKey` in `OrderByInput`. A consumer deriving sort
202
+ * keys from the scalar list emits `_createdAt`, which the server refuses.
203
+ *
204
+ * `ops[op].argTypes.orderBy` names the input type (`[PageOrderByInput]`) and
205
+ * stops there: enough to print a variable definition, not enough to type a
206
+ * call site.
207
+ *
208
+ * ABSENT means "this projection has nothing to say" — an embedded model, or a
209
+ * server that predates the field. A consumer must WIDEN on absent, never read
210
+ * it as "nothing is sortable".
211
+ */
212
+ orderBy?: {
213
+ fields: string[];
214
+ directions: string[];
215
+ };
216
+ unclassifiedFields?: FoirManifestUnclassifiedField[];
217
+ cacheControl?: {
218
+ scope: string;
219
+ maxAge?: number;
220
+ };
221
+ }
222
+ /**
223
+ * One built-in non-model surface.
224
+ *
225
+ * `queries` / `mutations` hold ROOT FIELD NAMES, and for every namespace but
226
+ * one the op name a caller sends IS that root field name — the server matches
227
+ * on it and constructs nothing (`resolveNamespaceRoot`).
228
+ *
229
+ * `operations` is the exception, and it is why `execute` / `query` are on this
230
+ * interface rather than a second one: there the op name is `execute.<key>` or
231
+ * `query.<key>` built from an operation KEY, while `queries` / `mutations`
232
+ * still hold plain bookkeeping field names.
233
+ */
234
+ export interface FoirManifestNamespace {
235
+ queries?: string[];
236
+ mutations?: string[];
237
+ /** `operations` only: operation keys reachable as `execute.<key>`. */
238
+ execute?: string[];
239
+ /** `operations` only: operation keys reachable as `query.<key>`. */
240
+ query?: string[];
241
+ /**
242
+ * Each of those root fields described the way a model op is described:
243
+ * arguments with their types, and the resolved shape of the result.
244
+ *
245
+ * Keyed by the token the op is ADDRESSED by — the root field name for every
246
+ * namespace but `operations`, where it is `execute.<key>` / `query.<key>` for
247
+ * the per-operation surfaces and the plain field name for the bookkeeping
248
+ * ones. The lists above stay authoritative for REACHABILITY; this is the
249
+ * description of what those names do.
250
+ *
251
+ * Because an entry is a `FoirManifestOp`, whatever prints a model op prints a
252
+ * namespace op — one code path, not two.
253
+ */
254
+ ops?: Record<string, FoirManifestOp>;
255
+ }
256
+ export interface FoirManifest {
257
+ schemaVersion: number;
258
+ channel: 'published' | 'draft';
259
+ models: Record<string, FoirManifestModel>;
260
+ /**
261
+ * Keyed by namespace name (`auth`, `customers`, `files`, `notifications`,
262
+ * `operations`, `schedules`, `search`, `secrets`). Deliberately an open
263
+ * record rather than the eight names: a namespace the platform adds must
264
+ * reach the generator, and a closed union would silently drop it.
265
+ */
266
+ namespaces: Record<string, FoirManifestNamespace>;
267
+ /** Root fields reachable by this credential that no model/namespace claims. */
268
+ unclassified?: {
269
+ queries?: string[];
270
+ mutations?: string[];
271
+ /**
272
+ * Subscription root fields the server declined to state the reachability
273
+ * of — today only `events`, whose scope is charged against the resolved
274
+ * data-plane authority rather than the api key's own scope set. Reported so
275
+ * the gap is visible; nothing is generated from it.
276
+ */
277
+ subscriptions?: string[];
278
+ };
279
+ /**
280
+ * Each union's expansion, once, keyed by union type name. A selection field
281
+ * references one by name rather than inlining it — seven models reaching one
282
+ * 56-member block union inlined it seven times and made the manifest 6.9x
283
+ * larger, 85% of it duplication.
284
+ *
285
+ * Absent on a server that predates selection trees, which is why every
286
+ * consumer must treat it as optional rather than assume the shape.
287
+ */
288
+ selectionUnions?: Record<string, FoirManifestSelectionUnion>;
289
+ /**
290
+ * Subscription root fields this credential may open over `/graphql/ws`.
291
+ *
292
+ * Unlike `models[].ops`, this list is NOT derived from the caller's schema
293
+ * variant: the server copies the whole Subscription root into every variant
294
+ * (the transport is out of band), so the variant admits all of them to
295
+ * everybody. The list is projected from the same table the socket charges at
296
+ * subscribe time, which is what makes it safe to generate against — a field
297
+ * that is here will be accepted, and one that is absent will be refused.
298
+ */
299
+ subscriptions?: FoirManifestSubscription[];
300
+ }
301
+ /**
302
+ * One subscription root field, with the tree a document is printed from.
303
+ */
304
+ export interface FoirManifestSubscription {
305
+ /** The Subscription root field name. */
306
+ field: string;
307
+ /** Argument names, sorted. */
308
+ args?: string[];
309
+ /**
310
+ * Each name in `args` mapped to the GraphQL type the field declares for it —
311
+ * `'String!'` — spelled exactly as a variable definition needs it, and for
312
+ * the same reason `FoirManifestOp.argTypes` exists: a subscribe frame carries
313
+ * a `variables` object like any other operation, so without the type a
314
+ * consumer would have to infer a literal form from the value it holds.
315
+ *
316
+ * It also decides the variable NAME. The socket resolves an argument-gated
317
+ * subscription's scope by reading `variables[<arg>]` BY NAME, so
318
+ * `subscription S($m: String!) { recordChanged(modelKey: $m) … }` opens and is
319
+ * then refused for a scope it cannot complete. Declaring `$<arg>` — which is
320
+ * what a printer driven by this map does — is what keeps the two in step.
321
+ */
322
+ argTypes?: Record<string, string>;
323
+ /** GraphQL named type of the event payload. */
324
+ type: string;
325
+ /**
326
+ * The scope the socket charges. Empty exactly when `argScope` is set. Carried
327
+ * so a client can say WHICH capability a refusal was about instead of
328
+ * reporting a bare failure.
329
+ */
330
+ scope?: string;
331
+ /** Set when the required scope is completed by a subscribe argument. */
332
+ argScope?: FoirManifestSubscriptionArgScope;
333
+ /** Resolved complete-by-default selection for the payload type. */
334
+ selection?: FoirManifestSelection;
335
+ /** Why `selection` is absent. Absent is not "no fields". */
336
+ selectionError?: string;
337
+ }
338
+ /**
339
+ * A subscription whose authorization depends on a value supplied at subscribe
340
+ * time.
341
+ *
342
+ * `recordChanged` is the one instance: the socket charges
343
+ * `records:read:<modelKey>` against the `modelKey` variable, so the field has
344
+ * no static yes/no. What is statically true is which values this credential's
345
+ * scopes admit, and that is what `values` carries.
346
+ */
347
+ export interface FoirManifestSubscriptionArgScope {
348
+ /** The subscribe argument whose value completes the scope. */
349
+ arg: string;
350
+ /** What the argument's value is appended to. */
351
+ prefix: string;
352
+ /**
353
+ * The argument values this credential admits, sorted. The ADDRESSABLE set,
354
+ * not a proof of exhaustiveness — a key holding the two-part `records:read`
355
+ * satisfies the socket for any string at all.
356
+ */
357
+ values: string[];
358
+ }
359
+ /**
360
+ * A resolved complete-by-default selection: what to ask for, already expanded.
361
+ *
362
+ * The server resolves this once per schema version — unions expanded per
363
+ * member, response-shape aliases assigned, cycles broken, field budget
364
+ * counted — so printing a document is string building rather than a schema
365
+ * walk. Nothing here requires the consumer to know a field's GraphQL type.
366
+ */
367
+ export interface FoirManifestSelection {
368
+ fields: FoirManifestSelectionField[];
369
+ /**
370
+ * Fields this tree emits when printed whole, relations excluded. Same unit
371
+ * the executor's complexity budget is denominated in.
372
+ */
373
+ cost: number;
374
+ }
375
+ export interface FoirManifestSelectionField {
376
+ key: string;
377
+ /**
378
+ * The response key to emit instead of `key`, set only where a union member's
379
+ * field name collides with an incompatible shape on another member. A
380
+ * consumer prints `alias: key` and types the result under `alias`.
381
+ */
382
+ alias?: string;
383
+ /** Nested selection for a composite or a builtin value object. */
384
+ fields?: FoirManifestSelectionField[];
385
+ /**
386
+ * Names a model whose published `selection` IS this field's selection.
387
+ *
388
+ * It appears where a record turns up inside a payload the caller did not
389
+ * address the record through: a connection's `node`, a search result's
390
+ * `record`. A REFERENCE rather than an inlined copy, so seven ops over one
391
+ * model do not carry seven copies of its tree — and so a caller's `omit`
392
+ * reaches the same tree whichever op it came through.
393
+ */
394
+ model?: string;
395
+ /** Names an entry in `FoirManifest.selectionUnions`. */
396
+ union?: string;
397
+ /**
398
+ * `include` governs this field, so it is NOT part of the default document.
399
+ * Emit it only when the caller asks for it.
400
+ */
401
+ relation?: boolean;
402
+ /**
403
+ * The cycle or depth rule stopped expansion here. Still selectable, but only
404
+ * as `__typename` — print that rather than an empty body, which is a parse
405
+ * error.
406
+ */
407
+ truncated?: boolean;
408
+ }
409
+ export interface FoirManifestSelectionUnion {
410
+ /** Sorted by type name, so the expansion is stable across runs. */
411
+ members: FoirManifestSelectionMember[];
412
+ }
413
+ export interface FoirManifestSelectionMember {
414
+ typeName: string;
415
+ fields: FoirManifestSelectionField[];
416
+ }
417
+ /**
418
+ * Fetch the manifest for the credential in `config`.
419
+ *
420
+ * Exported because two things outside this file need it: `foir types` reads it
421
+ * to generate `FoirSchema`, and the client's drift check reads its
422
+ * `schemaVersion`. Both would otherwise hand-roll the same fetch.
423
+ */
424
+ export declare function fetchFoirManifest(config: FoirClientConfig): Promise<FoirManifest>;