@madebyseed/seed-cli-tools 2.3.2 → 3.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/lib/commands/build.d.ts +2 -0
- package/lib/commands/build.js +30 -29
- package/lib/commands/build.js.map +1 -0
- package/lib/commands/deploy.d.ts +2 -0
- package/lib/commands/deploy.js +47 -30
- package/lib/commands/deploy.js.map +1 -0
- package/lib/commands/pull.d.ts +2 -0
- package/lib/commands/pull.js +39 -29
- package/lib/commands/pull.js.map +1 -0
- package/lib/commands/watch.d.ts +2 -0
- package/lib/commands/watch.js +44 -40
- package/lib/commands/watch.js.map +1 -0
- package/lib/commands/zip.d.ts +2 -0
- package/lib/commands/zip.js +23 -25
- package/lib/commands/zip.js.map +1 -0
- package/lib/config.d.ts +3 -0
- package/lib/config.js +21 -28
- package/lib/config.js.map +1 -0
- package/lib/gulpfile.d.ts +1 -0
- package/lib/gulpfile.js +26 -33
- package/lib/gulpfile.js.map +1 -0
- package/lib/tasks/build-assets.d.ts +1 -0
- package/lib/tasks/build-assets.js +80 -72
- package/lib/tasks/build-assets.js.map +1 -0
- package/lib/tasks/build-css.d.ts +1 -0
- package/lib/tasks/build-css.js +88 -82
- package/lib/tasks/build-css.js.map +1 -0
- package/lib/tasks/build-js.d.ts +1 -0
- package/lib/tasks/build-js.js +78 -82
- package/lib/tasks/build-js.js.map +1 -0
- package/lib/tasks/build-svg.d.ts +1 -0
- package/lib/tasks/build-svg.js +51 -54
- package/lib/tasks/build-svg.js.map +1 -0
- package/lib/tasks/build-utils.d.ts +1 -0
- package/lib/tasks/build-utils.js +68 -49
- package/lib/tasks/build-utils.js.map +1 -0
- package/lib/tasks/includes/config.d.ts +71 -0
- package/lib/tasks/includes/config.js +118 -163
- package/lib/tasks/includes/config.js.map +1 -0
- package/lib/tasks/includes/messages.d.ts +19 -0
- package/lib/tasks/includes/messages.js +80 -72
- package/lib/tasks/includes/messages.js.map +1 -0
- package/lib/tasks/includes/utilities.d.ts +71 -0
- package/lib/tasks/includes/utilities.js +127 -141
- package/lib/tasks/includes/utilities.js.map +1 -0
- package/lib/tasks/shopify-cli.d.ts +1 -0
- package/lib/tasks/shopify-cli.js +107 -93
- package/lib/tasks/shopify-cli.js.map +1 -0
- package/lib/tasks/watchers.d.ts +1 -0
- package/lib/tasks/watchers.js +29 -29
- package/lib/tasks/watchers.js.map +1 -0
- package/lib/types.d.ts +53 -0
- package/lib/types.js +3 -0
- package/lib/types.js.map +1 -0
- package/lib/utils.d.ts +102 -0
- package/lib/utils.js +310 -189
- package/lib/utils.js.map +1 -0
- package/package.json +36 -16
- package/src/commands/build.ts +39 -0
- package/src/commands/deploy.ts +79 -0
- package/src/commands/pull.ts +58 -0
- package/src/commands/watch.ts +72 -0
- package/src/commands/zip.ts +28 -0
- package/src/config.ts +28 -0
- package/src/gulpfile.ts +134 -0
- package/src/tasks/build-assets.ts +135 -0
- package/src/tasks/build-css.ts +129 -0
- package/src/tasks/build-js.ts +108 -0
- package/src/tasks/build-svg.ts +92 -0
- package/src/tasks/build-utils.ts +137 -0
- package/src/tasks/includes/config.ts +224 -0
- package/src/tasks/includes/messages.ts +157 -0
- package/src/tasks/includes/utilities.ts +170 -0
- package/src/tasks/shopify-cli.ts +199 -0
- package/src/tasks/watchers.ts +50 -0
- package/src/types/declarations.d.ts +72 -0
- package/src/types.ts +84 -0
- package/src/utils.ts +444 -0
- package/tsconfig.json +14 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/.babelrc +0 -3
- package/.eslintrc +0 -8
- /package/{src → src-legacy}/commands/build.js +0 -0
- /package/{src → src-legacy}/commands/deploy.js +0 -0
- /package/{src → src-legacy}/commands/pull.js +0 -0
- /package/{src → src-legacy}/commands/watch.js +0 -0
- /package/{src → src-legacy}/commands/zip.js +0 -0
- /package/{src → src-legacy}/config.js +0 -0
- /package/{src → src-legacy}/gulpfile.js +0 -0
- /package/{src → src-legacy}/tasks/build-assets.js +0 -0
- /package/{src → src-legacy}/tasks/build-css.js +0 -0
- /package/{src → src-legacy}/tasks/build-js.js +0 -0
- /package/{src → src-legacy}/tasks/build-svg.js +0 -0
- /package/{src → src-legacy}/tasks/build-utils.js +0 -0
- /package/{src → src-legacy}/tasks/includes/config.js +0 -0
- /package/{src → src-legacy}/tasks/includes/messages.js +0 -0
- /package/{src → src-legacy}/tasks/includes/utilities.js +0 -0
- /package/{src → src-legacy}/tasks/shopify-cli.js +0 -0
- /package/{src → src-legacy}/tasks/watchers.js +0 -0
- /package/{src → src-legacy}/utils.js +0 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { SpawnSyncReturns } from "child_process";
|
|
2
|
+
import type { ChildProcess } from "child_process";
|
|
3
|
+
|
|
4
|
+
export interface Config {
|
|
5
|
+
gulpFile: string;
|
|
6
|
+
gulp: string;
|
|
7
|
+
themeRoot: string;
|
|
8
|
+
seedConfig: string;
|
|
9
|
+
seedConfigDelimiter: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ShopifyCLI {
|
|
13
|
+
login: (store: string) => SpawnSyncReturns<Buffer>;
|
|
14
|
+
serve: (store: string, options?: Record<string, unknown>) => ChildProcess;
|
|
15
|
+
pull: (
|
|
16
|
+
store: string,
|
|
17
|
+
themeId?: string | undefined,
|
|
18
|
+
dir?: string,
|
|
19
|
+
nodelete?: boolean,
|
|
20
|
+
) => ChildProcess;
|
|
21
|
+
push: (
|
|
22
|
+
store: string,
|
|
23
|
+
themeId?: string | undefined,
|
|
24
|
+
nodelete?: boolean,
|
|
25
|
+
) => ChildProcess;
|
|
26
|
+
package: () => ChildProcess;
|
|
27
|
+
list: (
|
|
28
|
+
store: string,
|
|
29
|
+
options?: { role?: string; json?: boolean },
|
|
30
|
+
) => ChildProcess;
|
|
31
|
+
duplicate: (
|
|
32
|
+
store: string,
|
|
33
|
+
themeId: string,
|
|
34
|
+
name?: string,
|
|
35
|
+
json?: boolean,
|
|
36
|
+
) => ChildProcess;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface SeedConfig {
|
|
40
|
+
store?: string;
|
|
41
|
+
stores?: {
|
|
42
|
+
[key: string]: {
|
|
43
|
+
domain: string;
|
|
44
|
+
themes: {
|
|
45
|
+
[key: string]: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
themes?: {
|
|
50
|
+
[key: string]: string;
|
|
51
|
+
};
|
|
52
|
+
__developmentThemeId?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface SeedProjectConfig {
|
|
56
|
+
// Store Configuration
|
|
57
|
+
stores: {
|
|
58
|
+
[key: string]: {
|
|
59
|
+
domain: string; // mystore.myshopify.com
|
|
60
|
+
password?: string; // store password if needed
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
pull: {
|
|
65
|
+
ignoreFiles: string[];
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Build Configuration
|
|
69
|
+
build: {
|
|
70
|
+
js: {
|
|
71
|
+
type: "legacy" | "bundle";
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Re-export build config types
|
|
77
|
+
export type {
|
|
78
|
+
BuildConfig,
|
|
79
|
+
PathConfig,
|
|
80
|
+
TmpPathConfig,
|
|
81
|
+
DistPathConfig,
|
|
82
|
+
RootsConfig,
|
|
83
|
+
PluginsConfig,
|
|
84
|
+
} from "./tasks/includes/config";
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { red, yellow } from "chalk";
|
|
2
|
+
import figures from "figures";
|
|
3
|
+
import spawn from "cross-spawn";
|
|
4
|
+
import type { ChildProcess } from "child_process";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
7
|
+
import config from "./config";
|
|
8
|
+
import { SeedConfig, ShopifyCLI, SeedProjectConfig } from "./types";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get seed.project.json from project root dir
|
|
12
|
+
*
|
|
13
|
+
* @param {string} themeRoot - the path to theme root dir
|
|
14
|
+
* @returns {SeedProjectConfig | null} - project config object or null if not found
|
|
15
|
+
*/
|
|
16
|
+
export function getProjectConfig(themeRoot: string): SeedProjectConfig | null {
|
|
17
|
+
console.log(require(join(themeRoot, "seed.project.json")));
|
|
18
|
+
|
|
19
|
+
return require(join(themeRoot, "seed.project.json"));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get seed.config.js from project root dir
|
|
24
|
+
*
|
|
25
|
+
* @param {string} themeRoot - the path to theme root dir
|
|
26
|
+
* @returns {SeedConfig} - seed config object
|
|
27
|
+
*/
|
|
28
|
+
export function getSeedConfig(themeRoot: string): SeedConfig {
|
|
29
|
+
return require(join(themeRoot, "seed.config.js"));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get store name from seed.project.json or seed.config.js
|
|
34
|
+
*
|
|
35
|
+
* @param {string} themeRoot - the path to theme root dir
|
|
36
|
+
* @param {string} [store] - optional store name, defaults to "main"
|
|
37
|
+
* @returns {string | undefined} - store domain or undefined if not found
|
|
38
|
+
*/
|
|
39
|
+
export function getStoreName(
|
|
40
|
+
themeRoot: string,
|
|
41
|
+
store?: string,
|
|
42
|
+
): string | undefined {
|
|
43
|
+
// Default to "main" if no store specified
|
|
44
|
+
const storeKey = store || "main";
|
|
45
|
+
|
|
46
|
+
// Try to get from project config first
|
|
47
|
+
const projectConfig = getProjectConfig(themeRoot);
|
|
48
|
+
if (projectConfig?.stores?.[storeKey]) {
|
|
49
|
+
return projectConfig.stores[storeKey].domain;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Fallback to legacy config
|
|
53
|
+
const legacyConfig = getSeedConfig(themeRoot);
|
|
54
|
+
return store && legacyConfig.stores?.[store]
|
|
55
|
+
? legacyConfig.stores[store].domain
|
|
56
|
+
: legacyConfig.store;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get store password from seed.project.json
|
|
61
|
+
*
|
|
62
|
+
* @param {string} themeRoot - the path to theme root dir
|
|
63
|
+
* @param {string} [store] - optional store name, defaults to "main"
|
|
64
|
+
* @returns {string | undefined} - store password or undefined if not found
|
|
65
|
+
*/
|
|
66
|
+
export function getStorePassword(
|
|
67
|
+
themeRoot: string,
|
|
68
|
+
store?: string,
|
|
69
|
+
): string | undefined {
|
|
70
|
+
const storeKey = store || "main";
|
|
71
|
+
const projectConfig = getProjectConfig(themeRoot);
|
|
72
|
+
return projectConfig?.stores?.[storeKey]?.password;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Wrappers for Shopify CLI commands
|
|
77
|
+
*
|
|
78
|
+
* @summary a set of utility functions used to wrap shopify's CLI
|
|
79
|
+
* @namespace seed-cli.shopifyCLI
|
|
80
|
+
* @memberof seed-cli
|
|
81
|
+
*/
|
|
82
|
+
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
|
+
login: (store: string) => {
|
|
91
|
+
const args = ["switch", "--store", store];
|
|
92
|
+
const options = {
|
|
93
|
+
env: process.env,
|
|
94
|
+
stdio: "inherit" as const,
|
|
95
|
+
shell: true,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
return spawn.sync("shopify", args, options);
|
|
99
|
+
},
|
|
100
|
+
|
|
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
|
+
serve: (store: string, options = {}) => {
|
|
110
|
+
return spawn("shopify theme", ["dev", "--store", store, "--path", "dist"], {
|
|
111
|
+
env: process.env,
|
|
112
|
+
stdio: "inherit" as const,
|
|
113
|
+
shell: true,
|
|
114
|
+
...options,
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
|
|
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
|
+
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");
|
|
133
|
+
|
|
134
|
+
return spawn("shopify theme", args, {
|
|
135
|
+
env: process.env,
|
|
136
|
+
stdio: "inherit" as const,
|
|
137
|
+
shell: true,
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
|
|
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
|
+
push: (store: string, themeId?: string, nodelete = true) => {
|
|
151
|
+
let args = ["push", "--store", store, "--path", "dist"];
|
|
152
|
+
if (themeId) args = args.concat(["--theme", themeId]);
|
|
153
|
+
|
|
154
|
+
if (nodelete) args.push("--nodelete");
|
|
155
|
+
|
|
156
|
+
return spawn("shopify theme", args, {
|
|
157
|
+
env: process.env,
|
|
158
|
+
stdio: "inherit" as const,
|
|
159
|
+
shell: true,
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* shopify theme package
|
|
165
|
+
*
|
|
166
|
+
* @memberof seed-cli.shopifyCLI
|
|
167
|
+
* @returns {ChildProcess} - node's ChildProcess
|
|
168
|
+
*/
|
|
169
|
+
package: () => {
|
|
170
|
+
return spawn("shopify theme", ["package", "--path", "dist"], {
|
|
171
|
+
env: process.env,
|
|
172
|
+
stdio: "inherit" as const,
|
|
173
|
+
shell: true,
|
|
174
|
+
});
|
|
175
|
+
},
|
|
176
|
+
|
|
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
|
+
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");
|
|
190
|
+
|
|
191
|
+
return spawn("shopify theme", args, {
|
|
192
|
+
env: process.env,
|
|
193
|
+
stdio: options.json ? "pipe" : ("inherit" as const),
|
|
194
|
+
shell: true,
|
|
195
|
+
});
|
|
196
|
+
},
|
|
197
|
+
|
|
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
|
+
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, {
|
|
215
|
+
env: process.env,
|
|
216
|
+
stdio: json ? "pipe" : ("inherit" as const),
|
|
217
|
+
shell: true,
|
|
218
|
+
});
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Get the live theme ID from a store
|
|
224
|
+
*/
|
|
225
|
+
export async function getLiveThemeId(store: string): Promise<string> {
|
|
226
|
+
return new Promise((resolve, reject) => {
|
|
227
|
+
const listProcess = shopifyCLI.list(store, { role: "live", json: true });
|
|
228
|
+
let output = "";
|
|
229
|
+
let errorOutput = "";
|
|
230
|
+
|
|
231
|
+
listProcess.stdout?.on("data", (data: Buffer) => {
|
|
232
|
+
output += data.toString();
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
listProcess.stderr?.on("data", (data: Buffer) => {
|
|
236
|
+
errorOutput += data.toString();
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
listProcess.on("close", (code: number) => {
|
|
240
|
+
if (code !== 0) {
|
|
241
|
+
reject(new Error(`Failed to get live theme: ${errorOutput}`));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
const response = JSON.parse(output);
|
|
247
|
+
const liveTheme = response.themes?.find(
|
|
248
|
+
(theme: any) => theme.role === "live",
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
if (!liveTheme) {
|
|
252
|
+
reject(new Error("No live theme found"));
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
resolve(liveTheme.id.toString());
|
|
257
|
+
} catch (error) {
|
|
258
|
+
reject(new Error(`Failed to parse theme list response: ${error}`));
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Duplicate a theme and return the new theme ID
|
|
266
|
+
*/
|
|
267
|
+
export async function duplicateTheme(
|
|
268
|
+
store: string,
|
|
269
|
+
sourceThemeId: string,
|
|
270
|
+
name?: string,
|
|
271
|
+
): Promise<string> {
|
|
272
|
+
return new Promise((resolve, reject) => {
|
|
273
|
+
const duplicateProcess = shopifyCLI.duplicate(
|
|
274
|
+
store,
|
|
275
|
+
sourceThemeId,
|
|
276
|
+
name,
|
|
277
|
+
true,
|
|
278
|
+
);
|
|
279
|
+
let output = "";
|
|
280
|
+
let errorOutput = "";
|
|
281
|
+
|
|
282
|
+
duplicateProcess.stdout?.on("data", (data: Buffer) => {
|
|
283
|
+
output += data.toString();
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
duplicateProcess.stderr?.on("data", (data: Buffer) => {
|
|
287
|
+
errorOutput += data.toString();
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
duplicateProcess.on("close", (code: number) => {
|
|
291
|
+
if (code !== 0) {
|
|
292
|
+
reject(new Error(`Failed to duplicate theme: ${errorOutput}`));
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
try {
|
|
297
|
+
const response = JSON.parse(output);
|
|
298
|
+
resolve(response.theme.id.toString());
|
|
299
|
+
} catch (error) {
|
|
300
|
+
reject(new Error(`Failed to parse duplicate response: ${error}`));
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Duplicate a theme from live theme
|
|
308
|
+
*/
|
|
309
|
+
export async function duplicateFromLive(
|
|
310
|
+
store: string,
|
|
311
|
+
name?: string,
|
|
312
|
+
): Promise<string> {
|
|
313
|
+
const liveThemeId = await getLiveThemeId(store);
|
|
314
|
+
const newThemeId = await duplicateTheme(store, liveThemeId, name);
|
|
315
|
+
return newThemeId;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Get theme ID from seed.config.js
|
|
320
|
+
*
|
|
321
|
+
* @param {string} themeRoot - the path to theme root dir
|
|
322
|
+
* @param {string} environment - theme name/environment
|
|
323
|
+
* @param {string} [store] - optional store name
|
|
324
|
+
* @returns {string} themeID
|
|
325
|
+
*/
|
|
326
|
+
export function getThemeID(
|
|
327
|
+
themeRoot: string,
|
|
328
|
+
environment: string,
|
|
329
|
+
store?: string,
|
|
330
|
+
): string | undefined {
|
|
331
|
+
const config = getSeedConfig(themeRoot);
|
|
332
|
+
return store && config.stores?.[store]
|
|
333
|
+
? config.stores[store].themes[environment]
|
|
334
|
+
: config.themes?.[environment];
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Get dev theme ID from seed.config.js
|
|
339
|
+
*
|
|
340
|
+
* @param {string} themeRoot - the path to theme root dir
|
|
341
|
+
* @returns {string} - development store theme ID
|
|
342
|
+
*/
|
|
343
|
+
export function getDevThemeID(themeRoot: string): string | undefined {
|
|
344
|
+
return getSeedConfig(themeRoot).__developmentThemeId;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Given a string, finds the first themeID and returns it, if no themeID found
|
|
349
|
+
* returns false.
|
|
350
|
+
*
|
|
351
|
+
* @param {string} string - string to extract theme id from
|
|
352
|
+
* @return {string|boolean} - themeID or false if not found
|
|
353
|
+
*/
|
|
354
|
+
export function extractThemeId(string: string): string | false {
|
|
355
|
+
const regex = /\d{12}/;
|
|
356
|
+
const match = string.match(regex);
|
|
357
|
+
return match && match.length ? match[0] : false;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Logs out to terminal the output of a piped child process
|
|
362
|
+
*
|
|
363
|
+
* @param {child_process} serveProcess shopify cli serve spawned child process
|
|
364
|
+
*/
|
|
365
|
+
export function logChildProcessOutput(process: ChildProcess): void {
|
|
366
|
+
process.stdout?.on("data", (data: Buffer | string) => {
|
|
367
|
+
console.log(data.toString());
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Writes the development theme ID as a key to seed config file
|
|
373
|
+
*
|
|
374
|
+
* @param {string} themeID - development theme ID
|
|
375
|
+
*/
|
|
376
|
+
export function setDevThemeID(themeID: string): void {
|
|
377
|
+
const data = readFileSync(config.seedConfig, { encoding: "utf8" }).split(
|
|
378
|
+
config.seedConfigDelimiter,
|
|
379
|
+
);
|
|
380
|
+
data[1] = `\n __developmentThemeId: '${themeID}'` + "\n};";
|
|
381
|
+
writeFileSync(config.seedConfig, data.join(config.seedConfigDelimiter));
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Logs into seed config shopify store while logging useful messages
|
|
386
|
+
* and handling errors.
|
|
387
|
+
*
|
|
388
|
+
* @param {string} [store] - optional store name, defaults to "main"
|
|
389
|
+
* @returns {boolean} whether login was successful or not
|
|
390
|
+
*/
|
|
391
|
+
export function login(store?: string): boolean {
|
|
392
|
+
const domain = getStoreName(config.themeRoot, store);
|
|
393
|
+
|
|
394
|
+
if (!domain) {
|
|
395
|
+
storeErrorMessage(store);
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
console.log(`Logging into ${yellow(domain)} with Shopify CLI...`);
|
|
400
|
+
const loginProcess = shopifyCLI.login(domain);
|
|
401
|
+
if (loginProcess.error) {
|
|
402
|
+
console.log("");
|
|
403
|
+
console.log(
|
|
404
|
+
red(
|
|
405
|
+
` ${figures.cross} Failed logging into ${domain}, are you sure you're using the correct account?`,
|
|
406
|
+
),
|
|
407
|
+
);
|
|
408
|
+
console.log("");
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return true;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Outputs error message if there's no store field in seed config
|
|
417
|
+
*
|
|
418
|
+
* @param {string} [store] - optional store name that was not found
|
|
419
|
+
*/
|
|
420
|
+
export function storeErrorMessage(store?: string): void {
|
|
421
|
+
if (store) {
|
|
422
|
+
console.log("");
|
|
423
|
+
console.log(
|
|
424
|
+
red(
|
|
425
|
+
` The store ${store} does not exist in seed.project.json or seed.config.js`,
|
|
426
|
+
),
|
|
427
|
+
);
|
|
428
|
+
console.log(
|
|
429
|
+
" Check to see if you spelled the store correctly in your config files and when running the command.",
|
|
430
|
+
);
|
|
431
|
+
console.log("");
|
|
432
|
+
} else {
|
|
433
|
+
console.log("");
|
|
434
|
+
console.log(
|
|
435
|
+
red(
|
|
436
|
+
` ${figures.cross} No 'main' store found in seed.project.json or seed.config.js`,
|
|
437
|
+
),
|
|
438
|
+
);
|
|
439
|
+
console.log(
|
|
440
|
+
" Add a 'main' store to your seed.project.json or specify which store to use with --store <store>",
|
|
441
|
+
);
|
|
442
|
+
console.log("");
|
|
443
|
+
}
|
|
444
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./lib",
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"composite": true,
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"strict": true
|
|
11
|
+
},
|
|
12
|
+
"include": ["./**/*.ts"],
|
|
13
|
+
"exclude": ["node_modules", "lib"]
|
|
14
|
+
}
|