mirror of
https://github.com/DinheroDevelopmentGroup/modular-minecraft-proxy.git
synced 2024-11-23 07:38:18 -05:00
m3 skeleton
only list for now
This commit is contained in:
parent
c0d1876548
commit
350b3237ae
20 changed files with 390 additions and 55 deletions
125
package-lock.json
generated
125
package-lock.json
generated
|
@ -9,7 +9,16 @@
|
|||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minecraft-protocol": "^1.47.0"
|
||||
"@types/text-table": "^0.2.5",
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^12.1.0",
|
||||
"minecraft-protocol": "^1.47.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"text-table": "^0.2.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"bin": {
|
||||
"m3": "dist/m3/cli.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.1",
|
||||
|
@ -306,6 +315,16 @@
|
|||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/cli/node_modules/commander": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
||||
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/cli/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
|
@ -643,6 +662,12 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/text-table": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/text-table/-/text-table-0.2.5.tgz",
|
||||
"integrity": "sha512-hcZhlNvMkQG/k1vcZ6yHOl6WAYftQ2MLfTHcYRZ2xYZFD8tGVnE3qFV0lj1smQeDSR7/yY0PyuUalauf33bJeA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.3.0.tgz",
|
||||
|
@ -946,13 +971,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
|
||||
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
|
@ -1312,17 +1339,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
|
||||
"integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
|
@ -1400,13 +1422,12 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
||||
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
|
||||
"dev": true,
|
||||
"version": "12.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
|
||||
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
|
@ -1664,6 +1685,46 @@
|
|||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/espree": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
|
||||
|
@ -3681,16 +3742,18 @@
|
|||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-eof": {
|
||||
|
@ -3774,7 +3837,6 @@
|
|||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
|
@ -4045,6 +4107,15 @@
|
|||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.23.8",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
|
||||
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
11
package.json
11
package.json
|
@ -23,7 +23,13 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"minecraft-protocol": "^1.47.0"
|
||||
"@types/text-table": "^0.2.5",
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^12.1.0",
|
||||
"minecraft-protocol": "^1.47.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"text-table": "^0.2.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.1",
|
||||
|
@ -40,5 +46,8 @@
|
|||
"scripty": "^2.1.1",
|
||||
"typescript": "^5.5.4",
|
||||
"typescript-eslint": "^8.3.0"
|
||||
},
|
||||
"bin": {
|
||||
"m3": "./dist/m3/bin.js"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import chalk from 'chalk';
|
||||
import { createClient, type ServerClient } from 'minecraft-protocol';
|
||||
import { dirname, resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { resolve } from 'path';
|
||||
import { Worker } from 'worker_threads';
|
||||
|
||||
import { TARGET_OPTIONS } from '../settings.js';
|
||||
|
@ -9,13 +8,8 @@ import { Channel } from '../util/channel.js';
|
|||
import { importModulesGenerator } from '../util/import-modules.js';
|
||||
import { type Message } from '../worker/parent.js';
|
||||
|
||||
if (!('require' in globalThis)) {
|
||||
globalThis.__filename = fileURLToPath(import.meta.url);
|
||||
globalThis.__dirname = dirname(__filename);
|
||||
}
|
||||
|
||||
const WORKER_PATH = resolve(__dirname, '../worker');
|
||||
const MODULE_DIR_PATH = resolve(__dirname, '../module');
|
||||
const WORKER_PATH = resolve(import.meta.dirname, '../worker');
|
||||
const MODULES_DIR_PATH = resolve(import.meta.dirname, '../modules');
|
||||
|
||||
export class Instance {
|
||||
public readonly client;
|
||||
|
@ -68,7 +62,7 @@ export class Instance {
|
|||
let moduleStart = NaN;
|
||||
|
||||
for await (const module of importModulesGenerator(
|
||||
MODULE_DIR_PATH,
|
||||
MODULES_DIR_PATH,
|
||||
'global.js',
|
||||
{
|
||||
pre(entry) {
|
||||
|
|
35
src/m3/README.md
Normal file
35
src/m3/README.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
<!--
|
||||
I probably won't actually make this into its own repo
|
||||
don't think that because there is a README.md file,
|
||||
it's its own git repo.
|
||||
-->
|
||||
|
||||
# MMP Module Manager
|
||||
|
||||
- _aka_ MMM _aka_ M3 (official-est name)
|
||||
|
||||
A CLI Tool to automagically manage your modules.
|
||||
|
||||
(no more manually `git clone`-ing dependencies!)
|
||||
|
||||
<!-- Upon further inspection, this idea is shit
|
||||
# Specification vs Implementation
|
||||
|
||||
Some call it a bug, but I call it (either) a revoluionary (or stupid) idea.
|
||||
|
||||
Instead of just writing a _package_, what you might do in other scenarios. You write a specification.
|
||||
|
||||
Nothing formal, it can be just a markdown file or, if you want to get more fancy, a [d.ts type definition](https://www.typescriptlang.org/docs/handbook/declaration-files/templates/module-d-ts.html).
|
||||
|
||||
But then, modules, packages, libraries, whatever you want to call them (modules, in this case) are identified (imported by other modules/packages/libraries) by their specification, not their implementation.
|
||||
|
||||
`ddg.chat`, the semi-official (made by Dinhero Development Group, the same people who made MMP, the module loader) chat library, is then the specification that defines how a chat library should behave.
|
||||
|
||||
`ddg.chat`, instead of declaring how chat parsing should be implemented (by analyzing the downstream `chat_message` and `chat_command` packets), declares how a chat library should interface and expose itself to the rest of the ecosystem (there should be a default exported object that has `writeDownstream` and `writeUpstream` functions ...)
|
||||
|
||||
This allows you to mix and match implementations, as long as they share the same specification.
|
||||
|
||||
I don't really see any real-world use for this aside from person A creating a module, deprecating/archiving/abandoning it and person B creating an equivalent better module.
|
||||
|
||||
Things like this happen all the time in other ecosystems and are usually referred to as "spiritual successors". So my idea might not be so revolutionary after all.
|
||||
-->
|
10
src/m3/bin.ts
Executable file
10
src/m3/bin.ts
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { importDirectory } from '../util/import.js';
|
||||
import program from './program.js';
|
||||
|
||||
await importDirectory(resolve(import.meta.dirname, 'command'));
|
||||
|
||||
program.parse(process.argv);
|
32
src/m3/command/list.ts
Normal file
32
src/m3/command/list.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
import chalk from 'chalk';
|
||||
import { readdir } from 'fs/promises';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { createTable } from '../../util/table.js';
|
||||
import { Module } from '../module.js';
|
||||
import program, { modulesDir } from '../program.js';
|
||||
|
||||
program
|
||||
.command('list')
|
||||
.description('List installed modules')
|
||||
.action(async () => {
|
||||
const tableData: Record<string, string>[] = [];
|
||||
|
||||
for (const entry of await readdir(modulesDir, { withFileTypes: true })) {
|
||||
if (!entry.isDirectory()) continue;
|
||||
|
||||
try {
|
||||
const modulePath = resolve(modulesDir, entry.name);
|
||||
const module = await Module.fromDir(modulePath);
|
||||
|
||||
tableData.push({
|
||||
[chalk.bold('Name')]: module.global.name,
|
||||
[chalk.bold('Dependency?')]: module.local.manual ? 'no' : 'yes',
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
console.info(createTable(tableData));
|
||||
});
|
44
src/m3/module.ts
Normal file
44
src/m3/module.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { readFile } from 'fs/promises';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import type { GlobalModuleData, LocalModuleData } from './types.js';
|
||||
import { GlobalModuleDataSchema, LocalModuleDataSchema } from './types.js';
|
||||
|
||||
async function getLocalData(path: string): Promise<LocalModuleData> {
|
||||
try {
|
||||
const raw = await readFile(path, 'utf8');
|
||||
const data = JSON.parse(raw) as unknown;
|
||||
|
||||
return LocalModuleDataSchema.parse(data);
|
||||
} catch (error) {
|
||||
throw new Error(`Could not load local module data: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function getGlobalData(path: string): Promise<GlobalModuleData> {
|
||||
try {
|
||||
const raw = await readFile(path, 'utf8');
|
||||
const data = JSON.parse(raw) as unknown;
|
||||
|
||||
return GlobalModuleDataSchema.parse(data);
|
||||
} catch (error) {
|
||||
throw new Error(`Could not load global module data: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
export class Module {
|
||||
public static async fromDir(path: string): Promise<Module> {
|
||||
const localPath = resolve(path, 'm3.local.json');
|
||||
const globalPath = resolve(path, 'm3.global.json');
|
||||
|
||||
return new Module(
|
||||
await getLocalData(localPath),
|
||||
await getGlobalData(globalPath),
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
public readonly local: LocalModuleData,
|
||||
public readonly global: GlobalModuleData,
|
||||
) {}
|
||||
}
|
47
src/m3/program.ts
Normal file
47
src/m3/program.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
import { Command } from 'commander';
|
||||
import { basename, resolve } from 'path';
|
||||
|
||||
const program = new Command();
|
||||
export default program;
|
||||
|
||||
program.name('m3').description('MMP Module Manager');
|
||||
|
||||
// #region This doesn't look like it belongs here...
|
||||
|
||||
// Should always be set
|
||||
export let modulesDir: string;
|
||||
|
||||
// If cwd is a module,
|
||||
// cwd will be {modulesDir}/{moduleDir}
|
||||
export let moduleDir: string | undefined;
|
||||
|
||||
const cwd = process.cwd();
|
||||
const cwdn = basename(cwd);
|
||||
|
||||
const parent = resolve('..');
|
||||
|
||||
// are we in a module?
|
||||
// (parent is modules dir)
|
||||
if (basename(parent) === 'modules') {
|
||||
modulesDir = parent;
|
||||
moduleDir = cwdn;
|
||||
} else {
|
||||
switch (cwdn) {
|
||||
case 'modular-minecraft-proxy':
|
||||
modulesDir = resolve('src/modules');
|
||||
break;
|
||||
case 'src':
|
||||
modulesDir = resolve('modules');
|
||||
break;
|
||||
case 'modules':
|
||||
modulesDir = resolve('.');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error We are testing if modulesDir *hasn't* been set here
|
||||
if (modulesDir === undefined) {
|
||||
throw new Error('Could not locate modules directory');
|
||||
}
|
||||
|
||||
// #endregion
|
25
src/m3/types.ts
Normal file
25
src/m3/types.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Module directory structure
|
||||
// <implementation>
|
||||
// ├─ [local.ts] TypeScript
|
||||
// ├─ [global.ts] TypeScript
|
||||
// ├─ m3.local.json JSON(LocalModuleData)
|
||||
// ├─ m3.global.json JSON(GlobalModuleData)
|
||||
// └─ ...
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
export const LocalModuleDataSchema = z.object({
|
||||
// manual -> required by the user
|
||||
// auto -> a dependency to another module
|
||||
manual: z.boolean(),
|
||||
});
|
||||
|
||||
export type LocalModuleData = z.infer<typeof LocalModuleDataSchema>;
|
||||
|
||||
export const GlobalModuleDataSchema = z.object({
|
||||
dependencies: z.array(z.string().url()),
|
||||
// * This is different from package.json's name as it is required to be the same as the directory's
|
||||
name: z.string(),
|
||||
});
|
||||
|
||||
export type GlobalModuleData = z.infer<typeof GlobalModuleDataSchema>;
|
5
src/module/.gitignore
vendored
5
src/module/.gitignore
vendored
|
@ -1,5 +0,0 @@
|
|||
*
|
||||
!.gitignore
|
||||
|
||||
# internal modules
|
||||
!proxy
|
7
src/modules/.gitignore
vendored
Normal file
7
src/modules/.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
*
|
||||
!.gitignore
|
||||
|
||||
# for whatever reason, you need to unignore
|
||||
# the directories AND files within them
|
||||
!internal.*
|
||||
!internal.*/**
|
|
@ -8,7 +8,7 @@ export default async function (instance: Instance): Promise<void> {
|
|||
const downstreamQueue: RawPacket[] = [];
|
||||
const upstreamQueue: RawPacket[] = [];
|
||||
|
||||
const channel = instance.createChannel<Message>('proxy');
|
||||
const channel = instance.createChannel<Message>('internal.proxy');
|
||||
|
||||
const client = instance.client;
|
||||
const server = instance.server;
|
|
@ -7,8 +7,7 @@ import { type Direction as Direction, type Message } from './shared.js';
|
|||
|
||||
export type PacketEventMap = Record<string, (packet: Packet) => AsyncVoid>;
|
||||
|
||||
// ? Should I export the channel
|
||||
export const channel = createChannel<Message>('proxy');
|
||||
const channel = createChannel<Message>('internal.proxy');
|
||||
|
||||
function write(direction: Direction, packet: RawPacket): void {
|
||||
channel.write({
|
4
src/modules/internal.proxy/m3.global.json
Normal file
4
src/modules/internal.proxy/m3.global.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "internal.proxy",
|
||||
"dependencies": []
|
||||
}
|
3
src/modules/internal.proxy/m3.local.json
Normal file
3
src/modules/internal.proxy/m3.local.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"manual": true
|
||||
}
|
|
@ -24,6 +24,8 @@ export async function* importModulesGenerator(
|
|||
index: string,
|
||||
callbacks?: Callbacks,
|
||||
): AsyncGenerator<unknown> {
|
||||
console.log('importModulesGenerator', { directory, index });
|
||||
|
||||
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
||||
const path = resolve(entry.path, entry.name, index);
|
||||
|
||||
|
|
10
src/util/import.ts
Normal file
10
src/util/import.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { readdir } from 'fs/promises';
|
||||
import { resolve } from 'path';
|
||||
|
||||
export async function importDirectory(path: string): Promise<void> {
|
||||
for (const entry of await readdir(path, { withFileTypes: true })) {
|
||||
if (!entry.isFile()) continue;
|
||||
|
||||
await import(resolve(path, entry.name));
|
||||
}
|
||||
}
|
54
src/util/table.ts
Normal file
54
src/util/table.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import stripAnsi from 'strip-ansi';
|
||||
import table from 'text-table';
|
||||
|
||||
class TableGenerator {
|
||||
// #region Taken directly from table.Options
|
||||
|
||||
/** Separator to use between columns, (default: ' '). */
|
||||
hsep?: string | undefined;
|
||||
|
||||
/** An array of alignment types for each column, default ['l','l',...]. */
|
||||
align?: Array<'l' | 'r' | 'c' | '.' | null | undefined> | undefined;
|
||||
|
||||
/** A callback function to use when calculating the string length. */
|
||||
stringLength?(str: string): number;
|
||||
|
||||
// #endregion
|
||||
|
||||
public generate(data: Record<string, string>[] | string[][]): string {
|
||||
const rows: string[][] = [];
|
||||
|
||||
if (typeof data[0] === 'object') {
|
||||
const keys = new Set<string>();
|
||||
|
||||
for (const row of data) {
|
||||
for (const key of Object.keys(row)) {
|
||||
keys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
const header = Array.from(keys);
|
||||
|
||||
rows.push(header);
|
||||
|
||||
for (const inRow of data as Record<string, string>[]) {
|
||||
const outRow = header.map((key) => inRow[key] ?? '');
|
||||
|
||||
rows.push(outRow);
|
||||
}
|
||||
}
|
||||
|
||||
return table(rows, {
|
||||
hsep: this.hsep,
|
||||
align: this.align,
|
||||
stringLength: this.stringLength,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const generator = new TableGenerator();
|
||||
generator.stringLength = (string) => stripAnsi(string).length;
|
||||
|
||||
export function createTable(data: Record<string, string>[] | string[][]) {
|
||||
return generator.generate(data);
|
||||
}
|
|
@ -1,15 +1,9 @@
|
|||
import chalk from 'chalk';
|
||||
import { dirname, resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { importModules } from '../util/import-modules.js';
|
||||
|
||||
if (!('require' in globalThis)) {
|
||||
globalThis.__filename = fileURLToPath(import.meta.url);
|
||||
globalThis.__dirname = dirname(__filename);
|
||||
}
|
||||
|
||||
const MODULE_DIR_PATH = resolve(__dirname, '../module');
|
||||
const MODULES_DIR_PATH = resolve(import.meta.dirname, '../modules');
|
||||
|
||||
console.group('Loading modules... (local)');
|
||||
|
||||
|
@ -17,7 +11,7 @@ const start = performance.now();
|
|||
|
||||
let moduleStart = NaN;
|
||||
|
||||
await importModules(MODULE_DIR_PATH, 'local.js', {
|
||||
await importModules(MODULES_DIR_PATH, 'local.js', {
|
||||
pre(entry) {
|
||||
const module = entry.name;
|
||||
console.group(`Loading ${module}...`);
|
||||
|
|
Loading…
Reference in a new issue