create-m5kdev 0.21.5 → 0.21.6
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/_virtual/_rolldown/runtime.cjs +23 -0
- package/dist/src/constants.cjs +13 -0
- package/dist/src/{constants.mjs.map → constants.cjs.map} +1 -1
- package/dist/src/{constants.d.mts → constants.d.cts} +1 -1
- package/dist/src/create.cjs +36 -0
- package/dist/src/create.cjs.map +1 -0
- package/dist/src/{create.d.mts → create.d.cts} +2 -2
- package/dist/src/fs.cjs +56 -0
- package/dist/src/fs.cjs.map +1 -0
- package/dist/src/{fs.d.mts → fs.d.cts} +2 -2
- package/dist/src/{index.mjs → index.cjs} +2 -4
- package/dist/src/index.cjs.map +1 -0
- package/dist/src/paths.cjs +17 -0
- package/dist/src/paths.cjs.map +1 -0
- package/dist/src/{paths.d.mts → paths.d.cts} +1 -1
- package/dist/src/prompts.cjs +48 -0
- package/dist/src/prompts.cjs.map +1 -0
- package/dist/src/{prompts.d.mts → prompts.d.cts} +2 -2
- package/dist/src/{runCli.mjs → runCli.cjs} +6 -4
- package/dist/src/runCli.cjs.map +1 -0
- package/dist/src/{runCli.d.mts → runCli.d.cts} +1 -1
- package/dist/src/{strings.mjs → strings.cjs} +10 -4
- package/dist/src/{strings.mjs.map → strings.cjs.map} +1 -1
- package/dist/src/{strings.d.mts → strings.d.cts} +2 -2
- package/dist/src/types.cjs +0 -0
- package/dist/src/{types.d.mts → types.d.cts} +1 -1
- package/package.json +1 -1
- package/dist/src/constants.mjs +0 -10
- package/dist/src/create.mjs +0 -33
- package/dist/src/create.mjs.map +0 -1
- package/dist/src/fs.mjs +0 -50
- package/dist/src/fs.mjs.map +0 -1
- package/dist/src/index.mjs.map +0 -1
- package/dist/src/paths.mjs +0 -13
- package/dist/src/paths.mjs.map +0 -1
- package/dist/src/prompts.mjs +0 -45
- package/dist/src/prompts.mjs.map +0 -1
- package/dist/src/runCli.mjs.map +0 -1
- package/dist/src/types.mjs +0 -1
- /package/dist/src/{index.d.mts → index.d.cts} +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
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 __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
//#endregion
|
|
23
|
+
exports.__toESM = __toESM;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/constants.ts
|
|
3
|
+
const TEMPLATE_NAME = "minimal-app";
|
|
4
|
+
const DEFAULT_APP_NAME = "M5 Starter";
|
|
5
|
+
function getDefaultDescription(appName) {
|
|
6
|
+
return `${appName} is a blog publishing platform scaffolded with the m5kdev stack.`;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
exports.DEFAULT_APP_NAME = DEFAULT_APP_NAME;
|
|
10
|
+
exports.TEMPLATE_NAME = TEMPLATE_NAME;
|
|
11
|
+
exports.getDefaultDescription = getDefaultDescription;
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=constants.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.
|
|
1
|
+
{"version":3,"file":"constants.cjs","names":[],"sources":["../../src/constants.ts"],"sourcesContent":["export const TEMPLATE_NAME = \"minimal-app\";\r\n\r\nexport const DEFAULT_APP_NAME = \"M5 Starter\";\r\n\r\nexport function getDefaultDescription(appName: string): string {\r\n return `${appName} is a blog publishing platform scaffolded with the m5kdev stack.`;\r\n}\r\n"],"mappings":";;AAAA,MAAa,gBAAgB;AAE7B,MAAa,mBAAmB;AAEhC,SAAgB,sBAAsB,SAAyB;AAC7D,QAAO,GAAG,QAAQ"}
|
|
@@ -4,4 +4,4 @@ declare const DEFAULT_APP_NAME = "M5 Starter";
|
|
|
4
4
|
declare function getDefaultDescription(appName: string): string;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { DEFAULT_APP_NAME, TEMPLATE_NAME, getDefaultDescription };
|
|
7
|
-
//# sourceMappingURL=constants.d.
|
|
7
|
+
//# sourceMappingURL=constants.d.cts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_src_constants = require("./constants.cjs");
|
|
4
|
+
const require_src_strings = require("./strings.cjs");
|
|
5
|
+
const require_src_fs = require("./fs.cjs");
|
|
6
|
+
const require_src_paths = require("./paths.cjs");
|
|
7
|
+
const require_src_prompts = require("./prompts.cjs");
|
|
8
|
+
let node_path = require("node:path");
|
|
9
|
+
node_path = require_runtime.__toESM(node_path);
|
|
10
|
+
//#region src/create.ts
|
|
11
|
+
async function scaffoldProject(initialOptions) {
|
|
12
|
+
const options = await require_src_prompts.resolveCreateCommandOptions(initialOptions);
|
|
13
|
+
const appSlug = require_src_strings.slugifyAppName(options.appName);
|
|
14
|
+
const targetDirectory = node_path.default.resolve(process.cwd(), options.targetDirectory);
|
|
15
|
+
const templateDirectory = require_src_paths.getTemplateRoot();
|
|
16
|
+
const context = {
|
|
17
|
+
appName: options.appName,
|
|
18
|
+
appDescription: options.appDescription,
|
|
19
|
+
appSlug,
|
|
20
|
+
packageScope: require_src_strings.derivePackageScope(appSlug),
|
|
21
|
+
betterAuthSecret: require_src_strings.createBetterAuthSecret()
|
|
22
|
+
};
|
|
23
|
+
await require_src_fs.ensureDirectoryState(targetDirectory, options.force);
|
|
24
|
+
await require_src_fs.copyTemplateDirectory(templateDirectory, targetDirectory, context);
|
|
25
|
+
if (!options.skipGit) await require_src_fs.runGitInit(targetDirectory);
|
|
26
|
+
if (!options.skipInstall) await require_src_fs.runInstall(targetDirectory);
|
|
27
|
+
return {
|
|
28
|
+
context,
|
|
29
|
+
targetDirectory,
|
|
30
|
+
templateName: require_src_constants.TEMPLATE_NAME
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
exports.scaffoldProject = scaffoldProject;
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=create.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.cjs","names":["resolveCreateCommandOptions","slugifyAppName","path","getTemplateRoot","derivePackageScope","createBetterAuthSecret","ensureDirectoryState","copyTemplateDirectory","runGitInit","runInstall","TEMPLATE_NAME"],"sources":["../../src/create.ts"],"sourcesContent":["import path from \"node:path\";\r\nimport { TEMPLATE_NAME } from \"./constants\";\r\nimport { copyTemplateDirectory, ensureDirectoryState, runGitInit, runInstall } from \"./fs\";\r\nimport { getTemplateRoot } from \"./paths\";\r\nimport { resolveCreateCommandOptions } from \"./prompts\";\r\nimport { createBetterAuthSecret, derivePackageScope, slugifyAppName } from \"./strings\";\r\nimport type { CreateCommandOptions, TemplateContext } from \"./types\";\r\n\r\nexport interface ScaffoldResult {\r\n context: TemplateContext;\r\n targetDirectory: string;\r\n templateName: string;\r\n}\r\n\r\nexport async function scaffoldProject(initialOptions: CreateCommandOptions): Promise<ScaffoldResult> {\r\n const options = await resolveCreateCommandOptions(initialOptions);\r\n const appSlug = slugifyAppName(options.appName!);\r\n const targetDirectory = path.resolve(process.cwd(), options.targetDirectory!);\r\n const templateDirectory = getTemplateRoot();\r\n\r\n const context: TemplateContext = {\r\n appName: options.appName!,\r\n appDescription: options.appDescription!,\r\n appSlug,\r\n packageScope: derivePackageScope(appSlug),\r\n betterAuthSecret: createBetterAuthSecret(),\r\n };\r\n\r\n await ensureDirectoryState(targetDirectory, options.force);\r\n await copyTemplateDirectory(templateDirectory, targetDirectory, context);\r\n\r\n if (!options.skipGit) {\r\n await runGitInit(targetDirectory);\r\n }\r\n\r\n if (!options.skipInstall) {\r\n await runInstall(targetDirectory);\r\n }\r\n\r\n return {\r\n context,\r\n targetDirectory,\r\n templateName: TEMPLATE_NAME,\r\n };\r\n}\r\n"],"mappings":";;;;;;;;;;AAcA,eAAsB,gBAAgB,gBAA+D;CACnG,MAAM,UAAU,MAAMA,oBAAAA,4BAA4B,eAAe;CACjE,MAAM,UAAUC,oBAAAA,eAAe,QAAQ,QAAS;CAChD,MAAM,kBAAkBC,UAAAA,QAAK,QAAQ,QAAQ,KAAK,EAAE,QAAQ,gBAAiB;CAC7E,MAAM,oBAAoBC,kBAAAA,iBAAiB;CAE3C,MAAM,UAA2B;EAC/B,SAAS,QAAQ;EACjB,gBAAgB,QAAQ;EACxB;EACA,cAAcC,oBAAAA,mBAAmB,QAAQ;EACzC,kBAAkBC,oBAAAA,wBAAwB;EAC3C;AAED,OAAMC,eAAAA,qBAAqB,iBAAiB,QAAQ,MAAM;AAC1D,OAAMC,eAAAA,sBAAsB,mBAAmB,iBAAiB,QAAQ;AAExE,KAAI,CAAC,QAAQ,QACX,OAAMC,eAAAA,WAAW,gBAAgB;AAGnC,KAAI,CAAC,QAAQ,YACX,OAAMC,eAAAA,WAAW,gBAAgB;AAGnC,QAAO;EACL;EACA;EACA,cAAcC,sBAAAA;EACf"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CreateCommandOptions, TemplateContext } from "./types.
|
|
1
|
+
import { CreateCommandOptions, TemplateContext } from "./types.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/create.d.ts
|
|
4
4
|
interface ScaffoldResult {
|
|
@@ -9,4 +9,4 @@ interface ScaffoldResult {
|
|
|
9
9
|
declare function scaffoldProject(initialOptions: CreateCommandOptions): Promise<ScaffoldResult>;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { ScaffoldResult, scaffoldProject };
|
|
12
|
-
//# sourceMappingURL=create.d.
|
|
12
|
+
//# sourceMappingURL=create.d.cts.map
|
package/dist/src/fs.cjs
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_src_strings = require("./strings.cjs");
|
|
4
|
+
let node_path = require("node:path");
|
|
5
|
+
node_path = require_runtime.__toESM(node_path);
|
|
6
|
+
let node_child_process = require("node:child_process");
|
|
7
|
+
let node_fs_promises = require("node:fs/promises");
|
|
8
|
+
node_fs_promises = require_runtime.__toESM(node_fs_promises);
|
|
9
|
+
//#region src/fs.ts
|
|
10
|
+
const execFileAsync = (0, require("node:util").promisify)(node_child_process.execFile);
|
|
11
|
+
const TEMPLATE_LINE_ENDING = "\r\n";
|
|
12
|
+
async function ensureDirectoryState(targetDirectory, force) {
|
|
13
|
+
const stat = await node_fs_promises.default.stat(targetDirectory).catch(() => null);
|
|
14
|
+
if (!stat) {
|
|
15
|
+
await node_fs_promises.default.mkdir(targetDirectory, { recursive: true });
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (!stat.isDirectory()) throw new Error(`Target path is not a directory: ${targetDirectory}`);
|
|
19
|
+
if ((await node_fs_promises.default.readdir(targetDirectory)).length > 0 && !force) throw new Error(`Target directory is not empty: ${targetDirectory}. Re-run with --force to overwrite.`);
|
|
20
|
+
}
|
|
21
|
+
async function copyTemplateDirectory(templateDirectory, targetDirectory, context) {
|
|
22
|
+
const entries = await node_fs_promises.default.readdir(templateDirectory, { withFileTypes: true });
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
const sourcePath = node_path.default.join(templateDirectory, entry.name);
|
|
25
|
+
const targetName = entry.name.endsWith(".tpl") ? entry.name.slice(0, -4) : entry.name;
|
|
26
|
+
const targetPath = node_path.default.join(targetDirectory, targetName);
|
|
27
|
+
if (entry.isDirectory()) {
|
|
28
|
+
await node_fs_promises.default.mkdir(targetPath, { recursive: true });
|
|
29
|
+
await copyTemplateDirectory(sourcePath, targetPath, context);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (!entry.isFile()) continue;
|
|
33
|
+
const rendered = require_src_strings.renderTemplate(await node_fs_promises.default.readFile(sourcePath, "utf8"), context).replace(/\r?\n/g, TEMPLATE_LINE_ENDING);
|
|
34
|
+
await node_fs_promises.default.mkdir(node_path.default.dirname(targetPath), { recursive: true });
|
|
35
|
+
await node_fs_promises.default.writeFile(targetPath, rendered, "utf8");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function runInstall(targetDirectory) {
|
|
39
|
+
await execFileAsync("pnpm", ["install"], {
|
|
40
|
+
cwd: targetDirectory,
|
|
41
|
+
env: process.env
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async function runGitInit(targetDirectory) {
|
|
45
|
+
await execFileAsync("git", ["init"], {
|
|
46
|
+
cwd: targetDirectory,
|
|
47
|
+
env: process.env
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
exports.copyTemplateDirectory = copyTemplateDirectory;
|
|
52
|
+
exports.ensureDirectoryState = ensureDirectoryState;
|
|
53
|
+
exports.runGitInit = runGitInit;
|
|
54
|
+
exports.runInstall = runInstall;
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=fs.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.cjs","names":["execFile","fs","path","renderTemplate"],"sources":["../../src/fs.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\r\nimport fs from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { promisify } from \"node:util\";\r\nimport type { TemplateContext } from \"./types\";\r\nimport { renderTemplate } from \"./strings\";\r\n\r\nconst execFileAsync = promisify(execFile);\r\nconst TEMPLATE_LINE_ENDING = \"\\r\\n\";\r\n\r\nexport async function ensureDirectoryState(\r\n targetDirectory: string,\r\n force: boolean\r\n): Promise<void> {\r\n const stat = await fs.stat(targetDirectory).catch(() => null);\r\n\r\n if (!stat) {\r\n await fs.mkdir(targetDirectory, { recursive: true });\r\n return;\r\n }\r\n\r\n if (!stat.isDirectory()) {\r\n throw new Error(`Target path is not a directory: ${targetDirectory}`);\r\n }\r\n\r\n const entries = await fs.readdir(targetDirectory);\r\n if (entries.length > 0 && !force) {\r\n throw new Error(\r\n `Target directory is not empty: ${targetDirectory}. Re-run with --force to overwrite.`\r\n );\r\n }\r\n}\r\n\r\nexport async function copyTemplateDirectory(\r\n templateDirectory: string,\r\n targetDirectory: string,\r\n context: TemplateContext\r\n): Promise<void> {\r\n const entries = await fs.readdir(templateDirectory, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const sourcePath = path.join(templateDirectory, entry.name);\r\n const targetName = entry.name.endsWith(\".tpl\") ? entry.name.slice(0, -4) : entry.name;\r\n const targetPath = path.join(targetDirectory, targetName);\r\n\r\n if (entry.isDirectory()) {\r\n await fs.mkdir(targetPath, { recursive: true });\r\n await copyTemplateDirectory(sourcePath, targetPath, context);\r\n continue;\r\n }\r\n\r\n if (!entry.isFile()) {\r\n continue;\r\n }\r\n\r\n const content = await fs.readFile(sourcePath, \"utf8\");\r\n const rendered = renderTemplate(content, context).replace(/\\r?\\n/g, TEMPLATE_LINE_ENDING);\r\n await fs.mkdir(path.dirname(targetPath), { recursive: true });\r\n await fs.writeFile(targetPath, rendered, \"utf8\");\r\n }\r\n}\r\n\r\nexport async function runInstall(targetDirectory: string): Promise<void> {\r\n await execFileAsync(\"pnpm\", [\"install\"], {\r\n cwd: targetDirectory,\r\n env: process.env,\r\n });\r\n}\r\n\r\nexport async function runGitInit(targetDirectory: string): Promise<void> {\r\n await execFileAsync(\"git\", [\"init\"], {\r\n cwd: targetDirectory,\r\n env: process.env,\r\n });\r\n}\r\n"],"mappings":";;;;;;;;;AAOA,MAAM,iBAAA,wBAAA,WAA0BA,mBAAAA,SAAS;AACzC,MAAM,uBAAuB;AAE7B,eAAsB,qBACpB,iBACA,OACe;CACf,MAAM,OAAO,MAAMC,iBAAAA,QAAG,KAAK,gBAAgB,CAAC,YAAY,KAAK;AAE7D,KAAI,CAAC,MAAM;AACT,QAAMA,iBAAAA,QAAG,MAAM,iBAAiB,EAAE,WAAW,MAAM,CAAC;AACpD;;AAGF,KAAI,CAAC,KAAK,aAAa,CACrB,OAAM,IAAI,MAAM,mCAAmC,kBAAkB;AAIvE,MADgB,MAAMA,iBAAAA,QAAG,QAAQ,gBAAgB,EACrC,SAAS,KAAK,CAAC,MACzB,OAAM,IAAI,MACR,kCAAkC,gBAAgB,qCACnD;;AAIL,eAAsB,sBACpB,mBACA,iBACA,SACe;CACf,MAAM,UAAU,MAAMA,iBAAAA,QAAG,QAAQ,mBAAmB,EAAE,eAAe,MAAM,CAAC;AAE5E,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,aAAaC,UAAAA,QAAK,KAAK,mBAAmB,MAAM,KAAK;EAC3D,MAAM,aAAa,MAAM,KAAK,SAAS,OAAO,GAAG,MAAM,KAAK,MAAM,GAAG,GAAG,GAAG,MAAM;EACjF,MAAM,aAAaA,UAAAA,QAAK,KAAK,iBAAiB,WAAW;AAEzD,MAAI,MAAM,aAAa,EAAE;AACvB,SAAMD,iBAAAA,QAAG,MAAM,YAAY,EAAE,WAAW,MAAM,CAAC;AAC/C,SAAM,sBAAsB,YAAY,YAAY,QAAQ;AAC5D;;AAGF,MAAI,CAAC,MAAM,QAAQ,CACjB;EAIF,MAAM,WAAWE,oBAAAA,eADD,MAAMF,iBAAAA,QAAG,SAAS,YAAY,OAAO,EACZ,QAAQ,CAAC,QAAQ,UAAU,qBAAqB;AACzF,QAAMA,iBAAAA,QAAG,MAAMC,UAAAA,QAAK,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AAC7D,QAAMD,iBAAAA,QAAG,UAAU,YAAY,UAAU,OAAO;;;AAIpD,eAAsB,WAAW,iBAAwC;AACvE,OAAM,cAAc,QAAQ,CAAC,UAAU,EAAE;EACvC,KAAK;EACL,KAAK,QAAQ;EACd,CAAC;;AAGJ,eAAsB,WAAW,iBAAwC;AACvE,OAAM,cAAc,OAAO,CAAC,OAAO,EAAE;EACnC,KAAK;EACL,KAAK,QAAQ;EACd,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TemplateContext } from "./types.
|
|
1
|
+
import { TemplateContext } from "./types.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/fs.d.ts
|
|
4
4
|
declare function ensureDirectoryState(targetDirectory: string, force: boolean): Promise<void>;
|
|
@@ -7,4 +7,4 @@ declare function runInstall(targetDirectory: string): Promise<void>;
|
|
|
7
7
|
declare function runGitInit(targetDirectory: string): Promise<void>;
|
|
8
8
|
//#endregion
|
|
9
9
|
export { copyTemplateDirectory, ensureDirectoryState, runGitInit, runInstall };
|
|
10
|
-
//# sourceMappingURL=fs.d.
|
|
10
|
+
//# sourceMappingURL=fs.d.cts.map
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { runCli } from "./runCli.mjs";
|
|
3
2
|
//#region src/index.ts
|
|
4
|
-
runCli(process.argv.slice(2)).catch((error) => {
|
|
3
|
+
require("./runCli.cjs").runCli(process.argv.slice(2)).catch((error) => {
|
|
5
4
|
const message = error instanceof Error ? error.message : String(error);
|
|
6
5
|
console.error(message);
|
|
7
6
|
process.exitCode = 1;
|
|
8
7
|
});
|
|
9
8
|
//#endregion
|
|
10
|
-
export {};
|
|
11
9
|
|
|
12
|
-
//# sourceMappingURL=index.
|
|
10
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["runCli"],"sources":["../../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { runCli } from \"./runCli\";\r\n\r\nrunCli(process.argv.slice(2)).catch((error: unknown) => {\r\n const message = error instanceof Error ? error.message : String(error);\r\n console.error(message);\r\n process.exitCode = 1;\r\n});\r\n"],"mappings":";;wBAIAA,OAAO,QAAQ,KAAK,MAAM,EAAE,CAAC,CAAC,OAAO,UAAmB;CACtD,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,SAAQ,MAAM,QAAQ;AACtB,SAAQ,WAAW;EACnB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_src_constants = require("./constants.cjs");
|
|
4
|
+
let node_path = require("node:path");
|
|
5
|
+
node_path = require_runtime.__toESM(node_path);
|
|
6
|
+
let node_fs = require("node:fs");
|
|
7
|
+
node_fs = require_runtime.__toESM(node_fs);
|
|
8
|
+
//#region src/paths.ts
|
|
9
|
+
function getTemplateRoot() {
|
|
10
|
+
const sourcePath = node_path.default.resolve(__dirname, "../templates", require_src_constants.TEMPLATE_NAME);
|
|
11
|
+
if (node_fs.default.existsSync(sourcePath)) return sourcePath;
|
|
12
|
+
return node_path.default.resolve(__dirname, "../../templates", require_src_constants.TEMPLATE_NAME);
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
exports.getTemplateRoot = getTemplateRoot;
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=paths.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.cjs","names":["path","TEMPLATE_NAME","fs"],"sources":["../../src/paths.ts"],"sourcesContent":["import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { TEMPLATE_NAME } from \"./constants\";\r\n\r\nexport function getTemplateRoot(): string {\r\n const sourcePath = path.resolve(__dirname, \"../templates\", TEMPLATE_NAME);\r\n if (fs.existsSync(sourcePath)) {\r\n return sourcePath;\r\n }\r\n\r\n return path.resolve(__dirname, \"../../templates\", TEMPLATE_NAME);\r\n}\r\n"],"mappings":";;;;;;;;AAIA,SAAgB,kBAA0B;CACxC,MAAM,aAAaA,UAAAA,QAAK,QAAQ,WAAW,gBAAgBC,sBAAAA,cAAc;AACzE,KAAIC,QAAAA,QAAG,WAAW,WAAW,CAC3B,QAAO;AAGT,QAAOF,UAAAA,QAAK,QAAQ,WAAW,mBAAmBC,sBAAAA,cAAc"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_src_constants = require("./constants.cjs");
|
|
4
|
+
const require_src_strings = require("./strings.cjs");
|
|
5
|
+
let node_readline_promises = require("node:readline/promises");
|
|
6
|
+
node_readline_promises = require_runtime.__toESM(node_readline_promises);
|
|
7
|
+
let node_process = require("node:process");
|
|
8
|
+
//#region src/prompts.ts
|
|
9
|
+
function requireInteractive(yes) {
|
|
10
|
+
if (!yes && !process.stdin.isTTY) throw new Error("Missing required values in a non-interactive shell. Pass --yes or provide flags.");
|
|
11
|
+
}
|
|
12
|
+
async function promptValue(question, fallback) {
|
|
13
|
+
const rl = node_readline_promises.default.createInterface({
|
|
14
|
+
input: node_process.stdin,
|
|
15
|
+
output: node_process.stdout
|
|
16
|
+
});
|
|
17
|
+
try {
|
|
18
|
+
const suffix = fallback ? ` (${fallback})` : "";
|
|
19
|
+
return (await rl.question(`${question}${suffix}: `)).trim() || fallback || "";
|
|
20
|
+
} finally {
|
|
21
|
+
rl.close();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function resolveCreateCommandOptions(options) {
|
|
25
|
+
const resolved = { ...options };
|
|
26
|
+
if (!resolved.appName) {
|
|
27
|
+
requireInteractive(resolved.yes);
|
|
28
|
+
resolved.appName = resolved.yes ? resolved.targetDirectory ? require_src_strings.toDisplayName(pathBaseName(resolved.targetDirectory)) : require_src_constants.DEFAULT_APP_NAME : await promptValue("App name", resolved.targetDirectory ? pathBaseName(resolved.targetDirectory) : require_src_constants.DEFAULT_APP_NAME);
|
|
29
|
+
}
|
|
30
|
+
resolved.appName = require_src_strings.toDisplayName(resolved.appName);
|
|
31
|
+
if (!resolved.targetDirectory) {
|
|
32
|
+
requireInteractive(resolved.yes);
|
|
33
|
+
resolved.targetDirectory = resolved.yes ? require_src_strings.slugifyAppName(resolved.appName) : await promptValue("Target directory", require_src_strings.slugifyAppName(resolved.appName));
|
|
34
|
+
}
|
|
35
|
+
if (!resolved.appDescription) {
|
|
36
|
+
requireInteractive(resolved.yes);
|
|
37
|
+
const fallback = require_src_constants.getDefaultDescription(resolved.appName);
|
|
38
|
+
resolved.appDescription = resolved.yes ? fallback : await promptValue("App description", fallback);
|
|
39
|
+
}
|
|
40
|
+
return resolved;
|
|
41
|
+
}
|
|
42
|
+
function pathBaseName(value) {
|
|
43
|
+
return value.replace(/[\\/]+$/g, "").split(/[\\/]/).filter(Boolean).at(-1) || "M5 Starter";
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
exports.resolveCreateCommandOptions = resolveCreateCommandOptions;
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=prompts.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.cjs","names":["readline","toDisplayName","DEFAULT_APP_NAME","slugifyAppName","getDefaultDescription"],"sources":["../../src/prompts.ts"],"sourcesContent":["import readline from \"node:readline/promises\";\r\nimport { stdin as input, stdout as output } from \"node:process\";\r\nimport { DEFAULT_APP_NAME, getDefaultDescription } from \"./constants\";\r\nimport { slugifyAppName, toDisplayName } from \"./strings\";\r\nimport type { CreateCommandOptions } from \"./types\";\r\n\r\nfunction requireInteractive(yes: boolean): void {\r\n if (!yes && !process.stdin.isTTY) {\r\n throw new Error(\"Missing required values in a non-interactive shell. Pass --yes or provide flags.\");\r\n }\r\n}\r\n\r\nasync function promptValue(question: string, fallback?: string): Promise<string> {\r\n const rl = readline.createInterface({ input, output });\r\n\r\n try {\r\n const suffix = fallback ? ` (${fallback})` : \"\";\r\n const response = await rl.question(`${question}${suffix}: `);\r\n return response.trim() || fallback || \"\";\r\n } finally {\r\n rl.close();\r\n }\r\n}\r\n\r\nexport async function resolveCreateCommandOptions(\r\n options: CreateCommandOptions\r\n): Promise<CreateCommandOptions> {\r\n const resolved = { ...options };\r\n\r\n if (!resolved.appName) {\r\n requireInteractive(resolved.yes);\r\n resolved.appName = resolved.yes\r\n ? resolved.targetDirectory\r\n ? toDisplayName(pathBaseName(resolved.targetDirectory))\r\n : DEFAULT_APP_NAME\r\n : await promptValue(\"App name\", resolved.targetDirectory ? pathBaseName(resolved.targetDirectory) : DEFAULT_APP_NAME);\r\n }\r\n\r\n resolved.appName = toDisplayName(resolved.appName);\r\n\r\n if (!resolved.targetDirectory) {\r\n requireInteractive(resolved.yes);\r\n resolved.targetDirectory = resolved.yes\r\n ? slugifyAppName(resolved.appName)\r\n : await promptValue(\"Target directory\", slugifyAppName(resolved.appName));\r\n }\r\n\r\n if (!resolved.appDescription) {\r\n requireInteractive(resolved.yes);\r\n const fallback = getDefaultDescription(resolved.appName);\r\n resolved.appDescription = resolved.yes\r\n ? fallback\r\n : await promptValue(\"App description\", fallback);\r\n }\r\n\r\n return resolved;\r\n}\r\n\r\nfunction pathBaseName(value: string): string {\r\n const normalized = value.replace(/[\\\\/]+$/g, \"\");\r\n const segments = normalized.split(/[\\\\/]/).filter(Boolean);\r\n return segments.at(-1) || DEFAULT_APP_NAME;\r\n}\r\n"],"mappings":";;;;;;;;AAMA,SAAS,mBAAmB,KAAoB;AAC9C,KAAI,CAAC,OAAO,CAAC,QAAQ,MAAM,MACzB,OAAM,IAAI,MAAM,mFAAmF;;AAIvG,eAAe,YAAY,UAAkB,UAAoC;CAC/E,MAAM,KAAKA,uBAAAA,QAAS,gBAAgB;EAAE,OAAA,aAAA;EAAO,QAAA,aAAA;EAAQ,CAAC;AAEtD,KAAI;EACF,MAAM,SAAS,WAAW,KAAK,SAAS,KAAK;AAE7C,UADiB,MAAM,GAAG,SAAS,GAAG,WAAW,OAAO,IAAI,EAC5C,MAAM,IAAI,YAAY;WAC9B;AACR,KAAG,OAAO;;;AAId,eAAsB,4BACpB,SAC+B;CAC/B,MAAM,WAAW,EAAE,GAAG,SAAS;AAE/B,KAAI,CAAC,SAAS,SAAS;AACrB,qBAAmB,SAAS,IAAI;AAChC,WAAS,UAAU,SAAS,MACxB,SAAS,kBACPC,oBAAAA,cAAc,aAAa,SAAS,gBAAgB,CAAC,GACrDC,sBAAAA,mBACF,MAAM,YAAY,YAAY,SAAS,kBAAkB,aAAa,SAAS,gBAAgB,GAAGA,sBAAAA,iBAAiB;;AAGzH,UAAS,UAAUD,oBAAAA,cAAc,SAAS,QAAQ;AAElD,KAAI,CAAC,SAAS,iBAAiB;AAC7B,qBAAmB,SAAS,IAAI;AAChC,WAAS,kBAAkB,SAAS,MAChCE,oBAAAA,eAAe,SAAS,QAAQ,GAChC,MAAM,YAAY,oBAAoBA,oBAAAA,eAAe,SAAS,QAAQ,CAAC;;AAG7E,KAAI,CAAC,SAAS,gBAAgB;AAC5B,qBAAmB,SAAS,IAAI;EAChC,MAAM,WAAWC,sBAAAA,sBAAsB,SAAS,QAAQ;AACxD,WAAS,iBAAiB,SAAS,MAC/B,WACA,MAAM,YAAY,mBAAmB,SAAS;;AAGpD,QAAO;;AAGT,SAAS,aAAa,OAAuB;AAG3C,QAFmB,MAAM,QAAQ,YAAY,GAAG,CACpB,MAAM,QAAQ,CAAC,OAAO,QAAQ,CAC1C,GAAG,GAAG,IAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { CreateCommandOptions } from "./types.
|
|
1
|
+
import { CreateCommandOptions } from "./types.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/prompts.d.ts
|
|
4
4
|
declare function resolveCreateCommandOptions(options: CreateCommandOptions): Promise<CreateCommandOptions>;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { resolveCreateCommandOptions };
|
|
7
|
-
//# sourceMappingURL=prompts.d.
|
|
7
|
+
//# sourceMappingURL=prompts.d.cts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_src_create = require("./create.cjs");
|
|
2
3
|
//#region src/runCli.ts
|
|
3
4
|
async function runCli(argv) {
|
|
4
5
|
const parsed = parseCli(argv);
|
|
@@ -8,7 +9,7 @@ async function runCli(argv) {
|
|
|
8
9
|
}
|
|
9
10
|
if (parsed.command !== "create") throw new Error(`Unknown command: ${parsed.command}`);
|
|
10
11
|
const options = toCreateCommandOptions(parsed);
|
|
11
|
-
const result = await scaffoldProject(options);
|
|
12
|
+
const result = await require_src_create.scaffoldProject(options);
|
|
12
13
|
console.log("");
|
|
13
14
|
console.log(`Scaffolded ${result.context.appName} in ${result.targetDirectory}`);
|
|
14
15
|
console.log("");
|
|
@@ -96,6 +97,7 @@ function printHelp() {
|
|
|
96
97
|
console.log(" --skip-git Skip git init");
|
|
97
98
|
}
|
|
98
99
|
//#endregion
|
|
99
|
-
|
|
100
|
+
exports.parseCli = parseCli;
|
|
101
|
+
exports.runCli = runCli;
|
|
100
102
|
|
|
101
|
-
//# sourceMappingURL=runCli.
|
|
103
|
+
//# sourceMappingURL=runCli.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runCli.cjs","names":["scaffoldProject"],"sources":["../../src/runCli.ts"],"sourcesContent":["import { scaffoldProject } from \"./create\";\r\nimport type { CreateCommandOptions } from \"./types\";\r\n\r\ninterface ParsedCli {\r\n command?: string;\r\n directory?: string;\r\n help?: boolean;\r\n options: Record<string, string | boolean>;\r\n}\r\n\r\nexport async function runCli(argv: readonly string[]): Promise<void> {\r\n const parsed = parseCli(argv);\r\n\r\n if (\r\n !parsed.command ||\r\n parsed.help ||\r\n parsed.command === \"--help\" ||\r\n parsed.command === \"-h\" ||\r\n parsed.command === \"help\"\r\n ) {\r\n printHelp();\r\n return;\r\n }\r\n\r\n if (parsed.command !== \"create\") {\r\n throw new Error(`Unknown command: ${parsed.command}`);\r\n }\r\n\r\n const options = toCreateCommandOptions(parsed);\r\n const result = await scaffoldProject(options);\r\n\r\n console.log(\"\");\r\n console.log(`Scaffolded ${result.context.appName} in ${result.targetDirectory}`);\r\n console.log(\"\");\r\n console.log(\"Next steps:\");\r\n console.log(` cd ${result.targetDirectory}`);\r\n if (options.skipInstall) {\r\n console.log(\" pnpm install\");\r\n }\r\n console.log(\" pnpm --filter ./apps/server sync\");\r\n console.log(\" pnpm dev\");\r\n}\r\n\r\nexport function parseCli(argv: readonly string[]): ParsedCli {\r\n const normalizedArgv = normalizeCliArgv(argv);\r\n const [command, ...rest] = normalizedArgv;\r\n const options: Record<string, string | boolean> = {};\r\n let directory: string | undefined;\r\n let help = false;\r\n\r\n for (let index = 0; index < rest.length; index += 1) {\r\n const token = rest[index];\r\n\r\n if (token === \"--help\" || token === \"-h\") {\r\n help = true;\r\n continue;\r\n }\r\n\r\n if (!token.startsWith(\"--\")) {\r\n directory ??= token;\r\n continue;\r\n }\r\n\r\n const [rawKey, inlineValue] = token.slice(2).split(\"=\", 2);\r\n\r\n if (isBooleanFlag(rawKey)) {\r\n options[rawKey] = true;\r\n continue;\r\n }\r\n\r\n const nextValue = inlineValue ?? rest[index + 1];\r\n if (!nextValue || nextValue.startsWith(\"--\")) {\r\n throw new Error(`Missing value for --${rawKey}`);\r\n }\r\n\r\n options[rawKey] = nextValue;\r\n if (inlineValue === undefined) {\r\n index += 1;\r\n }\r\n }\r\n\r\n return { command, directory, help, options };\r\n}\r\n\r\nfunction normalizeCliArgv(argv: readonly string[]): readonly string[] {\r\n const [firstToken] = argv;\r\n\r\n if (!firstToken || firstToken === \"create\" || firstToken === \"--help\" || firstToken === \"-h\") {\r\n return argv;\r\n }\r\n\r\n if (firstToken === \"help\") {\r\n return [\"--help\"];\r\n }\r\n\r\n return [\"create\", ...argv];\r\n}\r\n\r\nfunction isBooleanFlag(value: string): boolean {\r\n return [\"yes\", \"force\", \"skip-install\", \"skip-git\"].includes(value);\r\n}\r\n\r\nfunction toCreateCommandOptions(parsed: ParsedCli): CreateCommandOptions {\r\n return {\r\n targetDirectory: parsed.directory,\r\n appName: getStringOption(parsed.options, \"name\"),\r\n appDescription: getStringOption(parsed.options, \"description\"),\r\n yes: Boolean(parsed.options.yes),\r\n force: Boolean(parsed.options.force),\r\n skipInstall: Boolean(parsed.options[\"skip-install\"]),\r\n skipGit: Boolean(parsed.options[\"skip-git\"]),\r\n };\r\n}\r\n\r\nfunction getStringOption(\r\n options: Record<string, string | boolean>,\r\n key: string\r\n): string | undefined {\r\n const value = options[key];\r\n return typeof value === \"string\" ? value : undefined;\r\n}\r\n\r\nfunction printHelp(): void {\r\n console.log(\"m5kdev\");\r\n console.log(\"\");\r\n console.log(\"Usage:\");\r\n console.log(\" pnpm create m5kdev [directory] [options]\");\r\n console.log(\" m5kdev [directory] [options]\");\r\n console.log(\" m5kdev create [directory] [options]\");\r\n console.log(\"\");\r\n console.log(\"Options:\");\r\n console.log(\" --name <value> Set the app name\");\r\n console.log(\" --description <value> Set the app description\");\r\n console.log(\" --yes Accept defaults for missing prompts\");\r\n console.log(\" --force Allow writing into a non-empty directory\");\r\n console.log(\" --skip-install Skip pnpm install\");\r\n console.log(\" --skip-git Skip git init\");\r\n}\r\n"],"mappings":";;;AAUA,eAAsB,OAAO,MAAwC;CACnE,MAAM,SAAS,SAAS,KAAK;AAE7B,KACE,CAAC,OAAO,WACR,OAAO,QACP,OAAO,YAAY,YACnB,OAAO,YAAY,QACnB,OAAO,YAAY,QACnB;AACA,aAAW;AACX;;AAGF,KAAI,OAAO,YAAY,SACrB,OAAM,IAAI,MAAM,oBAAoB,OAAO,UAAU;CAGvD,MAAM,UAAU,uBAAuB,OAAO;CAC9C,MAAM,SAAS,MAAMA,mBAAAA,gBAAgB,QAAQ;AAE7C,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,cAAc,OAAO,QAAQ,QAAQ,MAAM,OAAO,kBAAkB;AAChF,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,cAAc;AAC1B,SAAQ,IAAI,QAAQ,OAAO,kBAAkB;AAC7C,KAAI,QAAQ,YACV,SAAQ,IAAI,iBAAiB;AAE/B,SAAQ,IAAI,qCAAqC;AACjD,SAAQ,IAAI,aAAa;;AAG3B,SAAgB,SAAS,MAAoC;CAE3D,MAAM,CAAC,SAAS,GAAG,QADI,iBAAiB,KAAK;CAE7C,MAAM,UAA4C,EAAE;CACpD,IAAI;CACJ,IAAI,OAAO;AAEX,MAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;EACnD,MAAM,QAAQ,KAAK;AAEnB,MAAI,UAAU,YAAY,UAAU,MAAM;AACxC,UAAO;AACP;;AAGF,MAAI,CAAC,MAAM,WAAW,KAAK,EAAE;AAC3B,iBAAc;AACd;;EAGF,MAAM,CAAC,QAAQ,eAAe,MAAM,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE;AAE1D,MAAI,cAAc,OAAO,EAAE;AACzB,WAAQ,UAAU;AAClB;;EAGF,MAAM,YAAY,eAAe,KAAK,QAAQ;AAC9C,MAAI,CAAC,aAAa,UAAU,WAAW,KAAK,CAC1C,OAAM,IAAI,MAAM,uBAAuB,SAAS;AAGlD,UAAQ,UAAU;AAClB,MAAI,gBAAgB,KAAA,EAClB,UAAS;;AAIb,QAAO;EAAE;EAAS;EAAW;EAAM;EAAS;;AAG9C,SAAS,iBAAiB,MAA4C;CACpE,MAAM,CAAC,cAAc;AAErB,KAAI,CAAC,cAAc,eAAe,YAAY,eAAe,YAAY,eAAe,KACtF,QAAO;AAGT,KAAI,eAAe,OACjB,QAAO,CAAC,SAAS;AAGnB,QAAO,CAAC,UAAU,GAAG,KAAK;;AAG5B,SAAS,cAAc,OAAwB;AAC7C,QAAO;EAAC;EAAO;EAAS;EAAgB;EAAW,CAAC,SAAS,MAAM;;AAGrE,SAAS,uBAAuB,QAAyC;AACvE,QAAO;EACL,iBAAiB,OAAO;EACxB,SAAS,gBAAgB,OAAO,SAAS,OAAO;EAChD,gBAAgB,gBAAgB,OAAO,SAAS,cAAc;EAC9D,KAAK,QAAQ,OAAO,QAAQ,IAAI;EAChC,OAAO,QAAQ,OAAO,QAAQ,MAAM;EACpC,aAAa,QAAQ,OAAO,QAAQ,gBAAgB;EACpD,SAAS,QAAQ,OAAO,QAAQ,YAAY;EAC7C;;AAGH,SAAS,gBACP,SACA,KACoB;CACpB,MAAM,QAAQ,QAAQ;AACtB,QAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;;AAG7C,SAAS,YAAkB;AACzB,SAAQ,IAAI,SAAS;AACrB,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,SAAS;AACrB,SAAQ,IAAI,6CAA6C;AACzD,SAAQ,IAAI,iCAAiC;AAC7C,SAAQ,IAAI,wCAAwC;AACpD,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,WAAW;AACvB,SAAQ,IAAI,8CAA8C;AAC1D,SAAQ,IAAI,qDAAqD;AACjE,SAAQ,IAAI,iEAAiE;AAC7E,SAAQ,IAAI,sEAAsE;AAClF,SAAQ,IAAI,+CAA+C;AAC3D,SAAQ,IAAI,2CAA2C"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
let node_crypto = require("node:crypto");
|
|
2
4
|
//#region src/strings.ts
|
|
3
5
|
function slugifyAppName(value) {
|
|
4
6
|
const slug = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+/g, "").replace(/-+$/g, "").replace(/-{2,}/g, "-");
|
|
@@ -14,7 +16,7 @@ function toDisplayName(value) {
|
|
|
14
16
|
return normalized;
|
|
15
17
|
}
|
|
16
18
|
function createBetterAuthSecret() {
|
|
17
|
-
return randomBytes(24).toString("base64url");
|
|
19
|
+
return (0, node_crypto.randomBytes)(24).toString("base64url");
|
|
18
20
|
}
|
|
19
21
|
function renderTemplate(content, context) {
|
|
20
22
|
const replacements = {
|
|
@@ -29,6 +31,10 @@ function renderTemplate(content, context) {
|
|
|
29
31
|
});
|
|
30
32
|
}
|
|
31
33
|
//#endregion
|
|
32
|
-
|
|
34
|
+
exports.createBetterAuthSecret = createBetterAuthSecret;
|
|
35
|
+
exports.derivePackageScope = derivePackageScope;
|
|
36
|
+
exports.renderTemplate = renderTemplate;
|
|
37
|
+
exports.slugifyAppName = slugifyAppName;
|
|
38
|
+
exports.toDisplayName = toDisplayName;
|
|
33
39
|
|
|
34
|
-
//# sourceMappingURL=strings.
|
|
40
|
+
//# sourceMappingURL=strings.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strings.
|
|
1
|
+
{"version":3,"file":"strings.cjs","names":[],"sources":["../../src/strings.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\r\nimport type { TemplateContext } from \"./types\";\r\n\r\nexport function slugifyAppName(value: string): string {\r\n const slug = value\r\n .trim()\r\n .toLowerCase()\r\n .replace(/[^a-z0-9]+/g, \"-\")\r\n .replace(/^-+/g, \"\")\r\n .replace(/-+$/g, \"\")\r\n .replace(/-{2,}/g, \"-\");\r\n\r\n if (!slug) {\r\n throw new Error(\"Unable to derive an app slug from the provided name.\");\r\n }\r\n\r\n return slug;\r\n}\r\n\r\nexport function derivePackageScope(appSlug: string): string {\r\n return `@${appSlug}`;\r\n}\r\n\r\nexport function toDisplayName(value: string): string {\r\n const normalized = value.trim();\r\n if (!normalized) {\r\n throw new Error(\"App name cannot be empty.\");\r\n }\r\n\r\n return normalized;\r\n}\r\n\r\nexport function createBetterAuthSecret(): string {\r\n return randomBytes(24).toString(\"base64url\");\r\n}\r\n\r\nexport function renderTemplate(content: string, context: TemplateContext): string {\r\n const replacements: Record<string, string> = {\r\n APP_NAME: context.appName,\r\n APP_DESCRIPTION: context.appDescription,\r\n APP_SLUG: context.appSlug,\r\n PACKAGE_SCOPE: context.packageScope,\r\n BETTER_AUTH_SECRET: context.betterAuthSecret,\r\n };\r\n\r\n return content.replace(/\\{\\{([A-Z_]+)\\}\\}/g, (match, token: string) => {\r\n const replacement = replacements[token];\r\n return replacement ?? match;\r\n });\r\n}\r\n"],"mappings":";;;;AAGA,SAAgB,eAAe,OAAuB;CACpD,MAAM,OAAO,MACV,MAAM,CACN,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,QAAQ,GAAG,CACnB,QAAQ,QAAQ,GAAG,CACnB,QAAQ,UAAU,IAAI;AAEzB,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,uDAAuD;AAGzE,QAAO;;AAGT,SAAgB,mBAAmB,SAAyB;AAC1D,QAAO,IAAI;;AAGb,SAAgB,cAAc,OAAuB;CACnD,MAAM,aAAa,MAAM,MAAM;AAC/B,KAAI,CAAC,WACH,OAAM,IAAI,MAAM,4BAA4B;AAG9C,QAAO;;AAGT,SAAgB,yBAAiC;AAC/C,SAAA,GAAA,YAAA,aAAmB,GAAG,CAAC,SAAS,YAAY;;AAG9C,SAAgB,eAAe,SAAiB,SAAkC;CAChF,MAAM,eAAuC;EAC3C,UAAU,QAAQ;EAClB,iBAAiB,QAAQ;EACzB,UAAU,QAAQ;EAClB,eAAe,QAAQ;EACvB,oBAAoB,QAAQ;EAC7B;AAED,QAAO,QAAQ,QAAQ,uBAAuB,OAAO,UAAkB;AAErE,SADoB,aAAa,UACX;GACtB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TemplateContext } from "./types.
|
|
1
|
+
import { TemplateContext } from "./types.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/strings.d.ts
|
|
4
4
|
declare function slugifyAppName(value: string): string;
|
|
@@ -8,4 +8,4 @@ declare function createBetterAuthSecret(): string;
|
|
|
8
8
|
declare function renderTemplate(content: string, context: TemplateContext): string;
|
|
9
9
|
//#endregion
|
|
10
10
|
export { createBetterAuthSecret, derivePackageScope, renderTemplate, slugifyAppName, toDisplayName };
|
|
11
|
-
//# sourceMappingURL=strings.d.
|
|
11
|
+
//# sourceMappingURL=strings.d.cts.map
|
|
File without changes
|
package/package.json
CHANGED
package/dist/src/constants.mjs
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
//#region src/constants.ts
|
|
2
|
-
const TEMPLATE_NAME = "minimal-app";
|
|
3
|
-
const DEFAULT_APP_NAME = "M5 Starter";
|
|
4
|
-
function getDefaultDescription(appName) {
|
|
5
|
-
return `${appName} is a blog publishing platform scaffolded with the m5kdev stack.`;
|
|
6
|
-
}
|
|
7
|
-
//#endregion
|
|
8
|
-
export { DEFAULT_APP_NAME, TEMPLATE_NAME, getDefaultDescription };
|
|
9
|
-
|
|
10
|
-
//# sourceMappingURL=constants.mjs.map
|
package/dist/src/create.mjs
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { TEMPLATE_NAME } from "./constants.mjs";
|
|
2
|
-
import { createBetterAuthSecret, derivePackageScope, slugifyAppName } from "./strings.mjs";
|
|
3
|
-
import { copyTemplateDirectory, ensureDirectoryState, runGitInit, runInstall } from "./fs.mjs";
|
|
4
|
-
import { getTemplateRoot } from "./paths.mjs";
|
|
5
|
-
import { resolveCreateCommandOptions } from "./prompts.mjs";
|
|
6
|
-
import path from "node:path";
|
|
7
|
-
//#region src/create.ts
|
|
8
|
-
async function scaffoldProject(initialOptions) {
|
|
9
|
-
const options = await resolveCreateCommandOptions(initialOptions);
|
|
10
|
-
const appSlug = slugifyAppName(options.appName);
|
|
11
|
-
const targetDirectory = path.resolve(process.cwd(), options.targetDirectory);
|
|
12
|
-
const templateDirectory = getTemplateRoot();
|
|
13
|
-
const context = {
|
|
14
|
-
appName: options.appName,
|
|
15
|
-
appDescription: options.appDescription,
|
|
16
|
-
appSlug,
|
|
17
|
-
packageScope: derivePackageScope(appSlug),
|
|
18
|
-
betterAuthSecret: createBetterAuthSecret()
|
|
19
|
-
};
|
|
20
|
-
await ensureDirectoryState(targetDirectory, options.force);
|
|
21
|
-
await copyTemplateDirectory(templateDirectory, targetDirectory, context);
|
|
22
|
-
if (!options.skipGit) await runGitInit(targetDirectory);
|
|
23
|
-
if (!options.skipInstall) await runInstall(targetDirectory);
|
|
24
|
-
return {
|
|
25
|
-
context,
|
|
26
|
-
targetDirectory,
|
|
27
|
-
templateName: TEMPLATE_NAME
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
//#endregion
|
|
31
|
-
export { scaffoldProject };
|
|
32
|
-
|
|
33
|
-
//# sourceMappingURL=create.mjs.map
|
package/dist/src/create.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create.mjs","names":[],"sources":["../../src/create.ts"],"sourcesContent":["import path from \"node:path\";\r\nimport { TEMPLATE_NAME } from \"./constants\";\r\nimport { copyTemplateDirectory, ensureDirectoryState, runGitInit, runInstall } from \"./fs\";\r\nimport { getTemplateRoot } from \"./paths\";\r\nimport { resolveCreateCommandOptions } from \"./prompts\";\r\nimport { createBetterAuthSecret, derivePackageScope, slugifyAppName } from \"./strings\";\r\nimport type { CreateCommandOptions, TemplateContext } from \"./types\";\r\n\r\nexport interface ScaffoldResult {\r\n context: TemplateContext;\r\n targetDirectory: string;\r\n templateName: string;\r\n}\r\n\r\nexport async function scaffoldProject(initialOptions: CreateCommandOptions): Promise<ScaffoldResult> {\r\n const options = await resolveCreateCommandOptions(initialOptions);\r\n const appSlug = slugifyAppName(options.appName!);\r\n const targetDirectory = path.resolve(process.cwd(), options.targetDirectory!);\r\n const templateDirectory = getTemplateRoot();\r\n\r\n const context: TemplateContext = {\r\n appName: options.appName!,\r\n appDescription: options.appDescription!,\r\n appSlug,\r\n packageScope: derivePackageScope(appSlug),\r\n betterAuthSecret: createBetterAuthSecret(),\r\n };\r\n\r\n await ensureDirectoryState(targetDirectory, options.force);\r\n await copyTemplateDirectory(templateDirectory, targetDirectory, context);\r\n\r\n if (!options.skipGit) {\r\n await runGitInit(targetDirectory);\r\n }\r\n\r\n if (!options.skipInstall) {\r\n await runInstall(targetDirectory);\r\n }\r\n\r\n return {\r\n context,\r\n targetDirectory,\r\n templateName: TEMPLATE_NAME,\r\n };\r\n}\r\n"],"mappings":";;;;;;;AAcA,eAAsB,gBAAgB,gBAA+D;CACnG,MAAM,UAAU,MAAM,4BAA4B,eAAe;CACjE,MAAM,UAAU,eAAe,QAAQ,QAAS;CAChD,MAAM,kBAAkB,KAAK,QAAQ,QAAQ,KAAK,EAAE,QAAQ,gBAAiB;CAC7E,MAAM,oBAAoB,iBAAiB;CAE3C,MAAM,UAA2B;EAC/B,SAAS,QAAQ;EACjB,gBAAgB,QAAQ;EACxB;EACA,cAAc,mBAAmB,QAAQ;EACzC,kBAAkB,wBAAwB;EAC3C;AAED,OAAM,qBAAqB,iBAAiB,QAAQ,MAAM;AAC1D,OAAM,sBAAsB,mBAAmB,iBAAiB,QAAQ;AAExE,KAAI,CAAC,QAAQ,QACX,OAAM,WAAW,gBAAgB;AAGnC,KAAI,CAAC,QAAQ,YACX,OAAM,WAAW,gBAAgB;AAGnC,QAAO;EACL;EACA;EACA,cAAc;EACf"}
|
package/dist/src/fs.mjs
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { renderTemplate } from "./strings.mjs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { execFile } from "node:child_process";
|
|
4
|
-
import fs from "node:fs/promises";
|
|
5
|
-
import { promisify } from "node:util";
|
|
6
|
-
//#region src/fs.ts
|
|
7
|
-
const execFileAsync = promisify(execFile);
|
|
8
|
-
const TEMPLATE_LINE_ENDING = "\r\n";
|
|
9
|
-
async function ensureDirectoryState(targetDirectory, force) {
|
|
10
|
-
const stat = await fs.stat(targetDirectory).catch(() => null);
|
|
11
|
-
if (!stat) {
|
|
12
|
-
await fs.mkdir(targetDirectory, { recursive: true });
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
if (!stat.isDirectory()) throw new Error(`Target path is not a directory: ${targetDirectory}`);
|
|
16
|
-
if ((await fs.readdir(targetDirectory)).length > 0 && !force) throw new Error(`Target directory is not empty: ${targetDirectory}. Re-run with --force to overwrite.`);
|
|
17
|
-
}
|
|
18
|
-
async function copyTemplateDirectory(templateDirectory, targetDirectory, context) {
|
|
19
|
-
const entries = await fs.readdir(templateDirectory, { withFileTypes: true });
|
|
20
|
-
for (const entry of entries) {
|
|
21
|
-
const sourcePath = path.join(templateDirectory, entry.name);
|
|
22
|
-
const targetName = entry.name.endsWith(".tpl") ? entry.name.slice(0, -4) : entry.name;
|
|
23
|
-
const targetPath = path.join(targetDirectory, targetName);
|
|
24
|
-
if (entry.isDirectory()) {
|
|
25
|
-
await fs.mkdir(targetPath, { recursive: true });
|
|
26
|
-
await copyTemplateDirectory(sourcePath, targetPath, context);
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
if (!entry.isFile()) continue;
|
|
30
|
-
const rendered = renderTemplate(await fs.readFile(sourcePath, "utf8"), context).replace(/\r?\n/g, TEMPLATE_LINE_ENDING);
|
|
31
|
-
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
32
|
-
await fs.writeFile(targetPath, rendered, "utf8");
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
async function runInstall(targetDirectory) {
|
|
36
|
-
await execFileAsync("pnpm", ["install"], {
|
|
37
|
-
cwd: targetDirectory,
|
|
38
|
-
env: process.env
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
async function runGitInit(targetDirectory) {
|
|
42
|
-
await execFileAsync("git", ["init"], {
|
|
43
|
-
cwd: targetDirectory,
|
|
44
|
-
env: process.env
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
//#endregion
|
|
48
|
-
export { copyTemplateDirectory, ensureDirectoryState, runGitInit, runInstall };
|
|
49
|
-
|
|
50
|
-
//# sourceMappingURL=fs.mjs.map
|
package/dist/src/fs.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fs.mjs","names":[],"sources":["../../src/fs.ts"],"sourcesContent":["import { execFile } from \"node:child_process\";\r\nimport fs from \"node:fs/promises\";\r\nimport path from \"node:path\";\r\nimport { promisify } from \"node:util\";\r\nimport type { TemplateContext } from \"./types\";\r\nimport { renderTemplate } from \"./strings\";\r\n\r\nconst execFileAsync = promisify(execFile);\r\nconst TEMPLATE_LINE_ENDING = \"\\r\\n\";\r\n\r\nexport async function ensureDirectoryState(\r\n targetDirectory: string,\r\n force: boolean\r\n): Promise<void> {\r\n const stat = await fs.stat(targetDirectory).catch(() => null);\r\n\r\n if (!stat) {\r\n await fs.mkdir(targetDirectory, { recursive: true });\r\n return;\r\n }\r\n\r\n if (!stat.isDirectory()) {\r\n throw new Error(`Target path is not a directory: ${targetDirectory}`);\r\n }\r\n\r\n const entries = await fs.readdir(targetDirectory);\r\n if (entries.length > 0 && !force) {\r\n throw new Error(\r\n `Target directory is not empty: ${targetDirectory}. Re-run with --force to overwrite.`\r\n );\r\n }\r\n}\r\n\r\nexport async function copyTemplateDirectory(\r\n templateDirectory: string,\r\n targetDirectory: string,\r\n context: TemplateContext\r\n): Promise<void> {\r\n const entries = await fs.readdir(templateDirectory, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const sourcePath = path.join(templateDirectory, entry.name);\r\n const targetName = entry.name.endsWith(\".tpl\") ? entry.name.slice(0, -4) : entry.name;\r\n const targetPath = path.join(targetDirectory, targetName);\r\n\r\n if (entry.isDirectory()) {\r\n await fs.mkdir(targetPath, { recursive: true });\r\n await copyTemplateDirectory(sourcePath, targetPath, context);\r\n continue;\r\n }\r\n\r\n if (!entry.isFile()) {\r\n continue;\r\n }\r\n\r\n const content = await fs.readFile(sourcePath, \"utf8\");\r\n const rendered = renderTemplate(content, context).replace(/\\r?\\n/g, TEMPLATE_LINE_ENDING);\r\n await fs.mkdir(path.dirname(targetPath), { recursive: true });\r\n await fs.writeFile(targetPath, rendered, \"utf8\");\r\n }\r\n}\r\n\r\nexport async function runInstall(targetDirectory: string): Promise<void> {\r\n await execFileAsync(\"pnpm\", [\"install\"], {\r\n cwd: targetDirectory,\r\n env: process.env,\r\n });\r\n}\r\n\r\nexport async function runGitInit(targetDirectory: string): Promise<void> {\r\n await execFileAsync(\"git\", [\"init\"], {\r\n cwd: targetDirectory,\r\n env: process.env,\r\n });\r\n}\r\n"],"mappings":";;;;;;AAOA,MAAM,gBAAgB,UAAU,SAAS;AACzC,MAAM,uBAAuB;AAE7B,eAAsB,qBACpB,iBACA,OACe;CACf,MAAM,OAAO,MAAM,GAAG,KAAK,gBAAgB,CAAC,YAAY,KAAK;AAE7D,KAAI,CAAC,MAAM;AACT,QAAM,GAAG,MAAM,iBAAiB,EAAE,WAAW,MAAM,CAAC;AACpD;;AAGF,KAAI,CAAC,KAAK,aAAa,CACrB,OAAM,IAAI,MAAM,mCAAmC,kBAAkB;AAIvE,MADgB,MAAM,GAAG,QAAQ,gBAAgB,EACrC,SAAS,KAAK,CAAC,MACzB,OAAM,IAAI,MACR,kCAAkC,gBAAgB,qCACnD;;AAIL,eAAsB,sBACpB,mBACA,iBACA,SACe;CACf,MAAM,UAAU,MAAM,GAAG,QAAQ,mBAAmB,EAAE,eAAe,MAAM,CAAC;AAE5E,MAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,aAAa,KAAK,KAAK,mBAAmB,MAAM,KAAK;EAC3D,MAAM,aAAa,MAAM,KAAK,SAAS,OAAO,GAAG,MAAM,KAAK,MAAM,GAAG,GAAG,GAAG,MAAM;EACjF,MAAM,aAAa,KAAK,KAAK,iBAAiB,WAAW;AAEzD,MAAI,MAAM,aAAa,EAAE;AACvB,SAAM,GAAG,MAAM,YAAY,EAAE,WAAW,MAAM,CAAC;AAC/C,SAAM,sBAAsB,YAAY,YAAY,QAAQ;AAC5D;;AAGF,MAAI,CAAC,MAAM,QAAQ,CACjB;EAIF,MAAM,WAAW,eADD,MAAM,GAAG,SAAS,YAAY,OAAO,EACZ,QAAQ,CAAC,QAAQ,UAAU,qBAAqB;AACzF,QAAM,GAAG,MAAM,KAAK,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;AAC7D,QAAM,GAAG,UAAU,YAAY,UAAU,OAAO;;;AAIpD,eAAsB,WAAW,iBAAwC;AACvE,OAAM,cAAc,QAAQ,CAAC,UAAU,EAAE;EACvC,KAAK;EACL,KAAK,QAAQ;EACd,CAAC;;AAGJ,eAAsB,WAAW,iBAAwC;AACvE,OAAM,cAAc,OAAO,CAAC,OAAO,EAAE;EACnC,KAAK;EACL,KAAK,QAAQ;EACd,CAAC"}
|
package/dist/src/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { runCli } from \"./runCli\";\r\n\r\nrunCli(process.argv.slice(2)).catch((error: unknown) => {\r\n const message = error instanceof Error ? error.message : String(error);\r\n console.error(message);\r\n process.exitCode = 1;\r\n});\r\n"],"mappings":";;;AAIA,OAAO,QAAQ,KAAK,MAAM,EAAE,CAAC,CAAC,OAAO,UAAmB;CACtD,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,SAAQ,MAAM,QAAQ;AACtB,SAAQ,WAAW;EACnB"}
|
package/dist/src/paths.mjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { TEMPLATE_NAME } from "./constants.mjs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import fs from "node:fs";
|
|
4
|
-
//#region src/paths.ts
|
|
5
|
-
function getTemplateRoot() {
|
|
6
|
-
const sourcePath = path.resolve(__dirname, "../templates", TEMPLATE_NAME);
|
|
7
|
-
if (fs.existsSync(sourcePath)) return sourcePath;
|
|
8
|
-
return path.resolve(__dirname, "../../templates", TEMPLATE_NAME);
|
|
9
|
-
}
|
|
10
|
-
//#endregion
|
|
11
|
-
export { getTemplateRoot };
|
|
12
|
-
|
|
13
|
-
//# sourceMappingURL=paths.mjs.map
|
package/dist/src/paths.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"paths.mjs","names":[],"sources":["../../src/paths.ts"],"sourcesContent":["import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { TEMPLATE_NAME } from \"./constants\";\r\n\r\nexport function getTemplateRoot(): string {\r\n const sourcePath = path.resolve(__dirname, \"../templates\", TEMPLATE_NAME);\r\n if (fs.existsSync(sourcePath)) {\r\n return sourcePath;\r\n }\r\n\r\n return path.resolve(__dirname, \"../../templates\", TEMPLATE_NAME);\r\n}\r\n"],"mappings":";;;;AAIA,SAAgB,kBAA0B;CACxC,MAAM,aAAa,KAAK,QAAQ,WAAW,gBAAgB,cAAc;AACzE,KAAI,GAAG,WAAW,WAAW,CAC3B,QAAO;AAGT,QAAO,KAAK,QAAQ,WAAW,mBAAmB,cAAc"}
|
package/dist/src/prompts.mjs
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_APP_NAME, getDefaultDescription } from "./constants.mjs";
|
|
2
|
-
import { slugifyAppName, toDisplayName } from "./strings.mjs";
|
|
3
|
-
import readline from "node:readline/promises";
|
|
4
|
-
import { stdin, stdout } from "node:process";
|
|
5
|
-
//#region src/prompts.ts
|
|
6
|
-
function requireInteractive(yes) {
|
|
7
|
-
if (!yes && !process.stdin.isTTY) throw new Error("Missing required values in a non-interactive shell. Pass --yes or provide flags.");
|
|
8
|
-
}
|
|
9
|
-
async function promptValue(question, fallback) {
|
|
10
|
-
const rl = readline.createInterface({
|
|
11
|
-
input: stdin,
|
|
12
|
-
output: stdout
|
|
13
|
-
});
|
|
14
|
-
try {
|
|
15
|
-
const suffix = fallback ? ` (${fallback})` : "";
|
|
16
|
-
return (await rl.question(`${question}${suffix}: `)).trim() || fallback || "";
|
|
17
|
-
} finally {
|
|
18
|
-
rl.close();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
async function resolveCreateCommandOptions(options) {
|
|
22
|
-
const resolved = { ...options };
|
|
23
|
-
if (!resolved.appName) {
|
|
24
|
-
requireInteractive(resolved.yes);
|
|
25
|
-
resolved.appName = resolved.yes ? resolved.targetDirectory ? toDisplayName(pathBaseName(resolved.targetDirectory)) : DEFAULT_APP_NAME : await promptValue("App name", resolved.targetDirectory ? pathBaseName(resolved.targetDirectory) : DEFAULT_APP_NAME);
|
|
26
|
-
}
|
|
27
|
-
resolved.appName = toDisplayName(resolved.appName);
|
|
28
|
-
if (!resolved.targetDirectory) {
|
|
29
|
-
requireInteractive(resolved.yes);
|
|
30
|
-
resolved.targetDirectory = resolved.yes ? slugifyAppName(resolved.appName) : await promptValue("Target directory", slugifyAppName(resolved.appName));
|
|
31
|
-
}
|
|
32
|
-
if (!resolved.appDescription) {
|
|
33
|
-
requireInteractive(resolved.yes);
|
|
34
|
-
const fallback = getDefaultDescription(resolved.appName);
|
|
35
|
-
resolved.appDescription = resolved.yes ? fallback : await promptValue("App description", fallback);
|
|
36
|
-
}
|
|
37
|
-
return resolved;
|
|
38
|
-
}
|
|
39
|
-
function pathBaseName(value) {
|
|
40
|
-
return value.replace(/[\\/]+$/g, "").split(/[\\/]/).filter(Boolean).at(-1) || "M5 Starter";
|
|
41
|
-
}
|
|
42
|
-
//#endregion
|
|
43
|
-
export { resolveCreateCommandOptions };
|
|
44
|
-
|
|
45
|
-
//# sourceMappingURL=prompts.mjs.map
|
package/dist/src/prompts.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.mjs","names":[],"sources":["../../src/prompts.ts"],"sourcesContent":["import readline from \"node:readline/promises\";\r\nimport { stdin as input, stdout as output } from \"node:process\";\r\nimport { DEFAULT_APP_NAME, getDefaultDescription } from \"./constants\";\r\nimport { slugifyAppName, toDisplayName } from \"./strings\";\r\nimport type { CreateCommandOptions } from \"./types\";\r\n\r\nfunction requireInteractive(yes: boolean): void {\r\n if (!yes && !process.stdin.isTTY) {\r\n throw new Error(\"Missing required values in a non-interactive shell. Pass --yes or provide flags.\");\r\n }\r\n}\r\n\r\nasync function promptValue(question: string, fallback?: string): Promise<string> {\r\n const rl = readline.createInterface({ input, output });\r\n\r\n try {\r\n const suffix = fallback ? ` (${fallback})` : \"\";\r\n const response = await rl.question(`${question}${suffix}: `);\r\n return response.trim() || fallback || \"\";\r\n } finally {\r\n rl.close();\r\n }\r\n}\r\n\r\nexport async function resolveCreateCommandOptions(\r\n options: CreateCommandOptions\r\n): Promise<CreateCommandOptions> {\r\n const resolved = { ...options };\r\n\r\n if (!resolved.appName) {\r\n requireInteractive(resolved.yes);\r\n resolved.appName = resolved.yes\r\n ? resolved.targetDirectory\r\n ? toDisplayName(pathBaseName(resolved.targetDirectory))\r\n : DEFAULT_APP_NAME\r\n : await promptValue(\"App name\", resolved.targetDirectory ? pathBaseName(resolved.targetDirectory) : DEFAULT_APP_NAME);\r\n }\r\n\r\n resolved.appName = toDisplayName(resolved.appName);\r\n\r\n if (!resolved.targetDirectory) {\r\n requireInteractive(resolved.yes);\r\n resolved.targetDirectory = resolved.yes\r\n ? slugifyAppName(resolved.appName)\r\n : await promptValue(\"Target directory\", slugifyAppName(resolved.appName));\r\n }\r\n\r\n if (!resolved.appDescription) {\r\n requireInteractive(resolved.yes);\r\n const fallback = getDefaultDescription(resolved.appName);\r\n resolved.appDescription = resolved.yes\r\n ? fallback\r\n : await promptValue(\"App description\", fallback);\r\n }\r\n\r\n return resolved;\r\n}\r\n\r\nfunction pathBaseName(value: string): string {\r\n const normalized = value.replace(/[\\\\/]+$/g, \"\");\r\n const segments = normalized.split(/[\\\\/]/).filter(Boolean);\r\n return segments.at(-1) || DEFAULT_APP_NAME;\r\n}\r\n"],"mappings":";;;;;AAMA,SAAS,mBAAmB,KAAoB;AAC9C,KAAI,CAAC,OAAO,CAAC,QAAQ,MAAM,MACzB,OAAM,IAAI,MAAM,mFAAmF;;AAIvG,eAAe,YAAY,UAAkB,UAAoC;CAC/E,MAAM,KAAK,SAAS,gBAAgB;EAAE,OAAA;EAAO,QAAA;EAAQ,CAAC;AAEtD,KAAI;EACF,MAAM,SAAS,WAAW,KAAK,SAAS,KAAK;AAE7C,UADiB,MAAM,GAAG,SAAS,GAAG,WAAW,OAAO,IAAI,EAC5C,MAAM,IAAI,YAAY;WAC9B;AACR,KAAG,OAAO;;;AAId,eAAsB,4BACpB,SAC+B;CAC/B,MAAM,WAAW,EAAE,GAAG,SAAS;AAE/B,KAAI,CAAC,SAAS,SAAS;AACrB,qBAAmB,SAAS,IAAI;AAChC,WAAS,UAAU,SAAS,MACxB,SAAS,kBACP,cAAc,aAAa,SAAS,gBAAgB,CAAC,GACrD,mBACF,MAAM,YAAY,YAAY,SAAS,kBAAkB,aAAa,SAAS,gBAAgB,GAAG,iBAAiB;;AAGzH,UAAS,UAAU,cAAc,SAAS,QAAQ;AAElD,KAAI,CAAC,SAAS,iBAAiB;AAC7B,qBAAmB,SAAS,IAAI;AAChC,WAAS,kBAAkB,SAAS,MAChC,eAAe,SAAS,QAAQ,GAChC,MAAM,YAAY,oBAAoB,eAAe,SAAS,QAAQ,CAAC;;AAG7E,KAAI,CAAC,SAAS,gBAAgB;AAC5B,qBAAmB,SAAS,IAAI;EAChC,MAAM,WAAW,sBAAsB,SAAS,QAAQ;AACxD,WAAS,iBAAiB,SAAS,MAC/B,WACA,MAAM,YAAY,mBAAmB,SAAS;;AAGpD,QAAO;;AAGT,SAAS,aAAa,OAAuB;AAG3C,QAFmB,MAAM,QAAQ,YAAY,GAAG,CACpB,MAAM,QAAQ,CAAC,OAAO,QAAQ,CAC1C,GAAG,GAAG,IAAA"}
|
package/dist/src/runCli.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runCli.mjs","names":[],"sources":["../../src/runCli.ts"],"sourcesContent":["import { scaffoldProject } from \"./create\";\r\nimport type { CreateCommandOptions } from \"./types\";\r\n\r\ninterface ParsedCli {\r\n command?: string;\r\n directory?: string;\r\n help?: boolean;\r\n options: Record<string, string | boolean>;\r\n}\r\n\r\nexport async function runCli(argv: readonly string[]): Promise<void> {\r\n const parsed = parseCli(argv);\r\n\r\n if (\r\n !parsed.command ||\r\n parsed.help ||\r\n parsed.command === \"--help\" ||\r\n parsed.command === \"-h\" ||\r\n parsed.command === \"help\"\r\n ) {\r\n printHelp();\r\n return;\r\n }\r\n\r\n if (parsed.command !== \"create\") {\r\n throw new Error(`Unknown command: ${parsed.command}`);\r\n }\r\n\r\n const options = toCreateCommandOptions(parsed);\r\n const result = await scaffoldProject(options);\r\n\r\n console.log(\"\");\r\n console.log(`Scaffolded ${result.context.appName} in ${result.targetDirectory}`);\r\n console.log(\"\");\r\n console.log(\"Next steps:\");\r\n console.log(` cd ${result.targetDirectory}`);\r\n if (options.skipInstall) {\r\n console.log(\" pnpm install\");\r\n }\r\n console.log(\" pnpm --filter ./apps/server sync\");\r\n console.log(\" pnpm dev\");\r\n}\r\n\r\nexport function parseCli(argv: readonly string[]): ParsedCli {\r\n const normalizedArgv = normalizeCliArgv(argv);\r\n const [command, ...rest] = normalizedArgv;\r\n const options: Record<string, string | boolean> = {};\r\n let directory: string | undefined;\r\n let help = false;\r\n\r\n for (let index = 0; index < rest.length; index += 1) {\r\n const token = rest[index];\r\n\r\n if (token === \"--help\" || token === \"-h\") {\r\n help = true;\r\n continue;\r\n }\r\n\r\n if (!token.startsWith(\"--\")) {\r\n directory ??= token;\r\n continue;\r\n }\r\n\r\n const [rawKey, inlineValue] = token.slice(2).split(\"=\", 2);\r\n\r\n if (isBooleanFlag(rawKey)) {\r\n options[rawKey] = true;\r\n continue;\r\n }\r\n\r\n const nextValue = inlineValue ?? rest[index + 1];\r\n if (!nextValue || nextValue.startsWith(\"--\")) {\r\n throw new Error(`Missing value for --${rawKey}`);\r\n }\r\n\r\n options[rawKey] = nextValue;\r\n if (inlineValue === undefined) {\r\n index += 1;\r\n }\r\n }\r\n\r\n return { command, directory, help, options };\r\n}\r\n\r\nfunction normalizeCliArgv(argv: readonly string[]): readonly string[] {\r\n const [firstToken] = argv;\r\n\r\n if (!firstToken || firstToken === \"create\" || firstToken === \"--help\" || firstToken === \"-h\") {\r\n return argv;\r\n }\r\n\r\n if (firstToken === \"help\") {\r\n return [\"--help\"];\r\n }\r\n\r\n return [\"create\", ...argv];\r\n}\r\n\r\nfunction isBooleanFlag(value: string): boolean {\r\n return [\"yes\", \"force\", \"skip-install\", \"skip-git\"].includes(value);\r\n}\r\n\r\nfunction toCreateCommandOptions(parsed: ParsedCli): CreateCommandOptions {\r\n return {\r\n targetDirectory: parsed.directory,\r\n appName: getStringOption(parsed.options, \"name\"),\r\n appDescription: getStringOption(parsed.options, \"description\"),\r\n yes: Boolean(parsed.options.yes),\r\n force: Boolean(parsed.options.force),\r\n skipInstall: Boolean(parsed.options[\"skip-install\"]),\r\n skipGit: Boolean(parsed.options[\"skip-git\"]),\r\n };\r\n}\r\n\r\nfunction getStringOption(\r\n options: Record<string, string | boolean>,\r\n key: string\r\n): string | undefined {\r\n const value = options[key];\r\n return typeof value === \"string\" ? value : undefined;\r\n}\r\n\r\nfunction printHelp(): void {\r\n console.log(\"m5kdev\");\r\n console.log(\"\");\r\n console.log(\"Usage:\");\r\n console.log(\" pnpm create m5kdev [directory] [options]\");\r\n console.log(\" m5kdev [directory] [options]\");\r\n console.log(\" m5kdev create [directory] [options]\");\r\n console.log(\"\");\r\n console.log(\"Options:\");\r\n console.log(\" --name <value> Set the app name\");\r\n console.log(\" --description <value> Set the app description\");\r\n console.log(\" --yes Accept defaults for missing prompts\");\r\n console.log(\" --force Allow writing into a non-empty directory\");\r\n console.log(\" --skip-install Skip pnpm install\");\r\n console.log(\" --skip-git Skip git init\");\r\n}\r\n"],"mappings":";;AAUA,eAAsB,OAAO,MAAwC;CACnE,MAAM,SAAS,SAAS,KAAK;AAE7B,KACE,CAAC,OAAO,WACR,OAAO,QACP,OAAO,YAAY,YACnB,OAAO,YAAY,QACnB,OAAO,YAAY,QACnB;AACA,aAAW;AACX;;AAGF,KAAI,OAAO,YAAY,SACrB,OAAM,IAAI,MAAM,oBAAoB,OAAO,UAAU;CAGvD,MAAM,UAAU,uBAAuB,OAAO;CAC9C,MAAM,SAAS,MAAM,gBAAgB,QAAQ;AAE7C,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,cAAc,OAAO,QAAQ,QAAQ,MAAM,OAAO,kBAAkB;AAChF,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,cAAc;AAC1B,SAAQ,IAAI,QAAQ,OAAO,kBAAkB;AAC7C,KAAI,QAAQ,YACV,SAAQ,IAAI,iBAAiB;AAE/B,SAAQ,IAAI,qCAAqC;AACjD,SAAQ,IAAI,aAAa;;AAG3B,SAAgB,SAAS,MAAoC;CAE3D,MAAM,CAAC,SAAS,GAAG,QADI,iBAAiB,KAAK;CAE7C,MAAM,UAA4C,EAAE;CACpD,IAAI;CACJ,IAAI,OAAO;AAEX,MAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;EACnD,MAAM,QAAQ,KAAK;AAEnB,MAAI,UAAU,YAAY,UAAU,MAAM;AACxC,UAAO;AACP;;AAGF,MAAI,CAAC,MAAM,WAAW,KAAK,EAAE;AAC3B,iBAAc;AACd;;EAGF,MAAM,CAAC,QAAQ,eAAe,MAAM,MAAM,EAAE,CAAC,MAAM,KAAK,EAAE;AAE1D,MAAI,cAAc,OAAO,EAAE;AACzB,WAAQ,UAAU;AAClB;;EAGF,MAAM,YAAY,eAAe,KAAK,QAAQ;AAC9C,MAAI,CAAC,aAAa,UAAU,WAAW,KAAK,CAC1C,OAAM,IAAI,MAAM,uBAAuB,SAAS;AAGlD,UAAQ,UAAU;AAClB,MAAI,gBAAgB,KAAA,EAClB,UAAS;;AAIb,QAAO;EAAE;EAAS;EAAW;EAAM;EAAS;;AAG9C,SAAS,iBAAiB,MAA4C;CACpE,MAAM,CAAC,cAAc;AAErB,KAAI,CAAC,cAAc,eAAe,YAAY,eAAe,YAAY,eAAe,KACtF,QAAO;AAGT,KAAI,eAAe,OACjB,QAAO,CAAC,SAAS;AAGnB,QAAO,CAAC,UAAU,GAAG,KAAK;;AAG5B,SAAS,cAAc,OAAwB;AAC7C,QAAO;EAAC;EAAO;EAAS;EAAgB;EAAW,CAAC,SAAS,MAAM;;AAGrE,SAAS,uBAAuB,QAAyC;AACvE,QAAO;EACL,iBAAiB,OAAO;EACxB,SAAS,gBAAgB,OAAO,SAAS,OAAO;EAChD,gBAAgB,gBAAgB,OAAO,SAAS,cAAc;EAC9D,KAAK,QAAQ,OAAO,QAAQ,IAAI;EAChC,OAAO,QAAQ,OAAO,QAAQ,MAAM;EACpC,aAAa,QAAQ,OAAO,QAAQ,gBAAgB;EACpD,SAAS,QAAQ,OAAO,QAAQ,YAAY;EAC7C;;AAGH,SAAS,gBACP,SACA,KACoB;CACpB,MAAM,QAAQ,QAAQ;AACtB,QAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;;AAG7C,SAAS,YAAkB;AACzB,SAAQ,IAAI,SAAS;AACrB,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,SAAS;AACrB,SAAQ,IAAI,6CAA6C;AACzD,SAAQ,IAAI,iCAAiC;AAC7C,SAAQ,IAAI,wCAAwC;AACpD,SAAQ,IAAI,GAAG;AACf,SAAQ,IAAI,WAAW;AACvB,SAAQ,IAAI,8CAA8C;AAC1D,SAAQ,IAAI,qDAAqD;AACjE,SAAQ,IAAI,iEAAiE;AAC7E,SAAQ,IAAI,sEAAsE;AAClF,SAAQ,IAAI,+CAA+C;AAC3D,SAAQ,IAAI,2CAA2C"}
|
package/dist/src/types.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
File without changes
|