@zohofinance/commerce 1.1.0 → 2.0.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.
@@ -6,12 +6,15 @@ type SchemaSetting = {
6
6
  };
7
7
  type SchemaBlock = {
8
8
  type: string;
9
+ name?: string;
9
10
  settings?: SchemaSetting[];
10
11
  };
11
12
  type SectionSchema = {
12
13
  settings?: SchemaSetting[];
13
14
  blocks?: SchemaBlock[];
14
15
  };
15
- export declare function prepareSectionData(sectionData: SectionsType[string], schemaData?: SectionSchema, sectionKey?: string): import("types/common").SectionType;
16
+ export declare function prepareSectionData(sectionData: SectionsType[string], schemaData?: SectionSchema, sectionKey?: string, editorOptions?: {
17
+ jsonType: string;
18
+ }, cwd?: string): import("types/common").SectionType;
16
19
  export {};
17
20
  //# sourceMappingURL=prepare-section-data.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prepare-section-data.d.ts","sourceRoot":"","sources":["../../src/utils/prepare-section-data.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAwFF,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,EACjC,UAAU,CAAC,EAAE,aAAa,EAC1B,UAAU,CAAC,EAAE,MAAM,sCAqDpB"}
1
+ {"version":3,"file":"prepare-section-data.d.ts","sourceRoot":"","sources":["../../src/utils/prepare-section-data.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAwFF,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,EACjC,UAAU,CAAC,EAAE,aAAa,EAC1B,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,EACpC,GAAG,CAAC,EAAE,MAAM,sCAmFb"}
@@ -1,4 +1,6 @@
1
1
  import { resolveThemeAssetUrlsInValue } from './resolve-theme-asset-url.js';
2
+ import { buildBlockZcommerceAttributes } from './editor-attributes.js';
3
+ import { resolveSchemaName } from './resolve-schema-translations.js';
2
4
  function isBlankImagePickerValue(value) {
3
5
  if (value === null || value === '') {
4
6
  return true;
@@ -61,7 +63,7 @@ function normalizeBlocksRecursively(blockData, sectionKey) {
61
63
  normalizeBlocksRecursively(child, sectionKey);
62
64
  }
63
65
  }
64
- export function prepareSectionData(sectionData, schemaData, sectionKey) {
66
+ export function prepareSectionData(sectionData, schemaData, sectionKey, editorOptions, cwd) {
65
67
  normalizeBlocksRecursively(sectionData, sectionKey);
66
68
  if (schemaData?.settings && sectionData.settings) {
67
69
  applyImagePickerDefaults(sectionData.settings, schemaData.settings);
@@ -90,5 +92,26 @@ export function prepareSectionData(sectionData, schemaData, sectionKey) {
90
92
  return block;
91
93
  });
92
94
  }
95
+ if (editorOptions && Array.isArray(sectionData.blocks)) {
96
+ const { jsonType } = editorOptions;
97
+ const blockSchemaNameMap = new Map((schemaData?.blocks || []).map((b) => [b.type, b.name]));
98
+ sectionData.blocks = sectionData.blocks.map((block) => {
99
+ const rawKey = (block.block_key || block.id || '');
100
+ const cleanKey = rawKey.startsWith('block_')
101
+ ? rawKey.replace(/^block_/, '').replace(/_section_.*$/, '')
102
+ : rawKey;
103
+ const blockType = (block.type || '');
104
+ const existingDisplayName = block.display_name;
105
+ const displayName = existingDisplayName
106
+ || (cwd
107
+ ? resolveSchemaName(blockSchemaNameMap.get(blockType), blockType, cwd)
108
+ : blockType);
109
+ return {
110
+ ...block,
111
+ type: blockType,
112
+ zcommerce_attributes: buildBlockZcommerceAttributes(blockType, cleanKey, sectionKey || '', jsonType, displayName)
113
+ };
114
+ });
115
+ }
93
116
  return sectionData;
94
117
  }
@@ -0,0 +1,3 @@
1
+ export declare function resolveSchemaTranslations<T>(schema: T, cwd: string): T;
2
+ export declare function resolveSchemaName(name: string | undefined, fallback: string, cwd: string): string;
3
+ //# sourceMappingURL=resolve-schema-translations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-schema-translations.d.ts","sourceRoot":"","sources":["../../src/utils/resolve-schema-translations.ts"],"names":[],"mappings":"AA+CA,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAItE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMjG"}
@@ -0,0 +1,61 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ const localeCache = new Map();
4
+ function loadSchemaLocale(cwd) {
5
+ if (localeCache.has(cwd))
6
+ return localeCache.get(cwd);
7
+ const filePath = path.join(cwd, 'i18n', 'en.schema.json');
8
+ try {
9
+ const locale = fs.existsSync(filePath)
10
+ ? JSON.parse(fs.readFileSync(filePath, 'utf-8'))
11
+ : null;
12
+ localeCache.set(cwd, locale);
13
+ return locale;
14
+ }
15
+ catch {
16
+ localeCache.set(cwd, null);
17
+ return null;
18
+ }
19
+ }
20
+ function lookupTKey(key, locale) {
21
+ const parts = key.slice(2).split('.');
22
+ let node = locale;
23
+ for (const part of parts) {
24
+ if (node == null || typeof node !== 'object')
25
+ return undefined;
26
+ node = node[part];
27
+ }
28
+ return typeof node === 'string' ? node : undefined;
29
+ }
30
+ function resolveTKeysIn(value, locale) {
31
+ if (typeof value === 'string' && value.startsWith('t:')) {
32
+ return lookupTKey(value, locale) ?? value;
33
+ }
34
+ if (Array.isArray(value)) {
35
+ return value.map((item) => resolveTKeysIn(item, locale));
36
+ }
37
+ if (value !== null && typeof value === 'object') {
38
+ const out = {};
39
+ for (const [k, v] of Object.entries(value)) {
40
+ out[k] = resolveTKeysIn(v, locale);
41
+ }
42
+ return out;
43
+ }
44
+ return value;
45
+ }
46
+ export function resolveSchemaTranslations(schema, cwd) {
47
+ const locale = loadSchemaLocale(cwd);
48
+ if (!locale)
49
+ return schema;
50
+ return resolveTKeysIn(schema, locale);
51
+ }
52
+ export function resolveSchemaName(name, fallback, cwd) {
53
+ if (!name)
54
+ return fallback;
55
+ if (!name.startsWith('t:'))
56
+ return name;
57
+ const locale = loadSchemaLocale(cwd);
58
+ if (!locale)
59
+ return name;
60
+ return lookupTKey(name, locale) ?? name;
61
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"template-engine.d.ts","sourceRoot":"","sources":["../../src/utils/template-engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAwBlC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,UAGN,MAAM,kBAAkB,CAAC;AAc1B,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,cAAc,CAAC;AAEtB,qBAAa,cAAc;;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,QAAQ,CACT;IAEP,IAAI,OAAO,IAGK,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CADzE;IACD,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,EAGzE;IAED,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACzB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAM;IAEP,GAAG,EAAE,MAAM,CAAC;gBAEA,OAAO,gBAAK,EAAE,UAAU,EAAE,UAAU;IAQhD,iBAAiB,CAAC,OAAO,KAAK;IA+DxB,mBAAmB,CAAC,EACxB,QAAQ,EACR,IAAI,EACL,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC;IA+F7C,cAAc,CAAC,EACnB,aAAa,EACb,QAAQ,EACR,IAAI,EACL,EAAE;QACD,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,GAAG,CAAC;KACX;IA6FK,YAAY,CAAC,EACjB,MAAgB,EAChB,sBAAsB,EACtB,IAAI,EACL,EAAE;QACD,MAAM,EAAE,MAAM,CAAC;QACf,sBAAsB,EAAE,MAAM,CAAC;QAC/B,IAAI,EAAE,MAAM,CAAC;KACd;IAgBK,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAO1C,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAI/C,WAAW,CAAC,QAAQ,EAAE,MAAM;IAI5B,OAAO;CAGR"}
1
+ {"version":3,"file":"template-engine.d.ts","sourceRoot":"","sources":["../../src/utils/template-engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAwBlC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,UAGN,MAAM,kBAAkB,CAAC;AAgB1B,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,cAAc,CAAC;AAEtB,qBAAa,cAAc;;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,QAAQ,CACT;IAEP,IAAI,OAAO,IAGK,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CADzE;IACD,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,EAGzE;IAED,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACzB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAM;IAEP,GAAG,EAAE,MAAM,CAAC;gBAEA,OAAO,gBAAK,EAAE,UAAU,EAAE,UAAU;IAQhD,iBAAiB,CAAC,OAAO,KAAK;IA+DxB,mBAAmB,CAAC,EACxB,QAAQ,EACR,IAAI,EACL,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,WAAW,CAAA;KAAE,CAAC;IA+F7C,cAAc,CAAC,EACnB,aAAa,EACb,QAAQ,EACR,IAAI,EACL,EAAE;QACD,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,QAAQ,EAAE,YAAY,CAAC;QACvB,IAAI,EAAE,GAAG,CAAC;KACX;IA+GK,YAAY,CAAC,EACjB,MAAgB,EAChB,sBAAsB,EACtB,IAAI,EACL,EAAE;QACD,MAAM,EAAE,MAAM,CAAC;QACf,sBAAsB,EAAE,MAAM,CAAC;QAC/B,IAAI,EAAE,MAAM,CAAC;KACd;IAgBK,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAO1C,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAI/C,WAAW,CAAC,QAAQ,EAAE,MAAM;IAI5B,OAAO;CAGR"}
@@ -7,9 +7,11 @@ import { LiquidError } from '../utils/liquid-error.js';
7
7
  import { extractLiquidErrorLocation, toThemeRelativePath } from './stack-trace.js';
8
8
  import { promises as fs } from 'fs';
9
9
  import { prepareSectionData } from './prepare-section-data.js';
10
+ import { buildSectionComponentAttr } from './editor-attributes.js';
10
11
  import { normalizeLiquidBlankAssignments } from './normalize-liquid-blank.js';
11
12
  import { createNormalizedLiquidFs } from './normalized-liquid-fs.js';
12
13
  import { resolveSchemaSettings } from './resolve-schema-settings.js';
14
+ import { resolveSchemaName } from './resolve-schema-translations.js';
13
15
  import { attachCliStackTrace, withLiquidRenderFrame, renderTrackedLiquidFile, renderTrackedLiquidString } from './liquid-render-frame.js';
14
16
  export class TemplateEngine {
15
17
  engine;
@@ -159,6 +161,8 @@ export class TemplateEngine {
159
161
  async renderSections({ section_order, sections, data }) {
160
162
  let renderedSection = '';
161
163
  let renderedSectionsArr = [];
164
+ const editorMode = this.engine.__editorMode;
165
+ const editorJsonType = this.engine.__editorJsonType || 'template';
162
166
  for (const section of section_order || []) {
163
167
  let sectionToRender = sections[section].type || '';
164
168
  let liquidSection = `sections/${sectionToRender}.liquid`;
@@ -189,14 +193,24 @@ export class TemplateEngine {
189
193
  console.error(`Failed to parse schema for section ${sectionToRender}:`, error);
190
194
  }
191
195
  }
192
- sections[section] = prepareSectionData(sections[section], schemaData, section);
196
+ sections[section] = prepareSectionData(sections[section], schemaData, section, editorMode ? { jsonType: editorJsonType } : undefined, this.cwd);
197
+ const sectionContext = {
198
+ ...sections[section],
199
+ id: `section_${section}`,
200
+ ...(editorMode ? {
201
+ settingid: `setting_section_${sectionToRender}`,
202
+ display_name: resolveSchemaName(schemaData?.name, sectionToRender, this.cwd)
203
+ } : {})
204
+ };
193
205
  let sectionData = await this.renderFile(this.getFilePath(`sections/${sectionToRender}.liquid`), {
194
206
  ...data,
195
- section: {
196
- ...sections[section],
197
- id: `section_${section}`
198
- }
207
+ section: sectionContext
199
208
  });
209
+ if (editorMode) {
210
+ const displayName = resolveSchemaName(schemaData?.name, sectionToRender, this.cwd);
211
+ const attrJson = buildSectionComponentAttr(sectionToRender, section, editorJsonType, displayName);
212
+ sectionData = `<div data-zcommerce-component='${attrJson.replace(/'/g, '&#39;')}' style="display:contents">${sectionData}</div>`;
213
+ }
200
214
  renderedSectionsArr.push(sectionData);
201
215
  }
202
216
  await Promise.all(renderedSectionsArr).then((arr) => {
@@ -0,0 +1,2 @@
1
+ export declare function getMock<T>(name: string, builtin: T): T;
2
+ //# sourceMappingURL=theme-mocks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-mocks.d.ts","sourceRoot":"","sources":["../../src/utils/theme-mocks.ts"],"names":[],"mappings":"AAkCA,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAQtD"}
@@ -0,0 +1,40 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ /**
4
+ * Theme-level mock overrides for `theme dev` without --storeUrl.
5
+ *
6
+ * A theme may ship `mocks/<name>.json` next to `pages/` (e.g. mocks/products.json,
7
+ * mocks/global-objects.json). When present, it replaces the built-in mock of the same
8
+ * name, so a preview can use data that fits the theme. `mocks/` is not a theme folder:
9
+ * `theme build` never copies it and theme validation skips it.
10
+ *
11
+ * Objects are merged one level deep over the built-in (so a global-objects override can
12
+ * set just `store` and `menu` and keep `routes`); arrays and other values replace it.
13
+ * Files are read on every call so edits show up on the next page load.
14
+ */
15
+ const MOCKS_DIR = 'mocks';
16
+ function readOverride(name) {
17
+ const file = path.join(process.cwd(), MOCKS_DIR, `${name}.json`);
18
+ if (!fs.existsSync(file)) {
19
+ return undefined;
20
+ }
21
+ try {
22
+ return JSON.parse(fs.readFileSync(file, 'utf-8'));
23
+ }
24
+ catch (error) {
25
+ console.warn(`Ignoring ${MOCKS_DIR}/${name}.json: ${error.message}`);
26
+ return undefined;
27
+ }
28
+ }
29
+ function isPlainObject(value) {
30
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
31
+ }
32
+ export function getMock(name, builtin) {
33
+ const override = readOverride(name);
34
+ if (override === undefined) {
35
+ return builtin;
36
+ }
37
+ return isPlainObject(override) && isPlainObject(builtin)
38
+ ? { ...builtin, ...override }
39
+ : override;
40
+ }