webpack 3.8.0 → 3.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +716 -716
  3. package/buildin/.eslintrc +7 -7
  4. package/buildin/amd-define.js +3 -3
  5. package/buildin/amd-options.js +2 -2
  6. package/buildin/global.js +21 -21
  7. package/buildin/harmony-module.js +24 -24
  8. package/buildin/module.js +22 -22
  9. package/buildin/system.js +7 -7
  10. package/hot/.eslintrc +9 -9
  11. package/hot/dev-server.js +53 -53
  12. package/hot/emitter.js +2 -2
  13. package/hot/log-apply-result.js +38 -38
  14. package/hot/log.js +44 -44
  15. package/hot/only-dev-server.js +71 -71
  16. package/hot/poll.js +34 -34
  17. package/hot/signal.js +51 -51
  18. package/lib/APIPlugin.js +45 -45
  19. package/lib/AsyncDependenciesBlock.js +43 -43
  20. package/lib/AutomaticPrefetchPlugin.js +36 -36
  21. package/lib/BasicEvaluatedExpression.js +203 -203
  22. package/lib/CaseSensitiveModulesWarning.js +49 -49
  23. package/lib/ChunkRenderError.js +24 -24
  24. package/lib/ChunkTemplate.js +36 -36
  25. package/lib/CompatibilityPlugin.js +57 -57
  26. package/lib/Compiler.js +523 -523
  27. package/lib/ConstPlugin.js +60 -60
  28. package/lib/ContextModule.js +431 -431
  29. package/lib/ContextReplacementPlugin.js +111 -111
  30. package/lib/DefinePlugin.js +123 -123
  31. package/lib/DelegatedModule.js +98 -98
  32. package/lib/DelegatedModuleFactoryPlugin.js +59 -59
  33. package/lib/DelegatedPlugin.js +30 -30
  34. package/lib/DependenciesBlockVariable.js +51 -51
  35. package/lib/DllEntryPlugin.js +37 -37
  36. package/lib/DllModule.js +58 -58
  37. package/lib/DllModuleFactory.js +20 -20
  38. package/lib/DllPlugin.js +38 -38
  39. package/lib/DllReferencePlugin.js +62 -62
  40. package/lib/DynamicEntryPlugin.js +59 -59
  41. package/lib/EntryModuleNotFoundError.js +22 -22
  42. package/lib/EntryOptionPlugin.js +31 -31
  43. package/lib/EnvironmentPlugin.js +50 -50
  44. package/lib/ErrorHelpers.js +31 -31
  45. package/lib/EvalDevToolModulePlugin.js +22 -22
  46. package/lib/EvalDevToolModuleTemplatePlugin.js +33 -33
  47. package/lib/EvalSourceMapDevToolModuleTemplatePlugin.js +75 -75
  48. package/lib/EvalSourceMapDevToolPlugin.js +32 -32
  49. package/lib/ExportPropertyMainTemplatePlugin.js +31 -31
  50. package/lib/ExtendedAPIPlugin.js +47 -47
  51. package/lib/ExternalModuleFactoryPlugin.js +91 -91
  52. package/lib/ExternalsPlugin.js +21 -21
  53. package/lib/FlagDependencyExportsPlugin.js +101 -101
  54. package/lib/FunctionModulePlugin.js +24 -24
  55. package/lib/HashedModuleIdsPlugin.js +42 -42
  56. package/lib/HotUpdateChunkTemplate.js +31 -31
  57. package/lib/IgnorePlugin.js +69 -69
  58. package/lib/JsonpExportMainTemplatePlugin.js +37 -37
  59. package/lib/JsonpHotUpdateChunkTemplatePlugin.js +27 -27
  60. package/lib/JsonpTemplatePlugin.js +21 -21
  61. package/lib/LibManifestPlugin.js +63 -63
  62. package/lib/LibraryTemplatePlugin.js +92 -92
  63. package/lib/LoaderOptionsPlugin.js +36 -36
  64. package/lib/LoaderTargetPlugin.js +19 -19
  65. package/lib/MemoryOutputFileSystem.js +5 -5
  66. package/lib/ModuleBuildError.js +42 -42
  67. package/lib/ModuleDependencyError.js +22 -22
  68. package/lib/ModuleDependencyWarning.js +22 -22
  69. package/lib/ModuleError.js +24 -24
  70. package/lib/ModuleFilenameHelpers.js +162 -162
  71. package/lib/ModuleNotFoundError.js +26 -26
  72. package/lib/ModuleReason.js +50 -50
  73. package/lib/ModuleTemplate.js +23 -23
  74. package/lib/ModuleWarning.js +24 -24
  75. package/lib/MovedToPluginWarningPlugin.js +21 -21
  76. package/lib/MultiCompiler.js +164 -164
  77. package/lib/MultiEntryPlugin.js +39 -39
  78. package/lib/MultiModuleFactory.js +19 -19
  79. package/lib/MultiStats.js +79 -79
  80. package/lib/MultiWatching.js +32 -32
  81. package/lib/NamedChunksPlugin.js +30 -30
  82. package/lib/NamedModulesPlugin.js +27 -27
  83. package/lib/NewWatchingPlugin.js +15 -15
  84. package/lib/NoEmitOnErrorsPlugin.js +22 -22
  85. package/lib/NoErrorsPlugin.js +29 -29
  86. package/lib/NodeStuffPlugin.js +97 -97
  87. package/lib/NormalModuleReplacementPlugin.js +45 -45
  88. package/lib/NullFactory.js +12 -12
  89. package/lib/OptionsApply.js +10 -10
  90. package/lib/ParserHelpers.js +85 -85
  91. package/lib/PrefetchPlugin.js +31 -31
  92. package/lib/ProgressPlugin.js +192 -192
  93. package/lib/ProvidePlugin.js +55 -55
  94. package/lib/RawModule.js +54 -54
  95. package/lib/RequestShortener.js +63 -63
  96. package/lib/RequireJsStuffPlugin.js +31 -31
  97. package/lib/RuleSet.js +444 -444
  98. package/lib/SetVarMainTemplatePlugin.js +41 -41
  99. package/lib/SingleEntryPlugin.js +35 -35
  100. package/lib/SizeFormatHelpers.js +18 -18
  101. package/lib/SourceMapDevToolModuleOptionsPlugin.js +37 -37
  102. package/lib/UnsupportedFeatureWarning.js +21 -21
  103. package/lib/UseStrictPlugin.js +34 -34
  104. package/lib/WarnCaseSensitiveModulesPlugin.js +31 -31
  105. package/lib/WatchIgnorePlugin.js +49 -49
  106. package/lib/WebpackError.js +11 -11
  107. package/lib/WebpackOptionsDefaulter.js +129 -129
  108. package/lib/WebpackOptionsValidationError.js +196 -196
  109. package/lib/compareLocations.js +36 -36
  110. package/lib/dependencies/AMDDefineDependency.js +142 -142
  111. package/lib/dependencies/AMDPlugin.js +119 -119
  112. package/lib/dependencies/AMDRequireDependenciesBlock.js +33 -33
  113. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +177 -177
  114. package/lib/dependencies/AMDRequireDependency.js +67 -67
  115. package/lib/dependencies/AMDRequireItemDependency.js +22 -22
  116. package/lib/dependencies/CommonJsRequireDependency.js +22 -22
  117. package/lib/dependencies/CommonJsRequireDependencyParserPlugin.js +89 -89
  118. package/lib/dependencies/ConstDependency.js +32 -32
  119. package/lib/dependencies/ContextDependencyHelpers.js +71 -71
  120. package/lib/dependencies/ContextElementDependency.js +21 -21
  121. package/lib/dependencies/CriticalDependencyWarning.js +20 -20
  122. package/lib/dependencies/DelegatedExportsDependency.js +33 -33
  123. package/lib/dependencies/DelegatedSourceDependency.js +18 -18
  124. package/lib/dependencies/DllEntryDependency.js +20 -20
  125. package/lib/dependencies/HarmonyCompatibilityDependency.js +30 -30
  126. package/lib/dependencies/HarmonyExportHeaderDependency.js +28 -28
  127. package/lib/dependencies/ImportDependenciesBlock.js +17 -17
  128. package/lib/dependencies/ImportEagerContextDependency.js +22 -22
  129. package/lib/dependencies/ImportLazyContextDependency.js +22 -22
  130. package/lib/dependencies/ImportLazyOnceContextDependency.js +22 -22
  131. package/lib/dependencies/ImportParserPlugin.js +89 -89
  132. package/lib/dependencies/ImportPlugin.js +60 -60
  133. package/lib/dependencies/ImportWeakContextDependency.js +22 -22
  134. package/lib/dependencies/LoaderDependency.js +18 -18
  135. package/lib/dependencies/LoaderPlugin.js +60 -60
  136. package/lib/dependencies/LocalModule.js +23 -23
  137. package/lib/dependencies/LocalModuleDependency.js +24 -24
  138. package/lib/dependencies/LocalModulesHelpers.js +46 -46
  139. package/lib/dependencies/ModuleDependency.js +23 -23
  140. package/lib/dependencies/ModuleHotAcceptDependency.js +23 -23
  141. package/lib/dependencies/ModuleHotDeclineDependency.js +23 -23
  142. package/lib/dependencies/MultiEntryDependency.js +20 -20
  143. package/lib/dependencies/NullDependency.js +24 -24
  144. package/lib/dependencies/PrefetchDependency.js +18 -18
  145. package/lib/dependencies/RequireContextDependency.js +26 -26
  146. package/lib/dependencies/RequireContextDependencyParserPlugin.js +50 -50
  147. package/lib/dependencies/RequireContextPlugin.js +96 -96
  148. package/lib/dependencies/RequireEnsureDependenciesBlock.js +22 -22
  149. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +102 -102
  150. package/lib/dependencies/RequireEnsureDependency.js +38 -38
  151. package/lib/dependencies/RequireEnsureItemDependency.js +21 -21
  152. package/lib/dependencies/RequireEnsurePlugin.js +40 -40
  153. package/lib/dependencies/RequireHeaderDependency.js +26 -26
  154. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +21 -21
  155. package/lib/dependencies/RequireIncludePlugin.js +33 -33
  156. package/lib/dependencies/RequireResolveDependency.js +22 -22
  157. package/lib/dependencies/RequireResolveDependencyParserPlugin.js +71 -71
  158. package/lib/dependencies/RequireResolveHeaderDependency.js +26 -26
  159. package/lib/dependencies/SingleEntryDependency.js +18 -18
  160. package/lib/dependencies/SystemPlugin.js +44 -44
  161. package/lib/dependencies/UnsupportedDependency.js +23 -23
  162. package/lib/dependencies/WebpackMissingModule.js +18 -18
  163. package/lib/dependencies/getFunctionExpression.js +44 -44
  164. package/lib/formatLocation.js +54 -54
  165. package/lib/node/NodeChunkTemplatePlugin.js +27 -27
  166. package/lib/node/NodeEnvironmentPlugin.js +25 -25
  167. package/lib/node/NodeHotUpdateChunkTemplatePlugin.js +27 -27
  168. package/lib/node/NodeMainTemplate.runtime.js +24 -24
  169. package/lib/node/NodeMainTemplateAsync.runtime.js +40 -40
  170. package/lib/node/NodeOutputFileSystem.js +22 -22
  171. package/lib/node/NodeSourcePlugin.js +88 -88
  172. package/lib/node/NodeTargetPlugin.js +15 -15
  173. package/lib/node/NodeTemplatePlugin.js +27 -27
  174. package/lib/node/NodeWatchFileSystem.js +72 -72
  175. package/lib/optimize/ChunkModuleIdRangePlugin.js +53 -53
  176. package/lib/optimize/DedupePlugin.js +15 -15
  177. package/lib/optimize/FlagIncludedChunksPlugin.js +35 -35
  178. package/lib/optimize/LimitChunkCountPlugin.js +59 -59
  179. package/lib/optimize/MinChunkSizePlugin.js +65 -65
  180. package/lib/optimize/RemoveEmptyChunksPlugin.js +21 -21
  181. package/lib/optimize/UglifyJsPlugin.js +9 -9
  182. package/lib/performance/AssetsOverSizeLimitWarning.js +23 -23
  183. package/lib/performance/EntrypointsOverSizeLimitWarning.js +28 -28
  184. package/lib/performance/NoAsyncChunksWarning.js +20 -20
  185. package/lib/performance/SizeLimitsPlugin.js +102 -102
  186. package/lib/prepareOptions.js +29 -29
  187. package/lib/removeAndDo.js +15 -15
  188. package/lib/util/Semaphore.js +32 -32
  189. package/lib/util/identifier.js +38 -38
  190. package/lib/validateSchema.js +66 -66
  191. package/lib/web/WebEnvironmentPlugin.js +18 -18
  192. package/lib/webworker/WebWorkerChunkTemplatePlugin.js +29 -29
  193. package/lib/webworker/WebWorkerHotUpdateChunkTemplatePlugin.js +28 -28
  194. package/lib/webworker/WebWorkerMainTemplate.runtime.js +58 -58
  195. package/lib/webworker/WebWorkerTemplatePlugin.js +20 -20
  196. package/package.json +1 -1
  197. package/schemas/ajv.absolutePath.js +29 -29
  198. package/schemas/webpackOptionsSchema.json +16 -0
