automate-electron-ipc
Version:
Node library for automating the generation of IPC components for Electron apps.
78 lines (77 loc) • 3.45 kB
JavaScript
/*
* Apache License 2.0
*
* Copyright (c) 2024, Mattias Aabmets
*
* The contents of this file are subject to the terms and conditions defined in the License.
* You may not use, modify, or distribute this file except in compliance with the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
import path from "node:path";
export class ImportsGenerator {
projectUsesNodeNext;
targetFilePath;
seenImports;
constructor(projectUsesNodeNext, targetFilePath) {
this.projectUsesNodeNext = projectUsesNodeNext;
this.targetFilePath = targetFilePath;
this.seenImports = {
customTypes: new Set(),
nameSpaces: new Set(),
};
}
splitTypeNamespace(typeName) {
const [value1, value2] = typeName.split(".", 2);
return value2 ? [value1, value2] : [null, value1];
}
getImportPath(...paths) {
const joined = path.join(...paths);
const normalizedPath = joined.replaceAll(path.sep, "/");
const extLen = path.extname(normalizedPath).length;
const baseName = normalizedPath.slice(0, normalizedPath.length - extLen);
return this.projectUsesNodeNext ? `${baseName}.js` : baseName;
}
adjustImportPath(importPath, sourceFilePath) {
const sourceDir = path.dirname(sourceFilePath);
const targetDir = path.dirname(this.targetFilePath);
const importAbsolutePath = path.normalize(path.join(sourceDir, importPath));
let adjustedPath = path.relative(targetDir, importAbsolutePath);
adjustedPath = adjustedPath.replace(/\\/g, "/");
if (!["..", "./"].includes(adjustedPath.slice(0, 2))) {
adjustedPath = `./${adjustedPath}`;
}
return adjustedPath;
}
getDeclaration(parsedFileSpecs, parsedCustomType) {
const importSpecArray = parsedFileSpecs.specs.importSpecArray;
const typeSpecArray = parsedFileSpecs.specs.typeSpecArray;
const [nameSpace, customType] = this.splitTypeNamespace(parsedCustomType);
const importSpec = importSpecArray.find((spec) => {
const hasNameSpace = nameSpace && spec.namespace === nameSpace;
const hasCustomType = spec.customTypes.includes(customType);
return hasNameSpace || hasCustomType;
});
const typeSpec = typeSpecArray.find((spec) => {
return spec.name === customType;
});
if (typeSpec) {
const adjustedImportPath = this.adjustImportPath(this.getImportPath(path.basename(parsedFileSpecs.fullPath)), parsedFileSpecs.fullPath);
if (!this.seenImports.customTypes.has(customType)) {
return `import type { ${customType} } from "${adjustedImportPath}";`;
}
}
else if (importSpec) {
const adjustedImportPath = this.adjustImportPath(this.getImportPath(importSpec.fromPath), parsedFileSpecs.fullPath);
if (nameSpace && !this.seenImports.nameSpaces.has(nameSpace)) {
this.seenImports.nameSpaces.add(nameSpace);
return `import type * as ${nameSpace} from "${adjustedImportPath}";`;
}
else if (customType && !this.seenImports.customTypes.has(customType)) {
this.seenImports.customTypes.add(customType);
return `import type { ${customType} } from "${adjustedImportPath}";`;
}
}
return null;
}
}