@fersonull/create-npm 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +143 -0
- package/dist/utils.d.ts +6 -0
- package/dist/utils.js +71 -0
- package/package.json +22 -0
- package/src/cli.ts +176 -0
- package/src/utils.ts +38 -0
- package/tsconfig.json +12 -0
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
async function main() {
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
const projectName = args[0];
|
|
14
|
+
const isWindows = process.platform === "win32";
|
|
15
|
+
if (!projectName) {
|
|
16
|
+
utils_1.log.error("Please provide a package name as an argument.");
|
|
17
|
+
utils_1.log.info("Usage: npx create-npm <project-name>");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(projectName)) {
|
|
21
|
+
utils_1.log.error("Invalid project name. Use only alphanumeric characters, dashes, and underscores.");
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
const projectPath = path_1.default.resolve(process.cwd(), projectName);
|
|
25
|
+
const srcPath = path_1.default.join(projectPath, "src");
|
|
26
|
+
if ((0, fs_1.existsSync)(projectPath)) {
|
|
27
|
+
utils_1.log.error("Package with the same name already exists.");
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
(0, fs_1.mkdirSync)(projectPath);
|
|
32
|
+
(0, fs_1.mkdirSync)(srcPath);
|
|
33
|
+
const initGit = (0, child_process_1.spawnSync)("git", ["init"], {
|
|
34
|
+
cwd: projectPath,
|
|
35
|
+
encoding: "utf-8",
|
|
36
|
+
});
|
|
37
|
+
if (initGit.error || initGit.status !== 0) {
|
|
38
|
+
throw new Error(initGit.error?.message);
|
|
39
|
+
}
|
|
40
|
+
const packageJsonContent = {
|
|
41
|
+
name: projectName,
|
|
42
|
+
description: "This developer is lazy to add a description",
|
|
43
|
+
keywords: [],
|
|
44
|
+
author: "",
|
|
45
|
+
version: "1.0.0",
|
|
46
|
+
type: "module",
|
|
47
|
+
main: "./dist/index.cjs",
|
|
48
|
+
module: "./dist/index.js",
|
|
49
|
+
types: "./dist/index.d.ts",
|
|
50
|
+
exports: {
|
|
51
|
+
".": {
|
|
52
|
+
types: "./dist/index.d.ts",
|
|
53
|
+
import: "./dist/index.js",
|
|
54
|
+
require: "./dist/index.cjs",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
scripts: {
|
|
58
|
+
test: "vitest run",
|
|
59
|
+
"test:watch": "vitest",
|
|
60
|
+
build: "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
61
|
+
dev: "tsup src/index.ts --format cjs,esm --watch --dts",
|
|
62
|
+
},
|
|
63
|
+
files: ["dist", "README.md", "LICENCE"],
|
|
64
|
+
devDependencies: {
|
|
65
|
+
tsup: "^8.5.1",
|
|
66
|
+
typescript: "^5.9.3",
|
|
67
|
+
vitest: "^4.0.18",
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
const tsconfigContent = {
|
|
71
|
+
compilerOptions: {
|
|
72
|
+
target: "ESNext",
|
|
73
|
+
module: "NodeNext",
|
|
74
|
+
moduleResolution: "NodeNext",
|
|
75
|
+
declaration: true,
|
|
76
|
+
strict: true,
|
|
77
|
+
outDir: "dist",
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
const gitIgnoreContent = `
|
|
81
|
+
# Dependencies
|
|
82
|
+
node_modules/
|
|
83
|
+
.pnpm-store/
|
|
84
|
+
|
|
85
|
+
# Build
|
|
86
|
+
dist/
|
|
87
|
+
build/
|
|
88
|
+
|
|
89
|
+
# Environment and Secrets
|
|
90
|
+
.env
|
|
91
|
+
.env.local
|
|
92
|
+
.env.*.local
|
|
93
|
+
|
|
94
|
+
# Logs
|
|
95
|
+
npm-debug.log*
|
|
96
|
+
yarn-debug.log*
|
|
97
|
+
yarn-error.log*
|
|
98
|
+
|
|
99
|
+
# System Files
|
|
100
|
+
.DS_Store
|
|
101
|
+
Thumbs.db
|
|
102
|
+
|
|
103
|
+
# IDEs
|
|
104
|
+
.vscode/
|
|
105
|
+
.idea/
|
|
106
|
+
*.swp
|
|
107
|
+
`;
|
|
108
|
+
(0, fs_1.writeFileSync)(path_1.default.join(projectPath, "package.json"), JSON.stringify(packageJsonContent, null, 2), { mode: 0o644 });
|
|
109
|
+
(0, fs_1.writeFileSync)(path_1.default.join(projectPath, "tsconfig.json"), JSON.stringify(tsconfigContent, null, 2), { mode: 0o644 });
|
|
110
|
+
(0, fs_1.writeFileSync)(path_1.default.join(projectPath, ".gitignore"), gitIgnoreContent, {
|
|
111
|
+
mode: 0o644,
|
|
112
|
+
});
|
|
113
|
+
(0, fs_1.writeFileSync)(path_1.default.join(srcPath, "index.ts"), ``, { mode: 0o644 });
|
|
114
|
+
utils_1.log.success(initGit.stdout);
|
|
115
|
+
const shouldInstall = await (0, utils_1.promptConfirm)('Would you like to run "npm install" now?');
|
|
116
|
+
const npmCmd = isWindows ? "npm.cmd" : "npm";
|
|
117
|
+
if (shouldInstall) {
|
|
118
|
+
const npmInstall = (0, child_process_1.spawnSync)(npmCmd, ["install"], {
|
|
119
|
+
cwd: projectPath,
|
|
120
|
+
stdio: "inherit",
|
|
121
|
+
shell: isWindows,
|
|
122
|
+
});
|
|
123
|
+
if (npmInstall.status !== 0 || npmInstall.error) {
|
|
124
|
+
utils_1.log.error("Dependency installation failed. You can manually install it later.");
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
utils_1.log.success("\nDependencies installed successfully.");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
utils_1.log.success(`\nProject created at ${projectPath}`);
|
|
131
|
+
console.log("\nNext steps:");
|
|
132
|
+
console.log(` cd ${projectName}`);
|
|
133
|
+
console.log(" npm run dev\n");
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
utils_1.log.error(error instanceof Error ? error.message : String(error));
|
|
137
|
+
if ((0, fs_1.existsSync)(projectPath)) {
|
|
138
|
+
(0, fs_1.rmSync)(projectPath, { recursive: true, force: true });
|
|
139
|
+
}
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
main();
|
package/dist/utils.d.ts
ADDED
package/dist/utils.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.promptConfirm = exports.log = void 0;
|
|
37
|
+
const readline = __importStar(require("readline"));
|
|
38
|
+
exports.log = {
|
|
39
|
+
error: (message) => {
|
|
40
|
+
console.log("\x1b[31m%s\x1b[0m", `Error: ${message}`);
|
|
41
|
+
},
|
|
42
|
+
success: (message) => {
|
|
43
|
+
console.log("\x1b[32m%s\x1b[0m", message);
|
|
44
|
+
},
|
|
45
|
+
info: (message) => {
|
|
46
|
+
console.log("\x1b[36m%s\x1b[0m", message);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
const promptConfirm = (question) => {
|
|
50
|
+
const rl = readline.createInterface({
|
|
51
|
+
input: process.stdin,
|
|
52
|
+
output: process.stdout,
|
|
53
|
+
});
|
|
54
|
+
return new Promise((resolve) => {
|
|
55
|
+
const ask = () => {
|
|
56
|
+
rl.question(`${question} (Y/n) → `, (answer) => {
|
|
57
|
+
const normalized = answer.trim().toLowerCase() || "y";
|
|
58
|
+
if (["y", "yes"].includes(normalized)) {
|
|
59
|
+
rl.close();
|
|
60
|
+
resolve(true);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
rl.close();
|
|
64
|
+
resolve(false);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
ask();
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
exports.promptConfirm = promptConfirm;
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fersonull/create-npm",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Automated project scaffolding tool",
|
|
5
|
+
"main": "dist/cli.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-npm-pack": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "npm run build && node ./dist/cli.js",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"author": {
|
|
15
|
+
"name": "Jasfer Monton"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "^20.0.0",
|
|
20
|
+
"typescript": "^5.0.0"
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from "child_process";
|
|
4
|
+
import { mkdirSync, existsSync, writeFileSync, rmSync } from "fs";
|
|
5
|
+
import { log, promptConfirm } from "./utils";
|
|
6
|
+
import path from "path";
|
|
7
|
+
|
|
8
|
+
async function main() {
|
|
9
|
+
const args: string[] = process.argv.slice(2);
|
|
10
|
+
const projectName: string = args[0];
|
|
11
|
+
const isWindows = process.platform === "win32";
|
|
12
|
+
|
|
13
|
+
if (!projectName) {
|
|
14
|
+
log.error("Please provide a package name as an argument.");
|
|
15
|
+
log.info("Usage: npx create-npm <project-name>");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(projectName)) {
|
|
20
|
+
log.error(
|
|
21
|
+
"Invalid project name. Use only alphanumeric characters, dashes, and underscores.",
|
|
22
|
+
);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const projectPath: string = path.resolve(process.cwd(), projectName);
|
|
27
|
+
const srcPath = path.join(projectPath, "src");
|
|
28
|
+
|
|
29
|
+
if (existsSync(projectPath)) {
|
|
30
|
+
log.error("Package with the same name already exists.");
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
mkdirSync(projectPath);
|
|
36
|
+
mkdirSync(srcPath);
|
|
37
|
+
|
|
38
|
+
const initGit = spawnSync("git", ["init"], {
|
|
39
|
+
cwd: projectPath,
|
|
40
|
+
encoding: "utf-8",
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (initGit.error || initGit.status !== 0) {
|
|
44
|
+
throw new Error(initGit.error?.message);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const packageJsonContent = {
|
|
48
|
+
name: projectName,
|
|
49
|
+
description: "This developer is lazy to add a description",
|
|
50
|
+
keywords: [],
|
|
51
|
+
author: "",
|
|
52
|
+
version: "1.0.0",
|
|
53
|
+
type: "module",
|
|
54
|
+
main: "./dist/index.cjs",
|
|
55
|
+
module: "./dist/index.js",
|
|
56
|
+
types: "./dist/index.d.ts",
|
|
57
|
+
exports: {
|
|
58
|
+
".": {
|
|
59
|
+
types: "./dist/index.d.ts",
|
|
60
|
+
import: "./dist/index.js",
|
|
61
|
+
require: "./dist/index.cjs",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
scripts: {
|
|
65
|
+
test: "vitest run",
|
|
66
|
+
"test:watch": "vitest",
|
|
67
|
+
build: "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
68
|
+
dev: "tsup src/index.ts --format cjs,esm --watch --dts",
|
|
69
|
+
},
|
|
70
|
+
files: ["dist", "README.md", "LICENCE"],
|
|
71
|
+
devDependencies: {
|
|
72
|
+
tsup: "^8.5.1",
|
|
73
|
+
typescript: "^5.9.3",
|
|
74
|
+
vitest: "^4.0.18",
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const tsconfigContent = {
|
|
79
|
+
compilerOptions: {
|
|
80
|
+
target: "ESNext",
|
|
81
|
+
module: "NodeNext",
|
|
82
|
+
moduleResolution: "NodeNext",
|
|
83
|
+
declaration: true,
|
|
84
|
+
strict: true,
|
|
85
|
+
outDir: "dist",
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const gitIgnoreContent = `
|
|
90
|
+
# Dependencies
|
|
91
|
+
node_modules/
|
|
92
|
+
.pnpm-store/
|
|
93
|
+
|
|
94
|
+
# Build
|
|
95
|
+
dist/
|
|
96
|
+
build/
|
|
97
|
+
|
|
98
|
+
# Environment and Secrets
|
|
99
|
+
.env
|
|
100
|
+
.env.local
|
|
101
|
+
.env.*.local
|
|
102
|
+
|
|
103
|
+
# Logs
|
|
104
|
+
npm-debug.log*
|
|
105
|
+
yarn-debug.log*
|
|
106
|
+
yarn-error.log*
|
|
107
|
+
|
|
108
|
+
# System Files
|
|
109
|
+
.DS_Store
|
|
110
|
+
Thumbs.db
|
|
111
|
+
|
|
112
|
+
# IDEs
|
|
113
|
+
.vscode/
|
|
114
|
+
.idea/
|
|
115
|
+
*.swp
|
|
116
|
+
`;
|
|
117
|
+
|
|
118
|
+
writeFileSync(
|
|
119
|
+
path.join(projectPath, "package.json"),
|
|
120
|
+
JSON.stringify(packageJsonContent, null, 2),
|
|
121
|
+
{ mode: 0o644 },
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
writeFileSync(
|
|
125
|
+
path.join(projectPath, "tsconfig.json"),
|
|
126
|
+
JSON.stringify(tsconfigContent, null, 2),
|
|
127
|
+
{ mode: 0o644 },
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
writeFileSync(path.join(projectPath, ".gitignore"), gitIgnoreContent, {
|
|
131
|
+
mode: 0o644,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
writeFileSync(path.join(srcPath, "index.ts"), ``, { mode: 0o644 });
|
|
135
|
+
|
|
136
|
+
log.success(initGit.stdout);
|
|
137
|
+
|
|
138
|
+
const shouldInstall = await promptConfirm(
|
|
139
|
+
'Would you like to run "npm install" now?',
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
const npmCmd = isWindows ? "npm.cmd" : "npm";
|
|
143
|
+
|
|
144
|
+
if (shouldInstall) {
|
|
145
|
+
const npmInstall = spawnSync(npmCmd, ["install"], {
|
|
146
|
+
cwd: projectPath,
|
|
147
|
+
stdio: "inherit",
|
|
148
|
+
shell: isWindows,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
if (npmInstall.status !== 0 || npmInstall.error) {
|
|
152
|
+
log.error(
|
|
153
|
+
"Dependency installation failed. You can manually install it later.",
|
|
154
|
+
);
|
|
155
|
+
} else {
|
|
156
|
+
log.success("\nDependencies installed successfully.");
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
log.success(`\nProject created at ${projectPath}`);
|
|
161
|
+
|
|
162
|
+
console.log("\nNext steps:");
|
|
163
|
+
console.log(` cd ${projectName}`);
|
|
164
|
+
console.log(" npm run dev\n");
|
|
165
|
+
} catch (error) {
|
|
166
|
+
log.error(error instanceof Error ? error.message : String(error));
|
|
167
|
+
|
|
168
|
+
if (existsSync(projectPath)) {
|
|
169
|
+
rmSync(projectPath, { recursive: true, force: true });
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
main();
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as readline from "readline";
|
|
2
|
+
|
|
3
|
+
export const log = {
|
|
4
|
+
error: (message: string) => {
|
|
5
|
+
console.log("\x1b[31m%s\x1b[0m", `Error: ${message}`);
|
|
6
|
+
},
|
|
7
|
+
success: (message: string) => {
|
|
8
|
+
console.log("\x1b[32m%s\x1b[0m", message);
|
|
9
|
+
},
|
|
10
|
+
info: (message: string) => {
|
|
11
|
+
console.log("\x1b[36m%s\x1b[0m", message);
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const promptConfirm = (question: string): Promise<boolean> => {
|
|
16
|
+
const rl = readline.createInterface({
|
|
17
|
+
input: process.stdin,
|
|
18
|
+
output: process.stdout,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
const ask = () => {
|
|
23
|
+
rl.question(`${question} (Y/n) → `, (answer) => {
|
|
24
|
+
const normalized = answer.trim().toLowerCase() || "y";
|
|
25
|
+
|
|
26
|
+
if (["y", "yes"].includes(normalized)) {
|
|
27
|
+
rl.close();
|
|
28
|
+
resolve(true);
|
|
29
|
+
} else {
|
|
30
|
+
rl.close();
|
|
31
|
+
resolve(false);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
ask();
|
|
37
|
+
});
|
|
38
|
+
};
|
package/tsconfig.json
ADDED