@madebyseed/seed-cli-tools 3.0.0 → 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 -88
  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 -94
  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
  /**
@@ -14,7 +15,6 @@ import { SeedConfig, ShopifyCLI, SeedProjectConfig } from "./types";
14
15
  * @returns {SeedProjectConfig | null} - project config object or null if not found
15
16
  */
16
17
  export function getProjectConfig(themeRoot: string): SeedProjectConfig | null {
17
- console.log(require(join(themeRoot, "seed.project.json")));
18
18
 
19
19
  return require(join(themeRoot, "seed.project.json"));
20
20
  }
@@ -79,142 +79,112 @@ export function getStorePassword(
79
79
  * @namespace seed-cli.shopifyCLI
80
80
  * @memberof seed-cli
81
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).
82
86
  export const shopifyCLI: ShopifyCLI = {
83
- /**
84
- * shopify login
85
- *
86
- * @memberof seed-cli.shopifyCLI
87
- * @param {string} store - store's myshopify domain name
88
- * @returns {object} - spawnSync object or, node's <ChildProcess> object if async
89
- */
90
87
  login: (store: string) => {
91
- const args = ["switch", "--store", store];
92
- const options = {
88
+ const { command, args, shell } = shopifyCommand([
89
+ "switch",
90
+ "--store",
91
+ store,
92
+ ]);
93
+ return spawn.sync(command, args, {
93
94
  env: process.env,
94
95
  stdio: "inherit" as const,
95
- shell: true,
96
- };
97
-
98
- return spawn.sync("shopify", args, options);
96
+ shell,
97
+ });
99
98
  },
100
99
 
101
- /**
102
- * shopify theme serve
103
- *
104
- * @memberof seed-cli.shopifyCLI
105
- * @param {string} store - store's myshopify domain name
106
- * @param {object} options - node spawn options
107
- * @returns {object} - node's ChildProcess
108
- */
109
100
  serve: (store: string, options = {}) => {
110
- 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, {
111
110
  env: process.env,
112
111
  stdio: "inherit" as const,
113
- shell: true,
112
+ shell,
114
113
  ...options,
115
114
  });
116
115
  },
117
116
 
118
- /**
119
- * shopify theme pull
120
- *
121
- * @memberof seed-cli.shopifyCLI
122
- * @param {string} store - store's myshopify domain name
123
- * @param {string} themeId - shopify theme id to pull from
124
- * @param {string} dir - directory to pull into
125
- * @param {boolean} [nodelete = true] - run command with --no-delete flag
126
- * @returns {object} - node's ChildProcess
127
- */
128
117
  pull: (store: string, themeId?: string, dir = "./src", nodelete = true) => {
129
- let args = ["pull", "--store", store];
130
- if (themeId) args = args.concat(["--theme", themeId, "--path", dir]);
131
-
132
- 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");
133
121
 
134
- return spawn("shopify theme", args, {
122
+ const { command, args, shell } = shopifyCommand(sub);
123
+ return spawn(command, args, {
135
124
  env: process.env,
136
125
  stdio: "inherit" as const,
137
- shell: true,
126
+ shell,
138
127
  });
139
128
  },
140
129
 
141
- /**
142
- * shopify theme push
143
- *
144
- * @memberof seed-cli.shopifyCLI
145
- * @param {string} store - store's myshopify domain name
146
- * @param {string} themeId - shopify theme id to push into
147
- * @param {boolean} [nodelete = true] - run command with --no-delete flag
148
- * @returns {ChildProcess} - node's ChildProcess
149
- */
150
130
  push: (store: string, themeId?: string, nodelete = true) => {
151
- let args = ["push", "--store", store, "--path", "dist"];
152
- 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");
153
134
 
154
- if (nodelete) args.push("--nodelete");
155
-
156
- return spawn("shopify theme", args, {
135
+ const { command, args, shell } = shopifyCommand(sub);
136
+ return spawn(command, args, {
157
137
  env: process.env,
158
138
  stdio: "inherit" as const,
159
- shell: true,
139
+ shell,
160
140
  });
161
141
  },
162
142
 
163
- /**
164
- * shopify theme package
165
- *
166
- * @memberof seed-cli.shopifyCLI
167
- * @returns {ChildProcess} - node's ChildProcess
168
- */
169
143
  package: () => {
170
- 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, {
171
151
  env: process.env,
172
152
  stdio: "inherit" as const,
173
- shell: true,
153
+ shell,
174
154
  });
175
155
  },
176
156
 
177
- /**
178
- * shopify theme list
179
- *
180
- * @memberof seed-cli.shopifyCLI
181
- * @param {string} store - store's myshopify domain name
182
- * @param {object} options - additional options (role, json, etc.)
183
- * @returns {ChildProcess} - node's ChildProcess
184
- */
185
157
  list: (store: string, options: { role?: string; json?: boolean } = {}) => {
186
- let args = ["list", "--store", store];
187
-
188
- if (options.role) args = args.concat(["--role", options.role]);
189
- 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");
190
161
 
191
- return spawn("shopify theme", args, {
162
+ const { command, args, shell } = shopifyCommand(sub);
163
+ return spawn(command, args, {
192
164
  env: process.env,
193
165
  stdio: options.json ? "pipe" : ("inherit" as const),
194
- shell: true,
166
+ shell,
195
167
  });
196
168
  },
197
169
 
198
- /**
199
- * shopify theme duplicate
200
- *
201
- * @memberof seed-cli.shopifyCLI
202
- * @param {string} store - store's myshopify domain name
203
- * @param {string} themeId - theme ID to duplicate
204
- * @param {string} [name] - optional name for the duplicated theme
205
- * @param {boolean} [json] - return JSON output
206
- * @returns {ChildProcess} - node's ChildProcess
207
- */
208
170
  duplicate: (store: string, themeId: string, name?: string, json = false) => {
209
- let args = ["duplicate", "--store", store, "--theme", themeId, "--force"];
210
-
211
- if (name) args = args.concat(["--name", name]);
212
- if (json) args.push("--json");
213
-
214
- 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, {
215
185
  env: process.env,
216
186
  stdio: json ? "pipe" : ("inherit" as const),
217
- shell: true,
187
+ shell,
218
188
  });
219
189
  },
220
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
  }