@notambourine/metafields 0.0.7 → 0.2.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.
Files changed (73) hide show
  1. package/README.md +126 -94
  2. package/dist/admin-shapes.d.ts +57 -0
  3. package/dist/admin-shapes.d.ts.map +1 -0
  4. package/dist/admin-shapes.js +67 -0
  5. package/dist/admin-shapes.js.map +1 -0
  6. package/dist/admin.d.ts +8 -7
  7. package/dist/admin.d.ts.map +1 -1
  8. package/dist/admin.js +116 -126
  9. package/dist/admin.js.map +1 -1
  10. package/dist/app-config.d.ts +5 -0
  11. package/dist/app-config.d.ts.map +1 -0
  12. package/dist/app-config.js +50 -0
  13. package/dist/app-config.js.map +1 -0
  14. package/dist/builders.js +2 -2
  15. package/dist/builders.js.map +1 -1
  16. package/dist/changes.d.ts +20 -0
  17. package/dist/changes.d.ts.map +1 -0
  18. package/dist/changes.js +85 -0
  19. package/dist/changes.js.map +1 -0
  20. package/dist/cli.js +153 -85
  21. package/dist/cli.js.map +1 -1
  22. package/dist/doctor.d.ts +16 -0
  23. package/dist/doctor.d.ts.map +1 -0
  24. package/dist/doctor.js +61 -0
  25. package/dist/doctor.js.map +1 -0
  26. package/dist/fleet.d.ts +7 -6
  27. package/dist/fleet.d.ts.map +1 -1
  28. package/dist/fleet.js +18 -18
  29. package/dist/fleet.js.map +1 -1
  30. package/dist/generator.js +1 -1
  31. package/dist/generator.js.map +1 -1
  32. package/dist/index.d.ts +12 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +6 -1
  35. package/dist/index.js.map +1 -1
  36. package/dist/liquid.d.ts.map +1 -1
  37. package/dist/liquid.js +4 -19
  38. package/dist/liquid.js.map +1 -1
  39. package/dist/metafield-types.d.ts +601 -0
  40. package/dist/metafield-types.d.ts.map +1 -0
  41. package/dist/metafield-types.js +150 -0
  42. package/dist/metafield-types.js.map +1 -0
  43. package/dist/migration.d.ts +3 -2
  44. package/dist/migration.d.ts.map +1 -1
  45. package/dist/migration.js +4 -6
  46. package/dist/migration.js.map +1 -1
  47. package/dist/planner.d.ts +2 -2
  48. package/dist/planner.d.ts.map +1 -1
  49. package/dist/planner.js +5 -3
  50. package/dist/planner.js.map +1 -1
  51. package/dist/pull.d.ts.map +1 -1
  52. package/dist/pull.js +14 -61
  53. package/dist/pull.js.map +1 -1
  54. package/dist/references.d.ts +13 -0
  55. package/dist/references.d.ts.map +1 -0
  56. package/dist/references.js +69 -0
  57. package/dist/references.js.map +1 -0
  58. package/dist/schema.d.ts.map +1 -1
  59. package/dist/schema.js +1 -0
  60. package/dist/schema.js.map +1 -1
  61. package/dist/type-check.d.ts +14 -0
  62. package/dist/type-check.d.ts.map +1 -0
  63. package/dist/type-check.js +61 -0
  64. package/dist/type-check.js.map +1 -0
  65. package/dist/type-registry.d.ts +21 -0
  66. package/dist/type-registry.d.ts.map +1 -0
  67. package/dist/type-registry.js +48 -0
  68. package/dist/type-registry.js.map +1 -0
  69. package/package.json +3 -2
  70. package/dist/repair.d.ts +0 -16
  71. package/dist/repair.d.ts.map +0 -1
  72. package/dist/repair.js +0 -53
  73. package/dist/repair.js.map +0 -1
package/README.md CHANGED
@@ -1,8 +1,13 @@
1
1
  # @notambourine/metafields
2
2
 
