ecomcoder-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/bin/ecomcoder +20 -0
  2. package/dist/cli.d.ts +13 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +114 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/create-dummy-products.d.ts +2 -0
  7. package/dist/commands/create-dummy-products.d.ts.map +1 -0
  8. package/dist/commands/create-dummy-products.js +231 -0
  9. package/dist/commands/create-dummy-products.js.map +1 -0
  10. package/dist/commands/create-metafield.d.ts +2 -0
  11. package/dist/commands/create-metafield.d.ts.map +1 -0
  12. package/dist/commands/create-metafield.js +126 -0
  13. package/dist/commands/create-metafield.js.map +1 -0
  14. package/dist/commands/get-metafield.d.ts +2 -0
  15. package/dist/commands/get-metafield.d.ts.map +1 -0
  16. package/dist/commands/get-metafield.js +108 -0
  17. package/dist/commands/get-metafield.js.map +1 -0
  18. package/dist/commands/list-products.d.ts +2 -0
  19. package/dist/commands/list-products.d.ts.map +1 -0
  20. package/dist/commands/list-products.js +62 -0
  21. package/dist/commands/list-products.js.map +1 -0
  22. package/dist/commands/set-product-rating.d.ts +2 -0
  23. package/dist/commands/set-product-rating.d.ts.map +1 -0
  24. package/dist/commands/set-product-rating.js +111 -0
  25. package/dist/commands/set-product-rating.js.map +1 -0
  26. package/dist/lib/api-client.d.ts +17 -0
  27. package/dist/lib/api-client.d.ts.map +1 -0
  28. package/dist/lib/api-client.js +45 -0
  29. package/dist/lib/api-client.js.map +1 -0
  30. package/dist/lib/args-parser.d.ts +21 -0
  31. package/dist/lib/args-parser.d.ts.map +1 -0
  32. package/dist/lib/args-parser.js +35 -0
  33. package/dist/lib/args-parser.js.map +1 -0
  34. package/dist/lib/shopify-client.d.ts +14 -0
  35. package/dist/lib/shopify-client.d.ts.map +1 -0
  36. package/dist/lib/shopify-client.js +33 -0
  37. package/dist/lib/shopify-client.js.map +1 -0
  38. package/dist/lib/types.d.ts +58 -0
  39. package/dist/lib/types.d.ts.map +1 -0
  40. package/dist/lib/types.js +5 -0
  41. package/dist/lib/types.js.map +1 -0
  42. package/package.json +49 -0
