create-m5kdev 0.4.1 → 0.5.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.
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var tslib_1 = require("tslib");
4
+ var node_child_process_1 = require("node:child_process");
5
+ var promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
6
+ var node_os_1 = tslib_1.__importDefault(require("node:os"));
7
+ var node_path_1 = tslib_1.__importDefault(require("node:path"));
8
+ var node_util_1 = require("node:util");
9
+ var create_1 = require("../create");
10
+ var execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
11
+ var maybeDescribe = process.env.CLI_SMOKE === "1" ? describe : describe.skip;
12
+ maybeDescribe("create command smoke test", function () {
13
+ var tempRoot = "";
14
+ var initialCwd = "";
15
+ beforeAll(function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
16
+ return tslib_1.__generator(this, function (_a) {
17
+ switch (_a.label) {
18
+ case 0:
19
+ initialCwd = process.cwd();
20
+ return [4 /*yield*/, promises_1.default.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), "m5kdev-cli-smoke-"))];
21
+ case 1:
22
+ tempRoot = _a.sent();
23
+ process.chdir(tempRoot);
24
+ return [2 /*return*/];
25
+ }
26
+ });
27
+ }); });
28
+ afterAll(function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
29
+ return tslib_1.__generator(this, function (_a) {
30
+ switch (_a.label) {
31
+ case 0:
32
+ process.chdir(initialCwd);
33
+ return [4 /*yield*/, promises_1.default.rm(tempRoot, { recursive: true, force: true })];
34
+ case 1:
35
+ _a.sent();
36
+ return [2 /*return*/];
37
+ }
38
+ });
39
+ }); });
40
+ it("scaffolds a project and runs the generated commands", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
41
+ var result;
42
+ return tslib_1.__generator(this, function (_a) {
43
+ switch (_a.label) {
44
+ case 0:
45
+ jest.setTimeout(10 * 60 * 1000);
46
+ return [4 /*yield*/, (0, create_1.scaffoldProject)({
47
+ targetDirectory: "smoke-app",
48
+ appName: "Smoke App",
49
+ appDescription: "Smoke test app",
50
+ yes: true,
51
+ force: false,
52
+ skipInstall: false,
53
+ skipGit: true,
54
+ })];
55
+ case 1:
56
+ result = _a.sent();
57
+ return [4 /*yield*/, execFileAsync("pnpm", ["check-types"], {
58
+ cwd: result.targetDirectory,
59
+ env: process.env,
60
+ })];
61
+ case 2:
62
+ _a.sent();
63
+ return [4 /*yield*/, execFileAsync("pnpm", ["lint"], {
64
+ cwd: result.targetDirectory,
65
+ env: process.env,
66
+ })];
67
+ case 3:
68
+ _a.sent();
69
+ return [4 /*yield*/, execFileAsync("pnpm", ["--filter", "./apps/server", "sync"], {
70
+ cwd: result.targetDirectory,
71
+ env: process.env,
72
+ })];
73
+ case 4:
74
+ _a.sent();
75
+ return [4 /*yield*/, execFileAsync("pnpm", ["--filter", "./apps/server", "build"], {
76
+ cwd: result.targetDirectory,
77
+ env: process.env,
78
+ })];
79
+ case 5:
80
+ _a.sent();
81
+ return [4 /*yield*/, execFileAsync("pnpm", ["--filter", "./apps/webapp", "build"], {
82
+ cwd: result.targetDirectory,
83
+ env: process.env,
84
+ })];
85
+ case 6:
86
+ _a.sent();
87
+ return [2 /*return*/];
88
+ }
89
+ });
90
+ }); });
91
+ });
@@ -0,0 +1,102 @@
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
+ });
@@ -0,0 +1,44 @@
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
+ });
@@ -0,0 +1,24 @@
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
+ });
@@ -0,0 +1,9 @@
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 ADDED
@@ -0,0 +1,54 @@
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 ADDED
@@ -0,0 +1,119 @@
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 ADDED
@@ -0,0 +1,9 @@
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 ADDED
@@ -0,0 +1,14 @@
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
+ }
@@ -0,0 +1,98 @@
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
+ }