@shoppexio/builder-runtime 0.1.5 → 0.1.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.
@@ -0,0 +1,10 @@
1
+ export type BlockSettingsRecord = Record<string, unknown>;
2
+ /**
3
+ * Manifest fields use scoped keys (`faq.items`). Legacy block code often read short keys (`items`).
4
+ * Builder persists the manifest path on `block.settings[event.path]`.
5
+ */
6
+ export declare function blockSettingLookupKeys(blockType: string, shortKey: string): string[];
7
+ export declare function readBlockStringSetting(settings: BlockSettingsRecord, keys: string | readonly string[], fallback?: string | null): string | null;
8
+ export declare function readBlockArraySetting<T>(settings: BlockSettingsRecord, keys: string | readonly string[]): T[] | null;
9
+ export declare function preferNonEmptyBlockList<T>(primary: T[] | null, fallback: T[] | null | undefined): T[];
10
+ //# sourceMappingURL=block-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-settings.d.ts","sourceRoot":"","sources":["../src/block-settings.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAMpF;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,mBAAmB,EAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,MAAM,GAAG,IAAI,CASf;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,mBAAmB,EAC7B,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAC/B,CAAC,EAAE,GAAG,IAAI,CASZ;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,OAAO,EAAE,CAAC,EAAE,GAAG,IAAI,EACnB,QAAQ,EAAE,CAAC,EAAE,GAAG,IAAI,GAAG,SAAS,GAC/B,CAAC,EAAE,CAIL"}
@@ -0,0 +1,39 @@
1
+ import { resolveManifestSettingRecordValue } from './manifest-setting-paths.js';
2
+ /**
3
+ * Manifest fields use scoped keys (`faq.items`). Legacy block code often read short keys (`items`).
4
+ * Builder persists the manifest path on `block.settings[event.path]`.
5
+ */
6
+ export function blockSettingLookupKeys(blockType, shortKey) {
7
+ const scopedKey = `${blockType}.${shortKey}`;
8
+ if (scopedKey === shortKey) {
9
+ return [shortKey];
10
+ }
11
+ return [scopedKey, shortKey];
12
+ }
13
+ export function readBlockStringSetting(settings, keys, fallback) {
14
+ const candidates = typeof keys === 'string' ? [keys] : keys;
15
+ for (const key of candidates) {
16
+ const resolved = resolveManifestSettingRecordValue(settings, key);
17
+ if (typeof resolved === 'string') {
18
+ return resolved;
19
+ }
20
+ }
21
+ return fallback ?? null;
22
+ }
23
+ export function readBlockArraySetting(settings, keys) {
24
+ const candidates = typeof keys === 'string' ? [keys] : keys;
25
+ for (const key of candidates) {
26
+ const resolved = resolveManifestSettingRecordValue(settings, key);
27
+ if (Array.isArray(resolved)) {
28
+ return resolved;
29
+ }
30
+ }
31
+ return null;
32
+ }
33
+ export function preferNonEmptyBlockList(primary, fallback) {
34
+ if (primary && primary.length > 0)
35
+ return primary;
36
+ if (fallback && fallback.length > 0)
37
+ return fallback;
38
+ return primary ?? fallback ?? [];
39
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './manifest-setting-paths.js';
2
+ export * from './block-settings.js';
2
3
  export * from './preview-fixtures.js';
3
4
  export * from './product-page.js';
4
5
  export * from './standard-product-page.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAChF,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAC;AAChF,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './manifest-setting-paths.js';
2
+ export * from './block-settings.js';
2
3
  export * from './preview-fixtures.js';
3
4
  export * from './product-page.js';
4
5
  export * from './standard-product-page.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shoppexio/builder-runtime",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Theme-side Builder v2 runtime helpers for Shoppex storefront themes",
5
5
  "type": "module",
6
6
  "repository": {
@@ -0,0 +1,66 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import {
3
+ blockSettingLookupKeys,
4
+ preferNonEmptyBlockList,
5
+ readBlockArraySetting,
6
+ readBlockStringSetting,
7
+ } from './block-settings.js';
8
+
9
+ describe('block-settings', () => {
10
+ it('builds scoped and short lookup keys for block types', () => {
11
+ expect(blockSettingLookupKeys('faq', 'items')).toEqual(['faq.items', 'items']);
12
+ expect(blockSettingLookupKeys('hero', 'title')).toEqual(['hero.title', 'title']);
13
+ });
14
+
15
+ it('reads list settings from manifest-scoped block keys', () => {
16
+ const settings = {
17
+ 'faq.items': [{ question: 'Q1', answer: 'A1' }],
18
+ };
19
+
20
+ expect(
21
+ readBlockArraySetting<{ question: string; answer: string }>(
22
+ settings,
23
+ blockSettingLookupKeys('faq', 'items'),
24
+ ),
25
+ ).toEqual([{ question: 'Q1', answer: 'A1' }]);
26
+ });
27
+
28
+ it('falls back to short keys when legacy data used items only', () => {
29
+ const settings = {
30
+ items: [{ question: 'Legacy', answer: 'Still works' }],
31
+ };
32
+
33
+ expect(
34
+ readBlockArraySetting<{ question: string; answer: string }>(
35
+ settings,
36
+ blockSettingLookupKeys('faq', 'items'),
37
+ ),
38
+ ).toEqual([{ question: 'Legacy', answer: 'Still works' }]);
39
+ });
40
+
41
+ it('reads string settings from scoped manifest keys', () => {
42
+ const settings = {
43
+ 'faq.title': 'Help center',
44
+ };
45
+
46
+ expect(
47
+ readBlockStringSetting(settings, blockSettingLookupKeys('faq', 'title'), 'Default'),
48
+ ).toBe('Help center');
49
+ });
50
+
51
+ it('prefers non-empty primary lists over fallbacks', () => {
52
+ expect(
53
+ preferNonEmptyBlockList(
54
+ [{ question: 'Block', answer: 'A' }],
55
+ [{ question: 'Content', answer: 'B' }],
56
+ ),
57
+ ).toEqual([{ question: 'Block', answer: 'A' }]);
58
+
59
+ expect(
60
+ preferNonEmptyBlockList(
61
+ [],
62
+ [{ question: 'Content', answer: 'B' }],
63
+ ),
64
+ ).toEqual([{ question: 'Content', answer: 'B' }]);
65
+ });
66
+ });
@@ -0,0 +1,53 @@
1
+ import { resolveManifestSettingRecordValue } from './manifest-setting-paths.js';
2
+
3
+ export type BlockSettingsRecord = Record<string, unknown>;
4
+
5
+ /**
6
+ * Manifest fields use scoped keys (`faq.items`). Legacy block code often read short keys (`items`).
7
+ * Builder persists the manifest path on `block.settings[event.path]`.
8
+ */
9
+ export function blockSettingLookupKeys(blockType: string, shortKey: string): string[] {
10
+ const scopedKey = `${blockType}.${shortKey}`;
11
+ if (scopedKey === shortKey) {
12
+ return [shortKey];
13
+ }
14
+ return [scopedKey, shortKey];
15
+ }
16
+
17
+ export function readBlockStringSetting(
18
+ settings: BlockSettingsRecord,
19
+ keys: string | readonly string[],
20
+ fallback?: string | null,
21
+ ): string | null {
22
+ const candidates = typeof keys === 'string' ? [keys] : keys;
23
+ for (const key of candidates) {
24
+ const resolved = resolveManifestSettingRecordValue(settings, key);
25
+ if (typeof resolved === 'string') {
26
+ return resolved;
27
+ }
28
+ }
29
+ return fallback ?? null;
30
+ }
31
+
32
+ export function readBlockArraySetting<T>(
33
+ settings: BlockSettingsRecord,
34
+ keys: string | readonly string[],
35
+ ): T[] | null {
36
+ const candidates = typeof keys === 'string' ? [keys] : keys;
37
+ for (const key of candidates) {
38
+ const resolved = resolveManifestSettingRecordValue(settings, key);
39
+ if (Array.isArray(resolved)) {
40
+ return resolved as T[];
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+
46
+ export function preferNonEmptyBlockList<T>(
47
+ primary: T[] | null,
48
+ fallback: T[] | null | undefined,
49
+ ): T[] {
50
+ if (primary && primary.length > 0) return primary;
51
+ if (fallback && fallback.length > 0) return fallback;
52
+ return primary ?? fallback ?? [];
53
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './manifest-setting-paths.js';
2
+ export * from './block-settings.js';
2
3
  export * from './preview-fixtures.js';
3
4
  export * from './product-page.js';
4
5
  export * from './standard-product-page.js';