Skip to content

Commit

Permalink
Merge pull request #48 from timocov/fix_detect_ts_lib_files
Browse files Browse the repository at this point in the history
Fix detecting TypeScript default lib files
  • Loading branch information
timocov authored Jun 29, 2018
2 parents cd6c746 + cce5698 commit e1f41aa
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 37 deletions.
1 change: 1 addition & 0 deletions .dev-deps/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
32 changes: 32 additions & 0 deletions .dev-deps/README.md
Original file line number Diff line number Diff line change
@@ -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.
12 changes: 12 additions & 0 deletions .dev-deps/package.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -24,6 +24,7 @@ git:
cache:
directories:
- "node_modules"
- ".dev-deps/node_modules"

script:
- sh ./travis-script.sh
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
"**/*.js.map": true,
"tests/**/*.js": true,
},
"typescript.tsdk": ".dev-deps/node_modules/typescript/lib",
"tslint.nodePath": ".dev-deps/",
}
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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": {
Expand Down
27 changes: 14 additions & 13 deletions src/bundle-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 ')}`);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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) {
Expand Down
3 changes: 1 addition & 2 deletions src/check-diagnostics-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export function checkDiagnosticsErrors(diagnostics: ReadonlyArray<ts.Diagnostic>
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);
}
12 changes: 1 addition & 11 deletions src/module-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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[];
Expand Down Expand Up @@ -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 };
Expand Down
4 changes: 0 additions & 4 deletions src/node-modules-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit e1f41aa

Please sign in to comment.