@dineroregnskab/eslint-plugin-custom-rules 2.0.5 → 2.0.6

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 (174) hide show
  1. package/node_modules/@aashutoshrathi/word-wrap/LICENSE +21 -0
  2. package/node_modules/@aashutoshrathi/word-wrap/README.md +182 -0
  3. package/node_modules/@aashutoshrathi/word-wrap/index.d.ts +50 -0
  4. package/node_modules/@aashutoshrathi/word-wrap/index.js +52 -0
  5. package/node_modules/@aashutoshrathi/word-wrap/package.json +81 -0
  6. package/node_modules/@angular-eslint/bundled-angular-compiler/README.md +1 -0
  7. package/node_modules/@angular-eslint/bundled-angular-compiler/dist/index.d.ts +5 -0
  8. package/node_modules/@angular-eslint/bundled-angular-compiler/dist/index.js +32004 -0
  9. package/node_modules/@angular-eslint/bundled-angular-compiler/package.json +19 -0
  10. package/node_modules/@angular-eslint/template-parser/LICENSE +21 -0
  11. package/node_modules/@angular-eslint/template-parser/README.md +1 -0
  12. package/node_modules/@angular-eslint/template-parser/dist/convert-source-span-to-loc.d.ts +6 -0
  13. package/node_modules/@angular-eslint/template-parser/dist/convert-source-span-to-loc.js +69 -0
  14. package/node_modules/@angular-eslint/template-parser/dist/index.d.ts +44 -0
  15. package/node_modules/@angular-eslint/template-parser/dist/index.js +219 -0
  16. package/node_modules/@angular-eslint/template-parser/package.json +28 -0
  17. package/node_modules/@eslint/eslintrc/LICENSE +19 -0
  18. package/node_modules/@eslint/eslintrc/README.md +115 -0
  19. package/node_modules/@eslint/eslintrc/conf/config-schema.js +79 -0
  20. package/node_modules/@eslint/eslintrc/conf/environments.js +215 -0
  21. package/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs +1104 -0
  22. package/node_modules/@eslint/eslintrc/dist/eslintrc-universal.cjs.map +1 -0
  23. package/node_modules/@eslint/eslintrc/dist/eslintrc.cjs +4333 -0
  24. package/node_modules/@eslint/eslintrc/dist/eslintrc.cjs.map +1 -0
  25. package/node_modules/@eslint/eslintrc/lib/cascading-config-array-factory.js +532 -0
  26. package/node_modules/@eslint/eslintrc/lib/config-array/config-array.js +523 -0
  27. package/node_modules/@eslint/eslintrc/lib/config-array/config-dependency.js +115 -0
  28. package/node_modules/@eslint/eslintrc/lib/config-array/extracted-config.js +145 -0
  29. package/node_modules/@eslint/eslintrc/lib/config-array/ignore-pattern.js +238 -0
  30. package/node_modules/@eslint/eslintrc/lib/config-array/index.js +19 -0
  31. package/node_modules/@eslint/eslintrc/lib/config-array/override-tester.js +225 -0
  32. package/node_modules/@eslint/eslintrc/lib/config-array-factory.js +1149 -0
  33. package/node_modules/@eslint/eslintrc/lib/flat-compat.js +318 -0
  34. package/node_modules/@eslint/eslintrc/lib/index-universal.js +29 -0
  35. package/node_modules/@eslint/eslintrc/lib/index.js +56 -0
  36. package/node_modules/@eslint/eslintrc/lib/shared/ajv.js +191 -0
  37. package/node_modules/@eslint/eslintrc/lib/shared/config-ops.js +135 -0
  38. package/node_modules/@eslint/eslintrc/lib/shared/config-validator.js +325 -0
  39. package/node_modules/@eslint/eslintrc/lib/shared/deprecation-warnings.js +63 -0
  40. package/node_modules/@eslint/eslintrc/lib/shared/naming.js +96 -0
  41. package/node_modules/@eslint/eslintrc/lib/shared/relative-module-resolver.js +42 -0
  42. package/node_modules/@eslint/eslintrc/lib/shared/types.js +149 -0
  43. package/node_modules/@eslint/eslintrc/package.json +82 -0
  44. package/node_modules/@eslint/eslintrc/universal.js +9 -0
  45. package/node_modules/@eslint/js/LICENSE +19 -0
  46. package/node_modules/@eslint/js/README.md +57 -0
  47. package/node_modules/@eslint/js/package.json +31 -0
  48. package/node_modules/@eslint/js/src/configs/eslint-all.js +211 -0
  49. package/node_modules/@eslint/js/src/configs/eslint-recommended.js +76 -0
  50. package/node_modules/@eslint/js/src/index.js +17 -0
  51. package/node_modules/@eslint-community/eslint-utils/LICENSE +21 -0
  52. package/node_modules/@eslint-community/eslint-utils/README.md +37 -0
  53. package/node_modules/@eslint-community/eslint-utils/index.js +2068 -0
  54. package/node_modules/@eslint-community/eslint-utils/index.js.map +1 -0
  55. package/node_modules/@eslint-community/eslint-utils/index.mjs +2027 -0
  56. package/node_modules/@eslint-community/eslint-utils/index.mjs.map +1 -0
  57. package/node_modules/@eslint-community/eslint-utils/package.json +73 -0
  58. package/node_modules/@eslint-community/regexpp/LICENSE +21 -0
  59. package/node_modules/@eslint-community/regexpp/README.md +177 -0
  60. package/node_modules/@eslint-community/regexpp/index.d.ts +1065 -0
  61. package/node_modules/@eslint-community/regexpp/index.js +2747 -0
  62. package/node_modules/@eslint-community/regexpp/index.js.map +1 -0
  63. package/node_modules/@eslint-community/regexpp/index.mjs +2737 -0
  64. package/node_modules/@eslint-community/regexpp/index.mjs.map +1 -0
  65. package/node_modules/@eslint-community/regexpp/package.json +93 -0
  66. package/node_modules/@humanwhocodes/config-array/LICENSE +201 -0
  67. package/node_modules/@humanwhocodes/config-array/README.md +342 -0
  68. package/node_modules/@humanwhocodes/config-array/api.js +1061 -0
  69. package/node_modules/@humanwhocodes/config-array/package.json +61 -0
  70. package/node_modules/@humanwhocodes/module-importer/CHANGELOG.md +15 -0
  71. package/node_modules/@humanwhocodes/module-importer/LICENSE +201 -0
  72. package/node_modules/@humanwhocodes/module-importer/README.md +80 -0
  73. package/node_modules/@humanwhocodes/module-importer/dist/module-importer.cjs +22 -0
  74. package/node_modules/@humanwhocodes/module-importer/dist/module-importer.d.cts +27 -0
  75. package/node_modules/@humanwhocodes/module-importer/dist/module-importer.d.ts +2 -0
  76. package/node_modules/@humanwhocodes/module-importer/dist/module-importer.js +18 -0
  77. package/node_modules/@humanwhocodes/module-importer/package.json +65 -0
  78. package/node_modules/@humanwhocodes/module-importer/src/module-importer.cjs +81 -0
  79. package/node_modules/@humanwhocodes/module-importer/src/module-importer.js +22 -0
  80. package/node_modules/@humanwhocodes/object-schema/.eslintrc.js +29 -0
  81. package/node_modules/@humanwhocodes/object-schema/.github/workflows/nodejs-test.yml +27 -0
  82. package/node_modules/@humanwhocodes/object-schema/.github/workflows/release-please.yml +39 -0
  83. package/node_modules/@humanwhocodes/object-schema/CHANGELOG.md +26 -0
  84. package/node_modules/@humanwhocodes/object-schema/LICENSE +29 -0
  85. package/node_modules/@humanwhocodes/object-schema/README.md +234 -0
  86. package/node_modules/@humanwhocodes/object-schema/package.json +33 -0
  87. package/node_modules/@humanwhocodes/object-schema/src/index.js +7 -0
  88. package/node_modules/@humanwhocodes/object-schema/src/merge-strategy.js +53 -0
  89. package/node_modules/@humanwhocodes/object-schema/src/object-schema.js +301 -0
  90. package/node_modules/@humanwhocodes/object-schema/src/validation-strategy.js +102 -0
  91. package/node_modules/@humanwhocodes/object-schema/tests/merge-strategy.js +66 -0
  92. package/node_modules/@humanwhocodes/object-schema/tests/object-schema.js +659 -0
  93. package/node_modules/@humanwhocodes/object-schema/tests/validation-strategy.js +186 -0
  94. package/node_modules/@nodelib/fs.scandir/LICENSE +21 -0
  95. package/node_modules/@nodelib/fs.scandir/README.md +171 -0
  96. package/node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts +20 -0
  97. package/node_modules/@nodelib/fs.scandir/out/adapters/fs.js +19 -0
  98. package/node_modules/@nodelib/fs.scandir/out/constants.d.ts +4 -0
  99. package/node_modules/@nodelib/fs.scandir/out/constants.js +17 -0
  100. package/node_modules/@nodelib/fs.scandir/out/index.d.ts +12 -0
  101. package/node_modules/@nodelib/fs.scandir/out/index.js +26 -0
  102. package/node_modules/@nodelib/fs.scandir/out/providers/async.d.ts +7 -0
  103. package/node_modules/@nodelib/fs.scandir/out/providers/async.js +104 -0
  104. package/node_modules/@nodelib/fs.scandir/out/providers/common.d.ts +1 -0
  105. package/node_modules/@nodelib/fs.scandir/out/providers/common.js +13 -0
  106. package/node_modules/@nodelib/fs.scandir/out/providers/sync.d.ts +5 -0
  107. package/node_modules/@nodelib/fs.scandir/out/providers/sync.js +54 -0
  108. package/node_modules/@nodelib/fs.scandir/out/settings.d.ts +20 -0
  109. package/node_modules/@nodelib/fs.scandir/out/settings.js +24 -0
  110. package/node_modules/@nodelib/fs.scandir/out/types/index.d.ts +20 -0
  111. package/node_modules/@nodelib/fs.scandir/out/types/index.js +2 -0
  112. package/node_modules/@nodelib/fs.scandir/out/utils/fs.d.ts +2 -0
  113. package/node_modules/@nodelib/fs.scandir/out/utils/fs.js +19 -0
  114. package/node_modules/@nodelib/fs.scandir/out/utils/index.d.ts +2 -0
  115. package/node_modules/@nodelib/fs.scandir/out/utils/index.js +5 -0
  116. package/node_modules/@nodelib/fs.scandir/package.json +44 -0
  117. package/node_modules/@nodelib/fs.stat/LICENSE +21 -0
  118. package/node_modules/@nodelib/fs.stat/README.md +126 -0
  119. package/node_modules/@nodelib/fs.stat/out/adapters/fs.d.ts +13 -0
  120. package/node_modules/@nodelib/fs.stat/out/adapters/fs.js +17 -0
  121. package/node_modules/@nodelib/fs.stat/out/index.d.ts +12 -0
  122. package/node_modules/@nodelib/fs.stat/out/index.js +26 -0
  123. package/node_modules/@nodelib/fs.stat/out/providers/async.d.ts +4 -0
  124. package/node_modules/@nodelib/fs.stat/out/providers/async.js +36 -0
  125. package/node_modules/@nodelib/fs.stat/out/providers/sync.d.ts +3 -0
  126. package/node_modules/@nodelib/fs.stat/out/providers/sync.js +23 -0
  127. package/node_modules/@nodelib/fs.stat/out/settings.d.ts +16 -0
  128. package/node_modules/@nodelib/fs.stat/out/settings.js +16 -0
  129. package/node_modules/@nodelib/fs.stat/out/types/index.d.ts +4 -0
  130. package/node_modules/@nodelib/fs.stat/out/types/index.js +2 -0
  131. package/node_modules/@nodelib/fs.stat/package.json +37 -0
  132. package/node_modules/@nodelib/fs.walk/LICENSE +21 -0
  133. package/node_modules/@nodelib/fs.walk/README.md +215 -0
  134. package/node_modules/@nodelib/fs.walk/out/index.d.ts +14 -0
  135. package/node_modules/@nodelib/fs.walk/out/index.js +34 -0
  136. package/node_modules/@nodelib/fs.walk/out/providers/async.d.ts +12 -0
  137. package/node_modules/@nodelib/fs.walk/out/providers/async.js +30 -0
  138. package/node_modules/@nodelib/fs.walk/out/providers/index.d.ts +4 -0
  139. package/node_modules/@nodelib/fs.walk/out/providers/index.js +9 -0
  140. package/node_modules/@nodelib/fs.walk/out/providers/stream.d.ts +12 -0
  141. package/node_modules/@nodelib/fs.walk/out/providers/stream.js +34 -0
  142. package/node_modules/@nodelib/fs.walk/out/providers/sync.d.ts +10 -0
  143. package/node_modules/@nodelib/fs.walk/out/providers/sync.js +14 -0
  144. package/node_modules/@nodelib/fs.walk/out/readers/async.d.ts +30 -0
  145. package/node_modules/@nodelib/fs.walk/out/readers/async.js +97 -0
  146. package/node_modules/@nodelib/fs.walk/out/readers/common.d.ts +7 -0
  147. package/node_modules/@nodelib/fs.walk/out/readers/common.js +31 -0
  148. package/node_modules/@nodelib/fs.walk/out/readers/reader.d.ts +6 -0
  149. package/node_modules/@nodelib/fs.walk/out/readers/reader.js +11 -0
  150. package/node_modules/@nodelib/fs.walk/out/readers/sync.d.ts +15 -0
  151. package/node_modules/@nodelib/fs.walk/out/readers/sync.js +59 -0
  152. package/node_modules/@nodelib/fs.walk/out/settings.d.ts +30 -0
  153. package/node_modules/@nodelib/fs.walk/out/settings.js +26 -0
  154. package/node_modules/@nodelib/fs.walk/out/types/index.d.ts +8 -0
  155. package/node_modules/@nodelib/fs.walk/out/types/index.js +2 -0
  156. package/node_modules/@nodelib/fs.walk/package.json +44 -0
  157. package/node_modules/@ungap/structured-clone/.github/workflows/node.js.yml +31 -0
  158. package/node_modules/@ungap/structured-clone/LICENSE +15 -0
  159. package/node_modules/@ungap/structured-clone/README.md +95 -0
  160. package/node_modules/@ungap/structured-clone/cjs/deserialize.js +78 -0
  161. package/node_modules/@ungap/structured-clone/cjs/index.js +27 -0
  162. package/node_modules/@ungap/structured-clone/cjs/json.js +24 -0
  163. package/node_modules/@ungap/structured-clone/cjs/package.json +1 -0
  164. package/node_modules/@ungap/structured-clone/cjs/serialize.js +160 -0
  165. package/node_modules/@ungap/structured-clone/cjs/types.js +22 -0
  166. package/node_modules/@ungap/structured-clone/esm/deserialize.js +79 -0
  167. package/node_modules/@ungap/structured-clone/esm/index.js +25 -0
  168. package/node_modules/@ungap/structured-clone/esm/json.js +21 -0
  169. package/node_modules/@ungap/structured-clone/esm/serialize.js +161 -0
  170. package/node_modules/@ungap/structured-clone/esm/types.js +11 -0
  171. package/node_modules/@ungap/structured-clone/package.json +53 -0
  172. package/node_modules/@ungap/structured-clone/structured-json.js +1 -0
  173. package/package.json +1 -1
  174. package/rules/dayjs-with-timezone.js +29 -0
