shop-cli 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/README.md +8 -7
- package/dist/cli/gid.d.ts +13 -2
- package/dist/cli/gid.js +75 -7
- package/dist/cli/globalFlags.d.ts +1 -0
- package/dist/cli/globalFlags.js +4 -0
- package/dist/cli/help/registry.js +188 -182
- package/dist/cli/help/render.js +7 -3
- package/dist/cli/verbs/_shared.js +4 -4
- package/dist/cli/verbs/files.js +11 -2
- package/dist/cli/verbs/mobile-platform-applications.js +4 -2
- package/dist/cli/verbs/products.js +8 -7
- package/dist/cli/verbs/publishables.js +1 -1
- package/dist/cli.js +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -137,7 +137,7 @@ shop products list --select seo.title --select seo.description
|
|
|
137
137
|
Include connections when using `--view all`:
|
|
138
138
|
|
|
139
139
|
```bash
|
|
140
|
-
shop products get --id 123 --view all --include variants --include images
|
|
140
|
+
shop products get --id gid://shopify/Product/123 --view all --include variants --include images
|
|
141
141
|
```
|
|
142
142
|
|
|
143
143
|
Override selection entirely with raw GraphQL:
|
|
@@ -155,7 +155,7 @@ With `--select`, use the `on_TypeName` prefix:
|
|
|
155
155
|
|
|
156
156
|
```bash
|
|
157
157
|
# Select apps from an AppCatalog via publications
|
|
158
|
-
shop products get --id 123 --include resourcePublicationsV2 \
|
|
158
|
+
shop products get --id gid://shopify/Product/123 --include resourcePublicationsV2 \
|
|
159
159
|
--select resourcePublicationsV2.nodes.publication.catalog.on_AppCatalog.apps.nodes.title
|
|
160
160
|
```
|
|
161
161
|
|
|
@@ -204,6 +204,7 @@ shop products list --quiet
|
|
|
204
204
|
| `--set-json` | Set a field value as JSON (repeatable) |
|
|
205
205
|
| `--tags` | Comma-separated tags |
|
|
206
206
|
| `--dry-run` | Print GraphQL operation without executing |
|
|
207
|
+
| `--strict-ids` | Require full `gid://shopify/...` IDs (or env `SHOP_CLI_STRICT_IDS=1`) |
|
|
207
208
|
|
|
208
209
|
## Raw GraphQL
|
|
209
210
|
|
|
@@ -229,23 +230,23 @@ shop products list --first 5
|
|
|
229
230
|
shop products list --published
|
|
230
231
|
|
|
231
232
|
# Get a specific product
|
|
232
|
-
shop products get --id 123
|
|
233
|
+
shop products get --id gid://shopify/Product/123
|
|
233
234
|
|
|
234
235
|
# Create a product
|
|
235
236
|
shop products create --set title="My Product" --set status="ACTIVE"
|
|
236
237
|
|
|
237
238
|
# Update a product
|
|
238
|
-
shop products update --id 123 --set title="Updated Title"
|
|
239
|
+
shop products update --id gid://shopify/Product/123 --set title="Updated Title"
|
|
239
240
|
|
|
240
241
|
# Add tags to a product
|
|
241
|
-
shop products add-tags --id 123 --tags "summer,featured"
|
|
242
|
+
shop products add-tags --id gid://shopify/Product/123 --tags "summer,featured"
|
|
242
243
|
|
|
243
244
|
# Publish to a sales channel
|
|
244
245
|
shop publications resolve --publication "Online Store"
|
|
245
|
-
shop products publish --id 123 --publication "Online Store" --now
|
|
246
|
+
shop products publish --id gid://shopify/Product/123 --publication "Online Store" --now
|
|
246
247
|
|
|
247
248
|
# Work with metafields
|
|
248
|
-
shop products metafields upsert --id 123 \
|
|
249
|
+
shop products metafields upsert --id gid://shopify/Product/123 \
|
|
249
250
|
--set namespace=custom \
|
|
250
251
|
--set key=foo \
|
|
251
252
|
--set type=single_line_text_field \
|
package/dist/cli/gid.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
-
export type ShopifyGidType = 'AbandonedCheckout' | 'Abandonment' | 'AndroidApplication' | 'App' | 'Metafield' | 'Job' | 'Product' | 'ProductOption' | 'ProductOptionValue' | 'ProductFeed' | 'ProductVariant' | 'Collection' | 'Customer' | 'CustomerPaymentMethod' | 'CustomerSegmentMembersQuery' | 'StaffMember' | 'Order' | 'OrderTransaction' | 'CalculatedOrder' | 'CalculatedLineItem' | 'CalculatedDiscountApplication' | 'CalculatedShippingLine' | 'AppInstallation' | 'AppSubscription' | 'DiscountAutomaticNode' | 'DiscountCodeNode' | 'DiscountNode' | 'DiscountRedeemCode' | 'DiscountRedeemCodeBulkCreation' | 'InventoryItem' | 'InventoryLevel' | 'InventoryShipment' | 'InventoryTransfer' | 'InventoryTransferLineItem' | 'Location' | 'FulfillmentOrder' | 'Fulfillment' | 'FulfillmentHold' | 'FulfillmentService' | 'FulfillmentConstraintRule' | 'GiftCard' | 'Return' | 'ReturnLineItem' | 'ReturnReasonDefinition' | 'ReturnableFulfillment' | 'DeliveryProfile' | 'DeliveryCustomization' | 'DeliveryCarrierService' | 'File' | 'PaymentTerms' | 'PaymentTermsTemplate' | 'PaymentSchedule' | 'PaymentMandate' | 'PaymentCustomization' | 'PriceList' | 'Publication' | 'Refund' | 'Article' | 'Blog' | 'Page' | 'Comment' | 'Event' | 'Menu' | 'Channel' | 'Catalog' | 'Market' | 'MarketRegionCountry' | 'MarketWebPresence' | 'BusinessEntity' | 'Company' | 'CompanyAddress' | 'CompanyContact' | 'CompanyContactRole' | 'CompanyContactRoleAssignment' | 'CompanyLocation' | 'CompanyLocationStaffMemberAssignment' | 'StoreCreditAccount' | 'StorefrontAccessToken' | 'DraftOrder' | 'DraftOrderTag' | 'BulkOperation' | 'UrlRedirect' | 'UrlRedirectImport' | 'Segment' | 'SavedSearch' | 'ScriptTag' | 'CartTransform' | 'Validation' | 'OnlineStoreTheme' | 'CheckoutProfile' | 'WebPixel' | 'ServerPixel' | 'MarketingActivity' | 'MarketingEvent' | 'WebhookSubscription' | 'Domain' | 'MetafieldDefinition' | 'Metaobject' | 'MetaobjectDefinition' | 'Shop' | 'MarketWebPresence' | 'SellingPlanGroup' | 'ShippingPackage' | 'ShopifyPaymentsDispute' | 'ShopifyPaymentsDisputeEvidence' | 'SubscriptionContract' | 'SubscriptionDraft' | 'SubscriptionLine' | 'SubscriptionManualDiscount' | 'SubscriptionBillingAttempt' | 'AppleApplication' | 'CashTrackingSession' | 'PointOfSaleDevice' | 'CustomerAccountPage' | 'FlowActionDefinition' | 'MailingAddress';
|
|
1
|
+
export type ShopifyGidType = 'AbandonedCheckout' | 'Abandonment' | 'AndroidApplication' | 'App' | 'Metafield' | 'Job' | 'Product' | 'ProductOption' | 'ProductOptionValue' | 'ProductFeed' | 'ProductVariant' | 'Collection' | 'Customer' | 'CustomerPaymentMethod' | 'CustomerSegmentMembersQuery' | 'StaffMember' | 'Order' | 'OrderTransaction' | 'CalculatedOrder' | 'CalculatedLineItem' | 'CalculatedDiscountApplication' | 'CalculatedShippingLine' | 'AppInstallation' | 'AppSubscription' | 'DiscountAutomaticNode' | 'DiscountCodeNode' | 'DiscountNode' | 'DiscountRedeemCode' | 'DiscountRedeemCodeBulkCreation' | 'InventoryItem' | 'InventoryLevel' | 'InventoryShipment' | 'InventoryTransfer' | 'InventoryTransferLineItem' | 'Location' | 'FulfillmentOrder' | 'Fulfillment' | 'FulfillmentHold' | 'FulfillmentService' | 'FulfillmentConstraintRule' | 'GiftCard' | 'Return' | 'ReturnLineItem' | 'ReturnReasonDefinition' | 'ReturnableFulfillment' | 'DeliveryProfile' | 'DeliveryCustomization' | 'DeliveryCarrierService' | 'File' | 'PaymentTerms' | 'PaymentTermsTemplate' | 'PaymentSchedule' | 'PaymentMandate' | 'PaymentCustomization' | 'PriceList' | 'Publication' | 'Refund' | 'Article' | 'Blog' | 'Page' | 'Comment' | 'Event' | 'Menu' | 'Channel' | 'Catalog' | 'Market' | 'MarketRegionCountry' | 'MarketWebPresence' | 'BusinessEntity' | 'Company' | 'CompanyAddress' | 'CompanyContact' | 'CompanyContactRole' | 'CompanyContactRoleAssignment' | 'CompanyLocation' | 'CompanyLocationStaffMemberAssignment' | 'StoreCreditAccount' | 'StorefrontAccessToken' | 'DraftOrder' | 'DraftOrderTag' | 'BulkOperation' | 'UrlRedirect' | 'UrlRedirectImport' | 'Segment' | 'SavedSearch' | 'ScriptTag' | 'CartTransform' | 'Validation' | 'OnlineStoreTheme' | 'CheckoutProfile' | 'WebPixel' | 'ServerPixel' | 'MarketingActivity' | 'MarketingEvent' | 'WebhookSubscription' | 'Domain' | 'ExternalVideo' | 'MediaImage' | 'Model3d' | 'MetafieldDefinition' | 'Metaobject' | 'MetaobjectDefinition' | 'Shop' | 'MarketWebPresence' | 'SellingPlanGroup' | 'ShippingPackage' | 'ShopifyPaymentsDispute' | 'ShopifyPaymentsDisputeEvidence' | 'SubscriptionContract' | 'SubscriptionDraft' | 'SubscriptionLine' | 'SubscriptionManualDiscount' | 'SubscriptionBillingAttempt' | 'Video' | 'AppleApplication' | 'CashTrackingSession' | 'PointOfSaleDevice' | 'CustomerAccountPage' | 'FlowActionDefinition' | 'MailingAddress';
|
|
2
2
|
export declare const isGid: (value: string) => boolean;
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const parseEnvBoolean: (value: string | undefined) => boolean;
|
|
4
|
+
export declare const setStrictIdsMode: (enabled: boolean) => void;
|
|
5
|
+
export declare const isStrictIdsMode: () => boolean;
|
|
6
|
+
export declare const parseShopifyGid: (value: string) => {
|
|
7
|
+
raw: string;
|
|
8
|
+
type: string;
|
|
9
|
+
id: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const getShopifyGidType: (value: string) => string;
|
|
12
|
+
export declare const assertShopifyGidType: (value: string, expectedType: ShopifyGidType, label?: string) => string;
|
|
13
|
+
export declare const assertShopifyGidTypeIn: (value: string, allowedTypes: readonly ShopifyGidType[], label?: string) => string;
|
|
14
|
+
export declare const coerceGid: (value: string, type: ShopifyGidType, label?: string) => string;
|
package/dist/cli/gid.js
CHANGED
|
@@ -18,25 +18,93 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var gid_exports = {};
|
|
20
20
|
__export(gid_exports, {
|
|
21
|
+
assertShopifyGidType: () => assertShopifyGidType,
|
|
22
|
+
assertShopifyGidTypeIn: () => assertShopifyGidTypeIn,
|
|
21
23
|
coerceGid: () => coerceGid,
|
|
22
|
-
|
|
24
|
+
getShopifyGidType: () => getShopifyGidType,
|
|
25
|
+
isGid: () => isGid,
|
|
26
|
+
isStrictIdsMode: () => isStrictIdsMode,
|
|
27
|
+
parseEnvBoolean: () => parseEnvBoolean,
|
|
28
|
+
parseShopifyGid: () => parseShopifyGid,
|
|
29
|
+
setStrictIdsMode: () => setStrictIdsMode
|
|
23
30
|
});
|
|
24
31
|
module.exports = __toCommonJS(gid_exports);
|
|
25
32
|
var import_errors = require("./errors");
|
|
26
|
-
const isGid = (value) => value.startsWith("gid://");
|
|
27
|
-
const
|
|
28
|
-
if (
|
|
29
|
-
|
|
33
|
+
const isGid = (value) => value.trim().startsWith("gid://");
|
|
34
|
+
const parseEnvBoolean = (value) => {
|
|
35
|
+
if (value === void 0) return false;
|
|
36
|
+
const v = value.trim().toLowerCase();
|
|
37
|
+
if (v === "") return true;
|
|
38
|
+
if (v === "1" || v === "true" || v === "yes" || v === "y" || v === "on") return true;
|
|
39
|
+
if (v === "0" || v === "false" || v === "no" || v === "n" || v === "off") return false;
|
|
40
|
+
return true;
|
|
41
|
+
};
|
|
42
|
+
let strictIdsMode = parseEnvBoolean(process.env.SHOP_CLI_STRICT_IDS);
|
|
43
|
+
const setStrictIdsMode = (enabled) => {
|
|
44
|
+
strictIdsMode = enabled;
|
|
45
|
+
};
|
|
46
|
+
const isStrictIdsMode = () => strictIdsMode;
|
|
47
|
+
const parseShopifyGid = (value) => {
|
|
48
|
+
const raw = value.trim();
|
|
49
|
+
if (!raw.startsWith("gid://")) throw new import_errors.CliError(`Invalid Shopify GID: ${value}`, 2);
|
|
50
|
+
const parts = raw.split("/");
|
|
51
|
+
const scheme = parts[0];
|
|
52
|
+
const host = parts[2];
|
|
53
|
+
const type = parts[3];
|
|
54
|
+
const id = parts.slice(4).join("/");
|
|
55
|
+
if (scheme !== "gid:" || host !== "shopify" || !type || !id) {
|
|
56
|
+
throw new import_errors.CliError(`Invalid Shopify GID: ${value}`, 2);
|
|
57
|
+
}
|
|
58
|
+
return { raw, type, id };
|
|
59
|
+
};
|
|
60
|
+
const getShopifyGidType = (value) => parseShopifyGid(value).type;
|
|
61
|
+
const assertShopifyGidType = (value, expectedType, label = "GID") => {
|
|
62
|
+
const parsed = parseShopifyGid(value);
|
|
63
|
+
if (parsed.type !== expectedType) {
|
|
64
|
+
throw new import_errors.CliError(
|
|
65
|
+
`${label} must be a Shopify GID of type ${expectedType}. Got type ${parsed.type}: ${parsed.raw}`,
|
|
66
|
+
2
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
return parsed.raw;
|
|
70
|
+
};
|
|
71
|
+
const assertShopifyGidTypeIn = (value, allowedTypes, label = "GID") => {
|
|
72
|
+
const parsed = parseShopifyGid(value);
|
|
73
|
+
if (!allowedTypes.includes(parsed.type)) {
|
|
74
|
+
throw new import_errors.CliError(
|
|
75
|
+
`${label} must be a Shopify GID of type one of ${allowedTypes.join(", ")}. Got type ${parsed.type}: ${parsed.raw}`,
|
|
76
|
+
2
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
return parsed.raw;
|
|
80
|
+
};
|
|
81
|
+
const coerceGid = (value, type, label = `ID for ${type}`) => {
|
|
82
|
+
const raw = value.trim();
|
|
83
|
+
if (isGid(raw)) return assertShopifyGidType(raw, type, label);
|
|
84
|
+
if (isStrictIdsMode()) {
|
|
85
|
+
throw new import_errors.CliError(
|
|
86
|
+
`${label} must be a full Shopify GID of type ${type} (gid://shopify/${type}/...). Strict IDs mode is enabled (SHOP_CLI_STRICT_IDS or --strict-ids). Got: ${value}`,
|
|
87
|
+
2
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
if (!/^\d+$/.test(raw)) {
|
|
30
91
|
throw new import_errors.CliError(
|
|
31
92
|
`Expected a numeric ID or full GID for ${type}. Got: ${value}`,
|
|
32
93
|
2
|
|
33
94
|
);
|
|
34
95
|
}
|
|
35
|
-
return `gid://shopify/${type}/${
|
|
96
|
+
return `gid://shopify/${type}/${raw}`;
|
|
36
97
|
};
|
|
37
98
|
// Annotate the CommonJS export names for ESM import in node:
|
|
38
99
|
0 && (module.exports = {
|
|
100
|
+
assertShopifyGidType,
|
|
101
|
+
assertShopifyGidTypeIn,
|
|
39
102
|
coerceGid,
|
|
40
|
-
|
|
103
|
+
getShopifyGidType,
|
|
104
|
+
isGid,
|
|
105
|
+
isStrictIdsMode,
|
|
106
|
+
parseEnvBoolean,
|
|
107
|
+
parseShopifyGid,
|
|
108
|
+
setStrictIdsMode
|
|
41
109
|
});
|
|
42
110
|
//# sourceMappingURL=gid.js.map
|
package/dist/cli/globalFlags.js
CHANGED
|
@@ -76,6 +76,10 @@ const parseGlobalFlags = (args) => {
|
|
|
76
76
|
parsed.dryRun = true;
|
|
77
77
|
continue;
|
|
78
78
|
}
|
|
79
|
+
if (flag === "--strict-ids") {
|
|
80
|
+
parsed.strictIds = true;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
79
83
|
if (flag === "--no-fail-on-user-errors") {
|
|
80
84
|
parsed.noFailOnUserErrors = true;
|
|
81
85
|
continue;
|