@madebyseed/seed-cli-tools 3.0.2 → 4.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 (81) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/__fixtures__/legacy-js-min/baseline/theme.dev.js +13 -0
  3. package/__fixtures__/legacy-js-min/baseline/theme.prod.js +1 -0
  4. package/__fixtures__/legacy-js-min/dist/assets/theme.js +13 -0
  5. package/__fixtures__/legacy-js-min/package.json +9 -0
  6. package/__fixtures__/legacy-js-min/src/scripts/components/sample.js +4 -0
  7. package/__fixtures__/legacy-js-min/src/scripts/theme.js +9 -0
  8. package/__fixtures__/legacy-js-min/src/scripts/vendor/lib.js +7 -0
  9. package/__fixtures__/legacy-js-min/src/scripts/vendor.js +3 -0
  10. package/__fixtures__/legacy-js-min/verify.sh +34 -0
  11. package/__fixtures__/module-js-min/dist/assets/components-greeter.js +6 -0
  12. package/__fixtures__/module-js-min/dist/assets/components-greeter.js.map +1 -0
  13. package/__fixtures__/module-js-min/dist/assets/components-items.js +5 -0
  14. package/__fixtures__/module-js-min/dist/assets/components-items.js.map +1 -0
  15. package/__fixtures__/module-js-min/dist/assets/header.js +20 -0
  16. package/__fixtures__/module-js-min/dist/assets/header.js.map +1 -0
  17. package/__fixtures__/module-js-min/dist/assets/sections-cart-items.js +8 -0
  18. package/__fixtures__/module-js-min/dist/assets/sections-cart-items.js.map +1 -0
  19. package/__fixtures__/module-js-min/dist/assets/vendor-lib.js +4 -0
  20. package/__fixtures__/module-js-min/dist/assets/vendor-lib.js.map +1 -0
  21. package/__fixtures__/module-js-min/package.json +9 -0
  22. package/__fixtures__/module-js-min/seed.project.json +15 -0
  23. package/__fixtures__/module-js-min/src/scripts/components/greeter.js +4 -0
  24. package/__fixtures__/module-js-min/src/scripts/components/items.js +3 -0
  25. package/__fixtures__/module-js-min/src/scripts/header.js +18 -0
  26. package/__fixtures__/module-js-min/src/scripts/sections/cart/items.js +6 -0
  27. package/__fixtures__/module-js-min/src/scripts/vendor/lib.js +2 -0
  28. package/__fixtures__/module-js-min/verify.sh +58 -0
  29. package/lib/commands/watch.js +55 -7
  30. package/lib/commands/watch.js.map +1 -1
  31. package/lib/shopify-bin.d.ts +14 -0
  32. package/lib/shopify-bin.js +18 -0
  33. package/lib/shopify-bin.js.map +1 -0
  34. package/lib/tasks/build-js-module.d.ts +2 -0
  35. package/lib/tasks/build-js-module.js +93 -0
  36. package/lib/tasks/build-js-module.js.map +1 -0
  37. package/lib/tasks/build-js.js +13 -1
  38. package/lib/tasks/build-js.js.map +1 -1
  39. package/lib/tasks/includes/config.d.ts +2 -0
  40. package/lib/tasks/includes/config.js +3 -0
  41. package/lib/tasks/includes/config.js.map +1 -1
  42. package/lib/tasks/includes/js-mode.d.ts +12 -0
  43. package/lib/tasks/includes/js-mode.js +42 -0
  44. package/lib/tasks/includes/js-mode.js.map +1 -0
  45. package/lib/tasks/watch-tui/App.d.ts +8 -0
  46. package/lib/tasks/watch-tui/App.js +337 -0
  47. package/lib/tasks/watch-tui/App.js.map +1 -0
  48. package/lib/tasks/watch-tui/classify.d.ts +39 -0
  49. package/lib/tasks/watch-tui/classify.js +84 -0
  50. package/lib/tasks/watch-tui/classify.js.map +1 -0
  51. package/lib/tasks/watch-tui/index.d.ts +30 -0
  52. package/lib/tasks/watch-tui/index.js +299 -0
  53. package/lib/tasks/watch-tui/index.js.map +1 -0
  54. package/lib/tasks/watch-tui/shopify-parse.d.ts +24 -0
  55. package/lib/tasks/watch-tui/shopify-parse.js +87 -0
  56. package/lib/tasks/watch-tui/shopify-parse.js.map +1 -0
  57. package/lib/tasks/watch-tui/state.d.ts +68 -0
  58. package/lib/tasks/watch-tui/state.js +61 -0
  59. package/lib/tasks/watch-tui/state.js.map +1 -0
  60. package/lib/tasks/watch-tui/theme-info.d.ts +10 -0
  61. package/lib/tasks/watch-tui/theme-info.js +79 -0
  62. package/lib/tasks/watch-tui/theme-info.js.map +1 -0
  63. package/lib/utils.js +63 -87
  64. package/lib/utils.js.map +1 -1
  65. package/package.json +11 -2
  66. package/src/commands/watch.ts +70 -20
  67. package/src/shopify-bin.ts +21 -0
  68. package/src/tasks/build-js-module.ts +92 -0
  69. package/src/tasks/build-js.ts +13 -1
  70. package/src/tasks/includes/config.ts +5 -0
  71. package/src/tasks/includes/js-mode.ts +48 -0
  72. package/src/tasks/watch-tui/App.tsx +486 -0
  73. package/src/tasks/watch-tui/classify.ts +120 -0
  74. package/src/tasks/watch-tui/index.ts +342 -0
  75. package/src/tasks/watch-tui/shopify-parse.ts +103 -0
  76. package/src/tasks/watch-tui/state.ts +113 -0
  77. package/src/tasks/watch-tui/theme-info.ts +109 -0
  78. package/src/types/declarations.d.ts +19 -1
  79. package/src/utils.ts +64 -93
  80. package/tsconfig.json +3 -2
  81. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,109 @@
1
+ import { existsSync, readFileSync } from "fs";
2
+ import { join } from "path";
3
+ import type { ThemeInfo } from "./state";
4
+
5
+ interface SeedContextFile {
6
+ version?: string;
7
+ activeContext?: string;
8
+ contexts?: Record<string, SeedContext>;
9
+ }
10
+
11
+ interface SeedContext {
12
+ name?: string;
13
+ status?: string;
14
+ git?: { branch?: string; baseBranch?: string };
15
+ shopify?: {
16
+ storeDomain?: string;
17
+ previewThemeName?: string;
18
+ previewThemeId?: string;
19
+ previewUrl?: string;
20
+ customizerUrl?: string;
21
+ };
22
+ asana?: { taskUrl?: string };
23
+ github?: { prUrl?: string };
24
+ }
25
+
26
+ interface SeedProjectConfig {
27
+ stores?: Record<string, { domain?: string }>;
28
+ }
29
+
30
+ interface SeedLegacyConfig {
31
+ store?: string;
32
+ stores?: Record<string, { domain?: string }>;
33
+ }
34
+
35
+ /**
36
+ * Build dashboard info from whatever config files exist. Precedence:
37
+ * 1. seed.context.json (active context) — full info
38
+ * 2. seed.project.json (newer project config) — store domain only
39
+ * 3. seed.config.js (legacy) — store domain only
40
+ * Returns an empty object if nothing is present; the dashboard renders
41
+ * whatever fields are populated.
42
+ */
43
+ export function loadThemeInfo(cwd: string, storeKey = "main"): ThemeInfo {
44
+ const info: ThemeInfo = {};
45
+
46
+ const context = loadContext(cwd);
47
+ if (context) Object.assign(info, context);
48
+
49
+ if (!info.storeDomain) {
50
+ info.storeDomain =
51
+ loadProjectStore(cwd, storeKey) ?? loadLegacyStore(cwd, storeKey);
52
+ }
53
+
54
+ return info;
55
+ }
56
+
57
+ function loadContext(cwd: string): Partial<ThemeInfo> | null {
58
+ const file = join(cwd, "seed.context.json");
59
+ if (!existsSync(file)) return null;
60
+
61
+ try {
62
+ const parsed: SeedContextFile = JSON.parse(readFileSync(file, "utf-8"));
63
+ const id = parsed.activeContext;
64
+ if (!id || !parsed.contexts?.[id]) return null;
65
+
66
+ const ctx = parsed.contexts[id];
67
+ return {
68
+ contextName: ctx.name,
69
+ contextStatus: ctx.status,
70
+ branch: ctx.git?.branch,
71
+ baseBranch: ctx.git?.baseBranch,
72
+ storeDomain: ctx.shopify?.storeDomain,
73
+ previewThemeName: ctx.shopify?.previewThemeName,
74
+ previewThemeId: ctx.shopify?.previewThemeId,
75
+ previewUrl: ctx.shopify?.previewUrl,
76
+ customizerUrl: ctx.shopify?.customizerUrl,
77
+ asanaTaskUrl: ctx.asana?.taskUrl,
78
+ prUrl: ctx.github?.prUrl,
79
+ };
80
+ } catch {
81
+ return null;
82
+ }
83
+ }
84
+
85
+ function loadProjectStore(cwd: string, storeKey: string): string | undefined {
86
+ const file = join(cwd, "seed.project.json");
87
+ if (!existsSync(file)) return undefined;
88
+
89
+ try {
90
+ const parsed: SeedProjectConfig = JSON.parse(readFileSync(file, "utf-8"));
91
+ return parsed.stores?.[storeKey]?.domain;
92
+ } catch {
93
+ return undefined;
94
+ }
95
+ }
96
+
97
+ function loadLegacyStore(cwd: string, storeKey: string): string | undefined {
98
+ const file = join(cwd, "seed.config.js");
99
+ if (!existsSync(file)) return undefined;
100
+
101
+ try {
102
+ // require() caches; delete first so dev-edits to seed.config.js show up.
103
+ delete require.cache[require.resolve(file)];
104
+ const legacy: SeedLegacyConfig = require(file);
105
+ return legacy.stores?.[storeKey]?.domain || legacy.store;
106
+ } catch {
107
+ return undefined;
108
+ }
109
+ }
@@ -26,7 +26,17 @@ declare module "postcss-reporter" {
26
26
  }
