@fmaplabs/meta-manifest 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -1
- package/dist/{chunk-PFU5VAO7.js → chunk-AUR2YQCW.js} +2 -2
- package/dist/{chunk-3R6VQ3Z3.js → chunk-VSJUGUH7.js} +15 -3
- package/dist/chunk-VSJUGUH7.js.map +1 -0
- package/dist/{chunk-GH5DXHS5.js → chunk-ZTWFDJHN.js} +318 -54
- package/dist/chunk-ZTWFDJHN.js.map +1 -0
- package/dist/cli/index.cjs +306 -32
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +35 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +332 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +168 -36
- package/dist/index.d.ts +168 -36
- package/dist/index.js +6 -2
- package/dist/node/client.cjs.map +1 -1
- package/dist/node/client.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-3R6VQ3Z3.js.map +0 -1
- package/dist/chunk-GH5DXHS5.js.map +0 -1
- /package/dist/{chunk-PFU5VAO7.js.map → chunk-AUR2YQCW.js.map} +0 -0
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
PULL_DEFINITION_QUERY,
|
|
5
5
|
UPDATE_DEFINITION_MUTATION,
|
|
6
6
|
execute
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VSJUGUH7.js";
|
|
8
8
|
|
|
9
9
|
// src/fields/base.ts
|
|
10
10
|
var Field = class {
|
|
@@ -13,6 +13,14 @@ var Field = class {
|
|
|
13
13
|
required = false;
|
|
14
14
|
name;
|
|
15
15
|
description;
|
|
16
|
+
filterable = false;
|
|
17
|
+
/** Apply the shared field options; call from each concrete constructor. */
|
|
18
|
+
applyCommon(opts) {
|
|
19
|
+
this.required = opts.required ?? false;
|
|
20
|
+
this.name = opts.name;
|
|
21
|
+
this.description = opts.description;
|
|
22
|
+
this.filterable = opts.filterable ?? false;
|
|
23
|
+
}
|
|
16
24
|
/** Constraint validation on an already-typed value. */
|
|
17
25
|
check(_value) {
|
|
18
26
|
return [];
|
|
@@ -69,9 +77,7 @@ var BooleanField = class extends Field {
|
|
|
69
77
|
shopifyType = "boolean";
|
|
70
78
|
constructor(opts) {
|
|
71
79
|
super();
|
|
72
|
-
this.
|
|
73
|
-
this.name = opts.name;
|
|
74
|
-
this.description = opts.description;
|
|
80
|
+
this.applyCommon(opts);
|
|
75
81
|
}
|
|
76
82
|
validations() {
|
|
77
83
|
return [];
|
|
@@ -97,9 +103,7 @@ var ListField = class extends Field {
|
|
|
97
103
|
this.inner = inner;
|
|
98
104
|
this.o = o;
|
|
99
105
|
this.shopifyType = `list.${inner.shopifyType}`;
|
|
100
|
-
this.
|
|
101
|
-
this.name = o.name;
|
|
102
|
-
this.description = o.description;
|
|
106
|
+
this.applyCommon(o);
|
|
103
107
|
}
|
|
104
108
|
inner;
|
|
105
109
|
o;
|
|
@@ -135,9 +139,7 @@ var MeasurementField = class extends Field {
|
|
|
135
139
|
constructor(opts, shopifyType) {
|
|
136
140
|
super();
|
|
137
141
|
this.shopifyType = shopifyType;
|
|
138
|
-
this.
|
|
139
|
-
this.name = opts.name;
|
|
140
|
-
this.description = opts.description;
|
|
142
|
+
this.applyCommon(opts);
|
|
141
143
|
}
|
|
142
144
|
shopifyType;
|
|
143
145
|
wireIsJson = true;
|
|
@@ -173,9 +175,7 @@ var MoneyField = class extends Field {
|
|
|
173
175
|
wireIsJson = true;
|
|
174
176
|
constructor(opts) {
|
|
175
177
|
super();
|
|
176
|
-
this.
|
|
177
|
-
this.name = opts.name;
|
|
178
|
-
this.description = opts.description;
|
|
178
|
+
this.applyCommon(opts);
|
|
179
179
|
}
|
|
180
180
|
validations() {
|
|
181
181
|
return [];
|
|
@@ -201,9 +201,7 @@ var NumericField = class extends Field {
|
|
|
201
201
|
constructor(opts) {
|
|
202
202
|
super();
|
|
203
203
|
this.opts = opts;
|
|
204
|
-
this.
|
|
205
|
-
this.name = opts.name;
|
|
206
|
-
this.description = opts.description;
|
|
204
|
+
this.applyCommon(opts);
|
|
207
205
|
}
|
|
208
206
|
opts;
|
|
209
207
|
toJson(value) {
|
|
@@ -268,9 +266,7 @@ var RatingField = class extends Field {
|
|
|
268
266
|
constructor(o) {
|
|
269
267
|
super();
|
|
270
268
|
this.o = o;
|
|
271
|
-
this.
|
|
272
|
-
this.name = o.name;
|
|
273
|
-
this.description = o.description;
|
|
269
|
+
this.applyCommon(o);
|
|
274
270
|
}
|
|
275
271
|
o;
|
|
276
272
|
shopifyType = "rating";
|
|
@@ -325,9 +321,7 @@ function rating(opts) {
|
|
|
325
321
|
var GidField = class extends Field {
|
|
326
322
|
constructor(opts) {
|
|
327
323
|
super();
|
|
328
|
-
this.
|
|
329
|
-
this.name = opts.name;
|
|
330
|
-
this.description = opts.description;
|
|
324
|
+
this.applyCommon(opts);
|
|
331
325
|
}
|
|
332
326
|
toJson(value) {
|
|
333
327
|
return value;
|
|
@@ -395,9 +389,7 @@ function ref(target, opts = {}) {
|
|
|
395
389
|
var StringScalarField = class extends Field {
|
|
396
390
|
constructor(opts) {
|
|
397
391
|
super();
|
|
398
|
-
this.
|
|
399
|
-
this.name = opts.name;
|
|
400
|
-
this.description = opts.description;
|
|
392
|
+
this.applyCommon(opts);
|
|
401
393
|
}
|
|
402
394
|
toJson(value) {
|
|
403
395
|
return value;
|
|
@@ -447,9 +439,7 @@ var JsonField = class extends Field {
|
|
|
447
439
|
wireIsJson = true;
|
|
448
440
|
constructor(opts) {
|
|
449
441
|
super();
|
|
450
|
-
this.
|
|
451
|
-
this.name = opts.name;
|
|
452
|
-
this.description = opts.description;
|
|
442
|
+
this.applyCommon(opts);
|
|
453
443
|
}
|
|
454
444
|
validations() {
|
|
455
445
|
return [];
|
|
@@ -483,9 +473,7 @@ var TextField = class extends Field {
|
|
|
483
473
|
super();
|
|
484
474
|
this.opts = opts;
|
|
485
475
|
this.shopifyType = multiline ? "multi_line_text_field" : "single_line_text_field";
|
|
486
|
-
this.
|
|
487
|
-
this.name = opts.name;
|
|
488
|
-
this.description = opts.description;
|
|
476
|
+
this.applyCommon(opts);
|
|
489
477
|
}
|
|
490
478
|
opts;
|
|
491
479
|
shopifyType;
|
|
@@ -553,16 +541,44 @@ function mapAccess(access) {
|
|
|
553
541
|
const out = {};
|
|
554
542
|
if (access.admin) out.admin = access.admin.toUpperCase();
|
|
555
543
|
if (access.storefront) out.storefront = access.storefront.toUpperCase();
|
|
544
|
+
if (access.customerAccount) out.customerAccount = access.customerAccount.toUpperCase();
|
|
556
545
|
return out;
|
|
557
546
|
}
|
|
558
547
|
function mapCapabilities(caps) {
|
|
559
548
|
if (!caps) return void 0;
|
|
560
549
|
const out = {};
|
|
561
|
-
|
|
550
|
+
if (caps.publishable != null) out.publishable = { enabled: caps.publishable };
|
|
551
|
+
if (caps.translatable != null) out.translatable = { enabled: caps.translatable };
|
|
552
|
+
if (caps.renderable != null) {
|
|
553
|
+
if (typeof caps.renderable === "boolean") {
|
|
554
|
+
out.renderable = { enabled: caps.renderable };
|
|
555
|
+
} else {
|
|
556
|
+
const data = {};
|
|
557
|
+
if (caps.renderable.metaTitleKey != null) data.metaTitleKey = caps.renderable.metaTitleKey;
|
|
558
|
+
if (caps.renderable.metaDescriptionKey != null) data.metaDescriptionKey = caps.renderable.metaDescriptionKey;
|
|
559
|
+
out.renderable = Object.keys(data).length ? { enabled: true, data } : { enabled: true };
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
if (caps.onlineStore != null) {
|
|
563
|
+
const data = { urlHandle: caps.onlineStore.urlHandle };
|
|
564
|
+
if (caps.onlineStore.createRedirects != null) data.createRedirects = caps.onlineStore.createRedirects;
|
|
565
|
+
out.onlineStore = { enabled: true, data };
|
|
566
|
+
}
|
|
562
567
|
return Object.keys(out).length ? out : void 0;
|
|
563
568
|
}
|
|
569
|
+
function validateSeoKeys(caps, fieldKeys, name) {
|
|
570
|
+
const r = caps?.renderable;
|
|
571
|
+
if (!r || typeof r === "boolean") return;
|
|
572
|
+
for (const prop of ["metaTitleKey", "metaDescriptionKey"]) {
|
|
573
|
+
const key = r[prop];
|
|
574
|
+
if (key != null && !fieldKeys.has(key)) {
|
|
575
|
+
throw new Error(`renderable.${prop} "${key}" is not a declared field key on "${name}".`);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
564
579
|
function toDefinitionInput(schema) {
|
|
565
580
|
const { config } = schema;
|
|
581
|
+
validateSeoKeys(config.capabilities, new Set(Object.keys(schema.fields)), config.name);
|
|
566
582
|
const fieldDefinitions = Object.entries(schema.fields).map(([key, field]) => {
|
|
567
583
|
const def = {
|
|
568
584
|
key,
|
|
@@ -572,6 +588,7 @@ function toDefinitionInput(schema) {
|
|
|
572
588
|
validations: field.validations()
|
|
573
589
|
};
|
|
574
590
|
if (field.description != null) def.description = field.description;
|
|
591
|
+
if (field.filterable) def.capabilities = { adminFilterable: { enabled: true } };
|
|
575
592
|
return def;
|
|
576
593
|
});
|
|
577
594
|
const out = {
|
|
@@ -644,6 +661,12 @@ function defineMetaobject(handle, config) {
|
|
|
644
661
|
|
|
645
662
|
// src/codegen.ts
|
|
646
663
|
var APP_PREFIX = "$app:";
|
|
664
|
+
function isMerchant(type) {
|
|
665
|
+
return !type.startsWith(APP_PREFIX);
|
|
666
|
+
}
|
|
667
|
+
function filterableEntry(field) {
|
|
668
|
+
return field.filterable ? ["filterable: true"] : [];
|
|
669
|
+
}
|
|
647
670
|
var SIMPLE = {
|
|
648
671
|
single_line_text_field: "text",
|
|
649
672
|
multi_line_text_field: "multilineText",
|
|
@@ -725,8 +748,8 @@ function scalarEntries(field, warnings, builder) {
|
|
|
725
748
|
jsonArr("file_type_options", "accept");
|
|
726
749
|
return e;
|
|
727
750
|
}
|
|
728
|
-
function scalarCall(builder, field, warnings) {
|
|
729
|
-
const lit = optsLiteral(scalarEntries(field, warnings, builder));
|
|
751
|
+
function scalarCall(builder, field, warnings, extra = []) {
|
|
752
|
+
const lit = optsLiteral([...scalarEntries(field, warnings, builder), ...extra]);
|
|
730
753
|
return lit ? `m.${builder}(${lit})` : `m.${builder}()`;
|
|
731
754
|
}
|
|
732
755
|
function fieldCall(field, typeToIdent, warnings) {
|
|
@@ -736,6 +759,7 @@ function fieldCall(field, typeToIdent, warnings) {
|
|
|
736
759
|
const max = v(field.validations, "max");
|
|
737
760
|
const e = [`min: ${Number(min ?? 1)}`, `max: ${Number(max ?? 5)}`];
|
|
738
761
|
if (field.required) e.unshift("required: true");
|
|
762
|
+
e.push(...filterableEntry(field));
|
|
739
763
|
if (min === void 0 || max === void 0) warnings.push(`rating field "${field.key}" missing min/max`);
|
|
740
764
|
return `m.rating(${optsLiteral(e)})`;
|
|
741
765
|
}
|
|
@@ -746,7 +770,11 @@ function fieldCall(field, typeToIdent, warnings) {
|
|
|
746
770
|
warnings.push(`unresolved reference on field "${field.key}"`);
|
|
747
771
|
return `m.json() /* TODO: unmapped reference */`;
|
|
748
772
|
}
|
|
749
|
-
|
|
773
|
+
const refEntries = [];
|
|
774
|
+
if (field.required) refEntries.push("required: true");
|
|
775
|
+
refEntries.push(...filterableEntry(field));
|
|
776
|
+
const opts = optsLiteral(refEntries);
|
|
777
|
+
return opts ? `m.ref(() => ${ident}, ${opts})` : `m.ref(() => ${ident})`;
|
|
750
778
|
}
|
|
751
779
|
if (type.startsWith("list.")) {
|
|
752
780
|
const inner = type.slice("list.".length);
|
|
@@ -756,6 +784,7 @@ function fieldCall(field, typeToIdent, warnings) {
|
|
|
756
784
|
const max = v(field.validations, "list.max");
|
|
757
785
|
if (min !== void 0) listEntries.push(`min: ${Number(min)}`);
|
|
758
786
|
if (max !== void 0) listEntries.push(`max: ${Number(max)}`);
|
|
787
|
+
listEntries.push(...filterableEntry(field));
|
|
759
788
|
const listOpts = optsLiteral(listEntries);
|
|
760
789
|
let innerCall;
|
|
761
790
|
if (inner === "metaobject_reference") {
|
|
@@ -774,17 +803,53 @@ function fieldCall(field, typeToIdent, warnings) {
|
|
|
774
803
|
}
|
|
775
804
|
return listOpts ? `m.list(${innerCall}, ${listOpts})` : `m.list(${innerCall})`;
|
|
776
805
|
}
|
|
777
|
-
if (SIMPLE[type]) return scalarCall(SIMPLE[type], field, warnings);
|
|
806
|
+
if (SIMPLE[type]) return scalarCall(SIMPLE[type], field, warnings, filterableEntry(field));
|
|
778
807
|
warnings.push(`unmapped field type "${type}" on field "${field.key}"`);
|
|
779
808
|
return `m.json() /* TODO: unmapped type ${type} */`;
|
|
780
809
|
}
|
|
810
|
+
function accessSource(access) {
|
|
811
|
+
if (!access) return "";
|
|
812
|
+
const parts = [];
|
|
813
|
+
if (access.admin === "MERCHANT_READ_WRITE") parts.push(`admin: "merchant_read_write"`);
|
|
814
|
+
if (access.storefront === "PUBLIC_READ") parts.push(`storefront: "public_read"`);
|
|
815
|
+
if (access.customerAccount === "READ") parts.push(`customerAccount: "read"`);
|
|
816
|
+
return parts.length ? `{ ${parts.join(", ")} }` : "";
|
|
817
|
+
}
|
|
818
|
+
function capabilitiesSource(caps) {
|
|
819
|
+
if (!caps) return "";
|
|
820
|
+
const parts = [];
|
|
821
|
+
if (caps.publishable?.enabled) parts.push(`publishable: true`);
|
|
822
|
+
if (caps.translatable?.enabled) parts.push(`translatable: true`);
|
|
823
|
+
if (caps.renderable?.enabled) {
|
|
824
|
+
const d = caps.renderable.data;
|
|
825
|
+
const dparts = [];
|
|
826
|
+
if (d?.metaTitleKey != null) dparts.push(`metaTitleKey: ${JSON.stringify(d.metaTitleKey)}`);
|
|
827
|
+
if (d?.metaDescriptionKey != null) dparts.push(`metaDescriptionKey: ${JSON.stringify(d.metaDescriptionKey)}`);
|
|
828
|
+
parts.push(dparts.length ? `renderable: { ${dparts.join(", ")} }` : `renderable: true`);
|
|
829
|
+
}
|
|
830
|
+
if (caps.onlineStore?.enabled && caps.onlineStore.data?.urlHandle != null) {
|
|
831
|
+
parts.push(`onlineStore: { urlHandle: ${JSON.stringify(caps.onlineStore.data.urlHandle)} }`);
|
|
832
|
+
}
|
|
833
|
+
return parts.length ? `{ ${parts.join(", ")} }` : "";
|
|
834
|
+
}
|
|
835
|
+
function defConfigLines(def) {
|
|
836
|
+
const lines = [];
|
|
837
|
+
if (isMerchant(def.type)) lines.push(` scope: "merchant",`);
|
|
838
|
+
if (def.name) lines.push(` name: ${JSON.stringify(def.name)},`);
|
|
839
|
+
if (def.description != null) lines.push(` description: ${JSON.stringify(def.description)},`);
|
|
840
|
+
if (def.displayNameKey != null) lines.push(` displayName: ${JSON.stringify(def.displayNameKey)},`);
|
|
841
|
+
const access = accessSource(def.access);
|
|
842
|
+
if (access) lines.push(` access: ${access},`);
|
|
843
|
+
const caps = capabilitiesSource(def.capabilities);
|
|
844
|
+
if (caps) lines.push(` capabilities: ${caps},`);
|
|
845
|
+
return lines.length ? `
|
|
846
|
+
${lines.join("\n")}` : "";
|
|
847
|
+
}
|
|
781
848
|
function defSource(def, typeToIdent, warnings) {
|
|
782
849
|
const ident = typeToIdent.get(def.type);
|
|
783
850
|
const handle = handleOf(def.type);
|
|
784
851
|
const fields = def.fields.map((f) => ` ${f.key}: ${fieldCall(f, typeToIdent, warnings)},`).join("\n");
|
|
785
|
-
const
|
|
786
|
-
name: ${JSON.stringify(def.name)},` : "";
|
|
787
|
-
return `export const ${ident} = defineMetaobject(${JSON.stringify(handle)}, {${name}
|
|
852
|
+
return `export const ${ident} = defineMetaobject(${JSON.stringify(handle)}, {${defConfigLines(def)}
|
|
788
853
|
fields: {
|
|
789
854
|
${fields}
|
|
790
855
|
},
|
|
@@ -844,6 +909,42 @@ function sameValidations(a, b) {
|
|
|
844
909
|
const norm = (v2) => JSON.stringify([...v2].sort((x, y) => x.name.localeCompare(y.name)));
|
|
845
910
|
return norm(a) === norm(b);
|
|
846
911
|
}
|
|
912
|
+
var CAP_KEYS = ["publishable", "translatable", "renderable", "onlineStore"];
|
|
913
|
+
function accessChanged(local, remote) {
|
|
914
|
+
for (const key of ["admin", "storefront", "customerAccount"]) {
|
|
915
|
+
const lv = local[key];
|
|
916
|
+
if (lv != null && remote?.[key] !== lv) return true;
|
|
917
|
+
}
|
|
918
|
+
return false;
|
|
919
|
+
}
|
|
920
|
+
function capabilitiesChanged(local, remote) {
|
|
921
|
+
for (const key of CAP_KEYS) {
|
|
922
|
+
const lc = local[key];
|
|
923
|
+
if (!lc) continue;
|
|
924
|
+
const rc = remote?.[key];
|
|
925
|
+
if ((rc?.enabled ?? false) !== lc.enabled) return true;
|
|
926
|
+
const ldata = lc.data;
|
|
927
|
+
if (ldata) {
|
|
928
|
+
const rdata = rc?.data;
|
|
929
|
+
for (const [k, v2] of Object.entries(ldata)) {
|
|
930
|
+
if (v2 != null && rdata?.[k] !== v2) return true;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
return false;
|
|
935
|
+
}
|
|
936
|
+
function disablesOnlineStore(local, remote) {
|
|
937
|
+
return local.onlineStore?.enabled === false && remote?.onlineStore?.enabled === true;
|
|
938
|
+
}
|
|
939
|
+
function definitionChanges(local, remote) {
|
|
940
|
+
const changes = [];
|
|
941
|
+
if (local.name != null && local.name !== remote.name) changes.push("name");
|
|
942
|
+
if (local.description != null && local.description !== remote.description) changes.push("description");
|
|
943
|
+
if (local.displayNameKey != null && local.displayNameKey !== remote.displayNameKey) changes.push("displayNameKey");
|
|
944
|
+
if (local.access && accessChanged(local.access, remote.access)) changes.push("access");
|
|
945
|
+
if (local.capabilities && capabilitiesChanged(local.capabilities, remote.capabilities)) changes.push("capabilities");
|
|
946
|
+
return changes;
|
|
947
|
+
}
|
|
847
948
|
function diff(local, remote) {
|
|
848
949
|
const ops = [];
|
|
849
950
|
const remoteByType = new Map(remote.map((d) => [d.type, d]));
|
|
@@ -867,6 +968,7 @@ function diff(local, remote) {
|
|
|
867
968
|
}
|
|
868
969
|
const changes = {};
|
|
869
970
|
if (rf.required !== lf.required) changes.required = lf.required;
|
|
971
|
+
if (rf.filterable !== lf.filterable) changes.filterable = lf.filterable;
|
|
870
972
|
if (!sameValidations(rf.validations, lf.validations)) changes.validations = lf.validations;
|
|
871
973
|
if (Object.keys(changes).length) {
|
|
872
974
|
ops.push({ kind: "updateField", type: localDef.type, key: lf.key, changes });
|
|
@@ -877,49 +979,179 @@ function diff(local, remote) {
|
|
|
877
979
|
ops.push({ kind: "removeField", type: localDef.type, key: rf.key, destructive: true });
|
|
878
980
|
}
|
|
879
981
|
}
|
|
982
|
+
const metaChanges = definitionChanges(localDef, remoteDef);
|
|
983
|
+
if (metaChanges.length) {
|
|
984
|
+
const destructive = localDef.capabilities ? disablesOnlineStore(localDef.capabilities, remoteDef.capabilities) : false;
|
|
985
|
+
ops.push({
|
|
986
|
+
kind: "updateDefinition",
|
|
987
|
+
type: localDef.type,
|
|
988
|
+
changes: metaChanges,
|
|
989
|
+
...destructive ? { destructive: true } : {}
|
|
990
|
+
});
|
|
991
|
+
}
|
|
880
992
|
}
|
|
881
993
|
return ops;
|
|
882
994
|
}
|
|
883
995
|
|
|
884
996
|
// src/sync/normalize.ts
|
|
885
|
-
function
|
|
886
|
-
const
|
|
887
|
-
|
|
997
|
+
function localCapabilities(caps) {
|
|
998
|
+
const out = {};
|
|
999
|
+
if (caps?.publishable) out.publishable = { enabled: caps.publishable.enabled };
|
|
1000
|
+
if (caps?.translatable) out.translatable = { enabled: caps.translatable.enabled };
|
|
1001
|
+
if (caps?.renderable) {
|
|
1002
|
+
out.renderable = { enabled: caps.renderable.enabled };
|
|
1003
|
+
if (caps.renderable.data) out.renderable.data = { ...caps.renderable.data };
|
|
1004
|
+
}
|
|
1005
|
+
out.onlineStore = caps?.onlineStore ? { enabled: caps.onlineStore.enabled, data: { urlHandle: caps.onlineStore.data?.urlHandle } } : { enabled: false };
|
|
1006
|
+
return out;
|
|
1007
|
+
}
|
|
1008
|
+
function normalizeDefinition(def) {
|
|
1009
|
+
const out = {
|
|
888
1010
|
type: def.type,
|
|
889
1011
|
name: def.name,
|
|
1012
|
+
capabilities: localCapabilities(def.capabilities),
|
|
890
1013
|
fields: def.fieldDefinitions.map((f) => ({
|
|
891
1014
|
key: f.key,
|
|
892
1015
|
type: f.type,
|
|
893
1016
|
required: f.required,
|
|
1017
|
+
filterable: f.capabilities?.adminFilterable?.enabled ?? false,
|
|
894
1018
|
validations: f.validations
|
|
895
1019
|
}))
|
|
896
1020
|
};
|
|
1021
|
+
if (def.description != null) out.description = def.description;
|
|
1022
|
+
if (def.displayNameKey != null) out.displayNameKey = def.displayNameKey;
|
|
1023
|
+
if (def.access) out.access = { ...def.access };
|
|
1024
|
+
return out;
|
|
1025
|
+
}
|
|
1026
|
+
function normalizeLocal(schema) {
|
|
1027
|
+
return normalizeDefinition(schema.toDefinitionInput());
|
|
1028
|
+
}
|
|
1029
|
+
function remoteAccess(access) {
|
|
1030
|
+
if (!access) return void 0;
|
|
1031
|
+
const out = {};
|
|
1032
|
+
if (access.admin != null) out.admin = access.admin;
|
|
1033
|
+
if (access.storefront != null) out.storefront = access.storefront;
|
|
1034
|
+
if (access.customerAccount != null) out.customerAccount = access.customerAccount;
|
|
1035
|
+
return out;
|
|
1036
|
+
}
|
|
1037
|
+
function remoteCapabilities(caps) {
|
|
1038
|
+
const out = {};
|
|
1039
|
+
if (!caps) return out;
|
|
1040
|
+
if (caps.publishable) out.publishable = { enabled: !!caps.publishable.enabled };
|
|
1041
|
+
if (caps.translatable) out.translatable = { enabled: !!caps.translatable.enabled };
|
|
1042
|
+
if (caps.renderable) {
|
|
1043
|
+
out.renderable = { enabled: !!caps.renderable.enabled };
|
|
1044
|
+
const d = caps.renderable.data;
|
|
1045
|
+
if (d) {
|
|
1046
|
+
const data = {};
|
|
1047
|
+
if (d.metaTitleKey != null) data.metaTitleKey = d.metaTitleKey;
|
|
1048
|
+
if (d.metaDescriptionKey != null) data.metaDescriptionKey = d.metaDescriptionKey;
|
|
1049
|
+
if (Object.keys(data).length) out.renderable.data = data;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
if (caps.onlineStore) {
|
|
1053
|
+
out.onlineStore = { enabled: !!caps.onlineStore.enabled };
|
|
1054
|
+
if (caps.onlineStore.data?.urlHandle != null) out.onlineStore.data = { urlHandle: caps.onlineStore.data.urlHandle };
|
|
1055
|
+
}
|
|
1056
|
+
return out;
|
|
897
1057
|
}
|
|
898
1058
|
function normalizeRemote(def) {
|
|
899
|
-
|
|
1059
|
+
const out = {
|
|
900
1060
|
type: def.type,
|
|
901
1061
|
name: def.name,
|
|
1062
|
+
capabilities: remoteCapabilities(def.capabilities),
|
|
902
1063
|
fields: def.fieldDefinitions.map((f) => ({
|
|
903
1064
|
key: f.key,
|
|
904
1065
|
type: typeof f.type === "string" ? f.type : f.type.name,
|
|
905
1066
|
required: f.required,
|
|
1067
|
+
filterable: f.capabilities?.adminFilterable?.enabled ?? false,
|
|
906
1068
|
validations: f.validations ?? []
|
|
907
1069
|
}))
|
|
908
1070
|
};
|
|
1071
|
+
if (def.description != null) out.description = def.description;
|
|
1072
|
+
if (def.displayNameKey != null) out.displayNameKey = def.displayNameKey;
|
|
1073
|
+
const access = remoteAccess(def.access);
|
|
1074
|
+
if (access) out.access = access;
|
|
1075
|
+
return out;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
// src/sync/resolve.ts
|
|
1079
|
+
var APP_PREFIX2 = "$app:";
|
|
1080
|
+
function effectiveScope(schema, config) {
|
|
1081
|
+
return schema.config.scope ?? config.scope ?? "app";
|
|
1082
|
+
}
|
|
1083
|
+
function effectiveType(handle, scope) {
|
|
1084
|
+
return scope === "merchant" ? handle : `${APP_PREFIX2}${handle}`;
|
|
1085
|
+
}
|
|
1086
|
+
function rewriteReference(v2, effByCanonical) {
|
|
1087
|
+
if (v2.name === "metaobject_definition_type") {
|
|
1088
|
+
const mapped = effByCanonical.get(v2.value);
|
|
1089
|
+
return mapped ? { ...v2, value: mapped } : v2;
|
|
1090
|
+
}
|
|
1091
|
+
if (v2.name === "metaobject_definition_types") {
|
|
1092
|
+
try {
|
|
1093
|
+
const parsed = JSON.parse(v2.value);
|
|
1094
|
+
if (Array.isArray(parsed)) {
|
|
1095
|
+
const rewritten = parsed.map((t) => typeof t === "string" ? effByCanonical.get(t) ?? t : t);
|
|
1096
|
+
return { ...v2, value: JSON.stringify(rewritten) };
|
|
1097
|
+
}
|
|
1098
|
+
} catch {
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
return v2;
|
|
1102
|
+
}
|
|
1103
|
+
function resolveAdmin(out, handle, scope, config) {
|
|
1104
|
+
const explicitAdmin = out.access?.admin;
|
|
1105
|
+
if (scope === "merchant") {
|
|
1106
|
+
if (explicitAdmin != null) {
|
|
1107
|
+
throw new Error(
|
|
1108
|
+
`"${handle}" is merchant-scoped but sets access.admin; admin access is only valid on app-scoped metaobjects.`
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1113
|
+
if (explicitAdmin == null) {
|
|
1114
|
+
const admin = config.merchantEditable ? "MERCHANT_READ_WRITE" : "MERCHANT_READ";
|
|
1115
|
+
out.access = { ...out.access, admin };
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
function resolveDefinitions(schemas, config = {}) {
|
|
1119
|
+
const effByCanonical = /* @__PURE__ */ new Map();
|
|
1120
|
+
for (const s of schemas) {
|
|
1121
|
+
effByCanonical.set(`${APP_PREFIX2}${s.handle}`, effectiveType(s.handle, effectiveScope(s, config)));
|
|
1122
|
+
}
|
|
1123
|
+
return schemas.map((s) => {
|
|
1124
|
+
const scope = effectiveScope(s, config);
|
|
1125
|
+
const base = s.toDefinitionInput();
|
|
1126
|
+
const fieldDefinitions = base.fieldDefinitions.map((f) => ({
|
|
1127
|
+
...f,
|
|
1128
|
+
validations: f.validations.map((v2) => rewriteReference(v2, effByCanonical))
|
|
1129
|
+
}));
|
|
1130
|
+
const out = { ...base, type: effectiveType(s.handle, scope), fieldDefinitions };
|
|
1131
|
+
resolveAdmin(out, s.handle, scope, config);
|
|
1132
|
+
return out;
|
|
1133
|
+
});
|
|
909
1134
|
}
|
|
910
1135
|
|
|
911
1136
|
// src/sync/pull.ts
|
|
1137
|
+
function toDefinition(type, node) {
|
|
1138
|
+
return {
|
|
1139
|
+
type,
|
|
1140
|
+
name: node.name,
|
|
1141
|
+
description: node.description,
|
|
1142
|
+
displayNameKey: node.displayNameKey,
|
|
1143
|
+
access: node.access,
|
|
1144
|
+
capabilities: node.capabilities,
|
|
1145
|
+
fieldDefinitions: node.fieldDefinitions
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
912
1148
|
async function pull(client, types) {
|
|
913
1149
|
const out = [];
|
|
914
1150
|
for (const type of types) {
|
|
915
1151
|
const data = await execute(client, PULL_DEFINITION_QUERY, { type });
|
|
916
1152
|
const node = data.metaobjectDefinitionByType;
|
|
917
1153
|
if (!node) continue;
|
|
918
|
-
out.push({
|
|
919
|
-
id: node.id,
|
|
920
|
-
type,
|
|
921
|
-
definition: { type, name: node.name, fieldDefinitions: node.fieldDefinitions }
|
|
922
|
-
});
|
|
1154
|
+
out.push({ id: node.id, type, definition: toDefinition(type, node) });
|
|
923
1155
|
}
|
|
924
1156
|
return out;
|
|
925
1157
|
}
|
|
@@ -937,7 +1169,7 @@ async function pullAll(client, opts = {}) {
|
|
|
937
1169
|
const canonical = toCanonicalType(node.type);
|
|
938
1170
|
if (appOwnedOnly && !canonical) continue;
|
|
939
1171
|
const type = canonical ?? node.type;
|
|
940
|
-
out.push({ id: node.id, type, definition:
|
|
1172
|
+
out.push({ id: node.id, type, definition: toDefinition(type, node) });
|
|
941
1173
|
}
|
|
942
1174
|
after = data.metaobjectDefinitions.pageInfo.hasNextPage ? data.metaobjectDefinitions.pageInfo.endCursor : null;
|
|
943
1175
|
} while (after !== null);
|
|
@@ -945,6 +1177,25 @@ async function pullAll(client, opts = {}) {
|
|
|
945
1177
|
}
|
|
946
1178
|
|
|
947
1179
|
// src/sync/push.ts
|
|
1180
|
+
function definitionUpdateFor(def, changes) {
|
|
1181
|
+
const out = {};
|
|
1182
|
+
for (const c of changes) {
|
|
1183
|
+
if (c === "name") out.name = def.name;
|
|
1184
|
+
else if (c === "description") out.description = def.description;
|
|
1185
|
+
else if (c === "displayNameKey") out.displayNameKey = def.displayNameKey;
|
|
1186
|
+
else if (c === "access") out.access = def.access;
|
|
1187
|
+
else if (c === "capabilities") {
|
|
1188
|
+
const caps = def.capabilities;
|
|
1189
|
+
const payload = {};
|
|
1190
|
+
if (caps?.publishable) payload.publishable = caps.publishable;
|
|
1191
|
+
if (caps?.translatable) payload.translatable = caps.translatable;
|
|
1192
|
+
if (caps?.renderable) payload.renderable = caps.renderable;
|
|
1193
|
+
payload.onlineStore = caps?.onlineStore ?? { enabled: false };
|
|
1194
|
+
out.capabilities = payload;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
return out;
|
|
1198
|
+
}
|
|
948
1199
|
function fieldInputFor(defByType, type, key) {
|
|
949
1200
|
return defByType.get(type)?.fieldDefinitions.find((f) => f.key === key);
|
|
950
1201
|
}
|
|
@@ -1045,14 +1296,22 @@ async function push(client, plan, sources, options) {
|
|
|
1045
1296
|
if (id2) idByType.set(op.type, id2);
|
|
1046
1297
|
return { op, status: "applied", id: id2 };
|
|
1047
1298
|
}
|
|
1048
|
-
const destructive =
|
|
1299
|
+
const destructive = "destructive" in op && op.destructive === true;
|
|
1049
1300
|
if (destructive && !allowDestructive) return { op, status: "skipped", reason: "destructive" };
|
|
1050
1301
|
if (failedTypes.has(op.type)) return { op, status: "blocked", reason: `blocked: definition "${op.type}" was not created` };
|
|
1051
1302
|
const id = idByType.get(op.type);
|
|
1052
1303
|
if (id == null) return { op, status: "blocked", reason: `no definition id for "${op.type}"` };
|
|
1053
|
-
|
|
1054
|
-
if (
|
|
1055
|
-
|
|
1304
|
+
let definition;
|
|
1305
|
+
if (op.kind === "updateDefinition") {
|
|
1306
|
+
const def = defByType.get(op.type);
|
|
1307
|
+
if (!def) return { op, status: "blocked", reason: `no definition input for "${op.type}"` };
|
|
1308
|
+
definition = definitionUpdateFor(def, op.changes);
|
|
1309
|
+
} else {
|
|
1310
|
+
const fieldDefinitions = fieldOpsFor(op);
|
|
1311
|
+
if (!fieldDefinitions) return { op, status: "blocked", reason: `no field input for "${op.type}"` };
|
|
1312
|
+
definition = { fieldDefinitions };
|
|
1313
|
+
}
|
|
1314
|
+
const data = await execute(client, UPDATE_DEFINITION_MUTATION, { id, definition });
|
|
1056
1315
|
const payload = data.metaobjectDefinitionUpdate;
|
|
1057
1316
|
if (payload.userErrors.length) return { op, status: "failed", userErrors: payload.userErrors };
|
|
1058
1317
|
return { op, status: "applied", id: payload.metaobjectDefinition?.id ?? id };
|
|
@@ -1073,6 +1332,9 @@ async function push(client, plan, sources, options) {
|
|
|
1073
1332
|
validations: field.validations
|
|
1074
1333
|
};
|
|
1075
1334
|
if (field.description != null) update.description = field.description;
|
|
1335
|
+
if ("filterable" in op.changes) {
|
|
1336
|
+
update.capabilities = { adminFilterable: { enabled: op.changes.filterable ?? false } };
|
|
1337
|
+
}
|
|
1076
1338
|
return [{ update }];
|
|
1077
1339
|
}
|
|
1078
1340
|
case "removeField":
|
|
@@ -1099,10 +1361,12 @@ export {
|
|
|
1099
1361
|
defineMetaobject,
|
|
1100
1362
|
generateSchemaSource,
|
|
1101
1363
|
diff,
|
|
1364
|
+
normalizeDefinition,
|
|
1102
1365
|
normalizeLocal,
|
|
1103
1366
|
normalizeRemote,
|
|
1367
|
+
resolveDefinitions,
|
|
1104
1368
|
pull,
|
|
1105
1369
|
pullAll,
|
|
1106
1370
|
push
|
|
1107
1371
|
};
|
|
1108
|
-
//# sourceMappingURL=chunk-
|
|
1372
|
+
//# sourceMappingURL=chunk-ZTWFDJHN.js.map
|