@substrat-run/contracts 0.81.0 → 0.82.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.
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mFAAmF;IACnF,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7E;;;;OAIG;IACH,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACtE;AAED,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA4ED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,UAAU,GAClB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA+GzB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC5C,KAAK,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAM,GAC3E,UAAU,CA2BZ"}
1
+ {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mFAAmF;IACnF,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7E;;;;OAIG;IACH,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACtE;AAED,+EAA+E;AAC/E,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA4GD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,UAAU,GAClB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6JzB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC5C,KAAK,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAM,GAC3E,UAAU,CA2BZ"}
package/dist/openapi.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { LIST_PAGE_DEFAULT, LIST_PAGE_MAX, pageSchema } from './pagination.js';
2
+ import { LIST_PAGE_DEFAULT, LIST_PAGE_MAX, PAGE_LINK_HEADER, PAGE_TOTAL_HEADER, } from './pagination.js';
3
3
  import { DOCUMENTED_ERROR_CODES, PROBLEM_CATALOG, problem, } from './errors.js';
4
4
  /** Where the one problem schema lives in the document, referenced from every failure. */
5
5
  const PROBLEM_SCHEMA_REF = '#/components/schemas/Problem';
@@ -64,6 +64,35 @@ const jsonSchema = (schema, io) => {
64
64
  const { $schema: _, ...rest } = z.toJSONSchema(schema, { io, target: 'draft-2020-12' });
65
65
  return rest;
66
66
  };
67
+ /**
68
+ * The response headers a paged read carries (#829) — documented, because a walk a
69
+ * client cannot discover is a walk that does not exist.
70
+ *
71
+ * `Link` is RFC 8288 and hands over a URL to FOLLOW, so the filters and the page
72
+ * size travel with it and a client never reassembles a query string. Its absence
73
+ * is how the walk ends.
74
+ */
75
+ function pageResponseHeaders(withTotal) {
76
+ return {
77
+ [PAGE_LINK_HEADER]: {
78
+ description: 'RFC 8288 link to the next page, e.g. `<https://…/customers?limit=20&cursor=01J8Z…>; ' +
79
+ 'rel="next"`. Follow it verbatim — it carries this request\'s filters and page ' +
80
+ 'size. Absent when the walk is over, so a client stops rather than fetching an ' +
81
+ 'empty page.',
82
+ schema: { type: 'string' },
83
+ },
84
+ ...(withTotal
85
+ ? {
86
+ [PAGE_TOTAL_HEADER]: {
87
+ description: 'Rows matching this request\'s filter — the same `WHERE` the page ran under, ' +
88
+ 'never the whole table. A snapshot: rows written mid-walk can make it ' +
89
+ 'disagree with the rows eventually seen.',
90
+ schema: { type: 'integer', minimum: 0 },
91
+ },
92
+ }
93
+ : {}),
94
+ };
95
+ }
67
96
  /**
68
97
  * Render a catalog as an OpenAPI 3.1 document (a plain JSON-able object).
69
98
  * Pure and deterministic: same catalog in, byte-identical document out — that
@@ -106,6 +135,42 @@ export function buildOpenApiDocument(info, catalog) {
106
135
  schema: { type: 'string', enum: ['asc', 'desc'], default: op.paged.order ?? 'asc' },
107
136
  });
108
137
  }
138
+ // A GET or DELETE carries its input in the QUERY STRING, and the document has to
139
+ // say so (#830). It used to emit every input field as a `requestBody` regardless of
140
+ // verb, so a paged read documented `limit`/`cursor` twice — once as the parameters
141
+ // this builder adds, once inside a JSON body — and documented `q`, `status` and the
142
+ // rest ONLY as body properties. A client generated from that could not discover the
143
+ // filters at all, and the one calling convention that works (`?q=…&limit=100`) did
144
+ // not appear anywhere in the document.
145
+ //
146
+ // The split is not a new declaration: `mountOperations` already decides it, and
147
+ // decides it by VERB — `takesBody = POST | PUT | PATCH`, everything else reads
148
+ // `c.req.query()`. Mirroring that rule here is what keeps the document and the router
149
+ // describing one surface, which is the whole point of deriving both from the model.
150
+ const takesBody = verb === 'post' || verb === 'put' || verb === 'patch';
151
+ if (!takesBody && op.input) {
152
+ const named = new Set(params.map((p) => p['name']));
153
+ const shape = jsonSchema(op.input, 'input');
154
+ const required = new Set(shape.required ?? []);
155
+ for (const [field, fieldSchema] of Object.entries(shape.properties ?? {})) {
156
+ // Already stated: a path parameter, or one of the paged trio the input restates
157
+ // (`limit`/`cursor` are declared by the operation AND added above). Emitting it
158
+ // twice is the wart #823 acknowledged; deduping by name is the whole fix.
159
+ if (named.has(field))
160
+ continue;
161
+ // A single-valued literal is SUPPLIED BY THE ROUTE, not chosen by the caller —
162
+ // `mountOperations` pins it and overrides whatever arrived. Documenting it as a
163
+ // query parameter would invite a client to send a value that cannot matter.
164
+ if ('const' in fieldSchema)
165
+ continue;
166
+ params.push({
167
+ name: field,
168
+ in: 'query',
169
+ required: required.has(field),
170
+ schema: fieldSchema,
171
+ });
172
+ }
173
+ }
109
174
  const existing = (paths[url] ?? {});
110
175
  paths[url] = {
111
176
  ...existing,
@@ -115,7 +180,10 @@ export function buildOpenApiDocument(info, catalog) {
115
180
  ...(params.length > 0 ? { parameters: params } : {}),
116
181
  ...(op.description ? { description: op.description } : {}),
117
182
  ...(op.tag ? { tags: [op.tag] } : {}),
118
- ...(op.input
183
+ // Only for a verb that carries one. A `requestBody` on a GET describes a call
184
+ // nobody can make: the mount never reads a body there, so a client that sent one
185
+ // would be ignored (#830).
186
+ ...(op.input && takesBody
119
187
  ? {
120
188
  requestBody: {
121
189
  required: !op.inputOptional,
@@ -127,14 +195,20 @@ export function buildOpenApiDocument(info, catalog) {
127
195
  '200': {
128
196
  description: op.paged
129
197
  ? op.paged.total
130
- ? 'One page of results, with the total matching this list’s filter.'
131
- : 'One page of results.'
198
+ ? 'One page of results. The walk is in the response headers.'
199
+ : 'One page of results. The walk is in the response headers.'
132
200
  : 'The operation result.',
201
+ // A page's BODY is the entries, and the walk rides in headers (#829).
202
+ // Wrapping the body renamed a live endpoint's response, which made
203
+ // adopting paging a breaking change for consumers a vertical cannot see —
204
+ // and could not be done at all for the list reads whose published shape
205
+ // was a bare array. In headers the body is what it always was.
206
+ ...(op.paged ? { headers: pageResponseHeaders(op.paged.total === true) } : {}),
133
207
  ...(op.output
134
208
  ? {
135
209
  content: {
136
210
  'application/json': {
137
- schema: jsonSchema(op.paged ? pageSchema(op.output, op.paged.total === true) : op.output, 'output'),
211
+ schema: jsonSchema(op.paged ? z.array(op.output) : op.output, 'output'),
138
212
  },
139
213
  },
140
214
  }
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"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"}
@@ -83,6 +83,61 @@ export declare function pageOf<T>(entries: T[], limit: number, key: (entry: T) =
83
83
  * filter the page ran under — see `CountedPage`.
84
84
  */
85
85
  export declare function countedPageOf<T>(entries: T[], limit: number, key: (entry: T) => string, total: number): CountedPage<T>;
86
+ /**
87
+ * Where a page's metadata rides on the WIRE (#829).
88
+ *
89
+ * The kernel-side shape is `Page<T>` above and stays that way — an operation is
90
+ * transport-agnostic, and an in-process caller (a test, a seed, another
91
+ * operation, an MCP tool) must be able to walk a list without an HTTP response to
92
+ * read headers off. What changes is only the HTTP PROJECTION: the body is the
93
+ * entries, and the walk is described in headers.
94
+ *
95
+ * **Because the alternative made adoption a breaking change.** Wrapping the body
96
+ * renames a live endpoint's response — `[…]` or `{ customers: […] }` becomes
97
+ * `{ entries: […] }` — and a vertical with API consumers it cannot see has no way
98
+ * to soften that. The rational move was then to NOT adopt paging, which is the
99
+ * opposite of what an unbounded list read deserves. In headers, a list endpoint
100
+ * returns what it always returned and gains a walk; nobody's client breaks, and
101
+ * the bare-array lists (which cannot carry a second key at all) adopt for free.
102
+ *
103
+ * `Link` rather than a bare cursor header: it is RFC 8288, it is what GitHub
104
+ * serves, and it hands the client a URL to FOLLOW rather than one to assemble —
105
+ * so the filter and page size travel with it automatically. The absence of a
106
+ * `rel="next"` link is how the walk ends.
107
+ *
108
+ * Deliberately NOT `Content-Range: items 0-19/340`. That describes an OFFSET
109
+ * window, and keyset paging does not know its offset — that ignorance is exactly
110
+ * what keeps it correct while rows are being written. Emitting a start index
111
+ * would be inventing a number.
112
+ */
113
+ export declare const PAGE_LINK_HEADER = "Link";
114
+ /** The opt-in total (`paged.total`), as a count — never a range. */
115
+ export declare const PAGE_TOTAL_HEADER = "X-Total-Count";
116
+ /**
117
+ * The headers a cross-origin browser client cannot read unless the server says
118
+ * it may. Nothing in the platform sets CORS today (a vertical serves its app and
119
+ * its API from one origin), so this exists for the vertical that opens its API to
120
+ * browser callers and would otherwise ship a walk no browser can follow — a
121
+ * failure that looks like "there is only one page".
122
+ */
123
+ export declare const PAGE_EXPOSED_HEADERS: readonly ["Link", "X-Total-Count"];
124
+ /**
125
+ * The `Link` header value for the next page, or null when the walk is over.
126
+ *
127
+ * Built from the REQUEST url so every other query parameter — the filters, the
128
+ * page size, a declared sort — rides along untouched. Only `cursor` is replaced,
129
+ * which is the one thing the client must not have to reassemble.
130
+ */
131
+ export declare function nextPageLink(requestUrl: string, nextCursor: string | null): string | null;
132
+ /**
133
+ * Is this an operation result the page projection applies to?
134
+ *
135
+ * Structural, and checked rather than assumed: a paged operation whose handler
136
+ * returns something else (mid-refactor, or a vertical that declared `paged` and
137
+ * has not adopted `pageOf` yet) must reach the client unchanged rather than be
138
+ * silently emptied into a body of `undefined`.
139
+ */
140
+ export declare function isPage(value: unknown): value is Page<unknown>;
86
141
  /**
87
142
  * The Zod shape of a page of `entry` — what a paged operation actually returns.
88
143
  *
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,uFAAuF;AACvF,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;iBAIxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxB;AAED,uDAAuD;AACvD,MAAM,WAAW,IAAI,CAAC,CAAC;IACrB,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,CAAC,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAGzF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,OAAO,EAAE,CAAC,EAAE,EACZ,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,EACzB,KAAK,EAAE,MAAM,GACZ,WAAW,CAAC,CAAC,CAAC,CAEhB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,UAAQ;;;kBAY1E"}
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,uFAAuF;AACvF,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;iBAIxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxB;AAED,uDAAuD;AACvD,MAAM,WAAW,IAAI,CAAC,CAAC;IACrB,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,CAAC,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAGzF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC7B,OAAO,EAAE,CAAC,EAAE,EACZ,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,EACzB,KAAK,EAAE,MAAM,GACZ,WAAW,CAAC,CAAC,CAAC,CAEhB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAEvC,oEAAoE;AACpE,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,oCAAiD,CAAC;AAEnF;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAKzF;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,CAO7D;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,UAAQ;;;kBAY1E"}
@@ -48,6 +48,72 @@ export function pageOf(entries, limit, key) {
48
48
  export function countedPageOf(entries, limit, key, total) {
49
49
  return { ...pageOf(entries, limit, key), total };
50
50
  }
51
+ /**
52
+ * Where a page's metadata rides on the WIRE (#829).
53
+ *
54
+ * The kernel-side shape is `Page<T>` above and stays that way — an operation is
55
+ * transport-agnostic, and an in-process caller (a test, a seed, another
56
+ * operation, an MCP tool) must be able to walk a list without an HTTP response to
57
+ * read headers off. What changes is only the HTTP PROJECTION: the body is the
58
+ * entries, and the walk is described in headers.
59
+ *
60
+ * **Because the alternative made adoption a breaking change.** Wrapping the body
61
+ * renames a live endpoint's response — `[…]` or `{ customers: […] }` becomes
62
+ * `{ entries: […] }` — and a vertical with API consumers it cannot see has no way
63
+ * to soften that. The rational move was then to NOT adopt paging, which is the
64
+ * opposite of what an unbounded list read deserves. In headers, a list endpoint
65
+ * returns what it always returned and gains a walk; nobody's client breaks, and
66
+ * the bare-array lists (which cannot carry a second key at all) adopt for free.
67
+ *
68
+ * `Link` rather than a bare cursor header: it is RFC 8288, it is what GitHub
69
+ * serves, and it hands the client a URL to FOLLOW rather than one to assemble —
70
+ * so the filter and page size travel with it automatically. The absence of a
71
+ * `rel="next"` link is how the walk ends.
72
+ *
73
+ * Deliberately NOT `Content-Range: items 0-19/340`. That describes an OFFSET
74
+ * window, and keyset paging does not know its offset — that ignorance is exactly
75
+ * what keeps it correct while rows are being written. Emitting a start index
76
+ * would be inventing a number.
77
+ */
78
+ export const PAGE_LINK_HEADER = 'Link';
79
+ /** The opt-in total (`paged.total`), as a count — never a range. */
80
+ export const PAGE_TOTAL_HEADER = 'X-Total-Count';
81
+ /**
82
+ * The headers a cross-origin browser client cannot read unless the server says
83
+ * it may. Nothing in the platform sets CORS today (a vertical serves its app and
84
+ * its API from one origin), so this exists for the vertical that opens its API to
85
+ * browser callers and would otherwise ship a walk no browser can follow — a
86
+ * failure that looks like "there is only one page".
87
+ */
88
+ export const PAGE_EXPOSED_HEADERS = [PAGE_LINK_HEADER, PAGE_TOTAL_HEADER];
89
+ /**
90
+ * The `Link` header value for the next page, or null when the walk is over.
91
+ *
92
+ * Built from the REQUEST url so every other query parameter — the filters, the
93
+ * page size, a declared sort — rides along untouched. Only `cursor` is replaced,
94
+ * which is the one thing the client must not have to reassemble.
95
+ */
96
+ export function nextPageLink(requestUrl, nextCursor) {
97
+ if (nextCursor === null)
98
+ return null;
99
+ const url = new URL(requestUrl);
100
+ url.searchParams.set('cursor', nextCursor);
101
+ return `<${url.toString()}>; rel="next"`;
102
+ }
103
+ /**
104
+ * Is this an operation result the page projection applies to?
105
+ *
106
+ * Structural, and checked rather than assumed: a paged operation whose handler
107
+ * returns something else (mid-refactor, or a vertical that declared `paged` and
108
+ * has not adopted `pageOf` yet) must reach the client unchanged rather than be
109
+ * silently emptied into a body of `undefined`.
110
+ */
111
+ export function isPage(value) {
112
+ return (typeof value === 'object' &&
113
+ value !== null &&
114
+ Array.isArray(value.entries) &&
115
+ 'nextCursor' in value);
116
+ }
51
117
  /**
52
118
  * The Zod shape of a page of `entry` — what a paged operation actually returns.
53
119
  *
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,iDAAiD;AACjD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,uFAAuF;AACvF,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC;AAEjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC;IACvF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACpC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AA0CH;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAI,OAAY,EAAE,KAAa,EAAE,GAAyB;IAC9E,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AACxE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAY,EACZ,KAAa,EACb,GAAyB,EACzB,KAAa;IAEb,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;AACnD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAsB,KAAQ,EAAE,SAAS,GAAG,KAAK;IACzE,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC;QACpB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;QACvB,kFAAkF;QAClF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAClC,CAAC,CAAC;IACH,OAAO,SAAS;QACd,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;YACV,0EAA0E;YAC1E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;SACtC,CAAC;QACJ,CAAC,CAAC,IAAI,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,iDAAiD;AACjD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,uFAAuF;AACvF,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC;AAEjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC;IACvF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACpC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AA0CH;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAI,OAAY,EAAE,KAAa,EAAE,GAAyB;IAC9E,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;AACxE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAY,EACZ,KAAa,EACb,GAAyB,EACzB,KAAa;IAEb,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;AACnD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEvC,oEAAoE;AACpE,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,gBAAgB,EAAE,iBAAiB,CAAU,CAAC;AAEnF;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkB,EAAE,UAAyB;IACxE,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAChC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC3C,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC;AAC3C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,KAAK,CAAC,OAAO,CAAE,KAAuB,CAAC,OAAO,CAAC;QAC/C,YAAY,IAAI,KAAK,CACtB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAsB,KAAQ,EAAE,SAAS,GAAG,KAAK;IACzE,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC;QACpB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC;QACvB,kFAAkF;QAClF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAClC,CAAC,CAAC;IACH,OAAO,SAAS;QACd,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;YACV,0EAA0E;YAC1E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;SACtC,CAAC;QACJ,CAAC,CAAC,IAAI,CAAC;AACX,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@substrat-run/contracts",
3
- "version": "0.81.0",
3
+ "version": "0.82.0",
4
4
  "description": "Substrat kernel contract schemas — Zod is the source of truth (master plan D-22); OAS/JSON Schema are emitted artifacts",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {