@gesslar/toolkit 0.2.4 → 0.2.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.
- package/package.json +6 -6
- package/src/lib/Collection.js +73 -30
- package/src/lib/Data.js +0 -13
- package/src/lib/FS.js +2 -3
- package/src/lib/Util.js +12 -1
- package/src/lib/Valid.js +12 -0
- package/src/types/Collection.d.ts +88 -6
- package/src/types/Data.d.ts +0 -3
- package/src/types/Util.d.ts +6 -1
- package/src/types/Valid.d.ts +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gesslar/toolkit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Get in, bitches, we're going toolkitting.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -49,16 +49,16 @@
|
|
|
49
49
|
"license": "Unlicense",
|
|
50
50
|
"homepage": "https://github.com/gesslar/toolkit#readme",
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"globby": "^
|
|
52
|
+
"globby": "^15.0.0",
|
|
53
53
|
"json5": "^2.2.3",
|
|
54
54
|
"yaml": "^2.8.1"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@stylistic/eslint-plugin": "^5.4.0",
|
|
58
|
-
"@types/node": "^24.
|
|
59
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
60
|
-
"@typescript-eslint/parser": "^8.
|
|
58
|
+
"@types/node": "^24.6.2",
|
|
59
|
+
"@typescript-eslint/eslint-plugin": "^8.45.0",
|
|
60
|
+
"@typescript-eslint/parser": "^8.45.0",
|
|
61
61
|
"eslint": "^9.36.0",
|
|
62
|
-
"eslint-plugin-jsdoc": "^60.
|
|
62
|
+
"eslint-plugin-jsdoc": "^60.7.1"
|
|
63
63
|
}
|
|
64
64
|
}
|
package/src/lib/Collection.js
CHANGED
|
@@ -139,6 +139,11 @@ export default class Collection {
|
|
|
139
139
|
|
|
140
140
|
Valid.type(arr, req, `Invalid array. Expected '${req}', got '${arrType}'`)
|
|
141
141
|
|
|
142
|
+
// Validate type parameter if provided
|
|
143
|
+
if(type !== undefined) {
|
|
144
|
+
Valid.type(type, "string", `Invalid type parameter. Expected 'string', got '${Data.typeOf(type)}'`)
|
|
145
|
+
}
|
|
146
|
+
|
|
142
147
|
const checkType = type ? Util.capitalize(type) : null
|
|
143
148
|
|
|
144
149
|
return arr.every(
|
|
@@ -169,7 +174,7 @@ export default class Collection {
|
|
|
169
174
|
* @param {Array} arr2 - The second array.
|
|
170
175
|
* @returns {Array} The intersection of the two arrays.
|
|
171
176
|
*/
|
|
172
|
-
static
|
|
177
|
+
static intersection(arr1, arr2) {
|
|
173
178
|
const req = "Array"
|
|
174
179
|
const arr1Type = Data.typeOf(arr1)
|
|
175
180
|
const arr2Type = Data.typeOf(arr2)
|
|
@@ -190,14 +195,14 @@ export default class Collection {
|
|
|
190
195
|
* array for efficiency.
|
|
191
196
|
*
|
|
192
197
|
* Example:
|
|
193
|
-
*
|
|
194
|
-
*
|
|
198
|
+
* Collection.intersects([1, 2, 3], [3, 4, 5]) // returns true
|
|
199
|
+
* Collection.intersects(["a", "b"], ["c", "d"]) // returns false
|
|
195
200
|
*
|
|
196
201
|
* @param {Array} arr1 - The first array to check for intersection.
|
|
197
202
|
* @param {Array} arr2 - The second array to check for intersection.
|
|
198
203
|
* @returns {boolean} True if any element is shared between the arrays, false otherwise.
|
|
199
204
|
*/
|
|
200
|
-
static
|
|
205
|
+
static intersects(arr1, arr2) {
|
|
201
206
|
const req = "Array"
|
|
202
207
|
const arr1Type = Data.typeOf(arr1)
|
|
203
208
|
const arr2Type = Data.typeOf(arr2)
|
|
@@ -245,22 +250,6 @@ export default class Collection {
|
|
|
245
250
|
throw Sass.new("Invalid position")
|
|
246
251
|
}
|
|
247
252
|
|
|
248
|
-
/**
|
|
249
|
-
* Checks if all elements in an array are strings.
|
|
250
|
-
*
|
|
251
|
-
* @param {Array} arr - The array to check.
|
|
252
|
-
* @returns {boolean} Returns true if all elements are strings, false otherwise.
|
|
253
|
-
* @example
|
|
254
|
-
* uniformStringArray(['a', 'b', 'c']) // returns true
|
|
255
|
-
* uniformStringArray(['a', 1, 'c']) // returns false
|
|
256
|
-
*/
|
|
257
|
-
static uniformStringArray(arr) {
|
|
258
|
-
if(!Data.isType(arr, "Array"))
|
|
259
|
-
return false
|
|
260
|
-
|
|
261
|
-
return arr.every(item => typeof item === "string")
|
|
262
|
-
}
|
|
263
|
-
|
|
264
253
|
/**
|
|
265
254
|
* Filters an array asynchronously using a predicate function.
|
|
266
255
|
* Applies the predicate to all items in parallel and returns filtered results.
|
|
@@ -345,14 +334,11 @@ export default class Collection {
|
|
|
345
334
|
let current = obj // a moving reference to internal objects within obj
|
|
346
335
|
const len = keys.length
|
|
347
336
|
|
|
337
|
+
Valid.prototypePollutionProtection(keys)
|
|
338
|
+
|
|
348
339
|
for(let i = 0; i < len; i++) {
|
|
349
340
|
const elem = keys[i]
|
|
350
341
|
|
|
351
|
-
// Prevent prototype pollution
|
|
352
|
-
if(elem === "__proto__" || elem === "constructor" || elem === "prototype") {
|
|
353
|
-
throw Sass.new(`Dangerous key "${elem}" not allowed in object path`)
|
|
354
|
-
}
|
|
355
|
-
|
|
356
342
|
if(!current[elem])
|
|
357
343
|
current[elem] = {}
|
|
358
344
|
|
|
@@ -383,10 +369,7 @@ export default class Collection {
|
|
|
383
369
|
const nested = Collection.assureObjectPath(obj, keys.slice(0, -1))
|
|
384
370
|
const finalKey = keys[keys.length-1]
|
|
385
371
|
|
|
386
|
-
|
|
387
|
-
if(finalKey === "__proto__" || finalKey === "constructor" || finalKey === "prototype") {
|
|
388
|
-
throw Sass.new(`Dangerous key "${finalKey}" not allowed in object path`)
|
|
389
|
-
}
|
|
372
|
+
Valid.prototypePollutionProtection([finalKey])
|
|
390
373
|
|
|
391
374
|
nested[finalKey] = value
|
|
392
375
|
}
|
|
@@ -474,7 +457,6 @@ export default class Collection {
|
|
|
474
457
|
* @returns {Promise<object>} The allocated object
|
|
475
458
|
*/
|
|
476
459
|
static async allocateObject(source, spec) {
|
|
477
|
-
// Data
|
|
478
460
|
const workSource = [],
|
|
479
461
|
workSpec = [],
|
|
480
462
|
result = {}
|
|
@@ -516,4 +498,65 @@ export default class Collection {
|
|
|
516
498
|
return result
|
|
517
499
|
}
|
|
518
500
|
|
|
501
|
+
static flattenObjectArray(objects) {
|
|
502
|
+
const req = "Array"
|
|
503
|
+
const type = Data.typeOf(objects)
|
|
504
|
+
|
|
505
|
+
Valid.type(objects, req, `Invalid objects array. Expected '${req}', got '${type}'`)
|
|
506
|
+
|
|
507
|
+
return objects.reduce((acc, curr) => {
|
|
508
|
+
const elemType = Data.typeOf(curr)
|
|
509
|
+
|
|
510
|
+
if(!Data.isPlainObject(curr))
|
|
511
|
+
throw Sass.new(`Invalid array element. Expected plain object, got '${elemType}'`)
|
|
512
|
+
|
|
513
|
+
Valid.prototypePollutionProtection(Object.keys(curr))
|
|
514
|
+
|
|
515
|
+
Object.entries(curr).forEach(([key, value]) => {
|
|
516
|
+
if(!acc[key])
|
|
517
|
+
acc[key] = []
|
|
518
|
+
|
|
519
|
+
acc[key].push(value)
|
|
520
|
+
})
|
|
521
|
+
|
|
522
|
+
return acc
|
|
523
|
+
}, {})
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
static trimArray(arr, except=[]) {
|
|
527
|
+
Valid.type(arr, "Array")
|
|
528
|
+
Valid.type(except, "Array")
|
|
529
|
+
|
|
530
|
+
Collection.trimArrayLeft(arr, except)
|
|
531
|
+
Collection.trimArrayRight(arr, except)
|
|
532
|
+
|
|
533
|
+
return arr
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
static trimArrayRight(arr, except=[]) {
|
|
537
|
+
Valid.type(arr, "Array")
|
|
538
|
+
Valid.type(except, "Array")
|
|
539
|
+
|
|
540
|
+
arr.reverse()
|
|
541
|
+
Collection.trimArrayLeft(arr, except)
|
|
542
|
+
arr.reverse()
|
|
543
|
+
|
|
544
|
+
return arr
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
static trimArrayLeft(arr, except=[]) {
|
|
548
|
+
Valid.type(arr, "Array")
|
|
549
|
+
Valid.type(except, "Array")
|
|
550
|
+
|
|
551
|
+
while(arr.length > 0) {
|
|
552
|
+
const value = arr[0]
|
|
553
|
+
|
|
554
|
+
if(value || except.includes(value))
|
|
555
|
+
break
|
|
556
|
+
|
|
557
|
+
arr.shift()
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return arr
|
|
561
|
+
}
|
|
519
562
|
}
|
package/src/lib/Data.js
CHANGED
|
@@ -323,19 +323,6 @@ export default class Data {
|
|
|
323
323
|
}, {})
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
/**
|
|
327
|
-
* Checks if all elements in an array are strings.
|
|
328
|
-
*
|
|
329
|
-
* @param {Array} arr - The array to check.
|
|
330
|
-
* @returns {boolean} Returns true if all elements are strings, false otherwise.
|
|
331
|
-
* @example
|
|
332
|
-
* uniformStringArray(['a', 'b', 'c']) // returns true
|
|
333
|
-
* uniformStringArray(['a', 1, 'c']) // returns false
|
|
334
|
-
*/
|
|
335
|
-
static uniformStringArray(arr) {
|
|
336
|
-
return Array.isArray(arr) && arr.every(item => typeof item === "string")
|
|
337
|
-
}
|
|
338
|
-
|
|
339
326
|
/**
|
|
340
327
|
* Filters an array asynchronously using a predicate function.
|
|
341
328
|
* Applies the predicate to all items in parallel and returns filtered results.
|
package/src/lib/FS.js
CHANGED
|
@@ -3,7 +3,6 @@ import path from "node:path"
|
|
|
3
3
|
import url from "node:url"
|
|
4
4
|
|
|
5
5
|
import Collection from "./Collection.js"
|
|
6
|
-
import Data from "./Data.js"
|
|
7
6
|
import DirectoryObject from "./DirectoryObject.js"
|
|
8
7
|
import FileObject from "./FileObject.js"
|
|
9
8
|
import Sass from "./Sass.js"
|
|
@@ -73,7 +72,7 @@ export default class FS {
|
|
|
73
72
|
(
|
|
74
73
|
(typeof glob === "string" && glob.length > 0) ||
|
|
75
74
|
(
|
|
76
|
-
|
|
75
|
+
Collection.isArrayUniform(glob, "string") &&
|
|
77
76
|
glob.length > 0
|
|
78
77
|
)
|
|
79
78
|
),
|
|
@@ -92,7 +91,7 @@ export default class FS {
|
|
|
92
91
|
|
|
93
92
|
if(
|
|
94
93
|
Array.isArray(globbyArray) &&
|
|
95
|
-
|
|
94
|
+
Collection.isArrayUniform(globbyArray, "string") &&
|
|
96
95
|
!globbyArray.length
|
|
97
96
|
)
|
|
98
97
|
throw Sass.new(
|
package/src/lib/Util.js
CHANGED
|
@@ -2,6 +2,8 @@ import {createHash} from "node:crypto"
|
|
|
2
2
|
import {performance} from "node:perf_hooks"
|
|
3
3
|
import {EventEmitter} from "node:events"
|
|
4
4
|
import Sass from "./Sass.js"
|
|
5
|
+
import Valid from "./Valid.js"
|
|
6
|
+
import Collection from "./Collection.js"
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Utility class providing common helper functions for string manipulation,
|
|
@@ -300,9 +302,18 @@ export default class Util {
|
|
|
300
302
|
}
|
|
301
303
|
|
|
302
304
|
static regexify(input, trim=true, flags=[]) {
|
|
305
|
+
Valid.type(input, "String")
|
|
306
|
+
Valid.type(trim, "Boolean")
|
|
307
|
+
Valid.type(flags, "Array")
|
|
308
|
+
|
|
309
|
+
Valid.assert(
|
|
310
|
+
flags.length === 0 ||
|
|
311
|
+
(flags.length > 0 && Collection.isArrayUniform(flags, "String")),
|
|
312
|
+
"All flags must be strings")
|
|
313
|
+
|
|
303
314
|
return new RegExp(
|
|
304
315
|
input
|
|
305
|
-
.split(
|
|
316
|
+
.split(/\r\n|\r|\n/)
|
|
306
317
|
.map(i => trim ? i.trim() : i)
|
|
307
318
|
.filter(i => trim ? Boolean(i) : true)
|
|
308
319
|
.join("")
|
package/src/lib/Valid.js
CHANGED
|
@@ -2,6 +2,7 @@ import _assert from "node:assert/strict"
|
|
|
2
2
|
|
|
3
3
|
import Sass from "./Sass.js"
|
|
4
4
|
import Data from "./Data.js"
|
|
5
|
+
import Collection from "./Collection.js"
|
|
5
6
|
|
|
6
7
|
export default class Valid {
|
|
7
8
|
/**
|
|
@@ -46,4 +47,15 @@ export default class Valid {
|
|
|
46
47
|
throw Sass.new(`${message}${arg ? `: ${arg}` : ""}`)
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
static #restrictedProto = ["__proto__", "constructor", "prototype"]
|
|
51
|
+
static prototypePollutionProtection(keys) {
|
|
52
|
+
Valid.type(keys, "String[]")
|
|
53
|
+
|
|
54
|
+
const oopsIDidItAgain = Collection.intersection(this.#restrictedProto, keys)
|
|
55
|
+
|
|
56
|
+
Valid.assert(
|
|
57
|
+
oopsIDidItAgain.length === 0,
|
|
58
|
+
`We don't pee in your pool, don't pollute ours with your ${String(oopsIDidItAgain)}`
|
|
59
|
+
)
|
|
60
|
+
}
|
|
49
61
|
}
|
|
@@ -138,7 +138,7 @@ export default class Collection {
|
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
140
|
* Maps an array through an async function, executing operations sequentially.
|
|
141
|
-
*
|
|
141
|
+
*
|
|
142
142
|
* Unlike Promise.all(array.map(fn)), this executes each async operation
|
|
143
143
|
* one at a time, maintaining order and preventing overwhelming external resources.
|
|
144
144
|
*
|
|
@@ -174,17 +174,14 @@ export default class Collection {
|
|
|
174
174
|
static isArrayUnique<T>(arr: Array<T>): Array<T>
|
|
175
175
|
|
|
176
176
|
/** Get the intersection of two arrays */
|
|
177
|
-
static
|
|
177
|
+
static intersection<T>(arr1: Array<T>, arr2: Array<T>): Array<T>
|
|
178
178
|
|
|
179
179
|
/** Check if two arrays have any elements in common */
|
|
180
|
-
static
|
|
180
|
+
static intersects<T>(arr1: Array<T>, arr2: Array<T>): boolean
|
|
181
181
|
|
|
182
182
|
/** Pad an array to a specified length */
|
|
183
183
|
static arrayPad<T>(arr: Array<T>, length: number, value: T, position?: number): Array<T>
|
|
184
184
|
|
|
185
|
-
/** Check if all elements in an array are strings */
|
|
186
|
-
static uniformStringArray(arr: Array<unknown>): arr is Array<string>
|
|
187
|
-
|
|
188
185
|
/** Filter an array asynchronously */
|
|
189
186
|
static asyncFilter<T>(arr: Array<T>, predicate: (item: T) => Promise<boolean>): Promise<Array<T>>
|
|
190
187
|
|
|
@@ -215,4 +212,89 @@ export default class Collection {
|
|
|
215
212
|
|
|
216
213
|
/** Allocate an object from a source array and spec */
|
|
217
214
|
static allocateObject(source: Array<unknown>, spec: Array<unknown> | ((source: Array<unknown>) => Promise<Array<unknown>> | Array<unknown>)): Promise<Record<string, unknown>>
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Flattens an array of plain objects into a single object where each key contains
|
|
218
|
+
* an array of all values for that key across all input objects.
|
|
219
|
+
*
|
|
220
|
+
* @param objects - Array of plain objects to flatten
|
|
221
|
+
* @returns Object with keys mapped to arrays of values from all input objects
|
|
222
|
+
*
|
|
223
|
+
* @throws {Sass} If objects is not an Array or if any element is not a plain object
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```typescript
|
|
227
|
+
* import { Collection } from '@gesslar/toolkit'
|
|
228
|
+
*
|
|
229
|
+
* const objects = [
|
|
230
|
+
* { name: 'Alice', age: 25 },
|
|
231
|
+
* { name: 'Bob', age: 30 },
|
|
232
|
+
* { name: 'Charlie', age: 35 }
|
|
233
|
+
* ]
|
|
234
|
+
*
|
|
235
|
+
* const result = Collection.flattenObjectArray(objects)
|
|
236
|
+
* // result: { name: ['Alice', 'Bob', 'Charlie'], age: [25, 30, 35] }
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
static flattenObjectArray(objects: Array<Record<string, unknown>>): Record<string, Array<unknown>>
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Trims falsy values from both ends of an array.
|
|
243
|
+
*
|
|
244
|
+
* @param arr - The array to trim
|
|
245
|
+
* @param except - Array of values to exclude from trimming (default: [])
|
|
246
|
+
* @returns The trimmed array (modified in place)
|
|
247
|
+
*
|
|
248
|
+
* @throws {Sass} If arr or except is not an Array
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```typescript
|
|
252
|
+
* import { Collection } from '@gesslar/toolkit'
|
|
253
|
+
*
|
|
254
|
+
* const arr = [null, 0, 1, 2, "", undefined]
|
|
255
|
+
* Collection.trimArray(arr)
|
|
256
|
+
* console.log(arr) // [1, 2]
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
static trimArray<T>(arr: Array<T>, except?: Array<T>): Array<T>
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Trims falsy values from the right end of an array.
|
|
263
|
+
*
|
|
264
|
+
* @param arr - The array to trim
|
|
265
|
+
* @param except - Array of values to exclude from trimming (default: [])
|
|
266
|
+
* @returns The trimmed array (modified in place)
|
|
267
|
+
*
|
|
268
|
+
* @throws {Sass} If arr or except is not an Array
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```typescript
|
|
272
|
+
* import { Collection } from '@gesslar/toolkit'
|
|
273
|
+
*
|
|
274
|
+
* const arr = [1, "", undefined]
|
|
275
|
+
* Collection.trimArrayRight(arr)
|
|
276
|
+
* console.log(arr) // [1]
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
static trimArrayRight<T>(arr: Array<T>, except?: Array<T>): Array<T>
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Trims falsy values from the left end of an array.
|
|
283
|
+
*
|
|
284
|
+
* @param arr - The array to trim
|
|
285
|
+
* @param except - Array of values to exclude from trimming (default: [])
|
|
286
|
+
* @returns The trimmed array (modified in place)
|
|
287
|
+
*
|
|
288
|
+
* @throws {Sass} If arr or except is not an Array
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```typescript
|
|
292
|
+
* import { Collection } from '@gesslar/toolkit'
|
|
293
|
+
*
|
|
294
|
+
* const arr = [null, undefined, "value"]
|
|
295
|
+
* Collection.trimArrayLeft(arr)
|
|
296
|
+
* console.log(arr) // ["value"]
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
static trimArrayLeft<T>(arr: Array<T>, except?: Array<T>): Array<T>
|
|
218
300
|
}
|
package/src/types/Data.d.ts
CHANGED
|
@@ -125,9 +125,6 @@ export default class Data {
|
|
|
125
125
|
/** Deeply merge objects */
|
|
126
126
|
static mergeObject<T extends Record<string, any>>(...sources: Array<T>): T
|
|
127
127
|
|
|
128
|
-
/** Check if all elements in an array are strings */
|
|
129
|
-
static uniformStringArray(arr: Array<unknown>): arr is Array<string>
|
|
130
|
-
|
|
131
128
|
/** Filter an array asynchronously */
|
|
132
129
|
static asyncFilter<T>(arr: Array<T>, predicate: (item: T) => Promise<boolean>): Promise<Array<T>>
|
|
133
130
|
|
package/src/types/Util.d.ts
CHANGED
|
@@ -224,10 +224,15 @@ declare class Util {
|
|
|
224
224
|
* them to be written across multiple lines with proper formatting and indentation.
|
|
225
225
|
* The resulting regex is functionally identical to writing it as a single line.
|
|
226
226
|
*
|
|
227
|
-
* @param input - Multiline string containing the regex pattern
|
|
227
|
+
* @param input - Multiline string containing the regex pattern (required)
|
|
228
228
|
* @param trim - Whether to trim whitespace from each line (default: true)
|
|
229
229
|
* @param flags - Array of regex flags to apply (default: [])
|
|
230
230
|
* @returns A new RegExp object with the processed pattern
|
|
231
|
+
*
|
|
232
|
+
* @throws Will throw if input is not a string
|
|
233
|
+
* @throws Will throw if trim is not a boolean
|
|
234
|
+
* @throws Will throw if flags is not an array
|
|
235
|
+
* @throws Will throw if flags contains non-string elements
|
|
231
236
|
*
|
|
232
237
|
* @example
|
|
233
238
|
* ```typescript
|
package/src/types/Valid.d.ts
CHANGED
|
@@ -7,4 +7,7 @@ export default class Valid {
|
|
|
7
7
|
|
|
8
8
|
/** Assert a condition */
|
|
9
9
|
static assert(condition: boolean, message: string, arg?: number | null): void
|
|
10
|
+
|
|
11
|
+
/** Protect against prototype pollution by checking for dangerous keys */
|
|
12
|
+
static prototypePollutionProtection(keys: string[]): void
|
|
10
13
|
}
|