From 6b7488f9e0d88dc4dcfc984aaf4f42938f46fcd8 Mon Sep 17 00:00:00 2001 From: donvercety Date: Fri, 15 Feb 2019 17:03:54 +0200 Subject: [PATCH 1/7] Must export the namespace. Fix to work with auto-loading in VSCode, --- types/node-cache/index.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/types/node-cache/index.d.ts b/types/node-cache/index.d.ts index 6bac061ecb..18406d6962 100644 --- a/types/node-cache/index.d.ts +++ b/types/node-cache/index.d.ts @@ -283,3 +283,5 @@ declare class NodeCache extends events.EventEmitter implements NodeCache.NodeCac } export = NodeCache; +export as namespace NodeCache; + From 238048135c5159f7a8fa8e11e3f177662c3a5619 Mon Sep 17 00:00:00 2001 From: donvercety Date: Fri, 15 Feb 2019 19:09:18 +0200 Subject: [PATCH 2/7] fixing double new line in file --- types/node-cache/index.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/types/node-cache/index.d.ts b/types/node-cache/index.d.ts index 18406d6962..61100a574d 100644 --- a/types/node-cache/index.d.ts +++ b/types/node-cache/index.d.ts @@ -284,4 +284,3 @@ declare class NodeCache extends events.EventEmitter implements NodeCache.NodeCac export = NodeCache; export as namespace NodeCache; - From c1008222d7e6140054d04e45837ea5b793a79e47 Mon Sep 17 00:00:00 2001 From: Jessica Date: Sat, 16 Feb 2019 23:47:39 +0900 Subject: [PATCH 3/7] Add types for the babel.config.js API --- types/babel__core/babel__core-tests.ts | 53 +++++++++ types/babel__core/index.d.ts | 155 ++++++++++++++++++++++++- 2 files changed, 207 insertions(+), 1 deletion(-) diff --git a/types/babel__core/babel__core-tests.ts b/types/babel__core/babel__core-tests.ts index ba51ac21be..5f8f5078e4 100644 --- a/types/babel__core/babel__core-tests.ts +++ b/types/babel__core/babel__core-tests.ts @@ -39,3 +39,56 @@ babel.transformFromAstAsync(parsedAst!, sourceCode, options).then(transformFromA const { code, map, ast } = transformFromAstAsyncResult!; const { body } = ast!.program; }); + +function checkOptions(_options: babel.TransformOptions) {} +function checkConfigFunction(_config: babel.ConfigFunction) {} + +checkOptions({ envName: 'banana' }); +// babel uses object destructuring default to provide the envName fallback so null is not allowed +// $ExpectError +checkOptions({ envName: null }); +checkOptions({ caller: { name: '@babel/register' } }); +checkOptions({ caller: { name: 'babel-jest', supportsStaticESM: false } }); +// don't add an index signature; users should augment the interface instead if they need to +// $ExpectError +checkOptions({ caller: { name: '', tomato: true } }); + +// $ExpectError +checkConfigFunction(() => {}); +// you technically can do that though you probably shouldn't +checkConfigFunction(() => ({})); +checkConfigFunction(api => { + api.assertVersion(7); + api.assertVersion("^7.2"); + + api.cache.forever(); + api.cache.never(); + api.cache.using(() => true); + api.cache.using(() => 1); + api.cache.using(() => '1'); + api.cache.using(() => null); + api.cache.using(() => undefined); + // $ExpectError + api.cache.using(() => ({})); + api.cache.invalidate(() => 2); + + // $ExpectType string + api.env(); + + api.env('development'); + api.env(['production', 'test']); + // $ExpectType 42 + api.env(name => 42); + + // $ExpectType string + api.version; + + return { + shouldPrintComment(comment) { + // $ExpectType string + comment; + + return true; + } + }; +}); diff --git a/types/babel__core/index.d.ts b/types/babel__core/index.d.ts index 66501d24db..89883afa6a 100644 --- a/types/babel__core/index.d.ts +++ b/types/babel__core/index.d.ts @@ -82,7 +82,7 @@ export interface TransformOptions { * * Default: env vars */ - envName?: string | null; + envName?: string; /** * Enable code generation @@ -112,6 +112,14 @@ export interface TransformOptions { */ cwd?: string | null; + /** + * Utilities may pass a caller object to identify themselves to Babel and + * pass capability-related flags for use by configs, presets and plugins. + * + * @see https://babeljs.io/docs/en/next/options#caller + */ + caller?: TransformCaller; + /** * This is an object of keys that represent different environments. For example, you may have: `{ env: { production: { \/* specific options *\/ } } }` * which will use those options when the `envName` is `production` @@ -284,6 +292,14 @@ export interface TransformOptions { wrapPluginVisitorMethod?: ((pluginAlias: string, visitorType: "enter" | "exit", callback: (path: NodePath, state: any) => void) => (path: NodePath, state: any) => void) | null; } +export interface TransformCaller { + // the only required property + name: string; + // set to true by e.g. `babel-loader` and `babel-jest` + supportsStaticESM?: boolean; + // augment this with a "declare module '@babel/core' { ... }" if you need more keys +} + export type FileResultCallback = (err: Error | null, result: BabelFileResult | null) => any; /** @@ -528,4 +544,141 @@ export interface CreateConfigItemOptions { */ export function createConfigItem(value: PluginTarget | [PluginTarget, PluginOptions] | [PluginTarget, PluginOptions, string | undefined], options?: CreateConfigItemOptions): ConfigItem; +// NOTE: the documentation says the ConfigAPI also exposes @babel/core's exports, but it actually doesn't +/** + * @see https://babeljs.io/docs/en/next/config-files#config-function-api + */ +export interface ConfigAPI { + /** + * The version string for the Babel version that is loading the config file. + * + * @see https://babeljs.io/docs/en/next/config-files#apiversion + */ + version: string; + /** + * @see https://babeljs.io/docs/en/next/config-files#apicache + */ + cache: SimpleCacheConfigurator; + /** + * @see https://babeljs.io/docs/en/next/config-files#apienv + */ + env: EnvFunction; + // undocumented; currently hardcoded to return 'false' + // async(): boolean + /** + * This API is used as a way to access the `caller` data that has been passed to Babel. + * Since many instances of Babel may be running in the same process with different `caller` values, + * this API is designed to automatically configure `api.cache`, the same way `api.env()` does. + * + * The `caller` value is available as the first parameter of the callback function. + * It is best used with something like this to toggle configuration behavior + * based on a specific environment: + * + * @example + * function isBabelRegister(caller?: { name: string }) { + * return !!(caller && caller.name === "@babel/register") + * } + * api.caller(isBabelRegister) + * + * @see https://babeljs.io/docs/en/next/config-files#apicallercb + */ + caller(callerCallback: (caller: TransformOptions['caller']) => T): T + /** + * While `api.version` can be useful in general, it's sometimes nice to just declare your version. + * This API exposes a simple way to do that with: + * + * @example + * api.assertVersion(7) + * + * @see https://babeljs.io/docs/en/next/config-files#apiassertversionrange + */ + assertVersion(majorVersion: number): boolean + /** + * While `api.version` can be useful in general, it's sometimes nice to just declare your version. + * This API exposes a simple way to do that with: + * + * @example + * api.assertVersion("^7.2") + * + * @see https://babeljs.io/docs/en/next/config-files#apiassertversionrange + */ + assertVersion(semverExpression: string): boolean + // NOTE: this is an undocumented reexport from "@babel/parser" but it's missing from its types + // tokTypes: typeof tokTypes +} + +/** + * JS configs are great because they can compute a config on the fly, + * but the downside there is that it makes caching harder. + * Babel wants to avoid re-executing the config function every time a file is compiled, + * because then it would also need to re-execute any plugin and preset functions + * referenced in that config. + * + * To avoid this, Babel expects users of config functions to tell it how to manage caching + * within a config file. + * + * @see https://babeljs.io/docs/en/next/config-files#apicache + */ +export interface SimpleCacheConfigurator { + // there is an undocumented call signature that is a shorthand for forever()/never()/using(). + // (ever: boolean): void + // (callback: CacheCallback): T + /** + * Permacache the computed config and never call the function again. + */ + forever(): void + /** + * Do not cache this config, and re-execute the function every time. + */ + never(): void + /** + * Any time the using callback returns a value other than the one that was expected, + * the overall config function will be called again and a new entry will be added to the cache. + * + * @example + * api.cache.using(() => process.env.NODE_ENV) + */ + using(callback: SimpleCacheCallback): T + /** + * Any time the using callback returns a value other than the one that was expected, + * the overall config function will be called again and all entries in the cache will + * be replaced with the result. + * + * @example + * api.cache.invalidate(() => process.env.NODE_ENV) + */ + invalidate(callback: SimpleCacheCallback): T +} + +// https://github.com/babel/babel/blob/v7.3.3/packages/babel-core/src/config/caching.js#L231 +export type SimpleCacheKey = string | boolean | number | null | undefined +export type SimpleCacheCallback = () => T + +/** + * Since `NODE_ENV` is a fairly common way to toggle behavior, Babel also includes an API function + * meant specifically for that. This API is used as a quick way to check the `"envName"` that Babel + * was loaded with, which takes `NODE_ENV` into account if no other overriding environment is set. + * + * @see https://babeljs.io/docs/en/next/config-files#apienv + */ +export interface EnvFunction { + /** + * @returns the current `envName` string + */ + (): string + /** + * @returns `true` if the `envName` is `===` the argument + */ + (envName: string): boolean + /** + * @returns `true` if the `envName` is `===` any of the given strings + */ + (envNames: ReadonlyArray): boolean + // the official documentation is completely wrong for this one... + // this just passes the callback to `cache.using` but with an additional argument. + (envCallback: (envName: NonNullable) => T): T +} + +export type ConfigFunction = (api: ConfigAPI) => TransformOptions; + export as namespace babel; From d1a839a64b05a575e04b1c0640d92dad23bd3802 Mon Sep 17 00:00:00 2001 From: Jessica Date: Sun, 17 Feb 2019 01:15:30 +0900 Subject: [PATCH 4/7] Also declare rootMode --- types/babel__core/babel__core-tests.ts | 7 +++++-- types/babel__core/index.d.ts | 12 +++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/types/babel__core/babel__core-tests.ts b/types/babel__core/babel__core-tests.ts index 5f8f5078e4..59414d768d 100644 --- a/types/babel__core/babel__core-tests.ts +++ b/types/babel__core/babel__core-tests.ts @@ -44,14 +44,17 @@ function checkOptions(_options: babel.TransformOptions) {} function checkConfigFunction(_config: babel.ConfigFunction) {} checkOptions({ envName: 'banana' }); -// babel uses object destructuring default to provide the envName fallback so null is not allowed -// $ExpectError checkOptions({ envName: null }); checkOptions({ caller: { name: '@babel/register' } }); checkOptions({ caller: { name: 'babel-jest', supportsStaticESM: false } }); // don't add an index signature; users should augment the interface instead if they need to // $ExpectError checkOptions({ caller: { name: '', tomato: true } }); +checkOptions({ rootMode: 'upward-optional' }); +// $ExpectError +checkOptions({ rootMode: 'potato' }); +// babel uses object destructuring default to provide the envName fallback so null is not allowed +// $ExpectError // $ExpectError checkConfigFunction(() => {}); diff --git a/types/babel__core/index.d.ts b/types/babel__core/index.d.ts index 89883afa6a..8c4f2ef25a 100644 --- a/types/babel__core/index.d.ts +++ b/types/babel__core/index.d.ts @@ -1,8 +1,9 @@ -// Type definitions for @babel/core 7.0 +// Type definitions for @babel/core 7.1 // Project: https://github.com/babel/babel/tree/master/packages/babel-core, https://babeljs.io // Definitions by: Troy Gerwien // Marvin Hagemeister // Melvin Groenhoff +// Jessica Franco // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.9 @@ -54,6 +55,15 @@ export interface TransformOptions { */ root?: string | null; + /** + * This option, combined with the "root" value, defines how Babel chooses its project root. + * The different modes define different ways that Babel can process the "root" value to get + * the final project root. + * + * @see https://babeljs.io/docs/en/next/options#rootmode + */ + rootMode?: 'root' | 'upward' | 'upward-optional'; + /** * The config file to load Babel's config from. Defaults to searching for "babel.config.js" inside the "root" folder. `false` will disable searching for config files. * From 6ddb0f2b9fa600de24df1cd2b5c94f77182ff297 Mon Sep 17 00:00:00 2001 From: Jessica Date: Sun, 17 Feb 2019 01:18:58 +0900 Subject: [PATCH 5/7] Fix lint warnings, dangling comment --- types/babel__core/babel__core-tests.ts | 4 +-- types/babel__core/index.d.ts | 37 +++++++++----------------- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/types/babel__core/babel__core-tests.ts b/types/babel__core/babel__core-tests.ts index 59414d768d..b44e45c605 100644 --- a/types/babel__core/babel__core-tests.ts +++ b/types/babel__core/babel__core-tests.ts @@ -44,6 +44,8 @@ function checkOptions(_options: babel.TransformOptions) {} function checkConfigFunction(_config: babel.ConfigFunction) {} checkOptions({ envName: 'banana' }); +// babel uses object destructuring default to provide the envName fallback so null is not allowed +// $ExpectError checkOptions({ envName: null }); checkOptions({ caller: { name: '@babel/register' } }); checkOptions({ caller: { name: 'babel-jest', supportsStaticESM: false } }); @@ -53,8 +55,6 @@ checkOptions({ caller: { name: '', tomato: true } }); checkOptions({ rootMode: 'upward-optional' }); // $ExpectError checkOptions({ rootMode: 'potato' }); -// babel uses object destructuring default to provide the envName fallback so null is not allowed -// $ExpectError // $ExpectError checkConfigFunction(() => {}); diff --git a/types/babel__core/index.d.ts b/types/babel__core/index.d.ts index 8c4f2ef25a..1315ac821b 100644 --- a/types/babel__core/index.d.ts +++ b/types/babel__core/index.d.ts @@ -592,27 +592,18 @@ export interface ConfigAPI { * * @see https://babeljs.io/docs/en/next/config-files#apicallercb */ - caller(callerCallback: (caller: TransformOptions['caller']) => T): T - /** - * While `api.version` can be useful in general, it's sometimes nice to just declare your version. - * This API exposes a simple way to do that with: - * - * @example - * api.assertVersion(7) - * - * @see https://babeljs.io/docs/en/next/config-files#apiassertversionrange - */ - assertVersion(majorVersion: number): boolean + caller(callerCallback: (caller: TransformOptions['caller']) => T): T; /** * While `api.version` can be useful in general, it's sometimes nice to just declare your version. * This API exposes a simple way to do that with: * * @example + * api.assertVersion(7) // major version only * api.assertVersion("^7.2") * * @see https://babeljs.io/docs/en/next/config-files#apiassertversionrange */ - assertVersion(semverExpression: string): boolean + assertVersion(versionRange: number | string): boolean; // NOTE: this is an undocumented reexport from "@babel/parser" but it's missing from its types // tokTypes: typeof tokTypes } @@ -636,11 +627,11 @@ export interface SimpleCacheConfigurator { /** * Permacache the computed config and never call the function again. */ - forever(): void + forever(): void; /** * Do not cache this config, and re-execute the function every time. */ - never(): void + never(): void; /** * Any time the using callback returns a value other than the one that was expected, * the overall config function will be called again and a new entry will be added to the cache. @@ -648,7 +639,7 @@ export interface SimpleCacheConfigurator { * @example * api.cache.using(() => process.env.NODE_ENV) */ - using(callback: SimpleCacheCallback): T + using(callback: SimpleCacheCallback): T; /** * Any time the using callback returns a value other than the one that was expected, * the overall config function will be called again and all entries in the cache will @@ -657,12 +648,12 @@ export interface SimpleCacheConfigurator { * @example * api.cache.invalidate(() => process.env.NODE_ENV) */ - invalidate(callback: SimpleCacheCallback): T + invalidate(callback: SimpleCacheCallback): T; } // https://github.com/babel/babel/blob/v7.3.3/packages/babel-core/src/config/caching.js#L231 -export type SimpleCacheKey = string | boolean | number | null | undefined -export type SimpleCacheCallback = () => T +export type SimpleCacheKey = string | boolean | number | null | undefined; +export type SimpleCacheCallback = () => T; /** * Since `NODE_ENV` is a fairly common way to toggle behavior, Babel also includes an API function @@ -675,18 +666,14 @@ export interface EnvFunction { /** * @returns the current `envName` string */ - (): string - /** - * @returns `true` if the `envName` is `===` the argument - */ - (envName: string): boolean + (): string; /** * @returns `true` if the `envName` is `===` any of the given strings */ - (envNames: ReadonlyArray): boolean + (envName: string | ReadonlyArray): boolean; // the official documentation is completely wrong for this one... // this just passes the callback to `cache.using` but with an additional argument. - (envCallback: (envName: NonNullable) => T): T + (envCallback: (envName: NonNullable) => T): T; } export type ConfigFunction = (api: ConfigAPI) => TransformOptions; From 047097d85050d79117560302b10ccdf1337949af Mon Sep 17 00:00:00 2001 From: Jessica Date: Sun, 17 Feb 2019 01:27:04 +0900 Subject: [PATCH 6/7] Correct comment --- types/babel__core/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/babel__core/index.d.ts b/types/babel__core/index.d.ts index 1315ac821b..7f03a7585a 100644 --- a/types/babel__core/index.d.ts +++ b/types/babel__core/index.d.ts @@ -305,7 +305,7 @@ export interface TransformOptions { export interface TransformCaller { // the only required property name: string; - // set to true by e.g. `babel-loader` and `babel-jest` + // e.g. set to true by `babel-loader` and false by `babel-jest` supportsStaticESM?: boolean; // augment this with a "declare module '@babel/core' { ... }" if you need more keys } From b5328a7049cf07e4c4d8a9211d26080b4a5ef231 Mon Sep 17 00:00:00 2001 From: Jessica Date: Sun, 17 Feb 2019 01:41:00 +0900 Subject: [PATCH 7/7] It's not actually wrong, just misleading --- types/babel__core/index.d.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/types/babel__core/index.d.ts b/types/babel__core/index.d.ts index 7f03a7585a..3875d40d71 100644 --- a/types/babel__core/index.d.ts +++ b/types/babel__core/index.d.ts @@ -671,8 +671,9 @@ export interface EnvFunction { * @returns `true` if the `envName` is `===` any of the given strings */ (envName: string | ReadonlyArray): boolean; - // the official documentation is completely wrong for this one... + // the official documentation is misleading for this one... // this just passes the callback to `cache.using` but with an additional argument. + // it returns its result instead of necessarily returning a boolean. (envCallback: (envName: NonNullable) => T): T; }