Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Davilarek committed Feb 11, 2024
2 parents 923c024 + 069b044 commit 2acda56
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 26 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/automated-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Node.js CI

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '20.x'
- uses: pnpm/action-setup@v3
with:
version: 8
- run: pnpm i
- run: pnpm run build
- run: pnpm test
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
"discord-mod-compiler": "dist/cli.js"
},
"scripts": {
"test": "npm run cli ./test/sample/index.js RePlugged",
"test": "tsc && node ./test/check-converters.js",
"cli": "tsc && node dist/cli.js",
"cli-debug": "tsc && node --inspect dist/cli.js",
"cli-nobuild": "node dist/cli.js",
"build": "tsc"
},
"keywords": [],
Expand Down
9 changes: 9 additions & 0 deletions src/api/ModImplementation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { WebpackApi } from "./Webpack.js";

export interface IModImplementation {
WebpackApi: typeof WebpackApi,
/**
* shall be true when a mod requires the Dev to bundle their code into single file
*/
importsForbidden?: boolean,
}
11 changes: 0 additions & 11 deletions src/api/index.ts → src/api/RuntimeGenerators.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
import IBaseWebpackApi, { WebpackApi } from "./Webpack/index.js";

interface ModImplementation {
WebpackApi: typeof WebpackApi,
/**
* shall be true when a mod requires the Dev to bundle their code into single file
*/
importsForbidden?: boolean,
}
export { IBaseWebpackApi, WebpackApi, ModImplementation };

/**
* Creates a function from a given path that gets resolved at runtime.
* @param path - The path to create the function from.
Expand Down
3 changes: 1 addition & 2 deletions src/api/Webpack/index.ts → src/api/Webpack.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
interface IBaseWebpackApi {
export interface IBaseWebpackApi {
getModule(filter: (match: any) => boolean): any;
}
export default IBaseWebpackApi;

class DummyWebpackApi implements IBaseWebpackApi {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down
6 changes: 3 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import converter from "./converter.js";
import { File } from "@babel/types";
import { myPackageName } from "./utils.js";
import { transformSync } from "@babel/core";
import { ModImplementation } from "./api/index.js";
import { IModImplementation } from "./api/ModImplementation.js";

if (process.argv.length != 4) {
console.log("Usage:\n\t" + myPackageName + " <input file> <target client mod>\nExample:\n\t" + myPackageName + " ./index.js BetterDiscord");
console.error(`Usage:\n\t${myPackageName} <input file> <target client mod>\nExample:\n\t${myPackageName} ./index.js BetterDiscord`);
process.exit(1);
}

Expand Down Expand Up @@ -42,7 +42,7 @@ if (!isClientModSupported) {

const filler = import(url.pathToFileURL(`${__dirname}/converters/${targetDiscordMod}.js`).href);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
filler.then((x: { default: ModImplementation }) => {
filler.then((x: { default: IModImplementation }) => {
if (x.default.importsForbidden)
console.warn('\x1b[33m%s\x1b[0m', `Warning: Target mod ${targetDiscordMod} requires your code to be bundled into single file`);
const out = converter(ast as File & { errors: [] }, x);
Expand Down
8 changes: 4 additions & 4 deletions src/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { ParseResult } from "@babel/parser";
import { File, Identifier, ImportDeclaration, ImportSpecifier, MemberExpression, Statement } from "@babel/types";
import { NonFunctionType, myPackageName } from "./utils.js";
import { ModImplementation } from "./api/index.js";
import { IModImplementation } from "./api/ModImplementation";

function removeASTLocation(ast: Statement[] | Statement) {
if (Array.isArray(ast)) {
Expand Down Expand Up @@ -95,7 +95,7 @@ function deepFind<K>(obj: any, path: string): K | undefined {

const getKeyValue = <T, K extends keyof T>(obj: T, key: K): T[K] => obj[key];

export default function (ast: ParseResult<File>, targetedDiscordModApiLibrary: { default: ModImplementation }): Statement[] {
export default function (ast: ParseResult<File>, targetedDiscordModApiLibrary: { default: IModImplementation }): Statement[] {
const parsedBody = ast.program.body;
const importStatements = parsedBody.filter(x => x.type == "ImportDeclaration");
const importsToBake = [];
Expand Down Expand Up @@ -134,11 +134,11 @@ export default function (ast: ParseResult<File>, targetedDiscordModApiLibrary: {
console.log(trueObj);
if (trueObj != undefined && importsToBake.includes((trueObj.object as Identifier).name)) {
removeASTLocation(trueObj as unknown as Statement);
const propDesc = Object.getOwnPropertyDescriptor(targetedDiscordModApiLibrary.default, (trueObj.object as Identifier).name as keyof ModImplementation);
const propDesc = Object.getOwnPropertyDescriptor(targetedDiscordModApiLibrary.default, (trueObj.object as Identifier).name as keyof IModImplementation);
if (!propDesc)
continue;
// const targetClass = targetedDiscordModApiLibrary.default[(trueObj.object as Identifier).name];
const targetClass: ModImplementation[keyof ModImplementation] = propDesc.value ?? propDesc.get!(); // TODO: don't make value `any`
const targetClass: IModImplementation[keyof IModImplementation] = propDesc.value ?? propDesc.get!(); // TODO: don't make value `any`
if (targetClass == undefined)
continue;
const replacementObject = getKeyValue(targetClass, (trueObj.property as Identifier).name as keyof typeof targetClass) as { object: string, property: string };
Expand Down
6 changes: 4 additions & 2 deletions src/converters/betterdiscord.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { IBaseWebpackApi, ModImplementation, createFunctionFromObjectProperty } from "../api/index.js";
import { IModImplementation } from "../api/ModImplementation.js";
import { createFunctionFromObjectProperty } from "../api/RuntimeGenerators.js";
import { IBaseWebpackApi } from "../api/Webpack.js";

class BDWebpackApi implements IBaseWebpackApi {
get getModule() {
Expand All @@ -9,4 +11,4 @@ class BDWebpackApi implements IBaseWebpackApi {
export default {
WebpackApi: new BDWebpackApi(),
importsForbidden: true,
} as ModImplementation;
} as IModImplementation;
6 changes: 4 additions & 2 deletions src/converters/replugged.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { IBaseWebpackApi, ModImplementation, createFunctionFromObjectProperty } from "../api/index.js";
import { IModImplementation } from "../api/ModImplementation.js";
import { createFunctionFromObjectProperty } from "../api/RuntimeGenerators.js";
import { IBaseWebpackApi } from "../api/Webpack.js";

class RPWebpackApi implements IBaseWebpackApi {
get getModule() {
Expand All @@ -8,4 +10,4 @@ class RPWebpackApi implements IBaseWebpackApi {

export default {
WebpackApi: new RPWebpackApi(),
} as ModImplementation;
} as IModImplementation;
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from "./api/index.js";
export * from './api/Webpack.js';
20 changes: 20 additions & 0 deletions test/check-converters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import fs from 'fs';
import path from 'path';
import { execSync } from 'child_process';

// Read the files in ./src/converters
const files = fs.readdirSync('./src/converters');

// Filter .ts files and remove extension
const tsFiles = files.filter(file => path.extname(file) === '.ts').map(file => path.basename(file, '.ts'));

for (const file of tsFiles) {
console.log(`Testing ${file}`);

try {
execSync(`npm run cli-nobuild ./test/sample/index.js ${file}`, { stdio: 'inherit' });
} catch (error) {
console.error(`Error in ${file}`);
process.exit(1);
}
}

0 comments on commit 2acda56

Please sign in to comment.