ecomcoder-cli 1.2.15 → 1.3.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 (75) hide show
  1. package/dist/__tests__/test-utils.d.ts +123 -0
  2. package/dist/__tests__/test-utils.d.ts.map +1 -0
  3. package/dist/__tests__/test-utils.js +133 -0
  4. package/dist/__tests__/test-utils.js.map +1 -0
  5. package/dist/cli.d.ts +8 -7
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +70 -65
  8. package/dist/cli.js.map +1 -1
  9. package/dist/commands/docs/index.d.ts +10 -0
  10. package/dist/commands/docs/index.d.ts.map +1 -0
  11. package/dist/commands/docs/index.js +43 -0
  12. package/dist/commands/docs/index.js.map +1 -0
  13. package/dist/commands/metafield/index.d.ts +10 -0
  14. package/dist/commands/metafield/index.d.ts.map +1 -0
  15. package/dist/commands/metafield/index.js +55 -0
  16. package/dist/commands/metafield/index.js.map +1 -0
  17. package/dist/commands/product/__tests__/service.test.d.ts +7 -0
  18. package/dist/commands/product/__tests__/service.test.d.ts.map +1 -0
  19. package/dist/commands/product/__tests__/service.test.js +299 -0
  20. package/dist/commands/product/__tests__/service.test.js.map +1 -0
  21. package/dist/commands/product/__tests__/update-description.test.d.ts +5 -0
  22. package/dist/commands/product/__tests__/update-description.test.d.ts.map +1 -0
  23. package/dist/commands/product/__tests__/update-description.test.js +110 -0
  24. package/dist/commands/product/__tests__/update-description.test.js.map +1 -0
  25. package/dist/commands/product/get.d.ts +2 -0
  26. package/dist/commands/product/get.d.ts.map +1 -0
  27. package/dist/commands/product/get.js +305 -0
  28. package/dist/commands/product/get.js.map +1 -0
  29. package/dist/commands/product/index.d.ts +10 -0
  30. package/dist/commands/product/index.d.ts.map +1 -0
  31. package/dist/commands/product/index.js +73 -0
  32. package/dist/commands/product/index.js.map +1 -0
  33. package/dist/commands/product/queries.d.ts +32 -0
  34. package/dist/commands/product/queries.d.ts.map +1 -0
  35. package/dist/commands/product/queries.js +195 -0
  36. package/dist/commands/product/queries.js.map +1 -0
  37. package/dist/commands/product/service.d.ts +51 -0
  38. package/dist/commands/product/service.d.ts.map +1 -0
  39. package/dist/commands/product/service.js +237 -0
  40. package/dist/commands/product/service.js.map +1 -0
  41. package/dist/commands/product/types.d.ts +165 -0
  42. package/dist/commands/product/types.d.ts.map +1 -0
  43. package/dist/commands/product/types.js +6 -0
  44. package/dist/commands/product/types.js.map +1 -0
  45. package/dist/commands/product/update-description.d.ts +8 -0
  46. package/dist/commands/product/update-description.d.ts.map +1 -0
  47. package/dist/commands/product/update-description.js +86 -0
  48. package/dist/commands/product/update-description.js.map +1 -0
  49. package/dist/commands/product/update-price.d.ts +8 -0
  50. package/dist/commands/product/update-price.d.ts.map +1 -0
  51. package/dist/commands/product/update-price.js +101 -0
  52. package/dist/commands/product/update-price.js.map +1 -0
  53. package/dist/commands/product/update-template.d.ts +8 -0
  54. package/dist/commands/product/update-template.d.ts.map +1 -0
  55. package/dist/commands/product/update-template.js +114 -0
  56. package/dist/commands/product/update-template.js.map +1 -0
  57. package/dist/commands/product/utils.d.ts +69 -0
  58. package/dist/commands/product/utils.d.ts.map +1 -0
  59. package/dist/commands/product/utils.js +180 -0
  60. package/dist/commands/product/utils.js.map +1 -0
  61. package/dist/commands/products/index.d.ts +10 -0
  62. package/dist/commands/products/index.d.ts.map +1 -0
  63. package/dist/commands/products/index.js +62 -0
  64. package/dist/commands/products/index.js.map +1 -0
  65. package/dist/lib/api-client.d.ts.map +1 -1
  66. package/dist/lib/api-client.js +11 -0
  67. package/dist/lib/api-client.js.map +1 -1
  68. package/dist/lib/args-parser.d.ts.map +1 -1
  69. package/dist/lib/args-parser.js +2 -1
  70. package/dist/lib/args-parser.js.map +1 -1
  71. package/dist/lib/command-registry.d.ts +64 -0
  72. package/dist/lib/command-registry.d.ts.map +1 -0
  73. package/dist/lib/command-registry.js +76 -0
  74. package/dist/lib/command-registry.js.map +1 -0
  75. package/package.json +10 -2
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Test Utilities
3
+ *
4
+ * Shared helpers for testing CLI commands
5
+ */
6
+ import type { ShopifyCredentials } from '../lib/types.js';
7
+ /**
8
+ * Mock Shopify credentials for testing
9
+ */
10
+ export declare const mockCredentials: ShopifyCredentials;
11
+ /**
12
+ * Mock GraphQL response helper
13
+ */
14
+ export declare function mockGraphQLResponse<T>(data: T, errors?: any[]): {
15
+ data: T;
16
+ errors: any[] | undefined;
17
+ };
18
+ /**
19
+ * Mock product data
20
+ */
21
+ export declare const mockProduct: {
22
+ id: string;
23
+ title: string;
24
+ description: string;
25
+ descriptionHtml: string;
26
+ handle: string;
27
+ productType: string;
28
+ vendor: string;
29
+ tags: string[];
30
+ status: "ACTIVE";
31
+ templateSuffix: null;
32
+ variants: {
33
+ edges: {
34
+ node: {
35
+ id: string;
36
+ title: string;
37
+ sku: string;
38
+ price: string;
39
+ compareAtPrice: null;
40
+ inventoryQuantity: number;
41
+ availableForSale: boolean;
42
+ };
43
+ }[];
44
+ };
45
+ images: {
46
+ edges: never[];
47
+ };
48
+ priceRangeV2: {
49
+ minVariantPrice: {
50
+ amount: string;
51
+ currencyCode: string;
52
+ };
53
+ maxVariantPrice: {
54
+ amount: string;
55
+ currencyCode: string;
56
+ };
57
+ };
58
+ };
59
+ /**
60
+ * Mock product with multiple variants
61
+ */
62
+ export declare const mockProductMultipleVariants: {
63
+ variants: {
64
+ edges: {
65
+ node: {
66
+ id: string;
67
+ title: string;
68
+ sku: string;
69
+ price: string;
70
+ compareAtPrice: null;
71
+ inventoryQuantity: number;
72
+ availableForSale: boolean;
73
+ };
74
+ }[];
75
+ };
76
+ id: string;
77
+ title: string;
78
+ description: string;
79
+ descriptionHtml: string;
80
+ handle: string;
81
+ productType: string;
82
+ vendor: string;
83
+ tags: string[];
84
+ status: "ACTIVE";
85
+ templateSuffix: null;
86
+ images: {
87
+ edges: never[];
88
+ };
89
+ priceRangeV2: {
90
+ minVariantPrice: {
91
+ amount: string;
92
+ currencyCode: string;
93
+ };
94
+ maxVariantPrice: {
95
+ amount: string;
96
+ currencyCode: string;
97
+ };
98
+ };
99
+ };
100
+ /**
101
+ * Mock variant data
102
+ */
103
+ export declare const mockVariant: {
104
+ id: string;
105
+ price: string;
106
+ compareAtPrice: null;
107
+ };
108
+ /**
109
+ * Mock user errors
110
+ */
111
+ export declare const mockUserErrors: {
112
+ field: string[];
113
+ message: string;
114
+ }[];
115
+ /**
116
+ * Parse JSON output from CLI commands
117
+ */
118
+ export declare function parseCommandOutput(output: string): any;
119
+ /**
120
+ * Create mock shopifyGraphQL function
121
+ */
122
+ export declare function createMockShopifyGraphQL(mockResponse: any): (credentials: ShopifyCredentials, query: string, variables?: any) => Promise<any>;
123
+ //# sourceMappingURL=test-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/__tests__/test-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,kBAG7B,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE;;;EAK7D;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCvB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BvC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW;;;;CAIvB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc;;;GAK1B,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAMtD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,GAAG,IAC1C,aAAa,kBAAkB,EAAE,OAAO,MAAM,EAAE,YAAY,GAAG,kBAG9E"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Test Utilities
3
+ *
4
+ * Shared helpers for testing CLI commands
5
+ */
6
+ /**
7
+ * Mock Shopify credentials for testing
8
+ */
9
+ export const mockCredentials = {
10
+ shopifyUrl: 'https://test-shop.myshopify.com',
11
+ shopifyAdminPassword: 'shpat_test_token_12345'
12
+ };
13
+ /**
14
+ * Mock GraphQL response helper
15
+ */
16
+ export function mockGraphQLResponse(data, errors) {
17
+ return {
18
+ data,
19
+ errors: errors || undefined
20
+ };
21
+ }
22
+ /**
23
+ * Mock product data
24
+ */
25
+ export const mockProduct = {
26
+ id: 'gid://shopify/Product/123456789',
27
+ title: 'Test Product',
28
+ description: 'Test description',
29
+ descriptionHtml: '<p>Test description</p>',
30
+ handle: 'test-product',
31
+ productType: 'Test Type',
32
+ vendor: 'Test Vendor',
33
+ tags: ['test', 'sample'],
34
+ status: 'ACTIVE',
35
+ templateSuffix: null,
36
+ variants: {
37
+ edges: [
38
+ {
39
+ node: {
40
+ id: 'gid://shopify/ProductVariant/987654321',
41
+ title: 'Default Title',
42
+ sku: 'TEST-SKU',
43
+ price: '29.99',
44
+ compareAtPrice: null,
45
+ inventoryQuantity: 100,
46
+ availableForSale: true
47
+ }
48
+ }
49
+ ]
50
+ },
51
+ images: {
52
+ edges: []
53
+ },
54
+ priceRangeV2: {
55
+ minVariantPrice: {
56
+ amount: '29.99',
57
+ currencyCode: 'USD'
58
+ },
59
+ maxVariantPrice: {
60
+ amount: '29.99',
61
+ currencyCode: 'USD'
62
+ }
63
+ }
64
+ };
65
+ /**
66
+ * Mock product with multiple variants
67
+ */
68
+ export const mockProductMultipleVariants = {
69
+ ...mockProduct,
70
+ variants: {
71
+ edges: [
72
+ {
73
+ node: {
74
+ id: 'gid://shopify/ProductVariant/111',
75
+ title: 'Small',
76
+ sku: 'TEST-SKU-S',
77
+ price: '29.99',
78
+ compareAtPrice: null,
79
+ inventoryQuantity: 50,
80
+ availableForSale: true,
81
+ }
82
+ },
83
+ {
84
+ node: {
85
+ id: 'gid://shopify/ProductVariant/222',
86
+ title: 'Medium',
87
+ sku: 'TEST-SKU-M',
88
+ price: '29.99',
89
+ compareAtPrice: null,
90
+ inventoryQuantity: 50,
91
+ availableForSale: true,
92
+ }
93
+ }
94
+ ]
95
+ }
96
+ };
97
+ /**
98
+ * Mock variant data
99
+ */
100
+ export const mockVariant = {
101
+ id: 'gid://shopify/ProductVariant/987654321',
102
+ price: '29.99',
103
+ compareAtPrice: null
104
+ };
105
+ /**
106
+ * Mock user errors
107
+ */
108
+ export const mockUserErrors = [
109
+ {
110
+ field: ['input', 'price'],
111
+ message: 'Price must be positive'
112
+ }
113
+ ];
114
+ /**
115
+ * Parse JSON output from CLI commands
116
+ */
117
+ export function parseCommandOutput(output) {
118
+ try {
119
+ return JSON.parse(output);
120
+ }
121
+ catch (error) {
122
+ throw new Error(`Failed to parse command output: ${output}`);
123
+ }
124
+ }
125
+ /**
126
+ * Create mock shopifyGraphQL function
127
+ */
128
+ export function createMockShopifyGraphQL(mockResponse) {
129
+ return async (credentials, query, variables) => {
130
+ return mockResponse;
131
+ };
132
+ }
133
+ //# sourceMappingURL=test-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../../src/__tests__/test-utils.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * EcomCoder CLI - Main Entry Point
3
+ * EcomCoder CLI - Main Entry Point (Refactored)
4
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=...
5
+ * Architecture: Command Registry Pattern
6
+ *
7
+ * Benefits:
8
+ * Open/Closed Principle - Add commands without modifying this file
9
+ * Single Responsibility - This file only routes, doesn't know command details
10
+ * Scalability - Supports unlimited commands
11
+ * ✅ Testability - Easy to test routing logic
11
12
  */
