@kotao/storefront 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +50 -2
  2. package/dist/bridge-ZKbKqgFd.d.ts +239 -0
  3. package/dist/cart-documents-BLavRDiu.d.ts +89 -0
  4. package/dist/cart-documents.d.ts +1 -2
  5. package/dist/cart-documents.js +1 -1
  6. package/dist/{chunk-M7BPQ54D.js → chunk-2MRB6SMP.js} +4 -3
  7. package/dist/chunk-2MRB6SMP.js.map +1 -0
  8. package/dist/chunk-CKGI3Y7L.js +19 -0
  9. package/dist/chunk-CKGI3Y7L.js.map +1 -0
  10. package/dist/{chunk-4TEFGD42.js → chunk-EG34HLSX.js} +209 -162
  11. package/dist/chunk-EG34HLSX.js.map +1 -0
  12. package/dist/chunk-O6YZEY7X.js +1382 -0
  13. package/dist/chunk-O6YZEY7X.js.map +1 -0
  14. package/dist/{chunk-7MTCGXIG.js → chunk-R4N565GX.js} +8 -4
  15. package/dist/chunk-R4N565GX.js.map +1 -0
  16. package/dist/{chunk-XMTWFJCZ.js → chunk-RFM27BKZ.js} +31 -7
  17. package/dist/chunk-RFM27BKZ.js.map +1 -0
  18. package/dist/{chunk-MYDKIJRH.js → chunk-SVMYFYIA.js} +2 -2
  19. package/dist/{chunk-MYDKIJRH.js.map → chunk-SVMYFYIA.js.map} +1 -1
  20. package/dist/{chunk-H3D7BAOL.js → chunk-VOTBNOWH.js} +21 -3
  21. package/dist/chunk-VOTBNOWH.js.map +1 -0
  22. package/dist/{chunk-PXVDVUFX.js → chunk-W74FGUZH.js} +10 -3
  23. package/dist/chunk-W74FGUZH.js.map +1 -0
  24. package/dist/{chunk-2IWNUDSZ.js → chunk-WNXI3MPM.js} +2 -2
  25. package/dist/chunk-WNXI3MPM.js.map +1 -0
  26. package/dist/chunk-XXNCFWXT.js +2118 -0
  27. package/dist/chunk-XXNCFWXT.js.map +1 -0
  28. package/dist/{client-bsiNPHBi.d.ts → client-CwOPPpFF.d.ts} +11 -1
  29. package/dist/{createCartHandler-C4RrPwSG.d.ts → createCartHandler-7DdKB-GF.d.ts} +1 -1
  30. package/dist/custom-css-Bl7Ur3-H.d.ts +6 -0
  31. package/dist/editor.d.ts +57 -104
  32. package/dist/editor.js +270 -1
  33. package/dist/editor.js.map +1 -1
  34. package/dist/events-react.d.ts +1 -1
  35. package/dist/events-react.js +1 -1
  36. package/dist/events.d.ts +3 -3
  37. package/dist/events.js +1 -1
  38. package/dist/{fetch-M3Y-fQrW.d.ts → fetch-Bq_cc8_G.d.ts} +5 -0
  39. package/dist/hydrogen-Bu7k0kE4.d.ts +259 -0
  40. package/dist/index.d.ts +74 -51
  41. package/dist/index.js +19 -15
  42. package/dist/index.js.map +1 -1
  43. package/dist/react-router.d.ts +30 -9
  44. package/dist/react-router.js +16 -7
  45. package/dist/react-router.js.map +1 -1
  46. package/dist/react.d.ts +79 -11
  47. package/dist/react.js +279 -10
  48. package/dist/react.js.map +1 -1
  49. package/dist/{routing-sEonP93J.d.ts → routing-Bz3Cg0BW.d.ts} +36 -6
  50. package/dist/seo.d.ts +7 -4
  51. package/dist/seo.js +2 -2
  52. package/dist/settings.d.ts +14 -4
  53. package/dist/settings.js +2 -2
  54. package/dist/{shop-BJSvtmnV.d.ts → shop-CnrnSAJw.d.ts} +33 -6
  55. package/dist/{store-CtCWHI8H.d.ts → store-DO08fzJi.d.ts} +1 -1
  56. package/dist/storefront-api-types.d.ts +12 -0
  57. package/dist/{types-BDhHWZsP.d.ts → types-BkY0yET-.d.ts} +3 -3
  58. package/dist/{types-bcbQzx87.d.ts → types-DZX8ScsJ.d.ts} +2 -0
  59. package/package.json +4 -4
  60. package/dist/cart-documents-CwwRTvm8.d.ts +0 -21
  61. package/dist/chunk-2IWNUDSZ.js.map +0 -1
  62. package/dist/chunk-4TEFGD42.js.map +0 -1
  63. package/dist/chunk-7MTCGXIG.js.map +0 -1
  64. package/dist/chunk-H3D7BAOL.js.map +0 -1
  65. package/dist/chunk-M7BPQ54D.js.map +0 -1
  66. package/dist/chunk-PXVDVUFX.js.map +0 -1
  67. package/dist/chunk-PXZ737N3.js +0 -439
  68. package/dist/chunk-PXZ737N3.js.map +0 -1
  69. package/dist/chunk-XMTWFJCZ.js.map +0 -1
