source: frontend/node_modules/webpack/lib/util/deprecation.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 9.9 KB
RevLine 
[9af201e]1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const util = require("util");
9
10/** @type {Map<string, () => void>} */
11const deprecationCache = new Map();
12
13/**
14 * Defines the fake hook marker type used by this module.
15 * @typedef {object} FakeHookMarker
16 * @property {true} _fakeHook it's a fake hook
17 */
18
19/**
20 * Defines the shared type used by this module.
21 * @template T
22 * @typedef {T & FakeHookMarker} FakeHook<T>
23 */
24
25/**
26 * Creates a deprecation.
27 * @param {string} message deprecation message
28 * @param {string} code deprecation code
29 * @returns {() => void} function to trigger deprecation
30 */
31const createDeprecation = (message, code) => {
32 const cached = deprecationCache.get(message);
33 if (cached !== undefined) return cached;
34 const fn = util.deprecate(
35 () => {},
36 message,
37 `DEP_WEBPACK_DEPRECATION_${code}`
38 );
39 deprecationCache.set(message, fn);
40 return fn;
41};
42
43/** @typedef {"concat" | "entry" | "filter" | "find" | "findIndex" | "includes" | "indexOf" | "join" | "lastIndexOf" | "map" | "reduce" | "reduceRight" | "slice" | "some"} COPY_METHODS_NAMES */
44
45/** @type {COPY_METHODS_NAMES[]} */
46const COPY_METHODS = [
47 "concat",
48 "entry",
49 "filter",
50 "find",
51 "findIndex",
52 "includes",
53 "indexOf",
54 "join",
55 "lastIndexOf",
56 "map",
57 "reduce",
58 "reduceRight",
59 "slice",
60 "some"
61];
62
63/** @typedef {"copyWithin" | "entries" | "fill" | "keys" | "pop" | "reverse" | "shift" | "splice" | "sort" | "unshift"} DISABLED_METHODS_NAMES */
64
65/** @type {DISABLED_METHODS_NAMES[]} */
66const DISABLED_METHODS = [
67 "copyWithin",
68 "entries",
69 "fill",
70 "keys",
71 "pop",
72 "reverse",
73 "shift",
74 "splice",
75 "sort",
76 "unshift"
77];
78
79/**
80 * Defines the set with deprecated array methods type used by this module.
81 * @template T
82 * @typedef {Set<T> & { [Symbol.isConcatSpreadable]: boolean } & { push: (...items: T[]) => void, length?: number } & { [P in DISABLED_METHODS_NAMES]: () => void } & { [P in COPY_METHODS_NAMES]: P extends keyof Array<T> ? () => Pick<Array<T>, P> : never }} SetWithDeprecatedArrayMethods
83 */
84
85/**
86 * Processes the provided set.
87 * @template T
88 * @param {Set<T>} set new set
89 * @param {string} name property name
90 * @returns {void}
91 */
92module.exports.arrayToSetDeprecation = (set, name) => {
93 for (const method of COPY_METHODS) {
94 if (/** @type {SetWithDeprecatedArrayMethods<T>} */ (set)[method]) continue;
95 const d = createDeprecation(
96 `${name} was changed from Array to Set (using Array method '${method}' is deprecated)`,
97 "ARRAY_TO_SET"
98 );
99 /** @type {EXPECTED_ANY} */
100 (set)[method] =
101 // eslint-disable-next-line func-names
102 function () {
103 d();
104 // eslint-disable-next-line unicorn/prefer-spread
105 const array = Array.from(this);
106 return Array.prototype[
107 /** @type {keyof COPY_METHODS} */ (method)
108 ].apply(
109 array,
110 // eslint-disable-next-line prefer-rest-params
111 arguments
112 );
113 };
114 }
115 const dPush = createDeprecation(
116 `${name} was changed from Array to Set (using Array method 'push' is deprecated)`,
117 "ARRAY_TO_SET_PUSH"
118 );
119 const dLength = createDeprecation(
120 `${name} was changed from Array to Set (using Array property 'length' is deprecated)`,
121 "ARRAY_TO_SET_LENGTH"
122 );
123 const dIndexer = createDeprecation(
124 `${name} was changed from Array to Set (indexing Array is deprecated)`,
125 "ARRAY_TO_SET_INDEXER"
126 );
127 /** @type {SetWithDeprecatedArrayMethods<T>} */
128 (set).push = function push() {
129 dPush();
130 // eslint-disable-next-line prefer-rest-params, unicorn/prefer-spread
131 for (const item of Array.from(arguments)) {
132 this.add(item);
133 }
134 return this.size;
135 };
136 for (const method of DISABLED_METHODS) {
137 if (/** @type {SetWithDeprecatedArrayMethods<T>} */ (set)[method]) continue;
138
139 /** @type {SetWithDeprecatedArrayMethods<T>} */
140 (set)[method] = () => {
141 throw new Error(
142 `${name} was changed from Array to Set (using Array method '${method}' is not possible)`
143 );
144 };
145 }
146 /**
147 * Creates an index getter.
148 * @param {number} index index
149 * @returns {() => T | undefined} value
150 */
151 const createIndexGetter = (index) => {
152 /**
153 * Returns the value at this location.
154 * @this {Set<T>} a Set
155 * @returns {T | undefined} the value at this location
156 */
157 // eslint-disable-next-line func-style
158 const fn = function () {
159 dIndexer();
160 let i = 0;
161 for (const item of this) {
162 if (i++ === index) return item;
163 }
164 };
165 return fn;
166 };
167 /**
168 * Define index getter.
169 * @param {number} index index
170 */
171 const defineIndexGetter = (index) => {
172 Object.defineProperty(set, index, {
173 get: createIndexGetter(index),
174 set(value) {
175 throw new Error(
176 `${name} was changed from Array to Set (indexing Array with write is not possible)`
177 );
178 }
179 });
180 };
181 defineIndexGetter(0);
182 let indexerDefined = 1;
183 Object.defineProperty(set, "length", {
184 get() {
185 dLength();
186 const length = this.size;
187 for (indexerDefined; indexerDefined < length + 1; indexerDefined++) {
188 defineIndexGetter(indexerDefined);
189 }
190 return length;
191 },
192 set(value) {
193 throw new Error(
194 `${name} was changed from Array to Set (writing to Array property 'length' is not possible)`
195 );
196 }
197 });
198 /** @type {SetWithDeprecatedArrayMethods<T>} */
199 (set)[Symbol.isConcatSpreadable] = true;
200};
201
202/**
203 * Returns } SetDeprecatedArray.
204 * @template T
205 * @param {string} name name
206 * @returns {{ new <T = EXPECTED_ANY>(values?: ReadonlyArray<T> | null): SetDeprecatedArray<T> }} SetDeprecatedArray
207 */
208module.exports.createArrayToSetDeprecationSet = (name) => {
209 let initialized = false;
210
211 /**
212 * Represents SetDeprecatedArray.
213 * @template T
214 */
215 class SetDeprecatedArray extends Set {
216 /**
217 * Creates an instance of SetDeprecatedArray.
218 * @param {ReadonlyArray<T> | null=} items items
219 */
220 constructor(items) {
221 super(items);
222 if (!initialized) {
223 initialized = true;
224 module.exports.arrayToSetDeprecation(
225 /** @type {SetWithDeprecatedArrayMethods<T>} */
226 (SetDeprecatedArray.prototype),
227 name
228 );
229 }
230 }
231 }
232 return SetDeprecatedArray;
233};
234
235/**
236 * Returns fake hook which redirects.
237 * @template {object} T
238 * @param {T} fakeHook fake hook implementation
239 * @param {string=} message deprecation message (not deprecated when unset)
240 * @param {string=} code deprecation code (not deprecated when unset)
241 * @returns {FakeHook<T>} fake hook which redirects
242 */
243module.exports.createFakeHook = (fakeHook, message, code) => {
244 if (message && code) {
245 fakeHook = deprecateAllProperties(fakeHook, message, code);
246 }
247 return Object.freeze(
248 Object.assign(fakeHook, { _fakeHook: /** @type {true} */ (true) })
249 );
250};
251
252/**
253 * Deprecate all properties.
254 * @template T
255 * @param {T} obj object
256 * @param {string} message deprecation message
257 * @param {string} code deprecation code
258 * @returns {T} object with property access deprecated
259 */
260const deprecateAllProperties = (obj, message, code) => {
261 const newObj = {};
262 const descriptors = Object.getOwnPropertyDescriptors(obj);
263 for (const name of Object.keys(descriptors)) {
264 const descriptor = descriptors[name];
265 if (typeof descriptor.value === "function") {
266 Object.defineProperty(newObj, name, {
267 ...descriptor,
268 value: util.deprecate(descriptor.value, message, code)
269 });
270 } else if (descriptor.get || descriptor.set) {
271 Object.defineProperty(newObj, name, {
272 ...descriptor,
273 get: descriptor.get && util.deprecate(descriptor.get, message, code),
274 set: descriptor.set && util.deprecate(descriptor.set, message, code)
275 });
276 } else {
277 let value = descriptor.value;
278 Object.defineProperty(newObj, name, {
279 configurable: descriptor.configurable,
280 enumerable: descriptor.enumerable,
281 get: util.deprecate(() => value, message, code),
282 set: descriptor.writable
283 ? util.deprecate(
284 /**
285 * Handles the callback logic for this hook.
286 * @template T
287 * @param {T} v value
288 * @returns {T} result
289 */
290 (v) => (value = v),
291 message,
292 code
293 )
294 : undefined
295 });
296 }
297 }
298 return /** @type {T} */ (newObj);
299};
300
301module.exports.deprecateAllProperties = deprecateAllProperties;
302
303/**
304 * Returns frozen object with deprecation when modifying.
305 * @template {object} T
306 * @param {T} obj object
307 * @param {string} name property name
308 * @param {string} code deprecation code
309 * @param {string} note additional note
310 * @returns {T} frozen object with deprecation when modifying
311 */
312module.exports.soonFrozenObjectDeprecation = (obj, name, code, note = "") => {
313 const message = `${name} will be frozen in future, all modifications are deprecated.${
314 note && `\n${note}`
315 }`;
316 return /** @type {T} */ (
317 new Proxy(obj, {
318 set: util.deprecate(
319 /**
320 * Handles the callback logic for this hook.
321 * @param {object} target target
322 * @param {string | symbol} property property
323 * @param {EXPECTED_ANY} value value
324 * @param {EXPECTED_ANY} receiver receiver
325 * @returns {boolean} result
326 */
327 (target, property, value, receiver) =>
328 Reflect.set(target, property, value, receiver),
329 message,
330 code
331 ),
332 defineProperty: util.deprecate(
333 /**
334 * Handles the define property callback for this hook.
335 * @param {object} target target
336 * @param {string | symbol} property property
337 * @param {PropertyDescriptor} descriptor descriptor
338 * @returns {boolean} result
339 */
340 (target, property, descriptor) =>
341 Reflect.defineProperty(target, property, descriptor),
342 message,
343 code
344 ),
345 deleteProperty: util.deprecate(
346 /**
347 * Handles the delete property callback for this hook.
348 * @param {object} target target
349 * @param {string | symbol} property property
350 * @returns {boolean} result
351 */
352 (target, property) => Reflect.deleteProperty(target, property),
353 message,
354 code
355 ),
356 setPrototypeOf: util.deprecate(
357 /**
358 * Updates prototype of using the provided target.
359 * @param {object} target target
360 * @param {EXPECTED_OBJECT | null} proto proto
361 * @returns {boolean} result
362 */
363 (target, proto) => Reflect.setPrototypeOf(target, proto),
364 message,
365 code
366 )
367 })
368 );
369};
Note: See TracBrowser for help on using the repository browser.