1 | "use strict";
|
---|
2 |
|
---|
3 | Object.defineProperty(exports, "__esModule", {
|
---|
4 | value: true
|
---|
5 | });
|
---|
6 | exports.createCachedDescriptors = createCachedDescriptors;
|
---|
7 | exports.createUncachedDescriptors = createUncachedDescriptors;
|
---|
8 | exports.createDescriptor = createDescriptor;
|
---|
9 |
|
---|
10 | function _gensync() {
|
---|
11 | const data = require("gensync");
|
---|
12 |
|
---|
13 | _gensync = function () {
|
---|
14 | return data;
|
---|
15 | };
|
---|
16 |
|
---|
17 | return data;
|
---|
18 | }
|
---|
19 |
|
---|
20 | var _files = require("./files");
|
---|
21 |
|
---|
22 | var _item = require("./item");
|
---|
23 |
|
---|
24 | var _caching = require("./caching");
|
---|
25 |
|
---|
26 | var _resolveTargets = require("./resolve-targets");
|
---|
27 |
|
---|
28 | function isEqualDescriptor(a, b) {
|
---|
29 | return a.name === b.name && a.value === b.value && a.options === b.options && a.dirname === b.dirname && a.alias === b.alias && a.ownPass === b.ownPass && (a.file && a.file.request) === (b.file && b.file.request) && (a.file && a.file.resolved) === (b.file && b.file.resolved);
|
---|
30 | }
|
---|
31 |
|
---|
32 | function* handlerOf(value) {
|
---|
33 | return value;
|
---|
34 | }
|
---|
35 |
|
---|
36 | function optionsWithResolvedBrowserslistConfigFile(options, dirname) {
|
---|
37 | if (typeof options.browserslistConfigFile === "string") {
|
---|
38 | options.browserslistConfigFile = (0, _resolveTargets.resolveBrowserslistConfigFile)(options.browserslistConfigFile, dirname);
|
---|
39 | }
|
---|
40 |
|
---|
41 | return options;
|
---|
42 | }
|
---|
43 |
|
---|
44 | function createCachedDescriptors(dirname, options, alias) {
|
---|
45 | const {
|
---|
46 | plugins,
|
---|
47 | presets,
|
---|
48 | passPerPreset
|
---|
49 | } = options;
|
---|
50 | return {
|
---|
51 | options: optionsWithResolvedBrowserslistConfigFile(options, dirname),
|
---|
52 | plugins: plugins ? () => createCachedPluginDescriptors(plugins, dirname)(alias) : () => handlerOf([]),
|
---|
53 | presets: presets ? () => createCachedPresetDescriptors(presets, dirname)(alias)(!!passPerPreset) : () => handlerOf([])
|
---|
54 | };
|
---|
55 | }
|
---|
56 |
|
---|
57 | function createUncachedDescriptors(dirname, options, alias) {
|
---|
58 | let plugins;
|
---|
59 | let presets;
|
---|
60 | return {
|
---|
61 | options: optionsWithResolvedBrowserslistConfigFile(options, dirname),
|
---|
62 |
|
---|
63 | *plugins() {
|
---|
64 | if (!plugins) {
|
---|
65 | plugins = yield* createPluginDescriptors(options.plugins || [], dirname, alias);
|
---|
66 | }
|
---|
67 |
|
---|
68 | return plugins;
|
---|
69 | },
|
---|
70 |
|
---|
71 | *presets() {
|
---|
72 | if (!presets) {
|
---|
73 | presets = yield* createPresetDescriptors(options.presets || [], dirname, alias, !!options.passPerPreset);
|
---|
74 | }
|
---|
75 |
|
---|
76 | return presets;
|
---|
77 | }
|
---|
78 |
|
---|
79 | };
|
---|
80 | }
|
---|
81 |
|
---|
82 | const PRESET_DESCRIPTOR_CACHE = new WeakMap();
|
---|
83 | const createCachedPresetDescriptors = (0, _caching.makeWeakCacheSync)((items, cache) => {
|
---|
84 | const dirname = cache.using(dir => dir);
|
---|
85 | return (0, _caching.makeStrongCacheSync)(alias => (0, _caching.makeStrongCache)(function* (passPerPreset) {
|
---|
86 | const descriptors = yield* createPresetDescriptors(items, dirname, alias, passPerPreset);
|
---|
87 | return descriptors.map(desc => loadCachedDescriptor(PRESET_DESCRIPTOR_CACHE, desc));
|
---|
88 | }));
|
---|
89 | });
|
---|
90 | const PLUGIN_DESCRIPTOR_CACHE = new WeakMap();
|
---|
91 | const createCachedPluginDescriptors = (0, _caching.makeWeakCacheSync)((items, cache) => {
|
---|
92 | const dirname = cache.using(dir => dir);
|
---|
93 | return (0, _caching.makeStrongCache)(function* (alias) {
|
---|
94 | const descriptors = yield* createPluginDescriptors(items, dirname, alias);
|
---|
95 | return descriptors.map(desc => loadCachedDescriptor(PLUGIN_DESCRIPTOR_CACHE, desc));
|
---|
96 | });
|
---|
97 | });
|
---|
98 | const DEFAULT_OPTIONS = {};
|
---|
99 |
|
---|
100 | function loadCachedDescriptor(cache, desc) {
|
---|
101 | const {
|
---|
102 | value,
|
---|
103 | options = DEFAULT_OPTIONS
|
---|
104 | } = desc;
|
---|
105 | if (options === false) return desc;
|
---|
106 | let cacheByOptions = cache.get(value);
|
---|
107 |
|
---|
108 | if (!cacheByOptions) {
|
---|
109 | cacheByOptions = new WeakMap();
|
---|
110 | cache.set(value, cacheByOptions);
|
---|
111 | }
|
---|
112 |
|
---|
113 | let possibilities = cacheByOptions.get(options);
|
---|
114 |
|
---|
115 | if (!possibilities) {
|
---|
116 | possibilities = [];
|
---|
117 | cacheByOptions.set(options, possibilities);
|
---|
118 | }
|
---|
119 |
|
---|
120 | if (possibilities.indexOf(desc) === -1) {
|
---|
121 | const matches = possibilities.filter(possibility => isEqualDescriptor(possibility, desc));
|
---|
122 |
|
---|
123 | if (matches.length > 0) {
|
---|
124 | return matches[0];
|
---|
125 | }
|
---|
126 |
|
---|
127 | possibilities.push(desc);
|
---|
128 | }
|
---|
129 |
|
---|
130 | return desc;
|
---|
131 | }
|
---|
132 |
|
---|
133 | function* createPresetDescriptors(items, dirname, alias, passPerPreset) {
|
---|
134 | return yield* createDescriptors("preset", items, dirname, alias, passPerPreset);
|
---|
135 | }
|
---|
136 |
|
---|
137 | function* createPluginDescriptors(items, dirname, alias) {
|
---|
138 | return yield* createDescriptors("plugin", items, dirname, alias);
|
---|
139 | }
|
---|
140 |
|
---|
141 | function* createDescriptors(type, items, dirname, alias, ownPass) {
|
---|
142 | const descriptors = yield* _gensync().all(items.map((item, index) => createDescriptor(item, dirname, {
|
---|
143 | type,
|
---|
144 | alias: `${alias}$${index}`,
|
---|
145 | ownPass: !!ownPass
|
---|
146 | })));
|
---|
147 | assertNoDuplicates(descriptors);
|
---|
148 | return descriptors;
|
---|
149 | }
|
---|
150 |
|
---|
151 | function* createDescriptor(pair, dirname, {
|
---|
152 | type,
|
---|
153 | alias,
|
---|
154 | ownPass
|
---|
155 | }) {
|
---|
156 | const desc = (0, _item.getItemDescriptor)(pair);
|
---|
157 |
|
---|
158 | if (desc) {
|
---|
159 | return desc;
|
---|
160 | }
|
---|
161 |
|
---|
162 | let name;
|
---|
163 | let options;
|
---|
164 | let value = pair;
|
---|
165 |
|
---|
166 | if (Array.isArray(value)) {
|
---|
167 | if (value.length === 3) {
|
---|
168 | [value, options, name] = value;
|
---|
169 | } else {
|
---|
170 | [value, options] = value;
|
---|
171 | }
|
---|
172 | }
|
---|
173 |
|
---|
174 | let file = undefined;
|
---|
175 | let filepath = null;
|
---|
176 |
|
---|
177 | if (typeof value === "string") {
|
---|
178 | if (typeof type !== "string") {
|
---|
179 | throw new Error("To resolve a string-based item, the type of item must be given");
|
---|
180 | }
|
---|
181 |
|
---|
182 | const resolver = type === "plugin" ? _files.loadPlugin : _files.loadPreset;
|
---|
183 | const request = value;
|
---|
184 | ({
|
---|
185 | filepath,
|
---|
186 | value
|
---|
187 | } = yield* resolver(value, dirname));
|
---|
188 | file = {
|
---|
189 | request,
|
---|
190 | resolved: filepath
|
---|
191 | };
|
---|
192 | }
|
---|
193 |
|
---|
194 | if (!value) {
|
---|
195 | throw new Error(`Unexpected falsy value: ${String(value)}`);
|
---|
196 | }
|
---|
197 |
|
---|
198 | if (typeof value === "object" && value.__esModule) {
|
---|
199 | if (value.default) {
|
---|
200 | value = value.default;
|
---|
201 | } else {
|
---|
202 | throw new Error("Must export a default export when using ES6 modules.");
|
---|
203 | }
|
---|
204 | }
|
---|
205 |
|
---|
206 | if (typeof value !== "object" && typeof value !== "function") {
|
---|
207 | throw new Error(`Unsupported format: ${typeof value}. Expected an object or a function.`);
|
---|
208 | }
|
---|
209 |
|
---|
210 | if (filepath !== null && typeof value === "object" && value) {
|
---|
211 | throw new Error(`Plugin/Preset files are not allowed to export objects, only functions. In ${filepath}`);
|
---|
212 | }
|
---|
213 |
|
---|
214 | return {
|
---|
215 | name,
|
---|
216 | alias: filepath || alias,
|
---|
217 | value,
|
---|
218 | options,
|
---|
219 | dirname,
|
---|
220 | ownPass,
|
---|
221 | file
|
---|
222 | };
|
---|
223 | }
|
---|
224 |
|
---|
225 | function assertNoDuplicates(items) {
|
---|
226 | const map = new Map();
|
---|
227 |
|
---|
228 | for (const item of items) {
|
---|
229 | if (typeof item.value !== "function") continue;
|
---|
230 | let nameMap = map.get(item.value);
|
---|
231 |
|
---|
232 | if (!nameMap) {
|
---|
233 | nameMap = new Set();
|
---|
234 | map.set(item.value, nameMap);
|
---|
235 | }
|
---|
236 |
|
---|
237 | if (nameMap.has(item.name)) {
|
---|
238 | const conflicts = items.filter(i => i.value === item.value);
|
---|
239 | throw new Error([`Duplicate plugin/preset detected.`, `If you'd like to use two separate instances of a plugin,`, `they need separate names, e.g.`, ``, ` plugins: [`, ` ['some-plugin', {}],`, ` ['some-plugin', {}, 'some unique name'],`, ` ]`, ``, `Duplicates detected are:`, `${JSON.stringify(conflicts, null, 2)}`].join("\n"));
|
---|
240 | }
|
---|
241 |
|
---|
242 | nameMap.add(item.name);
|
---|
243 | }
|
---|
244 | } |
---|