@esposter/shared 4.1.2 → 4.3.1
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/README.md +1 -1
- package/dist/index.d.ts +110 -4
- package/dist/index.js +352 -73
- package/package.json +6 -11
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ pnpm i @esposter/shared zod
|
|
|
23
23
|
|
|
24
24
|
## <a name="documentation">📖 Documentation</a>
|
|
25
25
|
|
|
26
|
-
We highly recommend you take a look at the [documentation](https://
|
|
26
|
+
We highly recommend you take a look at the [documentation](https://github.com/Esposter/Esposter/tree/main/openspec/specs/shared) to level up.
|
|
27
27
|
|
|
28
28
|
### Key Exports
|
|
29
29
|
|
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,19 @@ export declare class TypedEventEmitter<TEventMap extends EventListenerMap<TEvent
|
|
|
56
56
|
removeAllListeners(event?: keyof TEventMap): void;
|
|
57
57
|
}
|
|
58
58
|
//#endregion
|
|
59
|
+
//#region src/models/history/History.d.ts
|
|
60
|
+
export interface History<T> {
|
|
61
|
+
future: T[];
|
|
62
|
+
limit: number;
|
|
63
|
+
past: T[];
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/models/history/HistoryStep.d.ts
|
|
67
|
+
export interface HistoryStep<T> {
|
|
68
|
+
entry?: T;
|
|
69
|
+
history: History<T>;
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
59
72
|
//#region src/models/indexedDb/DatabaseStoreSchema.d.ts
|
|
60
73
|
export interface DatabaseStoreSchema {
|
|
61
74
|
indexes: Record<string, IDBValidKey>;
|
|
@@ -135,6 +148,39 @@ export interface DatabaseOpenOptions<TSchema extends DatabaseSchema = DatabaseSc
|
|
|
135
148
|
upgrade?: (database: UpgradeDatabase<TSchema>, oldVersion: number, newVersion: null | number, transaction: DatabaseTransaction<TSchema, DatabaseStoreName<TSchema>, "versionchange">) => void;
|
|
136
149
|
}
|
|
137
150
|
//#endregion
|
|
151
|
+
//#region src/models/jsonPatch/JsonPatchOperationType.d.ts
|
|
152
|
+
export declare enum JsonPatchOperationType {
|
|
153
|
+
Add = "add",
|
|
154
|
+
Copy = "copy",
|
|
155
|
+
Move = "move",
|
|
156
|
+
Remove = "remove",
|
|
157
|
+
Replace = "replace",
|
|
158
|
+
Test = "test"
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/models/jsonPatch/JsonPatchOperation.d.ts
|
|
162
|
+
export type JsonPatchOperation = JsonPatchFromOperation | JsonPatchRemoveOperation | JsonPatchValueOperation;
|
|
163
|
+
interface JsonPatchFromOperation {
|
|
164
|
+
from: string;
|
|
165
|
+
op: JsonPatchOperationType.Copy | JsonPatchOperationType.Move;
|
|
166
|
+
path: string;
|
|
167
|
+
}
|
|
168
|
+
interface JsonPatchRemoveOperation {
|
|
169
|
+
op: JsonPatchOperationType.Remove;
|
|
170
|
+
path: string;
|
|
171
|
+
}
|
|
172
|
+
interface JsonPatchValueOperation {
|
|
173
|
+
op: JsonPatchOperationType.Add | JsonPatchOperationType.Replace | JsonPatchOperationType.Test;
|
|
174
|
+
path: string;
|
|
175
|
+
value: unknown;
|
|
176
|
+
}
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region src/models/jsonPatch/ApplyPatchesResult.d.ts
|
|
179
|
+
export interface ApplyPatchesResult<T> {
|
|
180
|
+
document: T;
|
|
181
|
+
inverses: JsonPatchOperation[];
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
138
184
|
//#region src/models/message/MentionType.d.ts
|
|
139
185
|
export declare enum MentionType {
|
|
140
186
|
Role = "role",
|
|
@@ -173,7 +219,6 @@ export declare const RoutePath: {
|
|
|
173
219
|
readonly Calls: (id: string) => string;
|
|
174
220
|
readonly CallsIndex: "/calls";
|
|
175
221
|
readonly Clicker: "/clicker";
|
|
176
|
-
readonly Docs: "/docs";
|
|
177
222
|
readonly Dungeons: "/dungeons";
|
|
178
223
|
readonly FluidSimulator: "/fluid-simulator";
|
|
179
224
|
readonly Genshin: "/genshin";
|
|
@@ -2012,7 +2057,7 @@ export interface Dedent {
|
|
|
2012
2057
|
export type UniqueArraySchemaKey<TSchema extends z.ZodType> = TSchema extends z.ZodObject ? keyof TSchema["shape"] & string : keyof z.output<TSchema> & string;
|
|
2013
2058
|
//#endregion
|
|
2014
2059
|
//#region src/models/zod/CreateUniqueArraySchema.d.ts
|
|
2015
|
-
export type CreateUniqueArraySchema = (<TOutput extends object, TInput, TSchema extends z.ZodType<TOutput, TInput>>(schema: TSchema, key: UniqueArraySchemaKey<TSchema>) => z.ZodArray<TSchema>) & (<TOutput extends Primitive, TInput, TSchema extends z.ZodType<TOutput, TInput>>(schema: TSchema) => z.ZodArray<TSchema>);
|
|
2060
|
+
export type CreateUniqueArraySchema = (<TOutput extends object, TInput, TSchema extends z.ZodType<TOutput, TInput>>(schema: TSchema, key: readonly UniqueArraySchemaKey<TSchema>[] | UniqueArraySchemaKey<TSchema>) => z.ZodArray<TSchema>) & (<TOutput extends Primitive, TInput, TSchema extends z.ZodType<TOutput, TInput>>(schema: TSchema) => z.ZodArray<TSchema>);
|
|
2016
2061
|
//#endregion
|
|
2017
2062
|
//#region src/services/app/constants.d.ts
|
|
2018
2063
|
export declare const MAX_READ_LIMIT = 1e3;
|
|
@@ -2038,6 +2083,18 @@ export declare const withFinalizer: <T>(callback: () => T, finalizer?: () => voi
|
|
|
2038
2083
|
//#region src/services/error/withFinalizerAsync.d.ts
|
|
2039
2084
|
export declare const withFinalizerAsync: <T>(callback: () => Promisable<T>, finalizer?: () => Promisable<void>) => Promise<T>;
|
|
2040
2085
|
//#endregion
|
|
2086
|
+
//#region src/services/history/createHistory.d.ts
|
|
2087
|
+
export declare const createHistory: <T>(limit: number) => History<T>;
|
|
2088
|
+
//#endregion
|
|
2089
|
+
//#region src/services/history/pushHistory.d.ts
|
|
2090
|
+
export declare const pushHistory: <T>(history: History<T>, entry: T) => History<T>;
|
|
2091
|
+
//#endregion
|
|
2092
|
+
//#region src/services/history/redoHistory.d.ts
|
|
2093
|
+
export declare const redoHistory: <T>(history: History<T>) => HistoryStep<T>;
|
|
2094
|
+
//#endregion
|
|
2095
|
+
//#region src/services/history/undoHistory.d.ts
|
|
2096
|
+
export declare const undoHistory: <T>(history: History<T>) => HistoryStep<T>;
|
|
2097
|
+
//#endregion
|
|
2041
2098
|
//#region src/services/indexedDb/getRequestError.d.ts
|
|
2042
2099
|
export declare const getRequestError: (request: IDBRequest) => DOMException;
|
|
2043
2100
|
//#endregion
|
|
@@ -2071,6 +2128,37 @@ export declare const wrapUpgradeDatabase: <TSchema extends DatabaseSchema = Data
|
|
|
2071
2128
|
//#region src/services/indexedDb/wrapUpgradeTransaction.d.ts
|
|
2072
2129
|
export declare const wrapUpgradeTransaction: <TSchema extends DatabaseSchema>(transaction: IDBTransaction) => DatabaseTransaction<TSchema, DatabaseStoreName<TSchema>, "versionchange">;
|
|
2073
2130
|
//#endregion
|
|
2131
|
+
//#region src/services/jsonPatch/addJsonValue.d.ts
|
|
2132
|
+
export declare const addJsonValue: (document: unknown, path: string, value: unknown) => ApplyPatchesResult<unknown>;
|
|
2133
|
+
//#endregion
|
|
2134
|
+
//#region src/services/jsonPatch/applyPatch.d.ts
|
|
2135
|
+
export declare const applyPatch: (document: unknown, operation: JsonPatchOperation) => ApplyPatchesResult<unknown>;
|
|
2136
|
+
//#endregion
|
|
2137
|
+
//#region src/services/jsonPatch/applyPatches.d.ts
|
|
2138
|
+
export declare const applyPatches: <T>(document: T, operations: JsonPatchOperation[]) => ApplyPatchesResult<T>;
|
|
2139
|
+
//#endregion
|
|
2140
|
+
//#region src/services/jsonPatch/constants.d.ts
|
|
2141
|
+
export declare const APPEND_SEGMENT = "-";
|
|
2142
|
+
export declare const JSON_POINTER_REGEX: RegExp;
|
|
2143
|
+
//#endregion
|
|
2144
|
+
//#region src/services/jsonPatch/parseArrayIndex.d.ts
|
|
2145
|
+
export declare const parseArrayIndex: (segment: string, maxIndex: number) => number | undefined;
|
|
2146
|
+
//#endregion
|
|
2147
|
+
//#region src/services/jsonPatch/parseJsonPointer.d.ts
|
|
2148
|
+
export declare const parseJsonPointer: (pointer: string) => string[];
|
|
2149
|
+
//#endregion
|
|
2150
|
+
//#region src/services/jsonPatch/readJsonValue.d.ts
|
|
2151
|
+
export declare const readJsonValue: (document: unknown, segments: string[]) => unknown;
|
|
2152
|
+
//#endregion
|
|
2153
|
+
//#region src/services/jsonPatch/removeJsonValue.d.ts
|
|
2154
|
+
export declare const removeJsonValue: (document: unknown, path: string) => ApplyPatchesResult<unknown>;
|
|
2155
|
+
//#endregion
|
|
2156
|
+
//#region src/services/jsonPatch/toJsonPointer.d.ts
|
|
2157
|
+
export declare const toJsonPointer: (segments: string[]) => string;
|
|
2158
|
+
//#endregion
|
|
2159
|
+
//#region src/services/jsonPatch/updateJsonValue.d.ts
|
|
2160
|
+
export declare const updateJsonValue: (document: unknown, segments: string[], update: (value: unknown) => unknown) => unknown;
|
|
2161
|
+
//#endregion
|
|
2074
2162
|
//#region src/services/message/constants.d.ts
|
|
2075
2163
|
export declare const MENTION_ID_ATTRIBUTE = "data-id";
|
|
2076
2164
|
export declare const MENTION_ITEM_TYPE_ATTRIBUTE = "data-mention-type";
|
|
@@ -2164,7 +2252,7 @@ export declare const MAX_NESTING_DEPTH = 256;
|
|
|
2164
2252
|
export declare const SRCSET_DESCRIPTOR_REGEX: RegExp;
|
|
2165
2253
|
export declare const ESCAPED_TEXT_CHARACTERS_REGEX: RegExp;
|
|
2166
2254
|
export declare const ESCAPED_ATTRIBUTE_CHARACTERS_REGEX: RegExp;
|
|
2167
|
-
export declare const SANITIZER_ADVISORY_WATCH_SINCE = "2026-10-
|
|
2255
|
+
export declare const SANITIZER_ADVISORY_WATCH_SINCE = "2026-10-21";
|
|
2168
2256
|
//#endregion
|
|
2169
2257
|
//#region src/services/sanitizeHtml/escapeAttribute.d.ts
|
|
2170
2258
|
export declare const escapeAttribute: (value: string) => string;
|
|
@@ -2237,15 +2325,27 @@ export declare const chunkBySerializedSize: <T>(items: T[], maxBytes: number, ma
|
|
|
2237
2325
|
//#region src/util/array/takeOne.d.ts
|
|
2238
2326
|
export declare const takeOne: TakeOne;
|
|
2239
2327
|
//#endregion
|
|
2328
|
+
//#region src/util/array/takeRandom.d.ts
|
|
2329
|
+
export declare const takeRandom: <T>(values: readonly T[], random: () => number) => T;
|
|
2330
|
+
//#endregion
|
|
2240
2331
|
//#region src/util/date/getEndOfDay.d.ts
|
|
2241
2332
|
export declare const getEndOfDay: (date: Date) => Date;
|
|
2242
2333
|
//#endregion
|
|
2243
2334
|
//#region src/util/date/getZonedDateTime.d.ts
|
|
2244
2335
|
export declare const getZonedDateTime: (date: Date) => Temporal.ZonedDateTime;
|
|
2245
2336
|
//#endregion
|
|
2337
|
+
//#region src/util/dom/checkIsNestedControl.d.ts
|
|
2338
|
+
export declare const checkIsNestedControl: (event: MouseEvent) => boolean;
|
|
2339
|
+
//#endregion
|
|
2246
2340
|
//#region src/util/dom/checkIsNestedInteraction.d.ts
|
|
2247
2341
|
export declare const checkIsNestedInteraction: (event: MouseEvent) => boolean;
|
|
2248
2342
|
//#endregion
|
|
2343
|
+
//#region src/util/dom/downloadFile.d.ts
|
|
2344
|
+
export declare const downloadFile: (filename: string, blobPart: BlobPart, type: string) => void;
|
|
2345
|
+
//#endregion
|
|
2346
|
+
//#region src/util/dom/downloadUrl.d.ts
|
|
2347
|
+
export declare const downloadUrl: (url: string, filename: string) => void;
|
|
2348
|
+
//#endregion
|
|
2249
2349
|
//#region src/util/environment/checkIsServer.d.ts
|
|
2250
2350
|
export declare const checkIsServer: () => boolean;
|
|
2251
2351
|
//#endregion
|
|
@@ -2280,6 +2380,9 @@ export declare const checkIsSameBytes: (first: ArrayBuffer | ArrayBufferView | S
|
|
|
2280
2380
|
//#region src/util/object/checkIsSameValueZero.d.ts
|
|
2281
2381
|
export declare const checkIsSameValueZero: (first: unknown, second: unknown) => boolean;
|
|
2282
2382
|
//#endregion
|
|
2383
|
+
//#region src/util/object/clonePlainDeep.d.ts
|
|
2384
|
+
export declare const clonePlainDeep: <T>(data: T) => T;
|
|
2385
|
+
//#endregion
|
|
2283
2386
|
//#region src/util/object/getEnumerableKeys.d.ts
|
|
2284
2387
|
export declare const getEnumerableKeys: (value: object) => PropertyKey[];
|
|
2285
2388
|
//#endregion
|
|
@@ -2358,7 +2461,7 @@ export declare const encodeUrlSubDelimiters: (value: string) => string;
|
|
|
2358
2461
|
export declare const getDecodedUriComponent: (value: string, fallback: string) => string;
|
|
2359
2462
|
//#endregion
|
|
2360
2463
|
//#region src/util/text/normalizeString.d.ts
|
|
2361
|
-
export declare const normalizeString: (value:
|
|
2464
|
+
export declare const normalizeString: (value: string | undefined) => string;
|
|
2362
2465
|
//#endregion
|
|
2363
2466
|
//#region src/util/text/streamToText.d.ts
|
|
2364
2467
|
export declare const streamToText: (readable: NodeJS.ReadableStream) => Promise<string>;
|
|
@@ -2372,6 +2475,9 @@ export declare const truncate: (string: string, length: number) => string;
|
|
|
2372
2475
|
//#region src/util/text/uncapitalize.d.ts
|
|
2373
2476
|
export declare const uncapitalize: <T extends string>(string: T) => Uncapitalize<T>;
|
|
2374
2477
|
//#endregion
|
|
2478
|
+
//#region src/util/time/constants.d.ts
|
|
2479
|
+
export declare const MILLISECONDS_PER_SECOND = 1e3;
|
|
2480
|
+
//#endregion
|
|
2375
2481
|
//#region src/util/time/hrtime.d.ts
|
|
2376
2482
|
export declare const hrtime: (previousHrTime?: [number, number]) => [number, number];
|
|
2377
2483
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -90,6 +90,17 @@ var TypedEventEmitter = class {
|
|
|
90
90
|
}
|
|
91
91
|
};
|
|
92
92
|
//#endregion
|
|
93
|
+
//#region src/models/jsonPatch/JsonPatchOperationType.ts
|
|
94
|
+
let JsonPatchOperationType = /* @__PURE__ */ function(JsonPatchOperationType) {
|
|
95
|
+
JsonPatchOperationType["Add"] = "add";
|
|
96
|
+
JsonPatchOperationType["Copy"] = "copy";
|
|
97
|
+
JsonPatchOperationType["Move"] = "move";
|
|
98
|
+
JsonPatchOperationType["Remove"] = "remove";
|
|
99
|
+
JsonPatchOperationType["Replace"] = "replace";
|
|
100
|
+
JsonPatchOperationType["Test"] = "test";
|
|
101
|
+
return JsonPatchOperationType;
|
|
102
|
+
}({});
|
|
103
|
+
//#endregion
|
|
93
104
|
//#region src/models/message/MentionType.ts
|
|
94
105
|
let MentionType = /* @__PURE__ */ function(MentionType) {
|
|
95
106
|
MentionType["Role"] = "role";
|
|
@@ -118,7 +129,6 @@ const RoutePath = {
|
|
|
118
129
|
Calls: (id) => `/calls/${id}`,
|
|
119
130
|
CallsIndex: "/calls",
|
|
120
131
|
Clicker: "/clicker",
|
|
121
|
-
Docs: "/docs",
|
|
122
132
|
Dungeons: "/dungeons",
|
|
123
133
|
FluidSimulator: "/fluid-simulator",
|
|
124
134
|
Genshin: "/genshin",
|
|
@@ -231,6 +241,50 @@ const withFinalizerAsync = async (callback, finalizer) => {
|
|
|
231
241
|
});
|
|
232
242
|
};
|
|
233
243
|
//#endregion
|
|
244
|
+
//#region src/services/history/createHistory.ts
|
|
245
|
+
const createHistory = (limit) => ({
|
|
246
|
+
future: [],
|
|
247
|
+
limit,
|
|
248
|
+
past: []
|
|
249
|
+
});
|
|
250
|
+
//#endregion
|
|
251
|
+
//#region src/services/history/pushHistory.ts
|
|
252
|
+
const pushHistory = (history, entry) => {
|
|
253
|
+
const past = [...history.past, entry];
|
|
254
|
+
return {
|
|
255
|
+
future: [],
|
|
256
|
+
limit: history.limit,
|
|
257
|
+
past: past.slice(Math.max(past.length - history.limit, 0))
|
|
258
|
+
};
|
|
259
|
+
};
|
|
260
|
+
//#endregion
|
|
261
|
+
//#region src/services/history/redoHistory.ts
|
|
262
|
+
const redoHistory = (history) => {
|
|
263
|
+
const [entry] = history.future;
|
|
264
|
+
if (entry === void 0) return { history };
|
|
265
|
+
return {
|
|
266
|
+
entry,
|
|
267
|
+
history: {
|
|
268
|
+
...pushHistory(history, entry),
|
|
269
|
+
future: history.future.slice(1)
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
//#endregion
|
|
274
|
+
//#region src/services/history/undoHistory.ts
|
|
275
|
+
const undoHistory = (history) => {
|
|
276
|
+
const entry = history.past.at(-1);
|
|
277
|
+
if (entry === void 0) return { history };
|
|
278
|
+
return {
|
|
279
|
+
entry,
|
|
280
|
+
history: {
|
|
281
|
+
future: [entry, ...history.future],
|
|
282
|
+
limit: history.limit,
|
|
283
|
+
past: history.past.slice(0, -1)
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
};
|
|
287
|
+
//#endregion
|
|
234
288
|
//#region src/services/indexedDb/getRequestError.ts
|
|
235
289
|
const getRequestError = (request) => request.error ?? new DOMException("The request failed without an error", "UnknownError");
|
|
236
290
|
//#endregion
|
|
@@ -322,7 +376,9 @@ const wrapUpgradeDatabase = (database) => ({
|
|
|
322
376
|
//#region src/services/indexedDb/wrapUpgradeTransaction.ts
|
|
323
377
|
const wrapUpgradeTransaction = (transaction) => {
|
|
324
378
|
const done = getTransactionDone(transaction);
|
|
325
|
-
getResultAsync(() => done).match(noop,
|
|
379
|
+
getResultAsync(() => done).match(noop, (error) => {
|
|
380
|
+
if (transaction.error) console.error(error);
|
|
381
|
+
});
|
|
326
382
|
return {
|
|
327
383
|
get done() {
|
|
328
384
|
return done;
|
|
@@ -360,6 +416,243 @@ const openDatabase = (name, version, options = {}) => new Promise((resolve, reje
|
|
|
360
416
|
});
|
|
361
417
|
});
|
|
362
418
|
//#endregion
|
|
419
|
+
//#region src/services/jsonPatch/constants.ts
|
|
420
|
+
const APPEND_SEGMENT = "-";
|
|
421
|
+
const JSON_POINTER_REGEX = /^(?:\/(?:[^/~]|~[01])*)*$/u;
|
|
422
|
+
//#endregion
|
|
423
|
+
//#region src/services/jsonPatch/parseArrayIndex.ts
|
|
424
|
+
const ARRAY_INDEX_REGEX = /^(?:0|[1-9]\d*)$/u;
|
|
425
|
+
const parseArrayIndex = (segment, maxIndex) => {
|
|
426
|
+
const index = Number(segment);
|
|
427
|
+
return ARRAY_INDEX_REGEX.test(segment) && index <= maxIndex ? index : void 0;
|
|
428
|
+
};
|
|
429
|
+
//#endregion
|
|
430
|
+
//#region src/services/jsonPatch/parseJsonPointer.ts
|
|
431
|
+
const parseJsonPointer = (pointer) => {
|
|
432
|
+
if (pointer === "") return [];
|
|
433
|
+
else if (!JSON_POINTER_REGEX.test(pointer)) throw new InvalidOperationError("Read", pointer, "not a JSON Pointer");
|
|
434
|
+
return pointer.slice(1).split("/").map((segment) => segment.replaceAll("~1", "/").replaceAll("~0", "~"));
|
|
435
|
+
};
|
|
436
|
+
//#endregion
|
|
437
|
+
//#region src/services/jsonPatch/toJsonPointer.ts
|
|
438
|
+
const toJsonPointer = (segments) => segments.map((segment) => `/${segment.replaceAll("~", "~0").replaceAll("/", "~1")}`).join("");
|
|
439
|
+
//#endregion
|
|
440
|
+
//#region src/util/object/checkIsPlainObject.ts
|
|
441
|
+
const checkIsPlainObject = (data) => {
|
|
442
|
+
if (typeof data !== "object" || data === null) return false;
|
|
443
|
+
const prototype = Object.getPrototypeOf(data);
|
|
444
|
+
return prototype === null || prototype === Object.prototype;
|
|
445
|
+
};
|
|
446
|
+
//#endregion
|
|
447
|
+
//#region src/services/jsonPatch/readJsonValue.ts
|
|
448
|
+
const readJsonValue = (document, segments) => {
|
|
449
|
+
let value = document;
|
|
450
|
+
for (const segment of segments) {
|
|
451
|
+
const index = Array.isArray(value) ? parseArrayIndex(segment, value.length - 1) : void 0;
|
|
452
|
+
if (Array.isArray(value) && index !== void 0) value = value[index];
|
|
453
|
+
else if (checkIsPlainObject(value) && Object.hasOwn(value, segment)) value = value[segment];
|
|
454
|
+
else throw new InvalidOperationError("Read", toJsonPointer(segments), "no such member");
|
|
455
|
+
}
|
|
456
|
+
return value;
|
|
457
|
+
};
|
|
458
|
+
//#endregion
|
|
459
|
+
//#region src/services/jsonPatch/updateJsonValue.ts
|
|
460
|
+
const updateJsonValue = (document, segments, update) => {
|
|
461
|
+
const [segment, ...restSegments] = segments;
|
|
462
|
+
if (segment === void 0) return update(document);
|
|
463
|
+
const index = Array.isArray(document) ? parseArrayIndex(segment, document.length - 1) : void 0;
|
|
464
|
+
if (Array.isArray(document) && index !== void 0) return document.with(index, updateJsonValue(document[index], restSegments, update));
|
|
465
|
+
else if (checkIsPlainObject(document) && Object.hasOwn(document, segment)) return {
|
|
466
|
+
...document,
|
|
467
|
+
[segment]: updateJsonValue(document[segment], restSegments, update)
|
|
468
|
+
};
|
|
469
|
+
else throw new InvalidOperationError("Update", toJsonPointer(segments), "no such member");
|
|
470
|
+
};
|
|
471
|
+
//#endregion
|
|
472
|
+
//#region src/services/jsonPatch/addJsonValue.ts
|
|
473
|
+
const addJsonValue = (document, path, value) => {
|
|
474
|
+
const segments = parseJsonPointer(path);
|
|
475
|
+
const parentSegments = segments.slice(0, -1);
|
|
476
|
+
const key = segments.at(-1);
|
|
477
|
+
if (key === void 0) return {
|
|
478
|
+
document: value,
|
|
479
|
+
inverses: [{
|
|
480
|
+
op: "replace",
|
|
481
|
+
path,
|
|
482
|
+
value: document
|
|
483
|
+
}]
|
|
484
|
+
};
|
|
485
|
+
const parent = readJsonValue(document, parentSegments);
|
|
486
|
+
if (Array.isArray(parent)) {
|
|
487
|
+
const index = key === "-" ? parent.length : parseArrayIndex(key, parent.length);
|
|
488
|
+
if (index === void 0) throw new InvalidOperationError("Update", path, "no such index in the array");
|
|
489
|
+
return {
|
|
490
|
+
document: updateJsonValue(document, parentSegments, () => parent.toSpliced(index, 0, value)),
|
|
491
|
+
inverses: [{
|
|
492
|
+
op: "remove",
|
|
493
|
+
path: toJsonPointer([...parentSegments, `${index}`])
|
|
494
|
+
}]
|
|
495
|
+
};
|
|
496
|
+
} else if (checkIsPlainObject(parent)) return {
|
|
497
|
+
document: updateJsonValue(document, parentSegments, () => ({
|
|
498
|
+
...parent,
|
|
499
|
+
[key]: value
|
|
500
|
+
})),
|
|
501
|
+
inverses: [Object.hasOwn(parent, key) ? {
|
|
502
|
+
op: "replace",
|
|
503
|
+
path,
|
|
504
|
+
value: parent[key]
|
|
505
|
+
} : {
|
|
506
|
+
op: "remove",
|
|
507
|
+
path
|
|
508
|
+
}]
|
|
509
|
+
};
|
|
510
|
+
else throw new InvalidOperationError("Update", path, "its parent holds no members");
|
|
511
|
+
};
|
|
512
|
+
//#endregion
|
|
513
|
+
//#region src/services/jsonPatch/removeJsonValue.ts
|
|
514
|
+
const removeJsonValue = (document, path) => {
|
|
515
|
+
const segments = parseJsonPointer(path);
|
|
516
|
+
const parentSegments = segments.slice(0, -1);
|
|
517
|
+
const key = segments.at(-1);
|
|
518
|
+
if (key === void 0) throw new InvalidOperationError("Delete", path, "the root cannot be removed");
|
|
519
|
+
const parent = readJsonValue(document, parentSegments);
|
|
520
|
+
const index = Array.isArray(parent) ? parseArrayIndex(key, parent.length - 1) : void 0;
|
|
521
|
+
if (Array.isArray(parent) && index !== void 0) return {
|
|
522
|
+
document: updateJsonValue(document, parentSegments, () => parent.toSpliced(index, 1)),
|
|
523
|
+
inverses: [{
|
|
524
|
+
op: "add",
|
|
525
|
+
path,
|
|
526
|
+
value: parent[index]
|
|
527
|
+
}]
|
|
528
|
+
};
|
|
529
|
+
else if (checkIsPlainObject(parent) && Object.hasOwn(parent, key)) {
|
|
530
|
+
const { [key]: removedValue, ...restParent } = parent;
|
|
531
|
+
return {
|
|
532
|
+
document: updateJsonValue(document, parentSegments, () => restParent),
|
|
533
|
+
inverses: [{
|
|
534
|
+
op: "add",
|
|
535
|
+
path,
|
|
536
|
+
value: removedValue
|
|
537
|
+
}]
|
|
538
|
+
};
|
|
539
|
+
} else throw new InvalidOperationError("Delete", path, "no such member");
|
|
540
|
+
};
|
|
541
|
+
//#endregion
|
|
542
|
+
//#region src/util/object/checkIsCustomMethod.ts
|
|
543
|
+
const checkIsCustomMethod = (value, methodName) => {
|
|
544
|
+
const method = Reflect.get(value, methodName);
|
|
545
|
+
return typeof method === "function" && method !== Object.prototype[methodName];
|
|
546
|
+
};
|
|
547
|
+
//#endregion
|
|
548
|
+
//#region src/util/object/checkIsSameBytes.ts
|
|
549
|
+
const toBytes = (view) => ArrayBuffer.isView(view) ? new Uint8Array(view.buffer, view.byteOffset, view.byteLength) : new Uint8Array(view);
|
|
550
|
+
const checkIsSameBytes = (first, second) => {
|
|
551
|
+
const firstBytes = toBytes(first);
|
|
552
|
+
const secondBytes = toBytes(second);
|
|
553
|
+
return firstBytes.length === secondBytes.length && firstBytes.every((byte, index) => byte === secondBytes[index]);
|
|
554
|
+
};
|
|
555
|
+
//#endregion
|
|
556
|
+
//#region src/util/object/checkIsSameValueZero.ts
|
|
557
|
+
const checkIsSameValueZero = (first, second) => first === second || Number.isNaN(first) && Number.isNaN(second);
|
|
558
|
+
//#endregion
|
|
559
|
+
//#region src/util/object/getEnumerableKeys.ts
|
|
560
|
+
const getEnumerableKeys = (value) => Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
|
|
561
|
+
//#endregion
|
|
562
|
+
//#region src/util/object/checkIsDeepEqual.ts
|
|
563
|
+
const checkIsBinary = (value) => ArrayBuffer.isView(value) || value instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && value instanceof SharedArrayBuffer;
|
|
564
|
+
const checkIsDeepEqual = (first, second) => {
|
|
565
|
+
if (first === second) return true;
|
|
566
|
+
if (typeof first !== "object" || typeof second !== "object" || first === null || second === null) return checkIsSameValueZero(first, second);
|
|
567
|
+
if (Object.getPrototypeOf(first) !== Object.getPrototypeOf(second)) return false;
|
|
568
|
+
if (Array.isArray(first) || Array.isArray(second)) {
|
|
569
|
+
if (!Array.isArray(first) || !Array.isArray(second) || first.length !== second.length) return false;
|
|
570
|
+
for (const [index, item] of first.entries()) if (!checkIsDeepEqual(item, second[index])) return false;
|
|
571
|
+
return true;
|
|
572
|
+
}
|
|
573
|
+
if (checkIsBinary(first) && checkIsBinary(second)) return checkIsSameBytes(first, second);
|
|
574
|
+
if (first instanceof RegExp && second instanceof RegExp) return first.source === second.source && first.flags === second.flags;
|
|
575
|
+
if (first instanceof WeakMap || first instanceof WeakSet || first instanceof Promise || first instanceof Blob) return false;
|
|
576
|
+
if (checkIsCustomMethod(first, "valueOf") && checkIsCustomMethod(second, "valueOf")) return checkIsSameValueZero(first.valueOf(), second.valueOf());
|
|
577
|
+
if (checkIsCustomMethod(first, "toString") && checkIsCustomMethod(second, "toString")) return first.toString() === second.toString();
|
|
578
|
+
if (first instanceof Map && second instanceof Map) {
|
|
579
|
+
if (first.size !== second.size) return false;
|
|
580
|
+
for (const [key, value] of first) if (!second.has(key) || !checkIsDeepEqual(value, second.get(key))) return false;
|
|
581
|
+
return true;
|
|
582
|
+
}
|
|
583
|
+
if (first instanceof Set && second instanceof Set) {
|
|
584
|
+
if (first.size !== second.size) return false;
|
|
585
|
+
for (const value of first) if (!second.has(value)) return false;
|
|
586
|
+
return true;
|
|
587
|
+
}
|
|
588
|
+
const firstKeys = getEnumerableKeys(first);
|
|
589
|
+
if (firstKeys.length !== getEnumerableKeys(second).length) return false;
|
|
590
|
+
return firstKeys.every((key) => Object.prototype.propertyIsEnumerable.call(second, key) && checkIsDeepEqual(Reflect.get(first, key), Reflect.get(second, key)));
|
|
591
|
+
};
|
|
592
|
+
//#endregion
|
|
593
|
+
//#region src/util/validation/exhaustiveGuard.ts
|
|
594
|
+
const exhaustiveGuard = (value) => {
|
|
595
|
+
throw new InvalidOperationError("Read", exhaustiveGuard.name, JSON.stringify(value));
|
|
596
|
+
};
|
|
597
|
+
//#endregion
|
|
598
|
+
//#region src/services/jsonPatch/applyPatch.ts
|
|
599
|
+
const applyPatch = (document, operation) => {
|
|
600
|
+
switch (operation.op) {
|
|
601
|
+
case "add": return addJsonValue(document, operation.path, operation.value);
|
|
602
|
+
case "copy": return addJsonValue(document, operation.path, readJsonValue(document, parseJsonPointer(operation.from)));
|
|
603
|
+
case "move": {
|
|
604
|
+
if (operation.from === operation.path) {
|
|
605
|
+
readJsonValue(document, parseJsonPointer(operation.from));
|
|
606
|
+
return {
|
|
607
|
+
document,
|
|
608
|
+
inverses: []
|
|
609
|
+
};
|
|
610
|
+
} else if (operation.path.startsWith(`${operation.from}/`)) throw new InvalidOperationError("Update", operation.path, "a value cannot move into itself");
|
|
611
|
+
const removed = removeJsonValue(document, operation.from);
|
|
612
|
+
const added = addJsonValue(removed.document, operation.path, readJsonValue(document, parseJsonPointer(operation.from)));
|
|
613
|
+
return {
|
|
614
|
+
document: added.document,
|
|
615
|
+
inverses: [...added.inverses, ...removed.inverses]
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
case "remove": return removeJsonValue(document, operation.path);
|
|
619
|
+
case "replace": {
|
|
620
|
+
const segments = parseJsonPointer(operation.path);
|
|
621
|
+
const replacedValue = readJsonValue(document, segments);
|
|
622
|
+
return {
|
|
623
|
+
document: updateJsonValue(document, segments, () => operation.value),
|
|
624
|
+
inverses: [{
|
|
625
|
+
op: "replace",
|
|
626
|
+
path: operation.path,
|
|
627
|
+
value: replacedValue
|
|
628
|
+
}]
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
case "test":
|
|
632
|
+
if (!checkIsDeepEqual(readJsonValue(document, parseJsonPointer(operation.path)), operation.value)) throw new InvalidOperationError("Read", operation.path, "the value differs from the test's");
|
|
633
|
+
return {
|
|
634
|
+
document,
|
|
635
|
+
inverses: []
|
|
636
|
+
};
|
|
637
|
+
default: return exhaustiveGuard(operation);
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
//#endregion
|
|
641
|
+
//#region src/services/jsonPatch/applyPatches.ts
|
|
642
|
+
const applyPatches = (document, operations) => {
|
|
643
|
+
let patchedDocument = document;
|
|
644
|
+
const inverseGroups = [];
|
|
645
|
+
for (const operation of operations) {
|
|
646
|
+
const result = applyPatch(patchedDocument, operation);
|
|
647
|
+
patchedDocument = result.document;
|
|
648
|
+
inverseGroups.push(result.inverses);
|
|
649
|
+
}
|
|
650
|
+
return {
|
|
651
|
+
document: patchedDocument,
|
|
652
|
+
inverses: inverseGroups.toReversed().flat()
|
|
653
|
+
};
|
|
654
|
+
};
|
|
655
|
+
//#endregion
|
|
363
656
|
//#region src/services/message/constants.ts
|
|
364
657
|
const MENTION_ID_ATTRIBUTE = "data-id";
|
|
365
658
|
const MENTION_ITEM_TYPE_ATTRIBUTE = "data-mention-type";
|
|
@@ -971,7 +1264,7 @@ const checkIsAllowedUrl = (url, allowedSchemes) => {
|
|
|
971
1264
|
const beforePath = takeOne(normalizedUrl.split(PATH_DELIMITER_REGEX), 0);
|
|
972
1265
|
const separatorIndex = beforePath.indexOf(SCHEME_SEPARATOR);
|
|
973
1266
|
if (separatorIndex === -1) return true;
|
|
974
|
-
const scheme = beforePath.slice(0, separatorIndex).
|
|
1267
|
+
const scheme = beforePath.slice(0, separatorIndex).replaceAll(NON_SCHEME_CHARACTERS_REGEX, "").toLowerCase();
|
|
975
1268
|
return allowedSchemes.includes(scheme);
|
|
976
1269
|
};
|
|
977
1270
|
//#endregion
|
|
@@ -1109,7 +1402,7 @@ const MAX_NESTING_DEPTH = 256;
|
|
|
1109
1402
|
const SRCSET_DESCRIPTOR_REGEX = /^(?:\d+w|\d*\.?\d+x|\d+h)$/u;
|
|
1110
1403
|
const ESCAPED_TEXT_CHARACTERS_REGEX = /[&<>]/gu;
|
|
1111
1404
|
const ESCAPED_ATTRIBUTE_CHARACTERS_REGEX = /[&"<>]/gu;
|
|
1112
|
-
const SANITIZER_ADVISORY_WATCH_SINCE = "2026-10-
|
|
1405
|
+
const SANITIZER_ADVISORY_WATCH_SINCE = "2026-10-21";
|
|
1113
1406
|
//#endregion
|
|
1114
1407
|
//#region src/services/sanitizeHtml/getChildNodes.ts
|
|
1115
1408
|
const getChildNodes = (element) => "content" in element ? element.content.childNodes : element.childNodes;
|
|
@@ -1213,6 +1506,7 @@ const filterStyle = (value, rules) => {
|
|
|
1213
1506
|
//#endregion
|
|
1214
1507
|
//#region src/services/sanitizeHtml/filterAttributes.ts
|
|
1215
1508
|
const getTagPolicy = (tagPolicies, tagName) => Object.hasOwn(tagPolicies, tagName) ? tagPolicies[tagName] : void 0;
|
|
1509
|
+
const checkIsMetaRefresh = (tagName, attributes) => tagName === "meta" && attributes["http-equiv"]?.trim().toLowerCase() === "refresh";
|
|
1216
1510
|
const filterAttributes = (element, policy) => {
|
|
1217
1511
|
const { tagName } = element;
|
|
1218
1512
|
const allowedAttributes = getTagPolicy(policy.allowedAttributes, tagName) ?? [];
|
|
@@ -1223,6 +1517,7 @@ const filterAttributes = (element, policy) => {
|
|
|
1223
1517
|
const kept = {};
|
|
1224
1518
|
for (const [name, value] of Object.entries(attributes)) {
|
|
1225
1519
|
if (name === "class" ? !isClassAllowed : !allowedAttributes.includes(name)) continue;
|
|
1520
|
+
if (name === "content" && checkIsMetaRefresh(tagName, attributes)) continue;
|
|
1226
1521
|
const filteredValue = filterValue(tagName, name, value, policy);
|
|
1227
1522
|
if (filteredValue !== void 0) kept[name] = filteredValue;
|
|
1228
1523
|
}
|
|
@@ -1370,8 +1665,15 @@ const normalizeString = (value) => value?.trim() ?? "";
|
|
|
1370
1665
|
//#region src/services/zod/createNormalizedStringSchema.ts
|
|
1371
1666
|
const createNormalizedStringSchema = (maxLength, schema = z.string()) => schema.transform(normalizeString).pipe(z.string().max(maxLength));
|
|
1372
1667
|
//#endregion
|
|
1668
|
+
//#region src/util/id/constants.ts
|
|
1669
|
+
const ID_SEPARATOR = "|";
|
|
1670
|
+
//#endregion
|
|
1373
1671
|
//#region src/services/zod/createUniqueArraySchema.ts
|
|
1374
|
-
const
|
|
1672
|
+
const getItemKey = (item, key) => {
|
|
1673
|
+
const record = item;
|
|
1674
|
+
return typeof key === "string" ? record[key] : key.map((part) => record[part]).join("|");
|
|
1675
|
+
};
|
|
1676
|
+
const createUniqueArraySchema = (schema, key) => schema.array().refine((array) => new Set(key === void 0 ? array : array.map((item) => getItemKey(item, key))).size === array.length, { error: "Array items must be unique" });
|
|
1375
1677
|
//#endregion
|
|
1376
1678
|
//#region src/services/zstd/constants.ts
|
|
1377
1679
|
const DEFAULT_COMPRESSION_LEVEL = 12;
|
|
@@ -1457,13 +1759,16 @@ const chunkBySerializedSize = (items, maxBytes, maxCount) => {
|
|
|
1457
1759
|
return chunks;
|
|
1458
1760
|
};
|
|
1459
1761
|
//#endregion
|
|
1762
|
+
//#region src/util/array/takeRandom.ts
|
|
1763
|
+
const takeRandom = (values, random) => takeOne(values, Math.floor(random() * values.length));
|
|
1764
|
+
//#endregion
|
|
1460
1765
|
//#region src/util/date/getZonedDateTime.ts
|
|
1461
1766
|
const getZonedDateTime = (date) => Temporal.Instant.fromEpochMilliseconds(date.getTime()).toZonedDateTimeISO(Temporal.Now.timeZoneId());
|
|
1462
1767
|
//#endregion
|
|
1463
1768
|
//#region src/util/date/getEndOfDay.ts
|
|
1464
1769
|
const getEndOfDay = (date) => /* @__PURE__ */ new Date(getZonedDateTime(date).startOfDay().add({ days: 1 }).epochMilliseconds - 1);
|
|
1465
1770
|
//#endregion
|
|
1466
|
-
//#region src/util/dom/
|
|
1771
|
+
//#region src/util/dom/checkIsNestedControl.ts
|
|
1467
1772
|
const NESTED_INTERACTION_SELECTOR = [
|
|
1468
1773
|
"a[href]",
|
|
1469
1774
|
"button",
|
|
@@ -1487,12 +1792,31 @@ const NESTED_INTERACTION_SELECTOR = [
|
|
|
1487
1792
|
"[role='switch']",
|
|
1488
1793
|
"[role='tab']"
|
|
1489
1794
|
].join(", ");
|
|
1490
|
-
const
|
|
1795
|
+
const checkIsNestedControl = (event) => {
|
|
1491
1796
|
const { currentTarget, target } = event;
|
|
1492
1797
|
if (!(currentTarget instanceof Element) || !(target instanceof Element)) return false;
|
|
1493
1798
|
const interactiveElement = target.closest(NESTED_INTERACTION_SELECTOR);
|
|
1494
|
-
|
|
1495
|
-
|
|
1799
|
+
return Boolean(interactiveElement && interactiveElement !== currentTarget && currentTarget.contains(interactiveElement));
|
|
1800
|
+
};
|
|
1801
|
+
//#endregion
|
|
1802
|
+
//#region src/util/dom/checkIsNestedInteraction.ts
|
|
1803
|
+
const checkIsNestedInteraction = (event) => checkIsNestedControl(event) || Boolean(window.getSelection()?.toString());
|
|
1804
|
+
//#endregion
|
|
1805
|
+
//#region src/util/dom/downloadUrl.ts
|
|
1806
|
+
const downloadUrl = (url, filename) => {
|
|
1807
|
+
const anchor = window.document.createElement("a");
|
|
1808
|
+
anchor.href = url;
|
|
1809
|
+
anchor.download = filename;
|
|
1810
|
+
anchor.click();
|
|
1811
|
+
};
|
|
1812
|
+
//#endregion
|
|
1813
|
+
//#region src/util/dom/downloadFile.ts
|
|
1814
|
+
const downloadFile = (filename, blobPart, type) => {
|
|
1815
|
+
const url = URL.createObjectURL(new Blob([blobPart], { type }));
|
|
1816
|
+
downloadUrl(url, filename);
|
|
1817
|
+
window.setTimeout(() => {
|
|
1818
|
+
URL.revokeObjectURL(url);
|
|
1819
|
+
}, 0);
|
|
1496
1820
|
};
|
|
1497
1821
|
//#endregion
|
|
1498
1822
|
//#region src/util/environment/checkIsServer.ts
|
|
@@ -1510,9 +1834,6 @@ const waitForSynchronizedFunctions = async () => {
|
|
|
1510
1834
|
await Promise.allSettled(pendingPromises);
|
|
1511
1835
|
};
|
|
1512
1836
|
//#endregion
|
|
1513
|
-
//#region src/util/id/constants.ts
|
|
1514
|
-
const ID_SEPARATOR = "|";
|
|
1515
|
-
//#endregion
|
|
1516
1837
|
//#region src/util/id/uuid/constants.ts
|
|
1517
1838
|
const UUIDV4_REGEX = /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/iu;
|
|
1518
1839
|
//#endregion
|
|
@@ -1524,63 +1845,23 @@ const getOrCreate = (map, key, create) => {
|
|
|
1524
1845
|
return value;
|
|
1525
1846
|
};
|
|
1526
1847
|
//#endregion
|
|
1527
|
-
//#region src/util/object/
|
|
1528
|
-
const
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
const
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
//#region src/util/object/checkIsSameValueZero.ts
|
|
1542
|
-
const checkIsSameValueZero = (first, second) => first === second || Number.isNaN(first) && Number.isNaN(second);
|
|
1543
|
-
//#endregion
|
|
1544
|
-
//#region src/util/object/getEnumerableKeys.ts
|
|
1545
|
-
const getEnumerableKeys = (value) => Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
|
|
1546
|
-
//#endregion
|
|
1547
|
-
//#region src/util/object/checkIsDeepEqual.ts
|
|
1548
|
-
const checkIsBinary = (value) => ArrayBuffer.isView(value) || value instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && value instanceof SharedArrayBuffer;
|
|
1549
|
-
const checkIsDeepEqual = (first, second) => {
|
|
1550
|
-
if (first === second) return true;
|
|
1551
|
-
if (typeof first !== "object" || typeof second !== "object" || first === null || second === null) return checkIsSameValueZero(first, second);
|
|
1552
|
-
if (Object.getPrototypeOf(first) !== Object.getPrototypeOf(second)) return false;
|
|
1553
|
-
if (Array.isArray(first) || Array.isArray(second)) {
|
|
1554
|
-
if (!Array.isArray(first) || !Array.isArray(second) || first.length !== second.length) return false;
|
|
1555
|
-
for (const [index, item] of first.entries()) if (!checkIsDeepEqual(item, second[index])) return false;
|
|
1556
|
-
return true;
|
|
1557
|
-
}
|
|
1558
|
-
if (checkIsBinary(first) && checkIsBinary(second)) return checkIsSameBytes(first, second);
|
|
1559
|
-
if (first instanceof RegExp && second instanceof RegExp) return first.source === second.source && first.flags === second.flags;
|
|
1560
|
-
if (first instanceof WeakMap || first instanceof WeakSet || first instanceof Promise || first instanceof Blob) return false;
|
|
1561
|
-
if (checkIsCustomMethod(first, "valueOf") && checkIsCustomMethod(second, "valueOf")) return checkIsSameValueZero(first.valueOf(), second.valueOf());
|
|
1562
|
-
if (checkIsCustomMethod(first, "toString") && checkIsCustomMethod(second, "toString")) return first.toString() === second.toString();
|
|
1563
|
-
if (first instanceof Map && second instanceof Map) {
|
|
1564
|
-
if (first.size !== second.size) return false;
|
|
1565
|
-
for (const [key, value] of first) if (!second.has(key) || !checkIsDeepEqual(value, second.get(key))) return false;
|
|
1566
|
-
return true;
|
|
1567
|
-
}
|
|
1568
|
-
if (first instanceof Set && second instanceof Set) {
|
|
1569
|
-
if (first.size !== second.size) return false;
|
|
1570
|
-
for (const value of first) if (!second.has(value)) return false;
|
|
1571
|
-
return true;
|
|
1848
|
+
//#region src/util/object/clonePlainDeep.ts
|
|
1849
|
+
const clone = (data, copies) => {
|
|
1850
|
+
if (!Array.isArray(data) && !checkIsPlainObject(data)) return data;
|
|
1851
|
+
else if (copies.has(data)) return copies.get(data);
|
|
1852
|
+
else if (Array.isArray(data)) {
|
|
1853
|
+
const copy = [];
|
|
1854
|
+
copies.set(data, copy);
|
|
1855
|
+
for (const [index, item] of data.entries()) copy[index] = clone(item, copies);
|
|
1856
|
+
return copy;
|
|
1857
|
+
} else {
|
|
1858
|
+
const copy = {};
|
|
1859
|
+
copies.set(data, copy);
|
|
1860
|
+
for (const [key, value] of Object.entries(data)) copy[key] = clone(value, copies);
|
|
1861
|
+
return copy;
|
|
1572
1862
|
}
|
|
1573
|
-
const firstKeys = getEnumerableKeys(first);
|
|
1574
|
-
if (firstKeys.length !== getEnumerableKeys(second).length) return false;
|
|
1575
|
-
return firstKeys.every((key) => Object.prototype.propertyIsEnumerable.call(second, key) && checkIsDeepEqual(Reflect.get(first, key), Reflect.get(second, key)));
|
|
1576
|
-
};
|
|
1577
|
-
//#endregion
|
|
1578
|
-
//#region src/util/object/checkIsPlainObject.ts
|
|
1579
|
-
const checkIsPlainObject = (data) => {
|
|
1580
|
-
if (typeof data !== "object" || data === null) return false;
|
|
1581
|
-
const prototype = Object.getPrototypeOf(data);
|
|
1582
|
-
return prototype === null || prototype === Object.prototype;
|
|
1583
1863
|
};
|
|
1864
|
+
const clonePlainDeep = (data) => clone(data, /* @__PURE__ */ new WeakMap());
|
|
1584
1865
|
//#endregion
|
|
1585
1866
|
//#region src/util/object/getPropertyNames.ts
|
|
1586
1867
|
const getPropertyNames = () => new Proxy({}, { get: (_target, property) => property });
|
|
@@ -1878,6 +2159,9 @@ const truncate = (string, length) => {
|
|
|
1878
2159
|
//#region src/util/text/uncapitalize.ts
|
|
1879
2160
|
const uncapitalize = (string) => `${string.charAt(0).toLowerCase()}${string.slice(1)}`;
|
|
1880
2161
|
//#endregion
|
|
2162
|
+
//#region src/util/time/constants.ts
|
|
2163
|
+
const MILLISECONDS_PER_SECOND = 1e3;
|
|
2164
|
+
//#endregion
|
|
1881
2165
|
//#region src/util/time/hrtime.ts
|
|
1882
2166
|
const hrtime = (previousHrTime) => {
|
|
1883
2167
|
if (checkIsServer()) return process.hrtime(previousHrTime);
|
|
@@ -1910,9 +2194,4 @@ const sleep = (durationMs) => new Promise((resolve) => {
|
|
|
1910
2194
|
}, durationMs);
|
|
1911
2195
|
});
|
|
1912
2196
|
//#endregion
|
|
1913
|
-
|
|
1914
|
-
const exhaustiveGuard = (value) => {
|
|
1915
|
-
throw new InvalidOperationError("Read", exhaustiveGuard.name, JSON.stringify(value));
|
|
1916
|
-
};
|
|
1917
|
-
//#endregion
|
|
1918
|
-
export { ALL_SPECIAL_VALUES, CHARSET_PARAMETER_REGEX, CUSTOM_EMOJI_ID_ATTRIBUTE, CUSTOM_EMOJI_NAME_ATTRIBUTE, DEFAULT_ALLOWED_ATTRIBUTES, DEFAULT_ALLOWED_SCHEMES, DEFAULT_ALLOWED_TAGS, DEFAULT_COMPRESSION_LEVEL, DEFAULT_FACET_SCORE, DEFAULT_LINK_ATTRIBUTES, DEFAULT_SOURCE_SCORE, DEFAULT_TEXT_CHARSET, DEFAULT_TYPE_SCORE, ESCAPED_ATTRIBUTE_CHARACTERS_REGEX, ESCAPED_TEXT_CHARACTERS_REGEX, FacetScoreMap, ForbiddenError, GIBIBYTE, HTML_NAMESPACE, ID_SEPARATOR, IMPORTANT_REGEX, InvalidOperationError, ItemMetadata, KIBIBYTE, MAX_NESTING_DEPTH, MAX_READ_LIMIT, MAX_WINDOW_LOG, MEDIA_TYPE_REGEX, MENTION_EVERYONE_ID, MENTION_HERE_ID, MENTION_ID_ATTRIBUTE, MENTION_ITEM_TYPE_ATTRIBUTE, MENTION_LABEL_ATTRIBUTE, MENTION_SELECTOR, MENTION_TYPE, MENTION_TYPE_ATTRIBUTE, MIN_WINDOW_LOG, MentionType, NON_TEXT_TAGS, NotFoundError, NotInitializedError, ObjectMethod, Operation, PATH_SEPARATOR_REGEX, RoutePath, SANITIZER_ADVISORY_WATCH_SINCE, SITE_NAME, SPOILER_ATTRIBUTE, SPOILER_SELECTOR, SRCSET_ATTRIBUTE, SRCSET_DESCRIPTOR_REGEX, Serializable, SourceScoreMap, TEXT_MEDIA_TYPE_REGEX, TypeScoreMap, TypedEventEmitter, URL_ATTRIBUTES, UUIDV4_REGEX, VOID_TAGS, WordFilteredError, applyItemMetadataMixin, capitalize, charset, checkContainsProfanity, checkIsAllowedUrl, checkIsCustomMethod, checkIsDeepEqual, checkIsNestedInteraction, checkIsPlainObject, checkIsSameBytes, checkIsSameValueZero, checkIsServer, checkIsUnsafeUrlCharacter, checkIsWhitespaceCharacter, chunk, chunkBySerializedSize, collectText, contentType, createEvictingPromiseCache, createItemEntityTypeSchema, createNormalizedStringSchema, createUniqueArraySchema, css, dedent, encodeUrlSubDelimiters, englishProfaneWords, escapeAttribute, escapeCharacters, escapeText, exhaustiveGuard, extension, filterAttributes, filterClasses, filterHtml, filterSrcset, filterStyle, getChildNodes, getDecodedUriComponent, getEndOfDay, getEnumerableKeys, getExtensionMimeTypeMap, getMediaType, getMentions, getMimeScore, getMimeTypeEntryMap, getOrCreate, getPropertyNames, getRawData, getRequestError, getResult, getResultAsync, getSynchronizedFunction, getTransactionDone, getTransactionObjectStore, getWindowLog, getZonedDateTime, hrtime, html, jsonDateParse, lookup, matchesClassPattern, mergeObjectsStrict, noop, normalizeString, now, omitDeep, openDatabase, renderNode, reportFinalizerError, requestToPromise, sanitizeHtml, sanitizeTextHtml, settleAll, sleep, streamToText, takeOne, toAppError, toKebabCase, toRawDeep, truncate, uncapitalize, waitForSynchronizedFunctions, withFinalizer, withFinalizerAsync, wrapDatabase, wrapIndex, wrapObjectStore, wrapTransaction, wrapUpgradeDatabase, wrapUpgradeTransaction };
|
|
2197
|
+
export { ALL_SPECIAL_VALUES, APPEND_SEGMENT, CHARSET_PARAMETER_REGEX, CUSTOM_EMOJI_ID_ATTRIBUTE, CUSTOM_EMOJI_NAME_ATTRIBUTE, DEFAULT_ALLOWED_ATTRIBUTES, DEFAULT_ALLOWED_SCHEMES, DEFAULT_ALLOWED_TAGS, DEFAULT_COMPRESSION_LEVEL, DEFAULT_FACET_SCORE, DEFAULT_LINK_ATTRIBUTES, DEFAULT_SOURCE_SCORE, DEFAULT_TEXT_CHARSET, DEFAULT_TYPE_SCORE, ESCAPED_ATTRIBUTE_CHARACTERS_REGEX, ESCAPED_TEXT_CHARACTERS_REGEX, FacetScoreMap, ForbiddenError, GIBIBYTE, HTML_NAMESPACE, ID_SEPARATOR, IMPORTANT_REGEX, InvalidOperationError, ItemMetadata, JSON_POINTER_REGEX, JsonPatchOperationType, KIBIBYTE, MAX_NESTING_DEPTH, MAX_READ_LIMIT, MAX_WINDOW_LOG, MEDIA_TYPE_REGEX, MENTION_EVERYONE_ID, MENTION_HERE_ID, MENTION_ID_ATTRIBUTE, MENTION_ITEM_TYPE_ATTRIBUTE, MENTION_LABEL_ATTRIBUTE, MENTION_SELECTOR, MENTION_TYPE, MENTION_TYPE_ATTRIBUTE, MILLISECONDS_PER_SECOND, MIN_WINDOW_LOG, MentionType, NON_TEXT_TAGS, NotFoundError, NotInitializedError, ObjectMethod, Operation, PATH_SEPARATOR_REGEX, RoutePath, SANITIZER_ADVISORY_WATCH_SINCE, SITE_NAME, SPOILER_ATTRIBUTE, SPOILER_SELECTOR, SRCSET_ATTRIBUTE, SRCSET_DESCRIPTOR_REGEX, Serializable, SourceScoreMap, TEXT_MEDIA_TYPE_REGEX, TypeScoreMap, TypedEventEmitter, URL_ATTRIBUTES, UUIDV4_REGEX, VOID_TAGS, WordFilteredError, addJsonValue, applyItemMetadataMixin, applyPatch, applyPatches, capitalize, charset, checkContainsProfanity, checkIsAllowedUrl, checkIsCustomMethod, checkIsDeepEqual, checkIsNestedControl, checkIsNestedInteraction, checkIsPlainObject, checkIsSameBytes, checkIsSameValueZero, checkIsServer, checkIsUnsafeUrlCharacter, checkIsWhitespaceCharacter, chunk, chunkBySerializedSize, clonePlainDeep, collectText, contentType, createEvictingPromiseCache, createHistory, createItemEntityTypeSchema, createNormalizedStringSchema, createUniqueArraySchema, css, dedent, downloadFile, downloadUrl, encodeUrlSubDelimiters, englishProfaneWords, escapeAttribute, escapeCharacters, escapeText, exhaustiveGuard, extension, filterAttributes, filterClasses, filterHtml, filterSrcset, filterStyle, getChildNodes, getDecodedUriComponent, getEndOfDay, getEnumerableKeys, getExtensionMimeTypeMap, getMediaType, getMentions, getMimeScore, getMimeTypeEntryMap, getOrCreate, getPropertyNames, getRawData, getRequestError, getResult, getResultAsync, getSynchronizedFunction, getTransactionDone, getTransactionObjectStore, getWindowLog, getZonedDateTime, hrtime, html, jsonDateParse, lookup, matchesClassPattern, mergeObjectsStrict, noop, normalizeString, now, omitDeep, openDatabase, parseArrayIndex, parseJsonPointer, pushHistory, readJsonValue, redoHistory, removeJsonValue, renderNode, reportFinalizerError, requestToPromise, sanitizeHtml, sanitizeTextHtml, settleAll, sleep, streamToText, takeOne, takeRandom, toAppError, toJsonPointer, toKebabCase, toRawDeep, truncate, uncapitalize, undoHistory, updateJsonValue, waitForSynchronizedFunctions, withFinalizer, withFinalizerAsync, wrapDatabase, wrapIndex, wrapObjectStore, wrapTransaction, wrapUpgradeDatabase, wrapUpgradeTransaction };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@esposter/shared",
|
|
3
|
-
"version": "4.1
|
|
3
|
+
"version": "4.3.1",
|
|
4
4
|
"description": "A library that contains shared typescript code.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"error-handling",
|
|
@@ -40,8 +40,6 @@
|
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "tsdown",
|
|
43
|
-
"format": "oxfmt",
|
|
44
|
-
"format:check": "oxfmt --check",
|
|
45
43
|
"lint": "eslint .",
|
|
46
44
|
"lint:fix": "eslint --fix .",
|
|
47
45
|
"test": "vitest",
|
|
@@ -50,20 +48,17 @@
|
|
|
50
48
|
"dependencies": {
|
|
51
49
|
"mime-db": "^1.54.0",
|
|
52
50
|
"neverthrow": "^8.2.0",
|
|
53
|
-
"node-html-parser": "^9.0.
|
|
51
|
+
"node-html-parser": "^9.0.5",
|
|
54
52
|
"parse5": "^8.0.1"
|
|
55
53
|
},
|
|
56
54
|
"devDependencies": {
|
|
57
|
-
"@arethetypeswrong/core": "^0.18.5",
|
|
58
55
|
"@azure/data-tables": "^13.3.2",
|
|
59
|
-
"@esposter/configuration": "4.1
|
|
56
|
+
"@esposter/configuration": "4.3.1",
|
|
60
57
|
"@types/node": "^26.6.5",
|
|
61
|
-
"fake-indexeddb": "^6.2.
|
|
62
|
-
"happy-dom": "^21.0.
|
|
63
|
-
"publint": "^0.3.25",
|
|
58
|
+
"fake-indexeddb": "^6.2.6",
|
|
59
|
+
"happy-dom": "^21.0.4",
|
|
64
60
|
"tsdown": "^0.23.1",
|
|
65
61
|
"type-fest": "^5.10.0",
|
|
66
|
-
"vitest": "^5.0.4",
|
|
67
62
|
"vue": "^3.5.44"
|
|
68
63
|
},
|
|
69
64
|
"peerDependencies": {
|
|
@@ -72,5 +67,5 @@
|
|
|
72
67
|
"inlinedDependencies": {
|
|
73
68
|
"type-fest": "5.10.0"
|
|
74
69
|
},
|
|
75
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "777a39636b789c13af33ed13370246ccf6dbaf31"
|
|
76
71
|
}
|