@minimaltech/electron-infra
Version:
Minimal Technology ElectronJS Infrastructure
122 lines • 6.46 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const common_1 = require("../common");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const typescript_1 = __importDefault(require("typescript"));
// ------------------------------------------------------------------------------------
const interfaceDeclarations = ['export {}'];
const interfaceNames = [];
const ipcMethods = [];
const ipcSenderMethods = [];
const ipcHandlerMethods = [];
const ipcSubscriberMethods = [];
// ------------------------------------------------------------------------------------
const processFile = (opts) => {
const { filePath, program } = opts;
console.info('[processFile] Processing... | File: %s', filePath);
const typeChecker = program.getTypeChecker();
const sourceFile = program.getSourceFile(filePath);
if (!sourceFile) {
console.error('[processFile] sourceFile NOT FOUND | File: %s', filePath);
return;
}
typescript_1.default.forEachChild(sourceFile, node => {
if (!typescript_1.default.isClassDeclaration(node) || !node.name) {
return;
}
const className = node.name.text;
const interfaceName = `I${className}Methods`;
interfaceNames.push(interfaceName);
const methodSignatures = [];
node.members.forEach(member => {
if (!typescript_1.default.isMethodDeclaration(member) ||
!member.name ||
!typescript_1.default.canHaveDecorators(member)) {
return;
}
const methodName = member.name.text;
const ipcMethod = `${className}.${methodName}`;
ipcMethods.push(ipcMethod);
// ----------------------------------------
const decorators = typescript_1.default.getDecorators(member);
const decoratorStrings = decorators === null || decorators === void 0 ? void 0 : decorators.map(d => d.expression.expression.text);
if (decoratorStrings === null || decoratorStrings === void 0 ? void 0 : decoratorStrings.includes(common_1.ExposeVerbs.HANDLER)) {
ipcHandlerMethods.push(ipcMethod);
}
if (decoratorStrings === null || decoratorStrings === void 0 ? void 0 : decoratorStrings.includes(common_1.ExposeVerbs.SUBSCRIBER)) {
ipcSubscriberMethods.push(ipcMethod);
}
if (decoratorStrings === null || decoratorStrings === void 0 ? void 0 : decoratorStrings.includes(common_1.ExposeVerbs.SENDER)) {
ipcSenderMethods.push(ipcMethod);
}
// ----------------------------------------
const parameters = member.parameters
.map(param => {
const paramName = param.name.text;
const paramType = typeChecker.getTypeAtLocation(param);
const typeString = typeChecker.typeToString(paramType);
return `${paramName}: ${typeString}`;
})
.join(', ');
const returnType = typeChecker.getReturnTypeOfSignature(typeChecker.getSignatureFromDeclaration(member));
const returnTypeString = typeChecker.typeToString(returnType);
methodSignatures.push(`\t${methodName}: (${parameters}) => ${returnTypeString};`);
});
const interfaceDeclaration = `export interface ${interfaceName} {\n${methodSignatures.join('\n')}\n}`;
interfaceDeclarations.push(interfaceDeclaration);
});
};
// ------------------------------------------------------------------------------------
const main = () => {
const t = new Date().getTime();
console.info('[electron-infra] START | Generating routes/types...');
// ------------------------------------------------------------------------------------
// ts-node ./generate-types.ts ./src/controllers ./interface.d.ts
const srcDir = path_1.default.resolve(process.argv[2]);
const outputFile = path_1.default.resolve(process.argv[3]);
console.info('[electron-infra] srcDir: %s', srcDir);
console.info('[electron-infra] outputFile: %s', outputFile);
console.info();
const program = typescript_1.default.createProgram([path_1.default.join(srcDir, 'index.ts')], {
target: typescript_1.default.ScriptTarget.ES5,
module: typescript_1.default.ModuleKind.CommonJS,
});
if (!path_1.default.isAbsolute(srcDir)) {
console.error('[electron-infra] srcDir: %s | Required srcDir must be absolute path!', srcDir);
process.exit(-1);
}
if (!path_1.default.isAbsolute(outputFile) || !outputFile.endsWith('d.ts')) {
console.error("[electron-infra] outputFile: %s | Required outputFile must be absolute path and name ends with '.d.ts'!", outputFile);
process.exit(-1);
}
const files = fs_1.default.readdirSync(srcDir);
if (!files.length) {
console.error('[electron-infra] srcDir: %s | No file to export!', srcDir);
process.exit(-1);
}
files.forEach(file => {
const filePath = path_1.default.join(srcDir, file);
if (!filePath.endsWith('.ts') || file === 'index.ts') {
return;
}
processFile({ filePath, program });
});
interfaceDeclarations.push(`export type TControllerMethods =\n\t| ${interfaceNames.map(el => `keyof ${el}`).join('\n\t| ')}`, `export type TIpcMethods =\n\t | ${ipcMethods.map(el => `'${el}'`).join('\n\t| ')}`, ipcSenderMethods.length
? `export type TIpcSenderMethods =\n\t | ${ipcSenderMethods.map(el => `'${el}'`).join('\n\t| ')}`
: '', ipcHandlerMethods.length
? `export type TIpcHandlerMethods =\n\t | ${ipcHandlerMethods.map(el => `'${el}'`).join('\n\t| ')}`
: '', ipcSubscriberMethods.length
? `export type TIpcSubscriberMethods =\n\t | ${ipcSubscriberMethods.map(el => `'${el}'`).join('\n\t| ')}`
: '');
fs_1.default.writeFileSync(outputFile, interfaceDeclarations.join('\n\n'), 'utf8');
console.info();
console.info('[electron-infra] Generated outputFile | outputFile: %s', outputFile);
console.info('[electron-infra] DONE | Generated routes/types | Tooks: %s(ms)', new Date().getTime() - t);
};
main();
//# sourceMappingURL=typegen.js.map