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 | var _files = require("./files");
|
11 |
|
12 | var _item = require("./item");
|
13 |
|
14 | var _caching = require("./caching");
|
15 |
|
16 | function isEqualDescriptor(a, b) {
|
17 | 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);
|
18 | }
|
19 |
|
20 | function createCachedDescriptors(dirname, options, alias) {
|
21 | const {
|
22 | plugins,
|
23 | presets,
|
24 | passPerPreset
|
25 | } = options;
|
26 | return {
|
27 | options,
|
28 | plugins: plugins ? () => createCachedPluginDescriptors(plugins, dirname)(alias) : () => [],
|
29 | presets: presets ? () => createCachedPresetDescriptors(presets, dirname)(alias)(!!passPerPreset) : () => []
|
30 | };
|
31 | }
|
32 |
|
33 | function createUncachedDescriptors(dirname, options, alias) {
|
34 | let plugins;
|
35 | let presets;
|
36 | return {
|
37 | options,
|
38 | plugins: () => {
|
39 | if (!plugins) {
|
40 | plugins = createPluginDescriptors(options.plugins || [], dirname, alias);
|
41 | }
|
42 |
|
43 | return plugins;
|
44 | },
|
45 | presets: () => {
|
46 | if (!presets) {
|
47 | presets = createPresetDescriptors(options.presets || [], dirname, alias, !!options.passPerPreset);
|
48 | }
|
49 |
|
50 | return presets;
|
51 | }
|
52 | };
|
53 | }
|
54 |
|
55 | const PRESET_DESCRIPTOR_CACHE = new WeakMap();
|
56 | const createCachedPresetDescriptors = (0, _caching.makeWeakCacheSync)((items, cache) => {
|
57 | const dirname = cache.using(dir => dir);
|
58 | return (0, _caching.makeStrongCacheSync)(alias => (0, _caching.makeStrongCacheSync)(passPerPreset => createPresetDescriptors(items, dirname, alias, passPerPreset).map(desc => loadCachedDescriptor(PRESET_DESCRIPTOR_CACHE, desc))));
|
59 | });
|
60 | const PLUGIN_DESCRIPTOR_CACHE = new WeakMap();
|
61 | const createCachedPluginDescriptors = (0, _caching.makeWeakCacheSync)((items, cache) => {
|
62 | const dirname = cache.using(dir => dir);
|
63 | return (0, _caching.makeStrongCacheSync)(alias => createPluginDescriptors(items, dirname, alias).map(desc => loadCachedDescriptor(PLUGIN_DESCRIPTOR_CACHE, desc)));
|
64 | });
|
65 | const DEFAULT_OPTIONS = {};
|
66 |
|
67 | function loadCachedDescriptor(cache, desc) {
|
68 | const {
|
69 | value,
|
70 | options = DEFAULT_OPTIONS
|
71 | } = desc;
|
72 | if (options === false) return desc;
|
73 | let cacheByOptions = cache.get(value);
|
74 |
|
75 | if (!cacheByOptions) {
|
76 | cacheByOptions = new WeakMap();
|
77 | cache.set(value, cacheByOptions);
|
78 | }
|
79 |
|
80 | let possibilities = cacheByOptions.get(options);
|
81 |
|
82 | if (!possibilities) {
|
83 | possibilities = [];
|
84 | cacheByOptions.set(options, possibilities);
|
85 | }
|
86 |
|
87 | if (possibilities.indexOf(desc) === -1) {
|
88 | const matches = possibilities.filter(possibility => isEqualDescriptor(possibility, desc));
|
89 |
|
90 | if (matches.length > 0) {
|
91 | return matches[0];
|
92 | }
|
93 |
|
94 | possibilities.push(desc);
|
95 | }
|
96 |
|
97 | return desc;
|
98 | }
|
99 |
|
100 | function createPresetDescriptors(items, dirname, alias, passPerPreset) {
|
101 | return createDescriptors("preset", items, dirname, alias, passPerPreset);
|
102 | }
|
103 |
|
104 | function createPluginDescriptors(items, dirname, alias) {
|
105 | return createDescriptors("plugin", items, dirname, alias);
|
106 | }
|
107 |
|
108 | function createDescriptors(type, items, dirname, alias, ownPass) {
|
109 | const descriptors = items.map((item, index) => createDescriptor(item, dirname, {
|
110 | type,
|
111 | alias: `${alias}$${index}`,
|
112 | ownPass: !!ownPass
|
113 | }));
|
114 | assertNoDuplicates(descriptors);
|
115 | return descriptors;
|
116 | }
|
117 |
|
118 | function createDescriptor(pair, dirname, {
|
119 | type,
|
120 | alias,
|
121 | ownPass
|
122 | }) {
|
123 | const desc = (0, _item.getItemDescriptor)(pair);
|
124 |
|
125 | if (desc) {
|
126 | return desc;
|
127 | }
|
128 |
|
129 | let name;
|
130 | let options;
|
131 | let value = pair;
|
132 |
|
133 | if (Array.isArray(value)) {
|
134 | if (value.length === 3) {
|
135 | [value, options, name] = value;
|
136 | } else {
|
137 | [value, options] = value;
|
138 | }
|
139 | }
|
140 |
|
141 | let file = undefined;
|
142 | let filepath = null;
|
143 |
|
144 | if (typeof value === "string") {
|
145 | if (typeof type !== "string") {
|
146 | throw new Error("To resolve a string-based item, the type of item must be given");
|
147 | }
|
148 |
|
149 | const resolver = type === "plugin" ? _files.loadPlugin : _files.loadPreset;
|
150 | const request = value;
|
151 | ({
|
152 | filepath,
|
153 | value
|
154 | } = resolver(value, dirname));
|
155 | file = {
|
156 | request,
|
157 | resolved: filepath
|
158 | };
|
159 | }
|
160 |
|
161 | if (!value) {
|
162 | throw new Error(`Unexpected falsy value: ${String(value)}`);
|
163 | }
|
164 |
|
165 | if (typeof value === "object" && value.__esModule) {
|
166 | if (value.default) {
|
167 | value = value.default;
|
168 | } else {
|
169 | throw new Error("Must export a default export when using ES6 modules.");
|
170 | }
|
171 | }
|
172 |
|
173 | if (typeof value !== "object" && typeof value !== "function") {
|
174 | throw new Error(`Unsupported format: ${typeof value}. Expected an object or a function.`);
|
175 | }
|
176 |
|
177 | if (filepath !== null && typeof value === "object" && value) {
|
178 | throw new Error(`Plugin/Preset files are not allowed to export objects, only functions. In ${filepath}`);
|
179 | }
|
180 |
|
181 | return {
|
182 | name,
|
183 | alias: filepath || alias,
|
184 | value,
|
185 | options,
|
186 | dirname,
|
187 | ownPass,
|
188 | file
|
189 | };
|
190 | }
|
191 |
|
192 | function assertNoDuplicates(items) {
|
193 | const map = new Map();
|
194 |
|
195 | for (const item of items) {
|
196 | if (typeof item.value !== "function") continue;
|
197 | let nameMap = map.get(item.value);
|
198 |
|
199 | if (!nameMap) {
|
200 | nameMap = new Set();
|
201 | map.set(item.value, nameMap);
|
202 | }
|
203 |
|
204 | if (nameMap.has(item.name)) {
|
205 | const conflicts = items.filter(i => i.value === item.value);
|
206 | 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"));
|
207 | }
|
208 |
|
209 | nameMap.add(item.name);
|
210 | }
|
211 | } |
\ | No newline at end of file |