@create-node-app/core 0.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/dist/index.mjs ADDED
@@ -0,0 +1,839 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw new Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ // index.ts
10
+ import chalk4 from "chalk";
11
+ import envinfo from "envinfo";
12
+
13
+ // installer.ts
14
+ import _2 from "underscore";
15
+ import path3 from "path";
16
+ import fs4 from "fs";
17
+ import chalk3 from "chalk";
18
+ import os3 from "os";
19
+ import semver2 from "semver";
20
+ import spawn2 from "cross-spawn";
21
+ import { execSync as execSync2 } from "child_process";
22
+
23
+ // helpers.ts
24
+ import { execSync } from "child_process";
25
+ import spawn from "cross-spawn";
26
+ import chalk from "chalk";
27
+ import semver from "semver";
28
+ import dns from "dns";
29
+ import { URL as URL2 } from "url";
30
+ var shouldUseYarn = () => {
31
+ try {
32
+ execSync("yarnpkg --version", { stdio: "ignore" });
33
+ return true;
34
+ } catch (e) {
35
+ console.log(e);
36
+ return false;
37
+ }
38
+ };
39
+ var checkThatNpmCanReadCwd = () => {
40
+ const cwd = process.cwd();
41
+ let childOutput = null;
42
+ try {
43
+ childOutput = spawn.sync("npm", ["config", "list"]).output.join("");
44
+ } catch (err) {
45
+ return true;
46
+ }
47
+ if (typeof childOutput !== "string") {
48
+ return true;
49
+ }
50
+ const lines = childOutput.split("\n");
51
+ const prefix = " cwd = ";
52
+ const line = lines.find((l) => l.indexOf(prefix) === 0);
53
+ if (typeof line !== "string") {
54
+ return true;
55
+ }
56
+ const npmCWD = line.substring(prefix.length);
57
+ if (npmCWD === cwd) {
58
+ return true;
59
+ }
60
+ console.error(
61
+ chalk.red(
62
+ `Could not start an npm process in the right directory.
63
+
64
+ The current directory is: ${chalk.bold(cwd)}
65
+ However, a newly started npm process runs in: ${chalk.bold(
66
+ npmCWD
67
+ )}
68
+
69
+ This is probably caused by a misconfigured system terminal shell.`
70
+ )
71
+ );
72
+ if (process.platform === "win32") {
73
+ console.error(
74
+ chalk.red(`On Windows, this can usually be fixed by running:
75
+
76
+ `) + ` ${chalk.cyan(
77
+ "reg"
78
+ )} delete "HKCU\\Software\\Microsoft\\Command Processor" /v AutoRun /f
79
+ ${chalk.cyan(
80
+ "reg"
81
+ )} delete "HKLM\\Software\\Microsoft\\Command Processor" /v AutoRun /f
82
+
83
+ ` + chalk.red(`Try to run the above two lines in the terminal.
84
+ `) + chalk.red(
85
+ `To learn more about this problem, read: https://blogs.msdn.microsoft.com/oldnewthing/20071121-00/?p=24433/`
86
+ )
87
+ );
88
+ }
89
+ return false;
90
+ };
91
+ var checkNpmVersion = () => {
92
+ let hasMinNpm = false;
93
+ let npmVersion = void 0;
94
+ try {
95
+ npmVersion = execSync("npm --version").toString().trim();
96
+ hasMinNpm = semver.gte(npmVersion, "3.0.0");
97
+ } catch (err) {
98
+ }
99
+ return {
100
+ hasMinNpm,
101
+ npmVersion
102
+ };
103
+ };
104
+ var getProxy = () => {
105
+ if (process.env.HTTPS_PROXY) {
106
+ return process.env.HTTPS_PROXY;
107
+ }
108
+ try {
109
+ const httpsProxy = execSync("npm config get https-proxy").toString().trim();
110
+ return httpsProxy !== "null" ? httpsProxy : void 0;
111
+ } catch (e) {
112
+ }
113
+ return "";
114
+ };
115
+ var checkIfOnline = (useYarn) => {
116
+ if (!useYarn) {
117
+ return Promise.resolve(true);
118
+ }
119
+ return new Promise((resolve) => {
120
+ dns.lookup("registry.yarnpkg.com", (err) => {
121
+ let proxy;
122
+ if (err != null && (proxy = getProxy())) {
123
+ dns.lookup(new URL2(proxy).hostname, (proxyErr) => {
124
+ resolve(!proxyErr);
125
+ });
126
+ } else {
127
+ resolve(!err);
128
+ }
129
+ });
130
+ });
131
+ };
132
+
133
+ // package.ts
134
+ import { existsSync } from "fs";
135
+ import merge from "lodash.merge";
136
+
137
+ // paths.ts
138
+ import fs2 from "fs";
139
+ import os2 from "os";
140
+ import path2 from "path";
141
+
142
+ // git.ts
143
+ import os from "os";
144
+ import childProcess from "child_process";
145
+ import path from "path";
146
+ import { promisify } from "util";
147
+ import fs from "fs";
148
+ import download from "download";
149
+ import debug from "debug";
150
+ var log = debug("cna:git");
151
+ var exec = promisify(childProcess.exec);
152
+ var filterGit = (src) => {
153
+ return !/(\\|\/)\.git\b/.test(src);
154
+ };
155
+ var clone = (git, target, branch) => {
156
+ const command = ["git", "clone", "--depth=1", "-b", branch, git, target];
157
+ return exec(command.join(" "));
158
+ };
159
+ var pull = async (cwd) => {
160
+ await exec("git checkout -f", { cwd });
161
+ await exec("git pull", { cwd });
162
+ };
163
+ var downloadRepository = async ({
164
+ git = "",
165
+ zip,
166
+ offline = false,
167
+ target = "./",
168
+ branch = "main",
169
+ way = "git",
170
+ targetId,
171
+ cacheDir: optsCacheDir
172
+ }) => {
173
+ const absoluteTarget = path.isAbsolute(target) ? target : path.resolve(target);
174
+ const isGithub = /^[^/]+\/[^/]+$/.test(git);
175
+ const gitUrl = isGithub ? `https://github.com/${git}` : git;
176
+ const zipUrl = isGithub ? `https://github.com/${git}/archive/${branch}.zip` : zip;
177
+ const id = targetId || Buffer.from(`${git}@${branch}`).toString("base64");
178
+ let cacheDir = optsCacheDir || path.join(os.homedir(), ".cache", "cna", id);
179
+ cacheDir = path.isAbsolute(cacheDir) ? cacheDir : path.resolve(cacheDir);
180
+ log("cache folder: %s", cacheDir);
181
+ log("git url: %s", gitUrl);
182
+ log("zip url: %s", zipUrl);
183
+ const cached = fs.existsSync(cacheDir);
184
+ const createByGit = async () => {
185
+ log("git mode");
186
+ if (!cached) {
187
+ if (!gitUrl) {
188
+ throw new Error(
189
+ `Expect parameter opts.git when opts.way is 'git', but got ${gitUrl}`
190
+ );
191
+ }
192
+ await clone(gitUrl, cacheDir, branch);
193
+ }
194
+ if (offline) {
195
+ fs.cpSync(cacheDir, absoluteTarget, {
196
+ force: true,
197
+ filter: filterGit,
198
+ recursive: true
199
+ });
200
+ return;
201
+ }
202
+ await pull(cacheDir);
203
+ setTimeout(() => {
204
+ fs.cpSync(cacheDir, absoluteTarget, {
205
+ force: true,
206
+ filter: filterGit,
207
+ recursive: true
208
+ });
209
+ }, 400);
210
+ };
211
+ const createByZip = async () => {
212
+ log("zip mode");
213
+ if (!zipUrl) {
214
+ throw new Error(
215
+ `Expect parameter opts.zip when opts.way is 'zip', but got ${zipUrl}`
216
+ );
217
+ }
218
+ await download(zipUrl, target, { extract: true });
219
+ };
220
+ switch (way) {
221
+ case "git":
222
+ return createByGit();
223
+ case "zip":
224
+ return createByZip();
225
+ default:
226
+ throw new Error(`Expect parameter opts.way is 'git' or 'zip'`);
227
+ }
228
+ };
229
+
230
+ // paths.ts
231
+ var solveValuesFromAddonUrl = (addon) => {
232
+ const url = new URL(addon);
233
+ const origin = `${url.protocol}//${url.host}`;
234
+ const [org, repo, , branch = "", ...subdir] = url.pathname.slice(1).split("/");
235
+ const ignorePackage = url.searchParams.get("ignorePackage") === "true";
236
+ return {
237
+ url: `${origin}/${org}/${repo}`,
238
+ branch,
239
+ subdir: subdir.join("/"),
240
+ protocol: url.protocol,
241
+ host: url.host,
242
+ pathname: url.pathname,
243
+ ignorePackage
244
+ };
245
+ };
246
+ var solveRepositoryPath = async ({
247
+ url,
248
+ branch,
249
+ subdir
250
+ }) => {
251
+ const targetId = Buffer.from(`${url}#${branch}#${subdir}`).toString("base64");
252
+ const target = path2.join(os2.homedir(), ".cna", targetId);
253
+ try {
254
+ await downloadRepository({
255
+ git: url,
256
+ branch,
257
+ target,
258
+ targetId
259
+ });
260
+ } catch {
261
+ }
262
+ return { dir: target, subdir };
263
+ };
264
+ var solveAddonPath = async (addon) => {
265
+ try {
266
+ const { url, branch, subdir, protocol, host, pathname, ignorePackage } = solveValuesFromAddonUrl(addon);
267
+ if (protocol === "file:") {
268
+ return {
269
+ dir: path2.resolve(host, pathname),
270
+ subdir
271
+ };
272
+ }
273
+ const gitData = await solveRepositoryPath({
274
+ url,
275
+ branch,
276
+ subdir
277
+ });
278
+ return { ...gitData, ignorePackage };
279
+ } catch {
280
+ return {
281
+ dir: path2.resolve(__dirname, "..", "addons", addon),
282
+ ignorePackage: void 0
283
+ };
284
+ }
285
+ };
286
+ var getAddonPackagePath = async (addon, name = "package", ignorePackage = false) => {
287
+ const {
288
+ dir,
289
+ subdir,
290
+ ignorePackage: addonIgnorePackage
291
+ } = await solveAddonPath(addon);
292
+ if (name === "package.json" && (ignorePackage || addonIgnorePackage)) {
293
+ throw new Error("package.json should be ignored for file addon");
294
+ }
295
+ if (subdir) {
296
+ return path2.resolve(dir, subdir, name);
297
+ }
298
+ return path2.resolve(dir, name);
299
+ };
300
+ var getAddonTemplateDirPath = async (addonUrl) => {
301
+ const { dir, subdir = "" } = await solveAddonPath(addonUrl);
302
+ let templateDirPath = path2.resolve(dir, subdir);
303
+ const templateDirPathWithTemplate = path2.resolve(templateDirPath, "template");
304
+ return new Promise((resolve, reject) => {
305
+ fs2.stat(templateDirPathWithTemplate, (err, stats) => {
306
+ if (err) {
307
+ return reject(err);
308
+ }
309
+ if (stats.isDirectory()) {
310
+ templateDirPath = templateDirPathWithTemplate;
311
+ }
312
+ resolve(templateDirPath);
313
+ });
314
+ });
315
+ };
316
+
317
+ // package.ts
318
+ var getInstallableSetup = ({
319
+ dependencies,
320
+ devDependencies,
321
+ ...packageJson
322
+ }) => {
323
+ const getInstallableDeps = (deps = {}) => Object.entries(deps).map(([dep, version]) => `${dep}@${version}`);
324
+ return {
325
+ packageJson,
326
+ dependencies: getInstallableDeps(dependencies),
327
+ devDependencies: getInstallableDeps(devDependencies)
328
+ };
329
+ };
330
+ var requireIfExists = (path4) => {
331
+ if (existsSync(path4)) {
332
+ return __require(path4);
333
+ }
334
+ throw new Error(`file ${path4} not exists`);
335
+ };
336
+ var loadAddonsPackages = async ({
337
+ addons = [],
338
+ ignorePackage: globalIgnorePackage = false,
339
+ ...config
340
+ }) => {
341
+ const setup = await addons.reduce(
342
+ async (setupPromise, { url: addon, ignorePackage }) => {
343
+ let packageJson = await setupPromise;
344
+ try {
345
+ const template = requireIfExists(
346
+ await getAddonPackagePath(addon, "template.json")
347
+ );
348
+ packageJson = merge(packageJson, template.package || {});
349
+ } catch {
350
+ }
351
+ try {
352
+ const addonPackageJson = requireIfExists(
353
+ await getAddonPackagePath(
354
+ addon,
355
+ "package.json",
356
+ globalIgnorePackage || ignorePackage
357
+ )
358
+ );
359
+ return merge(packageJson, addonPackageJson);
360
+ } catch {
361
+ }
362
+ try {
363
+ const resolveAddonPackage = requireIfExists(
364
+ await getAddonPackagePath(addon)
365
+ );
366
+ packageJson = resolveAddonPackage(packageJson, config);
367
+ } catch {
368
+ }
369
+ return packageJson;
370
+ },
371
+ Promise.resolve({
372
+ name: config.appName,
373
+ dependencies: {},
374
+ devDependencies: {},
375
+ scripts: {}
376
+ })
377
+ );
378
+ return getInstallableSetup(setup);
379
+ };
380
+
381
+ // loaders.ts
382
+ import _ from "underscore";
383
+ import fs3 from "fs";
384
+ import chalk2 from "chalk";
385
+ import readdirp from "readdirp";
386
+ import { dirname } from "path";
387
+ var SRC_PATH_PATTERN = "[src]/";
388
+ var DEFAULT_SRC_PATH = "src/";
389
+ var getSrcDirPattern = (srcDir) => `${srcDir === "." ? "" : srcDir}/`;
390
+ var copyFile = async (src, dest, verbose = false) => {
391
+ try {
392
+ const parentDir = dirname(dest);
393
+ if (parentDir) {
394
+ fs3.mkdirSync(parentDir, { recursive: true });
395
+ }
396
+ fs3.cpSync(src, dest, { force: true, recursive: true });
397
+ if (verbose) {
398
+ console.log(chalk2.green(`Added "${dest}" from "${src}" successfully`));
399
+ }
400
+ } catch (err) {
401
+ console.log(chalk2.red(`Cannot copy file ${src} to ${dest}`));
402
+ if (verbose) {
403
+ console.log(chalk2.red(err));
404
+ }
405
+ throw err;
406
+ }
407
+ };
408
+ var writeFile = async (path4, content, flag = "w", verbose = false) => {
409
+ try {
410
+ const parentDir = dirname(path4);
411
+ if (parentDir) {
412
+ fs3.mkdirSync(parentDir, { recursive: true });
413
+ }
414
+ fs3.writeFileSync(path4, content, { flag });
415
+ if (verbose) {
416
+ console.log(chalk2.green(`Added "${path4}" successfully`));
417
+ }
418
+ } catch (err) {
419
+ console.log(chalk2.red(`Cannot write file ${path4}`));
420
+ if (verbose) {
421
+ console.log(chalk2.red(err));
422
+ }
423
+ throw err;
424
+ }
425
+ };
426
+ var appendFile = async (src, dest, verbose = false) => {
427
+ const content = fs3.readFileSync(src, "utf8");
428
+ return writeFile(dest, content, "a+", verbose);
429
+ };
430
+ var getModeFromPath = (path4 = "") => {
431
+ const matchExts = (...exts) => exts.find((ext) => path4.endsWith(ext));
432
+ if (matchExts(".append")) {
433
+ return "append";
434
+ }
435
+ if (matchExts(".append.template", ".template.append")) {
436
+ return "appendTemplate";
437
+ }
438
+ if (matchExts(".template")) {
439
+ return "copyTemplate";
440
+ }
441
+ return "copy";
442
+ };
443
+ var copyLoader = ({ root, templateDir, verbose, srcDir }) => ({ path: path4 }) => {
444
+ return copyFile(
445
+ `${templateDir}/${path4}`,
446
+ `${root}/${path4}`.replace(SRC_PATH_PATTERN, getSrcDirPattern(srcDir)),
447
+ verbose
448
+ );
449
+ };
450
+ var appendLoader = ({ root, templateDir, verbose, srcDir }) => ({ path: path4 }) => {
451
+ const newPath = path4.replace(/.append$/, "").replace(SRC_PATH_PATTERN, getSrcDirPattern(srcDir));
452
+ return appendFile(`${templateDir}/${path4}`, `${root}/${newPath}`, verbose);
453
+ };
454
+ var templateLoader = ({
455
+ root,
456
+ templateDir,
457
+ appName,
458
+ alias,
459
+ verbose,
460
+ mode = "",
461
+ srcDir,
462
+ runCommand,
463
+ installCommand
464
+ }) => async ({ path: path4 }) => {
465
+ const flag = mode.includes("append") ? "a+" : "w";
466
+ const file = fs3.readFileSync(`${templateDir}/${path4}`, "utf8");
467
+ const newFile = _.template(file);
468
+ const newPath = path4.replace(/.template$/, "").replace(/.append$/, "").replace(SRC_PATH_PATTERN, getSrcDirPattern(srcDir));
469
+ return writeFile(
470
+ `${root}/${newPath}`,
471
+ newFile({
472
+ project: alias,
473
+ projectImport: alias,
474
+ projectImportPath: alias === "" ? "" : `${alias}/`,
475
+ projectName: appName,
476
+ srcDir: srcDir || ".",
477
+ runCommand,
478
+ installCommand
479
+ }),
480
+ flag,
481
+ verbose
482
+ );
483
+ };
484
+ var fileLoader = ({
485
+ root,
486
+ templateDir,
487
+ appName,
488
+ originalDirectory,
489
+ alias,
490
+ verbose,
491
+ srcDir = DEFAULT_SRC_PATH,
492
+ runCommand,
493
+ installCommand
494
+ }) => ({ path: path4 }) => {
495
+ const mode = getModeFromPath(path4);
496
+ const loaders = {
497
+ copy: copyLoader,
498
+ append: appendLoader,
499
+ copyTemplate: templateLoader,
500
+ appendTemplate: appendLoader
501
+ };
502
+ return loaders[mode]({
503
+ root,
504
+ templateDir,
505
+ appName,
506
+ originalDirectory,
507
+ alias,
508
+ verbose,
509
+ mode,
510
+ srcDir,
511
+ runCommand,
512
+ installCommand
513
+ })({
514
+ path: path4
515
+ });
516
+ };
517
+ var loadFiles = async ({
518
+ root,
519
+ addons = [],
520
+ appName,
521
+ originalDirectory,
522
+ alias,
523
+ verbose,
524
+ srcDir = DEFAULT_SRC_PATH,
525
+ runCommand,
526
+ installCommand
527
+ }) => {
528
+ for await (const { url: addonUrl } of addons) {
529
+ const templateDir = await getAddonTemplateDirPath(addonUrl);
530
+ if (!fs3.statSync(templateDir).isDirectory()) {
531
+ continue;
532
+ }
533
+ for await (const entry of readdirp(templateDir, {
534
+ fileFilter: [
535
+ "!package.js",
536
+ "!package.json",
537
+ "!package-lock.json",
538
+ "!template.json",
539
+ "!yarn.lock",
540
+ "!pnpm-lock.yaml"
541
+ ],
542
+ directoryFilter: ["!package"]
543
+ })) {
544
+ try {
545
+ await fileLoader({
546
+ root,
547
+ templateDir,
548
+ appName,
549
+ originalDirectory,
550
+ alias,
551
+ verbose,
552
+ srcDir,
553
+ runCommand,
554
+ installCommand
555
+ })(entry);
556
+ } catch (err) {
557
+ if (verbose) {
558
+ console.log(err);
559
+ }
560
+ throw err;
561
+ }
562
+ }
563
+ }
564
+ };
565
+
566
+ // installer.ts
567
+ var install = (root, useYarn = false, dependencies = [], verbose = false, isOnline = true, isDevDependencies = false) => {
568
+ return new Promise((resolve, reject) => {
569
+ let command;
570
+ let args;
571
+ if (useYarn) {
572
+ command = "yarnpkg";
573
+ args = ["add"];
574
+ if (!isOnline) {
575
+ args.push("--offline");
576
+ }
577
+ if (isDevDependencies) {
578
+ args.push("--dev");
579
+ }
580
+ args.push(...dependencies);
581
+ args.push("--cwd");
582
+ args.push(root);
583
+ if (!isOnline) {
584
+ console.log(chalk3.yellow("You appear to be offline."));
585
+ console.log(chalk3.yellow("Falling back to the local Yarn cache."));
586
+ console.log();
587
+ }
588
+ } else {
589
+ command = "npm";
590
+ args = ["install", "--loglevel", "error"];
591
+ if (isDevDependencies) {
592
+ args.push("--save-dev");
593
+ } else {
594
+ args.push("--save");
595
+ }
596
+ args.push(...dependencies);
597
+ }
598
+ if (verbose) {
599
+ args.push("--verbose");
600
+ }
601
+ const child = spawn2(command, args, { stdio: "inherit", cwd: root });
602
+ child.on("close", (code) => {
603
+ if (code !== 0) {
604
+ reject(new Error(`${command} ${args.join(" ")}`));
605
+ return;
606
+ }
607
+ resolve();
608
+ });
609
+ });
610
+ };
611
+ var run = async ({
612
+ root,
613
+ appName,
614
+ originalDirectory,
615
+ verbose = false,
616
+ useYarn = false,
617
+ addons = [],
618
+ dependencies = [],
619
+ devDependencies = [],
620
+ alias = "",
621
+ installDependencies = true,
622
+ srcDir = "",
623
+ runCommand = "",
624
+ installCommand = ""
625
+ }) => {
626
+ let isOnline = true;
627
+ if (useYarn) {
628
+ isOnline = await checkIfOnline(useYarn);
629
+ }
630
+ if (_2.isEmpty(addons)) {
631
+ console.log();
632
+ console.log(chalk3.yellow("No addons specified to bootstrap application."));
633
+ console.log();
634
+ process.exit(0);
635
+ }
636
+ await loadFiles({
637
+ root,
638
+ addons,
639
+ appName,
640
+ originalDirectory,
641
+ alias,
642
+ verbose,
643
+ srcDir,
644
+ runCommand,
645
+ installCommand
646
+ });
647
+ if (installDependencies) {
648
+ console.log(
649
+ chalk3.green("Installing packages. This might take a couple of minutes.")
650
+ );
651
+ console.log(chalk3.green("Installing dependencies..."));
652
+ console.log();
653
+ await install(root, useYarn, dependencies, verbose, isOnline, false);
654
+ if (devDependencies.length > 0) {
655
+ console.log();
656
+ console.log(chalk3.green("Installing devDependencies..."));
657
+ console.log();
658
+ await install(root, useYarn, devDependencies, verbose, isOnline, true);
659
+ }
660
+ } else {
661
+ console.log(chalk3.yellow("Skip package installation."));
662
+ console.log(chalk3.yellow("Run npm install/yarn in your project."));
663
+ const packageJson = JSON.parse(
664
+ fs4.readFileSync(`${root}/package.json`, "utf8")
665
+ );
666
+ packageJson.dependencies = dependencies.reduce((dep, elem) => {
667
+ const nextDep = dep;
668
+ if (/.+@(\^|~)?[0-9a-zA-Z-.]+$/.test(elem)) {
669
+ const [name, version] = elem.split("@");
670
+ nextDep[name] = `${version}`;
671
+ } else {
672
+ nextDep[elem] = "*";
673
+ }
674
+ return nextDep;
675
+ }, {});
676
+ packageJson.devDependencies = devDependencies.reduce((dep, elem) => {
677
+ const nextDep = dep;
678
+ if (/.+@(\^|~)?[0-9a-zA-Z-.]+$/.test(elem)) {
679
+ const [name, version] = elem.split("@");
680
+ nextDep[name] = `${version}`;
681
+ } else {
682
+ nextDep[elem] = "*";
683
+ }
684
+ return nextDep;
685
+ }, {});
686
+ fs4.writeFileSync(
687
+ path3.join(root, "package.json"),
688
+ JSON.stringify(packageJson, null, 2) + os3.EOL
689
+ );
690
+ }
691
+ spawn2("git", ["init"], {
692
+ cwd: root
693
+ });
694
+ if (installDependencies && isOnline) {
695
+ const packageJson = JSON.parse(
696
+ fs4.readFileSync(`${root}/package.json`, "utf8")
697
+ );
698
+ if (packageJson.scripts && packageJson.scripts["lint:fix"]) {
699
+ spawn2(runCommand, ["lint:fix"], { stdio: "inherit", cwd: root });
700
+ }
701
+ }
702
+ };
703
+ var createApp = async ({
704
+ name,
705
+ verbose = false,
706
+ useNpm = false,
707
+ addons = [],
708
+ alias = "",
709
+ installDependencies = true,
710
+ ignorePackage = false,
711
+ srcDir = ""
712
+ }) => {
713
+ const root = path3.resolve(name);
714
+ const appName = path3.basename(root);
715
+ fs4.mkdirSync(name, {
716
+ recursive: true
717
+ });
718
+ console.log(`Creating a new Node app in ${chalk3.green(root)}.`);
719
+ console.log();
720
+ const useYarn = useNpm ? false : shouldUseYarn();
721
+ const command = useYarn ? "yarn" : "npm run";
722
+ const { packageJson, dependencies, devDependencies } = await loadAddonsPackages({
723
+ addons,
724
+ appName,
725
+ command,
726
+ ignorePackage,
727
+ srcDir
728
+ });
729
+ fs4.writeFileSync(
730
+ path3.join(root, "package.json"),
731
+ JSON.stringify(packageJson, null, 2) + os3.EOL
732
+ );
733
+ const originalDirectory = process.cwd();
734
+ process.chdir(root);
735
+ if (!useYarn && !checkThatNpmCanReadCwd()) {
736
+ process.exit(1);
737
+ }
738
+ if (!semver2.satisfies(process.version, ">=16.0.0")) {
739
+ console.log(
740
+ chalk3.yellow(
741
+ `You are using Node ${process.version} so the project will be bootstrapped with an old unsupported version of tools.
742
+
743
+ Please update to Node 16 or higher for a better, fully supported experience.
744
+ `
745
+ )
746
+ );
747
+ }
748
+ if (!useYarn) {
749
+ const npmInfo = checkNpmVersion();
750
+ if (!npmInfo.hasMinNpm) {
751
+ if (npmInfo.npmVersion) {
752
+ console.log(
753
+ chalk3.yellow(
754
+ `You are using npm ${npmInfo.npmVersion} so the project will be bootstrapped with an old unsupported version of tools.
755
+
756
+ Please update to npm 3 or higher for a better, fully supported experience.
757
+ `
758
+ )
759
+ );
760
+ }
761
+ }
762
+ }
763
+ if (useYarn) {
764
+ let yarnUsesDefaultRegistry = true;
765
+ try {
766
+ yarnUsesDefaultRegistry = execSync2("yarnpkg config get registry").toString().trim() === "https://registry.yarnpkg.com";
767
+ } catch (e) {
768
+ }
769
+ if (false) {
770
+ fs4.cpSync(
771
+ __require.resolve("./yarn.lock.cached"),
772
+ path3.join(root, "yarn.lock"),
773
+ { force: true }
774
+ );
775
+ }
776
+ }
777
+ return run({
778
+ root,
779
+ appName,
780
+ originalDirectory,
781
+ verbose,
782
+ useYarn,
783
+ addons,
784
+ dependencies,
785
+ devDependencies,
786
+ alias,
787
+ installDependencies,
788
+ srcDir,
789
+ runCommand: command,
790
+ installCommand: useYarn ? "yarn" : "npm install"
791
+ });
792
+ };
793
+
794
+ // index.ts
795
+ var printEnvInfo = async () => {
796
+ console.log(chalk4.bold("\nEnvironment Info:"));
797
+ const info = await envinfo.run(
798
+ {
799
+ System: ["OS", "CPU"],
800
+ Binaries: ["Node", "npm", "Yarn"],
801
+ Browsers: ["Chrome", "Edge", "Internet Explorer", "Firefox", "Safari"]
802
+ },
803
+ {
804
+ duplicates: true,
805
+ showNotFound: true
806
+ }
807
+ );
808
+ console.log(info);
809
+ process.exit(0);
810
+ };
811
+ var createNodeApp = async (programName, options, transformOptions) => {
812
+ if (options.info) {
813
+ await printEnvInfo();
814
+ }
815
+ if (typeof options.projectName === "undefined") {
816
+ console.error("Please specify the project directory:");
817
+ console.log(
818
+ ` ${chalk4.cyan(programName)} ${chalk4.green("[project-directory]")}`
819
+ );
820
+ console.log();
821
+ console.log("For example:");
822
+ console.log(` ${chalk4.cyan(programName)} ${chalk4.green("my-app")}`);
823
+ console.log();
824
+ console.log(
825
+ `Run ${chalk4.cyan(`${programName} --help`)} to see all options.`
826
+ );
827
+ process.exit(1);
828
+ }
829
+ const appOptions = await transformOptions(options);
830
+ await createApp({
831
+ ...appOptions,
832
+ name: appOptions.projectName,
833
+ installDependencies: !options.nodeps
834
+ });
835
+ };
836
+ export {
837
+ createNodeApp,
838
+ printEnvInfo
839
+ };