3
- Declare merchant-owned Shopify metafield and metaobject definitions in TypeScript, inspect drift,
4
- and create only what is missing. Schema sync creates and never updates; `--repair` is the one
5
- opt-in that rewrites a definition, and nothing deletes one.
3
+ Declare Shopify metafield and metaobject definitions in TypeScript, inspect store drift, and apply
4
+ controlled changes. The CLI never deletes or retypes a definition.
5
+
6
+ Requires Node.js 22.18 or newer.
7
+
8
+ ## Quick start
9
+
10
+ Create `schema.ts`:
6
11
 
7
12
  ```ts
8
13
  import { defineSchema, field, metaobject } from '@notambourine/metafields';
@@ -29,141 +34,149 @@ export default defineSchema({
29
34
  });
30
35
  ```
31
36
 
37
+ Validate it, inspect a store, then apply the plan:
38
+
32
39
  ```sh
33
40
  npx @notambourine/metafields ./schema.ts --validate
34
41
  npx @notambourine/metafields ./schema.ts --store example.myshopify.com
35
42
  npx @notambourine/metafields ./schema.ts --store example.myshopify.com --apply
36
- npx @notambourine/metafields ./schema.ts --store example.myshopify.com --check
37
43
  ```
38
44
 
39
- The default command is a dry run. Importing a TypeScript schema executes trusted local code, so
40
- compile declarations to canonical JSON before a secret-bearing workflow consumes pull-request
41
- output.
42
-
43
- Schema modules use Node's built-in type stripping and must use erasable TypeScript syntax.
45
+ Schema modules run as trusted local code through Node's type stripping. Use erasable TypeScript
46
+ syntax. Compile untrusted pull-request declarations before a credentialed workflow consumes them:
44
47
 
45
- See `metafields --help` for `pull`, `compile`, `emit`, and migration commands.
48
+ ```sh
49
+ npx @notambourine/metafields compile ./schema.ts --out ./schema.json
50
+ ```
46
51
 
47
- ## Auth
52
+ Every command accepts `--json` and answers with a single JSON object on stdout, carrying the
53
+ identities it left out under `excluded` or `skipped`. Without `--json`, the document goes to
54
+ stdout and those identities to stderr, so stdout stays pipeable. Writing to `--out` reports
55
+ `{"status":"written","out":"..."}` instead of the document.
48
56
 
49
- Set `SHOPIFY_APP_CLIENT_ID` (or pass `--client-id`) and `SHOPIFY_APP_SECRET`, and the CLI mints a
50
- short-lived Admin token per store with the `client_credentials` grant. Two grant errors stay
51
- distinct in the output because a fleet treats them differently: `app_not_installed` means the store
52
- has not installed the app, `shop_not_permitted` means the app and the store are in different
53
- organizations.
57
+ ## Changes and safety
54
58
 
55
- `SHOPIFY_ADMIN_ACCESS_TOKEN` still works and reaches one store; app auth is an option, not a
56
- requirement. Complete app credentials win when both are set, and half-set ones fall back to the
57
- token rather than failing. Only a fleet, which one token cannot reach, requires the app.
59
+ Without `--apply`, the CLI only reports drift. A definition is updated as one unit: if any part is
60
+ blocked or needs `--force`, its other changes wait too. Other definitions continue independently.
58
61
 
59
- Minted tokens are never logged, and Shopify credential prefixes are redacted from errors.
62
+ | Change | Required mode |
63
+ | --- | --- |
64
+ | Create a definition or add a metaobject field | `--apply` |
65
+ | Update labels, `displayNameKey`, or enable a capability | `--apply` |
66
+ | Change access, validations, constraints, or `required` | `--apply --force` |
67
+ | Disable a capability | `--apply --force` |
68
+ | Delete or retype a definition | Never performed |
69
+ | Change invalid values or a definition Shopify is still validating | Never performed |
60
70
 
61
- ## Repair
71
+ `--force` opts into changes that can break a storefront or strand stored values. For schema sync it
72
+ requires `--apply`; it cannot override Shopify constraints or repair data.
62
73
 
63
- `--repair` issues the update mutations that resolve drift a plan reported as `CONFLICT`. It is
64
- never implied by `--apply`, so the only way a definition is rewritten is a human typing the flag.
65
- Without `--apply` it is a dry run that reports exactly what it would change.
74
+ Use `--dry-run` to cancel requested writes while preserving the plan and exit code:
66
75
 
