ecomcoder-cli 1.3.3 → 1.3.5
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 +0 -23
- package/dist/cli.js +4 -84
- package/dist/cli.js.map +1 -1
- package/dist/commands/discount/index.d.ts.map +1 -1
- package/dist/commands/discount/index.js +10 -49
- package/dist/commands/discount/index.js.map +1 -1
- package/dist/commands/docs/index.d.ts.map +1 -1
- package/dist/commands/docs/index.js +4 -18
- package/dist/commands/docs/index.js.map +1 -1
- package/dist/commands/metafield/index.d.ts.map +1 -1
- package/dist/commands/metafield/index.js +6 -24
- package/dist/commands/metafield/index.js.map +1 -1
- package/dist/commands/product/create.d.ts +8 -0
- package/dist/commands/product/create.d.ts.map +1 -0
- package/dist/commands/product/create.js +166 -0
- package/dist/commands/product/create.js.map +1 -0
- package/dist/commands/product/get-metafield.d.ts +8 -0
- package/dist/commands/product/get-metafield.d.ts.map +1 -0
- package/dist/commands/product/get-metafield.js +131 -0
- package/dist/commands/product/get-metafield.js.map +1 -0
- package/dist/commands/product/index.d.ts.map +1 -1
- package/dist/commands/product/index.js +42 -42
- package/dist/commands/product/index.js.map +1 -1
- package/dist/commands/product/queries.d.ts +19 -0
- package/dist/commands/product/queries.d.ts.map +1 -1
- package/dist/commands/product/queries.js +122 -0
- package/dist/commands/product/queries.js.map +1 -1
- package/dist/commands/product/service.d.ts +35 -1
- package/dist/commands/product/service.d.ts.map +1 -1
- package/dist/commands/product/service.js +241 -1
- package/dist/commands/product/service.js.map +1 -1
- package/dist/commands/product/set-metafield.d.ts +8 -0
- package/dist/commands/product/set-metafield.d.ts.map +1 -0
- package/dist/commands/product/set-metafield.js +174 -0
- package/dist/commands/product/set-metafield.js.map +1 -0
- package/dist/commands/product/types.d.ts +88 -0
- package/dist/commands/product/types.d.ts.map +1 -1
- package/dist/commands/product/update-status.d.ts +8 -0
- package/dist/commands/product/update-status.d.ts.map +1 -0
- package/dist/commands/product/update-status.js +105 -0
- package/dist/commands/product/update-status.js.map +1 -0
- package/dist/commands/products/index.d.ts.map +1 -1
- package/dist/commands/products/index.js +5 -31
- package/dist/commands/products/index.js.map +1 -1
- package/dist/commands/shop/get-metafield.d.ts +8 -0
- package/dist/commands/shop/get-metafield.d.ts.map +1 -0
- package/dist/commands/shop/get-metafield.js +117 -0
- package/dist/commands/shop/get-metafield.js.map +1 -0
- package/dist/commands/shop/index.d.ts +10 -0
- package/dist/commands/shop/index.d.ts.map +1 -0
- package/dist/commands/shop/index.js +38 -0
- package/dist/commands/shop/index.js.map +1 -0
- package/dist/commands/shop/queries.d.ts +24 -0
- package/dist/commands/shop/queries.d.ts.map +1 -0
- package/dist/commands/shop/queries.js +83 -0
- package/dist/commands/shop/queries.js.map +1 -0
- package/dist/commands/shop/service.d.ts +30 -0
- package/dist/commands/shop/service.d.ts.map +1 -0
- package/dist/commands/shop/service.js +131 -0
- package/dist/commands/shop/service.js.map +1 -0
- package/dist/commands/shop/set-metafield.d.ts +8 -0
- package/dist/commands/shop/set-metafield.d.ts.map +1 -0
- package/dist/commands/shop/set-metafield.js +174 -0
- package/dist/commands/shop/set-metafield.js.map +1 -0
- package/dist/commands/shop/types.d.ts +84 -0
- package/dist/commands/shop/types.d.ts.map +1 -0
- package/dist/commands/shop/types.js +6 -0
- package/dist/commands/shop/types.js.map +1 -0
- package/dist/lib/command-registry.d.ts +2 -0
- package/dist/lib/command-registry.d.ts.map +1 -1
- package/dist/lib/command-registry.js.map +1 -1
- package/dist/lib/help-generator.d.ts +28 -0
- package/dist/lib/help-generator.d.ts.map +1 -0
- package/dist/lib/help-generator.js +131 -0
- package/dist/lib/help-generator.js.map +1 -0
- package/dist/lib/help-utils.d.ts +17 -0
- package/dist/lib/help-utils.d.ts.map +1 -0
- package/dist/lib/help-utils.js +24 -0
- package/dist/lib/help-utils.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update Product Status Command
|
|
3
|
+
*
|
|
4
|
+
* Following Command Pattern - thin orchestration layer
|
|
5
|
+
* Delegates business logic to ProductService
|
|
6
|
+
*/
|
|
7
|
+
import { getCredentials, getSessionId } from '../../lib/api-client.js';
|
|
8
|
+
import { parseArgs, hasHelpFlag } from '../../lib/args-parser.js';
|
|
9
|
+
import { ProductService } from './service.js';
|
|
10
|
+
function showHelp() {
|
|
11
|
+
console.log(`
|
|
12
|
+
Update Product Status
|
|
13
|
+
|
|
14
|
+
USAGE:
|
|
15
|
+
ecomcoder product update-status [OPTIONS]
|
|
16
|
+
|
|
17
|
+
REQUIRED OPTIONS:
|
|
18
|
+
--id <id> Product ID (numeric or GID)
|
|
19
|
+
--status <status> Product status: ACTIVE, DRAFT, ARCHIVED, or UNLISTED
|
|
20
|
+
|
|
21
|
+
OPTIONAL:
|
|
22
|
+
--session-id Session ID (auto-provided via SESSION_ID env var)
|
|
23
|
+
--help, -h Show this help message
|
|
24
|
+
|
|
25
|
+
STATUS VALUES:
|
|
26
|
+
ACTIVE Product is ready to sell (can be published to channels)
|
|
27
|
+
DRAFT Product not ready to sell (hidden from customers)
|
|
28
|
+
ARCHIVED Product no longer sold (hidden from customers)
|
|
29
|
+
UNLISTED Active but requires direct link (no search/collections)
|
|
30
|
+
|
|
31
|
+
EXAMPLES:
|
|
32
|
+
# Publish product (make it active)
|
|
33
|
+
ecomcoder product update-status --id=123456789 --status=ACTIVE
|
|
34
|
+
|
|
35
|
+
# Set to draft (hide from customers)
|
|
36
|
+
ecomcoder product update-status --id=123 --status=DRAFT
|
|
37
|
+
|
|
38
|
+
# Archive product (no longer sold)
|
|
39
|
+
ecomcoder product update-status --id=123 --status=ARCHIVED
|
|
40
|
+
|
|
41
|
+
# Unlisted (active but requires direct link)
|
|
42
|
+
ecomcoder product update-status --id=123 --status=UNLISTED
|
|
43
|
+
|
|
44
|
+
NOTES:
|
|
45
|
+
- Status change is immediate
|
|
46
|
+
- ACTIVE status does NOT automatically publish to channels
|
|
47
|
+
- Use Shopify Admin to manage channel publishing separately
|
|
48
|
+
- UNLISTED is available in API version 2025-10 and later
|
|
49
|
+
`);
|
|
50
|
+
process.exit(0);
|
|
51
|
+
}
|
|
52
|
+
export async function run(argv = process.argv.slice(2)) {
|
|
53
|
+
if (hasHelpFlag(argv)) {
|
|
54
|
+
showHelp();
|
|
55
|
+
}
|
|
56
|
+
const args = parseArgs(argv);
|
|
57
|
+
// Validate required arguments
|
|
58
|
+
if (!args.id) {
|
|
59
|
+
console.error(JSON.stringify({
|
|
60
|
+
success: false,
|
|
61
|
+
error: 'Missing required argument: --id'
|
|
62
|
+
}));
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
if (!args.status) {
|
|
66
|
+
console.error(JSON.stringify({
|
|
67
|
+
success: false,
|
|
68
|
+
error: 'Missing required argument: --status'
|
|
69
|
+
}));
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
// Validate status value
|
|
73
|
+
const validStatuses = ['ACTIVE', 'DRAFT', 'ARCHIVED', 'UNLISTED'];
|
|
74
|
+
const statusUpper = args.status.toUpperCase();
|
|
75
|
+
if (!validStatuses.includes(statusUpper)) {
|
|
76
|
+
console.error(JSON.stringify({
|
|
77
|
+
success: false,
|
|
78
|
+
error: `Invalid status. Must be one of: ${validStatuses.join(', ')}`
|
|
79
|
+
}));
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
// Get credentials
|
|
84
|
+
const sessionId = getSessionId(args.sessionId);
|
|
85
|
+
const credentials = await getCredentials(sessionId, args.backendUrl, args.jwt);
|
|
86
|
+
// Execute update via service
|
|
87
|
+
const result = await ProductService.updateStatus(credentials, {
|
|
88
|
+
id: args.id,
|
|
89
|
+
status: statusUpper
|
|
90
|
+
});
|
|
91
|
+
// Output result
|
|
92
|
+
console.log(JSON.stringify(result, null, 2));
|
|
93
|
+
if (!result.success) {
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
console.error(JSON.stringify({
|
|
99
|
+
success: false,
|
|
100
|
+
error: error.message || 'Unknown error occurred'
|
|
101
|
+
}));
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=update-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-status.js","sourceRoot":"","sources":["../../../src/commands/product/update-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/products/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/products/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CA0B/C"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Following Open/Closed Principle - commands register themselves
|
|
5
5
|
*/
|
|
6
6
|
import { registry } from '../../lib/command-registry.js';
|
|
7
|
+
import { HelpGenerator } from '../../lib/help-generator.js';
|
|
7
8
|
/**
|
|
8
9
|
* Register all products commands
|
|
9
10
|
*/
|
|
@@ -11,32 +12,9 @@ export function registerProductsCommands() {
|
|
|
11
12
|
// Register command group
|
|
12
13
|
registry.registerGroup({
|
|
13
14
|
command: 'products',
|
|
14
|
-
description: '
|
|
15
|
+
description: 'Bulk product operations',
|
|
15
16
|
showHelp: () => {
|
|
16
|
-
console.log(
|
|
17
|
-
Products Commands - Bulk product operations and utilities
|
|
18
|
-
|
|
19
|
-
USAGE:
|
|
20
|
-
ecomcoder products <subcommand> [options]
|
|
21
|
-
|
|
22
|
-
SUBCOMMANDS:
|
|
23
|
-
create Create dummy Shopify products for testing
|
|
24
|
-
list List products in your Shopify store
|
|
25
|
-
set-rating Set rating metafields on a product
|
|
26
|
-
|
|
27
|
-
EXAMPLES:
|
|
28
|
-
# Create 10 dummy products
|
|
29
|
-
ecomcoder products create --count=10
|
|
30
|
-
|
|
31
|
-
# List 50 products
|
|
32
|
-
ecomcoder products list --limit=50
|
|
33
|
-
|
|
34
|
-
# Set product rating
|
|
35
|
-
ecomcoder products set-rating --product-id="gid://shopify/Product/123" --rating=4.5 --count=127
|
|
36
|
-
|
|
37
|
-
For detailed help on a specific subcommand:
|
|
38
|
-
ecomcoder products <subcommand> --help
|
|
39
|
-
`);
|
|
17
|
+
console.log(HelpGenerator.generateGroupHelp('products'));
|
|
40
18
|
}
|
|
41
19
|
});
|
|
42
20
|
// Register individual subcommands
|
|
@@ -44,19 +22,15 @@ For detailed help on a specific subcommand:
|
|
|
44
22
|
command: 'products',
|
|
45
23
|
subcommand: 'create',
|
|
46
24
|
description: 'Create dummy Shopify products for testing',
|
|
25
|
+
quickExample: 'ecomcoder products create --count=10',
|
|
47
26
|
handler: async () => await import('../create-dummy-products.js')
|
|
48
27
|
});
|
|
49
28
|
registry.register({
|
|
50
29
|
command: 'products',
|
|
51
30
|
subcommand: 'list',
|
|
52
31
|
description: 'List products in your Shopify store',
|
|
32
|
+
quickExample: 'ecomcoder products list --limit=50',
|
|
53
33
|
handler: async () => await import('../list-products.js')
|
|
54
34
|
});
|
|
55
|
-
registry.register({
|
|
56
|
-
command: 'products',
|
|
57
|
-
subcommand: 'set-rating',
|
|
58
|
-
description: 'Set rating metafields on a product',
|
|
59
|
-
handler: async () => await import('../set-product-rating.js')
|
|
60
|
-
});
|
|
61
35
|
}
|
|
62
36
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/products/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/products/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;GAEG;AACH,MAAM,UAAU,wBAAwB;IACtC,yBAAyB;IACzB,QAAQ,CAAC,aAAa,CAAC;QACrB,OAAO,EAAE,UAAU;QACnB,WAAW,EAAE,yBAAyB;QACtC,QAAQ,EAAE,GAAG,EAAE;YACb,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC;QAC3D,CAAC;KACF,CAAC,CAAC;IAEH,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,CAAC;QAChB,OAAO,EAAE,UAAU;QACnB,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,2CAA2C;QACxD,YAAY,EAAE,sCAAsC;QACpD,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,6BAA6B,CAAC;KACjE,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,CAAC;QAChB,OAAO,EAAE,UAAU;QACnB,UAAU,EAAE,MAAM;QAClB,WAAW,EAAE,qCAAqC;QAClD,YAAY,EAAE,oCAAoC;QAClD,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,qBAAqB,CAAC;KACzD,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-metafield.d.ts","sourceRoot":"","sources":["../../../src/commands/shop/get-metafield.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA8EH,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,iBAwC/D"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get Shop Metafield Command
|
|
3
|
+
*
|
|
4
|
+
* Following Command Pattern - thin orchestration layer
|
|
5
|
+
* Delegates business logic to ShopService
|
|
6
|
+
*/
|
|
7
|
+
import { getCredentials, getSessionId } from '../../lib/api-client.js';
|
|
8
|
+
import { parseArgs, hasHelpFlag } from '../../lib/args-parser.js';
|
|
9
|
+
import { ShopService } from './service.js';
|
|
10
|
+
function showHelp() {
|
|
11
|
+
console.log(`
|
|
12
|
+
Get Shop Metafield
|
|
13
|
+
|
|
14
|
+
USAGE:
|
|
15
|
+
ecomcoder shop get-metafield [OPTIONS]
|
|
16
|
+
|
|
17
|
+
QUERY OPTIONS (choose one):
|
|
18
|
+
--namespace <ns> --key <key> Get specific metafield
|
|
19
|
+
--namespace <ns> Get all metafields in namespace
|
|
20
|
+
(no namespace/key) Get all metafields for shop
|
|
21
|
+
|
|
22
|
+
OPTIONAL:
|
|
23
|
+
--session-id Session ID (auto-provided via SESSION_ID env var)
|
|
24
|
+
--help, -h Show this help message
|
|
25
|
+
|
|
26
|
+
EXAMPLES:
|
|
27
|
+
# Get specific metafield by namespace and key
|
|
28
|
+
ecomcoder shop get-metafield \\
|
|
29
|
+
--namespace=custom \\
|
|
30
|
+
--key=announcement
|
|
31
|
+
|
|
32
|
+
# Get all metafields in a namespace
|
|
33
|
+
ecomcoder shop get-metafield \\
|
|
34
|
+
--namespace=custom
|
|
35
|
+
|
|
36
|
+
# Get all metafields for shop (all namespaces)
|
|
37
|
+
ecomcoder shop get-metafield
|
|
38
|
+
|
|
39
|
+
OUTPUT FORMATS:
|
|
40
|
+
Specific metafield (namespace + key):
|
|
41
|
+
{
|
|
42
|
+
"success": true,
|
|
43
|
+
"data": {
|
|
44
|
+
"metafield": {
|
|
45
|
+
"id": "gid://shopify/Metafield/123",
|
|
46
|
+
"namespace": "custom",
|
|
47
|
+
"key": "announcement",
|
|
48
|
+
"value": "Black Friday Sale!",
|
|
49
|
+
"type": "single_line_text_field",
|
|
50
|
+
"createdAt": "2024-01-20T10:30:00Z",
|
|
51
|
+
"updatedAt": "2024-01-20T15:45:00Z"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
Multiple metafields (namespace or all):
|
|
57
|
+
{
|
|
58
|
+
"success": true,
|
|
59
|
+
"data": {
|
|
60
|
+
"metafields": [...],
|
|
61
|
+
"count": 5
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
Not found:
|
|
66
|
+
{
|
|
67
|
+
"success": true,
|
|
68
|
+
"data": {
|
|
69
|
+
"metafield": null
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
NOTES:
|
|
74
|
+
- Returns up to 250 metafields when querying multiple
|
|
75
|
+
- Namespace filter is optional (omit to get all namespaces)
|
|
76
|
+
- Key requires namespace (cannot query by key alone)
|
|
77
|
+
- Metafield values are always strings (parse JSON for complex types)
|
|
78
|
+
`);
|
|
79
|
+
process.exit(0);
|
|
80
|
+
}
|
|
81
|
+
export async function run(argv = process.argv.slice(2)) {
|
|
82
|
+
if (hasHelpFlag(argv)) {
|
|
83
|
+
showHelp();
|
|
84
|
+
}
|
|
85
|
+
const args = parseArgs(argv);
|
|
86
|
+
// Validate key requires namespace
|
|
87
|
+
if (args.key && !args.namespace) {
|
|
88
|
+
console.error(JSON.stringify({
|
|
89
|
+
success: false,
|
|
90
|
+
error: 'Key requires namespace. Use --namespace with --key'
|
|
91
|
+
}));
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
// Get credentials
|
|
96
|
+
const sessionId = getSessionId(args.sessionId);
|
|
97
|
+
const credentials = await getCredentials(sessionId, args.backendUrl, args.jwt);
|
|
98
|
+
// Execute get metafield via service
|
|
99
|
+
const result = await ShopService.getMetafield(credentials, {
|
|
100
|
+
namespace: args.namespace,
|
|
101
|
+
key: args.key
|
|
102
|
+
});
|
|
103
|
+
// Output result
|
|
104
|
+
console.log(JSON.stringify(result, null, 2));
|
|
105
|
+
if (!result.success) {
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
console.error(JSON.stringify({
|
|
111
|
+
success: false,
|
|
112
|
+
error: error.message || 'Unknown error occurred'
|
|
113
|
+
}));
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=get-metafield.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-metafield.js","sourceRoot":"","sources":["../../../src/commands/shop/get-metafield.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,SAAS,QAAQ;IACf,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmEb,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,OAAiB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9D,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,QAAQ,EAAE,CAAC;IACb,CAAC;IAED,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAE7B,kCAAkC;IAClC,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,oDAAoD;SAC5D,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,kBAAkB;QAClB,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAE/E,oCAAoC;QACpC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,YAAY,CAAC,WAAW,EAAE;YACzD,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC,CAAC;QAEH,gBAAgB;QAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAE7C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,wBAAwB;SACjD,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/shop/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CA4B3C"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shop Commands Registration
|
|
3
|
+
*
|
|
4
|
+
* Following Open/Closed Principle - commands register themselves
|
|
5
|
+
*/
|
|
6
|
+
import { registry } from '../../lib/command-registry.js';
|
|
7
|
+
import { HelpGenerator } from '../../lib/help-generator.js';
|
|
8
|
+
/**
|
|
9
|
+
* Register all shop commands
|
|
10
|
+
*/
|
|
11
|
+
export function registerShopCommands() {
|
|
12
|
+
// Register command group
|
|
13
|
+
registry.registerGroup({
|
|
14
|
+
command: 'shop',
|
|
15
|
+
description: 'Store-wide settings and metafields',
|
|
16
|
+
showHelp: () => {
|
|
17
|
+
console.log(HelpGenerator.generateGroupHelp('shop'));
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
// Register individual subcommands
|
|
21
|
+
registry.register({
|
|
22
|
+
command: 'shop',
|
|
23
|
+
subcommand: 'set-metafield',
|
|
24
|
+
description: 'Set or update shop metafield values',
|
|
25
|
+
category: 'Metafields',
|
|
26
|
+
quickExample: 'ecomcoder shop set-metafield --namespace=custom --key=announcement --value="Sale!" --type=single_line_text_field',
|
|
27
|
+
handler: async () => await import('./set-metafield.js')
|
|
28
|
+
});
|
|
29
|
+
registry.register({
|
|
30
|
+
command: 'shop',
|
|
31
|
+
subcommand: 'get-metafield',
|
|
32
|
+
description: 'View shop metafield values',
|
|
33
|
+
category: 'Metafields',
|
|
34
|
+
quickExample: 'ecomcoder shop get-metafield --namespace=custom --key=announcement',
|
|
35
|
+
handler: async () => await import('./get-metafield.js')
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/shop/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,yBAAyB;IACzB,QAAQ,CAAC,aAAa,CAAC;QACrB,OAAO,EAAE,MAAM;QACf,WAAW,EAAE,oCAAoC;QACjD,QAAQ,EAAE,GAAG,EAAE;YACb,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;QACvD,CAAC;KACF,CAAC,CAAC;IAEH,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,CAAC;QAChB,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,eAAe;QAC3B,WAAW,EAAE,qCAAqC;QAClD,QAAQ,EAAE,YAAY;QACtB,YAAY,EAAE,kHAAkH;QAChI,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,oBAAoB,CAAC;KACxD,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,CAAC;QAChB,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,eAAe;QAC3B,WAAW,EAAE,4BAA4B;QACzC,QAAQ,EAAE,YAAY;QACtB,YAAY,EAAE,oEAAoE;QAClF,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,oBAAoB,CAAC;KACxD,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL Queries and Mutations for Shop Operations
|
|
3
|
+
*
|
|
4
|
+
* Following Single Responsibility Principle - this module only contains GraphQL strings
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Get shop ID (needed for metafield mutations)
|
|
8
|
+
*/
|
|
9
|
+
export declare const GET_SHOP_ID = "\n query getShopId {\n shop {\n id\n }\n }\n";
|
|
10
|
+
/**
|
|
11
|
+
* Get specific shop metafield by namespace and key
|
|
12
|
+
*/
|
|
13
|
+
export declare const GET_SHOP_METAFIELD = "\n query getShopMetafield($namespace: String!, $key: String!) {\n shop {\n id\n metafield(namespace: $namespace, key: $key) {\n id\n namespace\n key\n value\n type\n createdAt\n updatedAt\n }\n }\n }\n";
|
|
14
|
+
/**
|
|
15
|
+
* Get shop metafields (multiple)
|
|
16
|
+
* Used for querying all metafields or by namespace
|
|
17
|
+
*/
|
|
18
|
+
export declare const GET_SHOP_METAFIELDS = "\n query getShopMetafields($namespace: String, $first: Int) {\n shop {\n id\n metafields(namespace: $namespace, first: $first) {\n edges {\n node {\n id\n namespace\n key\n value\n type\n createdAt\n updatedAt\n }\n }\n }\n }\n }\n";
|
|
19
|
+
/**
|
|
20
|
+
* Set metafield values for shop
|
|
21
|
+
* Maximum 25 metafields per request, atomic operation
|
|
22
|
+
*/
|
|
23
|
+
export declare const METAFIELDS_SET = "\n mutation metafieldsSet($metafields: [MetafieldsSetInput!]!) {\n metafieldsSet(metafields: $metafields) {\n metafields {\n id\n namespace\n key\n value\n type\n createdAt\n updatedAt\n }\n userErrors {\n field\n message\n code\n }\n }\n }\n";
|
|
24
|
+
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../src/commands/shop/queries.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,eAAO,MAAM,WAAW,8DAMvB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,sRAe9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,gXAmB/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,yVAmB1B,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GraphQL Queries and Mutations for Shop Operations
|
|
3
|
+
*
|
|
4
|
+
* Following Single Responsibility Principle - this module only contains GraphQL strings
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Get shop ID (needed for metafield mutations)
|
|
8
|
+
*/
|
|
9
|
+
export const GET_SHOP_ID = `
|
|
10
|
+
query getShopId {
|
|
11
|
+
shop {
|
|
12
|
+
id
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
/**
|
|
17
|
+
* Get specific shop metafield by namespace and key
|
|
18
|
+
*/
|
|
19
|
+
export const GET_SHOP_METAFIELD = `
|
|
20
|
+
query getShopMetafield($namespace: String!, $key: String!) {
|
|
21
|
+
shop {
|
|
22
|
+
id
|
|
23
|
+
metafield(namespace: $namespace, key: $key) {
|
|
24
|
+
id
|
|
25
|
+
namespace
|
|
26
|
+
key
|
|
27
|
+
value
|
|
28
|
+
type
|
|
29
|
+
createdAt
|
|
30
|
+
updatedAt
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
/**
|
|
36
|
+
* Get shop metafields (multiple)
|
|
37
|
+
* Used for querying all metafields or by namespace
|
|
38
|
+
*/
|
|
39
|
+
export const GET_SHOP_METAFIELDS = `
|
|
40
|
+
query getShopMetafields($namespace: String, $first: Int) {
|
|
41
|
+
shop {
|
|
42
|
+
id
|
|
43
|
+
metafields(namespace: $namespace, first: $first) {
|
|
44
|
+
edges {
|
|
45
|
+
node {
|
|
46
|
+
id
|
|
47
|
+
namespace
|
|
48
|
+
key
|
|
49
|
+
value
|
|
50
|
+
type
|
|
51
|
+
createdAt
|
|
52
|
+
updatedAt
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`;
|
|
59
|
+
/**
|
|
60
|
+
* Set metafield values for shop
|
|
61
|
+
* Maximum 25 metafields per request, atomic operation
|
|
62
|
+
*/
|
|
63
|
+
export const METAFIELDS_SET = `
|
|
64
|
+
mutation metafieldsSet($metafields: [MetafieldsSetInput!]!) {
|
|
65
|
+
metafieldsSet(metafields: $metafields) {
|
|
66
|
+
metafields {
|
|
67
|
+
id
|
|
68
|
+
namespace
|
|
69
|
+
key
|
|
70
|
+
value
|
|
71
|
+
type
|
|
72
|
+
createdAt
|
|
73
|
+
updatedAt
|
|
74
|
+
}
|
|
75
|
+
userErrors {
|
|
76
|
+
field
|
|
77
|
+
message
|
|
78
|
+
code
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
`;
|
|
83
|
+
//# sourceMappingURL=queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../../src/commands/shop/queries.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;CAM1B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;CAejC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;CAmBlC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;CAmB7B,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shop Service - Business Logic Layer
|
|
3
|
+
*
|
|
4
|
+
* Following Service Layer Pattern - all shop business logic here
|
|
5
|
+
* Thin command handlers delegate to these methods
|
|
6
|
+
*/
|
|
7
|
+
import type { ShopifyCredentials } from '../../lib/types.js';
|
|
8
|
+
import { CommandResult, SetShopMetafieldInput, GetShopMetafieldInput } from './types.js';
|
|
9
|
+
export declare class ShopService {
|
|
10
|
+
/**
|
|
11
|
+
* Get shop ID
|
|
12
|
+
* Required for metafield mutations (ownerId)
|
|
13
|
+
*/
|
|
14
|
+
static getShopId(credentials: ShopifyCredentials): Promise<CommandResult<{
|
|
15
|
+
shopId: string;
|
|
16
|
+
}>>;
|
|
17
|
+
/**
|
|
18
|
+
* Set shop metafield value
|
|
19
|
+
*/
|
|
20
|
+
static setMetafield(credentials: ShopifyCredentials, input: SetShopMetafieldInput): Promise<CommandResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Get shop metafield(s)
|
|
23
|
+
* Supports:
|
|
24
|
+
* - Specific metafield (namespace + key)
|
|
25
|
+
* - All metafields in namespace (namespace only)
|
|
26
|
+
* - All metafields (no params)
|
|
27
|
+
*/
|
|
28
|
+
static getMetafield(credentials: ShopifyCredentials, input: GetShopMetafieldInput): Promise<CommandResult>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/commands/shop/service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAO7D,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,qBAAqB,EAKtB,MAAM,YAAY,CAAC;AAEpB,qBAAa,WAAW;IACtB;;;OAGG;WACU,SAAS,CAAC,WAAW,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAsBnG;;OAEG;WACU,YAAY,CACvB,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,aAAa,CAAC;IAiEzB;;;;;;OAMG;WACU,YAAY,CACvB,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,aAAa,CAAC;CAmD1B"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shop Service - Business Logic Layer
|
|
3
|
+
*
|
|
4
|
+
* Following Service Layer Pattern - all shop business logic here
|
|
5
|
+
* Thin command handlers delegate to these methods
|
|
6
|
+
*/
|
|
7
|
+
import { shopifyGraphQL } from '../../lib/shopify-client.js';
|
|
8
|
+
import { GET_SHOP_ID, GET_SHOP_METAFIELD, GET_SHOP_METAFIELDS, METAFIELDS_SET } from './queries.js';
|
|
9
|
+
export class ShopService {
|
|
10
|
+
/**
|
|
11
|
+
* Get shop ID
|
|
12
|
+
* Required for metafield mutations (ownerId)
|
|
13
|
+
*/
|
|
14
|
+
static async getShopId(credentials) {
|
|
15
|
+
const response = await shopifyGraphQL(credentials, GET_SHOP_ID, {});
|
|
16
|
+
if (!response.data?.shop) {
|
|
17
|
+
return {
|
|
18
|
+
success: false,
|
|
19
|
+
error: 'Shop not found'
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
success: true,
|
|
24
|
+
data: {
|
|
25
|
+
shopId: response.data.shop.id
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Set shop metafield value
|
|
31
|
+
*/
|
|
32
|
+
static async setMetafield(credentials, input) {
|
|
33
|
+
// Get shop ID first
|
|
34
|
+
const shopIdResult = await this.getShopId(credentials);
|
|
35
|
+
if (!shopIdResult.success || !shopIdResult.data) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
error: shopIdResult.error || 'Failed to get shop ID'
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const { shopId } = shopIdResult.data;
|
|
42
|
+
// Prepare metafield input
|
|
43
|
+
const metafieldInput = {
|
|
44
|
+
ownerId: shopId,
|
|
45
|
+
namespace: input.namespace,
|
|
46
|
+
key: input.key,
|
|
47
|
+
value: input.value,
|
|
48
|
+
type: input.type
|
|
49
|
+
};
|
|
50
|
+
// Execute mutation
|
|
51
|
+
const response = await shopifyGraphQL(credentials, METAFIELDS_SET, { metafields: [metafieldInput] });
|
|
52
|
+
// Check for user errors
|
|
53
|
+
const userErrors = response.data?.metafieldsSet?.userErrors || [];
|
|
54
|
+
if (userErrors.length > 0) {
|
|
55
|
+
const errors = userErrors
|
|
56
|
+
.map((e) => e.message)
|
|
57
|
+
.join(', ');
|
|
58
|
+
return {
|
|
59
|
+
success: false,
|
|
60
|
+
error: `GraphQL errors: ${errors}`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Return the set metafield
|
|
64
|
+
const metafield = response.data?.metafieldsSet?.metafields?.[0];
|
|
65
|
+
if (!metafield) {
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
error: 'No metafield returned from mutation'
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
data: {
|
|
74
|
+
metafield: {
|
|
75
|
+
id: metafield.id,
|
|
76
|
+
namespace: metafield.namespace,
|
|
77
|
+
key: metafield.key,
|
|
78
|
+
value: metafield.value,
|
|
79
|
+
type: metafield.type,
|
|
80
|
+
createdAt: metafield.createdAt,
|
|
81
|
+
updatedAt: metafield.updatedAt
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get shop metafield(s)
|
|
88
|
+
* Supports:
|
|
89
|
+
* - Specific metafield (namespace + key)
|
|
90
|
+
* - All metafields in namespace (namespace only)
|
|
91
|
+
* - All metafields (no params)
|
|
92
|
+
*/
|
|
93
|
+
static async getMetafield(credentials, input) {
|
|
94
|
+
// If both namespace and key provided, get specific metafield
|
|
95
|
+
if (input.namespace && input.key) {
|
|
96
|
+
const response = await shopifyGraphQL(credentials, GET_SHOP_METAFIELD, { namespace: input.namespace, key: input.key });
|
|
97
|
+
if (!response.data?.shop) {
|
|
98
|
+
return {
|
|
99
|
+
success: false,
|
|
100
|
+
error: 'Shop not found'
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
success: true,
|
|
105
|
+
data: {
|
|
106
|
+
metafield: response.data.shop.metafield
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Otherwise, get multiple metafields
|
|
111
|
+
const response = await shopifyGraphQL(credentials, GET_SHOP_METAFIELDS, {
|
|
112
|
+
namespace: input.namespace || undefined,
|
|
113
|
+
first: 250 // Maximum allowed
|
|
114
|
+
});
|
|
115
|
+
if (!response.data?.shop) {
|
|
116
|
+
return {
|
|
117
|
+
success: false,
|
|
118
|
+
error: 'Shop not found'
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const metafields = response.data.shop.metafields.edges.map((edge) => edge.node);
|
|
122
|
+
return {
|
|
123
|
+
success: true,
|
|
124
|
+
data: {
|
|
125
|
+
metafields,
|
|
126
|
+
count: metafields.length
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=service.js.map
|