@scalar/helpers 0.1.2 → 0.2.0
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/CHANGELOG.md +14 -0
- package/dist/array/sort-by-order.d.ts +47 -0
- package/dist/array/sort-by-order.d.ts.map +1 -0
- package/dist/array/sort-by-order.js +19 -0
- package/dist/array/sort-by-order.js.map +7 -0
- package/dist/object/prevent-pollution.d.ts +17 -0
- package/dist/object/prevent-pollution.d.ts.map +1 -0
- package/dist/object/prevent-pollution.js +11 -0
- package/dist/object/prevent-pollution.js.map +7 -0
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @scalar/helpers
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#7477](https://github.com/scalar/scalar/pull/7477) [`9ec8adf`](https://github.com/scalar/scalar/commit/9ec8adfea017333dee5bc3949104232f7dc57f4a) Thanks [@DemonHa](https://github.com/DemonHa)! - fix: correctly sort documents on the workspace
|
|
8
|
+
|
|
9
|
+
## 0.1.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#7387](https://github.com/scalar/scalar/pull/7387) [`bfd814a`](https://github.com/scalar/scalar/commit/bfd814a4219660face190041cc4845182b56ab03) Thanks [@geoffgscott](https://github.com/geoffgscott)! - hotfix: patch exports from build tooling bug
|
|
14
|
+
|
|
15
|
+
- [#7416](https://github.com/scalar/scalar/pull/7416) [`86f028d`](https://github.com/scalar/scalar/commit/86f028deb0b456f923edd261f5f4b0fa9b616b7d) Thanks [@amritk](https://github.com/amritk)! - feat: add update method to client v2
|
|
16
|
+
|
|
3
17
|
## 0.1.2
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Immutably sorts an array based on a given custom order, as specified by a separate list of identifiers.
|
|
3
|
+
*
|
|
4
|
+
* Note: Make sure that the identifier is unique for each item in the array.
|
|
5
|
+
* If the identifier is not unique, only the last occurrence of the identifier will be sorted.
|
|
6
|
+
* Any other elements will be overridden by the last occurrence of the identifier.
|
|
7
|
+
*
|
|
8
|
+
* This function efficiently arranges elements of an input array so that items whose IDs (obtained via the `getId` callback)
|
|
9
|
+
* match the order array will appear first, strictly in the order specified. Items not found in the order array will be
|
|
10
|
+
* appended after, maintaining their original order.
|
|
11
|
+
*
|
|
12
|
+
* This is a flexible utility: the identifier can be extracted from any data structure via the `getId` callback,
|
|
13
|
+
* and any primitive (string, number, symbol, etc.) can serve as the identifier type.
|
|
14
|
+
* Sorting is O(n) with respect to the array size, making it performant even for large arrays.
|
|
15
|
+
*
|
|
16
|
+
* @template T - The type of array elements.
|
|
17
|
+
* @template N - The type of values in the order array and the identifier returned by the getId callback.
|
|
18
|
+
* @param arr - The array to be sorted.
|
|
19
|
+
* @param order - Array specifying the desired sequence (contains identifiers returned by getId).
|
|
20
|
+
* @param getId - A callback to extract the unique identifier from each array element.
|
|
21
|
+
* @returns A new array sorted according to the order provided, with unmatched elements following.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Sorting an array of objects:
|
|
25
|
+
* const items = [
|
|
26
|
+
* { id: 'a', name: 'Alpha' },
|
|
27
|
+
* { id: 'b', name: 'Bravo' },
|
|
28
|
+
* { id: 'c', name: 'Charlie' }
|
|
29
|
+
* ];
|
|
30
|
+
* const order = ['c', 'a'];
|
|
31
|
+
* const sorted = sortByOrder(items, order, item => item.id);
|
|
32
|
+
* // Result:
|
|
33
|
+
* // [
|
|
34
|
+
* // { id: 'c', name: 'Charlie' },
|
|
35
|
+
* // { id: 'a', name: 'Alpha' },
|
|
36
|
+
* // { id: 'b', name: 'Bravo' }
|
|
37
|
+
* // ]
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Sorting an array of primitive values:
|
|
41
|
+
* const input = ['a', 'b', 'c', 'd'];
|
|
42
|
+
* const order = ['c', 'a'];
|
|
43
|
+
* sortByOrder(input, order, item => item);
|
|
44
|
+
* // Result: ['c', 'a', 'b', 'd']
|
|
45
|
+
*/
|
|
46
|
+
export declare function sortByOrder<T, N>(arr: T[], order: N[], getId: (item: T) => N): T[];
|
|
47
|
+
//# sourceMappingURL=sort-by-order.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sort-by-order.d.ts","sourceRoot":"","sources":["../../src/array/sort-by-order.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAkBlF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function sortByOrder(arr, order, getId) {
|
|
2
|
+
const orderMap = /* @__PURE__ */ new Map();
|
|
3
|
+
order.forEach((e, idx) => orderMap.set(e, idx));
|
|
4
|
+
const sorted = [];
|
|
5
|
+
const untagged = [];
|
|
6
|
+
arr.forEach((e) => {
|
|
7
|
+
const sortedIdx = orderMap.get(getId(e));
|
|
8
|
+
if (sortedIdx === void 0) {
|
|
9
|
+
untagged.push(e);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
sorted[sortedIdx] = e;
|
|
13
|
+
});
|
|
14
|
+
return [...sorted.filter((it) => it !== void 0), ...untagged];
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
sortByOrder
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=sort-by-order.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/array/sort-by-order.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Immutably sorts an array based on a given custom order, as specified by a separate list of identifiers.\n *\n * Note: Make sure that the identifier is unique for each item in the array.\n * If the identifier is not unique, only the last occurrence of the identifier will be sorted.\n * Any other elements will be overridden by the last occurrence of the identifier.\n *\n * This function efficiently arranges elements of an input array so that items whose IDs (obtained via the `getId` callback)\n * match the order array will appear first, strictly in the order specified. Items not found in the order array will be\n * appended after, maintaining their original order.\n *\n * This is a flexible utility: the identifier can be extracted from any data structure via the `getId` callback,\n * and any primitive (string, number, symbol, etc.) can serve as the identifier type.\n * Sorting is O(n) with respect to the array size, making it performant even for large arrays.\n *\n * @template T - The type of array elements.\n * @template N - The type of values in the order array and the identifier returned by the getId callback.\n * @param arr - The array to be sorted.\n * @param order - Array specifying the desired sequence (contains identifiers returned by getId).\n * @param getId - A callback to extract the unique identifier from each array element.\n * @returns A new array sorted according to the order provided, with unmatched elements following.\n *\n * @example\n * // Sorting an array of objects:\n * const items = [\n * { id: 'a', name: 'Alpha' },\n * { id: 'b', name: 'Bravo' },\n * { id: 'c', name: 'Charlie' }\n * ];\n * const order = ['c', 'a'];\n * const sorted = sortByOrder(items, order, item => item.id);\n * // Result:\n * // [\n * // { id: 'c', name: 'Charlie' },\n * // { id: 'a', name: 'Alpha' },\n * // { id: 'b', name: 'Bravo' }\n * // ]\n *\n * @example\n * // Sorting an array of primitive values:\n * const input = ['a', 'b', 'c', 'd'];\n * const order = ['c', 'a'];\n * sortByOrder(input, order, item => item);\n * // Result: ['c', 'a', 'b', 'd']\n */\nexport function sortByOrder<T, N>(arr: T[], order: N[], getId: (item: T) => N): T[] {\n // Map the order to keep a single lookup table\n const orderMap = new Map<N, number>()\n order.forEach((e, idx) => orderMap.set(e, idx))\n\n const sorted: T[] = []\n const untagged: T[] = []\n\n arr.forEach((e) => {\n const sortedIdx = orderMap.get(getId(e))\n if (sortedIdx === undefined) {\n untagged.push(e)\n return\n }\n sorted[sortedIdx] = e\n })\n\n return [...sorted.filter((it) => it !== undefined), ...untagged]\n}\n"],
|
|
5
|
+
"mappings": "AA6CO,SAAS,YAAkB,KAAU,OAAY,OAA4B;AAElF,QAAM,WAAW,oBAAI,IAAe;AACpC,QAAM,QAAQ,CAAC,GAAG,QAAQ,SAAS,IAAI,GAAG,GAAG,CAAC;AAE9C,QAAM,SAAc,CAAC;AACrB,QAAM,WAAgB,CAAC;AAEvB,MAAI,QAAQ,CAAC,MAAM;AACjB,UAAM,YAAY,SAAS,IAAI,MAAM,CAAC,CAAC;AACvC,QAAI,cAAc,QAAW;AAC3B,eAAS,KAAK,CAAC;AACf;AAAA,IACF;AACA,WAAO,SAAS,IAAI;AAAA,EACtB,CAAC;AAED,SAAO,CAAC,GAAG,OAAO,OAAO,CAAC,OAAO,OAAO,MAAS,GAAG,GAAG,QAAQ;AACjE;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates that a key is safe to use and does not pose a prototype pollution risk.
|
|
3
|
+
* Throws an error if a dangerous key is detected.
|
|
4
|
+
*
|
|
5
|
+
* @param key - The key to validate
|
|
6
|
+
* @param context - Optional context string to help identify where the validation failed
|
|
7
|
+
* @throws {Error} If the key matches a known prototype pollution vector
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* preventPollution('__proto__') // throws Error
|
|
12
|
+
* preventPollution('safeName') // passes
|
|
13
|
+
* preventPollution('constructor', 'operation update') // throws Error with context
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare const preventPollution: (key: string, context?: string) => void;
|
|
17
|
+
//# sourceMappingURL=prevent-pollution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prevent-pollution.d.ts","sourceRoot":"","sources":["../../src/object/prevent-pollution.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,EAAE,UAAU,MAAM,KAAG,IAQhE,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const PROTOTYPE_POLLUTION_KEYS = ["__proto__", "prototype", "constructor"];
|
|
2
|
+
const preventPollution = (key, context) => {
|
|
3
|
+
if (PROTOTYPE_POLLUTION_KEYS.includes(key)) {
|
|
4
|
+
const errorMessage = context ? `Prototype pollution key detected: "${key}" in ${context}` : `Prototype pollution key detected: "${key}"`;
|
|
5
|
+
throw new Error(errorMessage);
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
preventPollution
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=prevent-pollution.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/object/prevent-pollution.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * List of dangerous keys that can be used for prototype pollution attacks.\n * These keys should never be used as property names in dynamic object operations.\n */\nconst PROTOTYPE_POLLUTION_KEYS = ['__proto__', 'prototype', 'constructor'] as const\n\n/**\n * Validates that a key is safe to use and does not pose a prototype pollution risk.\n * Throws an error if a dangerous key is detected.\n *\n * @param key - The key to validate\n * @param context - Optional context string to help identify where the validation failed\n * @throws {Error} If the key matches a known prototype pollution vector\n *\n * @example\n * ```ts\n * preventPollution('__proto__') // throws Error\n * preventPollution('safeName') // passes\n * preventPollution('constructor', 'operation update') // throws Error with context\n * ```\n */\nexport const preventPollution = (key: string, context?: string): void => {\n if (PROTOTYPE_POLLUTION_KEYS.includes(key as never)) {\n const errorMessage = context\n ? `Prototype pollution key detected: \"${key}\" in ${context}`\n : `Prototype pollution key detected: \"${key}\"`\n\n throw new Error(errorMessage)\n }\n}\n"],
|
|
5
|
+
"mappings": "AAIA,MAAM,2BAA2B,CAAC,aAAa,aAAa,aAAa;AAiBlE,MAAM,mBAAmB,CAAC,KAAa,YAA2B;AACvE,MAAI,yBAAyB,SAAS,GAAY,GAAG;AACnD,UAAM,eAAe,UACjB,sCAAsC,GAAG,QAAQ,OAAO,KACxD,sCAAsC,GAAG;AAE7C,UAAM,IAAI,MAAM,YAAY;AAAA,EAC9B;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"helpers",
|
|
15
15
|
"js"
|
|
16
16
|
],
|
|
17
|
-
"version": "0.
|
|
17
|
+
"version": "0.2.0",
|
|
18
18
|
"engines": {
|
|
19
19
|
"node": ">=20"
|
|
20
20
|
},
|
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
"types": "./dist/array/*.d.ts",
|
|
28
28
|
"default": "./dist/array/*.js"
|
|
29
29
|
},
|
|
30
|
+
"./crypto/*": {
|
|
31
|
+
"import": "./dist/crypto/*.js",
|
|
32
|
+
"types": "./dist/crypto/*.d.ts",
|
|
33
|
+
"default": "./dist/crypto/*.js"
|
|
34
|
+
},
|
|
30
35
|
"./dom/*": {
|
|
31
36
|
"import": "./dist/dom/*.js",
|
|
32
37
|
"types": "./dist/dom/*.d.ts",
|
|
@@ -76,11 +81,6 @@
|
|
|
76
81
|
"import": "./dist/url/*.js",
|
|
77
82
|
"types": "./dist/url/*.d.ts",
|
|
78
83
|
"default": "./dist/url/*.js"
|
|
79
|
-
},
|
|
80
|
-
"./crypto/*": {
|
|
81
|
-
"import": "./dist/crypto/*.js",
|
|
82
|
-
"types": "./dist/crypto/*.d.ts",
|
|
83
|
-
"default": "./dist/crypto/*.js"
|
|
84
84
|
}
|
|
85
85
|
},
|
|
86
86
|
"files": [
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"jsdom": "26.1.0",
|
|
92
92
|
"vite": "7.1.11",
|
|
93
93
|
"vitest": "3.2.4",
|
|
94
|
-
"@scalar/build-tooling": "0.3.
|
|
94
|
+
"@scalar/build-tooling": "0.3.1"
|
|
95
95
|
},
|
|
96
96
|
"scripts": {
|
|
97
97
|
"build": "scalar-build-esbuild",
|