@jolibox/implement 1.1.4-beta.4

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.
Files changed (193) hide show
  1. package/.eslintrc.js +3 -0
  2. package/.rush/temp/package-deps_build.json +104 -0
  3. package/.rush/temp/shrinkwrap-deps.json +79 -0
  4. package/README.md +1 -0
  5. package/dist/common/api-factory/index.d.ts +21 -0
  6. package/dist/common/api-factory/validator/__tests__/validate/any.test.d.ts +1 -0
  7. package/dist/common/api-factory/validator/__tests__/validate/array.test.d.ts +1 -0
  8. package/dist/common/api-factory/validator/__tests__/validate/arraybuffer.test.d.ts +1 -0
  9. package/dist/common/api-factory/validator/__tests__/validate/boolean.test.d.ts +1 -0
  10. package/dist/common/api-factory/validator/__tests__/validate/enum.test.d.ts +1 -0
  11. package/dist/common/api-factory/validator/__tests__/validate/function.test.d.ts +1 -0
  12. package/dist/common/api-factory/validator/__tests__/validate/literal.test.d.ts +1 -0
  13. package/dist/common/api-factory/validator/__tests__/validate/nullish.test.d.ts +1 -0
  14. package/dist/common/api-factory/validator/__tests__/validate/number.test.d.ts +1 -0
  15. package/dist/common/api-factory/validator/__tests__/validate/object.test.d.ts +1 -0
  16. package/dist/common/api-factory/validator/__tests__/validate/or.test.d.ts +1 -0
  17. package/dist/common/api-factory/validator/__tests__/validate/record.test.d.ts +1 -0
  18. package/dist/common/api-factory/validator/__tests__/validate/string.test.d.ts +1 -0
  19. package/dist/common/api-factory/validator/__tests__/validate/symbol.test.d.ts +1 -0
  20. package/dist/common/api-factory/validator/__tests__/validate/tuple.test.d.ts +1 -0
  21. package/dist/common/api-factory/validator/__tests__/validate/type-asserts.test.d.ts +1 -0
  22. package/dist/common/api-factory/validator/__tests__/validate/utils.test.d.ts +1 -0
  23. package/dist/common/api-factory/validator/index.d.ts +29 -0
  24. package/dist/common/api-factory/validator/validate.d.ts +119 -0
  25. package/dist/common/can-i-use.d.ts +2 -0
  26. package/dist/common/context/index.d.ts +16 -0
  27. package/dist/common/context/types.d.ts +5 -0
  28. package/dist/common/context/url-parse.d.ts +22 -0
  29. package/dist/common/http/index.d.ts +13 -0
  30. package/dist/common/http/uuid.d.ts +2 -0
  31. package/dist/common/http/xua.d.ts +17 -0
  32. package/dist/common/report/base-tracker.d.ts +13 -0
  33. package/dist/common/report/create-trace.d.ts +7 -0
  34. package/dist/common/report/errors/error-types.d.ts +122 -0
  35. package/dist/common/report/errors/index.d.ts +13 -0
  36. package/dist/common/report/errors/report/index.d.ts +51 -0
  37. package/dist/common/report/errors/report/listeners.d.ts +1 -0
  38. package/dist/common/report/index.d.ts +3 -0
  39. package/dist/common/report/task-track/index.d.ts +23 -0
  40. package/dist/common/report/track.d.ts +3 -0
  41. package/dist/common/report/types.d.ts +75 -0
  42. package/dist/h5/ads/ads-action-detection.d.ts +6 -0
  43. package/dist/h5/ads/anti-cheating.d.ts +61 -0
  44. package/dist/h5/ads/index.d.ts +275 -0
  45. package/dist/h5/api/base.d.ts +13 -0
  46. package/dist/h5/api/get-system-info.d.ts +1 -0
  47. package/dist/h5/api/index.d.ts +4 -0
  48. package/dist/h5/api/lifecycle.d.ts +1 -0
  49. package/dist/h5/api/storage.d.ts +27 -0
  50. package/dist/h5/api/task.d.ts +1 -0
  51. package/dist/h5/bootstrap/index.d.ts +1 -0
  52. package/dist/h5/http/index.d.ts +33 -0
  53. package/dist/h5/http/utils/__tests__/uuid.test.d.ts +1 -0
  54. package/dist/h5/http/utils/__tests__/xua.test.d.ts +1 -0
  55. package/dist/h5/http/utils/index.d.ts +14 -0
  56. package/dist/h5/http/utils/session.d.ts +1 -0
  57. package/dist/h5/report/errors/index.d.ts +4 -0
  58. package/dist/h5/report/event-tracker.d.ts +8 -0
  59. package/dist/h5/report/index.d.ts +10 -0
  60. package/dist/h5/report/task-tracker.d.ts +14 -0
  61. package/dist/index.d.ts +3 -0
  62. package/dist/index.js +5026 -0
  63. package/dist/index.native.d.ts +2 -0
  64. package/dist/index.native.js +3743 -0
  65. package/dist/native/api/base.d.ts +13 -0
  66. package/dist/native/api/get-system-info.d.ts +1 -0
  67. package/dist/native/api/index.d.ts +7 -0
  68. package/dist/native/api/keyboard.d.ts +3 -0
  69. package/dist/native/api/lifecycle.d.ts +1 -0
  70. package/dist/native/api/login.d.ts +1 -0
  71. package/dist/native/api/request.d.ts +1 -0
  72. package/dist/native/api/storage.d.ts +25 -0
  73. package/dist/native/api/task.d.ts +1 -0
  74. package/dist/native/bootstrap/bridge.d.ts +4 -0
  75. package/dist/native/bootstrap/index.d.ts +1 -0
  76. package/dist/native/js-bridge/const.d.ts +5 -0
  77. package/dist/native/js-bridge/index.d.ts +2 -0
  78. package/dist/native/js-bridge/invoke.d.ts +21 -0
  79. package/dist/native/js-bridge/js-bridge.d.ts +6 -0
  80. package/dist/native/js-bridge/report.d.ts +63 -0
  81. package/dist/native/js-bridge/subscribe.d.ts +8 -0
  82. package/dist/native/js-bridge/types.d.ts +14 -0
  83. package/dist/native/js-bridge/utils.d.ts +17 -0
  84. package/dist/native/js-core/index.d.ts +3 -0
  85. package/dist/native/js-core/jolibox-js-core.d.ts +45 -0
  86. package/dist/native/js-core/message-port.d.ts +12 -0
  87. package/dist/native/js-core/utils.d.ts +7 -0
  88. package/dist/native/network/create-fetch.d.ts +27 -0
  89. package/dist/native/network/index.d.ts +11 -0
  90. package/dist/native/network/report.d.ts +15 -0
  91. package/dist/native/network/types.d.ts +61 -0
  92. package/dist/native/network/utils.d.ts +9 -0
  93. package/dist/native/report/errors/index.d.ts +4 -0
  94. package/dist/native/report/index.d.ts +10 -0
  95. package/dist/native/report/task-tracker.d.ts +20 -0
  96. package/dist/utils/index.d.ts +0 -0
  97. package/esbuild.config.js +66 -0
  98. package/implement.build.log +9 -0
  99. package/package.json +30 -0
  100. package/src/common/api-factory/index.ts +188 -0
  101. package/src/common/api-factory/validator/__tests__/validate/any.test.ts +68 -0
  102. package/src/common/api-factory/validator/__tests__/validate/array.test.ts +402 -0
  103. package/src/common/api-factory/validator/__tests__/validate/arraybuffer.test.ts +48 -0
  104. package/src/common/api-factory/validator/__tests__/validate/boolean.test.ts +27 -0
  105. package/src/common/api-factory/validator/__tests__/validate/enum.test.ts +106 -0
  106. package/src/common/api-factory/validator/__tests__/validate/function.test.ts +54 -0
  107. package/src/common/api-factory/validator/__tests__/validate/literal.test.ts +130 -0
  108. package/src/common/api-factory/validator/__tests__/validate/nullish.test.ts +41 -0
  109. package/src/common/api-factory/validator/__tests__/validate/number.test.ts +147 -0
  110. package/src/common/api-factory/validator/__tests__/validate/object.test.ts +131 -0
  111. package/src/common/api-factory/validator/__tests__/validate/or.test.ts +96 -0
  112. package/src/common/api-factory/validator/__tests__/validate/record.test.ts +274 -0
  113. package/src/common/api-factory/validator/__tests__/validate/string.test.ts +187 -0
  114. package/src/common/api-factory/validator/__tests__/validate/symbol.test.ts +23 -0
  115. package/src/common/api-factory/validator/__tests__/validate/tuple.test.ts +86 -0
  116. package/src/common/api-factory/validator/__tests__/validate/type-asserts.test.ts +13 -0
  117. package/src/common/api-factory/validator/__tests__/validate/utils.test.ts +44 -0
  118. package/src/common/api-factory/validator/index.ts +107 -0
  119. package/src/common/api-factory/validator/validate.ts +639 -0
  120. package/src/common/can-i-use.ts +19 -0
  121. package/src/common/context/index.ts +91 -0
  122. package/src/common/context/types.ts +5 -0
  123. package/src/common/context/url-parse.ts +63 -0
  124. package/src/common/http/index.ts +29 -0
  125. package/src/common/http/uuid.ts +11 -0
  126. package/src/common/http/xua.ts +79 -0
  127. package/src/common/report/base-tracker.ts +134 -0
  128. package/src/common/report/create-trace.ts +17 -0
  129. package/src/common/report/errors/error-types.ts +206 -0
  130. package/src/common/report/errors/index.ts +20 -0
  131. package/src/common/report/errors/report/index.ts +63 -0
  132. package/src/common/report/errors/report/listeners.ts +80 -0
  133. package/src/common/report/index.ts +3 -0
  134. package/src/common/report/task-track/index.ts +97 -0
  135. package/src/common/report/track.ts +49 -0
  136. package/src/common/report/types.ts +90 -0
  137. package/src/h5/ads/ads-action-detection.ts +31 -0
  138. package/src/h5/ads/anti-cheating.ts +244 -0
  139. package/src/h5/ads/index.ts +641 -0
  140. package/src/h5/api/base.ts +9 -0
  141. package/src/h5/api/get-system-info.ts +55 -0
  142. package/src/h5/api/index.ts +4 -0
  143. package/src/h5/api/lifecycle.ts +110 -0
  144. package/src/h5/api/storage.ts +173 -0
  145. package/src/h5/api/task.ts +197 -0
  146. package/src/h5/bootstrap/index.ts +16 -0
  147. package/src/h5/http/index.ts +189 -0
  148. package/src/h5/http/utils/__tests__/uuid.test.ts +16 -0
  149. package/src/h5/http/utils/__tests__/xua.test.ts +27 -0
  150. package/src/h5/http/utils/index.ts +19 -0
  151. package/src/h5/http/utils/session.ts +10 -0
  152. package/src/h5/report/errors/index.ts +40 -0
  153. package/src/h5/report/event-tracker.ts +40 -0
  154. package/src/h5/report/index.ts +56 -0
  155. package/src/h5/report/task-tracker.ts +35 -0
  156. package/src/index.native.ts +7 -0
  157. package/src/index.ts +9 -0
  158. package/src/native/api/base.ts +8 -0
  159. package/src/native/api/get-system-info.ts +41 -0
  160. package/src/native/api/index.ts +7 -0
  161. package/src/native/api/keyboard.ts +75 -0
  162. package/src/native/api/lifecycle.ts +76 -0
  163. package/src/native/api/login.ts +71 -0
  164. package/src/native/api/request.ts +154 -0
  165. package/src/native/api/storage.ts +287 -0
  166. package/src/native/api/task.ts +267 -0
  167. package/src/native/bootstrap/bridge.ts +59 -0
  168. package/src/native/bootstrap/index.ts +58 -0
  169. package/src/native/js-bridge/const.ts +11 -0
  170. package/src/native/js-bridge/index.ts +2 -0
  171. package/src/native/js-bridge/invoke.ts +210 -0
  172. package/src/native/js-bridge/js-bridge.ts +23 -0
  173. package/src/native/js-bridge/report.ts +311 -0
  174. package/src/native/js-bridge/subscribe.ts +50 -0
  175. package/src/native/js-bridge/types.ts +26 -0
  176. package/src/native/js-bridge/utils.ts +116 -0
  177. package/src/native/js-core/index.ts +4 -0
  178. package/src/native/js-core/jolibox-js-core.ts +188 -0
  179. package/src/native/js-core/message-port.ts +52 -0
  180. package/src/native/js-core/utils.ts +9 -0
  181. package/src/native/network/create-fetch.ts +237 -0
  182. package/src/native/network/index.ts +15 -0
  183. package/src/native/network/report.ts +58 -0
  184. package/src/native/network/types.ts +77 -0
  185. package/src/native/network/utils.ts +90 -0
  186. package/src/native/report/errors/index.ts +27 -0
  187. package/src/native/report/index.ts +51 -0
  188. package/src/native/report/task-tracker.ts +64 -0
  189. package/src/native/types/global.d.ts +26 -0
  190. package/src/native/types/native-method-map.d.ts +282 -0
  191. package/src/native/types/native-method.d.ts +30 -0
  192. package/src/utils/index.ts +0 -0
  193. package/tsconfig.json +18 -0
