From 4f10f7ed42577761657b1de67282df323eb215fe Mon Sep 17 00:00:00 2001 From: Huafu Gandon Date: Fri, 21 Sep 2018 08:47:49 +0200 Subject: [PATCH] feat(typings): emit declaration files, filtering out internals Closes #745 --- src/cli/config/init.ts | 6 ++ src/cli/config/migrate.ts | 6 ++ src/cli/help.ts | 8 ++- src/cli/index.ts | 6 ++ src/compiler.ts | 1 + src/config/config-set.ts | 106 +++++++++++++++++++++----------- src/index.ts | 38 +++++++----- src/transformers/hoist-jest.ts | 7 +++ src/transformers/index.ts | 3 + src/ts-jest-transformer.ts | 12 ++++ src/types.ts | 7 +++ src/util/backports.ts | 6 ++ src/util/get-package-version.ts | 3 + src/util/hacks.ts | 3 + src/util/importer.ts | 11 +++- src/util/json.ts | 13 ++++ src/util/jsonable-value.ts | 3 + src/util/logger.ts | 7 ++- src/util/memoize.ts | 3 + src/util/messages.ts | 16 +++++ src/util/normalize-slashes.ts | 3 + src/util/sha1.ts | 6 ++ src/util/ts-error.ts | 1 + src/util/version-checkers.ts | 12 ++++ tsconfig.build.json | 2 + 25 files changed, 233 insertions(+), 56 deletions(-) diff --git a/src/cli/config/init.ts b/src/cli/config/init.ts index 93a4f39c67..8c9797dffd 100644 --- a/src/cli/config/init.ts +++ b/src/cli/config/init.ts @@ -12,6 +12,9 @@ import { Arguments } from 'yargs' import { CliCommand } from '..' import { createJestPreset } from '../../config/create-jest-preset' +/** + * @internal + */ export const run: CliCommand = async (args: Arguments /* , logger: Logger */) => { const file = args._[0] || 'jest.config.js' const filePath = join(process.cwd(), file) @@ -94,6 +97,9 @@ Jest configuration written to "${filePath}". `) } +/** + * @internal + */ export const help: CliCommand = async () => { process.stdout.write(` Usage: diff --git a/src/cli/config/migrate.ts b/src/cli/config/migrate.ts index 3891944af5..f03e6d4b85 100644 --- a/src/cli/config/migrate.ts +++ b/src/cli/config/migrate.ts @@ -9,6 +9,9 @@ import { CliCommand } from '..' import { createJestPreset } from '../../config/create-jest-preset' import { backportJestConfig } from '../../util/backports' +/** + * @internal + */ export const run: CliCommand = async (args: Arguments /*, logger: Logger*/) => { const nullLogger = createLogger({ targets: [] }) const file = args._[0] @@ -153,6 +156,9 @@ function dedupSort(arr: any[]) { .sort((a, b) => (a.toString() > b.toString() ? 1 : a.toString() < b.toString() ? -1 : 0)) } +/** + * @internal + */ export const help: CliCommand = async () => { process.stdout.write(` Usage: diff --git a/src/cli/help.ts b/src/cli/help.ts index de0d5465d7..a1222efc52 100644 --- a/src/cli/help.ts +++ b/src/cli/help.ts @@ -1,5 +1,8 @@ import { Arguments } from 'yargs' +/** + * @internal + */ export const run = async (_: Arguments) => { process.stdout.write(` Usage: @@ -15,4 +18,7 @@ Example: `) } -export { run as help } +/** + * @internal + */ +export const help = run diff --git a/src/cli/index.ts b/src/cli/index.ts index a1f44f53a5..06f3421e14 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -8,6 +8,9 @@ const VALID_COMMANDS = ['help', 'config:migrate', 'config:init'] const logger = rootLogger.child({ [LogContexts.namespace]: 'cli', [LogContexts.application]: 'ts-jest' }) +/** + * @internal + */ export type CliCommand = (argv: Arguments, logger: Logger) => Promise async function cli(args: string[]): Promise { @@ -33,6 +36,9 @@ async function cli(args: string[]): Promise { return cmd(parsedArgv, logger) } +/** + * @internal + */ export async function processArgv(): Promise { try { await cli(process.argv.slice(2)) diff --git a/src/compiler.ts b/src/compiler.ts index b623292779..770aa583bd 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -45,6 +45,7 @@ const hasOwn = Object.prototype.hasOwnProperty /** * Register TypeScript compiler. + * @internal */ export function createCompiler(configs: ConfigSet): TsCompiler { const logger = configs.logger.child({ namespace: 'ts-compiler' }) diff --git a/src/config/config-set.ts b/src/config/config-set.ts index dbbad96797..00acbfafc9 100644 --- a/src/config/config-set.ts +++ b/src/config/config-set.ts @@ -57,14 +57,23 @@ interface ReadTsConfigResult { resolved: ParsedCommandLine } +/** + * @internal + */ // this regex MUST match nothing, it's the goal ;-) export const MATCH_NOTHING = /a^/ +/** + * @internal + */ export const IGNORE_DIAGNOSTIC_CODES = [ 6059, // "'rootDir' is expected to contain all source files." 18002, // "The 'files' list in config file is empty." 18003, // "No inputs were found in config file." ] +/** + * @internal + */ // WARNING: DO NOT CHANGE THE ORDER OF CODE NAMES! // ONLY APPEND IF YOU NEED TO ADD SOME export enum DiagnosticCodes { @@ -103,16 +112,6 @@ const toDiagnosticCodeList = (items: any, into: number[] = []): number[] => { } export class ConfigSet { - readonly logger: Logger - - constructor( - private readonly _jestConfig: jest.ProjectConfig, - readonly parentOptions?: TsJestGlobalOptions, - parentLogger?: Logger, - ) { - this.logger = parentLogger ? parentLogger.child({ [LogContexts.namespace]: 'config' }) : logger - } - @Memoize() get jest(): jest.ProjectConfig { const config = backportJestConfig(this.logger, this._jestConfig) @@ -234,6 +233,9 @@ export class ConfigSet { ) } + /** + * @internal + */ @Memoize() private get _typescript(): ReadTsConfigResult { const { @@ -252,6 +254,9 @@ export class ConfigSet { return result } + /** + * @internal + */ @Memoize() get raiseDiagnostics() { const { @@ -349,6 +354,9 @@ export class ConfigSet { return {} } + /** + * @internal + */ @Memoize() get filterDiagnostics() { const { @@ -392,6 +400,9 @@ export class ConfigSet { } } + /** + * @internal + */ @Memoize() get createTsError() { const { @@ -471,10 +482,54 @@ export class ConfigSet { return normalize(this.jest.cwd || process.cwd()) } + /** + * @internal + */ get isDoctoring() { return !!process.env.TS_JEST_DOCTOR } + /** + * @internal + */ + @Memoize() + get jsonValue() { + const jest = { ...this.jest } + const globals = (jest.globals = { ...jest.globals } as any) + // we need to remove some stuff from jest config + // this which does not depend on config + delete jest.name + delete jest.cacheDirectory + // we do not need this since its normalized version is in tsJest + delete globals['ts-jest'] + + return new JsonableValue({ + versions: this.versions, + transformers: this.astTransformers.map(t => `${t.name}@${t.version}`), + jest, + tsJest: this.tsJest, + babel: this.babel, + tsconfig: this.tsconfig, + }) + } + + get cacheKey(): string { + return this.jsonValue.serialized + } + readonly logger: Logger + /** + * @internal + */ + private readonly _jestConfig: jest.ProjectConfig + + constructor(jestConfig: jest.ProjectConfig, readonly parentOptions?: TsJestGlobalOptions, parentLogger?: Logger) { + this._jestConfig = jestConfig + this.logger = parentLogger ? parentLogger.child({ [LogContexts.namespace]: 'config' }) : logger + } + + /** + * @internal + */ makeDiagnostic( code: number, messageText: string, @@ -491,6 +546,9 @@ export class ConfigSet { } } + /** + * @internal + */ readTsConfig( compilerOptions?: object, resolvedConfigFile?: string | null, @@ -608,31 +666,9 @@ export class ConfigSet { return path } - @Memoize() - get jsonValue() { - const jest = { ...this.jest } - const globals = (jest.globals = { ...jest.globals } as any) - // we need to remove some stuff from jest config - // this which does not depend on config - delete jest.name - delete jest.cacheDirectory - // we do not need this since its normalized version is in tsJest - delete globals['ts-jest'] - - return new JsonableValue({ - versions: this.versions, - transformers: this.astTransformers.map(t => `${t.name}@${t.version}`), - jest, - tsJest: this.tsJest, - babel: this.babel, - tsconfig: this.tsconfig, - }) - } - - get cacheKey(): string { - return this.jsonValue.serialized - } - + /** + * @internal + */ toJSON() { return this.jsonValue.value } diff --git a/src/index.ts b/src/index.ts index e494dd773b..76e8775a37 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,47 +5,53 @@ import { TsJestGlobalOptions } from './types' import { VersionCheckers } from './util/version-checkers' // tslint:disable-next-line:no-var-requires -const version: string = require('../package.json').version +export const version: string = require('../package.json').version let transformer!: TsJestTransformer function defaultTransformer(): TsJestTransformer { return transformer || (transformer = createTransformer()) } -function createTransformer(baseConfig?: TsJestGlobalOptions) { +export function createTransformer(baseConfig?: TsJestGlobalOptions) { VersionCheckers.jest.warn() return new TsJestTransformer(baseConfig) } -function tsProcess(...args: any[]): any { +/** + * @internal + */ +export function process(...args: any[]): any { return (defaultTransformer().process as any)(...args) } -function getCacheKey(...args: any[]): any { +/** + * @internal + */ +export function getCacheKey(...args: any[]): any { return (defaultTransformer().getCacheKey as any)(...args) } +/** + * @internal + */ // we let jest doing the instrumentation, it does it well -const canInstrument = false +export const canInstrument = false const jestPreset = createJestPreset() +/** + * @internal + */ // for tests // tslint:disable-next-line:variable-name -const __singleton = () => transformer +export const __singleton = () => transformer +/** + * @internal + */ // tslint:disable-next-line:variable-name -const __resetModule = () => (transformer = undefined as any) +export const __resetModule = () => (transformer = undefined as any) export { - version, - // jest API =============== - createTransformer, - tsProcess as process, - getCacheKey, - canInstrument, // extra ================== createJestPreset, jestPreset, pathsToModuleNameMapper, - // tests ================== - __singleton, - __resetModule, } diff --git a/src/transformers/hoist-jest.ts b/src/transformers/hoist-jest.ts index 98776f8a50..f2eba92cc9 100644 --- a/src/transformers/hoist-jest.ts +++ b/src/transformers/hoist-jest.ts @@ -19,13 +19,20 @@ import { ConfigSet } from '../config/config-set' */ const HOIST_METHODS = ['mock', 'unmock'] +/** + * @internal + */ export const name = 'hoisting-jest-mock' // increment this each time the code is modified +/** + * @internal + */ export const version = 1 /** * The factory of hoisting transformer factory * @param cs Current jest configuration-set + * @internal */ export function factory(cs: ConfigSet) { const logger = cs.logger.child({ namespace: 'ts-hoisting' }) diff --git a/src/transformers/index.ts b/src/transformers/index.ts index bbc55e8f10..8167f7e7a5 100644 --- a/src/transformers/index.ts +++ b/src/transformers/index.ts @@ -2,4 +2,7 @@ import { AstTransformerDesc } from '../types' import * as hoisting from './hoist-jest' +/** + * @internal + */ export const internals: AstTransformerDesc[] = [hoisting] diff --git a/src/ts-jest-transformer.ts b/src/ts-jest-transformer.ts index bcbeafa47e..8403c2fcf7 100644 --- a/src/ts-jest-transformer.ts +++ b/src/ts-jest-transformer.ts @@ -20,11 +20,20 @@ interface ConfigSetIndexItem { } export class TsJestTransformer implements jest.Transformer { + /** + * @internal + */ private static readonly _configSetsIndex: ConfigSetIndexItem[] = [] + /** + * @internal + */ private static _lastTransformerId = 0 static get lastTransformerId() { return TsJestTransformer._lastTransformerId } + /** + * @internal + */ private static get _nextTransformerId() { return ++TsJestTransformer._lastTransformerId } @@ -43,6 +52,9 @@ export class TsJestTransformer implements jest.Transformer { this.logger.debug({ baseOptions }, 'created new transformer') } + /** + * @internal + */ /* istanbul ignore next */ [INSPECT_CUSTOM]() { return `[object TsJestTransformer<#${this.id}>]` diff --git a/src/types.ts b/src/types.ts index d01b7698d3..7e9b84081a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -115,8 +115,14 @@ export interface CreateJestPresetOptions { allowJs?: boolean } +/** + * @internal + */ export type ModulePatcher = (module: T) => T +/** + * @internal + */ export interface TsJestImporter { tryThese(moduleName: string, ...fallbacks: string[]): any } @@ -145,6 +151,7 @@ export interface TSCommon { /** * Track the project information. + * @internal */ export interface MemoryCache { contents: { [path: string]: string | undefined } diff --git a/src/util/backports.ts b/src/util/backports.ts index 4f7909c6e5..22f4d58efa 100644 --- a/src/util/backports.ts +++ b/src/util/backports.ts @@ -4,6 +4,9 @@ import { Deprecateds, Helps, interpolate } from './messages' const context = { [LogContexts.namespace]: 'backports' } +/** + * @internal + */ export const backportJestConfig = ( logger: Logger, config: T, @@ -108,6 +111,9 @@ export const backportJestConfig = { if ('TS_JEST_DEBUG' in process.env) { const shouldLog = !/^\s*(?:0|f(?:alse)?|no?|disabled?|off|)\s*$/i.test(process.env.TS_JEST_DEBUG || '') diff --git a/src/util/get-package-version.ts b/src/util/get-package-version.ts index 4a0fc7d6b9..4ffd70626e 100644 --- a/src/util/get-package-version.ts +++ b/src/util/get-package-version.ts @@ -1,3 +1,6 @@ +/** + * @internal + */ export function getPackageVersion(moduleName: string): string | undefined { try { return require(`${moduleName}/package.json`).version as string diff --git a/src/util/hacks.ts b/src/util/hacks.ts index f01e6542c4..709642fe1a 100644 --- a/src/util/hacks.ts +++ b/src/util/hacks.ts @@ -7,6 +7,9 @@ import { Errors, interpolate } from './messages' const logger = rootLogger.child({ namespace: 'hacks' }) +/** + * @internal + */ // tslint:disable-next-line:variable-name export const patchBabelCore_githubIssue6577: ModulePatcher = babel => { // There is an issue still open in Babel 6: https://github.com/babel/babel/issues/6577 diff --git a/src/util/importer.ts b/src/util/importer.ts index f063346d5c..07717293af 100644 --- a/src/util/importer.ts +++ b/src/util/importer.ts @@ -8,7 +8,7 @@ import { VersionCheckers } from './version-checkers' const logger = rootLogger.child({ namespace: 'Importer' }) -// When ading an optional dependency which has another reason, add the reason in ImportReasons, and +// When adding an optional dependency which has another reason, add the reason in ImportReasons, and // create a new method in Importer. Thus uses the importer.yourMethod(ImportReasons.TheReason) // in the relevant code, so that the user knows why it needs it and how to install it in the // case it can't import. @@ -23,6 +23,9 @@ const passThru = (action: () => void) => (input: any) => { return input } +/** + * @internal + */ export class Importer implements TsJestImporter { @Memoize() static get instance() { @@ -128,9 +131,15 @@ export class Importer implements TsJestImporter { } } +/** + * @internal + */ export const importer = Importer.instance let requireModule = (mod: string) => require(mod) +/** + * @internal + */ // so that we can test easier export function __requireModule(localRequire: typeof requireModule) { requireModule = localRequire diff --git a/src/util/json.ts b/src/util/json.ts index b395c112b6..956b5d4040 100644 --- a/src/util/json.ts +++ b/src/util/json.ts @@ -2,10 +2,16 @@ import stableStringify = require('fast-json-stable-stringify') const UNDEFINED = 'undefined' +/** + * @internal + */ export function stringify(input: any): string { return input === undefined ? UNDEFINED : stableStringify(input) } +/** + * @internal + */ export function parse(input: string): any { return input === UNDEFINED ? undefined : JSON.parse(input) } @@ -13,6 +19,9 @@ export function parse(input: string): any { interface NormalizeOptions { parse?: (input: string) => any } +/** + * @internal + */ export function normalize(input: string, { parse: parser = parse }: NormalizeOptions = {}): string { let result: string | undefined if (normalize.cache.has(input)) { @@ -25,6 +34,10 @@ export function normalize(input: string, { parse: parser = parse }: NormalizeOpt } return result === undefined ? input : result } + +/** + * @internal + */ // tslint:disable-next-line:no-namespace export namespace normalize { export const cache = new Map() diff --git a/src/util/jsonable-value.ts b/src/util/jsonable-value.ts index 9cd8a9fe20..08988e8535 100644 --- a/src/util/jsonable-value.ts +++ b/src/util/jsonable-value.ts @@ -1,5 +1,8 @@ import { stringify } from './json' +/** + * @internal + */ export class JsonableValue { private _serialized!: string private _value!: V diff --git a/src/util/logger.ts b/src/util/logger.ts index 60db2feda6..832f0dc789 100644 --- a/src/util/logger.ts +++ b/src/util/logger.ts @@ -13,7 +13,10 @@ const buildOptions = () => ({ targets: process.env.TS_JEST_LOG || undefined, }) -let rootLogger = createLogger(buildOptions()) +/** + * @internal + */ +export let rootLogger = createLogger(buildOptions()) backportTsJestDebugEnvVar(rootLogger) @@ -21,5 +24,3 @@ backportTsJestDebugEnvVar(rootLogger) if (original !== process.env.TS_JEST_LOG) { rootLogger = createLogger(buildOptions()) } - -export { rootLogger } diff --git a/src/util/memoize.ts b/src/util/memoize.ts index 5e7c5512d1..f1d10997b2 100644 --- a/src/util/memoize.ts +++ b/src/util/memoize.ts @@ -1,5 +1,8 @@ const cacheProp = Symbol.for('[memoize]') +/** + * @internal + */ export function Memoize(keyBuilder?: (...args: any[]) => any) { return (_: object, propertyKey: string, descriptor: TypedPropertyDescriptor) => { if (descriptor.value != null) { diff --git a/src/util/messages.ts b/src/util/messages.ts index 53e183e9c4..8c5345275a 100644 --- a/src/util/messages.ts +++ b/src/util/messages.ts @@ -1,4 +1,8 @@ // tslint:disable:max-line-length + +/** + * @internal + */ export enum Errors { UnableToLoadOneModule = 'Unable to load the module {{module}}. {{reason}} To fix it:\n{{fix}}', UnableToLoadAnyModule = 'Unable to load any of these modules: {{module}}. {{reason}}. To fix it:\n{{fix}}', @@ -18,12 +22,18 @@ export enum Errors { ConfigNoModuleInterop = 'If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.', } +/** + * @internal + */ export enum Helps { FixMissingModule = '{{label}}: `npm i -D {{module}}` (or `yarn add --dev {{module}}`)', IgnoreDiagnosticCode = 'customize using `[jest-config].globals.ts-jest.diagnostics` option', MigrateConfigUsingCLI = 'Your Jest configuration is outdated. Use the CLI to help migrating it: ts-jest config:migrate .', } +/** + * @internal + */ export enum Deprecateds { EnvVar = 'Using env. var "{{old}}" is deprecated, use "{{new}}" instead.', ConfigOption = '"[jest-config].{{oldPath}}" is deprecated, use "[jest-config].{{newPath}}" instead.', @@ -31,11 +41,17 @@ export enum Deprecateds { ConfigOptionUseBabelRcNote = 'See `babel-jest` related issue: https://github.com/facebook/jest/issues/3845', } +/** + * @internal + */ export enum ImportReasons { TsJest = 'Using "ts-jest" requires this package to be installed.', BabelJest = 'Using "babel-jest" requires this package to be installed.', } +/** + * @internal + */ export function interpolate(msg: string, vars: Record = {}): string { return msg.replace(/\{\{([^\}]+)\}\}/g, (_, key) => (key in vars ? vars[key] : _)) } diff --git a/src/util/normalize-slashes.ts b/src/util/normalize-slashes.ts index 235c0c39aa..98e78e73a1 100644 --- a/src/util/normalize-slashes.ts +++ b/src/util/normalize-slashes.ts @@ -1,3 +1,6 @@ +/** + * @internal + */ export function normalizeSlashes(value: string): string { return value.replace(/\\/g, '/') } diff --git a/src/util/sha1.ts b/src/util/sha1.ts index a87e35efc1..d2350a7825 100644 --- a/src/util/sha1.ts +++ b/src/util/sha1.ts @@ -1,10 +1,16 @@ import { createHash } from 'crypto' +/** + * @internal + */ // stores hashes made out of only one argument being a string export const cache: { [key: string]: string } = Object.create(null) type DataItem = string | Buffer +/** + * @internal + */ export function sha1(...data: DataItem[]): string { const canCache = data.length === 1 && typeof data[0] === 'string' // caching diff --git a/src/util/ts-error.ts b/src/util/ts-error.ts index 8f8730eba5..6c25a3bae2 100644 --- a/src/util/ts-error.ts +++ b/src/util/ts-error.ts @@ -13,6 +13,7 @@ export const INSPECT_CUSTOM = inspect.custom || 'inspect' /** * TypeScript diagnostics error. + * @internal */ export class TSError extends BaseError { name = 'TSError' diff --git a/src/util/version-checkers.ts b/src/util/version-checkers.ts index ce957258af..5af5d20629 100644 --- a/src/util/version-checkers.ts +++ b/src/util/version-checkers.ts @@ -6,6 +6,9 @@ import { Errors, interpolate } from './messages' const logger = rootLogger.child({ namespace: 'versions' }) +/** + * @internal + */ export enum ExpectedVersions { Jest = '>=22 <24', TypeScript = '>=2.7 <4', @@ -14,12 +17,18 @@ export enum ExpectedVersions { BabelCore = '>=7.0.0-beta.0 <8', } +/** + * @internal + */ export interface VersionChecker { raise: () => boolean | never warn: () => boolean forget: () => void } +/** + * @internal + */ // tslint:disable-next-line:variable-name export const VersionCheckers = { jest: createVersionChecker('jest', ExpectedVersions.Jest), @@ -31,6 +40,9 @@ export const VersionCheckers = { type CheckVersionAction = 'warn' | 'throw' +/** + * @internal + */ function checkVersion(name: string, expectedRange: string, action?: Exclude): boolean function checkVersion(name: string, expectedRange: string, action: 'throw'): true | never function checkVersion( diff --git a/tsconfig.build.json b/tsconfig.build.json index 9284ed7ee7..7676156412 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -5,6 +5,8 @@ "inlineSources": false, "inlineSourceMap": false, "noEmit": false, + "declaration": true, + "stripInternal": true, "outDir": "dist", "rootDir": "src", },