mirror of
https://github.com/DinheroDevelopmentGroup/modular-minecraft-proxy.git
synced 2024-11-27 01:25:57 -05:00
minimal m3 init
This commit is contained in:
parent
350b3237ae
commit
79f2d3be61
8 changed files with 1079 additions and 4 deletions
|
@ -35,6 +35,11 @@ export default tseslint.config(
|
|||
'@typescript-eslint/no-misused-promises': 'error',
|
||||
'object-shorthand': 'error',
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
'@typescript-eslint/explicit-function-return-type': [
|
||||
'error',
|
||||
{ allowExpressions: true },
|
||||
],
|
||||
'@typescript-eslint/strict-boolean-expressions': 'error',
|
||||
},
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
|
|
872
package-lock.json
generated
872
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -23,12 +23,15 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@inquirer/prompts": "^5.3.8",
|
||||
"@types/text-table": "^0.2.5",
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^12.1.0",
|
||||
"listr2": "^8.2.4",
|
||||
"minecraft-protocol": "^1.47.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"text-table": "^0.2.0",
|
||||
"tmp-promise": "^3.0.3",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
133
src/m3/command/init.ts
Normal file
133
src/m3/command/init.ts
Normal file
|
@ -0,0 +1,133 @@
|
|||
import { confirm, input } from '@inquirer/prompts';
|
||||
import { Argument } from 'commander';
|
||||
import { mkdir, writeFile } from 'fs/promises';
|
||||
import type { ListrTask } from 'listr2';
|
||||
import { Listr } from 'listr2';
|
||||
import { resolve } from 'path';
|
||||
import type { Writable } from 'stream';
|
||||
|
||||
import { exists } from '../../util/file.js';
|
||||
import { run } from '../process.js';
|
||||
import program, { moduleDir, modulesDir } from '../program.js';
|
||||
import type { GlobalModuleData, LocalModuleData } from '../types.js';
|
||||
|
||||
program
|
||||
.command('init')
|
||||
.description('Initialize a new module')
|
||||
.addArgument(new Argument('[name]', 'Name of the module').default(moduleDir))
|
||||
.option('-f, --override', 'Overwrite existing module')
|
||||
.option('--git', 'Initialize a new git repository')
|
||||
.option('--npm', 'Initialize a new npm package')
|
||||
.action(
|
||||
async (
|
||||
name: string | undefined,
|
||||
options: { git?: boolean; npm?: boolean; override?: boolean },
|
||||
) => {
|
||||
name =
|
||||
name ??
|
||||
(await input({ message: 'Name of the module', default: moduleDir }));
|
||||
const git =
|
||||
options.git ??
|
||||
(await confirm({
|
||||
message: 'Initialize a new git repo?',
|
||||
default: true,
|
||||
}));
|
||||
const npm =
|
||||
options.npm ??
|
||||
(await confirm({
|
||||
message: 'Initialize a new npm package?',
|
||||
default: true,
|
||||
}));
|
||||
|
||||
await init({
|
||||
override: options.override ?? false,
|
||||
|
||||
name,
|
||||
|
||||
git,
|
||||
npm,
|
||||
m3: true,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
interface InitOptions {
|
||||
override: boolean;
|
||||
|
||||
name: string;
|
||||
|
||||
git: boolean;
|
||||
npm: boolean;
|
||||
m3: boolean;
|
||||
}
|
||||
|
||||
async function init(options: InitOptions): Promise<void> {
|
||||
const directory = resolve(modulesDir, options.name);
|
||||
|
||||
if (!options.override && (await exists(directory))) {
|
||||
throw new Error(`Module ${options.name} already exists`);
|
||||
}
|
||||
|
||||
await mkdir(directory, { recursive: true });
|
||||
|
||||
const tasks: ListrTask[] = [];
|
||||
|
||||
if (options.git) {
|
||||
tasks.push({
|
||||
title: 'Initialize git',
|
||||
task: async (_ctx, task) => {
|
||||
await run(
|
||||
'git',
|
||||
['init'],
|
||||
{ cwd: directory },
|
||||
{ stdout: task.stdout() as Writable },
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (options.npm) {
|
||||
tasks.push({
|
||||
title: 'Initialize npm',
|
||||
task: async (_ctx, task) => {
|
||||
await run(
|
||||
'npm',
|
||||
['init', '-y'],
|
||||
{ cwd: directory },
|
||||
{ stdout: task.stdout() as Writable },
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (options.m3) {
|
||||
tasks.push({
|
||||
title: 'Initialize m3 json files',
|
||||
task: async (_ctx, _task) => {
|
||||
const global: GlobalModuleData = {
|
||||
name: options.name,
|
||||
dependencies: [],
|
||||
};
|
||||
|
||||
const local: LocalModuleData = {
|
||||
manual: true,
|
||||
};
|
||||
|
||||
await writeFile(
|
||||
resolve(directory, 'm3.global.json'),
|
||||
JSON.stringify(global),
|
||||
);
|
||||
|
||||
await writeFile(
|
||||
resolve(directory, 'm3.local.json'),
|
||||
JSON.stringify(local),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
await new Listr(tasks, {
|
||||
concurrent: true,
|
||||
exitOnError: false,
|
||||
}).run();
|
||||
}
|
30
src/m3/override.ts
Normal file
30
src/m3/override.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { Command, Option } from 'commander';
|
||||
|
||||
import { override } from '../util/reflect.js';
|
||||
|
||||
// Please forgive me, I had to
|
||||
|
||||
// even if you extend Command, when chaining, it will return Command instead of the extended class
|
||||
// thus, impossibilitating customization without monkey-patching
|
||||
|
||||
override(
|
||||
Command.prototype,
|
||||
'addOption',
|
||||
(original) =>
|
||||
function (this: Command, option: Option): Command {
|
||||
const result = original.call(this, option);
|
||||
|
||||
if (
|
||||
option.long &&
|
||||
!option.required &&
|
||||
!option.negate &&
|
||||
!option.optional
|
||||
) {
|
||||
this.addOption(
|
||||
new Option(option.long.replace(/^--/, '--no-')).hideHelp(),
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
);
|
30
src/m3/process.ts
Normal file
30
src/m3/process.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import type { ChildProcess, SpawnOptions } from 'child_process';
|
||||
import { spawn } from 'child_process';
|
||||
import type { Readable, Writable } from 'stream';
|
||||
|
||||
export async function run(
|
||||
command: string,
|
||||
args: string[],
|
||||
options: SpawnOptions,
|
||||
stdio?: { stdin?: Readable; stdout?: Writable; stderr?: Writable },
|
||||
): Promise<ChildProcess> {
|
||||
const child = spawn(command, args, options);
|
||||
|
||||
if (stdio !== undefined) {
|
||||
if (child.stdin !== null) stdio.stdin?.pipe(child.stdin);
|
||||
if (stdio.stdout !== undefined) child.stdout?.pipe(stdio.stdout);
|
||||
if (stdio.stderr !== null) stdio.stderr?.pipe(stdio.stderr);
|
||||
}
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
child.on('close', (code) => {
|
||||
if (code === 0) {
|
||||
resolve();
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return child;
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import './override.js';
|
||||
|
||||
import { Command } from 'commander';
|
||||
import { basename, resolve } from 'path';
|
||||
|
||||
|
|
8
src/util/reflect.ts
Normal file
8
src/util/reflect.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
export function override<T, K extends keyof T>(
|
||||
target: T,
|
||||
key: K,
|
||||
callback: (original: T[K]) => T[K],
|
||||
): void {
|
||||
const original = target[key];
|
||||
target[key] = callback(original);
|
||||
}
|
Loading…
Reference in a new issue