TypeScript/scripts/build/gulp-typescript-oop.js

88 lines
No EOL
3.2 KiB
TypeScript

// @ts-check
const path = require("path");
const child_process = require("child_process");
const tsc = require("gulp-typescript");
const Vinyl = require("vinyl");
const { Duplex, Readable } = require("stream");
/**
* @param {string} tsConfigFileName
* @param {tsc.Settings} settings
* @param {Object} options
* @param {string} [options.typescript]
*/
function createProject(tsConfigFileName, settings, options) {
settings = { ...settings };
options = { ...options };
if (settings.typescript) throw new Error();
const localSettings = { ...settings };
if (options.typescript) {
options.typescript = path.resolve(options.typescript);
localSettings.typescript = require(options.typescript);
}
const project = tsc.createProject(tsConfigFileName, localSettings);
const wrappedProject = /** @type {tsc.Project} */(() => {
const proc = child_process.fork(require.resolve("./main.js"));
/** @type {Duplex & { js?: Readable, dts?: Readable }} */
const compileStream = new Duplex({
objectMode: true,
read() {},
/** @param {*} file */
write(file, encoding, callback) {
proc.send({ method: "write", params: { path: file.path, cwd: file.cwd, base: file.base, sourceMap: file.sourceMap }});
callback();
},
final(callback) {
proc.send({ method: "final" });
callback();
}
});
const jsStream = compileStream.js = new Readable({
objectMode: true,
read() {}
});
const dtsStream = compileStream.dts = new Readable({
objectMode: true,
read() {}
});
proc.send({ method: "createProject", params: { tsConfigFileName, settings, options } });
proc.on("message", ({ method, params }) => {
if (method === "write") {
const file = new Vinyl({
path: params.path,
cwd: params.cwd,
base: params.base,
contents: Buffer.from(params.contents, "utf8")
});
if (params.sourceMap) file.sourceMap = params.sourceMap
compileStream.push(file);;
if (file.path.endsWith(".d.ts")) {
dtsStream.push(file);
}
else {
jsStream.push(file);
}
}
else if (method === "final") {
compileStream.push(null);
jsStream.push(null);
dtsStream.push(null);
proc.kill();
}
else if (method === "error") {
const error = new Error();
error.name = params.name;
error.message = params.message;
error.stack = params.stack;
compileStream.emit("error", error);
proc.kill();
}
});
return /** @type {*} */(compileStream);
});
return Object.assign(wrappedProject, project);
}
exports.createProject = createProject;