Convert @babel/core to TypeScript (#12929)
Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
parent
c8a91d9eef
commit
a647b9ea6b
@ -42,10 +42,10 @@
|
|||||||
"./lib/config/resolve-targets.js": "./lib/config/resolve-targets-browser.js",
|
"./lib/config/resolve-targets.js": "./lib/config/resolve-targets-browser.js",
|
||||||
"./lib/transform-file.js": "./lib/transform-file-browser.js",
|
"./lib/transform-file.js": "./lib/transform-file-browser.js",
|
||||||
"./lib/transformation/util/clone-deep.js": "./lib/transformation/util/clone-deep-browser.js",
|
"./lib/transformation/util/clone-deep.js": "./lib/transformation/util/clone-deep-browser.js",
|
||||||
"./src/config/files/index.js": "./src/config/files/index-browser.js",
|
"./src/config/files/index.ts": "./src/config/files/index-browser.ts",
|
||||||
"./src/config/resolve-targets.js": "./src/config/resolve-targets-browser.js",
|
"./src/config/resolve-targets.ts": "./src/config/resolve-targets-browser.ts",
|
||||||
"./src/transform-file.js": "./src/transform-file-browser.js",
|
"./src/transform-file.ts": "./src/transform-file-browser.ts",
|
||||||
"./src/transformation/util/clone-deep.js": "./src/transformation/util/clone-deep-browser.js"
|
"./src/transformation/util/clone-deep.ts": "./src/transformation/util/clone-deep-browser.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "workspace:^7.12.13",
|
"@babel/code-frame": "workspace:^7.12.13",
|
||||||
@ -65,6 +65,12 @@
|
|||||||
"source-map": "^0.5.0"
|
"source-map": "^0.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/helper-transform-fixture-test-runner": "workspace:*"
|
"@babel/helper-transform-fixture-test-runner": "workspace:*",
|
||||||
|
"@types/convert-source-map": "^1.5.1",
|
||||||
|
"@types/debug": "^4.1.0",
|
||||||
|
"@types/lodash": "^4.14.150",
|
||||||
|
"@types/resolve": "^1.3.2",
|
||||||
|
"@types/semver": "^5.4.0",
|
||||||
|
"@types/source-map": "^0.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import type { Targets } from "@babel/helper-compilation-targets";
|
import type { Targets } from "@babel/helper-compilation-targets";
|
||||||
|
|
||||||
import type { ConfigContext } from "./config-chain";
|
import type { ConfigContext } from "./config-chain";
|
||||||
@ -8,25 +6,23 @@ import type { CallerMetadata } from "./validation/options";
|
|||||||
export type { ConfigContext as FullConfig };
|
export type { ConfigContext as FullConfig };
|
||||||
|
|
||||||
export type FullPreset = {
|
export type FullPreset = {
|
||||||
...ConfigContext,
|
targets: Targets;
|
||||||
targets: Targets,
|
} & ConfigContext;
|
||||||
};
|
|
||||||
export type FullPlugin = {
|
export type FullPlugin = {
|
||||||
...FullPreset,
|
assumptions: { [name: string]: boolean };
|
||||||
assumptions: { [name: string]: boolean },
|
} & FullPreset;
|
||||||
};
|
|
||||||
|
|
||||||
// Context not including filename since it is used in places that cannot
|
// Context not including filename since it is used in places that cannot
|
||||||
// process 'ignore'/'only' and other filename-based logic.
|
// process 'ignore'/'only' and other filename-based logic.
|
||||||
export type SimpleConfig = {
|
export type SimpleConfig = {
|
||||||
envName: string,
|
envName: string;
|
||||||
caller: CallerMetadata | void,
|
caller: CallerMetadata | void;
|
||||||
};
|
};
|
||||||
export type SimplePreset = {
|
export type SimplePreset = {
|
||||||
...SimpleConfig,
|
targets: Targets;
|
||||||
targets: Targets,
|
} & SimpleConfig;
|
||||||
};
|
|
||||||
export type SimplePlugin = {
|
export type SimplePlugin = {
|
||||||
...SimplePreset,
|
assumptions: {
|
||||||
assumptions: { [name: string]: boolean },
|
[name: string]: boolean;
|
||||||
};
|
};
|
||||||
|
} & SimplePreset;
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
// @flow
|
import gensync from "gensync";
|
||||||
|
import type { Handler } from "gensync";
|
||||||
import gensync, { type Handler } from "gensync";
|
|
||||||
import {
|
import {
|
||||||
maybeAsync,
|
maybeAsync,
|
||||||
isAsync,
|
isAsync,
|
||||||
@ -12,60 +11,61 @@ import { isIterableIterator } from "./util";
|
|||||||
|
|
||||||
export type { CacheConfigurator };
|
export type { CacheConfigurator };
|
||||||
|
|
||||||
export type SimpleCacheConfigurator = SimpleCacheConfiguratorFn &
|
export type SimpleCacheConfigurator = {
|
||||||
SimpleCacheConfiguratorObj;
|
(forever: boolean): void;
|
||||||
|
<T>(handler: () => T): T;
|
||||||
|
|
||||||
type SimpleCacheConfiguratorFn = {
|
forever: () => void;
|
||||||
(boolean): void,
|
never: () => void;
|
||||||
<T>(handler: () => T): T,
|
using: <T>(handler: () => T) => T;
|
||||||
};
|
invalidate: <T>(handler: () => T) => T;
|
||||||
type SimpleCacheConfiguratorObj = {
|
|
||||||
forever: () => void,
|
|
||||||
never: () => void,
|
|
||||||
using: <T>(handler: () => T) => T,
|
|
||||||
invalidate: <T>(handler: () => T) => T,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CacheEntry<ResultT, SideChannel> = Array<{
|
export type CacheEntry<ResultT, SideChannel> = Array<{
|
||||||
value: ResultT,
|
value: ResultT;
|
||||||
valid: SideChannel => Handler<boolean>,
|
valid: (channel: SideChannel) => Handler<boolean>;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
const synchronize = <ArgsT, ResultT>(
|
const synchronize = <ArgsT extends any[], ResultT>(
|
||||||
gen: (...ArgsT) => Handler<ResultT>,
|
gen: (...args: ArgsT) => Handler<ResultT>,
|
||||||
// $FlowIssue https://github.com/facebook/flow/issues/7279
|
|
||||||
): ((...args: ArgsT) => ResultT) => {
|
): ((...args: ArgsT) => ResultT) => {
|
||||||
return gensync(gen).sync;
|
return gensync(gen).sync;
|
||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line require-yield, no-unused-vars
|
// eslint-disable-next-line require-yield
|
||||||
function* genTrue(data: any) {
|
function* genTrue() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeWeakCache<ArgT, ResultT, SideChannel>(
|
export function makeWeakCache<ArgT extends object, ResultT, SideChannel>(
|
||||||
handler: (ArgT, CacheConfigurator<SideChannel>) => Handler<ResultT> | ResultT,
|
handler: (
|
||||||
): (ArgT, SideChannel) => Handler<ResultT> {
|
arg: ArgT,
|
||||||
return makeCachedFunction<ArgT, ResultT, SideChannel, *>(WeakMap, handler);
|
cache: CacheConfigurator<SideChannel>,
|
||||||
|
) => Handler<ResultT> | ResultT,
|
||||||
|
): (arg: ArgT, data: SideChannel) => Handler<ResultT> {
|
||||||
|
return makeCachedFunction<ArgT, ResultT, SideChannel>(WeakMap, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeWeakCacheSync<ArgT, ResultT, SideChannel>(
|
export function makeWeakCacheSync<ArgT extends object, ResultT, SideChannel>(
|
||||||
handler: (ArgT, CacheConfigurator<SideChannel>) => ResultT,
|
handler: (arg: ArgT, cache?: CacheConfigurator<SideChannel>) => ResultT,
|
||||||
): (ArgT, SideChannel) => ResultT {
|
): (arg: ArgT, data?: SideChannel) => ResultT {
|
||||||
return synchronize<[ArgT, SideChannel], ResultT>(
|
return synchronize<[ArgT, SideChannel], ResultT>(
|
||||||
makeWeakCache<ArgT, ResultT, SideChannel>(handler),
|
makeWeakCache<ArgT, ResultT, SideChannel>(handler),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeStrongCache<ArgT, ResultT, SideChannel>(
|
export function makeStrongCache<ArgT, ResultT, SideChannel>(
|
||||||
handler: (ArgT, CacheConfigurator<SideChannel>) => Handler<ResultT> | ResultT,
|
handler: (
|
||||||
): (ArgT, SideChannel) => Handler<ResultT> {
|
arg: ArgT,
|
||||||
return makeCachedFunction<ArgT, ResultT, SideChannel, *>(Map, handler);
|
cache: CacheConfigurator<SideChannel>,
|
||||||
|
) => Handler<ResultT> | ResultT,
|
||||||
|
): (arg: ArgT, data: SideChannel) => Handler<ResultT> {
|
||||||
|
return makeCachedFunction<ArgT, ResultT, SideChannel>(Map, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeStrongCacheSync<ArgT, ResultT, SideChannel>(
|
export function makeStrongCacheSync<ArgT, ResultT, SideChannel>(
|
||||||
handler: (ArgT, CacheConfigurator<SideChannel>) => ResultT,
|
handler: (arg: ArgT, cache?: CacheConfigurator<SideChannel>) => ResultT,
|
||||||
): (ArgT, SideChannel) => ResultT {
|
): (arg: ArgT, data?: SideChannel) => ResultT {
|
||||||
return synchronize<[ArgT, SideChannel], ResultT>(
|
return synchronize<[ArgT, SideChannel], ResultT>(
|
||||||
makeStrongCache<ArgT, ResultT, SideChannel>(handler),
|
makeStrongCache<ArgT, ResultT, SideChannel>(handler),
|
||||||
);
|
);
|
||||||
@ -96,13 +96,16 @@ export function makeStrongCacheSync<ArgT, ResultT, SideChannel>(
|
|||||||
* 6. Store the result in the cache
|
* 6. Store the result in the cache
|
||||||
* 7. RETURN the result
|
* 7. RETURN the result
|
||||||
*/
|
*/
|
||||||
function makeCachedFunction<ArgT, ResultT, SideChannel, Cache: *>(
|
function makeCachedFunction<ArgT, ResultT, SideChannel>(
|
||||||
CallCache: Class<Cache>,
|
CallCache: new <Cached>() => CacheMap<ArgT, Cached, SideChannel>,
|
||||||
handler: (ArgT, CacheConfigurator<SideChannel>) => Handler<ResultT> | ResultT,
|
handler: (
|
||||||
): (ArgT, SideChannel) => Handler<ResultT> {
|
arg: ArgT,
|
||||||
const callCacheSync = new CallCache();
|
cache: CacheConfigurator<SideChannel>,
|
||||||
const callCacheAsync = new CallCache();
|
) => Handler<ResultT> | ResultT,
|
||||||
const futureCache = new CallCache();
|
): (arg: ArgT, data: SideChannel) => Handler<ResultT> {
|
||||||
|
const callCacheSync = new CallCache<ResultT>();
|
||||||
|
const callCacheAsync = new CallCache<ResultT>();
|
||||||
|
const futureCache = new CallCache<Lock<ResultT>>();
|
||||||
|
|
||||||
return function* cachedFunction(arg: ArgT, data: SideChannel) {
|
return function* cachedFunction(arg: ArgT, data: SideChannel) {
|
||||||
const asyncContext = yield* isAsync();
|
const asyncContext = yield* isAsync();
|
||||||
@ -121,19 +124,17 @@ function makeCachedFunction<ArgT, ResultT, SideChannel, Cache: *>(
|
|||||||
|
|
||||||
const handlerResult: Handler<ResultT> | ResultT = handler(arg, cache);
|
const handlerResult: Handler<ResultT> | ResultT = handler(arg, cache);
|
||||||
|
|
||||||
let finishLock: ?Lock<ResultT>;
|
let finishLock: Lock<ResultT>;
|
||||||
let value: ResultT;
|
let value: ResultT;
|
||||||
|
|
||||||
if (isIterableIterator(handlerResult)) {
|
if (isIterableIterator(handlerResult)) {
|
||||||
// Flow refines handlerResult to Generator<any, any, any>
|
const gen = handlerResult as Generator<unknown, ResultT, unknown>;
|
||||||
const gen = (handlerResult: Generator<*, ResultT, *>);
|
|
||||||
|
|
||||||
value = yield* onFirstPause(gen, () => {
|
value = yield* onFirstPause(gen, () => {
|
||||||
finishLock = setupAsyncLocks(cache, futureCache, arg);
|
finishLock = setupAsyncLocks(cache, futureCache, arg);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// $FlowIgnore doesn't refine handlerResult to ResultT
|
value = handlerResult;
|
||||||
value = (handlerResult: ResultT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFunctionCache(callCache, cache, arg, value);
|
updateFunctionCache(callCache, cache, arg, value);
|
||||||
@ -149,19 +150,14 @@ function makeCachedFunction<ArgT, ResultT, SideChannel, Cache: *>(
|
|||||||
|
|
||||||
type CacheMap<ArgT, ResultT, SideChannel> =
|
type CacheMap<ArgT, ResultT, SideChannel> =
|
||||||
| Map<ArgT, CacheEntry<ResultT, SideChannel>>
|
| Map<ArgT, CacheEntry<ResultT, SideChannel>>
|
||||||
|
// @ts-expect-error todo(flow->ts): add `extends object` constraint to ArgT
|
||||||
| WeakMap<ArgT, CacheEntry<ResultT, SideChannel>>;
|
| WeakMap<ArgT, CacheEntry<ResultT, SideChannel>>;
|
||||||
|
|
||||||
function* getCachedValue<
|
function* getCachedValue<ArgT, ResultT, SideChannel>(
|
||||||
ArgT,
|
cache: CacheMap<ArgT, ResultT, SideChannel>,
|
||||||
ResultT,
|
|
||||||
SideChannel,
|
|
||||||
// $FlowIssue https://github.com/facebook/flow/issues/4528
|
|
||||||
Cache: CacheMap<ArgT, ResultT, SideChannel>,
|
|
||||||
>(
|
|
||||||
cache: Cache,
|
|
||||||
arg: ArgT,
|
arg: ArgT,
|
||||||
data: SideChannel,
|
data: SideChannel,
|
||||||
): Handler<{ valid: true, value: ResultT } | { valid: false, value: null }> {
|
): Handler<{ valid: true; value: ResultT } | { valid: false; value: null }> {
|
||||||
const cachedValue: CacheEntry<ResultT, SideChannel> | void = cache.get(arg);
|
const cachedValue: CacheEntry<ResultT, SideChannel> | void = cache.get(arg);
|
||||||
|
|
||||||
if (cachedValue) {
|
if (cachedValue) {
|
||||||
@ -179,7 +175,7 @@ function* getCachedValueOrWait<ArgT, ResultT, SideChannel>(
|
|||||||
futureCache: CacheMap<ArgT, Lock<ResultT>, SideChannel>,
|
futureCache: CacheMap<ArgT, Lock<ResultT>, SideChannel>,
|
||||||
arg: ArgT,
|
arg: ArgT,
|
||||||
data: SideChannel,
|
data: SideChannel,
|
||||||
): Handler<{ valid: true, value: ResultT } | { valid: false, value: null }> {
|
): Handler<{ valid: true; value: ResultT } | { valid: false; value: null }> {
|
||||||
const cached = yield* getCachedValue(callCache, arg, data);
|
const cached = yield* getCachedValue(callCache, arg, data);
|
||||||
if (cached.valid) {
|
if (cached.valid) {
|
||||||
return cached;
|
return cached;
|
||||||
@ -212,8 +208,7 @@ function updateFunctionCache<
|
|||||||
ArgT,
|
ArgT,
|
||||||
ResultT,
|
ResultT,
|
||||||
SideChannel,
|
SideChannel,
|
||||||
// $FlowIssue https://github.com/facebook/flow/issues/4528
|
Cache extends CacheMap<ArgT, ResultT, SideChannel>
|
||||||
Cache: CacheMap<ArgT, ResultT, SideChannel>,
|
|
||||||
>(
|
>(
|
||||||
cache: Cache,
|
cache: Cache,
|
||||||
config: CacheConfigurator<SideChannel>,
|
config: CacheConfigurator<SideChannel>,
|
||||||
@ -253,7 +248,9 @@ class CacheConfigurator<SideChannel = void> {
|
|||||||
|
|
||||||
_configured: boolean = false;
|
_configured: boolean = false;
|
||||||
|
|
||||||
_pairs: Array<[mixed, (SideChannel) => Handler<mixed>]> = [];
|
_pairs: Array<
|
||||||
|
[cachedValue: unknown, handler: (data: SideChannel) => Handler<unknown>]
|
||||||
|
> = [];
|
||||||
|
|
||||||
_data: SideChannel;
|
_data: SideChannel;
|
||||||
|
|
||||||
@ -294,7 +291,7 @@ class CacheConfigurator<SideChannel = void> {
|
|||||||
this._configured = true;
|
this._configured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
using<T>(handler: SideChannel => T): T {
|
using<T>(handler: (data: SideChannel) => T): T {
|
||||||
if (!this._active) {
|
if (!this._active) {
|
||||||
throw new Error("Cannot change caching after evaluation has completed.");
|
throw new Error("Cannot change caching after evaluation has completed.");
|
||||||
}
|
}
|
||||||
@ -313,7 +310,8 @@ class CacheConfigurator<SideChannel = void> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (isThenable(key)) {
|
if (isThenable(key)) {
|
||||||
return key.then((key: mixed) => {
|
// @ts-expect-error todo(flow->ts): improve function return type annotation
|
||||||
|
return key.then((key: unknown) => {
|
||||||
this._pairs.push([key, fn]);
|
this._pairs.push([key, fn]);
|
||||||
return key;
|
return key;
|
||||||
});
|
});
|
||||||
@ -323,12 +321,12 @@ class CacheConfigurator<SideChannel = void> {
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidate<T>(handler: SideChannel => T): T {
|
invalidate<T>(handler: (data: SideChannel) => T): T {
|
||||||
this._invalidate = true;
|
this._invalidate = true;
|
||||||
return this.using(handler);
|
return this.using(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
validator(): SideChannel => Handler<boolean> {
|
validator(): (data: SideChannel) => Handler<boolean> {
|
||||||
const pairs = this._pairs;
|
const pairs = this._pairs;
|
||||||
return function* (data: SideChannel) {
|
return function* (data: SideChannel) {
|
||||||
for (const [key, fn] of pairs) {
|
for (const [key, fn] of pairs) {
|
||||||
@ -364,7 +362,7 @@ function makeSimpleConfigurator(
|
|||||||
cacheFn.using = cb => cache.using(() => assertSimpleType(cb()));
|
cacheFn.using = cb => cache.using(() => assertSimpleType(cb()));
|
||||||
cacheFn.invalidate = cb => cache.invalidate(() => assertSimpleType(cb()));
|
cacheFn.invalidate = cb => cache.invalidate(() => assertSimpleType(cb()));
|
||||||
|
|
||||||
return (cacheFn: any);
|
return cacheFn as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Types are limited here so that in the future these values can be used
|
// Types are limited here so that in the future these values can be used
|
||||||
@ -376,7 +374,7 @@ export type SimpleType =
|
|||||||
| null
|
| null
|
||||||
| void
|
| void
|
||||||
| Promise<SimpleType>;
|
| Promise<SimpleType>;
|
||||||
export function assertSimpleType(value: mixed): SimpleType {
|
export function assertSimpleType(value: unknown): SimpleType {
|
||||||
if (isThenable(value)) {
|
if (isThenable(value)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`You appear to be using an async cache handler, ` +
|
`You appear to be using an async cache handler, ` +
|
||||||
@ -397,6 +395,7 @@ export function assertSimpleType(value: mixed): SimpleType {
|
|||||||
"Cache keys must be either string, boolean, number, null, or undefined.",
|
"Cache keys must be either string, boolean, number, null, or undefined.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// @ts-expect-error todo(flow->ts) value is still typed as unknown, also assert function typically should not return a value
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,14 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import buildDebug from "debug";
|
import buildDebug from "debug";
|
||||||
import type { Handler } from "gensync";
|
import type { Handler } from "gensync";
|
||||||
import {
|
import { validate } from "./validation/options";
|
||||||
validate,
|
import type {
|
||||||
type ValidatedOptions,
|
ValidatedOptions,
|
||||||
type IgnoreList,
|
IgnoreList,
|
||||||
type ConfigApplicableTest,
|
ConfigApplicableTest,
|
||||||
type BabelrcSearch,
|
BabelrcSearch,
|
||||||
type CallerMetadata,
|
CallerMetadata,
|
||||||
|
IgnoreItem,
|
||||||
} from "./validation/options";
|
} from "./validation/options";
|
||||||
import pathPatternToRegex from "./pattern-to-regex";
|
import pathPatternToRegex from "./pattern-to-regex";
|
||||||
import { ConfigPrinter, ChainFormatter } from "./printer";
|
import { ConfigPrinter, ChainFormatter } from "./printer";
|
||||||
@ -21,41 +20,41 @@ import {
|
|||||||
findRelativeConfig,
|
findRelativeConfig,
|
||||||
findRootConfig,
|
findRootConfig,
|
||||||
loadConfig,
|
loadConfig,
|
||||||
type ConfigFile,
|
|
||||||
type IgnoreFile,
|
|
||||||
type FilePackageData,
|
|
||||||
} from "./files";
|
} from "./files";
|
||||||
|
import type { ConfigFile, IgnoreFile, FilePackageData } from "./files";
|
||||||
|
|
||||||
import { makeWeakCacheSync, makeStrongCacheSync } from "./caching";
|
import { makeWeakCacheSync, makeStrongCacheSync } from "./caching";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createCachedDescriptors,
|
createCachedDescriptors,
|
||||||
createUncachedDescriptors,
|
createUncachedDescriptors,
|
||||||
type UnloadedDescriptor,
|
} from "./config-descriptors";
|
||||||
type OptionsAndDescriptors,
|
import type {
|
||||||
type ValidatedFile,
|
UnloadedDescriptor,
|
||||||
|
OptionsAndDescriptors,
|
||||||
|
ValidatedFile,
|
||||||
} from "./config-descriptors";
|
} from "./config-descriptors";
|
||||||
|
|
||||||
export type ConfigChain = {
|
export type ConfigChain = {
|
||||||
plugins: Array<UnloadedDescriptor>,
|
plugins: Array<UnloadedDescriptor>;
|
||||||
presets: Array<UnloadedDescriptor>,
|
presets: Array<UnloadedDescriptor>;
|
||||||
options: Array<ValidatedOptions>,
|
options: Array<ValidatedOptions>;
|
||||||
files: Set<string>,
|
files: Set<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PresetInstance = {
|
export type PresetInstance = {
|
||||||
options: ValidatedOptions,
|
options: ValidatedOptions;
|
||||||
alias: string,
|
alias: string;
|
||||||
dirname: string,
|
dirname: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ConfigContext = {
|
export type ConfigContext = {
|
||||||
filename: string | void,
|
filename: string | void;
|
||||||
cwd: string,
|
cwd: string;
|
||||||
root: string,
|
root: string;
|
||||||
envName: string,
|
envName: string;
|
||||||
caller: CallerMetadata | void,
|
caller: CallerMetadata | void;
|
||||||
showConfig: boolean,
|
showConfig: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,7 +62,7 @@ export type ConfigContext = {
|
|||||||
*/
|
*/
|
||||||
export function* buildPresetChain(
|
export function* buildPresetChain(
|
||||||
arg: PresetInstance,
|
arg: PresetInstance,
|
||||||
context: *,
|
context: any,
|
||||||
): Handler<ConfigChain | null> {
|
): Handler<ConfigChain | null> {
|
||||||
const chain = yield* buildPresetChainWalker(arg, context);
|
const chain = yield* buildPresetChainWalker(arg, context);
|
||||||
if (!chain) return null;
|
if (!chain) return null;
|
||||||
@ -76,10 +75,7 @@ export function* buildPresetChain(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const buildPresetChainWalker: (
|
export const buildPresetChainWalker = makeChainWalker<PresetInstance>({
|
||||||
arg: PresetInstance,
|
|
||||||
context: *,
|
|
||||||
) => * = makeChainWalker({
|
|
||||||
root: preset => loadPresetDescriptors(preset),
|
root: preset => loadPresetDescriptors(preset),
|
||||||
env: (preset, envName) => loadPresetEnvDescriptors(preset)(envName),
|
env: (preset, envName) => loadPresetEnvDescriptors(preset)(envName),
|
||||||
overrides: (preset, index) => loadPresetOverridesDescriptors(preset)(index),
|
overrides: (preset, index) => loadPresetOverridesDescriptors(preset)(index),
|
||||||
@ -128,11 +124,11 @@ const loadPresetOverridesEnvDescriptors = makeWeakCacheSync(
|
|||||||
|
|
||||||
export type FileHandling = "transpile" | "ignored" | "unsupported";
|
export type FileHandling = "transpile" | "ignored" | "unsupported";
|
||||||
export type RootConfigChain = ConfigChain & {
|
export type RootConfigChain = ConfigChain & {
|
||||||
babelrc: ConfigFile | void,
|
babelrc: ConfigFile | void;
|
||||||
config: ConfigFile | void,
|
config: ConfigFile | void;
|
||||||
ignore: IgnoreFile | void,
|
ignore: IgnoreFile | void;
|
||||||
fileHandling: FileHandling,
|
fileHandling: FileHandling;
|
||||||
files: Set<string>,
|
files: Set<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -257,7 +253,6 @@ export function* buildRootChain(
|
|||||||
|
|
||||||
if (context.showConfig) {
|
if (context.showConfig) {
|
||||||
console.log(
|
console.log(
|
||||||
// $FlowIgnore: context.showConfig implies context.filename is not null
|
|
||||||
`Babel configs on "${context.filename}" (ascending priority):\n` +
|
`Babel configs on "${context.filename}" (ascending priority):\n` +
|
||||||
// print config by the order of ascending priority
|
// print config by the order of ascending priority
|
||||||
[configReport, babelRcReport, programmaticReport]
|
[configReport, babelRcReport, programmaticReport]
|
||||||
@ -288,7 +283,7 @@ export function* buildRootChain(
|
|||||||
function babelrcLoadEnabled(
|
function babelrcLoadEnabled(
|
||||||
context: ConfigContext,
|
context: ConfigContext,
|
||||||
pkgData: FilePackageData,
|
pkgData: FilePackageData,
|
||||||
babelrcRoots: BabelrcSearch | void,
|
babelrcRoots: BabelrcSearch | undefined,
|
||||||
babelrcRootsDirectory: string,
|
babelrcRootsDirectory: string,
|
||||||
): boolean {
|
): boolean {
|
||||||
if (typeof babelrcRoots === "boolean") return babelrcRoots;
|
if (typeof babelrcRoots === "boolean") return babelrcRoots;
|
||||||
@ -302,7 +297,9 @@ function babelrcLoadEnabled(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let babelrcPatterns = babelrcRoots;
|
let babelrcPatterns = babelrcRoots;
|
||||||
if (!Array.isArray(babelrcPatterns)) babelrcPatterns = [babelrcPatterns];
|
if (!Array.isArray(babelrcPatterns)) {
|
||||||
|
babelrcPatterns = [babelrcPatterns as IgnoreItem];
|
||||||
|
}
|
||||||
babelrcPatterns = babelrcPatterns.map(pat => {
|
babelrcPatterns = babelrcPatterns.map(pat => {
|
||||||
return typeof pat === "string"
|
return typeof pat === "string"
|
||||||
? path.resolve(babelrcRootsDirectory, pat)
|
? path.resolve(babelrcRootsDirectory, pat)
|
||||||
@ -374,7 +371,7 @@ const loadProgrammaticChain = makeChainWalker({
|
|||||||
/**
|
/**
|
||||||
* Build a config chain for a given file.
|
* Build a config chain for a given file.
|
||||||
*/
|
*/
|
||||||
const loadFileChainWalker = makeChainWalker({
|
const loadFileChainWalker = makeChainWalker<ValidatedFile>({
|
||||||
root: file => loadFileDescriptors(file),
|
root: file => loadFileDescriptors(file),
|
||||||
env: (file, envName) => loadFileEnvDescriptors(file)(envName),
|
env: (file, envName) => loadFileEnvDescriptors(file)(envName),
|
||||||
overrides: (file, index) => loadFileOverridesDescriptors(file)(index),
|
overrides: (file, index) => loadFileOverridesDescriptors(file)(index),
|
||||||
@ -499,36 +496,46 @@ function buildOverrideEnvDescriptors(
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeChainWalker<ArgT: { options: ValidatedOptions, dirname: string }>({
|
function makeChainWalker<
|
||||||
|
ArgT extends { options: ValidatedOptions; dirname: string }
|
||||||
|
>({
|
||||||
root,
|
root,
|
||||||
env,
|
env,
|
||||||
overrides,
|
overrides,
|
||||||
overridesEnv,
|
overridesEnv,
|
||||||
createLogger,
|
createLogger,
|
||||||
}: {|
|
}: {
|
||||||
root: ArgT => OptionsAndDescriptors,
|
root: (configEntry: ArgT) => OptionsAndDescriptors;
|
||||||
env: (ArgT, string) => OptionsAndDescriptors | null,
|
env: (configEntry: ArgT, env: string) => OptionsAndDescriptors | null;
|
||||||
overrides: (ArgT, number) => OptionsAndDescriptors,
|
overrides: (configEntry: ArgT, index: number) => OptionsAndDescriptors;
|
||||||
overridesEnv: (ArgT, number, string) => OptionsAndDescriptors | null,
|
overridesEnv: (
|
||||||
|
configEntry: ArgT,
|
||||||
|
index: number,
|
||||||
|
env: string,
|
||||||
|
) => OptionsAndDescriptors | null;
|
||||||
createLogger: (
|
createLogger: (
|
||||||
ArgT,
|
configEntry: ArgT,
|
||||||
ConfigContext,
|
context: ConfigContext,
|
||||||
ConfigPrinter | void,
|
printer: ConfigPrinter | void,
|
||||||
) => (OptionsAndDescriptors, ?number, ?string) => void,
|
) => (
|
||||||
|}): (
|
opts: OptionsAndDescriptors,
|
||||||
ArgT,
|
index?: number | null,
|
||||||
ConfigContext,
|
env?: string | null,
|
||||||
files?: Set<ConfigFile> | void,
|
) => void;
|
||||||
baseLogger: ConfigPrinter | void,
|
}): (
|
||||||
|
configEntry: ArgT,
|
||||||
|
context: ConfigContext,
|
||||||
|
files?: Set<ConfigFile>,
|
||||||
|
baseLogger?: ConfigPrinter,
|
||||||
) => Handler<ConfigChain | null> {
|
) => Handler<ConfigChain | null> {
|
||||||
return function* (input, context, files = new Set(), baseLogger) {
|
return function* (input, context, files = new Set(), baseLogger) {
|
||||||
const { dirname } = input;
|
const { dirname } = input;
|
||||||
|
|
||||||
const flattenedConfigs: Array<{|
|
const flattenedConfigs: Array<{
|
||||||
config: OptionsAndDescriptors,
|
config: OptionsAndDescriptors;
|
||||||
index: ?number,
|
index: number | undefined | null;
|
||||||
envName: ?string,
|
envName: string | undefined | null;
|
||||||
|}> = [];
|
}> = [];
|
||||||
|
|
||||||
const rootOpts = root(input);
|
const rootOpts = root(input);
|
||||||
if (configIsApplicable(rootOpts, dirname, context)) {
|
if (configIsApplicable(rootOpts, dirname, context)) {
|
||||||
@ -612,7 +619,7 @@ function* mergeExtendsChain(
|
|||||||
dirname: string,
|
dirname: string,
|
||||||
context: ConfigContext,
|
context: ConfigContext,
|
||||||
files: Set<ConfigFile>,
|
files: Set<ConfigFile>,
|
||||||
baseLogger: ConfigPrinter | void,
|
baseLogger?: ConfigPrinter,
|
||||||
): Handler<boolean> {
|
): Handler<boolean> {
|
||||||
if (opts.extends === undefined) return true;
|
if (opts.extends === undefined) return true;
|
||||||
|
|
||||||
@ -708,7 +715,7 @@ function dedupDescriptors(
|
|||||||
): Array<UnloadedDescriptor> {
|
): Array<UnloadedDescriptor> {
|
||||||
const map: Map<
|
const map: Map<
|
||||||
Function,
|
Function,
|
||||||
Map<string | void, { value: UnloadedDescriptor }>,
|
Map<string | void, { value: UnloadedDescriptor }>
|
||||||
> = new Map();
|
> = new Map();
|
||||||
|
|
||||||
const descriptors = [];
|
const descriptors = [];
|
||||||
@ -773,8 +780,8 @@ function configFieldIsApplicable(
|
|||||||
*/
|
*/
|
||||||
function shouldIgnore(
|
function shouldIgnore(
|
||||||
context: ConfigContext,
|
context: ConfigContext,
|
||||||
ignore: ?IgnoreList,
|
ignore: IgnoreList | undefined | null,
|
||||||
only: ?IgnoreList,
|
only: IgnoreList | undefined | null,
|
||||||
dirname: string,
|
dirname: string,
|
||||||
): boolean {
|
): boolean {
|
||||||
if (ignore && matchesPatterns(context, ignore, dirname)) {
|
if (ignore && matchesPatterns(context, ignore, dirname)) {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// @flow
|
import gensync from "gensync";
|
||||||
|
|
||||||
import gensync, { type Handler } from "gensync";
|
import type { Handler } from "gensync";
|
||||||
|
|
||||||
import { loadPlugin, loadPreset } from "./files";
|
import { loadPlugin, loadPreset } from "./files";
|
||||||
|
|
||||||
@ -10,8 +10,8 @@ import {
|
|||||||
makeWeakCacheSync,
|
makeWeakCacheSync,
|
||||||
makeStrongCacheSync,
|
makeStrongCacheSync,
|
||||||
makeStrongCache,
|
makeStrongCache,
|
||||||
type CacheConfigurator,
|
|
||||||
} from "./caching";
|
} from "./caching";
|
||||||
|
import type { CacheConfigurator } from "./caching";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ValidatedOptions,
|
ValidatedOptions,
|
||||||
@ -25,25 +25,25 @@ import { resolveBrowserslistConfigFile } from "./resolve-targets";
|
|||||||
// for the plugins and presets so we don't load the plugins/presets unless
|
// for the plugins and presets so we don't load the plugins/presets unless
|
||||||
// the options object actually ends up being applicable.
|
// the options object actually ends up being applicable.
|
||||||
export type OptionsAndDescriptors = {
|
export type OptionsAndDescriptors = {
|
||||||
options: ValidatedOptions,
|
options: ValidatedOptions;
|
||||||
plugins: () => Handler<Array<UnloadedDescriptor>>,
|
plugins: () => Handler<Array<UnloadedDescriptor>>;
|
||||||
presets: () => Handler<Array<UnloadedDescriptor>>,
|
presets: () => Handler<Array<UnloadedDescriptor>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents a plugin or presets at a given location in a config object.
|
// Represents a plugin or presets at a given location in a config object.
|
||||||
// At this point these have been resolved to a specific object or function,
|
// At this point these have been resolved to a specific object or function,
|
||||||
// but have not yet been executed to call functions with options.
|
// but have not yet been executed to call functions with options.
|
||||||
export type UnloadedDescriptor = {
|
export type UnloadedDescriptor = {
|
||||||
name: string | void,
|
name: string | undefined;
|
||||||
value: {} | Function,
|
value: any | Function;
|
||||||
options: {} | void | false,
|
options: {} | undefined | false;
|
||||||
dirname: string,
|
dirname: string;
|
||||||
alias: string,
|
alias: string;
|
||||||
ownPass?: boolean,
|
ownPass?: boolean;
|
||||||
file?: {
|
file?: {
|
||||||
request: string,
|
request: string;
|
||||||
resolved: string,
|
resolved: string;
|
||||||
} | void,
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
function isEqualDescriptor(
|
function isEqualDescriptor(
|
||||||
@ -63,9 +63,9 @@ function isEqualDescriptor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ValidatedFile = {
|
export type ValidatedFile = {
|
||||||
filepath: string,
|
filepath: string;
|
||||||
dirname: string,
|
dirname: string;
|
||||||
options: ValidatedOptions,
|
options: ValidatedOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line require-yield
|
// eslint-disable-next-line require-yield
|
||||||
@ -100,10 +100,13 @@ export function createCachedDescriptors(
|
|||||||
return {
|
return {
|
||||||
options: optionsWithResolvedBrowserslistConfigFile(options, dirname),
|
options: optionsWithResolvedBrowserslistConfigFile(options, dirname),
|
||||||
plugins: plugins
|
plugins: plugins
|
||||||
? () => createCachedPluginDescriptors(plugins, dirname)(alias)
|
? () =>
|
||||||
|
// @ts-expect-error todo(flow->ts) ts complains about incorrect arguments
|
||||||
|
createCachedPluginDescriptors(plugins, dirname)(alias)
|
||||||
: () => handlerOf([]),
|
: () => handlerOf([]),
|
||||||
presets: presets
|
presets: presets
|
||||||
? () =>
|
? () =>
|
||||||
|
// @ts-expect-error todo(flow->ts) ts complains about incorrect arguments
|
||||||
createCachedPresetDescriptors(presets, dirname)(alias)(
|
createCachedPresetDescriptors(presets, dirname)(alias)(
|
||||||
!!passPerPreset,
|
!!passPerPreset,
|
||||||
)
|
)
|
||||||
@ -295,9 +298,9 @@ export function* createDescriptor(
|
|||||||
alias,
|
alias,
|
||||||
ownPass,
|
ownPass,
|
||||||
}: {
|
}: {
|
||||||
type?: "plugin" | "preset",
|
type?: "plugin" | "preset";
|
||||||
alias: string,
|
alias: string;
|
||||||
ownPass?: boolean,
|
ownPass?: boolean;
|
||||||
},
|
},
|
||||||
): Handler<UnloadedDescriptor> {
|
): Handler<UnloadedDescriptor> {
|
||||||
const desc = getItemDescriptor(pair);
|
const desc = getItemDescriptor(pair);
|
||||||
@ -307,7 +310,8 @@ export function* createDescriptor(
|
|||||||
|
|
||||||
let name;
|
let name;
|
||||||
let options;
|
let options;
|
||||||
let value = pair;
|
// todo(flow->ts) better type annotation
|
||||||
|
let value: any = pair;
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
if (value.length === 3) {
|
if (value.length === 3) {
|
||||||
[value, options, name] = value;
|
[value, options, name] = value;
|
||||||
|
|||||||
@ -1,15 +1,12 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import buildDebug from "debug";
|
import buildDebug from "debug";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import json5 from "json5";
|
import json5 from "json5";
|
||||||
import gensync, { type Handler } from "gensync";
|
import gensync from "gensync";
|
||||||
import {
|
import type { Handler } from "gensync";
|
||||||
makeStrongCache,
|
import { makeStrongCache, makeWeakCacheSync } from "../caching";
|
||||||
makeWeakCacheSync,
|
import type { CacheConfigurator } from "../caching";
|
||||||
type CacheConfigurator,
|
import { makeConfigAPI } from "../helpers/config-api";
|
||||||
} from "../caching";
|
import type { ConfigAPI } from "../helpers/config-api";
|
||||||
import { makeConfigAPI, type ConfigAPI } from "../helpers/config-api";
|
|
||||||
import { makeStaticFileCache } from "./utils";
|
import { makeStaticFileCache } from "./utils";
|
||||||
import loadCjsOrMjsDefault from "./module-types";
|
import loadCjsOrMjsDefault from "./module-types";
|
||||||
import pathPatternToRegex from "../pattern-to-regex";
|
import pathPatternToRegex from "../pattern-to-regex";
|
||||||
@ -19,8 +16,7 @@ import type { CallerMetadata } from "../validation/options";
|
|||||||
import * as fs from "../../gensync-utils/fs";
|
import * as fs from "../../gensync-utils/fs";
|
||||||
|
|
||||||
import { createRequire } from "module";
|
import { createRequire } from "module";
|
||||||
// $FlowIgnore - https://github.com/facebook/flow/issues/6913#issuecomment-662787504
|
const require = createRequire(import.meta.url);
|
||||||
const require = createRequire(import /*::("")*/.meta.url);
|
|
||||||
|
|
||||||
const debug = buildDebug("babel:config:loading:files:configuration");
|
const debug = buildDebug("babel:config:loading:files:configuration");
|
||||||
|
|
||||||
@ -75,8 +71,7 @@ export function* findRelativeConfig(
|
|||||||
envName,
|
envName,
|
||||||
caller,
|
caller,
|
||||||
packageData.pkg?.dirname === loc
|
packageData.pkg?.dirname === loc
|
||||||
? // $FlowIgnore - packageData.pkg is not null
|
? packageToBabelConfig(packageData.pkg as ConfigFile)
|
||||||
packageToBabelConfig((packageData.pkg: ConfigFile))
|
|
||||||
: null,
|
: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -107,7 +102,7 @@ function* loadOneConfig(
|
|||||||
dirname: string,
|
dirname: string,
|
||||||
envName: string,
|
envName: string,
|
||||||
caller: CallerMetadata | void,
|
caller: CallerMetadata | void,
|
||||||
previousConfig?: ConfigFile | null = null,
|
previousConfig: ConfigFile | null = null,
|
||||||
): Handler<ConfigFile | null> {
|
): Handler<ConfigFile | null> {
|
||||||
const configs = yield* gensync.all(
|
const configs = yield* gensync.all(
|
||||||
names.map(filename =>
|
names.map(filename =>
|
||||||
@ -166,8 +161,8 @@ const LOADING_CONFIGS = new Set();
|
|||||||
const readConfigJS = makeStrongCache(function* readConfigJS(
|
const readConfigJS = makeStrongCache(function* readConfigJS(
|
||||||
filepath: string,
|
filepath: string,
|
||||||
cache: CacheConfigurator<{
|
cache: CacheConfigurator<{
|
||||||
envName: string,
|
envName: string;
|
||||||
caller: CallerMetadata | void,
|
caller: CallerMetadata | void;
|
||||||
}>,
|
}>,
|
||||||
): Handler<ConfigFile | null> {
|
): Handler<ConfigFile | null> {
|
||||||
if (!fs.exists.sync(filepath)) {
|
if (!fs.exists.sync(filepath)) {
|
||||||
@ -189,14 +184,14 @@ const readConfigJS = makeStrongCache(function* readConfigJS(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let options: mixed;
|
let options: unknown;
|
||||||
try {
|
try {
|
||||||
LOADING_CONFIGS.add(filepath);
|
LOADING_CONFIGS.add(filepath);
|
||||||
options = (yield* loadCjsOrMjsDefault(
|
options = yield* loadCjsOrMjsDefault(
|
||||||
filepath,
|
filepath,
|
||||||
"You appear to be using a native ECMAScript module configuration " +
|
"You appear to be using a native ECMAScript module configuration " +
|
||||||
"file, which is only supported when running Babel asynchronously.",
|
"file, which is only supported when running Babel asynchronously.",
|
||||||
): mixed);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
err.message = `${filepath}: Error while loading config - ${err.message}`;
|
err.message = `${filepath}: Error while loading config - ${err.message}`;
|
||||||
throw err;
|
throw err;
|
||||||
@ -206,8 +201,12 @@ const readConfigJS = makeStrongCache(function* readConfigJS(
|
|||||||
|
|
||||||
let assertCache = false;
|
let assertCache = false;
|
||||||
if (typeof options === "function") {
|
if (typeof options === "function") {
|
||||||
yield* []; // if we want to make it possible to use async configs
|
// @ts-expect-error - if we want to make it possible to use async configs
|
||||||
options = ((options: any): (api: ConfigAPI) => {})(makeConfigAPI(cache));
|
yield* [];
|
||||||
|
|
||||||
|
options = ((options as any) as (api: ConfigAPI) => {})(
|
||||||
|
makeConfigAPI(cache),
|
||||||
|
);
|
||||||
|
|
||||||
assertCache = true;
|
assertCache = true;
|
||||||
}
|
}
|
||||||
@ -218,6 +217,7 @@ const readConfigJS = makeStrongCache(function* readConfigJS(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-expect-error todo(flow->ts)
|
||||||
if (typeof options.then === "function") {
|
if (typeof options.then === "function") {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`You appear to be using an async configuration, ` +
|
`You appear to be using an async configuration, ` +
|
||||||
@ -239,7 +239,7 @@ const readConfigJS = makeStrongCache(function* readConfigJS(
|
|||||||
|
|
||||||
const packageToBabelConfig = makeWeakCacheSync(
|
const packageToBabelConfig = makeWeakCacheSync(
|
||||||
(file: ConfigFile): ConfigFile | null => {
|
(file: ConfigFile): ConfigFile | null => {
|
||||||
const babel: mixed = file.options[("babel": string)];
|
const babel: unknown = file.options["babel"];
|
||||||
|
|
||||||
if (typeof babel === "undefined") return null;
|
if (typeof babel === "undefined") return null;
|
||||||
|
|
||||||
@ -255,30 +255,32 @@ const packageToBabelConfig = makeWeakCacheSync(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const readConfigJSON5 = makeStaticFileCache((filepath, content): ConfigFile => {
|
const readConfigJSON5 = makeStaticFileCache(
|
||||||
let options;
|
(filepath, content): ConfigFile => {
|
||||||
try {
|
let options;
|
||||||
options = json5.parse(content);
|
try {
|
||||||
} catch (err) {
|
options = json5.parse(content);
|
||||||
err.message = `${filepath}: Error while parsing config - ${err.message}`;
|
} catch (err) {
|
||||||
throw err;
|
err.message = `${filepath}: Error while parsing config - ${err.message}`;
|
||||||
}
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
if (!options) throw new Error(`${filepath}: No config detected`);
|
if (!options) throw new Error(`${filepath}: No config detected`);
|
||||||
|
|
||||||
if (typeof options !== "object") {
|
if (typeof options !== "object") {
|
||||||
throw new Error(`${filepath}: Config returned typeof ${typeof options}`);
|
throw new Error(`${filepath}: Config returned typeof ${typeof options}`);
|
||||||
}
|
}
|
||||||
if (Array.isArray(options)) {
|
if (Array.isArray(options)) {
|
||||||
throw new Error(`${filepath}: Expected config object but found array`);
|
throw new Error(`${filepath}: Expected config object but found array`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filepath,
|
filepath,
|
||||||
dirname: path.dirname(filepath),
|
dirname: path.dirname(filepath),
|
||||||
options,
|
options,
|
||||||
};
|
};
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const readIgnoreConfig = makeStaticFileCache((filepath, content) => {
|
const readIgnoreConfig = makeStaticFileCache((filepath, content) => {
|
||||||
const ignoreDir = path.dirname(filepath);
|
const ignoreDir = path.dirname(filepath);
|
||||||
@ -319,7 +321,7 @@ export function* resolveShowConfigPath(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function throwConfigError(): empty {
|
function throwConfigError(): never {
|
||||||
throw new Error(`\
|
throw new Error(`\
|
||||||
Caching was left unconfigured. Babel's plugins, presets, and .babelrc.js files can be configured
|
Caching was left unconfigured. Babel's plugins, presets, and .babelrc.js files can be configured
|
||||||
for various types of caching, using the first param of their handler functions:
|
for various types of caching, using the first param of their handler functions:
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// @flow
|
|
||||||
// We keep this in a separate file so that in older node versions, where
|
// We keep this in a separate file so that in older node versions, where
|
||||||
// import() isn't supported, we can try/catch around the require() call
|
// import() isn't supported, we can try/catch around the require() call
|
||||||
// when loading this file.
|
// when loading this file.
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import type { Handler } from "gensync";
|
import type { Handler } from "gensync";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
@ -15,7 +13,8 @@ export type { ConfigFile, IgnoreFile, RelativeConfig, FilePackageData };
|
|||||||
|
|
||||||
// eslint-disable-next-line require-yield
|
// eslint-disable-next-line require-yield
|
||||||
export function* findConfigUpwards(
|
export function* findConfigUpwards(
|
||||||
rootDir: string, // eslint-disable-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
rootDir: string,
|
||||||
): Handler<string | null> {
|
): Handler<string | null> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -32,18 +31,24 @@ export function* findPackageData(filepath: string): Handler<FilePackageData> {
|
|||||||
|
|
||||||
// eslint-disable-next-line require-yield
|
// eslint-disable-next-line require-yield
|
||||||
export function* findRelativeConfig(
|
export function* findRelativeConfig(
|
||||||
pkgData: FilePackageData, // eslint-disable-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
envName: string, // eslint-disable-line no-unused-vars
|
pkgData: FilePackageData,
|
||||||
caller: CallerMetadata | void, // eslint-disable-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
envName: string,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
caller: CallerMetadata | void,
|
||||||
): Handler<RelativeConfig> {
|
): Handler<RelativeConfig> {
|
||||||
return { pkg: null, config: null, ignore: null };
|
return { config: null, ignore: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line require-yield
|
// eslint-disable-next-line require-yield
|
||||||
export function* findRootConfig(
|
export function* findRootConfig(
|
||||||
dirname: string, // eslint-disable-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
envName: string, // eslint-disable-line no-unused-vars
|
dirname: string,
|
||||||
caller: CallerMetadata | void, // eslint-disable-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
envName: string,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
caller: CallerMetadata | void,
|
||||||
): Handler<ConfigFile | null> {
|
): Handler<ConfigFile | null> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -52,27 +57,30 @@ export function* findRootConfig(
|
|||||||
export function* loadConfig(
|
export function* loadConfig(
|
||||||
name: string,
|
name: string,
|
||||||
dirname: string,
|
dirname: string,
|
||||||
envName: string, // eslint-disable-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
caller: CallerMetadata | void, // eslint-disable-line no-unused-vars
|
envName: string,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
caller: CallerMetadata | void,
|
||||||
): Handler<ConfigFile> {
|
): Handler<ConfigFile> {
|
||||||
throw new Error(`Cannot load ${name} relative to ${dirname} in a browser`);
|
throw new Error(`Cannot load ${name} relative to ${dirname} in a browser`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line require-yield
|
// eslint-disable-next-line require-yield
|
||||||
export function* resolveShowConfigPath(
|
export function* resolveShowConfigPath(
|
||||||
dirname: string, // eslint-disable-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
dirname: string,
|
||||||
): Handler<string | null> {
|
): Handler<string | null> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ROOT_CONFIG_FILENAMES = [];
|
export const ROOT_CONFIG_FILENAMES = [];
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
export function resolvePlugin(name: string, dirname: string): string | null {
|
export function resolvePlugin(name: string, dirname: string): string | null {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
export function resolvePreset(name: string, dirname: string): string | null {
|
export function resolvePreset(name: string, dirname: string): string | null {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -80,7 +88,10 @@ export function resolvePreset(name: string, dirname: string): string | null {
|
|||||||
export function loadPlugin(
|
export function loadPlugin(
|
||||||
name: string,
|
name: string,
|
||||||
dirname: string,
|
dirname: string,
|
||||||
): Handler<{ filepath: string, value: mixed }> {
|
): Handler<{
|
||||||
|
filepath: string;
|
||||||
|
value: unknown;
|
||||||
|
}> {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Cannot load plugin ${name} relative to ${dirname} in a browser`,
|
`Cannot load plugin ${name} relative to ${dirname} in a browser`,
|
||||||
);
|
);
|
||||||
@ -89,7 +100,10 @@ export function loadPlugin(
|
|||||||
export function loadPreset(
|
export function loadPreset(
|
||||||
name: string,
|
name: string,
|
||||||
dirname: string,
|
dirname: string,
|
||||||
): Handler<{ filepath: string, value: mixed }> {
|
): Handler<{
|
||||||
|
filepath: string;
|
||||||
|
value: unknown;
|
||||||
|
}> {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Cannot load preset ${name} relative to ${dirname} in a browser`,
|
`Cannot load preset ${name} relative to ${dirname} in a browser`,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
// @flow
|
type indexBrowserType = typeof import("./index-browser");
|
||||||
|
type indexType = typeof import("./index");
|
||||||
import typeof * as indexBrowserType from "./index-browser";
|
|
||||||
import typeof * as indexType from "./index";
|
|
||||||
|
|
||||||
// Kind of gross, but essentially asserting that the exports of this module are the same as the
|
// Kind of gross, but essentially asserting that the exports of this module are the same as the
|
||||||
// exports of index-browser, since this file may be replaced at bundle time with index-browser.
|
// exports of index-browser, since this file may be replaced at bundle time with index-browser.
|
||||||
((({}: any): $Exact<indexBrowserType>): $Exact<indexType>);
|
((({} as any) as indexBrowserType) as indexType);
|
||||||
|
|
||||||
export { findPackageData } from "./package";
|
export { findPackageData } from "./package";
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export default function* loadCjsOrMjsDefault(
|
|||||||
asyncError: string,
|
asyncError: string,
|
||||||
// TODO(Babel 8): Remove this
|
// TODO(Babel 8): Remove this
|
||||||
fallbackToTranspiledModule: boolean = false,
|
fallbackToTranspiledModule: boolean = false,
|
||||||
): Handler<mixed> {
|
): Handler<unknown> {
|
||||||
switch (guessJSModuleType(filepath)) {
|
switch (guessJSModuleType(filepath)) {
|
||||||
case "cjs":
|
case "cjs":
|
||||||
return loadCjsDefault(filepath, fallbackToTranspiledModule);
|
return loadCjsDefault(filepath, fallbackToTranspiledModule);
|
||||||
@ -48,7 +48,7 @@ function guessJSModuleType(filename: string): "cjs" | "mjs" | "unknown" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadCjsDefault(filepath: string, fallbackToTranspiledModule: boolean) {
|
function loadCjsDefault(filepath: string, fallbackToTranspiledModule: boolean) {
|
||||||
const module = (require(filepath): mixed);
|
const module = require(filepath) as any;
|
||||||
return module?.__esModule
|
return module?.__esModule
|
||||||
? // TODO (Babel 8): Remove "module" and "undefined" fallback
|
? // TODO (Babel 8): Remove "module" and "undefined" fallback
|
||||||
module.default || (fallbackToTranspiledModule ? module : undefined)
|
module.default || (fallbackToTranspiledModule ? module : undefined)
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import type { Handler } from "gensync";
|
import type { Handler } from "gensync";
|
||||||
import { makeStaticFileCache } from "./utils";
|
import { makeStaticFileCache } from "./utils";
|
||||||
@ -39,7 +37,7 @@ const readConfigPackage = makeStaticFileCache(
|
|||||||
(filepath, content): ConfigFile => {
|
(filepath, content): ConfigFile => {
|
||||||
let options;
|
let options;
|
||||||
try {
|
try {
|
||||||
options = (JSON.parse(content): mixed);
|
options = JSON.parse(content) as unknown;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
err.message = `${filepath}: Error while parsing JSON - ${err.message}`;
|
err.message = `${filepath}: Error while parsing JSON - ${err.message}`;
|
||||||
throw err;
|
throw err;
|
||||||
|
|||||||
@ -1,17 +1,14 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file handles all logic for converting string-based configuration references into loaded objects.
|
* This file handles all logic for converting string-based configuration references into loaded objects.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import buildDebug from "debug";
|
import buildDebug from "debug";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { type Handler } from "gensync";
|
import type { Handler } from "gensync";
|
||||||
import loadCjsOrMjsDefault from "./module-types";
|
import loadCjsOrMjsDefault from "./module-types";
|
||||||
|
|
||||||
import { createRequire } from "module";
|
import { createRequire } from "module";
|
||||||
// $FlowIgnore - https://github.com/facebook/flow/issues/6913#issuecomment-662787504
|
const require = createRequire(import.meta.url);
|
||||||
const require = createRequire(import /*::("")*/.meta.url);
|
|
||||||
|
|
||||||
const debug = buildDebug("babel:config:loading:files:plugins");
|
const debug = buildDebug("babel:config:loading:files:plugins");
|
||||||
|
|
||||||
@ -35,7 +32,7 @@ export function resolvePreset(name: string, dirname: string): string | null {
|
|||||||
export function* loadPlugin(
|
export function* loadPlugin(
|
||||||
name: string,
|
name: string,
|
||||||
dirname: string,
|
dirname: string,
|
||||||
): Handler<{ filepath: string, value: mixed }> {
|
): Handler<{ filepath: string; value: unknown }> {
|
||||||
const filepath = resolvePlugin(name, dirname);
|
const filepath = resolvePlugin(name, dirname);
|
||||||
if (!filepath) {
|
if (!filepath) {
|
||||||
throw new Error(`Plugin ${name} not found relative to ${dirname}`);
|
throw new Error(`Plugin ${name} not found relative to ${dirname}`);
|
||||||
@ -50,7 +47,7 @@ export function* loadPlugin(
|
|||||||
export function* loadPreset(
|
export function* loadPreset(
|
||||||
name: string,
|
name: string,
|
||||||
dirname: string,
|
dirname: string,
|
||||||
): Handler<{ filepath: string, value: mixed }> {
|
): Handler<{ filepath: string; value: unknown }> {
|
||||||
const filepath = resolvePreset(name, dirname);
|
const filepath = resolvePreset(name, dirname);
|
||||||
if (!filepath) {
|
if (!filepath) {
|
||||||
throw new Error(`Preset ${name} not found relative to ${dirname}`);
|
throw new Error(`Preset ${name} not found relative to ${dirname}`);
|
||||||
@ -151,7 +148,7 @@ function resolveStandardizedName(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const LOADING_MODULES = new Set();
|
const LOADING_MODULES = new Set();
|
||||||
function* requireModule(type: string, name: string): Handler<mixed> {
|
function* requireModule(type: string, name: string): Handler<unknown> {
|
||||||
if (LOADING_MODULES.has(name)) {
|
if (LOADING_MODULES.has(name)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Reentrant ${type} detected trying to load "${name}". This module is not ignored ` +
|
`Reentrant ${type} detected trying to load "${name}". This module is not ignored ` +
|
||||||
@ -162,7 +159,7 @@ function* requireModule(type: string, name: string): Handler<mixed> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
LOADING_MODULES.add(name);
|
LOADING_MODULES.add(name);
|
||||||
return (yield* loadCjsOrMjsDefault(
|
return yield* loadCjsOrMjsDefault(
|
||||||
name,
|
name,
|
||||||
`You appear to be using a native ECMAScript module ${type}, ` +
|
`You appear to be using a native ECMAScript module ${type}, ` +
|
||||||
"which is only supported when running Babel asynchronously.",
|
"which is only supported when running Babel asynchronously.",
|
||||||
@ -171,7 +168,7 @@ function* requireModule(type: string, name: string): Handler<mixed> {
|
|||||||
// export.
|
// export.
|
||||||
// See packages/babel-core/test/fixtures/option-manager/presets/es2015_named.js
|
// See packages/babel-core/test/fixtures/option-manager/presets/es2015_named.js
|
||||||
true,
|
true,
|
||||||
): mixed);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
err.message = `[BABEL]: ${err.message} (While processing: ${name})`;
|
err.message = `[BABEL]: ${err.message} (While processing: ${name})`;
|
||||||
throw err;
|
throw err;
|
||||||
|
|||||||
@ -1,38 +1,32 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
export type ConfigFile = {
|
export type ConfigFile = {
|
||||||
filepath: string,
|
filepath: string;
|
||||||
dirname: string,
|
dirname: string;
|
||||||
options: {},
|
options: {};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IgnoreFile = {
|
export type IgnoreFile = {
|
||||||
filepath: string,
|
filepath: string;
|
||||||
dirname: string,
|
dirname: string;
|
||||||
ignore: Array<RegExp>,
|
ignore: Array<RegExp>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RelativeConfig = {
|
export type RelativeConfig = {
|
||||||
// The actual config, either from package.json#babel, .babelrc, or
|
// The actual config, either from package.json#babel, .babelrc, or
|
||||||
// .babelrc.js, if there was one.
|
// .babelrc.js, if there was one.
|
||||||
config: ConfigFile | null,
|
config: ConfigFile | null;
|
||||||
|
|
||||||
// The .babelignore, if there was one.
|
// The .babelignore, if there was one.
|
||||||
ignore: IgnoreFile | null,
|
ignore: IgnoreFile | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FilePackageData = {
|
export type FilePackageData = {
|
||||||
// The file in the package.
|
// The file in the package.
|
||||||
filepath: string,
|
filepath: string;
|
||||||
|
|
||||||
// Any ancestor directories of the file that are within the package.
|
// Any ancestor directories of the file that are within the package.
|
||||||
directories: Array<string>,
|
directories: Array<string>;
|
||||||
|
|
||||||
// The contents of the package.json. May not be found if the package just
|
// The contents of the package.json. May not be found if the package just
|
||||||
// terminated at a node_modules folder without finding one.
|
// terminated at a node_modules folder without finding one.
|
||||||
pkg: ConfigFile | null,
|
pkg: ConfigFile | null;
|
||||||
|
|
||||||
// True if a package.json or node_modules folder was found while traversing
|
// True if a package.json or node_modules folder was found while traversing
|
||||||
// the directory structure.
|
// the directory structure.
|
||||||
isPackage: boolean,
|
isPackage: boolean;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,17 +1,16 @@
|
|||||||
// @flow
|
import type { Handler } from "gensync";
|
||||||
|
|
||||||
import type { Gensync, Handler } from "gensync";
|
import { makeStrongCache } from "../caching";
|
||||||
|
import type { CacheConfigurator } from "../caching";
|
||||||
import { makeStrongCache, type CacheConfigurator } from "../caching";
|
|
||||||
import * as fs from "../../gensync-utils/fs";
|
import * as fs from "../../gensync-utils/fs";
|
||||||
import nodeFs from "fs";
|
import nodeFs from "fs";
|
||||||
|
|
||||||
export function makeStaticFileCache<T>(
|
export function makeStaticFileCache<T>(
|
||||||
fn: (string, string) => T,
|
fn: (filepath: string, contents: string) => T,
|
||||||
): Gensync<[string], T | null> {
|
) {
|
||||||
return (makeStrongCache(function* (
|
return makeStrongCache(function* (
|
||||||
filepath: string,
|
filepath: string,
|
||||||
cache: CacheConfigurator<?void>,
|
cache: CacheConfigurator<void>,
|
||||||
): Handler<null | T> {
|
): Handler<null | T> {
|
||||||
const cached = cache.invalidate(() => fileMtime(filepath));
|
const cached = cache.invalidate(() => fileMtime(filepath));
|
||||||
|
|
||||||
@ -20,7 +19,7 @@ export function makeStaticFileCache<T>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return fn(filepath, yield* fs.readFile(filepath, "utf8"));
|
return fn(filepath, yield* fs.readFile(filepath, "utf8"));
|
||||||
}): Gensync<any, *>);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function fileMtime(filepath: string): number | null {
|
function fileMtime(filepath: string): number | null {
|
||||||
|
|||||||
@ -1,32 +1,29 @@
|
|||||||
// @flow
|
import gensync from "gensync";
|
||||||
|
import type { Handler } from "gensync";
|
||||||
import gensync, { type Handler } from "gensync";
|
|
||||||
import { forwardAsync, maybeAsync, isThenable } from "../gensync-utils/async";
|
import { forwardAsync, maybeAsync, isThenable } from "../gensync-utils/async";
|
||||||
|
|
||||||
import { mergeOptions } from "./util";
|
import { mergeOptions } from "./util";
|
||||||
import * as context from "../index";
|
import * as context from "../index";
|
||||||
import Plugin from "./plugin";
|
import Plugin from "./plugin";
|
||||||
import { getItemDescriptor } from "./item";
|
import { getItemDescriptor } from "./item";
|
||||||
import {
|
import { buildPresetChain } from "./config-chain";
|
||||||
buildPresetChain,
|
import type {
|
||||||
type ConfigContext,
|
ConfigContext,
|
||||||
type ConfigChain,
|
ConfigChain,
|
||||||
type PresetInstance,
|
PresetInstance,
|
||||||
} from "./config-chain";
|
} from "./config-chain";
|
||||||
import type { UnloadedDescriptor } from "./config-descriptors";
|
import type { UnloadedDescriptor } from "./config-descriptors";
|
||||||
import traverse from "@babel/traverse";
|
import traverse from "@babel/traverse";
|
||||||
import {
|
import { makeWeakCache, makeWeakCacheSync } from "./caching";
|
||||||
makeWeakCache,
|
import type { CacheConfigurator } from "./caching";
|
||||||
makeWeakCacheSync,
|
|
||||||
type CacheConfigurator,
|
|
||||||
} from "./caching";
|
|
||||||
import {
|
import {
|
||||||
validate,
|
validate,
|
||||||
checkNoUnwrappedItemOptionPairs,
|
checkNoUnwrappedItemOptionPairs,
|
||||||
type PluginItem,
|
|
||||||
} from "./validation/options";
|
} from "./validation/options";
|
||||||
|
import type { PluginItem } from "./validation/options";
|
||||||
import { validatePluginObject } from "./validation/plugins";
|
import { validatePluginObject } from "./validation/plugins";
|
||||||
import { makePluginAPI, makePresetAPI } from "./helpers/config-api";
|
import { makePluginAPI, makePresetAPI } from "./helpers/config-api";
|
||||||
|
import type { PluginAPI, PresetAPI } from "./helpers/config-api";
|
||||||
|
|
||||||
import loadPrivatePartialConfig from "./partial";
|
import loadPrivatePartialConfig from "./partial";
|
||||||
import type { ValidatedOptions } from "./validation/options";
|
import type { ValidatedOptions } from "./validation/options";
|
||||||
@ -34,172 +31,183 @@ import type { ValidatedOptions } from "./validation/options";
|
|||||||
import * as Context from "./cache-contexts";
|
import * as Context from "./cache-contexts";
|
||||||
|
|
||||||
type LoadedDescriptor = {
|
type LoadedDescriptor = {
|
||||||
value: {},
|
value: {};
|
||||||
options: {},
|
options: {};
|
||||||
dirname: string,
|
dirname: string;
|
||||||
alias: string,
|
alias: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type { InputOptions } from "./validation/options";
|
export type { InputOptions } from "./validation/options";
|
||||||
|
|
||||||
export type ResolvedConfig = {
|
export type ResolvedConfig = {
|
||||||
options: Object,
|
options: any;
|
||||||
passes: PluginPasses,
|
passes: PluginPasses;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type { Plugin };
|
export type { Plugin };
|
||||||
export type PluginPassList = Array<Plugin>;
|
export type PluginPassList = Array<Plugin>;
|
||||||
export type PluginPasses = Array<PluginPassList>;
|
export type PluginPasses = Array<PluginPassList>;
|
||||||
|
|
||||||
export default gensync<[any], ResolvedConfig | null>(function* loadFullConfig(
|
export default gensync<(inputOpts: unknown) => ResolvedConfig | null>(
|
||||||
inputOpts: mixed,
|
function* loadFullConfig(inputOpts) {
|
||||||
): Handler<ResolvedConfig | null> {
|
const result = yield* loadPrivatePartialConfig(inputOpts);
|
||||||
const result = yield* loadPrivatePartialConfig(inputOpts);
|
if (!result) {
|
||||||
if (!result) {
|
return null;
|
||||||
return null;
|
}
|
||||||
}
|
const { options, context, fileHandling } = result;
|
||||||
const { options, context, fileHandling } = result;
|
|
||||||
|
|
||||||
if (fileHandling === "ignored") {
|
if (fileHandling === "ignored") {
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
const optionDefaults = {};
|
|
||||||
|
|
||||||
const { plugins, presets } = options;
|
|
||||||
|
|
||||||
if (!plugins || !presets) {
|
|
||||||
throw new Error("Assertion failure - plugins and presets exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
const pluginContext: Context.FullPlugin = {
|
|
||||||
...context,
|
|
||||||
targets: options.targets,
|
|
||||||
assumptions: options.assumptions ?? {},
|
|
||||||
};
|
|
||||||
|
|
||||||
const toDescriptor = (item: PluginItem) => {
|
|
||||||
const desc = getItemDescriptor(item);
|
|
||||||
if (!desc) {
|
|
||||||
throw new Error("Assertion failure - must be config item");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return desc;
|
const optionDefaults = {};
|
||||||
};
|
|
||||||
|
|
||||||
const presetsDescriptors = presets.map(toDescriptor);
|
const { plugins, presets } = options;
|
||||||
const initialPluginsDescriptors = plugins.map(toDescriptor);
|
|
||||||
const pluginDescriptorsByPass: Array<Array<UnloadedDescriptor>> = [[]];
|
|
||||||
const passes: Array<Array<Plugin>> = [];
|
|
||||||
|
|
||||||
const ignored = yield* enhanceError(
|
if (!plugins || !presets) {
|
||||||
context,
|
throw new Error("Assertion failure - plugins and presets exist");
|
||||||
function* recursePresetDescriptors(
|
}
|
||||||
rawPresets: Array<UnloadedDescriptor>,
|
|
||||||
pluginDescriptorsPass: Array<UnloadedDescriptor>,
|
|
||||||
) {
|
|
||||||
const presets: Array<{|
|
|
||||||
preset: ConfigChain | null,
|
|
||||||
pass: Array<UnloadedDescriptor>,
|
|
||||||
|}> = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < rawPresets.length; i++) {
|
const pluginContext: Context.FullPlugin = {
|
||||||
const descriptor = rawPresets[i];
|
...context,
|
||||||
if (descriptor.options !== false) {
|
targets: options.targets,
|
||||||
try {
|
assumptions: options.assumptions ?? {},
|
||||||
// Presets normally run in reverse order, but if they
|
};
|
||||||
// have their own pass they run after the presets
|
|
||||||
// in the previous pass.
|
const toDescriptor = (item: PluginItem) => {
|
||||||
if (descriptor.ownPass) {
|
const desc = getItemDescriptor(item);
|
||||||
presets.push({
|
if (!desc) {
|
||||||
preset: yield* loadPresetDescriptor(descriptor, pluginContext),
|
throw new Error("Assertion failure - must be config item");
|
||||||
pass: [],
|
}
|
||||||
});
|
|
||||||
} else {
|
return desc;
|
||||||
presets.unshift({
|
};
|
||||||
preset: yield* loadPresetDescriptor(descriptor, pluginContext),
|
|
||||||
pass: pluginDescriptorsPass,
|
const presetsDescriptors = presets.map(toDescriptor);
|
||||||
});
|
const initialPluginsDescriptors = plugins.map(toDescriptor);
|
||||||
|
const pluginDescriptorsByPass: Array<Array<UnloadedDescriptor>> = [[]];
|
||||||
|
const passes: Array<Array<Plugin>> = [];
|
||||||
|
|
||||||
|
const ignored = yield* enhanceError(
|
||||||
|
context,
|
||||||
|
function* recursePresetDescriptors(
|
||||||
|
rawPresets: Array<UnloadedDescriptor>,
|
||||||
|
pluginDescriptorsPass: Array<UnloadedDescriptor>,
|
||||||
|
) {
|
||||||
|
const presets: Array<{
|
||||||
|
preset: ConfigChain | null;
|
||||||
|
pass: Array<UnloadedDescriptor>;
|
||||||
|
}> = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < rawPresets.length; i++) {
|
||||||
|
const descriptor = rawPresets[i];
|
||||||
|
if (descriptor.options !== false) {
|
||||||
|
try {
|
||||||
|
// Presets normally run in reverse order, but if they
|
||||||
|
// have their own pass they run after the presets
|
||||||
|
// in the previous pass.
|
||||||
|
if (descriptor.ownPass) {
|
||||||
|
presets.push({
|
||||||
|
preset: yield* loadPresetDescriptor(
|
||||||
|
descriptor,
|
||||||
|
pluginContext,
|
||||||
|
),
|
||||||
|
pass: [],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
presets.unshift({
|
||||||
|
preset: yield* loadPresetDescriptor(
|
||||||
|
descriptor,
|
||||||
|
pluginContext,
|
||||||
|
),
|
||||||
|
pass: pluginDescriptorsPass,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code === "BABEL_UNKNOWN_OPTION") {
|
||||||
|
checkNoUnwrappedItemOptionPairs(rawPresets, i, "preset", e);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
}
|
||||||
if (e.code === "BABEL_UNKNOWN_OPTION") {
|
}
|
||||||
checkNoUnwrappedItemOptionPairs(rawPresets, i, "preset", e);
|
|
||||||
|
// resolve presets
|
||||||
|
if (presets.length > 0) {
|
||||||
|
// The passes are created in the same order as the preset list, but are inserted before any
|
||||||
|
// existing additional passes.
|
||||||
|
pluginDescriptorsByPass.splice(
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
...presets
|
||||||
|
.map(o => o.pass)
|
||||||
|
.filter(p => p !== pluginDescriptorsPass),
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const { preset, pass } of presets) {
|
||||||
|
if (!preset) return true;
|
||||||
|
|
||||||
|
pass.push(...preset.plugins);
|
||||||
|
|
||||||
|
const ignored = yield* recursePresetDescriptors(
|
||||||
|
preset.presets,
|
||||||
|
pass,
|
||||||
|
);
|
||||||
|
if (ignored) return true;
|
||||||
|
|
||||||
|
preset.options.forEach(opts => {
|
||||||
|
mergeOptions(optionDefaults, opts);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)(presetsDescriptors, pluginDescriptorsByPass[0]);
|
||||||
|
|
||||||
|
if (ignored) return null;
|
||||||
|
|
||||||
|
const opts: any = optionDefaults;
|
||||||
|
mergeOptions(opts, options);
|
||||||
|
|
||||||
|
yield* enhanceError(context, function* loadPluginDescriptors() {
|
||||||
|
pluginDescriptorsByPass[0].unshift(...initialPluginsDescriptors);
|
||||||
|
|
||||||
|
for (const descs of pluginDescriptorsByPass) {
|
||||||
|
const pass = [];
|
||||||
|
passes.push(pass);
|
||||||
|
|
||||||
|
for (let i = 0; i < descs.length; i++) {
|
||||||
|
const descriptor: UnloadedDescriptor = descs[i];
|
||||||
|
if (descriptor.options !== false) {
|
||||||
|
try {
|
||||||
|
pass.push(yield* loadPluginDescriptor(descriptor, pluginContext));
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code === "BABEL_UNKNOWN_PLUGIN_PROPERTY") {
|
||||||
|
// print special message for `plugins: ["@babel/foo", { foo: "option" }]`
|
||||||
|
checkNoUnwrappedItemOptionPairs(descs, i, "plugin", e);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
// resolve presets
|
opts.plugins = passes[0];
|
||||||
if (presets.length > 0) {
|
opts.presets = passes
|
||||||
// The passes are created in the same order as the preset list, but are inserted before any
|
.slice(1)
|
||||||
// existing additional passes.
|
.filter(plugins => plugins.length > 0)
|
||||||
pluginDescriptorsByPass.splice(
|
.map(plugins => ({ plugins }));
|
||||||
1,
|
opts.passPerPreset = opts.presets.length > 0;
|
||||||
0,
|
|
||||||
...presets.map(o => o.pass).filter(p => p !== pluginDescriptorsPass),
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const { preset, pass } of presets) {
|
return {
|
||||||
if (!preset) return true;
|
options: opts,
|
||||||
|
passes: passes,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
pass.push(...preset.plugins);
|
function enhanceError<T extends Function>(context, fn: T): T {
|
||||||
|
return function* (arg1, arg2) {
|
||||||
const ignored = yield* recursePresetDescriptors(preset.presets, pass);
|
|
||||||
if (ignored) return true;
|
|
||||||
|
|
||||||
preset.options.forEach(opts => {
|
|
||||||
mergeOptions(optionDefaults, opts);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)(presetsDescriptors, pluginDescriptorsByPass[0]);
|
|
||||||
|
|
||||||
if (ignored) return null;
|
|
||||||
|
|
||||||
const opts: Object = optionDefaults;
|
|
||||||
mergeOptions(opts, options);
|
|
||||||
|
|
||||||
yield* enhanceError(context, function* loadPluginDescriptors() {
|
|
||||||
pluginDescriptorsByPass[0].unshift(...initialPluginsDescriptors);
|
|
||||||
|
|
||||||
for (const descs of pluginDescriptorsByPass) {
|
|
||||||
const pass = [];
|
|
||||||
passes.push(pass);
|
|
||||||
|
|
||||||
for (let i = 0; i < descs.length; i++) {
|
|
||||||
const descriptor: UnloadedDescriptor = descs[i];
|
|
||||||
if (descriptor.options !== false) {
|
|
||||||
try {
|
|
||||||
pass.push(yield* loadPluginDescriptor(descriptor, pluginContext));
|
|
||||||
} catch (e) {
|
|
||||||
if (e.code === "BABEL_UNKNOWN_PLUGIN_PROPERTY") {
|
|
||||||
// print special message for `plugins: ["@babel/foo", { foo: "option" }]`
|
|
||||||
checkNoUnwrappedItemOptionPairs(descs, i, "plugin", e);
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
opts.plugins = passes[0];
|
|
||||||
opts.presets = passes
|
|
||||||
.slice(1)
|
|
||||||
.filter(plugins => plugins.length > 0)
|
|
||||||
.map(plugins => ({ plugins }));
|
|
||||||
opts.passPerPreset = opts.presets.length > 0;
|
|
||||||
|
|
||||||
return {
|
|
||||||
options: opts,
|
|
||||||
passes: passes,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
function enhanceError<T: Function>(context, fn: T): T {
|
|
||||||
return (function* (arg1, arg2) {
|
|
||||||
try {
|
try {
|
||||||
return yield* fn(arg1, arg2);
|
return yield* fn(arg1, arg2);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -211,7 +219,7 @@ function enhanceError<T: Function>(context, fn: T): T {
|
|||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}: any);
|
} as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -255,7 +263,8 @@ const makeDescriptorLoader = <Context, API>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isThenable(item)) {
|
if (isThenable(item)) {
|
||||||
yield* []; // if we want to support async plugins
|
// @ts-expect-error - if we want to support async plugins
|
||||||
|
yield* [];
|
||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`You appear to be using a promise as a plugin, ` +
|
`You appear to be using a promise as a plugin, ` +
|
||||||
@ -270,12 +279,14 @@ const makeDescriptorLoader = <Context, API>(
|
|||||||
return { value: item, options, dirname, alias };
|
return { value: item, options, dirname, alias };
|
||||||
});
|
});
|
||||||
|
|
||||||
const pluginDescriptorLoader = makeDescriptorLoader<Context.SimplePlugin, *>(
|
const pluginDescriptorLoader = makeDescriptorLoader<
|
||||||
makePluginAPI,
|
Context.SimplePlugin,
|
||||||
);
|
PluginAPI
|
||||||
const presetDescriptorLoader = makeDescriptorLoader<Context.SimplePreset, *>(
|
>(makePluginAPI);
|
||||||
makePresetAPI,
|
const presetDescriptorLoader = makeDescriptorLoader<
|
||||||
);
|
Context.SimplePreset,
|
||||||
|
PresetAPI
|
||||||
|
>(makePresetAPI);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate a plugin for the given descriptor, returning the plugin/options pair.
|
* Instantiate a plugin for the given descriptor, returning the plugin/options pair.
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import semver from "semver";
|
import semver from "semver";
|
||||||
import type { Targets } from "@babel/helper-compilation-targets";
|
import type { Targets } from "@babel/helper-compilation-targets";
|
||||||
|
|
||||||
import { version as coreVersion } from "../../";
|
import { version as coreVersion } from "../../";
|
||||||
import {
|
import { assertSimpleType } from "../caching";
|
||||||
assertSimpleType,
|
import type {
|
||||||
type CacheConfigurator,
|
CacheConfigurator,
|
||||||
type SimpleCacheConfigurator,
|
SimpleCacheConfigurator,
|
||||||
type SimpleType,
|
SimpleType,
|
||||||
} from "../caching";
|
} from "../caching";
|
||||||
|
|
||||||
import type { CallerMetadata } from "../validation/options";
|
import type { CallerMetadata } from "../validation/options";
|
||||||
@ -16,38 +14,36 @@ import type { CallerMetadata } from "../validation/options";
|
|||||||
import * as Context from "../cache-contexts";
|
import * as Context from "../cache-contexts";
|
||||||
|
|
||||||
type EnvFunction = {
|
type EnvFunction = {
|
||||||
(): string,
|
(): string;
|
||||||
<T>((string) => T): T,
|
<T>(extractor: (babelEnv: string) => T): T;
|
||||||
(string): boolean,
|
(envVar: string): boolean;
|
||||||
(Array<string>): boolean,
|
(envVars: Array<string>): boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type CallerFactory = ((CallerMetadata | void) => mixed) => SimpleType;
|
type CallerFactory = (
|
||||||
|
extractor: (callerMetadata: CallerMetadata | void) => unknown,
|
||||||
|
) => SimpleType;
|
||||||
type TargetsFunction = () => Targets;
|
type TargetsFunction = () => Targets;
|
||||||
|
|
||||||
type AssumptionFunction = (name: string) => boolean | void;
|
type AssumptionFunction = (name: string) => boolean | void;
|
||||||
|
|
||||||
export type ConfigAPI = {|
|
export type ConfigAPI = {
|
||||||
version: string,
|
version: string;
|
||||||
cache: SimpleCacheConfigurator,
|
cache: SimpleCacheConfigurator;
|
||||||
env: EnvFunction,
|
env: EnvFunction;
|
||||||
async: () => boolean,
|
async: () => boolean;
|
||||||
assertVersion: typeof assertVersion,
|
assertVersion: typeof assertVersion;
|
||||||
caller?: CallerFactory,
|
caller?: CallerFactory;
|
||||||
|};
|
};
|
||||||
|
|
||||||
export type PresetAPI = {|
|
export type PresetAPI = {
|
||||||
...ConfigAPI,
|
targets: TargetsFunction;
|
||||||
targets: TargetsFunction,
|
} & ConfigAPI;
|
||||||
|};
|
|
||||||
|
|
||||||
export type PluginAPI = {|
|
export type PluginAPI = {
|
||||||
...PresetAPI,
|
assumption: AssumptionFunction;
|
||||||
assumption: AssumptionFunction,
|
} & PresetAPI;
|
||||||
|};
|
|
||||||
|
|
||||||
export function makeConfigAPI<SideChannel: Context.SimpleConfig>(
|
export function makeConfigAPI<SideChannel extends Context.SimpleConfig>(
|
||||||
cache: CacheConfigurator<SideChannel>,
|
cache: CacheConfigurator<SideChannel>,
|
||||||
): ConfigAPI {
|
): ConfigAPI {
|
||||||
const env: any = value =>
|
const env: any = value =>
|
||||||
@ -58,7 +54,7 @@ export function makeConfigAPI<SideChannel: Context.SimpleConfig>(
|
|||||||
}
|
}
|
||||||
if (!Array.isArray(value)) value = [value];
|
if (!Array.isArray(value)) value = [value];
|
||||||
|
|
||||||
return value.some((entry: mixed) => {
|
return value.some((entry: unknown) => {
|
||||||
if (typeof entry !== "string") {
|
if (typeof entry !== "string") {
|
||||||
throw new Error("Unexpected non-string value");
|
throw new Error("Unexpected non-string value");
|
||||||
}
|
}
|
||||||
@ -79,7 +75,7 @@ export function makeConfigAPI<SideChannel: Context.SimpleConfig>(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makePresetAPI<SideChannel: Context.SimplePreset>(
|
export function makePresetAPI<SideChannel extends Context.SimplePreset>(
|
||||||
cache: CacheConfigurator<SideChannel>,
|
cache: CacheConfigurator<SideChannel>,
|
||||||
): PresetAPI {
|
): PresetAPI {
|
||||||
const targets = () =>
|
const targets = () =>
|
||||||
@ -91,7 +87,7 @@ export function makePresetAPI<SideChannel: Context.SimplePreset>(
|
|||||||
return { ...makeConfigAPI(cache), targets };
|
return { ...makeConfigAPI(cache), targets };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makePluginAPI<SideChannel: Context.SimplePlugin>(
|
export function makePluginAPI<SideChannel extends Context.SimplePlugin>(
|
||||||
cache: CacheConfigurator<SideChannel>,
|
cache: CacheConfigurator<SideChannel>,
|
||||||
): PluginAPI {
|
): PluginAPI {
|
||||||
const assumption = name => cache.using(data => data.assumptions[name]);
|
const assumption = name => cache.using(data => data.assumptions[name]);
|
||||||
@ -133,12 +129,9 @@ function assertVersion(range: string | number): void {
|
|||||||
Error.stackTraceLimit = limit;
|
Error.stackTraceLimit = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Object.assign(
|
throw Object.assign(err, {
|
||||||
err,
|
code: "BABEL_VERSION_UNSUPPORTED",
|
||||||
({
|
version: coreVersion,
|
||||||
code: "BABEL_VERSION_UNSUPPORTED",
|
range,
|
||||||
version: coreVersion,
|
});
|
||||||
range,
|
|
||||||
}: any),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
export function getEnv(defaultValue: string = "development"): string {
|
export function getEnv(defaultValue: string = "development"): string {
|
||||||
return process.env.BABEL_ENV || process.env.NODE_ENV || defaultValue;
|
return process.env.BABEL_ENV || process.env.NODE_ENV || defaultValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import gensync from "gensync";
|
import gensync from "gensync";
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
@ -18,19 +16,19 @@ export { loadFullConfig as default };
|
|||||||
export type { PartialConfig } from "./partial";
|
export type { PartialConfig } from "./partial";
|
||||||
|
|
||||||
import { createConfigItem as createConfigItemImpl } from "./item";
|
import { createConfigItem as createConfigItemImpl } from "./item";
|
||||||
|
import type { ConfigItem } from "./item";
|
||||||
|
|
||||||
const loadOptionsRunner = gensync<[mixed], Object | null>(function* (opts) {
|
const loadOptionsRunner = gensync<(opts: unknown) => any>(function* (opts) {
|
||||||
const config = yield* loadFullConfig(opts);
|
const config = yield* loadFullConfig(opts);
|
||||||
// NOTE: We want to return "null" explicitly, while ?. alone returns undefined
|
// NOTE: We want to return "null" explicitly, while ?. alone returns undefined
|
||||||
return config?.options ?? null;
|
return config?.options ?? null;
|
||||||
});
|
});
|
||||||
|
|
||||||
const createConfigItemRunner = gensync<[PluginTarget, any], Object | null>(
|
const createConfigItemRunner = gensync<
|
||||||
// $FlowIgnore
|
(...args: Parameters<typeof createConfigItemImpl>) => ConfigItem
|
||||||
createConfigItemImpl,
|
>(createConfigItemImpl);
|
||||||
);
|
|
||||||
|
|
||||||
const maybeErrback = runner => (opts: mixed, callback: Function) => {
|
const maybeErrback = runner => (opts: unknown, callback?: Function) => {
|
||||||
if (callback === undefined && typeof opts === "function") {
|
if (callback === undefined && typeof opts === "function") {
|
||||||
callback = opts;
|
callback = opts;
|
||||||
opts = undefined;
|
opts = undefined;
|
||||||
@ -51,7 +49,7 @@ export const createConfigItemAsync = createConfigItemRunner.async;
|
|||||||
export function createConfigItem(
|
export function createConfigItem(
|
||||||
target: PluginTarget,
|
target: PluginTarget,
|
||||||
options: any,
|
options: any,
|
||||||
callback?: Function,
|
callback?: (err: Error, val: ConfigItem | null) => void,
|
||||||
) {
|
) {
|
||||||
if (callback !== undefined) {
|
if (callback !== undefined) {
|
||||||
return createConfigItemRunner.errback(target, options, callback);
|
return createConfigItemRunner.errback(target, options, callback);
|
||||||
|
|||||||
@ -1,15 +1,10 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
/*:: declare var invariant; */
|
|
||||||
|
|
||||||
import type { Handler } from "gensync";
|
import type { Handler } from "gensync";
|
||||||
import type { PluginTarget, PluginOptions } from "./validation/options";
|
import type { PluginTarget, PluginOptions } from "./validation/options";
|
||||||
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import {
|
import { createDescriptor } from "./config-descriptors";
|
||||||
createDescriptor,
|
|
||||||
type UnloadedDescriptor,
|
import type { UnloadedDescriptor } from "./config-descriptors";
|
||||||
} from "./config-descriptors";
|
|
||||||
|
|
||||||
export function createItemFromDescriptor(desc: UnloadedDescriptor): ConfigItem {
|
export function createItemFromDescriptor(desc: UnloadedDescriptor): ConfigItem {
|
||||||
return new ConfigItem(desc);
|
return new ConfigItem(desc);
|
||||||
@ -30,8 +25,8 @@ export function* createConfigItem(
|
|||||||
dirname = ".",
|
dirname = ".",
|
||||||
type,
|
type,
|
||||||
}: {
|
}: {
|
||||||
dirname?: string,
|
dirname?: string;
|
||||||
type?: "preset" | "plugin",
|
type?: "preset" | "plugin";
|
||||||
} = {},
|
} = {},
|
||||||
): Handler<ConfigItem> {
|
): Handler<ConfigItem> {
|
||||||
const descriptor = yield* createDescriptor(value, path.resolve(dirname), {
|
const descriptor = yield* createDescriptor(value, path.resolve(dirname), {
|
||||||
@ -42,10 +37,9 @@ export function* createConfigItem(
|
|||||||
return createItemFromDescriptor(descriptor);
|
return createItemFromDescriptor(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getItemDescriptor(item: mixed): UnloadedDescriptor | void {
|
export function getItemDescriptor(item: unknown): UnloadedDescriptor | void {
|
||||||
if ((item: any)?.[CONFIG_ITEM_BRAND]) {
|
if ((item as any)?.[CONFIG_ITEM_BRAND]) {
|
||||||
/*:: invariant(item instanceof ConfigItem) */
|
return (item as ConfigItem)._descriptor;
|
||||||
return item._descriptor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -74,7 +68,6 @@ class ConfigItem {
|
|||||||
/**
|
/**
|
||||||
* Used to detect ConfigItem instances from other Babel instances.
|
* Used to detect ConfigItem instances from other Babel instances.
|
||||||
*/
|
*/
|
||||||
// $FlowIgnore
|
|
||||||
[CONFIG_ITEM_BRAND] = true;
|
[CONFIG_ITEM_BRAND] = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,10 +98,9 @@ class ConfigItem {
|
|||||||
*/
|
*/
|
||||||
file: {
|
file: {
|
||||||
// The requested path, e.g. "@babel/env".
|
// The requested path, e.g. "@babel/env".
|
||||||
request: string,
|
request: string;
|
||||||
|
|
||||||
// The resolved absolute path of the file.
|
// The resolved absolute path of the file.
|
||||||
resolved: string,
|
resolved: string;
|
||||||
} | void;
|
} | void;
|
||||||
|
|
||||||
constructor(descriptor: UnloadedDescriptor) {
|
constructor(descriptor: UnloadedDescriptor) {
|
||||||
|
|||||||
@ -1,30 +1,26 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import gensync, { type Handler } from "gensync";
|
import gensync from "gensync";
|
||||||
|
import type { Handler } from "gensync";
|
||||||
import Plugin from "./plugin";
|
import Plugin from "./plugin";
|
||||||
import { mergeOptions } from "./util";
|
import { mergeOptions } from "./util";
|
||||||
import { createItemFromDescriptor } from "./item";
|
import { createItemFromDescriptor } from "./item";
|
||||||
import {
|
import { buildRootChain } from "./config-chain";
|
||||||
buildRootChain,
|
import type { ConfigContext, FileHandling } from "./config-chain";
|
||||||
type ConfigContext,
|
|
||||||
type FileHandling,
|
|
||||||
} from "./config-chain";
|
|
||||||
import { getEnv } from "./helpers/environment";
|
import { getEnv } from "./helpers/environment";
|
||||||
import {
|
import { validate } from "./validation/options";
|
||||||
validate,
|
|
||||||
type ValidatedOptions,
|
import type {
|
||||||
type NormalizedOptions,
|
ValidatedOptions,
|
||||||
type RootMode,
|
NormalizedOptions,
|
||||||
|
RootMode,
|
||||||
} from "./validation/options";
|
} from "./validation/options";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
findConfigUpwards,
|
findConfigUpwards,
|
||||||
resolveShowConfigPath,
|
resolveShowConfigPath,
|
||||||
ROOT_CONFIG_FILENAMES,
|
ROOT_CONFIG_FILENAMES,
|
||||||
type ConfigFile,
|
|
||||||
type IgnoreFile,
|
|
||||||
} from "./files";
|
} from "./files";
|
||||||
|
import type { ConfigFile, IgnoreFile } from "./files";
|
||||||
import { resolveTargets } from "./resolve-targets";
|
import { resolveTargets } from "./resolve-targets";
|
||||||
|
|
||||||
function* resolveRootMode(
|
function* resolveRootMode(
|
||||||
@ -45,12 +41,12 @@ function* resolveRootMode(
|
|||||||
if (upwardRootDir !== null) return upwardRootDir;
|
if (upwardRootDir !== null) return upwardRootDir;
|
||||||
|
|
||||||
throw Object.assign(
|
throw Object.assign(
|
||||||
(new Error(
|
new Error(
|
||||||
`Babel was run with rootMode:"upward" but a root could not ` +
|
`Babel was run with rootMode:"upward" but a root could not ` +
|
||||||
`be found when searching upward from "${rootDir}".\n` +
|
`be found when searching upward from "${rootDir}".\n` +
|
||||||
`One of the following config files must be in the directory tree: ` +
|
`One of the following config files must be in the directory tree: ` +
|
||||||
`"${ROOT_CONFIG_FILENAMES.join(", ")}".`,
|
`"${ROOT_CONFIG_FILENAMES.join(", ")}".`,
|
||||||
): any),
|
) as any,
|
||||||
{
|
{
|
||||||
code: "BABEL_ROOT_NOT_FOUND",
|
code: "BABEL_ROOT_NOT_FOUND",
|
||||||
dirname: rootDir,
|
dirname: rootDir,
|
||||||
@ -63,17 +59,17 @@ function* resolveRootMode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PrivPartialConfig = {
|
type PrivPartialConfig = {
|
||||||
options: NormalizedOptions,
|
options: NormalizedOptions;
|
||||||
context: ConfigContext,
|
context: ConfigContext;
|
||||||
fileHandling: FileHandling,
|
fileHandling: FileHandling;
|
||||||
ignore: IgnoreFile | void,
|
ignore: IgnoreFile | void;
|
||||||
babelrc: ConfigFile | void,
|
babelrc: ConfigFile | void;
|
||||||
config: ConfigFile | void,
|
config: ConfigFile | void;
|
||||||
files: Set<string>,
|
files: Set<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function* loadPrivatePartialConfig(
|
export default function* loadPrivatePartialConfig(
|
||||||
inputOpts: mixed,
|
inputOpts: unknown,
|
||||||
): Handler<PrivPartialConfig | null> {
|
): Handler<PrivPartialConfig | null> {
|
||||||
if (
|
if (
|
||||||
inputOpts != null &&
|
inputOpts != null &&
|
||||||
@ -121,7 +117,7 @@ export default function* loadPrivatePartialConfig(
|
|||||||
assumptions: {},
|
assumptions: {},
|
||||||
};
|
};
|
||||||
configChain.options.forEach(opts => {
|
configChain.options.forEach(opts => {
|
||||||
mergeOptions((merged: any), opts);
|
mergeOptions(merged as any, opts);
|
||||||
});
|
});
|
||||||
|
|
||||||
const options: NormalizedOptions = {
|
const options: NormalizedOptions = {
|
||||||
@ -163,47 +159,50 @@ export default function* loadPrivatePartialConfig(
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LoadPartialConfigOpts = {
|
type LoadPartialConfigOpts = {
|
||||||
showIgnoredFiles?: boolean,
|
showIgnoredFiles?: boolean;
|
||||||
...
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const loadPartialConfig = gensync<[any], PartialConfig | null>(
|
export const loadPartialConfig = gensync<
|
||||||
function* (opts?: LoadPartialConfigOpts): Handler<PartialConfig | null> {
|
(opts?: LoadPartialConfigOpts) => PartialConfig | null
|
||||||
let showIgnoredFiles = false;
|
>(function* (opts) {
|
||||||
// We only extract showIgnoredFiles if opts is an object, so that
|
let showIgnoredFiles = false;
|
||||||
// loadPrivatePartialConfig can throw the appropriate error if it's not.
|
// We only extract showIgnoredFiles if opts is an object, so that
|
||||||
if (typeof opts === "object" && opts !== null && !Array.isArray(opts)) {
|
// loadPrivatePartialConfig can throw the appropriate error if it's not.
|
||||||
({ showIgnoredFiles, ...opts } = opts);
|
if (typeof opts === "object" && opts !== null && !Array.isArray(opts)) {
|
||||||
|
({ showIgnoredFiles, ...opts } = opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result:
|
||||||
|
| PrivPartialConfig
|
||||||
|
| undefined
|
||||||
|
| null = yield* loadPrivatePartialConfig(opts);
|
||||||
|
if (!result) return null;
|
||||||
|
|
||||||
|
const { options, babelrc, ignore, config, fileHandling, files } = result;
|
||||||
|
|
||||||
|
if (fileHandling === "ignored" && !showIgnoredFiles) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
(options.plugins || []).forEach(item => {
|
||||||
|
// @ts-expect-error todo(flow->ts): better type annotation for `item.value`
|
||||||
|
if (item.value instanceof Plugin) {
|
||||||
|
throw new Error(
|
||||||
|
"Passing cached plugin instances is not supported in " +
|
||||||
|
"babel.loadPartialConfig()",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const result: ?PrivPartialConfig = yield* loadPrivatePartialConfig(opts);
|
return new PartialConfig(
|
||||||
if (!result) return null;
|
options,
|
||||||
|
babelrc ? babelrc.filepath : undefined,
|
||||||
const { options, babelrc, ignore, config, fileHandling, files } = result;
|
ignore ? ignore.filepath : undefined,
|
||||||
|
config ? config.filepath : undefined,
|
||||||
if (fileHandling === "ignored" && !showIgnoredFiles) {
|
fileHandling,
|
||||||
return null;
|
files,
|
||||||
}
|
);
|
||||||
|
});
|
||||||
(options.plugins || []).forEach(item => {
|
|
||||||
if (item.value instanceof Plugin) {
|
|
||||||
throw new Error(
|
|
||||||
"Passing cached plugin instances is not supported in " +
|
|
||||||
"babel.loadPartialConfig()",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return new PartialConfig(
|
|
||||||
options,
|
|
||||||
babelrc ? babelrc.filepath : undefined,
|
|
||||||
ignore ? ignore.filepath : undefined,
|
|
||||||
config ? config.filepath : undefined,
|
|
||||||
fileHandling,
|
|
||||||
files,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export type { PartialConfig };
|
export type { PartialConfig };
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// @flow
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
const sep = `\\${path.sep}`;
|
const sep = `\\${path.sep}`;
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import type { PluginObject } from "./validation/plugins";
|
import type { PluginObject } from "./validation/plugins";
|
||||||
|
|
||||||
export default class Plugin {
|
export default class Plugin {
|
||||||
key: ?string;
|
key: string | undefined | null;
|
||||||
manipulateOptions: ((options: mixed, parserOpts: mixed) => void) | void;
|
manipulateOptions: ((options: unknown, parserOpts: unknown) => void) | void;
|
||||||
post: Function | void;
|
post: Function | void;
|
||||||
pre: Function | void;
|
pre: Function | void;
|
||||||
visitor: {};
|
visitor: {};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// @flow
|
import gensync from "gensync";
|
||||||
|
|
||||||
import gensync, { type Handler } from "gensync";
|
import type { Handler } from "gensync";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
OptionsAndDescriptors,
|
OptionsAndDescriptors,
|
||||||
@ -14,19 +14,19 @@ export const ChainFormatter = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type PrintableConfig = {
|
type PrintableConfig = {
|
||||||
content: OptionsAndDescriptors,
|
content: OptionsAndDescriptors;
|
||||||
type: $Values<typeof ChainFormatter>,
|
type: typeof ChainFormatter[keyof typeof ChainFormatter];
|
||||||
callerName: ?string,
|
callerName: string | undefined | null;
|
||||||
filepath: ?string,
|
filepath: string | undefined | null;
|
||||||
index: ?number,
|
index: number | undefined | null;
|
||||||
envName: ?string,
|
envName: string | undefined | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Formatter = {
|
const Formatter = {
|
||||||
title(
|
title(
|
||||||
type: $Values<typeof ChainFormatter>,
|
type: typeof ChainFormatter[keyof typeof ChainFormatter],
|
||||||
callerName: ?string,
|
callerName?: string | null,
|
||||||
filepath: ?string,
|
filepath?: string | null,
|
||||||
): string {
|
): string {
|
||||||
let title = "";
|
let title = "";
|
||||||
if (type === ChainFormatter.Programmatic) {
|
if (type === ChainFormatter.Programmatic) {
|
||||||
@ -35,12 +35,11 @@ const Formatter = {
|
|||||||
title += " from " + callerName;
|
title += " from " + callerName;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// $FlowIgnore
|
|
||||||
title = "config " + filepath;
|
title = "config " + filepath;
|
||||||
}
|
}
|
||||||
return title;
|
return title;
|
||||||
},
|
},
|
||||||
loc(index: ?number, envName: ?string): string {
|
loc(index?: number | null, envName?: string | null): string {
|
||||||
let loc = "";
|
let loc = "";
|
||||||
if (index != null) {
|
if (index != null) {
|
||||||
loc += `.overrides[${index}]`;
|
loc += `.overrides[${index}]`;
|
||||||
@ -69,7 +68,9 @@ const Formatter = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function descriptorToConfig(d: UnloadedDescriptor): string | {} | Array<mixed> {
|
function descriptorToConfig(
|
||||||
|
d: UnloadedDescriptor,
|
||||||
|
): string | {} | Array<unknown> {
|
||||||
let name = d.file?.request;
|
let name = d.file?.request;
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
if (typeof d.value === "object") {
|
if (typeof d.value === "object") {
|
||||||
@ -97,14 +98,20 @@ export class ConfigPrinter {
|
|||||||
_stack: Array<PrintableConfig> = [];
|
_stack: Array<PrintableConfig> = [];
|
||||||
configure(
|
configure(
|
||||||
enabled: boolean,
|
enabled: boolean,
|
||||||
type: $Values<typeof ChainFormatter>,
|
type: typeof ChainFormatter[keyof typeof ChainFormatter],
|
||||||
{ callerName, filepath }: { callerName?: string, filepath?: string },
|
{
|
||||||
|
callerName,
|
||||||
|
filepath,
|
||||||
|
}: {
|
||||||
|
callerName?: string;
|
||||||
|
filepath?: string;
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
if (!enabled) return () => {};
|
if (!enabled) return () => {};
|
||||||
return (
|
return (
|
||||||
content: OptionsAndDescriptors,
|
content: OptionsAndDescriptors,
|
||||||
index: ?number,
|
index?: number | null,
|
||||||
envName: ?string,
|
envName?: string | null,
|
||||||
) => {
|
) => {
|
||||||
this._stack.push({
|
this._stack.push({
|
||||||
type,
|
type,
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import type { ValidatedOptions } from "./validation/options";
|
import type { ValidatedOptions } from "./validation/options";
|
||||||
import getTargets, { type Targets } from "@babel/helper-compilation-targets";
|
import getTargets from "@babel/helper-compilation-targets";
|
||||||
|
|
||||||
|
import type { Targets } from "@babel/helper-compilation-targets";
|
||||||
|
|
||||||
export function resolveBrowserslistConfigFile(
|
export function resolveBrowserslistConfigFile(
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
browserslistConfigFile: string,
|
browserslistConfigFile: string,
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
configFilePath: string,
|
configFilePath: string,
|
||||||
): string | void {
|
): string | void {
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -14,19 +14,19 @@ export function resolveBrowserslistConfigFile(
|
|||||||
|
|
||||||
export function resolveTargets(
|
export function resolveTargets(
|
||||||
options: ValidatedOptions,
|
options: ValidatedOptions,
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
root: string,
|
root: string,
|
||||||
): Targets {
|
): Targets {
|
||||||
let { targets } = options;
|
// todo(flow->ts) remove any and refactor to not assign different types into same variable
|
||||||
|
let targets: any = options.targets;
|
||||||
if (typeof targets === "string" || Array.isArray(targets)) {
|
if (typeof targets === "string" || Array.isArray(targets)) {
|
||||||
targets = { browsers: targets };
|
targets = { browsers: targets };
|
||||||
}
|
}
|
||||||
// $FlowIgnore it thinks that targets.esmodules doesn't exist.
|
|
||||||
if (targets && targets.esmodules) {
|
if (targets && targets.esmodules) {
|
||||||
targets = { ...targets, esmodules: "intersect" };
|
targets = { ...targets, esmodules: "intersect" };
|
||||||
}
|
}
|
||||||
|
|
||||||
return getTargets((targets: any), {
|
return getTargets(targets, {
|
||||||
ignoreBrowserslistConfig: true,
|
ignoreBrowserslistConfig: true,
|
||||||
browserslistEnv: options.browserslistEnv,
|
browserslistEnv: options.browserslistEnv,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,20 +1,20 @@
|
|||||||
// @flow
|
type browserType = typeof import("./resolve-targets-browser");
|
||||||
|
type nodeType = typeof import("./resolve-targets");
|
||||||
import typeof * as browserType from "./resolve-targets-browser";
|
|
||||||
import typeof * as nodeType from "./resolve-targets";
|
|
||||||
|
|
||||||
// Kind of gross, but essentially asserting that the exports of this module are the same as the
|
// Kind of gross, but essentially asserting that the exports of this module are the same as the
|
||||||
// exports of index-browser, since this file may be replaced at bundle time with index-browser.
|
// exports of index-browser, since this file may be replaced at bundle time with index-browser.
|
||||||
((({}: any): $Exact<browserType>): $Exact<nodeType>);
|
((({} as any) as browserType) as nodeType);
|
||||||
|
|
||||||
import type { ValidatedOptions } from "./validation/options";
|
import type { ValidatedOptions } from "./validation/options";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import getTargets, { type Targets } from "@babel/helper-compilation-targets";
|
import getTargets from "@babel/helper-compilation-targets";
|
||||||
|
|
||||||
|
import type { Targets } from "@babel/helper-compilation-targets";
|
||||||
|
|
||||||
export function resolveBrowserslistConfigFile(
|
export function resolveBrowserslistConfigFile(
|
||||||
browserslistConfigFile: string,
|
browserslistConfigFile: string,
|
||||||
configFileDir: string,
|
configFileDir: string,
|
||||||
): string | void {
|
): string | undefined {
|
||||||
return path.resolve(configFileDir, browserslistConfigFile);
|
return path.resolve(configFileDir, browserslistConfigFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,11 +22,11 @@ export function resolveTargets(
|
|||||||
options: ValidatedOptions,
|
options: ValidatedOptions,
|
||||||
root: string,
|
root: string,
|
||||||
): Targets {
|
): Targets {
|
||||||
let { targets } = options;
|
// todo(flow->ts) remove any and refactor to not assign different types into same variable
|
||||||
|
let targets: any = options.targets;
|
||||||
if (typeof targets === "string" || Array.isArray(targets)) {
|
if (typeof targets === "string" || Array.isArray(targets)) {
|
||||||
targets = { browsers: targets };
|
targets = { browsers: targets };
|
||||||
}
|
}
|
||||||
// $FlowIgnore it thinks that targets.esmodules doesn't exist.
|
|
||||||
if (targets && targets.esmodules) {
|
if (targets && targets.esmodules) {
|
||||||
targets = { ...targets, esmodules: "intersect" };
|
targets = { ...targets, esmodules: "intersect" };
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ export function resolveTargets(
|
|||||||
ignoreBrowserslistConfig = browserslistConfigFile === false;
|
ignoreBrowserslistConfig = browserslistConfigFile === false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getTargets((targets: any), {
|
return getTargets(targets, {
|
||||||
ignoreBrowserslistConfig,
|
ignoreBrowserslistConfig,
|
||||||
configFile,
|
configFile,
|
||||||
configPath: root,
|
configPath: root,
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import type { ValidatedOptions, NormalizedOptions } from "./validation/options";
|
import type { ValidatedOptions, NormalizedOptions } from "./validation/options";
|
||||||
|
|
||||||
export function mergeOptions(
|
export function mergeOptions(
|
||||||
@ -16,25 +14,22 @@ export function mergeOptions(
|
|||||||
mergeDefaultFields(targetObj, parserOpts);
|
mergeDefaultFields(targetObj, parserOpts);
|
||||||
} else {
|
} else {
|
||||||
const val = source[k];
|
const val = source[k];
|
||||||
if (val !== undefined) target[k] = (val: any);
|
if (val !== undefined) target[k] = val as any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeDefaultFields<T: {}>(target: T, source: T) {
|
function mergeDefaultFields<T extends {}>(target: T, source: T) {
|
||||||
for (const k of Object.keys(source)) {
|
for (const k of Object.keys(source)) {
|
||||||
const val = source[k];
|
const val = source[k];
|
||||||
if (val !== undefined) target[k] = (val: any);
|
if (val !== undefined) target[k] = val as any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isIterableIterator(value: mixed): boolean %checks {
|
export function isIterableIterator(value: any): value is IterableIterator<any> {
|
||||||
return (
|
return (
|
||||||
/*:: value instanceof Generator && */
|
|
||||||
// /*:: "@@iterator" in value && */
|
|
||||||
!!value &&
|
!!value &&
|
||||||
typeof value.next === "function" &&
|
typeof value.next === "function" &&
|
||||||
// $FlowIgnore
|
|
||||||
typeof value[Symbol.iterator] === "function"
|
typeof value[Symbol.iterator] === "function"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isBrowsersQueryValid,
|
isBrowsersQueryValid,
|
||||||
TargetNames,
|
TargetNames,
|
||||||
@ -29,10 +27,10 @@ import { assumptionsNames } from "./options";
|
|||||||
export type { RootPath } from "./options";
|
export type { RootPath } from "./options";
|
||||||
|
|
||||||
export type ValidatorSet = {
|
export type ValidatorSet = {
|
||||||
[string]: Validator<any>,
|
[name: string]: Validator<any>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Validator<T> = (OptionPath, mixed) => T;
|
export type Validator<T> = (loc: OptionPath, value: unknown) => T;
|
||||||
|
|
||||||
export function msg(loc: NestingPath | GeneralPath) {
|
export function msg(loc: NestingPath | GeneralPath) {
|
||||||
switch (loc.type) {
|
switch (loc.type) {
|
||||||
@ -47,6 +45,7 @@ export function msg(loc: NestingPath | GeneralPath) {
|
|||||||
case "access":
|
case "access":
|
||||||
return `${msg(loc.parent)}[${JSON.stringify(loc.name)}]`;
|
return `${msg(loc.parent)}[${JSON.stringify(loc.name)}]`;
|
||||||
default:
|
default:
|
||||||
|
// @ts-ignore should not happen when code is type checked
|
||||||
throw new Error(`Assertion failure: Unknown type ${loc.type}`);
|
throw new Error(`Assertion failure: Unknown type ${loc.type}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,19 +58,22 @@ export function access(loc: GeneralPath, name: string | number): AccessPath {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OptionPath = $ReadOnly<{
|
export type OptionPath = Readonly<{
|
||||||
type: "option",
|
type: "option";
|
||||||
name: string,
|
name: string;
|
||||||
parent: NestingPath,
|
parent: NestingPath;
|
||||||
}>;
|
}>;
|
||||||
type AccessPath = $ReadOnly<{
|
type AccessPath = Readonly<{
|
||||||
type: "access",
|
type: "access";
|
||||||
name: string | number,
|
name: string | number;
|
||||||
parent: GeneralPath,
|
parent: GeneralPath;
|
||||||
}>;
|
}>;
|
||||||
type GeneralPath = OptionPath | AccessPath;
|
type GeneralPath = OptionPath | AccessPath;
|
||||||
|
|
||||||
export function assertRootMode(loc: OptionPath, value: mixed): RootMode | void {
|
export function assertRootMode(
|
||||||
|
loc: OptionPath,
|
||||||
|
value: unknown,
|
||||||
|
): RootMode | void {
|
||||||
if (
|
if (
|
||||||
value !== undefined &&
|
value !== undefined &&
|
||||||
value !== "root" &&
|
value !== "root" &&
|
||||||
@ -87,7 +89,7 @@ export function assertRootMode(loc: OptionPath, value: mixed): RootMode | void {
|
|||||||
|
|
||||||
export function assertSourceMaps(
|
export function assertSourceMaps(
|
||||||
loc: OptionPath,
|
loc: OptionPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): SourceMapsOption | void {
|
): SourceMapsOption | void {
|
||||||
if (
|
if (
|
||||||
value !== undefined &&
|
value !== undefined &&
|
||||||
@ -104,7 +106,7 @@ export function assertSourceMaps(
|
|||||||
|
|
||||||
export function assertCompact(
|
export function assertCompact(
|
||||||
loc: OptionPath,
|
loc: OptionPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): CompactOption | void {
|
): CompactOption | void {
|
||||||
if (value !== undefined && typeof value !== "boolean" && value !== "auto") {
|
if (value !== undefined && typeof value !== "boolean" && value !== "auto") {
|
||||||
throw new Error(`${msg(loc)} must be a boolean, "auto", or undefined`);
|
throw new Error(`${msg(loc)} must be a boolean, "auto", or undefined`);
|
||||||
@ -114,7 +116,7 @@ export function assertCompact(
|
|||||||
|
|
||||||
export function assertSourceType(
|
export function assertSourceType(
|
||||||
loc: OptionPath,
|
loc: OptionPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): SourceTypeOption | void {
|
): SourceTypeOption | void {
|
||||||
if (
|
if (
|
||||||
value !== undefined &&
|
value !== undefined &&
|
||||||
@ -131,11 +133,11 @@ export function assertSourceType(
|
|||||||
|
|
||||||
export function assertCallerMetadata(
|
export function assertCallerMetadata(
|
||||||
loc: OptionPath,
|
loc: OptionPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): CallerMetadata | void {
|
): CallerMetadata | void {
|
||||||
const obj = assertObject(loc, value);
|
const obj = assertObject(loc, value);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
if (typeof obj[("name": string)] !== "string") {
|
if (typeof obj.name !== "string") {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${msg(loc)} set but does not contain "name" property string`,
|
`${msg(loc)} set but does not contain "name" property string`,
|
||||||
);
|
);
|
||||||
@ -161,12 +163,13 @@ export function assertCallerMetadata(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (value: any);
|
// @ts-expect-error todo(flow->ts)
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function assertInputSourceMap(
|
export function assertInputSourceMap(
|
||||||
loc: OptionPath,
|
loc: OptionPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): RootInputSourceMapOption | void {
|
): RootInputSourceMapOption | void {
|
||||||
if (
|
if (
|
||||||
value !== undefined &&
|
value !== undefined &&
|
||||||
@ -178,7 +181,7 @@ export function assertInputSourceMap(
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function assertString(loc: GeneralPath, value: mixed): string | void {
|
export function assertString(loc: GeneralPath, value: unknown): string | void {
|
||||||
if (value !== undefined && typeof value !== "string") {
|
if (value !== undefined && typeof value !== "string") {
|
||||||
throw new Error(`${msg(loc)} must be a string, or undefined`);
|
throw new Error(`${msg(loc)} must be a string, or undefined`);
|
||||||
}
|
}
|
||||||
@ -187,7 +190,7 @@ export function assertString(loc: GeneralPath, value: mixed): string | void {
|
|||||||
|
|
||||||
export function assertFunction(
|
export function assertFunction(
|
||||||
loc: GeneralPath,
|
loc: GeneralPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): Function | void {
|
): Function | void {
|
||||||
if (value !== undefined && typeof value !== "function") {
|
if (value !== undefined && typeof value !== "function") {
|
||||||
throw new Error(`${msg(loc)} must be a function, or undefined`);
|
throw new Error(`${msg(loc)} must be a function, or undefined`);
|
||||||
@ -195,7 +198,10 @@ export function assertFunction(
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function assertBoolean(loc: GeneralPath, value: mixed): boolean | void {
|
export function assertBoolean(
|
||||||
|
loc: GeneralPath,
|
||||||
|
value: unknown,
|
||||||
|
): boolean | void {
|
||||||
if (value !== undefined && typeof value !== "boolean") {
|
if (value !== undefined && typeof value !== "boolean") {
|
||||||
throw new Error(`${msg(loc)} must be a boolean, or undefined`);
|
throw new Error(`${msg(loc)} must be a boolean, or undefined`);
|
||||||
}
|
}
|
||||||
@ -204,21 +210,22 @@ export function assertBoolean(loc: GeneralPath, value: mixed): boolean | void {
|
|||||||
|
|
||||||
export function assertObject(
|
export function assertObject(
|
||||||
loc: GeneralPath,
|
loc: GeneralPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): { +[string]: mixed } | void {
|
): { readonly [key: string]: unknown } | void {
|
||||||
if (
|
if (
|
||||||
value !== undefined &&
|
value !== undefined &&
|
||||||
(typeof value !== "object" || Array.isArray(value) || !value)
|
(typeof value !== "object" || Array.isArray(value) || !value)
|
||||||
) {
|
) {
|
||||||
throw new Error(`${msg(loc)} must be an object, or undefined`);
|
throw new Error(`${msg(loc)} must be an object, or undefined`);
|
||||||
}
|
}
|
||||||
|
// @ts-expect-error todo(flow->ts) value is still typed as unknown, also assert function typically should not return a value
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function assertArray(
|
export function assertArray<T>(
|
||||||
loc: GeneralPath,
|
loc: GeneralPath,
|
||||||
value: mixed,
|
value: Array<T> | undefined | null,
|
||||||
): ?$ReadOnlyArray<mixed> {
|
): ReadonlyArray<T> | undefined | null {
|
||||||
if (value != null && !Array.isArray(value)) {
|
if (value != null && !Array.isArray(value)) {
|
||||||
throw new Error(`${msg(loc)} must be an array, or undefined`);
|
throw new Error(`${msg(loc)} must be an array, or undefined`);
|
||||||
}
|
}
|
||||||
@ -227,15 +234,16 @@ export function assertArray(
|
|||||||
|
|
||||||
export function assertIgnoreList(
|
export function assertIgnoreList(
|
||||||
loc: OptionPath,
|
loc: OptionPath,
|
||||||
value: mixed,
|
value: unknown[] | undefined,
|
||||||
): IgnoreList | void {
|
): IgnoreList | void {
|
||||||
const arr = assertArray(loc, value);
|
const arr = assertArray(loc, value);
|
||||||
if (arr) {
|
if (arr) {
|
||||||
arr.forEach((item, i) => assertIgnoreItem(access(loc, i), item));
|
arr.forEach((item, i) => assertIgnoreItem(access(loc, i), item));
|
||||||
}
|
}
|
||||||
return (arr: any);
|
// @ts-expect-error todo(flow->ts)
|
||||||
|
return arr;
|
||||||
}
|
}
|
||||||
function assertIgnoreItem(loc: GeneralPath, value: mixed): IgnoreItem {
|
function assertIgnoreItem(loc: GeneralPath, value: unknown): IgnoreItem {
|
||||||
if (
|
if (
|
||||||
typeof value !== "string" &&
|
typeof value !== "string" &&
|
||||||
typeof value !== "function" &&
|
typeof value !== "function" &&
|
||||||
@ -252,7 +260,7 @@ function assertIgnoreItem(loc: GeneralPath, value: mixed): IgnoreItem {
|
|||||||
|
|
||||||
export function assertConfigApplicableTest(
|
export function assertConfigApplicableTest(
|
||||||
loc: OptionPath,
|
loc: OptionPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): ConfigApplicableTest | void {
|
): ConfigApplicableTest | void {
|
||||||
if (value === undefined) return value;
|
if (value === undefined) return value;
|
||||||
|
|
||||||
@ -269,10 +277,10 @@ export function assertConfigApplicableTest(
|
|||||||
`${msg(loc)} must be a string/Function/RegExp, or an array of those`,
|
`${msg(loc)} must be a string/Function/RegExp, or an array of those`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (value: any);
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkValidTest(value: mixed): boolean {
|
function checkValidTest(value: unknown): value is string | Function | RegExp {
|
||||||
return (
|
return (
|
||||||
typeof value === "string" ||
|
typeof value === "string" ||
|
||||||
typeof value === "function" ||
|
typeof value === "function" ||
|
||||||
@ -282,7 +290,7 @@ function checkValidTest(value: mixed): boolean {
|
|||||||
|
|
||||||
export function assertConfigFileSearch(
|
export function assertConfigFileSearch(
|
||||||
loc: OptionPath,
|
loc: OptionPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): ConfigFileSearch | void {
|
): ConfigFileSearch | void {
|
||||||
if (
|
if (
|
||||||
value !== undefined &&
|
value !== undefined &&
|
||||||
@ -291,7 +299,7 @@ export function assertConfigFileSearch(
|
|||||||
) {
|
) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${msg(loc)} must be a undefined, a boolean, a string, ` +
|
`${msg(loc)} must be a undefined, a boolean, a string, ` +
|
||||||
`got ${JSON.stringify((value: any))}`,
|
`got ${JSON.stringify(value)}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +308,7 @@ export function assertConfigFileSearch(
|
|||||||
|
|
||||||
export function assertBabelrcSearch(
|
export function assertBabelrcSearch(
|
||||||
loc: OptionPath,
|
loc: OptionPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): BabelrcSearch | void {
|
): BabelrcSearch | void {
|
||||||
if (value === undefined || typeof value === "boolean") return value;
|
if (value === undefined || typeof value === "boolean") return value;
|
||||||
|
|
||||||
@ -315,15 +323,15 @@ export function assertBabelrcSearch(
|
|||||||
} else if (!checkValidTest(value)) {
|
} else if (!checkValidTest(value)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${msg(loc)} must be a undefined, a boolean, a string/Function/RegExp ` +
|
`${msg(loc)} must be a undefined, a boolean, a string/Function/RegExp ` +
|
||||||
`or an array of those, got ${JSON.stringify((value: any))}`,
|
`or an array of those, got ${JSON.stringify(value as any)}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (value: any);
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function assertPluginList(
|
export function assertPluginList(
|
||||||
loc: OptionPath,
|
loc: OptionPath,
|
||||||
value: mixed,
|
value: unknown[] | null | undefined,
|
||||||
): PluginList | void {
|
): PluginList | void {
|
||||||
const arr = assertArray(loc, value);
|
const arr = assertArray(loc, value);
|
||||||
if (arr) {
|
if (arr) {
|
||||||
@ -331,9 +339,9 @@ export function assertPluginList(
|
|||||||
// for plugin array for use during config chain processing.
|
// for plugin array for use during config chain processing.
|
||||||
arr.forEach((item, i) => assertPluginItem(access(loc, i), item));
|
arr.forEach((item, i) => assertPluginItem(access(loc, i), item));
|
||||||
}
|
}
|
||||||
return (arr: any);
|
return arr as any;
|
||||||
}
|
}
|
||||||
function assertPluginItem(loc: GeneralPath, value: mixed): PluginItem {
|
function assertPluginItem(loc: GeneralPath, value: unknown): PluginItem {
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
if (value.length === 0) {
|
if (value.length === 0) {
|
||||||
throw new Error(`${msg(loc)} must include an object`);
|
throw new Error(`${msg(loc)} must include an object`);
|
||||||
@ -369,9 +377,10 @@ function assertPluginItem(loc: GeneralPath, value: mixed): PluginItem {
|
|||||||
assertPluginTarget(loc, value);
|
assertPluginTarget(loc, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (value: any);
|
// @ts-expect-error todo(flow->ts)
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
function assertPluginTarget(loc: GeneralPath, value: mixed): PluginTarget {
|
function assertPluginTarget(loc: GeneralPath, value: unknown): PluginTarget {
|
||||||
if (
|
if (
|
||||||
(typeof value !== "object" || !value) &&
|
(typeof value !== "object" || !value) &&
|
||||||
typeof value !== "string" &&
|
typeof value !== "string" &&
|
||||||
@ -384,9 +393,9 @@ function assertPluginTarget(loc: GeneralPath, value: mixed): PluginTarget {
|
|||||||
|
|
||||||
export function assertTargets(
|
export function assertTargets(
|
||||||
loc: GeneralPath,
|
loc: GeneralPath,
|
||||||
value: mixed,
|
value: any,
|
||||||
): TargetsListOrObject {
|
): TargetsListOrObject {
|
||||||
if (isBrowsersQueryValid(value)) return (value: any);
|
if (isBrowsersQueryValid(value)) return value;
|
||||||
|
|
||||||
if (typeof value !== "object" || !value || Array.isArray(value)) {
|
if (typeof value !== "object" || !value || Array.isArray(value)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -416,10 +425,10 @@ export function assertTargets(
|
|||||||
} else assertBrowserVersion(subLoc, val);
|
} else assertBrowserVersion(subLoc, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (value: any);
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertBrowsersList(loc: GeneralPath, value: mixed) {
|
function assertBrowsersList(loc: GeneralPath, value: unknown) {
|
||||||
if (value !== undefined && !isBrowsersQueryValid(value)) {
|
if (value !== undefined && !isBrowsersQueryValid(value)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${msg(loc)} must be undefined, a string or an array of strings`,
|
`${msg(loc)} must be undefined, a string or an array of strings`,
|
||||||
@ -427,7 +436,7 @@ function assertBrowsersList(loc: GeneralPath, value: mixed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertBrowserVersion(loc: GeneralPath, value: mixed) {
|
function assertBrowserVersion(loc: GeneralPath, value: unknown) {
|
||||||
if (typeof value === "number" && Math.round(value) === value) return;
|
if (typeof value === "number" && Math.round(value) === value) return;
|
||||||
if (typeof value === "string") return;
|
if (typeof value === "string") return;
|
||||||
|
|
||||||
@ -436,7 +445,7 @@ function assertBrowserVersion(loc: GeneralPath, value: mixed) {
|
|||||||
|
|
||||||
export function assertAssumptions(
|
export function assertAssumptions(
|
||||||
loc: GeneralPath,
|
loc: GeneralPath,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): { [name: string]: boolean } | void {
|
): { [name: string]: boolean } | void {
|
||||||
if (value === undefined) return;
|
if (value === undefined) return;
|
||||||
|
|
||||||
@ -444,7 +453,8 @@ export function assertAssumptions(
|
|||||||
throw new Error(`${msg(loc)} must be an object or undefined.`);
|
throw new Error(`${msg(loc)} must be an object or undefined.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let root = loc;
|
// todo(flow->ts): remove any
|
||||||
|
let root: any = loc;
|
||||||
do {
|
do {
|
||||||
root = root.parent;
|
root = root.parent;
|
||||||
} while (root.type !== "root");
|
} while (root.type !== "root");
|
||||||
@ -465,5 +475,6 @@ export function assertAssumptions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (value: any);
|
// @ts-expect-error todo(flow->ts)
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import type { InputTargets, Targets } from "@babel/helper-compilation-targets";
|
import type { InputTargets, Targets } from "@babel/helper-compilation-targets";
|
||||||
|
|
||||||
import type { ConfigItem } from "../item";
|
import type { ConfigItem } from "../item";
|
||||||
@ -26,159 +24,99 @@ import {
|
|||||||
assertCompact,
|
assertCompact,
|
||||||
assertSourceType,
|
assertSourceType,
|
||||||
assertTargets,
|
assertTargets,
|
||||||
type ValidatorSet,
|
|
||||||
type Validator,
|
|
||||||
type OptionPath,
|
|
||||||
assertAssumptions,
|
assertAssumptions,
|
||||||
} from "./option-assertions";
|
} from "./option-assertions";
|
||||||
|
import type { ValidatorSet, Validator, OptionPath } from "./option-assertions";
|
||||||
import type { UnloadedDescriptor } from "../config-descriptors";
|
import type { UnloadedDescriptor } from "../config-descriptors";
|
||||||
|
|
||||||
const ROOT_VALIDATORS: ValidatorSet = {
|
const ROOT_VALIDATORS: ValidatorSet = {
|
||||||
cwd: (assertString: Validator<$PropertyType<ValidatedOptions, "cwd">>),
|
cwd: assertString as Validator<ValidatedOptions["cwd"]>,
|
||||||
root: (assertString: Validator<$PropertyType<ValidatedOptions, "root">>),
|
root: assertString as Validator<ValidatedOptions["root"]>,
|
||||||
rootMode: (assertRootMode: Validator<
|
rootMode: assertRootMode as Validator<ValidatedOptions["rootMode"]>,
|
||||||
$PropertyType<ValidatedOptions, "rootMode">,
|
configFile: assertConfigFileSearch as Validator<
|
||||||
>),
|
ValidatedOptions["configFile"]
|
||||||
configFile: (assertConfigFileSearch: Validator<
|
>,
|
||||||
$PropertyType<ValidatedOptions, "configFile">,
|
|
||||||
>),
|
|
||||||
|
|
||||||
caller: (assertCallerMetadata: Validator<
|
caller: assertCallerMetadata as Validator<ValidatedOptions["caller"]>,
|
||||||
$PropertyType<ValidatedOptions, "caller">,
|
filename: assertString as Validator<ValidatedOptions["filename"]>,
|
||||||
>),
|
filenameRelative: assertString as Validator<
|
||||||
filename: (assertString: Validator<
|
ValidatedOptions["filenameRelative"]
|
||||||
$PropertyType<ValidatedOptions, "filename">,
|
>,
|
||||||
>),
|
code: assertBoolean as Validator<ValidatedOptions["code"]>,
|
||||||
filenameRelative: (assertString: Validator<
|
ast: assertBoolean as Validator<ValidatedOptions["ast"]>,
|
||||||
$PropertyType<ValidatedOptions, "filenameRelative">,
|
|
||||||
>),
|
|
||||||
code: (assertBoolean: Validator<$PropertyType<ValidatedOptions, "code">>),
|
|
||||||
ast: (assertBoolean: Validator<$PropertyType<ValidatedOptions, "ast">>),
|
|
||||||
|
|
||||||
cloneInputAst: (assertBoolean: Validator<
|
cloneInputAst: assertBoolean as Validator<ValidatedOptions["cloneInputAst"]>,
|
||||||
$PropertyType<ValidatedOptions, "cloneInputAst">,
|
|
||||||
>),
|
|
||||||
|
|
||||||
envName: (assertString: Validator<
|
envName: assertString as Validator<ValidatedOptions["envName"]>,
|
||||||
$PropertyType<ValidatedOptions, "envName">,
|
|
||||||
>),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const BABELRC_VALIDATORS: ValidatorSet = {
|
const BABELRC_VALIDATORS: ValidatorSet = {
|
||||||
babelrc: (assertBoolean: Validator<
|
babelrc: assertBoolean as Validator<ValidatedOptions["babelrc"]>,
|
||||||
$PropertyType<ValidatedOptions, "babelrc">,
|
babelrcRoots: assertBabelrcSearch as Validator<
|
||||||
>),
|
ValidatedOptions["babelrcRoots"]
|
||||||
babelrcRoots: (assertBabelrcSearch: Validator<
|
>,
|
||||||
$PropertyType<ValidatedOptions, "babelrcRoots">,
|
|
||||||
>),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const NONPRESET_VALIDATORS: ValidatorSet = {
|
const NONPRESET_VALIDATORS: ValidatorSet = {
|
||||||
extends: (assertString: Validator<
|
extends: assertString as Validator<ValidatedOptions["extends"]>,
|
||||||
$PropertyType<ValidatedOptions, "extends">,
|
ignore: assertIgnoreList as Validator<ValidatedOptions["ignore"]>,
|
||||||
>),
|
only: assertIgnoreList as Validator<ValidatedOptions["only"]>,
|
||||||
ignore: (assertIgnoreList: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "ignore">,
|
|
||||||
>),
|
|
||||||
only: (assertIgnoreList: Validator<$PropertyType<ValidatedOptions, "only">>),
|
|
||||||
|
|
||||||
targets: (assertTargets: Validator<
|
targets: assertTargets as Validator<ValidatedOptions["targets"]>,
|
||||||
$PropertyType<ValidatedOptions, "targets">,
|
browserslistConfigFile: assertConfigFileSearch as Validator<
|
||||||
>),
|
ValidatedOptions["browserslistConfigFile"]
|
||||||
browserslistConfigFile: (assertConfigFileSearch: Validator<
|
>,
|
||||||
$PropertyType<ValidatedOptions, "browserslistConfigFile">,
|
browserslistEnv: assertString as Validator<
|
||||||
>),
|
ValidatedOptions["browserslistEnv"]
|
||||||
browserslistEnv: (assertString: Validator<
|
>,
|
||||||
$PropertyType<ValidatedOptions, "browserslistEnv">,
|
|
||||||
>),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const COMMON_VALIDATORS: ValidatorSet = {
|
const COMMON_VALIDATORS: ValidatorSet = {
|
||||||
// TODO: Should 'inputSourceMap' be moved to be a root-only option?
|
// TODO: Should 'inputSourceMap' be moved to be a root-only option?
|
||||||
// We may want a boolean-only version to be a common option, with the
|
// We may want a boolean-only version to be a common option, with the
|
||||||
// object only allowed as a root config argument.
|
// object only allowed as a root config argument.
|
||||||
inputSourceMap: (assertInputSourceMap: Validator<
|
inputSourceMap: assertInputSourceMap as Validator<
|
||||||
$PropertyType<ValidatedOptions, "inputSourceMap">,
|
ValidatedOptions["inputSourceMap"]
|
||||||
>),
|
>,
|
||||||
presets: (assertPluginList: Validator<
|
presets: assertPluginList as Validator<ValidatedOptions["presets"]>,
|
||||||
$PropertyType<ValidatedOptions, "presets">,
|
plugins: assertPluginList as Validator<ValidatedOptions["plugins"]>,
|
||||||
>),
|
passPerPreset: assertBoolean as Validator<ValidatedOptions["passPerPreset"]>,
|
||||||
plugins: (assertPluginList: Validator<
|
assumptions: assertAssumptions as Validator<ValidatedOptions["assumptions"]>,
|
||||||
$PropertyType<ValidatedOptions, "plugins">,
|
|
||||||
>),
|
|
||||||
passPerPreset: (assertBoolean: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "passPerPreset">,
|
|
||||||
>),
|
|
||||||
assumptions: (assertAssumptions: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "assumptions">,
|
|
||||||
>),
|
|
||||||
|
|
||||||
env: (assertEnvSet: Validator<$PropertyType<ValidatedOptions, "env">>),
|
env: assertEnvSet as Validator<ValidatedOptions["env"]>,
|
||||||
overrides: (assertOverridesList: Validator<
|
overrides: assertOverridesList as Validator<ValidatedOptions["overrides"]>,
|
||||||
$PropertyType<ValidatedOptions, "overrides">,
|
|
||||||
>),
|
|
||||||
|
|
||||||
// We could limit these to 'overrides' blocks, but it's not clear why we'd
|
// We could limit these to 'overrides' blocks, but it's not clear why we'd
|
||||||
// bother, when the ability to limit a config to a specific set of files
|
// bother, when the ability to limit a config to a specific set of files
|
||||||
// is a fairly general useful feature.
|
// is a fairly general useful feature.
|
||||||
test: (assertConfigApplicableTest: Validator<
|
test: assertConfigApplicableTest as Validator<ValidatedOptions["test"]>,
|
||||||
$PropertyType<ValidatedOptions, "test">,
|
include: assertConfigApplicableTest as Validator<ValidatedOptions["include"]>,
|
||||||
>),
|
exclude: assertConfigApplicableTest as Validator<ValidatedOptions["exclude"]>,
|
||||||
include: (assertConfigApplicableTest: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "include">,
|
|
||||||
>),
|
|
||||||
exclude: (assertConfigApplicableTest: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "exclude">,
|
|
||||||
>),
|
|
||||||
|
|
||||||
retainLines: (assertBoolean: Validator<
|
retainLines: assertBoolean as Validator<ValidatedOptions["retainLines"]>,
|
||||||
$PropertyType<ValidatedOptions, "retainLines">,
|
comments: assertBoolean as Validator<ValidatedOptions["comments"]>,
|
||||||
>),
|
shouldPrintComment: assertFunction as Validator<
|
||||||
comments: (assertBoolean: Validator<
|
ValidatedOptions["shouldPrintComment"]
|
||||||
$PropertyType<ValidatedOptions, "comments">,
|
>,
|
||||||
>),
|
compact: assertCompact as Validator<ValidatedOptions["compact"]>,
|
||||||
shouldPrintComment: (assertFunction: Validator<
|
minified: assertBoolean as Validator<ValidatedOptions["minified"]>,
|
||||||
$PropertyType<ValidatedOptions, "shouldPrintComment">,
|
auxiliaryCommentBefore: assertString as Validator<
|
||||||
>),
|
ValidatedOptions["auxiliaryCommentBefore"]
|
||||||
compact: (assertCompact: Validator<
|
>,
|
||||||
$PropertyType<ValidatedOptions, "compact">,
|
auxiliaryCommentAfter: assertString as Validator<
|
||||||
>),
|
ValidatedOptions["auxiliaryCommentAfter"]
|
||||||
minified: (assertBoolean: Validator<
|
>,
|
||||||
$PropertyType<ValidatedOptions, "minified">,
|
sourceType: assertSourceType as Validator<ValidatedOptions["sourceType"]>,
|
||||||
>),
|
wrapPluginVisitorMethod: assertFunction as Validator<
|
||||||
auxiliaryCommentBefore: (assertString: Validator<
|
ValidatedOptions["wrapPluginVisitorMethod"]
|
||||||
$PropertyType<ValidatedOptions, "auxiliaryCommentBefore">,
|
>,
|
||||||
>),
|
highlightCode: assertBoolean as Validator<ValidatedOptions["highlightCode"]>,
|
||||||
auxiliaryCommentAfter: (assertString: Validator<
|
sourceMaps: assertSourceMaps as Validator<ValidatedOptions["sourceMaps"]>,
|
||||||
$PropertyType<ValidatedOptions, "auxiliaryCommentAfter">,
|
sourceMap: assertSourceMaps as Validator<ValidatedOptions["sourceMap"]>,
|
||||||
>),
|
sourceFileName: assertString as Validator<ValidatedOptions["sourceFileName"]>,
|
||||||
sourceType: (assertSourceType: Validator<
|
sourceRoot: assertString as Validator<ValidatedOptions["sourceRoot"]>,
|
||||||
$PropertyType<ValidatedOptions, "sourceType">,
|
parserOpts: assertObject as Validator<ValidatedOptions["parserOpts"]>,
|
||||||
>),
|
generatorOpts: assertObject as Validator<ValidatedOptions["generatorOpts"]>,
|
||||||
wrapPluginVisitorMethod: (assertFunction: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "wrapPluginVisitorMethod">,
|
|
||||||
>),
|
|
||||||
highlightCode: (assertBoolean: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "highlightCode">,
|
|
||||||
>),
|
|
||||||
sourceMaps: (assertSourceMaps: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "sourceMaps">,
|
|
||||||
>),
|
|
||||||
sourceMap: (assertSourceMaps: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "sourceMap">,
|
|
||||||
>),
|
|
||||||
sourceFileName: (assertString: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "sourceFileName">,
|
|
||||||
>),
|
|
||||||
sourceRoot: (assertString: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "sourceRoot">,
|
|
||||||
>),
|
|
||||||
parserOpts: (assertObject: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "parserOpts">,
|
|
||||||
>),
|
|
||||||
generatorOpts: (assertObject: Validator<
|
|
||||||
$PropertyType<ValidatedOptions, "generatorOpts">,
|
|
||||||
>),
|
|
||||||
};
|
};
|
||||||
if (!process.env.BABEL_8_BREAKING) {
|
if (!process.env.BABEL_8_BREAKING) {
|
||||||
Object.assign(COMMON_VALIDATORS, {
|
Object.assign(COMMON_VALIDATORS, {
|
||||||
@ -192,95 +130,86 @@ if (!process.env.BABEL_8_BREAKING) {
|
|||||||
export type InputOptions = ValidatedOptions;
|
export type InputOptions = ValidatedOptions;
|
||||||
|
|
||||||
export type ValidatedOptions = {
|
export type ValidatedOptions = {
|
||||||
cwd?: string,
|
cwd?: string;
|
||||||
filename?: string,
|
filename?: string;
|
||||||
filenameRelative?: string,
|
filenameRelative?: string;
|
||||||
babelrc?: boolean,
|
babelrc?: boolean;
|
||||||
babelrcRoots?: BabelrcSearch,
|
babelrcRoots?: BabelrcSearch;
|
||||||
configFile?: ConfigFileSearch,
|
configFile?: ConfigFileSearch;
|
||||||
root?: string,
|
root?: string;
|
||||||
rootMode?: RootMode,
|
rootMode?: RootMode;
|
||||||
code?: boolean,
|
code?: boolean;
|
||||||
ast?: boolean,
|
ast?: boolean;
|
||||||
cloneInputAst?: boolean,
|
cloneInputAst?: boolean;
|
||||||
inputSourceMap?: RootInputSourceMapOption,
|
inputSourceMap?: RootInputSourceMapOption;
|
||||||
envName?: string,
|
envName?: string;
|
||||||
caller?: CallerMetadata,
|
caller?: CallerMetadata;
|
||||||
|
extends?: string;
|
||||||
extends?: string,
|
env?: EnvSet<ValidatedOptions>;
|
||||||
env?: EnvSet<ValidatedOptions>,
|
ignore?: IgnoreList;
|
||||||
ignore?: IgnoreList,
|
only?: IgnoreList;
|
||||||
only?: IgnoreList,
|
overrides?: OverridesList;
|
||||||
overrides?: OverridesList,
|
|
||||||
|
|
||||||
// Generally verify if a given config object should be applied to the given file.
|
// Generally verify if a given config object should be applied to the given file.
|
||||||
test?: ConfigApplicableTest,
|
test?: ConfigApplicableTest;
|
||||||
include?: ConfigApplicableTest,
|
include?: ConfigApplicableTest;
|
||||||
exclude?: ConfigApplicableTest,
|
exclude?: ConfigApplicableTest;
|
||||||
|
presets?: PluginList;
|
||||||
presets?: PluginList,
|
plugins?: PluginList;
|
||||||
plugins?: PluginList,
|
passPerPreset?: boolean;
|
||||||
passPerPreset?: boolean,
|
assumptions?: {
|
||||||
|
[name: string]: boolean;
|
||||||
assumptions?: { [name: string]: boolean },
|
};
|
||||||
|
|
||||||
// browserslists-related options
|
// browserslists-related options
|
||||||
targets?: TargetsListOrObject,
|
targets?: TargetsListOrObject;
|
||||||
browserslistConfigFile?: ConfigFileSearch,
|
browserslistConfigFile?: ConfigFileSearch;
|
||||||
browserslistEnv?: string,
|
browserslistEnv?: string;
|
||||||
|
|
||||||
// Options for @babel/generator
|
// Options for @babel/generator
|
||||||
retainLines?: boolean,
|
retainLines?: boolean;
|
||||||
comments?: boolean,
|
comments?: boolean;
|
||||||
shouldPrintComment?: Function,
|
shouldPrintComment?: Function;
|
||||||
compact?: CompactOption,
|
compact?: CompactOption;
|
||||||
minified?: boolean,
|
minified?: boolean;
|
||||||
auxiliaryCommentBefore?: string,
|
auxiliaryCommentBefore?: string;
|
||||||
auxiliaryCommentAfter?: string,
|
auxiliaryCommentAfter?: string;
|
||||||
|
|
||||||
// Parser
|
// Parser
|
||||||
sourceType?: SourceTypeOption,
|
sourceType?: SourceTypeOption;
|
||||||
|
wrapPluginVisitorMethod?: Function;
|
||||||
wrapPluginVisitorMethod?: Function,
|
highlightCode?: boolean;
|
||||||
highlightCode?: boolean,
|
|
||||||
|
|
||||||
// Sourcemap generation options.
|
// Sourcemap generation options.
|
||||||
sourceMaps?: SourceMapsOption,
|
sourceMaps?: SourceMapsOption;
|
||||||
sourceMap?: SourceMapsOption,
|
sourceMap?: SourceMapsOption;
|
||||||
sourceFileName?: string,
|
sourceFileName?: string;
|
||||||
sourceRoot?: string,
|
sourceRoot?: string;
|
||||||
|
|
||||||
// Deprecate top level parserOpts
|
// Deprecate top level parserOpts
|
||||||
parserOpts?: {},
|
parserOpts?: {};
|
||||||
// Deprecate top level generatorOpts
|
// Deprecate top level generatorOpts
|
||||||
generatorOpts?: {},
|
generatorOpts?: {};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NormalizedOptions = {
|
export type NormalizedOptions = {
|
||||||
...$Diff<ValidatedOptions, { targets: any }>,
|
readonly targets: Targets;
|
||||||
+targets: Targets,
|
} & Omit<ValidatedOptions, "targets">;
|
||||||
};
|
|
||||||
|
|
||||||
export type CallerMetadata = {
|
export type CallerMetadata = {
|
||||||
// If 'caller' is specified, require that the name is given for debugging
|
// If 'caller' is specified, require that the name is given for debugging
|
||||||
// messages.
|
// messages.
|
||||||
name: string,
|
name: string;
|
||||||
};
|
};
|
||||||
export type EnvSet<T> = {
|
export type EnvSet<T> = {
|
||||||
[string]: ?T,
|
[x: string]: T;
|
||||||
};
|
};
|
||||||
export type IgnoreItem = string | Function | RegExp;
|
export type IgnoreItem = string | Function | RegExp;
|
||||||
export type IgnoreList = $ReadOnlyArray<IgnoreItem>;
|
export type IgnoreList = ReadonlyArray<IgnoreItem>;
|
||||||
|
|
||||||
export type PluginOptions = {} | void | false;
|
export type PluginOptions = object | void | false;
|
||||||
export type PluginTarget = string | {} | Function;
|
export type PluginTarget = string | object | Function;
|
||||||
export type PluginItem =
|
export type PluginItem =
|
||||||
| ConfigItem
|
| ConfigItem
|
||||||
| Plugin
|
| Plugin
|
||||||
| PluginTarget
|
| PluginTarget
|
||||||
| [PluginTarget, PluginOptions]
|
| [PluginTarget, PluginOptions]
|
||||||
| [PluginTarget, PluginOptions, string | void];
|
| [PluginTarget, PluginOptions, string | void];
|
||||||
export type PluginList = $ReadOnlyArray<PluginItem>;
|
export type PluginList = ReadonlyArray<PluginItem>;
|
||||||
|
|
||||||
export type OverridesList = Array<ValidatedOptions>;
|
export type OverridesList = Array<ValidatedOptions>;
|
||||||
export type ConfigApplicableTest = IgnoreItem | Array<IgnoreItem>;
|
export type ConfigApplicableTest = IgnoreItem | Array<IgnoreItem>;
|
||||||
@ -296,7 +225,7 @@ export type RootMode = "root" | "upward" | "upward-optional";
|
|||||||
export type TargetsListOrObject =
|
export type TargetsListOrObject =
|
||||||
| Targets
|
| Targets
|
||||||
| InputTargets
|
| InputTargets
|
||||||
| $PropertyType<InputTargets, "browsers">;
|
| InputTargets["browsers"];
|
||||||
|
|
||||||
export type OptionsSource =
|
export type OptionsSource =
|
||||||
| "arguments"
|
| "arguments"
|
||||||
@ -306,20 +235,23 @@ export type OptionsSource =
|
|||||||
| "preset"
|
| "preset"
|
||||||
| "plugin";
|
| "plugin";
|
||||||
|
|
||||||
export type RootPath = $ReadOnly<{
|
export type RootPath = Readonly<{
|
||||||
type: "root",
|
type: "root";
|
||||||
source: OptionsSource,
|
source: OptionsSource;
|
||||||
}>;
|
}>;
|
||||||
type OverridesPath = $ReadOnly<{
|
|
||||||
type: "overrides",
|
type OverridesPath = Readonly<{
|
||||||
index: number,
|
type: "overrides";
|
||||||
parent: RootPath,
|
index: number;
|
||||||
|
parent: RootPath;
|
||||||
}>;
|
}>;
|
||||||
type EnvPath = $ReadOnly<{
|
|
||||||
type: "env",
|
type EnvPath = Readonly<{
|
||||||
name: string,
|
type: "env";
|
||||||
parent: RootPath | OverridesPath,
|
name: string;
|
||||||
|
parent: RootPath | OverridesPath;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type NestingPath = RootPath | OverridesPath | EnvPath;
|
export type NestingPath = RootPath | OverridesPath | EnvPath;
|
||||||
|
|
||||||
export const assumptionsNames = new Set<string>([
|
export const assumptionsNames = new Set<string>([
|
||||||
@ -369,7 +301,7 @@ function validateNested(loc: NestingPath, opts: {}) {
|
|||||||
type: "option",
|
type: "option",
|
||||||
name: key,
|
name: key,
|
||||||
parent: loc,
|
parent: loc,
|
||||||
};
|
} as const;
|
||||||
|
|
||||||
if (type === "preset" && NONPRESET_VALIDATORS[key]) {
|
if (type === "preset" && NONPRESET_VALIDATORS[key]) {
|
||||||
throw new Error(`${msg(optLoc)} is not allowed in preset options`);
|
throw new Error(`${msg(optLoc)} is not allowed in preset options`);
|
||||||
@ -405,22 +337,19 @@ function validateNested(loc: NestingPath, opts: {}) {
|
|||||||
NONPRESET_VALIDATORS[key] ||
|
NONPRESET_VALIDATORS[key] ||
|
||||||
BABELRC_VALIDATORS[key] ||
|
BABELRC_VALIDATORS[key] ||
|
||||||
ROOT_VALIDATORS[key] ||
|
ROOT_VALIDATORS[key] ||
|
||||||
(throwUnknownError: Validator<void>);
|
(throwUnknownError as Validator<void>);
|
||||||
|
|
||||||
validator(optLoc, opts[key]);
|
validator(optLoc, opts[key]);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (opts: any);
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
function throwUnknownError(loc: OptionPath) {
|
function throwUnknownError(loc: OptionPath) {
|
||||||
const key = loc.name;
|
const key = loc.name;
|
||||||
|
|
||||||
if (removed[key]) {
|
if (removed[key]) {
|
||||||
const {
|
const { message, version = 5 } = removed[key];
|
||||||
message,
|
|
||||||
version = 5,
|
|
||||||
}: { message: string, version?: number } = removed[key];
|
|
||||||
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Using removed Babel ${version} option: ${msg(loc)} - ${message}`,
|
`Using removed Babel ${version} option: ${msg(loc)} - ${message}`,
|
||||||
@ -432,7 +361,7 @@ function throwUnknownError(loc: OptionPath) {
|
|||||||
loc,
|
loc,
|
||||||
)}. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.`,
|
)}. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.`,
|
||||||
);
|
);
|
||||||
// $FlowIgnore
|
// @ts-expect-error todo(flow->ts): consider creating something like BabelConfigError with code field in it
|
||||||
unknownOptErr.code = "BABEL_UNKNOWN_OPTION";
|
unknownOptErr.code = "BABEL_UNKNOWN_OPTION";
|
||||||
|
|
||||||
throw unknownOptErr;
|
throw unknownOptErr;
|
||||||
@ -449,7 +378,10 @@ function assertNoDuplicateSourcemap(opts: {}): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertEnvSet(loc: OptionPath, value: mixed): EnvSet<ValidatedOptions> {
|
function assertEnvSet(
|
||||||
|
loc: OptionPath,
|
||||||
|
value: unknown,
|
||||||
|
): void | EnvSet<ValidatedOptions> {
|
||||||
if (loc.parent.type === "env") {
|
if (loc.parent.type === "env") {
|
||||||
throw new Error(`${msg(loc)} is not allowed inside of another .env block`);
|
throw new Error(`${msg(loc)} is not allowed inside of another .env block`);
|
||||||
}
|
}
|
||||||
@ -467,14 +399,17 @@ function assertEnvSet(loc: OptionPath, value: mixed): EnvSet<ValidatedOptions> {
|
|||||||
type: "env",
|
type: "env",
|
||||||
name: envName,
|
name: envName,
|
||||||
parent,
|
parent,
|
||||||
};
|
} as const;
|
||||||
validateNested(envLoc, env);
|
validateNested(envLoc, env);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (obj: any);
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertOverridesList(loc: OptionPath, value: mixed): OverridesList {
|
function assertOverridesList(
|
||||||
|
loc: OptionPath,
|
||||||
|
value: unknown[],
|
||||||
|
): undefined | OverridesList {
|
||||||
if (loc.parent.type === "env") {
|
if (loc.parent.type === "env") {
|
||||||
throw new Error(`${msg(loc)} is not allowed inside an .env block`);
|
throw new Error(`${msg(loc)} is not allowed inside an .env block`);
|
||||||
}
|
}
|
||||||
@ -494,11 +429,12 @@ function assertOverridesList(loc: OptionPath, value: mixed): OverridesList {
|
|||||||
type: "overrides",
|
type: "overrides",
|
||||||
index,
|
index,
|
||||||
parent,
|
parent,
|
||||||
};
|
} as const;
|
||||||
validateNested(overridesLoc, env);
|
validateNested(overridesLoc, env);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (arr: any);
|
// @ts-expect-error
|
||||||
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkNoUnwrappedItemOptionPairs(
|
export function checkNoUnwrappedItemOptionPairs(
|
||||||
|
|||||||
@ -1,45 +1,42 @@
|
|||||||
// @flow
|
|
||||||
import {
|
import {
|
||||||
assertString,
|
assertString,
|
||||||
assertFunction,
|
assertFunction,
|
||||||
assertObject,
|
assertObject,
|
||||||
msg,
|
msg,
|
||||||
type ValidatorSet,
|
} from "./option-assertions";
|
||||||
type Validator,
|
|
||||||
type OptionPath,
|
import type {
|
||||||
type RootPath,
|
ValidatorSet,
|
||||||
|
Validator,
|
||||||
|
OptionPath,
|
||||||
|
RootPath,
|
||||||
} from "./option-assertions";
|
} from "./option-assertions";
|
||||||
|
|
||||||
// Note: The casts here are just meant to be static assertions to make sure
|
// Note: The casts here are just meant to be static assertions to make sure
|
||||||
// that the assertion functions actually assert that the value's type matches
|
// that the assertion functions actually assert that the value's type matches
|
||||||
// the declared types.
|
// the declared types.
|
||||||
const VALIDATORS: ValidatorSet = {
|
const VALIDATORS: ValidatorSet = {
|
||||||
name: (assertString: Validator<$PropertyType<PluginObject, "name">>),
|
name: assertString as Validator<PluginObject["name"]>,
|
||||||
manipulateOptions: (assertFunction: Validator<
|
manipulateOptions: assertFunction as Validator<
|
||||||
$PropertyType<PluginObject, "manipulateOptions">,
|
PluginObject["manipulateOptions"]
|
||||||
>),
|
>,
|
||||||
pre: (assertFunction: Validator<$PropertyType<PluginObject, "pre">>),
|
pre: assertFunction as Validator<PluginObject["pre"]>,
|
||||||
post: (assertFunction: Validator<$PropertyType<PluginObject, "post">>),
|
post: assertFunction as Validator<PluginObject["post"]>,
|
||||||
inherits: (assertFunction: Validator<
|
inherits: assertFunction as Validator<PluginObject["inherits"]>,
|
||||||
$PropertyType<PluginObject, "inherits">,
|
visitor: assertVisitorMap as Validator<PluginObject["visitor"]>,
|
||||||
>),
|
|
||||||
visitor: (assertVisitorMap: Validator<
|
|
||||||
$PropertyType<PluginObject, "visitor">,
|
|
||||||
>),
|
|
||||||
|
|
||||||
parserOverride: (assertFunction: Validator<
|
parserOverride: assertFunction as Validator<PluginObject["parserOverride"]>,
|
||||||
$PropertyType<PluginObject, "parserOverride">,
|
generatorOverride: assertFunction as Validator<
|
||||||
>),
|
PluginObject["generatorOverride"]
|
||||||
generatorOverride: (assertFunction: Validator<
|
>,
|
||||||
$PropertyType<PluginObject, "generatorOverride">,
|
|
||||||
>),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function assertVisitorMap(loc: OptionPath, value: mixed): VisitorMap {
|
function assertVisitorMap(loc: OptionPath, value: unknown): VisitorMap {
|
||||||
const obj = assertObject(loc, value);
|
const obj = assertObject(loc, value);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
Object.keys(obj).forEach(prop => assertVisitorHandler(prop, obj[prop]));
|
Object.keys(obj).forEach(prop => assertVisitorHandler(prop, obj[prop]));
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
if (obj.enter || obj.exit) {
|
if (obj.enter || obj.exit) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${msg(
|
`${msg(
|
||||||
@ -48,12 +45,12 @@ function assertVisitorMap(loc: OptionPath, value: mixed): VisitorMap {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (obj: any);
|
return obj as VisitorMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertVisitorHandler(
|
function assertVisitorHandler(
|
||||||
key: string,
|
key: string,
|
||||||
value: mixed,
|
value: unknown,
|
||||||
): VisitorHandler | void {
|
): VisitorHandler | void {
|
||||||
if (value && typeof value === "object") {
|
if (value && typeof value === "object") {
|
||||||
Object.keys(value).forEach((handler: string) => {
|
Object.keys(value).forEach((handler: string) => {
|
||||||
@ -67,26 +64,29 @@ function assertVisitorHandler(
|
|||||||
throw new Error(`.visitor["${key}"] must be a function`);
|
throw new Error(`.visitor["${key}"] must be a function`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (value: any);
|
return value as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
type VisitorHandler = Function | { enter?: Function, exit?: Function };
|
type VisitorHandler =
|
||||||
|
| Function
|
||||||
|
| {
|
||||||
|
enter?: Function;
|
||||||
|
exit?: Function;
|
||||||
|
};
|
||||||
|
|
||||||
export type VisitorMap = {
|
export type VisitorMap = {
|
||||||
[string]: VisitorHandler,
|
[x: string]: VisitorHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PluginObject = {
|
export type PluginObject = {
|
||||||
name?: string,
|
name?: string;
|
||||||
manipulateOptions?: (options: mixed, parserOpts: mixed) => void,
|
manipulateOptions?: (options: unknown, parserOpts: unknown) => void;
|
||||||
|
pre?: Function;
|
||||||
pre?: Function,
|
post?: Function;
|
||||||
post?: Function,
|
inherits?: Function;
|
||||||
|
visitor?: VisitorMap;
|
||||||
inherits?: Function,
|
parserOverride?: Function;
|
||||||
visitor?: VisitorMap,
|
generatorOverride?: Function;
|
||||||
|
|
||||||
parserOverride?: Function,
|
|
||||||
generatorOverride?: Function,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function validatePluginObject(obj: {}): PluginObject {
|
export function validatePluginObject(obj: {}): PluginObject {
|
||||||
@ -108,11 +108,11 @@ export function validatePluginObject(obj: {}): PluginObject {
|
|||||||
const invalidPluginPropertyError = new Error(
|
const invalidPluginPropertyError = new Error(
|
||||||
`.${key} is not a valid Plugin property`,
|
`.${key} is not a valid Plugin property`,
|
||||||
);
|
);
|
||||||
// $FlowIgnore
|
// @ts-expect-error todo(flow->ts) consider additing BabelConfigError with code field
|
||||||
invalidPluginPropertyError.code = "BABEL_UNKNOWN_PLUGIN_PROPERTY";
|
invalidPluginPropertyError.code = "BABEL_UNKNOWN_PLUGIN_PROPERTY";
|
||||||
throw invalidPluginPropertyError;
|
throw invalidPluginPropertyError;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return (obj: any);
|
return obj as any;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
auxiliaryComment: {
|
auxiliaryComment: {
|
||||||
message: "Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`",
|
message: "Use `auxiliaryCommentBefore` or `auxiliaryCommentAfter`",
|
||||||
@ -64,17 +62,15 @@ export default {
|
|||||||
version: 6,
|
version: 6,
|
||||||
message: "Use `babel-plugin-module-resolver@3`'s 'resolvePath' options",
|
message: "Use `babel-plugin-module-resolver@3`'s 'resolvePath' options",
|
||||||
},
|
},
|
||||||
|
|
||||||
metadata: {
|
metadata: {
|
||||||
version: 6,
|
version: 6,
|
||||||
message:
|
message:
|
||||||
"Generated plugin metadata is always included in the output result",
|
"Generated plugin metadata is always included in the output result",
|
||||||
},
|
},
|
||||||
|
|
||||||
sourceMapTarget: {
|
sourceMapTarget: {
|
||||||
version: 6,
|
version: 6,
|
||||||
message:
|
message:
|
||||||
"The `sourceMapTarget` option has been removed because it makes more sense for the tooling " +
|
"The `sourceMapTarget` option has been removed because it makes more sense for the tooling " +
|
||||||
"that calls Babel to assign `map.file` themselves.",
|
"that calls Babel to assign `map.file` themselves.",
|
||||||
},
|
},
|
||||||
};
|
} as { [name: string]: { version?: number; message: string } };
|
||||||
|
|||||||
@ -1,18 +1,26 @@
|
|||||||
// @flow
|
import gensync from "gensync";
|
||||||
|
|
||||||
import gensync, { type Gensync, type Handler } from "gensync";
|
|
||||||
|
|
||||||
|
import type { Gensync, Handler } from "gensync";
|
||||||
type MaybePromise<T> = T | Promise<T>;
|
type MaybePromise<T> = T | Promise<T>;
|
||||||
|
|
||||||
const id = x => x;
|
const id = x => x;
|
||||||
|
|
||||||
const runGenerator = gensync(function* (item) {
|
const runGenerator: {
|
||||||
|
sync<Return>(gen: Generator<unknown, Return>): Return;
|
||||||
|
async<Return>(gen: Generator<unknown, Return>): Promise<Return>;
|
||||||
|
errback<Return>(
|
||||||
|
gen: Generator<unknown, Return>,
|
||||||
|
cb: (err: Error, val: Return) => void,
|
||||||
|
): void;
|
||||||
|
} = gensync<(item: Generator) => any>(function* <Return>(
|
||||||
|
item: Generator<unknown, Return>,
|
||||||
|
) {
|
||||||
return yield* item;
|
return yield* item;
|
||||||
});
|
});
|
||||||
|
|
||||||
// This Gensync returns true if the current execution context is
|
// This Gensync returns true if the current execution context is
|
||||||
// asynchronous, otherwise it returns false.
|
// asynchronous, otherwise it returns false.
|
||||||
export const isAsync = gensync<[], boolean>({
|
export const isAsync = gensync<() => boolean>({
|
||||||
sync: () => false,
|
sync: () => false,
|
||||||
errback: cb => cb(null, true),
|
errback: cb => cb(null, true),
|
||||||
});
|
});
|
||||||
@ -22,13 +30,13 @@ export const isAsync = gensync<[], boolean>({
|
|||||||
// but the current execution context is synchronous, it will throw the
|
// but the current execution context is synchronous, it will throw the
|
||||||
// provided error.
|
// provided error.
|
||||||
// This is used to handle user-provided functions which could be asynchronous.
|
// This is used to handle user-provided functions which could be asynchronous.
|
||||||
export function maybeAsync<T, Args: any[]>(
|
export function maybeAsync<Fn extends (...args: any) => any>(
|
||||||
fn: (...args: Args) => T,
|
fn: Fn,
|
||||||
message: string,
|
message: string,
|
||||||
): Gensync<Args, T> {
|
): Gensync<Fn> {
|
||||||
return gensync({
|
return gensync({
|
||||||
sync(...args) {
|
sync(...args) {
|
||||||
const result = fn.apply(this, args);
|
const result = fn.apply(this, args) as ReturnType<Fn>;
|
||||||
if (isThenable(result)) throw new Error(message);
|
if (isThenable(result)) throw new Error(message);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
@ -38,10 +46,10 @@ export function maybeAsync<T, Args: any[]>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const withKind = (gensync<[any], any>({
|
const withKind = gensync<(cb: (kind: "sync" | "async") => any) => any>({
|
||||||
sync: cb => cb("sync"),
|
sync: cb => cb("sync"),
|
||||||
async: cb => cb("async"),
|
async: cb => cb("async"),
|
||||||
}): <T>(cb: (kind: "sync" | "async") => MaybePromise<T>) => Handler<T>);
|
}) as <T>(cb: (kind: "sync" | "async") => MaybePromise<T>) => Handler<T>;
|
||||||
|
|
||||||
// This function wraps a generator (or a Gensync) into another function which,
|
// This function wraps a generator (or a Gensync) into another function which,
|
||||||
// when called, will run the provided generator in a sync or async way, depending
|
// when called, will run the provided generator in a sync or async way, depending
|
||||||
@ -57,14 +65,17 @@ const withKind = (gensync<[any], any>({
|
|||||||
// return wrappedFn(x);
|
// return wrappedFn(x);
|
||||||
// })
|
// })
|
||||||
// )
|
// )
|
||||||
export function forwardAsync<ActionArgs: mixed[], ActionReturn, Return>(
|
export function forwardAsync<
|
||||||
action: (...args: ActionArgs) => Handler<ActionReturn>,
|
Action extends (...args: unknown[]) => any,
|
||||||
|
Return
|
||||||
|
>(
|
||||||
|
action: (...args: Parameters<Action>) => Handler<ReturnType<Action>>,
|
||||||
cb: (
|
cb: (
|
||||||
adapted: (...args: ActionArgs) => MaybePromise<ActionReturn>,
|
adapted: (...args: Parameters<Action>) => MaybePromise<ReturnType<Action>>,
|
||||||
) => MaybePromise<Return>,
|
) => MaybePromise<Return>,
|
||||||
): Handler<Return> {
|
): Handler<Return> {
|
||||||
const g = gensync<ActionArgs, ActionReturn>(action);
|
const g = gensync<Action>(action);
|
||||||
return withKind<Return>(kind => {
|
return withKind(kind => {
|
||||||
const adapted = g[kind];
|
const adapted = g[kind];
|
||||||
return cb(adapted);
|
return cb(adapted);
|
||||||
});
|
});
|
||||||
@ -73,7 +84,7 @@ export function forwardAsync<ActionArgs: mixed[], ActionReturn, Return>(
|
|||||||
// If the given generator is executed asynchronously, the first time that it
|
// If the given generator is executed asynchronously, the first time that it
|
||||||
// is paused (i.e. When it yields a gensync generator which can't be run
|
// is paused (i.e. When it yields a gensync generator which can't be run
|
||||||
// synchronously), call the "firstPause" callback.
|
// synchronously), call the "firstPause" callback.
|
||||||
export const onFirstPause = (gensync<[any, any], any>({
|
export const onFirstPause = gensync<(gen: Generator, cb: Function) => any>({
|
||||||
name: "onFirstPause",
|
name: "onFirstPause",
|
||||||
arity: 2,
|
arity: 2,
|
||||||
sync: function (item) {
|
sync: function (item) {
|
||||||
@ -91,17 +102,16 @@ export const onFirstPause = (gensync<[any, any], any>({
|
|||||||
firstPause();
|
firstPause();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}): <T>(gen: Generator<*, T, *>, cb: Function) => Handler<T>);
|
}) as <T>(gen: Generator<any, T, any>, cb: Function) => Handler<T>;
|
||||||
|
|
||||||
// Wait for the given promise to be resolved
|
// Wait for the given promise to be resolved
|
||||||
export const waitFor = (gensync<[any], any>({
|
export const waitFor = gensync({
|
||||||
sync: id,
|
sync: id,
|
||||||
async: id,
|
async: id,
|
||||||
}): <T>(p: T | Promise<T>) => Handler<T>);
|
}) as <T>(p: T | Promise<T>) => Handler<T>;
|
||||||
|
|
||||||
export function isThenable(val: mixed): boolean %checks {
|
export function isThenable<T = any>(val: any): val is PromiseLike<T> {
|
||||||
return (
|
return (
|
||||||
/*:: val instanceof Promise && */
|
|
||||||
!!val &&
|
!!val &&
|
||||||
(typeof val === "object" || typeof val === "function") &&
|
(typeof val === "object" || typeof val === "function") &&
|
||||||
!!val.then &&
|
!!val.then &&
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import gensync from "gensync";
|
import gensync from "gensync";
|
||||||
|
|
||||||
export const readFile = gensync<[string, "utf8"], string>({
|
export const readFile = gensync<(filepath: string, encoding: "utf8") => string>(
|
||||||
sync: fs.readFileSync,
|
{
|
||||||
errback: fs.readFile,
|
sync: fs.readFileSync,
|
||||||
});
|
errback: fs.readFile,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
export const exists = gensync<[string], boolean>({
|
export const exists = gensync<(filepath: string) => boolean>({
|
||||||
sync(path) {
|
sync(path) {
|
||||||
try {
|
try {
|
||||||
fs.accessSync(path);
|
fs.accessSync(path);
|
||||||
@ -20,7 +20,7 @@ export const exists = gensync<[string], boolean>({
|
|||||||
errback: (path, cb) => fs.access(path, undefined, err => cb(null, !err)),
|
errback: (path, cb) => fs.access(path, undefined, err => cb(null, !err)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const stat = gensync<[string], *>({
|
export const stat = gensync<typeof fs.statSync>({
|
||||||
sync: fs.statSync,
|
sync: fs.statSync,
|
||||||
errback: fs.stat,
|
errback: fs.stat,
|
||||||
});
|
});
|
||||||
|
|||||||
37
packages/babel-core/src/gensync-utils/gensync.d.ts
vendored
Normal file
37
packages/babel-core/src/gensync-utils/gensync.d.ts
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
declare module "gensync" {
|
||||||
|
declare type Next = undefined | Function;
|
||||||
|
declare type Yield = mixed;
|
||||||
|
|
||||||
|
declare type Callback<Return> =
|
||||||
|
| ((err: Error, val: Return) => void)
|
||||||
|
| ((err: unknown) => void);
|
||||||
|
|
||||||
|
export type Gensync<Fn extends (...args: any) => any> = {
|
||||||
|
(...args: Parameters<Fn>): Handler<ReturnType<Fn>>;
|
||||||
|
sync(...args: Parameters<Fn>): ReturnType<Fn>;
|
||||||
|
async(...args: Parameters<Fn>): Promise<ReturnType<Fn>>;
|
||||||
|
errback(...args: [...Parameters<Fn>, Callback<ReturnType<Fn>>]): void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Handler<Return> = Generator<Yield, Return, Next>;
|
||||||
|
export type Options<Fn extends (...args: any) => any> = {
|
||||||
|
sync(...args: Parameters<Fn>): ReturnType<Fn>;
|
||||||
|
arity?: number;
|
||||||
|
name?: string;
|
||||||
|
} & (
|
||||||
|
| { async?: (...args: Parameters<Fn>) => Promise<ReturnType<Fn>> }
|
||||||
|
| {
|
||||||
|
errback(...args: [...Parameters<Fn>, Callback<ReturnType<Fn>>]): void;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
declare const gensync: {
|
||||||
|
<Fn extends (...args: any) => any>(
|
||||||
|
_: Options<Fn> | ((...args: Parameters<Fn>) => Handler<ReturnType<Fn>>),
|
||||||
|
): Gensync<Fn>;
|
||||||
|
|
||||||
|
all<Return>(gensyncs: Array<Handler<Return>>): Handler<Return[]>;
|
||||||
|
race<Return>(gensyncs: Array<Handler<Return>>): Handler<Return>;
|
||||||
|
};
|
||||||
|
export default gensync;
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
// @flow
|
declare const PACKAGE_JSON: { name: string; version: string };
|
||||||
|
|
||||||
export const version = PACKAGE_JSON.version;
|
export const version = PACKAGE_JSON.version;
|
||||||
|
|
||||||
export { default as File } from "./transformation/file/file";
|
export { default as File } from "./transformation/file/file";
|
||||||
@ -53,7 +52,7 @@ export const DEFAULT_EXTENSIONS = Object.freeze([
|
|||||||
".es",
|
".es",
|
||||||
".mjs",
|
".mjs",
|
||||||
".cjs",
|
".cjs",
|
||||||
]);
|
] as const);
|
||||||
|
|
||||||
// For easier backward-compatibility, provide an API like the one we exposed in Babel 6.
|
// For easier backward-compatibility, provide an API like the one we exposed in Babel 6.
|
||||||
import { loadOptions } from "./config";
|
import { loadOptions } from "./config";
|
||||||
|
|||||||
@ -1,39 +1,39 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import gensync from "gensync";
|
import gensync from "gensync";
|
||||||
|
|
||||||
import loadConfig, { type InputOptions } from "./config";
|
import loadConfig from "./config";
|
||||||
|
import type { InputOptions } from "./config";
|
||||||
import parser from "./parser";
|
import parser from "./parser";
|
||||||
import type { ParseResult } from "./parser";
|
import type { ParseResult } from "./parser";
|
||||||
import normalizeOptions from "./transformation/normalize-opts";
|
import normalizeOptions from "./transformation/normalize-opts";
|
||||||
|
|
||||||
type FileParseCallback = {
|
type FileParseCallback = {
|
||||||
(Error, null): any,
|
(err: Error, ast: null): any;
|
||||||
(null, ParseResult | null): any,
|
(err: null, ast: ParseResult | null): any;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Parse = {
|
type Parse = {
|
||||||
(code: string, callback: FileParseCallback): void,
|
(code: string, callback: FileParseCallback): void;
|
||||||
(code: string, opts: ?InputOptions, callback: FileParseCallback): void,
|
(
|
||||||
|
code: string,
|
||||||
// Here for backward-compatibility. Ideally use ".parseSync" if you want
|
opts: InputOptions | undefined | null,
|
||||||
// a synchronous API.
|
callback: FileParseCallback,
|
||||||
(code: string, opts: ?InputOptions): ParseResult | null,
|
): void;
|
||||||
|
(code: string, opts?: InputOptions | null): ParseResult | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseRunner = gensync<[string, ?InputOptions], ParseResult | null>(
|
const parseRunner = gensync<
|
||||||
function* parse(code, opts) {
|
(code: string, opts: InputOptions | undefined | null) => ParseResult | null
|
||||||
const config = yield* loadConfig(opts);
|
>(function* parse(code, opts) {
|
||||||
|
const config = yield* loadConfig(opts);
|
||||||
|
|
||||||
if (config === null) {
|
if (config === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return yield* parser(config.passes, normalizeOptions(config), code);
|
return yield* parser(config.passes, normalizeOptions(config), code);
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
export const parse: Parse = (function parse(code, opts, callback) {
|
export const parse: Parse = function parse(code, opts?, callback?) {
|
||||||
if (typeof opts === "function") {
|
if (typeof opts === "function") {
|
||||||
callback = opts;
|
callback = opts;
|
||||||
opts = undefined;
|
opts = undefined;
|
||||||
@ -44,7 +44,7 @@ export const parse: Parse = (function parse(code, opts, callback) {
|
|||||||
if (callback === undefined) return parseRunner.sync(code, opts);
|
if (callback === undefined) return parseRunner.sync(code, opts);
|
||||||
|
|
||||||
parseRunner.errback(code, opts, callback);
|
parseRunner.errback(code, opts, callback);
|
||||||
}: Function);
|
};
|
||||||
|
|
||||||
export const parseSync = parseRunner.sync;
|
export const parseSync = parseRunner.sync;
|
||||||
export const parseAsync = parseRunner.async;
|
export const parseAsync = parseRunner.async;
|
||||||
|
|||||||
@ -1,15 +1,17 @@
|
|||||||
import type { Handler } from "gensync";
|
import type { Handler } from "gensync";
|
||||||
import { parse } from "@babel/parser";
|
import { parse } from "@babel/parser";
|
||||||
|
import type * as t from "@babel/types";
|
||||||
import { codeFrameColumns } from "@babel/code-frame";
|
import { codeFrameColumns } from "@babel/code-frame";
|
||||||
import generateMissingPluginMessage from "./util/missing-plugin-helper";
|
import generateMissingPluginMessage from "./util/missing-plugin-helper";
|
||||||
|
import type { PluginPasses } from "../config";
|
||||||
|
|
||||||
type AstRoot = BabelNodeFile | BabelNodeProgram;
|
type AstRoot = t.File | t.Program;
|
||||||
|
|
||||||
export type ParseResult = AstRoot;
|
export type ParseResult = AstRoot;
|
||||||
|
|
||||||
export default function* parser(
|
export default function* parser(
|
||||||
pluginPasses: PluginPasses,
|
pluginPasses: PluginPasses,
|
||||||
{ parserOpts, highlightCode = true, filename = "unknown" }: Object,
|
{ parserOpts, highlightCode = true, filename = "unknown" }: any,
|
||||||
code: string,
|
code: string,
|
||||||
): Handler<ParseResult> {
|
): Handler<ParseResult> {
|
||||||
try {
|
try {
|
||||||
@ -28,7 +30,8 @@ export default function* parser(
|
|||||||
if (results.length === 0) {
|
if (results.length === 0) {
|
||||||
return parse(code, parserOpts);
|
return parse(code, parserOpts);
|
||||||
} else if (results.length === 1) {
|
} else if (results.length === 1) {
|
||||||
yield* []; // If we want to allow async parsers
|
// @ts-expect-error - If we want to allow async parsers
|
||||||
|
yield* [];
|
||||||
if (typeof results[0].then === "function") {
|
if (typeof results[0].then === "function") {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`You appear to be using an async parser plugin, ` +
|
`You appear to be using an async parser plugin, ` +
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
const pluginNameMap = {
|
const pluginNameMap = {
|
||||||
classProperties: {
|
classProperties: {
|
||||||
syntax: {
|
syntax: {
|
||||||
@ -290,7 +288,10 @@ to enable [parsing|transformation].
|
|||||||
*/
|
*/
|
||||||
export default function generateMissingPluginMessage(
|
export default function generateMissingPluginMessage(
|
||||||
missingPluginName: string,
|
missingPluginName: string,
|
||||||
loc: { line: number, column: number },
|
loc: {
|
||||||
|
line: number;
|
||||||
|
column: number;
|
||||||
|
},
|
||||||
codeFrame: string,
|
codeFrame: string,
|
||||||
): string {
|
): string {
|
||||||
let helpMessage =
|
let helpMessage =
|
||||||
|
|||||||
@ -105,7 +105,7 @@ function buildUmd(allowlist) {
|
|||||||
AMD_ARGUMENTS: t.arrayExpression([t.stringLiteral("exports")]),
|
AMD_ARGUMENTS: t.arrayExpression([t.stringLiteral("exports")]),
|
||||||
FACTORY_BODY: body,
|
FACTORY_BODY: body,
|
||||||
UMD_ROOT: t.identifier("this"),
|
UMD_ROOT: t.identifier("this"),
|
||||||
}),
|
}) as t.Statement,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,33 +1,30 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import gensync from "gensync";
|
import gensync from "gensync";
|
||||||
|
|
||||||
import loadConfig, { type InputOptions, type ResolvedConfig } from "./config";
|
import loadConfig from "./config";
|
||||||
import {
|
import type { InputOptions, ResolvedConfig } from "./config";
|
||||||
run,
|
import { run } from "./transformation";
|
||||||
type FileResult,
|
import type * as t from "@babel/types";
|
||||||
type FileResultCallback,
|
|
||||||
} from "./transformation";
|
|
||||||
|
|
||||||
type AstRoot = BabelNodeFile | BabelNodeProgram;
|
import type { FileResult, FileResultCallback } from "./transformation";
|
||||||
|
type AstRoot = t.File | t.Program;
|
||||||
|
|
||||||
type TransformFromAst = {
|
type TransformFromAst = {
|
||||||
(ast: AstRoot, code: string, callback: FileResultCallback): void,
|
(ast: AstRoot, code: string, callback: FileResultCallback): void;
|
||||||
(
|
(
|
||||||
ast: AstRoot,
|
ast: AstRoot,
|
||||||
code: string,
|
code: string,
|
||||||
opts: ?InputOptions,
|
opts: InputOptions | undefined | null,
|
||||||
callback: FileResultCallback,
|
callback: FileResultCallback,
|
||||||
): void,
|
): void;
|
||||||
|
(ast: AstRoot, code: string, opts?: InputOptions | null): FileResult | null;
|
||||||
// Here for backward-compatibility. Ideally use ".transformSync" if you want
|
|
||||||
// a synchronous API.
|
|
||||||
(ast: AstRoot, code: string, opts: ?InputOptions): FileResult | null,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const transformFromAstRunner = gensync<
|
const transformFromAstRunner = gensync<
|
||||||
[AstRoot, string, ?InputOptions],
|
(
|
||||||
FileResult | null,
|
ast: AstRoot,
|
||||||
|
code: string,
|
||||||
|
opts: InputOptions | undefined | null,
|
||||||
|
) => FileResult | null
|
||||||
>(function* (ast, code, opts) {
|
>(function* (ast, code, opts) {
|
||||||
const config: ResolvedConfig | null = yield* loadConfig(opts);
|
const config: ResolvedConfig | null = yield* loadConfig(opts);
|
||||||
if (config === null) return null;
|
if (config === null) return null;
|
||||||
@ -37,11 +34,11 @@ const transformFromAstRunner = gensync<
|
|||||||
return yield* run(config, code, ast);
|
return yield* run(config, code, ast);
|
||||||
});
|
});
|
||||||
|
|
||||||
export const transformFromAst: TransformFromAst = (function transformFromAst(
|
export const transformFromAst: TransformFromAst = function transformFromAst(
|
||||||
ast,
|
ast,
|
||||||
code,
|
code,
|
||||||
opts,
|
opts,
|
||||||
callback,
|
callback?,
|
||||||
) {
|
) {
|
||||||
if (typeof opts === "function") {
|
if (typeof opts === "function") {
|
||||||
callback = opts;
|
callback = opts;
|
||||||
@ -55,7 +52,7 @@ export const transformFromAst: TransformFromAst = (function transformFromAst(
|
|||||||
}
|
}
|
||||||
|
|
||||||
transformFromAstRunner.errback(ast, code, opts, callback);
|
transformFromAstRunner.errback(ast, code, opts, callback);
|
||||||
}: Function);
|
};
|
||||||
|
|
||||||
export const transformFromAstSync = transformFromAstRunner.sync;
|
export const transformFromAstSync = transformFromAstRunner.sync;
|
||||||
export const transformFromAstAsync = transformFromAstRunner.async;
|
export const transformFromAstAsync = transformFromAstRunner.async;
|
||||||
|
|||||||
@ -1,24 +1,22 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
// duplicated from transform-file so we do not have to import anything here
|
// duplicated from transform-file so we do not have to import anything here
|
||||||
type TransformFile = {
|
type TransformFile = {
|
||||||
(filename: string, callback: Function): void,
|
(filename: string, callback: Function): void;
|
||||||
(filename: string, opts: ?Object, callback: Function): void,
|
(filename: string, opts: any, callback: Function): void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const transformFile: TransformFile = (function transformFile(
|
export const transformFile: TransformFile = function transformFile(
|
||||||
filename,
|
filename,
|
||||||
opts,
|
opts,
|
||||||
callback,
|
callback?,
|
||||||
) {
|
) {
|
||||||
if (typeof opts === "function") {
|
if (typeof opts === "function") {
|
||||||
callback = opts;
|
callback = opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(new Error("Transforming files is not supported in browsers"), null);
|
callback(new Error("Transforming files is not supported in browsers"), null);
|
||||||
}: Function);
|
};
|
||||||
|
|
||||||
export function transformFileSync() {
|
export function transformFileSync(): never {
|
||||||
throw new Error("Transforming files is not supported in browsers");
|
throw new Error("Transforming files is not supported in browsers");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,40 +1,40 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import gensync from "gensync";
|
import gensync from "gensync";
|
||||||
|
|
||||||
import loadConfig, { type InputOptions, type ResolvedConfig } from "./config";
|
import loadConfig from "./config";
|
||||||
import {
|
import type { InputOptions, ResolvedConfig } from "./config";
|
||||||
run,
|
import { run } from "./transformation";
|
||||||
type FileResult,
|
import type { FileResult, FileResultCallback } from "./transformation";
|
||||||
type FileResultCallback,
|
|
||||||
} from "./transformation";
|
|
||||||
import * as fs from "./gensync-utils/fs";
|
import * as fs from "./gensync-utils/fs";
|
||||||
|
|
||||||
import typeof * as transformFileBrowserType from "./transform-file-browser";
|
type transformFileBrowserType = typeof import("./transform-file-browser");
|
||||||
import typeof * as transformFileType from "./transform-file";
|
type transformFileType = typeof import("./transform-file");
|
||||||
|
|
||||||
// Kind of gross, but essentially asserting that the exports of this module are the same as the
|
// Kind of gross, but essentially asserting that the exports of this module are the same as the
|
||||||
// exports of transform-file-browser, since this file may be replaced at bundle time with
|
// exports of transform-file-browser, since this file may be replaced at bundle time with
|
||||||
// transform-file-browser.
|
// transform-file-browser.
|
||||||
((({}: any): $Exact<transformFileBrowserType>): $Exact<transformFileType>);
|
((({} as any) as transformFileBrowserType) as transformFileType);
|
||||||
|
|
||||||
type TransformFile = {
|
type TransformFile = {
|
||||||
(filename: string, callback: FileResultCallback): void,
|
(filename: string, callback: FileResultCallback): void;
|
||||||
(filename: string, opts: ?InputOptions, callback: FileResultCallback): void,
|
(
|
||||||
|
filename: string,
|
||||||
|
opts: InputOptions | undefined | null,
|
||||||
|
callback: FileResultCallback,
|
||||||
|
): void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const transformFileRunner = gensync<[string, ?InputOptions], FileResult | null>(
|
const transformFileRunner = gensync<
|
||||||
function* (filename, opts) {
|
(filename: string, opts?: InputOptions) => FileResult | null
|
||||||
const options = { ...opts, filename };
|
>(function* (filename, opts: InputOptions) {
|
||||||
|
const options = { ...opts, filename };
|
||||||
|
|
||||||
const config: ResolvedConfig | null = yield* loadConfig(options);
|
const config: ResolvedConfig | null = yield* loadConfig(options);
|
||||||
if (config === null) return null;
|
if (config === null) return null;
|
||||||
|
|
||||||
const code = yield* fs.readFile(filename, "utf8");
|
const code = yield* fs.readFile(filename, "utf8");
|
||||||
return yield* run(config, code);
|
return yield* run(config, code);
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
export const transformFile: TransformFile = transformFileRunner.errback;
|
export const transformFile = transformFileRunner.errback as TransformFile;
|
||||||
export const transformFileSync = transformFileRunner.sync;
|
export const transformFileSync = transformFileRunner.sync;
|
||||||
export const transformFileAsync = transformFileRunner.async;
|
export const transformFileAsync = transformFileRunner.async;
|
||||||
|
|||||||
@ -1,33 +1,31 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import gensync from "gensync";
|
import gensync from "gensync";
|
||||||
|
|
||||||
import loadConfig, { type InputOptions, type ResolvedConfig } from "./config";
|
import loadConfig from "./config";
|
||||||
import {
|
import type { InputOptions, ResolvedConfig } from "./config";
|
||||||
run,
|
import { run } from "./transformation";
|
||||||
type FileResult,
|
|
||||||
type FileResultCallback,
|
import type { FileResult, FileResultCallback } from "./transformation";
|
||||||
} from "./transformation";
|
|
||||||
|
|
||||||
type Transform = {
|
type Transform = {
|
||||||
(code: string, callback: FileResultCallback): void,
|
(code: string, callback: FileResultCallback): void;
|
||||||
(code: string, opts: ?InputOptions, callback: FileResultCallback): void,
|
(
|
||||||
|
code: string,
|
||||||
// Here for backward-compatibility. Ideally use ".transformSync" if you want
|
opts: InputOptions | undefined | null,
|
||||||
// a synchronous API.
|
callback: FileResultCallback,
|
||||||
(code: string, opts: ?InputOptions): FileResult | null,
|
): void;
|
||||||
|
(code: string, opts?: InputOptions | null): FileResult | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const transformRunner = gensync<[string, ?InputOptions], FileResult | null>(
|
const transformRunner = gensync<
|
||||||
function* transform(code, opts) {
|
(code: string, opts?: InputOptions) => FileResult | null
|
||||||
const config: ResolvedConfig | null = yield* loadConfig(opts);
|
>(function* transform(code, opts) {
|
||||||
if (config === null) return null;
|
const config: ResolvedConfig | null = yield* loadConfig(opts);
|
||||||
|
if (config === null) return null;
|
||||||
|
|
||||||
return yield* run(config, code);
|
return yield* run(config, code);
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
export const transform: Transform = (function transform(code, opts, callback) {
|
export const transform: Transform = function transform(code, opts?, callback?) {
|
||||||
if (typeof opts === "function") {
|
if (typeof opts === "function") {
|
||||||
callback = opts;
|
callback = opts;
|
||||||
opts = undefined;
|
opts = undefined;
|
||||||
@ -38,7 +36,7 @@ export const transform: Transform = (function transform(code, opts, callback) {
|
|||||||
if (callback === undefined) return transformRunner.sync(code, opts);
|
if (callback === undefined) return transformRunner.sync(code, opts);
|
||||||
|
|
||||||
transformRunner.errback(code, opts, callback);
|
transformRunner.errback(code, opts, callback);
|
||||||
}: Function);
|
};
|
||||||
|
|
||||||
export const transformSync = transformRunner.sync;
|
export const transformSync = transformRunner.sync;
|
||||||
export const transformAsync = transformRunner.async;
|
export const transformAsync = transformRunner.async;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// @flow
|
import loadConfig from "../config";
|
||||||
|
|
||||||
import loadConfig, { type Plugin } from "../config";
|
import type { Plugin } from "../config";
|
||||||
|
|
||||||
let LOADED_PLUGIN: Plugin | void;
|
let LOADED_PLUGIN: Plugin | void;
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import * as helpers from "@babel/helpers";
|
import * as helpers from "@babel/helpers";
|
||||||
import { NodePath, Scope, type HubInterface } from "@babel/traverse";
|
import { NodePath, Scope } from "@babel/traverse";
|
||||||
|
import type { HubInterface } from "@babel/traverse";
|
||||||
import { codeFrameColumns } from "@babel/code-frame";
|
import { codeFrameColumns } from "@babel/code-frame";
|
||||||
import traverse from "@babel/traverse";
|
import traverse from "@babel/traverse";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
@ -22,27 +21,39 @@ const errorVisitor = {
|
|||||||
|
|
||||||
export type NodeLocation = {
|
export type NodeLocation = {
|
||||||
loc?: {
|
loc?: {
|
||||||
end?: { line: number, column: number },
|
end?: {
|
||||||
start: { line: number, column: number },
|
line: number;
|
||||||
},
|
column: number;
|
||||||
|
};
|
||||||
|
start: {
|
||||||
|
line: number;
|
||||||
|
column: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
_loc?: {
|
_loc?: {
|
||||||
end?: { line: number, column: number },
|
end?: {
|
||||||
start: { line: number, column: number },
|
line: number;
|
||||||
},
|
column: number;
|
||||||
|
};
|
||||||
|
start: {
|
||||||
|
line: number;
|
||||||
|
column: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class File {
|
export default class File {
|
||||||
_map: Map<any, any> = new Map();
|
_map: Map<any, any> = new Map();
|
||||||
opts: Object;
|
opts: any;
|
||||||
declarations: Object = {};
|
declarations: any = {};
|
||||||
path: NodePath = null;
|
path: NodePath<t.Program> = null;
|
||||||
ast: Object = {};
|
ast: any = {};
|
||||||
scope: Scope;
|
scope: Scope;
|
||||||
metadata: {} = {};
|
metadata: {} = {};
|
||||||
code: string = "";
|
code: string = "";
|
||||||
inputMap: Object | null = null;
|
inputMap: any | null = null;
|
||||||
|
|
||||||
hub: HubInterface = {
|
hub: HubInterface & { file: File } = {
|
||||||
// keep it for the usage in babel-core, ex: path.hub.file.opts.filename
|
// keep it for the usage in babel-core, ex: path.hub.file.opts.filename
|
||||||
file: this,
|
file: this,
|
||||||
getCode: () => this.code,
|
getCode: () => this.code,
|
||||||
@ -63,7 +74,7 @@ export default class File {
|
|||||||
parent: this.ast,
|
parent: this.ast,
|
||||||
container: this.ast,
|
container: this.ast,
|
||||||
key: "program",
|
key: "program",
|
||||||
}).setContext();
|
}).setContext() as NodePath<t.Program>;
|
||||||
this.scope = this.path.scope;
|
this.scope = this.path.scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +87,7 @@ export default class File {
|
|||||||
const { interpreter } = this.path.node;
|
const { interpreter } = this.path.node;
|
||||||
return interpreter ? interpreter.value : "";
|
return interpreter ? interpreter.value : "";
|
||||||
}
|
}
|
||||||
set shebang(value: string): void {
|
set shebang(value: string) {
|
||||||
if (value) {
|
if (value) {
|
||||||
this.path.get("interpreter").replaceWith(t.interpreterDirective(value));
|
this.path.get("interpreter").replaceWith(t.interpreterDirective(value));
|
||||||
} else {
|
} else {
|
||||||
@ -84,7 +95,7 @@ export default class File {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set(key: mixed, val: mixed) {
|
set(key: unknown, val: unknown) {
|
||||||
if (key === "helpersNamespace") {
|
if (key === "helpersNamespace") {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Babel 7.0.0-beta.56 has dropped support for the 'helpersNamespace' utility." +
|
"Babel 7.0.0-beta.56 has dropped support for the 'helpersNamespace' utility." +
|
||||||
@ -98,15 +109,15 @@ export default class File {
|
|||||||
this._map.set(key, val);
|
this._map.set(key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
get(key: mixed): any {
|
get(key: unknown): any {
|
||||||
return this._map.get(key);
|
return this._map.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
has(key: mixed): boolean {
|
has(key: unknown): boolean {
|
||||||
return this._map.has(key);
|
return this._map.has(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
getModuleName(): ?string {
|
getModuleName(): string | undefined | null {
|
||||||
return getModuleName(this.opts, this.opts);
|
return getModuleName(this.opts, this.opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +137,7 @@ export default class File {
|
|||||||
* helper exists, but was not available for the full given range, it will be
|
* helper exists, but was not available for the full given range, it will be
|
||||||
* considered unavailable.
|
* considered unavailable.
|
||||||
*/
|
*/
|
||||||
availableHelper(name: string, versionRange: ?string): boolean {
|
availableHelper(name: string, versionRange?: string | null): boolean {
|
||||||
let minVersion;
|
let minVersion;
|
||||||
try {
|
try {
|
||||||
minVersion = helpers.minVersion(name);
|
minVersion = helpers.minVersion(name);
|
||||||
@ -163,7 +174,7 @@ export default class File {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
addHelper(name: string): Object {
|
addHelper(name: string): any {
|
||||||
const declar = this.declarations[name];
|
const declar = this.declarations[name];
|
||||||
if (declar) return t.cloneNode(declar);
|
if (declar) return t.cloneNode(declar);
|
||||||
|
|
||||||
@ -220,9 +231,9 @@ export default class File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildCodeFrameError(
|
buildCodeFrameError(
|
||||||
node: ?NodeLocation,
|
node: NodeLocation | undefined | null,
|
||||||
msg: string,
|
msg: string,
|
||||||
Error: typeof Error = SyntaxError,
|
_Error: typeof Error = SyntaxError,
|
||||||
): Error {
|
): Error {
|
||||||
let loc = node && (node.loc || node._loc);
|
let loc = node && (node.loc || node._loc);
|
||||||
|
|
||||||
@ -230,7 +241,7 @@ export default class File {
|
|||||||
const state = {
|
const state = {
|
||||||
loc: null,
|
loc: null,
|
||||||
};
|
};
|
||||||
traverse(node, errorVisitor, this.scope, state);
|
traverse(node as t.Node, errorVisitor, this.scope, state);
|
||||||
loc = state.loc;
|
loc = state.loc;
|
||||||
|
|
||||||
let txt =
|
let txt =
|
||||||
@ -264,6 +275,6 @@ export default class File {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Error(msg);
|
return new _Error(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import type { PluginPasses } from "../../config";
|
import type { PluginPasses } from "../../config";
|
||||||
import convertSourceMap, { typeof SourceMap } from "convert-source-map";
|
import convertSourceMap from "convert-source-map";
|
||||||
|
type SourceMap = any;
|
||||||
import generate from "@babel/generator";
|
import generate from "@babel/generator";
|
||||||
|
|
||||||
import type File from "./file";
|
import type File from "./file";
|
||||||
@ -11,8 +10,8 @@ export default function generateCode(
|
|||||||
pluginPasses: PluginPasses,
|
pluginPasses: PluginPasses,
|
||||||
file: File,
|
file: File,
|
||||||
): {
|
): {
|
||||||
outputCode: string,
|
outputCode: string;
|
||||||
outputMap: SourceMap | null,
|
outputMap: SourceMap | null;
|
||||||
} {
|
} {
|
||||||
const { opts, ast, code, inputMap } = file;
|
const { opts, ast, code, inputMap } = file;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
// @flow
|
type SourceMap = any;
|
||||||
|
|
||||||
import typeof { SourceMap } from "convert-source-map";
|
|
||||||
import sourceMap from "source-map";
|
import sourceMap from "source-map";
|
||||||
|
|
||||||
export default function mergeSourceMap(
|
export default function mergeSourceMap(
|
||||||
@ -74,6 +72,7 @@ export default function mergeSourceMap(
|
|||||||
// Insert mappings with no original position to terminate any mappings
|
// Insert mappings with no original position to terminate any mappings
|
||||||
// that were found above, so that they don't expand beyond their correct
|
// that were found above, so that they don't expand beyond their correct
|
||||||
// range.
|
// range.
|
||||||
|
// @ts-expect-error todo(flow->ts) original and source field are missing
|
||||||
mergedGenerator.addMapping({
|
mergedGenerator.addMapping({
|
||||||
generated: {
|
generated: {
|
||||||
line: clearItem.line,
|
line: clearItem.line,
|
||||||
@ -93,14 +92,14 @@ export default function mergeSourceMap(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeMappingKey(item: { line: number, columnStart: number }) {
|
function makeMappingKey(item: { line: number; columnStart: number }) {
|
||||||
return `${item.line}/${item.columnStart}`;
|
return `${item.line}/${item.columnStart}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function eachOverlappingGeneratedOutputRange(
|
function eachOverlappingGeneratedOutputRange(
|
||||||
outputFile: ResolvedFileMappings,
|
outputFile: ResolvedFileMappings,
|
||||||
inputGeneratedRange: ResolvedGeneratedRange,
|
inputGeneratedRange: ResolvedGeneratedRange,
|
||||||
callback: ResolvedGeneratedRange => mixed,
|
callback: (range: ResolvedGeneratedRange) => unknown,
|
||||||
) {
|
) {
|
||||||
// Find the Babel-generated mappings that overlap with this range in the
|
// Find the Babel-generated mappings that overlap with this range in the
|
||||||
// input sourcemap. Generated locations within the input sourcemap
|
// input sourcemap. Generated locations within the input sourcemap
|
||||||
@ -137,10 +136,10 @@ function filterApplicableOriginalRanges(
|
|||||||
function eachInputGeneratedRange(
|
function eachInputGeneratedRange(
|
||||||
map: ResolvedMappings,
|
map: ResolvedMappings,
|
||||||
callback: (
|
callback: (
|
||||||
ResolvedGeneratedRange,
|
c: ResolvedGeneratedRange,
|
||||||
ResolvedOriginalRange,
|
b: ResolvedOriginalRange,
|
||||||
ResolvedSource,
|
a: ResolvedSource,
|
||||||
) => mixed,
|
) => unknown,
|
||||||
) {
|
) {
|
||||||
for (const { source, mappings } of map.sources) {
|
for (const { source, mappings } of map.sources) {
|
||||||
for (const { original, generated } of mappings) {
|
for (const { original, generated } of mappings) {
|
||||||
@ -151,34 +150,39 @@ function eachInputGeneratedRange(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResolvedMappings = {|
|
type ResolvedMappings = {
|
||||||
file: ?string,
|
file: string | undefined | null;
|
||||||
sourceRoot: ?string,
|
sourceRoot: string | undefined | null;
|
||||||
sources: Array<ResolvedFileMappings>,
|
sources: Array<ResolvedFileMappings>;
|
||||||
|};
|
};
|
||||||
type ResolvedFileMappings = {|
|
|
||||||
source: ResolvedSource,
|
type ResolvedFileMappings = {
|
||||||
mappings: OriginalMappings,
|
source: ResolvedSource;
|
||||||
|};
|
mappings: OriginalMappings;
|
||||||
type OriginalMappings = Array<{|
|
};
|
||||||
original: ResolvedOriginalRange,
|
|
||||||
generated: Array<ResolvedGeneratedRange>,
|
type OriginalMappings = Array<{
|
||||||
|}>;
|
original: ResolvedOriginalRange;
|
||||||
type ResolvedSource = {|
|
generated: Array<ResolvedGeneratedRange>;
|
||||||
path: string,
|
}>;
|
||||||
content: string | null,
|
|
||||||
|};
|
type ResolvedSource = {
|
||||||
type ResolvedOriginalRange = {|
|
path: string;
|
||||||
line: number,
|
content: string | null;
|
||||||
columnStart: number,
|
};
|
||||||
columnEnd: number,
|
|
||||||
name: string | null,
|
type ResolvedOriginalRange = {
|
||||||
|};
|
line: number;
|
||||||
type ResolvedGeneratedRange = {|
|
columnStart: number;
|
||||||
line: number,
|
columnEnd: number;
|
||||||
columnStart: number,
|
name: string | null;
|
||||||
columnEnd: number,
|
};
|
||||||
|};
|
|
||||||
|
type ResolvedGeneratedRange = {
|
||||||
|
line: number;
|
||||||
|
columnStart: number;
|
||||||
|
columnEnd: number;
|
||||||
|
};
|
||||||
|
|
||||||
function buildMappingData(map: SourceMap): ResolvedMappings {
|
function buildMappingData(map: SourceMap): ResolvedMappings {
|
||||||
const consumer = new sourceMap.SourceMapConsumer({
|
const consumer = new sourceMap.SourceMapConsumer({
|
||||||
@ -270,7 +274,7 @@ function buildMappingData(map: SourceMap): ResolvedMappings {
|
|||||||
|
|
||||||
function findInsertionLocation<T>(
|
function findInsertionLocation<T>(
|
||||||
array: Array<T>,
|
array: Array<T>,
|
||||||
callback: T => number,
|
callback: (item: T) => number,
|
||||||
): number {
|
): number {
|
||||||
let left = 0;
|
let left = 0;
|
||||||
let right = array.length;
|
let right = array.length;
|
||||||
@ -304,7 +308,7 @@ function findInsertionLocation<T>(
|
|||||||
|
|
||||||
function filterSortedArray<T>(
|
function filterSortedArray<T>(
|
||||||
array: Array<T>,
|
array: Array<T>,
|
||||||
callback: T => number,
|
callback: (item: T) => number,
|
||||||
): Array<T> {
|
): Array<T> {
|
||||||
const start = findInsertionLocation(array, callback);
|
const start = findInsertionLocation(array, callback);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// @flow
|
|
||||||
import traverse from "@babel/traverse";
|
import traverse from "@babel/traverse";
|
||||||
import typeof { SourceMap } from "convert-source-map";
|
import type * as t from "@babel/types";
|
||||||
|
type SourceMap = any;
|
||||||
import type { Handler } from "gensync";
|
import type { Handler } from "gensync";
|
||||||
|
|
||||||
import type { ResolvedConfig, PluginPasses } from "../config";
|
import type { ResolvedConfig, PluginPasses } from "../config";
|
||||||
@ -14,22 +14,23 @@ import generateCode from "./file/generate";
|
|||||||
import type File from "./file/file";
|
import type File from "./file/file";
|
||||||
|
|
||||||
export type FileResultCallback = {
|
export type FileResultCallback = {
|
||||||
(Error, null): any,
|
(err: Error, file: null): any;
|
||||||
(null, FileResult | null): any,
|
(err: null, file: FileResult | null): any;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FileResult = {
|
export type FileResult = {
|
||||||
metadata: {},
|
metadata: {};
|
||||||
options: {},
|
options: {};
|
||||||
ast: {} | null,
|
ast: {} | null;
|
||||||
code: string | null,
|
code: string | null;
|
||||||
map: SourceMap | null,
|
map: SourceMap | null;
|
||||||
|
sourceType: "string" | "module";
|
||||||
};
|
};
|
||||||
|
|
||||||
export function* run(
|
export function* run(
|
||||||
config: ResolvedConfig,
|
config: ResolvedConfig,
|
||||||
code: string,
|
code: string,
|
||||||
ast: ?(BabelNodeFile | BabelNodeProgram),
|
ast?: t.File | t.Program | null,
|
||||||
): Handler<FileResult> {
|
): Handler<FileResult> {
|
||||||
const file = yield* normalizeFile(
|
const file = yield* normalizeFile(
|
||||||
config.passes,
|
config.passes,
|
||||||
@ -91,7 +92,9 @@ function* transformFile(file: File, pluginPasses: PluginPasses): Handler<void> {
|
|||||||
if (fn) {
|
if (fn) {
|
||||||
const result = fn.call(pass, file);
|
const result = fn.call(pass, file);
|
||||||
|
|
||||||
|
// @ts-expect-error - If we want to support async .pre
|
||||||
yield* [];
|
yield* [];
|
||||||
|
|
||||||
if (isThenable(result)) {
|
if (isThenable(result)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`You appear to be using an plugin with an async .pre, ` +
|
`You appear to be using an plugin with an async .pre, ` +
|
||||||
@ -116,7 +119,9 @@ function* transformFile(file: File, pluginPasses: PluginPasses): Handler<void> {
|
|||||||
if (fn) {
|
if (fn) {
|
||||||
const result = fn.call(pass, file);
|
const result = fn.call(pass, file);
|
||||||
|
|
||||||
|
// @ts-expect-error - If we want to support async .post
|
||||||
yield* [];
|
yield* [];
|
||||||
|
|
||||||
if (isThenable(result)) {
|
if (isThenable(result)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`You appear to be using an plugin with an async .post, ` +
|
`You appear to be using an plugin with an async .post, ` +
|
||||||
@ -130,7 +135,7 @@ function* transformFile(file: File, pluginPasses: PluginPasses): Handler<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isThenable(val: mixed): boolean {
|
function isThenable<T extends PromiseLike<any>>(val: any): val is T {
|
||||||
return (
|
return (
|
||||||
!!val &&
|
!!val &&
|
||||||
(typeof val === "object" || typeof val === "function") &&
|
(typeof val === "object" || typeof val === "function") &&
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import buildDebug from "debug";
|
import buildDebug from "debug";
|
||||||
import type { Handler } from "gensync";
|
import type { Handler } from "gensync";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
import type { PluginPasses } from "../config";
|
import type { PluginPasses } from "../config";
|
||||||
import convertSourceMap, { typeof Converter } from "convert-source-map";
|
import convertSourceMap from "convert-source-map";
|
||||||
|
import type { SourceMapConverter as Converter } from "convert-source-map";
|
||||||
import File from "./file/file";
|
import File from "./file/file";
|
||||||
import parser from "../parser";
|
import parser from "../parser";
|
||||||
import cloneDeep from "./util/clone-deep";
|
import cloneDeep from "./util/clone-deep";
|
||||||
@ -15,16 +14,16 @@ const debug = buildDebug("babel:transform:file");
|
|||||||
const LARGE_INPUT_SOURCEMAP_THRESHOLD = 1_000_000;
|
const LARGE_INPUT_SOURCEMAP_THRESHOLD = 1_000_000;
|
||||||
|
|
||||||
export type NormalizedFile = {
|
export type NormalizedFile = {
|
||||||
code: string,
|
code: string;
|
||||||
ast: {},
|
ast: {};
|
||||||
inputMap: Converter | null,
|
inputMap: Converter | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function* normalizeFile(
|
export default function* normalizeFile(
|
||||||
pluginPasses: PluginPasses,
|
pluginPasses: PluginPasses,
|
||||||
options: Object,
|
options: any,
|
||||||
code: string,
|
code: string,
|
||||||
ast: ?(BabelNodeFile | BabelNodeProgram),
|
ast?: t.File | t.Program | null,
|
||||||
): Handler<File> {
|
): Handler<File> {
|
||||||
code = `${code || ""}`;
|
code = `${code || ""}`;
|
||||||
|
|
||||||
@ -66,16 +65,19 @@ export default function* normalizeFile(
|
|||||||
if (typeof options.filename === "string" && lastComment) {
|
if (typeof options.filename === "string" && lastComment) {
|
||||||
try {
|
try {
|
||||||
// when `lastComment` is non-null, EXTERNAL_SOURCEMAP_REGEX must have matches
|
// when `lastComment` is non-null, EXTERNAL_SOURCEMAP_REGEX must have matches
|
||||||
const match: [string, string] = (EXTERNAL_SOURCEMAP_REGEX.exec(
|
const match: [string, string] = EXTERNAL_SOURCEMAP_REGEX.exec(
|
||||||
lastComment,
|
lastComment,
|
||||||
): any);
|
) as any;
|
||||||
const inputMapContent: Buffer = fs.readFileSync(
|
const inputMapContent = fs.readFileSync(
|
||||||
path.resolve(path.dirname(options.filename), match[1]),
|
path.resolve(path.dirname(options.filename), match[1]),
|
||||||
);
|
);
|
||||||
if (inputMapContent.length > LARGE_INPUT_SOURCEMAP_THRESHOLD) {
|
if (inputMapContent.length > LARGE_INPUT_SOURCEMAP_THRESHOLD) {
|
||||||
debug("skip merging input map > 1 MB");
|
debug("skip merging input map > 1 MB");
|
||||||
} else {
|
} else {
|
||||||
inputMap = convertSourceMap.fromJSON(inputMapContent);
|
inputMap = convertSourceMap.fromJSON(
|
||||||
|
// todo:
|
||||||
|
(inputMapContent as unknown) as string,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
debug("discarding unknown file input sourcemap", err);
|
debug("discarding unknown file input sourcemap", err);
|
||||||
@ -116,19 +118,16 @@ function extractCommentsFromList(regex, comments, lastComment) {
|
|||||||
function extractComments(regex, ast) {
|
function extractComments(regex, ast) {
|
||||||
let lastComment = null;
|
let lastComment = null;
|
||||||
t.traverseFast(ast, node => {
|
t.traverseFast(ast, node => {
|
||||||
// $FlowIgnore destructuring with expressions is not supported
|
|
||||||
[node.leadingComments, lastComment] = extractCommentsFromList(
|
[node.leadingComments, lastComment] = extractCommentsFromList(
|
||||||
regex,
|
regex,
|
||||||
node.leadingComments,
|
node.leadingComments,
|
||||||
lastComment,
|
lastComment,
|
||||||
);
|
);
|
||||||
// $FlowIgnore destructuring with expressions is not supported
|
|
||||||
[node.innerComments, lastComment] = extractCommentsFromList(
|
[node.innerComments, lastComment] = extractCommentsFromList(
|
||||||
regex,
|
regex,
|
||||||
node.innerComments,
|
node.innerComments,
|
||||||
lastComment,
|
lastComment,
|
||||||
);
|
);
|
||||||
// $FlowIgnore destructuring with expressions is not supported
|
|
||||||
[node.trailingComments, lastComment] = extractCommentsFromList(
|
[node.trailingComments, lastComment] = extractCommentsFromList(
|
||||||
regex,
|
regex,
|
||||||
node.trailingComments,
|
node.trailingComments,
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import type { ResolvedConfig } from "../config";
|
import type { ResolvedConfig } from "../config";
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,11 @@
|
|||||||
// @flow
|
|
||||||
|
|
||||||
import type File from "./file/file";
|
import type File from "./file/file";
|
||||||
import type NodeLocation from "./file/file";
|
import type { NodeLocation } from "./file/file";
|
||||||
|
|
||||||
export default class PluginPass {
|
export default class PluginPass {
|
||||||
_map: Map<mixed, mixed> = new Map();
|
_map: Map<unknown, unknown> = new Map();
|
||||||
key: ?string;
|
key: string | undefined | null;
|
||||||
file: File;
|
file: File;
|
||||||
opts: Object;
|
opts: any;
|
||||||
|
|
||||||
// The working directory that Babel's programmatic options are loaded
|
// The working directory that Babel's programmatic options are loaded
|
||||||
// relative to.
|
// relative to.
|
||||||
@ -16,7 +14,7 @@ export default class PluginPass {
|
|||||||
// The absolute path of the file being compiled.
|
// The absolute path of the file being compiled.
|
||||||
filename: string | void;
|
filename: string | void;
|
||||||
|
|
||||||
constructor(file: File, key: ?string, options: ?Object) {
|
constructor(file: File, key?: string | null, options?: any | null) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.opts = options || {};
|
this.opts = options || {};
|
||||||
@ -24,15 +22,15 @@ export default class PluginPass {
|
|||||||
this.filename = file.opts.filename;
|
this.filename = file.opts.filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
set(key: mixed, val: mixed) {
|
set(key: unknown, val: unknown) {
|
||||||
this._map.set(key, val);
|
this._map.set(key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
get(key: mixed): any {
|
get(key: unknown): any {
|
||||||
return this._map.get(key);
|
return this._map.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
availableHelper(name: string, versionRange: ?string) {
|
availableHelper(name: string, versionRange?: string | null) {
|
||||||
return this.file.availableHelper(name, versionRange);
|
return this.file.availableHelper(name, versionRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,14 +42,19 @@ export default class PluginPass {
|
|||||||
return this.file.addImport();
|
return this.file.addImport();
|
||||||
}
|
}
|
||||||
|
|
||||||
buildCodeFrameError(node: ?NodeLocation, msg: string, Error?: typeof Error) {
|
buildCodeFrameError(
|
||||||
return this.file.buildCodeFrameError(node, msg, Error);
|
node: NodeLocation | undefined | null,
|
||||||
|
msg: string,
|
||||||
|
_Error?: typeof Error,
|
||||||
|
) {
|
||||||
|
return this.file.buildCodeFrameError(node, msg, _Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!process.env.BABEL_8_BREAKING) {
|
if (!process.env.BABEL_8_BREAKING) {
|
||||||
// $FlowIgnore
|
(PluginPass as any).prototype.getModuleName = function getModuleName():
|
||||||
PluginPass.prototype.getModuleName = function getModuleName(): ?string {
|
| string
|
||||||
|
| undefined {
|
||||||
return this.file.getModuleName();
|
return this.file.getModuleName();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
17
packages/babel-parser/tsconfig.json
Normal file
17
packages/babel-parser/tsconfig.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"include": [
|
||||||
|
"./typings"
|
||||||
|
],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "../babel-code-frame"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../babel-helper-fixtures"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../babel-helper-validator-identifier"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -167,3 +167,8 @@ export interface RecordAndTuplePluginOptions {
|
|||||||
export interface FlowPluginOptions {
|
export interface FlowPluginOptions {
|
||||||
all?: boolean;
|
all?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const tokTypes: {
|
||||||
|
// todo(flow->ts) real token type
|
||||||
|
[name: string]: any;
|
||||||
|
};
|
||||||
|
|||||||
35
yarn.lock
35
yarn.lock
@ -211,6 +211,12 @@ __metadata:
|
|||||||
"@babel/template": "workspace:^7.12.13"
|
"@babel/template": "workspace:^7.12.13"
|
||||||
"@babel/traverse": "workspace:^7.13.13"
|
"@babel/traverse": "workspace:^7.13.13"
|
||||||
"@babel/types": "workspace:^7.13.14"
|
"@babel/types": "workspace:^7.13.14"
|
||||||
|
"@types/convert-source-map": ^1.5.1
|
||||||
|
"@types/debug": ^4.1.0
|
||||||
|
"@types/lodash": ^4.14.150
|
||||||
|
"@types/resolve": ^1.3.2
|
||||||
|
"@types/semver": ^5.4.0
|
||||||
|
"@types/source-map": ^0.5.0
|
||||||
convert-source-map: ^1.7.0
|
convert-source-map: ^1.7.0
|
||||||
debug: ^4.1.0
|
debug: ^4.1.0
|
||||||
gensync: ^1.0.0-beta.2
|
gensync: ^1.0.0-beta.2
|
||||||
@ -659,6 +665,7 @@ __metadata:
|
|||||||
resolution: "@babel/helper-module-transforms@condition:BABEL_8_BREAKING?:workspace:^7.13.14#f57fb3"
|
resolution: "@babel/helper-module-transforms@condition:BABEL_8_BREAKING?:workspace:^7.13.14#f57fb3"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/helper-module-transforms-BABEL_8_BREAKING-false": "npm:@babel/helper-module-transforms@workspace:^7.13.14"
|
"@babel/helper-module-transforms-BABEL_8_BREAKING-false": "npm:@babel/helper-module-transforms@workspace:^7.13.14"
|
||||||
|
checksum: 82d133091e69e2b2c742cfeb03c3f9acb3d0a00391d3ab2624154aa537dc714eedc5d8145c6c671bacd63d5314de09982a36b216b520c22466e4af3e375aff2d
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -3992,6 +3999,20 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/convert-source-map@npm:^1.5.1":
|
||||||
|
version: 1.5.1
|
||||||
|
resolution: "@types/convert-source-map@npm:1.5.1"
|
||||||
|
checksum: 36cd50ea42b5e5c41db2415e4f42bdbc426e6b963a7d0d0a511164b789d4140629fbc0b3c5a29306ad3731ab41708088bb63e95972060cd3983af1f22b33f414
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/debug@npm:^4.1.0":
|
||||||
|
version: 4.1.5
|
||||||
|
resolution: "@types/debug@npm:4.1.5"
|
||||||
|
checksum: 416ad24bc589be0fb8c78bea972aa7d4ffdf6b136239701b1792674463b2dbf8c6707f6055ec484f79ec1f2b528ffef90c87e55df7e4a0f458184cad5bf0cfc8
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/eslint-scope@npm:^3.7.0":
|
"@types/eslint-scope@npm:^3.7.0":
|
||||||
version: 3.7.0
|
version: 3.7.0
|
||||||
resolution: "@types/eslint-scope@npm:3.7.0"
|
resolution: "@types/eslint-scope@npm:3.7.0"
|
||||||
@ -4163,6 +4184,20 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/resolve@npm:^1.3.2":
|
||||||
|
version: 1.20.0
|
||||||
|
resolution: "@types/resolve@npm:1.20.0"
|
||||||
|
checksum: 3c75135d5cf3652453ef8f099b109f7fec5e82fe67bf38048226614dbcd11a943affee383e5d28c12c5f03b049281a3e486395326b9810297f9649c7b00f41fd
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/semver@npm:^5.4.0":
|
||||||
|
version: 5.5.0
|
||||||
|
resolution: "@types/semver@npm:5.5.0"
|
||||||
|
checksum: df74589466e171c36dd868b760609e518830f212134c238674ddd6eb83653368c59f4510aa6523b7692ec99c5d8ab40b818e30f9d65e0df97c56bdbacef06661
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/semver@npm:^7.3.4":
|
"@types/semver@npm:^7.3.4":
|
||||||
version: 7.3.4
|
version: 7.3.4
|
||||||
resolution: "@types/semver@npm:7.3.4"
|
resolution: "@types/semver@npm:7.3.4"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user