opticedge-cloud-utils 1.1.3 → 1.1.5
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/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/parser.d.ts +2 -0
- package/dist/parser.js +13 -0
- package/dist/regex.d.ts +12 -1
- package/dist/regex.js +18 -2
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/parser.ts +9 -0
- package/src/regex.ts +18 -2
- package/tests/parser.test.ts +26 -0
- package/tests/regex.test.ts +53 -8
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ __exportStar(require("./tw/utils"), exports);
|
|
|
21
21
|
__exportStar(require("./tw/wallet"), exports);
|
|
22
22
|
__exportStar(require("./auth"), exports);
|
|
23
23
|
__exportStar(require("./env"), exports);
|
|
24
|
+
__exportStar(require("./parser"), exports);
|
|
24
25
|
__exportStar(require("./regex"), exports);
|
|
25
26
|
__exportStar(require("./secrets"), exports);
|
|
26
27
|
__exportStar(require("./task"), exports);
|
package/dist/parser.d.ts
ADDED
package/dist/parser.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toNumber = void 0;
|
|
4
|
+
// Helper: accept number or numeric-string, return number or null
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
const toNumber = (v) => {
|
|
7
|
+
if (typeof v === 'number' && Number.isFinite(v))
|
|
8
|
+
return v;
|
|
9
|
+
if (typeof v === 'string' && /^\d+$/.test(v))
|
|
10
|
+
return Number(v);
|
|
11
|
+
return null;
|
|
12
|
+
};
|
|
13
|
+
exports.toNumber = toNumber;
|
package/dist/regex.d.ts
CHANGED
|
@@ -1 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Escape user input so it can be safely used as a regex pattern string.
|
|
3
|
+
*
|
|
4
|
+
* - Escapes regex metacharacters.
|
|
5
|
+
* - Replaces any run of whitespace with the token `\s+` so searches tolerate variable whitespace.
|
|
6
|
+
* - Caps input length to avoid pathological long-input ReDoS vectors (default cap = 100).
|
|
7
|
+
*
|
|
8
|
+
* @param input - user-provided string to escape
|
|
9
|
+
* @param maxLength - maximum number of characters to consider from input (default 100)
|
|
10
|
+
* @returns a safe regex pattern string (do NOT wrap with // when passing to Mongo $regex)
|
|
11
|
+
*/
|
|
12
|
+
export declare function escapeForRegex(input: string, maxLength?: number): string;
|
package/dist/regex.js
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.escapeForRegex = escapeForRegex;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Escape user input so it can be safely used as a regex pattern string.
|
|
6
|
+
*
|
|
7
|
+
* - Escapes regex metacharacters.
|
|
8
|
+
* - Replaces any run of whitespace with the token `\s+` so searches tolerate variable whitespace.
|
|
9
|
+
* - Caps input length to avoid pathological long-input ReDoS vectors (default cap = 100).
|
|
10
|
+
*
|
|
11
|
+
* @param input - user-provided string to escape
|
|
12
|
+
* @param maxLength - maximum number of characters to consider from input (default 100)
|
|
13
|
+
* @returns a safe regex pattern string (do NOT wrap with // when passing to Mongo $regex)
|
|
14
|
+
*/
|
|
15
|
+
function escapeForRegex(input, maxLength = 100) {
|
|
16
|
+
const safeStr = String(input ?? '');
|
|
17
|
+
const capped = safeStr.length > maxLength ? safeStr.slice(0, maxLength) : safeStr;
|
|
18
|
+
// escape regex metacharacters: . * + ? ^ $ { } ( ) | [ ] \ /
|
|
19
|
+
const escaped = capped.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
20
|
+
// convert any whitespace run to the regex token \s+ (as a string)
|
|
21
|
+
return escaped.replace(/\s+/g, '\\s+');
|
|
6
22
|
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
package/src/parser.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Helper: accept number or numeric-string, return number or null
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3
|
+
const toNumber = (v: any): number | null => {
|
|
4
|
+
if (typeof v === 'number' && Number.isFinite(v)) return v
|
|
5
|
+
if (typeof v === 'string' && /^\d+$/.test(v)) return Number(v)
|
|
6
|
+
return null
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export { toNumber }
|
package/src/regex.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Escape user input so it can be safely used as a regex pattern string.
|
|
3
|
+
*
|
|
4
|
+
* - Escapes regex metacharacters.
|
|
5
|
+
* - Replaces any run of whitespace with the token `\s+` so searches tolerate variable whitespace.
|
|
6
|
+
* - Caps input length to avoid pathological long-input ReDoS vectors (default cap = 100).
|
|
7
|
+
*
|
|
8
|
+
* @param input - user-provided string to escape
|
|
9
|
+
* @param maxLength - maximum number of characters to consider from input (default 100)
|
|
10
|
+
* @returns a safe regex pattern string (do NOT wrap with // when passing to Mongo $regex)
|
|
11
|
+
*/
|
|
12
|
+
export function escapeForRegex(input: string, maxLength = 100): string {
|
|
13
|
+
const safeStr = String(input ?? '')
|
|
14
|
+
const capped = safeStr.length > maxLength ? safeStr.slice(0, maxLength) : safeStr
|
|
15
|
+
// escape regex metacharacters: . * + ? ^ $ { } ( ) | [ ] \ /
|
|
16
|
+
const escaped = capped.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
17
|
+
// convert any whitespace run to the regex token \s+ (as a string)
|
|
18
|
+
return escaped.replace(/\s+/g, '\\s+')
|
|
3
19
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { toNumber } from '../src'
|
|
2
|
+
|
|
3
|
+
describe('toNumber', () => {
|
|
4
|
+
it('returns the same number when input is a finite number', () => {
|
|
5
|
+
expect(toNumber(123)).toBe(123)
|
|
6
|
+
expect(toNumber(0)).toBe(0)
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it('returns number when input is a numeric string', () => {
|
|
10
|
+
expect(toNumber('456')).toBe(456)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('returns null for non-numeric strings', () => {
|
|
14
|
+
expect(toNumber('abc')).toBeNull()
|
|
15
|
+
expect(toNumber('123abc')).toBeNull()
|
|
16
|
+
expect(toNumber('')).toBeNull()
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('returns null for non-numbers', () => {
|
|
20
|
+
expect(toNumber(NaN)).toBeNull()
|
|
21
|
+
expect(toNumber(Infinity)).toBeNull()
|
|
22
|
+
expect(toNumber(undefined)).toBeNull()
|
|
23
|
+
expect(toNumber(null)).toBeNull()
|
|
24
|
+
expect(toNumber({})).toBeNull()
|
|
25
|
+
})
|
|
26
|
+
})
|
package/tests/regex.test.ts
CHANGED
|
@@ -1,24 +1,69 @@
|
|
|
1
|
+
// tests/regex.test.ts
|
|
1
2
|
import { escapeForRegex } from '../src/regex'
|
|
2
3
|
|
|
3
|
-
describe('
|
|
4
|
-
it('escapes regex special characters', () => {
|
|
4
|
+
describe('escapeForRegex', () => {
|
|
5
|
+
it('escapes regex special characters (including backslash)', () => {
|
|
5
6
|
const input = 'Pikachu.$^*+?()[]{}|\\'
|
|
6
7
|
const expected = 'Pikachu\\.\\$\\^\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\'
|
|
7
8
|
expect(escapeForRegex(input)).toBe(expected)
|
|
8
9
|
})
|
|
9
10
|
|
|
10
|
-
it('
|
|
11
|
+
it('replaces whitespace runs with \\s+ and escapes other metachars', () => {
|
|
12
|
+
const input = 'Charizard (Holo Rare)' // multiple spaces inside
|
|
13
|
+
const expected = 'Charizard\\s+\\(Holo\\s+Rare\\)'
|
|
14
|
+
expect(escapeForRegex(input)).toBe(expected)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('leaves plain alphanumerics unchanged', () => {
|
|
11
18
|
const input = 'Charmander123'
|
|
12
19
|
expect(escapeForRegex(input)).toBe('Charmander123')
|
|
13
20
|
})
|
|
14
21
|
|
|
15
|
-
it('
|
|
22
|
+
it('converts tabs and single spaces to \\s+ and escapes dots', () => {
|
|
23
|
+
const input = 'Lt. Surge\tPikachu'
|
|
24
|
+
const expected = 'Lt\\.\\s+Surge\\s+Pikachu'
|
|
25
|
+
expect(escapeForRegex(input)).toBe(expected)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('truncates input when maxLength is passed', () => {
|
|
29
|
+
const long = 'a'.repeat(200)
|
|
30
|
+
// override maxLength to 50 for this test
|
|
31
|
+
expect(escapeForRegex(long, 50)).toBe('a'.repeat(50))
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('applies default cap of 100 characters when input is longer and contains no metachars', () => {
|
|
35
|
+
const long = 'b'.repeat(150)
|
|
36
|
+
const out = escapeForRegex(long) // default cap = 100
|
|
37
|
+
expect(out).toBe('b'.repeat(100))
|
|
38
|
+
expect(out.length).toBe(100)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('handles empty string', () => {
|
|
16
42
|
expect(escapeForRegex('')).toBe('')
|
|
17
43
|
})
|
|
18
44
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
45
|
+
// -----------------------------
|
|
46
|
+
// NEW: coverage for safeStr branch
|
|
47
|
+
// -----------------------------
|
|
48
|
+
it('handles undefined input (covers input ?? "")', () => {
|
|
49
|
+
// call with undefined; TypeScript may complain so cast to any in test
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
51
|
+
expect(escapeForRegex(undefined as any)).toBe('')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('handles null input (covers input ?? "")', () => {
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
56
|
+
expect(escapeForRegex(null as any)).toBe('')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('coerces non-string input to string and escapes metachars if present', () => {
|
|
60
|
+
// number becomes "42"
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
62
|
+
expect(escapeForRegex(42 as any)).toBe('42')
|
|
63
|
+
|
|
64
|
+
// object coerces to "[object Object]" and special chars will be escaped if present
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
|
+
const objInput = { toString: () => 'X(1) Y' } as any
|
|
67
|
+
expect(escapeForRegex(objInput)).toBe('X\\(1\\)\\s+Y')
|
|
23
68
|
})
|
|
24
69
|
})
|