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.
- package/bin/ecomcoder +20 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +114 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/create-dummy-products.d.ts +2 -0
- package/dist/commands/create-dummy-products.d.ts.map +1 -0
- package/dist/commands/create-dummy-products.js +231 -0
- package/dist/commands/create-dummy-products.js.map +1 -0
- package/dist/commands/create-metafield.d.ts +2 -0
- package/dist/commands/create-metafield.d.ts.map +1 -0
- package/dist/commands/create-metafield.js +126 -0
- package/dist/commands/create-metafield.js.map +1 -0
- package/dist/commands/get-metafield.d.ts +2 -0
- package/dist/commands/get-metafield.d.ts.map +1 -0
- package/dist/commands/get-metafield.js +108 -0
- package/dist/commands/get-metafield.js.map +1 -0
- package/dist/commands/list-products.d.ts +2 -0
- package/dist/commands/list-products.d.ts.map +1 -0
- package/dist/commands/list-products.js +62 -0
- package/dist/commands/list-products.js.map +1 -0
- package/dist/commands/set-product-rating.d.ts +2 -0
- package/dist/commands/set-product-rating.d.ts.map +1 -0
- package/dist/commands/set-product-rating.js +111 -0
- package/dist/commands/set-product-rating.js.map +1 -0
- package/dist/lib/api-client.d.ts +17 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +45 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/args-parser.d.ts +21 -0
- package/dist/lib/args-parser.d.ts.map +1 -0
- package/dist/lib/args-parser.js +35 -0
- package/dist/lib/args-parser.js.map +1 -0
- package/dist/lib/shopify-client.d.ts +14 -0
- package/dist/lib/shopify-client.d.ts.map +1 -0
- package/dist/lib/shopify-client.js +33 -0
- package/dist/lib/shopify-client.js.map +1 -0
- package/dist/lib/types.d.ts +58 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +5 -0
- package/dist/lib/types.js.map +1 -0
- 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
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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":"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"}
|
|
@@ -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 @@
|
|
|
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
|
+
}
|