67
76
  ```sh
68
- metafields ./schema.ts --store example.myshopify.com --repair
69
- metafields ./schema.ts --store example.myshopify.com --repair --apply
77
+ npx @notambourine/metafields ./schema.ts \
78
+ --store example.myshopify.com --apply --force --dry-run
70
79
  ```
71
80
 
72
- Repairable: `required`, storefront `access`, `capabilities`, `validations`, `constraints`,
73
- metaobject `displayNameKey`, and a field missing from an existing metaobject.
81
+ Exit codes describe the result:
74
82
 
75
- Reported and skipped, never attempted:
83
+ - `0`: the store matches the schema.
84
+ - `1`: actionable drift remains.
85
+ - `2`: input is invalid, Shopify state is indeterminate, or an operation failed.
76
86
 
77
- - A `type` that differs. Shopify will not retype a definition that has stored values; that is what
78
- the migration commands are for.
79
- - Invalid stored values (`validationStatus: SOME_INVALID`). That is data, not shape.
80
- - Anything `INDETERMINATE`, meaning validation is still in progress. Wait, do not write.
87
+ Cosmetic label drift does not change the exit code. Mutations retry Shopify's explicit
88
+ `THROTTLED` response, but are not retried after a timeout or `5xx` because the first request may
89
+ have landed.
81
90
 
82
- A definition with any of those is skipped whole, so a partial update never reads like progress. It
83
- also keeps blocking writes to the fleet, the same as a conflict without `--repair`.
91
+ ## Metaobject references
84
92
 
85
- Shopify refuses `required: true` on a field whose existing entries are blank. That `userErrors`
86
- message is surfaced intact, because the operator needs to know which entries to fill.
93
+ `field.metaobject()` and `field.mixedMetaobject()` name metaobject types, which are the same on
94
+ every store. Shopify stores the reference as a definition ID, which is not, so the CLI resolves
95
+ types to that store's IDs when it writes and reports them as types when it reads. A referenced
96
+ metaobject must be declared in the same schema; it is created before anything that references it.
87
97
 
88
- ## Fleets
98
+ ## Authentication
89
99
 
90
- `--store` repeats, and `--stores-from <file>` sweeps a list of stores, one per line, with `#`
91
- comments:
100
+ For one store, set an Admin API token:
92
101
 
93
102
  ```sh
94
- metafields ./schema.ts --store flagship.myshopify.com --stores-from ./stores.txt --apply
103
+ export SHOPIFY_ADMIN_ACCESS_TOKEN=...
95
104
  ```
96
105
 
97
- - Every store is planned before any store is written to. Drift on one store that a repair cannot
98
- resolve exits nonzero having written nothing, because writing to the others first half-applies
99
- the fleet.
100
- - A swept store that cannot be reached is reported and does not abort the run, as long as one store
101
- could be planned. A swept store that has not installed the app is reported as `NOT-INSTALLED` and
102
- keeps the run green.
103
- - A store named on the command line never fails quietly; only a swept store is downgraded.
104
- - Writes run per store, so one store refusing does not stop the next, and every refusal is
105
- reported together.
106
- - Exit is `2` if any store was unreachable or refused a write, even when every reached store came
107
- back clean.
108
-
109
- ## Types
106
+ For one store or a fleet, set app credentials. The CLI mints a short-lived token for each store:
110
107
 
111
- The schema is the single declaration. Value types come back out of it with `InferMetafields` and
112
- `InferMetaobjects`, and fields declared `required: true` are not optional in the inferred type:
108
+ ```sh
109
+ export SHOPIFY_APP_CLIENT_ID=...
110
+ export SHOPIFY_APP_SECRET=...
111
+ ```
113
112
 