package/dist/editor.d.ts CHANGED
@@ -1,112 +1,65 @@
1
- import { T as ThemeSettingsStore, R as ResolvedSettings, c as ResolvedSection, b as ResolvedBlock } from './store-CtCWHI8H.js';
1
+ export { C as CreateStorefrontEditorBridgeArgs, b as CreateStorefrontEditorHostBridgeArgs, c as StorefrontEditorAppExtensionPreview, d as StorefrontEditorBlockSchema, e as StorefrontEditorBridge, f as StorefrontEditorCanvasAction, g as StorefrontEditorCanvasBlockAction, h as StorefrontEditorCanvasPosition, i as StorefrontEditorCanvasSectionAction, j as StorefrontEditorDocument, k as StorefrontEditorHostBridge, l as StorefrontEditorMessageEvent, S as StorefrontEditorMessageSource, a as StorefrontEditorMessageTarget, m as StorefrontEditorReady, n as StorefrontEditorRect, o as StorefrontEditorSectionPreset, p as StorefrontEditorSectionPresetBlock, q as StorefrontEditorSectionSchema, r as StorefrontEditorSelection, s as StorefrontEditorSelectionScope, t as StorefrontEditorSettingInput, u as StorefrontEditorSettingOption, v as StorefrontEditorThemeStyle, w as StorefrontEditorValuesDocument, x as createStorefrontEditorBridge, y as createStorefrontEditorHostBridge, z as positionStorefrontEditorCanvasToolbar } from './bridge-ZKbKqgFd.js';
2
+ export { S as STOREFRONT_SECTION_CUSTOM_CSS_SETTING, s as scopeStorefrontSectionCss } from './custom-css-Bl7Ur3-H.js';
3
+ export { HOSTED_SURFACE_DESIGN_INPUTS, HydrogenEditorManifest, HydrogenEditorManifestSchema } from '@kotao/storefront-contracts';
4
+ import { H as HydrogenEditorSecurityContext, C as CreateHydrogenEditorPreviewRuntimeArgs, a as HydrogenEditorPreviewRuntime } from './hydrogen-Bu7k0kE4.js';
5
+ export { b as CreateHydrogenEditorHostBridgeArgs, c as CreateHydrogenEditorSourceProjectionArgs, d as HYDROGEN_EDITOR_BRIDGE_LIMITS, e as HYDROGEN_EDITOR_PROTOCOL_VERSION, f as HydrogenEditorApplyResult, g as HydrogenEditorCanvasDispatchResult, h as HydrogenEditorCanvasIntent, i as HydrogenEditorCapabilityReason, j as HydrogenEditorConfigurationError, k as HydrogenEditorHostBridge, l as HydrogenEditorInstanceSnapshot, m as HydrogenEditorOperationBase, n as HydrogenEditorOperationFailure, o as HydrogenEditorOperationFailureCode, p as HydrogenEditorPreviewOperation, q as HydrogenEditorPreviewSnapshot, r as HydrogenEditorPreviewStore, s as HydrogenEditorProtocolFailure, t as HydrogenEditorProtocolFailureCode, u as HydrogenEditorReadyDocument, v as HydrogenEditorReadyInstance, w as HydrogenEditorReconciliation, x as HydrogenEditorReconciliationReason, y as createHydrogenEditorHostBridge, z as createHydrogenEditorPreviewRuntime, A as createHydrogenEditorSourceProjection, B as parseHydrogenEditorCanvasIntent, D as resolveHydrogenEditorStyles } from './hydrogen-Bu7k0kE4.js';
6
+ import './store-DO08fzJi.js';
2
7
 
