@shoppexio/builder-contracts 0.1.3 → 0.1.4
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/dist/edge-block-engine-frame-origins.d.ts +11 -0
- package/dist/edge-block-engine-frame-origins.d.ts.map +1 -0
- package/dist/edge-block-engine-frame-origins.js +23 -0
- package/dist/persistence.d.ts.map +1 -1
- package/dist/persistence.js +3 -0
- package/dist/preview-protocol.d.ts +16 -0
- package/dist/preview-protocol.d.ts.map +1 -1
- package/dist/preview-protocol.js +5 -3
- package/dist/theme-schemes.d.ts +8 -3
- package/dist/theme-schemes.d.ts.map +1 -1
- package/dist/theme-schemes.js +20 -1
- package/package.json +7 -1
- package/src/builder-contracts.test.ts +51 -1
- package/src/edge-block-engine-frame-origins.ts +26 -0
- package/src/persistence.ts +3 -0
- package/src/preview-protocol.ts +5 -3
- package/src/theme-schemes.ts +30 -2
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSOT for iframe embed origins allowed in the Edge Block Engine CSP (frame-src)
|
|
3
|
+
* and for custom-embed postMessage trust in storefront-commerce (when registered).
|
|
4
|
+
*/
|
|
5
|
+
export declare const EDGE_BLOCK_YOUTUBE_FRAME_ORIGINS: readonly ["https://www.youtube.com", "https://www.youtube-nocookie.com"];
|
|
6
|
+
/** Trusted origins for custom-embed resize postMessage (storefront-commerce). */
|
|
7
|
+
export declare const EDGE_BLOCK_CUSTOM_EMBED_TRUSTED_ORIGINS: readonly ["https://calendly.com", "https://substack.com", "https://shoppex.io"];
|
|
8
|
+
/** frame-src entries for custom embed blocks (includes Substack wildcard). */
|
|
9
|
+
export declare const EDGE_BLOCK_CUSTOM_EMBED_FRAME_SRC_ORIGINS: readonly ["https://calendly.com", "https://substack.com", "https://shoppex.io", "https://*.substack.com"];
|
|
10
|
+
export declare const EDGE_BLOCK_ALLOWED_FRAME_ORIGINS: readonly ["https://www.youtube.com", "https://www.youtube-nocookie.com", "https://calendly.com", "https://substack.com", "https://shoppex.io", "https://*.substack.com"];
|
|
11
|
+
//# sourceMappingURL=edge-block-engine-frame-origins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-block-engine-frame-origins.d.ts","sourceRoot":"","sources":["../src/edge-block-engine-frame-origins.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,gCAAgC,0EAGnC,CAAC;AAEX,iFAAiF;AACjF,eAAO,MAAM,uCAAuC,iFAI1C,CAAC;AAEX,8EAA8E;AAC9E,eAAO,MAAM,yCAAyC,2GAG5C,CAAC;AAEX,eAAO,MAAM,gCAAgC,0KAGnC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSOT for iframe embed origins allowed in the Edge Block Engine CSP (frame-src)
|
|
3
|
+
* and for custom-embed postMessage trust in storefront-commerce (when registered).
|
|
4
|
+
*/
|
|
5
|
+
export const EDGE_BLOCK_YOUTUBE_FRAME_ORIGINS = [
|
|
6
|
+
'https://www.youtube.com',
|
|
7
|
+
'https://www.youtube-nocookie.com',
|
|
8
|
+
];
|
|
9
|
+
/** Trusted origins for custom-embed resize postMessage (storefront-commerce). */
|
|
10
|
+
export const EDGE_BLOCK_CUSTOM_EMBED_TRUSTED_ORIGINS = [
|
|
11
|
+
'https://calendly.com',
|
|
12
|
+
'https://substack.com',
|
|
13
|
+
'https://shoppex.io',
|
|
14
|
+
];
|
|
15
|
+
/** frame-src entries for custom embed blocks (includes Substack wildcard). */
|
|
16
|
+
export const EDGE_BLOCK_CUSTOM_EMBED_FRAME_SRC_ORIGINS = [
|
|
17
|
+
...EDGE_BLOCK_CUSTOM_EMBED_TRUSTED_ORIGINS,
|
|
18
|
+
'https://*.substack.com',
|
|
19
|
+
];
|
|
20
|
+
export const EDGE_BLOCK_ALLOWED_FRAME_ORIGINS = [
|
|
21
|
+
...EDGE_BLOCK_YOUTUBE_FRAME_ORIGINS,
|
|
22
|
+
...EDGE_BLOCK_CUSTOM_EMBED_FRAME_SRC_ORIGINS,
|
|
23
|
+
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AAQ/B,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAmB1C,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAYtF;AA0BD;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAkDrF;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAAC,mBAAmB,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAgBhG;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,eAAe,GAAG,eAAe,CASvF;AAaD,wBAAgB,qCAAqC,CACnD,eAAe,EAAE,OAAO,EACxB,eAAe,EAAE,eAAe,GAC/B,UAAU,
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AAQ/B,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAmB1C,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAYtF;AA0BD;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAkDrF;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAAC,mBAAmB,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAgBhG;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,eAAe,GAAG,eAAe,CASvF;AAaD,wBAAgB,qCAAqC,CACnD,eAAe,EAAE,OAAO,EACxB,eAAe,EAAE,eAAe,GAC/B,UAAU,CAgBZ"}
|
package/dist/persistence.js
CHANGED
|
@@ -128,6 +128,9 @@ export function mergeBuilderSettingsIntoThemeSettings(currentSettings, builderSe
|
|
|
128
128
|
const root = isRecord(currentSettings) ? { ...currentSettings } : {};
|
|
129
129
|
const currentBuilderSettings = isRecord(root.builder_settings) ? root.builder_settings : {};
|
|
130
130
|
const sanitizedBuilderSettings = sanitizeBuilderSettingsState(builderSettings);
|
|
131
|
+
root.version = sanitizedBuilderSettings.version;
|
|
132
|
+
root.revision = sanitizedBuilderSettings.revision;
|
|
133
|
+
root.theme = sanitizedBuilderSettings.theme;
|
|
131
134
|
root.builder_settings = {
|
|
132
135
|
...currentBuilderSettings,
|
|
133
136
|
version: sanitizedBuilderSettings.version,
|
|
@@ -79,6 +79,10 @@ export declare const PreviewApplyBlockHtmlMessageSchema: z.ZodObject<{
|
|
|
79
79
|
pageId: z.ZodString;
|
|
80
80
|
sourceRevision: z.ZodString;
|
|
81
81
|
renderMode: z.ZodLiteral<"edge-block-engine">;
|
|
82
|
+
scope: z.ZodOptional<z.ZodEnum<{
|
|
83
|
+
page: "page";
|
|
84
|
+
block: "block";
|
|
85
|
+
}>>;
|
|
82
86
|
blocks: z.ZodArray<z.ZodObject<{
|
|
83
87
|
blockId: z.ZodString;
|
|
84
88
|
html: z.ZodString;
|
|
@@ -188,6 +192,10 @@ export declare const PreviewMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
|
|
|
188
192
|
pageId: z.ZodString;
|
|
189
193
|
sourceRevision: z.ZodString;
|
|
190
194
|
renderMode: z.ZodLiteral<"edge-block-engine">;
|
|
195
|
+
scope: z.ZodOptional<z.ZodEnum<{
|
|
196
|
+
page: "page";
|
|
197
|
+
block: "block";
|
|
198
|
+
}>>;
|
|
191
199
|
blocks: z.ZodArray<z.ZodObject<{
|
|
192
200
|
blockId: z.ZodString;
|
|
193
201
|
html: z.ZodString;
|
|
@@ -275,6 +283,10 @@ export declare const PreviewBlockHtmlAppliedResponseSchema: z.ZodObject<{
|
|
|
275
283
|
pageId: z.ZodString;
|
|
276
284
|
sourceRevision: z.ZodString;
|
|
277
285
|
renderMode: z.ZodLiteral<"edge-block-engine">;
|
|
286
|
+
scope: z.ZodOptional<z.ZodEnum<{
|
|
287
|
+
page: "page";
|
|
288
|
+
block: "block";
|
|
289
|
+
}>>;
|
|
278
290
|
blocks: z.ZodArray<z.ZodObject<{
|
|
279
291
|
blockId: z.ZodString;
|
|
280
292
|
html: z.ZodString;
|
|
@@ -435,6 +447,10 @@ export declare const PreviewResponseSchema: z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
435
447
|
pageId: z.ZodString;
|
|
436
448
|
sourceRevision: z.ZodString;
|
|
437
449
|
renderMode: z.ZodLiteral<"edge-block-engine">;
|
|
450
|
+
scope: z.ZodOptional<z.ZodEnum<{
|
|
451
|
+
page: "page";
|
|
452
|
+
block: "block";
|
|
453
|
+
}>>;
|
|
438
454
|
blocks: z.ZodArray<z.ZodObject<{
|
|
439
455
|
blockId: z.ZodString;
|
|
440
456
|
html: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview-protocol.d.ts","sourceRoot":"","sources":["../src/preview-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAG5B,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;kBAYxB,CAAC;AACZ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAMhC,CAAC;AAEZ,eAAO,MAAM,yBAAyB,mCAAiC,CAAC;AACxE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,2BAA2B;;;kBAK7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,kCAAkC
|
|
1
|
+
{"version":3,"file":"preview-protocol.d.ts","sourceRoot":"","sources":["../src/preview-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAG5B,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;kBAYxB,CAAC;AACZ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAMhC,CAAC;AAEZ,eAAO,MAAM,yBAAyB,mCAAiC,CAAC;AACxE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,eAAO,MAAM,2BAA2B;;;kBAK7B,CAAC;AACZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;kBAUpC,CAAC;AAEZ,eAAO,MAAM,0BAA0B;;;;;;;kBAM5B,CAAC;AAEZ,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;kBAMnC,CAAC;AAEZ,eAAO,MAAM,gCAAgC;;kBAIlC,CAAC;AAEZ,eAAO,MAAM,qBAAqB;;;EAA8B,CAAC;AACjE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,sCAAsC;;;;;;kBAKxC,CAAC;AAEZ,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAO/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,gCAAgC;;;;;;kBAQlC,CAAC;AAEZ,eAAO,MAAM,wBAAwB;;;;;;;;uCAenC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,eAAO,MAAM,0BAA0B;;;;;;;;;;;;kBAM5B,CAAC;AAEZ,eAAO,MAAM,4BAA4B;;;kBAK9B,CAAC;AAEZ,eAAO,MAAM,gCAAgC;;;;kBAMlC,CAAC;AAEZ,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;kBAUvC,CAAC;AAEZ,eAAO,MAAM,oCAAoC;;;;;;;;kBAUtC,CAAC;AAEZ,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;kBAMrC,CAAC;AAEZ,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA0B5B,CAAC;AAEZ;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;;kBAOnB,CAAC;AACZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,8BAA8B;;;;;;;;;;kBAOhC,CAAC;AAEZ;;;;GAIG;AACH,eAAO,MAAM,kCAAkC;;;;;;;;;;kBAOpC,CAAC;AAEZ;;;;GAIG;AACH,eAAO,MAAM,qCAAqC;;;;;;kBAQvC,CAAC;AAEZ,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAYhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
|
package/dist/preview-protocol.js
CHANGED
|
@@ -34,7 +34,8 @@ export const PreviewApplyBlockHtmlMessageSchema = z
|
|
|
34
34
|
pageId: z.string().min(1),
|
|
35
35
|
sourceRevision: z.string().min(1),
|
|
36
36
|
renderMode: EdgeBlockRenderModeSchema,
|
|
37
|
-
|
|
37
|
+
scope: z.enum(['block', 'page']).optional(),
|
|
38
|
+
blocks: z.array(PreviewBlockHtmlPatchSchema),
|
|
38
39
|
})
|
|
39
40
|
.strict();
|
|
40
41
|
export const PreviewReloadMessageSchema = z
|
|
@@ -129,7 +130,8 @@ export const PreviewBlockHtmlAppliedResponseSchema = z
|
|
|
129
130
|
pageId: z.string().min(1),
|
|
130
131
|
sourceRevision: z.string().min(1),
|
|
131
132
|
renderMode: EdgeBlockRenderModeSchema,
|
|
132
|
-
|
|
133
|
+
scope: z.enum(['block', 'page']).optional(),
|
|
134
|
+
blocks: z.array(PreviewBlockHtmlPatchSchema),
|
|
133
135
|
})
|
|
134
136
|
.strict();
|
|
135
137
|
export const PreviewBlockHtmlFailedResponseSchema = z
|
|
@@ -139,7 +141,7 @@ export const PreviewBlockHtmlFailedResponseSchema = z
|
|
|
139
141
|
pageId: z.string().min(1),
|
|
140
142
|
sourceRevision: z.string().min(1).optional(),
|
|
141
143
|
renderMode: EdgeBlockRenderModeSchema,
|
|
142
|
-
blockIds: z.array(z.string().min(1))
|
|
144
|
+
blockIds: z.array(z.string().min(1)),
|
|
143
145
|
error: z.string().min(1),
|
|
144
146
|
})
|
|
145
147
|
.strict();
|
package/dist/theme-schemes.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
export declare const PUBLIC_BUILDER_THEME_SCHEMES: readonly ["default", "classic", "nebula", "pulse", "phantom", "starlight", "apex", "vault", "
|
|
2
|
-
export declare const STARTER_BUILDER_THEME_SCHEMES: readonly ["blank"];
|
|
3
|
-
export declare const BUILDER_READY_THEME_SCHEMES: readonly ["blank", "default", "classic", "nebula", "pulse", "phantom", "starlight", "apex", "vault", "vortex", "clean-minimal"];
|
|
1
|
+
export declare const PUBLIC_BUILDER_THEME_SCHEMES: readonly ["default", "classic", "nebula", "pulse", "phantom", "starlight", "apex", "vault", "clean-minimal"];
|
|
4
2
|
export type PublicBuilderThemeScheme = (typeof PUBLIC_BUILDER_THEME_SCHEMES)[number];
|
|
3
|
+
export declare const STARTER_BUILDER_THEME_SCHEMES: readonly ["blank"];
|
|
4
|
+
export declare const THEME_STORE_DISABLED_SCHEMES: readonly ["vault", "nebula", "phantom", "clean-minimal"];
|
|
5
|
+
export declare const THEME_STORE_INSTALLABLE_SCHEMES: readonly ["default", "classic", "pulse", "starlight", "apex"];
|
|
6
|
+
export declare const BUILDER_READY_THEME_SCHEMES: readonly ["blank", "default", "classic", "nebula", "pulse", "phantom", "starlight", "apex", "vault", "clean-minimal"];
|
|
7
|
+
export type ThemeStoreInstallableScheme = (typeof THEME_STORE_INSTALLABLE_SCHEMES)[number];
|
|
5
8
|
export type StarterBuilderThemeScheme = (typeof STARTER_BUILDER_THEME_SCHEMES)[number];
|
|
6
9
|
export type BuilderReadyThemeScheme = (typeof BUILDER_READY_THEME_SCHEMES)[number];
|
|
7
10
|
export declare function isPublicBuilderThemeScheme(value: string): value is PublicBuilderThemeScheme;
|
|
11
|
+
export declare function isThemeStoreDisabledScheme(value: string): boolean;
|
|
12
|
+
export declare function isThemeStoreInstallableScheme(value: string): value is ThemeStoreInstallableScheme;
|
|
8
13
|
export declare function isStarterBuilderThemeScheme(value: string): value is StarterBuilderThemeScheme;
|
|
9
14
|
export declare function isBuilderReadyThemeScheme(value: string): value is BuilderReadyThemeScheme;
|
|
10
15
|
//# sourceMappingURL=theme-schemes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-schemes.d.ts","sourceRoot":"","sources":["../src/theme-schemes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,
|
|
1
|
+
{"version":3,"file":"theme-schemes.d.ts","sourceRoot":"","sources":["../src/theme-schemes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,8GAU/B,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,4BAA4B,CAAC,CAAC,MAAM,CAAC,CAAC;AAErF,eAAO,MAAM,6BAA6B,oBAAqB,CAAC;AAEhE,eAAO,MAAM,4BAA4B,0DAKe,CAAC;AAIzD,eAAO,MAAM,+BAA+B,+DAMY,CAAC;AAEzD,eAAO,MAAM,2BAA2B,uHAG9B,CAAC;AAEX,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,+BAA+B,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3F,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AACvF,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,wBAAwB,CAE3F;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,MAAM,GACZ,KAAK,IAAI,2BAA2B,CAEtC;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,yBAAyB,CAE7F;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,uBAAuB,CAEzF"}
|
package/dist/theme-schemes.js
CHANGED
|
@@ -7,10 +7,23 @@ export const PUBLIC_BUILDER_THEME_SCHEMES = [
|
|
|
7
7
|
'starlight',
|
|
8
8
|
'apex',
|
|
9
9
|
'vault',
|
|
10
|
-
'vortex',
|
|
11
10
|
'clean-minimal',
|
|
12
11
|
];
|
|
13
12
|
export const STARTER_BUILDER_THEME_SCHEMES = ['blank'];
|
|
13
|
+
export const THEME_STORE_DISABLED_SCHEMES = [
|
|
14
|
+
'vault',
|
|
15
|
+
'nebula',
|
|
16
|
+
'phantom',
|
|
17
|
+
'clean-minimal',
|
|
18
|
+
];
|
|
19
|
+
const THEME_STORE_DISABLED_SCHEME_SET = new Set(THEME_STORE_DISABLED_SCHEMES);
|
|
20
|
+
export const THEME_STORE_INSTALLABLE_SCHEMES = [
|
|
21
|
+
'default',
|
|
22
|
+
'classic',
|
|
23
|
+
'pulse',
|
|
24
|
+
'starlight',
|
|
25
|
+
'apex',
|
|
26
|
+
];
|
|
14
27
|
export const BUILDER_READY_THEME_SCHEMES = [
|
|
15
28
|
...STARTER_BUILDER_THEME_SCHEMES,
|
|
16
29
|
...PUBLIC_BUILDER_THEME_SCHEMES,
|
|
@@ -18,6 +31,12 @@ export const BUILDER_READY_THEME_SCHEMES = [
|
|
|
18
31
|
export function isPublicBuilderThemeScheme(value) {
|
|
19
32
|
return PUBLIC_BUILDER_THEME_SCHEMES.includes(value);
|
|
20
33
|
}
|
|
34
|
+
export function isThemeStoreDisabledScheme(value) {
|
|
35
|
+
return THEME_STORE_DISABLED_SCHEME_SET.has(value);
|
|
36
|
+
}
|
|
37
|
+
export function isThemeStoreInstallableScheme(value) {
|
|
38
|
+
return THEME_STORE_INSTALLABLE_SCHEMES.includes(value);
|
|
39
|
+
}
|
|
21
40
|
export function isStarterBuilderThemeScheme(value) {
|
|
22
41
|
return STARTER_BUILDER_THEME_SCHEMES.includes(value);
|
|
23
42
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shoppexio/builder-contracts",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Shared Builder v2 contracts for Shoppex dashboard, backend, preview runtime, and themes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -37,6 +37,12 @@
|
|
|
37
37
|
"import": "./dist/builder-settings.js",
|
|
38
38
|
"default": "./dist/builder-settings.js"
|
|
39
39
|
},
|
|
40
|
+
"./edge-block-engine-frame-origins": {
|
|
41
|
+
"bun": "./src/edge-block-engine-frame-origins.ts",
|
|
42
|
+
"types": "./dist/edge-block-engine-frame-origins.d.ts",
|
|
43
|
+
"import": "./dist/edge-block-engine-frame-origins.js",
|
|
44
|
+
"default": "./dist/edge-block-engine-frame-origins.js"
|
|
45
|
+
},
|
|
40
46
|
"./events": {
|
|
41
47
|
"bun": "./src/events.ts",
|
|
42
48
|
"types": "./dist/events.d.ts",
|
|
@@ -219,9 +219,59 @@ describe('@shoppex/builder-contracts', () => {
|
|
|
219
219
|
expect((persisted.builder_settings as Record<string, unknown>).seo).toEqual({
|
|
220
220
|
default_title: 'Keep this title',
|
|
221
221
|
});
|
|
222
|
+
expect(persisted.version).toBe(settings.version);
|
|
223
|
+
expect(persisted.revision).toBe(settings.revision);
|
|
224
|
+
expect(persisted.theme).toEqual(settings.theme);
|
|
222
225
|
expect(extractPersistedBuilderSettings(persisted)).toEqual(settings);
|
|
223
226
|
});
|
|
224
227
|
|
|
228
|
+
test('updates stale root-level builder fields when publishing nested builder settings', () => {
|
|
229
|
+
const settings = createEmptyBuilderSettings(4);
|
|
230
|
+
settings.theme.layout.home = {
|
|
231
|
+
blocks: [
|
|
232
|
+
{
|
|
233
|
+
id: 'hero-1',
|
|
234
|
+
type: 'hero',
|
|
235
|
+
visible: true,
|
|
236
|
+
settings: { 'hero.title': 'Published title' },
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const persisted = mergeBuilderSettingsIntoThemeSettings({
|
|
242
|
+
version: 2,
|
|
243
|
+
revision: 1,
|
|
244
|
+
theme: {
|
|
245
|
+
content: {},
|
|
246
|
+
layout: {
|
|
247
|
+
home: {
|
|
248
|
+
blocks: [
|
|
249
|
+
{
|
|
250
|
+
id: 'hero-1',
|
|
251
|
+
type: 'hero',
|
|
252
|
+
visible: true,
|
|
253
|
+
settings: { 'hero.title': 'Old title' },
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
style_slots: {},
|
|
259
|
+
pages: [],
|
|
260
|
+
terms: {},
|
|
261
|
+
},
|
|
262
|
+
builder_settings: {
|
|
263
|
+
seo: {
|
|
264
|
+
default_title: 'Keep this title',
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
}, settings);
|
|
268
|
+
|
|
269
|
+
expect(extractPersistedBuilderSettings(persisted)).toEqual(settings);
|
|
270
|
+
expect((persisted.builder_settings as Record<string, unknown>).seo).toEqual({
|
|
271
|
+
default_title: 'Keep this title',
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
225
275
|
test('coerces polluted v2 theme.typography into style_slots and strips invalid keys', () => {
|
|
226
276
|
const coerced = coercePersistedBuilderSettings({
|
|
227
277
|
version: 2,
|
|
@@ -857,7 +907,7 @@ describe('@shoppex/builder-contracts', () => {
|
|
|
857
907
|
|
|
858
908
|
test('parses official theme manifests with transparent contact-form backgrounds', () => {
|
|
859
909
|
const repoRoot = join(import.meta.dir, '../../..');
|
|
860
|
-
for (const theme of ['default', 'nebula', 'classic', 'pulse', 'starlight', 'vault', 'phantom', 'apex'
|
|
910
|
+
for (const theme of ['default', 'nebula', 'classic', 'pulse', 'starlight', 'vault', 'phantom', 'apex']) {
|
|
861
911
|
const manifestPath = join(repoRoot, 'themes', theme, 'theme.manifest.json');
|
|
862
912
|
const raw = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
863
913
|
expect(ThemeManifestSchema.safeParse(raw).success, `${theme} manifest should validate`).toBe(true);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSOT for iframe embed origins allowed in the Edge Block Engine CSP (frame-src)
|
|
3
|
+
* and for custom-embed postMessage trust in storefront-commerce (when registered).
|
|
4
|
+
*/
|
|
5
|
+
export const EDGE_BLOCK_YOUTUBE_FRAME_ORIGINS = [
|
|
6
|
+
'https://www.youtube.com',
|
|
7
|
+
'https://www.youtube-nocookie.com',
|
|
8
|
+
] as const;
|
|
9
|
+
|
|
10
|
+
/** Trusted origins for custom-embed resize postMessage (storefront-commerce). */
|
|
11
|
+
export const EDGE_BLOCK_CUSTOM_EMBED_TRUSTED_ORIGINS = [
|
|
12
|
+
'https://calendly.com',
|
|
13
|
+
'https://substack.com',
|
|
14
|
+
'https://shoppex.io',
|
|
15
|
+
] as const;
|
|
16
|
+
|
|
17
|
+
/** frame-src entries for custom embed blocks (includes Substack wildcard). */
|
|
18
|
+
export const EDGE_BLOCK_CUSTOM_EMBED_FRAME_SRC_ORIGINS = [
|
|
19
|
+
...EDGE_BLOCK_CUSTOM_EMBED_TRUSTED_ORIGINS,
|
|
20
|
+
'https://*.substack.com',
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
export const EDGE_BLOCK_ALLOWED_FRAME_ORIGINS = [
|
|
24
|
+
...EDGE_BLOCK_YOUTUBE_FRAME_ORIGINS,
|
|
25
|
+
...EDGE_BLOCK_CUSTOM_EMBED_FRAME_SRC_ORIGINS,
|
|
26
|
+
] as const;
|
package/src/persistence.ts
CHANGED
|
@@ -173,6 +173,9 @@ export function mergeBuilderSettingsIntoThemeSettings(
|
|
|
173
173
|
const currentBuilderSettings = isRecord(root.builder_settings) ? root.builder_settings : {};
|
|
174
174
|
const sanitizedBuilderSettings = sanitizeBuilderSettingsState(builderSettings);
|
|
175
175
|
|
|
176
|
+
root.version = sanitizedBuilderSettings.version;
|
|
177
|
+
root.revision = sanitizedBuilderSettings.revision;
|
|
178
|
+
root.theme = sanitizedBuilderSettings.theme;
|
|
176
179
|
root.builder_settings = {
|
|
177
180
|
...currentBuilderSettings,
|
|
178
181
|
version: sanitizedBuilderSettings.version,
|
package/src/preview-protocol.ts
CHANGED
|
@@ -42,7 +42,8 @@ export const PreviewApplyBlockHtmlMessageSchema = z
|
|
|
42
42
|
pageId: z.string().min(1),
|
|
43
43
|
sourceRevision: z.string().min(1),
|
|
44
44
|
renderMode: EdgeBlockRenderModeSchema,
|
|
45
|
-
|
|
45
|
+
scope: z.enum(['block', 'page']).optional(),
|
|
46
|
+
blocks: z.array(PreviewBlockHtmlPatchSchema),
|
|
46
47
|
})
|
|
47
48
|
.strict();
|
|
48
49
|
|
|
@@ -152,7 +153,8 @@ export const PreviewBlockHtmlAppliedResponseSchema = z
|
|
|
152
153
|
pageId: z.string().min(1),
|
|
153
154
|
sourceRevision: z.string().min(1),
|
|
154
155
|
renderMode: EdgeBlockRenderModeSchema,
|
|
155
|
-
|
|
156
|
+
scope: z.enum(['block', 'page']).optional(),
|
|
157
|
+
blocks: z.array(PreviewBlockHtmlPatchSchema),
|
|
156
158
|
})
|
|
157
159
|
.strict();
|
|
158
160
|
|
|
@@ -163,7 +165,7 @@ export const PreviewBlockHtmlFailedResponseSchema = z
|
|
|
163
165
|
pageId: z.string().min(1),
|
|
164
166
|
sourceRevision: z.string().min(1).optional(),
|
|
165
167
|
renderMode: EdgeBlockRenderModeSchema,
|
|
166
|
-
blockIds: z.array(z.string().min(1))
|
|
168
|
+
blockIds: z.array(z.string().min(1)),
|
|
167
169
|
error: z.string().min(1),
|
|
168
170
|
})
|
|
169
171
|
.strict();
|
package/src/theme-schemes.ts
CHANGED
|
@@ -7,18 +7,36 @@ export const PUBLIC_BUILDER_THEME_SCHEMES = [
|
|
|
7
7
|
'starlight',
|
|
8
8
|
'apex',
|
|
9
9
|
'vault',
|
|
10
|
-
'vortex',
|
|
11
10
|
'clean-minimal',
|
|
12
11
|
] as const;
|
|
13
12
|
|
|
13
|
+
export type PublicBuilderThemeScheme = (typeof PUBLIC_BUILDER_THEME_SCHEMES)[number];
|
|
14
|
+
|
|
14
15
|
export const STARTER_BUILDER_THEME_SCHEMES = ['blank'] as const;
|
|
15
16
|
|
|
17
|
+
export const THEME_STORE_DISABLED_SCHEMES = [
|
|
18
|
+
'vault',
|
|
19
|
+
'nebula',
|
|
20
|
+
'phantom',
|
|
21
|
+
'clean-minimal',
|
|
22
|
+
] as const satisfies readonly PublicBuilderThemeScheme[];
|
|
23
|
+
|
|
24
|
+
const THEME_STORE_DISABLED_SCHEME_SET = new Set<string>(THEME_STORE_DISABLED_SCHEMES);
|
|
25
|
+
|
|
26
|
+
export const THEME_STORE_INSTALLABLE_SCHEMES = [
|
|
27
|
+
'default',
|
|
28
|
+
'classic',
|
|
29
|
+
'pulse',
|
|
30
|
+
'starlight',
|
|
31
|
+
'apex',
|
|
32
|
+
] as const satisfies readonly PublicBuilderThemeScheme[];
|
|
33
|
+
|
|
16
34
|
export const BUILDER_READY_THEME_SCHEMES = [
|
|
17
35
|
...STARTER_BUILDER_THEME_SCHEMES,
|
|
18
36
|
...PUBLIC_BUILDER_THEME_SCHEMES,
|
|
19
37
|
] as const;
|
|
20
38
|
|
|
21
|
-
export type
|
|
39
|
+
export type ThemeStoreInstallableScheme = (typeof THEME_STORE_INSTALLABLE_SCHEMES)[number];
|
|
22
40
|
export type StarterBuilderThemeScheme = (typeof STARTER_BUILDER_THEME_SCHEMES)[number];
|
|
23
41
|
export type BuilderReadyThemeScheme = (typeof BUILDER_READY_THEME_SCHEMES)[number];
|
|
24
42
|
|
|
@@ -26,6 +44,16 @@ export function isPublicBuilderThemeScheme(value: string): value is PublicBuilde
|
|
|
26
44
|
return (PUBLIC_BUILDER_THEME_SCHEMES as readonly string[]).includes(value);
|
|
27
45
|
}
|
|
28
46
|
|
|
47
|
+
export function isThemeStoreDisabledScheme(value: string): boolean {
|
|
48
|
+
return THEME_STORE_DISABLED_SCHEME_SET.has(value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function isThemeStoreInstallableScheme(
|
|
52
|
+
value: string,
|
|
53
|
+
): value is ThemeStoreInstallableScheme {
|
|
54
|
+
return (THEME_STORE_INSTALLABLE_SCHEMES as readonly string[]).includes(value);
|
|
55
|
+
}
|
|
56
|
+
|
|
29
57
|
export function isStarterBuilderThemeScheme(value: string): value is StarterBuilderThemeScheme {
|
|
30
58
|
return (STARTER_BUILDER_THEME_SCHEMES as readonly string[]).includes(value);
|
|
31
59
|
}
|