114
- ```ts
115
- type Product = InferMetafields<typeof schema>['product'];
113
+ The client ID is resolved from `--client-id`, then `--app-config`, then
114
+ `SHOPIFY_APP_CLIENT_ID`. The secret is read only from `SHOPIFY_APP_SECRET`.
116
115
 
117
- const promo: string | undefined = product.custom.promo_text;
118
- const sku: string = product.custom.sku; // declared required
116
+ ```sh
117
+ npx @notambourine/metafields ./schema.ts \
118
+ --app-config ./shopify.app.toml --store example.myshopify.com --apply
119
119
  ```
120
120
 
121
- ## Liquid
121
+ `--app-config` reads only the top-level `client_id`. Complete app credentials take priority over a
122
+ static token; incomplete app credentials fall back to the token. Credentials are redacted from
123
+ errors.
122
124
 
123
- `emit --liquid` writes `.shopify/metafields.json`, the file Shopify's Liquid language server reads
124
- to complete and hover `product.metafields.custom.promo_text`:
125
+ ## Fleets
126
+
127
+ Repeat `--store` or load one store per line from a file. Lines beginning with `#` are ignored.
125
128
 
126
129
  ```sh
127
- metafields emit ./schema.ts --liquid --out .shopify/metafields.json
130
+ npx @notambourine/metafields ./schema.ts \
131
+ --store flagship.myshopify.com --stores-from ./stores.txt --apply
128
132
  ```
129
133
 
130
- Generating it from the schema means completions work without a store login, and cover definitions
131
- that are declared but not yet created. This drives editor assistance only: no theme-check rule
132
- validates metafields, so nothing here fails a build.
134
+ Each store is planned against the same schema. One store refusing a write does not stop the others.
135
+ A store named directly fails loudly; a swept store without the app is reported as `NOT-INSTALLED`
136
+ without failing the fleet. Other unreachable stores and rejected writes exit `2`.
133
137
 
134
- The file's shape carries less than the schema does. It has no field for `required`, validations, or
135
- access, it cannot represent metaobject definitions, and it has no group for `customer` or
136
- `draft_order` metafields, which are reported as skipped. Treat it as a generated artifact: `emit`
137
- replaces an existing one and refuses to overwrite a file it did not generate. Shopify's own
138
- `shopify theme metafields pull` overwrites the same path, so do not hand-edit it.
138
+ ## Pull and generated output
139
139
 
140
- ## Behavior
140
+ Pull existing definitions into a new schema file:
141
141
 
142
- - Dry run reports missing definitions without writing them.
143
- - `--apply` creates missing metaobject definitions in dependency order, then metafield definitions.
144
- - `--check` exits nonzero for missing or incompatible operational shape.
145
- - Cosmetic name and description drift is reported but never changed.
146
- - Existing definitions, values, and entries are never updated or deleted by schema sync. Only
147
- `--repair` updates one, and nothing deletes a definition or a field under any flag.
148
- - A description over 255 characters fails `--validate` and fails sync before the first request,
149
- listing every offender at once. The Admin API answers `TOO_LONG`, and one create rejected
150
- mid-run leaves a store half-applied behind an error that reads transient.
142
+ ```sh
143
+ npx @notambourine/metafields pull \
144
+ --store example.myshopify.com \
145
+ --owner product \
146
+ --namespace custom \
147
+ --metaobjects \
148
+ --out schema.ts
149
+ ```
151
150
 
152
- Exit `0` means the selected condition is satisfied, exit `1` means schema or migration drift, and
153
- exit `2` means invalid input, indeterminate Shopify state, or an API failure.
151
+ Owners and namespaces must be explicit unless their corresponding `--all-owners` or
152
+ `--all-namespaces` flag is passed. The output path must not exist; omit `--out` to write to stdout.
154
153
 
155
- `pull` requires explicit owners and namespaces:
154
+ Generate Liquid editor metadata from the schema:
156
155
 
157
156
  ```sh
158
- metafields pull --store example.myshopify.com \
159
- --owner product --namespace custom --metaobjects --out schema.ts
157
+ npx @notambourine/metafields emit ./schema.ts \
158
+ --liquid --out .shopify/metafields.json
160
159
  ```
161
160
 
162
- The output path must not exist. Without `--out`, the generated module is written to stdout.
161
+ The generated file supports Liquid completion and hover without a store login. It cannot represent
162
+ metaobjects, `required`, validations, access, customer metafields, or draft-order metafields.
163
+ `emit` refuses to replace a file it did not generate unless passed `--force`.
164
+
165
+ ## Types
166
+
167
+ Infer application types from the schema. Required declarations remain required:
168
+
169
+ ```ts
170
+ import type { InferMetafields, InferMetaobjects } from '@notambourine/metafields';
171
+ import schema from './schema.js';
172
+
173
+ type ProductMetafields = InferMetafields<typeof schema>['product'];
174
+ type Faq = InferMetaobjects<typeof schema>['faq'];
175
+ ```
163
176
 