package/bin/ecomcoder ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * EcomCoder CLI executable
5
+ * Runs the compiled JavaScript from dist/
6
+ */
7
+
8
+ import { fileURLToPath } from 'url';
9
+ import { dirname, join } from 'path';
10
+
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = dirname(__filename);
13
+
14
+ // Import and run the compiled CLI
15
+ const cliPath = join(__dirname, '..', 'dist', 'cli.js');
16
+
17
+ import(cliPath).catch((error) => {
18
+ console.error('Error loading CLI:', error.message);
19
+ process.exit(1);
20
+ });
package/dist/cli.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * EcomCoder CLI - Main Entry Point
4
+ *
5
+ * Command structure:
6
+ * ecomcoder products create --count=10
7
+ * ecomcoder products list --limit=50
8
+ * ecomcoder products set-rating --product-id=... --rating=4.5 --count=127
9
+ * ecomcoder metafield create --name=... --key=... --type=...
10
+ * ecomcoder metafield get --namespace=... --key=...
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG"}
package/dist/cli.js ADDED
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * EcomCoder CLI - Main Entry Point
4
+ *
5
+ * Command structure:
6
+ * ecomcoder products create --count=10
7
+ * ecomcoder products list --limit=50
8
+ * ecomcoder products set-rating --product-id=... --rating=4.5 --count=127
9
+ * ecomcoder metafield create --name=... --key=... --type=...
10
+ * ecomcoder metafield get --namespace=... --key=...
11
+ */
12
+ import { getPositionalArgs } from './lib/args-parser.js';
13
+ function showHelp() {
14
+ console.log(`
15
+ EcomCoder CLI - Shopify Development Utilities
16
+
17
+ USAGE:
18
+ ecomcoder <command> <subcommand> [options]
19
+
20
+ COMMANDS:
21
+ products create Create dummy Shopify products for testing
22
+ products list List products in your Shopify store
23
+ products set-rating Set rating metafields on a product
24
+ metafield create Create a metafield definition
25
+ metafield get Get metafield definition(s)
26
+
27
+ GLOBAL OPTIONS:
28
+ --session-id Session ID for authentication (auto-provided when used with Claude)
29
+ --help, -h Show help information
30
+
31
+ ENVIRONMENT VARIABLES:
32
+ SESSION_ID Session ID (auto-injected by Claude Agent SDK)
33
+ BACKEND_URL Backend API URL (default: http://localhost:8080)
34
+
35
+ EXAMPLES:
36
+ # Create 10 dummy products
37
+ ecomcoder products create --count=10
38
+
39
+ # List 50 products
40
+ ecomcoder products list --limit=50
41
+
42
+ # Set product rating
43
+ ecomcoder products set-rating --product-id="gid://shopify/Product/123" --rating=4.5 --count=127
44
+
45
+ # Create a metafield definition
46
+ ecomcoder metafield create --name="Upsell" --namespace=ecomcoder --key=upsell \\
47
+ --description="Related products" --type=list.product_reference --owner-type=PRODUCT
48
+
49
+ # Get metafield definition
50
+ ecomcoder metafield get --namespace=ecomcoder --key=upsell --owner-type=PRODUCT
51
+
52
+ For more help on specific commands, run:
53
+ ecomcoder <command> <subcommand> --help
54
+ `);
55
+ }
56
+ async function main() {
57
+ const args = process.argv.slice(2);
58
+ // Show help if no arguments or help flag
59
+ if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
60
+ showHelp();
61
+ process.exit(0);
62
+ }
63
+ const positional = getPositionalArgs(args);
64
+ const [command, subcommand] = positional;
65
+ // Route to appropriate command handler
66
+ try {
67
+ if (command === 'products') {
68
+ if (subcommand === 'create') {
69
+ const { run } = await import('./commands/create-dummy-products.js');
70
+ await run(args.slice(2)); // Pass remaining args after 'products create'
71
+ }
72
+ else if (subcommand === 'list') {
73
+ const { run } = await import('./commands/list-products.js');
74
+ await run(args.slice(2));
75
+ }
76
+ else if (subcommand === 'set-rating') {
77
+ const { run } = await import('./commands/set-product-rating.js');
78
+ await run(args.slice(2));
79
+ }
80
+ else {
81
+ console.error(`Unknown products subcommand: ${subcommand}`);
82
+ console.error(`Valid subcommands: create, list, set-rating`);
83
+ process.exit(1);
84
+ }
85
+ }
86
+ else if (command === 'metafield') {
87
+ if (subcommand === 'create') {
88
+ const { run } = await import('./commands/create-metafield.js');
89
+ await run(args.slice(2));
90
+ }
91
+ else if (subcommand === 'get') {
92
+ const { run } = await import('./commands/get-metafield.js');
93
+ await run(args.slice(2));
94
+ }
95
+ else {
96
+ console.error(`Unknown metafield subcommand: ${subcommand}`);
97
+ console.error(`Valid subcommands: create, get`);
98
+ process.exit(1);
99
+ }
100
+ }
101
+ else {
102
+ console.error(`Unknown command: ${command}`);
103
+ console.error(`Valid commands: products, metafield`);
104
+ console.error(`Run 'ecomcoder --help' for more information`);
105
+ process.exit(1);
106
+ }
107
+ }
108
+ catch (error) {
109
+ console.error(`Error executing command: ${error instanceof Error ? error.message : 'Unknown error'}`);
110
+ process.exit(1);
111
+ }
112
+ }
113
+ main();
114
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function run(argv?: string[]): Promise<void>;
2
+ //# sourceMappingURL=create-dummy-products.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-dummy-products.d.ts","sourceRoot":"","sources":["../../src/commands/create-dummy-products.ts"],"names":[],"mappings":"AAkEA,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,iBAyL/D"}
@@ -0,0 +1,231 @@
1
+ import { getCredentials, getSessionId } from '../lib/api-client.js';
2
+ import { shopifyGraphQL, rateLimit } from '../lib/shopify-client.js';
3
+ import { parseArgs, hasHelpFlag } from '../lib/args-parser.js';
4
+ // Dummy data generators
5
+ const PRODUCT_ADJECTIVES = ['Premium', 'Luxury', 'Essential', 'Modern', 'Classic', 'Vintage', 'Eco-Friendly', 'Handcrafted', 'Designer', 'Professional'];
6
+ const PRODUCT_TYPES = ['T-Shirt', 'Hoodie', 'Jeans', 'Sneakers', 'Backpack', 'Watch', 'Sunglasses', 'Hat', 'Jacket', 'Shorts'];
7
+ const PRODUCT_CATEGORIES = ['Clothing', 'Accessories', 'Footwear', 'Outerwear', 'Sportswear'];
8
+ const VENDORS = ['EcomCoder Brand', 'Urban Style Co.', 'Classic Threads', 'Modern Wear', 'Premium Goods'];
9
+ function generateDummyProduct(index) {
10
+ const adjective = PRODUCT_ADJECTIVES[Math.floor(Math.random() * PRODUCT_ADJECTIVES.length)];
11
+ const type = PRODUCT_TYPES[Math.floor(Math.random() * PRODUCT_TYPES.length)];
12
+ const category = PRODUCT_CATEGORIES[Math.floor(Math.random() * PRODUCT_CATEGORIES.length)];
13
+ const vendor = VENDORS[Math.floor(Math.random() * VENDORS.length)];
14
+ const price = (Math.random() * 80 + 20).toFixed(2);
15
+ const compareAtPrice = (parseFloat(price) * (1 + Math.random() * 0.5 + 0.2)).toFixed(2);
16
+ return {
17
+ product: {
18
+ title: `${adjective} ${type} #${index}`,
19
+ descriptionHtml: `<p>Discover our ${adjective.toLowerCase()} ${type.toLowerCase()}, perfect for any occasion. Made with high-quality materials and attention to detail.</p><ul><li>Premium quality</li><li>Comfortable fit</li><li>Durable construction</li></ul>`,
20
+ vendor,
21
+ productType: category,
22
+ tags: [category, type, adjective],
23
+ status: 'ACTIVE'
24
+ },
25
+ media: [
26
+ {
27
+ originalSource: 'https://izqrwzhtttdmmaasxncu.supabase.co/storage/v1/object/public/ai-context/2406942b-6848-4d88-ba43-652c09011a03.png',
28
+ mediaContentType: 'IMAGE',
29
+ alt: `${adjective} ${type} product image`
30
+ }
31
+ ],
32
+ pricing: {
33
+ price,
34
+ compareAtPrice
35
+ }
36
+ };
37
+ }
38
+ function showHelp() {
39
+ console.log(`
40
+ Create Dummy Shopify Products
41
+
42
+ USAGE:
43
+ ecomcoder products create [OPTIONS]
44
+
45
+ OPTIONS:
46
+ --count Number of dummy products to create (default: 10, max: 100)
47
+ --metafield-key Optional metafield key to set on created products
48
+ --session-id Session ID (auto-provided via SESSION_ID env var)
49
+ --help, -h Show this help message
50
+
51
+ EXAMPLES:
52
+ # Create 10 dummy products
53
+ ecomcoder products create --count=10
54
+
55
+ # Create 25 products with upsell metafield
56
+ ecomcoder products create --count=25 --metafield-key=upsell
57
+ `);
58
+ process.exit(0);
59
+ }
60
+ export async function run(argv = process.argv.slice(2)) {
61
+ if (hasHelpFlag(argv)) {
62
+ showHelp();
63
+ }
64
+ const args = parseArgs(argv);
65
+ const count = parseInt(args.count || '10', 10);
66
+ const metafieldKey = args.metafieldKey;
67
+ if (isNaN(count) || count < 1 || count > 100) {
68
+ console.error(JSON.stringify({
69
+ success: false,
70
+ error: 'Count must be a number between 1 and 100'
71
+ }));
72
+ process.exit(1);
73
+ }
74
+ try {
75
+ const sessionId = getSessionId(args.sessionId);
76
+ const credentials = await getCredentials(sessionId);
77
+ const results = {
78
+ total: count,
79
+ created: 0,
80
+ failed: 0,
81
+ products: []
82
+ };
83
+ console.error(`Creating ${count} dummy products...`);
84
+ for (let i = 1; i <= count; i++) {
85
+ const productData = generateDummyProduct(i);
86
+ try {
87
+ const result = await shopifyGraphQL(credentials, `
88
+ mutation productCreate($product: ProductCreateInput!, $media: [CreateMediaInput!]) {
89
+ productCreate(product: $product, media: $media) {
90
+ product {
91
+ id
92
+ title
93
+ handle
94
+ status
95
+ variants(first: 1) {
96
+ edges {
97
+ node {
98
+ id
99
+ price
100
+ }
101
+ }
102
+ }
103
+ }
104
+ userErrors {
105
+ field
106
+ message
107
+ }
108
+ }
109
+ }
110
+ `, {
111
+ product: productData.product,
112
+ media: productData.media
113
+ });
114
+ const productResult = result?.data?.productCreate;
115
+ const userErrors = productResult?.userErrors;
116
+ if (userErrors && userErrors.length > 0) {
117
+ console.error(`❌ Product ${i} failed: ${userErrors.map((e) => e.message).join(', ')}`);
118
+ results.failed++;
119
+ }
120
+ else if (productResult?.product) {
121
+ const product = productResult.product;
122
+ const variantId = product.variants?.edges?.[0]?.node?.id;
123
+ // Update variant prices
124
+ if (variantId) {
125
+ await shopifyGraphQL(credentials, `
126
+ mutation productVariantsBulkUpdate($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
127
+ productVariantsBulkUpdate(productId: $productId, variants: $variants) {
128
+ productVariants {
129
+ id
130
+ price
131
+ compareAtPrice
132
+ }
133
+ userErrors {
134
+ field
135
+ message
136
+ }
137
+ }
138
+ }
139
+ `, {
140
+ productId: product.id,
141
+ variants: [{
142
+ id: variantId,
143
+ price: productData.pricing.price,
144
+ compareAtPrice: productData.pricing.compareAtPrice
145
+ }]
146
+ });
147
+ }
148
+ console.error(`✅ Created: ${product.title} (${product.id})`);
149
+ results.created++;
150
+ results.products.push({
151
+ id: product.id,
152
+ title: product.title,
153
+ handle: product.handle,
154
+ status: product.status
155
+ });
156
+ }
157
+ if (i < count) {
158
+ await rateLimit(500);
159
+ }
160
+ }
161
+ catch (error) {
162
+ console.error(`❌ Product ${i} error: ${error instanceof Error ? error.message : 'Unknown error'}`);
163
+ results.failed++;
164
+ }
165
+ }
166
+ // Generate URLs
167
+ let firstProductAdminUrl = null;
168
+ let firstProductStorefrontUrl = null;
169
+ if (results.created > 0) {
170
+ const firstProduct = results.products[0];
171
+ const numericId = firstProduct.id.split('/').pop();
172
+ firstProductAdminUrl = `https://${credentials.shopifyUrl}/admin/products/${numericId}`;
173
+ firstProductStorefrontUrl = `https://${credentials.shopifyUrl}/products/${firstProduct.handle}`;
174
+ }
175
+ // Set metafields if requested
176
+ if (metafieldKey && results.created > 0) {
177
+ console.error(`\nSetting metafield on first product...`);
178
+ const productIds = results.products.map((p) => p.id);
179
+ try {
180
+ await shopifyGraphQL(credentials, `
181
+ mutation metafieldsSet($metafields: [MetafieldsSetInput!]!) {
182
+ metafieldsSet(metafields: $metafields) {
183
+ metafields {
184
+ id
185
+ key
186
+ value
187
+ }
188
+ userErrors {
189
+ field
190
+ message
191
+ code
192
+ }
193
+ }
194
+ }
195
+ `, {
196
+ metafields: [{
197
+ namespace: "ecomcoder",
198
+ key: metafieldKey,
199
+ type: "list.product_reference",
200
+ value: JSON.stringify(productIds),
201
+ ownerId: productIds[0]
202
+ }]
203
+ });
204
+ console.error(`✅ Set metafield on first product`);
205
+ }
206
+ catch (error) {
207
+ console.error(`❌ Error setting metafields: ${error instanceof Error ? error.message : 'Unknown error'}`);
208
+ }
209
+ }
210
+ if (firstProductAdminUrl) {
211
+ console.error(`\n🔗 Admin URL: ${firstProductAdminUrl}`);
212
+ console.error(`🌐 Storefront URL: ${firstProductStorefrontUrl}`);
213
+ }
214
+ console.log(JSON.stringify({
215
+ success: true,
216
+ data: {
217
+ ...results,
218
+ firstProductAdminUrl,
219
+ firstProductStorefrontUrl
220
+ }
221
+ }));
222
+ }
223
+ catch (error) {
224
+ console.error(JSON.stringify({
225
+ success: false,
226
+ error: error instanceof Error ? error.message : 'Unknown error'
227
+ }));
228
+ process.exit(1);
229
+ }
230
+ }
231
+ //# sourceMappingURL=create-dummy-products.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-dummy-products.js","sourceRoot":"","sources":["../../src/commands/create-dummy-products.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function run(argv?: string[]): Promise<void>;
2
+ //# sourceMappingURL=create-metafield.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-metafield.d.ts","sourceRoot":"","sources":["../../src/commands/create-metafield.ts"],"names":[],"mappings":"AAkCA,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,iBAsG/D"}
@@ -0,0 +1,126 @@
1
+ import { getCredentials, getSessionId } from '../lib/api-client.js';
2
+ import { shopifyGraphQL } from '../lib/shopify-client.js';
3
+ import { parseArgs, hasHelpFlag } from '../lib/args-parser.js';
4
+ function showHelp() {
5
+ console.log(`
6
+ Create Shopify Metafield Definition
7
+
8
+ USAGE:
9
+ ecomcoder metafield create [OPTIONS]
10
+
11
+ REQUIRED OPTIONS:
12
+ --name Display name for the metafield
13
+ --namespace Namespace (usually "ecomcoder")
14
+ --key Unique key identifier
15
+ --description Description of the metafield
16
+ --type Metafield type (see examples below)
17
+ --owner-type Owner type: PRODUCT, COLLECTION, CUSTOMER, ORDER, SHOP, VARIANT
18
+
19
+ COMMON METAFIELD TYPES:
20
+ single_line_text_field, multi_line_text_field, number_integer, number_decimal,
21
+ boolean, date, date_time, json, url, rating, list.product_reference
22
+
23
+ OTHER OPTIONS:
24
+ --session-id Session ID (auto-provided via SESSION_ID env var)
25
+ --help, -h Show this help message
26
+
27
+ EXAMPLES:
28
+ ecomcoder metafield create --name="Upsell Products" --namespace=ecomcoder --key=upsell \\
29
+ --description="Related products" --type=list.product_reference --owner-type=PRODUCT
30
+ `);
31
+ process.exit(0);
32
+ }
33
+ export async function run(argv = process.argv.slice(2)) {
34
+ if (hasHelpFlag(argv)) {
35
+ showHelp();
36
+ }
37
+ const args = parseArgs(argv);
38
+ const required = ['name', 'namespace', 'key', 'description', 'type', 'ownerType'];
39
+ const missing = required.filter(k => !args[k]);
40
+ if (missing.length > 0) {
41
+ console.error(JSON.stringify({
42
+ success: false,
43
+ error: `Missing required arguments: ${missing.join(', ')}`
44
+ }));
45
+ process.exit(1);
46
+ }
47
+ try {
48
+ const sessionId = getSessionId(args.sessionId);
49
+ const credentials = await getCredentials(sessionId);
50
+ // Create metafield definition
51
+ const createResult = await shopifyGraphQL(credentials, `
52
+ mutation CreateMetafieldDefinition($definition: MetafieldDefinitionInput!) {
53
+ metafieldDefinitionCreate(definition: $definition) {
54
+ createdDefinition {
55
+ id
56
+ name
57
+ key
58
+ namespace
59
+ type { name }
60
+ ownerType
61
+ }
62
+ userErrors {
63
+ field
64
+ message
65
+ code
66
+ }
67
+ }
68
+ }
69
+ `, {
70
+ definition: {
71
+ name: args.name,
72
+ namespace: args.namespace,
73
+ key: args.key,
74
+ description: args.description,
75
+ type: args.type,
76
+ ownerType: args.ownerType
77
+ }
78
+ });
79
+ const createdDefinition = createResult?.data?.metafieldDefinitionCreate?.createdDefinition;
80
+ const userErrors = createResult?.data?.metafieldDefinitionCreate?.userErrors;
81
+ if (userErrors && userErrors.length > 0) {
82
+ throw new Error(`Metafield creation failed: ${userErrors.map((e) => e.message).join(', ')}`);
83
+ }
84
+ if (!createdDefinition || !createdDefinition.id) {
85
+ throw new Error('Metafield created but no ID returned');
86
+ }
87
+ // Pin the metafield
88
+ const pinResult = await shopifyGraphQL(credentials, `
89
+ mutation metafieldDefinitionPin($definitionId: ID!) {
90
+ metafieldDefinitionPin(definitionId: $definitionId) {
91
+ pinnedDefinition {
92
+ id
93
+ pinnedPosition
94
+ }
95
+ userErrors {
96
+ message
97
+ }
98
+ }
99
+ }
100
+ `, {
101
+ definitionId: createdDefinition.id
102
+ });
103
+ const pinErrors = pinResult?.data?.metafieldDefinitionPin?.userErrors;
104
+ console.log(JSON.stringify({
105
+ success: true,
106
+ data: {
107
+ key: createdDefinition.key,
108
+ namespace: createdDefinition.namespace,
109
+ name: createdDefinition.name,
110
+ type: createdDefinition.type?.name,
111
+ ownerType: createdDefinition.ownerType,
112
+ id: createdDefinition.id,
113
+ pinned: pinResult?.data?.metafieldDefinitionPin?.pinnedDefinition ? true : false,
114
+ warnings: pinErrors && pinErrors.length > 0 ? `Pin failed: ${pinErrors.map((e) => e.message).join(', ')}` : null
115
+ }
116
+ }));
117
+ }
118
+ catch (error) {
119
+ console.error(JSON.stringify({
120
+ success: false,
121
+ error: error instanceof Error ? error.message : 'Unknown error'
122
+ }));
123
+ process.exit(1);
124
+ }
125
+ }
126
+ //# sourceMappingURL=create-metafield.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-metafield.js","sourceRoot":"","sources":["../../src/commands/create-metafield.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function run(argv?: string[]): Promise<void>;
2
+ //# sourceMappingURL=get-metafield.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-metafield.d.ts","sourceRoot":"","sources":["../../src/commands/get-metafield.ts"],"names":[],"mappings":"AA4BA,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,iBAmF/D"}
@@ -0,0 +1,108 @@
1
+ import { getCredentials, getSessionId } from '../lib/api-client.js';
2
+ import { shopifyGraphQL } from '../lib/shopify-client.js';
3
+ import { parseArgs, hasHelpFlag } from '../lib/args-parser.js';
4
+ function showHelp() {
5
+ console.log(`
6
+ Get Shopify Metafield Definition
7
+
8
+ USAGE:
9
+ ecomcoder metafield get [OPTIONS]
10
+
11
+ OPTIONS (choose one):
12
+ --id Metafield definition global ID
13
+ --namespace Metafield namespace (requires --key and --owner-type)
14
+ --key Metafield key (requires --namespace and --owner-type)
15
+ --owner-type Owner type: PRODUCT, COLLECTION, CUSTOMER, ORDER, SHOP, VARIANT
16
+
17
+ OTHER OPTIONS:
18
+ --session-id Session ID (auto-provided via SESSION_ID env var)
19
+ --help, -h Show this help message
20
+
21
+ EXAMPLES:
22
+ ecomcoder metafield get --namespace=ecomcoder --key=rating --owner-type=PRODUCT
23
+ ecomcoder metafield get --id="gid://shopify/MetafieldDefinition/123"
24
+ `);
25
+ process.exit(0);
26
+ }
27
+ export async function run(argv = process.argv.slice(2)) {
28
+ if (hasHelpFlag(argv)) {
29
+ showHelp();
30
+ }
31
+ const args = parseArgs(argv);
32
+ try {
33
+ const sessionId = getSessionId(args.sessionId);
34
+ const credentials = await getCredentials(sessionId);
35
+ let query;
36
+ let variables = {};
37
+ if (args.id) {
38
+ query = `
39
+ query GetMetafieldDefinition($id: ID!) {
40
+ metafieldDefinition(id: $id) {
41
+ id
42
+ name
43
+ key
44
+ namespace
45
+ description
46
+ type { name }
47
+ ownerType
48
+ pinnedPosition
49
+ metafieldsCount
50
+ }
51
+ }
52
+ `;
53
+ variables = { id: args.id };
54
+ }
55
+ else if (args.namespace && args.key && args.ownerType) {
56
+ query = `
57
+ query GetMetafieldDefinitions($ownerType: MetafieldOwnerType!, $namespace: String, $key: String, $first: Int) {
58
+ metafieldDefinitions(ownerType: $ownerType, namespace: $namespace, key: $key, first: $first) {
59
+ nodes {
60
+ id
61
+ name
62
+ key
63
+ namespace
64
+ description
65
+ type { name }
66
+ ownerType
67
+ pinnedPosition
68
+ metafieldsCount
69
+ }
70
+ }
71
+ }
72
+ `;
73
+ variables = {
74
+ ownerType: args.ownerType,
75
+ namespace: args.namespace,
76
+ key: args.key,
77
+ first: 50
78
+ };
79
+ }
80
+ else {
81
+ throw new Error('Must provide either --id OR (--namespace + --key + --owner-type)');
82
+ }
83
+ const result = await shopifyGraphQL(credentials, query, variables);
84
+ if (args.id) {
85
+ const definition = result?.data?.metafieldDefinition;
86
+ if (!definition) {
87
+ throw new Error(`Metafield definition not found with ID: ${args.id}`);
88
+ }
89
+ console.log(JSON.stringify({ success: true, data: definition }));
90
+ }
91
+ else {
92
+ const definitions = result?.data?.metafieldDefinitions?.nodes || [];
93
+ console.log(JSON.stringify({
94
+ success: true,
95
+ data: definitions,
96
+ count: definitions.length
97
+ }));
98
+ }
99
+ }
100
+ catch (error) {
101
+ console.error(JSON.stringify({
102
+ success: false,
103
+ error: error instanceof Error ? error.message : 'Unknown error'
104
+ }));
105
+ process.exit(1);
106
+ }
107
+ }
108
+ //# sourceMappingURL=get-metafield.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-metafield.js","sourceRoot":"","sources":["../../src/commands/get-metafield.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE/D,SAAS,QAAQ;IACf,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;CAmBb,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,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;QAEpD,IAAI,KAAa,CAAC;QAClB,IAAI,SAAS,GAAQ,EAAE,CAAC;QAExB,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,KAAK,GAAG;;;;;;;;;;;;;;OAcP,CAAC;YACF,SAAS,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QAC9B,CAAC;aAAM,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACxD,KAAK,GAAG;;;;;;;;;;;;;;;;OAgBP,CAAC;YACF,SAAS,GAAG;gBACV,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,KAAK,EAAE,EAAE;aACV,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;QACtF,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAEnE,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,UAAU,GAAG,MAAM,EAAE,IAAI,EAAE,mBAAmB,CAAC;YACrD,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CAAC,2CAA2C,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YACxE,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,GAAG,MAAM,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,IAAI,EAAE,CAAC;YACpE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;gBACzB,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,WAAW,CAAC,MAAM;aAC1B,CAAC,CAAC,CAAC;QACN,CAAC;IAEH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function run(argv?: string[]): Promise<void>;
2
+ //# sourceMappingURL=list-products.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-products.d.ts","sourceRoot":"","sources":["../../src/commands/list-products.ts"],"names":[],"mappings":"AAuBA,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,iBA4C/D"}
@@ -0,0 +1,62 @@
1
+ import { getCredentials, getSessionId } from '../lib/api-client.js';
2
+ import { shopifyGraphQL } from '../lib/shopify-client.js';
3
+ import { parseArgs, hasHelpFlag } from '../lib/args-parser.js';
4
+ function showHelp() {
5
+ console.log(`
6
+ List Shopify Products
7
+
8
+ USAGE:
9
+ ecomcoder products list [OPTIONS]
10
+
11
+ OPTIONS:
12
+ --limit Number of products to list (default: 10)
13
+ --session-id Session ID (auto-provided via SESSION_ID env var)
14
+ --help, -h Show this help message
15
+
16
+ EXAMPLES:
17
+ ecomcoder products list
18
+ ecomcoder products list --limit=50
19
+ `);
20
+ process.exit(0);
21
+ }
22
+ export async function run(argv = process.argv.slice(2)) {
23
+ if (hasHelpFlag(argv)) {
24
+ showHelp();
25
+ }
26
+ const args = parseArgs(argv);
27
+ const limit = parseInt(args.limit || '10', 10);
28
+ try {
29
+ const sessionId = getSessionId(args.sessionId);
30
+ const credentials = await getCredentials(sessionId);
31
+ const result = await shopifyGraphQL(credentials, `
32
+ query {
33
+ products(first: ${limit}) {
34
+ edges {
35
+ node {
36
+ id
37
+ title
38
+ handle
39
+ status
40
+ }
41
+ }
42
+ }
43
+ }
44
+ `);
45
+ const products = result?.data?.products?.edges?.map((e) => e.node) || [];
46
+ console.log(JSON.stringify({
47
+ success: true,
48
+ data: {
49
+ total: products.length,
50
+ products
51
+ }
52
+ }));
53
+ }
54
+ catch (error) {
55
+ console.error(JSON.stringify({
56
+ success: false,
57
+ error: error instanceof Error ? error.message : 'Unknown error'
58
+ }));
59
+ process.exit(1);
60
+ }
61
+ }
62
+ //# sourceMappingURL=list-products.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-products.js","sourceRoot":"","sources":["../../src/commands/list-products.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE/D,SAAS,QAAQ;IACf,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;CAcb,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;IAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IAE/C,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;QAEpD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE;;0BAE3B,KAAK;;;;;;;;;;;KAW1B,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAE9E,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACzB,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,KAAK,EAAE,QAAQ,CAAC,MAAM;gBACtB,QAAQ;aACT;SACF,CAAC,CAAC,CAAC;IAEN,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function run(argv?: string[]): Promise<void>;
2
+ //# sourceMappingURL=set-product-rating.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-product-rating.d.ts","sourceRoot":"","sources":["../../src/commands/set-product-rating.ts"],"names":[],"mappings":"AA0BA,wBAAsB,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,iBA6F/D"}
@@ -0,0 +1,111 @@
1
+ import { getCredentials, getSessionId } from '../lib/api-client.js';
2
+ import { shopifyGraphQL } from '../lib/shopify-client.js';
3
+ import { parseArgs, hasHelpFlag } from '../lib/args-parser.js';
4
+ function showHelp() {
5
+ console.log(`
6
+ Set Product Rating Metafields
7
+
8
+ USAGE:
9
+ ecomcoder products set-rating [OPTIONS]
10
+
11
+ REQUIRED OPTIONS:
12
+ --product-id Product GID (e.g., "gid://shopify/Product/123")
13
+ --rating Rating value (0.0 - 5.0)
14
+ --count Number of reviews (integer)
15
+
16
+ OTHER OPTIONS:
17
+ --session-id Session ID (auto-provided via SESSION_ID env var)
18
+ --help, -h Show this help message
19
+
20
+ EXAMPLES:
21
+ ecomcoder products set-rating --product-id="gid://shopify/Product/123" --rating=4.5 --count=127
22
+ `);
23
+ process.exit(0);
24
+ }
25
+ export async function run(argv = process.argv.slice(2)) {
26
+ if (hasHelpFlag(argv)) {
27
+ showHelp();
28
+ }
29
+ const args = parseArgs(argv);
30
+ const rating = parseFloat(args.rating);
31
+ const count = parseInt(args.count, 10);
32
+ if (!args.productId || isNaN(rating) || isNaN(count)) {
33
+ console.error(JSON.stringify({
34
+ success: false,
35
+ error: 'Missing required arguments: --product-id, --rating, --count'
36
+ }));
37
+ process.exit(1);
38
+ }
39
+ if (rating < 0 || rating > 5) {
40
+ console.error(JSON.stringify({
41
+ success: false,
42
+ error: 'Rating must be between 0.0 and 5.0'
43
+ }));
44
+ process.exit(1);
45
+ }
46
+ try {
47
+ const sessionId = getSessionId(args.sessionId);
48
+ const credentials = await getCredentials(sessionId);
49
+ const result = await shopifyGraphQL(credentials, `
50
+ mutation metafieldsSet($metafields: [MetafieldsSetInput!]!) {
51
+ metafieldsSet(metafields: $metafields) {
52
+ metafields {
53
+ id
54
+ key
55
+ value
56
+ namespace
57
+ type
58
+ }
59
+ userErrors {
60
+ field
61
+ message
62
+ code
63
+ }
64
+ }
65
+ }
66
+ `, {
67
+ metafields: [
68
+ {
69
+ namespace: "ecomcoder",
70
+ key: "rating",
71
+ type: "number_decimal",
72
+ value: rating.toString(),
73
+ ownerId: args.productId
74
+ },
75
+ {
76
+ namespace: "ecomcoder",
77
+ key: "rating_count",
78
+ type: "number_integer",
79
+ value: count.toString(),
80
+ ownerId: args.productId
81
+ }
82
+ ]
83
+ });
84
+ const userErrors = result?.data?.metafieldsSet?.userErrors;
85
+ const metafields = result?.data?.metafieldsSet?.metafields;
86
+ if (userErrors && userErrors.length > 0) {
87
+ throw new Error(`Failed to set metafields: ${userErrors.map((e) => e.message).join(', ')}`);
88
+ }
89
+ console.log(JSON.stringify({
90
+ success: true,
91
+ data: {
92
+ productId: args.productId,
93
+ rating,
94
+ count,
95
+ metafields: metafields?.map((m) => ({
96
+ key: m.key,
97
+ value: m.value,
98
+ type: m.type
99
+ }))
100
+ }
101
+ }));
102
+ }
103
+ catch (error) {
104
+ console.error(JSON.stringify({
105
+ success: false,
106
+ error: error instanceof Error ? error.message : 'Unknown error'
107
+ }));
108
+ process.exit(1);
109
+ }
110
+ }
111
+ //# sourceMappingURL=set-product-rating.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-product-rating.js","sourceRoot":"","sources":["../../src/commands/set-product-rating.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE/D,SAAS,QAAQ;IACf,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;CAiBb,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;IAC7B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAEvC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,6DAA6D;SACrE,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,oCAAoC;SAC5C,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;QAEpD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE;;;;;;;;;;;;;;;;;KAiBhD,EAAE;YACD,UAAU,EAAE;gBACV;oBACE,SAAS,EAAE,WAAW;oBACtB,GAAG,EAAE,QAAQ;oBACb,IAAI,EAAE,gBAAgB;oBACtB,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE;oBACxB,OAAO,EAAE,IAAI,CAAC,SAAS;iBACxB;gBACD;oBACE,SAAS,EAAE,WAAW;oBACtB,GAAG,EAAE,cAAc;oBACnB,IAAI,EAAE,gBAAgB;oBACtB,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE;oBACvB,OAAO,EAAE,IAAI,CAAC,SAAS;iBACxB;aACF;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC;QAC3D,MAAM,UAAU,GAAG,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC;QAE3D,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnG,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACzB,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,MAAM;gBACN,KAAK;gBACL,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;oBACvC,GAAG,EAAE,CAAC,CAAC,GAAG;oBACV,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,IAAI,EAAE,CAAC,CAAC,IAAI;iBACb,CAAC,CAAC;aACJ;SACF,CAAC,CAAC,CAAC;IAEN,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC3B,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC,CAAC,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Backend API Client
3
+ * Handles communication with the EcomCoder backend for fetching credentials
4
+ */
5
+ import type { ShopifyCredentials } from './types.js';
6
+ /**
7
+ * Fetch Shopify credentials from the backend
8
+ * Uses SESSION_ID from environment variable (injected by Claude Agent SDK)
9
+ * or explicit sessionId parameter
10
+ */
11
+ export declare function getCredentials(sessionId: string): Promise<ShopifyCredentials>;
12
+ /**
13
+ * Get session ID from environment variable or parameter
14
+ * Priority: parameter > environment variable
15
+ */
16
+ export declare function getSessionId(explicitSessionId?: string): string;
17
+ //# sourceMappingURL=api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA2BnF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ/D"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Backend API Client
3
+ * Handles communication with the EcomCoder backend for fetching credentials
4
+ */
5
+ /**
6
+ * Fetch Shopify credentials from the backend
7
+ * Uses SESSION_ID from environment variable (injected by Claude Agent SDK)
8
+ * or explicit sessionId parameter
9
+ */
10
+ export async function getCredentials(sessionId) {
11
+ const backendURL = process.env.BACKEND_URL || 'http://localhost:8080';
12
+ try {
13
+ const response = await fetch(`${backendURL}/api/internal/shopify-credentials`, {
14
+ method: 'POST',
15
+ headers: { 'Content-Type': 'application/json' },
16
+ body: JSON.stringify({ sessionId })
17
+ });
18
+ if (!response.ok) {
19
+ throw new Error(`Backend API returned ${response.status}`);
20
+ }
21
+ const data = await response.json();
22
+ if (!data.shopifyUrl || !data.shopifyAdminPassword) {
23
+ throw new Error('Invalid credentials returned from backend');
24
+ }
25
+ return {
26
+ shopifyUrl: data.shopifyUrl,
27
+ shopifyAdminPassword: data.shopifyAdminPassword
28
+ };
29
+ }
30
+ catch (error) {
31
+ throw new Error(`Failed to fetch credentials: ${error instanceof Error ? error.message : 'Unknown error'}`);
32
+ }
33
+ }
34
+ /**
35
+ * Get session ID from environment variable or parameter
36
+ * Priority: parameter > environment variable
37
+ */
38
+ export function getSessionId(explicitSessionId) {
39
+ const sessionId = explicitSessionId || process.env.SESSION_ID;
40
+ if (!sessionId) {
41
+ throw new Error('Session ID is required. Provide --session-id flag or set SESSION_ID environment variable.');
42
+ }
43
+ return sessionId;
44
+ }
45
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAiB;IACpD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,uBAAuB,CAAC;IAEtE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,mCAAmC,EAAE;YAC7E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;SACpC,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA6B,CAAC;QAE9D,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC/D,CAAC;QAED,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,UAAoB;YACrC,oBAAoB,EAAE,IAAI,CAAC,oBAA8B;SAC1D,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;IAC9G,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,iBAA0B;IACrD,MAAM,SAAS,GAAG,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IAE9D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,2FAA2F,CAAC,CAAC;IAC/G,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Command-line argument parsing utilities
3
+ */
4
+ /**
5
+ * Parse command-line arguments into a key-value object
6
+ * Converts kebab-case to camelCase
7
+ *
8
+ * Example:
9
+ * --session-id=abc123 --count=10
10
+ * => { sessionId: 'abc123', count: '10' }
11
+ */
12
+ export declare function parseArgs(argv?: string[]): Record<string, string>;
13
+ /**
14
+ * Check if help flag is present
15
+ */
16
+ export declare function hasHelpFlag(argv?: string[]): boolean;
17
+ /**
18
+ * Get positional arguments (non-flag arguments)
19
+ */
20
+ export declare function getPositionalArgs(argv?: string[]): string[];
21
+ //# sourceMappingURL=args-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args-parser.d.ts","sourceRoot":"","sources":["../../src/lib/args-parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYxF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAElE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,MAAM,EAAE,CAElF"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Command-line argument parsing utilities
3
+ */
4
+ /**
5
+ * Parse command-line arguments into a key-value object
6
+ * Converts kebab-case to camelCase
7
+ *
8
+ * Example:
9
+ * --session-id=abc123 --count=10
10
+ * => { sessionId: 'abc123', count: '10' }
11
+ */
12
+ export function parseArgs(argv = process.argv.slice(2)) {
13
+ const args = {};
14
+ for (const arg of argv) {
15
+ if (arg.startsWith('--')) {
16
+ const [key, value] = arg.slice(2).split('=');
17
+ const camelKey = key.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
18
+ args[camelKey] = value || 'true';
19
+ }
20
+ }
21
+ return args;
22
+ }
23
+ /**
24
+ * Check if help flag is present
25
+ */
26
+ export function hasHelpFlag(argv = process.argv) {
27
+ return argv.includes('--help') || argv.includes('-h');
28
+ }
29
+ /**
30
+ * Get positional arguments (non-flag arguments)
31
+ */
32
+ export function getPositionalArgs(argv = process.argv.slice(2)) {
33
+ return argv.filter(arg => !arg.startsWith('--') && !arg.startsWith('-'));
34
+ }
35
+ //# sourceMappingURL=args-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args-parser.js","sourceRoot":"","sources":["../../src/lib/args-parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,OAAiB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9D,MAAM,IAAI,GAA2B,EAAE,CAAC;IAExC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7C,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YAC/E,IAAI,CAAC,QAAQ,CAAC,GAAG,KAAK,IAAI,MAAM,CAAC;QACnC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAiB,OAAO,CAAC,IAAI;IACvD,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAiB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shopify GraphQL Client
3
+ * Helper functions for making Shopify Admin API calls
4
+ */
5
+ import type { ShopifyCredentials, ShopifyGraphQLResponse } from './types.js';
6
+ /**
7
+ * Execute a Shopify GraphQL query or mutation
8
+ */
9
+ export declare function shopifyGraphQL<T = any>(credentials: ShopifyCredentials, query: string, variables?: Record<string, any>): Promise<ShopifyGraphQLResponse<T>>;
10
+ /**
11
+ * Rate limiting helper - wait between API calls
12
+ */
13
+ export declare function rateLimit(ms?: number): Promise<void>;
14
+ //# sourceMappingURL=shopify-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shopify-client.d.ts","sourceRoot":"","sources":["../../src/lib/shopify-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAI7E;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,GAAG,GAAG,EAC1C,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC9B,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAoBpC;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,EAAE,GAAE,MAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/D"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Shopify GraphQL Client
3
+ * Helper functions for making Shopify Admin API calls
4
+ */
5
+ const SHOPIFY_API_VERSION = '2025-10';
6
+ /**
7
+ * Execute a Shopify GraphQL query or mutation
8
+ */
9
+ export async function shopifyGraphQL(credentials, query, variables) {
10
+ const url = `https://${credentials.shopifyUrl}/admin/api/${SHOPIFY_API_VERSION}/graphql.json`;
11
+ const response = await fetch(url, {
12
+ method: 'POST',
13
+ headers: {
14
+ 'Content-Type': 'application/json',
15
+ 'X-Shopify-Access-Token': credentials.shopifyAdminPassword
16
+ },
17
+ body: JSON.stringify({
18
+ query,
19
+ variables
20
+ })
21
+ });
22
+ if (!response.ok) {
23
+ throw new Error(`Shopify API returned ${response.status}: ${response.statusText}`);
24
+ }
25
+ return await response.json();
26
+ }
27
+ /**
28
+ * Rate limiting helper - wait between API calls
29
+ */
30
+ export async function rateLimit(ms = 500) {
31
+ await new Promise(resolve => setTimeout(resolve, ms));
32
+ }
33
+ //# sourceMappingURL=shopify-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shopify-client.js","sourceRoot":"","sources":["../../src/lib/shopify-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAEtC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAA+B,EAC/B,KAAa,EACb,SAA+B;IAE/B,MAAM,GAAG,GAAG,WAAW,WAAW,CAAC,UAAU,cAAc,mBAAmB,eAAe,CAAC;IAE9F,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,wBAAwB,EAAE,WAAW,CAAC,oBAAoB;SAC3D;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK;YACL,SAAS;SACV,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,wBAAwB,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAA+B,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAa,GAAG;IAC9C,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Shared TypeScript types for EcomCoder CLI
3
+ */
4
+ export interface ShopifyCredentials {
5
+ shopifyUrl: string;
6
+ shopifyAdminPassword: string;
7
+ }
8
+ export interface BackendAPIResponse<T = any> {
9
+ success: boolean;
10
+ data?: T;
11
+ error?: string;
12
+ }
13
+ export interface ProductCreateInput {
14
+ product: {
15
+ title: string;
16
+ descriptionHtml: string;
17
+ vendor: string;
18
+ productType: string;
19
+ tags: string[];
20
+ status: string;
21
+ };
22
+ media: Array<{
23
+ originalSource: string;
24
+ mediaContentType: string;
25
+ alt: string;
26
+ }>;
27
+ pricing: {
28
+ price: string;
29
+ compareAtPrice: string;
30
+ };
31
+ }
32
+ export interface ShopifyProduct {
33
+ id: string;
34
+ title: string;
35
+ handle: string;
36
+ status: string;
37
+ variants?: {
38
+ edges: Array<{
39
+ node: {
40
+ id: string;
41
+ price: string;
42
+ };
43
+ }>;
44
+ };
45
+ }
46
+ export interface ShopifyGraphQLResponse<T = any> {
47
+ data?: T;
48
+ errors?: Array<{
49
+ message: string;
50
+ extensions?: any;
51
+ }>;
52
+ }
53
+ export interface ShopifyUserError {
54
+ field: string[] | null;
55
+ message: string;
56
+ code?: string;
57
+ }
58
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,GAAG;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,eAAe,EAAE,MAAM,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,KAAK,EAAE,KAAK,CAAC;QACX,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC;QACzB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC,CAAC;IACH,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE;QACT,KAAK,EAAE,KAAK,CAAC;YACX,IAAI,EAAE;gBACJ,EAAE,EAAE,MAAM,CAAC;gBACX,KAAK,EAAE,MAAM,CAAC;aACf,CAAC;SACH,CAAC,CAAC;KACJ,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,GAAG;IAC7C,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,GAAG,CAAC;KAClB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared TypeScript types for EcomCoder CLI
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "ecomcoder-cli",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "CLI tools for EcomCoder - Shopify development utilities",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "ecomcoder": "bin/ecomcoder"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsc --watch",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "bin",
19
+ "README.md"
20
+ ],
21
+ "keywords": [
22
+ "shopify",
23
+ "ecommerce",
24
+ "cli",
25
+ "development",
26
+ "tools"
27
+ ],
28
+ "author": "EcomCoder",
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/ImadMoka/ecomcoder-cli.git"
33
+ },
34
+ "bugs": {
35
+ "url": "https://github.com/ImadMoka/ecomcoder-cli/issues"
36
+ },
37
+ "homepage": "https://github.com/ImadMoka/ecomcoder-cli#readme",
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "dependencies": {},
42
+ "devDependencies": {
43
+ "@types/node": "^20.10.0",
44
+ "typescript": "^5.3.3"
45
+ },
46
+ "engines": {
47
+ "node": ">=18.0.0"
48
+ }
49
+ }