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