164
177
  ## Migrations
165
178
 
166
- Migrations are declarative, copy-only, and compiled before credentials are introduced:
179
+ Migrations copy values to a new definition. They never retype or delete the source.
167
180
 
168
181
  ```ts
169
182
  import { defineMigration, transforms } from '@notambourine/metafields';
@@ -184,11 +197,30 @@ export default defineMigration({
184
197
  });
185
198
  ```
186
199
 
200
+ Compile before introducing credentials, inspect the plan, then apply it:
201
+
187
202
  ```sh
188
- metafields compile ./migration.ts --out ./migration.json
189
- metafields migrate ./migration.json --store example.myshopify.com
190
- metafields migrate ./migration.json --store example.myshopify.com --apply
203
+ npx @notambourine/metafields compile ./migration.ts --out ./migration.json
204
+ npx @notambourine/metafields migrate ./migration.json --store example.myshopify.com
205
+ npx @notambourine/metafields migrate ./migration.json --store example.myshopify.com --apply
191
206
  ```
192
207
 
193
- `0.0.x` is prerelease quality. Confirm owner scopes and behavior against a development store before
194
- production use.
208
+ Migration exit code `1` means rows remain pending.
209
+
210
+ ## API compatibility
211
+
212
+ `doctor` checks that Shopify still serves the selected API version and that the package's generated
213
+ metafield type table matches it. It needs no store or credentials.
214
+
215
+ ```sh
216
+ npx @notambourine/metafields doctor
217
+ npx @notambourine/metafields doctor --api-version 2026-07 --json
218
+ ```
219
+
220
+ An unsupported version or changed type table is a failed check. An unreachable Shopify registry is
221
+ indeterminate and exits `2`.
222
+
223
+ Run `npx @notambourine/metafields --help` for the complete CLI reference.
224
+
225
+ This `0.x` release is prerelease quality. Confirm scopes and behavior against a development store
226
+ before production use.
@@ -0,0 +1,57 @@
1
+ import type { ExistingField, ExistingMetafield, ExistingMetaobject } from './planner.js';
2
+ export interface RawField {
3
+ key: string;
4
+ name: string;
5
+ description?: string | null;
6
+ type: {
7
+ name: string;
8
+ };
9
+ required?: boolean;
10
+ validations: {
11
+ name: string;
12
+ value: string;
13
+ }[];
14
+ }
15
+ export interface RawMetafield extends RawField {
16
+ id: string;
17
+ namespace: string;
18
+ ownerType: string;
19
+ access: Record<string, string | null>;
20
+ capabilities: Record<string, {
21
+ enabled: boolean;
22
+ }>;
23
+ constraints?: {
24
+ key: string | null;
25
+ values: {
26
+ nodes: {
27
+ value: string;
28
+ }[];
29
+ };
30
+ } | null;
31
+ validationStatus: ExistingMetafield['validationStatus'];
32
+ invalidCount: number;
33
+ }
34
+ export interface RawMetaobject {
35
+ id: string;
36
+ type: string;
37
+ name: string;
38
+ description?: string | null;
39
+ displayNameKey?: string | null;
40
+ access: Record<string, string | null>;
41
+ capabilities: {
42
+ publishable: {
43
+ enabled: boolean;
44
+ };
45
+ translatable: {
46
+ enabled: boolean;
47
+ };
48
+ };
49
+ fieldDefinitions: RawField[];
50
+ }
51
+ export declare function mapField(value: RawField): ExistingField;
52
+ export declare function mapMetafield(value: RawMetafield): ExistingMetafield;
53
+ export declare function mapMetaobject(value: RawMetaobject): ExistingMetaobject;
54
+ export declare const FIELD_SELECTION = "\n key name description type { name } required validations { name value }\n";
55
+ export declare const METAFIELD_SELECTION = "\n id namespace key ownerType name description type { name }\n validations { name value }\n access { admin storefront customerAccount }\n capabilities {\n adminFilterable { enabled }\n analyticsQueryable { enabled }\n cartToOrderCopyable { enabled }\n smartCollectionCondition { enabled }\n uniqueValues { enabled }\n }\n constraints { key values(first: 250) { nodes { value } } }\n validationStatus\n invalidCount: metafieldsCount(validationStatus: INVALID)\n";
56
+ export declare const METAOBJECT_SELECTION = "\n id type name description displayNameKey\n access { admin storefront }\n capabilities { publishable { enabled } translatable { enabled } }\n fieldDefinitions { \n key name description type { name } required validations { name value }\n }\n";
57
+ //# sourceMappingURL=admin-shapes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-shapes.d.ts","sourceRoot":"","sources":["../src/admin-shapes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEzF,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAChD;AAED,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACnD,WAAW,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE;YAAE,KAAK,EAAE;gBAAE,KAAK,EAAE,MAAM,CAAA;aAAE,EAAE,CAAA;SAAE,CAAA;KAAE,GAAG,IAAI,CAAC;IACpF,gBAAgB,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IACxD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACtC,YAAY,EAAE;QAAE,WAAW,EAAE;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,CAAC;QAAC,YAAY,EAAE;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC;IACxF,gBAAgB,EAAE,QAAQ,EAAE,CAAC;CAC9B;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,aAAa,CASvD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,iBAAiB,CAcnE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,kBAAkB,CActE;AAID,eAAO,MAAM,eAAe,iFAE3B,CAAC;AAEF,eAAO,MAAM,mBAAmB,weAc/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,2PAKhC,CAAC"}
@@ -0,0 +1,67 @@
1
+ export function mapField(value) {
2
+ return {
3
+ key: value.key,
4
+ name: value.name,
5
+ description: value.description,
6
+ type: value.type,
7
+ required: value.required,
8
+ validations: value.validations,
9
+ };
10
+ }
11
+ export function mapMetafield(value) {
12
+ return {
13
+ ...mapField(value),
14
+ id: value.id,
15
+ namespace: value.namespace,
16
+ ownerType: value.ownerType,
17
+ access: value.access,
18
+ capabilities: Object.fromEntries(Object.entries(value.capabilities).map(([key, item]) => [key, item.enabled])),
19
+ constraints: value.constraints
20
+ ? { key: value.constraints.key, values: value.constraints.values.nodes.map((item) => item.value) }
21
+ : null,
22
+ validationStatus: value.validationStatus,
23
+ invalidCount: value.invalidCount,
24
+ };
25
+ }
26
+ export function mapMetaobject(value) {
27
+ return {
28
+ id: value.id,
29
+ type: value.type,
30
+ name: value.name,
31
+ description: value.description,
32
+ displayNameKey: value.displayNameKey,
33
+ access: value.access,
34
+ capabilities: {
35
+ publishable: value.capabilities.publishable.enabled,
36
+ translatable: value.capabilities.translatable.enabled,
37
+ },
38
+ fields: value.fieldDefinitions.map(mapField),
39
+ };
40
+ }
41
+ // Read and pull select the same definitions, so the selections live with the shapes they decode:
42
+ // a capability Shopify adds is then one edit, not two that can silently disagree.
43
+ export const FIELD_SELECTION = `
44
+ key name description type { name } required validations { name value }
45
+ `;
46
+ export const METAFIELD_SELECTION = `
47
+ id namespace key ownerType name description type { name }
48
+ validations { name value }
49
+ access { admin storefront customerAccount }
50
+ capabilities {
51
+ adminFilterable { enabled }
52
+ analyticsQueryable { enabled }
53
+ cartToOrderCopyable { enabled }
54
+ smartCollectionCondition { enabled }
55
+ uniqueValues { enabled }
56
+ }
57
+ constraints { key values(first: 250) { nodes { value } } }
58
+ validationStatus
59
+ invalidCount: metafieldsCount(validationStatus: INVALID)
60
+ `;
61
+ export const METAOBJECT_SELECTION = `
62
+ id type name description displayNameKey
63
+ access { admin storefront }
64
+ capabilities { publishable { enabled } translatable { enabled } }
65
+ fieldDefinitions { ${FIELD_SELECTION} }
66
+ `;
67
+ //# sourceMappingURL=admin-shapes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin-shapes.js","sourceRoot":"","sources":["../src/admin-shapes.ts"],"names":[],"mappings":"AAiCA,MAAM,UAAU,QAAQ,CAAC,KAAe;IACtC,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,WAAW,EAAE,KAAK,CAAC,WAAW;KAC/B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAmB;IAC9C,OAAO;QACL,GAAG,QAAQ,CAAC,KAAK,CAAC;QAClB,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9G,WAAW,EAAE,KAAK,CAAC,WAAW;YAC5B,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;YAClG,CAAC,CAAC,IAAI;QACR,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAoB;IAChD,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,YAAY,EAAE;YACZ,WAAW,EAAE,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,OAAO;YACnD,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO;SACtD;QACD,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,iGAAiG;AACjG,kFAAkF;AAClF,MAAM,CAAC,MAAM,eAAe,GAAG;;CAE9B,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;CAclC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;uBAIb,eAAe;CACrC,CAAC"}
package/dist/admin.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { CanonicalMetafield, CanonicalMetaobject, CompiledSchema } from './schema.js';
2
2
  import type { ExistingMetafield, ExistingMetaobject, ExistingSchema, Plan, SyncMode } from './planner.js';
