129 lines
3.4 KiB
JavaScript
129 lines
3.4 KiB
JavaScript
// @flow
|
|
|
|
import type { PluginTarget, PluginOptions } from "./validation/options";
|
|
|
|
import path from "path";
|
|
import {
|
|
createDescriptor,
|
|
type UnloadedDescriptor,
|
|
} from "./config-descriptors";
|
|
|
|
export function createItemFromDescriptor(desc: UnloadedDescriptor): ConfigItem {
|
|
return new ConfigItem(desc);
|
|
}
|
|
|
|
/**
|
|
* Create a config item using the same value format used in Babel's config
|
|
* files. Items returned from this function should be cached by the caller
|
|
* ideally, as recreating the config item will mean re-resolving the item
|
|
* and re-evaluating the plugin/preset function.
|
|
*/
|
|
export function createConfigItem(
|
|
value:
|
|
| PluginTarget
|
|
| [PluginTarget, PluginOptions]
|
|
| [PluginTarget, PluginOptions, string | void],
|
|
{
|
|
dirname = ".",
|
|
type,
|
|
}: {
|
|
dirname?: string,
|
|
type?: "preset" | "plugin",
|
|
} = {},
|
|
): ConfigItem {
|
|
const descriptor = createDescriptor(value, path.resolve(dirname), {
|
|
type,
|
|
alias: "programmatic item",
|
|
});
|
|
|
|
return createItemFromDescriptor(descriptor);
|
|
}
|
|
|
|
export function getItemDescriptor(item: mixed): UnloadedDescriptor | void {
|
|
if (item instanceof ConfigItem) {
|
|
return item._descriptor;
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
export type { ConfigItem };
|
|
|
|
/**
|
|
* A public representation of a plugin/preset that will _eventually_ be load.
|
|
* Users can use this to interact with the results of a loaded Babel
|
|
* configuration.
|
|
*
|
|
* Any changes to public properties of this class should be considered a
|
|
* breaking change to Babel's API.
|
|
*/
|
|
class ConfigItem {
|
|
/**
|
|
* The private underlying descriptor that Babel actually cares about.
|
|
* If you access this, you are a bad person.
|
|
*/
|
|
_descriptor: UnloadedDescriptor;
|
|
|
|
/**
|
|
* The resolved value of the item itself.
|
|
*/
|
|
value: {} | Function;
|
|
|
|
/**
|
|
* The options, if any, that were passed to the item.
|
|
* Mutating this will lead to undefined behavior. If you need
|
|
*/
|
|
options: {} | void;
|
|
|
|
/**
|
|
* The directory that the options for this item are relative to.
|
|
*/
|
|
dirname: string;
|
|
|
|
/**
|
|
* Get the name of the plugin, if the user gave it one.
|
|
*/
|
|
name: string | void;
|
|
|
|
/**
|
|
* Data about the file that the item was loaded from, if Babel knows it.
|
|
*/
|
|
file: {
|
|
// The requested path, e.g. "@babel/env".
|
|
request: string,
|
|
|
|
// The resolved absolute path of the file.
|
|
resolved: string,
|
|
} | void;
|
|
|
|
constructor(descriptor: UnloadedDescriptor) {
|
|
// Make people less likely to stumble onto this if they are exploring
|
|
// programmatically, and also make sure that if people happen to
|
|
// pass the item through JSON.stringify, it doesn't show up.
|
|
this._descriptor = descriptor;
|
|
Object.defineProperty(this, "_descriptor", ({ enumerable: false }: any));
|
|
|
|
if (this._descriptor.options === false) {
|
|
throw new Error("Assertion failure - unexpected false options");
|
|
}
|
|
|
|
this.value = this._descriptor.value;
|
|
this.options = this._descriptor.options;
|
|
this.dirname = this._descriptor.dirname;
|
|
this.name = this._descriptor.name;
|
|
this.file = this._descriptor.file
|
|
? {
|
|
request: this._descriptor.file.request,
|
|
resolved: this._descriptor.file.resolved,
|
|
}
|
|
: undefined;
|
|
|
|
// Freeze the object to make it clear that people shouldn't expect mutating
|
|
// this object to do anything. A new item should be created if they want
|
|
// to change something.
|
|
Object.freeze(this);
|
|
}
|
|
}
|
|
|
|
Object.freeze(ConfigItem.prototype);
|