Merge pull request #17468 from RyanCavanaugh/newTypesMap

Types Map
This commit is contained in:
Ryan Cavanaugh 2017-08-22 14:46:26 -07:00 committed by GitHub
commit 15e15ab84d
14 changed files with 646 additions and 41 deletions

View File

@ -463,10 +463,11 @@ gulp.task(serverFile, /*help*/ false, [servicesFile, typingsInstallerJs, cancell
.pipe(gulp.dest("src/server"));
});
const typesMapJson = path.join(builtLocalDirectory, "typesMap.json");
const tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
const tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");
gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile], (done) => {
gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile, typesMapJson], (done) => {
const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({}, /*useBuiltCompiler*/ true));
const {js, dts}: { js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream } = serverLibraryProject.src()
.pipe(sourcemaps.init())
@ -485,6 +486,15 @@ gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile], (done) => {
]);
});
gulp.task(typesMapJson, /*help*/ false, [], () => {
return gulp.src("src/server/typesMap.json")
.pipe(insert.transform((contents, file) => {
JSON.parse(contents);
return contents;
}))
.pipe(gulp.dest(builtLocalDirectory));
});
gulp.task("lssl", "Builds language service server library", [tsserverLibraryFile]);
gulp.task("local", "Builds the full compiler and services", [builtLocalCompiler, servicesFile, serverFile, builtGeneratedDiagnosticMessagesJSON, tsserverLibraryFile]);
gulp.task("tsc", "Builds only the compiler", [builtLocalCompiler]);

View File

