@memberjunction/global 6.2.0-edge.3 → 6.2.0-edge.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/ClassFactory.d.ts +16 -3
- package/dist/ClassFactory.d.ts.map +1 -1
- package/dist/ClassFactory.js +112 -48
- package/dist/ClassFactory.js.map +1 -1
- package/dist/DeepDiff.d.ts +2 -0
- package/dist/DeepDiff.d.ts.map +1 -1
- package/dist/DeepDiff.js +40 -38
- package/dist/DeepDiff.js.map +1 -1
- package/dist/ObjectCache.d.ts +1 -0
- package/dist/ObjectCache.d.ts.map +1 -1
- package/dist/ObjectCache.js +14 -22
- package/dist/ObjectCache.js.map +1 -1
- package/dist/SQLExpressionValidator.d.ts +36 -32
- package/dist/SQLExpressionValidator.d.ts.map +1 -1
- package/dist/SQLExpressionValidator.js +125 -117
- package/dist/SQLExpressionValidator.js.map +1 -1
- package/dist/SQLScreeningScanner.d.ts +91 -0
- package/dist/SQLScreeningScanner.d.ts.map +1 -0
- package/dist/SQLScreeningScanner.js +332 -0
- package/dist/SQLScreeningScanner.js.map +1 -0
- package/dist/__tests__/SQLExpressionValidator.security.test.js +176 -2
- package/dist/__tests__/SQLExpressionValidator.security.test.js.map +1 -1
- package/dist/__tests__/SQLScreeningScanner.test.d.ts +2 -0
- package/dist/__tests__/SQLScreeningScanner.test.d.ts.map +1 -0
- package/dist/__tests__/SQLScreeningScanner.test.js +172 -0
- package/dist/__tests__/SQLScreeningScanner.test.js.map +1 -0
- package/dist/__tests__/UUIDCollections.test.d.ts +2 -0
- package/dist/__tests__/UUIDCollections.test.d.ts.map +1 -0
- package/dist/__tests__/UUIDCollections.test.js +173 -0
- package/dist/__tests__/UUIDCollections.test.js.map +1 -0
- package/dist/__tests__/UUIDCompliance.test.d.ts +2 -1
- package/dist/__tests__/UUIDCompliance.test.d.ts.map +1 -1
- package/dist/__tests__/UUIDCompliance.test.js +290 -8
- package/dist/__tests__/UUIDCompliance.test.js.map +1 -1
- package/dist/__tests__/UUIDUtils.test.js +55 -0
- package/dist/__tests__/UUIDUtils.test.js.map +1 -1
- package/dist/__tests__/util.trimTrailingSlashes.test.d.ts +2 -0
- package/dist/__tests__/util.trimTrailingSlashes.test.d.ts.map +1 -0
- package/dist/__tests__/util.trimTrailingSlashes.test.js +23 -0
- package/dist/__tests__/util.trimTrailingSlashes.test.js.map +1 -0
- package/dist/__tests__/util.valuesEqual.test.d.ts +2 -0
- package/dist/__tests__/util.valuesEqual.test.d.ts.map +1 -0
- package/dist/__tests__/util.valuesEqual.test.js +37 -0
- package/dist/__tests__/util.valuesEqual.test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/util/UUIDCollections.d.ts +111 -0
- package/dist/util/UUIDCollections.d.ts.map +1 -0
- package/dist/util/UUIDCollections.js +163 -0
- package/dist/util/UUIDCollections.js.map +1 -0
- package/dist/util/UUIDUtils.d.ts.map +1 -1
- package/dist/util/UUIDUtils.js +58 -3
- package/dist/util/UUIDUtils.js.map +1 -1
- package/dist/util.d.ts +39 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +58 -0
- package/dist/util.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export * from './ClassUtils.js';
|
|
|
12
12
|
export * from './util/PatternUtils.js';
|
|
13
13
|
export * from './util/ResourcePatternUtils.js';
|
|
14
14
|
export * from './util/UUIDUtils.js';
|
|
15
|
+
export * from './util/UUIDCollections.js';
|
|
15
16
|
export * from './util/CronUtils.js';
|
|
16
17
|
export * from './util/SerializationUtils.js';
|
|
17
18
|
export * from './util/BinaryEncoding.js';
|
|
@@ -19,6 +20,7 @@ export * from './ValidationTypes.js';
|
|
|
19
20
|
export * from './JSONValidator.js';
|
|
20
21
|
export * from './SafeExpressionEvaluator.js';
|
|
21
22
|
export * from './fieldRules/index.js';
|
|
23
|
+
export * from './SQLScreeningScanner.js';
|
|
22
24
|
export * from './SQLExpressionValidator.js';
|
|
23
25
|
export * from './warningManager.js';
|
|
24
26
|
export * from './EncryptionUtils.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAChE,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,cAAc,CAAA;AAC5B,cAAc,0BAA0B,CAAA;AACxC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAEtC,2DAA2D;AAC3D,oCAAoC;AAEpC,0BAA0B;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,+BAA+B,CAAA;AAE7C,6DAA6D;AAC7D,oCAAoC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAChE,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,cAAc,CAAA;AAC5B,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAEtC,2DAA2D;AAC3D,oCAAoC;AAEpC,0BAA0B;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,+BAA+B,CAAA;AAE7C,6DAA6D;AAC7D,oCAAoC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/** A UUID as it arrives from data: possibly upper-case, padded, or missing. */
|
|
2
|
+
export type UUIDInput = string | null | undefined;
|
|
3
|
+
/** Reads the UUID used to match an item. */
|
|
4
|
+
export type UUIDSelector<T> = (item: T) => UUIDInput;
|
|
5
|
+
/**
|
|
6
|
+
* A `Set` of UUIDs that matches case- and whitespace-insensitively. Every ID is normalized on
|
|
7
|
+
* insert and on lookup, so `Has('A1B2…')` finds an ID added as `'a1b2…'`. Iterates normalized IDs.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const selected = new UUIDSet(selectedIds);
|
|
11
|
+
* const picked = rows.filter(r => selected.Has(r.ID));
|
|
12
|
+
*/
|
|
13
|
+
export declare class UUIDSet implements Iterable<string> {
|
|
14
|
+
private readonly ids;
|
|
15
|
+
constructor(ids?: Iterable<UUIDInput>);
|
|
16
|
+
/** Adds an ID. Returns this set, for chaining. */
|
|
17
|
+
Add(id: UUIDInput): this;
|
|
18
|
+
/** True when the ID is in the set, ignoring case and surrounding whitespace. */
|
|
19
|
+
Has(id: UUIDInput): boolean;
|
|
20
|
+
/** Removes an ID. Returns true when it was present. */
|
|
21
|
+
Delete(id: UUIDInput): boolean;
|
|
22
|
+
Clear(): void;
|
|
23
|
+
/** Number of distinct IDs (case variants of one ID count once). */
|
|
24
|
+
get Size(): number;
|
|
25
|
+
[Symbol.iterator](): Iterator<string>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A `Map` keyed by UUID that matches case- and whitespace-insensitively. Every key is normalized
|
|
29
|
+
* on insert and on lookup, so a value stored under `'a1b2…'` is found with `Get('A1B2…')`.
|
|
30
|
+
* Iterates `[normalizedKey, value]` pairs.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const roleNames = new UUIDMap(roles.map(r => [r.ID, r.Name]));
|
|
34
|
+
* const name = roleNames.Get(permission.RoleID);
|
|
35
|
+
*/
|
|
36
|
+
export declare class UUIDMap<V> implements Iterable<[string, V]> {
|
|
37
|
+
private readonly entries;
|
|
38
|
+
constructor(entries?: Iterable<readonly [UUIDInput, V]>);
|
|
39
|
+
/** The value stored for the ID, or undefined. */
|
|
40
|
+
Get(id: UUIDInput): V | undefined;
|
|
41
|
+
/** Stores a value for the ID, replacing any value stored under a case variant of it. */
|
|
42
|
+
Set(id: UUIDInput, value: V): this;
|
|
43
|
+
Has(id: UUIDInput): boolean;
|
|
44
|
+
Delete(id: UUIDInput): boolean;
|
|
45
|
+
Clear(): void;
|
|
46
|
+
get Size(): number;
|
|
47
|
+
/** Normalized keys. */
|
|
48
|
+
Keys(): IterableIterator<string>;
|
|
49
|
+
Values(): IterableIterator<V>;
|
|
50
|
+
[Symbol.iterator](): Iterator<[string, V]>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The items whose ID appears in `ids`, in `items` order. Linear: builds one {@link UUIDSet}
|
|
54
|
+
* (or reuses the one passed) instead of scanning `ids` once per item.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* const moved = FilterByUUIDs(this.Dashboards, droppedIds);
|
|
58
|
+
* const pending = FilterByUUIDs(artifacts, loadedIds, a => a.artifactId);
|
|
59
|
+
*/
|
|
60
|
+
export declare function FilterByUUIDs<T extends {
|
|
61
|
+
ID: UUIDInput;
|
|
62
|
+
}>(items: readonly T[], ids: Iterable<UUIDInput> | UUIDSet): T[];
|
|
63
|
+
export declare function FilterByUUIDs<T>(items: readonly T[], ids: Iterable<UUIDInput> | UUIDSet, getId: UUIDSelector<T>): T[];
|
|
64
|
+
/**
|
|
65
|
+
* The items whose ID does NOT appear in `ids`, in `items` order. The complement of
|
|
66
|
+
* {@link FilterByUUIDs}, with the same linear cost.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* const withoutPermission = ExcludeByUUIDs(roles, existingPermissions.map(p => p.RoleID));
|
|
70
|
+
*/
|
|
71
|
+
export declare function ExcludeByUUIDs<T extends {
|
|
72
|
+
ID: UUIDInput;
|
|
73
|
+
}>(items: readonly T[], ids: Iterable<UUIDInput> | UUIDSet): T[];
|
|
74
|
+
export declare function ExcludeByUUIDs<T>(items: readonly T[], ids: Iterable<UUIDInput> | UUIDSet, getId: UUIDSelector<T>): T[];
|
|
75
|
+
/**
|
|
76
|
+
* How many items share each ID. Look a count up with `.Get(id) ?? 0`; any casing works.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* const perEntity = CountByUUID(relationships, r => r.RelatedEntityID);
|
|
80
|
+
* const shared = (perEntity.Get(rel.RelatedEntityID) ?? 0) > 1;
|
|
81
|
+
*/
|
|
82
|
+
export declare function CountByUUID<T extends {
|
|
83
|
+
ID: UUIDInput;
|
|
84
|
+
}>(items: Iterable<T>): UUIDMap<number>;
|
|
85
|
+
export declare function CountByUUID<T>(items: Iterable<T>, getId: UUIDSelector<T>): UUIDMap<number>;
|
|
86
|
+
/**
|
|
87
|
+
* The items grouped by ID, each group in `items` order. Look a group up with `.Get(id) ?? []`;
|
|
88
|
+
* any casing works. Linear, where `items.filter(x => UUIDsEqual(x.ParentID, id))` run once per
|
|
89
|
+
* `id` scans the whole list every time.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* const rolesByUser = GroupByUUID(userRoles, r => r.UserID);
|
|
93
|
+
* const roles = rolesByUser.Get(user.ID) ?? [];
|
|
94
|
+
*/
|
|
95
|
+
export declare function GroupByUUID<T extends {
|
|
96
|
+
ID: UUIDInput;
|
|
97
|
+
}>(items: Iterable<T>): UUIDMap<T[]>;
|
|
98
|
+
export declare function GroupByUUID<T>(items: Iterable<T>, getId: UUIDSelector<T>): UUIDMap<T[]>;
|
|
99
|
+
/**
|
|
100
|
+
* The items keyed by ID, for repeated lookups. When two items share an ID, the FIRST one wins —
|
|
101
|
+
* the same answer `items.find(x => UUIDsEqual(x.ID, id))` would give.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* const usersByID = IndexByUUID(this.users);
|
|
105
|
+
* const owner = usersByID.Get(record.OwnerID);
|
|
106
|
+
*/
|
|
107
|
+
export declare function IndexByUUID<T extends {
|
|
108
|
+
ID: UUIDInput;
|
|
109
|
+
}>(items: Iterable<T>): UUIDMap<T>;
|
|
110
|
+
export declare function IndexByUUID<T>(items: Iterable<T>, getId: UUIDSelector<T>): UUIDMap<T>;
|
|
111
|
+
//# sourceMappingURL=UUIDCollections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UUIDCollections.d.ts","sourceRoot":"","sources":["../../src/util/UUIDCollections.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview UUID-keyed collections and set-based helpers for MemberJunction
|
|
3
|
+
*
|
|
4
|
+
* `UUIDsEqual` compares two IDs, so code that matches one list of records against another list of
|
|
5
|
+
* IDs tends to be written as a nested scan — for every item, `.some(id => UUIDsEqual(...))` over the
|
|
6
|
+
* other list. That is O(n x m), and every mismatched comparison lowercases both strings.
|
|
7
|
+
*
|
|
8
|
+
* The collections here normalize on every insert and every lookup (via {@link NormalizeUUID}), so
|
|
9
|
+
* they can be used exactly like a native `Set` / `Map` without anyone having to remember to
|
|
10
|
+
* normalize both sides. The helpers cover the five operations those nested scans actually perform:
|
|
11
|
+
* keep matches, drop matches, count per ID, group per ID, and look up by ID.
|
|
12
|
+
*
|
|
13
|
+
* Normalization follows `NormalizeUUID` exactly, including its handling of `null` / `undefined`
|
|
14
|
+
* (both normalize to `''`).
|
|
15
|
+
*
|
|
16
|
+
* @module @memberjunction/global/UUIDCollections
|
|
17
|
+
*/
|
|
18
|
+
import { NormalizeUUID } from './UUIDUtils.js';
|
|
19
|
+
/**
|
|
20
|
+
* A `Set` of UUIDs that matches case- and whitespace-insensitively. Every ID is normalized on
|
|
21
|
+
* insert and on lookup, so `Has('A1B2…')` finds an ID added as `'a1b2…'`. Iterates normalized IDs.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const selected = new UUIDSet(selectedIds);
|
|
25
|
+
* const picked = rows.filter(r => selected.Has(r.ID));
|
|
26
|
+
*/
|
|
27
|
+
export class UUIDSet {
|
|
28
|
+
constructor(ids) {
|
|
29
|
+
this.ids = new Set();
|
|
30
|
+
if (ids) {
|
|
31
|
+
for (const id of ids)
|
|
32
|
+
this.ids.add(NormalizeUUID(id));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Adds an ID. Returns this set, for chaining. */
|
|
36
|
+
Add(id) {
|
|
37
|
+
this.ids.add(NormalizeUUID(id));
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
/** True when the ID is in the set, ignoring case and surrounding whitespace. */
|
|
41
|
+
Has(id) {
|
|
42
|
+
return this.ids.has(NormalizeUUID(id));
|
|
43
|
+
}
|
|
44
|
+
/** Removes an ID. Returns true when it was present. */
|
|
45
|
+
Delete(id) {
|
|
46
|
+
return this.ids.delete(NormalizeUUID(id));
|
|
47
|
+
}
|
|
48
|
+
Clear() {
|
|
49
|
+
this.ids.clear();
|
|
50
|
+
}
|
|
51
|
+
/** Number of distinct IDs (case variants of one ID count once). */
|
|
52
|
+
get Size() {
|
|
53
|
+
return this.ids.size;
|
|
54
|
+
}
|
|
55
|
+
[Symbol.iterator]() {
|
|
56
|
+
return this.ids.values();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A `Map` keyed by UUID that matches case- and whitespace-insensitively. Every key is normalized
|
|
61
|
+
* on insert and on lookup, so a value stored under `'a1b2…'` is found with `Get('A1B2…')`.
|
|
62
|
+
* Iterates `[normalizedKey, value]` pairs.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* const roleNames = new UUIDMap(roles.map(r => [r.ID, r.Name]));
|
|
66
|
+
* const name = roleNames.Get(permission.RoleID);
|
|
67
|
+
*/
|
|
68
|
+
export class UUIDMap {
|
|
69
|
+
constructor(entries) {
|
|
70
|
+
this.entries = new Map();
|
|
71
|
+
if (entries) {
|
|
72
|
+
for (const [id, value] of entries)
|
|
73
|
+
this.entries.set(NormalizeUUID(id), value);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** The value stored for the ID, or undefined. */
|
|
77
|
+
Get(id) {
|
|
78
|
+
return this.entries.get(NormalizeUUID(id));
|
|
79
|
+
}
|
|
80
|
+
/** Stores a value for the ID, replacing any value stored under a case variant of it. */
|
|
81
|
+
Set(id, value) {
|
|
82
|
+
this.entries.set(NormalizeUUID(id), value);
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
Has(id) {
|
|
86
|
+
return this.entries.has(NormalizeUUID(id));
|
|
87
|
+
}
|
|
88
|
+
Delete(id) {
|
|
89
|
+
return this.entries.delete(NormalizeUUID(id));
|
|
90
|
+
}
|
|
91
|
+
Clear() {
|
|
92
|
+
this.entries.clear();
|
|
93
|
+
}
|
|
94
|
+
get Size() {
|
|
95
|
+
return this.entries.size;
|
|
96
|
+
}
|
|
97
|
+
/** Normalized keys. */
|
|
98
|
+
Keys() {
|
|
99
|
+
return this.entries.keys();
|
|
100
|
+
}
|
|
101
|
+
Values() {
|
|
102
|
+
return this.entries.values();
|
|
103
|
+
}
|
|
104
|
+
[Symbol.iterator]() {
|
|
105
|
+
return this.entries.entries();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The default selector: an item's `ID`. The overloads guarantee callers that omit `getId` pass items
|
|
110
|
+
* with an `ID`; this narrows instead of casting, so anything else reads as "no ID" rather than crashing.
|
|
111
|
+
*/
|
|
112
|
+
function readID(item) {
|
|
113
|
+
if (typeof item !== 'object' || item === null || !('ID' in item))
|
|
114
|
+
return undefined;
|
|
115
|
+
const id = item.ID;
|
|
116
|
+
return typeof id === 'string' ? id : undefined;
|
|
117
|
+
}
|
|
118
|
+
function asUUIDSet(ids) {
|
|
119
|
+
return ids instanceof UUIDSet ? ids : new UUIDSet(ids);
|
|
120
|
+
}
|
|
121
|
+
export function FilterByUUIDs(items, ids, getId) {
|
|
122
|
+
const wanted = asUUIDSet(ids);
|
|
123
|
+
const idOf = getId ?? readID;
|
|
124
|
+
return items.filter((item) => wanted.Has(idOf(item)));
|
|
125
|
+
}
|
|
126
|
+
export function ExcludeByUUIDs(items, ids, getId) {
|
|
127
|
+
const unwanted = asUUIDSet(ids);
|
|
128
|
+
const idOf = getId ?? readID;
|
|
129
|
+
return items.filter((item) => !unwanted.Has(idOf(item)));
|
|
130
|
+
}
|
|
131
|
+
export function CountByUUID(items, getId) {
|
|
132
|
+
const idOf = getId ?? readID;
|
|
133
|
+
const counts = new UUIDMap();
|
|
134
|
+
for (const item of items) {
|
|
135
|
+
const id = idOf(item);
|
|
136
|
+
counts.Set(id, (counts.Get(id) ?? 0) + 1);
|
|
137
|
+
}
|
|
138
|
+
return counts;
|
|
139
|
+
}
|
|
140
|
+
export function GroupByUUID(items, getId) {
|
|
141
|
+
const idOf = getId ?? readID;
|
|
142
|
+
const groups = new UUIDMap();
|
|
143
|
+
for (const item of items) {
|
|
144
|
+
const id = idOf(item);
|
|
145
|
+
const group = groups.Get(id);
|
|
146
|
+
if (group)
|
|
147
|
+
group.push(item);
|
|
148
|
+
else
|
|
149
|
+
groups.Set(id, [item]);
|
|
150
|
+
}
|
|
151
|
+
return groups;
|
|
152
|
+
}
|
|
153
|
+
export function IndexByUUID(items, getId) {
|
|
154
|
+
const idOf = getId ?? readID;
|
|
155
|
+
const index = new UUIDMap();
|
|
156
|
+
for (const item of items) {
|
|
157
|
+
const id = idOf(item);
|
|
158
|
+
if (!index.Has(id))
|
|
159
|
+
index.Set(id, item);
|
|
160
|
+
}
|
|
161
|
+
return index;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=UUIDCollections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UUIDCollections.js","sourceRoot":"","sources":["../../src/util/UUIDCollections.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UUIDUtils.d.ts","sourceRoot":"","sources":["../../src/util/UUIDUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGrE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"UUIDUtils.d.ts","sourceRoot":"","sources":["../../src/util/UUIDUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGrE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAatG;AAsDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAGpE"}
|
package/dist/util/UUIDUtils.js
CHANGED
|
@@ -49,13 +49,68 @@ export function UUIDsEqual(uuid1, uuid2) {
|
|
|
49
49
|
return true;
|
|
50
50
|
if (uuid1 == null || uuid2 == null)
|
|
51
51
|
return false;
|
|
52
|
-
// Fast path: identical references / already-equal strings (same value, same platform casing)
|
|
53
|
-
// are the overwhelmingly common case in tight `.find()`/`.some()` loops. Short-circuit before
|
|
54
|
-
// allocating two normalized copies via trim().toLowerCase().
|
|
52
|
+
// Fast path: identical references / already-equal strings (same value, same platform casing).
|
|
55
53
|
if (uuid1 === uuid2)
|
|
56
54
|
return true;
|
|
55
|
+
// Compare without allocating. `trim().toLowerCase()` on both sides built two new strings per
|
|
56
|
+
// call, and most calls in a `.filter`/`.some` scan are MISMATCHES, which the `===` path above
|
|
57
|
+
// never catches. The ASCII compare below settles every UUID-shaped input; anything it cannot
|
|
58
|
+
// settle exactly (a non-ASCII character) falls back to the original expression, so the
|
|
59
|
+
// result is identical to `uuid1.trim().toLowerCase() === uuid2.trim().toLowerCase()`.
|
|
60
|
+
const settled = compareTrimmedAsciiCaseInsensitive(uuid1, uuid2);
|
|
61
|
+
if (settled !== undefined)
|
|
62
|
+
return settled;
|
|
57
63
|
return uuid1.trim().toLowerCase() === uuid2.trim().toLowerCase();
|
|
58
64
|
}
|
|
65
|
+
/** Characters `String.prototype.trim` removes: ECMAScript WhiteSpace plus LineTerminator. */
|
|
66
|
+
function isTrimmable(code) {
|
|
67
|
+
return (code === 0x20 || (code >= 0x09 && code <= 0x0d) || code === 0xa0 || code === 0x1680 ||
|
|
68
|
+
(code >= 0x2000 && code <= 0x200a) || code === 0x2028 || code === 0x2029 || code === 0x202f ||
|
|
69
|
+
code === 0x205f || code === 0x3000 || code === 0xfeff);
|
|
70
|
+
}
|
|
71
|
+
function hasNonAscii(value, start, end) {
|
|
72
|
+
for (let i = start; i < end; i++) {
|
|
73
|
+
if (value.charCodeAt(i) > 0x7f)
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Compares the trimmed ranges of `a` and `b`, folding ASCII A-Z to a-z, without allocating.
|
|
80
|
+
* Returns the answer when ASCII rules decide it, or `undefined` when a non-ASCII character is
|
|
81
|
+
* involved (Unicode lower-casing can change a string's length or map outside ASCII, so only the
|
|
82
|
+
* original `toLowerCase()` path can answer those exactly).
|
|
83
|
+
*/
|
|
84
|
+
function compareTrimmedAsciiCaseInsensitive(a, b) {
|
|
85
|
+
let aStart = 0, aEnd = a.length, bStart = 0, bEnd = b.length;
|
|
86
|
+
while (aStart < aEnd && isTrimmable(a.charCodeAt(aStart)))
|
|
87
|
+
aStart++;
|
|
88
|
+
while (aEnd > aStart && isTrimmable(a.charCodeAt(aEnd - 1)))
|
|
89
|
+
aEnd--;
|
|
90
|
+
while (bStart < bEnd && isTrimmable(b.charCodeAt(bStart)))
|
|
91
|
+
bStart++;
|
|
92
|
+
while (bEnd > bStart && isTrimmable(b.charCodeAt(bEnd - 1)))
|
|
93
|
+
bEnd--;
|
|
94
|
+
const length = aEnd - aStart;
|
|
95
|
+
if (length !== bEnd - bStart) {
|
|
96
|
+
return hasNonAscii(a, aStart, aEnd) || hasNonAscii(b, bStart, bEnd) ? undefined : false;
|
|
97
|
+
}
|
|
98
|
+
for (let i = 0; i < length; i++) {
|
|
99
|
+
let x = a.charCodeAt(aStart + i);
|
|
100
|
+
let y = b.charCodeAt(bStart + i);
|
|
101
|
+
if (x === y)
|
|
102
|
+
continue;
|
|
103
|
+
if (x > 0x7f || y > 0x7f)
|
|
104
|
+
return undefined;
|
|
105
|
+
if (x >= 0x41 && x <= 0x5a)
|
|
106
|
+
x += 0x20;
|
|
107
|
+
if (y >= 0x41 && y <= 0x5a)
|
|
108
|
+
y += 0x20;
|
|
109
|
+
if (x !== y)
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
59
114
|
/**
|
|
60
115
|
* Canonical UUID format (8-4-4-4-12 hex groups). Case-insensitive; the version/variant digits are
|
|
61
116
|
* NOT constrained, so this validates SHAPE rather than RFC version — which is exactly what is needed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UUIDUtils.js","sourceRoot":"","sources":["../../src/util/UUIDUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,IAA+B;IACzD,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC5B,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,UAAU,CAAC,KAAgC,EAAE,KAAgC;IACzF,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAChD,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IACjD,6FAA6F;IAC7F,8FAA8F;IAC9F,
|
|
1
|
+
{"version":3,"file":"UUIDUtils.js","sourceRoot":"","sources":["../../src/util/UUIDUtils.ts"],"names":[],"mappings":"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"}
|
package/dist/util.d.ts
CHANGED
|
@@ -348,6 +348,20 @@ export declare function adjustCasing(word: string, options?: {
|
|
|
348
348
|
export declare function StripTrailingChars(s: string, charsToStrip: string, skipIfExactMatch: boolean): string;
|
|
349
349
|
/** @deprecated Use {@link StripTrailingChars}. */
|
|
350
350
|
export declare function stripTrailingChars(s: string, charsToStrip: string, skipIfExactMatch: boolean): string;
|
|
351
|
+
/**
|
|
352
|
+
* Removes every trailing `/` from a string, typically a base URL before a path is joined onto it.
|
|
353
|
+
*
|
|
354
|
+
* Linear in the length of the input. The regex `/\/+$/` is not: on a string holding many slashes that
|
|
355
|
+
* are NOT at the end, it backtracks quadratically, which makes it a denial-of-service vector on any
|
|
356
|
+
* caller-supplied URL.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```typescript
|
|
360
|
+
* TrimTrailingSlashes('http://localhost:4000///'); // 'http://localhost:4000'
|
|
361
|
+
* TrimTrailingSlashes('/'); // ''
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
364
|
+
export declare function TrimTrailingSlashes(s: string): string;
|
|
351
365
|
/**
|
|
352
366
|
* Recursively removes all spaces from a given string.
|
|
353
367
|
*
|
|
@@ -562,6 +576,31 @@ export declare function IsOnlyTimezoneShift(date1: Date, date2: Date): boolean;
|
|
|
562
576
|
* call in that case — `"…"?.getTime` is `undefined`, and calling it throws.
|
|
563
577
|
*/
|
|
564
578
|
export declare function ToEpochMs(value: Date | string | number | null | undefined): number;
|
|
579
|
+
/**
|
|
580
|
+
* Compares two values for equality, including cross-representation `Date` comparisons
|
|
581
|
+
* where one or both values may be `Date` instances, ISO date strings, or numeric epoch
|
|
582
|
+
* timestamps (e.g., comparing in-memory entity field values before and after database or
|
|
583
|
+
* JSON wire serialization).
|
|
584
|
+
*
|
|
585
|
+
* Returns `true` when:
|
|
586
|
+
* - `a === b` (strict identity for primitives and references)
|
|
587
|
+
* - Both `a` and `b` are `Date` instances with identical `.getTime()` epoch milliseconds
|
|
588
|
+
* - One side is a `Date` and the other is a `string` or `number` that parses to the same
|
|
589
|
+
* epoch milliseconds as the `Date`
|
|
590
|
+
*
|
|
591
|
+
* @param a - First value to compare
|
|
592
|
+
* @param b - Second value to compare
|
|
593
|
+
* @returns `true` if the values are equal, `false` otherwise
|
|
594
|
+
*
|
|
595
|
+
* @example
|
|
596
|
+
* ```typescript
|
|
597
|
+
* ValuesEqual(42, 42); // true
|
|
598
|
+
* ValuesEqual(new Date('2026-08-01T00:00:00.000Z'), new Date('2026-08-01T00:00:00.000Z')); // true
|
|
599
|
+
* ValuesEqual(new Date('2026-08-01T00:00:00.000Z'), '2026-08-01T00:00:00.000Z'); // true
|
|
600
|
+
* ValuesEqual('a', 'b'); // false
|
|
601
|
+
* ```
|
|
602
|
+
*/
|
|
603
|
+
export declare function ValuesEqual(a: unknown, b: unknown): boolean;
|
|
565
604
|
/**
|
|
566
605
|
* Locale-independent total order on strings (UTF-16 code units). Use for every sort whose
|
|
567
606
|
* result is EMITTED (generated code, SQL, file names, migration captures). Not for UI display —
|
package/dist/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/dist/util.js
CHANGED
|
@@ -1322,6 +1322,26 @@ export function StripTrailingChars(s, charsToStrip, skipIfExactMatch) {
|
|
|
1322
1322
|
export function stripTrailingChars(s, charsToStrip, skipIfExactMatch) {
|
|
1323
1323
|
return StripTrailingChars(s, charsToStrip, skipIfExactMatch);
|
|
1324
1324
|
}
|
|
1325
|
+
/**
|
|
1326
|
+
* Removes every trailing `/` from a string, typically a base URL before a path is joined onto it.
|
|
1327
|
+
*
|
|
1328
|
+
* Linear in the length of the input. The regex `/\/+$/` is not: on a string holding many slashes that
|
|
1329
|
+
* are NOT at the end, it backtracks quadratically, which makes it a denial-of-service vector on any
|
|
1330
|
+
* caller-supplied URL.
|
|
1331
|
+
*
|
|
1332
|
+
* @example
|
|
1333
|
+
* ```typescript
|
|
1334
|
+
* TrimTrailingSlashes('http://localhost:4000///'); // 'http://localhost:4000'
|
|
1335
|
+
* TrimTrailingSlashes('/'); // ''
|
|
1336
|
+
* ```
|
|
1337
|
+
*/
|
|
1338
|
+
export function TrimTrailingSlashes(s) {
|
|
1339
|
+
let end = s.length;
|
|
1340
|
+
while (end > 0 && s.charCodeAt(end - 1) === 47 /* '/' */) {
|
|
1341
|
+
end--;
|
|
1342
|
+
}
|
|
1343
|
+
return end === s.length ? s : s.substring(0, end);
|
|
1344
|
+
}
|
|
1325
1345
|
/**
|
|
1326
1346
|
* Recursively removes all spaces from a given string.
|
|
1327
1347
|
*
|
|
@@ -1831,6 +1851,44 @@ export function ToEpochMs(value) {
|
|
|
1831
1851
|
const ms = value instanceof Date ? value.getTime() : new Date(value).getTime();
|
|
1832
1852
|
return Number.isNaN(ms) ? 0 : ms;
|
|
1833
1853
|
}
|
|
1854
|
+
/**
|
|
1855
|
+
* Compares two values for equality, including cross-representation `Date` comparisons
|
|
1856
|
+
* where one or both values may be `Date` instances, ISO date strings, or numeric epoch
|
|
1857
|
+
* timestamps (e.g., comparing in-memory entity field values before and after database or
|
|
1858
|
+
* JSON wire serialization).
|
|
1859
|
+
*
|
|
1860
|
+
* Returns `true` when:
|
|
1861
|
+
* - `a === b` (strict identity for primitives and references)
|
|
1862
|
+
* - Both `a` and `b` are `Date` instances with identical `.getTime()` epoch milliseconds
|
|
1863
|
+
* - One side is a `Date` and the other is a `string` or `number` that parses to the same
|
|
1864
|
+
* epoch milliseconds as the `Date`
|
|
1865
|
+
*
|
|
1866
|
+
* @param a - First value to compare
|
|
1867
|
+
* @param b - Second value to compare
|
|
1868
|
+
* @returns `true` if the values are equal, `false` otherwise
|
|
1869
|
+
*
|
|
1870
|
+
* @example
|
|
1871
|
+
* ```typescript
|
|
1872
|
+
* ValuesEqual(42, 42); // true
|
|
1873
|
+
* ValuesEqual(new Date('2026-08-01T00:00:00.000Z'), new Date('2026-08-01T00:00:00.000Z')); // true
|
|
1874
|
+
* ValuesEqual(new Date('2026-08-01T00:00:00.000Z'), '2026-08-01T00:00:00.000Z'); // true
|
|
1875
|
+
* ValuesEqual('a', 'b'); // false
|
|
1876
|
+
* ```
|
|
1877
|
+
*/
|
|
1878
|
+
export function ValuesEqual(a, b) {
|
|
1879
|
+
if (a === b)
|
|
1880
|
+
return true;
|
|
1881
|
+
if (a instanceof Date && b instanceof Date) {
|
|
1882
|
+
return a.getTime() === b.getTime();
|
|
1883
|
+
}
|
|
1884
|
+
if (a instanceof Date && (typeof b === 'string' || typeof b === 'number')) {
|
|
1885
|
+
return a.getTime() === new Date(b).getTime();
|
|
1886
|
+
}
|
|
1887
|
+
if (b instanceof Date && (typeof a === 'string' || typeof a === 'number')) {
|
|
1888
|
+
return new Date(a).getTime() === b.getTime();
|
|
1889
|
+
}
|
|
1890
|
+
return false;
|
|
1891
|
+
}
|
|
1834
1892
|
/**
|
|
1835
1893
|
* Locale-independent total order on strings (UTF-16 code units). Use for every sort whose
|
|
1836
1894
|
* result is EMITTED (generated code, SQL, file names, migration captures). Not for UI display —
|