create-m5kdev 0.7.0 → 0.8.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/src/constants.d.mts +7 -0
- package/dist/src/constants.mjs +10 -0
- package/dist/src/constants.mjs.map +1 -0
- package/dist/src/create.d.mts +12 -0
- package/dist/src/create.mjs +33 -0
- package/dist/src/create.mjs.map +1 -0
- package/dist/src/fs.d.mts +10 -0
- package/dist/src/fs.mjs +50 -0
- package/dist/src/fs.mjs.map +1 -0
- package/dist/src/index.d.mts +1 -0
- package/dist/src/index.mjs +12 -0
- package/dist/src/index.mjs.map +1 -0
- package/dist/src/paths.d.mts +5 -0
- package/dist/src/paths.mjs +13 -0
- package/dist/src/paths.mjs.map +1 -0
- package/dist/src/prompts.d.mts +7 -0
- package/dist/src/prompts.mjs +45 -0
- package/dist/src/prompts.mjs.map +1 -0
- package/dist/src/runCli.d.mts +12 -0
- package/dist/src/runCli.mjs +101 -0
- package/dist/src/runCli.mjs.map +1 -0
- package/dist/src/strings.d.mts +11 -0
- package/dist/src/strings.mjs +34 -0
- package/dist/src/strings.mjs.map +1 -0
- package/dist/src/types.d.mts +22 -0
- package/package.json +3 -2
- package/dist/__tests__/create.smoke.test.js +0 -91
- package/dist/__tests__/create.test.js +0 -102
- package/dist/__tests__/runCli.test.js +0 -44
- package/dist/__tests__/strings.test.js +0 -24
- package/dist/constants.js +0 -9
- package/dist/create.js +0 -54
- package/dist/fs.js +0 -119
- package/dist/index.js +0 -9
- package/dist/paths.js +0 -14
- package/dist/prompts.js +0 -98
- package/dist/runCli.js +0 -119
- package/dist/src/__tests__/create.smoke.test.js +0 -56
- package/dist/src/__tests__/create.test.d.ts +0 -1
- package/dist/src/__tests__/create.test.js +0 -55
- package/dist/src/__tests__/runCli.test.d.ts +0 -1
- package/dist/src/__tests__/runCli.test.js +0 -44
- package/dist/src/__tests__/strings.test.d.ts +0 -1
- package/dist/src/__tests__/strings.test.js +0 -24
- package/dist/src/constants.d.ts +0 -3
- package/dist/src/constants.js +0 -9
- package/dist/src/create.d.ts +0 -7
- package/dist/src/create.js +0 -36
- package/dist/src/fs.d.ts +0 -5
- package/dist/src/fs.js +0 -60
- package/dist/src/index.d.ts +0 -2
- package/dist/src/index.js +0 -9
- package/dist/src/paths.d.ts +0 -1
- package/dist/src/paths.js +0 -14
- package/dist/src/prompts.d.ts +0 -2
- package/dist/src/prompts.js +0 -55
- package/dist/src/runCli.d.ts +0 -9
- package/dist/src/runCli.js +0 -107
- package/dist/src/strings.d.ts +0 -6
- package/dist/src/strings.js +0 -47
- package/dist/src/types.d.ts +0 -18
- package/dist/src/types.js +0 -2
- package/dist/strings.js +0 -47
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/types.js +0 -2
- /package/dist/src/{__tests__/create.smoke.test.d.ts → types.mjs} +0 -0
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var tslib_1 = require("tslib");
|
|
4
|
-
var promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
|
|
5
|
-
var node_os_1 = tslib_1.__importDefault(require("node:os"));
|
|
6
|
-
var node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
7
|
-
var create_1 = require("../create");
|
|
8
|
-
describe("scaffoldProject", function () {
|
|
9
|
-
var tempRoot = "";
|
|
10
|
-
var initialCwd = "";
|
|
11
|
-
beforeEach(function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
12
|
-
return tslib_1.__generator(this, function (_a) {
|
|
13
|
-
switch (_a.label) {
|
|
14
|
-
case 0:
|
|
15
|
-
initialCwd = process.cwd();
|
|
16
|
-
return [4 /*yield*/, promises_1.default.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), "m5kdev-cli-"))];
|
|
17
|
-
case 1:
|
|
18
|
-
tempRoot = _a.sent();
|
|
19
|
-
process.chdir(tempRoot);
|
|
20
|
-
return [2 /*return*/];
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
}); });
|
|
24
|
-
afterEach(function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
25
|
-
return tslib_1.__generator(this, function (_a) {
|
|
26
|
-
switch (_a.label) {
|
|
27
|
-
case 0:
|
|
28
|
-
process.chdir(initialCwd);
|
|
29
|
-
return [4 /*yield*/, promises_1.default.rm(tempRoot, { recursive: true, force: true })];
|
|
30
|
-
case 1:
|
|
31
|
-
_a.sent();
|
|
32
|
-
return [2 /*return*/];
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}); });
|
|
36
|
-
it("creates the minimal starter and replaces placeholders", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
37
|
-
var result, rootPackage, rootAgents, sharedEnv;
|
|
38
|
-
return tslib_1.__generator(this, function (_a) {
|
|
39
|
-
switch (_a.label) {
|
|
40
|
-
case 0: return [4 /*yield*/, (0, create_1.scaffoldProject)({
|
|
41
|
-
targetDirectory: "editorial-desk",
|
|
42
|
-
appName: "Editorial Desk",
|
|
43
|
-
appDescription: "A clean newsroom starter.",
|
|
44
|
-
yes: true,
|
|
45
|
-
force: false,
|
|
46
|
-
skipInstall: true,
|
|
47
|
-
skipGit: true,
|
|
48
|
-
})];
|
|
49
|
-
case 1:
|
|
50
|
-
result = _a.sent();
|
|
51
|
-
return [4 /*yield*/, expect(promises_1.default.stat(node_path_1.default.join(result.targetDirectory, "AGENTS.md"))).resolves.toBeTruthy()];
|
|
52
|
-
case 2:
|
|
53
|
-
_a.sent();
|
|
54
|
-
return [4 /*yield*/, expect(promises_1.default.stat(node_path_1.default.join(result.targetDirectory, "apps/server/src/modules/posts/posts.service.ts"))).resolves.toBeTruthy()];
|
|
55
|
-
case 3:
|
|
56
|
-
_a.sent();
|
|
57
|
-
return [4 /*yield*/, expect(promises_1.default.stat(node_path_1.default.join(result.targetDirectory, "apps/webapp/src/modules/posts/PostsRoute.tsx"))).resolves.toBeTruthy()];
|
|
58
|
-
case 4:
|
|
59
|
-
_a.sent();
|
|
60
|
-
return [4 /*yield*/, promises_1.default.readFile(node_path_1.default.join(result.targetDirectory, "package.json"), "utf8")];
|
|
61
|
-
case 5:
|
|
62
|
-
rootPackage = _a.sent();
|
|
63
|
-
return [4 /*yield*/, promises_1.default.readFile(node_path_1.default.join(result.targetDirectory, "AGENTS.md"), "utf8")];
|
|
64
|
-
case 6:
|
|
65
|
-
rootAgents = _a.sent();
|
|
66
|
-
return [4 /*yield*/, promises_1.default.readFile(node_path_1.default.join(result.targetDirectory, "apps/shared/.env"), "utf8")];
|
|
67
|
-
case 7:
|
|
68
|
-
sharedEnv = _a.sent();
|
|
69
|
-
expect(rootPackage).toContain("\"name\": \"editorial-desk\"");
|
|
70
|
-
expect(rootAgents).toContain("Editorial Desk");
|
|
71
|
-
expect(rootAgents).toContain("A clean newsroom starter.");
|
|
72
|
-
expect(sharedEnv).toContain("VITE_APP_NAME=Editorial Desk");
|
|
73
|
-
expect(sharedEnv).not.toContain("{{APP_NAME}}");
|
|
74
|
-
return [2 /*return*/];
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}); });
|
|
78
|
-
it("refuses to overwrite a non-empty directory without force", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
79
|
-
return tslib_1.__generator(this, function (_a) {
|
|
80
|
-
switch (_a.label) {
|
|
81
|
-
case 0: return [4 /*yield*/, promises_1.default.mkdir(node_path_1.default.join(tempRoot, "occupied"), { recursive: true })];
|
|
82
|
-
case 1:
|
|
83
|
-
_a.sent();
|
|
84
|
-
return [4 /*yield*/, promises_1.default.writeFile(node_path_1.default.join(tempRoot, "occupied", "README.md"), "taken", "utf8")];
|
|
85
|
-
case 2:
|
|
86
|
-
_a.sent();
|
|
87
|
-
return [4 /*yield*/, expect((0, create_1.scaffoldProject)({
|
|
88
|
-
targetDirectory: "occupied",
|
|
89
|
-
appName: "Occupied",
|
|
90
|
-
appDescription: "Collision test",
|
|
91
|
-
yes: true,
|
|
92
|
-
force: false,
|
|
93
|
-
skipInstall: true,
|
|
94
|
-
skipGit: true,
|
|
95
|
-
})).rejects.toThrow("Target directory is not empty")];
|
|
96
|
-
case 3:
|
|
97
|
-
_a.sent();
|
|
98
|
-
return [2 /*return*/];
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}); });
|
|
102
|
-
});
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var runCli_1 = require("../runCli");
|
|
4
|
-
describe("parseCli", function () {
|
|
5
|
-
it("parses the explicit create command", function () {
|
|
6
|
-
expect((0, runCli_1.parseCli)(["create", "blog-app", "--name", "Blog App"])).toEqual({
|
|
7
|
-
command: "create",
|
|
8
|
-
directory: "blog-app",
|
|
9
|
-
help: false,
|
|
10
|
-
options: {
|
|
11
|
-
name: "Blog App",
|
|
12
|
-
},
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
it("treats a bare directory as the create command", function () {
|
|
16
|
-
expect((0, runCli_1.parseCli)(["blog-app", "--description", "Starter app"])).toEqual({
|
|
17
|
-
command: "create",
|
|
18
|
-
directory: "blog-app",
|
|
19
|
-
help: false,
|
|
20
|
-
options: {
|
|
21
|
-
description: "Starter app",
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
it("treats flag-only input as the create command", function () {
|
|
26
|
-
expect((0, runCli_1.parseCli)(["--name", "Blog App", "--yes"])).toEqual({
|
|
27
|
-
command: "create",
|
|
28
|
-
directory: undefined,
|
|
29
|
-
help: false,
|
|
30
|
-
options: {
|
|
31
|
-
name: "Blog App",
|
|
32
|
-
yes: true,
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
it("recognizes help in create mode", function () {
|
|
37
|
-
expect((0, runCli_1.parseCli)(["create", "--help"])).toEqual({
|
|
38
|
-
command: "create",
|
|
39
|
-
directory: undefined,
|
|
40
|
-
help: true,
|
|
41
|
-
options: {},
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var strings_1 = require("../strings");
|
|
4
|
-
describe("string helpers", function () {
|
|
5
|
-
it("slugifies app names into kebab-case", function () {
|
|
6
|
-
expect((0, strings_1.slugifyAppName)(" Editorial Desk ")).toBe("editorial-desk");
|
|
7
|
-
expect((0, strings_1.slugifyAppName)("M5 / Blog --- Starter")).toBe("m5-blog-starter");
|
|
8
|
-
});
|
|
9
|
-
it("derives a scoped package name", function () {
|
|
10
|
-
expect((0, strings_1.derivePackageScope)("editorial-desk")).toBe("@editorial-desk");
|
|
11
|
-
});
|
|
12
|
-
it("renders template placeholders", function () {
|
|
13
|
-
expect((0, strings_1.renderTemplate)("Hello {{APP_NAME}} from {{PACKAGE_SCOPE}}", {
|
|
14
|
-
appName: "Editorial Desk",
|
|
15
|
-
appDescription: "A test app",
|
|
16
|
-
appSlug: "editorial-desk",
|
|
17
|
-
packageScope: "@editorial-desk",
|
|
18
|
-
betterAuthSecret: "secret",
|
|
19
|
-
})).toBe("Hello Editorial Desk from @editorial-desk");
|
|
20
|
-
});
|
|
21
|
-
it("creates non-empty auth secrets", function () {
|
|
22
|
-
expect((0, strings_1.createBetterAuthSecret)()).toHaveLength(32);
|
|
23
|
-
});
|
|
24
|
-
});
|
package/dist/constants.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_APP_NAME = exports.TEMPLATE_NAME = void 0;
|
|
4
|
-
exports.getDefaultDescription = getDefaultDescription;
|
|
5
|
-
exports.TEMPLATE_NAME = "minimal-app";
|
|
6
|
-
exports.DEFAULT_APP_NAME = "M5 Starter";
|
|
7
|
-
function getDefaultDescription(appName) {
|
|
8
|
-
return "".concat(appName, " is a blog publishing platform scaffolded with the m5kdev stack.");
|
|
9
|
-
}
|
package/dist/create.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.scaffoldProject = scaffoldProject;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
|
-
var node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
6
|
-
var constants_1 = require("./constants");
|
|
7
|
-
var fs_1 = require("./fs");
|
|
8
|
-
var paths_1 = require("./paths");
|
|
9
|
-
var prompts_1 = require("./prompts");
|
|
10
|
-
var strings_1 = require("./strings");
|
|
11
|
-
function scaffoldProject(initialOptions) {
|
|
12
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
13
|
-
var options, appSlug, targetDirectory, templateDirectory, context;
|
|
14
|
-
return tslib_1.__generator(this, function (_a) {
|
|
15
|
-
switch (_a.label) {
|
|
16
|
-
case 0: return [4 /*yield*/, (0, prompts_1.resolveCreateCommandOptions)(initialOptions)];
|
|
17
|
-
case 1:
|
|
18
|
-
options = _a.sent();
|
|
19
|
-
appSlug = (0, strings_1.slugifyAppName)(options.appName);
|
|
20
|
-
targetDirectory = node_path_1.default.resolve(process.cwd(), options.targetDirectory);
|
|
21
|
-
templateDirectory = (0, paths_1.getTemplateRoot)();
|
|
22
|
-
context = {
|
|
23
|
-
appName: options.appName,
|
|
24
|
-
appDescription: options.appDescription,
|
|
25
|
-
appSlug: appSlug,
|
|
26
|
-
packageScope: (0, strings_1.derivePackageScope)(appSlug),
|
|
27
|
-
betterAuthSecret: (0, strings_1.createBetterAuthSecret)(),
|
|
28
|
-
};
|
|
29
|
-
return [4 /*yield*/, (0, fs_1.ensureDirectoryState)(targetDirectory, options.force)];
|
|
30
|
-
case 2:
|
|
31
|
-
_a.sent();
|
|
32
|
-
return [4 /*yield*/, (0, fs_1.copyTemplateDirectory)(templateDirectory, targetDirectory, context)];
|
|
33
|
-
case 3:
|
|
34
|
-
_a.sent();
|
|
35
|
-
if (!!options.skipGit) return [3 /*break*/, 5];
|
|
36
|
-
return [4 /*yield*/, (0, fs_1.runGitInit)(targetDirectory)];
|
|
37
|
-
case 4:
|
|
38
|
-
_a.sent();
|
|
39
|
-
_a.label = 5;
|
|
40
|
-
case 5:
|
|
41
|
-
if (!!options.skipInstall) return [3 /*break*/, 7];
|
|
42
|
-
return [4 /*yield*/, (0, fs_1.runInstall)(targetDirectory)];
|
|
43
|
-
case 6:
|
|
44
|
-
_a.sent();
|
|
45
|
-
_a.label = 7;
|
|
46
|
-
case 7: return [2 /*return*/, {
|
|
47
|
-
context: context,
|
|
48
|
-
targetDirectory: targetDirectory,
|
|
49
|
-
templateName: constants_1.TEMPLATE_NAME,
|
|
50
|
-
}];
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
}
|
package/dist/fs.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ensureDirectoryState = ensureDirectoryState;
|
|
4
|
-
exports.copyTemplateDirectory = copyTemplateDirectory;
|
|
5
|
-
exports.runInstall = runInstall;
|
|
6
|
-
exports.runGitInit = runGitInit;
|
|
7
|
-
var tslib_1 = require("tslib");
|
|
8
|
-
var node_child_process_1 = require("node:child_process");
|
|
9
|
-
var promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
|
|
10
|
-
var node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
11
|
-
var node_util_1 = require("node:util");
|
|
12
|
-
var strings_1 = require("./strings");
|
|
13
|
-
var execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
14
|
-
var TEMPLATE_LINE_ENDING = "\r\n";
|
|
15
|
-
function ensureDirectoryState(targetDirectory, force) {
|
|
16
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
17
|
-
var stat, entries;
|
|
18
|
-
return tslib_1.__generator(this, function (_a) {
|
|
19
|
-
switch (_a.label) {
|
|
20
|
-
case 0: return [4 /*yield*/, promises_1.default.stat(targetDirectory).catch(function () { return null; })];
|
|
21
|
-
case 1:
|
|
22
|
-
stat = _a.sent();
|
|
23
|
-
if (!!stat) return [3 /*break*/, 3];
|
|
24
|
-
return [4 /*yield*/, promises_1.default.mkdir(targetDirectory, { recursive: true })];
|
|
25
|
-
case 2:
|
|
26
|
-
_a.sent();
|
|
27
|
-
return [2 /*return*/];
|
|
28
|
-
case 3:
|
|
29
|
-
if (!stat.isDirectory()) {
|
|
30
|
-
throw new Error("Target path is not a directory: ".concat(targetDirectory));
|
|
31
|
-
}
|
|
32
|
-
return [4 /*yield*/, promises_1.default.readdir(targetDirectory)];
|
|
33
|
-
case 4:
|
|
34
|
-
entries = _a.sent();
|
|
35
|
-
if (entries.length > 0 && !force) {
|
|
36
|
-
throw new Error("Target directory is not empty: ".concat(targetDirectory, ". Re-run with --force to overwrite."));
|
|
37
|
-
}
|
|
38
|
-
return [2 /*return*/];
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
function copyTemplateDirectory(templateDirectory, targetDirectory, context) {
|
|
44
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
45
|
-
var entries, _i, entries_1, entry, sourcePath, targetName, targetPath, content, rendered;
|
|
46
|
-
return tslib_1.__generator(this, function (_a) {
|
|
47
|
-
switch (_a.label) {
|
|
48
|
-
case 0: return [4 /*yield*/, promises_1.default.readdir(templateDirectory, { withFileTypes: true })];
|
|
49
|
-
case 1:
|
|
50
|
-
entries = _a.sent();
|
|
51
|
-
_i = 0, entries_1 = entries;
|
|
52
|
-
_a.label = 2;
|
|
53
|
-
case 2:
|
|
54
|
-
if (!(_i < entries_1.length)) return [3 /*break*/, 10];
|
|
55
|
-
entry = entries_1[_i];
|
|
56
|
-
sourcePath = node_path_1.default.join(templateDirectory, entry.name);
|
|
57
|
-
targetName = entry.name.endsWith(".tpl") ? entry.name.slice(0, -4) : entry.name;
|
|
58
|
-
targetPath = node_path_1.default.join(targetDirectory, targetName);
|
|
59
|
-
if (!entry.isDirectory()) return [3 /*break*/, 5];
|
|
60
|
-
return [4 /*yield*/, promises_1.default.mkdir(targetPath, { recursive: true })];
|
|
61
|
-
case 3:
|
|
62
|
-
_a.sent();
|
|
63
|
-
return [4 /*yield*/, copyTemplateDirectory(sourcePath, targetPath, context)];
|
|
64
|
-
case 4:
|
|
65
|
-
_a.sent();
|
|
66
|
-
return [3 /*break*/, 9];
|
|
67
|
-
case 5:
|
|
68
|
-
if (!entry.isFile()) {
|
|
69
|
-
return [3 /*break*/, 9];
|
|
70
|
-
}
|
|
71
|
-
return [4 /*yield*/, promises_1.default.readFile(sourcePath, "utf8")];
|
|
72
|
-
case 6:
|
|
73
|
-
content = _a.sent();
|
|
74
|
-
rendered = (0, strings_1.renderTemplate)(content, context).replace(/\r?\n/g, TEMPLATE_LINE_ENDING);
|
|
75
|
-
return [4 /*yield*/, promises_1.default.mkdir(node_path_1.default.dirname(targetPath), { recursive: true })];
|
|
76
|
-
case 7:
|
|
77
|
-
_a.sent();
|
|
78
|
-
return [4 /*yield*/, promises_1.default.writeFile(targetPath, rendered, "utf8")];
|
|
79
|
-
case 8:
|
|
80
|
-
_a.sent();
|
|
81
|
-
_a.label = 9;
|
|
82
|
-
case 9:
|
|
83
|
-
_i++;
|
|
84
|
-
return [3 /*break*/, 2];
|
|
85
|
-
case 10: return [2 /*return*/];
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
function runInstall(targetDirectory) {
|
|
91
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
92
|
-
return tslib_1.__generator(this, function (_a) {
|
|
93
|
-
switch (_a.label) {
|
|
94
|
-
case 0: return [4 /*yield*/, execFileAsync("pnpm", ["install"], {
|
|
95
|
-
cwd: targetDirectory,
|
|
96
|
-
env: process.env,
|
|
97
|
-
})];
|
|
98
|
-
case 1:
|
|
99
|
-
_a.sent();
|
|
100
|
-
return [2 /*return*/];
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
function runGitInit(targetDirectory) {
|
|
106
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
107
|
-
return tslib_1.__generator(this, function (_a) {
|
|
108
|
-
switch (_a.label) {
|
|
109
|
-
case 0: return [4 /*yield*/, execFileAsync("git", ["init"], {
|
|
110
|
-
cwd: targetDirectory,
|
|
111
|
-
env: process.env,
|
|
112
|
-
})];
|
|
113
|
-
case 1:
|
|
114
|
-
_a.sent();
|
|
115
|
-
return [2 /*return*/];
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
}
|
package/dist/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
var runCli_1 = require("./runCli");
|
|
5
|
-
(0, runCli_1.runCli)(process.argv.slice(2)).catch(function (error) {
|
|
6
|
-
var message = error instanceof Error ? error.message : String(error);
|
|
7
|
-
console.error(message);
|
|
8
|
-
process.exitCode = 1;
|
|
9
|
-
});
|
package/dist/paths.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getTemplateRoot = getTemplateRoot;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
|
-
var node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
6
|
-
var node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
7
|
-
var constants_1 = require("./constants");
|
|
8
|
-
function getTemplateRoot() {
|
|
9
|
-
var sourcePath = node_path_1.default.resolve(__dirname, "../templates", constants_1.TEMPLATE_NAME);
|
|
10
|
-
if (node_fs_1.default.existsSync(sourcePath)) {
|
|
11
|
-
return sourcePath;
|
|
12
|
-
}
|
|
13
|
-
return node_path_1.default.resolve(__dirname, "../../templates", constants_1.TEMPLATE_NAME);
|
|
14
|
-
}
|
package/dist/prompts.js
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveCreateCommandOptions = resolveCreateCommandOptions;
|
|
4
|
-
var tslib_1 = require("tslib");
|
|
5
|
-
var promises_1 = tslib_1.__importDefault(require("node:readline/promises"));
|
|
6
|
-
var node_process_1 = require("node:process");
|
|
7
|
-
var constants_1 = require("./constants");
|
|
8
|
-
var strings_1 = require("./strings");
|
|
9
|
-
function requireInteractive(yes) {
|
|
10
|
-
if (!yes && !process.stdin.isTTY) {
|
|
11
|
-
throw new Error("Missing required values in a non-interactive shell. Pass --yes or provide flags.");
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
function promptValue(question, fallback) {
|
|
15
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
16
|
-
var rl, suffix, response;
|
|
17
|
-
return tslib_1.__generator(this, function (_a) {
|
|
18
|
-
switch (_a.label) {
|
|
19
|
-
case 0:
|
|
20
|
-
rl = promises_1.default.createInterface({ input: node_process_1.stdin, output: node_process_1.stdout });
|
|
21
|
-
_a.label = 1;
|
|
22
|
-
case 1:
|
|
23
|
-
_a.trys.push([1, , 3, 4]);
|
|
24
|
-
suffix = fallback ? " (".concat(fallback, ")") : "";
|
|
25
|
-
return [4 /*yield*/, rl.question("".concat(question).concat(suffix, ": "))];
|
|
26
|
-
case 2:
|
|
27
|
-
response = _a.sent();
|
|
28
|
-
return [2 /*return*/, response.trim() || fallback || ""];
|
|
29
|
-
case 3:
|
|
30
|
-
rl.close();
|
|
31
|
-
return [7 /*endfinally*/];
|
|
32
|
-
case 4: return [2 /*return*/];
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
function resolveCreateCommandOptions(options) {
|
|
38
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
39
|
-
var resolved, _a, _b, _c, _d, fallback, _e, _f;
|
|
40
|
-
return tslib_1.__generator(this, function (_g) {
|
|
41
|
-
switch (_g.label) {
|
|
42
|
-
case 0:
|
|
43
|
-
resolved = tslib_1.__assign({}, options);
|
|
44
|
-
if (!!resolved.appName) return [3 /*break*/, 4];
|
|
45
|
-
requireInteractive(resolved.yes);
|
|
46
|
-
_a = resolved;
|
|
47
|
-
if (!resolved.yes) return [3 /*break*/, 1];
|
|
48
|
-
_b = resolved.targetDirectory
|
|
49
|
-
? (0, strings_1.toDisplayName)(pathBaseName(resolved.targetDirectory))
|
|
50
|
-
: constants_1.DEFAULT_APP_NAME;
|
|
51
|
-
return [3 /*break*/, 3];
|
|
52
|
-
case 1: return [4 /*yield*/, promptValue("App name", resolved.targetDirectory ? pathBaseName(resolved.targetDirectory) : constants_1.DEFAULT_APP_NAME)];
|
|
53
|
-
case 2:
|
|
54
|
-
_b = _g.sent();
|
|
55
|
-
_g.label = 3;
|
|
56
|
-
case 3:
|
|
57
|
-
_a.appName = _b;
|
|
58
|
-
_g.label = 4;
|
|
59
|
-
case 4:
|
|
60
|
-
resolved.appName = (0, strings_1.toDisplayName)(resolved.appName);
|
|
61
|
-
if (!!resolved.targetDirectory) return [3 /*break*/, 8];
|
|
62
|
-
requireInteractive(resolved.yes);
|
|
63
|
-
_c = resolved;
|
|
64
|
-
if (!resolved.yes) return [3 /*break*/, 5];
|
|
65
|
-
_d = (0, strings_1.slugifyAppName)(resolved.appName);
|
|
66
|
-
return [3 /*break*/, 7];
|
|
67
|
-
case 5: return [4 /*yield*/, promptValue("Target directory", (0, strings_1.slugifyAppName)(resolved.appName))];
|
|
68
|
-
case 6:
|
|
69
|
-
_d = _g.sent();
|
|
70
|
-
_g.label = 7;
|
|
71
|
-
case 7:
|
|
72
|
-
_c.targetDirectory = _d;
|
|
73
|
-
_g.label = 8;
|
|
74
|
-
case 8:
|
|
75
|
-
if (!!resolved.appDescription) return [3 /*break*/, 12];
|
|
76
|
-
requireInteractive(resolved.yes);
|
|
77
|
-
fallback = (0, constants_1.getDefaultDescription)(resolved.appName);
|
|
78
|
-
_e = resolved;
|
|
79
|
-
if (!resolved.yes) return [3 /*break*/, 9];
|
|
80
|
-
_f = fallback;
|
|
81
|
-
return [3 /*break*/, 11];
|
|
82
|
-
case 9: return [4 /*yield*/, promptValue("App description", fallback)];
|
|
83
|
-
case 10:
|
|
84
|
-
_f = _g.sent();
|
|
85
|
-
_g.label = 11;
|
|
86
|
-
case 11:
|
|
87
|
-
_e.appDescription = _f;
|
|
88
|
-
_g.label = 12;
|
|
89
|
-
case 12: return [2 /*return*/, resolved];
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
function pathBaseName(value) {
|
|
95
|
-
var normalized = value.replace(/[\\/]+$/g, "");
|
|
96
|
-
var segments = normalized.split(/[\\/]/).filter(Boolean);
|
|
97
|
-
return segments.at(-1) || constants_1.DEFAULT_APP_NAME;
|
|
98
|
-
}
|
package/dist/runCli.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.runCli = runCli;
|
|
4
|
-
exports.parseCli = parseCli;
|
|
5
|
-
var tslib_1 = require("tslib");
|
|
6
|
-
var create_1 = require("./create");
|
|
7
|
-
function runCli(argv) {
|
|
8
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
9
|
-
var parsed, options, result;
|
|
10
|
-
return tslib_1.__generator(this, function (_a) {
|
|
11
|
-
switch (_a.label) {
|
|
12
|
-
case 0:
|
|
13
|
-
parsed = parseCli(argv);
|
|
14
|
-
if (!parsed.command ||
|
|
15
|
-
parsed.help ||
|
|
16
|
-
parsed.command === "--help" ||
|
|
17
|
-
parsed.command === "-h" ||
|
|
18
|
-
parsed.command === "help") {
|
|
19
|
-
printHelp();
|
|
20
|
-
return [2 /*return*/];
|
|
21
|
-
}
|
|
22
|
-
if (parsed.command !== "create") {
|
|
23
|
-
throw new Error("Unknown command: ".concat(parsed.command));
|
|
24
|
-
}
|
|
25
|
-
options = toCreateCommandOptions(parsed);
|
|
26
|
-
return [4 /*yield*/, (0, create_1.scaffoldProject)(options)];
|
|
27
|
-
case 1:
|
|
28
|
-
result = _a.sent();
|
|
29
|
-
console.log("");
|
|
30
|
-
console.log("Scaffolded ".concat(result.context.appName, " in ").concat(result.targetDirectory));
|
|
31
|
-
console.log("");
|
|
32
|
-
console.log("Next steps:");
|
|
33
|
-
console.log(" cd ".concat(result.targetDirectory));
|
|
34
|
-
if (options.skipInstall) {
|
|
35
|
-
console.log(" pnpm install");
|
|
36
|
-
}
|
|
37
|
-
console.log(" pnpm --filter ./apps/server sync");
|
|
38
|
-
console.log(" pnpm dev");
|
|
39
|
-
return [2 /*return*/];
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
function parseCli(argv) {
|
|
45
|
-
var normalizedArgv = normalizeCliArgv(argv);
|
|
46
|
-
var command = normalizedArgv[0], rest = normalizedArgv.slice(1);
|
|
47
|
-
var options = {};
|
|
48
|
-
var directory;
|
|
49
|
-
var help = false;
|
|
50
|
-
for (var index = 0; index < rest.length; index += 1) {
|
|
51
|
-
var token = rest[index];
|
|
52
|
-
if (token === "--help" || token === "-h") {
|
|
53
|
-
help = true;
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
if (!token.startsWith("--")) {
|
|
57
|
-
directory !== null && directory !== void 0 ? directory : (directory = token);
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
var _a = token.slice(2).split("=", 2), rawKey = _a[0], inlineValue = _a[1];
|
|
61
|
-
if (isBooleanFlag(rawKey)) {
|
|
62
|
-
options[rawKey] = true;
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
var nextValue = inlineValue !== null && inlineValue !== void 0 ? inlineValue : rest[index + 1];
|
|
66
|
-
if (!nextValue || nextValue.startsWith("--")) {
|
|
67
|
-
throw new Error("Missing value for --".concat(rawKey));
|
|
68
|
-
}
|
|
69
|
-
options[rawKey] = nextValue;
|
|
70
|
-
if (inlineValue === undefined) {
|
|
71
|
-
index += 1;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return { command: command, directory: directory, help: help, options: options };
|
|
75
|
-
}
|
|
76
|
-
function normalizeCliArgv(argv) {
|
|
77
|
-
var firstToken = argv[0];
|
|
78
|
-
if (!firstToken || firstToken === "create" || firstToken === "--help" || firstToken === "-h") {
|
|
79
|
-
return argv;
|
|
80
|
-
}
|
|
81
|
-
if (firstToken === "help") {
|
|
82
|
-
return ["--help"];
|
|
83
|
-
}
|
|
84
|
-
return tslib_1.__spreadArray(["create"], argv, true);
|
|
85
|
-
}
|
|
86
|
-
function isBooleanFlag(value) {
|
|
87
|
-
return ["yes", "force", "skip-install", "skip-git"].includes(value);
|
|
88
|
-
}
|
|
89
|
-
function toCreateCommandOptions(parsed) {
|
|
90
|
-
return {
|
|
91
|
-
targetDirectory: parsed.directory,
|
|
92
|
-
appName: getStringOption(parsed.options, "name"),
|
|
93
|
-
appDescription: getStringOption(parsed.options, "description"),
|
|
94
|
-
yes: Boolean(parsed.options.yes),
|
|
95
|
-
force: Boolean(parsed.options.force),
|
|
96
|
-
skipInstall: Boolean(parsed.options["skip-install"]),
|
|
97
|
-
skipGit: Boolean(parsed.options["skip-git"]),
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
function getStringOption(options, key) {
|
|
101
|
-
var value = options[key];
|
|
102
|
-
return typeof value === "string" ? value : undefined;
|
|
103
|
-
}
|
|
104
|
-
function printHelp() {
|
|
105
|
-
console.log("m5kdev");
|
|
106
|
-
console.log("");
|
|
107
|
-
console.log("Usage:");
|
|
108
|
-
console.log(" pnpm create m5kdev [directory] [options]");
|
|
109
|
-
console.log(" m5kdev [directory] [options]");
|
|
110
|
-
console.log(" m5kdev create [directory] [options]");
|
|
111
|
-
console.log("");
|
|
112
|
-
console.log("Options:");
|
|
113
|
-
console.log(" --name <value> Set the app name");
|
|
114
|
-
console.log(" --description <value> Set the app description");
|
|
115
|
-
console.log(" --yes Accept defaults for missing prompts");
|
|
116
|
-
console.log(" --force Allow writing into a non-empty directory");
|
|
117
|
-
console.log(" --skip-install Skip pnpm install");
|
|
118
|
-
console.log(" --skip-git Skip git init");
|
|
119
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const node_child_process_1 = require("node:child_process");
|
|
5
|
-
const promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
|
|
6
|
-
const node_os_1 = tslib_1.__importDefault(require("node:os"));
|
|
7
|
-
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
8
|
-
const node_util_1 = require("node:util");
|
|
9
|
-
const create_1 = require("../create");
|
|
10
|
-
const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
11
|
-
const maybeDescribe = process.env.CLI_SMOKE === "1" ? describe : describe.skip;
|
|
12
|
-
maybeDescribe("create command smoke test", () => {
|
|
13
|
-
let tempRoot = "";
|
|
14
|
-
let initialCwd = "";
|
|
15
|
-
beforeAll(async () => {
|
|
16
|
-
initialCwd = process.cwd();
|
|
17
|
-
tempRoot = await promises_1.default.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), "m5kdev-cli-smoke-"));
|
|
18
|
-
process.chdir(tempRoot);
|
|
19
|
-
});
|
|
20
|
-
afterAll(async () => {
|
|
21
|
-
process.chdir(initialCwd);
|
|
22
|
-
await promises_1.default.rm(tempRoot, { recursive: true, force: true });
|
|
23
|
-
});
|
|
24
|
-
it("scaffolds a project and runs the generated commands", async () => {
|
|
25
|
-
jest.setTimeout(10 * 60 * 1000);
|
|
26
|
-
const result = await (0, create_1.scaffoldProject)({
|
|
27
|
-
targetDirectory: "smoke-app",
|
|
28
|
-
appName: "Smoke App",
|
|
29
|
-
appDescription: "Smoke test app",
|
|
30
|
-
yes: true,
|
|
31
|
-
force: false,
|
|
32
|
-
skipInstall: false,
|
|
33
|
-
skipGit: true,
|
|
34
|
-
});
|
|
35
|
-
await execFileAsync("pnpm", ["check-types"], {
|
|
36
|
-
cwd: result.targetDirectory,
|
|
37
|
-
env: process.env,
|
|
38
|
-
});
|
|
39
|
-
await execFileAsync("pnpm", ["lint"], {
|
|
40
|
-
cwd: result.targetDirectory,
|
|
41
|
-
env: process.env,
|
|
42
|
-
});
|
|
43
|
-
await execFileAsync("pnpm", ["--filter", "./apps/server", "sync"], {
|
|
44
|
-
cwd: result.targetDirectory,
|
|
45
|
-
env: process.env,
|
|
46
|
-
});
|
|
47
|
-
await execFileAsync("pnpm", ["--filter", "./apps/server", "build"], {
|
|
48
|
-
cwd: result.targetDirectory,
|
|
49
|
-
env: process.env,
|
|
50
|
-
});
|
|
51
|
-
await execFileAsync("pnpm", ["--filter", "./apps/webapp", "build"], {
|
|
52
|
-
cwd: result.targetDirectory,
|
|
53
|
-
env: process.env,
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|