@weatherboard/cms 0.4.0 → 0.6.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 +96 -1
- package/dist/contracts/query.d.cts +3 -0
- package/dist/contracts/query.d.mts +3 -0
- package/dist/contracts/query.d.ts +3 -0
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.cts +3 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +5 -1
- package/dist/index.mjs.map +4 -4
- package/dist/next.cjs +5 -1
- package/dist/next.cjs.map +4 -4
- package/dist/next.d.cts +3 -0
- package/dist/next.d.mts +3 -0
- package/dist/next.d.ts +3 -0
- package/dist/next.mjs +5 -1
- package/dist/next.mjs.map +4 -4
- package/dist/portable/menu-options.d.cts +8 -0
- package/dist/portable/menu-options.d.mts +8 -0
- package/dist/portable/menu-options.d.ts +8 -0
- package/dist/portable/menu.d.cts +69 -0
- package/dist/portable/menu.d.mts +69 -0
- package/dist/portable/menu.d.ts +69 -0
- package/dist/portable/sections.d.cts +12 -2
- package/dist/portable/sections.d.mts +12 -2
- package/dist/portable/sections.d.ts +12 -2
- package/dist/portable/site-content.d.cts +2 -2
- package/dist/portable/site-content.d.mts +2 -2
- package/dist/portable/site-content.d.ts +2 -2
- package/dist/sanity.cjs +1 -1
- package/dist/sanity.cjs.map +2 -2
- package/dist/sanity.mjs +1 -1
- package/dist/sanity.mjs.map +2 -2
- package/dist/server.cjs +5 -1
- package/dist/server.cjs.map +4 -4
- package/dist/server.d.cts +3 -0
- package/dist/server.d.mts +3 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.mjs +5 -1
- package/dist/server.mjs.map +4 -4
- package/dist/site-content.cjs +7 -3
- package/dist/site-content.cjs.map +4 -4
- package/dist/site-content.mjs +7 -3
- package/dist/site-content.mjs.map +4 -4
- package/package.json +1 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { MENU_LAYOUTS, MENU_DECORATIONS } from "./menu-options.js";
|
|
2
|
+
export { MENU_LAYOUTS, MENU_DECORATIONS, MENU_LAYOUT_DEFAULTS } from "./menu-options.js";
|
|
3
|
+
export type MenuLayout = (typeof MENU_LAYOUTS)[number];
|
|
4
|
+
export type MenuDecoration = (typeof MENU_DECORATIONS)[number];
|
|
5
|
+
/** CMS-owned saved shapes. `_key` remains the mapper's stable array identity. */
|
|
6
|
+
export type MenuMoney = {
|
|
7
|
+
readonly minor: number;
|
|
8
|
+
readonly currency: string;
|
|
9
|
+
};
|
|
10
|
+
export type MenuPrice = {
|
|
11
|
+
readonly _key: string;
|
|
12
|
+
readonly amount: MenuMoney;
|
|
13
|
+
readonly label?: string;
|
|
14
|
+
};
|
|
15
|
+
export type MenuExtra = {
|
|
16
|
+
readonly _key: string;
|
|
17
|
+
readonly name: string;
|
|
18
|
+
readonly amount: MenuMoney;
|
|
19
|
+
};
|
|
20
|
+
export type MenuItem = {
|
|
21
|
+
readonly _key: string;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly description?: string;
|
|
24
|
+
readonly prices: readonly MenuPrice[];
|
|
25
|
+
readonly priceNote?: string;
|
|
26
|
+
readonly extras: readonly MenuExtra[];
|
|
27
|
+
readonly dietary: readonly string[];
|
|
28
|
+
readonly allergenNote?: string;
|
|
29
|
+
readonly availability: "available" | "sold-out" | "hidden";
|
|
30
|
+
};
|
|
31
|
+
export type MenuSection = {
|
|
32
|
+
readonly _key: string;
|
|
33
|
+
readonly title: string;
|
|
34
|
+
readonly service?: string;
|
|
35
|
+
readonly items: readonly MenuItem[];
|
|
36
|
+
};
|
|
37
|
+
export type MenuVariant = {
|
|
38
|
+
readonly _key: string;
|
|
39
|
+
readonly label: string;
|
|
40
|
+
readonly note?: string;
|
|
41
|
+
readonly sections: readonly MenuSection[];
|
|
42
|
+
};
|
|
43
|
+
export type MenuDocument = {
|
|
44
|
+
/** The schema discriminator is required by the consuming site's mapper. */
|
|
45
|
+
readonly _type: "menu";
|
|
46
|
+
readonly _id: string;
|
|
47
|
+
readonly _rev: string;
|
|
48
|
+
/** The real published update date, preserved verbatim for stale displays. */
|
|
49
|
+
readonly _updatedAt: string;
|
|
50
|
+
readonly title: string;
|
|
51
|
+
readonly locationKeys: readonly string[];
|
|
52
|
+
readonly variants: readonly MenuVariant[];
|
|
53
|
+
readonly note?: string;
|
|
54
|
+
/** Approval is opaque to this reader. The site validates it with its contract. */
|
|
55
|
+
readonly signOff?: unknown;
|
|
56
|
+
};
|
|
57
|
+
export type MenuSectionInput = {
|
|
58
|
+
readonly kind: "menu";
|
|
59
|
+
readonly layout: MenuLayout;
|
|
60
|
+
readonly decoration: MenuDecoration;
|
|
61
|
+
readonly menu: MenuDocument;
|
|
62
|
+
};
|
|
63
|
+
/** Uses the same scoped type/id tags as every other CMS query. */
|
|
64
|
+
export declare function menuTags(scope: string, id?: string): readonly string[];
|
|
65
|
+
/** Validate saved field shapes without inferring approval or changing copy/order. */
|
|
66
|
+
export declare function parseMenuDocument(document: unknown, where?: string): MenuDocument;
|
|
67
|
+
/** Page references use the same single snapshot before checking their identity. */
|
|
68
|
+
export declare function parseReferencedMenuDocument(document: unknown, where: string): MenuDocument | null;
|
|
69
|
+
export declare function validMenuFallback(value: unknown): value is MenuDocument | null;
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
* whose every photo was dropped, a contact
|
|
34
34
|
* section switched off and empty) is skipped
|
|
35
35
|
*/
|
|
36
|
+
import type { MenuSectionInput } from "./menu.cjs";
|
|
36
37
|
import type { ActionInput, CompositionBlockInput, CopyInput } from "./site-content.cjs";
|
|
37
38
|
/** `Split`: text with media. */
|
|
38
39
|
export declare const SPLIT_LAYOUTS: readonly ["media-end", "media-start", "media-below"];
|
|
@@ -59,6 +60,7 @@ export declare const READER_SECTION_KINDS: {
|
|
|
59
60
|
readonly faqBlock: "faq";
|
|
60
61
|
readonly galleryBlock: "gallery";
|
|
61
62
|
readonly contactBlock: "contact";
|
|
63
|
+
readonly menuBlock: "menu";
|
|
62
64
|
};
|
|
63
65
|
/** A gallery is a `StaggerRow`, which holds two to four items. */
|
|
64
66
|
export declare const READER_GALLERY_PHOTO_MIN = 2;
|
|
@@ -69,11 +71,19 @@ export declare const SECTION_WARNINGS: {
|
|
|
69
71
|
readonly imageMissingAlt: "section.image.missing-alt";
|
|
70
72
|
readonly imageMissingAsset: "section.image.missing-asset";
|
|
71
73
|
readonly emptySkipped: "section.empty.skipped";
|
|
74
|
+
readonly menuUnavailable: "section.menu.unavailable";
|
|
72
75
|
};
|
|
73
76
|
export type SectionWarningCode = (typeof SECTION_WARNINGS)[keyof typeof SECTION_WARNINGS];
|
|
74
77
|
/** A named warning and the path in the stored document it is about. Never copy. */
|
|
75
78
|
export type SectionWarning = {
|
|
76
|
-
readonly code:
|
|
79
|
+
readonly code: typeof SECTION_WARNINGS.unknownType;
|
|
80
|
+
readonly where: string;
|
|
81
|
+
readonly type: string;
|
|
82
|
+
} | {
|
|
83
|
+
readonly code: typeof SECTION_WARNINGS.menuUnavailable;
|
|
84
|
+
readonly where: string;
|
|
85
|
+
} | {
|
|
86
|
+
readonly code: Exclude<SectionWarningCode, typeof SECTION_WARNINGS.unknownType | typeof SECTION_WARNINGS.menuUnavailable>;
|
|
77
87
|
readonly where: string;
|
|
78
88
|
};
|
|
79
89
|
/** A Sanity image as a site needs it. `asset` is the image asset's id; `alt` is never empty. */
|
|
@@ -129,7 +139,7 @@ export type ContactSectionInput = {
|
|
|
129
139
|
readonly action: ActionInput | null;
|
|
130
140
|
readonly image: SectionImageInput | null;
|
|
131
141
|
};
|
|
132
|
-
export type NewSectionInput = TextMediaSectionInput | FaqSectionInput | GallerySectionInput | ContactSectionInput;
|
|
142
|
+
export type NewSectionInput = TextMediaSectionInput | FaqSectionInput | GallerySectionInput | ContactSectionInput | MenuSectionInput;
|
|
133
143
|
/** One entry of `PageContent.sections`: a home section kind or one of the new kinds. */
|
|
134
144
|
export type PageSectionInput = Exclude<CompositionBlockInput, {
|
|
135
145
|
readonly kind: "campaign";
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
* whose every photo was dropped, a contact
|
|
34
34
|
* section switched off and empty) is skipped
|
|
35
35
|
*/
|
|
36
|
+
import type { MenuSectionInput } from "./menu.mjs";
|
|
36
37
|
import type { ActionInput, CompositionBlockInput, CopyInput } from "./site-content.mjs";
|
|
37
38
|
/** `Split`: text with media. */
|
|
38
39
|
export declare const SPLIT_LAYOUTS: readonly ["media-end", "media-start", "media-below"];
|
|
@@ -59,6 +60,7 @@ export declare const READER_SECTION_KINDS: {
|
|
|
59
60
|
readonly faqBlock: "faq";
|
|
60
61
|
readonly galleryBlock: "gallery";
|
|
61
62
|
readonly contactBlock: "contact";
|
|
63
|
+
readonly menuBlock: "menu";
|
|
62
64
|
};
|
|
63
65
|
/** A gallery is a `StaggerRow`, which holds two to four items. */
|
|
64
66
|
export declare const READER_GALLERY_PHOTO_MIN = 2;
|
|
@@ -69,11 +71,19 @@ export declare const SECTION_WARNINGS: {
|
|
|
69
71
|
readonly imageMissingAlt: "section.image.missing-alt";
|
|
70
72
|
readonly imageMissingAsset: "section.image.missing-asset";
|
|
71
73
|
readonly emptySkipped: "section.empty.skipped";
|
|
74
|
+
readonly menuUnavailable: "section.menu.unavailable";
|
|
72
75
|
};
|
|
73
76
|
export type SectionWarningCode = (typeof SECTION_WARNINGS)[keyof typeof SECTION_WARNINGS];
|
|
74
77
|
/** A named warning and the path in the stored document it is about. Never copy. */
|
|
75
78
|
export type SectionWarning = {
|
|
76
|
-
readonly code:
|
|
79
|
+
readonly code: typeof SECTION_WARNINGS.unknownType;
|
|
80
|
+
readonly where: string;
|
|
81
|
+
readonly type: string;
|
|
82
|
+
} | {
|
|
83
|
+
readonly code: typeof SECTION_WARNINGS.menuUnavailable;
|
|
84
|
+
readonly where: string;
|
|
85
|
+
} | {
|
|
86
|
+
readonly code: Exclude<SectionWarningCode, typeof SECTION_WARNINGS.unknownType | typeof SECTION_WARNINGS.menuUnavailable>;
|
|
77
87
|
readonly where: string;
|
|
78
88
|
};
|
|
79
89
|
/** A Sanity image as a site needs it. `asset` is the image asset's id; `alt` is never empty. */
|
|
@@ -129,7 +139,7 @@ export type ContactSectionInput = {
|
|
|
129
139
|
readonly action: ActionInput | null;
|
|
130
140
|
readonly image: SectionImageInput | null;
|
|
131
141
|
};
|
|
132
|
-
export type NewSectionInput = TextMediaSectionInput | FaqSectionInput | GallerySectionInput | ContactSectionInput;
|
|
142
|
+
export type NewSectionInput = TextMediaSectionInput | FaqSectionInput | GallerySectionInput | ContactSectionInput | MenuSectionInput;
|
|
133
143
|
/** One entry of `PageContent.sections`: a home section kind or one of the new kinds. */
|
|
134
144
|
export type PageSectionInput = Exclude<CompositionBlockInput, {
|
|
135
145
|
readonly kind: "campaign";
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
* whose every photo was dropped, a contact
|
|
34
34
|
* section switched off and empty) is skipped
|
|
35
35
|
*/
|
|
36
|
+
import type { MenuSectionInput } from "./menu.js";
|
|
36
37
|
import type { ActionInput, CompositionBlockInput, CopyInput } from "./site-content.js";
|
|
37
38
|
/** `Split`: text with media. */
|
|
38
39
|
export declare const SPLIT_LAYOUTS: readonly ["media-end", "media-start", "media-below"];
|
|
@@ -59,6 +60,7 @@ export declare const READER_SECTION_KINDS: {
|
|
|
59
60
|
readonly faqBlock: "faq";
|
|
60
61
|
readonly galleryBlock: "gallery";
|
|
61
62
|
readonly contactBlock: "contact";
|
|
63
|
+
readonly menuBlock: "menu";
|
|
62
64
|
};
|
|
63
65
|
/** A gallery is a `StaggerRow`, which holds two to four items. */
|
|
64
66
|
export declare const READER_GALLERY_PHOTO_MIN = 2;
|
|
@@ -69,11 +71,19 @@ export declare const SECTION_WARNINGS: {
|
|
|
69
71
|
readonly imageMissingAlt: "section.image.missing-alt";
|
|
70
72
|
readonly imageMissingAsset: "section.image.missing-asset";
|
|
71
73
|
readonly emptySkipped: "section.empty.skipped";
|
|
74
|
+
readonly menuUnavailable: "section.menu.unavailable";
|
|
72
75
|
};
|
|
73
76
|
export type SectionWarningCode = (typeof SECTION_WARNINGS)[keyof typeof SECTION_WARNINGS];
|
|
74
77
|
/** A named warning and the path in the stored document it is about. Never copy. */
|
|
75
78
|
export type SectionWarning = {
|
|
76
|
-
readonly code:
|
|
79
|
+
readonly code: typeof SECTION_WARNINGS.unknownType;
|
|
80
|
+
readonly where: string;
|
|
81
|
+
readonly type: string;
|
|
82
|
+
} | {
|
|
83
|
+
readonly code: typeof SECTION_WARNINGS.menuUnavailable;
|
|
84
|
+
readonly where: string;
|
|
85
|
+
} | {
|
|
86
|
+
readonly code: Exclude<SectionWarningCode, typeof SECTION_WARNINGS.unknownType | typeof SECTION_WARNINGS.menuUnavailable>;
|
|
77
87
|
readonly where: string;
|
|
78
88
|
};
|
|
79
89
|
/** A Sanity image as a site needs it. `asset` is the image asset's id; `alt` is never empty. */
|
|
@@ -129,7 +139,7 @@ export type ContactSectionInput = {
|
|
|
129
139
|
readonly action: ActionInput | null;
|
|
130
140
|
readonly image: SectionImageInput | null;
|
|
131
141
|
};
|
|
132
|
-
export type NewSectionInput = TextMediaSectionInput | FaqSectionInput | GallerySectionInput | ContactSectionInput;
|
|
142
|
+
export type NewSectionInput = TextMediaSectionInput | FaqSectionInput | GallerySectionInput | ContactSectionInput | MenuSectionInput;
|
|
133
143
|
/** One entry of `PageContent.sections`: a home section kind or one of the new kinds. */
|
|
134
144
|
export type PageSectionInput = Exclude<CompositionBlockInput, {
|
|
135
145
|
readonly kind: "campaign";
|
|
@@ -208,8 +208,8 @@ export declare function parseContentPage(document: unknown): PageContent;
|
|
|
208
208
|
export declare function parseSiteSettings(document: unknown): SiteSettingsContent;
|
|
209
209
|
/** By fixed id: a second home page at a random id is never read. */
|
|
210
210
|
export declare const HOME_PAGE_DOCUMENT_QUERY = "*[_id == $id][0]";
|
|
211
|
-
export declare const CONTENT_PAGES_QUERY = "*[_type == \"page\" && defined(slug.current)]|order(slug.current asc)";
|
|
212
|
-
export declare const CONTENT_PAGE_BY_SLUG_QUERY = "*[_type == \"page\" && slug.current == $slug][0]";
|
|
211
|
+
export declare const CONTENT_PAGES_QUERY = "*[_type == \"page\" && defined(slug.current)]|order(slug.current asc){..., \"sections\": coalesce(sections[]{..., _type == \"menuBlock\" => {menu->{_type, _id, _rev, _updatedAt, title, locationKeys, note, signOff,\n variants[]{_key, label, note, sections[]{_key, title, service, items[]{\n _key, name, description, priceNote, dietary, allergenNote, availability,\n prices[]{_key, label, amount{minor, currency}}, extras[]{_key, name, amount{minor, currency}}\n }}}}}}, sections)}";
|
|
212
|
+
export declare const CONTENT_PAGE_BY_SLUG_QUERY = "*[_type == \"page\" && slug.current == $slug][0]{..., \"sections\": coalesce(sections[]{..., _type == \"menuBlock\" => {menu->{_type, _id, _rev, _updatedAt, title, locationKeys, note, signOff,\n variants[]{_key, label, note, sections[]{_key, title, service, items[]{\n _key, name, description, priceNote, dietary, allergenNote, availability,\n prices[]{_key, label, amount{minor, currency}}, extras[]{_key, name, amount{minor, currency}}\n }}}}}}, sections)}";
|
|
213
213
|
export interface SiteContentReader {
|
|
214
214
|
/** `null` when no home page document exists yet. */
|
|
215
215
|
home: (options: {
|
|
@@ -208,8 +208,8 @@ export declare function parseContentPage(document: unknown): PageContent;
|
|
|
208
208
|
export declare function parseSiteSettings(document: unknown): SiteSettingsContent;
|
|
209
209
|
/** By fixed id: a second home page at a random id is never read. */
|
|
210
210
|
export declare const HOME_PAGE_DOCUMENT_QUERY = "*[_id == $id][0]";
|
|
211
|
-
export declare const CONTENT_PAGES_QUERY = "*[_type == \"page\" && defined(slug.current)]|order(slug.current asc)";
|
|
212
|
-
export declare const CONTENT_PAGE_BY_SLUG_QUERY = "*[_type == \"page\" && slug.current == $slug][0]";
|
|
211
|
+
export declare const CONTENT_PAGES_QUERY = "*[_type == \"page\" && defined(slug.current)]|order(slug.current asc){..., \"sections\": coalesce(sections[]{..., _type == \"menuBlock\" => {menu->{_type, _id, _rev, _updatedAt, title, locationKeys, note, signOff,\n variants[]{_key, label, note, sections[]{_key, title, service, items[]{\n _key, name, description, priceNote, dietary, allergenNote, availability,\n prices[]{_key, label, amount{minor, currency}}, extras[]{_key, name, amount{minor, currency}}\n }}}}}}, sections)}";
|
|
212
|
+
export declare const CONTENT_PAGE_BY_SLUG_QUERY = "*[_type == \"page\" && slug.current == $slug][0]{..., \"sections\": coalesce(sections[]{..., _type == \"menuBlock\" => {menu->{_type, _id, _rev, _updatedAt, title, locationKeys, note, signOff,\n variants[]{_key, label, note, sections[]{_key, title, service, items[]{\n _key, name, description, priceNote, dietary, allergenNote, availability,\n prices[]{_key, label, amount{minor, currency}}, extras[]{_key, name, amount{minor, currency}}\n }}}}}}, sections)}";
|
|
213
213
|
export interface SiteContentReader {
|
|
214
214
|
/** `null` when no home page document exists yet. */
|
|
215
215
|
home: (options: {
|
|
@@ -208,8 +208,8 @@ export declare function parseContentPage(document: unknown): PageContent;
|
|
|
208
208
|
export declare function parseSiteSettings(document: unknown): SiteSettingsContent;
|
|
209
209
|
/** By fixed id: a second home page at a random id is never read. */
|
|
210
210
|
export declare const HOME_PAGE_DOCUMENT_QUERY = "*[_id == $id][0]";
|
|
211
|
-
export declare const CONTENT_PAGES_QUERY = "*[_type == \"page\" && defined(slug.current)]|order(slug.current asc)";
|
|
212
|
-
export declare const CONTENT_PAGE_BY_SLUG_QUERY = "*[_type == \"page\" && slug.current == $slug][0]";
|
|
211
|
+
export declare const CONTENT_PAGES_QUERY = "*[_type == \"page\" && defined(slug.current)]|order(slug.current asc){..., \"sections\": coalesce(sections[]{..., _type == \"menuBlock\" => {menu->{_type, _id, _rev, _updatedAt, title, locationKeys, note, signOff,\n variants[]{_key, label, note, sections[]{_key, title, service, items[]{\n _key, name, description, priceNote, dietary, allergenNote, availability,\n prices[]{_key, label, amount{minor, currency}}, extras[]{_key, name, amount{minor, currency}}\n }}}}}}, sections)}";
|
|
212
|
+
export declare const CONTENT_PAGE_BY_SLUG_QUERY = "*[_type == \"page\" && slug.current == $slug][0]{..., \"sections\": coalesce(sections[]{..., _type == \"menuBlock\" => {menu->{_type, _id, _rev, _updatedAt, title, locationKeys, note, signOff,\n variants[]{_key, label, note, sections[]{_key, title, service, items[]{\n _key, name, description, priceNote, dietary, allergenNote, availability,\n prices[]{_key, label, amount{minor, currency}}, extras[]{_key, name, amount{minor, currency}}\n }}}}}}, sections)}";
|
|
213
213
|
export interface SiteContentReader {
|
|
214
214
|
/** `null` when no home page document exists yet. */
|
|
215
215
|
home: (options: {
|
package/dist/sanity.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var h=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var M=(e,t)=>{for(var n in t)h(e,n,{get:t[n],enumerable:!0})},R=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $(t))!z.call(e,o)&&o!==n&&h(e,o,{get:()=>t[o],enumerable:!(r=j(t,o))||r.enumerable});return e};var _=e=>R(h({},"__esModule",{value:!0}),e);var B={};M(B,{createSanityAdapter:()=>I,sanityBindingFromEnv:()=>O});module.exports=_(B);var U=require("server-only");var x=/^[A-Za-z][A-Za-z0-9_]{0,63}$/,P=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/,D=/^[a-z0-9]{6,12}\.[a-z][a-z0-9_-]{0,63}$/;function S(e){if(!e||!Array.isArray(e.types)||e.types.length===0)throw new TypeError("CMS dependencies require document types");let t=[...e.types];for(let r of t)if(typeof r!="string"||!x.test(r))throw new TypeError("Invalid CMS document type");if(e.ids!==void 0&&!Array.isArray(e.ids))throw new TypeError("Invalid CMS document IDs");let n=e.ids===void 0?void 0:[...e.ids];for(let r of n??[])if(typeof r!="string"||!P.test(r)||/^(drafts|versions)\./.test(r))throw new TypeError("Invalid CMS document ID");if(new Set(t).size+new Set(n).size>128)throw new TypeError("Too many CMS tags");return Object.freeze({types:Object.freeze(t),...n===void 0?{}:{ids:Object.freeze(n)}})}function b(e){if(!e||typeof e.name!="string"||!/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(e.name)||typeof e.query!="string"||e.query.trim()===""||typeof e.resolve!="function")throw new TypeError("Invalid CMS query configuration");let t=e.params;if(!t||typeof t!="object"||Object.getPrototypeOf(t)!==Object.prototype&&Object.getPrototypeOf(t)!==null)throw new TypeError("CMS params must be plain JSON scalars");let n={};for(let r of Reflect.ownKeys(t)){let o=Object.getOwnPropertyDescriptor(t,r);if(typeof r!="string"||!o||!Object.hasOwn(o,"value")||!o.enumerable)throw new TypeError("CMS params must be plain JSON scalars");let i=o.value;if(!(i===null||typeof i=="string"||typeof i=="boolean"||typeof i=="number"&&Number.isFinite(i)))throw new TypeError("CMS params must be plain JSON scalars");Object.defineProperty(n,r,{value:i,enumerable:!0})}return Object.freeze({name:e.name,query:e.query,params:Object.freeze(n),dependencies:S(e.dependencies),resolve:e.resolve})}function C(e,t){if(typeof e!="string"||e.length>77||!D.test(e))throw new TypeError("Invalid CMS scope");let n=S(t),r=[...[...new Set(n.types)].sort().map(o=>`cms:${e}:type:${o}`),...[...new Set(n.ids??[])].sort().map(o=>`cms:${e}:id:${o}`)];return Object.freeze(r)}var N=2*1024*1024;function v(e){if(!e||typeof e.projectId!="string"||!/^[a-z0-9]{6,12}$/.test(e.projectId)||typeof e.dataset!="string"||!/^[a-z][a-z0-9_-]{0,63}$/.test(e.dataset)||typeof e.apiVersion!="string"||!/^v?\d{4}-\d{2}-\d{2}$/.test(e.apiVersion))throw new TypeError("Invalid Sanity binding configuration");return Object.freeze({projectId:e.projectId,dataset:e.dataset,apiVersion:e.apiVersion.replace(/^v/,"")})}function I(e){let t=v(e?.binding),n=e.timeoutMs??1500,r=e.readToken;if(!Number.isSafeInteger(n)||n<=0||n>2147483647||e.fetchImpl!==void 0&&typeof e.fetchImpl!="function"||r!==void 0&&(typeof r!="string"||r.trim()===""||/[\r\n]/.test(r)))throw new TypeError("Invalid Sanity adapter configuration");let o=e.fetchImpl,i=`${t.projectId}.${t.dataset}`;return Object.freeze({scope:i,async read(A,c){let y;try{if(!c||!Number.isSafeInteger(c.revalidateSeconds)||c.revalidateSeconds<3600||!Array.isArray(c.tags))throw new TypeError;let s=[],p=[];for(let d of c.tags){if(typeof d!="string")throw new TypeError;if(d.startsWith(`cms:${i}:type:`))s.push(d.slice(`cms:${i}:type:`.length));else if(d.startsWith(`cms:${i}:id:`))p.push(d.slice(`cms:${i}:id:`.length));else throw new TypeError}let l=C(i,{types:s,ids:p});if(l.length!==c.tags.length||l.some((d,a)=>d!==c.tags[a]))throw new TypeError;y=b({...A,dependencies:{types:s,ids:p},resolve:d=>({data:d,fallbackFields:[]})})}catch{throw new TypeError("Invalid Sanity read configuration")}let f=new URL(`https://${t.projectId}.api.sanity.io/v${t.apiVersion}/data/query/${t.dataset}`);f.searchParams.set("query",y.query),f.searchParams.set("perspective","published");for(let s of Object.keys(y.params).sort())f.searchParams.set(`$${s}`,JSON.stringify(y.params[s]));let w=new AbortController,u,m=!1,g=()=>{w.abort(),u&&u.cancel().catch(()=>{})},T,E=new Promise(s=>{T=setTimeout(()=>{m=!0,g(),s({ok:!1,reason:"timeout"})},n)}),k=async()=>{try{let s=await(o??globalThis.fetch)(f.href,{method:"GET",redirect:"error",signal:w.signal,headers:r===void 0?{}:{Authorization:`Bearer ${r}`},next:{revalidate:c.revalidateSeconds,tags:[...c.tags]}});if(m)return s.body?.cancel().catch(()=>{}),{ok:!1,reason:"timeout"};if(!s.ok){s.body?.cancel().catch(()=>{});let a=s.status;return{ok:!1,reason:a===402?"plan-limit":a===401||a===403?"permission":a===429?"rate-limit":"upstream",status:a}}if(!s.body)return{ok:!1,reason:"malformed"};u=s.body.getReader();let p=0,l="",d=new TextDecoder("utf-8",{fatal:!0});for(;;){let a=await u.read();if(m)return{ok:!1,reason:"timeout"};if(a.done)break;if(p+=a.value.byteLength,p>N)return g(),{ok:!1,reason:"malformed"};try{l+=d.decode(a.value,{stream:!0})}catch{return g(),{ok:!1,reason:"malformed"}}}try{l+=d.decode();let a=JSON.parse(l);return!a||typeof a!="object"||Array.isArray(a)||!Object.hasOwn(a,"result")?{ok:!1,reason:"malformed"}:{ok:!0,value:a.result}}catch{return{ok:!1,reason:"malformed"}}}catch{return{ok:!1,reason:m?"timeout":"network"}}};try{return await Promise.race([k(),E])}finally{clearTimeout(T)}}})}function O(e){return v({projectId:e.SANITY_PROJECT_ID,dataset:e.SANITY_DATASET,apiVersion:e.SANITY_API_VERSION})}0&&(module.exports={createSanityAdapter,sanityBindingFromEnv});
|
|
2
2
|
//# sourceMappingURL=sanity.cjs.map
|
package/dist/sanity.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/sanity.ts", "../src/contracts/query.ts", "../src/adapters/sanity/adapter.ts"],
|
|
4
|
-
"sourcesContent": ["import \"server-only\";\nexport { createSanityAdapter, sanityBindingFromEnv } from \"./adapters/sanity/adapter.js\";\nexport type { SanityBinding, SanityAdapterOptions } from \"./adapters/sanity/adapter.js\";\n", "/** A-1822 S1 owns this implementation. S0 registers the public signatures. */\nexport type CmsParams = Readonly<Record<string, string | number | boolean | null>>;\nexport type CmsDependencies = {\n readonly types: readonly string[];\n readonly ids?: readonly string[];\n};\nexport type CmsResolution<T> = {\n readonly data: T;\n readonly fallbackFields: readonly string[];\n readonly warnings?: readonly (\"siteHero.layout.defaulted\" | \"siteHero.tagline.dropped\" | \"siteHero.taglines.defaulted\")[];\n};\nexport type CmsQuery<T> = {\n readonly name: string;\n readonly query: string;\n readonly params: CmsParams;\n readonly dependencies: CmsDependencies;\n readonly resolve: (raw: unknown, fallback: T) => CmsResolution<T>;\n};\n\nconst TYPE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;\nconst ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;\nconst SCOPE = /^[a-z0-9]{6,12}\\.[a-z][a-z0-9_-]{0,63}$/;\n\nfunction dependenciesCopy(dependencies: CmsDependencies): CmsDependencies {\n if (!dependencies || !Array.isArray(dependencies.types) || dependencies.types.length === 0) {\n throw new TypeError(\"CMS dependencies require document types\");\n }\n const types = [...dependencies.types];\n for (const type of types) {\n if (typeof type !== \"string\" || !TYPE.test(type)) throw new TypeError(\"Invalid CMS document type\");\n }\n if (dependencies.ids !== undefined && !Array.isArray(dependencies.ids)) throw new TypeError(\"Invalid CMS document IDs\");\n const ids = dependencies.ids === undefined ? undefined : [...dependencies.ids];\n for (const id of ids ?? []) {\n if (typeof id !== \"string\" || !ID.test(id) || /^(drafts|versions)\\./.test(id)) {\n throw new TypeError(\"Invalid CMS document ID\");\n }\n }\n if (new Set(types).size + new Set(ids).size > 128) throw new TypeError(\"Too many CMS tags\");\n return Object.freeze({ types: Object.freeze(types), ...(ids === undefined ? {} : { ids: Object.freeze(ids) }) });\n}\n\nexport function defineCmsQuery<T>(query: CmsQuery<T>): CmsQuery<T> {\n if (!query || typeof query.name !== \"string\" || !/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(query.name)\n || typeof query.query !== \"string\" || query.query.trim() === \"\" || typeof query.resolve !== \"function\") {\n throw new TypeError(\"Invalid CMS query configuration\");\n }\n const params = query.params;\n if (!params || typeof params !== \"object\" || (Object.getPrototypeOf(params) !== Object.prototype && Object.getPrototypeOf(params) !== null)) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const copied: Record<string, string | number | boolean | null> = {};\n for (const key of Reflect.ownKeys(params)) {\n const descriptor = Object.getOwnPropertyDescriptor(params, key);\n if (typeof key !== \"string\" || !descriptor || !Object.hasOwn(descriptor, \"value\") || !descriptor.enumerable) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const value: unknown = descriptor.value;\n if (!(value === null || typeof value === \"string\" || typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value)))) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n Object.defineProperty(copied, key, { value, enumerable: true });\n }\n return Object.freeze({ name: query.name, query: query.query, params: Object.freeze(copied), dependencies: dependenciesCopy(query.dependencies), resolve: query.resolve });\n}\n\nexport function cmsTags(scope: string, dependencies: CmsDependencies): readonly string[] {\n if (typeof scope !== \"string\" || scope.length > 77 || !SCOPE.test(scope)) throw new TypeError(\"Invalid CMS scope\");\n const copied = dependenciesCopy(dependencies);\n const tags = [\n ...[...new Set(copied.types)].sort().map((type) => `cms:${scope}:type:${type}`),\n ...[...new Set(copied.ids ?? [])].sort().map((id) => `cms:${scope}:id:${id}`),\n ];\n return Object.freeze(tags);\n}\n", "import type { CmsAdapter, CmsFetch } from \"../../runtime/reader.js\";\nimport { cmsTags, defineCmsQuery } from \"../../contracts/query.js\";\n\nexport type SanityBinding = {\n readonly projectId: string;\n readonly dataset: string;\n readonly apiVersion: string;\n};\nexport type SanityAdapterOptions = {\n readonly binding: SanityBinding;\n readonly readToken?: string;\n readonly fetchImpl?: CmsFetch;\n readonly timeoutMs?: number;\n};\n\nconst RESPONSE_LIMIT = 2 * 1024 * 1024;\n\nfunction bindingCopy(binding: SanityBinding): SanityBinding {\n if (!binding || typeof binding.projectId !== \"string\" || !/^[a-z0-9]{6,12}$/.test(binding.projectId)\n || typeof binding.dataset !== \"string\" || !/^[a-z][a-z0-9_-]{0,63}$/.test(binding.dataset)\n || typeof binding.apiVersion !== \"string\" || !/^v?\\d{4}-\\d{2}-\\d{2}$/.test(binding.apiVersion)) {\n throw new TypeError(\"Invalid Sanity binding configuration\");\n }\n return Object.freeze({ projectId: binding.projectId, dataset: binding.dataset, apiVersion: binding.apiVersion.replace(/^v/, \"\") });\n}\n\n/** Applies policy via fetch's Next metadata. Standard fetch has no persistent cache or HTML invalidation. */\nexport function createSanityAdapter(options: SanityAdapterOptions): CmsAdapter {\n const binding = bindingCopy(options?.binding);\n const timeoutMs = options.timeoutMs ?? 1500;\n const token = options.readToken;\n if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647\n || (options.fetchImpl !== undefined && typeof options.fetchImpl !== \"function\")\n || (token !== undefined && (typeof token !== \"string\" || token.trim() === \"\" || /[\\r\\n]/.test(token)))) {\n throw new TypeError(\"Invalid Sanity adapter configuration\");\n }\n const fetchImpl = options.fetchImpl;\n const scope = `${binding.projectId}.${binding.dataset}`;\n return Object.freeze({\n scope,\n async read(query, policy) {\n // Direct structural callers receive the same configuration refusals.\n let validated;\n try {\n if (!policy || !Number.isSafeInteger(policy.revalidateSeconds) || policy.revalidateSeconds < 3600 || !Array.isArray(policy.tags)) throw new TypeError();\n const types: string[] = [];\n const ids: string[] = [];\n for (const tag of policy.tags) {\n if (typeof tag !== \"string\") throw new TypeError();\n if (tag.startsWith(`cms:${scope}:type:`)) types.push(tag.slice(`cms:${scope}:type:`.length));\n else if (tag.startsWith(`cms:${scope}:id:`)) ids.push(tag.slice(`cms:${scope}:id:`.length));\n else throw new TypeError();\n }\n const expected = cmsTags(scope, { types, ids });\n if (expected.length !== policy.tags.length || expected.some((tag, i) => tag !== policy.tags[i])) throw new TypeError();\n validated = defineCmsQuery({ ...query, dependencies: { types, ids }, resolve: (raw: unknown) => ({ data: raw, fallbackFields: [] }) });\n } catch { throw new TypeError(\"Invalid Sanity read configuration\"); }\n const url = new URL(`https://${binding.projectId}.api.sanity.io/v${binding.apiVersion}/data/query/${binding.dataset}`);\n url.searchParams.set(\"query\", validated.query);\n url.searchParams.set(\"perspective\", \"published\");\n for (const key of Object.keys(validated.params).sort()) url.searchParams.set(`$${key}`, JSON.stringify(validated.params[key]));\n const controller = new AbortController();\n let bodyReader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n let expired = false;\n const cancel = (): void => {\n controller.abort();\n if (bodyReader) void bodyReader.cancel().catch(() => {});\n };\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<Awaited<ReturnType<CmsAdapter[\"read\"]>>>((resolve) => {\n timer = setTimeout(() => {\n expired = true;\n cancel();\n resolve({ ok: false, reason: \"timeout\" });\n }, timeoutMs);\n });\n const work = async (): Promise<Awaited<ReturnType<CmsAdapter[\"read\"]>>> => {\n try {\n // Look up global fetch at read time so Next's patched fetch is retained.\n const response = await (fetchImpl ?? globalThis.fetch)(url.href, {\n method: \"GET\", redirect: \"error\", signal: controller.signal,\n headers: token === undefined ? {} : { Authorization: `Bearer ${token}` },\n next: { revalidate: policy.revalidateSeconds, tags: [...policy.tags] },\n });\n if (expired) { void response.body?.cancel().catch(() => {}); return { ok: false, reason: \"timeout\" }; }\n if (!response.ok) {\n void response.body?.cancel().catch(() => {});\n const status = response.status;\n const reason = status === 402 ? \"plan-limit\" : status === 401 || status === 403 ? \"permission\"\n : status === 429 ? \"rate-limit\" : \"upstream\";\n return { ok: false, reason, status };\n }\n if (!response.body) return { ok: false, reason: \"malformed\" };\n bodyReader = response.body.getReader();\n let bytes = 0;\n let text = \"\";\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n while (true) {\n const chunk = await bodyReader.read();\n if (expired) return { ok: false, reason: \"timeout\" };\n if (chunk.done) break;\n bytes += chunk.value.byteLength;\n if (bytes > RESPONSE_LIMIT) { cancel(); return { ok: false, reason: \"malformed\" }; }\n try { text += decoder.decode(chunk.value, { stream: true }); }\n catch { cancel(); return { ok: false, reason: \"malformed\" }; }\n }\n try {\n text += decoder.decode();\n const envelope: unknown = JSON.parse(text);\n if (!envelope || typeof envelope !== \"object\" || Array.isArray(envelope) || !Object.hasOwn(envelope, \"result\")) return { ok: false, reason: \"malformed\" };\n return { ok: true, value: (envelope as Record<string, unknown>).result };\n } catch { return { ok: false, reason: \"malformed\" }; }\n } catch { return { ok: false, reason: expired ? \"timeout\" : \"network\" }; }\n };\n try { return await Promise.race([work(), deadline]); }\n finally { clearTimeout(timer); }\n },\n } satisfies CmsAdapter);\n}\n\nexport function sanityBindingFromEnv(env: Readonly<Record<string, string | undefined>>): SanityBinding {\n return bindingCopy({ projectId: env.SANITY_PROJECT_ID, dataset: env.SANITY_DATASET, apiVersion: env.SANITY_API_VERSION } as SanityBinding);\n}\n"],
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,yBAAAE,EAAA,yBAAAC,IAAA,eAAAC,EAAAJ,GAAA,IAAAK,EAAO,
|
|
4
|
+
"sourcesContent": ["import \"server-only\";\nexport { createSanityAdapter, sanityBindingFromEnv } from \"./adapters/sanity/adapter.js\";\nexport type { SanityBinding, SanityAdapterOptions } from \"./adapters/sanity/adapter.js\";\n", "import { MalformedContentError } from \"../portable/site-content.js\";\nimport { MENU_DOCUMENT_PROJECTION } from \"../portable/menu-options.js\";\nimport { parseMenuDocument, validMenuFallback, type MenuDocument } from \"../portable/menu.js\";\n\n/** A-1822 S1 owns this implementation. S0 registers the public signatures. */\nexport type CmsParams = Readonly<Record<string, string | number | boolean | null>>;\nexport type CmsDependencies = {\n readonly types: readonly string[];\n readonly ids?: readonly string[];\n};\nexport type CmsResolution<T> = {\n readonly data: T;\n readonly fallbackFields: readonly string[];\n readonly warnings?: readonly (\"siteHero.layout.defaulted\" | \"siteHero.tagline.dropped\" | \"siteHero.taglines.defaulted\")[];\n};\nexport type CmsQuery<T> = {\n readonly name: string;\n readonly query: string;\n readonly params: CmsParams;\n readonly dependencies: CmsDependencies;\n readonly resolve: (raw: unknown, fallback: T) => CmsResolution<T>;\n};\n\nconst TYPE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;\nconst ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;\nconst SCOPE = /^[a-z0-9]{6,12}\\.[a-z][a-z0-9_-]{0,63}$/;\n\nfunction dependenciesCopy(dependencies: CmsDependencies): CmsDependencies {\n if (!dependencies || !Array.isArray(dependencies.types) || dependencies.types.length === 0) {\n throw new TypeError(\"CMS dependencies require document types\");\n }\n const types = [...dependencies.types];\n for (const type of types) {\n if (typeof type !== \"string\" || !TYPE.test(type)) throw new TypeError(\"Invalid CMS document type\");\n }\n if (dependencies.ids !== undefined && !Array.isArray(dependencies.ids)) throw new TypeError(\"Invalid CMS document IDs\");\n const ids = dependencies.ids === undefined ? undefined : [...dependencies.ids];\n for (const id of ids ?? []) {\n if (typeof id !== \"string\" || !ID.test(id) || /^(drafts|versions)\\./.test(id)) {\n throw new TypeError(\"Invalid CMS document ID\");\n }\n }\n if (new Set(types).size + new Set(ids).size > 128) throw new TypeError(\"Too many CMS tags\");\n return Object.freeze({ types: Object.freeze(types), ...(ids === undefined ? {} : { ids: Object.freeze(ids) }) });\n}\n\nexport function defineCmsQuery<T>(query: CmsQuery<T>): CmsQuery<T> {\n if (!query || typeof query.name !== \"string\" || !/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(query.name)\n || typeof query.query !== \"string\" || query.query.trim() === \"\" || typeof query.resolve !== \"function\") {\n throw new TypeError(\"Invalid CMS query configuration\");\n }\n const params = query.params;\n if (!params || typeof params !== \"object\" || (Object.getPrototypeOf(params) !== Object.prototype && Object.getPrototypeOf(params) !== null)) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const copied: Record<string, string | number | boolean | null> = {};\n for (const key of Reflect.ownKeys(params)) {\n const descriptor = Object.getOwnPropertyDescriptor(params, key);\n if (typeof key !== \"string\" || !descriptor || !Object.hasOwn(descriptor, \"value\") || !descriptor.enumerable) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const value: unknown = descriptor.value;\n if (!(value === null || typeof value === \"string\" || typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value)))) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n Object.defineProperty(copied, key, { value, enumerable: true });\n }\n return Object.freeze({ name: query.name, query: query.query, params: Object.freeze(copied), dependencies: dependenciesCopy(query.dependencies), resolve: query.resolve });\n}\n\nexport function cmsTags(scope: string, dependencies: CmsDependencies): readonly string[] {\n if (typeof scope !== \"string\" || scope.length > 77 || !SCOPE.test(scope)) throw new TypeError(\"Invalid CMS scope\");\n const copied = dependenciesCopy(dependencies);\n const tags = [\n ...[...new Set(copied.types)].sort().map((type) => `cms:${scope}:type:${type}`),\n ...[...new Set(copied.ids ?? [])].sort().map((id) => `cms:${scope}:id:${id}`),\n ];\n return Object.freeze(tags);\n}\n\n/** Read one published menu by its document id; host supplies the last good snapshot. */\nexport function menuQuery(id: string): CmsQuery<MenuDocument | null> {\n return defineCmsQuery({\n name: \"menu.v1\",\n query: `*[_type == \"menu\" && _id == $id && !(_id in path(\"drafts.**\")) && !(_id in path(\"versions.**\"))][0]{${MENU_DOCUMENT_PROJECTION}}`,\n params: { id }, dependencies: { types: [\"menu\"], ids: [id] },\n resolve: (raw, fallback) => {\n if (!validMenuFallback(fallback) || (fallback !== null && fallback._id !== id)) throw new TypeError(\"Invalid CMS menu fallback\");\n if (raw === null || raw === undefined) return { data: fallback, fallbackFields: [\"$\"] };\n const data = parseMenuDocument(raw);\n if (data._id !== id) throw new MalformedContentError(\"menu\", [\"menu._id does not match the requested document\"]);\n return { data, fallbackFields: [] };\n },\n });\n}\n", "import type { CmsAdapter, CmsFetch } from \"../../runtime/reader.js\";\nimport { cmsTags, defineCmsQuery } from \"../../contracts/query.js\";\n\nexport type SanityBinding = {\n readonly projectId: string;\n readonly dataset: string;\n readonly apiVersion: string;\n};\nexport type SanityAdapterOptions = {\n readonly binding: SanityBinding;\n readonly readToken?: string;\n readonly fetchImpl?: CmsFetch;\n readonly timeoutMs?: number;\n};\n\nconst RESPONSE_LIMIT = 2 * 1024 * 1024;\n\nfunction bindingCopy(binding: SanityBinding): SanityBinding {\n if (!binding || typeof binding.projectId !== \"string\" || !/^[a-z0-9]{6,12}$/.test(binding.projectId)\n || typeof binding.dataset !== \"string\" || !/^[a-z][a-z0-9_-]{0,63}$/.test(binding.dataset)\n || typeof binding.apiVersion !== \"string\" || !/^v?\\d{4}-\\d{2}-\\d{2}$/.test(binding.apiVersion)) {\n throw new TypeError(\"Invalid Sanity binding configuration\");\n }\n return Object.freeze({ projectId: binding.projectId, dataset: binding.dataset, apiVersion: binding.apiVersion.replace(/^v/, \"\") });\n}\n\n/** Applies policy via fetch's Next metadata. Standard fetch has no persistent cache or HTML invalidation. */\nexport function createSanityAdapter(options: SanityAdapterOptions): CmsAdapter {\n const binding = bindingCopy(options?.binding);\n const timeoutMs = options.timeoutMs ?? 1500;\n const token = options.readToken;\n if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647\n || (options.fetchImpl !== undefined && typeof options.fetchImpl !== \"function\")\n || (token !== undefined && (typeof token !== \"string\" || token.trim() === \"\" || /[\\r\\n]/.test(token)))) {\n throw new TypeError(\"Invalid Sanity adapter configuration\");\n }\n const fetchImpl = options.fetchImpl;\n const scope = `${binding.projectId}.${binding.dataset}`;\n return Object.freeze({\n scope,\n async read(query, policy) {\n // Direct structural callers receive the same configuration refusals.\n let validated;\n try {\n if (!policy || !Number.isSafeInteger(policy.revalidateSeconds) || policy.revalidateSeconds < 3600 || !Array.isArray(policy.tags)) throw new TypeError();\n const types: string[] = [];\n const ids: string[] = [];\n for (const tag of policy.tags) {\n if (typeof tag !== \"string\") throw new TypeError();\n if (tag.startsWith(`cms:${scope}:type:`)) types.push(tag.slice(`cms:${scope}:type:`.length));\n else if (tag.startsWith(`cms:${scope}:id:`)) ids.push(tag.slice(`cms:${scope}:id:`.length));\n else throw new TypeError();\n }\n const expected = cmsTags(scope, { types, ids });\n if (expected.length !== policy.tags.length || expected.some((tag, i) => tag !== policy.tags[i])) throw new TypeError();\n validated = defineCmsQuery({ ...query, dependencies: { types, ids }, resolve: (raw: unknown) => ({ data: raw, fallbackFields: [] }) });\n } catch { throw new TypeError(\"Invalid Sanity read configuration\"); }\n const url = new URL(`https://${binding.projectId}.api.sanity.io/v${binding.apiVersion}/data/query/${binding.dataset}`);\n url.searchParams.set(\"query\", validated.query);\n url.searchParams.set(\"perspective\", \"published\");\n for (const key of Object.keys(validated.params).sort()) url.searchParams.set(`$${key}`, JSON.stringify(validated.params[key]));\n const controller = new AbortController();\n let bodyReader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n let expired = false;\n const cancel = (): void => {\n controller.abort();\n if (bodyReader) void bodyReader.cancel().catch(() => {});\n };\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<Awaited<ReturnType<CmsAdapter[\"read\"]>>>((resolve) => {\n timer = setTimeout(() => {\n expired = true;\n cancel();\n resolve({ ok: false, reason: \"timeout\" });\n }, timeoutMs);\n });\n const work = async (): Promise<Awaited<ReturnType<CmsAdapter[\"read\"]>>> => {\n try {\n // Look up global fetch at read time so Next's patched fetch is retained.\n const response = await (fetchImpl ?? globalThis.fetch)(url.href, {\n method: \"GET\", redirect: \"error\", signal: controller.signal,\n headers: token === undefined ? {} : { Authorization: `Bearer ${token}` },\n next: { revalidate: policy.revalidateSeconds, tags: [...policy.tags] },\n });\n if (expired) { void response.body?.cancel().catch(() => {}); return { ok: false, reason: \"timeout\" }; }\n if (!response.ok) {\n void response.body?.cancel().catch(() => {});\n const status = response.status;\n const reason = status === 402 ? \"plan-limit\" : status === 401 || status === 403 ? \"permission\"\n : status === 429 ? \"rate-limit\" : \"upstream\";\n return { ok: false, reason, status };\n }\n if (!response.body) return { ok: false, reason: \"malformed\" };\n bodyReader = response.body.getReader();\n let bytes = 0;\n let text = \"\";\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n while (true) {\n const chunk = await bodyReader.read();\n if (expired) return { ok: false, reason: \"timeout\" };\n if (chunk.done) break;\n bytes += chunk.value.byteLength;\n if (bytes > RESPONSE_LIMIT) { cancel(); return { ok: false, reason: \"malformed\" }; }\n try { text += decoder.decode(chunk.value, { stream: true }); }\n catch { cancel(); return { ok: false, reason: \"malformed\" }; }\n }\n try {\n text += decoder.decode();\n const envelope: unknown = JSON.parse(text);\n if (!envelope || typeof envelope !== \"object\" || Array.isArray(envelope) || !Object.hasOwn(envelope, \"result\")) return { ok: false, reason: \"malformed\" };\n return { ok: true, value: (envelope as Record<string, unknown>).result };\n } catch { return { ok: false, reason: \"malformed\" }; }\n } catch { return { ok: false, reason: expired ? \"timeout\" : \"network\" }; }\n };\n try { return await Promise.race([work(), deadline]); }\n finally { clearTimeout(timer); }\n },\n } satisfies CmsAdapter);\n}\n\nexport function sanityBindingFromEnv(env: Readonly<Record<string, string | undefined>>): SanityBinding {\n return bindingCopy({ projectId: env.SANITY_PROJECT_ID, dataset: env.SANITY_DATASET, apiVersion: env.SANITY_API_VERSION } as SanityBinding);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["sanity_exports", "__export", "createSanityAdapter", "sanityBindingFromEnv", "__toCommonJS", "import_server_only", "TYPE", "ID", "SCOPE", "dependenciesCopy", "dependencies", "types", "type", "ids", "id", "defineCmsQuery", "query", "params", "copied", "key", "descriptor", "value", "cmsTags", "scope", "tags", "RESPONSE_LIMIT", "bindingCopy", "binding", "createSanityAdapter", "options", "timeoutMs", "token", "fetchImpl", "scope", "query", "policy", "validated", "types", "ids", "tag", "expected", "cmsTags", "i", "defineCmsQuery", "raw", "url", "key", "controller", "bodyReader", "expired", "cancel", "timer", "deadline", "resolve", "work", "response", "status", "bytes", "text", "decoder", "chunk", "envelope", "sanityBindingFromEnv", "env"]
|
|
7
7
|
}
|
package/dist/sanity.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"server-only";var
|
|
1
|
+
import"server-only";var A=/^[A-Za-z][A-Za-z0-9_]{0,63}$/,E=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/,k=/^[a-z0-9]{6,12}\.[a-z][a-z0-9_-]{0,63}$/;function T(e){if(!e||!Array.isArray(e.types)||e.types.length===0)throw new TypeError("CMS dependencies require document types");let r=[...e.types];for(let t of r)if(typeof t!="string"||!A.test(t))throw new TypeError("Invalid CMS document type");if(e.ids!==void 0&&!Array.isArray(e.ids))throw new TypeError("Invalid CMS document IDs");let a=e.ids===void 0?void 0:[...e.ids];for(let t of a??[])if(typeof t!="string"||!E.test(t)||/^(drafts|versions)\./.test(t))throw new TypeError("Invalid CMS document ID");if(new Set(r).size+new Set(a).size>128)throw new TypeError("Too many CMS tags");return Object.freeze({types:Object.freeze(r),...a===void 0?{}:{ids:Object.freeze(a)}})}function S(e){if(!e||typeof e.name!="string"||!/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(e.name)||typeof e.query!="string"||e.query.trim()===""||typeof e.resolve!="function")throw new TypeError("Invalid CMS query configuration");let r=e.params;if(!r||typeof r!="object"||Object.getPrototypeOf(r)!==Object.prototype&&Object.getPrototypeOf(r)!==null)throw new TypeError("CMS params must be plain JSON scalars");let a={};for(let t of Reflect.ownKeys(r)){let d=Object.getOwnPropertyDescriptor(r,t);if(typeof t!="string"||!d||!Object.hasOwn(d,"value")||!d.enumerable)throw new TypeError("CMS params must be plain JSON scalars");let s=d.value;if(!(s===null||typeof s=="string"||typeof s=="boolean"||typeof s=="number"&&Number.isFinite(s)))throw new TypeError("CMS params must be plain JSON scalars");Object.defineProperty(a,t,{value:s,enumerable:!0})}return Object.freeze({name:e.name,query:e.query,params:Object.freeze(a),dependencies:T(e.dependencies),resolve:e.resolve})}function b(e,r){if(typeof e!="string"||e.length>77||!k.test(e))throw new TypeError("Invalid CMS scope");let a=T(r),t=[...[...new Set(a.types)].sort().map(d=>`cms:${e}:type:${d}`),...[...new Set(a.ids??[])].sort().map(d=>`cms:${e}:id:${d}`)];return Object.freeze(t)}var j=2*1024*1024;function C(e){if(!e||typeof e.projectId!="string"||!/^[a-z0-9]{6,12}$/.test(e.projectId)||typeof e.dataset!="string"||!/^[a-z][a-z0-9_-]{0,63}$/.test(e.dataset)||typeof e.apiVersion!="string"||!/^v?\d{4}-\d{2}-\d{2}$/.test(e.apiVersion))throw new TypeError("Invalid Sanity binding configuration");return Object.freeze({projectId:e.projectId,dataset:e.dataset,apiVersion:e.apiVersion.replace(/^v/,"")})}function $(e){let r=C(e?.binding),a=e.timeoutMs??1500,t=e.readToken;if(!Number.isSafeInteger(a)||a<=0||a>2147483647||e.fetchImpl!==void 0&&typeof e.fetchImpl!="function"||t!==void 0&&(typeof t!="string"||t.trim()===""||/[\r\n]/.test(t)))throw new TypeError("Invalid Sanity adapter configuration");let d=e.fetchImpl,s=`${r.projectId}.${r.dataset}`;return Object.freeze({scope:s,async read(v,c){let y;try{if(!c||!Number.isSafeInteger(c.revalidateSeconds)||c.revalidateSeconds<3600||!Array.isArray(c.tags))throw new TypeError;let o=[],p=[];for(let i of c.tags){if(typeof i!="string")throw new TypeError;if(i.startsWith(`cms:${s}:type:`))o.push(i.slice(`cms:${s}:type:`.length));else if(i.startsWith(`cms:${s}:id:`))p.push(i.slice(`cms:${s}:id:`.length));else throw new TypeError}let l=b(s,{types:o,ids:p});if(l.length!==c.tags.length||l.some((i,n)=>i!==c.tags[n]))throw new TypeError;y=S({...v,dependencies:{types:o,ids:p},resolve:i=>({data:i,fallbackFields:[]})})}catch{throw new TypeError("Invalid Sanity read configuration")}let f=new URL(`https://${r.projectId}.api.sanity.io/v${r.apiVersion}/data/query/${r.dataset}`);f.searchParams.set("query",y.query),f.searchParams.set("perspective","published");for(let o of Object.keys(y.params).sort())f.searchParams.set(`$${o}`,JSON.stringify(y.params[o]));let h=new AbortController,u,m=!1,g=()=>{h.abort(),u&&u.cancel().catch(()=>{})},w,I=new Promise(o=>{w=setTimeout(()=>{m=!0,g(),o({ok:!1,reason:"timeout"})},a)}),O=async()=>{try{let o=await(d??globalThis.fetch)(f.href,{method:"GET",redirect:"error",signal:h.signal,headers:t===void 0?{}:{Authorization:`Bearer ${t}`},next:{revalidate:c.revalidateSeconds,tags:[...c.tags]}});if(m)return o.body?.cancel().catch(()=>{}),{ok:!1,reason:"timeout"};if(!o.ok){o.body?.cancel().catch(()=>{});let n=o.status;return{ok:!1,reason:n===402?"plan-limit":n===401||n===403?"permission":n===429?"rate-limit":"upstream",status:n}}if(!o.body)return{ok:!1,reason:"malformed"};u=o.body.getReader();let p=0,l="",i=new TextDecoder("utf-8",{fatal:!0});for(;;){let n=await u.read();if(m)return{ok:!1,reason:"timeout"};if(n.done)break;if(p+=n.value.byteLength,p>j)return g(),{ok:!1,reason:"malformed"};try{l+=i.decode(n.value,{stream:!0})}catch{return g(),{ok:!1,reason:"malformed"}}}try{l+=i.decode();let n=JSON.parse(l);return!n||typeof n!="object"||Array.isArray(n)||!Object.hasOwn(n,"result")?{ok:!1,reason:"malformed"}:{ok:!0,value:n.result}}catch{return{ok:!1,reason:"malformed"}}}catch{return{ok:!1,reason:m?"timeout":"network"}}};try{return await Promise.race([O(),I])}finally{clearTimeout(w)}}})}function z(e){return C({projectId:e.SANITY_PROJECT_ID,dataset:e.SANITY_DATASET,apiVersion:e.SANITY_API_VERSION})}export{$ as createSanityAdapter,z as sanityBindingFromEnv};
|
|
2
2
|
//# sourceMappingURL=sanity.mjs.map
|
package/dist/sanity.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/sanity.ts", "../src/contracts/query.ts", "../src/adapters/sanity/adapter.ts"],
|
|
4
|
-
"sourcesContent": ["import \"server-only\";\nexport { createSanityAdapter, sanityBindingFromEnv } from \"./adapters/sanity/adapter.js\";\nexport type { SanityBinding, SanityAdapterOptions } from \"./adapters/sanity/adapter.js\";\n", "/** A-1822 S1 owns this implementation. S0 registers the public signatures. */\nexport type CmsParams = Readonly<Record<string, string | number | boolean | null>>;\nexport type CmsDependencies = {\n readonly types: readonly string[];\n readonly ids?: readonly string[];\n};\nexport type CmsResolution<T> = {\n readonly data: T;\n readonly fallbackFields: readonly string[];\n readonly warnings?: readonly (\"siteHero.layout.defaulted\" | \"siteHero.tagline.dropped\" | \"siteHero.taglines.defaulted\")[];\n};\nexport type CmsQuery<T> = {\n readonly name: string;\n readonly query: string;\n readonly params: CmsParams;\n readonly dependencies: CmsDependencies;\n readonly resolve: (raw: unknown, fallback: T) => CmsResolution<T>;\n};\n\nconst TYPE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;\nconst ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;\nconst SCOPE = /^[a-z0-9]{6,12}\\.[a-z][a-z0-9_-]{0,63}$/;\n\nfunction dependenciesCopy(dependencies: CmsDependencies): CmsDependencies {\n if (!dependencies || !Array.isArray(dependencies.types) || dependencies.types.length === 0) {\n throw new TypeError(\"CMS dependencies require document types\");\n }\n const types = [...dependencies.types];\n for (const type of types) {\n if (typeof type !== \"string\" || !TYPE.test(type)) throw new TypeError(\"Invalid CMS document type\");\n }\n if (dependencies.ids !== undefined && !Array.isArray(dependencies.ids)) throw new TypeError(\"Invalid CMS document IDs\");\n const ids = dependencies.ids === undefined ? undefined : [...dependencies.ids];\n for (const id of ids ?? []) {\n if (typeof id !== \"string\" || !ID.test(id) || /^(drafts|versions)\\./.test(id)) {\n throw new TypeError(\"Invalid CMS document ID\");\n }\n }\n if (new Set(types).size + new Set(ids).size > 128) throw new TypeError(\"Too many CMS tags\");\n return Object.freeze({ types: Object.freeze(types), ...(ids === undefined ? {} : { ids: Object.freeze(ids) }) });\n}\n\nexport function defineCmsQuery<T>(query: CmsQuery<T>): CmsQuery<T> {\n if (!query || typeof query.name !== \"string\" || !/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(query.name)\n || typeof query.query !== \"string\" || query.query.trim() === \"\" || typeof query.resolve !== \"function\") {\n throw new TypeError(\"Invalid CMS query configuration\");\n }\n const params = query.params;\n if (!params || typeof params !== \"object\" || (Object.getPrototypeOf(params) !== Object.prototype && Object.getPrototypeOf(params) !== null)) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const copied: Record<string, string | number | boolean | null> = {};\n for (const key of Reflect.ownKeys(params)) {\n const descriptor = Object.getOwnPropertyDescriptor(params, key);\n if (typeof key !== \"string\" || !descriptor || !Object.hasOwn(descriptor, \"value\") || !descriptor.enumerable) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const value: unknown = descriptor.value;\n if (!(value === null || typeof value === \"string\" || typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value)))) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n Object.defineProperty(copied, key, { value, enumerable: true });\n }\n return Object.freeze({ name: query.name, query: query.query, params: Object.freeze(copied), dependencies: dependenciesCopy(query.dependencies), resolve: query.resolve });\n}\n\nexport function cmsTags(scope: string, dependencies: CmsDependencies): readonly string[] {\n if (typeof scope !== \"string\" || scope.length > 77 || !SCOPE.test(scope)) throw new TypeError(\"Invalid CMS scope\");\n const copied = dependenciesCopy(dependencies);\n const tags = [\n ...[...new Set(copied.types)].sort().map((type) => `cms:${scope}:type:${type}`),\n ...[...new Set(copied.ids ?? [])].sort().map((id) => `cms:${scope}:id:${id}`),\n ];\n return Object.freeze(tags);\n}\n", "import type { CmsAdapter, CmsFetch } from \"../../runtime/reader.js\";\nimport { cmsTags, defineCmsQuery } from \"../../contracts/query.js\";\n\nexport type SanityBinding = {\n readonly projectId: string;\n readonly dataset: string;\n readonly apiVersion: string;\n};\nexport type SanityAdapterOptions = {\n readonly binding: SanityBinding;\n readonly readToken?: string;\n readonly fetchImpl?: CmsFetch;\n readonly timeoutMs?: number;\n};\n\nconst RESPONSE_LIMIT = 2 * 1024 * 1024;\n\nfunction bindingCopy(binding: SanityBinding): SanityBinding {\n if (!binding || typeof binding.projectId !== \"string\" || !/^[a-z0-9]{6,12}$/.test(binding.projectId)\n || typeof binding.dataset !== \"string\" || !/^[a-z][a-z0-9_-]{0,63}$/.test(binding.dataset)\n || typeof binding.apiVersion !== \"string\" || !/^v?\\d{4}-\\d{2}-\\d{2}$/.test(binding.apiVersion)) {\n throw new TypeError(\"Invalid Sanity binding configuration\");\n }\n return Object.freeze({ projectId: binding.projectId, dataset: binding.dataset, apiVersion: binding.apiVersion.replace(/^v/, \"\") });\n}\n\n/** Applies policy via fetch's Next metadata. Standard fetch has no persistent cache or HTML invalidation. */\nexport function createSanityAdapter(options: SanityAdapterOptions): CmsAdapter {\n const binding = bindingCopy(options?.binding);\n const timeoutMs = options.timeoutMs ?? 1500;\n const token = options.readToken;\n if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647\n || (options.fetchImpl !== undefined && typeof options.fetchImpl !== \"function\")\n || (token !== undefined && (typeof token !== \"string\" || token.trim() === \"\" || /[\\r\\n]/.test(token)))) {\n throw new TypeError(\"Invalid Sanity adapter configuration\");\n }\n const fetchImpl = options.fetchImpl;\n const scope = `${binding.projectId}.${binding.dataset}`;\n return Object.freeze({\n scope,\n async read(query, policy) {\n // Direct structural callers receive the same configuration refusals.\n let validated;\n try {\n if (!policy || !Number.isSafeInteger(policy.revalidateSeconds) || policy.revalidateSeconds < 3600 || !Array.isArray(policy.tags)) throw new TypeError();\n const types: string[] = [];\n const ids: string[] = [];\n for (const tag of policy.tags) {\n if (typeof tag !== \"string\") throw new TypeError();\n if (tag.startsWith(`cms:${scope}:type:`)) types.push(tag.slice(`cms:${scope}:type:`.length));\n else if (tag.startsWith(`cms:${scope}:id:`)) ids.push(tag.slice(`cms:${scope}:id:`.length));\n else throw new TypeError();\n }\n const expected = cmsTags(scope, { types, ids });\n if (expected.length !== policy.tags.length || expected.some((tag, i) => tag !== policy.tags[i])) throw new TypeError();\n validated = defineCmsQuery({ ...query, dependencies: { types, ids }, resolve: (raw: unknown) => ({ data: raw, fallbackFields: [] }) });\n } catch { throw new TypeError(\"Invalid Sanity read configuration\"); }\n const url = new URL(`https://${binding.projectId}.api.sanity.io/v${binding.apiVersion}/data/query/${binding.dataset}`);\n url.searchParams.set(\"query\", validated.query);\n url.searchParams.set(\"perspective\", \"published\");\n for (const key of Object.keys(validated.params).sort()) url.searchParams.set(`$${key}`, JSON.stringify(validated.params[key]));\n const controller = new AbortController();\n let bodyReader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n let expired = false;\n const cancel = (): void => {\n controller.abort();\n if (bodyReader) void bodyReader.cancel().catch(() => {});\n };\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<Awaited<ReturnType<CmsAdapter[\"read\"]>>>((resolve) => {\n timer = setTimeout(() => {\n expired = true;\n cancel();\n resolve({ ok: false, reason: \"timeout\" });\n }, timeoutMs);\n });\n const work = async (): Promise<Awaited<ReturnType<CmsAdapter[\"read\"]>>> => {\n try {\n // Look up global fetch at read time so Next's patched fetch is retained.\n const response = await (fetchImpl ?? globalThis.fetch)(url.href, {\n method: \"GET\", redirect: \"error\", signal: controller.signal,\n headers: token === undefined ? {} : { Authorization: `Bearer ${token}` },\n next: { revalidate: policy.revalidateSeconds, tags: [...policy.tags] },\n });\n if (expired) { void response.body?.cancel().catch(() => {}); return { ok: false, reason: \"timeout\" }; }\n if (!response.ok) {\n void response.body?.cancel().catch(() => {});\n const status = response.status;\n const reason = status === 402 ? \"plan-limit\" : status === 401 || status === 403 ? \"permission\"\n : status === 429 ? \"rate-limit\" : \"upstream\";\n return { ok: false, reason, status };\n }\n if (!response.body) return { ok: false, reason: \"malformed\" };\n bodyReader = response.body.getReader();\n let bytes = 0;\n let text = \"\";\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n while (true) {\n const chunk = await bodyReader.read();\n if (expired) return { ok: false, reason: \"timeout\" };\n if (chunk.done) break;\n bytes += chunk.value.byteLength;\n if (bytes > RESPONSE_LIMIT) { cancel(); return { ok: false, reason: \"malformed\" }; }\n try { text += decoder.decode(chunk.value, { stream: true }); }\n catch { cancel(); return { ok: false, reason: \"malformed\" }; }\n }\n try {\n text += decoder.decode();\n const envelope: unknown = JSON.parse(text);\n if (!envelope || typeof envelope !== \"object\" || Array.isArray(envelope) || !Object.hasOwn(envelope, \"result\")) return { ok: false, reason: \"malformed\" };\n return { ok: true, value: (envelope as Record<string, unknown>).result };\n } catch { return { ok: false, reason: \"malformed\" }; }\n } catch { return { ok: false, reason: expired ? \"timeout\" : \"network\" }; }\n };\n try { return await Promise.race([work(), deadline]); }\n finally { clearTimeout(timer); }\n },\n } satisfies CmsAdapter);\n}\n\nexport function sanityBindingFromEnv(env: Readonly<Record<string, string | undefined>>): SanityBinding {\n return bindingCopy({ projectId: env.SANITY_PROJECT_ID, dataset: env.SANITY_DATASET, apiVersion: env.SANITY_API_VERSION } as SanityBinding);\n}\n"],
|
|
5
|
-
"mappings": "AAAA,MAAO,
|
|
4
|
+
"sourcesContent": ["import \"server-only\";\nexport { createSanityAdapter, sanityBindingFromEnv } from \"./adapters/sanity/adapter.js\";\nexport type { SanityBinding, SanityAdapterOptions } from \"./adapters/sanity/adapter.js\";\n", "import { MalformedContentError } from \"../portable/site-content.js\";\nimport { MENU_DOCUMENT_PROJECTION } from \"../portable/menu-options.js\";\nimport { parseMenuDocument, validMenuFallback, type MenuDocument } from \"../portable/menu.js\";\n\n/** A-1822 S1 owns this implementation. S0 registers the public signatures. */\nexport type CmsParams = Readonly<Record<string, string | number | boolean | null>>;\nexport type CmsDependencies = {\n readonly types: readonly string[];\n readonly ids?: readonly string[];\n};\nexport type CmsResolution<T> = {\n readonly data: T;\n readonly fallbackFields: readonly string[];\n readonly warnings?: readonly (\"siteHero.layout.defaulted\" | \"siteHero.tagline.dropped\" | \"siteHero.taglines.defaulted\")[];\n};\nexport type CmsQuery<T> = {\n readonly name: string;\n readonly query: string;\n readonly params: CmsParams;\n readonly dependencies: CmsDependencies;\n readonly resolve: (raw: unknown, fallback: T) => CmsResolution<T>;\n};\n\nconst TYPE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;\nconst ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;\nconst SCOPE = /^[a-z0-9]{6,12}\\.[a-z][a-z0-9_-]{0,63}$/;\n\nfunction dependenciesCopy(dependencies: CmsDependencies): CmsDependencies {\n if (!dependencies || !Array.isArray(dependencies.types) || dependencies.types.length === 0) {\n throw new TypeError(\"CMS dependencies require document types\");\n }\n const types = [...dependencies.types];\n for (const type of types) {\n if (typeof type !== \"string\" || !TYPE.test(type)) throw new TypeError(\"Invalid CMS document type\");\n }\n if (dependencies.ids !== undefined && !Array.isArray(dependencies.ids)) throw new TypeError(\"Invalid CMS document IDs\");\n const ids = dependencies.ids === undefined ? undefined : [...dependencies.ids];\n for (const id of ids ?? []) {\n if (typeof id !== \"string\" || !ID.test(id) || /^(drafts|versions)\\./.test(id)) {\n throw new TypeError(\"Invalid CMS document ID\");\n }\n }\n if (new Set(types).size + new Set(ids).size > 128) throw new TypeError(\"Too many CMS tags\");\n return Object.freeze({ types: Object.freeze(types), ...(ids === undefined ? {} : { ids: Object.freeze(ids) }) });\n}\n\nexport function defineCmsQuery<T>(query: CmsQuery<T>): CmsQuery<T> {\n if (!query || typeof query.name !== \"string\" || !/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(query.name)\n || typeof query.query !== \"string\" || query.query.trim() === \"\" || typeof query.resolve !== \"function\") {\n throw new TypeError(\"Invalid CMS query configuration\");\n }\n const params = query.params;\n if (!params || typeof params !== \"object\" || (Object.getPrototypeOf(params) !== Object.prototype && Object.getPrototypeOf(params) !== null)) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const copied: Record<string, string | number | boolean | null> = {};\n for (const key of Reflect.ownKeys(params)) {\n const descriptor = Object.getOwnPropertyDescriptor(params, key);\n if (typeof key !== \"string\" || !descriptor || !Object.hasOwn(descriptor, \"value\") || !descriptor.enumerable) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n const value: unknown = descriptor.value;\n if (!(value === null || typeof value === \"string\" || typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value)))) {\n throw new TypeError(\"CMS params must be plain JSON scalars\");\n }\n Object.defineProperty(copied, key, { value, enumerable: true });\n }\n return Object.freeze({ name: query.name, query: query.query, params: Object.freeze(copied), dependencies: dependenciesCopy(query.dependencies), resolve: query.resolve });\n}\n\nexport function cmsTags(scope: string, dependencies: CmsDependencies): readonly string[] {\n if (typeof scope !== \"string\" || scope.length > 77 || !SCOPE.test(scope)) throw new TypeError(\"Invalid CMS scope\");\n const copied = dependenciesCopy(dependencies);\n const tags = [\n ...[...new Set(copied.types)].sort().map((type) => `cms:${scope}:type:${type}`),\n ...[...new Set(copied.ids ?? [])].sort().map((id) => `cms:${scope}:id:${id}`),\n ];\n return Object.freeze(tags);\n}\n\n/** Read one published menu by its document id; host supplies the last good snapshot. */\nexport function menuQuery(id: string): CmsQuery<MenuDocument | null> {\n return defineCmsQuery({\n name: \"menu.v1\",\n query: `*[_type == \"menu\" && _id == $id && !(_id in path(\"drafts.**\")) && !(_id in path(\"versions.**\"))][0]{${MENU_DOCUMENT_PROJECTION}}`,\n params: { id }, dependencies: { types: [\"menu\"], ids: [id] },\n resolve: (raw, fallback) => {\n if (!validMenuFallback(fallback) || (fallback !== null && fallback._id !== id)) throw new TypeError(\"Invalid CMS menu fallback\");\n if (raw === null || raw === undefined) return { data: fallback, fallbackFields: [\"$\"] };\n const data = parseMenuDocument(raw);\n if (data._id !== id) throw new MalformedContentError(\"menu\", [\"menu._id does not match the requested document\"]);\n return { data, fallbackFields: [] };\n },\n });\n}\n", "import type { CmsAdapter, CmsFetch } from \"../../runtime/reader.js\";\nimport { cmsTags, defineCmsQuery } from \"../../contracts/query.js\";\n\nexport type SanityBinding = {\n readonly projectId: string;\n readonly dataset: string;\n readonly apiVersion: string;\n};\nexport type SanityAdapterOptions = {\n readonly binding: SanityBinding;\n readonly readToken?: string;\n readonly fetchImpl?: CmsFetch;\n readonly timeoutMs?: number;\n};\n\nconst RESPONSE_LIMIT = 2 * 1024 * 1024;\n\nfunction bindingCopy(binding: SanityBinding): SanityBinding {\n if (!binding || typeof binding.projectId !== \"string\" || !/^[a-z0-9]{6,12}$/.test(binding.projectId)\n || typeof binding.dataset !== \"string\" || !/^[a-z][a-z0-9_-]{0,63}$/.test(binding.dataset)\n || typeof binding.apiVersion !== \"string\" || !/^v?\\d{4}-\\d{2}-\\d{2}$/.test(binding.apiVersion)) {\n throw new TypeError(\"Invalid Sanity binding configuration\");\n }\n return Object.freeze({ projectId: binding.projectId, dataset: binding.dataset, apiVersion: binding.apiVersion.replace(/^v/, \"\") });\n}\n\n/** Applies policy via fetch's Next metadata. Standard fetch has no persistent cache or HTML invalidation. */\nexport function createSanityAdapter(options: SanityAdapterOptions): CmsAdapter {\n const binding = bindingCopy(options?.binding);\n const timeoutMs = options.timeoutMs ?? 1500;\n const token = options.readToken;\n if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647\n || (options.fetchImpl !== undefined && typeof options.fetchImpl !== \"function\")\n || (token !== undefined && (typeof token !== \"string\" || token.trim() === \"\" || /[\\r\\n]/.test(token)))) {\n throw new TypeError(\"Invalid Sanity adapter configuration\");\n }\n const fetchImpl = options.fetchImpl;\n const scope = `${binding.projectId}.${binding.dataset}`;\n return Object.freeze({\n scope,\n async read(query, policy) {\n // Direct structural callers receive the same configuration refusals.\n let validated;\n try {\n if (!policy || !Number.isSafeInteger(policy.revalidateSeconds) || policy.revalidateSeconds < 3600 || !Array.isArray(policy.tags)) throw new TypeError();\n const types: string[] = [];\n const ids: string[] = [];\n for (const tag of policy.tags) {\n if (typeof tag !== \"string\") throw new TypeError();\n if (tag.startsWith(`cms:${scope}:type:`)) types.push(tag.slice(`cms:${scope}:type:`.length));\n else if (tag.startsWith(`cms:${scope}:id:`)) ids.push(tag.slice(`cms:${scope}:id:`.length));\n else throw new TypeError();\n }\n const expected = cmsTags(scope, { types, ids });\n if (expected.length !== policy.tags.length || expected.some((tag, i) => tag !== policy.tags[i])) throw new TypeError();\n validated = defineCmsQuery({ ...query, dependencies: { types, ids }, resolve: (raw: unknown) => ({ data: raw, fallbackFields: [] }) });\n } catch { throw new TypeError(\"Invalid Sanity read configuration\"); }\n const url = new URL(`https://${binding.projectId}.api.sanity.io/v${binding.apiVersion}/data/query/${binding.dataset}`);\n url.searchParams.set(\"query\", validated.query);\n url.searchParams.set(\"perspective\", \"published\");\n for (const key of Object.keys(validated.params).sort()) url.searchParams.set(`$${key}`, JSON.stringify(validated.params[key]));\n const controller = new AbortController();\n let bodyReader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n let expired = false;\n const cancel = (): void => {\n controller.abort();\n if (bodyReader) void bodyReader.cancel().catch(() => {});\n };\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<Awaited<ReturnType<CmsAdapter[\"read\"]>>>((resolve) => {\n timer = setTimeout(() => {\n expired = true;\n cancel();\n resolve({ ok: false, reason: \"timeout\" });\n }, timeoutMs);\n });\n const work = async (): Promise<Awaited<ReturnType<CmsAdapter[\"read\"]>>> => {\n try {\n // Look up global fetch at read time so Next's patched fetch is retained.\n const response = await (fetchImpl ?? globalThis.fetch)(url.href, {\n method: \"GET\", redirect: \"error\", signal: controller.signal,\n headers: token === undefined ? {} : { Authorization: `Bearer ${token}` },\n next: { revalidate: policy.revalidateSeconds, tags: [...policy.tags] },\n });\n if (expired) { void response.body?.cancel().catch(() => {}); return { ok: false, reason: \"timeout\" }; }\n if (!response.ok) {\n void response.body?.cancel().catch(() => {});\n const status = response.status;\n const reason = status === 402 ? \"plan-limit\" : status === 401 || status === 403 ? \"permission\"\n : status === 429 ? \"rate-limit\" : \"upstream\";\n return { ok: false, reason, status };\n }\n if (!response.body) return { ok: false, reason: \"malformed\" };\n bodyReader = response.body.getReader();\n let bytes = 0;\n let text = \"\";\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n while (true) {\n const chunk = await bodyReader.read();\n if (expired) return { ok: false, reason: \"timeout\" };\n if (chunk.done) break;\n bytes += chunk.value.byteLength;\n if (bytes > RESPONSE_LIMIT) { cancel(); return { ok: false, reason: \"malformed\" }; }\n try { text += decoder.decode(chunk.value, { stream: true }); }\n catch { cancel(); return { ok: false, reason: \"malformed\" }; }\n }\n try {\n text += decoder.decode();\n const envelope: unknown = JSON.parse(text);\n if (!envelope || typeof envelope !== \"object\" || Array.isArray(envelope) || !Object.hasOwn(envelope, \"result\")) return { ok: false, reason: \"malformed\" };\n return { ok: true, value: (envelope as Record<string, unknown>).result };\n } catch { return { ok: false, reason: \"malformed\" }; }\n } catch { return { ok: false, reason: expired ? \"timeout\" : \"network\" }; }\n };\n try { return await Promise.race([work(), deadline]); }\n finally { clearTimeout(timer); }\n },\n } satisfies CmsAdapter);\n}\n\nexport function sanityBindingFromEnv(env: Readonly<Record<string, string | undefined>>): SanityBinding {\n return bindingCopy({ projectId: env.SANITY_PROJECT_ID, dataset: env.SANITY_DATASET, apiVersion: env.SANITY_API_VERSION } as SanityBinding);\n}\n"],
|
|
5
|
+
"mappings": "AAAA,MAAO,cCuBP,IAAMA,EAAO,+BACPC,EAAK,qCACLC,EAAQ,0CAEd,SAASC,EAAiBC,EAAgD,CACxE,GAAI,CAACA,GAAgB,CAAC,MAAM,QAAQA,EAAa,KAAK,GAAKA,EAAa,MAAM,SAAW,EACvF,MAAM,IAAI,UAAU,yCAAyC,EAE/D,IAAMC,EAAQ,CAAC,GAAGD,EAAa,KAAK,EACpC,QAAWE,KAAQD,EACjB,GAAI,OAAOC,GAAS,UAAY,CAACN,EAAK,KAAKM,CAAI,EAAG,MAAM,IAAI,UAAU,2BAA2B,EAEnG,GAAIF,EAAa,MAAQ,QAAa,CAAC,MAAM,QAAQA,EAAa,GAAG,EAAG,MAAM,IAAI,UAAU,0BAA0B,EACtH,IAAMG,EAAMH,EAAa,MAAQ,OAAY,OAAY,CAAC,GAAGA,EAAa,GAAG,EAC7E,QAAWI,KAAMD,GAAO,CAAC,EACvB,GAAI,OAAOC,GAAO,UAAY,CAACP,EAAG,KAAKO,CAAE,GAAK,uBAAuB,KAAKA,CAAE,EAC1E,MAAM,IAAI,UAAU,yBAAyB,EAGjD,GAAI,IAAI,IAAIH,CAAK,EAAE,KAAO,IAAI,IAAIE,CAAG,EAAE,KAAO,IAAK,MAAM,IAAI,UAAU,mBAAmB,EAC1F,OAAO,OAAO,OAAO,CAAE,MAAO,OAAO,OAAOF,CAAK,EAAG,GAAIE,IAAQ,OAAY,CAAC,EAAI,CAAE,IAAK,OAAO,OAAOA,CAAG,CAAE,CAAG,CAAC,CACjH,CAEO,SAASE,EAAkBC,EAAiC,CACjE,GAAI,CAACA,GAAS,OAAOA,EAAM,MAAS,UAAY,CAAC,kCAAkC,KAAKA,EAAM,IAAI,GAC7F,OAAOA,EAAM,OAAU,UAAYA,EAAM,MAAM,KAAK,IAAM,IAAM,OAAOA,EAAM,SAAY,WAC5F,MAAM,IAAI,UAAU,iCAAiC,EAEvD,IAAMC,EAASD,EAAM,OACrB,GAAI,CAACC,GAAU,OAAOA,GAAW,UAAa,OAAO,eAAeA,CAAM,IAAM,OAAO,WAAa,OAAO,eAAeA,CAAM,IAAM,KACpI,MAAM,IAAI,UAAU,uCAAuC,EAE7D,IAAMC,EAA2D,CAAC,EAClE,QAAWC,KAAO,QAAQ,QAAQF,CAAM,EAAG,CACzC,IAAMG,EAAa,OAAO,yBAAyBH,EAAQE,CAAG,EAC9D,GAAI,OAAOA,GAAQ,UAAY,CAACC,GAAc,CAAC,OAAO,OAAOA,EAAY,OAAO,GAAK,CAACA,EAAW,WAC/F,MAAM,IAAI,UAAU,uCAAuC,EAE7D,IAAMC,EAAiBD,EAAW,MAClC,GAAI,EAAEC,IAAU,MAAQ,OAAOA,GAAU,UAAY,OAAOA,GAAU,WAAc,OAAOA,GAAU,UAAY,OAAO,SAASA,CAAK,GACpI,MAAM,IAAI,UAAU,uCAAuC,EAE7D,OAAO,eAAeH,EAAQC,EAAK,CAAE,MAAAE,EAAO,WAAY,EAAK,CAAC,CAChE,CACA,OAAO,OAAO,OAAO,CAAE,KAAML,EAAM,KAAM,MAAOA,EAAM,MAAO,OAAQ,OAAO,OAAOE,CAAM,EAAG,aAAcT,EAAiBO,EAAM,YAAY,EAAG,QAASA,EAAM,OAAQ,CAAC,CAC1K,CAEO,SAASM,EAAQC,EAAeb,EAAkD,CACvF,GAAI,OAAOa,GAAU,UAAYA,EAAM,OAAS,IAAM,CAACf,EAAM,KAAKe,CAAK,EAAG,MAAM,IAAI,UAAU,mBAAmB,EACjH,IAAML,EAAST,EAAiBC,CAAY,EACtCc,EAAO,CACX,GAAG,CAAC,GAAG,IAAI,IAAIN,EAAO,KAAK,CAAC,EAAE,KAAK,EAAE,IAAKN,GAAS,OAAOW,CAAK,SAASX,CAAI,EAAE,EAC9E,GAAG,CAAC,GAAG,IAAI,IAAIM,EAAO,KAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAKJ,GAAO,OAAOS,CAAK,OAAOT,CAAE,EAAE,CAC9E,EACA,OAAO,OAAO,OAAOU,CAAI,CAC3B,CC/DA,IAAMC,EAAiB,EAAI,KAAO,KAElC,SAASC,EAAYC,EAAuC,CAC1D,GAAI,CAACA,GAAW,OAAOA,EAAQ,WAAc,UAAY,CAAC,mBAAmB,KAAKA,EAAQ,SAAS,GAC9F,OAAOA,EAAQ,SAAY,UAAY,CAAC,0BAA0B,KAAKA,EAAQ,OAAO,GACtF,OAAOA,EAAQ,YAAe,UAAY,CAAC,wBAAwB,KAAKA,EAAQ,UAAU,EAC7F,MAAM,IAAI,UAAU,sCAAsC,EAE5D,OAAO,OAAO,OAAO,CAAE,UAAWA,EAAQ,UAAW,QAASA,EAAQ,QAAS,WAAYA,EAAQ,WAAW,QAAQ,KAAM,EAAE,CAAE,CAAC,CACnI,CAGO,SAASC,EAAoBC,EAA2C,CAC7E,IAAMF,EAAUD,EAAYG,GAAS,OAAO,EACtCC,EAAYD,EAAQ,WAAa,KACjCE,EAAQF,EAAQ,UACtB,GAAI,CAAC,OAAO,cAAcC,CAAS,GAAKA,GAAa,GAAKA,EAAY,YAChED,EAAQ,YAAc,QAAa,OAAOA,EAAQ,WAAc,YAChEE,IAAU,SAAc,OAAOA,GAAU,UAAYA,EAAM,KAAK,IAAM,IAAM,SAAS,KAAKA,CAAK,GACnG,MAAM,IAAI,UAAU,sCAAsC,EAE5D,IAAMC,EAAYH,EAAQ,UACpBI,EAAQ,GAAGN,EAAQ,SAAS,IAAIA,EAAQ,OAAO,GACrD,OAAO,OAAO,OAAO,CACnB,MAAAM,EACA,MAAM,KAAKC,EAAOC,EAAQ,CAExB,IAAIC,EACJ,GAAI,CACF,GAAI,CAACD,GAAU,CAAC,OAAO,cAAcA,EAAO,iBAAiB,GAAKA,EAAO,kBAAoB,MAAQ,CAAC,MAAM,QAAQA,EAAO,IAAI,EAAG,MAAM,IAAI,UAC5I,IAAME,EAAkB,CAAC,EACnBC,EAAgB,CAAC,EACvB,QAAWC,KAAOJ,EAAO,KAAM,CAC7B,GAAI,OAAOI,GAAQ,SAAU,MAAM,IAAI,UACvC,GAAIA,EAAI,WAAW,OAAON,CAAK,QAAQ,EAAGI,EAAM,KAAKE,EAAI,MAAM,OAAON,CAAK,SAAS,MAAM,CAAC,UAClFM,EAAI,WAAW,OAAON,CAAK,MAAM,EAAGK,EAAI,KAAKC,EAAI,MAAM,OAAON,CAAK,OAAO,MAAM,CAAC,MACrF,OAAM,IAAI,SACjB,CACA,IAAMO,EAAWC,EAAQR,EAAO,CAAE,MAAAI,EAAO,IAAAC,CAAI,CAAC,EAC9C,GAAIE,EAAS,SAAWL,EAAO,KAAK,QAAUK,EAAS,KAAK,CAACD,EAAKG,IAAMH,IAAQJ,EAAO,KAAKO,CAAC,CAAC,EAAG,MAAM,IAAI,UAC3GN,EAAYO,EAAe,CAAE,GAAGT,EAAO,aAAc,CAAE,MAAAG,EAAO,IAAAC,CAAI,EAAG,QAAUM,IAAkB,CAAE,KAAMA,EAAK,eAAgB,CAAC,CAAE,EAAG,CAAC,CACvI,MAAQ,CAAE,MAAM,IAAI,UAAU,mCAAmC,CAAG,CACpE,IAAMC,EAAM,IAAI,IAAI,WAAWlB,EAAQ,SAAS,mBAAmBA,EAAQ,UAAU,eAAeA,EAAQ,OAAO,EAAE,EACrHkB,EAAI,aAAa,IAAI,QAAST,EAAU,KAAK,EAC7CS,EAAI,aAAa,IAAI,cAAe,WAAW,EAC/C,QAAWC,KAAO,OAAO,KAAKV,EAAU,MAAM,EAAE,KAAK,EAAGS,EAAI,aAAa,IAAI,IAAIC,CAAG,GAAI,KAAK,UAAUV,EAAU,OAAOU,CAAG,CAAC,CAAC,EAC7H,IAAMC,EAAa,IAAI,gBACnBC,EACAC,EAAU,GACRC,EAAS,IAAY,CACzBH,EAAW,MAAM,EACbC,GAAiBA,EAAW,OAAO,EAAE,MAAM,IAAM,CAAC,CAAC,CACzD,EACIG,EACEC,EAAW,IAAI,QAAkDC,GAAY,CACjFF,EAAQ,WAAW,IAAM,CACvBF,EAAU,GACVC,EAAO,EACPG,EAAQ,CAAE,GAAI,GAAO,OAAQ,SAAU,CAAC,CAC1C,EAAGvB,CAAS,CACd,CAAC,EACKwB,EAAO,SAA8D,CACzE,GAAI,CAEF,IAAMC,EAAW,MAAOvB,GAAa,WAAW,OAAOa,EAAI,KAAM,CAC/D,OAAQ,MAAO,SAAU,QAAS,OAAQE,EAAW,OACrD,QAAShB,IAAU,OAAY,CAAC,EAAI,CAAE,cAAe,UAAUA,CAAK,EAAG,EACvE,KAAM,CAAE,WAAYI,EAAO,kBAAmB,KAAM,CAAC,GAAGA,EAAO,IAAI,CAAE,CACvE,CAAC,EACD,GAAIc,EAAW,OAAKM,EAAS,MAAM,OAAO,EAAE,MAAM,IAAM,CAAC,CAAC,EAAU,CAAE,GAAI,GAAO,OAAQ,SAAU,EACnG,GAAI,CAACA,EAAS,GAAI,CACXA,EAAS,MAAM,OAAO,EAAE,MAAM,IAAM,CAAC,CAAC,EAC3C,IAAMC,EAASD,EAAS,OAGxB,MAAO,CAAE,GAAI,GAAO,OAFLC,IAAW,IAAM,aAAeA,IAAW,KAAOA,IAAW,IAAM,aAC9EA,IAAW,IAAM,aAAe,WACR,OAAAA,CAAO,CACrC,CACA,GAAI,CAACD,EAAS,KAAM,MAAO,CAAE,GAAI,GAAO,OAAQ,WAAY,EAC5DP,EAAaO,EAAS,KAAK,UAAU,EACrC,IAAIE,EAAQ,EACRC,EAAO,GACLC,EAAU,IAAI,YAAY,QAAS,CAAE,MAAO,EAAK,CAAC,EACxD,OAAa,CACX,IAAMC,EAAQ,MAAMZ,EAAW,KAAK,EACpC,GAAIC,EAAS,MAAO,CAAE,GAAI,GAAO,OAAQ,SAAU,EACnD,GAAIW,EAAM,KAAM,MAEhB,GADAH,GAASG,EAAM,MAAM,WACjBH,EAAQhC,EAAkB,OAAAyB,EAAO,EAAU,CAAE,GAAI,GAAO,OAAQ,WAAY,EAChF,GAAI,CAAEQ,GAAQC,EAAQ,OAAOC,EAAM,MAAO,CAAE,OAAQ,EAAK,CAAC,CAAG,MACvD,CAAE,OAAAV,EAAO,EAAU,CAAE,GAAI,GAAO,OAAQ,WAAY,CAAG,CAC/D,CACA,GAAI,CACFQ,GAAQC,EAAQ,OAAO,EACvB,IAAME,EAAoB,KAAK,MAAMH,CAAI,EACzC,MAAI,CAACG,GAAY,OAAOA,GAAa,UAAY,MAAM,QAAQA,CAAQ,GAAK,CAAC,OAAO,OAAOA,EAAU,QAAQ,EAAU,CAAE,GAAI,GAAO,OAAQ,WAAY,EACjJ,CAAE,GAAI,GAAM,MAAQA,EAAqC,MAAO,CACzE,MAAQ,CAAE,MAAO,CAAE,GAAI,GAAO,OAAQ,WAAY,CAAG,CACvD,MAAQ,CAAE,MAAO,CAAE,GAAI,GAAO,OAAQZ,EAAU,UAAY,SAAU,CAAG,CAC3E,EACA,GAAI,CAAE,OAAO,MAAM,QAAQ,KAAK,CAACK,EAAK,EAAGF,CAAQ,CAAC,CAAG,QACrD,CAAU,aAAaD,CAAK,CAAG,CACjC,CACF,CAAsB,CACxB,CAEO,SAASW,EAAqBC,EAAkE,CACrG,OAAOrC,EAAY,CAAE,UAAWqC,EAAI,kBAAmB,QAASA,EAAI,eAAgB,WAAYA,EAAI,kBAAmB,CAAkB,CAC3I",
|
|
6
6
|
"names": ["TYPE", "ID", "SCOPE", "dependenciesCopy", "dependencies", "types", "type", "ids", "id", "defineCmsQuery", "query", "params", "copied", "key", "descriptor", "value", "cmsTags", "scope", "tags", "RESPONSE_LIMIT", "bindingCopy", "binding", "createSanityAdapter", "options", "timeoutMs", "token", "fetchImpl", "scope", "query", "policy", "validated", "types", "ids", "tag", "expected", "cmsTags", "i", "defineCmsQuery", "raw", "url", "key", "controller", "bodyReader", "expired", "cancel", "timer", "deadline", "resolve", "work", "response", "status", "bytes", "text", "decoder", "chunk", "envelope", "sanityBindingFromEnv", "env"]
|
|
7
7
|
}
|
package/dist/server.cjs
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var R=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var J=(n,e)=>{for(var t in e)R(n,t,{get:e[t],enumerable:!0})},Q=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of z(e))!B.call(n,r)&&r!==t&&R(n,r,{get:()=>e[r],enumerable:!(o=F(e,r))||o.enumerable});return n};var H=n=>Q(R({},"__esModule",{value:!0}),n);var on={};J(on,{MENU_DECORATIONS:()=>A,MENU_LAYOUTS:()=>_,MENU_LAYOUT_DEFAULTS:()=>O,createCmsReader:()=>v,menuQuery:()=>U,menuTags:()=>I,parseMenuDocument:()=>$});module.exports=H(on);var Sn=require("server-only");function M(n){if(!Array.isArray(n))return!1;for(let e=0;e<n.length;e+=1)if(!Object.hasOwn(n,e))return!1;return!0}var _=["stacked","columns"],A=["none","playful"],O={layout:"stacked",decoration:"none"},T=`_type, _id, _rev, _updatedAt, title, locationKeys, note, signOff,
|
|
2
|
+
variants[]{_key, label, note, sections[]{_key, title, service, items[]{
|
|
3
|
+
_key, name, description, priceNote, dietary, allergenNote, availability,
|
|
4
|
+
prices[]{_key, label, amount{minor, currency}}, extras[]{_key, name, amount{minor, currency}}
|
|
5
|
+
}}}`;function I(n,e){return C(n,{types:["menu"],...e===void 0?{}:{ids:[e]}})}function s(n,e){throw new h("menu",[`${n} ${e}`])}function x(n,e,t=new Set,o){if(n===null||typeof n=="string"||typeof n=="boolean"||typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="object"||n===null)return s(e,"is not plain JSON data");try{if(t.has(n))return s(e,"is not acyclic JSON data");let r=Array.isArray(n),u=Object.getPrototypeOf(n);if(r?u!==Array.prototype:u!==Object.prototype&&u!==null)return s(e,"is not an ordinary saved object");t.add(n);let c=Reflect.ownKeys(n),b=r?[]:{},k=0,p=0;for(let i of c){if(typeof i!="string")return s(e,"has a symbol key");let l=r&&i!=="length"?`${e}[${i}]`:`${e}.${i}`,d;try{d=i==="_id"&&o!==void 0?o:Object.getOwnPropertyDescriptor(n,i)}catch{return s(l,"could not be snapshotted as plain JSON data")}if(!d||!Object.hasOwn(d,"value"))return s(l,"is not a saved data property");if(r&&i==="length"){let S=d.value;if(typeof S!="number"||!Number.isSafeInteger(S)||S<0)return s(l,"is not a saved list length");k=S;continue}if(!d.enumerable||r&&!/^(0|[1-9]\d*)$/.test(i))return s(l,"is not a JSON data property");let w=d.value,y=x(w,l,t);Object.defineProperty(b,i,{value:y,enumerable:!0,writable:!0,configurable:!0}),p++}return r&&(p!==k||b.length!==k)?s(e,"is not a complete saved list"):b}catch(r){if(r instanceof h)throw r;return s(e,"could not be snapshotted as plain JSON data")}finally{t.delete(n)}}function g(n,e){return n===null||typeof n!="object"||Array.isArray(n)||Object.getPrototypeOf(n)!==Object.prototype&&Object.getPrototypeOf(n)!==null?s(e,"is not an ordinary saved object"):n}function a(n,e,t=!0){return typeof n!="string"||t&&n.trim()===""?s(e,"is not saved text"):n}function f(n,e,t){return n[e]===void 0||n[e]===null?{}:{[e]:a(n[e],`${t}.${e}`,!1)}}function m(n,e,t){return n==null?[]:M(n)?n.map((o,r)=>t(o,`${e}[${String(r)}]`)):s(e,"is not a complete saved list")}function D(n,e){let t=g(n,e);if(typeof t.minor!="number"||!Number.isSafeInteger(t.minor)||t.minor<0)return s(`${e}.minor`,"is not a whole non-negative safe amount");let o=a(t.currency,`${e}.currency`);return/^[A-Z]{3}$/.test(o)?{minor:t.minor,currency:o}:s(`${e}.currency`,"is not a three-letter currency code")}function Y(n,e){let t=g(n,e);return{_key:a(t._key,`${e}._key`),amount:D(t.amount,`${e}.amount`),...f(t,"label",e)}}function G(n,e){let t=g(n,e);return{_key:a(t._key,`${e}._key`),name:a(t.name,`${e}.name`),amount:D(t.amount,`${e}.amount`)}}function W(n,e){let t=g(n,e),o=t.availability??"available";return o!=="available"&&o!=="sold-out"&&o!=="hidden"?s(`${e}.availability`,"is not an availability choice"):{_key:a(t._key,`${e}._key`),name:a(t.name,`${e}.name`),...f(t,"description",e),...f(t,"priceNote",e),...f(t,"allergenNote",e),prices:m(t.prices,`${e}.prices`,Y),extras:m(t.extras,`${e}.extras`,G),dietary:m(t.dietary,`${e}.dietary`,a),availability:o}}function Z(n,e){let t=g(n,e);return{_key:a(t._key,`${e}._key`),title:a(t.title,`${e}.title`),...f(t,"service",e),items:m(t.items,`${e}.items`,W)}}function K(n,e){let t=g(n,e);return{_key:a(t._key,`${e}._key`),label:a(t.label,`${e}.label`),...f(t,"note",e),sections:m(t.sections,`${e}.sections`,Z)}}function V(n){if(n===null||typeof n!="object"||Array.isArray(n))return!1;let e=n._id;return typeof e=="string"&&e.trim()!==""&&!/^(drafts|versions)\./.test(e)}function $(n,e="menu"){return X(x(n,e),e)}function X(n,e){let t=g(n,e);if(t._type!=="menu")return s(`${e}._type`,"is not menu");if(!V(t))return s(`${e}._id`,"is not a published menu identity");let o=a(t._updatedAt,`${e}._updatedAt`);if(!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(o)||!Number.isFinite(Date.parse(o)))return s(`${e}._updatedAt`,"is not an update date");let r=m(t.variants,`${e}.variants`,K);return r.length===0?s(`${e}.variants`,"has no menu choices"):{_type:"menu",_id:a(t._id,`${e}._id`),_rev:a(t._rev,`${e}._rev`),_updatedAt:o,title:a(t.title,`${e}.title`),locationKeys:m(t.locationKeys,`${e}.locationKeys`,a),variants:r,...f(t,"note",e),...Object.hasOwn(t,"signOff")?{signOff:t.signOff}:{}}}function N(n){if(n===null)return!0;try{return $(n),!0}catch{return!1}}var P="malformed-content",h=class extends Error{code=P;documentId;problems;constructor(e,t){super(`${P}: ${e}: ${t.join("; ")}`),this.name="MalformedContentError",this.documentId=e,this.problems=t}};var j=`{..., "sections": coalesce(sections[]{..., _type == "menuBlock" => {menu->{${T}}}}, sections)}`,fn=`*[_type == "page" && defined(slug.current)]|order(slug.current asc)${j}`,mn=`*[_type == "page" && slug.current == $slug][0]${j}`;var nn=/^[A-Za-z][A-Za-z0-9_]{0,63}$/,en=/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/,tn=/^[a-z0-9]{6,12}\.[a-z][a-z0-9_-]{0,63}$/;function q(n){if(!n||!Array.isArray(n.types)||n.types.length===0)throw new TypeError("CMS dependencies require document types");let e=[...n.types];for(let o of e)if(typeof o!="string"||!nn.test(o))throw new TypeError("Invalid CMS document type");if(n.ids!==void 0&&!Array.isArray(n.ids))throw new TypeError("Invalid CMS document IDs");let t=n.ids===void 0?void 0:[...n.ids];for(let o of t??[])if(typeof o!="string"||!en.test(o)||/^(drafts|versions)\./.test(o))throw new TypeError("Invalid CMS document ID");if(new Set(e).size+new Set(t).size>128)throw new TypeError("Too many CMS tags");return Object.freeze({types:Object.freeze(e),...t===void 0?{}:{ids:Object.freeze(t)}})}function E(n){if(!n||typeof n.name!="string"||!/^[A-Za-z][A-Za-z0-9_.-]{0,127}$/.test(n.name)||typeof n.query!="string"||n.query.trim()===""||typeof n.resolve!="function")throw new TypeError("Invalid CMS query configuration");let e=n.params;if(!e||typeof e!="object"||Object.getPrototypeOf(e)!==Object.prototype&&Object.getPrototypeOf(e)!==null)throw new TypeError("CMS params must be plain JSON scalars");let t={};for(let o of Reflect.ownKeys(e)){let r=Object.getOwnPropertyDescriptor(e,o);if(typeof o!="string"||!r||!Object.hasOwn(r,"value")||!r.enumerable)throw new TypeError("CMS params must be plain JSON scalars");let u=r.value;if(!(u===null||typeof u=="string"||typeof u=="boolean"||typeof u=="number"&&Number.isFinite(u)))throw new TypeError("CMS params must be plain JSON scalars");Object.defineProperty(t,o,{value:u,enumerable:!0})}return Object.freeze({name:n.name,query:n.query,params:Object.freeze(t),dependencies:q(n.dependencies),resolve:n.resolve})}function C(n,e){if(typeof n!="string"||n.length>77||!tn.test(n))throw new TypeError("Invalid CMS scope");let t=q(e),o=[...[...new Set(t.types)].sort().map(r=>`cms:${n}:type:${r}`),...[...new Set(t.ids??[])].sort().map(r=>`cms:${n}:id:${r}`)];return Object.freeze(o)}function U(n){return E({name:"menu.v1",query:`*[_type == "menu" && _id == $id && !(_id in path("drafts.**")) && !(_id in path("versions.**"))][0]{${T}}`,params:{id:n},dependencies:{types:["menu"],ids:[n]},resolve:(e,t)=>{if(!N(t)||t!==null&&t._id!==n)throw new TypeError("Invalid CMS menu fallback");if(e==null)return{data:t,fallbackFields:["$"]};let o=$(e);if(o._id!==n)throw new h("menu",["menu._id does not match the requested document"]);return{data:o,fallbackFields:[]}}})}function L(n){if(!n||!Object.hasOwn(n,"data")||!Array.isArray(n.fallbackFields)||![...n.fallbackFields].every(e=>typeof e=="string"&&(e==="$"||/^[A-Za-z][A-Za-z0-9_.[\]-]{0,127}$/.test(e))))throw new TypeError("Invalid CMS resolution");if(n.warnings!==void 0&&(!Array.isArray(n.warnings)||![...n.warnings].every(e=>e==="siteHero.layout.defaulted"||e==="siteHero.tagline.dropped"||e==="siteHero.taglines.defaulted")))throw new TypeError("Invalid CMS resolution warnings");return{data:n.data,fallbackFields:Object.freeze([...new Set(n.fallbackFields)]),...n.warnings?.length?{warnings:Object.freeze([...new Set(n.warnings)])}:{}}}function v(n){let e=n?.revalidateSeconds??3600;if(!Number.isSafeInteger(e)||e<3600||!n?.adapter||typeof n.adapter.read!="function"||n.onDiagnostic!==void 0&&typeof n.onDiagnostic!="function")throw new TypeError("Invalid CMS reader configuration");let t=n.adapter;C(t.scope,{types:["ScopeValidation"]});let o=r=>{try{n.onDiagnostic?n.onDiagnostic(r):console.warn(JSON.stringify(r))}catch{}};return{async read(r,u){let c,b,k;try{if(c=E(r),k=C(t.scope,c.dependencies),!u||!Object.hasOwn(u,"fallback"))throw new TypeError;b=L(c.resolve(null,u.fallback))}catch{throw new TypeError("Invalid CMS query or fallback configuration")}let p=(d,w,y)=>(o({event:"cms.fallback",query:c.name,reason:d,fields:["$"],...w===void 0?{}:{status:w},...y?{warnings:y}:{}}),{data:b.data,source:"fallback",fallbackFields:["$"],reason:d,...y?{warnings:y}:{}}),i;try{i=await t.read({name:c.name,query:c.query,params:c.params},{tags:k,revalidateSeconds:e})}catch{return p("network")}if(!i.ok){let w=["configuration","network","timeout","rate-limit","upstream","plan-limit","permission","malformed"].includes(i.reason)?i.reason:"malformed",y=Number.isInteger(i.status)&&(i.status??0)>=100&&(i.status??0)<=599?i.status:void 0;return p(w,y)}if(i.value===null||i.value===void 0)return p("missing");let l;try{l=L(c.resolve(i.value,u.fallback))}catch{return p("malformed")}return l.fallbackFields.includes("$")?{...p("invalid-field",void 0,l.warnings),data:l.data}:l.fallbackFields.length>0?(o({event:"cms.partial-fallback",query:c.name,reason:"invalid-field",fields:l.fallbackFields,...l.warnings?{warnings:l.warnings}:{}}),{...l,source:"mixed",reason:"invalid-field"}):{...l,source:"cms"}}}}0&&(module.exports={MENU_DECORATIONS,MENU_LAYOUTS,MENU_LAYOUT_DEFAULTS,createCmsReader,menuQuery,menuTags,parseMenuDocument});
|
|
2
6
|
//# sourceMappingURL=server.cjs.map
|