@sanity/client 7.26.2 → 8.1.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/README.md +63 -341
- package/dist/browserUpload-2tz6Sdqp.js +87 -0
- package/dist/browserUpload-2tz6Sdqp.js.map +1 -0
- package/dist/browserUpload-CwpNx7Vl.js +87 -0
- package/dist/browserUpload-CwpNx7Vl.js.map +1 -0
- package/dist/config-3wiPP-sZ.js +126 -0
- package/dist/config-3wiPP-sZ.js.map +1 -0
- package/dist/csm.d.ts +122 -335
- package/dist/csm.js +79 -91
- package/dist/csm.js.map +1 -1
- package/dist/dist-C9ExSk2R.js +73 -0
- package/dist/dist-C9ExSk2R.js.map +1 -0
- package/dist/dist-Z8cIRxoB.js +69 -0
- package/dist/dist-Z8cIRxoB.js.map +1 -0
- package/dist/index.d.ts +112 -6722
- package/dist/index.js +2950 -2848
- package/dist/index.js.map +1 -1
- package/dist/{index.d.cts → index.node.d.ts} +4529 -5322
- package/dist/index.node.js +3264 -0
- package/dist/index.node.js.map +1 -0
- package/dist/isRecord-Kfmt-nk-.js +7 -0
- package/dist/isRecord-Kfmt-nk-.js.map +1 -0
- package/dist/media-library.d.ts +9 -100
- package/dist/media-library.js +36 -14
- package/dist/media-library.js.map +1 -1
- package/dist/request-BhMuKj0D.js +373 -0
- package/dist/request-BhMuKj0D.js.map +1 -0
- package/dist/request-SnMg7nUX.js +355 -0
- package/dist/request-SnMg7nUX.js.map +1 -0
- package/dist/resolveEditInfo-Cz-smq3a.js +339 -0
- package/dist/resolveEditInfo-Cz-smq3a.js.map +1 -0
- package/dist/rolldown-runtime-vyAXikos.js +9 -0
- package/dist/stega.d.ts +78 -7137
- package/dist/stega.js +27 -20
- package/dist/stega.js.map +1 -1
- package/dist/stegaClean-C18wLWau.js +21 -0
- package/dist/stegaClean-C18wLWau.js.map +1 -0
- package/dist/stegaEncodeSourceMap-DbM2fTN4.js +373 -0
- package/dist/stegaEncodeSourceMap-DbM2fTN4.js.map +1 -0
- package/dist/stegaEncodeSourceMap-YR3NQ3iz.js +163 -0
- package/dist/stegaEncodeSourceMap-YR3NQ3iz.js.map +1 -0
- package/dist/{index.browser.d.cts → types-BODIEY7F.d.ts} +4196 -5258
- package/dist/types-CfGzbXrl.d.ts +108 -0
- package/package.json +80 -142
- package/src/SanityClient.ts +101 -137
- package/src/agent/actions/AgentActionsClient.ts +12 -12
- package/src/agent/actions/commonTypes.ts +2 -1
- package/src/agent/actions/generate.ts +26 -6
- package/src/agent/actions/patch.ts +27 -7
- package/src/agent/actions/prompt.ts +19 -5
- package/src/agent/actions/transform.ts +23 -5
- package/src/agent/actions/translate.ts +23 -5
- package/src/assets/AssetsClient.ts +121 -24
- package/src/csm/applySourceDocuments.ts +5 -5
- package/src/csm/createEditUrl.ts +1 -1
- package/src/csm/draftUtils.ts +23 -5
- package/src/csm/index.ts +2 -2
- package/src/csm/studioPath.ts +2 -1
- package/src/csm/types.ts +8 -2
- package/src/data/dataMethods.ts +784 -349
- package/src/data/eventsource.ts +82 -49
- package/src/data/listen.ts +18 -23
- package/src/data/live.ts +60 -35
- package/src/data/resolveEventSourceFetch.ts +104 -0
- package/src/datasets/DatasetsClient.ts +58 -41
- package/src/defineCreateClient.ts +38 -22
- package/src/functions/FunctionsClient.ts +66 -0
- package/src/functions/invoke.ts +176 -0
- package/src/http/browserMiddleware.ts +7 -1
- package/src/http/browserUpload.ts +163 -0
- package/src/http/errors.ts +61 -6
- package/src/http/nodeMiddleware.ts +94 -30
- package/src/http/request.ts +304 -87
- package/src/http/requestOptions.ts +131 -15
- package/src/{index.browser.ts → index.node.ts} +9 -4
- package/src/index.ts +4 -3
- package/src/mediaLibrary/MediaLibraryVideoClient.ts +27 -12
- package/src/projects/ProjectsClient.ts +18 -16
- package/src/releases/ReleasesClient.ts +38 -33
- package/src/stega/index.ts +1 -2
- package/src/stega/stegaEncodeSourceMap.ts +5 -0
- package/src/stega/types.ts +2 -2
- package/src/types.ts +328 -103
- package/src/users/UsersClient.ts +10 -14
- package/src/util/shareReplayLatest.ts +1 -1
- package/src/validators.ts +1 -1
- package/src/warnings.ts +13 -2
- package/dist/_chunks-cjs/config.cjs +0 -206
- package/dist/_chunks-cjs/config.cjs.map +0 -1
- package/dist/_chunks-cjs/isRecord.cjs +0 -6
- package/dist/_chunks-cjs/isRecord.cjs.map +0 -1
- package/dist/_chunks-cjs/resolveEditInfo.cjs +0 -334
- package/dist/_chunks-cjs/resolveEditInfo.cjs.map +0 -1
- package/dist/_chunks-cjs/stegaClean.cjs +0 -46
- package/dist/_chunks-cjs/stegaClean.cjs.map +0 -1
- package/dist/_chunks-cjs/stegaEncodeSourceMap.cjs +0 -388
- package/dist/_chunks-cjs/stegaEncodeSourceMap.cjs.map +0 -1
- package/dist/_chunks-es/config.js +0 -207
- package/dist/_chunks-es/config.js.map +0 -1
- package/dist/_chunks-es/isRecord.js +0 -7
- package/dist/_chunks-es/isRecord.js.map +0 -1
- package/dist/_chunks-es/resolveEditInfo.js +0 -335
- package/dist/_chunks-es/resolveEditInfo.js.map +0 -1
- package/dist/_chunks-es/stegaClean.js +0 -47
- package/dist/_chunks-es/stegaClean.js.map +0 -1
- package/dist/_chunks-es/stegaEncodeSourceMap.js +0 -389
- package/dist/_chunks-es/stegaEncodeSourceMap.js.map +0 -1
- package/dist/csm.cjs +0 -99
- package/dist/csm.cjs.map +0 -1
- package/dist/csm.d.cts +0 -391
- package/dist/index.browser.cjs +0 -3106
- package/dist/index.browser.cjs.map +0 -1
- package/dist/index.browser.d.ts +0 -6802
- package/dist/index.browser.js +0 -3082
- package/dist/index.browser.js.map +0 -1
- package/dist/index.cjs +0 -2946
- package/dist/index.cjs.map +0 -1
- package/dist/media-library.cjs +0 -20
- package/dist/media-library.cjs.map +0 -1
- package/dist/media-library.d.cts +0 -117
- package/dist/stega.browser.cjs +0 -29
- package/dist/stega.browser.cjs.map +0 -1
- package/dist/stega.browser.d.cts +0 -7200
- package/dist/stega.browser.d.ts +0 -7200
- package/dist/stega.browser.js +0 -24
- package/dist/stega.browser.js.map +0 -1
- package/dist/stega.cjs +0 -29
- package/dist/stega.cjs.map +0 -1
- package/dist/stega.d.cts +0 -7200
- package/src/data/eventsourcePolyfill.ts +0 -7
- package/umd/.gitkeep +0 -1
- package/umd/sanityClient.js +0 -6543
- package/umd/sanityClient.min.js +0 -6
package/dist/stega.js
CHANGED
|
@@ -1,24 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as vercelStegaCleanAll, t as stegaClean } from "./stegaClean-C18wLWau.js";
|
|
2
|
+
import { r as encodeIntoResult, t as stegaEncodeSourceMap } from "./stegaEncodeSourceMap-YR3NQ3iz.js";
|
|
3
|
+
import { ObservableSanityClient, SanityClient, createClient as createClient$1, requester as requester$1 } from "@sanity/client";
|
|
2
4
|
export * from "@sanity/client";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Marks strings in an already fetched query result as potentially containing stega-encoded data,
|
|
7
|
+
* by re-typing them as `StegaString`. Comparing branded strings to string literals is a type error
|
|
8
|
+
* until they're cleaned with `stegaClean()`, which recovers the original type.
|
|
9
|
+
*
|
|
10
|
+
* This is an identity function, it only changes the type of the input, not its value.
|
|
11
|
+
* Prefer passing `ClientReturnStega` as the first generic to `client.fetch` when possible, and use
|
|
12
|
+
* this function for data that has already been fetched.
|
|
13
|
+
*
|
|
14
|
+
* @beta
|
|
15
|
+
*/
|
|
5
16
|
function stegaBrand(result) {
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
class SanityStegaClient extends SanityClient {
|
|
9
|
-
}
|
|
10
|
-
class ObservableSanityStegaClient extends ObservableSanityClient {
|
|
17
|
+
return result;
|
|
11
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated -- Use `import {SanityClient} from '@sanity/client'` instead
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
var SanityStegaClient = class extends SanityClient {}, ObservableSanityStegaClient = class extends ObservableSanityClient {};
|
|
24
|
+
/**
|
|
25
|
+
* @deprecated -- Use `import {requester} from '@sanity/client'` instead
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
12
28
|
const requester = requester$1, createClient = createClient$1;
|
|
13
|
-
export {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
createClient,
|
|
17
|
-
encodeIntoResult,
|
|
18
|
-
requester,
|
|
19
|
-
stegaBrand,
|
|
20
|
-
stegaClean,
|
|
21
|
-
stegaEncodeSourceMap,
|
|
22
|
-
vercelStegaCleanAll
|
|
23
|
-
};
|
|
24
|
-
//# sourceMappingURL=stega.js.map
|
|
29
|
+
export { ObservableSanityStegaClient, SanityStegaClient, createClient, encodeIntoResult, requester, stegaBrand, stegaClean, stegaEncodeSourceMap, vercelStegaCleanAll };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=stega.js.map
|
package/dist/stega.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stega.js","sources":["../src/stega/stegaBrand.ts","../src/stega/index.ts"],"sourcesContent":["import type {Any, ClientReturn} from '@sanity/client'\n\n/**\n * A string that might contain stega-encoded data, and is unsafe to compare against string literals\n * until it's been cleaned with `stegaClean()`.\n *\n * The type intersects a template literal that has a human readable suffix, with a brand property\n * that holds the original string type:\n * - The suffix makes TypeScript report \"This comparison appears to be unintentional\" (TS2367) when\n * the string is compared to a literal (`===`, `switch` cases), and makes it unassignable to\n * literal unions like `'left' | 'right'`, while keeping it assignable to `string` so rendering,\n * interpolation and string methods keep working. The suffix is a type-level fiction, the runtime\n * value never ends with that text.\n * - The brand property preserves the original type so `stegaClean()` can recover it exactly. It's\n * a string-keyed property rather than a `unique symbol` so that branded types stay structurally\n * compatible across duplicated copies of `@sanity/client` in `node_modules`. It only exists in\n * the type system and is never present at runtime.\n *\n * @beta\n */\nexport type StegaString<T extends string = string> =\n `${T} (may contain hidden stega characters)` & {\n readonly ' stegaBrand': T\n }\n\n/**\n * Deeply brands the string properties of a query result as `StegaString`, marking them as\n * potentially containing stega-encoded data.\n *\n * String properties that the stega encoder is guaranteed to never encode keep their plain type:\n * - keys starting with `_` (`_id`, `_type`, `_createdAt`, `_updatedAt`, `_key`, `_ref`, `_rev` and\n * so on), which also preserves discriminated union narrowing on `_type`\n * - `slug.current` patterns: a `current` key directly under a `slug` key, as well as string valued\n * `slug` keys (covering `\"slug\": slug.current` projections)\n * - Portable Text internals: the encoder only visits `children` of `_type: 'block'` objects and\n * `text` of `_type: 'span'` objects, so properties like `style`, `listItem` and `marks` stay\n * plain\n * - symbol-keyed properties (like TypeGen's `internalGroqTypeReferenceTo` reference marker): JSON\n * can't contain symbol keys, so they only exist in the type system and are never encoded\n *\n * Every other string is assumed to be \"poisoned\", even if the runtime `filter` happens to skip it\n * (URLs, dates, keys ending in `Id`, denylisted keys). Being conservative is safe: the worst case\n * is a redundant `stegaClean()` call, whereas under-branding would hide real bugs.\n *\n * The `Key` and `ParentKey` type parameters track the key the current value is found under, and\n * the key of the object containing it, they're only used internally during recursion.\n *\n * @beta\n */\nexport type StegaBranded<\n T,\n Key extends PropertyKey = number,\n ParentKey extends PropertyKey = number,\n> = 0 extends 1 & T\n ? T\n : T extends string\n ? T extends {readonly ' stegaBrand': string}\n ? T\n : Key extends `_${string}` | 'slug' | symbol\n ? T\n : Key extends 'current'\n ? ParentKey extends 'slug'\n ? T\n : StegaString<T>\n : StegaString<T>\n : T extends number | bigint | boolean | null | undefined\n ? T\n : T extends Date | RegExp | ((...args: never[]) => unknown)\n ? T\n : T extends readonly unknown[]\n ? {[Index in keyof T]: StegaBranded<T[Index], number, number>}\n : T extends {_type: 'block'}\n ? {[K in keyof T]: K extends 'children' ? StegaBranded<T[K], K, Key> : T[K]}\n : T extends {_type: 'span'}\n ? {[K in keyof T]: K extends 'text' ? StegaBranded<T[K], K, Key> : T[K]}\n : T extends object\n ? {[K in keyof T]: StegaBranded<T[K], K, Key>}\n : T\n\n/**\n * Drop-in replacement for `ClientReturn` that brands the result strings as `StegaString`, for use\n * as the first generic of `client.fetch` when stega is enabled:\n * ```ts\n * import {createClient} from '@sanity/client'\n * import type {ClientReturnStega} from '@sanity/client/stega'\n *\n * const query = '*[_type == \"post\"][0]'\n * const post = await client.fetch<ClientReturnStega<typeof query>>(query)\n * ```\n * When the query is registered in the `SanityQueries` interface (for example by `sanity typegen`),\n * the result type is looked up and deeply branded with `StegaBranded`. Otherwise it falls back to\n * `Fallback`, which defaults to `any`, just like `ClientReturn`.\n *\n * @beta\n */\nexport type ClientReturnStega<GroqString extends string, Fallback = Any> = StegaBranded<\n ClientReturn<GroqString, Fallback>\n>\n\n/**\n * Marks strings in an already fetched query result as potentially containing stega-encoded data,\n * by re-typing them as `StegaString`. Comparing branded strings to string literals is a type error\n * until they're cleaned with `stegaClean()`, which recovers the original type.\n *\n * This is an identity function, it only changes the type of the input, not its value.\n * Prefer passing `ClientReturnStega` as the first generic to `client.fetch` when possible, and use\n * this function for data that has already been fetched.\n *\n * @beta\n */\nexport function stegaBrand<Result>(result: Result): StegaBranded<Result> {\n return result as StegaBranded<Result>\n}\n","export * from '@sanity/client'\nimport {\n createClient as originalCreateClient,\n ObservableSanityClient,\n requester as originalRequester,\n SanityClient,\n} from '@sanity/client'\n\nexport {
|
|
1
|
+
{"version":3,"file":"stega.js","names":["originalRequester","originalCreateClient"],"sources":["../src/stega/stegaBrand.ts","../src/stega/index.ts"],"sourcesContent":["import type {Any, ClientReturn} from '@sanity/client'\n\n/**\n * A string that might contain stega-encoded data, and is unsafe to compare against string literals\n * until it's been cleaned with `stegaClean()`.\n *\n * The type intersects a template literal that has a human readable suffix, with a brand property\n * that holds the original string type:\n * - The suffix makes TypeScript report \"This comparison appears to be unintentional\" (TS2367) when\n * the string is compared to a literal (`===`, `switch` cases), and makes it unassignable to\n * literal unions like `'left' | 'right'`, while keeping it assignable to `string` so rendering,\n * interpolation and string methods keep working. The suffix is a type-level fiction, the runtime\n * value never ends with that text.\n * - The brand property preserves the original type so `stegaClean()` can recover it exactly. It's\n * a string-keyed property rather than a `unique symbol` so that branded types stay structurally\n * compatible across duplicated copies of `@sanity/client` in `node_modules`. It only exists in\n * the type system and is never present at runtime.\n *\n * @beta\n */\nexport type StegaString<T extends string = string> =\n `${T} (may contain hidden stega characters)` & {\n readonly ' stegaBrand': T\n }\n\n/**\n * Deeply brands the string properties of a query result as `StegaString`, marking them as\n * potentially containing stega-encoded data.\n *\n * String properties that the stega encoder is guaranteed to never encode keep their plain type:\n * - keys starting with `_` (`_id`, `_type`, `_createdAt`, `_updatedAt`, `_key`, `_ref`, `_rev` and\n * so on), which also preserves discriminated union narrowing on `_type`\n * - `slug.current` patterns: a `current` key directly under a `slug` key, as well as string valued\n * `slug` keys (covering `\"slug\": slug.current` projections)\n * - Portable Text internals: the encoder only visits `children` of `_type: 'block'` objects and\n * `text` of `_type: 'span'` objects, so properties like `style`, `listItem` and `marks` stay\n * plain\n * - symbol-keyed properties (like TypeGen's `internalGroqTypeReferenceTo` reference marker): JSON\n * can't contain symbol keys, so they only exist in the type system and are never encoded\n *\n * Every other string is assumed to be \"poisoned\", even if the runtime `filter` happens to skip it\n * (URLs, dates, keys ending in `Id`, denylisted keys). Being conservative is safe: the worst case\n * is a redundant `stegaClean()` call, whereas under-branding would hide real bugs.\n *\n * The `Key` and `ParentKey` type parameters track the key the current value is found under, and\n * the key of the object containing it, they're only used internally during recursion.\n *\n * @beta\n */\nexport type StegaBranded<\n T,\n Key extends PropertyKey = number,\n ParentKey extends PropertyKey = number,\n> = 0 extends 1 & T\n ? T\n : T extends string\n ? T extends {readonly ' stegaBrand': string}\n ? T\n : Key extends `_${string}` | 'slug' | symbol\n ? T\n : Key extends 'current'\n ? ParentKey extends 'slug'\n ? T\n : StegaString<T>\n : StegaString<T>\n : T extends number | bigint | boolean | null | undefined\n ? T\n : T extends Date | RegExp | ((...args: never[]) => unknown)\n ? T\n : T extends readonly unknown[]\n ? {[Index in keyof T]: StegaBranded<T[Index], number, number>}\n : T extends {_type: 'block'}\n ? {[K in keyof T]: K extends 'children' ? StegaBranded<T[K], K, Key> : T[K]}\n : T extends {_type: 'span'}\n ? {[K in keyof T]: K extends 'text' ? StegaBranded<T[K], K, Key> : T[K]}\n : T extends object\n ? {[K in keyof T]: StegaBranded<T[K], K, Key>}\n : T\n\n/**\n * Drop-in replacement for `ClientReturn` that brands the result strings as `StegaString`, for use\n * as the first generic of `client.fetch` when stega is enabled:\n * ```ts\n * import {createClient} from '@sanity/client'\n * import type {ClientReturnStega} from '@sanity/client/stega'\n *\n * const query = '*[_type == \"post\"][0]'\n * const post = await client.fetch<ClientReturnStega<typeof query>>(query)\n * ```\n * When the query is registered in the `SanityQueries` interface (for example by `sanity typegen`),\n * the result type is looked up and deeply branded with `StegaBranded`. Otherwise it falls back to\n * `Fallback`, which defaults to `any`, just like `ClientReturn`.\n *\n * @beta\n */\nexport type ClientReturnStega<GroqString extends string, Fallback = Any> = StegaBranded<\n ClientReturn<GroqString, Fallback>\n>\n\n/**\n * Marks strings in an already fetched query result as potentially containing stega-encoded data,\n * by re-typing them as `StegaString`. Comparing branded strings to string literals is a type error\n * until they're cleaned with `stegaClean()`, which recovers the original type.\n *\n * This is an identity function, it only changes the type of the input, not its value.\n * Prefer passing `ClientReturnStega` as the first generic to `client.fetch` when possible, and use\n * this function for data that has already been fetched.\n *\n * @beta\n */\nexport function stegaBrand<Result>(result: Result): StegaBranded<Result> {\n return result as StegaBranded<Result>\n}\n","export * from '@sanity/client'\nimport {\n createClient as originalCreateClient,\n ObservableSanityClient,\n requester as originalRequester,\n SanityClient,\n} from '@sanity/client'\n\nexport {type ClientReturnStega, stegaBrand, type StegaBranded, type StegaString} from './stegaBrand'\nexport {stegaClean, type StegaCleaned, vercelStegaCleanAll} from './stegaClean'\nexport {encodeIntoResult, stegaEncodeSourceMap} from './stegaEncodeSourceMap'\nexport * from './types'\n\n/**\n * @deprecated -- Use `import {SanityClient} from '@sanity/client'` instead\n * @public\n */\nexport class SanityStegaClient extends SanityClient {}\n\n/**\n * @deprecated -- Use `import {ObservableSanityClient} from '@sanity/client'` instead\n * @public\n */\nexport class ObservableSanityStegaClient extends ObservableSanityClient {}\n\n/**\n * @deprecated -- Use `import {requester} from '@sanity/client'` instead\n * @public\n */\nexport const requester = originalRequester\n\n/**\n * @deprecated -- Use `import {createClient} from '@sanity/client'` instead\n * @public\n */\nexport const createClient = originalCreateClient\n"],"mappings":";;;;;;;;;;;;;;;AA8GA,SAAgB,WAAmB,QAAsC;CACvE,OAAO;AACT;;;;;AC/FA,IAAa,oBAAb,cAAuC,aAAa,CAAC,GAMxC,8BAAb,cAAiD,uBAAuB,CAAC;;;;;AAMzE,MAAa,YAAYA,aAMZ,eAAeC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { t as w } from "./dist-Z8cIRxoB.js";
|
|
2
|
+
/**
|
|
3
|
+
* Can take a `result` JSON from a `const {result} = client.fetch(query, params, {filterResponse: false})`
|
|
4
|
+
* and remove all stega-encoded data from it.
|
|
5
|
+
* If the result type has strings branded as `StegaString` (by `ClientReturnStega` or `stegaBrand()`),
|
|
6
|
+
* the brand is stripped and the original string type is restored.
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
function stegaClean(result) {
|
|
10
|
+
return w(result);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Can take a `result` JSON from a `const {result} = client.fetch(query, params, {filterResponse: false})`
|
|
14
|
+
* and remove all stega-encoded data from it.
|
|
15
|
+
* @alpha
|
|
16
|
+
* @deprecated Use `stegaClean` instead
|
|
17
|
+
*/
|
|
18
|
+
const vercelStegaCleanAll = stegaClean;
|
|
19
|
+
export { vercelStegaCleanAll as n, stegaClean as t };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=stegaClean-C18wLWau.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stegaClean-C18wLWau.js","names":["vercelStegaClean"],"sources":["../src/stega/stegaClean.ts"],"sourcesContent":["import {vercelStegaClean} from '@vercel/stega'\n\n/**\n * The result of removing stega-encoded data from a value with `stegaClean()`: strings that were\n * branded as `StegaString` are returned to their original type, everything else is left as-is.\n * @public\n */\nexport type StegaCleaned<T> = 0 extends 1 & T\n ? T\n : T extends {readonly ' stegaBrand': infer Original extends string}\n ? Original\n : T extends string | number | bigint | boolean | null | undefined\n ? T\n : T extends Date | RegExp | ((...args: never[]) => unknown)\n ? T\n : T extends readonly unknown[]\n ? {[Index in keyof T]: StegaCleaned<T[Index]>}\n : T extends object\n ? {[K in keyof T]: StegaCleaned<T[K]>}\n : T\n\n/**\n * Can take a `result` JSON from a `const {result} = client.fetch(query, params, {filterResponse: false})`\n * and remove all stega-encoded data from it.\n * If the result type has strings branded as `StegaString` (by `ClientReturnStega` or `stegaBrand()`),\n * the brand is stripped and the original string type is restored.\n * @public\n */\nexport function stegaClean<Result = unknown>(result: Result): StegaCleaned<Result> {\n return vercelStegaClean(result) as StegaCleaned<Result>\n}\n\n/**\n * Can take a `result` JSON from a `const {result} = client.fetch(query, params, {filterResponse: false})`\n * and remove all stega-encoded data from it.\n * @alpha\n * @deprecated Use `stegaClean` instead\n */\nexport const vercelStegaCleanAll = stegaClean\n"],"mappings":";;;;;;;;AA4BA,SAAgB,WAA6B,QAAsC;CACjF,OAAOA,EAAiB,MAAM;AAChC;;;;;;;AAQA,MAAa,sBAAsB"}
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import { t as require_dist } from "./dist-C9ExSk2R.js";
|
|
2
|
+
import { t as isRecord } from "./isRecord-Kfmt-nk-.js";
|
|
3
|
+
var import_dist = require_dist();
|
|
4
|
+
/** @internal */
|
|
5
|
+
function isDraftId(id) {
|
|
6
|
+
return id.startsWith("drafts.");
|
|
7
|
+
}
|
|
8
|
+
/** @internal */
|
|
9
|
+
function isVersionId(id) {
|
|
10
|
+
return id.startsWith("versions.");
|
|
11
|
+
}
|
|
12
|
+
/** @internal */
|
|
13
|
+
function isPublishedId(id) {
|
|
14
|
+
return !isDraftId(id) && !isVersionId(id);
|
|
15
|
+
}
|
|
16
|
+
function asPublishedId(value) {
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @internal
|
|
21
|
+
* Given an id, returns the versionId if it exists.
|
|
22
|
+
* e.g. `versions.summer-drop.foo` = `summer-drop`
|
|
23
|
+
* e.g. `drafts.foo` = `undefined`
|
|
24
|
+
* e.g. `foo` = `undefined`
|
|
25
|
+
*/
|
|
26
|
+
function getVersionFromId(id) {
|
|
27
|
+
if (!isVersionId(id)) return;
|
|
28
|
+
let [_versionPrefix, versionId, ..._publishedId] = id.split(".");
|
|
29
|
+
return versionId;
|
|
30
|
+
}
|
|
31
|
+
/** @internal */
|
|
32
|
+
function getPublishedId(id) {
|
|
33
|
+
if (isVersionId(id)) return asPublishedId(id.split(".").slice(2).join("."));
|
|
34
|
+
if (isDraftId(id)) return asPublishedId(id.slice(7));
|
|
35
|
+
if (isPublishedId(id)) return id;
|
|
36
|
+
throw Error(`Unable to resolve a published id from "${id}"`);
|
|
37
|
+
}
|
|
38
|
+
/** @internal */
|
|
39
|
+
const reKeySegment = /_key\s*==\s*['"](.*)['"]/;
|
|
40
|
+
/** @internal */
|
|
41
|
+
function isKeySegment(segment) {
|
|
42
|
+
return typeof segment == "string" ? reKeySegment.test(segment.trim()) : typeof segment == "object" && "_key" in segment;
|
|
43
|
+
}
|
|
44
|
+
/** @alpha */
|
|
45
|
+
function toString(path) {
|
|
46
|
+
if (!Array.isArray(path)) throw Error("Path is not an array");
|
|
47
|
+
return path.reduce((target, segment, i) => {
|
|
48
|
+
let segmentType = typeof segment;
|
|
49
|
+
if (segmentType === "number") return `${target}[${segment}]`;
|
|
50
|
+
if (segmentType === "string") return `${target}${i === 0 ? "" : "."}${segment}`;
|
|
51
|
+
if (isKeySegment(segment) && segment._key) return `${target}[_key=="${segment._key}"]`;
|
|
52
|
+
if (Array.isArray(segment)) {
|
|
53
|
+
let [from, to] = segment;
|
|
54
|
+
return `${target}[${from}:${to}]`;
|
|
55
|
+
}
|
|
56
|
+
throw Error(`Unsupported path segment \`${JSON.stringify(segment)}\``);
|
|
57
|
+
}, "");
|
|
58
|
+
}
|
|
59
|
+
const ESCAPE = {
|
|
60
|
+
"\f": "\\f",
|
|
61
|
+
"\n": "\\n",
|
|
62
|
+
"\r": "\\r",
|
|
63
|
+
" ": "\\t",
|
|
64
|
+
"'": "\\'",
|
|
65
|
+
"\\": "\\\\"
|
|
66
|
+
}, UNESCAPE = {
|
|
67
|
+
"\\f": "\f",
|
|
68
|
+
"\\n": "\n",
|
|
69
|
+
"\\r": "\r",
|
|
70
|
+
"\\t": " ",
|
|
71
|
+
"\\'": "'",
|
|
72
|
+
"\\\\": "\\"
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
function jsonPath(path) {
|
|
78
|
+
return `$${path.map((segment) => typeof segment == "string" ? `['${segment.replace(/[\f\n\r\t'\\]/g, (match) => ESCAPE[match])}']` : typeof segment == "number" ? `[${segment}]` : segment._key === "" ? `[${segment._index}]` : `[?(@._key=='${segment._key.replace(/['\\]/g, (match) => ESCAPE[match])}')]`).join("")}`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
function jsonPathArray(path) {
|
|
84
|
+
return path.map((segment) => typeof segment == "string" ? `['${segment.replace(/[\f\n\r\t'\\]/g, (match) => ESCAPE[match])}']` : typeof segment == "number" ? `[${segment}]` : segment._key === "" ? `[${segment._index}]` : `[?(@._key=='${segment._key.replace(/['\\]/g, (match) => ESCAPE[match])}')]`);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
function parseJsonPath(path) {
|
|
90
|
+
let parsed = [], parseRe = /\['(.*?)'\]|\[(\d+)\]|\[\?\(@\._key=='(.*?)'\)\]/g, match;
|
|
91
|
+
for (; (match = parseRe.exec(path)) !== null;) {
|
|
92
|
+
if (match[1] !== void 0) {
|
|
93
|
+
let key = match[1].replace(/\\(\\|f|n|r|t|')/g, (m) => UNESCAPE[m]);
|
|
94
|
+
parsed.push(key);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (match[2] !== void 0) {
|
|
98
|
+
parsed.push(parseInt(match[2], 10));
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (match[3] !== void 0) {
|
|
102
|
+
let _key = match[3].replace(/\\(\\')/g, (m) => UNESCAPE[m]);
|
|
103
|
+
parsed.push({
|
|
104
|
+
_key,
|
|
105
|
+
_index: -1
|
|
106
|
+
});
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return parsed;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* @internal
|
|
114
|
+
*/
|
|
115
|
+
function jsonPathToStudioPath(path) {
|
|
116
|
+
return path.map((segment) => {
|
|
117
|
+
if (typeof segment == "string" || typeof segment == "number") return segment;
|
|
118
|
+
if (segment._key !== "") return { _key: segment._key };
|
|
119
|
+
if (segment._index !== -1) return segment._index;
|
|
120
|
+
throw Error(`invalid segment:${JSON.stringify(segment)}`);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
function jsonPathToMappingPath(path) {
|
|
127
|
+
return path.map((segment) => {
|
|
128
|
+
if (typeof segment == "string" || typeof segment == "number") return segment;
|
|
129
|
+
if (segment._index !== -1) return segment._index;
|
|
130
|
+
throw Error(`invalid segment:${JSON.stringify(segment)}`);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/** @internal */
|
|
134
|
+
function createEditUrl(options) {
|
|
135
|
+
let { baseUrl, workspace: _workspace = "default", tool: _tool = "default", id: _id, type, path, projectId, dataset } = options;
|
|
136
|
+
if (!baseUrl) throw Error("baseUrl is required");
|
|
137
|
+
if (!path) throw Error("path is required");
|
|
138
|
+
if (!_id) throw Error("id is required");
|
|
139
|
+
if (baseUrl !== "/" && baseUrl.endsWith("/")) throw Error("baseUrl must not end with a slash");
|
|
140
|
+
let workspace = _workspace === "default" ? void 0 : _workspace, tool = _tool === "default" ? void 0 : _tool, id = getPublishedId(_id), stringifiedPath = Array.isArray(path) ? toString(jsonPathToStudioPath(path)) : path, searchParams = new URLSearchParams({
|
|
141
|
+
baseUrl,
|
|
142
|
+
id,
|
|
143
|
+
type,
|
|
144
|
+
path: stringifiedPath
|
|
145
|
+
});
|
|
146
|
+
if (workspace && searchParams.set("workspace", workspace), tool && searchParams.set("tool", tool), projectId && searchParams.set("projectId", projectId), dataset && searchParams.set("dataset", dataset), isPublishedId(_id)) searchParams.set("perspective", "published");
|
|
147
|
+
else if (isVersionId(_id)) {
|
|
148
|
+
let versionId = getVersionFromId(_id);
|
|
149
|
+
searchParams.set("perspective", versionId);
|
|
150
|
+
}
|
|
151
|
+
let segments = [baseUrl === "/" ? "" : baseUrl];
|
|
152
|
+
workspace && segments.push(workspace);
|
|
153
|
+
let routerParams = [
|
|
154
|
+
"mode=presentation",
|
|
155
|
+
`id=${id}`,
|
|
156
|
+
`type=${type}`,
|
|
157
|
+
`path=${encodeURIComponent(stringifiedPath)}`
|
|
158
|
+
];
|
|
159
|
+
return tool && routerParams.push(`tool=${tool}`), segments.push("intent", "edit", `${routerParams.join(";")}?${searchParams}`), segments.join("/");
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* @internal
|
|
163
|
+
*/
|
|
164
|
+
function resolveMapping(resultPath, csm) {
|
|
165
|
+
if (!csm?.mappings) return;
|
|
166
|
+
let resultMappingPath = jsonPath(jsonPathToMappingPath(resultPath));
|
|
167
|
+
if (csm.mappings[resultMappingPath] !== void 0) return {
|
|
168
|
+
mapping: csm.mappings[resultMappingPath],
|
|
169
|
+
matchedPath: resultMappingPath,
|
|
170
|
+
pathSuffix: ""
|
|
171
|
+
};
|
|
172
|
+
let resultMappingPathArray = jsonPathArray(jsonPathToMappingPath(resultPath));
|
|
173
|
+
for (let i = resultMappingPathArray.length - 1; i >= 0; i--) {
|
|
174
|
+
let key = `$${resultMappingPathArray.slice(0, i).join("")}`, mappingFound = csm.mappings[key];
|
|
175
|
+
if (mappingFound) return {
|
|
176
|
+
mapping: mappingFound,
|
|
177
|
+
matchedPath: key,
|
|
178
|
+
pathSuffix: resultMappingPath.substring(key.length)
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/** @internal */
|
|
183
|
+
function resolveStudioBaseRoute(studioUrl) {
|
|
184
|
+
let baseUrl = typeof studioUrl == "string" ? studioUrl : studioUrl.baseUrl;
|
|
185
|
+
return baseUrl !== "/" && (baseUrl = baseUrl.replace(/\/$/, "")), typeof studioUrl == "string" ? { baseUrl } : {
|
|
186
|
+
...studioUrl,
|
|
187
|
+
baseUrl
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/** @internal */
|
|
191
|
+
function isArray(value) {
|
|
192
|
+
return value !== null && Array.isArray(value);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* generic way to walk a nested object or array and apply a mapping function to each value
|
|
196
|
+
* @internal
|
|
197
|
+
*/
|
|
198
|
+
function walkMap(value, mappingFn, path = []) {
|
|
199
|
+
if (isArray(value)) return value.map((v, idx) => {
|
|
200
|
+
if (isRecord(v)) {
|
|
201
|
+
let _key = v._key;
|
|
202
|
+
if (typeof _key == "string") return walkMap(v, mappingFn, path.concat({
|
|
203
|
+
_key,
|
|
204
|
+
_index: idx
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
return walkMap(v, mappingFn, path.concat(idx));
|
|
208
|
+
});
|
|
209
|
+
if (isRecord(value)) {
|
|
210
|
+
if (value._type === "block" || value._type === "span") {
|
|
211
|
+
let result = { ...value };
|
|
212
|
+
return value._type === "block" ? result.children = walkMap(value.children, mappingFn, path.concat("children")) : value._type === "span" && (result.text = walkMap(value.text, mappingFn, path.concat("text"))), result;
|
|
213
|
+
}
|
|
214
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, walkMap(v, mappingFn, path.concat(k))]));
|
|
215
|
+
}
|
|
216
|
+
return mappingFn(value, path);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* @internal
|
|
220
|
+
*/
|
|
221
|
+
function encodeIntoResult(result, csm, encoder) {
|
|
222
|
+
return walkMap(result, (value, path) => {
|
|
223
|
+
if (typeof value != "string") return value;
|
|
224
|
+
let resolveMappingResult = resolveMapping(path, csm);
|
|
225
|
+
if (!resolveMappingResult) return value;
|
|
226
|
+
let { mapping, matchedPath } = resolveMappingResult;
|
|
227
|
+
if (mapping.type !== "value" || mapping.source.type !== "documentValue") return value;
|
|
228
|
+
let sourceDocument = csm.documents[mapping.source.document], sourcePath = csm.paths[mapping.source.path], matchPathSegments = parseJsonPath(matchedPath);
|
|
229
|
+
return encoder({
|
|
230
|
+
sourcePath: parseJsonPath(sourcePath).concat(path.slice(matchPathSegments.length)),
|
|
231
|
+
sourceDocument,
|
|
232
|
+
resultPath: path,
|
|
233
|
+
value
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
const filterDefault = ({ sourcePath, resultPath, value }) => {
|
|
238
|
+
if (isValidDate(value) || isValidURL(value)) return !1;
|
|
239
|
+
let endPath = sourcePath.at(-1);
|
|
240
|
+
return !(sourcePath.at(-2) === "slug" && endPath === "current" || typeof endPath == "string" && (endPath.startsWith("_") || endPath.endsWith("Id")) || sourcePath.some((path) => path === "meta" || path === "metadata" || path === "openGraph" || path === "seo") || hasTypeLike(sourcePath) || hasTypeLike(resultPath) || typeof endPath == "string" && denylist.has(endPath));
|
|
241
|
+
}, denylist = /* @__PURE__ */ new Set(/* @__PURE__ */ "color.colour.currency.email.format.gid.hex.href.hsl.hsla.icon.id.index.key.language.layout.link.linkAction.locale.lqip.page.path.ref.rgb.rgba.route.secret.slug.status.tag.template.theme.type.textTheme.unit.url.username.variant.website".split("."));
|
|
242
|
+
function isValidDate(dateString) {
|
|
243
|
+
return /^\d{4}-\d{2}-\d{2}/.test(dateString) ? !!Date.parse(dateString) : !1;
|
|
244
|
+
}
|
|
245
|
+
const allowedProtocols = /* @__PURE__ */ new Set([
|
|
246
|
+
"app:",
|
|
247
|
+
"data:",
|
|
248
|
+
"discord:",
|
|
249
|
+
"file:",
|
|
250
|
+
"ftp:",
|
|
251
|
+
"ftps:",
|
|
252
|
+
"geo:",
|
|
253
|
+
"http:",
|
|
254
|
+
"https:",
|
|
255
|
+
"imap:",
|
|
256
|
+
"javascript:",
|
|
257
|
+
"magnet:",
|
|
258
|
+
"mailto:",
|
|
259
|
+
"maps:",
|
|
260
|
+
"ms-excel:",
|
|
261
|
+
"ms-powerpoint:",
|
|
262
|
+
"ms-word:",
|
|
263
|
+
"slack:",
|
|
264
|
+
"sms:",
|
|
265
|
+
"spotify:",
|
|
266
|
+
"steam:",
|
|
267
|
+
"teams:",
|
|
268
|
+
"tel:",
|
|
269
|
+
"vscode:",
|
|
270
|
+
"zoom:"
|
|
271
|
+
]);
|
|
272
|
+
function isValidURL(url) {
|
|
273
|
+
try {
|
|
274
|
+
let { protocol } = new URL(url, url.startsWith("/") ? "https://acme.com" : void 0);
|
|
275
|
+
return allowedProtocols.has(protocol) || protocol.startsWith("web+");
|
|
276
|
+
} catch {
|
|
277
|
+
return !1;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
function hasTypeLike(path) {
|
|
281
|
+
return path.some((segment) => typeof segment == "string" && segment.match(/type/i) !== null);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Uses `@vercel/stega` to embed edit info JSON into strings in your query result.
|
|
285
|
+
* The JSON payloads are added using invisible characters so they don't show up visually.
|
|
286
|
+
* The edit info is generated from the Content Source Map (CSM) that is returned from Sanity for the query.
|
|
287
|
+
* @public
|
|
288
|
+
*/
|
|
289
|
+
function stegaEncodeSourceMap(result, resultSourceMap, config) {
|
|
290
|
+
let { filter, logger, enabled } = config;
|
|
291
|
+
if (!enabled) {
|
|
292
|
+
let msg = "config.enabled must be true, don't call this function otherwise";
|
|
293
|
+
throw logger?.error?.(`[@sanity/client]: ${msg}`, {
|
|
294
|
+
result,
|
|
295
|
+
resultSourceMap,
|
|
296
|
+
config
|
|
297
|
+
}), TypeError(msg);
|
|
298
|
+
}
|
|
299
|
+
if (!resultSourceMap) return logger?.error?.("[@sanity/client]: Missing Content Source Map from response body", {
|
|
300
|
+
result,
|
|
301
|
+
resultSourceMap,
|
|
302
|
+
config
|
|
303
|
+
}), result;
|
|
304
|
+
if (!config.studioUrl) {
|
|
305
|
+
let msg = "config.studioUrl must be defined";
|
|
306
|
+
throw logger?.error?.(`[@sanity/client]: ${msg}`, {
|
|
307
|
+
result,
|
|
308
|
+
resultSourceMap,
|
|
309
|
+
config
|
|
310
|
+
}), TypeError(msg);
|
|
311
|
+
}
|
|
312
|
+
let report = {
|
|
313
|
+
encoded: [],
|
|
314
|
+
skipped: []
|
|
315
|
+
}, resultWithStega = encodeIntoResult(result, resultSourceMap, ({ sourcePath, sourceDocument, resultPath, value }) => {
|
|
316
|
+
if ((typeof filter == "function" ? filter({
|
|
317
|
+
sourcePath,
|
|
318
|
+
resultPath,
|
|
319
|
+
filterDefault,
|
|
320
|
+
sourceDocument,
|
|
321
|
+
value
|
|
322
|
+
}) : filterDefault({
|
|
323
|
+
sourcePath,
|
|
324
|
+
resultPath,
|
|
325
|
+
filterDefault,
|
|
326
|
+
sourceDocument,
|
|
327
|
+
value
|
|
328
|
+
})) === !1) return logger && report.skipped.push({
|
|
329
|
+
path: prettyPathForLogging(sourcePath),
|
|
330
|
+
value: `${value.slice(0, 20)}${value.length > 20 ? "..." : ""}`,
|
|
331
|
+
length: value.length
|
|
332
|
+
}), value;
|
|
333
|
+
logger && report.encoded.push({
|
|
334
|
+
path: prettyPathForLogging(sourcePath),
|
|
335
|
+
value: `${value.slice(0, 20)}${value.length > 20 ? "..." : ""}`,
|
|
336
|
+
length: value.length
|
|
337
|
+
});
|
|
338
|
+
let { baseUrl, workspace, tool } = resolveStudioBaseRoute(typeof config.studioUrl == "function" ? config.studioUrl(sourceDocument) : config.studioUrl);
|
|
339
|
+
if (!baseUrl) return value;
|
|
340
|
+
let { _id: id, _type: type, _projectId: projectId, _dataset: dataset } = sourceDocument;
|
|
341
|
+
return (0, import_dist.vercelStegaCombine)(value, {
|
|
342
|
+
origin: "sanity.io",
|
|
343
|
+
href: createEditUrl({
|
|
344
|
+
baseUrl,
|
|
345
|
+
workspace,
|
|
346
|
+
tool,
|
|
347
|
+
id,
|
|
348
|
+
type,
|
|
349
|
+
path: sourcePath,
|
|
350
|
+
...!config.omitCrossDatasetReferenceData && {
|
|
351
|
+
dataset,
|
|
352
|
+
projectId
|
|
353
|
+
}
|
|
354
|
+
})
|
|
355
|
+
}, !1);
|
|
356
|
+
});
|
|
357
|
+
if (logger) {
|
|
358
|
+
let isSkipping = report.skipped.length, isEncoding = report.encoded.length;
|
|
359
|
+
if ((isSkipping || isEncoding) && ((logger?.groupCollapsed || logger.log)?.("[@sanity/client]: Encoding source map into result"), logger.log?.(`[@sanity/client]: Paths encoded: ${report.encoded.length}, skipped: ${report.skipped.length}`)), report.encoded.length > 0 && (logger?.log?.("[@sanity/client]: Table of encoded paths"), (logger?.table || logger.log)?.(report.encoded)), report.skipped.length > 0) {
|
|
360
|
+
let skipped = /* @__PURE__ */ new Set();
|
|
361
|
+
for (let { path } of report.skipped) skipped.add(path.replace(reKeySegment, "0").replace(/\[\d+\]/g, "[]"));
|
|
362
|
+
logger?.log?.("[@sanity/client]: List of skipped paths", [...skipped.values()]);
|
|
363
|
+
}
|
|
364
|
+
(isSkipping || isEncoding) && logger?.groupEnd?.();
|
|
365
|
+
}
|
|
366
|
+
return resultWithStega;
|
|
367
|
+
}
|
|
368
|
+
function prettyPathForLogging(path) {
|
|
369
|
+
return toString(jsonPathToStudioPath(path));
|
|
370
|
+
}
|
|
371
|
+
export { encodeIntoResult, stegaEncodeSourceMap };
|
|
372
|
+
|
|
373
|
+
//# sourceMappingURL=stegaEncodeSourceMap-DbM2fTN4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stegaEncodeSourceMap-DbM2fTN4.js","names":["studioPath.toString","vercelStegaCombine","studioPathToString"],"sources":["../src/csm/draftUtils.ts","../src/csm/studioPath.ts","../src/csm/jsonPath.ts","../src/csm/createEditUrl.ts","../src/csm/resolveMapping.ts","../src/csm/resolveEditInfo.ts","../src/csm/isArray.ts","../src/csm/walkMap.ts","../src/stega/encodeIntoResult.ts","../src/stega/filterDefault.ts","../src/stega/stegaEncodeSourceMap.ts"],"sourcesContent":["// nominal/opaque type hack\ntype Opaque<T, K> = T & {__opaqueId__: K}\n\n/** @internal */\nexport type DraftId = Opaque<string, 'draftId'>\n\n/** @internal */\nexport type PublishedId = Opaque<string, 'publishedId'>\n\n/** @internal */\nexport const DRAFTS_FOLDER = 'drafts'\n\n/** @internal */\nexport const VERSION_FOLDER = 'versions'\n\nconst PATH_SEPARATOR = '.'\nconst DRAFTS_PREFIX = `${DRAFTS_FOLDER}${PATH_SEPARATOR}`\nconst VERSION_PREFIX = `${VERSION_FOLDER}${PATH_SEPARATOR}`\n\n/** @internal */\nexport function isDraftId(id: string): id is DraftId {\n return id.startsWith(DRAFTS_PREFIX)\n}\n\n/** @internal */\nexport function isVersionId(id: string): boolean {\n return id.startsWith(VERSION_PREFIX)\n}\n\n/** @internal */\nexport function isPublishedId(id: string): id is PublishedId {\n return !isDraftId(id) && !isVersionId(id)\n}\n\n/**\n * A phantom brand like `DraftId` has no runtime representation, so it can never be produced\n * by narrowing a string - there's nothing to check. These two functions are the only places\n * allowed to assert a plain string into a branded id.\n */\nfunction asDraftId(value: string): DraftId {\n return value as DraftId\n}\n\nfunction asPublishedId(value: string): PublishedId {\n return value as PublishedId\n}\n\n/** @internal */\nexport function getDraftId(id: string): DraftId {\n if (isVersionId(id)) {\n const publishedId = getPublishedId(id)\n return asDraftId(DRAFTS_PREFIX + publishedId)\n }\n\n return isDraftId(id) ? id : ((DRAFTS_PREFIX + id) as DraftId)\n}\n\n/** @internal */\nexport function getVersionId(id: string, version: string): string {\n if (version === 'drafts' || version === 'published') {\n throw new Error('Version can not be \"published\" or \"drafts\"')\n }\n\n return `${VERSION_PREFIX}${version}${PATH_SEPARATOR}${getPublishedId(id)}`\n}\n\n/**\n * @internal\n * Given an id, returns the versionId if it exists.\n * e.g. `versions.summer-drop.foo` = `summer-drop`\n * e.g. `drafts.foo` = `undefined`\n * e.g. `foo` = `undefined`\n */\nexport function getVersionFromId(id: string): string | undefined {\n if (!isVersionId(id)) return undefined\n const [_versionPrefix, versionId, ..._publishedId] = id.split(PATH_SEPARATOR)\n\n return versionId\n}\n\n/** @internal */\nexport function getPublishedId(id: string): PublishedId {\n if (isVersionId(id)) {\n // make sure to only remove the versions prefix and the bundle name\n return asPublishedId(id.split(PATH_SEPARATOR).slice(2).join(PATH_SEPARATOR))\n }\n\n if (isDraftId(id)) {\n return asPublishedId(id.slice(DRAFTS_PREFIX.length))\n }\n\n if (isPublishedId(id)) {\n return id\n }\n\n // Unreachable: `isPublishedId` is defined as `!isDraftId(id) && !isVersionId(id)`, both of\n // which were already checked (and found false) above, so this can never execute.\n throw new Error(`Unable to resolve a published id from \"${id}\"`)\n}\n","/** @alpha */\nexport type KeyedSegment = {_key: string}\n\n/** @alpha */\nexport type IndexTuple = [number | '', number | '']\n\n/** @alpha */\nexport type PathSegment = string | number | KeyedSegment | IndexTuple\n\n/** @alpha */\nexport type Path = PathSegment[]\n\nconst rePropName =\n /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g\n/** @internal */\nexport const reKeySegment = /_key\\s*==\\s*['\"](.*)['\"]/\nconst reIndexTuple = /^\\d*:\\d*$/\n\n/** @internal */\nexport function isIndexSegment(segment: PathSegment): segment is number {\n return typeof segment === 'number' || (typeof segment === 'string' && /^\\[\\d+\\]$/.test(segment))\n}\n\n/** @internal */\nexport function isKeySegment(segment: PathSegment): segment is KeyedSegment {\n if (typeof segment === 'string') {\n return reKeySegment.test(segment.trim())\n }\n\n return typeof segment === 'object' && '_key' in segment\n}\n\n/** @internal */\nexport function isIndexTuple(segment: PathSegment): segment is IndexTuple {\n if (typeof segment === 'string' && reIndexTuple.test(segment)) {\n return true\n }\n\n if (!Array.isArray(segment) || segment.length !== 2) {\n return false\n }\n\n const [from, to] = segment\n return (typeof from === 'number' || from === '') && (typeof to === 'number' || to === '')\n}\n\n/** @internal */\n// oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- caller-supplied return type; removing it breaks `get<Result>(...)` call sites\nexport function get<Result = unknown, Fallback = unknown>(\n obj: unknown,\n path: Path | string,\n defaultVal?: Fallback,\n): Result | typeof defaultVal {\n const select = typeof path === 'string' ? fromString(path) : path\n if (!Array.isArray(select)) {\n throw new Error('Path must be an array or a string')\n }\n\n let acc: unknown = obj\n for (let i = 0; i < select.length; i++) {\n const segment = select[i]\n if (isIndexSegment(segment)) {\n if (!Array.isArray(acc)) {\n return defaultVal\n }\n\n acc = acc[segment]\n }\n\n if (isKeySegment(segment)) {\n if (!Array.isArray(acc)) {\n return defaultVal\n }\n\n acc = acc.find((item) => item._key === segment._key)\n }\n\n if (typeof segment === 'string') {\n acc =\n typeof acc === 'object' && acc !== null\n ? ((acc as Record<string, unknown>)[segment] as Result)\n : undefined\n }\n\n if (typeof acc === 'undefined') {\n return defaultVal\n }\n }\n\n return acc as Result\n}\n\n/** @alpha */\nexport function toString(path: Path): string {\n if (!Array.isArray(path)) {\n throw new Error('Path is not an array')\n }\n\n return path.reduce<string>((target, segment, i) => {\n const segmentType = typeof segment\n if (segmentType === 'number') {\n return `${target}[${segment}]`\n }\n\n if (segmentType === 'string') {\n const separator = i === 0 ? '' : '.'\n return `${target}${separator}${segment}`\n }\n\n if (isKeySegment(segment) && segment._key) {\n return `${target}[_key==\"${segment._key}\"]`\n }\n\n if (Array.isArray(segment)) {\n const [from, to] = segment\n return `${target}[${from}:${to}]`\n }\n\n throw new Error(`Unsupported path segment \\`${JSON.stringify(segment)}\\``)\n }, '')\n}\n\n/** @alpha */\nexport function fromString(path: string): Path {\n if (typeof path !== 'string') {\n throw new Error('Path is not a string')\n }\n\n const segments = path.match(rePropName)\n if (!segments) {\n throw new Error('Invalid path string')\n }\n\n return segments.map(parsePathSegment)\n}\n\nfunction parsePathSegment(segment: string): PathSegment {\n if (isIndexSegment(segment)) {\n return parseIndexSegment(segment)\n }\n\n if (isKeySegment(segment)) {\n return parseKeySegment(segment)\n }\n\n if (isIndexTuple(segment)) {\n return parseIndexTupleSegment(segment)\n }\n\n return segment\n}\n\nfunction parseIndexSegment(segment: string): PathSegment {\n return Number(segment.replace(/[^\\d]/g, ''))\n}\n\nfunction parseKeySegment(segment: string): KeyedSegment {\n const segments = segment.match(reKeySegment)\n return {_key: segments![1]}\n}\n\nfunction parseIndexTupleSegment(segment: string): IndexTuple {\n const [from, to] = segment.split(':').map((seg) => (seg === '' ? seg : Number(seg)))\n return [from, to]\n}\n","import * as studioPath from './studioPath'\nimport type {\n ContentSourceMapParsedPath,\n ContentSourceMapParsedPathKeyedSegment,\n ContentSourceMapPaths,\n Path,\n} from './types'\n\nconst ESCAPE: Record<string, string> = {\n '\\f': '\\\\f',\n '\\n': '\\\\n',\n '\\r': '\\\\r',\n '\\t': '\\\\t',\n \"'\": \"\\\\'\",\n '\\\\': '\\\\\\\\',\n}\n\nconst UNESCAPE: Record<string, string> = {\n '\\\\f': '\\f',\n '\\\\n': '\\n',\n '\\\\r': '\\r',\n '\\\\t': '\\t',\n \"\\\\'\": \"'\",\n '\\\\\\\\': '\\\\',\n}\n\n/**\n * @internal\n */\nexport function jsonPath(path: ContentSourceMapParsedPath): ContentSourceMapPaths[number] {\n return `$${path\n .map((segment) => {\n if (typeof segment === 'string') {\n const escapedKey = segment.replace(/[\\f\\n\\r\\t'\\\\]/g, (match) => {\n return ESCAPE[match]\n })\n return `['${escapedKey}']`\n }\n\n if (typeof segment === 'number') {\n return `[${segment}]`\n }\n\n if (segment._key !== '') {\n const escapedKey = segment._key.replace(/['\\\\]/g, (match) => {\n return ESCAPE[match]\n })\n return `[?(@._key=='${escapedKey}')]`\n }\n\n return `[${segment._index}]`\n })\n .join('')}`\n}\n/**\n * @internal\n */\nexport function jsonPathArray(path: ContentSourceMapParsedPath): string[] {\n return path.map((segment) => {\n if (typeof segment === 'string') {\n const escapedKey = segment.replace(/[\\f\\n\\r\\t'\\\\]/g, (match) => {\n return ESCAPE[match]\n })\n return `['${escapedKey}']`\n }\n\n if (typeof segment === 'number') {\n return `[${segment}]`\n }\n\n if (segment._key !== '') {\n const escapedKey = segment._key.replace(/['\\\\]/g, (match) => {\n return ESCAPE[match]\n })\n return `[?(@._key=='${escapedKey}')]`\n }\n\n return `[${segment._index}]`\n })\n}\n\n/**\n * @internal\n */\nexport function parseJsonPath(path: ContentSourceMapPaths[number]): ContentSourceMapParsedPath {\n const parsed: ContentSourceMapParsedPath = []\n\n const parseRe = /\\['(.*?)'\\]|\\[(\\d+)\\]|\\[\\?\\(@\\._key=='(.*?)'\\)\\]/g\n let match: RegExpExecArray | null\n\n while ((match = parseRe.exec(path)) !== null) {\n if (match[1] !== undefined) {\n const key = match[1].replace(/\\\\(\\\\|f|n|r|t|')/g, (m) => {\n return UNESCAPE[m]\n })\n\n parsed.push(key)\n continue\n }\n\n if (match[2] !== undefined) {\n parsed.push(parseInt(match[2], 10))\n continue\n }\n\n if (match[3] !== undefined) {\n const _key = match[3].replace(/\\\\(\\\\')/g, (m) => {\n return UNESCAPE[m]\n })\n\n parsed.push({\n _key,\n _index: -1,\n })\n continue\n }\n }\n\n return parsed\n}\n\n/**\n * @internal\n */\nexport function jsonPathToStudioPath(path: ContentSourceMapParsedPath): Path {\n return path.map((segment) => {\n if (typeof segment === 'string') {\n return segment\n }\n\n if (typeof segment === 'number') {\n return segment\n }\n\n if (segment._key !== '') {\n return {_key: segment._key}\n }\n\n if (segment._index !== -1) {\n return segment._index\n }\n\n throw new Error(`invalid segment:${JSON.stringify(segment)}`)\n })\n}\n\n/**\n * @internal\n */\nexport function studioPathToJsonPath(path: Path | string): ContentSourceMapParsedPath {\n const parsedPath = typeof path === 'string' ? studioPath.fromString(path) : path\n\n return parsedPath.map((segment) => {\n if (typeof segment === 'string') {\n return segment\n }\n\n if (typeof segment === 'number') {\n return segment\n }\n\n if (Array.isArray(segment)) {\n throw new Error(`IndexTuple segments aren't supported:${JSON.stringify(segment)}`)\n }\n\n if (isContentSourceMapParsedPathKeyedSegment(segment)) {\n return segment\n }\n\n if (segment._key) {\n return {_key: segment._key, _index: -1}\n }\n\n throw new Error(`invalid segment:${JSON.stringify(segment)}`)\n })\n}\n\nfunction isContentSourceMapParsedPathKeyedSegment(\n segment: studioPath.PathSegment | ContentSourceMapParsedPath[number],\n): segment is ContentSourceMapParsedPathKeyedSegment {\n return typeof segment === 'object' && '_key' in segment && '_index' in segment\n}\n\n/**\n * @internal\n */\nexport function jsonPathToMappingPath(path: ContentSourceMapParsedPath): (string | number)[] {\n return path.map((segment) => {\n if (typeof segment === 'string') {\n return segment\n }\n\n if (typeof segment === 'number') {\n return segment\n }\n\n if (segment._index !== -1) {\n return segment._index\n }\n\n throw new Error(`invalid segment:${JSON.stringify(segment)}`)\n })\n}\n","import {getPublishedId, getVersionFromId, isPublishedId, isVersionId} from './draftUtils'\nimport {jsonPathToStudioPath} from './jsonPath'\nimport * as studioPath from './studioPath'\nimport type {CreateEditUrlOptions, EditIntentUrl, StudioBaseUrl} from './types'\n\n/** @internal */\nexport function createEditUrl(options: CreateEditUrlOptions): `${StudioBaseUrl}${EditIntentUrl}` {\n const {\n baseUrl,\n workspace: _workspace = 'default',\n tool: _tool = 'default',\n id: _id,\n type,\n path,\n projectId,\n dataset,\n } = options\n\n if (!baseUrl) {\n throw new Error('baseUrl is required')\n }\n if (!path) {\n throw new Error('path is required')\n }\n if (!_id) {\n throw new Error('id is required')\n }\n if (baseUrl !== '/' && baseUrl.endsWith('/')) {\n throw new Error('baseUrl must not end with a slash')\n }\n\n const workspace = _workspace === 'default' ? undefined : _workspace\n const tool = _tool === 'default' ? undefined : _tool\n const id = getPublishedId(_id)\n const stringifiedPath = Array.isArray(path)\n ? studioPath.toString(jsonPathToStudioPath(path))\n : path\n\n // oxlint-disable-next-line no-warning-comments\n // @TODO Using searchParams as a temporary workaround until `@sanity/overlays` can decode state from the path reliably\n const searchParams = new URLSearchParams({\n baseUrl,\n id,\n type,\n path: stringifiedPath,\n })\n if (workspace) {\n searchParams.set('workspace', workspace)\n }\n if (tool) {\n searchParams.set('tool', tool)\n }\n if (projectId) {\n searchParams.set('projectId', projectId)\n }\n if (dataset) {\n searchParams.set('dataset', dataset)\n }\n if (isPublishedId(_id)) {\n searchParams.set('perspective', 'published')\n } else if (isVersionId(_id)) {\n const versionId = getVersionFromId(_id)!\n searchParams.set('perspective', versionId)\n }\n\n const segments = [baseUrl === '/' ? '' : baseUrl]\n if (workspace) {\n segments.push(workspace)\n }\n const routerParams = [\n 'mode=presentation',\n `id=${id}`,\n `type=${type}`,\n `path=${encodeURIComponent(stringifiedPath)}`,\n ]\n if (tool) {\n routerParams.push(`tool=${tool}`)\n }\n segments.push('intent', 'edit', `${routerParams.join(';')}?${searchParams}`)\n return segments.join('/') as unknown as `${StudioBaseUrl}${EditIntentUrl}`\n}\n","import {jsonPath, jsonPathArray, jsonPathToMappingPath} from './jsonPath'\nimport type {ContentSourceMap, ContentSourceMapMapping, ContentSourceMapParsedPath} from './types'\n\n/**\n * @internal\n */\nexport function resolveMapping(\n resultPath: ContentSourceMapParsedPath,\n csm?: ContentSourceMap,\n):\n | {\n mapping: ContentSourceMapMapping\n matchedPath: string\n pathSuffix: string\n }\n | undefined {\n if (!csm?.mappings) {\n return undefined\n }\n const resultMappingPath = jsonPath(jsonPathToMappingPath(resultPath))\n\n if (csm.mappings[resultMappingPath] !== undefined) {\n return {\n mapping: csm.mappings[resultMappingPath],\n matchedPath: resultMappingPath,\n pathSuffix: '',\n }\n }\n\n const resultMappingPathArray = jsonPathArray(jsonPathToMappingPath(resultPath))\n for (let i = resultMappingPathArray.length - 1; i >= 0; i--) {\n const key = `$${resultMappingPathArray.slice(0, i).join('')}`\n const mappingFound = csm.mappings[key]\n if (mappingFound) {\n const pathSuffix = resultMappingPath.substring(key.length)\n return {mapping: mappingFound, matchedPath: key, pathSuffix}\n }\n }\n\n return undefined\n}\n","import {parseJsonPath} from './jsonPath'\nimport {resolveMapping} from './resolveMapping'\nimport type {\n CreateEditUrlOptions,\n ResolveEditInfoOptions,\n StudioBaseRoute,\n StudioBaseUrl,\n StudioUrl,\n} from './types'\n\n/** @internal */\nexport function resolveEditInfo(options: ResolveEditInfoOptions): CreateEditUrlOptions | undefined {\n const {resultSourceMap: csm, resultPath} = options\n const {mapping, pathSuffix} = resolveMapping(resultPath, csm) || {}\n\n if (!mapping) {\n // console.warn('no mapping for path', { path: resultPath, sourceMap: csm })\n return undefined\n }\n\n if (mapping.source.type === 'literal') {\n return undefined\n }\n\n if (mapping.source.type === 'unknown') {\n return undefined\n }\n\n const sourceDoc = csm.documents[mapping.source.document]\n const sourcePath = csm.paths[mapping.source.path]\n\n if (sourceDoc && sourcePath) {\n const {baseUrl, workspace, tool} = resolveStudioBaseRoute(\n typeof options.studioUrl === 'function' ? options.studioUrl(sourceDoc) : options.studioUrl,\n )\n if (!baseUrl) return undefined\n const {_id, _type, _projectId, _dataset} = sourceDoc\n return {\n baseUrl,\n workspace,\n tool,\n id: _id,\n type: _type,\n path: parseJsonPath(sourcePath + pathSuffix),\n projectId: _projectId,\n dataset: _dataset,\n } satisfies CreateEditUrlOptions\n }\n\n return undefined\n}\n\n/** @internal */\nexport function resolveStudioBaseRoute(studioUrl: StudioUrl): StudioBaseRoute {\n let baseUrl: StudioBaseUrl = typeof studioUrl === 'string' ? studioUrl : studioUrl.baseUrl\n if (baseUrl !== '/') {\n baseUrl = baseUrl.replace(/\\/$/, '')\n }\n if (typeof studioUrl === 'string') {\n return {baseUrl}\n }\n return {...studioUrl, baseUrl}\n}\n","/** @internal */\nexport function isArray(value: unknown): value is Array<unknown> {\n return value !== null && Array.isArray(value)\n}\n","import {isRecord} from '../util/isRecord'\nimport {isArray} from './isArray'\nimport type {ContentSourceMapParsedPath, WalkMapFn} from './types'\n\n/**\n * generic way to walk a nested object or array and apply a mapping function to each value\n * @internal\n */\nexport function walkMap(\n value: unknown,\n mappingFn: WalkMapFn,\n path: ContentSourceMapParsedPath = [],\n): unknown {\n if (isArray(value)) {\n return value.map((v, idx) => {\n if (isRecord(v)) {\n const _key = v['_key']\n if (typeof _key === 'string') {\n return walkMap(v, mappingFn, path.concat({_key, _index: idx}))\n }\n }\n\n return walkMap(v, mappingFn, path.concat(idx))\n })\n }\n\n if (isRecord(value)) {\n // Handle Portable Text in a faster way\n if (value._type === 'block' || value._type === 'span') {\n const result = {...value}\n if (value._type === 'block') {\n result.children = walkMap(value.children, mappingFn, path.concat('children'))\n } else if (value._type === 'span') {\n result.text = walkMap(value.text, mappingFn, path.concat('text'))\n }\n return result\n }\n\n return Object.fromEntries(\n Object.entries(value).map(([k, v]) => [k, walkMap(v, mappingFn, path.concat(k))]),\n )\n }\n\n return mappingFn(value, path)\n}\n","import type {ContentSourceMap} from '@sanity/client/csm'\n\nimport {parseJsonPath} from '../csm/jsonPath'\nimport {resolveMapping} from '../csm/resolveMapping'\nimport {walkMap} from '../csm/walkMap'\nimport type {Encoder} from './types'\n\n/**\n * @internal\n */\nexport function encodeIntoResult<Result>(\n result: Result,\n csm: ContentSourceMap,\n encoder: Encoder,\n): Result {\n return walkMap(result, (value, path) => {\n // Only map strings, we could extend this in the future to support other types like integers...\n if (typeof value !== 'string') {\n return value\n }\n\n const resolveMappingResult = resolveMapping(path, csm)\n if (!resolveMappingResult) {\n return value\n }\n\n const {mapping, matchedPath} = resolveMappingResult\n if (mapping.type !== 'value') {\n return value\n }\n\n if (mapping.source.type !== 'documentValue') {\n return value\n }\n\n const sourceDocument = csm.documents[mapping.source.document!]\n const sourcePath = csm.paths[mapping.source.path]\n\n const matchPathSegments = parseJsonPath(matchedPath)\n const sourcePathSegments = parseJsonPath(sourcePath)\n const fullSourceSegments = sourcePathSegments.concat(path.slice(matchPathSegments.length))\n\n return encoder({\n sourcePath: fullSourceSegments,\n sourceDocument,\n resultPath: path,\n value,\n })\n }) as Result\n}\n","import type {ContentSourceMapParsedPath, FilterDefault} from './types'\n\nexport const filterDefault: FilterDefault = ({sourcePath, resultPath, value}) => {\n // Skips encoding on URL or Date strings, similar to the `skip: 'auto'` parameter in vercelStegaCombine()\n if (isValidDate(value) || isValidURL(value)) {\n return false\n }\n\n const endPath = sourcePath.at(-1)\n // Never encode slugs\n if (sourcePath.at(-2) === 'slug' && endPath === 'current') {\n return false\n }\n\n // Skip underscored keys, and strings that end with `Id`, needs better heuristics but it works for now\n if (typeof endPath === 'string' && (endPath.startsWith('_') || endPath.endsWith('Id'))) {\n return false\n }\n\n // Don't encode into anything that is suggested it'll render for SEO in meta tags\n if (\n sourcePath.some(\n (path) => path === 'meta' || path === 'metadata' || path === 'openGraph' || path === 'seo',\n )\n ) {\n return false\n }\n\n // If the sourcePath or resultPath contains something that sounds like a type, like iconType, we skip encoding, as it's most\n // of the time used for logic that breaks if it contains stega characters\n if (hasTypeLike(sourcePath) || hasTypeLike(resultPath)) {\n return false\n }\n\n // Finally, we ignore a bunch of paths that are typically used for page building\n if (typeof endPath === 'string' && denylist.has(endPath)) {\n return false\n }\n\n return true\n}\n\nconst denylist = new Set([\n 'color',\n 'colour',\n 'currency',\n 'email',\n 'format',\n 'gid',\n 'hex',\n 'href',\n 'hsl',\n 'hsla',\n 'icon',\n 'id',\n 'index',\n 'key',\n 'language',\n 'layout',\n 'link',\n 'linkAction',\n 'locale',\n 'lqip',\n 'page',\n 'path',\n 'ref',\n 'rgb',\n 'rgba',\n 'route',\n 'secret',\n 'slug',\n 'status',\n 'tag',\n 'template',\n 'theme',\n 'type',\n 'textTheme',\n 'unit',\n 'url',\n 'username',\n 'variant',\n 'website',\n])\n\nfunction isValidDate(dateString: string) {\n return /^\\d{4}-\\d{2}-\\d{2}/.test(dateString) ? Boolean(Date.parse(dateString)) : false\n}\n\nconst allowedProtocols = new Set([\n 'app:',\n 'data:',\n 'discord:',\n 'file:',\n 'ftp:',\n 'ftps:',\n 'geo:',\n 'http:',\n 'https:',\n 'imap:',\n 'javascript:',\n 'magnet:',\n 'mailto:',\n 'maps:',\n 'ms-excel:',\n 'ms-powerpoint:',\n 'ms-word:',\n 'slack:',\n 'sms:',\n 'spotify:',\n 'steam:',\n 'teams:',\n 'tel:',\n 'vscode:',\n 'zoom:',\n])\n\nfunction isValidURL(url: string) {\n try {\n const {protocol} = new URL(url, url.startsWith('/') ? 'https://acme.com' : undefined)\n return allowedProtocols.has(protocol) || protocol.startsWith('web+')\n } catch {\n return false\n }\n}\n\nfunction hasTypeLike(path: ContentSourceMapParsedPath): boolean {\n return path.some((segment) => typeof segment === 'string' && segment.match(/type/i) !== null)\n}\n","import {vercelStegaCombine} from '@vercel/stega'\n\nimport {createEditUrl} from '../csm/createEditUrl'\nimport {jsonPathToStudioPath} from '../csm/jsonPath'\nimport {resolveStudioBaseRoute} from '../csm/resolveEditInfo'\nimport {reKeySegment, toString as studioPathToString} from '../csm/studioPath'\nimport {encodeIntoResult} from './encodeIntoResult'\n// Re-export so `encodeIntoResult` is a genuine export of this module - which\n// forms its own output chunk via the dynamic import in `dataMethods`. Without\n// this, rolldown absorbs `encodeIntoResult` into the chunk but omits it from\n// the chunk's exports, breaking `@sanity/client/stega`'s re-export of it.\nexport {encodeIntoResult} from './encodeIntoResult'\nimport {filterDefault} from './filterDefault'\nimport {\n type ContentSourceMap,\n type ContentSourceMapParsedPath,\n type InitializedStegaConfig,\n} from './types'\n\nconst TRUNCATE_LENGTH = 20\n\n/**\n * Uses `@vercel/stega` to embed edit info JSON into strings in your query result.\n * The JSON payloads are added using invisible characters so they don't show up visually.\n * The edit info is generated from the Content Source Map (CSM) that is returned from Sanity for the query.\n * @public\n */\nexport function stegaEncodeSourceMap<Result = unknown>(\n result: Result,\n resultSourceMap: ContentSourceMap | undefined,\n config: InitializedStegaConfig,\n): Result {\n const {filter, logger, enabled} = config\n if (!enabled) {\n const msg = \"config.enabled must be true, don't call this function otherwise\"\n logger?.error?.(`[@sanity/client]: ${msg}`, {result, resultSourceMap, config})\n throw new TypeError(msg)\n }\n\n if (!resultSourceMap) {\n logger?.error?.('[@sanity/client]: Missing Content Source Map from response body', {\n result,\n resultSourceMap,\n config,\n })\n return result\n }\n\n if (!config.studioUrl) {\n const msg = 'config.studioUrl must be defined'\n logger?.error?.(`[@sanity/client]: ${msg}`, {result, resultSourceMap, config})\n throw new TypeError(msg)\n }\n\n const report: Record<'encoded' | 'skipped', {path: string; length: number; value: string}[]> = {\n encoded: [],\n skipped: [],\n }\n\n const resultWithStega = encodeIntoResult(\n result,\n resultSourceMap,\n ({sourcePath, sourceDocument, resultPath, value}) => {\n // Allow userland to control when to opt-out of encoding\n if (\n (typeof filter === 'function'\n ? filter({sourcePath, resultPath, filterDefault, sourceDocument, value})\n : filterDefault({sourcePath, resultPath, filterDefault, sourceDocument, value})) === false\n ) {\n if (logger) {\n report.skipped.push({\n path: prettyPathForLogging(sourcePath),\n value: `${value.slice(0, TRUNCATE_LENGTH)}${\n value.length > TRUNCATE_LENGTH ? '...' : ''\n }`,\n length: value.length,\n })\n }\n return value\n }\n\n if (logger) {\n report.encoded.push({\n path: prettyPathForLogging(sourcePath),\n value: `${value.slice(0, TRUNCATE_LENGTH)}${value.length > TRUNCATE_LENGTH ? '...' : ''}`,\n length: value.length,\n })\n }\n\n const {baseUrl, workspace, tool} = resolveStudioBaseRoute(\n typeof config.studioUrl === 'function'\n ? config.studioUrl(sourceDocument)\n : config.studioUrl!,\n )\n if (!baseUrl) return value\n const {_id: id, _type: type, _projectId: projectId, _dataset: dataset} = sourceDocument\n\n return vercelStegaCombine(\n value,\n {\n origin: 'sanity.io',\n href: createEditUrl({\n baseUrl,\n workspace,\n tool,\n id,\n type,\n path: sourcePath,\n ...(!config.omitCrossDatasetReferenceData && {dataset, projectId}),\n }),\n },\n // We use custom logic to determine if we should skip encoding\n false,\n )\n },\n )\n\n if (logger) {\n const isSkipping = report.skipped.length\n const isEncoding = report.encoded.length\n if (isSkipping || isEncoding) {\n ;(logger?.groupCollapsed || logger.log)?.('[@sanity/client]: Encoding source map into result')\n logger.log?.(\n `[@sanity/client]: Paths encoded: ${report.encoded.length}, skipped: ${report.skipped.length}`,\n )\n }\n if (report.encoded.length > 0) {\n logger?.log?.(`[@sanity/client]: Table of encoded paths`)\n ;(logger?.table || logger.log)?.(report.encoded)\n }\n if (report.skipped.length > 0) {\n const skipped = new Set<string>()\n for (const {path} of report.skipped) {\n skipped.add(path.replace(reKeySegment, '0').replace(/\\[\\d+\\]/g, '[]'))\n }\n logger?.log?.(`[@sanity/client]: List of skipped paths`, [...skipped.values()])\n }\n\n if (isSkipping || isEncoding) {\n logger?.groupEnd?.()\n }\n }\n\n return resultWithStega\n}\n\nfunction prettyPathForLogging(path: ContentSourceMapParsedPath): string {\n return studioPathToString(jsonPathToStudioPath(path))\n}\n"],"mappings":"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"}
|