@ -88,6 +88,8 @@ var watchGuardSources = filesFromConfig(path.join(serverDirectory, "watchGuard/t
var serverSources = filesFromConfig(path.join(serverDirectory, "tsconfig.json"))
var languageServiceLibrarySources = filesFromConfig(path.join(serverDirectory, "tsconfig.library.json"));
var typesMapOutputPath = path.join(builtLocalDirectory, 'typesMap.json');
var harnessCoreSources = [
"harness.ts",
"virtualFileSystem.ts",
@ -423,6 +425,7 @@ var buildProtocolTs = path.join(scriptsDirectory, "buildProtocol.ts");
var buildProtocolJs = path.join(scriptsDirectory, "buildProtocol.js");
var buildProtocolDts = path.join(builtLocalDirectory, "protocol.d.ts");
var typescriptServicesDts = path.join(builtLocalDirectory, "typescriptServices.d.ts");
var typesMapJson = path.join(builtLocalDirectory, "typesMap.json");
file(buildProtocolTs);
@ -587,6 +590,16 @@ var serverFile = path.join(builtLocalDirectory, "tsserver.js");
compileFile(serverFile, serverSources, [builtLocalDirectory, copyright, cancellationTokenFile, typingsInstallerFile, watchGuardFile].concat(serverSources).concat(servicesSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"], preserveConstEnums: true, lib: "es6" });
var tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
var tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");
file(typesMapOutputPath, function() {
var content = fs.readFileSync(path.join(serverDirectory, 'typesMap.json'));
// Validate that it's valid JSON
try {
JSON.parse(content);
} catch (e) {
console.log("Parse error in typesMap.json: " + e);
}
fs.writeFileSync(typesMapOutputPath, content);
});
compileFile(
tsserverLibraryFile,
languageServiceLibrarySources,
@ -609,7 +622,7 @@ compileFile(
// Local target to build the language service server library
desc("Builds language service server library");
task("lssl", [tsserverLibraryFile, tsserverLibraryDefinitionFile]);
task("lssl", [tsserverLibraryFile, tsserverLibraryDefinitionFile, typesMapOutputPath]);
desc("Emit the start of the build fold");
task("build-fold-start", [], function () {
@ -638,7 +651,6 @@ task("release", function () {
// Set the default task to "local"
task("default", ["local"]);
// Cleans the built directory
desc("Cleans the compiler output, declare files, and tests");
task("clean", function () {

View File

@ -93,5 +93,8 @@
"fs": false,
"os": false,
"path": false
},
"dependencies": {
"browser-resolve": "^1.11.2"
}
}

View File

@ -18,14 +18,28 @@ namespace ts.projectSystem {
})
};
const customSafeList = {
path: <Path>"/typeMapList.json",
content: JSON.stringify({
"quack": {
"match": "/duckquack-(\\d+)\\.min\\.js",
"types": ["duck-types"]
export const customTypesMap = {
path: <Path>"/typesMap.json",
content: `{
"typesMap": {
"jquery": {
"match": "jquery(-(\\\\.?\\\\d+)+)?(\\\\.intellisense)?(\\\\.min)?\\\\.js$",
"types": ["jquery"]
},
"quack": {
"match": "/duckquack-(\\\\d+)\\\\.min\\\\.js",
"types": ["duck-types"]
}
},
})
"simpleMap": {
"Bacon": "baconjs",
"bliss": "blissfuljs",
"commander": "commander",
"cordova": "cordova",
"react": "react",
"lodash": "lodash"
}
}`
};
export interface PostExecAction {
@ -59,7 +73,7 @@ namespace ts.projectSystem {
installTypingHost: server.ServerHost,
readonly typesRegistry = createMap<void>(),
log?: TI.Log) {
super(installTypingHost, globalTypingsCacheLocation, safeList.path, throttleLimit, log);
super(installTypingHost, globalTypingsCacheLocation, safeList.path, customTypesMap.path, throttleLimit, log);
}
protected postExecActions: PostExecAction[] = [];
@ -229,6 +243,7 @@ namespace ts.projectSystem {
useSingleInferredProject,
useInferredProjectPerProjectRoot: false,
typingsInstaller,
typesMapLocation: customTypesMap.path,
eventHandler,
...opts
});
@ -1491,9 +1506,8 @@ namespace ts.projectSystem {
path: "/lib/duckquack-3.min.js",
content: "whoa do @@ not parse me ok thanks!!!"
};
const host = createServerHost([customSafeList, file1, office]);
const host = createServerHost([file1, office, customTypesMap]);
const projectService = createProjectService(host);
projectService.loadSafeList(customSafeList.path);
try {
projectService.openExternalProject({ projectFileName: "project", options: {}, rootFiles: toExternalFiles([file1.path, office.path]) });
const proj = projectService.externalProjects[0];

View File

@ -322,7 +322,7 @@ namespace ts.projectSystem {
content: "declare const lodash: { x: number }"
};
const host = createServerHost([file1, file2, file3]);
const host = createServerHost([file1, file2, file3, customTypesMap]);
const installer = new (class extends Installer {
constructor() {
super(host, { typesRegistry: createTypesRegistry("lodash", "react") });
@ -445,7 +445,7 @@ namespace ts.projectSystem {
content: "declare const moment: { x: number }"
};
const host = createServerHost([file1, file2, file3, packageJson]);
const host = createServerHost([file1, file2, file3, packageJson, customTypesMap]);
const installer = new (class extends Installer {
constructor() {
super(host, { typesRegistry: createTypesRegistry("jquery", "commander", "moment", "express") });
@ -521,7 +521,7 @@ namespace ts.projectSystem {
};
const typingFiles = [commander, express, jquery, moment, lodash];
const host = createServerHost([lodashJs, commanderJs, file3, packageJson]);
const host = createServerHost([lodashJs, commanderJs, file3, packageJson, customTypesMap]);
const installer = new (class extends Installer {
constructor() {
super(host, { throttleLimit: 3, typesRegistry: createTypesRegistry("commander", "express", "jquery", "moment", "lodash") });
@ -600,7 +600,7 @@ namespace ts.projectSystem {
typings: typingsName("gulp")
};
const host = createServerHost([lodashJs, commanderJs, file3]);
const host = createServerHost([lodashJs, commanderJs, file3, customTypesMap]);
const installer = new (class extends Installer {
constructor() {
super(host, { throttleLimit: 1, typesRegistry: createTypesRegistry("commander", "jquery", "lodash", "cordova", "gulp", "grunt") });

View File

@ -109,6 +109,11 @@ namespace ts.server {
"smart": IndentStyle.Smart
});
export interface TypesMapFile {
typesMap: SafeList;
simpleMap: string[];
}
/**
* How to understand this block:
* * The 'match' property is a regexp that matches a filename.
@ -330,6 +335,7 @@ namespace ts.server {
globalPlugins?: ReadonlyArray<string>;
pluginProbeLocations?: ReadonlyArray<string>;
allowLocalPluginLoads?: boolean;
typesMapLocation?: string;
}
export class ProjectService {
@ -391,6 +397,7 @@ namespace ts.server {
public readonly globalPlugins: ReadonlyArray<string>;
public readonly pluginProbeLocations: ReadonlyArray<string>;
public readonly allowLocalPluginLoads: boolean;
public readonly typesMapLocation: string | undefined;
/** Tracks projects that we have already sent telemetry for. */
private readonly seenProjects = createMap<true>();
@ -407,6 +414,7 @@ namespace ts.server {
this.globalPlugins = opts.globalPlugins || emptyArray;
this.pluginProbeLocations = opts.pluginProbeLocations || emptyArray;
this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads;
this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.host.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation;
Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService");
@ -414,6 +422,10 @@ namespace ts.server {
this.directoryWatchers = new DirectoryWatchers(this);
this.throttledOperations = new ThrottledOperations(this.host);
if (opts.typesMapLocation) {
this.loadTypesMap();
}
this.typingsInstaller.attach(this);
this.typingsCache = new TypingsCache(this.typingsInstaller);
@ -451,6 +463,27 @@ namespace ts.server {
this.eventHandler(event);
}
private loadTypesMap() {
try {
const fileContent = this.host.readFile(this.typesMapLocation);
if (fileContent === undefined) {
this.logger.info(`Provided types map file "${this.typesMapLocation}" doesn't exist`);
return;
}
const raw: TypesMapFile = JSON.parse(fileContent);
// Parse the regexps
for (const k of Object.keys(raw.typesMap)) {
raw.typesMap[k].match = new RegExp(raw.typesMap[k].match as {} as string, "i");
}
// raw is now fixed and ready
this.safelist = raw.typesMap;
}
catch (e) {
this.logger.info(`Error loading types map: ${e}`);
this.safelist = defaultTypeSafeList;
}
}
updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void {
const project = this.findProject(response.projectName);
if (!project) {
@ -1712,23 +1745,14 @@ namespace ts.server {
this.safelist = defaultTypeSafeList;
}
loadSafeList(fileName: string): void {
const raw: SafeList = JSON.parse(this.host.readFile(fileName, "utf-8"));
// Parse the regexps
for (const k of Object.keys(raw)) {
raw[k].match = new RegExp(raw[k].match as {} as string, "i");
}
// raw is now fixed and ready
this.safelist = raw;
}
applySafeList(proj: protocol.ExternalProject): void {
applySafeList(proj: protocol.ExternalProject): NormalizedPath[] {
const { rootFiles, typeAcquisition } = proj;
const types = (typeAcquisition && typeAcquisition.include) || [];
const excludeRules: string[] = [];
const normalizedNames = rootFiles.map(f => normalizeSlashes(f.fileName));
const normalizedNames = rootFiles.map(f => normalizeSlashes(f.fileName)) as NormalizedPath[];
const excludedFiles: NormalizedPath[] = [];
for (const name of Object.keys(this.safelist)) {
const rule = this.safelist[name];
@ -1787,7 +1811,17 @@ namespace ts.server {
}
const excludeRegexes = excludeRules.map(e => new RegExp(e, "i"));
proj.rootFiles = proj.rootFiles.filter((_file, index) => !excludeRegexes.some(re => re.test(normalizedNames[index])));
const filesToKeep: ts.server.protocol.ExternalFile[] = [];
for (let i = 0; i < proj.rootFiles.length; i++) {
if (excludeRegexes.some(re => re.test(normalizedNames[i]))) {
excludedFiles.push(normalizedNames[i]);
}
else {
filesToKeep.push(proj.rootFiles[i]);
}
}
proj.rootFiles = filesToKeep;
return excludedFiles;
}
openExternalProject(proj: protocol.ExternalProject, suppressRefreshOfInferredProjects = false): void {
@ -1798,7 +1832,7 @@ namespace ts.server {
proj.typeAcquisition = typeAcquisition;
}
this.applySafeList(proj);
const excludedFiles = this.applySafeList(proj);
let tsConfigFiles: NormalizedPath[];
const rootFiles: protocol.ExternalFile[] = [];
@ -1822,6 +1856,7 @@ namespace ts.server {
const externalProject = this.findExternalProjectByProjectName(proj.projectFileName);
let exisingConfigFiles: string[];
if (externalProject) {
externalProject.excludedFiles = excludedFiles;
if (!tsConfigFiles) {
const compilerOptions = convertCompilerOptions(proj.options);
if (this.exceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader)) {
@ -1891,7 +1926,8 @@ namespace ts.server {
else {
// no config files - remove the item from the collection
this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName);
this.createAndAddExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition);
const newProj = this.createAndAddExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition);
newProj.excludedFiles = excludedFiles;
}
if (!suppressRefreshOfInferredProjects) {
this.refreshInferredProjects();

View File

@ -376,6 +376,10 @@ namespace ts.server {
return this.getLanguageService().getEmitOutput(info.fileName, emitOnlyDtsFiles);
}
getExcludedFiles(): ReadonlyArray<NormalizedPath> {
return emptyArray;
}
getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean) {
if (!this.program) {
return [];
@ -1166,6 +1170,7 @@ namespace ts.server {
* These are created only if a host explicitly calls `openExternalProject`.
*/
export class ExternalProject extends Project {
excludedFiles: ReadonlyArray<NormalizedPath> = [];
private typeAcquisition: TypeAcquisition;
constructor(public externalProjectName: string,
projectService: ProjectService,
@ -1175,6 +1180,11 @@ namespace ts.server {
public compileOnSaveEnabled: boolean,
private readonly projectFilePath?: string) {
super(externalProjectName, ProjectKind.External, projectService, documentRegistry, /*hasExplicitListOfFiles*/ true, languageServiceEnabled, compilerOptions, compileOnSaveEnabled);
}
getExcludedFiles() {
return this.excludedFiles;
}
getProjectRootPath() {

View File

@ -14,6 +14,7 @@ namespace ts.server {
globalTypingsCacheLocation: string;
logger: Logger;
typingSafeListLocation: string;
typesMapLocation: string | undefined;
npmLocation: string | undefined;
telemetryEnabled: boolean;
globalPlugins: ReadonlyArray<string>;
@ -250,6 +251,7 @@ namespace ts.server {
eventPort: number,
readonly globalTypingsCacheLocation: string,
readonly typingSafeListLocation: string,
readonly typesMapLocation: string,
private readonly npmLocation: string | undefined,
private newLine: string) {
this.throttledOperations = new ThrottledOperations(host);
@ -295,6 +297,9 @@ namespace ts.server {
if (this.typingSafeListLocation) {
args.push(Arguments.TypingSafeListLocation, this.typingSafeListLocation);
}
if (this.typesMapLocation) {
args.push(Arguments.TypesMapLocation, this.typesMapLocation);
}
if (this.npmLocation) {
args.push(Arguments.NpmLocation, this.npmLocation);
}
@ -408,10 +413,10 @@ namespace ts.server {
class IOSession extends Session {
constructor(options: IOSessionOptions) {
const { host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, npmLocation, canUseEvents } = options;
const { host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, canUseEvents } = options;
const typingsInstaller = disableAutomaticTypingAcquisition
? undefined
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, npmLocation, host.newLine);
: new NodeTypingsInstaller(telemetryEnabled, logger, host, installerEventPort, globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, host.newLine);
super({
host,
@ -768,6 +773,7 @@ namespace ts.server {
setStackTraceLimit();
const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation);
const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(sys.getExecutingFilePath(), "../typesMap.json");
const npmLocation = findArgument(Arguments.NpmLocation);
function parseStringArray(argName: string): ReadonlyArray<string> {
@ -797,6 +803,7 @@ namespace ts.server {
disableAutomaticTypingAcquisition,
globalTypingsCacheLocation: getGlobalTypingsCacheLocation(),
typingSafeListLocation,
typesMapLocation,
npmLocation,
telemetryEnabled,
logger,

View File

@ -12,6 +12,7 @@ namespace ts.server {
export const LogFile = "--logFile";
export const EnableTelemetry = "--enableTelemetry";
export const TypingSafeListLocation = "--typingSafeListLocation";
export const TypesMapLocation = "--typesMapLocation";
/**
* This argument specifies the location of the NPM executable.
* typingsInstaller will run the command with `${npmLocation} install ...`.

487
src/server/typesMap.json Normal file
View File

@ -0,0 +1,487 @@
{
"typesMap": {
"jquery": {
"match": "jquery(-(\\.?\\d+)+)?(\\.intellisense)?(\\.min)?\\.js$",
"types": ["jquery"]
},
"WinJS": {
"match": "^(.*\\/winjs-[.\\d]+)\\/js\\/base\\.js$",
"exclude": [["^", 1, "/.*"]],
"types": ["winjs"]
},
"Kendo": {
"match": "^(.*\\/kendo)\\/kendo\\.all\\.min\\.js$",
"exclude": [["^", 1, "/.*"]],
"types": ["kendo-ui"]
},
"Office Nuget": {
"match": "^(.*\\/office\\/1)\\/excel-\\d+\\.debug\\.js$",
"exclude": [["^", 1, "/.*"]],
"types": ["office"]
},
"Minified files": {
"match": "^(.+\\.min\\.js)$",
"exclude": [["^", 1, "$"]]
}
},
"simpleMap": {
"accounting": "accounting",
"ace.js": "ace",
"ag-grid": "ag-grid",
"alertify": "alertify",
"alt": "alt",
"amcharts.js": "amcharts",
"amplify": "amplifyjs",
"angular": "angular",
"angular-bootstrap-lightbox": "angular-bootstrap-lightbox",
"angular-cookie": "angular-cookie",
"angular-file-upload": "angular-file-upload",
"angularfire": "angularfire",
"angular-gettext": "angular-gettext",
"angular-google-analytics": "angular-google-analytics",
"angular-local-storage": "angular-local-storage",
"angularLocalStorage": "angularLocalStorage",
"angular-scroll": "angular-scroll",
"angular-spinner": "angular-spinner",
"angular-strap": "angular-strap",
"angulartics": "angulartics",
"angular-toastr": "angular-toastr",
"angular-translate": "angular-translate",
"angular-ui-router": "angular-ui-router",
"angular-ui-tree": "angular-ui-tree",
"angular-wizard": "angular-wizard",
"async": "async",
"atmosphere": "atmosphere",
"aws-sdk": "aws-sdk",
"aws-sdk-js": "aws-sdk",
"axios": "axios",
"backbone": "backbone",
"backbone.layoutmanager": "backbone.layoutmanager",
"backbone.paginator": "backbone.paginator",
"backbone.radio": "backbone.radio",
"backbone-associations": "backbone-associations",
"backbone-relational": "backbone-relational",
"backgrid": "backgrid",
"Bacon": "baconjs",
"benchmark": "benchmark",
"blazy": "blazy",
"bliss": "blissfuljs",
"bluebird": "bluebird",
"body-parser": "body-parser",
"bootbox": "bootbox",
"bootstrap": "bootstrap",
"bootstrap-editable": "x-editable",
"bootstrap-maxlength": "bootstrap-maxlength",
"bootstrap-notify": "bootstrap-notify",
"bootstrap-slider": "bootstrap-slider",
"bootstrap-switch": "bootstrap-switch",
"bowser": "bowser",
"breeze": "breeze",
"browserify": "browserify",
"bson": "bson",
"c3": "c3",
"canvasjs": "canvasjs",
"chai": "chai",
"chalk": "chalk",
"chance": "chance",
"chartist": "chartist",
"cheerio": "cheerio",
"chokidar": "chokidar",
"chosen.jquery": "chosen",
"chroma": "chroma-js",
"ckeditor.js": "ckeditor",
"cli-color": "cli-color",
"clipboard": "clipboard",
"codemirror": "codemirror",
"colors": "colors",
"commander": "commander",
"commonmark": "commonmark",
"compression": "compression",
"confidence": "confidence",
"connect": "connect",
"Control.FullScreen": "leaflet.fullscreen",
"cookie": "cookie",
"cookie-parser": "cookie-parser",
"cookies": "cookies",
"core": "core-js",
"core-js": "core-js",
"crossfilter": "crossfilter",
"crossroads": "crossroads",
"css": "css",
"ct-ui-router-extras": "ui-router-extras",
"d3": "d3",
"dagre-d3": "dagre-d3",
"dat.gui": "dat-gui",
"debug": "debug",
"deep-diff": "deep-diff",
"Dexie": "dexie",
"dialogs": "angular-dialog-service",
"dojo.js": "dojo",
"doT": "dot",
"dragula": "dragula",
"drop": "drop",
"dropbox": "dropboxjs",
"dropzone": "dropzone",
"Dts Name": "Dts Name",
"dust-core": "dustjs-linkedin",
"easeljs": "easeljs",
"ejs": "ejs",
"ember": "ember",
"envify": "envify",
"epiceditor": "epiceditor",
"es6-promise": "es6-promise",
"ES6-Promise": "es6-promise",
"es6-shim": "es6-shim",
"expect": "expect",
"express": "express",
"express-session": "express-session",
"ext-all.js": "extjs",
"extend": "extend",
"fabric": "fabricjs",
"faker": "faker",
"fastclick": "fastclick",
"favico": "favico.js",
"featherlight": "featherlight",
"FileSaver": "FileSaver",
"fingerprint": "fingerprintjs",
"fixed-data-table": "fixed-data-table",
"flickity.pkgd": "flickity",
"flight": "flight",
"flow": "flowjs",
"Flux": "flux",
"formly": "angular-formly",
"foundation": "foundation",
"fpsmeter": "fpsmeter",
"fuse": "fuse",
"generator": "yeoman-generator",
"gl-matrix": "gl-matrix",
"globalize": "globalize",
"graceful-fs": "graceful-fs",
"gridstack": "gridstack",
"gulp": "gulp",
"gulp-rename": "gulp-rename",
"gulp-uglify": "gulp-uglify",
"gulp-util": "gulp-util",
"hammer": "hammerjs",
"handlebars": "handlebars",
"hasher": "hasher",
"he": "he",
"hello.all": "hellojs",
"highcharts.js": "highcharts",
"highlight": "highlightjs",
"history": "history",
"History": "history",
"hopscotch": "hopscotch",
"hotkeys": "angular-hotkeys",
"html2canvas": "html2canvas",
"humane": "humane",
"i18next": "i18next",
"icheck": "icheck",
"impress": "impress",
"incremental-dom": "incremental-dom",
"Inquirer": "inquirer",
"insight": "insight",
"interact": "interactjs",
"intercom": "intercomjs",
"intro": "intro.js",
"ion.rangeSlider": "ion.rangeSlider",
"ionic": "ionic",
"is": "is_js",
"iscroll": "iscroll",
"jade": "jade",
"jasmine": "jasmine",
"joint": "jointjs",
"jquery": "jquery",
"jquery.address": "jquery.address",
"jquery.are-you-sure": "jquery.are-you-sure",
"jquery.blockUI": "jquery.blockUI",
"jquery.bootstrap.wizard": "jquery.bootstrap.wizard",
"jquery.bootstrap-touchspin": "bootstrap-touchspin",
"jquery.color": "jquery.color",
"jquery.colorbox": "jquery.colorbox",
"jquery.contextMenu": "jquery.contextMenu",
"jquery.cookie": "jquery.cookie",
"jquery.customSelect": "jquery.customSelect",
"jquery.cycle.all": "jquery.cycle",
"jquery.cycle2": "jquery.cycle2",
"jquery.dataTables": "jquery.dataTables",
"jquery.dropotron": "jquery.dropotron",
"jquery.fancybox.pack.js": "fancybox",
"jquery.fancytree-all": "jquery.fancytree",
"jquery.fileupload": "jquery.fileupload",
"jquery.flot": "flot",
"jquery.form": "jquery.form",
"jquery.gridster": "jquery.gridster",
"jquery.handsontable.full": "jquery-handsontable",
"jquery.joyride": "jquery.joyride",
"jquery.jqGrid": "jqgrid",
"jquery.mmenu": "jquery.mmenu",
"jquery.mockjax": "jquery-mockjax",
"jquery.noty": "jquery.noty",
"jquery.payment": "jquery.payment",
"jquery.pjax": "jquery.pjax",
"jquery.placeholder": "jquery.placeholder",
"jquery.qrcode": "jquery.qrcode",
"jquery.qtip": "qtip2",
"jquery.raty": "raty",
"jquery.scrollTo": "jquery.scrollTo",
"jquery.signalR": "signalr",
"jquery.simplemodal": "jquery.simplemodal",
"jquery.timeago": "jquery.timeago",
"jquery.tinyscrollbar": "jquery.tinyscrollbar",
"jquery.tipsy": "jquery.tipsy",
"jquery.tooltipster": "tooltipster",
"jquery.transit": "jquery.transit",
"jquery.uniform": "jquery.uniform",
"jquery.watch": "watch",
"jquery-sortable": "jquery-sortable",
"jquery-ui": "jqueryui",
"js.cookie": "js-cookie",
"js-data": "js-data",
"js-data-angular": "js-data-angular",
"js-data-http": "js-data-http",
"jsdom": "jsdom",
"jsnlog": "jsnlog",
"json5": "json5",
"jspdf": "jspdf",
"jsrender": "jsrender",
"js-signals": "js-signals",
"jstorage": "jstorage",
"jstree": "jstree",
"js-yaml": "js-yaml",
"jszip": "jszip",
"katex": "katex",
"kefir": "kefir",
"keymaster": "keymaster",
"keypress": "keypress",
"kinetic": "kineticjs",
"knockback": "knockback",
"knockout": "knockout",
"knockout.mapping": "knockout.mapping",
"knockout.validation": "knockout.validation",
"knockout-paging": "knockout-paging",
"knockout-pre-rendered": "knockout-pre-rendered",
"ladda": "ladda",
"later": "later",
"lazy": "lazy.js",
"Leaflet.Editable": "leaflet-editable",
"leaflet.js": "leaflet",
"less": "less",
"linq": "linq",
"loading-bar": "angular-loading-bar",
"lodash": "lodash",
"log4javascript": "log4javascript",
"loglevel": "loglevel",
"lokijs": "lokijs",
"lovefield": "lovefield",
"lunr": "lunr",
"lz-string": "lz-string",
"mailcheck": "mailcheck",
"maquette": "maquette",
"marked": "marked",
"math": "mathjs",
"MathJax.js": "mathjax",
"matter": "matter-js",
"md5": "blueimp-md5",
"md5.js": "crypto-js",
"messenger": "messenger",
"method-override": "method-override",
"minimatch": "minimatch",
"minimist": "minimist",
"mithril": "mithril",
"mobile-detect": "mobile-detect",
"mocha": "mocha",
"mock-ajax": "jasmine-ajax",
"modernizr": "modernizr",
"Modernizr": "Modernizr",
"moment": "moment",
"moment-range": "moment-range",
"moment-timezone": "moment-timezone",
"mongoose": "mongoose",
"morgan": "morgan",
"mousetrap": "mousetrap",
"ms": "ms",
"mustache": "mustache",
"native.history": "history",
"nconf": "nconf",
"ncp": "ncp",
"nedb": "nedb",
"ng-cordova": "ng-cordova",
"ngDialog": "ng-dialog",
"ng-flow-standalone": "ng-flow",
"ng-grid": "ng-grid",
"ng-i18next": "ng-i18next",
"ng-table": "ng-table",
"node_redis": "redis",
"node-clone": "clone",
"node-fs-extra": "fs-extra",
"node-glob": "glob",
"Nodemailer": "nodemailer",
"node-mime": "mime",
"node-mkdirp": "mkdirp",
"node-mongodb-native": "mongodb",
"node-mysql": "mysql",
"node-open": "open",
"node-optimist": "optimist",
"node-progress": "progress",
"node-semver": "semver",
"node-tar": "tar",
"node-uuid": "node-uuid",
"node-xml2js": "xml2js",
"nopt": "nopt",
"notify": "notify",
"nouislider": "nouislider",
"npm": "npm",
"nprogress": "nprogress",
"numbro": "numbro",
"numeral": "numeraljs",
"nunjucks": "nunjucks",
"nv.d3": "nvd3",
"object-assign": "object-assign",
"oboe-browser": "oboe",
"office": "office-js",
"offline": "offline-js",
"onsenui": "onsenui",
"OpenLayers.js": "openlayers",
"openpgp": "openpgp",
"p2": "p2",
"packery.pkgd": "packery",
"page": "page",
"pako": "pako",
"papaparse": "papaparse",
"passport": "passport",
"passport-local": "passport-local",
"path": "pathjs",
"peer": "peerjs",
"peg": "pegjs",
"photoswipe": "photoswipe",
"picker.js": "pickadate",
"pikaday": "pikaday",
"pixi": "pixi.js",
"platform": "platform",
"Please": "pleasejs",
"plottable": "plottable",
"polymer": "polymer",
"postal": "postal",
"preloadjs": "preloadjs",
"progress": "progress",
"purify": "dompurify",
"purl": "purl",
"q": "q",
"qs": "qs",
"qunit": "qunit",
"ractive": "ractive",
"rangy-core": "rangy",
"raphael": "raphael",
"raven": "ravenjs",
"react": "react",
"react-bootstrap": "react-bootstrap",
"react-intl": "react-intl",
"react-redux": "react-redux",
"ReactRouter": "react-router",
"ready": "domready",
"redux": "redux",
"request": "request",
"require": "require",
"restangular": "restangular",
"reveal": "reveal",
"rickshaw": "rickshaw",
"rimraf": "rimraf",
"rivets": "rivets",
"rx": "rx",
"rx.angular": "rx-angular",
"sammy": "sammyjs",
"SAT": "sat",
"sax-js": "sax",
"screenfull": "screenfull",
"seedrandom": "seedrandom",
"select2": "select2",
"selectize": "selectize",
"serve-favicon": "serve-favicon",
"serve-static": "serve-static",
"shelljs": "shelljs",
"should": "should",
"showdown": "showdown",
"sigma": "sigmajs",
"signature_pad": "signature_pad",
"sinon": "sinon",
"sjcl": "sjcl",
"slick": "slick-carousel",
"smoothie": "smoothie",
"socket.io": "socket.io",
"socket.io-client": "socket.io-client",
"sockjs": "sockjs-client",
"sortable": "angular-ui-sortable",
"soundjs": "soundjs",
"source-map": "source-map",
"spectrum": "spectrum",
"spin": "spin",
"sprintf": "sprintf",
"stampit": "stampit",
"state-machine": "state-machine",
"Stats": "stats",
"store": "storejs",
"string": "string",
"string_score": "string_score",
"strophe": "strophe",
"stylus": "stylus",
"sugar": "sugar",
"superagent": "superagent",
"svg": "svgjs",
"svg-injector": "svg-injector",
"swfobject": "swfobject",
"swig": "swig",
"swipe": "swipe",
"swiper": "swiper",
"system.js": "systemjs",
"tether": "tether",
"three": "threejs",
"through": "through",
"through2": "through2",
"timeline": "timelinejs",
"tinycolor": "tinycolor",
"tmhDynamicLocale": "angular-dynamic-locale",
"toaster": "angularjs-toaster",
"toastr": "toastr",
"tracking": "tracking",
"trunk8": "trunk8",
"turf": "turf",
"tweenjs": "tweenjs",
"TweenMax": "gsap",
"twig": "twig",
"twix": "twix",
"typeahead.bundle": "typeahead",
"typescript": "typescript",
"ui": "winjs",
"ui-bootstrap-tpls": "angular-ui-bootstrap",
"ui-grid": "ui-grid",
"uikit": "uikit",
"underscore": "underscore",
"underscore.string": "underscore.string",
"update-notifier": "update-notifier",
"url": "jsurl",
"UUID": "uuid",
"validator": "validator",
"vega": "vega",
"vex": "vex-js",
"video": "videojs",
"vue": "vue",
"vue-router": "vue-router",
"webtorrent": "webtorrent",
"when": "when",
"winston": "winston",
"wrench-js": "wrench",
"ws": "ws",
"xlsx": "xlsx",
"xml2json": "x2js",
"xmlbuilder-js": "xmlbuilder",
"xregexp": "xregexp",
"yargs": "yargs",
"yosay": "yosay",
"yui": "yui",
"yui3": "yui",
"zepto": "zepto",
"ZeroClipboard": "zeroclipboard",
"ZSchema-browser": "z-schema"
}
}

View File

@ -17,10 +17,10 @@ namespace ts.server.typingsInstaller {
constructor(private readonly logFile?: string) {
}
isEnabled() {
isEnabled = () => {
return this.logEnabled && this.logFile !== undefined;
}
writeLine(text: string) {
writeLine = (text: string) => {
try {
fs.appendFileSync(this.logFile, text + sys.newLine);
}
@ -77,11 +77,12 @@ namespace ts.server.typingsInstaller {
private delayedInitializationError: InitializationFailedResponse;
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, npmLocation: string | undefined, throttleLimit: number, log: Log) {
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, typesMapLocation: string, npmLocation: string | undefined, throttleLimit: number, log: Log) {
super(
sys,
globalTypingsCacheLocation,
typingSafeListLocation ? toPath(typingSafeListLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
typesMapLocation ? toPath(typesMapLocation, "", createGetCanonicalFileName(sys.useCaseSensitiveFileNames)) : toPath("typesMap.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
throttleLimit,
log);
this.npmPath = npmLocation !== undefined ? npmLocation : getDefaultNPMLocation(process.argv[0]);
@ -175,6 +176,7 @@ namespace ts.server.typingsInstaller {
const logFilePath = findArgument(server.Arguments.LogFile);
const globalTypingsCacheLocation = findArgument(server.Arguments.GlobalCacheLocation);
const typingSafeListLocation = findArgument(server.Arguments.TypingSafeListLocation);
const typesMapLocation = findArgument(server.Arguments.TypesMapLocation);
const npmLocation = findArgument(server.Arguments.NpmLocation);
const log = new FileLog(logFilePath);
@ -189,6 +191,6 @@ namespace ts.server.typingsInstaller {
}
process.exit(0);
});
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, npmLocation, /*throttleLimit*/5, log);
const installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, /*throttleLimit*/5, log);
installer.listen();
}

View File

@ -97,10 +97,11 @@ namespace ts.server.typingsInstaller {
protected readonly installTypingHost: InstallTypingHost,
private readonly globalCachePath: string,
private readonly safeListPath: Path,
private readonly typesMapLocation: Path,
private readonly throttleLimit: number,
protected readonly log = nullLog) {
if (this.log.isEnabled()) {
this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}'`);
this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}', types map path ${typesMapLocation}`);
}
this.processCacheLocation(this.globalCachePath);
}
@ -145,7 +146,7 @@ namespace ts.server.typingsInstaller {
}
if (this.safeList === undefined) {
this.safeList = JsTyping.loadSafeList(this.installTypingHost, this.safeListPath);
this.initializeSafeList();
}
const discoverTypingsResult = JsTyping.discoverTypings(
this.installTypingHost,
@ -178,6 +179,20 @@ namespace ts.server.typingsInstaller {
}
}
private initializeSafeList() {
// Prefer the safe list from the types map if it exists
if (this.typesMapLocation) {
const safeListFromMap = JsTyping.loadTypesMap(this.installTypingHost, this.typesMapLocation);
if (safeListFromMap) {
this.log.writeLine(`Loaded safelist from types map file '${this.typesMapLocation}'`);
this.safeList = safeListFromMap;
return;
}
this.log.writeLine(`Failed to load safelist from types map file '${this.typesMapLocation}'`);
}
this.safeList = JsTyping.loadSafeList(this.installTypingHost, this.safeListPath);
}
private processCacheLocation(cacheLocation: string) {
if (this.log.isEnabled()) {
this.log.writeLine(`Processing cache location '${cacheLocation}'`);

View File

@ -49,7 +49,7 @@ namespace ts.server {
export function createInstallTypingsRequest(project: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>, cachePath?: string): DiscoverTypings {
return {
projectName: project.getProjectName(),
fileNames: project.getFileNames(/*excludeFilesFromExternalLibraries*/ true, /*excludeConfigFiles*/ true),
fileNames: project.getFileNames(/*excludeFilesFromExternalLibraries*/ true, /*excludeConfigFiles*/ true).concat(project.getExcludedFiles() as NormalizedPath[]),
compilerOptions: project.getCompilerOptions(),
typeAcquisition,
unresolvedImports,

View File

@ -47,6 +47,14 @@ namespace ts.JsTyping {
return createMapFromTemplate<string>(result.config);
}
export function loadTypesMap(host: TypingResolutionHost, typesMapPath: Path): SafeList | undefined {
const result = readConfigFile(typesMapPath, path => host.readFile(path));
if (result.config) {
return createMapFromTemplate<string>(result.config.simpleMap);
}
return undefined;
}
/**
* @param host is the object providing I/O related operations.
* @param fileNames are the file names that belong to the same project