Skip to content
This repository has been archived by the owner on May 26, 2024. It is now read-only.

Commit

Permalink
script(build): rewrite
Browse files Browse the repository at this point in the history
not the best but better than the last one (still on testing)
  • Loading branch information
pylixonly committed Feb 15, 2024
1 parent 9007080 commit 31d8a05
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 56 deletions.
12 changes: 0 additions & 12 deletions scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ import { createHash } from "crypto";
import esbuild from "esbuild";
import { readFile, readdir } from "fs/promises";
import { createServer } from "http";
import path from "path";
import { argv } from "process";
import { fileURLToPath } from "url";
import { $ } from "./util.ts";

const rootDirname = path.dirname(fileURLToPath(import.meta.url) + "..");
const isFlag = (s, l) => argv.slice(2).some(c => c === `-${s}` || c === `--${l}`);

const isRelease = isFlag("r", "release");
Expand Down Expand Up @@ -79,8 +76,6 @@ try {
name: "swc",
setup(build) {
build.onLoad({ filter: /\.[jt]sx?/ }, async args => {
const filePath = path.relative(rootDirname, args.path);

const result = await swc.transformFile(args.path, {
jsc: {
externalHelpers: true,
Expand All @@ -94,13 +89,6 @@ try {
},
});

if (filePath?.startsWith("src/core")) {
let aliased = "@pyoncord/" + filePath.slice(9, -path.extname(filePath).length);
if (aliased.endsWith("/index")) aliased = aliased.slice(0, -6);

result.code += `(window.__pathToExports??=[]).push(['${aliased}', () => require('${filePath}')])\n`;
}

return { contents: result.code };
});
}
Expand Down
180 changes: 143 additions & 37 deletions scripts/prepare.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
// WARNING! ENTER AT YOUR OWN PERIL
// do not read the code
import esbuild from "esbuild";
import { existsSync } from "fs";
import { appendFile, cp, mkdir, rm } from "fs/promises";
import { cp, mkdir, rm } from "fs/promises";
import path from "path";
import ts, { TransformationContext } from "typescript";
import { fileURLToPath } from "url";

import { $ } from "./util";

const libPath = "lib";
const rootDirname = path.dirname(fileURLToPath(import.meta.url) + "..");
Expand All @@ -21,50 +18,159 @@ for (const file of [
"package.json",
"LICENSE",
"README.md",
"src/global.d.ts",
"src/modules.d.ts"
"src/global.d.ts"
]) {
await cp(
path.resolve(file),
libPath + "/" + path.basename(file)
);
}

// oh no, this is very bad
const pluginSetup = async build => {
build.onLoad({ filter: /\.[jt]sx?/ }, async args => {
const filePath = path.relative(rootDirname, args.path);
// TODO: this good?
const isModule = (n: string) => [".ts", ".tsx", ".js", ".jsx"].some(ext => n.endsWith(ext));

if (filePath?.startsWith("../src/core")) {
let trimmedPath = filePath.slice(12, -path.extname(filePath).length);
if (trimmedPath.endsWith("/index")) trimmedPath = trimmedPath.slice(0, -6);
const resolveToAlias = (currentDir: string, fileThing: string) => {
const filePath = path.relative(currentDir, fileThing);
if (filePath.startsWith("src/core")) {
const extNameLength = isModule(filePath) ? -path.extname(filePath).length : void 0;
let aliasPath = "@pyoncord/" + filePath.slice(9, extNameLength);
if (aliasPath.endsWith("/index")) aliasPath = aliasPath.slice(0, -6);
return aliasPath;
}

const declarationContents = [
`declare module "${"@pyoncord/" + trimmedPath}" {`,
` export * from "./${"core/" + trimmedPath}";`,
"}"
].join("\n") + "\n";
// Otherwise, just append @pyoncord-internal
return "@pyoncord-internal/" + filePath;
};

await appendFile(libPath + "/alias.d.ts", declarationContents);
}
function resolveModuleToAlias(currentDir: string, sourcePath: string, moduleName: string) {
// is a relative import
if (moduleName.startsWith(".")) {
const dirName = path.dirname(sourcePath);
const fullPath = path.resolve(dirName, moduleName);

return null;
});
return resolveToAlias(currentDir, fullPath);
} else if (moduleName.startsWith("@")) {
const fromCore = moduleName.slice(1);

build.onEnd(async () => {
await appendFile(libPath + "/alias.d.ts", "export {};\n");
});
};
return resolveToAlias(currentDir, "src/core/" + fromCore);
}

return moduleName;
}

const modulify = (currentDir: string) => ((context: TransformationContext) => {
return {
transformSourceFile(sourceFile) {
const moduleName = resolveToAlias(currentDir, sourceFile.fileName);

function convertNode(node: ts.Node) {
// Convert imports
if (
ts.isImportDeclaration(node)
&& node.moduleSpecifier
&& ts.isStringLiteral(node.moduleSpecifier)
) {
return ts.factory.updateImportDeclaration(
node,
node.modifiers,
node.importClause,
ts.factory.createStringLiteral(
resolveModuleToAlias(
currentDir,
sourceFile.fileName,
node.moduleSpecifier.text)
),
node.attributes
);
}

// Convert exports
if (
ts.isExportDeclaration(node) &&
node.moduleSpecifier &&
ts.isStringLiteral(node.moduleSpecifier)
) {
return ts.factory.updateExportDeclaration(
node,
node.modifiers,
node.isTypeOnly,
node.exportClause,
ts.factory.createStringLiteral(
resolveModuleToAlias(
currentDir,
sourceFile.fileName,
node.moduleSpecifier.text)
),
node.attributes
);
}

function visitChilds(child: ts.Node): ts.Node | undefined {
// Skip 'declare's keyword
if (child.kind === ts.SyntaxKind.DeclareKeyword) return undefined;

return ts.visitEachChild(child, visitChilds, context);
}

return ts.visitEachChild(node, visitChilds, context);
}

await esbuild.build({
entryPoints: ["src/entry.js"],
write: false,
bundle: true,
external: ["~*", "*.png"],
plugins: [{
name: "typeMapper",
setup: pluginSetup
}]
sourceFile = ts.visitNode(
sourceFile,
() => ts.visitEachChild(sourceFile, node => convertNode(node), context)
) as ts.SourceFile;

const statements = ts.factory.createModuleDeclaration(
[ts.factory.createToken(ts.SyntaxKind.DeclareKeyword)],
ts.factory.createStringLiteral(moduleName),
ts.factory.createModuleBlock(sourceFile.statements)
);

return ts.factory.updateSourceFile(sourceFile, [statements]);
},
transformBundle: n => n
};
});

await $`tsc`;
function build(
override: {
compilerOptions?: ts.CompilerOptions;
include?: string[];
exclude?: string[];
files?: string[];
extends?: string;
} = {},
currentDir = process.cwd()
) {
const configFile = ts.findConfigFile(currentDir, ts.sys.fileExists, "tsconfig.json");
if (!configFile) throw Error("tsconfig.json not found");
const { config } = ts.readConfigFile(configFile, ts.sys.readFile);

config.compilerOptions = Object.assign({}, config.compilerOptions, override.compilerOptions);
if (override.include) config.include = override.include;
if (override.exclude) config.exclude = override.exclude;
if (override.files) config.files = override.files;
if (override.extends) config.extends = override.extends;

const { options, fileNames, errors } = ts.parseJsonConfigFileContent(config, ts.sys, currentDir);

const program = ts.createProgram({
options,
rootNames: fileNames,
configFileParsingDiagnostics: errors
});

const { emitSkipped } = program.emit(
undefined,
undefined,
undefined,
true,
{
afterDeclarations: [modulify(currentDir)]
}
);

if (emitSkipped) process.exit(1);
}

build();
2 changes: 1 addition & 1 deletion src/core/metro/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { proxyLazy } from "@utils/proxyLazy";
import { after } from "spitroast";

export * as internal from "@internal/metro";
export * as internal from "../../internal/metro";
export * as common from "@metro/common";

declare const modules: Record<number, any>;
Expand Down
3 changes: 1 addition & 2 deletions src/core/utils/findInReactTree.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { findInTree } from "@utils";

import { SearchFilter, SearchTree } from "./findInTree";
import { SearchFilter, SearchTree } from "@utils/findInTree";

export function findInReactTree(tree: SearchTree, filter: SearchFilter): any {
return findInTree(tree, filter, {
Expand Down
5 changes: 4 additions & 1 deletion src/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
type PyoncordObject = Omit<typeof import("./src/core"), "default"> & {
type _index = typeof import("./core/index");
type Index = _index extends {} ? _index : typeof import("@pyoncord");

type PyoncordObject = Omit<Index, "default"> & {
unload: () => void;
};

Expand Down
3 changes: 0 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@
"@*": [
"src/core/*"
],
"@internal/*": [
"src/internal/*"
],
"@plugins/*": [
"src/plugins/*"
]
Expand Down

1 comment on commit 31d8a05

@pylixonly
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i love misnaming commits

Please sign in to comment.