@@ -0,0 +1,639 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ type Constructor<T> = new (...args: any[]) => T;
3
+
4
+ export type Primitive = string | number | symbol | boolean | undefined | null;
5
+
6
+ export let collectError = false;
7
+
8
+ export function setCollect(flag: boolean) {
9
+ collectError = flag;
10
+ }
11
+ function deepClone<T>(obj: T): T {
12
+ if (obj === null || typeof obj !== 'object') {
13
+ return obj;
14
+ }
15
+
16
+ if (Array.isArray(obj)) {
17
+ return obj.map((item) => deepClone(item)) as T;
18
+ }
19
+
20
+ return Object.keys(obj as object).reduce((acc, key) => {
21
+ acc[key as keyof T] = deepClone((obj as any)[key]);
22
+ return acc;
23
+ }, {} as T);
24
+ }
25
+
26
+ export abstract class Validator<T = unknown> {
27
+ path?: string;
28
+ errors: string[] = [];
29
+
30
+ abstract validate(x: unknown): x is T;
31
+
32
+ protected fail(message: string): false;
33
+ protected fail(options: { expect: string; actual: unknown }): false;
34
+ protected fail(options: { expect: string; actual: unknown } | string) {
35
+ if (collectError) {
36
+ if (typeof options === 'string') {
37
+ this.errors.push(options);
38
+ } else {
39
+ let message = `${this.path} should be ${options.expect}`;
40
+ if (this._optional && options.expect !== 'undefined') {
41
+ message += ' or undefined, ';
42
+ } else {
43
+ message += ', ';
44
+ }
45
+ message += `but got ${echo(options.actual)}`;
46
+ this.errors.push(message);
47
+ }
48
+ }
49
+ return false;
50
+ }
51
+
52
+ hasFallback = false;
53
+ _fallback?: T;
54
+ fallback(v: T) {
55
+ this.hasFallback = true;
56
+ this._fallback = v;
57
+ return this;
58
+ }
59
+
60
+ get fallbackValue(): T {
61
+ return deepClone(this._fallback as T);
62
+ }
63
+
64
+ hasDefault = false;
65
+ protected _default?: T;
66
+ default(v: T) {
67
+ this.hasDefault = true;
68
+ this._default = v;
69
+ return this;
70
+ }
71
+
72
+ get defaultValue() {
73
+ if (typeof this._default === 'function') {
74
+ return this._default;
75
+ }
76
+ return deepClone(this._default as T);
77
+ }
78
+
79
+ _optional = false;
80
+ optional(): Validator<T | undefined> {
81
+ this._optional = true;
82
+ return this as Validator<T | undefined>;
83
+ }
84
+ }
85
+
86
+ export function isNumber(x: unknown): x is number {
87
+ return typeof x === 'number';
88
+ }
89
+
90
+ export function echo(x: unknown) {
91
+ const s = getType(x);
92
+ switch (s) {
93
+ case 'string':
94
+ return `"${x}"`;
95
+ case 'number':
96
+ case 'boolean':
97
+ case 'null':
98
+ case 'undefined':
99
+ return String(x);
100
+ default:
101
+ return `a(n) ${s}`;
102
+ }
103
+ }
104
+
105
+ export function getType(x: unknown) {
106
+ if (typeof x === 'function') return 'function';
107
+
108
+ const type = Object.prototype.toString.call(x).slice(8).slice(0, -1);
109
+
110
+ return type.toLowerCase();
111
+ }
112
+
113
+ export class $number extends Validator<number> {
114
+ private _min?: number;
115
+ private _max?: number;
116
+ private _isInt?: boolean;
117
+ private _greater?: number;
118
+
119
+ validate(x: unknown): x is number {
120
+ if (this._optional && x === undefined) return true;
121
+
122
+ if (!isNumber(x)) {
123
+ return this.fail({ expect: 'number', actual: x });
124
+ }
125
+
126
+ if (isNumber(this._min) && x < this._min) {
127
+ return this.fail(`the value of ${this.path} should be greater than or equal to ${this._min}`);
128
+ }
129
+
130
+ if (isNumber(this._max) && x > this._max) {
131
+ return this.fail(`the value of ${this.path} should be less than or equal to ${this._max}`);
132
+ }
133
+
134
+ if (isNumber(this._greater) && x <= this._greater) {
135
+ return this.fail(`the value of ${this.path} should be greater than ${this._greater}`);
136
+ }
137
+
138
+ if (this._isInt && x !== Math.floor(x)) {
139
+ return this.fail(`the value of ${this.path} should be integer but got ${x}`);
140
+ }
141
+ return true;
142
+ }
143
+
144
+ min(v: number) {
145
+ this._min = v;
146
+ return this;
147
+ }
148
+
149
+ max(v: number) {
150
+ this._max = v;
151
+ return this;
152
+ }
153
+
154
+ isInt(v: boolean) {
155
+ this._isInt = v;
156
+ return this;
157
+ }
158
+
159
+ greater(v: number) {
160
+ this._greater = v;
161
+ return this;
162
+ }
163
+ }
164
+
165
+ export class $boolean extends Validator<boolean> {
166
+ validate(x: unknown): x is boolean {
167
+ if (this._optional && x === undefined) return true;
168
+
169
+ if (typeof x !== 'boolean') {
170
+ return this.fail({ expect: 'boolean', actual: x });
171
+ }
172
+
173
+ return true;
174
+ }
175
+ }
176
+
177
+ export class $string extends Validator<string> {
178
+ private _minLength?: number;
179
+ private _maxLength?: number;
180
+ private _pattern?: string | RegExp;
181
+
182
+ validate(x: unknown): x is string {
183
+ if (this._optional && x === undefined) return true;
184
+
185
+ if (typeof x !== 'string') {
186
+ return this.fail({ expect: 'string', actual: x });
187
+ }
188
+
189
+ if (isNumber(this._maxLength) && x.length > this._maxLength) {
190
+ return this.fail(`the length of ${this.path} should be less than or equal to ${this._maxLength}`);
191
+ }
192
+
193
+ if (isNumber(this._minLength) && x.length < this._minLength) {
194
+ return this.fail(`the length of ${this.path} should be greater than or equal to ${this._minLength}`);
195
+ }
196
+
197
+ if (typeof this._pattern === 'string') {
198
+ const reg = new RegExp(this._pattern);
199
+ if (!reg.test(x)) {
200
+ return this.fail(`${this.path} should match pattern "${this._pattern}"`);
201
+ }
202
+ } else if (this._pattern) {
203
+ if (!this._pattern.test(x)) {
204
+ return this.fail(`${this.path} should match pattern "${this._pattern.toString()}"`);
205
+ }
206
+ }
207
+
208
+ return true;
209
+ }
210
+
211
+ minLength(len: number) {
212
+ this._minLength = len;
213
+ return this;
214
+ }
215
+
216
+ maxLength(len: number) {
217
+ this._maxLength = len;
218
+ return this;
219
+ }
220
+
221
+ pattern(patten: string | RegExp) {
222
+ this._pattern = patten;
223
+ return this;
224
+ }
225
+ }
226
+
227
+ export class $symbol extends Validator<symbol> {
228
+ validate(x: unknown): x is symbol {
229
+ if (this._optional && x === undefined) return true;
230
+
231
+ if (typeof x !== 'symbol') {
232
+ return this.fail({ expect: 'symbol', actual: x });
233
+ }
234
+
235
+ return true;
236
+ }
237
+ }
238
+
239
+ export class $any<T = any> extends Validator<T> {
240
+ // eslint-disable-next-line class-methods-use-this
241
+ validate(x: unknown): x is T {
242
+ return true;
243
+ }
244
+ }
245
+
246
+ export class $undefined extends Validator<undefined> {
247
+ validate(x: unknown): x is undefined {
248
+ if (x !== undefined) {
249
+ return this.fail({ expect: 'undefined', actual: x });
250
+ }
251
+ return true;
252
+ }
253
+ }
254
+
255
+ export class $null extends Validator<null> {
256
+ validate(x: unknown): x is null {
257
+ if (this._optional && x === undefined) return true;
258
+
259
+ if (x !== null) {
260
+ return this.fail({ expect: 'null', actual: x });
261
+ }
262
+ return true;
263
+ }
264
+ }
265
+
266
+ export class $function extends Validator<(...args: any[]) => any> {
267
+ validate(x: unknown): x is (...args: any[]) => any {
268
+ if (this._optional && x === undefined) return true;
269
+
270
+ if (typeof x !== 'function') {
271
+ return this.fail({ expect: 'function', actual: x });
272
+ }
273
+ return true;
274
+ }
275
+ }
276
+
277
+ export class $enum<T> extends Validator<T> {
278
+ private readonly _items: (string | number | undefined)[];
279
+ constructor(..._items: (string | number | undefined)[]) {
280
+ super();
281
+ this._items = _items;
282
+ }
283
+
284
+ validate(x: unknown): x is T {
285
+ if (this._optional && x === undefined) return true;
286
+
287
+ if (!this._items.includes(x as any)) {
288
+ const enums = this._items.map((i) => JSON.stringify(i)).join(', ');
289
+
290
+ return this.fail(`expect ${this.path} to be one of ${enums}, but got ${echo(x)}`);
291
+ }
292
+
293
+ return true;
294
+ }
295
+ }
296
+
297
+ export class $array<T extends unknown> extends Validator<T[]> {
298
+ private _minItems?: number;
299
+ private _maxItems?: number;
300
+ private _uniqueItems?: boolean;
301
+ private _length?: number;
302
+
303
+ constructor(private readonly _item?: Validator) {
304
+ super();
305
+ }
306
+
307
+ validate(x: unknown): x is T[] {
308
+ if (this._optional && x === undefined) return true;
309
+
310
+ if (!Array.isArray(x)) {
311
+ return this.fail({ expect: 'array', actual: x });
312
+ }
313
+
314
+ if (isNumber(this._minItems) && x.length < this._minItems) {
315
+ return this.fail(`the length of ${this.path} should be greater than or equal to ${this._minItems}`);
316
+ }
317
+
318
+ if (isNumber(this._maxItems) && x.length > this._maxItems) {
319
+ return this.fail(`the length of ${this.path} should be less than or equal to ${this._maxItems}`);
320
+ }
321
+
322
+ if (isNumber(this._length) && x.length !== this._length) {
323
+ return this.fail(`the length of ${this.path} should be equal to ${this._length}`);
324
+ }
325
+
326
+ const validator = this._item;
327
+
328
+ if (!validator) return true;
329
+
330
+ let result = true;
331
+
332
+ x.forEach((item, index) => {
333
+ validator.path = `${this.path}[${index}]`;
334
+ validator.errors = this.errors;
335
+
336
+ if (item === undefined && validator.hasDefault) {
337
+ x[index] = validator.defaultValue;
338
+ return;
339
+ }
340
+ if (!validator.validate(item)) {
341
+ if (validator.hasFallback) {
342
+ x[index] = validator.fallbackValue;
343
+ } else {
344
+ result = false;
345
+ }
346
+ }
347
+ });
348
+
349
+ if (this._uniqueItems) {
350
+ const map = new Map();
351
+ for (let i in x) {
352
+ if (map.has(x[i])) {
353
+ result = this.fail(
354
+ `${this.path} should NOT have duplicate items (${this.path}[${map.get(x[i])}] and ${
355
+ this.path
356
+ }[${i}] are identical)`
357
+ );
358
+ } else {
359
+ map.set(x[i], i);
360
+ }
361
+ }
362
+ }
363
+
364
+ return result;
365
+ }
366
+
367
+ minItems(len: number) {
368
+ this._minItems = len;
369
+ return this;
370
+ }
371
+
372
+ maxItems(len: number) {
373
+ this._maxItems = len;
374
+ return this;
375
+ }
376
+
377
+ uniqueItems() {
378
+ this._uniqueItems = true;
379
+ return this;
380
+ }
381
+
382
+ length(len: number) {
383
+ this._length = len;
384
+ return this;
385
+ }
386
+ }
387
+
388
+ export class $record<T> extends Validator<Record<string, T>> {
389
+ constructor(private readonly _value: Validator) {
390
+ super();
391
+ }
392
+
393
+ validate(x: unknown): x is Record<string, T> {
394
+ if (this._optional && x === undefined) return true;
395
+
396
+ const type = getType(x);
397
+
398
+ if (type !== 'object') {
399
+ return this.fail({ expect: 'object', actual: x });
400
+ }
401
+
402
+ const values = x as Record<string, unknown>;
403
+
404
+ const validator = this._value;
405
+ validator.errors = this.errors;
406
+
407
+ let result = true;
408
+
409
+ // eslint-disable-next-line guard-for-in
410
+ for (const k in values) {
411
+ const value = values[k];
412
+
413
+ if (/^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/.test(k)) {
414
+ validator.path = `${this.path}.${k}`;
415
+ } else {
416
+ validator.path = `${this.path}["${k}"]`;
417
+ }
418
+
419
+ if (value === undefined && validator._optional) {
420
+ continue;
421
+ }
422
+
423
+ if (value === undefined && validator.hasDefault) {
424
+ values[k] = validator.defaultValue;
425
+ continue;
426
+ }
427
+
428
+ if (!validator.validate(value)) {
429
+ if (validator.hasFallback) {
430
+ values[k] = validator.fallbackValue;
431
+ } else {
432
+ result = false;
433
+ }
434
+ }
435
+ }
436
+
437
+ return result;
438
+ }
439
+ }
440
+
441
+ export class $object<T extends object> extends Validator<T> {
442
+ constructor(private readonly _object: Record<string, Validator> = {}) {
443
+ super();
444
+ }
445
+
446
+ validate(x: unknown): x is T {
447
+ if (this._optional && x === undefined) return true;
448
+
449
+ if (getType(x) !== 'object') {
450
+ return this.fail({ expect: 'object', actual: x });
451
+ }
452
+
453
+ const values = x as Record<string, unknown>;
454
+
455
+ let result = true;
456
+
457
+ // eslint-disable-next-line guard-for-in
458
+ for (const k in this._object) {
459
+ const value = values[k];
460
+ const validator = this._object[k];
461
+
462
+ validator.errors = this.errors;
463
+
464
+ if (/^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/.test(k)) {
465
+ validator.path = `${this.path}.${k}`;
466
+ } else {
467
+ validator.path = `${this.path}["${k}"]`;
468
+ }
469
+
470
+ if (validator._optional && value === undefined) {
471
+ continue;
472
+ }
473
+
474
+ if (value === undefined && validator.hasDefault) {
475
+ values[k] = validator.defaultValue;
476
+ continue;
477
+ }
478
+
479
+ if (!validator.validate(value)) {
480
+ if (validator.hasFallback) {
481
+ values[k] = validator.fallbackValue;
482
+ } else {
483
+ result = false;
484
+ }
485
+ }
486
+ }
487
+
488
+ return result;
489
+ }
490
+ }
491
+
492
+ export class $literal<T extends Primitive> extends Validator<T> {
493
+ constructor(private readonly value: T) {
494
+ super();
495
+ }
496
+
497
+ validate(x: unknown): x is T {
498
+ if (x === undefined && this._optional) return true;
499
+
500
+ if (x !== this.value) {
501
+ return this.fail({ expect: echo(this.value), actual: x });
502
+ }
503
+ return true;
504
+ }
505
+ }
506
+
507
+ export class $or<T> extends Validator<T> {
508
+ private readonly _items: Validator[];
509
+ constructor(..._items: Validator[]) {
510
+ super();
511
+ this._items = _items;
512
+ }
513
+
514
+ validate(x: unknown): x is T {
515
+ if (x === undefined && this._optional) return true;
516
+
517
+ const orErrors: string[] = [];
518
+
519
+ let result = false;
520
+ const itemLength = this._items.length;
521
+ for (let i = 0; i < itemLength; i++) {
522
+ const validator = this._items[i];
523
+ validator.errors = [];
524
+ validator.path = this.path;
525
+ if (!validator.validate(x)) {
526
+ orErrors.push(validator.errors.join('; '));
527
+ } else if (!result) {
528
+ result = true;
529
+ break;
530
+ }
531
+ }
532
+
533
+ if (!result) {
534
+ const grouped = orErrors.join('\nor ');
535
+ this.errors.push(grouped);
536
+ }
537
+ return result;
538
+ }
539
+ }
540
+
541
+ export class $tuple<T extends unknown[]> extends Validator<T> {
542
+ private readonly _items: Validator[];
543
+ private readonly _minItems: number;
544
+
545
+ constructor(..._items: Validator[]) {
546
+ super();
547
+ this._items = _items;
548
+
549
+ let optionalCount = 0;
550
+ let i = _items.length - 1;
551
+ for (; i >= 0; i--) {
552
+ const validator = _items[i];
553
+ if (validator._optional || validator.hasDefault) {
554
+ optionalCount += 1;
555
+ } else {
556
+ break;
557
+ }
558
+ }
559
+ this._minItems = _items.length - optionalCount;
560
+ }
561
+
562
+ validate(x: unknown): x is T {
563
+ if (x === undefined && this._optional) return true;
564
+
565
+ if (!Array.isArray(x)) {
566
+ return this.fail({ expect: 'array', actual: x });
567
+ }
568
+
569
+ if (x.length < this._minItems) {
570
+ return this.fail(`the length of ${this.path} should be greater than or equal to ${this._minItems}`);
571
+ }
572
+
573
+ let result = true;
574
+
575
+ this._items.forEach((validator, index) => {
576
+ validator.path = `${this.path}[${index}]`;
577
+ validator.errors = this.errors;
578
+
579
+ const item = x[index];
580
+
581
+ if (item === undefined && validator.hasDefault) {
582
+ x[index] = validator.defaultValue;
583
+ return;
584
+ }
585
+
586
+ if (!validator.validate(x[index])) {
587
+ if (validator.hasFallback) {
588
+ x[index] = validator._fallback;
589
+ } else {
590
+ result = false;
591
+ }
592
+ }
593
+ });
594
+
595
+ return result;
596
+ }
597
+ }
598
+
599
+ export class $arraybuffer extends Validator<ArrayBuffer> {
600
+ validate(x: unknown): x is ArrayBuffer {
601
+ if (x === undefined && this._optional) return true;
602
+
603
+ if (x instanceof ArrayBuffer) {
604
+ return true;
605
+ }
606
+
607
+ return this.fail({ expect: 'arraybuffer', actual: x });
608
+ }
609
+ }
610
+
611
+ export type TypedArray =
612
+ | Uint8Array
613
+ | Int8Array
614
+ | Uint8ClampedArray
615
+ | Uint16Array
616
+ | Int16Array
617
+ | Uint32Array
618
+ | Int32Array
619
+ | Float32Array
620
+ | Float64Array;
621
+
622
+ export class $typedarray<T extends TypedArray> extends Validator<T> {
623
+ private readonly _ctor: Constructor<T>;
624
+
625
+ constructor(ctor: Constructor<T>) {
626
+ super();
627
+ this._ctor = ctor;
628
+ }
629
+
630
+ validate(x: unknown): x is T {
631
+ if (x === undefined && this._optional) return true;
632
+
633
+ if (x instanceof this._ctor) {
634
+ return true;
635
+ }
636
+
637
+ return this.fail({ expect: `typedarray of ${this._ctor.name}`, actual: x });
638
+ }
639
+ }
@@ -0,0 +1,19 @@
1
+ import { CanIUseInfo, canIUseConfig, logger } from '@jolibox/common';
2
+
3
+ export function registerCanIUseFactory(platform: keyof typeof canIUseConfig.config) {
4
+ let configMap = canIUseConfig.config[platform];
5
+ if (!configMap) {
6
+ configMap = {};
7
+ canIUseConfig.config[platform] = configMap;
8
+ }
9
+
10
+ return (name: string, config: CanIUseInfo): void => {
11
+ if (configMap![name]) {
12
+ logger.warn(`[can i use] ${name} already registered`);
13
+ return;
14
+ }
15
+ configMap![name] = {
16
+ ...config
17
+ };
18
+ };
19
+ }