@relyio/sdk 0.15.0 → 0.16.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.
- package/CHANGELOG.md +53 -0
- package/dist/chunk-7BZW6XYJ.cjs +433 -0
- package/dist/chunk-CQHEG7QA.js +411 -0
- package/dist/{chunk-PCFTJLEP.js → chunk-DIZY6CKM.js} +2 -2
- package/dist/{chunk-X4KSS7PP.cjs → chunk-GHYB6IZK.cjs} +2 -2
- package/dist/{chunk-PXA5ONIU.js → chunk-NIUOPIIB.js} +384 -549
- package/dist/{chunk-3BHDGUNS.cjs → chunk-RLLZUFDB.cjs} +421 -582
- package/dist/client/index.cjs +4 -3
- package/dist/client/index.d.cts +3 -4
- package/dist/client/index.d.ts +3 -4
- package/dist/client/index.js +2 -1
- package/dist/{define-content-type-Ds5rCAYl.d.ts → define-content-type-CAWSlgn0.d.ts} +528 -79
- package/dist/{define-content-type-B2gQZkTy.d.cts → define-content-type-LkI0rS2W.d.cts} +528 -79
- package/dist/{define-schema-CxpIYFFR.d.ts → define-schema-Dxu3RoHV.d.ts} +1 -1
- package/dist/{define-schema-Cm_5y3ei.d.cts → define-schema-wlsJOrnY.d.cts} +1 -1
- package/dist/{index-DQ7eTUPQ.d.ts → index-BH8JksfG.d.ts} +447 -179
- package/dist/{index-Db3_tmYf.d.ts → index-CGtYxUuh.d.ts} +1 -1
- package/dist/{index-DY64WjZM.d.cts → index-CcHmRALk.d.cts} +1 -1
- package/dist/{index-F0UuHpRj.d.cts → index-D80MXUkf.d.cts} +447 -179
- package/dist/index.cjs +96 -71
- package/dist/index.d.cts +26 -16
- package/dist/index.d.ts +26 -16
- package/dist/index.js +4 -3
- package/dist/markdown/index.cjs +10 -2
- package/dist/markdown/index.d.cts +12 -3
- package/dist/markdown/index.d.ts +12 -3
- package/dist/markdown/index.js +10 -2
- package/dist/preview/index.cjs +29 -0
- package/dist/preview/index.d.cts +117 -0
- package/dist/preview/index.d.ts +117 -0
- package/dist/preview/index.js +4 -0
- package/dist/rich-text/index.d.cts +2 -2
- package/dist/rich-text/index.d.ts +2 -2
- package/dist/schema/index.cjs +33 -33
- package/dist/schema/index.d.cts +3 -3
- package/dist/schema/index.d.ts +3 -3
- package/dist/schema/index.js +1 -1
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +9 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @relyio/sdk
|
|
2
2
|
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 40be474: **Breaking: `relyio.query({ from, … })` takes `list`'s options exactly and answers a list's envelope, `{ data, page, meta }`.** The ad-hoc query used to answer `{ data: { result, metadata } }`; it answers `{ data: records[], page: { nextCursor, hasMore }, meta }` for every query now — an aggregate's rows are records, a singleton fetch is a list of one, and `meta` carries what `metadata` did. Read `data` where you read `data.result`, and `meta` where you read `data.metadata`. A fetch's records are the entries `list` answers, `_metadata` and `localizations` included. Saved queries (`relyio.query(name, …)`) are unchanged.
|
|
8
|
+
|
|
9
|
+
What `query` takes, as `list` takes it:
|
|
10
|
+
|
|
11
|
+
- **`cursor`.** Page by the `page.nextCursor` an answer hands back; a walk by cursor visits every row once, including rows tied on the sort value (a fetch's sort now ends on the entry's id). `page` with `limit` still works, sent as the offset the page starts at.
|
|
12
|
+
- **`locale`** as a code, a list of codes or `'*'`. A list or `'*'` returns the other locales under `_metadata.localizations`; a code the schema does not declare is refused. The locale rides the request's query string (`?locale=`, `?locales=`), as a list's does, and is no longer a `parameters.locale` of the query (one still sent there over HTTP is refused, naming `?locale=`).
|
|
13
|
+
- **`select` beside `include`.** `select` picks whole fields and keeps `_metadata`, so an include path expands beside it. A fetch's `select` is no longer an alias map: `select: { price: 'pricing.basePrice' }` over HTTP is refused, naming the key (the alias form stays an aggregate's).
|
|
14
|
+
|
|
15
|
+
`@relyio/agents`' `countEntries` reads the count from `data`.
|
|
16
|
+
|
|
17
|
+
Over HTTP, `POST /v1/query` answers the same envelope and takes `?cursor=`, `?locale=` and `?locales=`; the committed OpenAPI document declares them.
|
|
18
|
+
|
|
19
|
+
- c691af8: **Breaking: an entry's `_children` is a `{ data, page }` block.** A `get`, `list`, `listAll` or `children` read that asks for `children` used to type `_children` as `{ items, total, hasMore }`; it is now `{ data, page: { offset, limit, total } }`. Read `_children.data` where you read `_children.items` and `_children.page.total` where you read `_children.total`. The block holds the first `limit` children and does not page: `offset` is always `0`, more remain when `data.length < page.total`, and `children(id)` lists every child from its own first page, paging by its own cursor rather than from where `_children` stopped. `total` now counts the parent's children past the block too, rather than only the ones in it, so a parent with 12 children read 10 at a time reports 12. For a key limited to some locales it is an upper bound, since it still counts children past `limit` that hold none of the key's locales.
|
|
20
|
+
|
|
21
|
+
A singleton's or a settings group's `versions()` now answers `currentVersion` as the requested locale's own version counter, the number its `_metadata.version` reports in that locale, rather than the counter its shared fields keep. A locale with nothing written of its own, or one the key cannot read, answers `0` and an empty list.
|
|
22
|
+
|
|
23
|
+
- 09c1203: **A refused write says why in `error.context.blockage`.** A `ResourceConflictError` that is not a stale version now carries `context.blockage`, `{ kind, facts }`, where `kind` is `'draft-exists'` (the Studio holds an unpublished draft on the entry or locale), `'release-locked'` (a scheduled release holds the entry) or `'slug-taken'` (another entry holds the slug), so `if (error.context?.blockage?.kind === 'draft-exists')` replaces matching the message. The error's message is the API's sentence on its own for a blockage, and still ends with the re-read-and-retry advice only for a stale version. A kind this build has not heard of arrives as the string it is.
|
|
24
|
+
- feec931: **`defineLocale` is exported from the package root, beside the other `define*` helpers.** `import { defineSchema, defineContentType, defineLocale, fields } from '@relyio/sdk'` now works, so a keyed schema is written from one import. `@relyio/sdk/schema` still exports it too, and both names are the same function; nothing to migrate.
|
|
25
|
+
- 80c52f3: **`FieldTypeName` is gone from `@relyio/sdk/types`, and the published declarations no longer import a file the package does not ship.** `FieldTypeName` listed 18 names, most of them not field kinds (`'string'`, `'number'`, `'geopoint'`, `'color'`); `FieldDefinition.type` in that module is now `FieldKind`, the field-kind union the schema package declares. The built `.d.ts` files also imported `./live-visitor.js` for `VisitorRetry` and `VisitorResyncReason`, a file `dist` never had, so a project with `skipLibCheck` read both as `any`; the contract's declarations are now rolled in, as the schema's already were.
|
|
26
|
+
- 8557d92: **Cancel a read, search, query or batch with `signal`; `HttpClient` is narrowed to the requests the SDK makes.** This is a breaking release for anyone who reached the HTTP client through `getHttpClient()`.
|
|
27
|
+
|
|
28
|
+
**New.** `signal` is an option of `content(…).list()`, `listAll()`, `get()` and `children()`, of `singleton(…).get()` and `settings(…).get()`, of `search()`, `autocomplete()` and `similar()`, of both forms of `query()` and of `batch()`. Aborting it rejects the call with the platform's `AbortError` — not a `TimeoutError` — and a signal that has already fired sends nothing. The client's `timeout` still applies beside it. Writes other than `batch()` do not take a `signal` yet.
|
|
29
|
+
|
|
30
|
+
**Fixed.** A response whose content type is neither JSON nor text (`application/octet-stream`, a vendor type) was read as JSON and then as text, and the second read failed with `Body is unusable`. The body is now read once: it is the parsed JSON when it is JSON, else its text.
|
|
31
|
+
|
|
32
|
+
**Breaking.** These `HttpClient` members are removed: `get`, `post`, `put`, `patch`, `delete`, `request`, `setDefaultHeaders`, `getDefaultHeaders`, `setBaseUrl` and `getBaseUrl`. `send` and `fetchPayload` name a route by the path the committed document declares and are the requests; use `createClient({ baseUrl, headers })` and `updateConfig()` to change the address or headers, and `setApiKey()` on the client to rotate a key.
|
|
33
|
+
|
|
34
|
+
- 382590c: Breaking for code that calls them on the client from `getHttpClient()`: `configure`, `withHeaders` and `setApiKey` are no longer public methods of `HttpClient`, which now has two, `send` and `fetchPayload`. They were only ever called by the SDK's own client, for `updateConfig()`, `with()` and `setApiKey()`; call those on the client instead.
|
|
35
|
+
- 7690cd4: **`client.query(name, { fresh })` takes a feed position.** A saved query run by its name is now kept at the edge, for as long as the query's own cache policy allows, so `fresh` takes a change's `fresh` (a changes-feed cursor) as every other read does, sent as `?_fresh=`: the answer is then never one stored before that change. `fresh: true` still reads past every cache.
|
|
36
|
+
- 14926a8: **A pull request's preview deployment reads that pull request's preview.** On a Vercel preview deployment (`VERCEL_ENV=preview`), a client configured with no `dataset` and holding a preview key (`rly_prev_…`) now sends `X-RelyIO-Dataset: previewDatasetSlug(VERCEL_GIT_COMMIT_REF)` — the dataset `relyio ci preview` creates for that branch. A published key never sends a preview, since it may not read one. When the API answers that no such dataset exists — a branch with no pull request, a plan with no previews, an archived preview — the client reads the key's default dataset instead, logs that once, and asks for the preview again about a minute later (`UNKNOWN_PREVIEW_RECHECK_MS`, exported from `@relyio/sdk/preview`), so a preview CI creates after the site's first read is picked up without a redeploy. `isPreviewKey` and `PREVIEW_KEY_PREFIX` are exported beside `isPublishableKey`. Production, Vercel's development environment, and every other host are unchanged. The order a client picks its dataset in is: an active `relyio dev` sandbox, then an explicit `dataset`, then the preview, then the key's default. `NODE_ENV` plays no part, so a preview build (which runs with `NODE_ENV=production`) is still recognised. The new `@relyio/sdk/preview` subpath exports `previewDatasetSlug(branch)` — `preview/<readable branch, at most 40 characters>-<first 8 hex digits of the branch's SHA-256>`, so branches differing only in case or punctuation get different datasets — and `previewAtBuild` / `previewAtRequest`, which a framework package uses to read the branch while a site is built.
|
|
37
|
+
- 4c46dc8: **`RelyIOConfig.realtime` and the `RealtimeConfig` type are removed.** The option (`enabled`, `wsUrl`, `maxReconnectAttempts`, `reconnectDelay`, `heartbeatInterval`) had defaults and nothing read it, so setting it changed nothing. It also sat beside the real `liveUrl` and `webSocket` options, which invites configuring the wrong one. Delete any `realtime: { … }` from `createClient()` and `updateConfig()` calls, and any import of `RealtimeConfig`; configure live through `liveUrl` and `webSocket` only. `getConfig().realtime` no longer exists.
|
|
38
|
+
- 525b360: **A taken slug says which field, locale and entry in `error.context.blockage.facts`.** A `slug-taken` blockage now carries `{ path, code: 'SLUG_TAKEN', locale, slug, entryId }`: the slug field's path (with its locale for a localized slug), the locale whose reservation collided, the slug, and the id of the entry that holds it. In a batch, the clash is reported on the entry that claimed the slug, and the chunk's other writes come back rolled back with it.
|
|
39
|
+
- 720c08b: **A typed asset `where` admits the `file.*` filters, and a read that asks for `children` is typed with `_children`.** `relyio.asset(type).list({ where: { 'file.status': 'ready' } })` now compiles on a client typed by your schema, for the paths the list accepts (`file.status`, `file.backend`, `file.mimeType`, `file.fileName`, `file.size`, `file.extracted.width`, `.height` and `.duration`); the binding's internal members stay refused. `get`, `list`, `listAll` and `children` with a `children` option return `_children: { items, total, hasMore }`, which the API document now declares on an entry read. A typed write still sets one locale per call; the guides say so.
|
|
40
|
+
- e1ad65f: **The version reads are typed as what the API sends.** `content(type).version(id, { version })` returns `ContentVersion<T>`: that locale's own fields at the top level, each optional since a locale's version holds no shared field, and `_metadata` with `status: 'version'` and no `defaultLocale` or `availableLocales`. `singleton(key).version(…)` and `settings(group).version(…)` return `DocumentVersion<T>`, `{ version, locale, publishedAt, publishedBy, fields }`, the fields nested. `content(type).versions(id)` returns `ContentVersionRow<T>[]`, each row's fields under `fields`; `singleton(key).versions()` and `settings(group).versions()` return `DocumentVersionRow[]`, a version's `version`, `locale`, `publishedAt` and `publishedBy` and no fields. Each was typed as the document itself, so `version.title` compiled where the value is `version.fields.title`, and `row.versionNumber` where it is `row.version`. To migrate, read a singleton's or settings group's version fields from `.fields`, an entry's history row's from `.fields`, and a singleton's or settings group's history row number from `.version`.
|
|
41
|
+
- dafff9c: **A view filter's `operator` offers only what deploy accepts on some field.** `ViewFilterOperator` no longer has `isTrue`, `isFalse`, `today`, `yesterday`, `thisWeek`, `thisMonth`, `thisYear`, `includes` or `notIncludes`: deploy refused each of them on every field, so a view naming one compiled and was then turned away. Write a boolean as `{ operator: 'is', value: true }`, a recent date as `inTheLast` with `{ amount, unit }` or a day as `isOn`, and tags as `hasValue` or `isEmpty`. A view that names a removed operator now fails to compile, rather than at deploy.
|
|
42
|
+
|
|
43
|
+
### Patch Changes
|
|
44
|
+
|
|
45
|
+
- b1f381b: **A typed asset read checks its include paths.** `relyio.asset('photo').get(id, { include: ['nope'] })` no longer compiles: an asset type's include paths are its declared fields', as a content type's are, and the error lists the paths that hold. A path that crosses into an asset a reference reaches — `'hero.photographer'`, `'hero(alt)'` — is checked against that asset's fields too, where any path used to be accepted. A path that was already right still compiles.
|
|
46
|
+
- c985f02: An asset upload's byte transfers, the presigned `PUT` and each multipart part, go through the client's `fetch` option instead of the global `fetch`, so a wrapper that records, proxies or forbids network access sees them.
|
|
47
|
+
- 87b21ab: **`error.withContext(...)` keeps every field of the error.** It used to rebuild the error through the base constructor's argument order, so a `ValidationError`, `InvalidPayloadError`, `TimeoutError` and every contract error with a constructor of its own (`PlanFeatureUnavailableError`, `UsageQuotaExceededError`, `RateLimitError`, `PayloadTooLargeError`, `TransactionRolledBackError`, `ServiceIndeterminateError`, `ServerError`, `UnknownContractError`) came back with its status code or context in the wrong field. It now copies the error, so violations, timeout, feature, meter and the rest survive.
|
|
48
|
+
|
|
49
|
+
**`TransactionRolledBackError` no longer says the batch "rolled back at operation N".** `failedIndex` is the index of the operation the refusal was served for, not necessarily the one that failed; the message now says that.
|
|
50
|
+
|
|
51
|
+
- b94b0f3: **`richTextFromMarkdown` and `readRichTextMarkdown` now fit the field they are written to.** `create({ body: richTextFromMarkdown(md) })` compiled only for a field declaring every block; for a field declaring none it was TS2322. Both take the field's value type as a type argument, inferred from where the result is assigned or passed. The parser still reads no schema, so the write validates the tree as before.
|
|
52
|
+
- dedf501: A request to a host that cannot be reached is reported on the first attempt. A refused connection (`ECONNREFUSED`) or an unresolvable host (`ENOTFOUND`) is the same on every attempt, so a wrong `baseUrl` no longer spends three attempts and about 2.5 seconds before the error. A 503, a timeout or a connection dropped after the request was sent still retry as before.
|
|
53
|
+
- 73953f0: The retry policy the client sends with is now exported: `retryPolicyFor(maxAttempts)`, the `DefaultRetryPolicy` class, `isReplaySafe(request)` and the `RetryPolicy` and `RetryableRequest` types. `@relyio/cli` sends through the same policy and reads refusals with the same `ErrorMapper`, so both packages give one refusal the same error class. The client's own retries are unchanged.
|
|
54
|
+
- 74c2cb0: **The `TRANSACTION_ROLLED_BACK` fix text in the bundled API types no longer says to fix the operation at `details.failedIndex`.** That index is the operation the refusal was served for, not necessarily the one that failed; the text now says so, matching `TransactionRolledBackError`'s message.
|
|
55
|
+
|
|
3
56
|
## 0.15.0
|
|
4
57
|
|
|
5
58
|
### Minor Changes
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkMWMSFIWN_cjs = require('./chunk-MWMSFIWN.cjs');
|
|
4
|
+
|
|
5
|
+
/* RelyIO SDK - Built with ❤️ by the RelyIO Team */
|
|
6
|
+
|
|
7
|
+
// ../../platform/api-contract/dist/chunk-46347LG2.js
|
|
8
|
+
function defineRoute(route) {
|
|
9
|
+
if (route.kind === "raw" && route.standardShape === void 0) {
|
|
10
|
+
throw new Error("kind 'raw' requires a named StandardShape");
|
|
11
|
+
}
|
|
12
|
+
if (route.kind === "raw" && route.success === 302 && !route.headers.some((header) => header.name === "Location")) {
|
|
13
|
+
throw new Error("a raw route declaring success 302 must declare its 'Location' header");
|
|
14
|
+
}
|
|
15
|
+
if (route.kind === "stream" && route.stream === void 0) {
|
|
16
|
+
throw new Error("kind 'stream' requires a StreamDeclaration");
|
|
17
|
+
}
|
|
18
|
+
if (route.kind === "collection" && route.page === void 0) {
|
|
19
|
+
throw new Error("kind 'collection' requires a page dialect");
|
|
20
|
+
}
|
|
21
|
+
if (route.queues === true) {
|
|
22
|
+
if (route.kind !== "object" && route.kind !== "empty") {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`kind '${route.kind}' cannot declare \`queues\`: only an object or empty route answers 202 beside its own status`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
if (route.kind === "object" && route.success === 202) {
|
|
28
|
+
throw new Error("a route whose own status is 202 cannot also declare `queues`");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if ((route.kind === "object" || route.kind === "collection") && route.negotiated !== void 0) {
|
|
32
|
+
refuseMismatchedAlternate(route, route.negotiated["text/event-stream"]);
|
|
33
|
+
}
|
|
34
|
+
return route;
|
|
35
|
+
}
|
|
36
|
+
chunkMWMSFIWN_cjs.__name(defineRoute, "defineRoute");
|
|
37
|
+
function refuseMismatchedAlternate(route, stream) {
|
|
38
|
+
if (stream.kind !== "stream") {
|
|
39
|
+
throw new Error("a negotiated 'text/event-stream' alternate must be kind 'stream'");
|
|
40
|
+
}
|
|
41
|
+
if (stream.stream.mediaType !== "text/event-stream") {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`a negotiated 'text/event-stream' alternate declares media type "${stream.stream.mediaType}"`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
const own = [...new Set(route.codes)].sort();
|
|
47
|
+
const alternate = [...new Set(stream.codes)].sort();
|
|
48
|
+
if (own.length !== alternate.length || own.some((code, index) => code !== alternate[index])) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`a negotiated alternate refuses with [${alternate.join(", ")}] while its route refuses with [${own.join(", ")}]; one route refuses with one set of codes on every transport`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
chunkMWMSFIWN_cjs.__name(refuseMismatchedAlternate, "refuseMismatchedAlternate");
|
|
55
|
+
|
|
56
|
+
// ../../platform/api-contract/dist/index.js
|
|
57
|
+
var HEADER_RETRY_AFTER = { name: "Retry-After" };
|
|
58
|
+
var HEADER_IF_MATCH = {
|
|
59
|
+
name: "If-Match",
|
|
60
|
+
in: "request",
|
|
61
|
+
required: false
|
|
62
|
+
};
|
|
63
|
+
function entityTag(parts) {
|
|
64
|
+
return `"${parts.entryUid}:${parts.locale}:${parts.version}:${parts.sharedVersion}"`;
|
|
65
|
+
}
|
|
66
|
+
chunkMWMSFIWN_cjs.__name(entityTag, "entityTag");
|
|
67
|
+
var HEADER_IDEMPOTENCY_KEY = {
|
|
68
|
+
name: "Idempotency-Key",
|
|
69
|
+
in: "request",
|
|
70
|
+
required: false
|
|
71
|
+
};
|
|
72
|
+
var FRESH_PARAMETER = "_fresh";
|
|
73
|
+
var K = new Uint32Array([
|
|
74
|
+
1116352408,
|
|
75
|
+
1899447441,
|
|
76
|
+
3049323471,
|
|
77
|
+
3921009573,
|
|
78
|
+
961987163,
|
|
79
|
+
1508970993,
|
|
80
|
+
2453635748,
|
|
81
|
+
2870763221,
|
|
82
|
+
3624381080,
|
|
83
|
+
310598401,
|
|
84
|
+
607225278,
|
|
85
|
+
1426881987,
|
|
86
|
+
1925078388,
|
|
87
|
+
2162078206,
|
|
88
|
+
2614888103,
|
|
89
|
+
3248222580,
|
|
90
|
+
3835390401,
|
|
91
|
+
4022224774,
|
|
92
|
+
264347078,
|
|
93
|
+
604807628,
|
|
94
|
+
770255983,
|
|
95
|
+
1249150122,
|
|
96
|
+
1555081692,
|
|
97
|
+
1996064986,
|
|
98
|
+
2554220882,
|
|
99
|
+
2821834349,
|
|
100
|
+
2952996808,
|
|
101
|
+
3210313671,
|
|
102
|
+
3336571891,
|
|
103
|
+
3584528711,
|
|
104
|
+
113926993,
|
|
105
|
+
338241895,
|
|
106
|
+
666307205,
|
|
107
|
+
773529912,
|
|
108
|
+
1294757372,
|
|
109
|
+
1396182291,
|
|
110
|
+
1695183700,
|
|
111
|
+
1986661051,
|
|
112
|
+
2177026350,
|
|
113
|
+
2456956037,
|
|
114
|
+
2730485921,
|
|
115
|
+
2820302411,
|
|
116
|
+
3259730800,
|
|
117
|
+
3345764771,
|
|
118
|
+
3516065817,
|
|
119
|
+
3600352804,
|
|
120
|
+
4094571909,
|
|
121
|
+
275423344,
|
|
122
|
+
430227734,
|
|
123
|
+
506948616,
|
|
124
|
+
659060556,
|
|
125
|
+
883997877,
|
|
126
|
+
958139571,
|
|
127
|
+
1322822218,
|
|
128
|
+
1537002063,
|
|
129
|
+
1747873779,
|
|
130
|
+
1955562222,
|
|
131
|
+
2024104815,
|
|
132
|
+
2227730452,
|
|
133
|
+
2361852424,
|
|
134
|
+
2428436474,
|
|
135
|
+
2756734187,
|
|
136
|
+
3204031479,
|
|
137
|
+
3329325298
|
|
138
|
+
]);
|
|
139
|
+
var rotr = /* @__PURE__ */ chunkMWMSFIWN_cjs.__name((value, bits) => value >>> bits | value << 32 - bits, "rotr");
|
|
140
|
+
function sha256Hex(text) {
|
|
141
|
+
const bytes = new globalThis.TextEncoder().encode(text);
|
|
142
|
+
const blocks = Math.ceil((bytes.length + 9) / 64);
|
|
143
|
+
const padded = new Uint8Array(blocks * 64);
|
|
144
|
+
padded.set(bytes);
|
|
145
|
+
padded[bytes.length] = 128;
|
|
146
|
+
const view = new DataView(padded.buffer);
|
|
147
|
+
const bits = bytes.length * 8;
|
|
148
|
+
view.setUint32(padded.length - 8, Math.floor(bits / 4294967296));
|
|
149
|
+
view.setUint32(padded.length - 4, bits >>> 0);
|
|
150
|
+
const hash = new Uint32Array([
|
|
151
|
+
1779033703,
|
|
152
|
+
3144134277,
|
|
153
|
+
1013904242,
|
|
154
|
+
2773480762,
|
|
155
|
+
1359893119,
|
|
156
|
+
2600822924,
|
|
157
|
+
528734635,
|
|
158
|
+
1541459225
|
|
159
|
+
]);
|
|
160
|
+
const w = new Uint32Array(64);
|
|
161
|
+
for (let block = 0; block < blocks; block++) {
|
|
162
|
+
for (let i = 0; i < 16; i++) w[i] = view.getUint32(block * 64 + i * 4);
|
|
163
|
+
for (let i = 16; i < 64; i++) {
|
|
164
|
+
const w15 = w[i - 15];
|
|
165
|
+
const w2 = w[i - 2];
|
|
166
|
+
const s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ w15 >>> 3;
|
|
167
|
+
const s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ w2 >>> 10;
|
|
168
|
+
w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
|
|
169
|
+
}
|
|
170
|
+
let a = hash[0];
|
|
171
|
+
let b = hash[1];
|
|
172
|
+
let c = hash[2];
|
|
173
|
+
let d = hash[3];
|
|
174
|
+
let e = hash[4];
|
|
175
|
+
let f = hash[5];
|
|
176
|
+
let g = hash[6];
|
|
177
|
+
let h = hash[7];
|
|
178
|
+
for (let i = 0; i < 64; i++) {
|
|
179
|
+
const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
180
|
+
const choice = e & f ^ ~e & g;
|
|
181
|
+
const t1 = h + s1 + choice + K[i] + w[i] >>> 0;
|
|
182
|
+
const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
|
|
183
|
+
const majority = a & b ^ a & c ^ b & c;
|
|
184
|
+
const t2 = s0 + majority >>> 0;
|
|
185
|
+
h = g;
|
|
186
|
+
g = f;
|
|
187
|
+
f = e;
|
|
188
|
+
e = d + t1 >>> 0;
|
|
189
|
+
d = c;
|
|
190
|
+
c = b;
|
|
191
|
+
b = a;
|
|
192
|
+
a = t1 + t2 >>> 0;
|
|
193
|
+
}
|
|
194
|
+
hash[0] = hash[0] + a;
|
|
195
|
+
hash[1] = hash[1] + b;
|
|
196
|
+
hash[2] = hash[2] + c;
|
|
197
|
+
hash[3] = hash[3] + d;
|
|
198
|
+
hash[4] = hash[4] + e;
|
|
199
|
+
hash[5] = hash[5] + f;
|
|
200
|
+
hash[6] = hash[6] + g;
|
|
201
|
+
hash[7] = hash[7] + h;
|
|
202
|
+
}
|
|
203
|
+
return Array.from(hash, (word) => word.toString(16).padStart(8, "0")).join("");
|
|
204
|
+
}
|
|
205
|
+
chunkMWMSFIWN_cjs.__name(sha256Hex, "sha256Hex");
|
|
206
|
+
var PREVIEW_DATASET_PREFIX = "preview/";
|
|
207
|
+
var READABLE_MAX = 40;
|
|
208
|
+
var HASH_DIGITS = 8;
|
|
209
|
+
function previewDatasetSlug(branch) {
|
|
210
|
+
const name = branch.startsWith("refs/heads/") ? branch.slice("refs/heads/".length) : branch;
|
|
211
|
+
if (name === "") {
|
|
212
|
+
throw new TypeError(`previewDatasetSlug: ${JSON.stringify(branch)} names no Git branch`);
|
|
213
|
+
}
|
|
214
|
+
const readable = name.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replaceAll(/^-+|-+$/g, "").slice(0, READABLE_MAX).replace(/-+$/, "");
|
|
215
|
+
const hash = sha256Hex(name).slice(0, HASH_DIGITS);
|
|
216
|
+
return `${PREVIEW_DATASET_PREFIX}${readable === "" ? "" : `${readable}-`}${hash}`;
|
|
217
|
+
}
|
|
218
|
+
chunkMWMSFIWN_cjs.__name(previewDatasetSlug, "previewDatasetSlug");
|
|
219
|
+
var VISITOR_LIVE_PATH = "/visitor/changes";
|
|
220
|
+
var VISITOR_QUERY = {
|
|
221
|
+
/** The publishable key. */
|
|
222
|
+
key: "key",
|
|
223
|
+
/** A dataset id or name the key reaches; absent, the key's default dataset. */
|
|
224
|
+
dataset: "dataset",
|
|
225
|
+
/** The cursor to continue from; absent, the socket starts now. */
|
|
226
|
+
since: "since",
|
|
227
|
+
/** Comma-separated content types to keep; absent keeps every type. */
|
|
228
|
+
types: "types",
|
|
229
|
+
/** Comma-separated entry ids to keep; absent keeps every entry. */
|
|
230
|
+
ids: "ids",
|
|
231
|
+
/** The poll's client id. Required on a poll, and not read on a socket. */
|
|
232
|
+
client: "client"
|
|
233
|
+
};
|
|
234
|
+
var VISITOR_CURSOR = /^[\w.~-]{1,256}$/;
|
|
235
|
+
var VISITOR_POLL_INTERVAL_MS = 15e3;
|
|
236
|
+
var VISITOR_KEEPALIVE = { request: "ping", response: "pong" };
|
|
237
|
+
var VISITOR_FRAMES = {
|
|
238
|
+
opened: "feed.opened",
|
|
239
|
+
changes: "feed.changes",
|
|
240
|
+
resync: "feed.resync"
|
|
241
|
+
};
|
|
242
|
+
defineRoute({
|
|
243
|
+
kind: "object",
|
|
244
|
+
headers: [HEADER_RETRY_AFTER],
|
|
245
|
+
codes: [
|
|
246
|
+
"REQUEST_INVALID",
|
|
247
|
+
"MISSING_API_KEY",
|
|
248
|
+
"INVALID_API_KEY",
|
|
249
|
+
"ACCESS_DENIED",
|
|
250
|
+
"METHOD_NOT_ALLOWED",
|
|
251
|
+
"SERVICE_INDETERMINATE",
|
|
252
|
+
"USAGE_QUOTA_EXCEEDED",
|
|
253
|
+
"RATE_LIMIT_EXCEEDED"
|
|
254
|
+
]
|
|
255
|
+
});
|
|
256
|
+
var VISITOR_CLOSE_CODES = {
|
|
257
|
+
/** A query the door cannot read: a malformed `since`, filter, `dataset` or `client`. */
|
|
258
|
+
requestInvalid: 4400,
|
|
259
|
+
/** No publishable key, or one that is unknown, revoked, expired, a secret key or a preview key. */
|
|
260
|
+
keyRefused: 4401,
|
|
261
|
+
/** The page's `Origin` is absent, or not on the key's allowed origins. */
|
|
262
|
+
originRefused: 4403,
|
|
263
|
+
/** `dataset` names nothing the key reaches. */
|
|
264
|
+
datasetRefused: 4404,
|
|
265
|
+
/** The key's scope, the project's counter or the feed could not be reached just now. */
|
|
266
|
+
unavailable: 1013,
|
|
267
|
+
/**
|
|
268
|
+
* The project holds as many visitor connections as its plan allows — Starter's 100 — or its
|
|
269
|
+
* Organization is suspended. As HTTP's 402: more needs a bigger plan, or visitors leaving.
|
|
270
|
+
*/
|
|
271
|
+
allowanceReached: 4402,
|
|
272
|
+
/** This client's address holds as many connections to the project as one address may. */
|
|
273
|
+
addressLimitReached: 4429,
|
|
274
|
+
/** The project is at its per-project safety ceiling — Pro's 50,000 — whatever it would pay for. */
|
|
275
|
+
ceilingReached: 4503
|
|
276
|
+
};
|
|
277
|
+
var VISITOR_CLOSE_RETRY = {
|
|
278
|
+
4400: "stop",
|
|
279
|
+
4401: "stop",
|
|
280
|
+
4403: "stop",
|
|
281
|
+
4404: "stop",
|
|
282
|
+
1013: "retry",
|
|
283
|
+
4402: "back-off",
|
|
284
|
+
4429: "back-off",
|
|
285
|
+
4503: "back-off"
|
|
286
|
+
};
|
|
287
|
+
var VISITOR_POLL_RETRY = {
|
|
288
|
+
REQUEST_INVALID: "stop",
|
|
289
|
+
MISSING_API_KEY: "stop",
|
|
290
|
+
INVALID_API_KEY: "stop",
|
|
291
|
+
ACCESS_DENIED: "stop",
|
|
292
|
+
METHOD_NOT_ALLOWED: "stop",
|
|
293
|
+
SERVICE_INDETERMINATE: "retry",
|
|
294
|
+
USAGE_QUOTA_EXCEEDED: "back-off",
|
|
295
|
+
RATE_LIMIT_EXCEEDED: "back-off"
|
|
296
|
+
};
|
|
297
|
+
var VISITOR_ADMISSION_RETRY_AFTER_SECONDS = 60;
|
|
298
|
+
function parseVisitorFrame(text) {
|
|
299
|
+
let value;
|
|
300
|
+
try {
|
|
301
|
+
value = JSON.parse(text);
|
|
302
|
+
} catch {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
if (!isRecord2(value) || !isCursor(value.cursor)) return null;
|
|
306
|
+
switch (value.type) {
|
|
307
|
+
case VISITOR_FRAMES.opened: {
|
|
308
|
+
return hasOnly(value, ["type", "cursor"]) ? { type: VISITOR_FRAMES.opened, cursor: value.cursor } : null;
|
|
309
|
+
}
|
|
310
|
+
case VISITOR_FRAMES.changes: {
|
|
311
|
+
const changes = hasOnly(value, ["type", "changes", "cursor"]) ? readVisitorChanges(value.changes) : null;
|
|
312
|
+
return changes === null ? null : { type: VISITOR_FRAMES.changes, changes, cursor: value.cursor };
|
|
313
|
+
}
|
|
314
|
+
case VISITOR_FRAMES.resync: {
|
|
315
|
+
return hasOnly(value, ["type", "reason", "cursor"]) && isResyncReason(value.reason) ? { type: VISITOR_FRAMES.resync, reason: value.reason, cursor: value.cursor } : null;
|
|
316
|
+
}
|
|
317
|
+
default: {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
chunkMWMSFIWN_cjs.__name(parseVisitorFrame, "parseVisitorFrame");
|
|
323
|
+
function readVisitorPollAnswer(value) {
|
|
324
|
+
if (!isRecord2(value) || !isCursor(value.cursor)) return null;
|
|
325
|
+
if (value.kind === "resync") {
|
|
326
|
+
return hasOnly(value, ["kind", "reason", "cursor"]) && isResyncReason(value.reason) ? { kind: "resync", reason: value.reason, cursor: value.cursor } : null;
|
|
327
|
+
}
|
|
328
|
+
if (value.kind !== "changes" || !hasOnly(value, ["kind", "changes", "cursor"])) return null;
|
|
329
|
+
const changes = readVisitorChanges(value.changes);
|
|
330
|
+
return changes === null ? null : { kind: "changes", changes, cursor: value.cursor };
|
|
331
|
+
}
|
|
332
|
+
chunkMWMSFIWN_cjs.__name(readVisitorPollAnswer, "readVisitorPollAnswer");
|
|
333
|
+
var CHANGE_KINDS = /* @__PURE__ */ new Set([
|
|
334
|
+
"published",
|
|
335
|
+
"updated",
|
|
336
|
+
"unpublished",
|
|
337
|
+
"deleted"
|
|
338
|
+
]);
|
|
339
|
+
var RESYNC_REASONS = /* @__PURE__ */ new Set([
|
|
340
|
+
"retention",
|
|
341
|
+
"dataset-replaced",
|
|
342
|
+
"ahead-of-head",
|
|
343
|
+
"foreign-cursor",
|
|
344
|
+
"too-far-behind"
|
|
345
|
+
]);
|
|
346
|
+
function isResyncReason(value) {
|
|
347
|
+
return typeof value === "string" && RESYNC_REASONS.has(value);
|
|
348
|
+
}
|
|
349
|
+
chunkMWMSFIWN_cjs.__name(isResyncReason, "isResyncReason");
|
|
350
|
+
function readVisitorChanges(value) {
|
|
351
|
+
if (!Array.isArray(value)) return null;
|
|
352
|
+
const changes = [];
|
|
353
|
+
for (const item of value) {
|
|
354
|
+
if (!isRecord2(item) || !hasOnly(item, ["entryId", "contentType", "locale", "kind"])) return null;
|
|
355
|
+
const { entryId, contentType, locale, kind } = item;
|
|
356
|
+
if (!isNonEmptyString2(entryId) || !isNonEmptyString2(contentType)) return null;
|
|
357
|
+
if (locale !== null && typeof locale !== "string") return null;
|
|
358
|
+
if (typeof kind !== "string" || !CHANGE_KINDS.has(kind)) return null;
|
|
359
|
+
changes.push({ entryId, contentType, locale, kind });
|
|
360
|
+
}
|
|
361
|
+
return changes;
|
|
362
|
+
}
|
|
363
|
+
chunkMWMSFIWN_cjs.__name(readVisitorChanges, "readVisitorChanges");
|
|
364
|
+
function isCursor(value) {
|
|
365
|
+
return typeof value === "string" && VISITOR_CURSOR.test(value);
|
|
366
|
+
}
|
|
367
|
+
chunkMWMSFIWN_cjs.__name(isCursor, "isCursor");
|
|
368
|
+
function isRecord2(value) {
|
|
369
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
370
|
+
}
|
|
371
|
+
chunkMWMSFIWN_cjs.__name(isRecord2, "isRecord2");
|
|
372
|
+
function isNonEmptyString2(value) {
|
|
373
|
+
return typeof value === "string" && value.length > 0;
|
|
374
|
+
}
|
|
375
|
+
chunkMWMSFIWN_cjs.__name(isNonEmptyString2, "isNonEmptyString2");
|
|
376
|
+
function hasOnly(value, keys) {
|
|
377
|
+
const present = Object.keys(value);
|
|
378
|
+
return present.length === keys.length && present.every((key) => keys.includes(key));
|
|
379
|
+
}
|
|
380
|
+
chunkMWMSFIWN_cjs.__name(hasOnly, "hasOnly");
|
|
381
|
+
|
|
382
|
+
// src/preview/index.ts
|
|
383
|
+
var UNKNOWN_PREVIEW_RECHECK_MS = 6e4;
|
|
384
|
+
var NOT_PREVIEW = Object.freeze({ state: "not-preview" });
|
|
385
|
+
function previewAtRequest(env) {
|
|
386
|
+
return vercel(env) ?? NOT_PREVIEW;
|
|
387
|
+
}
|
|
388
|
+
chunkMWMSFIWN_cjs.__name(previewAtRequest, "previewAtRequest");
|
|
389
|
+
function previewAtBuild(env) {
|
|
390
|
+
const fromVercel = vercel(env);
|
|
391
|
+
if (fromVercel !== void 0) return fromVercel;
|
|
392
|
+
if (env.CONTEXT !== void 0) {
|
|
393
|
+
if (env.CONTEXT !== "deploy-preview") return NOT_PREVIEW;
|
|
394
|
+
return hasValue(env.HEAD) ? { state: "preview", host: "netlify", branch: env.HEAD } : { state: "no-branch", host: "netlify" };
|
|
395
|
+
}
|
|
396
|
+
if (env.CF_PAGES !== void 0) return { state: "undecidable", host: "cloudflare-pages" };
|
|
397
|
+
return NOT_PREVIEW;
|
|
398
|
+
}
|
|
399
|
+
chunkMWMSFIWN_cjs.__name(previewAtBuild, "previewAtBuild");
|
|
400
|
+
function vercel(env) {
|
|
401
|
+
if (env.VERCEL_ENV === void 0) return void 0;
|
|
402
|
+
if (env.VERCEL_ENV !== "preview") return NOT_PREVIEW;
|
|
403
|
+
return hasValue(env.VERCEL_GIT_COMMIT_REF) ? { state: "preview", host: "vercel", branch: env.VERCEL_GIT_COMMIT_REF } : { state: "no-branch", host: "vercel" };
|
|
404
|
+
}
|
|
405
|
+
chunkMWMSFIWN_cjs.__name(vercel, "vercel");
|
|
406
|
+
function hasValue(value) {
|
|
407
|
+
return value !== void 0 && value !== "";
|
|
408
|
+
}
|
|
409
|
+
chunkMWMSFIWN_cjs.__name(hasValue, "hasValue");
|
|
410
|
+
|
|
411
|
+
exports.FRESH_PARAMETER = FRESH_PARAMETER;
|
|
412
|
+
exports.HEADER_IDEMPOTENCY_KEY = HEADER_IDEMPOTENCY_KEY;
|
|
413
|
+
exports.HEADER_IF_MATCH = HEADER_IF_MATCH;
|
|
414
|
+
exports.HEADER_RETRY_AFTER = HEADER_RETRY_AFTER;
|
|
415
|
+
exports.PREVIEW_DATASET_PREFIX = PREVIEW_DATASET_PREFIX;
|
|
416
|
+
exports.UNKNOWN_PREVIEW_RECHECK_MS = UNKNOWN_PREVIEW_RECHECK_MS;
|
|
417
|
+
exports.VISITOR_ADMISSION_RETRY_AFTER_SECONDS = VISITOR_ADMISSION_RETRY_AFTER_SECONDS;
|
|
418
|
+
exports.VISITOR_CLOSE_CODES = VISITOR_CLOSE_CODES;
|
|
419
|
+
exports.VISITOR_CLOSE_RETRY = VISITOR_CLOSE_RETRY;
|
|
420
|
+
exports.VISITOR_FRAMES = VISITOR_FRAMES;
|
|
421
|
+
exports.VISITOR_KEEPALIVE = VISITOR_KEEPALIVE;
|
|
422
|
+
exports.VISITOR_LIVE_PATH = VISITOR_LIVE_PATH;
|
|
423
|
+
exports.VISITOR_POLL_INTERVAL_MS = VISITOR_POLL_INTERVAL_MS;
|
|
424
|
+
exports.VISITOR_POLL_RETRY = VISITOR_POLL_RETRY;
|
|
425
|
+
exports.VISITOR_QUERY = VISITOR_QUERY;
|
|
426
|
+
exports.entityTag = entityTag;
|
|
427
|
+
exports.parseVisitorFrame = parseVisitorFrame;
|
|
428
|
+
exports.previewAtBuild = previewAtBuild;
|
|
429
|
+
exports.previewAtRequest = previewAtRequest;
|
|
430
|
+
exports.previewDatasetSlug = previewDatasetSlug;
|
|
431
|
+
exports.readVisitorPollAnswer = readVisitorPollAnswer;
|
|
432
|
+
//# sourceMappingURL=chunk-7BZW6XYJ.cjs.map
|
|
433
|
+
//# sourceMappingURL=chunk-7BZW6XYJ.cjs.map
|