144 lines
3.5 KiB
TypeScript
144 lines
3.5 KiB
TypeScript
import {spawnSync} from 'node:child_process';
|
|
import fs from 'node:fs';
|
|
import ts from 'typescript';
|
|
|
|
type Route = {uri: string; name: string | undefined};
|
|
const supportedPrefixes = ['auth.', 'user.', 'skinlib.', 'texture.', 'admin.'];
|
|
|
|
type TreeObject = Record<string, Tree>;
|
|
type Tree = TreeObject | string;
|
|
const tree: TreeObject = {};
|
|
|
|
function parseURI(uri: string): ts.ArrowFunction {
|
|
const matches = /{([a-z]+)}/.exec(uri);
|
|
if (matches?.[0] && matches?.[1]) {
|
|
const parameter = matches[1];
|
|
const type = parameter.endsWith('id')
|
|
|| parameter === 'texture'
|
|
|| parameter === 'user'
|
|
|| parameter === 'player'
|
|
|| parameter === 'report'
|
|
? ts.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword)
|
|
: ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
|
|
|
|
return ts.factory.createArrowFunction(
|
|
undefined,
|
|
undefined,
|
|
[
|
|
ts.factory.createParameterDeclaration(
|
|
undefined,
|
|
undefined,
|
|
ts.factory.createIdentifier(parameter),
|
|
undefined,
|
|
type,
|
|
),
|
|
],
|
|
undefined,
|
|
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
ts.factory.createTemplateExpression(
|
|
ts.factory.createTemplateHead(
|
|
'/' + uri.slice(0, matches.index),
|
|
'/' + uri.slice(0, matches.index),
|
|
),
|
|
[
|
|
ts.factory.createTemplateSpan(
|
|
ts.factory.createIdentifier(parameter),
|
|
ts.factory.createTemplateTail(
|
|
uri.slice(matches.index + matches[0].length),
|
|
uri.slice(matches.index + matches[0].length),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
return ts.factory.createArrowFunction(
|
|
undefined,
|
|
undefined,
|
|
[],
|
|
undefined,
|
|
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
ts.factory.createAsExpression(
|
|
ts.factory.createStringLiteral(`/${uri}`),
|
|
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('const'), undefined),
|
|
),
|
|
);
|
|
}
|
|
|
|
function parseTree(tree: Tree): ts.ObjectLiteralExpression {
|
|
const properties = Object.entries(tree)
|
|
.sort(([a], [b]) => (a > b ? 1 : -1))
|
|
.map(([key, value]) => {
|
|
if (typeof value === 'string') {
|
|
return ts.factory.createPropertyAssignment(
|
|
ts.factory.createIdentifier(key),
|
|
parseURI(value),
|
|
);
|
|
}
|
|
|
|
return ts.factory.createPropertyAssignment(
|
|
ts.factory.createIdentifier(key),
|
|
parseTree(value),
|
|
);
|
|
});
|
|
|
|
return ts.factory.createObjectLiteralExpression(properties);
|
|
}
|
|
|
|
const {stdout} = spawnSync(
|
|
'php',
|
|
['artisan', 'route:list', '--json', '--columns=uri,name'],
|
|
{encoding: 'utf8'},
|
|
);
|
|
let routes: Route[] = [];
|
|
try {
|
|
routes = JSON.parse(stdout) as Route[];
|
|
} catch (error) {
|
|
console.error(stdout);
|
|
throw error;
|
|
}
|
|
|
|
for (const route of routes
|
|
.filter(
|
|
route =>
|
|
route.name
|
|
&& supportedPrefixes.some(prefix => route.name!.startsWith(prefix))
|
|
&& !route.name.endsWith('.'),
|
|
)) {
|
|
const path = route.name!.split('.');
|
|
const {length} = path;
|
|
|
|
// eslint-disable-next-line unicorn/no-array-reduce
|
|
path.reduce((object: TreeObject, p, index) => {
|
|
if (index === length - 1) {
|
|
object[p] = route.uri;
|
|
return tree;
|
|
}
|
|
|
|
object[p] ||= {};
|
|
|
|
return object[p];
|
|
}, tree);
|
|
}
|
|
|
|
const ast = ts.factory.createExportAssignment(
|
|
undefined,
|
|
undefined,
|
|
parseTree(tree),
|
|
);
|
|
const sourceFile = ts.createSourceFile(
|
|
'urls.ts',
|
|
'',
|
|
ts.ScriptTarget.ES2020,
|
|
false,
|
|
ts.ScriptKind.TS,
|
|
);
|
|
const printer = ts.createPrinter({
|
|
newLine: ts.NewLineKind.LineFeed,
|
|
});
|
|
const code = printer.printNode(ts.EmitHint.Unspecified, ast, sourceFile);
|
|
fs.writeFileSync('./resources/assets/src/scripts/urls.ts', code, {
|
|
encoding: 'utf8',
|
|
});
|