12
13
  export {};
13
14
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG"}
package/dist/cli.js CHANGED
@@ -1,16 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * EcomCoder CLI - Main Entry Point
3
+ * EcomCoder CLI - Main Entry Point (Refactored)
4
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=...
5
+ * Architecture: Command Registry Pattern
6
+ *
7
+ * Benefits:
8
+ * Open/Closed Principle - Add commands without modifying this file
9
+ * Single Responsibility - This file only routes, doesn't know command details
10
+ * Scalability - Supports unlimited commands
11
+ * ✅ Testability - Easy to test routing logic
11
12
  */
12
13
  import { getPositionalArgs } from './lib/args-parser.js';
13
- function showHelp() {
14
+ import { registry } from './lib/command-registry.js';
15
+ // Register all command groups
16
+ import { registerProductCommands } from './commands/product/index.js';
17
+ import { registerMetafieldCommands } from './commands/metafield/index.js';
18
+ import { registerProductsCommands } from './commands/products/index.js';
19
+ import { registerDocsCommands } from './commands/docs/index.js';
20
+ // Initialize registry
21
+ registerProductCommands();
22
+ registerMetafieldCommands();
23
+ registerProductsCommands();
24
+ registerDocsCommands();
25
+ function showMainHelp() {
14
26
  console.log(`
15
27
  EcomCoder CLI - Shopify Development Utilities
16
28
 
@@ -18,12 +30,16 @@ USAGE:
18
30
  ecomcoder <command> <subcommand> [options]
19
31
 
20
32
  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 metafield definition
25
- metafield get Get metafield definition(s)
26
- docs search Search Shopify theme documentation
33
+ products create Create dummy Shopify products for testing
34
+ products list List products in your Shopify store
35
+ products set-rating Set rating metafields on a product
36
+ product get Get detailed product data
37
+ product update-description Update product description
38
+ product update-price Update product price and compare-at price
39
+ product update-template Change product template assignment
40
+ metafield create Create metafield definition
41
+ metafield get Get metafield definition(s)
42
+ docs search Search Shopify theme documentation
27
43
 
28
44
  GLOBAL OPTIONS:
29
45
  --session-id Session ID for authentication (auto-provided when used with Claude)
@@ -46,6 +62,19 @@ EXAMPLES:
46
62
  # Set product rating
47
63
  ecomcoder products set-rating --product-id="gid://shopify/Product/123" --rating=4.5 --count=127
48
64
 
65
+ # Get product details
66
+ ecomcoder product get --id=123456789
67
+ ecomcoder product get --title="Blue T-Shirt"
68
+
69
+ # Update product description
70
+ ecomcoder product update-description --id=123 --description="Premium cotton t-shirt"
71
+
72
+ # Update product price
73
+ ecomcoder product update-price --id=123 --price=34.99 --compare-at-price=49.99
74
+
75
+ # Change product template
76
+ ecomcoder product update-template --id=123 --template=premium
77
+
49
78
  # Create product-level metafield
50
79
  ecomcoder metafield create --name="Rating" --key=rating --type=number_decimal --owner-type=PRODUCT
51
80
 
@@ -64,71 +93,47 @@ For more help on specific commands, run:
64
93
  }
65
94
  async function main() {
66
95
  const args = process.argv.slice(2);
67
- // Show help only if no arguments (not if help flag is after a subcommand)
96
+ // Show help if no arguments
68
97
  if (args.length === 0) {
69
- showHelp();
98
+ showMainHelp();
70
99
  process.exit(0);
71
100
  }
72
101
  const positional = getPositionalArgs(args);
73
102
  const [command, subcommand] = positional;
74
103
  // Show main help if help flag with no command
75
104
  if ((args.includes('--help') || args.includes('-h')) && !command) {
76
- showHelp();
105
+ showMainHelp();
77
106
  process.exit(0);
78
107
  }
79
- // Route to appropriate command handler
80
108
  try {
81
- if (command === 'products') {
82
- if (subcommand === 'create') {
83
- const { run } = await import('./commands/create-dummy-products.js');
84
- await run(args.slice(2)); // Pass remaining args after 'products create'
85
- }
86
- else if (subcommand === 'list') {
87
- const { run } = await import('./commands/list-products.js');
88
- await run(args.slice(2));
89
- }
90
- else if (subcommand === 'set-rating') {
91
- const { run } = await import('./commands/set-product-rating.js');
92
- await run(args.slice(2));
93
- }
94
- else {
95
- console.error(`Unknown products subcommand: ${subcommand}`);
96
- console.error(`Valid subcommands: create, list, set-rating`);
97
- process.exit(1);
98
- }
99
- }
100
- else if (command === 'metafield') {
101
- if (subcommand === 'create') {
102
- const { run } = await import('./commands/create-metafield.js');
103
- await run(args.slice(2));
104
- }
105
- else if (subcommand === 'get') {
106
- const { run } = await import('./commands/get-metafield.js');
107
- await run(args.slice(2));
108
- }
109
- else {
110
- console.error(`Unknown metafield subcommand: ${subcommand}`);
111
- console.error(`Valid subcommands: create, get`);
112
- process.exit(1);
113
- }
114
- }
115
- else if (command === 'docs') {
116
- if (subcommand === 'search') {
117
- const { run } = await import('./commands/docs-search.js');
118
- await run(args.slice(2));
119
- }
120
- else {
121
- console.error(`Unknown docs subcommand: ${subcommand}`);
122
- console.error(`Valid subcommands: search`);
123
- process.exit(1);
124
- }
125
- }
126
- else {
109
+ // Check if command group exists
110
+ const group = registry.getGroup(command);
111
+ if (!group) {
112
+ // Command not found
113
+ const availableCommands = registry.getAllCommands();
127
114
  console.error(`Unknown command: ${command}`);
128
- console.error(`Valid commands: products, metafield, docs`);
115
+ console.error(`Valid commands: ${availableCommands.join(', ')}`);
129
116
  console.error(`Run 'ecomcoder --help' for more information`);
130
117
  process.exit(1);
131
118
  }
119
+ // Show group help ONLY if no subcommand
120
+ if (!subcommand) {
121
+ group.showHelp();
122
+ process.exit(0);
123
+ }
124
+ // Try to get command handler
125
+ const handler = await registry.get(command, subcommand);
126
+ if (!handler) {
127
+ // Subcommand not found
128
+ const availableCommands = registry.getCommandsInGroup(command)
129
+ .map(cmd => cmd.subcommand)
130
+ .filter(Boolean);
131
+ console.error(`Unknown ${command} subcommand: ${subcommand}`);
132
+ console.error(`Valid subcommands: ${availableCommands.join(', ')}`);
133
+ process.exit(1);
134
+ }
135
+ // Execute command (command itself handles --help)
136
+ await handler.run(args.slice(2)); // Pass remaining args
132
137
  }
133
138
  catch (error) {
134
139
  console.error(`Error executing command: ${error instanceof Error ? error.message : 'Unknown error'}`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Docs Commands Registration
3
+ *
4
+ * Following Open/Closed Principle - commands register themselves
5
+ */
6
+ /**
7
+ * Register all docs commands
8
+ */
9
+ export declare function registerDocsCommands(): void;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/docs/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAiC3C"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Docs Commands Registration
3
+ *
4
+ * Following Open/Closed Principle - commands register themselves
5
+ */
6
+ import { registry } from '../../lib/command-registry.js';
7
+ /**
8
+ * Register all docs commands
9
+ */
10
+ export function registerDocsCommands() {
11
+ // Register command group
12
+ registry.registerGroup({
13
+ command: 'docs',
14
+ description: 'Search Shopify theme documentation',
15
+ showHelp: () => {
16
+ console.log(`
17
+ Docs Commands - Search Shopify theme documentation
18
+
19
+ USAGE:
20
+ ecomcoder docs <subcommand> [options]
21
+
22
+ SUBCOMMANDS:
23
+ search Search Shopify theme docs using RAG
24
+
25
+ EXAMPLES:
26
+ # Search Shopify theme docs
27
+ ecomcoder docs search --query="How do sections work?"
28
+ ecomcoder docs search --query="Liquid filters for dates"
29
+
30
+ For detailed help on a specific subcommand:
31
+ ecomcoder docs <subcommand> --help
32
+ `);
33
+ }
34
+ });
35
+ // Register individual subcommands
36
+ registry.register({
37
+ command: 'docs',
38
+ subcommand: 'search',
39
+ description: 'Search Shopify theme documentation',
40
+ handler: async () => await import('../docs-search.js')
41
+ });
42
+ }
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/docs/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,yBAAyB;IACzB,QAAQ,CAAC,aAAa,CAAC;QACrB,OAAO,EAAE,MAAM;QACf,WAAW,EAAE,oCAAoC;QACjD,QAAQ,EAAE,GAAG,EAAE;YACb,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;CAgBjB,CAAC,CAAC;QACC,CAAC;KACF,CAAC,CAAC;IAEH,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,CAAC;QAChB,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,oCAAoC;QACjD,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,mBAAmB,CAAC;KACvD,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Metafield Commands Registration
3
+ *
4
+ * Following Open/Closed Principle - commands register themselves
5
+ */
6
+ /**
7
+ * Register all metafield commands
8
+ */
9
+ export declare function registerMetafieldCommands(): void;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/metafield/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CA8ChD"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Metafield Commands Registration
3
+ *
4
+ * Following Open/Closed Principle - commands register themselves
5
+ */
6
+ import { registry } from '../../lib/command-registry.js';
7
+ /**
8
+ * Register all metafield commands
9
+ */
10
+ export function registerMetafieldCommands() {
11
+ // Register command group
12
+ registry.registerGroup({
13
+ command: 'metafield',
14
+ description: 'Manage Shopify metafield definitions',
15
+ showHelp: () => {
16
+ console.log(`
17
+ Metafield Commands - Manage Shopify metafield definitions
18
+
19
+ USAGE:
20
+ ecomcoder metafield <subcommand> [options]
21
+
22
+ SUBCOMMANDS:
23
+ create Create metafield definition
24
+ get Get metafield definition(s)
25
+
26
+ EXAMPLES:
27
+ # Create product-level metafield
28
+ ecomcoder metafield create --name="Rating" --key=rating --type=number_decimal --owner-type=PRODUCT
29
+
30
+ # Create shop-level metafield (global)
31
+ ecomcoder metafield create --name="Cart Upsell" --key=cart_upsell --type=product_reference --owner-type=SHOP
32
+
33
+ # Get metafield definition
34
+ ecomcoder metafield get --namespace=ecomcoder --key=upsell --owner-type=PRODUCT
35
+
36
+ For detailed help on a specific subcommand:
37
+ ecomcoder metafield <subcommand> --help
38
+ `);
39
+ }
40
+ });
41
+ // Register individual subcommands
42
+ registry.register({
43
+ command: 'metafield',
44
+ subcommand: 'create',
45
+ description: 'Create metafield definition',
46
+ handler: async () => await import('../create-metafield.js')
47
+ });
48
+ registry.register({
49
+ command: 'metafield',
50
+ subcommand: 'get',
51
+ description: 'Get metafield definition(s)',
52
+ handler: async () => await import('../get-metafield.js')
53
+ });
54
+ }
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/metafield/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,yBAAyB;IACvC,yBAAyB;IACzB,QAAQ,CAAC,aAAa,CAAC;QACrB,OAAO,EAAE,WAAW;QACpB,WAAW,EAAE,sCAAsC;QACnD,QAAQ,EAAE,GAAG,EAAE;YACb,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;CAsBjB,CAAC,CAAC;QACC,CAAC;KACF,CAAC,CAAC;IAEH,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,CAAC;QAChB,OAAO,EAAE,WAAW;QACpB,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,6BAA6B;QAC1C,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,wBAAwB,CAAC;KAC5D,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,CAAC;QAChB,OAAO,EAAE,WAAW;QACpB,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,6BAA6B;QAC1C,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,qBAAqB,CAAC;KACzD,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * ProductService Tests
3
+ *
4
+ * Tests for product service layer business logic
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.test.d.ts","sourceRoot":"","sources":["../../../../src/commands/product/__tests__/service.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}