3
- import { type RepairItem, type RepairPlan } from './repair.js';
3
+ import { type DriftItem, type DriftPlan } from './changes.js';
4
4
  export declare const DEFAULT_API_VERSION = "2026-07";
5
5
  export declare class AdminError extends Error {
6
6
  readonly requestId?: string;
@@ -28,15 +28,16 @@ export declare class AdminClient {
28
28
  readMetafield(definition: Pick<CanonicalMetafield, 'ownerType' | 'namespace' | 'key'>): Promise<ExistingMetafield | null>;
29
29
  createMetaobject(definition: CanonicalMetaobject): Promise<void>;
30
30
  createMetafield(definition: CanonicalMetafield): Promise<void>;
31
- repairMetaobject(entry: RepairItem): Promise<void>;
32
- repairMetafield(entry: RepairItem): Promise<void>;
31
+ updateMetaobject(entry: DriftItem, force?: boolean): Promise<void>;
32
+ updateMetafield(entry: DriftItem, force?: boolean): Promise<void>;
33
33
  }
34
34
  export interface ApplyResult {
35
35
  plan: Plan;
36
- applied: string[];
37
- repaired: string[];
36
+ created: string[];
37
+ updated: string[];
38
+ skipped: string[];
38
39
  }
39
40
  export declare function planStore(client: AdminClient, schema: CompiledSchema): Promise<Plan>;
40
- export declare function applyPlan(client: AdminClient, schema: CompiledSchema, plan: Plan, repair?: RepairPlan): Promise<ApplyResult>;
41
- export declare function synchronize(client: AdminClient, schema: CompiledSchema, mode: SyncMode): Promise<ApplyResult>;
41
+ export declare function applyPlan(client: AdminClient, schema: CompiledSchema, plan: Plan, drift: DriftPlan, force?: boolean): Promise<ApplyResult>;
42
+ export declare function synchronize(client: AdminClient, schema: CompiledSchema, mode: SyncMode, force?: boolean): Promise<ApplyResult>;
42
43
  //# sourceMappingURL=admin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAkB,kBAAkB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC3G,OAAO,KAAK,EACK,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,EACrF,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAiC,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9F,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B,YAAY,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAI9C;CACF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMpD;AAID,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAQD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED,qBAAa,WAAW;;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAM1B,YAAY,OAAO,EAAE,kBAAkB,EActC;IAEK,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAyCrG;IAEK,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAYhE;IAEK,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAMrE;IAEK,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE,WAAW,GAAG,WAAW,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAS9H;IAEK,gBAAgB,CAAC,UAAU,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKrE;IAEK,eAAe,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQnE;IAEK,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAQvD;IAEK,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtD;CACF;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1F;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,IAAI,EACV,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,WAAW,CAAC,CA+BtB;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,WAAW,CAAC,CAOtB"}
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"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"}