@bigcommerce/create-catalyst 0.11.0 → 0.13.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/index.cjs +3 -3
- package/dist/index.js +285 -417
- package/dist/index.js.map +1 -1
- package/package.json +13 -15
package/dist/index.js
CHANGED
|
@@ -53,12 +53,12 @@ var __async = (__this, __arguments, generator) => {
|
|
|
53
53
|
|
|
54
54
|
// src/index.ts
|
|
55
55
|
import { program } from "@commander-js/extra-typings";
|
|
56
|
-
import
|
|
56
|
+
import chalk7 from "chalk";
|
|
57
57
|
|
|
58
58
|
// package.json
|
|
59
59
|
var package_default = {
|
|
60
60
|
name: "@bigcommerce/create-catalyst",
|
|
61
|
-
version: "0.
|
|
61
|
+
version: "0.13.0",
|
|
62
62
|
type: "module",
|
|
63
63
|
bin: "bin/index.cjs",
|
|
64
64
|
files: [
|
|
@@ -77,209 +77,48 @@ var package_default = {
|
|
|
77
77
|
},
|
|
78
78
|
dependencies: {
|
|
79
79
|
"@commander-js/extra-typings": "^12.1.0",
|
|
80
|
-
"@inquirer/prompts": "^
|
|
80
|
+
"@inquirer/prompts": "^7.0.0",
|
|
81
81
|
chalk: "^5.3.0",
|
|
82
82
|
commander: "^12.1.0",
|
|
83
83
|
dotenv: "^16.4.5",
|
|
84
84
|
"fs-extra": "^11.2.0",
|
|
85
85
|
giget: "^1.2.3",
|
|
86
86
|
"lodash.kebabcase": "^4.1.1",
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
ora: "^8.0.1",
|
|
87
|
+
nypm: "^0.3.12",
|
|
88
|
+
ora: "^8.1.0",
|
|
90
89
|
semver: "^7.6.3",
|
|
91
90
|
zod: "^3.23.8",
|
|
92
|
-
"zod-validation-error": "^3.
|
|
91
|
+
"zod-validation-error": "^3.4.0"
|
|
93
92
|
},
|
|
94
93
|
devDependencies: {
|
|
95
|
-
"@bigcommerce/eslint-config": "^2.9.
|
|
94
|
+
"@bigcommerce/eslint-config": "^2.9.1",
|
|
96
95
|
"@bigcommerce/eslint-config-catalyst": "workspace:^",
|
|
97
|
-
"@swc/core": "^1.7.
|
|
96
|
+
"@swc/core": "^1.7.26",
|
|
98
97
|
"@swc/jest": "^0.2.36",
|
|
99
98
|
"@types/fs-extra": "^11.0.4",
|
|
100
|
-
"@types/jest": "^29.5.
|
|
99
|
+
"@types/jest": "^29.5.13",
|
|
101
100
|
"@types/lodash.kebabcase": "^4.1.9",
|
|
102
|
-
"@types/
|
|
103
|
-
"@types/node": "^20.14.15",
|
|
101
|
+
"@types/node": "^20.16.10",
|
|
104
102
|
"@types/prompts": "^2.4.9",
|
|
105
103
|
"@types/semver": "^7.5.8",
|
|
106
|
-
eslint: "^8.57.
|
|
104
|
+
eslint: "^8.57.1",
|
|
107
105
|
jest: "^29.7.0",
|
|
108
|
-
msw: "^2.
|
|
106
|
+
msw: "^2.4.9",
|
|
109
107
|
prettier: "^3.3.3",
|
|
110
|
-
tsup: "^8.
|
|
111
|
-
typescript: "^5.
|
|
108
|
+
tsup: "^8.3.0",
|
|
109
|
+
typescript: "^5.6.2"
|
|
112
110
|
}
|
|
113
111
|
};
|
|
114
112
|
|
|
115
113
|
// src/commands/create.ts
|
|
116
|
-
import { Command
|
|
114
|
+
import { Command, Option } from "@commander-js/extra-typings";
|
|
117
115
|
import { input, select as select2 } from "@inquirer/prompts";
|
|
118
|
-
import
|
|
119
|
-
import {
|
|
116
|
+
import chalk5 from "chalk";
|
|
117
|
+
import { execSync as execSync4 } from "child_process";
|
|
120
118
|
import { pathExistsSync } from "fs-extra/esm";
|
|
121
|
-
import kebabCase2 from "lodash.kebabcase";
|
|
122
|
-
import { join as join4 } from "path";
|
|
123
|
-
import { promisify as promisify3 } from "util";
|
|
124
|
-
import { z as z6 } from "zod";
|
|
125
|
-
|
|
126
|
-
// src/utils/apply-integration.ts
|
|
127
|
-
import { exec as execCallback } from "child_process";
|
|
128
|
-
import { readJsonSync } from "fs-extra/esm";
|
|
129
|
-
import { downloadTemplate } from "giget";
|
|
130
|
-
import { addDependency, addDevDependency } from "nypm";
|
|
131
|
-
import { join } from "path";
|
|
132
|
-
import { promisify as promisify2 } from "util";
|
|
133
|
-
|
|
134
|
-
// src/commands/integration.ts
|
|
135
|
-
import { Command } from "@commander-js/extra-typings";
|
|
136
|
-
import { exec as execCb } from "child_process";
|
|
137
|
-
import { parse } from "dotenv";
|
|
138
|
-
import { outputFileSync, writeJsonSync } from "fs-extra/esm";
|
|
139
119
|
import kebabCase from "lodash.kebabcase";
|
|
140
|
-
import {
|
|
141
|
-
import {
|
|
142
|
-
import { z } from "zod";
|
|
143
|
-
var exec = promisify(execCb);
|
|
144
|
-
var ManifestSchema = z.object({
|
|
145
|
-
name: z.string(),
|
|
146
|
-
dependencies: z.object({ add: z.array(z.string()) }),
|
|
147
|
-
devDependencies: z.object({ add: z.array(z.string()) }),
|
|
148
|
-
environmentVariables: z.array(z.string())
|
|
149
|
-
});
|
|
150
|
-
var integration = new Command("integration").argument("<integration-name>", "Formatted name of the integration").option("--commit-hash <hash>", "Override integration source branch with a specific commit hash").action((integrationNameRaw, options) => __async(void 0, null, function* () {
|
|
151
|
-
const integrationName = z.string().transform(kebabCase).parse(integrationNameRaw);
|
|
152
|
-
const manifest = {
|
|
153
|
-
name: integrationName,
|
|
154
|
-
dependencies: { add: [] },
|
|
155
|
-
devDependencies: { add: [] },
|
|
156
|
-
environmentVariables: []
|
|
157
|
-
};
|
|
158
|
-
yield exec("git fetch --tags");
|
|
159
|
-
const { stdout: headRefStdOut } = yield exec("git rev-parse --abbrev-ref HEAD");
|
|
160
|
-
let [sourceRef] = headRefStdOut.split("\n");
|
|
161
|
-
if (options.commitHash) {
|
|
162
|
-
sourceRef = options.commitHash;
|
|
163
|
-
}
|
|
164
|
-
const { stdout: catalystTags } = yield exec("git tag --list @bigcommerce/catalyst-core@\\*");
|
|
165
|
-
const [latestCoreTag] = catalystTags.split("\n").filter(Boolean).sort((a, b) => {
|
|
166
|
-
const versionA = coerce(a.replace("@bigcommerce/catalyst-core@", ""));
|
|
167
|
-
const versionB = coerce(b.replace("@bigcommerce/catalyst-core@", ""));
|
|
168
|
-
if (versionA && versionB) {
|
|
169
|
-
return compare(versionA, versionB);
|
|
170
|
-
}
|
|
171
|
-
return 0;
|
|
172
|
-
}).reverse();
|
|
173
|
-
const PackageDependenciesSchema = z.object({
|
|
174
|
-
dependencies: z.object({}).passthrough(),
|
|
175
|
-
devDependencies: z.object({}).passthrough()
|
|
176
|
-
});
|
|
177
|
-
const getPackageDeps = (ref) => __async(void 0, null, function* () {
|
|
178
|
-
const { stdout } = yield exec(`git show ${ref}:core/package.json`);
|
|
179
|
-
return PackageDependenciesSchema.parse(JSON.parse(stdout));
|
|
180
|
-
});
|
|
181
|
-
const integrationJson = yield getPackageDeps(sourceRef);
|
|
182
|
-
const latestCoreTagJson = yield getPackageDeps(latestCoreTag);
|
|
183
|
-
const diffObjectKeys = (a, b) => {
|
|
184
|
-
return Object.keys(a).filter((key) => !Object.keys(b).includes(key));
|
|
185
|
-
};
|
|
186
|
-
manifest.dependencies.add = diffObjectKeys(
|
|
187
|
-
integrationJson.dependencies,
|
|
188
|
-
latestCoreTagJson.dependencies
|
|
189
|
-
);
|
|
190
|
-
manifest.devDependencies.add = diffObjectKeys(
|
|
191
|
-
integrationJson.devDependencies,
|
|
192
|
-
latestCoreTagJson.devDependencies
|
|
193
|
-
);
|
|
194
|
-
const { stdout: latestCoreEnv } = yield exec(`git show ${latestCoreTag}:core/.env.example`);
|
|
195
|
-
const { stdout: integrationEnv } = yield exec(`git show ${sourceRef}:core/.env.example`);
|
|
196
|
-
manifest.environmentVariables = diffObjectKeys(parse(integrationEnv), parse(latestCoreEnv));
|
|
197
|
-
const { stdout: integrationDiff } = yield exec(
|
|
198
|
-
`git diff ${latestCoreTag}...${sourceRef} -- ':(exclude)core/package.json' ':(exclude)pnpm-lock.yaml'`
|
|
199
|
-
);
|
|
200
|
-
outputFileSync(`integrations/${integrationName}/integration.patch`, integrationDiff);
|
|
201
|
-
writeJsonSync(`integrations/${integrationName}/manifest.json`, manifest, {
|
|
202
|
-
spaces: 2
|
|
203
|
-
});
|
|
204
|
-
console.log("Integration created successfully.");
|
|
205
|
-
}));
|
|
206
|
-
|
|
207
|
-
// src/utils/spinner.ts
|
|
208
|
-
import { oraPromise } from "ora";
|
|
209
|
-
var spinner = (action, oraOpts) => __async(void 0, null, function* () {
|
|
210
|
-
return oraPromise(action, __spreadValues({
|
|
211
|
-
spinner: "triangle"
|
|
212
|
-
}, oraOpts)).catch(() => process.exit(1));
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
// src/utils/apply-integration.ts
|
|
216
|
-
var exec2 = promisify2(execCallback);
|
|
217
|
-
function applyIntegration(_0, _1) {
|
|
218
|
-
return __async(this, arguments, function* (integration2, { projectDir, packageManager }) {
|
|
219
|
-
if (!integration2) {
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
const integrationDir = join(projectDir, "integrations", integration2);
|
|
223
|
-
yield spinner(
|
|
224
|
-
downloadTemplate(`github:bigcommerce/catalyst/integrations/${integration2}#main`, {
|
|
225
|
-
dir: integrationDir,
|
|
226
|
-
offline: false
|
|
227
|
-
}),
|
|
228
|
-
{
|
|
229
|
-
text: `Cloning ${integration2} integration...`,
|
|
230
|
-
successText: `${integration2} integration cloned successfully`,
|
|
231
|
-
failText: (err) => `Failed to clone ${integration2} integration: ${err.message}`
|
|
232
|
-
}
|
|
233
|
-
);
|
|
234
|
-
try {
|
|
235
|
-
readJsonSync(join(integrationDir, "manifest.json"));
|
|
236
|
-
} catch (err) {
|
|
237
|
-
console.error(
|
|
238
|
-
`
|
|
239
|
-
No manifest.json found in the ${integration2} integration folder. Please check that the integration exists in the Catalyst monorepo: https://github.com/bigcommerce/catalyst`
|
|
240
|
-
);
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
const manifest = ManifestSchema.parse(readJsonSync(join(integrationDir, "manifest.json")));
|
|
244
|
-
if (manifest.dependencies.add.length) {
|
|
245
|
-
yield spinner(
|
|
246
|
-
addDependency(manifest.dependencies.add, {
|
|
247
|
-
cwd: projectDir,
|
|
248
|
-
silent: true,
|
|
249
|
-
packageManager
|
|
250
|
-
}),
|
|
251
|
-
{
|
|
252
|
-
text: "Installing integration dependencies...",
|
|
253
|
-
successText: "Integration dependencies installed successfully",
|
|
254
|
-
failText: (err) => `Failed to install dependencies: ${err.message}`
|
|
255
|
-
}
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
if (manifest.devDependencies.add.length) {
|
|
259
|
-
yield spinner(
|
|
260
|
-
addDevDependency(manifest.devDependencies.add, {
|
|
261
|
-
cwd: projectDir,
|
|
262
|
-
silent: true,
|
|
263
|
-
packageManager
|
|
264
|
-
}),
|
|
265
|
-
{
|
|
266
|
-
text: "Installing integration development dependencies...",
|
|
267
|
-
successText: "Integration development dependencies installed successfully",
|
|
268
|
-
failText: (err) => `Failed to install integration development dependencies: ${err.message}`
|
|
269
|
-
}
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
yield spinner(
|
|
273
|
-
exec2(`git apply -p2 ${join(integrationDir, "integration.patch")}`, { cwd: projectDir }),
|
|
274
|
-
{
|
|
275
|
-
text: "Applying integration patch...",
|
|
276
|
-
successText: "Integration patch applied successfully",
|
|
277
|
-
failText: (err) => `Failed to apply integration patch: ${err.message}`
|
|
278
|
-
}
|
|
279
|
-
);
|
|
280
|
-
console.log("\nIntegration applied successfully! Feel free to delete the `integrations` folder.");
|
|
281
|
-
});
|
|
282
|
-
}
|
|
120
|
+
import { join as join2 } from "path";
|
|
121
|
+
import { z as z3 } from "zod";
|
|
283
122
|
|
|
284
123
|
// src/utils/check-storefront-limit.ts
|
|
285
124
|
import chalk from "chalk";
|
|
@@ -310,106 +149,97 @@ var checkStorefrontLimit = (channels, storeInfo) => {
|
|
|
310
149
|
};
|
|
311
150
|
|
|
312
151
|
// src/utils/clone-catalyst.ts
|
|
313
|
-
import
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
import {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
{
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
152
|
+
import { execSync as execSync3 } from "child_process";
|
|
153
|
+
|
|
154
|
+
// src/utils/checkout-ref.ts
|
|
155
|
+
import { execSync } from "child_process";
|
|
156
|
+
|
|
157
|
+
// src/utils/is-exec-exception.ts
|
|
158
|
+
function isExecException(error) {
|
|
159
|
+
return typeof error === "object" && error !== null && "stdout" in error && "stderr" in error;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// src/utils/checkout-ref.ts
|
|
163
|
+
function checkoutRef(repoDir, ref) {
|
|
164
|
+
try {
|
|
165
|
+
execSync(`git checkout ${ref}`, {
|
|
166
|
+
cwd: repoDir,
|
|
167
|
+
stdio: "inherit",
|
|
168
|
+
encoding: "utf8"
|
|
169
|
+
});
|
|
170
|
+
console.log(`Checked out ref ${ref} successfully.`);
|
|
171
|
+
} catch (error) {
|
|
172
|
+
if (isExecException(error)) {
|
|
173
|
+
const stderr = error.stderr ? error.stderr.toString() : "";
|
|
174
|
+
if (stderr.includes(`fatal: reference is not a tree: ${ref}`) || stderr.includes(`fatal: ambiguous argument '${ref}'`) || stderr.includes(`unknown revision or path not in the working tree`)) {
|
|
175
|
+
console.error(`Ref '${ref}' not found in the repository.`);
|
|
176
|
+
} else {
|
|
177
|
+
console.error(`Error checking out ref '${ref}':`, stderr.trim());
|
|
178
|
+
}
|
|
179
|
+
} else if (error instanceof Error) {
|
|
180
|
+
console.error(`Error checking out ref '${ref}':`, error.message);
|
|
181
|
+
} else {
|
|
182
|
+
console.error(`Unknown error occurred while checking out ref '${ref}'.`);
|
|
337
183
|
}
|
|
338
|
-
|
|
339
|
-
switch (codeEditor) {
|
|
340
|
-
case "vscode":
|
|
341
|
-
yield ensureDir(join2(projectDir, ".vscode"));
|
|
342
|
-
writeJsonSync2(
|
|
343
|
-
join2(projectDir, ".vscode/settings.json"),
|
|
344
|
-
{ "typescript.tsdk": "node_modules/typescript/lib" },
|
|
345
|
-
{ spaces: 2 }
|
|
346
|
-
);
|
|
347
|
-
break;
|
|
348
|
-
default:
|
|
349
|
-
break;
|
|
350
|
-
}
|
|
351
|
-
const packageJson = z2.object({
|
|
352
|
-
name: z2.string(),
|
|
353
|
-
description: z2.string(),
|
|
354
|
-
version: z2.string(),
|
|
355
|
-
scripts: z2.object({}).passthrough().optional(),
|
|
356
|
-
dependencies: z2.object({}).passthrough(),
|
|
357
|
-
devDependencies: z2.object({}).passthrough()
|
|
358
|
-
}).passthrough().parse(
|
|
359
|
-
merge({}, readJsonSync2(join2(projectDir, "package.json")), {
|
|
360
|
-
name: projectName,
|
|
361
|
-
description: ""
|
|
362
|
-
})
|
|
363
|
-
);
|
|
364
|
-
delete packageJson.dependencies["@bigcommerce/catalyst-client"];
|
|
365
|
-
delete packageJson.devDependencies["@bigcommerce/eslint-config-catalyst"];
|
|
366
|
-
if (!includeFunctionalTests) {
|
|
367
|
-
delete packageJson.devDependencies["@faker-js/faker"];
|
|
368
|
-
delete packageJson.devDependencies["@playwright/test"];
|
|
369
|
-
}
|
|
370
|
-
writeJsonSync2(join2(projectDir, "package.json"), packageJson, { spaces: 2 });
|
|
371
|
-
if (!includeFunctionalTests) {
|
|
372
|
-
const tsConfigJson = z2.object({
|
|
373
|
-
include: z2.array(z2.string()).optional()
|
|
374
|
-
}).passthrough().parse(readJsonSync2(join2(projectDir, "tsconfig.json")));
|
|
375
|
-
tsConfigJson.include = (_a = tsConfigJson.include) == null ? void 0 : _a.filter(
|
|
376
|
-
(include) => !["tests/**/*", "playwright.config.ts"].includes(include)
|
|
377
|
-
);
|
|
378
|
-
writeJsonSync2(join2(projectDir, "tsconfig.json"), tsConfigJson, { spaces: 2 });
|
|
379
|
-
}
|
|
380
|
-
if (!includeFunctionalTests) {
|
|
381
|
-
const eslint = (yield readFile(join2(projectDir, ".eslintrc.cjs"), { encoding: "utf-8" })).replace(/['"]playwright-report\/\*\*['"],?/, "").replace(/['"]test-results\/\*\*['"],?/, "");
|
|
382
|
-
yield writeFile(join2(projectDir, ".eslintrc.cjs"), eslint);
|
|
383
|
-
removeSync(join2(projectDir, "tests"));
|
|
384
|
-
removeSync(join2(projectDir, "playwright.config.ts"));
|
|
184
|
+
process.exit(1);
|
|
385
185
|
}
|
|
386
|
-
}
|
|
186
|
+
}
|
|
387
187
|
|
|
388
|
-
// src/utils/
|
|
389
|
-
import
|
|
390
|
-
|
|
391
|
-
const rawPackageJsonUrl = "https://raw.githubusercontent.com/bigcommerce/catalyst/main/core/package.json";
|
|
392
|
-
const response = yield fetch(rawPackageJsonUrl);
|
|
188
|
+
// src/utils/has-github-ssh.ts
|
|
189
|
+
import { execSync as execSync2 } from "child_process";
|
|
190
|
+
function hasGitHubSSH() {
|
|
393
191
|
try {
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
192
|
+
const output = execSync2("ssh -T git@github.com", {
|
|
193
|
+
encoding: "utf8",
|
|
194
|
+
stdio: "pipe"
|
|
195
|
+
}).toString();
|
|
196
|
+
return output.includes("successfully authenticated");
|
|
197
|
+
} catch (error) {
|
|
198
|
+
if (isExecException(error)) {
|
|
199
|
+
const stdout = error.stdout ? error.stdout.toString() : "";
|
|
200
|
+
const stderr = error.stderr ? error.stderr.toString() : "";
|
|
201
|
+
const combinedOutput = stdout + stderr;
|
|
202
|
+
if (combinedOutput.includes("successfully authenticated")) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return false;
|
|
398
207
|
}
|
|
399
|
-
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/utils/clone-catalyst.ts
|
|
211
|
+
var cloneCatalyst = ({
|
|
212
|
+
projectName,
|
|
213
|
+
projectDir,
|
|
214
|
+
ghRef
|
|
215
|
+
}) => {
|
|
216
|
+
const repositoryName = "bigcommerce/catalyst";
|
|
217
|
+
const useSSH = hasGitHubSSH();
|
|
218
|
+
console.log(`Cloning ${repositoryName} using ${useSSH ? "SSH" : "HTTPS"}...
|
|
219
|
+
`);
|
|
220
|
+
const cloneCommand = `git clone ${useSSH ? `git@github.com:${repositoryName}` : `https://github.com/${repositoryName}`}.git${projectName ? ` ${projectName}` : ""}`;
|
|
221
|
+
execSync3(cloneCommand, { stdio: "inherit" });
|
|
222
|
+
console.log();
|
|
223
|
+
execSync3("git remote rename origin upstream", { cwd: projectDir, stdio: "inherit" });
|
|
224
|
+
console.log();
|
|
225
|
+
if (ghRef) {
|
|
226
|
+
checkoutRef(projectDir, ghRef);
|
|
227
|
+
console.log();
|
|
228
|
+
}
|
|
229
|
+
};
|
|
400
230
|
|
|
401
231
|
// src/utils/https.ts
|
|
402
|
-
import
|
|
403
|
-
import { z as
|
|
232
|
+
import chalk2 from "chalk";
|
|
233
|
+
import { z as z2 } from "zod";
|
|
404
234
|
|
|
405
235
|
// src/utils/parse.ts
|
|
406
|
-
import * as
|
|
236
|
+
import * as z from "zod";
|
|
407
237
|
import { fromZodError } from "zod-validation-error";
|
|
408
|
-
var
|
|
238
|
+
var parse = (data, schema) => {
|
|
409
239
|
try {
|
|
410
240
|
return schema.parse(data);
|
|
411
241
|
} catch (error) {
|
|
412
|
-
if (error instanceof
|
|
242
|
+
if (error instanceof z.ZodError) {
|
|
413
243
|
console.error(fromZodError(error).toString());
|
|
414
244
|
}
|
|
415
245
|
process.exit(1);
|
|
@@ -417,25 +247,25 @@ var parse2 = (data, schema) => {
|
|
|
417
247
|
};
|
|
418
248
|
|
|
419
249
|
// src/utils/https.ts
|
|
420
|
-
var BigCommerceStoreInfo =
|
|
421
|
-
features:
|
|
422
|
-
storefront_limits:
|
|
423
|
-
active:
|
|
424
|
-
total_including_inactive:
|
|
250
|
+
var BigCommerceStoreInfo = z2.object({
|
|
251
|
+
features: z2.object({
|
|
252
|
+
storefront_limits: z2.object({
|
|
253
|
+
active: z2.number(),
|
|
254
|
+
total_including_inactive: z2.number()
|
|
425
255
|
})
|
|
426
256
|
})
|
|
427
257
|
});
|
|
428
|
-
var BigCommerceV3ApiResponseSchema = (schema) =>
|
|
258
|
+
var BigCommerceV3ApiResponseSchema = (schema) => z2.object({
|
|
429
259
|
data: schema,
|
|
430
|
-
meta:
|
|
260
|
+
meta: z2.object({})
|
|
431
261
|
});
|
|
432
262
|
var BigCommerceChannelsV3ResponseSchema = BigCommerceV3ApiResponseSchema(
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
id:
|
|
436
|
-
name:
|
|
437
|
-
status:
|
|
438
|
-
platform:
|
|
263
|
+
z2.array(
|
|
264
|
+
z2.object({
|
|
265
|
+
id: z2.number(),
|
|
266
|
+
name: z2.string(),
|
|
267
|
+
status: z2.string(),
|
|
268
|
+
platform: z2.string()
|
|
439
269
|
})
|
|
440
270
|
)
|
|
441
271
|
);
|
|
@@ -486,20 +316,20 @@ var Https = class {
|
|
|
486
316
|
});
|
|
487
317
|
if (!response.ok) {
|
|
488
318
|
console.error(
|
|
489
|
-
|
|
319
|
+
chalk2.red(`
|
|
490
320
|
POST /device/token failed: ${response.status} ${response.statusText}
|
|
491
321
|
`)
|
|
492
322
|
);
|
|
493
323
|
process.exit(1);
|
|
494
324
|
}
|
|
495
|
-
const DeviceCodeSchema =
|
|
496
|
-
device_code:
|
|
497
|
-
user_code:
|
|
498
|
-
verification_uri:
|
|
499
|
-
expires_in:
|
|
500
|
-
interval:
|
|
325
|
+
const DeviceCodeSchema = z2.object({
|
|
326
|
+
device_code: z2.string(),
|
|
327
|
+
user_code: z2.string(),
|
|
328
|
+
verification_uri: z2.string(),
|
|
329
|
+
expires_in: z2.number(),
|
|
330
|
+
interval: z2.number()
|
|
501
331
|
});
|
|
502
|
-
return
|
|
332
|
+
return parse(yield response.json(), DeviceCodeSchema);
|
|
503
333
|
});
|
|
504
334
|
}
|
|
505
335
|
checkDeviceCode(deviceCode) {
|
|
@@ -513,13 +343,13 @@ POST /device/token failed: ${response.status} ${response.statusText}
|
|
|
513
343
|
if (response.status !== 200) {
|
|
514
344
|
throw new Error("Device code not yet verified");
|
|
515
345
|
}
|
|
516
|
-
const DeviceCodeSuccessSchema =
|
|
517
|
-
access_token:
|
|
518
|
-
store_hash:
|
|
519
|
-
context:
|
|
520
|
-
api_uri:
|
|
346
|
+
const DeviceCodeSuccessSchema = z2.object({
|
|
347
|
+
access_token: z2.string(),
|
|
348
|
+
store_hash: z2.string(),
|
|
349
|
+
context: z2.string(),
|
|
350
|
+
api_uri: z2.string().url()
|
|
521
351
|
});
|
|
522
|
-
return
|
|
352
|
+
return parse(yield response.json(), DeviceCodeSuccessSchema);
|
|
523
353
|
});
|
|
524
354
|
}
|
|
525
355
|
api(path, opts = {}) {
|
|
@@ -541,24 +371,24 @@ POST /device/token failed: ${response.status} ${response.statusText}
|
|
|
541
371
|
return __async(this, null, function* () {
|
|
542
372
|
const res = yield this.api("/v2/store");
|
|
543
373
|
if (!res.ok) {
|
|
544
|
-
console.error(
|
|
374
|
+
console.error(chalk2.red(`
|
|
545
375
|
GET /v2/store failed: ${res.status} ${res.statusText}
|
|
546
376
|
`));
|
|
547
377
|
process.exit(1);
|
|
548
378
|
}
|
|
549
|
-
return
|
|
379
|
+
return parse(yield res.json(), BigCommerceStoreInfo);
|
|
550
380
|
});
|
|
551
381
|
}
|
|
552
382
|
channels(query = "") {
|
|
553
383
|
return __async(this, null, function* () {
|
|
554
384
|
const res = yield this.api(`/v3/channels${query}`);
|
|
555
385
|
if (!res.ok) {
|
|
556
|
-
console.error(
|
|
386
|
+
console.error(chalk2.red(`
|
|
557
387
|
GET /v3/channels failed: ${res.status} ${res.statusText}
|
|
558
388
|
`));
|
|
559
389
|
process.exit(1);
|
|
560
390
|
}
|
|
561
|
-
return
|
|
391
|
+
return parse(yield res.json(), BigCommerceChannelsV3ResponseSchema);
|
|
562
392
|
});
|
|
563
393
|
}
|
|
564
394
|
createChannelMenus(channelId) {
|
|
@@ -578,7 +408,7 @@ GET /v3/channels failed: ${res.status} ${res.statusText}
|
|
|
578
408
|
});
|
|
579
409
|
if (!res.ok) {
|
|
580
410
|
console.warn(
|
|
581
|
-
|
|
411
|
+
chalk2.yellow(
|
|
582
412
|
`
|
|
583
413
|
Failed to create channel menus: ${res.status} ${res.statusText}. You may want to create these later: https://developer.bigcommerce.com/docs/rest-management/channels/menus#create-channel-menus
|
|
584
414
|
`
|
|
@@ -596,7 +426,7 @@ Failed to create channel menus: ${res.status} ${res.statusText}. You may want to
|
|
|
596
426
|
});
|
|
597
427
|
if (!res.ok) {
|
|
598
428
|
console.error(
|
|
599
|
-
|
|
429
|
+
chalk2.red(
|
|
600
430
|
`
|
|
601
431
|
POST /v3/storefront/api-token-customer-impersonation failed: ${res.status} ${res.statusText}
|
|
602
432
|
`
|
|
@@ -604,12 +434,12 @@ POST /v3/storefront/api-token-customer-impersonation failed: ${res.status} ${res
|
|
|
604
434
|
);
|
|
605
435
|
process.exit(1);
|
|
606
436
|
}
|
|
607
|
-
const BigCommerceCustomerImpersonationTokenSchema =
|
|
608
|
-
data:
|
|
609
|
-
token:
|
|
437
|
+
const BigCommerceCustomerImpersonationTokenSchema = z2.object({
|
|
438
|
+
data: z2.object({
|
|
439
|
+
token: z2.string()
|
|
610
440
|
})
|
|
611
441
|
});
|
|
612
|
-
return
|
|
442
|
+
return parse(yield res.json(), BigCommerceCustomerImpersonationTokenSchema);
|
|
613
443
|
});
|
|
614
444
|
}
|
|
615
445
|
sampleDataApi(path, opts = {}) {
|
|
@@ -636,51 +466,51 @@ POST /v3/storefront/api-token-customer-impersonation failed: ${res.status} ${res
|
|
|
636
466
|
});
|
|
637
467
|
if (!res.ok) {
|
|
638
468
|
console.error(
|
|
639
|
-
|
|
469
|
+
chalk2.red(`
|
|
640
470
|
POST /v3/channels/catalyst failed: ${res.status} ${res.statusText}
|
|
641
471
|
`)
|
|
642
472
|
);
|
|
643
473
|
process.exit(1);
|
|
644
474
|
}
|
|
645
|
-
const SampleDataChannelCreateSchema =
|
|
646
|
-
data:
|
|
647
|
-
id:
|
|
648
|
-
name:
|
|
649
|
-
storefront_api_token:
|
|
475
|
+
const SampleDataChannelCreateSchema = z2.object({
|
|
476
|
+
data: z2.object({
|
|
477
|
+
id: z2.number(),
|
|
478
|
+
name: z2.string().min(1),
|
|
479
|
+
storefront_api_token: z2.string()
|
|
650
480
|
})
|
|
651
481
|
});
|
|
652
|
-
return
|
|
482
|
+
return parse(yield res.json(), SampleDataChannelCreateSchema);
|
|
653
483
|
});
|
|
654
484
|
}
|
|
655
485
|
};
|
|
656
486
|
|
|
657
487
|
// src/utils/install-dependencies.ts
|
|
658
|
-
import
|
|
659
|
-
import {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
});
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
});
|
|
488
|
+
import chalk3 from "chalk";
|
|
489
|
+
import { installDependencies as installDeps } from "nypm";
|
|
490
|
+
|
|
491
|
+
// src/utils/spinner.ts
|
|
492
|
+
import { oraPromise } from "ora";
|
|
493
|
+
var spinner = (action, oraOpts) => __async(void 0, null, function* () {
|
|
494
|
+
return oraPromise(action, __spreadValues({
|
|
495
|
+
spinner: "triangle"
|
|
496
|
+
}, oraOpts)).catch(() => process.exit(1));
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
// src/utils/install-dependencies.ts
|
|
500
|
+
var installAllDeps = (projectDir) => __async(void 0, null, function* () {
|
|
501
|
+
yield installDeps({ cwd: projectDir, silent: true, packageManager: "pnpm" });
|
|
672
502
|
});
|
|
673
|
-
var installDependencies = (projectDir
|
|
674
|
-
return spinner(installAllDeps(projectDir
|
|
503
|
+
var installDependencies = (projectDir) => __async(void 0, null, function* () {
|
|
504
|
+
return spinner(installAllDeps(projectDir), {
|
|
675
505
|
text: `Installing dependencies. This could take a minute...`,
|
|
676
506
|
successText: `Dependencies installed successfully`,
|
|
677
|
-
failText: (err) =>
|
|
507
|
+
failText: (err) => chalk3.red(`Failed to install dependencies: ${err.message}`)
|
|
678
508
|
});
|
|
679
509
|
});
|
|
680
510
|
|
|
681
511
|
// src/utils/login.ts
|
|
682
512
|
import { select } from "@inquirer/prompts";
|
|
683
|
-
import
|
|
513
|
+
import chalk4 from "chalk";
|
|
684
514
|
var poll = (auth, deviceCode, interval, expiresIn) => __async(void 0, null, function* () {
|
|
685
515
|
const intervalMs = interval * 1e3;
|
|
686
516
|
const expiresAtMs = expiresIn * 1e3;
|
|
@@ -688,11 +518,11 @@ var poll = (auth, deviceCode, interval, expiresIn) => __async(void 0, null, func
|
|
|
688
518
|
for (let i = 0; i < retries; i += 1) {
|
|
689
519
|
try {
|
|
690
520
|
return yield auth.checkDeviceCode(deviceCode);
|
|
691
|
-
} catch (
|
|
521
|
+
} catch (e) {
|
|
692
522
|
}
|
|
693
523
|
yield new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
694
524
|
}
|
|
695
|
-
console.error(
|
|
525
|
+
console.error(chalk4.red("\nDevice code expired. Please try again.\n"));
|
|
696
526
|
process.exit(1);
|
|
697
527
|
});
|
|
698
528
|
var login = (bigCommerceAuthUrl, storeHash, accessToken) => __async(void 0, null, function* () {
|
|
@@ -714,11 +544,11 @@ var login = (bigCommerceAuthUrl, storeHash, accessToken) => __async(void 0, null
|
|
|
714
544
|
console.log(
|
|
715
545
|
[
|
|
716
546
|
`
|
|
717
|
-
Please visit ${
|
|
547
|
+
Please visit ${chalk4.cyan(deviceCode.verification_uri)} and enter the code: ${chalk4.yellow(
|
|
718
548
|
deviceCode.user_code
|
|
719
549
|
)}
|
|
720
550
|
`,
|
|
721
|
-
`The code will expire in ${
|
|
551
|
+
`The code will expire in ${chalk4.yellow(`${deviceCode.expires_in / 60} minutes`)}
|
|
722
552
|
`
|
|
723
553
|
].join("\n")
|
|
724
554
|
);
|
|
@@ -736,74 +566,54 @@ Please visit ${chalk5.cyan(deviceCode.verification_uri)} and enter the code: ${c
|
|
|
736
566
|
};
|
|
737
567
|
});
|
|
738
568
|
|
|
739
|
-
// src/utils/pm.ts
|
|
740
|
-
var packageManagerChoices = ["npm", "pnpm", "yarn"];
|
|
741
|
-
function getPackageManager() {
|
|
742
|
-
var _a;
|
|
743
|
-
const userAgent = (_a = process.env.npm_config_user_agent) != null ? _a : "";
|
|
744
|
-
if (userAgent.startsWith("yarn")) {
|
|
745
|
-
return "yarn";
|
|
746
|
-
}
|
|
747
|
-
if (userAgent.startsWith("pnpm")) {
|
|
748
|
-
return "pnpm";
|
|
749
|
-
}
|
|
750
|
-
return "npm";
|
|
751
|
-
}
|
|
752
|
-
|
|
753
569
|
// src/utils/write-env.ts
|
|
754
570
|
import { randomBytes } from "crypto";
|
|
755
|
-
import { outputFileSync
|
|
756
|
-
import { join
|
|
571
|
+
import { outputFileSync } from "fs-extra/esm";
|
|
572
|
+
import { join } from "path";
|
|
757
573
|
var writeEnv = (projectDir, {
|
|
758
574
|
channelId,
|
|
759
575
|
storeHash,
|
|
760
|
-
accessToken,
|
|
761
576
|
customerImpersonationToken
|
|
762
577
|
}) => {
|
|
763
|
-
|
|
764
|
-
|
|
578
|
+
outputFileSync(
|
|
579
|
+
join(projectDir, ".env.local"),
|
|
765
580
|
[
|
|
766
|
-
`AUTH_SECRET=${randomBytes(32).toString("hex")}`,
|
|
767
581
|
`BIGCOMMERCE_STORE_HASH=${storeHash}`,
|
|
768
582
|
`BIGCOMMERCE_CHANNEL_ID=${channelId}`,
|
|
769
|
-
`BIGCOMMERCE_ACCESS_TOKEN=${accessToken}`,
|
|
770
583
|
`BIGCOMMERCE_CUSTOMER_IMPERSONATION_TOKEN=${customerImpersonationToken}`,
|
|
584
|
+
"",
|
|
585
|
+
`AUTH_SECRET=${randomBytes(32).toString("hex")}`,
|
|
771
586
|
`CLIENT_LOGGER=false`,
|
|
772
587
|
`ENABLE_ADMIN_ROUTE=true`,
|
|
773
|
-
`
|
|
588
|
+
`DEFAULT_REVALIDATE_TARGET=3600`
|
|
774
589
|
].join("\n")
|
|
775
590
|
);
|
|
776
591
|
};
|
|
777
592
|
|
|
778
593
|
// src/commands/create.ts
|
|
779
|
-
var
|
|
780
|
-
var create = new Command2("create").description("Command to scaffold and connect a Catalyst storefront to your BigCommerce store").option("--project-name <name>", "Name of your Catalyst project").option("--project-dir <dir>", "Directory in which to create your project", process.cwd()).option("--store-hash <hash>", "BigCommerce store hash").option("--access-token <token>", "BigCommerce access token").option("--channel-id <id>", "BigCommerce channel ID").option("--customer-impersonation-token <token>", "BigCommerce customer impersonation token").option("--integration <provider>", "Integration to apply to your new storefront").addOption(
|
|
781
|
-
new Option(
|
|
782
|
-
"--gh-ref <ref>",
|
|
783
|
-
"Clone a specific ref from the bigcommerce/catalyst repository"
|
|
784
|
-
).default(getLatestCoreTag)
|
|
785
|
-
).addOption(
|
|
594
|
+
var create = new Command("create").description("Command to scaffold and connect a Catalyst storefront to your BigCommerce store").option("--project-name <name>", "Name of your Catalyst project").option("--project-dir <dir>", "Directory in which to create your project", process.cwd()).option("--store-hash <hash>", "BigCommerce store hash").option("--access-token <token>", "BigCommerce access token").option("--channel-id <id>", "BigCommerce channel ID").option("--customer-impersonation-token <token>", "BigCommerce customer impersonation token").option("--gh-ref <ref>", "Clone a specific ref from the bigcommerce/catalyst repository").addOption(
|
|
786
595
|
new Option("--bigcommerce-hostname <hostname>", "BigCommerce hostname").default("bigcommerce.com").hideHelp()
|
|
787
596
|
).addOption(
|
|
788
597
|
new Option("--sample-data-api-url <url>", "BigCommerce sample data API URL").default("https://api.bc-sample.store").hideHelp()
|
|
789
|
-
).addOption(
|
|
790
|
-
new Option("--package-manager <pm>", "Override detected package manager").choices(packageManagerChoices).default(getPackageManager()).hideHelp()
|
|
791
|
-
).addOption(
|
|
792
|
-
new Option("--code-editor <editor>", "Your preferred code editor").choices(["vscode"]).default("vscode").hideHelp()
|
|
793
|
-
).addOption(
|
|
794
|
-
new Option("--include-functional-tests", "Include the functional test suite").default(false).hideHelp()
|
|
795
598
|
).action((options) => __async(void 0, null, function* () {
|
|
796
|
-
const {
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
599
|
+
const { ghRef } = options;
|
|
600
|
+
try {
|
|
601
|
+
execSync4("which git", { stdio: "ignore" });
|
|
602
|
+
} catch (e) {
|
|
603
|
+
console.error(chalk5.red("Error: git is required to create a Catalyst project\n"));
|
|
604
|
+
process.exit(1);
|
|
605
|
+
}
|
|
606
|
+
try {
|
|
607
|
+
execSync4("which pnpm", { stdio: "ignore" });
|
|
608
|
+
} catch (e) {
|
|
609
|
+
console.error(chalk5.red("Error: pnpm is required to create a Catalyst project\n"));
|
|
610
|
+
console.error(chalk5.yellow("Tip: Enable it by running `corepack enable pnpm`\n"));
|
|
611
|
+
process.exit(1);
|
|
806
612
|
}
|
|
613
|
+
const URLSchema = z3.string().url();
|
|
614
|
+
const sampleDataApiUrl = parse(options.sampleDataApiUrl, URLSchema);
|
|
615
|
+
const bigcommerceApiUrl = parse(`https://api.${options.bigcommerceHostname}`, URLSchema);
|
|
616
|
+
const bigcommerceAuthUrl = parse(`https://login.${options.bigcommerceHostname}`, URLSchema);
|
|
807
617
|
let projectName;
|
|
808
618
|
let projectDir;
|
|
809
619
|
let storeHash = options.storeHash;
|
|
@@ -814,24 +624,24 @@ var create = new Command2("create").description("Command to scaffold and connect
|
|
|
814
624
|
channelId = parseInt(options.channelId, 10);
|
|
815
625
|
}
|
|
816
626
|
if (!pathExistsSync(options.projectDir)) {
|
|
817
|
-
console.error(
|
|
627
|
+
console.error(chalk5.red(`Error: --projectDir ${options.projectDir} is not a valid path
|
|
818
628
|
`));
|
|
819
629
|
process.exit(1);
|
|
820
630
|
}
|
|
821
631
|
if (options.projectName) {
|
|
822
|
-
projectName =
|
|
823
|
-
projectDir =
|
|
632
|
+
projectName = kebabCase(options.projectName);
|
|
633
|
+
projectDir = join2(options.projectDir, projectName);
|
|
824
634
|
if (pathExistsSync(projectDir)) {
|
|
825
|
-
console.error(
|
|
635
|
+
console.error(chalk5.red(`Error: ${projectDir} already exists
|
|
826
636
|
`));
|
|
827
637
|
process.exit(1);
|
|
828
638
|
}
|
|
829
639
|
}
|
|
830
640
|
if (!options.projectName) {
|
|
831
641
|
const validateProjectName = (i) => {
|
|
832
|
-
const formatted =
|
|
642
|
+
const formatted = kebabCase(i);
|
|
833
643
|
if (!formatted) return "Project name is required";
|
|
834
|
-
const targetDir =
|
|
644
|
+
const targetDir = join2(options.projectDir, formatted);
|
|
835
645
|
if (pathExistsSync(targetDir)) return `Destination '${targetDir}' already exists`;
|
|
836
646
|
projectName = formatted;
|
|
837
647
|
projectDir = targetDir;
|
|
@@ -854,21 +664,17 @@ var create = new Command2("create").description("Command to scaffold and connect
|
|
|
854
664
|
console.log(`
|
|
855
665
|
Creating '${projectName}' at '${projectDir}'
|
|
856
666
|
`);
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
Using ${chalk6.bold(packageManager)}
|
|
860
|
-
`);
|
|
861
|
-
yield installDependencies(projectDir, packageManager);
|
|
862
|
-
yield applyIntegration(options.integration, { projectDir, packageManager });
|
|
667
|
+
cloneCatalyst({ projectDir, projectName, ghRef });
|
|
668
|
+
yield installDependencies(projectDir);
|
|
863
669
|
console.log(
|
|
864
670
|
[
|
|
865
671
|
`
|
|
866
|
-
${
|
|
672
|
+
${chalk5.green("Success!")} Created '${projectName}' at '${projectDir}'
|
|
867
673
|
`,
|
|
868
674
|
`Next steps:`,
|
|
869
|
-
|
|
675
|
+
chalk5.yellow(`
|
|
870
676
|
- cd ${projectName} && cp .env.example .env.local`),
|
|
871
|
-
|
|
677
|
+
chalk5.yellow(`
|
|
872
678
|
- Populate .env.local with your BigCommerce API credentials
|
|
873
679
|
`)
|
|
874
680
|
].join("\n")
|
|
@@ -931,47 +737,37 @@ ${chalk6.green("Success!")} Created '${projectName}' at '${projectDir}'
|
|
|
931
737
|
console.log(`
|
|
932
738
|
Creating '${projectName}' at '${projectDir}'
|
|
933
739
|
`);
|
|
934
|
-
|
|
740
|
+
cloneCatalyst({ projectDir, projectName, ghRef });
|
|
935
741
|
writeEnv(projectDir, {
|
|
936
742
|
channelId: channelId.toString(),
|
|
937
743
|
storeHash,
|
|
938
|
-
accessToken,
|
|
939
744
|
customerImpersonationToken
|
|
940
745
|
});
|
|
941
|
-
|
|
942
|
-
Using ${chalk6.bold(packageManager)}
|
|
943
|
-
`);
|
|
944
|
-
yield installDependencies(projectDir, packageManager);
|
|
945
|
-
yield spinner(exec3(`${packageManager} run --prefix ${projectDir} generate`), {
|
|
946
|
-
text: "Creating GraphQL schema...",
|
|
947
|
-
successText: "Created GraphQL schema",
|
|
948
|
-
failText: (err) => chalk6.red(`Failed to create GraphQL schema: ${err.message}`)
|
|
949
|
-
});
|
|
950
|
-
yield applyIntegration(options.integration, { projectDir, packageManager });
|
|
746
|
+
yield installDependencies(projectDir);
|
|
951
747
|
console.log(
|
|
952
748
|
`
|
|
953
|
-
${
|
|
749
|
+
${chalk5.green("Success!")} Created '${projectName}' at '${projectDir}'
|
|
954
750
|
`,
|
|
955
751
|
"\nNext steps:\n",
|
|
956
|
-
|
|
957
|
-
cd ${projectName} &&
|
|
752
|
+
chalk5.yellow(`
|
|
753
|
+
cd ${projectName} && pnpm run dev
|
|
958
754
|
`)
|
|
959
755
|
);
|
|
960
756
|
}));
|
|
961
757
|
|
|
962
758
|
// src/commands/init.ts
|
|
963
|
-
import { Command as
|
|
759
|
+
import { Command as Command2, Option as Option2 } from "@commander-js/extra-typings";
|
|
964
760
|
import { input as input2, select as select3 } from "@inquirer/prompts";
|
|
965
|
-
import
|
|
966
|
-
import * as
|
|
967
|
-
var init = new
|
|
761
|
+
import chalk6 from "chalk";
|
|
762
|
+
import * as z4 from "zod";
|
|
763
|
+
var init = new Command2("init").description("Connect a BigCommerce store with an existing Catalyst project").option("--store-hash <hash>", "BigCommerce store hash").option("--access-token <token>", "BigCommerce access token").addOption(
|
|
968
764
|
new Option2("--bigcommerce-hostname <hostname>", "BigCommerce hostname").default("bigcommerce.com").hideHelp()
|
|
969
765
|
).addOption(
|
|
970
766
|
new Option2("--sample-data-api-url <url>", "BigCommerce sample data API URL").default("https://api.bc-sample.store").hideHelp()
|
|
971
767
|
).action((options) => __async(void 0, null, function* () {
|
|
972
768
|
const projectDir = process.cwd();
|
|
973
|
-
const URLSchema =
|
|
974
|
-
const sampleDataApiUrl =
|
|
769
|
+
const URLSchema = z4.string().url();
|
|
770
|
+
const sampleDataApiUrl = parse(options.sampleDataApiUrl, URLSchema);
|
|
975
771
|
const bigCommerceApiUrl = `https://api.${options.bigcommerceHostname}`;
|
|
976
772
|
const bigCommerceAuthUrl = `https://login.${options.bigcommerceHostname}`;
|
|
977
773
|
let storeHash = options.storeHash;
|
|
@@ -985,7 +781,7 @@ var init = new Command3("init").description("Connect a BigCommerce store with an
|
|
|
985
781
|
}
|
|
986
782
|
if (!storeHash || !accessToken) {
|
|
987
783
|
console.log(
|
|
988
|
-
|
|
784
|
+
chalk6.yellow("\nYou must authenticate with a store to overwrite your local environment.\n")
|
|
989
785
|
);
|
|
990
786
|
process.exit(1);
|
|
991
787
|
}
|
|
@@ -1042,13 +838,85 @@ var init = new Command3("init").description("Connect a BigCommerce store with an
|
|
|
1042
838
|
writeEnv(projectDir, {
|
|
1043
839
|
channelId: channelId.toString(),
|
|
1044
840
|
storeHash,
|
|
1045
|
-
accessToken,
|
|
1046
841
|
customerImpersonationToken
|
|
1047
842
|
});
|
|
1048
843
|
}));
|
|
1049
844
|
|
|
845
|
+
// src/commands/integration.ts
|
|
846
|
+
import { Command as Command3 } from "@commander-js/extra-typings";
|
|
847
|
+
import { exec as execCb } from "child_process";
|
|
848
|
+
import { parse as parse2 } from "dotenv";
|
|
849
|
+
import { outputFileSync as outputFileSync2, writeJsonSync } from "fs-extra/esm";
|
|
850
|
+
import kebabCase2 from "lodash.kebabcase";
|
|
851
|
+
import { coerce, compare } from "semver";
|
|
852
|
+
import { promisify } from "util";
|
|
853
|
+
import { z as z5 } from "zod";
|
|
854
|
+
var exec = promisify(execCb);
|
|
855
|
+
var ManifestSchema = z5.object({
|
|
856
|
+
name: z5.string(),
|
|
857
|
+
dependencies: z5.object({ add: z5.array(z5.string()) }),
|
|
858
|
+
devDependencies: z5.object({ add: z5.array(z5.string()) }),
|
|
859
|
+
environmentVariables: z5.array(z5.string())
|
|
860
|
+
});
|
|
861
|
+
var integration = new Command3("integration").argument("<integration-name>", "Formatted name of the integration").option("--commit-hash <hash>", "Override integration source branch with a specific commit hash").action((integrationNameRaw, options) => __async(void 0, null, function* () {
|
|
862
|
+
const integrationName = z5.string().transform(kebabCase2).parse(integrationNameRaw);
|
|
863
|
+
const manifest = {
|
|
864
|
+
name: integrationName,
|
|
865
|
+
dependencies: { add: [] },
|
|
866
|
+
devDependencies: { add: [] },
|
|
867
|
+
environmentVariables: []
|
|
868
|
+
};
|
|
869
|
+
yield exec("git fetch --tags");
|
|
870
|
+
const { stdout: headRefStdOut } = yield exec("git rev-parse --abbrev-ref HEAD");
|
|
871
|
+
let [sourceRef] = headRefStdOut.split("\n");
|
|
872
|
+
if (options.commitHash) {
|
|
873
|
+
sourceRef = options.commitHash;
|
|
874
|
+
}
|
|
875
|
+
const { stdout: catalystTags } = yield exec("git tag --list @bigcommerce/catalyst-core@\\*");
|
|
876
|
+
const [latestCoreTag] = catalystTags.split("\n").filter(Boolean).sort((a, b) => {
|
|
877
|
+
const versionA = coerce(a.replace("@bigcommerce/catalyst-core@", ""));
|
|
878
|
+
const versionB = coerce(b.replace("@bigcommerce/catalyst-core@", ""));
|
|
879
|
+
if (versionA && versionB) {
|
|
880
|
+
return compare(versionA, versionB);
|
|
881
|
+
}
|
|
882
|
+
return 0;
|
|
883
|
+
}).reverse();
|
|
884
|
+
const PackageDependenciesSchema = z5.object({
|
|
885
|
+
dependencies: z5.object({}).passthrough(),
|
|
886
|
+
devDependencies: z5.object({}).passthrough()
|
|
887
|
+
});
|
|
888
|
+
const getPackageDeps = (ref) => __async(void 0, null, function* () {
|
|
889
|
+
const { stdout } = yield exec(`git show ${ref}:core/package.json`);
|
|
890
|
+
return PackageDependenciesSchema.parse(JSON.parse(stdout));
|
|
891
|
+
});
|
|
892
|
+
const integrationJson = yield getPackageDeps(sourceRef);
|
|
893
|
+
const latestCoreTagJson = yield getPackageDeps(latestCoreTag);
|
|
894
|
+
const diffObjectKeys = (a, b) => {
|
|
895
|
+
return Object.keys(a).filter((key) => !Object.keys(b).includes(key));
|
|
896
|
+
};
|
|
897
|
+
manifest.dependencies.add = diffObjectKeys(
|
|
898
|
+
integrationJson.dependencies,
|
|
899
|
+
latestCoreTagJson.dependencies
|
|
900
|
+
);
|
|
901
|
+
manifest.devDependencies.add = diffObjectKeys(
|
|
902
|
+
integrationJson.devDependencies,
|
|
903
|
+
latestCoreTagJson.devDependencies
|
|
904
|
+
);
|
|
905
|
+
const { stdout: latestCoreEnv } = yield exec(`git show ${latestCoreTag}:core/.env.example`);
|
|
906
|
+
const { stdout: integrationEnv } = yield exec(`git show ${sourceRef}:core/.env.example`);
|
|
907
|
+
manifest.environmentVariables = diffObjectKeys(parse2(integrationEnv), parse2(latestCoreEnv));
|
|
908
|
+
const { stdout: integrationDiff } = yield exec(
|
|
909
|
+
`git diff ${latestCoreTag}...${sourceRef} -- ':(exclude)core/package.json' ':(exclude)pnpm-lock.yaml'`
|
|
910
|
+
);
|
|
911
|
+
outputFileSync2(`integrations/${integrationName}/integration.patch`, integrationDiff);
|
|
912
|
+
writeJsonSync(`integrations/${integrationName}/manifest.json`, manifest, {
|
|
913
|
+
spaces: 2
|
|
914
|
+
});
|
|
915
|
+
console.log("Integration created successfully.");
|
|
916
|
+
}));
|
|
917
|
+
|
|
1050
918
|
// src/index.ts
|
|
1051
|
-
console.log(
|
|
919
|
+
console.log(chalk7.cyanBright(`
|
|
1052
920
|
\u25E2 ${package_default.name} v${package_default.version}
|
|
1053
921
|
`));
|
|
1054
922
|
program.name(package_default.name).version(package_default.version).description("A command line tool to create a new Catalyst project.").addCommand(create, { isDefault: true }).addCommand(init).addCommand(integration);
|