xjs-common 12.0.0-alpha.2 → 13.0.0-alpha.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 +36 -31
- package/build/const/types.d.ts +3 -0
- package/build/func/decorator/d-type.d.ts +6 -25
- package/build/func/decorator/d-type.js +7 -6
- package/build/func/u-array.d.ts +3 -3
- package/build/func/u-array.js +2 -2
- package/build/func/u-obj.d.ts +13 -6
- package/build/func/u-obj.js +15 -13
- package/build/func/u-type.d.ts +5 -4
- package/build/func/u-type.js +9 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,6 +27,7 @@ import { delay, int2array, UHttp, retry, MaybeArray, Loggable } from "xjs-common
|
|
|
27
27
|
retry(async () => { }, { count: 2 });
|
|
28
28
|
|
|
29
29
|
// utility types
|
|
30
|
+
let dateCtor: Ctor = Date; // constructor type like class type.
|
|
30
31
|
let maybeArray: MaybeArray<number> = 0; // also number array is applicable.
|
|
31
32
|
let logger: Loggable = console; // object implements log/warn/error is applicable.
|
|
32
33
|
|
|
@@ -124,18 +125,8 @@ this flag is true by default at the target higher than `ES2022`, [here is for mo
|
|
|
124
125
|
```ts
|
|
125
126
|
import { Type, DType, UType, UObj } from "xjs-common";
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
@DType.number
|
|
130
|
-
id: number;
|
|
131
|
-
@DType.string
|
|
132
|
-
strA: string;
|
|
133
|
-
@DType.recursive
|
|
134
|
-
objA: Cls_B;
|
|
135
|
-
p: number;
|
|
136
|
-
constructor() { }
|
|
137
|
-
}
|
|
138
|
-
class Cls_B {
|
|
128
|
+
interface If_B { aryB: number[], boolB: boolean, q: number }
|
|
129
|
+
class Cls_B implements If_B {
|
|
139
130
|
@DType.array({ t: Type.number })
|
|
140
131
|
aryB: number[];
|
|
141
132
|
@DType.boolean
|
|
@@ -143,37 +134,51 @@ class Cls_B {
|
|
|
143
134
|
q: number;
|
|
144
135
|
constructor() { }
|
|
145
136
|
}
|
|
137
|
+
interface If_A { id: number, strA: string, objA: If_B, p: number }
|
|
138
|
+
class Cls_A implements If_A {
|
|
139
|
+
@DType.required
|
|
140
|
+
@DType.number
|
|
141
|
+
id: number;
|
|
142
|
+
@DType.string
|
|
143
|
+
strA: string;
|
|
144
|
+
@DType.recursive(Cls_B)
|
|
145
|
+
objA: If_B;
|
|
146
|
+
p: number;
|
|
147
|
+
constructor(substance?: If_A) { Object.assign(this, substance); }
|
|
148
|
+
}
|
|
146
149
|
(() => {
|
|
147
|
-
const valid_b1 =
|
|
148
|
-
const
|
|
150
|
+
const valid_b1: If_B = { aryB: [1, 2, 3], boolB: true, q: 1 };
|
|
151
|
+
const valid_a1: If_A = { id: 1, strA: "a", objA: valid_b1, p: 1 };
|
|
149
152
|
|
|
150
153
|
// remove non decorated fields.
|
|
151
|
-
const cropped = UObj.crop(
|
|
152
|
-
console.log(!!cropped.id && !cropped.p
|
|
154
|
+
const cropped = UObj.crop(valid_a1, Cls_A);
|
|
155
|
+
console.log(!!cropped.id && !cropped.p); // true;
|
|
156
|
+
console.log(!!cropped.objA.aryB && !cropped.objA.q); // true
|
|
153
157
|
|
|
154
|
-
//
|
|
155
|
-
|
|
158
|
+
// passing class object instead of ctor is allowed.
|
|
159
|
+
UObj.crop(new Cls_A(valid_a1));
|
|
156
160
|
|
|
157
|
-
|
|
158
|
-
console.log(UType.validate(
|
|
161
|
+
// validation. below are valid cases.
|
|
162
|
+
console.log(UType.validate({ id: 0 }, Cls_A)); // []
|
|
163
|
+
console.log(UType.validate(valid_a1, Cls_A)); // []
|
|
159
164
|
|
|
160
165
|
// validation. below are invalid cases.
|
|
161
166
|
const invalid1 = {};
|
|
162
|
-
console.log(UType.validate(
|
|
167
|
+
console.log(UType.validate(invalid1, Cls_A)); // [ 'id' ]
|
|
163
168
|
|
|
164
|
-
const
|
|
165
|
-
console.log(UType.validate(
|
|
169
|
+
const invalid2 = { id: 0, strA: [], objA: valid_b1 };
|
|
170
|
+
console.log(UType.validate(invalid2, Cls_A)); // [ 'strA' ]
|
|
166
171
|
|
|
167
|
-
const
|
|
168
|
-
console.log(UType.validate(
|
|
172
|
+
const invalid3 = { id: "0", strA: "a", objA: valid_b1 };
|
|
173
|
+
console.log(UType.validate(invalid3, Cls_A)); // [ 'id' ]
|
|
169
174
|
|
|
170
|
-
const invalid_b1 =
|
|
171
|
-
const
|
|
172
|
-
console.log(UType.validate(
|
|
175
|
+
const invalid_b1 = { aryB: [1, 2, 3], boolB: 1 };
|
|
176
|
+
const invalid4 = { id: 0, strA: "a", objA: invalid_b1 };
|
|
177
|
+
console.log(UType.validate(invalid4, Cls_A)); // [ 'objA.boolB' ]
|
|
173
178
|
|
|
174
|
-
const invalid_b2 =
|
|
175
|
-
const
|
|
176
|
-
console.log(UType.validate(
|
|
179
|
+
const invalid_b2 = { aryB: ["1"], boolB: true };
|
|
180
|
+
const invalid5 = { id: 0, strA: "a", objA: invalid_b2 };
|
|
181
|
+
console.log(UType.validate(invalid5, Cls_A)); // [ 'objA.aryB.0' ]
|
|
177
182
|
})();
|
|
178
183
|
```
|
|
179
184
|
# Error definition
|
package/build/const/types.d.ts
CHANGED
|
@@ -1,30 +1,12 @@
|
|
|
1
|
-
import { Type } from "../../const/types";
|
|
1
|
+
import { Ctor, Type } from "../../const/types";
|
|
2
2
|
export declare const smbl_tm: unique symbol;
|
|
3
|
-
interface
|
|
3
|
+
export interface TypeDesc {
|
|
4
4
|
t?: Type;
|
|
5
5
|
req?: boolean;
|
|
6
|
-
}
|
|
7
|
-
export interface TypeDesc extends BasicTypeDesc {
|
|
8
6
|
ary?: TypeDesc;
|
|
9
|
-
rec?: boolean;
|
|
10
7
|
rcd?: TypeDesc;
|
|
8
|
+
obj?: Ctor;
|
|
11
9
|
}
|
|
12
|
-
type ArrayTypeDesc = TypeDesc & {
|
|
13
|
-
t?: never;
|
|
14
|
-
rec?: never;
|
|
15
|
-
rcd?: never;
|
|
16
|
-
};
|
|
17
|
-
type ClassTypeDesc = TypeDesc & {
|
|
18
|
-
t?: never;
|
|
19
|
-
ary?: never;
|
|
20
|
-
rcd?: never;
|
|
21
|
-
};
|
|
22
|
-
type RecordTypeDesc = TypeDesc & {
|
|
23
|
-
t?: never;
|
|
24
|
-
arys?: never;
|
|
25
|
-
rec?: never;
|
|
26
|
-
};
|
|
27
|
-
type AnyTypeDesc = BasicTypeDesc | ArrayTypeDesc | ClassTypeDesc | RecordTypeDesc;
|
|
28
10
|
export interface TypeMap {
|
|
29
11
|
[k: string]: TypeDesc;
|
|
30
12
|
}
|
|
@@ -37,10 +19,9 @@ export declare namespace DType {
|
|
|
37
19
|
function number(target: Object, propKey: string): void;
|
|
38
20
|
function boolean(target: Object, propKey: string): void;
|
|
39
21
|
function required(target: Object, propKey: string): void;
|
|
40
|
-
function array(elmDesc?:
|
|
22
|
+
function array(elmDesc?: TypeDesc | Ctor): (target: Object, propKey: string) => void;
|
|
41
23
|
/** NOTE: this may allow array type because array is essentialy object type has properties. */
|
|
42
|
-
function record(elmDesc?:
|
|
43
|
-
function recursive(target: Object, propKey: string)
|
|
24
|
+
function record(elmDesc?: TypeDesc | Ctor): (target: Object, propKey: string) => void;
|
|
25
|
+
function recursive(ctor: Ctor): (target: Object, propKey: string) => void;
|
|
44
26
|
function keep(target: Object, propKey: string): void;
|
|
45
27
|
}
|
|
46
|
-
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Type } from "../../const/types";
|
|
2
2
|
import { XjsErr } from "../../obj/xjs-err";
|
|
3
|
+
import { UType } from "../u-type";
|
|
3
4
|
const s_errCode = 30;
|
|
4
5
|
export const smbl_tm = Symbol.for("xjs:typeMap");
|
|
5
6
|
/**
|
|
@@ -32,16 +33,16 @@ export var DType;
|
|
|
32
33
|
}
|
|
33
34
|
DType.required = required;
|
|
34
35
|
function array(elmDesc = {}) {
|
|
35
|
-
return (target, propKey) => setDesc(target, propKey, (td) => td.ary = elmDesc);
|
|
36
|
+
return (target, propKey) => setDesc(target, propKey, (td) => UType.isFunction(elmDesc) ? td.ary = { obj: elmDesc } : td.ary = elmDesc);
|
|
36
37
|
}
|
|
37
38
|
DType.array = array;
|
|
38
39
|
/** NOTE: this may allow array type because array is essentialy object type has properties. */
|
|
39
40
|
function record(elmDesc = {}) {
|
|
40
|
-
return (target, propKey) => setDesc(target, propKey, (td) => td.rcd = elmDesc);
|
|
41
|
+
return (target, propKey) => setDesc(target, propKey, (td) => UType.isFunction(elmDesc) ? td.rcd = { obj: elmDesc } : td.rcd = elmDesc);
|
|
41
42
|
}
|
|
42
43
|
DType.record = record;
|
|
43
|
-
function recursive(
|
|
44
|
-
setDesc(target, propKey, (td) => td.
|
|
44
|
+
function recursive(ctor) {
|
|
45
|
+
return (target, propKey) => setDesc(target, propKey, (td) => td.obj = ctor);
|
|
45
46
|
}
|
|
46
47
|
DType.recursive = recursive;
|
|
47
48
|
function keep(target, propKey) {
|
|
@@ -50,10 +51,10 @@ export var DType;
|
|
|
50
51
|
DType.keep = keep;
|
|
51
52
|
function setDesc(target, propKey, setter) {
|
|
52
53
|
const map = target[smbl_tm] ? Object.assign({}, target[smbl_tm]) : {};
|
|
53
|
-
map[propKey] ??= { t: null, req: false,
|
|
54
|
+
map[propKey] ??= { t: null, req: false, obj: null, ary: null, rcd: null };
|
|
54
55
|
const td = map[propKey];
|
|
55
56
|
setter(td);
|
|
56
|
-
const structualDescs = [[td.ary, "array"], [td.
|
|
57
|
+
const structualDescs = [[td.ary, "array"], [td.obj, "recursive"], [td.rcd, "record"]].filter(e => e[0]);
|
|
57
58
|
if (structualDescs.length > 0) {
|
|
58
59
|
let ex1 = null, ex2 = null;
|
|
59
60
|
if (td.t) {
|
package/build/func/u-array.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ export declare namespace UArray {
|
|
|
3
3
|
/**
|
|
4
4
|
* compares two arrays to valuate equality.
|
|
5
5
|
* if one side is null or undefined, it returns true when other side is the same.
|
|
6
|
-
* this function has compatibility
|
|
6
|
+
* this function has compatibility {@link AlmostArray} like {@link Uint8Array} etc.
|
|
7
7
|
* @param v1 it uses equal operator for comparing elements, so applying object element is not recommended.
|
|
8
8
|
* @param v2 same as v1.
|
|
9
9
|
* @param sort it uses {@link Array.sort()} on v1 and v2 if true. default is true.
|
|
10
|
-
* @param useStrictEqual check equality whether
|
|
10
|
+
* @param useStrictEqual check equality whether {@link Array} or not and it uses `===` operator for compareing elements if true, otherwise using `==` operator. default is true.
|
|
11
11
|
*/
|
|
12
12
|
function eq(v1: any[] | AlmostArray, v2: any[] | AlmostArray, op?: {
|
|
13
13
|
sort?: boolean;
|
|
@@ -28,7 +28,7 @@ export declare namespace UArray {
|
|
|
28
28
|
}): T[];
|
|
29
29
|
/**
|
|
30
30
|
* chop array to partial arrays which have specified length. the remainder is added to end of a result.
|
|
31
|
-
* this function has compatibility to
|
|
31
|
+
* this function has compatibility to {@link AlmostArray} like {@link Uint8Array} etc.
|
|
32
32
|
*/
|
|
33
33
|
function chop<E>(array: E[], len: number): E[][];
|
|
34
34
|
function chop<T extends AlmostArray>(array: T, len: number): T[];
|
package/build/func/u-array.js
CHANGED
|
@@ -4,11 +4,11 @@ export var UArray;
|
|
|
4
4
|
/**
|
|
5
5
|
* compares two arrays to valuate equality.
|
|
6
6
|
* if one side is null or undefined, it returns true when other side is the same.
|
|
7
|
-
* this function has compatibility
|
|
7
|
+
* this function has compatibility {@link AlmostArray} like {@link Uint8Array} etc.
|
|
8
8
|
* @param v1 it uses equal operator for comparing elements, so applying object element is not recommended.
|
|
9
9
|
* @param v2 same as v1.
|
|
10
10
|
* @param sort it uses {@link Array.sort()} on v1 and v2 if true. default is true.
|
|
11
|
-
* @param useStrictEqual check equality whether
|
|
11
|
+
* @param useStrictEqual check equality whether {@link Array} or not and it uses `===` operator for compareing elements if true, otherwise using `==` operator. default is true.
|
|
12
12
|
*/
|
|
13
13
|
function eq(v1, v2, op = {}) {
|
|
14
14
|
const { sort, useStrictEqual } = Object.assign({ sort: true, useStrictEqual: true }, op);
|
package/build/func/u-obj.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MaybeArray, NonObject, NormalRecord, Type } from "../const/types";
|
|
1
|
+
import { Ctor, MaybeArray, NonObject, NormalRecord, Type } from "../const/types";
|
|
2
2
|
export declare namespace UObj {
|
|
3
3
|
/**
|
|
4
4
|
* assign properties to the object with specified property keys.
|
|
@@ -9,12 +9,19 @@ export declare namespace UObj {
|
|
|
9
9
|
*/
|
|
10
10
|
function assignProperties<T extends NormalRecord, S extends NormalRecord>(t: T, s: S, keys?: (keyof S)[], keepDtypeClass?: boolean): T & Partial<S>;
|
|
11
11
|
/**
|
|
12
|
-
* crop properties of the object. the properties
|
|
13
|
-
* @param o object whose properties
|
|
14
|
-
* @param keys property names to be remained.
|
|
15
|
-
* @param
|
|
12
|
+
* crop properties of the object other than specified. the properties are to be removed with `delete` operator.
|
|
13
|
+
* @param o object whose properties to be removed.
|
|
14
|
+
* @param keys property names to be remained.
|
|
15
|
+
* @param removeKeys if true, it removes `keys` instead of remaining it.
|
|
16
16
|
*/
|
|
17
|
-
function crop<T extends NormalRecord>(o: T, keys
|
|
17
|
+
function crop<T extends NormalRecord>(o: T, keys: (keyof T)[], removeKeys?: boolean): Partial<T>;
|
|
18
|
+
/**
|
|
19
|
+
* crop properties that is not decorated with {@link DType}. the properties will be removed with `delete` operator.
|
|
20
|
+
* this treats constructual decorator such as {@link DType.recursive} recursively.
|
|
21
|
+
* @param o object whose properties to be removed. if this is class object decorated with {@link DType}, it can omits `ctor` parameter.
|
|
22
|
+
* @param ctor class constructor type whose properties are decorated with {@link DType}. **NOTE** that need to have public constructor without any parameter.
|
|
23
|
+
*/
|
|
24
|
+
function crop<T extends NormalRecord>(o: T, ctor?: Ctor): Partial<T>;
|
|
18
25
|
/**
|
|
19
26
|
* manipulate properties of an object.
|
|
20
27
|
* as default if the properties contains object, it also manipulates properties of that recursively.
|
package/build/func/u-obj.js
CHANGED
|
@@ -20,20 +20,22 @@ export var UObj;
|
|
|
20
20
|
return t;
|
|
21
21
|
}
|
|
22
22
|
UObj.assignProperties = assignProperties;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
function crop(o, keys, exclusive) {
|
|
30
|
-
if (!keys && !o[smbl_tm])
|
|
31
|
-
return {};
|
|
32
|
-
const _keys = keys ?? Object.keys(o[smbl_tm]);
|
|
23
|
+
function crop(o, keys_or_ctor, removeKeys) {
|
|
24
|
+
const tm = Array.isArray(keys_or_ctor) ? null
|
|
25
|
+
: (!keys_or_ctor || o instanceof keys_or_ctor ? o[smbl_tm] : new keys_or_ctor()[smbl_tm]);
|
|
26
|
+
const _keys = tm ? Object.keys(tm) : (keys_or_ctor ?? []);
|
|
27
|
+
if (_keys.length === 0)
|
|
28
|
+
return removeKeys ? o : {};
|
|
33
29
|
Object.keys(o).filter(k => {
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
if (tm && tm[k] && o[k]) {
|
|
31
|
+
if (tm[k].obj)
|
|
32
|
+
crop(o[k], tm[k]?.obj);
|
|
33
|
+
else {
|
|
34
|
+
const vCtor = tm[k].ary?.obj ?? tm[k].rcd?.obj;
|
|
35
|
+
Object.values(o[k]).forEach(v => crop(v, vCtor));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return !!removeKeys === _keys.includes(k);
|
|
37
39
|
}).forEach(k => delete o[k]);
|
|
38
40
|
return o;
|
|
39
41
|
}
|
package/build/func/u-type.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MaybeArray, Type } from "../const/types";
|
|
1
|
+
import { Ctor, MaybeArray, Type } from "../const/types";
|
|
2
2
|
export declare namespace UType {
|
|
3
3
|
function isDefined(v: any): boolean;
|
|
4
4
|
function isEmpty(v: any): boolean;
|
|
@@ -17,10 +17,11 @@ export declare namespace UType {
|
|
|
17
17
|
function isArray(v: any, t: Type.object): v is object[];
|
|
18
18
|
function isArray(v: any): v is any[];
|
|
19
19
|
/**
|
|
20
|
-
* validate properties
|
|
21
|
-
* @param o object to be validated.
|
|
20
|
+
* validate properties decorated with {@link DType}.
|
|
21
|
+
* @param o object to be validated. if this is class object decorated with {@link DType}, it can omits `ctor` parameter.
|
|
22
|
+
* @param ctor class constructor type whose properties are decorated. **NOTE** that need to have public constructor without any parameter.
|
|
22
23
|
* @returns invalid property keys. returns an empty array if `o` is valid.
|
|
23
24
|
*/
|
|
24
|
-
function validate(o: any): string[];
|
|
25
|
+
function validate(o: any, ctor?: Ctor): string[];
|
|
25
26
|
function takeAsArray<T>(v: MaybeArray<T>): T[];
|
|
26
27
|
}
|
package/build/func/u-type.js
CHANGED
|
@@ -29,14 +29,16 @@ export var UType;
|
|
|
29
29
|
}
|
|
30
30
|
UType.isArray = isArray;
|
|
31
31
|
/**
|
|
32
|
-
* validate properties
|
|
33
|
-
* @param o object to be validated.
|
|
32
|
+
* validate properties decorated with {@link DType}.
|
|
33
|
+
* @param o object to be validated. if this is class object decorated with {@link DType}, it can omits `ctor` parameter.
|
|
34
|
+
* @param ctor class constructor type whose properties are decorated. **NOTE** that need to have public constructor without any parameter.
|
|
34
35
|
* @returns invalid property keys. returns an empty array if `o` is valid.
|
|
35
36
|
*/
|
|
36
|
-
function validate(o) {
|
|
37
|
-
|
|
37
|
+
function validate(o, ctor) {
|
|
38
|
+
const _o = (!ctor || o instanceof ctor) ? o : Object.assign(new ctor(), o);
|
|
39
|
+
if (!_o[smbl_tm])
|
|
38
40
|
return [];
|
|
39
|
-
return Object.entries(
|
|
41
|
+
return Object.entries(_o[smbl_tm]).flatMap(e => validateProp(e[0], _o[e[0]], e[1]));
|
|
40
42
|
}
|
|
41
43
|
UType.validate = validate;
|
|
42
44
|
function validateProp(k, prop, td) {
|
|
@@ -51,8 +53,8 @@ export var UType;
|
|
|
51
53
|
if (td.rcd)
|
|
52
54
|
return UType.isObject(prop)
|
|
53
55
|
? Object.entries(prop).flatMap(e => validateProp(e[0], e[1], td.rcd)).map(joinKey) : [k];
|
|
54
|
-
if (td.
|
|
55
|
-
return validate(prop).flatMap(joinKey);
|
|
56
|
+
if (td.obj)
|
|
57
|
+
return validate(prop, td.obj).flatMap(joinKey);
|
|
56
58
|
return [];
|
|
57
59
|
}
|
|
58
60
|
function takeAsArray(v) {
|