diff --git a/.dev-deps/.npmrc b/.dev-deps/.npmrc new file mode 100644 index 00000000..43c97e71 --- /dev/null +++ b/.dev-deps/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/.dev-deps/README.md b/.dev-deps/README.md new file mode 100644 index 00000000..68da623f --- /dev/null +++ b/.dev-deps/README.md @@ -0,0 +1,32 @@ +# Developer's dependencies + +This folder is needed to have some developer's dependencies here, which are used to compile/lint the code. + +## Why + +The tool is written in TypeScript, and it uses TypeScript to do stuff also. +So, we should have TypeScript in both dev and prod dependency list: + +- in dev for the compiler (`tsc`) and TSLint (because TSLint should use the same version of TypeScript as we compile the code) +- in prod TypeScript only for its API (with declaration files) + +The possible solutions of this issue might be: + +1. If TypeScript's team will provide 2 separate packages `typescript` and `typescript-cli`. + + In this case we can use `typescript` as prod dependency and `typescript-cli` as dev one. + +1. `npm` will allows to have the same dependency both in `devDependencies` and `dependencies` and will install it in separate folders. + + In this case we can just put 2 `typescript`'s in separate dependencies list and control which we need in each case. + +But neither TypeScript or npm does not have a solution (and will not have). + +That is why we have `.dev-deps` with developer's dependencies. + +This mechanism allows us use the latest compiler to compile source code +(and use new features like mapped or conditional types in source code) +and check that source code is compatible with specific TypeScript version and its API. + +For example, we can use 2.9.2 to compile (and use conditional types in the code), +and check that source code is compatible with API of 2.6.2. diff --git a/.dev-deps/package.json b/.dev-deps/package.json new file mode 100644 index 00000000..8b6a9c56 --- /dev/null +++ b/.dev-deps/package.json @@ -0,0 +1,12 @@ +{ + "private": true, + "scripts": { + "lint": "tslint --config ../tslint.json --project ../tsconfig.json", + "compile": "tsc --version && tsc --project ../tsconfig.json", + "compile-tests": "tsc --project ../tsconfig.tests.json" + }, + "devDependencies": { + "tslint": "~5.10.0", + "typescript": "~2.9.2" + } +} diff --git a/.travis.yml b/.travis.yml index b5b20d4b..01549dd2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ branches: env: # minimal supported version - just compile - - TS_VERSION="2.5.1" COMPILE_ONLY=1 + - TS_VERSION="2.6.1" COMPILE_ONLY=1 # current (latest) supported version - compile and run tests - TS_VERSION="2.9.2" @@ -24,6 +24,7 @@ git: cache: directories: - "node_modules" + - ".dev-deps/node_modules" script: - sh ./travis-script.sh diff --git a/.vscode/settings.json b/.vscode/settings.json index e872ad68..36b9927d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,4 +5,6 @@ "**/*.js.map": true, "tests/**/*.js": true, }, + "typescript.tsdk": ".dev-deps/node_modules/typescript/lib", + "tslint.nodePath": ".dev-deps/", } diff --git a/package.json b/package.json index 4b31b5c6..4e4df79a 100644 --- a/package.json +++ b/package.json @@ -10,15 +10,14 @@ "url": "https://github.com/timocov/dts-bundle-generator/issues" }, "dependencies": { - "typescript": "^2.5.1", + "typescript": "^2.6.1", "yargs": "~11.0.0" }, "devDependencies": { "@types/jasmine": "~2.8.7", "@types/node": "7.0.8", "@types/yargs": "~10.0.1", - "jasmine": "~2.9.0", - "tslint": "~5.10.0" + "jasmine": "~2.9.0" }, "license": "MIT", "readme": "README.md", @@ -27,10 +26,11 @@ "url": "git+https://github.com/timocov/dts-bundle-generator.git" }, "scripts": { - "lint": "tslint --config tslint.json --project tsconfig.json", - "compile": "tsc", - "compile-tests": "tsc --project tsconfig.tests.json", + "lint": "cd .dev-deps/ && npm run lint", + "compile": "cd .dev-deps/ && npm run compile", + "compile-tests": "cd .dev-deps/ && npm run compile-tests", "prepare-release": "npm run compile && node build/index.js && npm run lint && npm run compile-tests && npm run test && node build/prod-ready", + "postinstall": "cd .dev-deps/ && npm install", "test": "jasmine tests/all-test-cases.js" }, "yargs": { diff --git a/src/bundle-generator.ts b/src/bundle-generator.ts index dedfc7ae..96a3fb68 100644 --- a/src/bundle-generator.ts +++ b/src/bundle-generator.ts @@ -62,7 +62,20 @@ export function generateDtsBundle(filePath: string, options: GenerationOptions = }; const sourceFiles = program.getSourceFiles().filter((file: ts.SourceFile) => { - return getModuleInfo(file.fileName, criteria).type !== ModuleType.ShouldNotBeUsed; + interface CompatibilityProgramPart { + // this method was introduced in TypeScript 2.6 + // but to the public API it was added only in TypeScript 3.0 + // so, to be compiled with TypeScript < 3.0 we need to have this hack + isSourceFileDefaultLibrary(file: ts.SourceFile): boolean; + } + + type CommonKeys = keyof (CompatibilityProgramPart | ts.Program); + + // if current ts.Program has isSourceFileDefaultLibrary method - then use it + // if it does not have it yet - use fallback + type CompatibleProgram = CommonKeys extends never ? ts.Program & CompatibilityProgramPart : ts.Program; + + return !(program as CompatibleProgram).isSourceFileDefaultLibrary(file); }); verboseLog(`Input source files:\n ${sourceFiles.map((file: ts.SourceFile) => file.fileName).join('\n ')}`); @@ -171,10 +184,6 @@ interface UpdateParams { // tslint:disable-next-line:cyclomatic-complexity function updateResult(params: UpdateParams, result: CollectingResult): void { - if (params.currentModule.type === ModuleType.ShouldNotBeUsed) { - return; - } - for (const statement of params.statements) { // we should skip import and exports statements if (skippedNodes.indexOf(statement.kind) !== -1) { @@ -268,10 +277,6 @@ function updateResultForImportedEqExportAssignment(exportAssignment: ts.ExportAs } function updateResultForModuleDeclaration(moduleDecl: ts.ModuleDeclaration, params: UpdateParams, result: CollectingResult): void { - if (params.currentModule.type === ModuleType.ShouldNotBeUsed) { - return; - } - if (moduleDecl.body === undefined || !ts.isModuleBlock(moduleDecl.body)) { return; } @@ -280,10 +285,6 @@ function updateResultForModuleDeclaration(moduleDecl: ts.ModuleDeclaration, para const moduleFileName = resolveModuleFileName(params.currentModule.fileName, moduleName); const moduleInfo = params.getModuleInfo(moduleFileName); - if (moduleInfo.type === ModuleType.ShouldNotBeUsed) { - return; - } - // if we have declaration of external module inside internal one // we need to just add it to result without any processing if (!params.currentModule.isExternal && moduleInfo.isExternal) { diff --git a/src/check-diagnostics-errors.ts b/src/check-diagnostics-errors.ts index b32edad4..d79f280e 100644 --- a/src/check-diagnostics-errors.ts +++ b/src/check-diagnostics-errors.ts @@ -17,7 +17,6 @@ export function checkDiagnosticsErrors(diagnostics: ReadonlyArray return; } - // `as ts.Diagnostic[]` we need to correct compile with TypeScript 2.5.1 - errorLog(ts.formatDiagnostics(diagnostics as ts.Diagnostic[], formatDiagnosticsHost).trim()); + errorLog(ts.formatDiagnostics(diagnostics, formatDiagnosticsHost).trim()); throw new Error(failMessage); } diff --git a/src/module-info.ts b/src/module-info.ts index 729806f9..50dce597 100644 --- a/src/module-info.ts +++ b/src/module-info.ts @@ -3,11 +3,9 @@ import * as path from 'path'; import { getLibraryName, getTypesLibraryName, - isTypescriptLibFile, } from './node-modules-helpers'; export const enum ModuleType { - ShouldNotBeUsed, ShouldBeInlined, ShouldBeImported, ShouldBeReferencedAsTypes, @@ -40,11 +38,7 @@ export interface UsedForModulesModuleInfo extends UsedModuleInfoCommon { isExternal: true; } -export interface NotUsedModuleInfo { - type: ModuleType.ShouldNotBeUsed; -} - -export type ModuleInfo = NotUsedModuleInfo | InlinedModuleInfo | ImportedModuleInfo | ReferencedModuleInfo | UsedForModulesModuleInfo; +export type ModuleInfo = InlinedModuleInfo | ImportedModuleInfo | ReferencedModuleInfo | UsedForModulesModuleInfo; export interface ModuleCriteria { inlinedLibraries: string[]; @@ -79,10 +73,6 @@ function getModuleInfoImpl(currentFilePath: string, originalFileName: string, cr return { type: ModuleType.ShouldBeInlined, fileName: originalFileName, isExternal: false }; } - if (isTypescriptLibFile(currentFilePath)) { - return { type: ModuleType.ShouldNotBeUsed }; - } - const typesLibraryName = getTypesLibraryName(currentFilePath); if (shouldLibraryBeInlined(npmLibraryName, typesLibraryName, criteria.inlinedLibraries)) { return { type: ModuleType.ShouldBeInlined, fileName: originalFileName, isExternal: true }; diff --git a/src/node-modules-helpers.ts b/src/node-modules-helpers.ts index 7b09ca6c..ed20e9cd 100644 --- a/src/node-modules-helpers.ts +++ b/src/node-modules-helpers.ts @@ -28,7 +28,3 @@ export function getTypesLibraryName(path: string): string | null { return libraryName.substring(typesFolderPrefix.length); } - -export function isTypescriptLibFile(fileName: string): boolean { - return /node_modules[\\\/]typescript[\\\/]lib[\\\/]lib(\..+)?\.d\.ts$/i.test(fileName); -}