package/lib/RuleSet.js CHANGED
@@ -1,444 +1,444 @@
1
- /*
2
- MIT License http://www.opensource.org/licenses/mit-license.php
3
- Author Tobias Koppers @sokra
4
- */
5
- /*
6
- <rules>: <rule>
7
- <rules>: [<rule>]
8
- <rule>: {
9
- resource: {
10
- test: <condition>,
11
- include: <condition>,
12
- exclude: <condition>,
13
- },
14
- resource: <condition>, -> resource.test
15
- test: <condition>, -> resource.test
16
- include: <condition>, -> resource.include
17
- exclude: <condition>, -> resource.exclude
18
- resourceQuery: <condition>,
19
- compiler: <condition>,
20
- issuer: <condition>,
21
- use: "loader", -> use[0].loader
22
- loader: <>, -> use[0].loader
23
- loaders: <>, -> use
24
- options: {}, -> use[0].options,
25
- query: {}, -> options
26
- parser: {},
27
- use: [
28
- "loader" -> use[x].loader
29
- ],
30
- use: [
31
- {
32
- loader: "loader",
33
- options: {}
34
- }
35
- ],
36
- rules: [
37
- <rule>
38
- ],
39
- oneOf: [
40
- <rule>
41
- ]
42
- }
43
-
44
- <condition>: /regExp/
45
- <condition>: function(arg) {}
46
- <condition>: "starting"
47
- <condition>: [<condition>] // or
48
- <condition>: { and: [<condition>] }
49
- <condition>: { or: [<condition>] }
50
- <condition>: { not: [<condition>] }
51
- <condition>: { test: <condition>, include: <condition>, exclude: <condition> }
52
-
53
-
54
- normalized:
55
-
56
- {
57
- resource: function(),
58
- resourceQuery: function(),
59
- compiler: function(),
60
- issuer: function(),
61
- use: [
62
- {
63
- loader: string,
64
- options: string,
65
- <any>: <any>
66
- }
67
- ],
68
- rules: [<rule>],
69
- oneOf: [<rule>],
70
- <any>: <any>,
71
- }
72
-
73
- */
74
-
75
- "use strict";
76
-
77
- module.exports = class RuleSet {
78
- constructor(rules) {
79
- this.references = Object.create(null);
80
- this.rules = RuleSet.normalizeRules(rules, this.references, "ref-");
81
- }
82
-
83
- static normalizeRules(rules, refs, ident) {
84
- if(Array.isArray(rules)) {
85
- return rules.map((rule, idx) => {
86
- return RuleSet.normalizeRule(rule, refs, `${ident}-${idx}`);
87
- });
88
- } else if(rules) {
89
- return [RuleSet.normalizeRule(rules, refs, ident)];
90
- } else {
91
- return [];
92
- }
93
- }
94
-
95
- static normalizeRule(rule, refs, ident) {
96
- if(typeof rule === "string")
97
- return {
98
- use: [{
99
- loader: rule
100
- }]
101
- };
102
- if(!rule)
103
- throw new Error("Unexcepted null when object was expected as rule");
104
- if(typeof rule !== "object")
105
- throw new Error("Unexcepted " + typeof rule + " when object was expected as rule (" + rule + ")");
106
-
107
- const newRule = {};
108
- let useSource;
109
- let resourceSource;
110
- let condition;
111
-
112
- if(rule.test || rule.include || rule.exclude) {
113
- checkResourceSource("test + include + exclude");
114
- condition = {
115
- test: rule.test,
116
- include: rule.include,
117
- exclude: rule.exclude
118
- };
119
- try {
120
- newRule.resource = RuleSet.normalizeCondition(condition);
121
- } catch(error) {
122
- throw new Error(RuleSet.buildErrorMessage(condition, error));
123
- }
124
- }
125
-
126
- if(rule.resource) {
127
- checkResourceSource("resource");
128
- try {
129
- newRule.resource = RuleSet.normalizeCondition(rule.resource);
130
- } catch(error) {
131
- throw new Error(RuleSet.buildErrorMessage(rule.resource, error));
132
- }
133
- }
134
-
135
- if(rule.resourceQuery) {
136
- try {
137
- newRule.resourceQuery = RuleSet.normalizeCondition(rule.resourceQuery);
138
- } catch(error) {
139
- throw new Error(RuleSet.buildErrorMessage(rule.resourceQuery, error));
140
- }
141
- }
142
-
143
- if(rule.compiler) {
144
- try {
145
- newRule.compiler = RuleSet.normalizeCondition(rule.compiler);
146
- } catch(error) {
147
- throw new Error(RuleSet.buildErrorMessage(rule.compiler, error));
148
- }
149
- }
150
-
151
- if(rule.issuer) {
152
- try {
153
- newRule.issuer = RuleSet.normalizeCondition(rule.issuer);
154
- } catch(error) {
155
- throw new Error(RuleSet.buildErrorMessage(rule.issuer, error));
156
- }
157
- }
158
-
159
- if(rule.loader && rule.loaders)
160
- throw new Error(RuleSet.buildErrorMessage(rule, new Error("Provided loader and loaders for rule (use only one of them)")));
161
-
162
- const loader = rule.loaders || rule.loader;
163
- if(typeof loader === "string" && !rule.options && !rule.query) {
164
- checkUseSource("loader");
165
- newRule.use = RuleSet.normalizeUse(loader.split("!"), ident);
166
- } else if(typeof loader === "string" && (rule.options || rule.query)) {
167
- checkUseSource("loader + options/query");
168
- newRule.use = RuleSet.normalizeUse({
169
- loader: loader,
170
- options: rule.options,
171
- query: rule.query
172
- }, ident);
173
- } else if(loader && (rule.options || rule.query)) {
174
- throw new Error(RuleSet.buildErrorMessage(rule, new Error("options/query cannot be used with loaders (use options for each array item)")));
175
- } else if(loader) {
176
- checkUseSource("loaders");
177
- newRule.use = RuleSet.normalizeUse(loader, ident);
178
- } else if(rule.options || rule.query) {
179
- throw new Error(RuleSet.buildErrorMessage(rule, new Error("options/query provided without loader (use loader + options)")));
180
- }
181
-
182
- if(rule.use) {
183
- checkUseSource("use");
184
- newRule.use = RuleSet.normalizeUse(rule.use, ident);
185
- }
186
-
187
- if(rule.rules)
188
- newRule.rules = RuleSet.normalizeRules(rule.rules, refs, `${ident}-rules`);
189
-
190
- if(rule.oneOf)
191
- newRule.oneOf = RuleSet.normalizeRules(rule.oneOf, refs, `${ident}-oneOf`);
192
-
193
- const keys = Object.keys(rule).filter((key) => {
194
- return ["resource", "resourceQuery", "compiler", "test", "include", "exclude", "issuer", "loader", "options", "query", "loaders", "use", "rules", "oneOf"].indexOf(key) < 0;
195
- });
196
- keys.forEach((key) => {
197
- newRule[key] = rule[key];
198
- });
199
-
200
- function checkUseSource(newSource) {
201
- if(useSource && useSource !== newSource)
202
- throw new Error(RuleSet.buildErrorMessage(rule, new Error("Rule can only have one result source (provided " + newSource + " and " + useSource + ")")));
203
- useSource = newSource;
204
- }
205
-
206
- function checkResourceSource(newSource) {
207
- if(resourceSource && resourceSource !== newSource)
208
- throw new Error(RuleSet.buildErrorMessage(rule, new Error("Rule can only have one resource source (provided " + newSource + " and " + resourceSource + ")")));
209
- resourceSource = newSource;
210
- }
211
-
212
- if(Array.isArray(newRule.use)) {
213
- newRule.use.forEach((item) => {
214
- if(item.ident) {
215
- refs[item.ident] = item.options;
216
- }
217
- });
218
- }
219
-
220
- return newRule;
221
- }
222
-
223
- static buildErrorMessage(condition, error) {
224
- const conditionAsText = JSON.stringify(condition, (key, value) => {
225
- return value === undefined ? "undefined" : value;
226
- }, 2);
227
- return error.message + " in " + conditionAsText;
228
- }
229
-
230
- static normalizeUse(use, ident) {
231
- if(Array.isArray(use)) {
232
- return use
233
- .map((item, idx) => RuleSet.normalizeUse(item, `${ident}-${idx}`))
234
- .reduce((arr, items) => arr.concat(items), []);
235
- }
236
- return [RuleSet.normalizeUseItem(use, ident)];
237
- }
238
-
239
- static normalizeUseItemFunction(use, data) {
240
- const result = use(data);
241
- if(typeof result === "string") {
242
- return RuleSet.normalizeUseItem(result);
243
- }
244
- return result;
245
- }
246
-
247
- static normalizeUseItemString(useItemString) {
248
- const idx = useItemString.indexOf("?");
249
- if(idx >= 0) {
250
- return {
251
- loader: useItemString.substr(0, idx),
252
- options: useItemString.substr(idx + 1)
253
- };
254
- }
255
- return {
256
- loader: useItemString
257
- };
258
- }
259
-
260
- static normalizeUseItem(item, ident) {
261
- if(typeof item === "function")
262
- return item;
263
-
264
- if(typeof item === "string") {
265
- return RuleSet.normalizeUseItemString(item);
266
- }
267
-
268
- const newItem = {};
269
-
270
- if(item.options && item.query)
271
- throw new Error("Provided options and query in use");
272
-
273
- if(!item.loader)
274
- throw new Error("No loader specified");
275
-
276
- newItem.options = item.options || item.query;
277
-
278
- if(typeof newItem.options === "object" && newItem.options) {
279
- if(newItem.options.ident)
280
- newItem.ident = newItem.options.ident;
281
- else
282
- newItem.ident = ident;
283
- }
284
-
285
- const keys = Object.keys(item).filter(function(key) {
286
- return ["options", "query"].indexOf(key) < 0;
287
- });
288
-
289
- keys.forEach(function(key) {
290
- newItem[key] = item[key];
291
- });
292
-
293
- return newItem;
294
- }
295
-
296
- static normalizeCondition(condition) {
297
- if(!condition)
298
- throw new Error("Expected condition but got falsy value");
299
- if(typeof condition === "string") {
300
- return str => str.indexOf(condition) === 0;
301
- }
302
- if(typeof condition === "function") {
303
- return condition;
304
- }
305
- if(condition instanceof RegExp) {
306
- return condition.test.bind(condition);
307
- }
308
- if(Array.isArray(condition)) {
309
- const items = condition.map(c => RuleSet.normalizeCondition(c));
310
- return orMatcher(items);
311
- }
312
- if(typeof condition !== "object")
313
- throw Error("Unexcepted " + typeof condition + " when condition was expected (" + condition + ")");
314
-
315
- const matchers = [];
316
- Object.keys(condition).forEach(key => {
317
- const value = condition[key];
318
- switch(key) {
319
- case "or":
320
- case "include":
321
- case "test":
322
- if(value)
323
- matchers.push(RuleSet.normalizeCondition(value));
324
- break;
325
- case "and":
326
- if(value) {
327
- const items = value.map(c => RuleSet.normalizeCondition(c));
328
- matchers.push(andMatcher(items));
329
- }
330
- break;
331
- case "not":
332
- case "exclude":
333
- if(value) {
334
- const matcher = RuleSet.normalizeCondition(value);
335
- matchers.push(notMatcher(matcher));
336
- }
337
- break;
338
- default:
339
- throw new Error("Unexcepted property " + key + " in condition");
340
- }
341
- });
342
- if(matchers.length === 0)
343
- throw new Error("Excepted condition but got " + condition);
344
- if(matchers.length === 1)
345
- return matchers[0];
346
- return andMatcher(matchers);
347
- }
348
-
349
- exec(data) {
350
- const result = [];
351
- this._run(data, {
352
- rules: this.rules
353
- }, result);
354
- return result;
355
- }
356
-
357
- _run(data, rule, result) {
358
- // test conditions
359
- if(rule.resource && !data.resource)
360
- return false;
361
- if(rule.resourceQuery && !data.resourceQuery)
362
- return false;
363
- if(rule.compiler && !data.compiler)
364
- return false;
365
- if(rule.issuer && !data.issuer)
366
- return false;
367
- if(rule.resource && !rule.resource(data.resource))
368
- return false;
369
- if(data.issuer && rule.issuer && !rule.issuer(data.issuer))
370
- return false;
371
- if(data.resourceQuery && rule.resourceQuery && !rule.resourceQuery(data.resourceQuery))
372
- return false;
373
- if(data.compiler && rule.compiler && !rule.compiler(data.compiler))
374
- return false;
375
-
376
- // apply
377
- const keys = Object.keys(rule).filter((key) => {
378
- return ["resource", "resourceQuery", "compiler", "issuer", "rules", "oneOf", "use", "enforce"].indexOf(key) < 0;
379
- });
380
- keys.forEach((key) => {
381
- result.push({
382
- type: key,
383
- value: rule[key]
384
- });
385
- });
386
-
387
- if(rule.use) {
388
- rule.use.forEach((use) => {
389
- result.push({
390
- type: "use",
391
- value: typeof use === "function" ? RuleSet.normalizeUseItemFunction(use, data) : use,
392
- enforce: rule.enforce
393
- });
394
- });
395
- }
396
-
397
- if(rule.rules) {
398
- for(let i = 0; i < rule.rules.length; i++) {
399
- this._run(data, rule.rules[i], result);
400
- }
401
- }
402
-
403
- if(rule.oneOf) {
404
- for(let i = 0; i < rule.oneOf.length; i++) {
405
- if(this._run(data, rule.oneOf[i], result))
406
- break;
407
- }
408
- }
409
-
410
- return true;
411
- }
412
-
413
- findOptionsByIdent(ident) {
414
- const options = this.references[ident];
415
- if(!options) throw new Error("Can't find options with ident '" + ident + "'");
416
- return options;
417
- }
418
- };
419
-
420
- function notMatcher(matcher) {
421
- return function(str) {
422
- return !matcher(str);
423
- };
424
- }
425
-
426
- function orMatcher(items) {
427
- return function(str) {
428
- for(let i = 0; i < items.length; i++) {
429
- if(items[i](str))
430
- return true;
431
- }
432
- return false;
433
- };
434
- }
435
-
436
- function andMatcher(items) {
437
- return function(str) {
438
- for(let i = 0; i < items.length; i++) {
439
- if(!items[i](str))
440
- return false;
441
- }
442
- return true;
443
- };
444
- }
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+ /*
6
+ <rules>: <rule>
7
+ <rules>: [<rule>]
8
+ <rule>: {
9
+ resource: {
10
+ test: <condition>,
11
+ include: <condition>,
12
+ exclude: <condition>,
13
+ },
14
+ resource: <condition>, -> resource.test
15
+ test: <condition>, -> resource.test
16
+ include: <condition>, -> resource.include
17
+ exclude: <condition>, -> resource.exclude
18
+ resourceQuery: <condition>,
19
+ compiler: <condition>,
20
+ issuer: <condition>,
21
+ use: "loader", -> use[0].loader
22
+ loader: <>, -> use[0].loader
23
+ loaders: <>, -> use
24
+ options: {}, -> use[0].options,
25
+ query: {}, -> options
26
+ parser: {},
27
+ use: [
28
+ "loader" -> use[x].loader
29
+ ],
30
+ use: [
31
+ {
32
+ loader: "loader",
33
+ options: {}
34
+ }
35
+ ],
36
+ rules: [
37
+ <rule>
38
+ ],
39
+ oneOf: [
40
+ <rule>
41
+ ]
42
+ }
43
+
44
+ <condition>: /regExp/
45
+ <condition>: function(arg) {}
46
+ <condition>: "starting"
47
+ <condition>: [<condition>] // or
48
+ <condition>: { and: [<condition>] }
49
+ <condition>: { or: [<condition>] }
50
+ <condition>: { not: [<condition>] }
51
+ <condition>: { test: <condition>, include: <condition>, exclude: <condition> }
52
+
53
+
54
+ normalized:
55
+
56
+ {
57
+ resource: function(),
58
+ resourceQuery: function(),
59
+ compiler: function(),
60
+ issuer: function(),
61
+ use: [
62
+ {
63
+ loader: string,
64
+ options: string,
65
+ <any>: <any>
66
+ }
67
+ ],
68
+ rules: [<rule>],
69
+ oneOf: [<rule>],
70
+ <any>: <any>,
71
+ }
72
+
73
+ */
74
+
75
+ "use strict";
76
+
77
+ module.exports = class RuleSet {
78
+ constructor(rules) {
79
+ this.references = Object.create(null);
80
+ this.rules = RuleSet.normalizeRules(rules, this.references, "ref-");
81
+ }
82
+
83
+ static normalizeRules(rules, refs, ident) {
84
+ if(Array.isArray(rules)) {
85
+ return rules.map((rule, idx) => {
86
+ return RuleSet.normalizeRule(rule, refs, `${ident}-${idx}`);
87
+ });
88
+ } else if(rules) {
89
+ return [RuleSet.normalizeRule(rules, refs, ident)];
90
+ } else {
91
+ return [];
92
+ }
93
+ }
94
+
95
+ static normalizeRule(rule, refs, ident) {
96
+ if(typeof rule === "string")
97
+ return {
98
+ use: [{
99
+ loader: rule
100
+ }]
101
+ };
102
+ if(!rule)
103
+ throw new Error("Unexcepted null when object was expected as rule");
104
+ if(typeof rule !== "object")
105
+ throw new Error("Unexcepted " + typeof rule + " when object was expected as rule (" + rule + ")");
106
+
107
+ const newRule = {};
108
+ let useSource;
109
+ let resourceSource;
110
+ let condition;
111
+
112
+ if(rule.test || rule.include || rule.exclude) {
113
+ checkResourceSource("test + include + exclude");
114
+ condition = {
115
+ test: rule.test,
116
+ include: rule.include,
117
+ exclude: rule.exclude
118
+ };
119
+ try {
120
+ newRule.resource = RuleSet.normalizeCondition(condition);
121
+ } catch(error) {
122
+ throw new Error(RuleSet.buildErrorMessage(condition, error));
123
+ }
124
+ }
125
+
126
+ if(rule.resource) {
127
+ checkResourceSource("resource");
128
+ try {
129
+ newRule.resource = RuleSet.normalizeCondition(rule.resource);
130
+ } catch(error) {
131
+ throw new Error(RuleSet.buildErrorMessage(rule.resource, error));
132
+ }
133
+ }
134
+
135
+ if(rule.resourceQuery) {
136
+ try {
137
+ newRule.resourceQuery = RuleSet.normalizeCondition(rule.resourceQuery);
138
+ } catch(error) {
139
+ throw new Error(RuleSet.buildErrorMessage(rule.resourceQuery, error));
140
+ }
141
+ }
142
+
143
+ if(rule.compiler) {
144
+ try {
145
+ newRule.compiler = RuleSet.normalizeCondition(rule.compiler);
146
+ } catch(error) {
147
+ throw new Error(RuleSet.buildErrorMessage(rule.compiler, error));
148
+ }
149
+ }
150
+
151
+ if(rule.issuer) {
152
+ try {
153
+ newRule.issuer = RuleSet.normalizeCondition(rule.issuer);
154
+ } catch(error) {
155
+ throw new Error(RuleSet.buildErrorMessage(rule.issuer, error));
156
+ }
157
+ }
158
+
159
+ if(rule.loader && rule.loaders)
160
+ throw new Error(RuleSet.buildErrorMessage(rule, new Error("Provided loader and loaders for rule (use only one of them)")));
161
+
162
+ const loader = rule.loaders || rule.loader;
163
+ if(typeof loader === "string" && !rule.options && !rule.query) {
164
+ checkUseSource("loader");
165
+ newRule.use = RuleSet.normalizeUse(loader.split("!"), ident);
166
+ } else if(typeof loader === "string" && (rule.options || rule.query)) {
167
+ checkUseSource("loader + options/query");
168
+ newRule.use = RuleSet.normalizeUse({
169
+ loader: loader,
170
+ options: rule.options,
171
+ query: rule.query
172
+ }, ident);
173
+ } else if(loader && (rule.options || rule.query)) {
174
+ throw new Error(RuleSet.buildErrorMessage(rule, new Error("options/query cannot be used with loaders (use options for each array item)")));
175
+ } else if(loader) {
176
+ checkUseSource("loaders");
177
+ newRule.use = RuleSet.normalizeUse(loader, ident);
178
+ } else if(rule.options || rule.query) {
179
+ throw new Error(RuleSet.buildErrorMessage(rule, new Error("options/query provided without loader (use loader + options)")));
180
+ }
181
+
182
+ if(rule.use) {
183
+ checkUseSource("use");
184
+ newRule.use = RuleSet.normalizeUse(rule.use, ident);
185
+ }
186
+
187
+ if(rule.rules)
188
+ newRule.rules = RuleSet.normalizeRules(rule.rules, refs, `${ident}-rules`);
189
+
190
+ if(rule.oneOf)
191
+ newRule.oneOf = RuleSet.normalizeRules(rule.oneOf, refs, `${ident}-oneOf`);
192
+
193
+ const keys = Object.keys(rule).filter((key) => {
194
+ return ["resource", "resourceQuery", "compiler", "test", "include", "exclude", "issuer", "loader", "options", "query", "loaders", "use", "rules", "oneOf"].indexOf(key) < 0;
195
+ });
196
+ keys.forEach((key) => {
197
+ newRule[key] = rule[key];
198
+ });
199
+
200
+ function checkUseSource(newSource) {
201
+ if(useSource && useSource !== newSource)
202
+ throw new Error(RuleSet.buildErrorMessage(rule, new Error("Rule can only have one result source (provided " + newSource + " and " + useSource + ")")));
203
+ useSource = newSource;
204
+ }
205
+
206
+ function checkResourceSource(newSource) {
207
+ if(resourceSource && resourceSource !== newSource)
208
+ throw new Error(RuleSet.buildErrorMessage(rule, new Error("Rule can only have one resource source (provided " + newSource + " and " + resourceSource + ")")));
209
+ resourceSource = newSource;
210
+ }
211
+
212
+ if(Array.isArray(newRule.use)) {
213
+ newRule.use.forEach((item) => {
214
+ if(item.ident) {
215
+ refs[item.ident] = item.options;
216
+ }
217
+ });
218
+ }
219
+
220
+ return newRule;
221
+ }
222
+
223
+ static buildErrorMessage(condition, error) {
224
+ const conditionAsText = JSON.stringify(condition, (key, value) => {
225
+ return value === undefined ? "undefined" : value;
226
+ }, 2);
227
+ return error.message + " in " + conditionAsText;
228
+ }
229
+
230
+ static normalizeUse(use, ident) {
231
+ if(Array.isArray(use)) {
232
+ return use
233
+ .map((item, idx) => RuleSet.normalizeUse(item, `${ident}-${idx}`))
234
+ .reduce((arr, items) => arr.concat(items), []);
235
+ }
236
+ return [RuleSet.normalizeUseItem(use, ident)];
237
+ }
238
+
239
+ static normalizeUseItemFunction(use, data) {
240
+ const result = use(data);
241
+ if(typeof result === "string") {
242
+ return RuleSet.normalizeUseItem(result);
243
+ }
244
+ return result;
245
+ }
246
+
247
+ static normalizeUseItemString(useItemString) {
248
+ const idx = useItemString.indexOf("?");
249
+ if(idx >= 0) {
250
+ return {
251
+ loader: useItemString.substr(0, idx),
252
+ options: useItemString.substr(idx + 1)
253
+ };
254
+ }
255
+ return {
256
+ loader: useItemString
257
+ };
258
+ }
259
+
260
+ static normalizeUseItem(item, ident) {
261
+ if(typeof item === "function")
262
+ return item;
263
+
264
+ if(typeof item === "string") {
265
+ return RuleSet.normalizeUseItemString(item);
266
+ }
267
+
268
+ const newItem = {};
269
+
270
+ if(item.options && item.query)
271
+ throw new Error("Provided options and query in use");
272
+
273
+ if(!item.loader)
274
+ throw new Error("No loader specified");
275
+
276
+ newItem.options = item.options || item.query;
277
+
278
+ if(typeof newItem.options === "object" && newItem.options) {
279
+ if(newItem.options.ident)
280
+ newItem.ident = newItem.options.ident;
281
+ else
282
+ newItem.ident = ident;
283
+ }
284
+
285
+ const keys = Object.keys(item).filter(function(key) {
286
+ return ["options", "query"].indexOf(key) < 0;
287
+ });
288
+
289
+ keys.forEach(function(key) {
290
+ newItem[key] = item[key];
291
+ });
292
+
293
+ return newItem;
294
+ }
295
+
296
+ static normalizeCondition(condition) {
297
+ if(!condition)
298
+ throw new Error("Expected condition but got falsy value");
299
+ if(typeof condition === "string") {
300
+ return str => str.indexOf(condition) === 0;
301
+ }
302
+ if(typeof condition === "function") {
303
+ return condition;
304
+ }
305
+ if(condition instanceof RegExp) {
306
+ return condition.test.bind(condition);
307
+ }
308
+ if(Array.isArray(condition)) {
309
+ const items = condition.map(c => RuleSet.normalizeCondition(c));
310
+ return orMatcher(items);
311
+ }
312
+ if(typeof condition !== "object")
313
+ throw Error("Unexcepted " + typeof condition + " when condition was expected (" + condition + ")");
314
+
315
+ const matchers = [];
316
+ Object.keys(condition).forEach(key => {
317
+ const value = condition[key];
318
+ switch(key) {
319
+ case "or":
320
+ case "include":
321
+ case "test":
322
+ if(value)
323
+ matchers.push(RuleSet.normalizeCondition(value));
324
+ break;
325
+ case "and":
326
+ if(value) {
327
+ const items = value.map(c => RuleSet.normalizeCondition(c));
328
+ matchers.push(andMatcher(items));
329
+ }
330
+ break;
331
+ case "not":
332
+ case "exclude":
333
+ if(value) {
334
+ const matcher = RuleSet.normalizeCondition(value);
335
+ matchers.push(notMatcher(matcher));
336
+ }
337
+ break;
338
+ default:
339
+ throw new Error("Unexcepted property " + key + " in condition");
340
+ }
341
+ });
342
+ if(matchers.length === 0)
343
+ throw new Error("Excepted condition but got " + condition);
344
+ if(matchers.length === 1)
345
+ return matchers[0];
346
+ return andMatcher(matchers);
347
+ }
348
+
349
+ exec(data) {
350
+ const result = [];
351
+ this._run(data, {
352
+ rules: this.rules
353
+ }, result);
354
+ return result;
355
+ }
356
+
357
+ _run(data, rule, result) {
358
+ // test conditions
359
+ if(rule.resource && !data.resource)
360
+ return false;
361
+ if(rule.resourceQuery && !data.resourceQuery)
362
+ return false;
363
+ if(rule.compiler && !data.compiler)
364
+ return false;
365
+ if(rule.issuer && !data.issuer)
366
+ return false;
367
+ if(rule.resource && !rule.resource(data.resource))
368
+ return false;
369
+ if(data.issuer && rule.issuer && !rule.issuer(data.issuer))
370
+ return false;
371
+ if(data.resourceQuery && rule.resourceQuery && !rule.resourceQuery(data.resourceQuery))
372
+ return false;
373
+ if(data.compiler && rule.compiler && !rule.compiler(data.compiler))
374
+ return false;
375
+
376
+ // apply
377
+ const keys = Object.keys(rule).filter((key) => {
378
+ return ["resource", "resourceQuery", "compiler", "issuer", "rules", "oneOf", "use", "enforce"].indexOf(key) < 0;
379
+ });
380
+ keys.forEach((key) => {
381
+ result.push({
382
+ type: key,
383
+ value: rule[key]
384
+ });
385
+ });
386
+
387
+ if(rule.use) {
388
+ rule.use.forEach((use) => {
389
+ result.push({
390
+ type: "use",
391
+ value: typeof use === "function" ? RuleSet.normalizeUseItemFunction(use, data) : use,
392
+ enforce: rule.enforce
393
+ });
394
+ });
395
+ }
396
+
397
+ if(rule.rules) {
398
+ for(let i = 0; i < rule.rules.length; i++) {
399
+ this._run(data, rule.rules[i], result);
400
+ }
401
+ }
402
+
403
+ if(rule.oneOf) {
404
+ for(let i = 0; i < rule.oneOf.length; i++) {
405
+ if(this._run(data, rule.oneOf[i], result))
406
+ break;
407
+ }
408
+ }
409
+
410
+ return true;
411
+ }
412
+
413
+ findOptionsByIdent(ident) {
414
+ const options = this.references[ident];
415
+ if(!options) throw new Error("Can't find options with ident '" + ident + "'");
416
+ return options;
417
+ }
418
+ };
419
+
420
+ function notMatcher(matcher) {
421
+ return function(str) {
422
+ return !matcher(str);
423
+ };
424
+ }
425
+
426
+ function orMatcher(items) {
427
+ return function(str) {
428
+ for(let i = 0; i < items.length; i++) {
429
+ if(items[i](str))
430
+ return true;
431
+ }
432
+ return false;
433
+ };
434
+ }
435
+
436
+ function andMatcher(items) {
437
+ return function(str) {
438
+ for(let i = 0; i < items.length; i++) {
439
+ if(!items[i](str))
440
+ return false;
441
+ }
442
+ return true;
443
+ };
444
+ }