@project-selene/create-mod 0.0.7 → 0.1.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/main.mjs CHANGED
@@ -30,15 +30,15 @@ async function copyDir(src, dest) {
30
30
  }
31
31
  async function runNpmInstall(cwd) {
32
32
  return new Promise((resolve, reject) => {
33
- const cmd = process.platform === "win32" ? "npm.cmd" : "npm";
34
- const child = spawn(cmd, ["install"], { cwd, stdio: "inherit" });
33
+ const child = spawn("npm install", { cwd, stdio: "inherit", shell: process.platform === "win32" });
34
+ child.on("error", reject);
35
35
  child.on("close", (code) => code === 0 ? resolve() : reject(new Error("npm install failed")));
36
36
  });
37
37
  }
38
38
  async function runGitInit(cwd) {
39
39
  return new Promise((resolve, reject) => {
40
- const cmd = process.platform === "win32" ? "git.cmd" : "git";
41
- const child = spawn(cmd, ["init"], { cwd, stdio: "inherit" });
40
+ const child = spawn("git init", { cwd, stdio: "inherit", shell: process.platform === "win32" });
41
+ child.on("error", reject);
42
42
  child.on("close", (code) => code === 0 ? resolve() : reject(new Error("git init failed")));
43
43
  });
44
44
  }
@@ -55,19 +55,19 @@ async function askPackageFields(providedBase) {
55
55
  const result = Object.assign({}, providedBase);
56
56
  const prompts = [];
57
57
  if (!providedBase.name) {
58
- prompts.push({ name: "name", message: descriptions.name, type: "input" });
58
+ prompts.push({ name: "name", message: descriptions.name + ":", type: "input" });
59
59
  }
60
60
  if (!providedBase.description) {
61
- prompts.push({ name: "description", message: descriptions.description, type: "input" });
61
+ prompts.push({ name: "description", message: descriptions.description + ":", type: "input" });
62
62
  }
63
63
  if (!providedBase.author) {
64
- prompts.push({ name: "author", message: descriptions.author, type: "input" });
64
+ prompts.push({ name: "author", message: descriptions.author + ":", type: "input" });
65
65
  }
66
66
  if (!providedBase.packageName) {
67
67
  const defaultPackageName = providedBase.name ? providedBase.name.toLowerCase().replace(/\s+/g, "-") : void 0;
68
68
  prompts.push({
69
69
  name: "packageName",
70
- message: descriptions.packageName,
70
+ message: descriptions.packageName + ":",
71
71
  type: "input",
72
72
  default: defaultPackageName,
73
73
  validate: (input) => {
@@ -90,7 +90,6 @@ async function askPackageFields(providedBase) {
90
90
  async function applyPackageFields(pkgPath, raw, provided) {
91
91
  const replaced = raw.replace(/<package-name>/g, provided.packageName || "").replace(/<description>/g, provided.description || "").replace(/<author>/g, provided.author || "").replace(/<uuid>/g, uuidv4()).replace(/<name>/g, provided.name || "");
92
92
  await fsp.writeFile(pkgPath, replaced, "utf8");
93
- console.log("Replaced tokens in package.json.");
94
93
  }
95
94
  async function main() {
96
95
  const program = new Command();
@@ -121,8 +120,8 @@ async function main() {
121
120
  packageName: opts.packageName
122
121
  };
123
122
  const provided = await askPackageFields(providedBase);
123
+ console.log("Copying template to", destPath, "...");
124
124
  await copyDir(templatePath, destPath);
125
- console.log("Template copied to", destPath);
126
125
  const pkgPath = path.join(destPath, "package.json");
127
126
  const pkgExists = await fsp.stat(pkgPath).then(() => true).catch(() => false);
128
127
  if (pkgExists) {
@@ -131,7 +130,9 @@ async function main() {
131
130
  }
132
131
  console.log("Installing dependencies...");
133
132
  await runNpmInstall(destPath);
134
- console.log("Done. Project initialized at", destPath);
133
+ console.log("Installing git repository...");
134
+ await runGitInit(destPath).catch(() => console.warn("Git initialization failed"));
135
+ console.log("Done.");
135
136
  } catch (err) {
136
137
  console.error("Error:", err.message || err);
137
138
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@project-selene/create-mod",
3
- "version": "0.0.7",
3
+ "version": "0.1.0",
4
4
  "description": "A script for creating new Alabaster Dawn mods.",
5
5
  "main": "dist/main.mjs",
6
6
  "bin": "dist/main.mjs",
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ dist
3
+ rawAssets
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
- }