@project-selene/create-mod 0.0.7 → 0.0.8
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/main.mjs +4 -4
- package/package.json +1 -1
- package/template/.gitignore +3 -0
- package/src/main.mts +0 -182
- package/tsconfig.json +0 -45
package/dist/main.mjs
CHANGED
|
@@ -30,15 +30,13 @@ async function copyDir(src, dest) {
|
|
|
30
30
|
}
|
|
31
31
|
async function runNpmInstall(cwd) {
|
|
32
32
|
return new Promise((resolve, reject) => {
|
|
33
|
-
const
|
|
34
|
-
const child = spawn(cmd, ["install"], { cwd, stdio: "inherit" });
|
|
33
|
+
const child = spawn("npm", ["install"], { cwd, stdio: "inherit" });
|
|
35
34
|
child.on("close", (code) => code === 0 ? resolve() : reject(new Error("npm install failed")));
|
|
36
35
|
});
|
|
37
36
|
}
|
|
38
37
|
async function runGitInit(cwd) {
|
|
39
38
|
return new Promise((resolve, reject) => {
|
|
40
|
-
const
|
|
41
|
-
const child = spawn(cmd, ["init"], { cwd, stdio: "inherit" });
|
|
39
|
+
const child = spawn("git", ["init"], { cwd, stdio: "inherit" });
|
|
42
40
|
child.on("close", (code) => code === 0 ? resolve() : reject(new Error("git init failed")));
|
|
43
41
|
});
|
|
44
42
|
}
|
|
@@ -131,6 +129,8 @@ async function main() {
|
|
|
131
129
|
}
|
|
132
130
|
console.log("Installing dependencies...");
|
|
133
131
|
await runNpmInstall(destPath);
|
|
132
|
+
console.log("Installing git repository...");
|
|
133
|
+
await runGitInit(destPath);
|
|
134
134
|
console.log("Done. Project initialized at", destPath);
|
|
135
135
|
} catch (err) {
|
|
136
136
|
console.error("Error:", err.message || err);
|
package/package.json
CHANGED
package/src/main.mts
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { spawn } from 'child_process';
|
|
4
|
-
import { Command } from 'commander';
|
|
5
|
-
import { promises as fsp } from 'fs';
|
|
6
|
-
import inquirer, { type DistinctQuestion } from 'inquirer';
|
|
7
|
-
import path from 'path';
|
|
8
|
-
import { v4 as uuidv4 } from "uuid";
|
|
9
|
-
|
|
10
|
-
const __templateDir = path.resolve(import.meta.url.substring('file:///'.length), '../../template');
|
|
11
|
-
|
|
12
|
-
interface Arguments {
|
|
13
|
-
packageName?: string;
|
|
14
|
-
name?: string;
|
|
15
|
-
description?: string;
|
|
16
|
-
author?: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const descriptions = {
|
|
20
|
-
name: 'The name displayed to mod users',
|
|
21
|
-
packageName: 'The name used for the npm package (no spaces, lowercase)',
|
|
22
|
-
description: 'A short description of the mod',
|
|
23
|
-
author: 'The author of the mod'
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
async function copyDir(src: string, dest: string) {
|
|
27
|
-
await fsp.mkdir(dest, { recursive: true });
|
|
28
|
-
const entries = await fsp.readdir(src, { withFileTypes: true });
|
|
29
|
-
for (const ent of entries) {
|
|
30
|
-
const srcPath = path.join(src, ent.name);
|
|
31
|
-
const destPath = path.join(dest, ent.name);
|
|
32
|
-
if (ent.isDirectory()) {
|
|
33
|
-
await copyDir(srcPath, destPath);
|
|
34
|
-
} else if (ent.isSymbolicLink()) {
|
|
35
|
-
const link = await fsp.readlink(srcPath);
|
|
36
|
-
await fsp.symlink(link, destPath);
|
|
37
|
-
} else {
|
|
38
|
-
await fsp.copyFile(srcPath, destPath);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async function runNpmInstall(cwd: string) {
|
|
44
|
-
return new Promise<void>((resolve, reject) => {
|
|
45
|
-
const cmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
46
|
-
const child = spawn(cmd, ['install'], { cwd, stdio: 'inherit' });
|
|
47
|
-
child.on('close', (code) => code === 0 ? resolve() : reject(new Error('npm install failed')));
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function runGitInit(cwd: string) {
|
|
52
|
-
return new Promise<void>((resolve, reject) => {
|
|
53
|
-
const cmd = process.platform === 'win32' ? 'git.cmd' : 'git';
|
|
54
|
-
const child = spawn(cmd, ['init'], { cwd, stdio: 'inherit' });
|
|
55
|
-
child.on('close', (code) => code === 0 ? resolve() : reject(new Error('git init failed')));
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async function askDestName(): Promise<string> {
|
|
60
|
-
const ans = await inquirer.prompt([{ name: 'dest', message: 'Project folder name:', type: 'input' }]);
|
|
61
|
-
const dest = (ans.dest || '').trim();
|
|
62
|
-
if (!dest) {
|
|
63
|
-
console.error('No folder name provided. Exiting.');
|
|
64
|
-
process.exit(1);
|
|
65
|
-
}
|
|
66
|
-
return dest;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async function askPackageFields(providedBase: Arguments): Promise<Arguments> {
|
|
70
|
-
const result = Object.assign({}, providedBase);
|
|
71
|
-
const prompts: DistinctQuestion[] = [];
|
|
72
|
-
|
|
73
|
-
if (!providedBase.name) {
|
|
74
|
-
prompts.push({ name: 'name', message: descriptions.name, type: 'input' });
|
|
75
|
-
}
|
|
76
|
-
if (!providedBase.description) {
|
|
77
|
-
prompts.push({ name: 'description', message: descriptions.description, type: 'input' });
|
|
78
|
-
}
|
|
79
|
-
if (!providedBase.author) {
|
|
80
|
-
prompts.push({ name: 'author', message: descriptions.author, type: 'input' });
|
|
81
|
-
}
|
|
82
|
-
if (!providedBase.packageName) {
|
|
83
|
-
const defaultPackageName = providedBase.name ? providedBase.name.toLowerCase().replace(/\s+/g, '-') : undefined;
|
|
84
|
-
prompts.push({
|
|
85
|
-
name: 'packageName',
|
|
86
|
-
message: descriptions.packageName,
|
|
87
|
-
type: 'input',
|
|
88
|
-
default: defaultPackageName,
|
|
89
|
-
validate: (input) => {
|
|
90
|
-
if (!input) return 'Package name cannot be empty';
|
|
91
|
-
if (/\s/.test(input)) return 'Package name cannot contain spaces';
|
|
92
|
-
if (input.toLowerCase() !== input) return 'Package name must be lowercase';
|
|
93
|
-
if (!/^(?:(?:@(?:[a-z0-9-*~][a-z0-9-*._~]*)?\/[a-z0-9-._~])|[a-z0-9-~])[a-z0-9-._~]*$/.test(input)) {
|
|
94
|
-
return 'Invalid npm package name. Refer to https://docs.npmjs.com/creating-a-package-json-file#required-name-and-version-fields for rules.';
|
|
95
|
-
}
|
|
96
|
-
return true;
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (prompts.length) {
|
|
102
|
-
const answers = await inquirer.prompt(prompts);
|
|
103
|
-
for (const k of Object.keys(answers) as Array<keyof Arguments>) result[k] = answers[k] || result[k];
|
|
104
|
-
}
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
async function applyPackageFields(pkgPath: string, raw: string, provided: Arguments) {
|
|
109
|
-
const replaced = raw
|
|
110
|
-
.replace(/<package-name>/g, provided.packageName || '')
|
|
111
|
-
.replace(/<description>/g, provided.description || '')
|
|
112
|
-
.replace(/<author>/g, provided.author || '')
|
|
113
|
-
.replace(/<uuid>/g, uuidv4())
|
|
114
|
-
.replace(/<name>/g, provided.name || '')
|
|
115
|
-
await fsp.writeFile(pkgPath, replaced, 'utf8');
|
|
116
|
-
console.log('Replaced tokens in package.json.');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
async function main() {
|
|
120
|
-
const program = new Command();
|
|
121
|
-
program
|
|
122
|
-
.argument('[dir]', 'destination folder name')
|
|
123
|
-
.option('-n, --name <name>', descriptions.name)
|
|
124
|
-
.option('-p, --package-name <name>', descriptions.packageName)
|
|
125
|
-
.option('-d, --description <description>', descriptions.description)
|
|
126
|
-
.option('-a, --author <author>', descriptions.author)
|
|
127
|
-
.parse(process.argv);
|
|
128
|
-
|
|
129
|
-
program.addHelpCommand();
|
|
130
|
-
|
|
131
|
-
const opts = program.opts();
|
|
132
|
-
const destName = opts.dir || await askDestName();
|
|
133
|
-
const cwd = process.cwd();
|
|
134
|
-
const templatePath = __templateDir;
|
|
135
|
-
|
|
136
|
-
const destPath = path.join(cwd, destName);
|
|
137
|
-
|
|
138
|
-
try {
|
|
139
|
-
const stat = await fsp.stat(templatePath);
|
|
140
|
-
if (!stat.isDirectory()) throw new Error('template is not a directory');
|
|
141
|
-
} catch (err) {
|
|
142
|
-
console.error('Could not find template directory at', templatePath);
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
try {
|
|
147
|
-
const exists = await fsp.stat(destPath).then(() => true).catch(() => false);
|
|
148
|
-
if (exists) {
|
|
149
|
-
console.error(`Destination ${destPath} already exists. Aborting.`);
|
|
150
|
-
process.exit(1);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const providedBase: Arguments = {
|
|
154
|
-
name: opts.name,
|
|
155
|
-
description: opts.description || opts.desc,
|
|
156
|
-
author: opts.author,
|
|
157
|
-
packageName: opts.packageName,
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const provided = await askPackageFields(providedBase);
|
|
161
|
-
|
|
162
|
-
await copyDir(templatePath, destPath);
|
|
163
|
-
console.log('Template copied to', destPath);
|
|
164
|
-
|
|
165
|
-
// After copy, apply the provided package fields to the destination package.json
|
|
166
|
-
const pkgPath = path.join(destPath, 'package.json');
|
|
167
|
-
const pkgExists = await fsp.stat(pkgPath).then(() => true).catch(() => false);
|
|
168
|
-
if (pkgExists) {
|
|
169
|
-
const raw = await fsp.readFile(pkgPath, 'utf8');
|
|
170
|
-
await applyPackageFields(pkgPath, raw, provided);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
console.log('Installing dependencies...');
|
|
174
|
-
await runNpmInstall(destPath);
|
|
175
|
-
console.log('Done. Project initialized at', destPath);
|
|
176
|
-
} catch (err: any) {
|
|
177
|
-
console.error('Error:', err.message || err);
|
|
178
|
-
process.exit(1);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
main();
|
package/tsconfig.json
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
// File Layout
|
|
5
|
-
"rootDir": "./src",
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
|
|
8
|
-
// Environment Settings
|
|
9
|
-
// See also https://aka.ms/tsconfig/module
|
|
10
|
-
"module": "nodenext",
|
|
11
|
-
"target": "esnext",
|
|
12
|
-
// "types": [],
|
|
13
|
-
// For nodejs:
|
|
14
|
-
"lib": ["esnext"],
|
|
15
|
-
"types": ["node", "inquirer"],
|
|
16
|
-
// and npm install -D @types/node
|
|
17
|
-
|
|
18
|
-
// Other Outputs
|
|
19
|
-
"sourceMap": true,
|
|
20
|
-
"declaration": true,
|
|
21
|
-
"declarationMap": true,
|
|
22
|
-
|
|
23
|
-
// Stricter Typechecking Options
|
|
24
|
-
"noUncheckedIndexedAccess": true,
|
|
25
|
-
"exactOptionalPropertyTypes": true,
|
|
26
|
-
|
|
27
|
-
// Style Options
|
|
28
|
-
// "noImplicitReturns": true,
|
|
29
|
-
// "noImplicitOverride": true,
|
|
30
|
-
// "noUnusedLocals": true,
|
|
31
|
-
// "noUnusedParameters": true,
|
|
32
|
-
// "noFallthroughCasesInSwitch": true,
|
|
33
|
-
// "noPropertyAccessFromIndexSignature": true,
|
|
34
|
-
|
|
35
|
-
// Recommended Options
|
|
36
|
-
"strict": true,
|
|
37
|
-
"jsx": "react-jsx",
|
|
38
|
-
"verbatimModuleSyntax": true,
|
|
39
|
-
"isolatedModules": true,
|
|
40
|
-
"noUncheckedSideEffectImports": true,
|
|
41
|
-
"moduleDetection": "force",
|
|
42
|
-
"skipLibCheck": true,
|
|
43
|
-
},
|
|
44
|
-
"exclude": ["template/**/*"]
|
|
45
|
-
}
|