@simplysm/core-common 13.0.76 → 13.0.78
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 +64 -21
- package/dist/extensions/arr-ext.d.ts +1 -1
- package/dist/extensions/arr-ext.d.ts.map +1 -1
- package/dist/extensions/arr-ext.helpers.d.ts +8 -0
- package/dist/extensions/arr-ext.helpers.d.ts.map +1 -1
- package/dist/extensions/arr-ext.helpers.js +65 -0
- package/dist/extensions/arr-ext.helpers.js.map +2 -2
- package/dist/extensions/arr-ext.js +16 -124
- package/dist/extensions/arr-ext.js.map +2 -2
- package/dist/extensions/arr-ext.types.d.ts +40 -32
- package/dist/extensions/arr-ext.types.d.ts.map +1 -1
- package/dist/extensions/map-ext.js.map +1 -1
- package/dist/extensions/set-ext.js.map +1 -1
- package/dist/features/event-emitter.d.ts +4 -4
- package/dist/features/event-emitter.d.ts.map +1 -1
- package/dist/features/event-emitter.js.map +1 -1
- package/dist/features/serial-queue.js +2 -2
- package/dist/features/serial-queue.js.map +1 -1
- package/dist/index.d.ts +13 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -13
- package/dist/index.js.map +1 -1
- package/dist/types/date-only.js +2 -2
- package/dist/types/date-only.js.map +1 -1
- package/dist/types/date-time.js +2 -2
- package/dist/types/date-time.js.map +1 -1
- package/dist/types/time.js +2 -2
- package/dist/types/time.js.map +1 -1
- package/dist/types/uuid.d.ts +2 -2
- package/dist/types/uuid.d.ts.map +1 -1
- package/dist/types/uuid.js +1 -1
- package/dist/types/uuid.js.map +1 -1
- package/dist/utils/bytes.d.ts +10 -10
- package/dist/utils/bytes.d.ts.map +1 -1
- package/dist/utils/bytes.js +10 -10
- package/dist/utils/bytes.js.map +1 -1
- package/dist/utils/date-format.d.ts +1 -1
- package/dist/utils/date-format.d.ts.map +1 -1
- package/dist/utils/date-format.js +2 -2
- package/dist/utils/date-format.js.map +1 -1
- package/dist/utils/error.d.ts +1 -1
- package/dist/utils/error.d.ts.map +1 -1
- package/dist/utils/error.js +2 -2
- package/dist/utils/error.js.map +1 -1
- package/dist/utils/json.d.ts +4 -2
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js +9 -9
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/num.d.ts +10 -10
- package/dist/utils/num.d.ts.map +1 -1
- package/dist/utils/num.js +11 -11
- package/dist/utils/num.js.map +1 -1
- package/dist/utils/obj.d.ts +40 -40
- package/dist/utils/obj.d.ts.map +1 -1
- package/dist/utils/obj.js +102 -99
- package/dist/utils/obj.js.map +1 -1
- package/dist/utils/path.d.ts +3 -3
- package/dist/utils/path.d.ts.map +1 -1
- package/dist/utils/path.js +6 -6
- package/dist/utils/path.js.map +1 -1
- package/dist/utils/primitive.d.ts +1 -1
- package/dist/utils/primitive.d.ts.map +1 -1
- package/dist/utils/primitive.js +2 -2
- package/dist/utils/primitive.js.map +1 -1
- package/dist/utils/str.d.ts +16 -16
- package/dist/utils/str.d.ts.map +1 -1
- package/dist/utils/str.js +16 -16
- package/dist/utils/str.js.map +1 -1
- package/dist/utils/transferable.d.ts +3 -3
- package/dist/utils/transferable.d.ts.map +1 -1
- package/dist/utils/transferable.js +10 -10
- package/dist/utils/transferable.js.map +1 -1
- package/dist/utils/wait.d.ts +2 -2
- package/dist/utils/wait.d.ts.map +1 -1
- package/dist/utils/wait.js +5 -5
- package/dist/utils/wait.js.map +1 -1
- package/dist/utils/xml.d.ts +2 -2
- package/dist/utils/xml.d.ts.map +1 -1
- package/dist/utils/xml.js +4 -4
- package/dist/utils/xml.js.map +1 -1
- package/dist/{zip/sd-zip.d.ts → utils/zip.d.ts} +1 -1
- package/dist/utils/zip.d.ts.map +1 -0
- package/dist/{zip/sd-zip.js → utils/zip.js} +1 -1
- package/dist/{zip/sd-zip.js.map → utils/zip.js.map} +1 -1
- package/package.json +1 -1
- package/src/extensions/arr-ext.helpers.ts +86 -0
- package/src/extensions/arr-ext.ts +22 -170
- package/src/extensions/arr-ext.types.ts +76 -48
- package/src/extensions/map-ext.ts +3 -3
- package/src/extensions/set-ext.ts +2 -2
- package/src/features/event-emitter.ts +6 -6
- package/src/features/serial-queue.ts +2 -2
- package/src/index.ts +16 -16
- package/src/types/date-only.ts +2 -2
- package/src/types/date-time.ts +2 -2
- package/src/types/time.ts +2 -2
- package/src/types/uuid.ts +2 -2
- package/src/utils/bytes.ts +15 -15
- package/src/utils/date-format.ts +1 -1
- package/src/utils/error.ts +1 -1
- package/src/utils/json.ts +9 -7
- package/src/utils/num.ts +15 -15
- package/src/utils/obj.ts +119 -116
- package/src/utils/path.ts +3 -3
- package/src/utils/primitive.ts +1 -1
- package/src/utils/str.ts +16 -16
- package/src/utils/transferable.ts +9 -9
- package/src/utils/wait.ts +3 -3
- package/src/utils/xml.ts +2 -2
- package/tests/extensions/array-extension.spec.ts +7 -5
- package/tests/types/uuid.spec.ts +4 -4
- package/tests/utils/bytes-utils.spec.ts +42 -49
- package/tests/utils/date-format.spec.ts +89 -88
- package/tests/utils/debounce-queue.spec.ts +3 -1
- package/tests/utils/json.spec.ts +61 -68
- package/tests/utils/number.spec.ts +41 -46
- package/tests/utils/object.spec.ts +120 -139
- package/tests/utils/path.spec.ts +19 -19
- package/tests/utils/primitive.spec.ts +12 -12
- package/tests/utils/string.spec.ts +66 -74
- package/tests/utils/transferable.spec.ts +55 -62
- package/tests/utils/wait.spec.ts +10 -10
- package/tests/utils/xml.spec.ts +25 -25
- package/dist/zip/sd-zip.d.ts.map +0 -1
- /package/src/{zip/sd-zip.ts → utils/zip.ts} +0 -0
- /package/tests/{zip/sd-zip.spec.ts → utils/zip.spec.ts} +0 -0
package/src/types/time.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ArgumentError } from "../errors/argument-error";
|
|
2
|
-
import { convert12To24,
|
|
2
|
+
import { convert12To24, format } from "../utils/date-format";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Time class (without date: HH:mm:ss.fff, immutable)
|
|
@@ -205,7 +205,7 @@ export class Time {
|
|
|
205
205
|
* @see dtFormat for supported format strings
|
|
206
206
|
*/
|
|
207
207
|
toFormatString(formatStr: string): string {
|
|
208
|
-
return
|
|
208
|
+
return format(formatStr, {
|
|
209
209
|
hour: this.hour,
|
|
210
210
|
minute: this.minute,
|
|
211
211
|
second: this.second,
|
package/src/types/uuid.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { ArgumentError } from "../errors/argument-error";
|
|
|
7
7
|
* Generates cryptographically secure UUIDs based on crypto.getRandomValues. (Chrome 79+, Node.js compatible)
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
|
-
* const id = Uuid.
|
|
10
|
+
* const id = Uuid.generate();
|
|
11
11
|
* const fromStr = new Uuid("550e8400-e29b-41d4-a716-446655440000");
|
|
12
12
|
*/
|
|
13
13
|
export class Uuid {
|
|
@@ -47,7 +47,7 @@ export class Uuid {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/** Create new UUID v4 instance */
|
|
50
|
-
static
|
|
50
|
+
static generate(): Uuid {
|
|
51
51
|
const bytes = new Uint8Array(16);
|
|
52
52
|
crypto.getRandomValues(bytes);
|
|
53
53
|
|
package/src/utils/bytes.ts
CHANGED
|
@@ -5,11 +5,11 @@ import { ArgumentError } from "../errors/argument-error";
|
|
|
5
5
|
* Uint8Array utility functions (complex operations only)
|
|
6
6
|
*
|
|
7
7
|
* Features:
|
|
8
|
-
* -
|
|
9
|
-
* -
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
8
|
+
* - concat: Concatenate multiple Uint8Arrays
|
|
9
|
+
* - toHex: Convert Uint8Array to hex string
|
|
10
|
+
* - fromHex: Convert hex string to Uint8Array
|
|
11
|
+
* - toBase64: Convert Uint8Array to base64 string
|
|
12
|
+
* - fromBase64: Convert base64 string to Uint8Array
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
/** Lookup table for hex conversion (performance optimization) */
|
|
@@ -31,10 +31,10 @@ const BASE64_LOOKUP: number[] = Array.from({ length: 256 }, (_, i) => {
|
|
|
31
31
|
* @example
|
|
32
32
|
* const a = new Uint8Array([1, 2]);
|
|
33
33
|
* const b = new Uint8Array([3, 4]);
|
|
34
|
-
*
|
|
34
|
+
* concat([a, b]);
|
|
35
35
|
* // Uint8Array([1, 2, 3, 4])
|
|
36
36
|
*/
|
|
37
|
-
export function
|
|
37
|
+
export function concat(arrays: Bytes[]): Bytes {
|
|
38
38
|
const total = arrays.reduce((sum, arr) => sum + arr.length, 0);
|
|
39
39
|
const result = new Uint8Array(total);
|
|
40
40
|
let offset = 0;
|
|
@@ -50,10 +50,10 @@ export function bytesConcat(arrays: Bytes[]): Bytes {
|
|
|
50
50
|
* @param bytes Uint8Array to convert
|
|
51
51
|
* @returns Lowercase hex string
|
|
52
52
|
* @example
|
|
53
|
-
*
|
|
53
|
+
* toHex(new Uint8Array([255, 0, 127]));
|
|
54
54
|
* // "ff007f"
|
|
55
55
|
*/
|
|
56
|
-
export function
|
|
56
|
+
export function toHex(bytes: Bytes): string {
|
|
57
57
|
const h = hexTable;
|
|
58
58
|
let result = "";
|
|
59
59
|
for (let i = 0; i < bytes.length; i++) {
|
|
@@ -68,10 +68,10 @@ export function bytesToHex(bytes: Bytes): string {
|
|
|
68
68
|
* @returns Converted Uint8Array
|
|
69
69
|
* @throws {ArgumentError} If odd length or invalid hex characters are present
|
|
70
70
|
* @example
|
|
71
|
-
*
|
|
71
|
+
* fromHex("ff007f");
|
|
72
72
|
* // Uint8Array([255, 0, 127])
|
|
73
73
|
*/
|
|
74
|
-
export function
|
|
74
|
+
export function fromHex(hex: string): Bytes {
|
|
75
75
|
if (hex.length % 2 !== 0) {
|
|
76
76
|
throw new ArgumentError("Hex string must have even length", { hex });
|
|
77
77
|
}
|
|
@@ -90,10 +90,10 @@ export function bytesFromHex(hex: string): Bytes {
|
|
|
90
90
|
* @param bytes Uint8Array to convert
|
|
91
91
|
* @returns Base64 encoded string
|
|
92
92
|
* @example
|
|
93
|
-
*
|
|
93
|
+
* toBase64(new Uint8Array([72, 101, 108, 108, 111]));
|
|
94
94
|
* // "SGVsbG8="
|
|
95
95
|
*/
|
|
96
|
-
export function
|
|
96
|
+
export function toBase64(bytes: Bytes): string {
|
|
97
97
|
if (bytes.length === 0) {
|
|
98
98
|
return "";
|
|
99
99
|
}
|
|
@@ -118,10 +118,10 @@ export function bytesToBase64(bytes: Bytes): string {
|
|
|
118
118
|
* @returns Decoded Uint8Array
|
|
119
119
|
* @throws {ArgumentError} If invalid base64 character is present
|
|
120
120
|
* @example
|
|
121
|
-
*
|
|
121
|
+
* fromBase64("SGVsbG8=");
|
|
122
122
|
* // Uint8Array([72, 101, 108, 108, 111])
|
|
123
123
|
*/
|
|
124
|
-
export function
|
|
124
|
+
export function fromBase64(base64: string): Bytes {
|
|
125
125
|
// Remove whitespace and normalize padding
|
|
126
126
|
const cleanBase64 = base64.replace(/\s/g, "").replace(/=+$/, "");
|
|
127
127
|
|
package/src/utils/date-format.ts
CHANGED
package/src/utils/error.ts
CHANGED
package/src/utils/json.ts
CHANGED
|
@@ -6,9 +6,9 @@ import { DateTime } from "../types/date-time";
|
|
|
6
6
|
import { DateOnly } from "../types/date-only";
|
|
7
7
|
import { Time } from "../types/time";
|
|
8
8
|
import { Uuid } from "../types/uuid";
|
|
9
|
-
import {
|
|
9
|
+
import { nullToUndefined } from "./obj";
|
|
10
10
|
import { SdError } from "../errors/sd-error";
|
|
11
|
-
import {
|
|
11
|
+
import { toHex, fromHex } from "./bytes";
|
|
12
12
|
import { env } from "../env";
|
|
13
13
|
|
|
14
14
|
interface TypedObject {
|
|
@@ -33,7 +33,7 @@ interface TypedObject {
|
|
|
33
33
|
* - If object has toJSON method, it is called and the result is used (except for custom types like Date, DateTime)
|
|
34
34
|
* - Safe in Worker environments as global prototypes are not modified
|
|
35
35
|
*/
|
|
36
|
-
export function
|
|
36
|
+
export function stringify(
|
|
37
37
|
obj: unknown,
|
|
38
38
|
options?: {
|
|
39
39
|
space?: string | number;
|
|
@@ -105,7 +105,7 @@ export function jsonStringify(
|
|
|
105
105
|
if (options?.redactBytes === true) {
|
|
106
106
|
return { __type__: "Uint8Array", data: "__hidden__" };
|
|
107
107
|
}
|
|
108
|
-
return { __type__: "Uint8Array", data:
|
|
108
|
+
return { __type__: "Uint8Array", data: toHex(currValue) };
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// Array processing
|
|
@@ -171,13 +171,15 @@ export function jsonStringify(
|
|
|
171
171
|
* Objects with `__type__` and `data` keys are used for type restoration.
|
|
172
172
|
* Be careful if user data contains objects with `{ __type__: "Date" | "DateTime" | "DateOnly" | "Time" | "Uuid" | "Set" | "Map" | "Error" | "Uint8Array", data: ... }`
|
|
173
173
|
* format as they may be unintentionally converted to types.
|
|
174
|
+
* All JSON null values are converted to undefined.
|
|
175
|
+
* This is intentional for the simplysm framework's null-free convention.
|
|
174
176
|
*
|
|
175
177
|
* @security In development mode (`__DEV__`), the error message includes the entire JSON string.
|
|
176
178
|
* In production mode, only JSON length is included.
|
|
177
179
|
*/
|
|
178
|
-
export function
|
|
180
|
+
export function parse<TResult = unknown>(json: string): TResult {
|
|
179
181
|
try {
|
|
180
|
-
return
|
|
182
|
+
return nullToUndefined(
|
|
181
183
|
JSON.parse(json, (_key, value: unknown) => {
|
|
182
184
|
if (value != null && typeof value === "object") {
|
|
183
185
|
// Restore types based on __type__ marker
|
|
@@ -216,7 +218,7 @@ export function jsonParse<TResult = unknown>(json: string): TResult {
|
|
|
216
218
|
"Uint8Array serialized with redactBytes option cannot be restored via parse",
|
|
217
219
|
);
|
|
218
220
|
}
|
|
219
|
-
return
|
|
221
|
+
return fromHex(typed.data);
|
|
220
222
|
}
|
|
221
223
|
}
|
|
222
224
|
}
|
package/src/utils/num.ts
CHANGED
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
* Number utility functions
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
//#region
|
|
5
|
+
//#region parseInt / parseFloat / parseRoundedInt
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Parse string to integer
|
|
9
9
|
* Remove non-numeric characters (except 0-9, -, .) before parsing
|
|
10
10
|
*
|
|
11
11
|
* @note Strings with decimal points return only the integer part (e.g., '12.34' → 12).
|
|
12
|
-
* Use {@link
|
|
12
|
+
* Use {@link parseRoundedInt} if rounding is needed.
|
|
13
13
|
* @note Hyphens (-) in the middle of the string are preserved, which may result in unintended negative numbers.
|
|
14
14
|
* Example: `"가-123나"` → `-123`
|
|
15
15
|
*/
|
|
16
|
-
export function
|
|
16
|
+
export function parseInt(text: unknown): number | undefined {
|
|
17
17
|
if (typeof text === "number") return Math.trunc(text);
|
|
18
18
|
if (typeof text !== "string") return undefined;
|
|
19
19
|
const txt = text.replace(/[^0-9.\-]/g, "").trim();
|
|
@@ -26,8 +26,8 @@ export function numParseInt(text: unknown): number | undefined {
|
|
|
26
26
|
/**
|
|
27
27
|
* Parse string to float, then round and return integer
|
|
28
28
|
*/
|
|
29
|
-
export function
|
|
30
|
-
const float =
|
|
29
|
+
export function parseRoundedInt(text: unknown): number | undefined {
|
|
30
|
+
const float = parseFloat(text);
|
|
31
31
|
return float !== undefined ? Math.round(float) : undefined;
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -35,7 +35,7 @@ export function numParseRoundedInt(text: unknown): number | undefined {
|
|
|
35
35
|
* Parse string to float
|
|
36
36
|
* Remove non-numeric characters before parsing
|
|
37
37
|
*/
|
|
38
|
-
export function
|
|
38
|
+
export function parseFloat(text: unknown): number | undefined {
|
|
39
39
|
if (typeof text === "number") return text;
|
|
40
40
|
if (typeof text !== "string") return undefined;
|
|
41
41
|
const txt = text.replace(/[^0-9.\-]/g, "").trim();
|
|
@@ -47,7 +47,7 @@ export function numParseFloat(text: unknown): number | undefined {
|
|
|
47
47
|
|
|
48
48
|
//#endregion
|
|
49
49
|
|
|
50
|
-
//#region
|
|
50
|
+
//#region isNullOrEmpty
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
* Check undefined, null, 0 (type guard)
|
|
@@ -59,7 +59,7 @@ export function numParseFloat(text: unknown): number | undefined {
|
|
|
59
59
|
* @returns true if undefined, null, or 0
|
|
60
60
|
* @example
|
|
61
61
|
* const count: number | undefined = getValue();
|
|
62
|
-
* if (
|
|
62
|
+
* if (isNullOrEmpty(count)) {
|
|
63
63
|
* // count: 0 | undefined
|
|
64
64
|
* console.log("Empty");
|
|
65
65
|
* } else {
|
|
@@ -67,13 +67,13 @@ export function numParseFloat(text: unknown): number | undefined {
|
|
|
67
67
|
* console.log(`Count: ${count}`);
|
|
68
68
|
* }
|
|
69
69
|
*/
|
|
70
|
-
export function
|
|
70
|
+
export function isNullOrEmpty(val: number | undefined): val is 0 | undefined {
|
|
71
71
|
return val == null || val === 0;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
//#endregion
|
|
75
75
|
|
|
76
|
-
//#region
|
|
76
|
+
//#region format
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
79
|
* Format number to string with thousand separators
|
|
@@ -82,15 +82,15 @@ export function numIsNullOrEmpty(val: number | undefined): val is 0 | undefined
|
|
|
82
82
|
* @param digit.max Maximum decimal places
|
|
83
83
|
* @param digit.min Minimum decimal places (pad with 0 if insufficient)
|
|
84
84
|
* @example
|
|
85
|
-
*
|
|
86
|
-
*
|
|
85
|
+
* format(1234.567, { max: 2 }) // "1,234.57"
|
|
86
|
+
* format(1234, { min: 2 }) // "1,234.00"
|
|
87
87
|
*/
|
|
88
|
-
export function
|
|
89
|
-
export function
|
|
88
|
+
export function format(val: number, digit?: { max?: number; min?: number }): string;
|
|
89
|
+
export function format(
|
|
90
90
|
val: number | undefined,
|
|
91
91
|
digit?: { max?: number; min?: number },
|
|
92
92
|
): string | undefined;
|
|
93
|
-
export function
|
|
93
|
+
export function format(
|
|
94
94
|
val: number | undefined,
|
|
95
95
|
digit?: { max?: number; min?: number },
|
|
96
96
|
): string | undefined {
|