Cleanup, remove some unneeded dependencies, make it easier to add gulp.watch support later

This commit is contained in:
Ron Buckton 2018-06-20 18:24:12 -07:00
parent 5bc8f957f1
commit c8c0428162
14 changed files with 539 additions and 678 deletions

View file

@ -24,12 +24,13 @@ const getDirSize = require("./scripts/build/getDirSize");
const project = require("./scripts/build/project");
const replace = require("./scripts/build/replace");
const convertConstEnums = require("./scripts/build/convertConstEnum");
const makeLibraryTargets = require("./scripts/build/lib");
const needsUpdate = require("./scripts/build/needsUpdate");
const getDiffTool = require("./scripts/build/getDiffTool");
const baselineAccept = require("./scripts/build/baselineAccept");
const cmdLineOptions = require("./scripts/build/options");
const exec = require("./scripts/build/exec");
const _debugMode = require("./scripts/build/debugMode");
const { libraryTargets, generateLibs } = require("./scripts/build/lib");
const { runConsoleTests, cleanTestDirs, writeTestConfigFile, refBaseline, localBaseline, refRwcBaseline, localRwcBaseline } = require("./scripts/build/tests");
Error.stackTraceLimit = 1000;
@ -37,11 +38,10 @@ Error.stackTraceLimit = 1000;
// Constants
const host = cmdLineOptions.host;
const copyright = "CopyrightNotice.txt";
const libraryTargets = makeLibraryTargets([copyright]);
// Compile using the LKG compiler
project.addTypeScript("lkg", "./lib/typescript.js");
project.addTypeScript("default", "lkg");
project.addTypeScript("built", "./built/local/typescriptServices.js");
project.addTypeScript("default", "lkg"); // Compile using the LKG compiler by default
const scriptsProject = "scripts/tsconfig.json";
const configurePrereleaseJs = "scripts/configurePrerelease.js";
@ -50,7 +50,7 @@ const generateLocalizedDiagnosticMessagesJs = "scripts/generateLocalizedDiagnost
const buildProtocolJs = "scripts/buildProtocol.js";
const produceLKGJs = "scripts/produceLKG.js";
const word2mdJs = "scripts/word2md.js";
gulp.task("scripts", /*help*/ false, [project(scriptsProject)], undefined, {
gulp.task("scripts", /*help*/ false, () => project.compile(scriptsProject), {
aliases: [
configurePrereleaseJs,
processDiagnosticMessagesJs,
@ -60,7 +60,7 @@ gulp.task("scripts", /*help*/ false, [project(scriptsProject)], undefined, {
word2mdJs
]
});
gulp.task("clean-scripts", /*help*/ false, [project.clean(scriptsProject)]);
gulp.task("clean-scripts", /*help*/ false, () => project.clean(scriptsProject));
// Nightly management tasks
gulp.task(
@ -78,8 +78,8 @@ gulp.task(
const importDefinitelyTypedTestsProject = "scripts/importDefinitelyTypedTests/tsconfig.json";
const importDefinitelyTypedTestsJs = "scripts/importDefinitelyTypedTests/importDefinitelyTypedTests.js";
gulp.task(importDefinitelyTypedTestsJs, /*help*/ false, [project(importDefinitelyTypedTestsProject)]);
gulp.task("clean:" + importDefinitelyTypedTestsJs, /*help*/ false, [project.clean(importDefinitelyTypedTestsProject)]);
gulp.task(importDefinitelyTypedTestsJs, /*help*/ false, () => project.compile(importDefinitelyTypedTestsProject));
gulp.task("clean:" + importDefinitelyTypedTestsJs, /*help*/ false, () => project.clean(importDefinitelyTypedTestsProject));
gulp.task(
"importDefinitelyTypedTests",
@ -90,7 +90,7 @@ gulp.task(
gulp.task(
"lib",
"Builds the library targets",
libraryTargets);
() => generateLibs([copyright]));
// The generated diagnostics map; built for the compiler and for the "generate-diagnostics" task
const diagnosticInformationMapTs = "src/compiler/diagnosticInformationMap.generated.ts";
@ -145,20 +145,18 @@ gulp.task(typescriptServicesProject, /*help*/ false, () => {
// NOTE: flatten services so that we can properly strip @internal
project.flatten("src/services/tsconfig.json", typescriptServicesProject, {
compilerOptions: {
"removeComments": true,
"stripInternal": true,
"outFile": "typescriptServices.js"
}
});
})
});
const typescriptServicesJs = "built/local/typescriptServices.js";
const typescriptServicesDts = "built/local/typescriptServices.d.ts";
const typescriptServicesProjectTask = project.defer(typescriptServicesProject, {
dts: files => files.pipe(convertConstEnums()),
release: { compilerOptions: { removeComments: true } }
});
gulp.task(typescriptServicesJs, /*help*/ false, ["lib", "generate-diagnostics", typescriptServicesProject], typescriptServicesProjectTask, { aliases: [typescriptServicesDts] });
gulp.task(typescriptServicesJs, /*help*/ false, ["lib", "generate-diagnostics", typescriptServicesProject], () =>
project.compile(typescriptServicesProject, { dts: convertConstEnums() }),
{ aliases: [typescriptServicesDts] });
const typescriptJs = "built/local/typescript.js";
gulp.task(typescriptJs, /*help*/ false, [typescriptServicesJs], () =>
@ -186,28 +184,25 @@ gulp.task(typescriptStandaloneDts, /*help*/ false, [typescriptServicesDts], () =
// build all 'typescriptServices'-related outputs
gulp.task("typescriptServices", /*help*/ false, [typescriptServicesJs, typescriptServicesDts, typescriptJs, typescriptDts, typescriptStandaloneDts]);
// Add the "built" compiler with a dependency on the built version of the compiler.
project.addTypeScript("built", "./built/local/typescriptServices.js", [typescriptServicesJs]);
const tscProject = "src/tsc/tsconfig.json";
const tscJs = "built/local/tsc.js";
gulp.task(tscJs, /*help*/ false, [project(tscProject, { typescript: "built", release: { compilerOptions: { removeComments: true } } })]);
gulp.task(tscJs, /*help*/ false, [typescriptServicesJs], () => project.compile(tscProject, { typescript: "built" }));
const cancellationTokenProject = "src/cancellationToken/tsconfig.json";
const cancellationTokenJs = "built/local/cancellationToken.js";
gulp.task(cancellationTokenJs, /*help*/ false, [project(cancellationTokenProject, { typescript: "built", release: { compilerOptions: { removeComments: true } } })]);
gulp.task(cancellationTokenJs, /*help*/ false, [typescriptServicesJs], () => project.compile(cancellationTokenProject, { typescript: "built" }));
const typingsInstallerProject = "src/typingsInstaller/tsconfig.json";
const typingsInstallerJs = "built/local/typingsInstaller.js";
gulp.task(typingsInstallerJs, /*help*/ false, [project(typingsInstallerProject, { typescript: "built", release: { compilerOptions: { removeComments: true } } })]);
gulp.task(typingsInstallerJs, /*help*/ false, [typescriptServicesJs], () => project.compile(typingsInstallerProject, { typescript: "built" }));
const tsserverProject = "src/tsserver/tsconfig.json";
const tsserverJs = "built/local/tsserver.js";
gulp.task(tsserverJs, /*help*/ false, [project(tsserverProject, { typescript: "built", release: { compilerOptions: { removeComments: true } } })]);
gulp.task(tsserverJs, /*help*/ false, [typescriptServicesJs], () => project.compile(tsserverProject, { typescript: "built" }));
const watchGuardProject = "src/watchGuard/tsconfig.json";
const watchGuardJs = "built/local/watchGuard.js";
gulp.task(watchGuardJs, /*help*/ false, [project(watchGuardProject, { typescript: "built", release: { compilerOptions: { removeComments: true } } })]);
gulp.task(watchGuardJs, /*help*/ false, [typescriptServicesJs], () => project.compile(watchGuardProject, { typescript: "built" }));
const typesMapJson = "built/local/typesMap.json";
gulp.task(typesMapJson, /*help*/ false, [], () =>
@ -249,42 +244,43 @@ gulp.task(
"Generates a Markdown version of the Language Specification",
[specMd]);
gulp.task("produce-LKG", /*help*/ false, ["scripts", "local", cancellationTokenJs, typingsInstallerJs, watchGuardJs], () => {
const expectedFiles = [
tscJs,
typescriptServicesJs,
tsserverJs,
typescriptJs,
typescriptDts,
typescriptServicesDts,
tsserverlibraryDts,
tsserverlibraryDts,
typingsInstallerJs,
cancellationTokenJs
].concat(libraryTargets);
const missingFiles = expectedFiles
.concat(localizationTargets)
.filter(f => !fs.existsSync(f));
if (missingFiles.length > 0) {
throw new Error("Cannot replace the LKG unless all built targets are present in directory 'built/local/'. The following files are missing:\n" + missingFiles.join("\n"));
}
const sizeBefore = getDirSize("lib");
return exec(host, [produceLKGJs]).then(() => {
const sizeAfter = getDirSize("lib");
if (sizeAfter > (sizeBefore * 1.10)) {
throw new Error("The lib folder increased by 10% or more. This likely indicates a bug.");
}
});
});
gulp.task(
"LKG",
"Makes a new LKG out of the built js files",
() => runSequence("clean-built", "dontUseDebugMode", ["scripts", "local", cancellationTokenJs, typingsInstallerJs, watchGuardJs],
() => {
const expectedFiles = [
tscJs,
typescriptServicesJs,
tsserverJs,
typescriptJs,
typescriptDts,
typescriptServicesDts,
tsserverlibraryDts,
tsserverlibraryDts,
typingsInstallerJs,
cancellationTokenJs
].concat(libraryTargets);
const missingFiles = expectedFiles
.concat(localizationTargets)
.filter(f => !fs.existsSync(f));
if (missingFiles.length > 0) {
throw new Error("Cannot replace the LKG unless all built targets are present in directory 'built/local/'. The following files are missing:\n" + missingFiles.join("\n"));
}
const sizeBefore = getDirSize("lib");
return exec(host, [produceLKGJs]).then(() => {
const sizeAfter = getDirSize("lib");
if (sizeAfter > (sizeBefore * 1.10)) {
throw new Error("The lib folder increased by 10% or more. This likely indicates a bug.");
}
});
}));
() => runSequence("clean-built", "dontUseDebugMode", "produce-LKG"));
// Task to build the tests infrastructure using the built compiler
const testRunnerProject = "src/testRunner/tsconfig.json";
const runJs = "built/local/run.js";
gulp.task(runJs, /*help*/ false, [project(testRunnerProject, { typescript: "built", deps: [tsserverlibraryDts] })]);
gulp.task(runJs, /*help*/ false, [typescriptServicesJs, tsserverlibraryDts], () => project.compile(testRunnerProject, { typescript: "built" }));
gulp.task(
"tests",
@ -310,8 +306,8 @@ gulp.task(
const webTestServerProject = "tests/webTestServer.tsconfig.json";
const webTestServerJs = "tests/webTestServer.js";
gulp.task(webTestServerJs, /*help*/ false, [project(webTestServerProject, { typescript: "built", release: { compilerOptions: { removeComments: true } } })])
gulp.task("clean:" + webTestServerJs, /*help*/ false, [project.clean(webTestServerProject, { typescript: "built" })])
gulp.task(webTestServerJs, /*help*/ false, [typescriptServicesJs], () => project.compile(webTestServerProject, { typescript: "built" }));
gulp.task("clean:" + webTestServerJs, /*help*/ false, () => project.clean(webTestServerProject));
const bundlePath = path.resolve("built/local/bundle.js");
@ -447,8 +443,8 @@ gulp.task(
// Webhost
const webtscProject = "tests/webhost/webtsc.tsconfig.json";
const webtscJs = "tests/webhost/webtsc.js";
gulp.task(webtscJs, /*help*/ false, [project(webtscProject, { typescript: "built", release: { compilerOptions: { removeComments: true } } })]);
gulp.task("clean:" + webtscJs, /*help*/ false, [project.clean(webtscProject, { typescript: "built" })]);
gulp.task(webtscJs, /*help*/ false, [typescriptServicesJs], () => project.compile(webtscProject, { typescript: "built" }));
gulp.task("clean:" + webtscJs, /*help*/ false, () => project.clean(webtscProject));
gulp.task("webhost", "Builds the tsc web host", [webtscJs], () =>
gulp.src("built/local/lib.d.ts")
@ -457,8 +453,8 @@ gulp.task("webhost", "Builds the tsc web host", [webtscJs], () =>
// Perf compiler
const perftscProject = "tests/perftsc.tsconfig.json";
const perftscJs = "built/local/perftsc.js";
gulp.task(perftscJs, /*help*/ false, [project(perftscProject, { typescript: "built", release: { compilerOptions: { removeComments: true } } })]);
gulp.task("clean:" + perftscJs, /*help*/ false, [project.clean(perftscProject, { typescript: "built" })]);
gulp.task(perftscJs, /*help*/ false, [typescriptServicesJs], () => project.compile(perftscProject, { typescript: "built" }));
gulp.task("clean:" + perftscJs, /*help*/ false, () => project.clean(perftscProject));
gulp.task(
"perftsc",
@ -477,8 +473,8 @@ gulp.task(loggedIOJs, /*help*/ false, [], (done) => {
const instrumenterProject = "src/instrumenter/tsconfig.json";
const instrumenterJs = "built/local/instrumenter.js";
gulp.task(instrumenterJs, /*help*/ false, [project(instrumenterProject)]);
gulp.task("clean:" + instrumenterJs, /*help*/ false, [project.clean(instrumenterProject)]);
gulp.task(instrumenterJs, /*help*/ false, () => project.compile(instrumenterProject));
gulp.task("clean:" + instrumenterJs, /*help*/ false, () => project.clean(instrumenterProject));
gulp.task(
"tsc-instrumented",
@ -497,9 +493,9 @@ gulp.task(
gulp.task(
"build-rules",
"Compiles tslint rules to js",
[project("scripts/tslint/tsconfig.json")]);
() => project.compile("scripts/tslint/tsconfig.json"));
gulp.task("clean-rules", /*help*/ false, [project.clean("scripts/tslint/tsconfig.json")]);
gulp.task("clean-rules", /*help*/ false, () => project.clean("scripts/tslint/tsconfig.json"));
gulp.task(
"lint",

111
package-lock.json generated
View file

@ -11,7 +11,7 @@
"dev": true,
"requires": {
"acorn": "5.7.1",
"css": "2.2.1",
"css": "2.2.3",
"normalize-path": "2.1.1",
"source-map": "0.5.7",
"through2": "2.0.3"
@ -408,6 +408,7 @@
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
"integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
"dev": true,
"requires": {
"ansi-wrap": "0.1.0"
}
@ -439,7 +440,8 @@
"ansi-wrap": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
"integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768="
"integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
"dev": true
},
"append-buffer": {
"version": "1.0.2",
@ -468,7 +470,8 @@
"arr-diff": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
"integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
"integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
"dev": true
},
"arr-flatten": {
"version": "1.1.0",
@ -479,7 +482,8 @@
"arr-union": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
"array-differ": {
"version": "1.0.0",
@ -584,7 +588,8 @@
"assign-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
"dev": true
},
"astw": {
"version": "2.2.0",
@ -1171,7 +1176,8 @@
"color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"dev": true
},
"combine-source-map": {
"version": "0.8.0",
@ -1353,23 +1359,17 @@
}
},
"css": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz",
"integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/css/-/css-2.2.3.tgz",
"integrity": "sha512-0W171WccAjQGGTKLhw4m2nnl0zPHUlTO/I8td4XzJgIB8Hg3ZZx71qT4G4eX8OVsSiaAKiUMy73E3nsbPlg2DQ==",
"dev": true,
"requires": {
"inherits": "2.0.3",
"source-map": "0.1.43",
"source-map-resolve": "0.3.1",
"source-map-resolve": "0.5.1",
"urix": "0.1.0"
},
"dependencies": {
"atob": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz",
"integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=",
"dev": true
},
"source-map": {
"version": "0.1.43",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
@ -1378,24 +1378,6 @@
"requires": {
"amdefine": "1.0.1"
}
},
"source-map-resolve": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz",
"integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=",
"dev": true,
"requires": {
"atob": "1.1.3",
"resolve-url": "0.2.1",
"source-map-url": "0.3.0",
"urix": "0.1.0"
}
},
"source-map-url": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz",
"integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=",
"dev": true
}
}
},
@ -1405,7 +1387,7 @@
"integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
"dev": true,
"requires": {
"es5-ext": "0.10.42"
"es5-ext": "0.10.45"
}
},
"date-now": {
@ -1632,12 +1614,6 @@
"integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
"dev": true
},
"duplexer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},
"duplexer2": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
@ -1706,9 +1682,9 @@
}
},
"es5-ext": {
"version": "0.10.42",
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.42.tgz",
"integrity": "sha512-AJxO1rmPe1bDEfSR6TJ/FgMFYuTBhR5R57KW58iCkYACMyFbrkqVyzXSurYoScDGvgyMpk7uRF/lPUPPTmsRSA==",
"version": "0.10.45",
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz",
"integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==",
"dev": true,
"requires": {
"es6-iterator": "2.0.3",
@ -1723,7 +1699,7 @@
"dev": true,
"requires": {
"d": "1.0.0",
"es5-ext": "0.10.42",
"es5-ext": "0.10.45",
"es6-symbol": "3.1.1"
}
},
@ -1757,7 +1733,7 @@
"dev": true,
"requires": {
"d": "1.0.0",
"es5-ext": "0.10.42"
"es5-ext": "0.10.45"
}
},
"es6-weak-map": {
@ -1767,7 +1743,7 @@
"dev": true,
"requires": {
"d": "1.0.0",
"es5-ext": "0.10.42",
"es5-ext": "0.10.45",
"es6-iterator": "2.0.3",
"es6-symbol": "3.1.1"
}
@ -1828,7 +1804,7 @@
"dev": true,
"requires": {
"d": "1.0.0",
"es5-ext": "0.10.42"
"es5-ext": "0.10.45"
}
},
"events": {
@ -1916,6 +1892,7 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
"integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
"dev": true,
"requires": {
"assign-symbols": "1.0.0",
"is-extendable": "1.0.1"
@ -1925,6 +1902,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
"dev": true,
"requires": {
"is-plain-object": "2.0.4"
}
@ -2000,6 +1978,7 @@
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz",
"integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=",
"dev": true,
"requires": {
"ansi-gray": "0.1.1",
"color-support": "1.1.3",
@ -2760,7 +2739,7 @@
"@gulp-sourcemaps/map-sources": "1.0.0",
"acorn": "5.7.1",
"convert-source-map": "1.5.1",
"css": "2.2.1",
"css": "2.2.3",
"debug-fabulous": "1.1.0",
"detect-newline": "2.1.0",
"graceful-fs": "4.1.11",
@ -3406,6 +3385,7 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
"dev": true,
"requires": {
"isobject": "3.0.1"
}
@ -3473,7 +3453,8 @@
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"dev": true
},
"istanbul": {
"version": "0.4.5",
@ -3672,15 +3653,6 @@
"dev": true,
"optional": true
},
"lazypipe": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lazypipe/-/lazypipe-1.0.1.tgz",
"integrity": "sha1-FHGu9rN6NA1Rw030Rpnc7wZMGUA=",
"dev": true,
"requires": {
"stream-combiner": "0.2.2"
}
},
"lazystream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
@ -3902,7 +3874,7 @@
"integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=",
"dev": true,
"requires": {
"es5-ext": "0.10.42"
"es5-ext": "0.10.45"
}
},
"make-iterator": {
@ -3955,7 +3927,7 @@
"dev": true,
"requires": {
"d": "1.0.0",
"es5-ext": "0.10.42",
"es5-ext": "0.10.45",
"es6-weak-map": "2.0.2",
"event-emitter": "0.3.5",
"is-promise": "2.1.0",
@ -4657,6 +4629,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
"integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==",
"dev": true,
"requires": {
"ansi-colors": "1.1.0",
"arr-diff": "4.0.0",
@ -4668,6 +4641,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
"integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
"dev": true,
"requires": {
"ansi-wrap": "0.1.0"
}
@ -5478,16 +5452,6 @@
"readable-stream": "2.3.6"
}
},
"stream-combiner": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
"integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=",
"dev": true,
"requires": {
"duplexer": "0.1.1",
"through": "2.3.8"
}
},
"stream-combiner2": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
@ -5712,7 +5676,8 @@
"time-stamp": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
"integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM="
"integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
"dev": true
},
"timers-browserify": {
"version": "1.4.2",
@ -5729,7 +5694,7 @@
"integrity": "sha512-tsEStd7kmACHENhsUPaxb8Jf8/+GZZxyNFQbZD07HQOyooOa6At1rQqjffgvg7n+dxscQa9cjjMdWhJtsP2sxg==",
"dev": true,
"requires": {
"es5-ext": "0.10.42",
"es5-ext": "0.10.45",
"next-tick": "1.0.0"
}
},

View file

@ -61,8 +61,8 @@
"chalk": "latest",
"convert-source-map": "latest",
"del": "latest",
"fs-extra": "^6.0.1",
"fancy-log": "latest",
"fs-extra": "^6.0.1",
"gulp": "3.X",
"gulp-clone": "latest",
"gulp-concat": "latest",

5
scripts/build/chalk.js Normal file
View file

@ -0,0 +1,5 @@
// @ts-check
// this just fixes the incorrect types for chalk :/
const chalk = /**@type {import("chalk").Chalk}*/(require("chalk").default || require("chalk"));
module.exports = chalk;

View file

@ -1,20 +0,0 @@
// @ts-check
const chalk = /**@type {import("chalk").Chalk}*/(require("chalk").default || require("chalk"));
exports.useColors = process.stdout.isTTY;
for (const arg of process.argv) {
if (arg === "--no-color") exports["useColors"] = false;
else if (arg === "--color") exports["useColors"] = true;
}
/**
* @param {string} message
* @param {import("chalk").Chalk} color
*/
function addColor(message, color) {
return exports.useColors ? color(message) : message;
}
exports.addColor = addColor;
/** @type {{[P in Exclude<keyof import("chalk").Chalk, "constructor" | "enabled" | "level">]: import("chalk").Chalk[P]}} */
exports.color = chalk;

View file

@ -11,20 +11,37 @@ const formatDiagnosticsHost = exports.formatDiagnosticsHost = {
/**
* @param {Diagnostic[]} diagnostics
* @param {boolean} [pretty]
* @param {{ cwd?: string, pretty?: boolean }} [options]
*/
function formatDiagnostics(diagnostics, pretty) {
return pretty ? ts.formatDiagnosticsWithColorAndContext(diagnostics, formatDiagnosticsHost) :
ts.formatDiagnostics(diagnostics, formatDiagnosticsHost);
function formatDiagnostics(diagnostics, options) {
return options && options.pretty
? ts.formatDiagnosticsWithColorAndContext(diagnostics, getFormatDiagnosticsHost(options && options.cwd))
: ts.formatDiagnostics(diagnostics, getFormatDiagnosticsHost(options && options.cwd));
}
exports.formatDiagnostics = formatDiagnostics;
/** @param {Diagnostic[]} diagnostics */
function reportDiagnostics(diagnostics) {
log(formatDiagnostics(diagnostics, process.stdout.isTTY));
/**
* @param {Diagnostic[]} diagnostics
* @param {{ cwd?: string }} [options]
*/
function reportDiagnostics(diagnostics, options) {
log(formatDiagnostics(diagnostics, { cwd: options && options.cwd, pretty: process.stdout.isTTY }));
}
exports.reportDiagnostics = reportDiagnostics;
/**
* @param {string | undefined} cwd
* @returns {FormatDiagnosticsHost}
*/
function getFormatDiagnosticsHost(cwd) {
if (!cwd || cwd === process.cwd()) return formatDiagnosticsHost;
return {
getCanonicalFileName: formatDiagnosticsHost.getCanonicalFileName,
getCurrentDirectory: () => cwd,
getNewLine: formatDiagnosticsHost.getNewLine
};
}
/**
* @typedef {import("../../lib/typescript").FormatDiagnosticsHost} FormatDiagnosticsHost
* @typedef {import("../../lib/typescript").Diagnostic} Diagnostic

View file

@ -2,7 +2,7 @@
const cp = require("child_process");
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
const isWin = /^win/.test(process.platform);
const { addColor, color } = require("./colors");
const chalk = require("./chalk");
module.exports = exec;
@ -15,7 +15,7 @@ module.exports = exec;
*/
function exec(cmd, args, options = {}) {
return /**@type {Promise<{exitCode: number}>}*/(new Promise((resolve, reject) => {
log(addColor(`${cmd} ${args.join(" ")}`, color.gray));
log(`> ${chalk.green(cmd)} ${args.join(" ")}`);
// TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition
const subshellFlag = isWin ? "/c" : "-c";
const command = isWin ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`];

View file

@ -1 +1,8 @@
// @ts-check
/**
* @typedef {import("gulp").Gulp} Gulp
* @typedef {import("gulp-help").GulpHelp} GulpHelp
* @typedef {GulpHelp & { Gulp: new () => Gulp }} DotGulpModule
* @type {DotGulpModule}
*/
module.exports = require("gulp-help")(require("gulp"));

View file

@ -4,26 +4,27 @@ const path = require("path");
const gulp = require("./gulp");
const newer = require("gulp-newer");
const concat = require("gulp-concat");
module.exports = exports = makeLibraryTargets;
const merge2 = require("merge2");
/** @type {{ libs: string[], paths?: Record<string, string>, sources?: Record<string, string[]> }} */
const libraries = readJson("./src/lib/libs.json");
const libs = libraries.libs.map(lib => {
const relativeSources = ["header.d.ts"].concat(libraries.sources && libraries.sources[lib] || [lib + ".d.ts"]);
const relativeTarget = libraries.paths && libraries.paths[lib] || ("lib." + lib + ".d.ts");
const sources = relativeSources.map(s => path.posix.join("src/lib", s));
const target = `built/local/${relativeTarget}`;
return { target, relativeTarget, sources };
});
exports.libraryTargets = libs.map(lib => lib.target);
/**
* @param {string[]} prepends
*/
function makeLibraryTargets(prepends) {
return libraries.libs.map(lib => {
const relativeSources = ["header.d.ts"].concat(libraries.sources && libraries.sources[lib] || [lib + ".d.ts"]);
const relativeTarget = libraries.paths && libraries.paths[lib] || ("lib." + lib + ".d.ts");
const sources = prepends.concat(relativeSources.map(s => path.posix.join("src/lib", s)));
const target = `built/local/${relativeTarget}`;
gulp.task(target, /*help*/ false, [], () =>
gulp.src(sources)
.pipe(newer(target))
.pipe(concat(relativeTarget, { newLine: "\n\n" }))
.pipe(gulp.dest("built/local")));
return target;
});
}
function generateLibs(prepends) {
return merge2(libs.map(({ sources, target, relativeTarget }) =>
gulp.src(prepends.concat(sources))
.pipe(newer(target))
.pipe(concat(relativeTarget, { newLine: "\n\n" }))
.pipe(gulp.dest("built/local"))));
}
exports.generateLibs = generateLibs;

View file

@ -1,11 +0,0 @@
// @ts-check
const { PassThrough } = require("stream");
/**
* @returns {NodeJS.ReadWriteStream}
*/
function pass() {
return new PassThrough({ objectMode: true });
}
module.exports = pass;

View file

@ -1,14 +0,0 @@
// @ts-check
const fs = require("fs");
const insert = require("gulp-insert");
const pass = require("./pass");
/**
* @param {(() => string[] | undefined) | string[]} [prepends]
* @returns {NodeJS.ReadWriteStream}
*/
function prepend(prepends) {
if (typeof prepends === "function") prepends = prepends();
return (prepends || []).reduce((stream, file) => stream.pipe(insert.prepend(fs.readFileSync(file))), pass());
}
module.exports = prepend;

View file

@ -2,8 +2,6 @@
const path = require("path");
const fs = require("fs");
const gulp = require("./gulp");
const PluginError = require("plugin-error");
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
const gulpif = require("gulp-if");
const sourcemaps = require("gulp-sourcemaps");
const merge2 = require("merge2");
@ -11,105 +9,140 @@ const tsc = require("gulp-typescript");
const tsc_oop = require("./gulp-typescript-oop");
const upToDate = require("./upToDate");
const ts = require("../../lib/typescript");
const debugMode = require("./debugMode");
const del = require("del");
const needsUpdate = require("./needsUpdate");
const mkdirp = require("./mkdirp");
const { reportDiagnostics } = require("./diagnostics");
const { PassThrough } = require("stream");
module.exports = exports = project;
class CompilationGulp extends gulp.Gulp {
/**
* @param {import("gulp-help").GulpHelp | import("gulp").Gulp} gulp
*/
constructor(gulp) {
super();
// forward notifications to the outer gulp.
this.on("task_start", e => gulp.emit("task_start", e));
this.on("task_stop", e => gulp.emit("task_stop", e));
this.on("task_err", e => gulp.emit("task_err", e));
this.on("task_not_found", e => gulp.emit("task_not_found", e));
this.on("task_recursion", e => gulp.emit("task_recursion", e));
this.on("err", e => gulp.emit("err", e));
}
/** @type {Map<string, Map<string, ResolvedProject>>} */
const typescriptProjects = new Map();
/** @type {Record<string, { typescript: string, deps?: string[] }>} */
const typescriptRegistry = { };
/**
* Defines a series of gulp tasks for a TypeScript project, returning the root task name.
* @param {string} projectSpec
* @param {ProjectOptions} [options]
* @param {(project: ParsedCommandLine, destPath: string, options: ResolvedProjectOptions) => NodeJS.ReadWriteStream} [task]
*/
function project(projectSpec, options, task) {
return makeProject(projectSpec, resolveProjectOptions(options), /*referer*/ undefined, task).taskName;
dispose() {
this.removeAllListeners();
this.reset();
}
// Do not reset tasks when `gulp.start()` is called
_resetAllTasks() {}
_resetSpecificTasks() {}
_resetTask() {}
}
exports.project = project;
// internal `Gulp` instance for compilation artifacts.
const compilationGulp = new CompilationGulp(gulp);
/** @type {Map<ResolvedProjectSpec, ProjectGraph>} */
const projectGraphCache = new Map();
/** @type {Map<string, { typescript: string, alias: string, paths: ResolvedPathOptions }>} */
const typescriptAliasMap = new Map();
/**
* Defines a deferred gulp pipeline for a TypeScript project.
* @param {string} projectSpec
* @param {ProjectOptions} [options]
* @param {(project: ParsedCommandLine, destPath: string, options: ResolvedProjectOptions) => NodeJS.ReadWriteStream} [task]
* Defines a gulp orchestration for a TypeScript project, returning a callback that can be used to trigger compilation.
* @param {string} projectSpec The path to a tsconfig.json file or its containing directory.
* @param {ProjectOptions} [options] Project compilation options.
* @returns {() => Promise<void>}
*/
function defer(projectSpec, options, task) {
function createCompiler(projectSpec, options) {
const resolvedOptions = resolveProjectOptions(options);
resolvedOptions.defer = true;
const resolvedProject = prepareProject(projectSpec, resolvedOptions, /*referer*/ undefined, task);
return getProjectTaskFunction(resolvedProject);
const resolvedProjectSpec = resolveProjectSpec(projectSpec, resolvedOptions.paths, /*referrer*/ undefined);
const taskName = compileTaskName(ensureCompileTask(getOrCreateProjectGraph(resolvedProjectSpec, resolvedOptions.paths), resolvedOptions), resolvedOptions.typescript);
return () => new Promise((resolve, reject) => compilationGulp.start(taskName, err => err ? reject(err) : resolve(err)));
}
exports.defer = defer;
exports.createCompiler = createCompiler;
/**
* Defines a series of gulp tasks to clean the outputs of a TypeScript project, returning the root task name.
* @param {string} projectSpec
* @param {CleanOptions} [options]
* Defines and executes a gulp orchestration for a TypeScript project.
* @param {string} projectSpec The path to a tsconfig.json file or its containing directory.
* @param {ProjectOptions} [options] Project compilation options.
* @returns {Promise<void>}
*
* @typedef ProjectOptions
* @property {string} [cwd] The path to use for the current working directory. Defaults to `process.cwd()`.
* @property {string} [base] The path to use as the base for relative paths. Defaults to `cwd`.
* @property {string} [typescript] A module specifier or path (relative to gulpfile.js) to the version of TypeScript to use.
* @property {Hook} [js] Pipeline hook for .js file outputs. For multiple steps, use `stream-combiner`.
* @property {Hook} [dts] Pipeline hook for .d.ts file outputs. For multiple steps, use `stream-combiner`.
* @property {boolean} [verbose] Indicates whether verbose logging is enabled.
* @property {boolean} [force] Force recompilation (no up-to-date check).
* @property {boolean} [inProcess] Indicates whether to run gulp-typescript in-process or out-of-process (default).
*
* @typedef {NodeJS.ReadWriteStream | (() => NodeJS.ReadWriteStream)} Hook
*/
function compile(projectSpec, options) {
const compiler = createCompiler(projectSpec, options);
return compiler();
}
exports.compile = compile;
/**
* Defines a gulp orchestration to clean the outputs of a TypeScript project, returning a callback that can be used to trigger compilation.
* @param {string} projectSpec The path to a tsconfig.json file or its containing directory.
* @param {PathOptions} [options] Project clean options.
*/
function createCleaner(projectSpec, options) {
const paths = resolvePathOptions(options);
const resolvedProjectSpec = resolveProjectSpec(projectSpec, paths, /*referrer*/ undefined);
const taskName = cleanTaskName(ensureCleanTask(getOrCreateProjectGraph(resolvedProjectSpec, paths)));
return () => new Promise((resolve, reject) => compilationGulp.start(taskName, err => err ? reject(err) : resolve(err)));
}
exports.createCleaner = createCleaner;
/**
* Defines and executes a gulp orchestration to clean the outputs of a TypeScript project.
* @param {string} projectSpec The path to a tsconfig.json file or its containing directory.
* @param {PathOptions} [options] Project clean options.
*/
function clean(projectSpec, options) {
return makeClean(projectSpec, resolveCleanOptions(options), /*referer*/ undefined);
const cleaner = createCleaner(projectSpec, options);
return cleaner();
}
exports.clean = clean;
/**
* Defines the default task behavior.
* @param {ParsedCommandLine} parsedProject
* @param {string} destPath
* @param {ResolvedTaskConfiguration} options
*/
function defaultTask(parsedProject, destPath, options) {
const { sourceMap, inlineSourceMap, inlineSources = false, sourceRoot, declarationMap } = parsedProject.options;
const configFilePath = parsedProject.options.configFilePath;
const sourceMapPath = inlineSourceMap ? undefined : ".";
const sourceMapOptions = { includeContent: inlineSources, sourceRoot, destPath };
const project = options.inProcess
? tsc.createProject(configFilePath, Object.assign({}, options.compilerOptions, { typescript: require(options.typescript)}))
: tsc_oop.createProject(configFilePath, Object.assign({}, options.compilerOptions), { typescript: options.typescript });
const stream = project.src()
.pipe(gulpif(!options.force, upToDate(parsedProject, { verbose: options.verbose })))
.pipe(gulpif(sourceMap || inlineSourceMap, sourcemaps.init()))
.pipe(project());
const js = stream.js
.pipe(gulpif(sourceMap || inlineSourceMap, sourcemaps.write(sourceMapPath, sourceMapOptions)));
const dts = stream.dts
.pipe(gulpif(declarationMap, sourcemaps.write(sourceMapPath, sourceMapOptions)));
return merge2([options.js ? options.js(js) : js, options.dts ? options.dts(dts) : dts])
.pipe(gulp.dest(destPath));
}
exports.defaultTask = defaultTask;
/**
* Adds a named alias for a TypeScript language service path
* @param {string} alias
* @param {string} typescript
* @param {string[]} [deps]
* @param {string} alias An alias for a TypeScript version.
* @param {string} typescript An alias or module specifier for a TypeScript version.
* @param {PathOptions} [options] Options used to resolve the path to `typescript`.
*/
function addTypeScript(alias, typescript, deps) {
typescriptRegistry[alias] = { typescript, deps };
function addTypeScript(alias, typescript, options) {
const paths = resolvePathOptions(options);
typescriptAliasMap.set(alias, { typescript, alias, paths });
}
exports.addTypeScript = addTypeScript;
/**
* Flattens a project with project references into a single project.
* @param {string} projectSpec
* @param {string} flattenedProjectSpec
* @param {FlattenOptions} [options]
* @param {string} projectSpec The path to a tsconfig.json file or its containing directory.
* @param {string} flattenedProjectSpec The output path for the flattened tsconfig.json file.
* @param {FlattenOptions} [options] Options used to flatten a project hierarchy.
*
* @typedef FlattenOptions
* @property {string} [cwd] The path to use for the current working directory. Defaults to `process.cwd()`.
* @property {CompilerOptions} [compilerOptions] Compiler option overrides.
* @property {boolean} [force] Forces creation of the output project.
*/
function flatten(projectSpec, flattenedProjectSpec, options = {}) {
const paths = resolvePathOptions(options);
const files = [];
const resolvedOutputSpec = path.resolve(flattenedProjectSpec);
const resolvedOutputSpec = path.resolve(paths.cwd, flattenedProjectSpec);
const resolvedOutputDirectory = path.dirname(resolvedOutputSpec);
const resolvedProjectSpec = resolveProjectSpec(projectSpec);
const parsedProject = ts.getParsedCommandLineOfConfigFile(resolvedProjectSpec, {}, parseConfigFileHost);
recur(parsedProject);
const resolvedProjectSpec = resolveProjectSpec(projectSpec, paths, /*referrer*/ undefined);
const projectGraph = getOrCreateProjectGraph(resolvedProjectSpec, paths);
recur(projectGraph);
const config = {
extends: normalizeSlashes(path.relative(resolvedOutputDirectory, resolvedProjectSpec)),
@ -123,418 +156,384 @@ function flatten(projectSpec, flattenedProjectSpec, options = {}) {
}
/**
* @param {ParsedCommandLine} parsedProject
* @param {ProjectGraph} projectGraph
*/
function recur(parsedProject) {
if (parsedProject.projectReferences) {
for (const ref of parsedProject.projectReferences) {
const resolvedProjectSpec = resolveProjectSpec(ref.path, parsedProject);
const referencedProject = ts.getParsedCommandLineOfConfigFile(resolvedProjectSpec, {}, parseConfigFileHost);
recur(referencedProject);
}
function recur(projectGraph) {
for (const ref of projectGraph.references) {
recur(ref.target);
}
for (const file of parsedProject.fileNames) {
files.push(normalizeSlashes(path.relative(resolvedOutputDirectory, path.resolve(file))));
for (const file of projectGraph.project.fileNames) {
files.push(normalizeSlashes(path.relative(resolvedOutputDirectory, path.resolve(projectGraph.projectDirectory, file))));
}
}
}
exports.flatten = flatten;
/**
* @param {string} typescript
* Resolve a TypeScript specifier into a fully-qualified module specifier and any requisite dependencies.
* @param {string} typescript An unresolved module specifier to a TypeScript version.
* @param {ResolvedPathOptions} paths Paths used to resolve `typescript`.
* @returns {ResolvedTypeScript}
*
* @typedef {string & {_isResolvedTypeScript: never}} ResolvedTypeScriptSpec
*
* @typedef ResolvedTypeScript
* @property {ResolvedTypeScriptSpec} typescript
* @property {string} [alias]
*/
function resolveTypeScript(typescript) {
/** @type {string[] | undefined} */
let deps;
while (typescript in typescriptRegistry) {
const entry = typescriptRegistry[typescript];
typescript = entry.typescript;
if (!deps) deps = entry.deps;
function resolveTypeScript(typescript, paths) {
let alias;
while (typescriptAliasMap.has(typescript)) {
({ typescript, alias, paths } = typescriptAliasMap.get(typescript));
}
if (typescript === "default") {
typescript = require.resolve("../../lib/typescript");
}
else if (isPath(typescript)) {
typescript = path.resolve(process.cwd(), typescript);
typescript = path.resolve(paths.cwd, typescript);
}
return { typescript, deps };
return { typescript: /**@type {ResolvedTypeScriptSpec}*/(normalizeSlashes(typescript)), alias };
}
/**
* Gets a suffix to append to Gulp task names that vary by TypeScript version.
* @param {ResolvedTypeScript} typescript A resolved module specifier to a TypeScript version.
* @param {ResolvedPathOptions} paths Paths used to resolve a relative reference to `typescript`.
*/
function getTaskNameSuffix(typescript, paths) {
return typescript.typescript === resolveTypeScript("default", paths).typescript ? "" :
typescript.alias ? `@${typescript.alias}` :
isPath(typescript.typescript) ? `@${normalizeSlashes(path.relative(paths.base, typescript.typescript))}` :
`@${typescript}`;
}
/** @type {ResolvedPathOptions} */
const defaultPaths = { cwd: process.cwd(), base: process.cwd() };
/**
* @param {PathOptions | undefined} options Path options to resolve and normalize.
* @returns {ResolvedPathOptions}
*
* @typedef PathOptions
* @property {string} [cwd] The path to use for the current working directory. Defaults to `process.cwd()`.
* @property {string} [base] The path to use as the base for relative paths. Defaults to `cwd`.
*
* @typedef ResolvedPathOptions
* @property {string} cwd The path to use for the current working directory. Defaults to `process.cwd()`.
* @property {string} base The path to use as the base for relative paths. Defaults to `cwd`.
*/
function resolvePathOptions(options) {
const cwd = options && options.cwd ? path.resolve(process.cwd(), options.cwd) : process.cwd();
const base = options && options.base ? path.resolve(cwd, options.base) : cwd;
return cwd === defaultPaths.cwd && base === defaultPaths.base ? defaultPaths : { cwd, base };
}
/**
* @param {ProjectOptions} [options]
* @returns {ResolvedProjectOptions}
*
* @typedef ResolvedProjectOptions
* @property {ResolvedPathOptions} paths
* @property {ResolvedTypeScript} typescript A resolved reference to a TypeScript implementation.
* @property {Hook} [js] Pipeline hook for .js file outputs.
* @property {Hook} [dts] Pipeline hook for .d.ts file outputs.
* @property {boolean} [verbose] Indicates whether verbose logging is enabled.
* @property {boolean} [force] Force recompilation (no up-to-date check).
* @property {boolean} [inProcess] Indicates whether to run gulp-typescript in-process or out-of-process (default).
*/
function resolveProjectOptions(options = {}) {
const resolvedTypeScript = resolveTypeScript(options.typescript || "default");
const paths = resolvePathOptions(options);
const typescript = resolveTypeScript(options.typescript || "default", paths);
return {
typescript: resolvedTypeScript.typescript,
deps: concat(options.deps, resolvedTypeScript.deps),
compilerOptions: options.compilerOptions || {},
paths,
typescript,
js: options.js,
dts: options.dts,
debug: resolveProjectConfiguration(options.debug),
release: resolveProjectConfiguration(options.release),
verbose: options.verbose || false,
force: options.force || false,
inProcess: options.inProcess || false,
defer: false
inProcess: options.inProcess || false
};
}
/**
* @param {CleanOptions} [options]
* @returns {ResolvedCleanOptions}
* @param {Hook} hook
* @returns {NodeJS.ReadWriteStream}
*/
function resolveCleanOptions(options = {}) {
const resolvedTypeScript = resolveTypeScript(options.typescript || "default");
return { typescript: resolvedTypeScript.typescript };
function evaluateHook(hook) {
return (typeof hook === "function" ? hook() : hook) || new PassThrough({ objectMode: true });
}
/**
* @param {ProjectConfiguration} [config]
* @returns {ResolvedProjectConfiguration}
* @param {ResolvedProjectOptions} left
* @param {ResolvedProjectOptions} right
* @returns {ResolvedProjectOptions}
*/
function resolveProjectConfiguration(config = {}) {
function mergeProjectOptions(left, right) {
if (left.typescript !== right.typescript) throw new Error("Cannot merge project options targeting different TypeScript packages");
if (tryReuseProjectOptions(left, right)) return left;
return {
compilerOptions: config.compilerOptions || {},
deps: config.deps,
js: config.js,
dts: config.dts,
force: config.force,
inProcess: config.inProcess
paths: left.paths,
typescript: left.typescript,
js: right.js || left.js,
dts: right.dts || left.dts,
verbose: right.verbose || left.verbose,
force: right.force || left.force,
inProcess: right.inProcess || left.inProcess
};
}
/**
* @param {ResolvedProjectOptions} a
* @param {ResolvedProjectOptions} b
* @param {ResolvedProjectOptions} left
* @param {ResolvedProjectOptions} right
*/
function mergeProjectOptions(a, b) {
return {
typescript: a.typescript || b.typescript,
deps: distinct(concat(a.deps, b.deps)),
compilerOptions: Object.assign({}, a.compilerOptions, b.compilerOptions),
js: b.js || a.js,
dts: b.dts || a.dts,
debug: mergeProjectConfigurations(a.debug, b.debug),
release: mergeProjectConfigurations(a.release, b.release),
verbose: b.verbose || a.verbose,
force: b.force || a.force,
inProcess: b.inProcess || a.inProcess,
defer: a.defer || b.defer
};
function tryReuseProjectOptions(left, right) {
return left === right
|| left.js === (right.js || left.js)
&& left.dts === (right.dts || left.dts)
&& !left.verbose === !(right.verbose || left.verbose)
&& !left.force === !(right.force || left.force)
&& !left.inProcess === !(right.inProcess || left.inProcess);
}
/**
* @param {ResolvedProjectConfiguration} a
* @param {ResolvedProjectConfiguration} b
* @param {ResolvedProjectSpec} projectSpec
* @param {ResolvedPathOptions} paths
* @returns {UnqualifiedProjectName}
*
* @typedef {string & {_isUnqualifiedProjectName:never}} UnqualifiedProjectName
*/
function mergeProjectConfigurations(a, b) {
return {
compilerOptions: Object.assign({}, a.compilerOptions, b.compilerOptions),
deps: concat(a.deps, b.deps),
js: b.js || a.js,
dts: b.dts || a.dts,
force: b.force !== undefined ? b.force : a.force,
inProcess: b.inProcess !== undefined ? b.inProcess : a.inProcess
};
function getUnqualifiedProjectName(projectSpec, paths) {
return /**@type {UnqualifiedProjectName}*/(normalizeSlashes(path.relative(paths.base, projectSpec)));
}
/**
* @param {ResolvedProjectOptions} options
* @returns {ResolvedTaskConfiguration}
* @param {UnqualifiedProjectName} projectName
* @param {ResolvedPathOptions} paths
* @param {ResolvedTypeScript} typescript
* @returns {QualifiedProjectName}
*
* @typedef {string & {_isQualifiedProjectName:never}} QualifiedProjectName
*/
function getResolvedTaskConfiguration(options) {
const config = debugMode.useDebugMode ? options.debug : options.release
return {
typescript: options.typescript,
compilerOptions: Object.assign({}, options.compilerOptions, config.compilerOptions),
deps: concat(options.deps, config.deps),
dts: config.dts || options.dts,
js: config.js || options.js,
verbose: options.verbose,
force: config.force !== undefined ? config.force : options.force,
inProcess: config.inProcess !== undefined ? config.inProcess : options.inProcess
};
function getQualifiedProjectName(projectName, paths, typescript) {
return /**@type {QualifiedProjectName}*/(projectName + getTaskNameSuffix(typescript, paths));
}
/**
* @template T
* @param {T[] | undefined} a
* @param {T[] | undefined} b
* @returns {T[] | undefined}
/**
* @typedef {import("../../lib/typescript").ParseConfigFileHost} ParseConfigFileHost
* @type {ParseConfigFileHost}
*/
function concat(a, b) {
return a ? b ? a.concat(b) : a : b;
}
/**
* @template T
* @param {T[] | undefined} ar
* @returns {T[] | undefined}
*/
function distinct(ar) {
return ar && [...new Set(ar)];
}
/**
* @param {string} projectSpec
* @param {ResolvedProjectOptions} resolvedOptions
* @param {ParsedCommandLine} [referer]
* @param {Task} [task]
*/
function prepareProject(projectSpec, resolvedOptions, referer, task) {
const resolvedProject = resolveProject(projectSpec, resolvedOptions, referer);
if (resolvedProject.resolvedOptions !== resolvedOptions) {
resolvedProject.resolvedOptions = mergeProjectOptions(resolvedProject.resolvedOptions, resolvedOptions);
}
if (task) resolvedProject.task = task;
return resolvedProject;
}
/**
* @param {string} projectSpec
* @param {ResolvedProjectOptions} resolvedOptions
* @param {ParsedCommandLine} [referer]
* @param {Task} [task]
*/
function makeProject(projectSpec, resolvedOptions, referer, task) {
const resolvedProject = prepareProject(projectSpec, resolvedOptions, referer, task);
if (!resolvedProject.projectTaskCreated || resolvedProject.task) {
createProjectTask(resolvedProject);
}
return resolvedProject;
}
/**
* @param {string} projectSpec
* @param {ResolvedCleanOptions} resolvedOptions
* @param {ParsedCommandLine} [referer]
*/
function makeClean(projectSpec, resolvedOptions, referer) {
const projects = getProjects(resolvedOptions);
const resolvedProjectSpec = resolveProjectSpec(projectSpec, referer, projects);
const resolvedProject = projects.get(resolvedProjectSpec);
if (!resolvedProject) throw new PluginError("clean", `Project not found: '${projectSpec}'. Add project via 'project()' first.`);
if (!resolvedProject.cleanTaskCreated) {
createCleanTask(resolvedProject);
}
return "clean:" + resolvedProject.projectName;
}
/**
* @param {ResolvedProjectOptions | ResolvedCleanOptions} resolvedOptions
*/
function getProjects(resolvedOptions) {
let projects = typescriptProjects.get(resolvedOptions.typescript);
if (!projects) typescriptProjects.set(resolvedOptions.typescript, projects = new Map());
return projects;
}
/**
* @param {string} resolvedProjectSpec
* @param {ResolvedProjectOptions} resolvedOptions
*/
function getProjectName(resolvedProjectSpec, resolvedOptions) {
let projectName = path.relative(process.cwd(), resolvedProjectSpec);
if (resolvedOptions.typescript !== resolveTypeScript("default").typescript) {
projectName += `@${isPath(resolvedOptions.typescript) ? path.relative(process.cwd(), resolvedOptions.typescript) : resolvedOptions.typescript}`;
}
return normalizeSlashes(projectName);
}
/** @type {FormatDiagnosticsHost} */
const formatDiagnosticsHost = {
getCanonicalFileName: fileName => fileName,
getCurrentDirectory: () => process.cwd(),
getNewLine: () => ts.sys.newLine
};
/** @type {ParseConfigFileHost} */
const parseConfigFileHost = {
useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
fileExists: fileName => ts.sys.fileExists(fileName),
readFile: fileName => ts.sys.readFile(fileName),
getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
getCurrentDirectory: () => process.cwd(),
readDirectory: (rootDir, extensions, exclude, include, depth) => ts.sys.readDirectory(rootDir, extensions, exclude, include, depth),
onUnRecoverableConfigFileDiagnostic: diagnostic => {
log.warn(ts.formatDiagnosticsWithColorAndContext([diagnostic], formatDiagnosticsHost));
}
onUnRecoverableConfigFileDiagnostic: diagnostic => reportDiagnostics([diagnostic])
};
/**
* @param {string} projectSpec
* @param {ResolvedProjectOptions} resolvedOptions
* @param {ParsedCommandLine} [referer]
* @param {string} [cwd]
* @returns {ParseConfigFileHost}
*/
function resolveProject(projectSpec, resolvedOptions, referer) {
const projects = getProjects(resolvedOptions);
const resolvedProjectSpec = resolveProjectSpec(projectSpec, referer, projects);
let resolvedProject = projects.get(resolvedProjectSpec);
if (!resolvedProject) {
const projectName = getProjectName(resolvedProjectSpec, resolvedOptions);
resolvedProject = {
resolvedProjectSpec,
projectName,
taskName: "project:" + projectName,
parsedProject: undefined,
resolvedOptions,
destPath: undefined,
projectTaskCreated: false,
cleanTaskCreated: false,
task: undefined,
projectTask: undefined
function getParseConfigFileHost(cwd) {
if (!cwd || cwd === process.cwd()) return parseConfigFileHost;
return {
useCaseSensitiveFileNames: parseConfigFileHost.useCaseSensitiveFileNames,
fileExists: parseConfigFileHost.fileExists,
readFile: parseConfigFileHost.readFile,
getCurrentDirectory: () => cwd,
readDirectory: parseConfigFileHost.readDirectory,
onUnRecoverableConfigFileDiagnostic: diagnostic => reportDiagnostics([diagnostic], { cwd })
};
}
/**
* @param {ResolvedProjectSpec} projectSpec
* @param {ResolvedPathOptions} paths
* @returns {ProjectGraph}
*
* @typedef ProjectGraph
* @property {ResolvedProjectSpec} projectSpec The fully qualified path to the tsconfig.json of the project
* @property {UnqualifiedProjectName} projectName The relative project name, excluding any TypeScript suffix.
* @property {string} projectDirectory The fully qualified path to the project directory.
* @property {ParsedCommandLine} project The parsed tsconfig.json file.
* @property {ProjectGraphReference[]} references An array of project references.
* @property {Map<ResolvedTypeScriptSpec, ProjectGraphConfiguration>} configurations TypeScript-specific configurations for the project.
* @property {boolean} cleanTaskCreated A value indicating whether a `clean:` task has been created for this project (not dependent on TypeScript version).
*
* @typedef ProjectGraphReference
* @property {ProjectGraph} source The referring project.
* @property {ProjectGraph} target The referenced project.
*/
function getOrCreateProjectGraph(projectSpec, paths) {
let projectGraph = projectGraphCache.get(projectSpec);
if (!projectGraph) {
const project = ts.getParsedCommandLineOfConfigFile(projectSpec, {}, getParseConfigFileHost(paths.cwd));
projectGraph = {
projectSpec,
projectName: getUnqualifiedProjectName(projectSpec, paths),
projectDirectory: path.dirname(projectSpec),
project,
references: [],
configurations: new Map(),
cleanTaskCreated: false
};
if (!resolvedOptions.defer) {
getParsedProject(resolvedProject);
getDestPath(resolvedProject);
projectGraphCache.set(projectSpec, projectGraph);
if (project.projectReferences) {
for (const projectReference of project.projectReferences) {
const resolvedProjectSpec = resolveProjectSpec(projectReference.path, paths, projectGraph);
const referencedProject = getOrCreateProjectGraph(resolvedProjectSpec, paths);
const reference = { source: projectGraph, target: referencedProject };
projectGraph.references.push(reference);
}
}
projects.set(resolvedProjectSpec, resolvedProject);
}
return resolvedProject;
return projectGraph;
}
/**
* @param {ResolvedProject} resolvedProject
* @param {ProjectGraph} projectGraph
* @param {ResolvedProjectOptions} resolvedOptions
* @returns {ProjectGraphConfiguration}
*
* @typedef ProjectGraphConfiguration
* @property {QualifiedProjectName} projectName
* @property {ResolvedProjectOptions} resolvedOptions
* @property {boolean} compileTaskCreated
*/
function getParsedProject(resolvedProject) {
if (!resolvedProject.parsedProject) {
resolvedProject.parsedProject = ts.getParsedCommandLineOfConfigFile(
resolvedProject.resolvedProjectSpec,
resolvedProject.resolvedOptions.compilerOptions,
parseConfigFileHost);
function getOrCreateProjectGraphConfiguration(projectGraph, resolvedOptions) {
let projectGraphConfig = projectGraph.configurations.get(resolvedOptions.typescript.typescript);
if (!projectGraphConfig) {
projectGraphConfig = {
projectName: getQualifiedProjectName(projectGraph.projectName, resolvedOptions.paths, resolvedOptions.typescript),
resolvedOptions,
compileTaskCreated: false
};
projectGraph.configurations.set(resolvedOptions.typescript.typescript, projectGraphConfig);
}
return resolvedProject.parsedProject;
}
/**
* @param {ResolvedProject} resolvedProject
*/
function getDestPath(resolvedProject) {
if (!resolvedProject.destPath) {
resolvedProject.destPath = resolveDestPath(getParsedProject(resolvedProject));
}
return resolvedProject.destPath;
return projectGraphConfig;
}
/**
* @param {string} projectSpec
* @param {ParsedCommandLine} [referer]
* @param {Map<string, ResolvedProject>} [projects]
* @param {ResolvedPathOptions} paths
* @param {ProjectGraph | undefined} referrer
* @returns {ResolvedProjectSpec}
*
* @typedef {string & {_isResolvedProjectSpec: never}} ResolvedProjectSpec
*/
function resolveProjectSpec(projectSpec, referer, projects) {
projectSpec = referer ? path.resolve(path.dirname(referer.options.configFilePath), projectSpec) : path.resolve(projectSpec);
projectSpec = normalizeSlashes(projectSpec);
// quick checks for existing project in cache
if (projects && projects.has(projectSpec)) return projectSpec;
const configSpec = normalizeSlashes(path.join(projectSpec, "tsconfig.json"));
if (projects && projects.has(configSpec)) return configSpec;
// slower checks against file system
if (fs.existsSync(projectSpec) && fs.statSync(projectSpec).isDirectory()) {
return configSpec;
}
return projectSpec;
function resolveProjectSpec(projectSpec, paths, referrer) {
projectSpec = path.resolve(paths.cwd, referrer && referrer.projectDirectory || "", projectSpec);
if (!ts.sys.fileExists(projectSpec)) projectSpec = path.join(projectSpec, "tsconfig.json");
return /**@type {ResolvedProjectSpec}*/(normalizeSlashes(projectSpec));
}
/**
* @param {ParsedCommandLine} parsedProject
* @param {ProjectGraph} projectGraph
* @param {ResolvedPathOptions} paths
*/
function resolveDestPath(parsedProject) {
function resolveDestPath(projectGraph, paths) {
/** @type {string} */
let destPath = path.dirname(parsedProject.options.configFilePath);
if (parsedProject.options.outDir) {
destPath = path.resolve(destPath, parsedProject.options.outDir);
let destPath = projectGraph.projectDirectory;
if (projectGraph.project.options.outDir) {
destPath = path.resolve(paths.cwd, destPath, projectGraph.project.options.outDir);
}
else if (parsedProject.options.outFile || parsedProject.options.out) {
destPath = path.dirname(path.resolve(destPath, parsedProject.options.outFile || parsedProject.options.out));
else if (projectGraph.project.options.outFile || projectGraph.project.options.out) {
destPath = path.dirname(path.resolve(paths.cwd, destPath, projectGraph.project.options.outFile || projectGraph.project.options.out));
}
return normalizeSlashes(path.relative(process.cwd(), destPath));
return normalizeSlashes(path.relative(paths.base, destPath));
}
/**
* @param {ResolvedProject} resolvedProject
*/
function createProjectTask(resolvedProject) {
const { parsedProject, resolvedOptions, taskName } = resolvedProject;
const deps = makeProjectDeps(parsedProject, resolvedOptions);
gulp.task(taskName, /*help*/ false, (resolvedOptions.deps || []).concat(deps), getProjectTaskFunction(resolvedProject));
resolvedProject.projectTaskCreated = true;
}
/**
* @param {ResolvedProject} resolvedProject
*/
function getProjectTaskFunction(resolvedProject) {
if (!resolvedProject.projectTask) {
resolvedProject.projectTask = () => (resolvedProject.task || exports.defaultTask)(
getParsedProject(resolvedProject),
getDestPath(resolvedProject),
getResolvedTaskConfiguration(resolvedProject.resolvedOptions));
}
return resolvedProject.projectTask;
}
/**
* @param {ParsedCommandLine | undefined} parsedProject
* @param {ProjectGraph} projectGraph
* @param {ResolvedProjectOptions} resolvedOptions
*/
function makeProjectDeps(parsedProject, resolvedOptions) {
/** @type {string[]} */
const deps = [];
if (parsedProject && parsedProject.projectReferences) {
for (const projectReference of parsedProject.projectReferences) {
const projectReferenceOptions = resolveProjectOptions({
typescript: resolvedOptions.typescript,
deps: resolvedOptions.deps
});
deps.push(makeProject(projectReference.path, projectReferenceOptions, parsedProject).taskName);
}
function ensureCompileTask(projectGraph, resolvedOptions) {
const projectGraphConfig = getOrCreateProjectGraphConfiguration(projectGraph, resolvedOptions);
projectGraphConfig.resolvedOptions = resolvedOptions = mergeProjectOptions(resolvedOptions, resolvedOptions);
if (!projectGraphConfig.compileTaskCreated) {
const deps = makeProjectReferenceCompileTasks(projectGraph, resolvedOptions.typescript, resolvedOptions.paths);
compilationGulp.task(compileTaskName(projectGraph, resolvedOptions.typescript), deps, () => {
const destPath = resolveDestPath(projectGraph, resolvedOptions.paths);
const { sourceMap, inlineSourceMap, inlineSources = false, sourceRoot, declarationMap } = projectGraph.project.options;
const configFilePath = projectGraph.project.options.configFilePath;
const sourceMapPath = inlineSourceMap ? undefined : ".";
const sourceMapOptions = { includeContent: inlineSources, sourceRoot, destPath };
const project = resolvedOptions.inProcess
? tsc.createProject(configFilePath, { typescript: require(resolvedOptions.typescript.typescript) })
: tsc_oop.createProject(configFilePath, {}, { typescript: resolvedOptions.typescript.typescript });
const stream = project.src()
.pipe(gulpif(!resolvedOptions.force, upToDate(projectGraph.project, { verbose: resolvedOptions.verbose })))
.pipe(gulpif(sourceMap || inlineSourceMap, sourcemaps.init()))
.pipe(project());
const js = stream.js
.pipe(evaluateHook(resolvedOptions.js))
.pipe(gulpif(sourceMap || inlineSourceMap, sourcemaps.write(sourceMapPath, sourceMapOptions)));
const dts = stream.dts
.pipe(evaluateHook(resolvedOptions.dts))
.pipe(gulpif(declarationMap, sourcemaps.write(sourceMapPath, sourceMapOptions)));
return merge2([js, dts])
.pipe(gulp.dest(destPath));
});
projectGraphConfig.compileTaskCreated = true;
}
return deps;
return projectGraph;
}
/**
* @param {ResolvedProject} resolvedProject
* @param {ProjectGraph} projectGraph
* @param {ResolvedTypeScript} typescript
* @param {ResolvedPathOptions} paths
*/
function createCleanTask(resolvedProject) {
const { parsedProject, resolvedOptions, projectName } = resolvedProject;
const deps = makeCleanDeps(parsedProject, resolvedOptions);
gulp.task("clean:" + projectName, /*help*/ false, deps, () => {
let outputs = ts.getAllProjectOutputs(parsedProject);
if (!parsedProject.options.inlineSourceMap) {
if (parsedProject.options.sourceMap) {
outputs = outputs.concat(outputs.filter(file => /\.jsx?$/.test(file)).map(file => file + ".map"));
}
if (parsedProject.options.declarationMap) {
outputs = outputs.concat(outputs.filter(file => /\.d.ts$/.test(file)).map(file => file + ".map"));
}
}
return del(outputs);
});
resolvedProject.cleanTaskCreated = true;
function makeProjectReferenceCompileTasks(projectGraph, typescript, paths) {
return projectGraph.references.map(({target}) => compileTaskName(ensureCompileTask(target, { paths, typescript }), typescript));
}
/**
* @param {ParsedCommandLine} parsedProject
* @param {ResolvedCleanOptions} resolvedOptions
* @param {ProjectGraph} projectGraph
*/
function makeCleanDeps(parsedProject, resolvedOptions) {
/** @type {string[]} */
const deps = [];
if (parsedProject.projectReferences) {
for (const projectReference of parsedProject.projectReferences) {
const projectReferenceOptions = resolveCleanOptions({ typescript: resolvedOptions.typescript });
deps.push(makeClean(projectReference.path, projectReferenceOptions, parsedProject));
}
function ensureCleanTask(projectGraph) {
if (!projectGraph.cleanTaskCreated) {
const deps = makeProjectReferenceCleanTasks(projectGraph);
compilationGulp.task(cleanTaskName(projectGraph), deps, () => {
let outputs = ts.getAllProjectOutputs(projectGraph.project);
if (!projectGraph.project.options.inlineSourceMap) {
if (projectGraph.project.options.sourceMap) {
outputs = outputs.concat(outputs.filter(file => /\.jsx?$/.test(file)).map(file => file + ".map"));
}
if (projectGraph.project.options.declarationMap) {
outputs = outputs.concat(outputs.filter(file => /\.d.ts$/.test(file)).map(file => file + ".map"));
}
}
return del(outputs);
});
projectGraph.cleanTaskCreated = true;
}
return deps;
return projectGraph;
}
/**
* @param {ProjectGraph} projectGraph
*/
function makeProjectReferenceCleanTasks(projectGraph) {
return projectGraph.references.map(({target}) => cleanTaskName(ensureCleanTask(target)));
}
/**
* @param {ProjectGraph} projectGraph
* @param {ResolvedTypeScript} typescript
*/
function compileTaskName(projectGraph, typescript) {
return `compile:${projectGraph.configurations.get(typescript.typescript).projectName}`;
}
/**
* @param {ProjectGraph} projectGraph
*/
function cleanTaskName(projectGraph) {
return `clean:${projectGraph.projectName}`;
}
/**
@ -555,83 +554,5 @@ function isPath(moduleSpec) {
/**
* @typedef {import("../../lib/typescript").ParsedCommandLine & { options: CompilerOptions }} ParsedCommandLine
* @typedef {import("../../lib/typescript").CompilerOptions & { configFilePath?: string }} CompilerOptions
* @typedef {import("../../lib/typescript").ParseConfigFileHost} ParseConfigFileHost
* @typedef {import("../../lib/typescript").FormatDiagnosticsHost} FormatDiagnosticsHost
* @typedef {(project: ParsedCommandLine, destPath: string, options: ResolvedTaskConfiguration) => NodeJS.ReadWriteStream} Task
*
* @typedef ProjectOptions
* @property {string} [typescript] A module specifier or path (relative to gulpfile.js) to the version of TypeScript to use.
* @property {string[]} [deps] Gulp task dependencies for all tasks created for a project.
* @property {CompilerOptions} [compilerOptions] Default options to pass to the compiler.
* @property {(stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream} [js] Pipeline hook for .js file outputs.
* @property {(stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream} [dts] Pipeline hook for .d.ts file outputs.
* @property {ProjectConfiguration} [debug] Project option overrides when building a "debug" build.
* @property {ProjectConfiguration} [release] Project option overrides when building a "release" build.
* @property {boolean} [verbose] Indicates whether verbose logging is enabled.
* @property {boolean} [force] Force recompilation (no up-to-date check).
* @property {boolean} [inProcess] Indicates whether to run gulp-typescript in-process or out-of-process (default).
*
* @typedef ProjectConfiguration
* @property {CompilerOptions} [compilerOptions] Default options to pass to the compiler.
* @property {string[]} [deps] Gulp task dependencies for all tasks created for a project.
* @property {(stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream} [js] Pipeline hook for .js file outputs.
* @property {(stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream} [dts] Pipeline hook for .d.ts file outputs.
* @property {boolean} [force] Force recompilation (no up-to-date check).
* @property {boolean} [inProcess] Indicates whether to run gulp-typescript in-process or out-of-process (default).
*
* @typedef ResolvedProjectOptions
* @property {string} typescript A module specifier or path (relative to gulpfile.js) to the version of TypeScript to use.
* @property {CompilerOptions} compilerOptions Default options to pass to the compiler.
* @property {string[] | undefined} deps Gulp task dependencies for all tasks created for a project.
* @property {(stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream | undefined} js Pipeline hook for .js file outputs.
* @property {(stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream | undefined} dts Pipeline hook for .d.ts file outputs.
* @property {ResolvedProjectConfiguration} debug Project option overrides when building a "debug" build.
* @property {ResolvedProjectConfiguration} release Project option overrides when building a "release" build.
* @property {boolean} verbose Indicates whether verbose logging is enabled.
* @property {boolean} force Force recompilation (no up-to-date check).
* @property {boolean} inProcess Indicates whether to run gulp-typescript in-process or out-of-process (default).
* @property {boolean} defer Defer loading the project until later (not supported for projects with project references).
*
* @typedef ResolvedProjectConfiguration
* @property {CompilerOptions} compilerOptions Project configuration overrides to pass to the compiler.
* @property {string[] | undefined} deps Gulp task dependencies for all tasks created for a project.
* @property {(stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream | undefined} js Pipeline hook for .js file outputs.
* @property {(stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream | undefined} dts Pipeline hook for .d.ts file outputs.
* @property {boolean | undefined} force Force recompilation (no up-to-date check).
* @property {boolean | undefined} inProcess Indicates whether to run gulp-typescript in-process or out-of-process (default).
*
* @typedef ResolvedTaskConfiguration
* @property {string} typescript
* @property {CompilerOptions} compilerOptions Project configuration overrides to pass to the compiler.
* @property {string[] | undefined} deps Gulp task dependencies for all tasks created for a project.
* @property {(stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream | undefined} js Pipeline hook for .js file outputs.
* @property {(stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream | undefined} dts Pipeline hook for .d.ts file outputs.
* @property {boolean} verbose Indicates whether verbose logging is enabled.
* @property {boolean} force Force recompilation (no up-to-date check).
* @property {boolean} inProcess Indicates whether to run gulp-typescript in-process or out-of-process (default).
*
* @typedef ResolvedProject
* @property {string} resolvedProjectSpec
* @property {string} projectName
* @property {string} taskName
* @property {ParsedCommandLine | undefined} parsedProject
* @property {string | undefined} destPath
* @property {ResolvedProjectOptions} resolvedOptions
* @property {Task | undefined} task
* @property {(() => NodeJS.ReadWriteStream) | undefined} projectTask
* @property {boolean} projectTaskCreated
* @property {boolean} cleanTaskCreated
*
* @typedef CleanOptions
* @property {string} [typescript] A module specifier or path (relative to gulpfile.js) to the version of TypeScript to use.
*
* @typedef ResolvedCleanOptions
* @property {string | undefined} typescript A module specifier or path (relative to gulpfile.js) to the version of TypeScript to use.
*
* @typedef FlattenOptions
* @property {CompilerOptions} [compilerOptions]
* @property {string} [base]
* @property {boolean} [force]
*/
void 0;
void 0;

View file

@ -3,7 +3,7 @@ const path = require("path");
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
const ts = require("../../lib/typescript");
const { Duplex } = require("stream");
const { addColor, color } = require("./colors");
const chalk = require("./chalk");
const Vinyl = require("vinyl");
/**
@ -86,7 +86,7 @@ function normalizeSlashes(file) {
* @private
*/
function fileName(file) {
return addColor(normalizeSlashes(path.relative(process.cwd(), path.resolve(file))), color.cyan);
return chalk.cyan(normalizeSlashes(path.relative(process.cwd(), path.resolve(file))));
}
/**

View file

@ -1016,12 +1016,6 @@ namespace ts {
* Gets the UpToDateStatus for a project
*/
export function getUpToDateStatus(host: UpToDateHost, project: ParsedCommandLine | undefined): UpToDateStatus {
if (project === undefined) {
return {
type: UpToDateStatusType.Unbuildable, reason: "File deleted mid-build"
};
}
if (project === undefined) {
return { type: UpToDateStatusType.Unbuildable, reason: "File deleted mid-build" };
}