@@ -0,0 +1,1061 @@
1
+ 'use strict';
2
+
3
+ var path = require('path');
4
+ var minimatch = require('minimatch');
5
+ var createDebug = require('debug');
6
+ var objectSchema = require('@humanwhocodes/object-schema');
7
+
8
+ /**
9
+ * @fileoverview ConfigSchema
10
+ * @author Nicholas C. Zakas
11
+ */
12
+
13
+ //------------------------------------------------------------------------------
14
+ // Helpers
15
+ //------------------------------------------------------------------------------
16
+
17
+ const NOOP_STRATEGY = {
18
+ required: false,
19
+ merge() {
20
+ return undefined;
21
+ },
22
+ validate() { }
23
+ };
24
+
25
+ //------------------------------------------------------------------------------
26
+ // Exports
27
+ //------------------------------------------------------------------------------
28
+
29
+ /**
30
+ * The base schema that every ConfigArray uses.
31
+ * @type Object
32
+ */
33
+ const baseSchema = Object.freeze({
34
+ name: {
35
+ required: false,
36
+ merge() {
37
+ return undefined;
38
+ },
39
+ validate(value) {
40
+ if (typeof value !== 'string') {
41
+ throw new TypeError('Property must be a string.');
42
+ }
43
+ }
44
+ },
45
+ files: NOOP_STRATEGY,
46
+ ignores: NOOP_STRATEGY
47
+ });
48
+
49
+ /**
50
+ * @fileoverview ConfigSchema
51
+ * @author Nicholas C. Zakas
52
+ */
53
+
54
+ //------------------------------------------------------------------------------
55
+ // Helpers
56
+ //------------------------------------------------------------------------------
57
+
58
+ /**
59
+ * Asserts that a given value is an array.
60
+ * @param {*} value The value to check.
61
+ * @returns {void}
62
+ * @throws {TypeError} When the value is not an array.
63
+ */
64
+ function assertIsArray(value) {
65
+ if (!Array.isArray(value)) {
66
+ throw new TypeError('Expected value to be an array.');
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Asserts that a given value is an array containing only strings and functions.
72
+ * @param {*} value The value to check.
73
+ * @returns {void}
74
+ * @throws {TypeError} When the value is not an array of strings and functions.
75
+ */
76
+ function assertIsArrayOfStringsAndFunctions(value, name) {
77
+ assertIsArray(value);
78
+
79
+ if (value.some(item => typeof item !== 'string' && typeof item !== 'function')) {
80
+ throw new TypeError('Expected array to only contain strings and functions.');
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Asserts that a given value is a non-empty array.
86
+ * @param {*} value The value to check.
87
+ * @returns {void}
88
+ * @throws {TypeError} When the value is not an array or an empty array.
89
+ */
90
+ function assertIsNonEmptyArray(value) {
91
+ if (!Array.isArray(value) || value.length === 0) {
92
+ throw new TypeError('Expected value to be a non-empty array.');
93
+ }
94
+ }
95
+
96
+ //------------------------------------------------------------------------------
97
+ // Exports
98
+ //------------------------------------------------------------------------------
99
+
100
+ /**
101
+ * The schema for `files` and `ignores` that every ConfigArray uses.
102
+ * @type Object
103
+ */
104
+ const filesAndIgnoresSchema = Object.freeze({
105
+ files: {
106
+ required: false,
107
+ merge() {
108
+ return undefined;
109
+ },
110
+ validate(value) {
111
+
112
+ // first check if it's an array
113
+ assertIsNonEmptyArray(value);
114
+
115
+ // then check each member
116
+ value.forEach(item => {
117
+ if (Array.isArray(item)) {
118
+ assertIsArrayOfStringsAndFunctions(item);
119
+ } else if (typeof item !== 'string' && typeof item !== 'function') {
120
+ throw new TypeError('Items must be a string, a function, or an array of strings and functions.');
121
+ }
122
+ });
123
+
124
+ }
125
+ },
126
+ ignores: {
127
+ required: false,
128
+ merge() {
129
+ return undefined;
130
+ },
131
+ validate: assertIsArrayOfStringsAndFunctions
132
+ }
133
+ });
134
+
135
+ /**
136
+ * @fileoverview ConfigArray
137
+ * @author Nicholas C. Zakas
138
+ */
139
+
140
+
141
+ //------------------------------------------------------------------------------
142
+ // Helpers
143
+ //------------------------------------------------------------------------------
144
+
145
+ const Minimatch = minimatch.Minimatch;
146
+ const minimatchCache = new Map();
147
+ const negatedMinimatchCache = new Map();
148
+ const debug = createDebug('@hwc/config-array');
149
+
150
+ const MINIMATCH_OPTIONS = {
151
+ // matchBase: true,
152
+ dot: true
153
+ };
154
+
155
+ const CONFIG_TYPES = new Set(['array', 'function']);
156
+
157
+ const FILES_AND_IGNORES_SCHEMA = new objectSchema.ObjectSchema(filesAndIgnoresSchema);
158
+
159
+ /**
160
+ * Shorthand for checking if a value is a string.
161
+ * @param {any} value The value to check.
162
+ * @returns {boolean} True if a string, false if not.
163
+ */
164
+ function isString(value) {
165
+ return typeof value === 'string';
166
+ }
167
+
168
+ /**
169
+ * Asserts that the files and ignores keys of a config object are valid as per base schema.
170
+ * @param {object} config The config object to check.
171
+ * @returns {void}
172
+ * @throws {TypeError} If the files and ignores keys of a config object are not valid.
173
+ */
174
+ function assertValidFilesAndIgnores(config) {
175
+ if (!config || typeof config !== 'object') {
176
+ return;
177
+ }
178
+ const validateConfig = { };
179
+ if ('files' in config) {
180
+ validateConfig.files = config.files;
181
+ }
182
+ if ('ignores' in config) {
183
+ validateConfig.ignores = config.ignores;
184
+ }
185
+ FILES_AND_IGNORES_SCHEMA.validate(validateConfig);
186
+ }
187
+
188
+ /**
189
+ * Wrapper around minimatch that caches minimatch patterns for
190
+ * faster matching speed over multiple file path evaluations.
191
+ * @param {string} filepath The file path to match.
192
+ * @param {string} pattern The glob pattern to match against.
193
+ * @param {object} options The minimatch options to use.
194
+ * @returns
195
+ */
196
+ function doMatch(filepath, pattern, options = {}) {
197
+
198
+ let cache = minimatchCache;
199
+
200
+ if (options.flipNegate) {
201
+ cache = negatedMinimatchCache;
202
+ }
203
+
204
+ let matcher = cache.get(pattern);
205
+
206
+ if (!matcher) {
207
+ matcher = new Minimatch(pattern, Object.assign({}, MINIMATCH_OPTIONS, options));
208
+ cache.set(pattern, matcher);
209
+ }
210
+
211
+ return matcher.match(filepath);
212
+ }
213
+
214
+ /**
215
+ * Normalizes a `ConfigArray` by flattening it and executing any functions
216
+ * that are found inside.
217
+ * @param {Array} items The items in a `ConfigArray`.
218
+ * @param {Object} context The context object to pass into any function
219
+ * found.
220
+ * @param {Array<string>} extraConfigTypes The config types to check.
221
+ * @returns {Promise<Array>} A flattened array containing only config objects.
222
+ * @throws {TypeError} When a config function returns a function.
223
+ */
224
+ async function normalize(items, context, extraConfigTypes) {
225
+
226
+ const allowFunctions = extraConfigTypes.includes('function');
227
+ const allowArrays = extraConfigTypes.includes('array');
228
+
229
+ async function* flatTraverse(array) {
230
+ for (let item of array) {
231
+ if (typeof item === 'function') {
232
+ if (!allowFunctions) {
233
+ throw new TypeError('Unexpected function.');
234
+ }
235
+
236
+ item = item(context);
237
+ if (item.then) {
238
+ item = await item;
239
+ }
240
+ }
241
+
242
+ if (Array.isArray(item)) {
243
+ if (!allowArrays) {
244
+ throw new TypeError('Unexpected array.');
245
+ }
246
+ yield* flatTraverse(item);
247
+ } else if (typeof item === 'function') {
248
+ throw new TypeError('A config function can only return an object or array.');
249
+ } else {
250
+ yield item;
251
+ }
252
+ }
253
+ }
254
+
255
+ /*
256
+ * Async iterables cannot be used with the spread operator, so we need to manually
257
+ * create the array to return.
258
+ */
259
+ const asyncIterable = await flatTraverse(items);
260
+ const configs = [];
261
+
262
+ for await (const config of asyncIterable) {
263
+ configs.push(config);
264
+ }
265
+
266
+ return configs;
267
+ }
268
+
269
+ /**
270
+ * Normalizes a `ConfigArray` by flattening it and executing any functions
271
+ * that are found inside.
272
+ * @param {Array} items The items in a `ConfigArray`.
273
+ * @param {Object} context The context object to pass into any function
274
+ * found.
275
+ * @param {Array<string>} extraConfigTypes The config types to check.
276
+ * @returns {Array} A flattened array containing only config objects.
277
+ * @throws {TypeError} When a config function returns a function.
278
+ */
279
+ function normalizeSync(items, context, extraConfigTypes) {
280
+
281
+ const allowFunctions = extraConfigTypes.includes('function');
282
+ const allowArrays = extraConfigTypes.includes('array');
283
+
284
+ function* flatTraverse(array) {
285
+ for (let item of array) {
286
+ if (typeof item === 'function') {
287
+
288
+ if (!allowFunctions) {
289
+ throw new TypeError('Unexpected function.');
290
+ }
291
+
292
+ item = item(context);
293
+ if (item.then) {
294
+ throw new TypeError('Async config functions are not supported.');
295
+ }
296
+ }
297
+
298
+ if (Array.isArray(item)) {
299
+
300
+ if (!allowArrays) {
301
+ throw new TypeError('Unexpected array.');
302
+ }
303
+
304
+ yield* flatTraverse(item);
305
+ } else if (typeof item === 'function') {
306
+ throw new TypeError('A config function can only return an object or array.');
307
+ } else {
308
+ yield item;
309
+ }
310
+ }
311
+ }
312
+
313
+ return [...flatTraverse(items)];
314
+ }
315
+
316
+ /**
317
+ * Determines if a given file path should be ignored based on the given
318
+ * matcher.
319
+ * @param {Array<string|() => boolean>} ignores The ignore patterns to check.
320
+ * @param {string} filePath The absolute path of the file to check.
321
+ * @param {string} relativeFilePath The relative path of the file to check.
322
+ * @returns {boolean} True if the path should be ignored and false if not.
323
+ */
324
+ function shouldIgnorePath(ignores, filePath, relativeFilePath) {
325
+
326
+ // all files outside of the basePath are ignored
327
+ if (relativeFilePath.startsWith('..')) {
328
+ return true;
329
+ }
330
+
331
+ return ignores.reduce((ignored, matcher) => {
332
+
333
+ if (!ignored) {
334
+
335
+ if (typeof matcher === 'function') {
336
+ return matcher(filePath);
337
+ }
338
+
339
+ // don't check negated patterns because we're not ignored yet
340
+ if (!matcher.startsWith('!')) {
341
+ return doMatch(relativeFilePath, matcher);
342
+ }
343
+
344
+ // otherwise we're still not ignored
345
+ return false;
346
+
347
+ }
348
+
349
+ // only need to check negated patterns because we're ignored
350
+ if (typeof matcher === 'string' && matcher.startsWith('!')) {
351
+ return !doMatch(relativeFilePath, matcher, {
352
+ flipNegate: true
353
+ });
354
+ }
355
+
356
+ return ignored;
357
+
358
+ }, false);
359
+
360
+ }
361
+
362
+ /**
363
+ * Determines if a given file path is matched by a config based on
364
+ * `ignores` only.
365
+ * @param {string} filePath The absolute file path to check.
366
+ * @param {string} basePath The base path for the config.
367
+ * @param {Object} config The config object to check.
368
+ * @returns {boolean} True if the file path is matched by the config,
369
+ * false if not.
370
+ */
371
+ function pathMatchesIgnores(filePath, basePath, config) {
372
+
373
+ /*
374
+ * For both files and ignores, functions are passed the absolute
375
+ * file path while strings are compared against the relative
376
+ * file path.
377
+ */
378
+ const relativeFilePath = path.relative(basePath, filePath);
379
+
380
+ return Object.keys(config).length > 1 &&
381
+ !shouldIgnorePath(config.ignores, filePath, relativeFilePath);
382
+ }
383
+
384
+
385
+ /**
386
+ * Determines if a given file path is matched by a config. If the config
387
+ * has no `files` field, then it matches; otherwise, if a `files` field
388
+ * is present then we match the globs in `files` and exclude any globs in
389
+ * `ignores`.
390
+ * @param {string} filePath The absolute file path to check.
391
+ * @param {string} basePath The base path for the config.
392
+ * @param {Object} config The config object to check.
393
+ * @returns {boolean} True if the file path is matched by the config,
394
+ * false if not.
395
+ */
396
+ function pathMatches(filePath, basePath, config) {
397
+
398
+ /*
399
+ * For both files and ignores, functions are passed the absolute
400
+ * file path while strings are compared against the relative
401
+ * file path.
402
+ */
403
+ const relativeFilePath = path.relative(basePath, filePath);
404
+
405
+ // match both strings and functions
406
+ const match = pattern => {
407
+
408
+ if (isString(pattern)) {
409
+ return doMatch(relativeFilePath, pattern);
410
+ }
411
+
412
+ if (typeof pattern === 'function') {
413
+ return pattern(filePath);
414
+ }
415
+
416
+ throw new TypeError(`Unexpected matcher type ${pattern}.`);
417
+ };
418
+
419
+ // check for all matches to config.files
420
+ let filePathMatchesPattern = config.files.some(pattern => {
421
+ if (Array.isArray(pattern)) {
422
+ return pattern.every(match);
423
+ }
424
+
425
+ return match(pattern);
426
+ });
427
+
428
+ /*
429
+ * If the file path matches the config.files patterns, then check to see
430
+ * if there are any files to ignore.
431
+ */
432
+ if (filePathMatchesPattern && config.ignores) {
433
+ filePathMatchesPattern = !shouldIgnorePath(config.ignores, filePath, relativeFilePath);
434
+ }
435
+
436
+ return filePathMatchesPattern;
437
+ }
438
+
439
+ /**
440
+ * Ensures that a ConfigArray has been normalized.
441
+ * @param {ConfigArray} configArray The ConfigArray to check.
442
+ * @returns {void}
443
+ * @throws {Error} When the `ConfigArray` is not normalized.
444
+ */
445
+ function assertNormalized(configArray) {
446
+ // TODO: Throw more verbose error
447
+ if (!configArray.isNormalized()) {
448
+ throw new Error('ConfigArray must be normalized to perform this operation.');
449
+ }
450
+ }
451
+
452
+ /**
453
+ * Ensures that config types are valid.
454
+ * @param {Array<string>} extraConfigTypes The config types to check.
455
+ * @returns {void}
456
+ * @throws {Error} When the config types array is invalid.
457
+ */
458
+ function assertExtraConfigTypes(extraConfigTypes) {
459
+ if (extraConfigTypes.length > 2) {
460
+ throw new TypeError('configTypes must be an array with at most two items.');
461
+ }
462
+
463
+ for (const configType of extraConfigTypes) {
464
+ if (!CONFIG_TYPES.has(configType)) {
465
+ throw new TypeError(`Unexpected config type "${configType}" found. Expected one of: "object", "array", "function".`);
466
+ }
467
+ }
468
+ }
469
+
470
+ //------------------------------------------------------------------------------
471
+ // Public Interface
472
+ //------------------------------------------------------------------------------
473
+
474
+ const ConfigArraySymbol = {
475
+ isNormalized: Symbol('isNormalized'),
476
+ configCache: Symbol('configCache'),
477
+ schema: Symbol('schema'),
478
+ finalizeConfig: Symbol('finalizeConfig'),
479
+ preprocessConfig: Symbol('preprocessConfig')
480
+ };
481
+
482
+ // used to store calculate data for faster lookup
483
+ const dataCache = new WeakMap();
484
+
485
+ /**
486
+ * Represents an array of config objects and provides method for working with
487
+ * those config objects.
488
+ */
489
+ class ConfigArray extends Array {
490
+
491
+ /**
492
+ * Creates a new instance of ConfigArray.
493
+ * @param {Iterable|Function|Object} configs An iterable yielding config
494
+ * objects, or a config function, or a config object.
495
+ * @param {string} [options.basePath=""] The path of the config file
496
+ * @param {boolean} [options.normalized=false] Flag indicating if the
497
+ * configs have already been normalized.
498
+ * @param {Object} [options.schema] The additional schema
499
+ * definitions to use for the ConfigArray schema.
500
+ * @param {Array<string>} [options.configTypes] List of config types supported.
501
+ */
502
+ constructor(configs, {
503
+ basePath = '',
504
+ normalized = false,
505
+ schema: customSchema,
506
+ extraConfigTypes = []
507
+ } = {}
508
+ ) {
509
+ super();
510
+
511
+ /**
512
+ * Tracks if the array has been normalized.
513
+ * @property isNormalized
514
+ * @type boolean
515
+ * @private
516
+ */
517
+ this[ConfigArraySymbol.isNormalized] = normalized;
518
+
519
+ /**
520
+ * The schema used for validating and merging configs.
521
+ * @property schema
522
+ * @type ObjectSchema
523
+ * @private
524
+ */
525
+ this[ConfigArraySymbol.schema] = new objectSchema.ObjectSchema(
526
+ Object.assign({}, customSchema, baseSchema)
527
+ );
528
+
529
+ /**
530
+ * The path of the config file that this array was loaded from.
531
+ * This is used to calculate filename matches.
532
+ * @property basePath
533
+ * @type string
534
+ */
535
+ this.basePath = basePath;
536
+
537
+ assertExtraConfigTypes(extraConfigTypes);
538
+
539
+ /**
540
+ * The supported config types.
541
+ * @property configTypes
542
+ * @type Array<string>
543
+ */
544
+ this.extraConfigTypes = Object.freeze([...extraConfigTypes]);
545
+
546
+ /**
547
+ * A cache to store calculated configs for faster repeat lookup.
548
+ * @property configCache
549
+ * @type Map
550
+ * @private
551
+ */
552
+ this[ConfigArraySymbol.configCache] = new Map();
553
+
554
+ // init cache
555
+ dataCache.set(this, {
556
+ explicitMatches: new Map(),
557
+ directoryMatches: new Map(),
558
+ files: undefined,
559
+ ignores: undefined
560
+ });
561
+
562
+ // load the configs into this array
563
+ if (Array.isArray(configs)) {
564
+ this.push(...configs);
565
+ } else {
566
+ this.push(configs);
567
+ }
568
+
569
+ }
570
+
571
+ /**
572
+ * Prevent normal array methods from creating a new `ConfigArray` instance.
573
+ * This is to ensure that methods such as `slice()` won't try to create a
574
+ * new instance of `ConfigArray` behind the scenes as doing so may throw
575
+ * an error due to the different constructor signature.
576
+ * @returns {Function} The `Array` constructor.
577
+ */
578
+ static get [Symbol.species]() {
579
+ return Array;
580
+ }
581
+
582
+ /**
583
+ * Returns the `files` globs from every config object in the array.
584
+ * This can be used to determine which files will be matched by a
585
+ * config array or to use as a glob pattern when no patterns are provided
586
+ * for a command line interface.
587
+ * @returns {Array<string|Function>} An array of matchers.
588
+ */
589
+ get files() {
590
+
591
+ assertNormalized(this);
592
+
593
+ // if this data has been cached, retrieve it
594
+ const cache = dataCache.get(this);
595
+
596
+ if (cache.files) {
597
+ return cache.files;
598
+ }
599
+
600
+ // otherwise calculate it
601
+
602
+ const result = [];
603
+
604
+ for (const config of this) {
605
+ if (config.files) {
606
+ config.files.forEach(filePattern => {
607
+ result.push(filePattern);
608
+ });
609
+ }
610
+ }
611
+
612
+ // store result
613
+ cache.files = result;
614
+ dataCache.set(this, cache);
615
+
616
+ return result;
617
+ }
618
+
619
+ /**
620
+ * Returns ignore matchers that should always be ignored regardless of
621
+ * the matching `files` fields in any configs. This is necessary to mimic
622
+ * the behavior of things like .gitignore and .eslintignore, allowing a
623
+ * globbing operation to be faster.
624
+ * @returns {string[]} An array of string patterns and functions to be ignored.
625
+ */
626
+ get ignores() {
627
+
628
+ assertNormalized(this);
629
+
630
+ // if this data has been cached, retrieve it
631
+ const cache = dataCache.get(this);
632
+
633
+ if (cache.ignores) {
634
+ return cache.ignores;
635
+ }
636
+
637
+ // otherwise calculate it
638
+
639
+ const result = [];
640
+
641
+ for (const config of this) {
642
+
643
+ /*
644
+ * We only count ignores if there are no other keys in the object.
645
+ * In this case, it acts list a globally ignored pattern. If there
646
+ * are additional keys, then ignores act like exclusions.
647
+ */
648
+ if (config.ignores && Object.keys(config).length === 1) {
649
+
650
+ /*
651
+ * If there are directory ignores, then we need to double up
652
+ * the patterns to be ignored. For instance, `foo` will also
653
+ * need `foo/**` in order to account for subdirectories.
654
+ */
655
+ config.ignores.forEach(ignore => {
656
+
657
+ result.push(ignore);
658
+
659
+ if (typeof ignore === 'string') {
660
+
661
+ // unignoring files won't work unless we unignore directories too
662
+ if (ignore.startsWith('!')) {
663
+
664
+ if (ignore.endsWith('/**')) {
665
+ result.push(ignore.slice(0, ignore.length - 3));
666
+ } else if (ignore.endsWith('/*')) {
667
+ result.push(ignore.slice(0, ignore.length - 2));
668
+ }
669
+ }
670
+
671
+ // directories should work with or without a trailing slash
672
+ if (ignore.endsWith('/')) {
673
+ result.push(ignore.slice(0, ignore.length - 1));
674
+ result.push(ignore + '**');
675
+ } else if (!ignore.endsWith('*')) {
676
+ result.push(ignore + '/**');
677
+ }
678
+
679
+ }
680
+ });
681
+ }
682
+ }
683
+
684
+ // store result
685
+ cache.ignores = result;
686
+ dataCache.set(this, cache);
687
+
688
+ return result;
689
+ }
690
+
691
+ /**
692
+ * Indicates if the config array has been normalized.
693
+ * @returns {boolean} True if the config array is normalized, false if not.
694
+ */
695
+ isNormalized() {
696
+ return this[ConfigArraySymbol.isNormalized];
697
+ }
698
+
699
+ /**
700
+ * Normalizes a config array by flattening embedded arrays and executing
701
+ * config functions.
702
+ * @param {ConfigContext} context The context object for config functions.
703
+ * @returns {Promise<ConfigArray>} The current ConfigArray instance.
704
+ */
705
+ async normalize(context = {}) {
706
+
707
+ if (!this.isNormalized()) {
708
+ const normalizedConfigs = await normalize(this, context, this.extraConfigTypes);
709
+ this.length = 0;
710
+ this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig].bind(this)));
711
+ this.forEach(assertValidFilesAndIgnores);
712
+ this[ConfigArraySymbol.isNormalized] = true;
713
+
714
+ // prevent further changes
715
+ Object.freeze(this);
716
+ }
717
+
718
+ return this;
719
+ }
720
+
721
+ /**
722
+ * Normalizes a config array by flattening embedded arrays and executing
723
+ * config functions.
724
+ * @param {ConfigContext} context The context object for config functions.
725
+ * @returns {ConfigArray} The current ConfigArray instance.
726
+ */
727
+ normalizeSync(context = {}) {
728
+
729
+ if (!this.isNormalized()) {
730
+ const normalizedConfigs = normalizeSync(this, context, this.extraConfigTypes);
731
+ this.length = 0;
732
+ this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig].bind(this)));
733
+ this.forEach(assertValidFilesAndIgnores);
734
+ this[ConfigArraySymbol.isNormalized] = true;
735
+
736
+ // prevent further changes
737
+ Object.freeze(this);
738
+ }
739
+
740
+ return this;
741
+ }
742
+
743
+ /**
744
+ * Finalizes the state of a config before being cached and returned by
745
+ * `getConfig()`. Does nothing by default but is provided to be
746
+ * overridden by subclasses as necessary.
747
+ * @param {Object} config The config to finalize.
748
+ * @returns {Object} The finalized config.
749
+ */
750
+ [ConfigArraySymbol.finalizeConfig](config) {
751
+ return config;
752
+ }
753
+
754
+ /**
755
+ * Preprocesses a config during the normalization process. This is the
756
+ * method to override if you want to convert an array item before it is
757
+ * validated for the first time. For example, if you want to replace a
758
+ * string with an object, this is the method to override.
759
+ * @param {Object} config The config to preprocess.
760
+ * @returns {Object} The config to use in place of the argument.
761
+ */
762
+ [ConfigArraySymbol.preprocessConfig](config) {
763
+ return config;
764
+ }
765
+
766
+ /**
767
+ * Determines if a given file path explicitly matches a `files` entry
768
+ * and also doesn't match an `ignores` entry. Configs that don't have
769
+ * a `files` property are not considered an explicit match.
770
+ * @param {string} filePath The complete path of a file to check.
771
+ * @returns {boolean} True if the file path matches a `files` entry
772
+ * or false if not.
773
+ */
774
+ isExplicitMatch(filePath) {
775
+
776
+ assertNormalized(this);
777
+
778
+ const cache = dataCache.get(this);
779
+
780
+ // first check the cache to avoid duplicate work
781
+ let result = cache.explicitMatches.get(filePath);
782
+
783
+ if (typeof result == 'boolean') {
784
+ return result;
785
+ }
786
+
787
+ // TODO: Maybe move elsewhere? Maybe combine with getConfig() logic?
788
+ const relativeFilePath = path.relative(this.basePath, filePath);
789
+
790
+ if (shouldIgnorePath(this.ignores, filePath, relativeFilePath)) {
791
+ debug(`Ignoring ${filePath}`);
792
+
793
+ // cache and return result
794
+ cache.explicitMatches.set(filePath, false);
795
+ return false;
796
+ }
797
+
798
+ // filePath isn't automatically ignored, so try to find a match
799
+
800
+ for (const config of this) {
801
+
802
+ if (!config.files) {
803
+ continue;
804
+ }
805
+
806
+ if (pathMatches(filePath, this.basePath, config)) {
807
+ debug(`Matching config found for ${filePath}`);
808
+ cache.explicitMatches.set(filePath, true);
809
+ return true;
810
+ }
811
+ }
812
+
813
+ return false;
814
+ }
815
+
816
+ /**
817
+ * Returns the config object for a given file path.
818
+ * @param {string} filePath The complete path of a file to get a config for.
819
+ * @returns {Object} The config object for this file.
820
+ */
821
+ getConfig(filePath) {
822
+
823
+ assertNormalized(this);
824
+
825
+ const cache = this[ConfigArraySymbol.configCache];
826
+
827
+ // first check the cache for a filename match to avoid duplicate work
828
+ if (cache.has(filePath)) {
829
+ return cache.get(filePath);
830
+ }
831
+
832
+ let finalConfig;
833
+
834
+ // next check to see if the file should be ignored
835
+
836
+ // check if this should be ignored due to its directory
837
+ if (this.isDirectoryIgnored(path.dirname(filePath))) {
838
+ debug(`Ignoring ${filePath} based on directory pattern`);
839
+
840
+ // cache and return result - finalConfig is undefined at this point
841
+ cache.set(filePath, finalConfig);
842
+ return finalConfig;
843
+ }
844
+
845
+ // TODO: Maybe move elsewhere?
846
+ const relativeFilePath = path.relative(this.basePath, filePath);
847
+
848
+ if (shouldIgnorePath(this.ignores, filePath, relativeFilePath)) {
849
+ debug(`Ignoring ${filePath} based on file pattern`);
850
+
851
+ // cache and return result - finalConfig is undefined at this point
852
+ cache.set(filePath, finalConfig);
853
+ return finalConfig;
854
+ }
855
+
856
+ // filePath isn't automatically ignored, so try to construct config
857
+
858
+ const matchingConfigIndices = [];
859
+ let matchFound = false;
860
+ const universalPattern = /\/\*{1,2}$/;
861
+
862
+ this.forEach((config, index) => {
863
+
864
+ if (!config.files) {
865
+
866
+ if (!config.ignores) {
867
+ debug(`Anonymous universal config found for ${filePath}`);
868
+ matchingConfigIndices.push(index);
869
+ return;
870
+ }
871
+
872
+ if (pathMatchesIgnores(filePath, this.basePath, config)) {
873
+ debug(`Matching config found for ${filePath} (based on ignores: ${config.ignores})`);
874
+ matchingConfigIndices.push(index);
875
+ return;
876
+ }
877
+
878
+ debug(`Skipped config found for ${filePath} (based on ignores: ${config.ignores})`);
879
+ return;
880
+ }
881
+
882
+ /*
883
+ * If a config has a files pattern ending in /** or /*, and the
884
+ * filePath only matches those patterns, then the config is only
885
+ * applied if there is another config where the filePath matches
886
+ * a file with a specific extensions such as *.js.
887
+ */
888
+
889
+ const universalFiles = config.files.filter(
890
+ pattern => universalPattern.test(pattern)
891
+ );
892
+
893
+ // universal patterns were found so we need to check the config twice
894
+ if (universalFiles.length) {
895
+
896
+ debug('Universal files patterns found. Checking carefully.');
897
+
898
+ const nonUniversalFiles = config.files.filter(
899
+ pattern => !universalPattern.test(pattern)
900
+ );
901
+
902
+ // check that the config matches without the non-universal files first
903
+ if (
904
+ nonUniversalFiles.length &&
905
+ pathMatches(
906
+ filePath, this.basePath,
907
+ { files: nonUniversalFiles, ignores: config.ignores }
908
+ )
909
+ ) {
910
+ debug(`Matching config found for ${filePath}`);
911
+ matchingConfigIndices.push(index);
912
+ matchFound = true;
913
+ return;
914
+ }
915
+
916
+ // if there wasn't a match then check if it matches with universal files
917
+ if (
918
+ universalFiles.length &&
919
+ pathMatches(
920
+ filePath, this.basePath,
921
+ { files: universalFiles, ignores: config.ignores }
922
+ )
923
+ ) {
924
+ debug(`Matching config found for ${filePath}`);
925
+ matchingConfigIndices.push(index);
926
+ return;
927
+ }
928
+
929
+ // if we make here, then there was no match
930
+ return;
931
+ }
932
+
933
+ // the normal case
934
+ if (pathMatches(filePath, this.basePath, config)) {
935
+ debug(`Matching config found for ${filePath}`);
936
+ matchingConfigIndices.push(index);
937
+ matchFound = true;
938
+ return;
939
+ }
940
+
941
+ });
942
+
943
+ // if matching both files and ignores, there will be no config to create
944
+ if (!matchFound) {
945
+ debug(`No matching configs found for ${filePath}`);
946
+
947
+ // cache and return result - finalConfig is undefined at this point
948
+ cache.set(filePath, finalConfig);
949
+ return finalConfig;
950
+ }
951
+
952
+ // check to see if there is a config cached by indices
953
+ finalConfig = cache.get(matchingConfigIndices.toString());
954
+
955
+ if (finalConfig) {
956
+
957
+ // also store for filename for faster lookup next time
958
+ cache.set(filePath, finalConfig);
959
+
960
+ return finalConfig;
961
+ }
962
+
963
+ // otherwise construct the config
964
+
965
+ finalConfig = matchingConfigIndices.reduce((result, index) => {
966
+ return this[ConfigArraySymbol.schema].merge(result, this[index]);
967
+ }, {}, this);
968
+
969
+ finalConfig = this[ConfigArraySymbol.finalizeConfig](finalConfig);
970
+
971
+ cache.set(filePath, finalConfig);
972
+ cache.set(matchingConfigIndices.toString(), finalConfig);
973
+
974
+ return finalConfig;
975
+ }
976
+
977
+ /**
978
+ * Determines if the given filepath is ignored based on the configs.
979
+ * @param {string} filePath The complete path of a file to check.
980
+ * @returns {boolean} True if the path is ignored, false if not.
981
+ * @deprecated Use `isFileIgnored` instead.
982
+ */
983
+ isIgnored(filePath) {
984
+ return this.isFileIgnored(filePath);
985
+ }
986
+
987
+ /**
988
+ * Determines if the given filepath is ignored based on the configs.
989
+ * @param {string} filePath The complete path of a file to check.
990
+ * @returns {boolean} True if the path is ignored, false if not.
991
+ */
992
+ isFileIgnored(filePath) {
993
+ return this.getConfig(filePath) === undefined;
994
+ }
995
+
996
+ /**
997
+ * Determines if the given directory is ignored based on the configs.
998
+ * This checks only default `ignores` that don't have `files` in the
999
+ * same config. A pattern such as `/foo` be considered to ignore the directory
1000
+ * while a pattern such as `/foo/**` is not considered to ignore the
1001
+ * directory because it is matching files.
1002
+ * @param {string} directoryPath The complete path of a directory to check.
1003
+ * @returns {boolean} True if the directory is ignored, false if not. Will
1004
+ * return true for any directory that is not inside of `basePath`.
1005
+ * @throws {Error} When the `ConfigArray` is not normalized.
1006
+ */
1007
+ isDirectoryIgnored(directoryPath) {
1008
+
1009
+ assertNormalized(this);
1010
+
1011
+ const relativeDirectoryPath = path.relative(this.basePath, directoryPath)
1012
+ .replace(/\\/g, '/');
1013
+
1014
+ if (relativeDirectoryPath.startsWith('..')) {
1015
+ return true;
1016
+ }
1017
+
1018
+ // first check the cache
1019
+ const cache = dataCache.get(this).directoryMatches;
1020
+
1021
+ if (cache.has(relativeDirectoryPath)) {
1022
+ return cache.get(relativeDirectoryPath);
1023
+ }
1024
+
1025
+ const directoryParts = relativeDirectoryPath.split('/');
1026
+ let relativeDirectoryToCheck = '';
1027
+ let result = false;
1028
+
1029
+ /*
1030
+ * In order to get the correct gitignore-style ignores, where an
1031
+ * ignored parent directory cannot have any descendants unignored,
1032
+ * we need to check every directory starting at the parent all
1033
+ * the way down to the actual requested directory.
1034
+ *
1035
+ * We aggressively cache all of this info to make sure we don't
1036
+ * have to recalculate everything for every call.
1037
+ */
1038
+ do {
1039
+
1040
+ relativeDirectoryToCheck += directoryParts.shift() + '/';
1041
+
1042
+ result = shouldIgnorePath(
1043
+ this.ignores,
1044
+ path.join(this.basePath, relativeDirectoryToCheck),
1045
+ relativeDirectoryToCheck
1046
+ );
1047
+
1048
+ cache.set(relativeDirectoryToCheck, result);
1049
+
1050
+ } while (!result && directoryParts.length);
1051
+
1052
+ // also cache the result for the requested path
1053
+ cache.set(relativeDirectoryPath, result);
1054
+
1055
+ return result;
1056
+ }
1057
+
1058
+ }
1059
+
1060
+ exports.ConfigArray = ConfigArray;
1061
+ exports.ConfigArraySymbol = ConfigArraySymbol;