@morda-dev/create-sdk 1.2.1 → 1.3.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/bin/create-sdk.js +51 -11
- package/package.json +1 -1
- package/src/cli/scaffold.js +20 -16
package/bin/create-sdk.js
CHANGED
|
@@ -13,7 +13,7 @@ const CURRENT_NODE_MAJOR = Number(process.versions.node.split(".")[0]);
|
|
|
13
13
|
if (CURRENT_NODE_MAJOR < REQUIRED_NODE_MAJOR) {
|
|
14
14
|
console.error(
|
|
15
15
|
`❌ Node.js ${REQUIRED_NODE_MAJOR}+ is required.\n` +
|
|
16
|
-
|
|
16
|
+
` You are using Node.js ${process.versions.node}`
|
|
17
17
|
);
|
|
18
18
|
process.exit(1);
|
|
19
19
|
}
|
|
@@ -35,7 +35,27 @@ const flags = {
|
|
|
35
35
|
const projectName = rawArgs.find((a) => !a.startsWith("-"));
|
|
36
36
|
|
|
37
37
|
/* ============================================================================
|
|
38
|
-
*
|
|
38
|
+
* Help (EARLY EXIT, SNAPSHOT SAFE)
|
|
39
|
+
* ============================================================================
|
|
40
|
+
*/
|
|
41
|
+
if (rawArgs.includes("--help") || rawArgs.includes("-h")) {
|
|
42
|
+
console.log(
|
|
43
|
+
`Usage:
|
|
44
|
+
create-sdk <project-name> [options]
|
|
45
|
+
|
|
46
|
+
Options:
|
|
47
|
+
--yes Skip all prompts
|
|
48
|
+
--no-git Do not initialize git repository
|
|
49
|
+
--no-install Do not install dependencies
|
|
50
|
+
--dry-run Show what would be done without writing files
|
|
51
|
+
--force Overwrite existing directory
|
|
52
|
+
--help, -h Show this help message`
|
|
53
|
+
);
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* ============================================================================
|
|
58
|
+
* Interactive / Non-interactive resolution
|
|
39
59
|
* ============================================================================
|
|
40
60
|
*/
|
|
41
61
|
let name = projectName;
|
|
@@ -66,7 +86,7 @@ if (!flags.yes && !name) {
|
|
|
66
86
|
],
|
|
67
87
|
{
|
|
68
88
|
onCancel: () => {
|
|
69
|
-
console.
|
|
89
|
+
console.error("❌ Cancelled");
|
|
70
90
|
process.exit(1);
|
|
71
91
|
},
|
|
72
92
|
}
|
|
@@ -77,19 +97,39 @@ if (!flags.yes && !name) {
|
|
|
77
97
|
installDeps = answers.installDeps;
|
|
78
98
|
}
|
|
79
99
|
|
|
100
|
+
/* ============================================================================
|
|
101
|
+
* Validation
|
|
102
|
+
* ============================================================================
|
|
103
|
+
*/
|
|
80
104
|
if (!name) {
|
|
81
105
|
console.error("❌ Project name is required");
|
|
82
106
|
process.exit(1);
|
|
83
107
|
}
|
|
84
108
|
|
|
85
109
|
/* ============================================================================
|
|
86
|
-
* Execute scaffold
|
|
110
|
+
* Execute scaffold (CLI CONTRACT OWNER)
|
|
87
111
|
* ============================================================================
|
|
88
112
|
*/
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
113
|
+
try {
|
|
114
|
+
await scaffold({
|
|
115
|
+
projectName: name,
|
|
116
|
+
initGit,
|
|
117
|
+
installDeps,
|
|
118
|
+
dryRun: flags.dryRun,
|
|
119
|
+
force: flags.force,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
if (flags.dryRun) {
|
|
123
|
+
console.log("ℹ️ Dry run completed. No files were written.");
|
|
124
|
+
} else {
|
|
125
|
+
console.log("🎉 SDK scaffolded successfully!");
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
process.exit(0);
|
|
129
|
+
} catch (err) {
|
|
130
|
+
const message =
|
|
131
|
+
err instanceof Error ? err.message : "Unexpected error occurred";
|
|
132
|
+
|
|
133
|
+
console.error(`❌ ${message}`);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
package/package.json
CHANGED
package/src/cli/scaffold.js
CHANGED
|
@@ -8,6 +8,10 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
8
8
|
const __dirname = path.dirname(__filename);
|
|
9
9
|
const templateDir = path.resolve(__dirname, "../../template");
|
|
10
10
|
|
|
11
|
+
const isTest =
|
|
12
|
+
process.env.NODE_ENV === "test" ||
|
|
13
|
+
process.env.VITEST === "true";
|
|
14
|
+
|
|
11
15
|
export async function scaffold({
|
|
12
16
|
projectName,
|
|
13
17
|
initGit = true,
|
|
@@ -26,7 +30,14 @@ export async function scaffold({
|
|
|
26
30
|
const targetDir = path.resolve(process.cwd(), dirName);
|
|
27
31
|
|
|
28
32
|
// ─────────────────────────────────────────────
|
|
29
|
-
//
|
|
33
|
+
// 🔒 CLI CONTRACT — EARLY FAILURE
|
|
34
|
+
// ─────────────────────────────────────────────
|
|
35
|
+
if (fs.existsSync(targetDir) && !force) {
|
|
36
|
+
throw new Error(`Directory "${dirName}" already exists`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ─────────────────────────────────────────────
|
|
40
|
+
// 🧪 DRY-RUN — NO SIDE EFFECTS
|
|
30
41
|
// ─────────────────────────────────────────────
|
|
31
42
|
if (dryRun) {
|
|
32
43
|
console.log("🧪 [dry-run] Creating SDK:", projectName);
|
|
@@ -35,26 +46,22 @@ export async function scaffold({
|
|
|
35
46
|
if (initGit) console.log("🧪 [dry-run] Would init git");
|
|
36
47
|
if (installDeps) console.log("🧪 [dry-run] Would install dependencies");
|
|
37
48
|
console.log("🧪 [dry-run] Done (NO filesystem changes)");
|
|
38
|
-
return;
|
|
49
|
+
return { targetDir };
|
|
39
50
|
}
|
|
40
51
|
|
|
41
52
|
// ─────────────────────────────────────────────
|
|
42
|
-
// REAL MODE —
|
|
53
|
+
// REAL MODE — FS MUTATIONS
|
|
43
54
|
// ─────────────────────────────────────────────
|
|
44
55
|
if (!fs.existsSync(templateDir)) {
|
|
45
56
|
throw new Error(`Template directory not found: ${templateDir}`);
|
|
46
57
|
}
|
|
47
58
|
|
|
48
|
-
if (fs.existsSync(targetDir)) {
|
|
49
|
-
if (!force) {
|
|
50
|
-
throw new Error(`Directory "${dirName}" already exists`);
|
|
51
|
-
}
|
|
59
|
+
if (fs.existsSync(targetDir) && force) {
|
|
52
60
|
fs.rmSync(targetDir, { recursive: true, force: true });
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
console.log("🚀 Creating SDK:", projectName);
|
|
56
64
|
|
|
57
|
-
// copy template
|
|
58
65
|
copyDir(templateDir, targetDir);
|
|
59
66
|
|
|
60
67
|
// package.json
|
|
@@ -63,11 +70,8 @@ export async function scaffold({
|
|
|
63
70
|
|
|
64
71
|
pkg.name = projectName;
|
|
65
72
|
pkg.version = "0.1.0";
|
|
66
|
-
|
|
67
|
-
// шаблон НЕ должен быть private
|
|
68
73
|
delete pkg.private;
|
|
69
74
|
|
|
70
|
-
// exports добавляются ТОЛЬКО тут
|
|
71
75
|
pkg.main = "./dist/index.js";
|
|
72
76
|
pkg.types = "./dist/index.d.ts";
|
|
73
77
|
pkg.exports = {
|
|
@@ -88,20 +92,20 @@ export async function scaffold({
|
|
|
88
92
|
fs.writeFileSync(readmePath, updated);
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
// git
|
|
92
|
-
if (initGit) {
|
|
95
|
+
// git (disabled in tests)
|
|
96
|
+
if (initGit && !isTest) {
|
|
93
97
|
try {
|
|
94
98
|
execSync("git init", { cwd: targetDir, stdio: "ignore" });
|
|
95
99
|
} catch {}
|
|
96
100
|
}
|
|
97
101
|
|
|
98
|
-
// deps
|
|
99
|
-
if (installDeps) {
|
|
102
|
+
// deps (disabled in tests)
|
|
103
|
+
if (installDeps && !isTest) {
|
|
100
104
|
execSync("npm install", {
|
|
101
105
|
cwd: targetDir,
|
|
102
106
|
stdio: "inherit",
|
|
103
107
|
});
|
|
104
108
|
}
|
|
105
109
|
|
|
106
|
-
|
|
110
|
+
return { targetDir };
|
|
107
111
|
}
|