3
- interface StorefrontEditorMessageTarget {
4
- postMessage(message: unknown, targetOrigin: string): void;
5
- }
6
- interface StorefrontEditorMessageEvent {
7
- readonly origin: string;
8
- readonly data: unknown;
9
- readonly source?: StorefrontEditorMessageTarget | null;
10
- }
11
- interface StorefrontEditorMessageSource {
12
- addEventListener(type: 'message', listener: (event: StorefrontEditorMessageEvent) => void): void;
13
- removeEventListener(type: 'message', listener: (event: StorefrontEditorMessageEvent) => void): void;
14
- }
15
- interface StorefrontEditorBridge {
16
- ready(): void;
17
- selectSection(sectionId: string): void;
18
- dispose(): void;
19
- }
20
- interface StorefrontEditorSettingOption {
21
- readonly value: string;
22
- readonly label: string;
23
- }
24
- interface StorefrontEditorSettingInput {
25
- readonly type: string;
26
- readonly name: string;
27
- readonly label: string;
28
- readonly defaultValue?: unknown;
29
- readonly placeholder?: string;
30
- readonly helpText?: string;
31
- readonly options?: readonly StorefrontEditorSettingOption[];
32
- readonly min?: number;
33
- readonly max?: number;
34
- readonly step?: number;
35
- readonly unit?: string;
36
- }
37
- interface StorefrontEditorBlockSchema {
38
- readonly type: string;
39
- readonly label: string;
40
- readonly settings: readonly StorefrontEditorSettingInput[];
41
- }
42
- interface StorefrontEditorSectionPresetBlock {
43
- readonly type: string;
44
- readonly settings?: ResolvedSettings;
45
- }
46
- interface StorefrontEditorSectionPreset {
47
- readonly name: string;
48
- readonly settings?: ResolvedSettings;
49
- readonly blocks?: readonly StorefrontEditorSectionPresetBlock[];
50
- }
51
- interface StorefrontEditorSectionSchema {
52
- readonly type: string;
53
- readonly label: string;
54
- readonly settings: readonly StorefrontEditorSettingInput[];
55
- readonly blocks?: readonly StorefrontEditorBlockSchema[];
56
- readonly presets?: readonly StorefrontEditorSectionPreset[];
57
- }
58
- interface StorefrontEditorSelection {
59
- readonly sectionId: string;
60
- readonly section?: ResolvedSection;
61
- readonly sections?: readonly ResolvedSection[];
62
- readonly schema?: StorefrontEditorSectionSchema;
63
- readonly schemas?: Readonly<Record<string, StorefrontEditorSectionSchema>>;
8
+ declare const GRANT_VERSION: 1;
9
+ type HydrogenEditorPreviewGrantErrorCode = 'INVALID_BASE_SHA' | 'INVALID_CHANNEL_NONCE' | 'INVALID_ENVIRONMENT' | 'INVALID_MANIFEST_HASH' | 'INVALID_PREVIEW_ORIGIN' | 'INVALID_SESSION_ID' | 'INVALID_SITE_ID' | 'INVALID_TIME' | 'INVALID_TTL' | 'INVALID_WORKSPACES_ORIGIN' | 'WEAK_SECRET';
10
+ declare class HydrogenEditorPreviewGrantError extends Error {
11
+ readonly code: HydrogenEditorPreviewGrantErrorCode;
12
+ constructor(code: HydrogenEditorPreviewGrantErrorCode, message: string);
13
+ }
14
+ interface HydrogenEditorPreviewGrantBinding {
15
+ readonly sessionId: string;
16
+ readonly siteId: string;
17
+ readonly environment: string;
18
+ readonly baseSha: string;
19
+ readonly manifestHash: string;
20
+ readonly workspacesOrigin: string;
21
+ readonly previewOrigin: string;
22
+ readonly channelNonce: string;
64
23
  }
65
- interface StorefrontEditorValuesDocument {
66
- readonly shopId: string;
67
- readonly sections: readonly ResolvedSection[];
24
+ interface HydrogenEditorPreviewGrantClaims extends HydrogenEditorPreviewGrantBinding {
25
+ readonly version: typeof GRANT_VERSION;
26
+ readonly issuedAt: number;
27
+ readonly expiresAt: number;
68
28
  }
69
- interface StorefrontEditorReady {
70
- readonly sections: readonly ResolvedSection[];
71
- readonly schemas?: Readonly<Record<string, StorefrontEditorSectionSchema>>;
72
- readonly globalInputs?: readonly StorefrontEditorSettingInput[];
73
- readonly templates?: Readonly<Record<string, StorefrontEditorValuesDocument>>;
74
- readonly sectionGroups?: Readonly<Record<string, StorefrontEditorValuesDocument>>;
29
+ interface SignedHydrogenEditorPreviewGrant {
30
+ readonly token: string;
31
+ readonly claims: HydrogenEditorPreviewGrantClaims;
32
+ readonly security: HydrogenEditorSecurityContext;
75
33
  }
76
- interface StorefrontEditorHostBridge {
77
- patchSection(sectionId: string, settings: ResolvedSettings): void;
78
- patchGlobal(settings: ResolvedSettings): void;
79
- insertSection(section: ResolvedSection, index?: number): void;
80
- removeSection(sectionId: string): void;
81
- reorderSection(sectionId: string, index: number): void;
82
- patchBlock(sectionId: string, blockId: string, settings: ResolvedSettings): void;
83
- insertBlock(sectionId: string, block: ResolvedBlock, index?: number): void;
84
- removeBlock(sectionId: string, blockId: string): void;
85
- reorderBlock(sectionId: string, blockId: string, index: number): void;
86
- replaceTemplate(handle: string, document: StorefrontEditorValuesDocument): void;
87
- replaceSectionGroup(handle: string, document: StorefrontEditorValuesDocument): void;
88
- dispose(): void;
34
+ interface SignHydrogenEditorPreviewGrantOptions {
35
+ readonly now: number;
36
+ readonly ttlMs: number;
89
37
  }
90
- interface CreateStorefrontEditorBridgeArgs {
91
- readonly adminOrigin: string;
92
- readonly shopId: string;
93
- readonly store: ThemeSettingsStore;
94
- readonly schemas?: Readonly<Record<string, StorefrontEditorSectionSchema>>;
95
- readonly globalInputs?: readonly StorefrontEditorSettingInput[];
96
- readonly templates?: Readonly<Record<string, StorefrontEditorValuesDocument>>;
97
- readonly sectionGroups?: Readonly<Record<string, StorefrontEditorValuesDocument>>;
98
- readonly transport: StorefrontEditorMessageSource;
99
- readonly target: StorefrontEditorMessageTarget;
38
+ interface VerifyHydrogenEditorPreviewGrantOptions {
39
+ readonly now: number;
100
40
  }
101
- interface CreateStorefrontEditorHostBridgeArgs {
102
- readonly onSelectSection: (selection: StorefrontEditorSelection) => void;
103
- readonly onReady?: (ready: StorefrontEditorReady) => void;
41
+ declare function createHydrogenEditorChannelNonce(): string;
42
+ declare function signHydrogenEditorPreviewGrant(binding: HydrogenEditorPreviewGrantBinding, secret: string, options: SignHydrogenEditorPreviewGrantOptions): Promise<SignedHydrogenEditorPreviewGrant>;
43
+ declare function verifyHydrogenEditorPreviewGrant(token: string, secret: string, expected: HydrogenEditorPreviewGrantBinding, options: VerifyHydrogenEditorPreviewGrantOptions): Promise<HydrogenEditorPreviewGrantClaims | null>;
44
+
45
+ declare const PREVIEW_BOOTSTRAP_VERSION: 1;
46
+ interface HydrogenEditorPreviewBootstrap {
47
+ readonly version: typeof PREVIEW_BOOTSTRAP_VERSION;
48
+ readonly workspacesOrigin: string;
104
49
  readonly previewOrigin: string;
105
- readonly shopId: string;
106
- readonly transport: StorefrontEditorMessageSource;
107
- readonly target: StorefrontEditorMessageTarget;
108
- }
109
- declare function createStorefrontEditorBridge({ adminOrigin, globalInputs, schemas, sectionGroups, shopId, store, target, templates, transport, }: CreateStorefrontEditorBridgeArgs): StorefrontEditorBridge;
110
- declare function createStorefrontEditorHostBridge({ onReady, onSelectSection, previewOrigin, shopId, target, transport, }: CreateStorefrontEditorHostBridgeArgs): StorefrontEditorHostBridge;
50
+ readonly security: HydrogenEditorSecurityContext;
51
+ }
52
+ interface CreateHydrogenEditorPreviewBootstrapArgs {
53
+ readonly token?: string | null;
54
+ readonly secret: string;
55
+ readonly expected: HydrogenEditorPreviewGrantBinding;
56
+ readonly now: number;
57
+ }
58
+ type CreateHydrogenEditorPreviewRuntimeFromBootstrapArgs = Omit<CreateHydrogenEditorPreviewRuntimeArgs, 'adminOrigin' | 'security'> & {
59
+ readonly bootstrap: HydrogenEditorPreviewBootstrap;
60
+ readonly currentOrigin: string;
61
+ };
62
+ declare function createHydrogenEditorPreviewBootstrap({ expected, now, secret, token, }: CreateHydrogenEditorPreviewBootstrapArgs): Promise<HydrogenEditorPreviewBootstrap | null>;
63
+ declare function createHydrogenEditorPreviewRuntimeFromBootstrap({ bootstrap, currentOrigin, ...runtime }: CreateHydrogenEditorPreviewRuntimeFromBootstrapArgs): HydrogenEditorPreviewRuntime;
111
64
 
112
- export { type CreateStorefrontEditorBridgeArgs, type CreateStorefrontEditorHostBridgeArgs, type StorefrontEditorBlockSchema, type StorefrontEditorBridge, type StorefrontEditorHostBridge, type StorefrontEditorMessageEvent, type StorefrontEditorMessageSource, type StorefrontEditorMessageTarget, type StorefrontEditorReady, type StorefrontEditorSectionPreset, type StorefrontEditorSectionPresetBlock, type StorefrontEditorSectionSchema, type StorefrontEditorSelection, type StorefrontEditorSettingInput, type StorefrontEditorSettingOption, type StorefrontEditorValuesDocument, createStorefrontEditorBridge, createStorefrontEditorHostBridge };
65
+ export { type CreateHydrogenEditorPreviewBootstrapArgs, CreateHydrogenEditorPreviewRuntimeArgs, type CreateHydrogenEditorPreviewRuntimeFromBootstrapArgs, type HydrogenEditorPreviewBootstrap, type HydrogenEditorPreviewGrantBinding, type HydrogenEditorPreviewGrantClaims, HydrogenEditorPreviewGrantError, type HydrogenEditorPreviewGrantErrorCode, HydrogenEditorPreviewRuntime, HydrogenEditorSecurityContext, type SignHydrogenEditorPreviewGrantOptions, type SignedHydrogenEditorPreviewGrant, type VerifyHydrogenEditorPreviewGrantOptions, createHydrogenEditorChannelNonce, createHydrogenEditorPreviewBootstrap, createHydrogenEditorPreviewRuntimeFromBootstrap, signHydrogenEditorPreviewGrant, verifyHydrogenEditorPreviewGrant };
package/dist/editor.js CHANGED
@@ -1,3 +1,272 @@
1
- export { createStorefrontEditorBridge, createStorefrontEditorHostBridge } from './chunk-PXZ737N3.js';
1
+ import { HydrogenEditorConfigurationError, createHydrogenEditorPreviewRuntime } from './chunk-XXNCFWXT.js';
2
+ export { HYDROGEN_EDITOR_BRIDGE_LIMITS, HYDROGEN_EDITOR_PROTOCOL_VERSION, HydrogenEditorConfigurationError, createHydrogenEditorHostBridge, createHydrogenEditorPreviewRuntime, createHydrogenEditorSourceProjection, parseHydrogenEditorCanvasIntent, resolveHydrogenEditorStyles } from './chunk-XXNCFWXT.js';
3
+ export { STOREFRONT_SECTION_CUSTOM_CSS_SETTING, createStorefrontEditorBridge, createStorefrontEditorHostBridge, positionStorefrontEditorCanvasToolbar, scopeStorefrontSectionCss } from './chunk-O6YZEY7X.js';
4
+ import { toBase64Url, fromBase64Url } from './chunk-CKGI3Y7L.js';
5
+ export { HOSTED_SURFACE_DESIGN_INPUTS, HydrogenEditorManifestSchema } from '@kotao/storefront-contracts';
6
+
7
+ // src/editor/preview-grant.ts
8
+ var GRANT_VERSION = 1;
9
+ var TOKEN_PREFIX = "v1";
10
+ var SIGNATURE_DOMAIN = "kotao:hydrogen-editor-preview-grant:v1";
11
+ var UUID = /^[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}$/u;
12
+ var ENVIRONMENT = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
13
+ var SHA_1 = /^[a-f0-9]{40}$/u;
14
+ var SHA_256 = /^[a-f0-9]{64}$/u;
15
+ var CHANNEL_NONCE = /^[A-Za-z0-9_-]{43}$/u;
16
+ var BASE64_URL = /^[A-Za-z0-9_-]+$/u;
17
+ var MAX_TTL_MS = 3e5;
18
+ var MAX_TOKEN_CHARS = 4096;
19
+ var MIN_SECRET_BYTES = 32;
20
+ var MAX_SECRET_BYTES = 4096;
21
+ var CLAIM_KEYS = [
22
+ "version",
23
+ "sessionId",
24
+ "siteId",
25
+ "environment",
26
+ "baseSha",
27
+ "manifestHash",
28
+ "workspacesOrigin",
29
+ "previewOrigin",
30
+ "channelNonce",
31
+ "issuedAt",
32
+ "expiresAt"
33
+ ];
34
+ var encoder = new TextEncoder();
35
+ var decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: false });
36
+ var HydrogenEditorPreviewGrantError = class extends Error {
37
+ code;
38
+ constructor(code, message) {
39
+ super(message);
40
+ this.name = "HydrogenEditorPreviewGrantError";
41
+ this.code = code;
42
+ }
43
+ };
44
+ function bytes(value) {
45
+ const copy = new Uint8Array(value.byteLength);
46
+ copy.set(value);
47
+ return copy;
48
+ }
49
+ async function hmacKey(secret) {
50
+ return crypto.subtle.importKey(
51
+ "raw",
52
+ encoder.encode(secret),
53
+ { name: "HMAC", hash: "SHA-256" },
54
+ false,
55
+ ["sign", "verify"]
56
+ );
57
+ }
58
+ function signatureInput(payload) {
59
+ return bytes(encoder.encode(`${SIGNATURE_DOMAIN}
60
+ ${payload}`));
61
+ }
62
+ function isHttpsOrigin(value) {
63
+ try {
64
+ const url = new URL(value);
65
+ return url.protocol === "https:" && url.username === "" && url.password === "" && url.origin === value && url.pathname === "/" && url.search === "" && url.hash === "";
66
+ } catch {
67
+ return false;
68
+ }
69
+ }
70
+ function requireHttpsOrigin(value, code, label) {
71
+ if (!isHttpsOrigin(value)) {
72
+ throw new HydrogenEditorPreviewGrantError(code, `${label} must be an exact HTTPS origin`);
73
+ }
74
+ }
75
+ function validSecret(secret) {
76
+ const secretBytes = encoder.encode(secret).byteLength;
77
+ return secretBytes >= MIN_SECRET_BYTES && secretBytes <= MAX_SECRET_BYTES;
78
+ }
79
+ function validChannelNonce(value) {
80
+ if (!CHANNEL_NONCE.test(value)) return false;
81
+ try {
82
+ const nonce = fromBase64Url(value);
83
+ return nonce.byteLength === 32 && toBase64Url(nonce) === value;
84
+ } catch {
85
+ return false;
86
+ }
87
+ }
88
+ function validateBinding(binding) {
89
+ if (!UUID.test(binding.sessionId)) {
90
+ throw new HydrogenEditorPreviewGrantError(
91
+ "INVALID_SESSION_ID",
92
+ "sessionId must be a canonical lowercase UUID"
93
+ );
94
+ }
95
+ if (!UUID.test(binding.siteId)) {
96
+ throw new HydrogenEditorPreviewGrantError(
97
+ "INVALID_SITE_ID",
98
+ "siteId must be a canonical lowercase UUID"
99
+ );
100
+ }
101
+ if (!ENVIRONMENT.test(binding.environment)) {
102
+ throw new HydrogenEditorPreviewGrantError(
103
+ "INVALID_ENVIRONMENT",
104
+ "environment must be a bounded deployment identifier"
105
+ );
106
+ }
107
+ if (!SHA_1.test(binding.baseSha)) {
108
+ throw new HydrogenEditorPreviewGrantError(
109
+ "INVALID_BASE_SHA",
110
+ "baseSha must be a lowercase 40-character Git SHA"
111
+ );
112
+ }
113
+ if (!SHA_256.test(binding.manifestHash)) {
114
+ throw new HydrogenEditorPreviewGrantError(
115
+ "INVALID_MANIFEST_HASH",
116
+ "manifestHash must be a lowercase SHA-256 digest"
117
+ );
118
+ }
119
+ requireHttpsOrigin(
120
+ binding.workspacesOrigin,
121
+ "INVALID_WORKSPACES_ORIGIN",
122
+ "workspacesOrigin"
123
+ );
124
+ requireHttpsOrigin(binding.previewOrigin, "INVALID_PREVIEW_ORIGIN", "previewOrigin");
125
+ if (!validChannelNonce(binding.channelNonce)) {
126
+ throw new HydrogenEditorPreviewGrantError(
127
+ "INVALID_CHANNEL_NONCE",
128
+ "channelNonce must be a canonical base64url-encoded 256-bit value"
129
+ );
130
+ }
131
+ }
132
+ function validateSigningInput(binding, secret, options) {
133
+ validateBinding(binding);
134
+ if (!validSecret(secret)) {
135
+ throw new HydrogenEditorPreviewGrantError(
136
+ "WEAK_SECRET",
137
+ "preview grant secret must contain 32..4096 UTF-8 bytes"
138
+ );
139
+ }
140
+ if (!Number.isSafeInteger(options.now) || options.now < 0) {
141
+ throw new HydrogenEditorPreviewGrantError(
142
+ "INVALID_TIME",
143
+ "preview grant time must be a non-negative safe integer"
144
+ );
145
+ }
146
+ if (!Number.isSafeInteger(options.ttlMs) || options.ttlMs <= 0 || options.ttlMs > MAX_TTL_MS || !Number.isSafeInteger(options.now + options.ttlMs)) {
147
+ throw new HydrogenEditorPreviewGrantError(
148
+ "INVALID_TTL",
149
+ "preview grant lifetime must be between 1 and 300000 milliseconds"
150
+ );
151
+ }
152
+ }
153
+ function isClaims(value) {
154
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
155
+ const keys = Object.keys(value);
156
+ if (keys.length !== CLAIM_KEYS.length || !CLAIM_KEYS.every((key) => keys.includes(key))) {
157
+ return false;
158
+ }
159
+ const claims = value;
160
+ return claims.version === GRANT_VERSION && typeof claims.sessionId === "string" && UUID.test(claims.sessionId) && typeof claims.siteId === "string" && UUID.test(claims.siteId) && typeof claims.environment === "string" && ENVIRONMENT.test(claims.environment) && typeof claims.baseSha === "string" && SHA_1.test(claims.baseSha) && typeof claims.manifestHash === "string" && SHA_256.test(claims.manifestHash) && typeof claims.workspacesOrigin === "string" && isHttpsOrigin(claims.workspacesOrigin) && typeof claims.previewOrigin === "string" && isHttpsOrigin(claims.previewOrigin) && typeof claims.channelNonce === "string" && validChannelNonce(claims.channelNonce) && typeof claims.issuedAt === "number" && Number.isSafeInteger(claims.issuedAt) && claims.issuedAt >= 0 && typeof claims.expiresAt === "number" && Number.isSafeInteger(claims.expiresAt) && claims.expiresAt > claims.issuedAt && claims.expiresAt - claims.issuedAt <= MAX_TTL_MS;
161
+ }
162
+ function matchesBinding(claims, binding) {
163
+ return claims.sessionId === binding.sessionId && claims.siteId === binding.siteId && claims.environment === binding.environment && claims.baseSha === binding.baseSha && claims.manifestHash === binding.manifestHash && claims.workspacesOrigin === binding.workspacesOrigin && claims.previewOrigin === binding.previewOrigin && claims.channelNonce === binding.channelNonce;
164
+ }
165
+ function createHydrogenEditorChannelNonce() {
166
+ return toBase64Url(crypto.getRandomValues(new Uint8Array(32)));
167
+ }
168
+ async function signHydrogenEditorPreviewGrant(binding, secret, options) {
169
+ validateSigningInput(binding, secret, options);
170
+ const claims = {
171
+ version: GRANT_VERSION,
172
+ ...binding,
173
+ issuedAt: options.now,
174
+ expiresAt: options.now + options.ttlMs
175
+ };
176
+ const payload = toBase64Url(encoder.encode(JSON.stringify(claims)));
177
+ const signature = await crypto.subtle.sign(
178
+ "HMAC",
179
+ await hmacKey(secret),
180
+ signatureInput(payload)
181
+ );
182
+ const token = `${TOKEN_PREFIX}.${payload}.${toBase64Url(new Uint8Array(signature))}`;
183
+ return {
184
+ token,
185
+ claims,
186
+ security: {
187
+ sessionId: claims.sessionId,
188
+ baseSha: claims.baseSha,
189
+ manifestHash: claims.manifestHash,
190
+ channelNonce: claims.channelNonce,
191
+ previewToken: token,
192
+ expiresAt: claims.expiresAt
193
+ }
194
+ };
195
+ }
196
+ async function verifyHydrogenEditorPreviewGrant(token, secret, expected, options) {
197
+ try {
198
+ if (typeof token !== "string" || token.length === 0 || token.length > MAX_TOKEN_CHARS || !validSecret(secret) || !Number.isSafeInteger(options.now) || options.now < 0) {
199
+ return null;
200
+ }
201
+ validateBinding(expected);
202
+ const [prefix, payload, encodedSignature, extra] = token.split(".");
203
+ if (prefix !== TOKEN_PREFIX || payload === void 0 || !BASE64_URL.test(payload) || encodedSignature === void 0 || encodedSignature.length !== 43 || !BASE64_URL.test(encodedSignature) || extra !== void 0) {
204
+ return null;
205
+ }
206
+ const signature = fromBase64Url(encodedSignature);
207
+ if (signature.byteLength !== 32 || toBase64Url(signature) !== encodedSignature) {
208
+ return null;
209
+ }
210
+ const validSignature = await crypto.subtle.verify(
211
+ "HMAC",
212
+ await hmacKey(secret),
213
+ bytes(signature),
214
+ signatureInput(payload)
215
+ );
216
+ if (!validSignature) return null;
217
+ const payloadBytes = fromBase64Url(payload);
218
+ if (toBase64Url(payloadBytes) !== payload) return null;
219
+ const claims = JSON.parse(decoder.decode(payloadBytes));
220
+ if (!isClaims(claims) || !matchesBinding(claims, expected)) return null;
221
+ if (claims.issuedAt > options.now || claims.expiresAt <= options.now) return null;
222
+ return claims;
223
+ } catch {
224
+ return null;
225
+ }
226
+ }
227
+
228
+ // src/editor/preview-bootstrap.ts
229
+ var PREVIEW_BOOTSTRAP_VERSION = 1;
230
+ async function createHydrogenEditorPreviewBootstrap({
231
+ expected,
232
+ now,
233
+ secret,
234
+ token
235
+ }) {
236
+ if (token === void 0 || token === null) return null;
237
+ const claims = await verifyHydrogenEditorPreviewGrant(token, secret, expected, { now });
238
+ if (claims === null) return null;
239
+ return {
240
+ version: PREVIEW_BOOTSTRAP_VERSION,
241
+ workspacesOrigin: claims.workspacesOrigin,
242
+ previewOrigin: claims.previewOrigin,
243
+ security: {
244
+ sessionId: claims.sessionId,
245
+ baseSha: claims.baseSha,
246
+ manifestHash: claims.manifestHash,
247
+ channelNonce: claims.channelNonce,
248
+ previewToken: token,
249
+ expiresAt: claims.expiresAt
250
+ }
251
+ };
252
+ }
253
+ function createHydrogenEditorPreviewRuntimeFromBootstrap({
254
+ bootstrap,
255
+ currentOrigin,
256
+ ...runtime
257
+ }) {
258
+ if (bootstrap.version !== PREVIEW_BOOTSTRAP_VERSION || currentOrigin !== bootstrap.previewOrigin) {
259
+ throw new HydrogenEditorConfigurationError(
260
+ "current preview origin does not match the authenticated editor grant"
261
+ );
262
+ }
263
+ return createHydrogenEditorPreviewRuntime({
264
+ ...runtime,
265
+ adminOrigin: bootstrap.workspacesOrigin,
266
+ security: bootstrap.security
267
+ });
268
+ }
269
+
270
+ export { HydrogenEditorPreviewGrantError, createHydrogenEditorChannelNonce, createHydrogenEditorPreviewBootstrap, createHydrogenEditorPreviewRuntimeFromBootstrap, signHydrogenEditorPreviewGrant, verifyHydrogenEditorPreviewGrant };
2
271
  //# sourceMappingURL=editor.js.map
3
272
  //# sourceMappingURL=editor.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"editor.js"}
1
+ {"version":3,"sources":["../src/editor/preview-grant.ts","../src/editor/preview-bootstrap.ts"],"names":[],"mappings":"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","file":"editor.js","sourcesContent":["import { fromBase64Url, toBase64Url } from '../geo/base64url'\nimport type { HydrogenEditorSecurityContext } from './hydrogen'\n\nconst GRANT_VERSION = 1 as const\nconst TOKEN_PREFIX = 'v1'\nconst SIGNATURE_DOMAIN = 'kotao:hydrogen-editor-preview-grant:v1'\nconst UUID = /^[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}$/u\nconst ENVIRONMENT = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u\nconst SHA_1 = /^[a-f0-9]{40}$/u\nconst SHA_256 = /^[a-f0-9]{64}$/u\nconst CHANNEL_NONCE = /^[A-Za-z0-9_-]{43}$/u\nconst BASE64_URL = /^[A-Za-z0-9_-]+$/u\nconst MAX_TTL_MS = 300_000\nconst MAX_TOKEN_CHARS = 4_096\nconst MIN_SECRET_BYTES = 32\nconst MAX_SECRET_BYTES = 4_096\nconst CLAIM_KEYS = [\n 'version',\n 'sessionId',\n 'siteId',\n 'environment',\n 'baseSha',\n 'manifestHash',\n 'workspacesOrigin',\n 'previewOrigin',\n 'channelNonce',\n 'issuedAt',\n 'expiresAt',\n] as const\nconst encoder = new TextEncoder()\nconst decoder = new TextDecoder('utf-8', { fatal: true, ignoreBOM: false })\n\nexport type HydrogenEditorPreviewGrantErrorCode =\n | 'INVALID_BASE_SHA'\n | 'INVALID_CHANNEL_NONCE'\n | 'INVALID_ENVIRONMENT'\n | 'INVALID_MANIFEST_HASH'\n | 'INVALID_PREVIEW_ORIGIN'\n | 'INVALID_SESSION_ID'\n | 'INVALID_SITE_ID'\n | 'INVALID_TIME'\n | 'INVALID_TTL'\n | 'INVALID_WORKSPACES_ORIGIN'\n | 'WEAK_SECRET'\n\nexport class HydrogenEditorPreviewGrantError extends Error {\n readonly code: HydrogenEditorPreviewGrantErrorCode\n\n constructor(code: HydrogenEditorPreviewGrantErrorCode, message: string) {\n super(message)\n this.name = 'HydrogenEditorPreviewGrantError'\n this.code = code\n }\n}\n\nexport interface HydrogenEditorPreviewGrantBinding {\n readonly sessionId: string\n readonly siteId: string\n readonly environment: string\n readonly baseSha: string\n readonly manifestHash: string\n readonly workspacesOrigin: string\n readonly previewOrigin: string\n readonly channelNonce: string\n}\n\nexport interface HydrogenEditorPreviewGrantClaims extends HydrogenEditorPreviewGrantBinding {\n readonly version: typeof GRANT_VERSION\n readonly issuedAt: number\n readonly expiresAt: number\n}\n\nexport interface SignedHydrogenEditorPreviewGrant {\n readonly token: string\n readonly claims: HydrogenEditorPreviewGrantClaims\n readonly security: HydrogenEditorSecurityContext\n}\n\nexport interface SignHydrogenEditorPreviewGrantOptions {\n readonly now: number\n readonly ttlMs: number\n}\n\nexport interface VerifyHydrogenEditorPreviewGrantOptions {\n readonly now: number\n}\n\nfunction bytes(value: Uint8Array): Uint8Array<ArrayBuffer> {\n const copy = new Uint8Array(value.byteLength)\n copy.set(value)\n return copy\n}\n\nasync function hmacKey(secret: string): Promise<CryptoKey> {\n return crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign', 'verify'],\n )\n}\n\nfunction signatureInput(payload: string): Uint8Array<ArrayBuffer> {\n return bytes(encoder.encode(`${SIGNATURE_DOMAIN}\\n${payload}`))\n}\n\nfunction isHttpsOrigin(value: string): boolean {\n try {\n const url = new URL(value)\n return (\n url.protocol === 'https:' &&\n url.username === '' &&\n url.password === '' &&\n url.origin === value &&\n url.pathname === '/' &&\n url.search === '' &&\n url.hash === ''\n )\n } catch {\n return false\n }\n}\n\nfunction requireHttpsOrigin(\n value: string,\n code: 'INVALID_PREVIEW_ORIGIN' | 'INVALID_WORKSPACES_ORIGIN',\n label: string,\n): void {\n if (!isHttpsOrigin(value)) {\n throw new HydrogenEditorPreviewGrantError(code, `${label} must be an exact HTTPS origin`)\n }\n}\n\nfunction validSecret(secret: string): boolean {\n const secretBytes = encoder.encode(secret).byteLength\n return secretBytes >= MIN_SECRET_BYTES && secretBytes <= MAX_SECRET_BYTES\n}\n\nfunction validChannelNonce(value: string): boolean {\n if (!CHANNEL_NONCE.test(value)) return false\n try {\n const nonce = fromBase64Url(value)\n return nonce.byteLength === 32 && toBase64Url(nonce) === value\n } catch {\n return false\n }\n}\n\nfunction validateBinding(binding: HydrogenEditorPreviewGrantBinding): void {\n if (!UUID.test(binding.sessionId)) {\n throw new HydrogenEditorPreviewGrantError(\n 'INVALID_SESSION_ID',\n 'sessionId must be a canonical lowercase UUID',\n )\n }\n if (!UUID.test(binding.siteId)) {\n throw new HydrogenEditorPreviewGrantError(\n 'INVALID_SITE_ID',\n 'siteId must be a canonical lowercase UUID',\n )\n }\n if (!ENVIRONMENT.test(binding.environment)) {\n throw new HydrogenEditorPreviewGrantError(\n 'INVALID_ENVIRONMENT',\n 'environment must be a bounded deployment identifier',\n )\n }\n if (!SHA_1.test(binding.baseSha)) {\n throw new HydrogenEditorPreviewGrantError(\n 'INVALID_BASE_SHA',\n 'baseSha must be a lowercase 40-character Git SHA',\n )\n }\n if (!SHA_256.test(binding.manifestHash)) {\n throw new HydrogenEditorPreviewGrantError(\n 'INVALID_MANIFEST_HASH',\n 'manifestHash must be a lowercase SHA-256 digest',\n )\n }\n requireHttpsOrigin(\n binding.workspacesOrigin,\n 'INVALID_WORKSPACES_ORIGIN',\n 'workspacesOrigin',\n )\n requireHttpsOrigin(binding.previewOrigin, 'INVALID_PREVIEW_ORIGIN', 'previewOrigin')\n if (!validChannelNonce(binding.channelNonce)) {\n throw new HydrogenEditorPreviewGrantError(\n 'INVALID_CHANNEL_NONCE',\n 'channelNonce must be a canonical base64url-encoded 256-bit value',\n )\n }\n}\n\nfunction validateSigningInput(\n binding: HydrogenEditorPreviewGrantBinding,\n secret: string,\n options: SignHydrogenEditorPreviewGrantOptions,\n): void {\n validateBinding(binding)\n if (!validSecret(secret)) {\n throw new HydrogenEditorPreviewGrantError(\n 'WEAK_SECRET',\n 'preview grant secret must contain 32..4096 UTF-8 bytes',\n )\n }\n if (!Number.isSafeInteger(options.now) || options.now < 0) {\n throw new HydrogenEditorPreviewGrantError(\n 'INVALID_TIME',\n 'preview grant time must be a non-negative safe integer',\n )\n }\n if (\n !Number.isSafeInteger(options.ttlMs) ||\n options.ttlMs <= 0 ||\n options.ttlMs > MAX_TTL_MS ||\n !Number.isSafeInteger(options.now + options.ttlMs)\n ) {\n throw new HydrogenEditorPreviewGrantError(\n 'INVALID_TTL',\n 'preview grant lifetime must be between 1 and 300000 milliseconds',\n )\n }\n}\n\nfunction isClaims(value: unknown): value is HydrogenEditorPreviewGrantClaims {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n const keys = Object.keys(value)\n if (keys.length !== CLAIM_KEYS.length || !CLAIM_KEYS.every((key) => keys.includes(key))) {\n return false\n }\n const claims = value as Partial<HydrogenEditorPreviewGrantClaims>\n return (\n claims.version === GRANT_VERSION &&\n typeof claims.sessionId === 'string' &&\n UUID.test(claims.sessionId) &&\n typeof claims.siteId === 'string' &&\n UUID.test(claims.siteId) &&\n typeof claims.environment === 'string' &&\n ENVIRONMENT.test(claims.environment) &&\n typeof claims.baseSha === 'string' &&\n SHA_1.test(claims.baseSha) &&\n typeof claims.manifestHash === 'string' &&\n SHA_256.test(claims.manifestHash) &&\n typeof claims.workspacesOrigin === 'string' &&\n isHttpsOrigin(claims.workspacesOrigin) &&\n typeof claims.previewOrigin === 'string' &&\n isHttpsOrigin(claims.previewOrigin) &&\n typeof claims.channelNonce === 'string' &&\n validChannelNonce(claims.channelNonce) &&\n typeof claims.issuedAt === 'number' &&\n Number.isSafeInteger(claims.issuedAt) &&\n claims.issuedAt >= 0 &&\n typeof claims.expiresAt === 'number' &&\n Number.isSafeInteger(claims.expiresAt) &&\n claims.expiresAt > claims.issuedAt &&\n claims.expiresAt - claims.issuedAt <= MAX_TTL_MS\n )\n}\n\nfunction matchesBinding(\n claims: HydrogenEditorPreviewGrantClaims,\n binding: HydrogenEditorPreviewGrantBinding,\n): boolean {\n return (\n claims.sessionId === binding.sessionId &&\n claims.siteId === binding.siteId &&\n claims.environment === binding.environment &&\n claims.baseSha === binding.baseSha &&\n claims.manifestHash === binding.manifestHash &&\n claims.workspacesOrigin === binding.workspacesOrigin &&\n claims.previewOrigin === binding.previewOrigin &&\n claims.channelNonce === binding.channelNonce\n )\n}\n\nexport function createHydrogenEditorChannelNonce(): string {\n return toBase64Url(crypto.getRandomValues(new Uint8Array(32)))\n}\n\nexport async function signHydrogenEditorPreviewGrant(\n binding: HydrogenEditorPreviewGrantBinding,\n secret: string,\n options: SignHydrogenEditorPreviewGrantOptions,\n): Promise<SignedHydrogenEditorPreviewGrant> {\n validateSigningInput(binding, secret, options)\n const claims: HydrogenEditorPreviewGrantClaims = {\n version: GRANT_VERSION,\n ...binding,\n issuedAt: options.now,\n expiresAt: options.now + options.ttlMs,\n }\n const payload = toBase64Url(encoder.encode(JSON.stringify(claims)))\n const signature = await crypto.subtle.sign(\n 'HMAC',\n await hmacKey(secret),\n signatureInput(payload),\n )\n const token = `${TOKEN_PREFIX}.${payload}.${toBase64Url(new Uint8Array(signature))}`\n return {\n token,\n claims,\n security: {\n sessionId: claims.sessionId,\n baseSha: claims.baseSha,\n manifestHash: claims.manifestHash,\n channelNonce: claims.channelNonce,\n previewToken: token,\n expiresAt: claims.expiresAt,\n },\n }\n}\n\nexport async function verifyHydrogenEditorPreviewGrant(\n token: string,\n secret: string,\n expected: HydrogenEditorPreviewGrantBinding,\n options: VerifyHydrogenEditorPreviewGrantOptions,\n): Promise<HydrogenEditorPreviewGrantClaims | null> {\n try {\n if (\n typeof token !== 'string' ||\n token.length === 0 ||\n token.length > MAX_TOKEN_CHARS ||\n !validSecret(secret) ||\n !Number.isSafeInteger(options.now) ||\n options.now < 0\n ) {\n return null\n }\n validateBinding(expected)\n const [prefix, payload, encodedSignature, extra] = token.split('.')\n if (\n prefix !== TOKEN_PREFIX ||\n payload === undefined ||\n !BASE64_URL.test(payload) ||\n encodedSignature === undefined ||\n encodedSignature.length !== 43 ||\n !BASE64_URL.test(encodedSignature) ||\n extra !== undefined\n ) {\n return null\n }\n const signature = fromBase64Url(encodedSignature)\n if (\n signature.byteLength !== 32 ||\n toBase64Url(signature) !== encodedSignature\n ) {\n return null\n }\n const validSignature = await crypto.subtle.verify(\n 'HMAC',\n await hmacKey(secret),\n bytes(signature),\n signatureInput(payload),\n )\n if (!validSignature) return null\n const payloadBytes = fromBase64Url(payload)\n if (toBase64Url(payloadBytes) !== payload) return null\n const claims: unknown = JSON.parse(decoder.decode(payloadBytes))\n if (!isClaims(claims) || !matchesBinding(claims, expected)) return null\n if (claims.issuedAt > options.now || claims.expiresAt <= options.now) return null\n return claims\n } catch {\n return null\n }\n}\n","import {\n createHydrogenEditorPreviewRuntime,\n HydrogenEditorConfigurationError,\n type CreateHydrogenEditorPreviewRuntimeArgs,\n type HydrogenEditorPreviewRuntime,\n type HydrogenEditorSecurityContext,\n} from './hydrogen'\nimport {\n verifyHydrogenEditorPreviewGrant,\n type HydrogenEditorPreviewGrantBinding,\n} from './preview-grant'\n\nconst PREVIEW_BOOTSTRAP_VERSION = 1 as const\n\nexport interface HydrogenEditorPreviewBootstrap {\n readonly version: typeof PREVIEW_BOOTSTRAP_VERSION\n readonly workspacesOrigin: string\n readonly previewOrigin: string\n readonly security: HydrogenEditorSecurityContext\n}\n\nexport interface CreateHydrogenEditorPreviewBootstrapArgs {\n readonly token?: string | null\n readonly secret: string\n readonly expected: HydrogenEditorPreviewGrantBinding\n readonly now: number\n}\n\nexport type CreateHydrogenEditorPreviewRuntimeFromBootstrapArgs = Omit<\n CreateHydrogenEditorPreviewRuntimeArgs,\n 'adminOrigin' | 'security'\n> & {\n readonly bootstrap: HydrogenEditorPreviewBootstrap\n readonly currentOrigin: string\n}\n\nexport async function createHydrogenEditorPreviewBootstrap({\n expected,\n now,\n secret,\n token,\n}: CreateHydrogenEditorPreviewBootstrapArgs): Promise<HydrogenEditorPreviewBootstrap | null> {\n if (token === undefined || token === null) return null\n const claims = await verifyHydrogenEditorPreviewGrant(token, secret, expected, { now })\n if (claims === null) return null\n\n return {\n version: PREVIEW_BOOTSTRAP_VERSION,\n workspacesOrigin: claims.workspacesOrigin,\n previewOrigin: claims.previewOrigin,\n security: {\n sessionId: claims.sessionId,\n baseSha: claims.baseSha,\n manifestHash: claims.manifestHash,\n channelNonce: claims.channelNonce,\n previewToken: token,\n expiresAt: claims.expiresAt,\n },\n }\n}\n\nexport function createHydrogenEditorPreviewRuntimeFromBootstrap({\n bootstrap,\n currentOrigin,\n ...runtime\n}: CreateHydrogenEditorPreviewRuntimeFromBootstrapArgs): HydrogenEditorPreviewRuntime {\n if (\n bootstrap.version !== PREVIEW_BOOTSTRAP_VERSION ||\n currentOrigin !== bootstrap.previewOrigin\n ) {\n throw new HydrogenEditorConfigurationError(\n 'current preview origin does not match the authenticated editor grant',\n )\n }\n\n return createHydrogenEditorPreviewRuntime({\n ...runtime,\n adminOrigin: bootstrap.workspacesOrigin,\n security: bootstrap.security,\n })\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { O as OfferTokenLocation, a as OfferTokenHistory } from './offer-token-C-nk_nj8.js';
4
- import { E as EventsClient, a as EventCheckoutSession, b as EventApprovalOfferResolution, P as PublicEvent, c as EventRegistrationSubmission } from './client-bsiNPHBi.js';
4
+ import { E as EventsClient, a as EventCheckoutSession, b as EventApprovalOfferResolution, P as PublicEvent, c as EventRegistrationSubmission } from './client-CwOPPpFF.js';
5
5
  import './types-CSNXbGFW.js';
6
6
  import './http-types-CGh8WGHB.js';
7
7
 
@@ -1,6 +1,6 @@
1
1
  import { StorefrontFormFields } from './chunk-VV653S52.js';
2
2
  import { offerTokenHrefMarker, consumeOfferTokenFragment } from './chunk-WG7HYVHJ.js';
3
- import { StorefrontEventsRequestError } from './chunk-7MTCGXIG.js';
3
+ import { StorefrontEventsRequestError } from './chunk-R4N565GX.js';
4
4
  import './chunk-IIOHENCG.js';
5
5
  import { useState, useRef, useEffect, useCallback, useId, useMemo, useLayoutEffect } from 'react';
6
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
package/dist/events.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { C as CartHandler } from './createCartHandler-C4RrPwSG.js';
2
- export { C as ClaimEventApprovalOffer, d as CreateEventApprovalRequest, e as CreateEventCheckoutSession, f as CreateEventWaitlistEntry, b as EventApprovalOfferResolution, g as EventApprovalRequestReceipt, a as EventCheckoutSession, h as EventFormAnswer, i as EventFormSubmissionInput, j as EventRegistrationMode, k as EventRegistrationResult, c as EventRegistrationSubmission, l as EventWaitlistReceipt, E as EventsClient, P as PublicEvent, m as PublicEventForm, n as PublicEventOccurrence, o as PublicEventTicketType, p as PublicEventVenue, S as StorefrontEventsRequestError, q as createEventsClient } from './client-bsiNPHBi.js';
1
+ import { C as CartHandler } from './createCartHandler-7DdKB-GF.js';
2
+ export { C as ClaimEventApprovalOffer, d as CreateEventApprovalRequest, e as CreateEventCheckoutSession, f as CreateEventWaitlistEntry, b as EventApprovalOfferResolution, g as EventApprovalRequestReceipt, a as EventCheckoutSession, h as EventFormAnswer, i as EventFormSubmissionInput, j as EventRegistrationMode, k as EventRegistrationResult, c as EventRegistrationSubmission, l as EventWaitlistReceipt, E as EventsClient, P as PublicEvent, m as PublicEventForm, n as PublicEventOccurrence, o as PublicEventSummary, p as PublicEventTicketType, q as PublicEventVenue, S as StorefrontEventsRequestError, r as createEventsClient } from './client-CwOPPpFF.js';
3
3
  export { a as OfferTokenHistory, O as OfferTokenLocation, c as consumeOfferTokenFragment, o as offerTokenHrefMarker } from './offer-token-C-nk_nj8.js';
4
4
  import './client-D51WdvYR.js';
5
5
  import './http-types-CGh8WGHB.js';
6
- import './types-bcbQzx87.js';
6
+ import './types-DZX8ScsJ.js';
7
7
  import './types-CSNXbGFW.js';
8
8
 
9
9
  declare class EventCartPreparationError extends Error {
package/dist/events.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { EventCartPreparationError, eventCartToken, prepareEventCart } from './chunk-4OQYNUGM.js';
2
2
  export { consumeOfferTokenFragment, offerTokenHrefMarker } from './chunk-WG7HYVHJ.js';
3
- export { StorefrontEventsRequestError, createEventsClient } from './chunk-7MTCGXIG.js';
3
+ export { StorefrontEventsRequestError, createEventsClient } from './chunk-R4N565GX.js';
4
4
  //# sourceMappingURL=events.js.map
5
5
  //# sourceMappingURL=events.js.map
@@ -18,6 +18,11 @@ interface FetchThemeSettingsOptions {
18
18
  readonly fetch?: typeof fetch;
19
19
  /** Same-origin settings endpoint (default `/api/storefront/settings`). */
20
20
  readonly endpoint?: string;
21
+ /**
22
+ * Restrict the response to one rendered template plus the base commerce templates and layout
23
+ * groups needed for a complete page. Omit for the legacy/full editor document.
24
+ */
25
+ readonly templateHandle?: string;
21
26
  /**
22
27
  * Explicit local-preview escape hatch for server-side theme workers that call the Kotao API directly.
23
28
  * Production themes should keep the default same-origin path.