27
27
 
28
28
  declare module "postcss-import" {
29
- function postcssImport(): any;
29
+ interface PostcssImportOptions {
30
+ path?: string | string[];
31
+ resolve?: (
32
+ id: string,
33
+ basedir: string,
34
+ importOptions: unknown,
35
+ ) => string | string[] | Promise<string | string[]>;
36
+ filter?: (path: string) => boolean;
37
+ skipDuplicates?: boolean;
38
+ }
39
+ function postcssImport(options?: PostcssImportOptions): any;
30
40
  export default postcssImport;
31
41
  }
32
42
 
@@ -70,3 +80,11 @@ declare module "gulp-include" {
70
80
  function include(options?: IncludeOptions): NodeJS.ReadWriteStream;
71
81
  export default include;
72
82
  }
83
+
84
+ declare module "gulp-terser" {
85
+ interface TerserOptions {
86
+ [key: string]: unknown;
87
+ }
88
+ function terser(options?: TerserOptions): NodeJS.ReadWriteStream;
89
+ export default terser;
90
+ }
package/src/utils.ts CHANGED
@@ -5,6 +5,7 @@ import type { ChildProcess } from "child_process";
5
5
  import { join } from "path";
6
6
  import { readFileSync, writeFileSync, existsSync } from "fs";
7
7
  import config from "./config";
8
+ import { shopifyCommand } from "./shopify-bin";
8
9
  import { SeedConfig, ShopifyCLI, SeedProjectConfig } from "./types";
9
10
 
10
11
  /**
@@ -78,142 +79,112 @@ export function getStorePassword(
78
79
  * @namespace seed-cli.shopifyCLI
79
80
  * @memberof seed-cli
80
81
  */
82
+ // All shopify spawn calls go through `shopifyCommand` so they pick up the
83
+ // bundled `@shopify/cli` binary advertised by seed-cli via SEED_SHOPIFY_BIN.
84
+ // PATH `shopify` is the fallback for when seed-tools is invoked outside the
85
+ // seed-cli wrapper (e.g. running gulp directly).
81
86
  export const shopifyCLI: ShopifyCLI = {
82
- /**
83
- * shopify login
84
- *
85
- * @memberof seed-cli.shopifyCLI
86
- * @param {string} store - store's myshopify domain name
87
- * @returns {object} - spawnSync object or, node's <ChildProcess> object if async
88
- */
89
87
  login: (store: string) => {
90
- const args = ["switch", "--store", store];
91
- const options = {
88
+ const { command, args, shell } = shopifyCommand([
89
+ "switch",
90
+ "--store",
91
+ store,
92
+ ]);
93
+ return spawn.sync(command, args, {
92
94
  env: process.env,
93
95
  stdio: "inherit" as const,
94
- shell: true,
95
- };
96
-
97
- return spawn.sync("shopify", args, options);
96
+ shell,
97
+ });
98
98
  },
99
99
 
100
- /**
101
- * shopify theme serve
102
- *
103
- * @memberof seed-cli.shopifyCLI
104
- * @param {string} store - store's myshopify domain name
105
- * @param {object} options - node spawn options
106
- * @returns {object} - node's ChildProcess
107
- */
108
100
  serve: (store: string, options = {}) => {
109
- return spawn("shopify theme", ["dev", "--store", store, "--path", "dist"], {
101
+ const { command, args, shell } = shopifyCommand([
102
+ "theme",
103
+ "dev",
104
+ "--store",
105
+ store,
106
+ "--path",
107
+ "dist",
108
+ ]);
109
+ return spawn(command, args, {
110
110
  env: process.env,
111
111
  stdio: "inherit" as const,
112
- shell: true,
112
+ shell,
113
113
  ...options,
114
114
  });
115
115
  },
116
116
 
117
- /**
118
- * shopify theme pull
119
- *
120
- * @memberof seed-cli.shopifyCLI
121
- * @param {string} store - store's myshopify domain name
122
- * @param {string} themeId - shopify theme id to pull from
123
- * @param {string} dir - directory to pull into
124
- * @param {boolean} [nodelete = true] - run command with --no-delete flag
125
- * @returns {object} - node's ChildProcess
126
- */
127
117
  pull: (store: string, themeId?: string, dir = "./src", nodelete = true) => {
128
- let args = ["pull", "--store", store];
129
- if (themeId) args = args.concat(["--theme", themeId, "--path", dir]);
130
-
131
- if (nodelete) args.push("--nodelete");
118
+ const sub = ["theme", "pull", "--store", store];
119
+ if (themeId) sub.push("--theme", themeId, "--path", dir);
120
+ if (nodelete) sub.push("--nodelete");
132
121
 
133
- return spawn("shopify theme", args, {
122
+ const { command, args, shell } = shopifyCommand(sub);
123
+ return spawn(command, args, {
134
124
  env: process.env,
135
125
  stdio: "inherit" as const,
136
- shell: true,
126
+ shell,
137
127
  });
138
128
  },
139
129
 
140
- /**
141
- * shopify theme push
142
- *
143
- * @memberof seed-cli.shopifyCLI
144
- * @param {string} store - store's myshopify domain name
145
- * @param {string} themeId - shopify theme id to push into
146
- * @param {boolean} [nodelete = true] - run command with --no-delete flag
147
- * @returns {ChildProcess} - node's ChildProcess
148
- */
149
130
  push: (store: string, themeId?: string, nodelete = true) => {
150
- let args = ["push", "--store", store, "--path", "dist"];
151
- if (themeId) args = args.concat(["--theme", themeId]);
131
+ const sub = ["theme", "push", "--store", store, "--path", "dist"];
132
+ if (themeId) sub.push("--theme", themeId);
133
+ if (nodelete) sub.push("--nodelete");
152
134
 
153
- if (nodelete) args.push("--nodelete");
154
-
155
- return spawn("shopify theme", args, {
135
+ const { command, args, shell } = shopifyCommand(sub);
136
+ return spawn(command, args, {
156
137
  env: process.env,
157
138
  stdio: "inherit" as const,
158
- shell: true,
139
+ shell,
159
140
  });
160
141
  },
161
142
 
162
- /**
163
- * shopify theme package
164
- *
165
- * @memberof seed-cli.shopifyCLI
166
- * @returns {ChildProcess} - node's ChildProcess
167
- */
168
143
  package: () => {
169
- return spawn("shopify theme", ["package", "--path", "dist"], {
144
+ const { command, args, shell } = shopifyCommand([
145
+ "theme",
146
+ "package",
147
+ "--path",
148
+ "dist",
149
+ ]);
150
+ return spawn(command, args, {
170
151
  env: process.env,
171
152
  stdio: "inherit" as const,
172
- shell: true,
153
+ shell,
173
154
  });
174
155
  },
175
156
 
176
- /**
177
- * shopify theme list
178
- *
179
- * @memberof seed-cli.shopifyCLI
180
- * @param {string} store - store's myshopify domain name
181
- * @param {object} options - additional options (role, json, etc.)
182
- * @returns {ChildProcess} - node's ChildProcess
183
- */
184
157
  list: (store: string, options: { role?: string; json?: boolean } = {}) => {
185
- let args = ["list", "--store", store];
186
-
187
- if (options.role) args = args.concat(["--role", options.role]);
188
- if (options.json) args.push("--json");
158
+ const sub = ["theme", "list", "--store", store];
159
+ if (options.role) sub.push("--role", options.role);
160
+ if (options.json) sub.push("--json");
189
161
 
190
- return spawn("shopify theme", args, {
162
+ const { command, args, shell } = shopifyCommand(sub);
163
+ return spawn(command, args, {
191
164
  env: process.env,
192
165
  stdio: options.json ? "pipe" : ("inherit" as const),
193
- shell: true,
166
+ shell,
194
167
  });
195
168
  },
196
169
 
197
- /**
198
- * shopify theme duplicate
199
- *
200
- * @memberof seed-cli.shopifyCLI
201
- * @param {string} store - store's myshopify domain name
202
- * @param {string} themeId - theme ID to duplicate
203
- * @param {string} [name] - optional name for the duplicated theme
204
- * @param {boolean} [json] - return JSON output
205
- * @returns {ChildProcess} - node's ChildProcess
206
- */
207
170
  duplicate: (store: string, themeId: string, name?: string, json = false) => {
208
- let args = ["duplicate", "--store", store, "--theme", themeId, "--force"];
209
-
210
- if (name) args = args.concat(["--name", name]);
211
- if (json) args.push("--json");
212
-
213
- return spawn("shopify theme", args, {
171
+ const sub = [
172
+ "theme",
173
+ "duplicate",
174
+ "--store",
175
+ store,
176
+ "--theme",
177
+ themeId,
178
+ "--force",
179
+ ];
180
+ if (name) sub.push("--name", name);
181
+ if (json) sub.push("--json");
182
+
183
+ const { command, args, shell } = shopifyCommand(sub);
184
+ return spawn(command, args, {
214
185
  env: process.env,
215
186
  stdio: json ? "pipe" : ("inherit" as const),
216
- shell: true,
187
+ shell,
217
188
  });
218
189
  },
219
190
  };
package/tsconfig.json CHANGED
@@ -7,8 +7,9 @@
7
7
  "declaration": true,
8
8
  "sourceMap": true,
9
9
  "esModuleInterop": true,
10
- "strict": true
10
+ "strict": true,
11
+ "jsx": "react"
11
12
  },
12
- "include": ["./**/*.ts"],
13
+ "include": ["./**/*.ts", "./**/*.tsx"],
13
14
  "exclude": ["node_modules", "lib"]
14
15
  }