@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,188 @@
1
+ import { APIError, isArray } from '@jolibox/common';
2
+
3
+ import { ResponseType, StandardResponse } from '@jolibox/types';
4
+ import { Track } from '../report';
5
+ import { reportError } from '../report/errors/report';
6
+ import { Type, typeAsserts, Validator } from './validator';
7
+ import { createAPIError, createUserAPIError } from '../report/errors';
8
+
9
+ let traceId = 1;
10
+
11
+ /**
12
+ * TODO: 埋点逻辑
13
+ */
14
+ type Response<T> = T | StandardResponse<T>;
15
+ type SyncFunction<Params extends unknown[], Return> = (
16
+ ...inputs: Params
17
+ ) => Return | { code: ResponseType; data: Return };
18
+ type AsyncFunction<Params extends unknown[], Return> = (
19
+ ...inputs: Params
20
+ ) => Promise<Response<Return> | Return>;
21
+ interface APIFactory {
22
+ createSyncAPI<Params extends unknown[], Return = void>(
23
+ method: string,
24
+ config: {
25
+ implement: SyncFunction<Params, Return>;
26
+ }
27
+ ): (...inputs: Params) => StandardResponse<Return>;
28
+
29
+ createAPI<Params extends unknown[], Return = void>(
30
+ method: string,
31
+ config: {
32
+ implement: Params extends undefined ? () => Promise<Return> : AsyncFunction<Params, Return>;
33
+ }
34
+ ): (...inputs: unknown[]) => Promise<StandardResponse<Return>>;
35
+ }
36
+
37
+ export const createAPIFactory = (track: Track) => {
38
+ /**
39
+ * create Sync API
40
+ */
41
+ function createSyncAPI<
42
+ ParamsSchema extends Validator<unknown[]>,
43
+ Inputs extends Type<ParamsSchema> & unknown[],
44
+ Return = void
45
+ >(
46
+ method: string,
47
+ config: {
48
+ paramsSchema?: ParamsSchema;
49
+ implement: (...inputs: Inputs) => Return | { code: ResponseType; data: Return };
50
+ }
51
+ ): (...inputs: Inputs) => StandardResponse<Return> {
52
+ return (...inputs) => {
53
+ const startTime = Date.now();
54
+ const reportExtra = { method, trace_id: traceId };
55
+ traceId += 1;
56
+
57
+ let status: ResponseType = 'SUCCESS';
58
+ let errMsg = `${method}:ok`;
59
+ let errNo = 0;
60
+
61
+ try {
62
+ // 类型校验
63
+ if (config.paramsSchema) {
64
+ try {
65
+ typeAsserts(config.paramsSchema, inputs, 'params');
66
+ } catch (err: unknown) {
67
+ const error = err as { message: string };
68
+ throw createUserAPIError(`${method}:fail ${error.message}`);
69
+ }
70
+ }
71
+ const res = config.implement(...inputs);
72
+ let data = res as Return;
73
+ let message = `${method}:ok`;
74
+ if (res && 'code' in (res as { code: ResponseType; data: Return })) {
75
+ const {
76
+ code,
77
+ data: originData,
78
+ message: originMessage
79
+ } = res as { code: ResponseType; data: Return; message: string };
80
+ status = code;
81
+ data = originData;
82
+ message = originMessage;
83
+ }
84
+
85
+ return {
86
+ code: status,
87
+ message,
88
+ data
89
+ };
90
+ } catch (error) {
91
+ const _error = error as { code?: number; message?: string; errNo?: number; errMsg?: string };
92
+ errNo = _error.code ?? _error.errNo ?? 2000;
93
+ status = 'FAILURE';
94
+ const msg = _error.message ?? _error.errMsg ?? `${error}`;
95
+ errMsg = `${method}:${status} ${msg.replace(/^\S+:(fail|cancel)\s?/, '')}`;
96
+ reportError(new APIError(errMsg, errNo));
97
+ return {
98
+ code: status,
99
+ message: errMsg
100
+ };
101
+ } finally {
102
+ const duration = Date.now() - startTime;
103
+ track('apiInvoked', { ...reportExtra, duration, status });
104
+ }
105
+ };
106
+ }
107
+
108
+ /**
109
+ * Async API
110
+ */
111
+
112
+ function createAPI<
113
+ ParamsSchema extends Validator<unknown[]>,
114
+ Inputs extends Type<ParamsSchema> & unknown[],
115
+ Return
116
+ >(
117
+ method: string,
118
+ config: {
119
+ paramsSchema?: ParamsSchema;
120
+ implement: Inputs extends undefined
121
+ ? () => Promise<Response<Return>>
122
+ : (...params: Inputs) => Promise<Response<Return>>;
123
+ }
124
+ ): (...inputs: unknown[]) => Promise<StandardResponse<Return>> {
125
+ // 异步 API
126
+ return async (..._inputs) => {
127
+ const inputs = isArray(_inputs) ? _inputs : [_inputs];
128
+
129
+ const startTime = Date.now();
130
+ const reportExtra = { method, trace_id: traceId };
131
+ traceId += 1;
132
+
133
+ let message = `${method}:ok`;
134
+ let status: ResponseType = 'SUCCESS';
135
+ const res: StandardResponse<Return> = {
136
+ code: status,
137
+ message
138
+ };
139
+
140
+ try {
141
+ if (config.paramsSchema) {
142
+ try {
143
+ typeAsserts(config.paramsSchema, inputs, 'params');
144
+ } catch (error) {
145
+ throw createUserAPIError((error as Error).message);
146
+ }
147
+ }
148
+
149
+ const data = await config.implement(...inputs);
150
+
151
+ let ret = data as Return;
152
+ if (ret && 'code' in (ret as unknown as { code: ResponseType; data: Return })) {
153
+ const {
154
+ code,
155
+ data: originData,
156
+ message: originMessage
157
+ } = ret as unknown as { code: ResponseType; data: Return; message: string };
158
+ status = code;
159
+ message = originMessage;
160
+ ret = originData;
161
+ }
162
+ Object.assign(res, {
163
+ code: status,
164
+ message,
165
+ data: ret
166
+ });
167
+ return res;
168
+ } catch (error: any) {
169
+ const _error = error as { code?: number; message?: string; errNo?: number; errMsg?: string };
170
+ const errNo = _error.code ?? _error.errNo ?? 2000;
171
+ status = 'FAILURE';
172
+ const msg = _error.message ?? _error.errMsg ?? `${error}`;
173
+ const errMsg = `${method}:${status} ${msg.replace(/^\S+:(fail|cancel)\s?/, '')}`;
174
+ Object.assign(res, {
175
+ code: status,
176
+ message: errMsg
177
+ });
178
+ reportError(new APIError(errMsg, errNo));
179
+ return res;
180
+ } finally {
181
+ const duration = Date.now() - startTime;
182
+ track('apiInvoked', { ...reportExtra, duration, status });
183
+ }
184
+ };
185
+ }
186
+
187
+ return { createAPI, createSyncAPI };
188
+ };
@@ -0,0 +1,68 @@
1
+ /* eslint-disable no-empty-function */
2
+ import { t, typeAsserts, Validator } from '../../index';
3
+
4
+ describe('any,unknown,as', () => {
5
+ function testSchema(schema: Validator) {
6
+ expect(schema.validate('')).toBe(true);
7
+
8
+ expect(schema.validate('str')).toBe(true);
9
+ expect(() => {
10
+ typeAsserts(schema, 'str');
11
+ }).not.toThrow();
12
+
13
+ expect(schema.validate(1)).toBe(true);
14
+ expect(() => {
15
+ typeAsserts(schema, 1);
16
+ }).not.toThrow();
17
+
18
+ expect(schema.validate(Symbol.for('1'))).toBe(true);
19
+ expect(() => {
20
+ typeAsserts(schema, Symbol.for('1'));
21
+ }).not.toThrow();
22
+
23
+ expect(schema.validate(null)).toBe(true);
24
+ expect(() => {
25
+ typeAsserts(schema, null);
26
+ }).not.toThrow();
27
+
28
+ expect(schema.validate(undefined)).toBe(true);
29
+ expect(() => {
30
+ typeAsserts(schema, undefined);
31
+ }).not.toThrow();
32
+
33
+ expect(schema.validate({})).toBe(true);
34
+ expect(() => {
35
+ typeAsserts(schema, {});
36
+ }).not.toThrow();
37
+
38
+ expect(schema.validate([])).toBe(true);
39
+ expect(() => {
40
+ typeAsserts(schema, []);
41
+ }).not.toThrow();
42
+
43
+ expect(schema.validate(() => {})).toBe(true);
44
+ expect(() => {
45
+ typeAsserts(schema, () => {});
46
+ }).not.toThrow();
47
+
48
+ expect(schema.validate(BigInt(1))).toBe(true);
49
+ expect(() => {
50
+ typeAsserts(schema, BigInt(1));
51
+ }).not.toThrow();
52
+ }
53
+
54
+ it('any', () => {
55
+ expect.hasAssertions();
56
+ testSchema(t.any());
57
+ });
58
+
59
+ it('unknown', () => {
60
+ expect.hasAssertions();
61
+ testSchema(t.unknown());
62
+ });
63
+
64
+ it('as', () => {
65
+ expect.hasAssertions();
66
+ testSchema(t.as());
67
+ });
68
+ });
@@ -0,0 +1,402 @@
1
+ /* eslint-disable no-empty-function */
2
+ import { t, typeAsserts } from '../../index';
3
+
4
+ describe('array', () => {
5
+ it('string array', () => {
6
+ expect.hasAssertions();
7
+ const schema = t.array(t.string());
8
+
9
+ expect(schema.validate(['str'])).toBe(true);
10
+
11
+ expect(schema.validate({})).toBe(false);
12
+ expect(() => {
13
+ typeAsserts(schema, {});
14
+ }).toThrow('param should be array, but got a(n) object');
15
+
16
+ expect(schema.validate(1)).toBe(false);
17
+ expect(() => {
18
+ typeAsserts(schema, 1);
19
+ }).toThrow('param should be array, but got 1');
20
+
21
+ expect(schema.validate('str')).toBe(false);
22
+ expect(() => {
23
+ typeAsserts(schema, 1);
24
+ }).toThrow('param should be array, but got 1');
25
+
26
+ expect(schema.validate([1])).toBe(false);
27
+ expect(() => {
28
+ typeAsserts(schema, [1]);
29
+ }).toThrow('param[0] should be string, but got 1');
30
+
31
+ expect(schema.validate([true])).toBe(false);
32
+ expect(() => {
33
+ typeAsserts(schema, [true]);
34
+ }).toThrow('param[0] should be string, but got true');
35
+
36
+ expect(schema.validate([false])).toBe(false);
37
+ expect(() => {
38
+ typeAsserts(schema, [false]);
39
+ }).toThrow('param[0] should be string, but got false');
40
+
41
+ expect(schema.validate([Symbol(1)])).toBe(false);
42
+ expect(() => {
43
+ typeAsserts(schema, [Symbol(1)]);
44
+ }).toThrow('param[0] should be string, but got a(n) symbol');
45
+
46
+ expect(schema.validate([null])).toBe(false);
47
+ expect(() => {
48
+ typeAsserts(schema, [null]);
49
+ }).toThrow('param[0] should be string, but got null');
50
+
51
+ expect(schema.validate([undefined])).toBe(false);
52
+ expect(() => {
53
+ typeAsserts(schema, [undefined]);
54
+ }).toThrow('param[0] should be string, but got undefined');
55
+
56
+ expect(schema.validate([BigInt(1)])).toBe(false);
57
+ expect(() => {
58
+ typeAsserts(schema, [BigInt(1)]);
59
+ }).toThrow('param[0] should be string, but got a(n) bigint');
60
+
61
+ expect(schema.validate([{}])).toBe(false);
62
+ expect(() => {
63
+ typeAsserts(schema, [{}]);
64
+ }).toThrow('param[0] should be string, but got a(n) object');
65
+
66
+ expect(schema.validate([() => {}])).toBe(false);
67
+ expect(() => {
68
+ typeAsserts(schema, [() => {}]);
69
+ }).toThrow('param[0] should be string, but got a(n) function');
70
+ });
71
+
72
+ it('number array', () => {
73
+ expect.hasAssertions();
74
+ const schema = t.array(t.number());
75
+
76
+ expect(schema.validate([1])).toBe(true);
77
+ expect(() => {
78
+ typeAsserts(schema, [1]);
79
+ }).not.toThrow();
80
+
81
+ expect(schema.validate(['str'])).toBe(false);
82
+ expect(() => {
83
+ typeAsserts(schema, ['str']);
84
+ }).toThrow('param[0] should be number, but got "str"');
85
+
86
+ expect(schema.validate([true])).toBe(false);
87
+ expect(() => {
88
+ typeAsserts(schema, [true]);
89
+ }).toThrow('param[0] should be number, but got true');
90
+
91
+ expect(schema.validate([false])).toBe(false);
92
+ expect(() => {
93
+ typeAsserts(schema, [false]);
94
+ }).toThrow('param[0] should be number, but got false');
95
+
96
+ expect(schema.validate([Symbol(1)])).toBe(false);
97
+ expect(() => {
98
+ typeAsserts(schema, [Symbol(1)]);
99
+ }).toThrow('param[0] should be number, but got a(n) symbol');
100
+
101
+ expect(schema.validate([null])).toBe(false);
102
+ expect(() => {
103
+ typeAsserts(schema, [null]);
104
+ }).toThrow('param[0] should be number, but got null');
105
+
106
+ expect(schema.validate([undefined])).toBe(false);
107
+ expect(() => {
108
+ typeAsserts(schema, [undefined]);
109
+ }).toThrow('param[0] should be number, but got undefined');
110
+
111
+ expect(schema.validate([BigInt(1)])).toBe(false);
112
+ expect(() => {
113
+ typeAsserts(schema, [BigInt(1)]);
114
+ }).toThrow('param[0] should be number, but got a(n) bigint');
115
+
116
+ expect(schema.validate([{}])).toBe(false);
117
+ expect(() => {
118
+ typeAsserts(schema, [{}]);
119
+ }).toThrow('param[0] should be number, but got a(n) object');
120
+
121
+ expect(schema.validate([() => {}])).toBe(false);
122
+ expect(() => {
123
+ typeAsserts(schema, [() => {}]);
124
+ }).toThrow('param[0] should be number, but got a(n) function');
125
+ });
126
+
127
+ it('boolean array', () => {
128
+ expect.hasAssertions();
129
+ const schema = t.array(t.boolean());
130
+
131
+ expect(schema.validate([true])).toBe(true);
132
+ expect(() => {
133
+ typeAsserts(schema, [true]);
134
+ }).not.toThrow();
135
+
136
+ expect(schema.validate([false])).toBe(true);
137
+ expect(() => {
138
+ typeAsserts(schema, [false]);
139
+ }).not.toThrow();
140
+
141
+ expect(schema.validate([1])).toBe(false);
142
+ expect(() => {
143
+ typeAsserts(schema, [1]);
144
+ }).toThrow('param[0] should be boolean, but got 1');
145
+
146
+ expect(schema.validate(['str'])).toBe(false);
147
+ expect(() => {
148
+ typeAsserts(schema, ['str']);
149
+ }).toThrow('param[0] should be boolean, but got "str"');
150
+
151
+ expect(schema.validate([Symbol(1)])).toBe(false);
152
+ expect(() => {
153
+ typeAsserts(schema, [Symbol(1)]);
154
+ }).toThrow('param[0] should be boolean, but got a(n) symbol');
155
+
156
+ expect(schema.validate([null])).toBe(false);
157
+ expect(() => {
158
+ typeAsserts(schema, [null]);
159
+ }).toThrow('param[0] should be boolean, but got null');
160
+
161
+ expect(schema.validate([undefined])).toBe(false);
162
+ expect(() => {
163
+ typeAsserts(schema, [undefined]);
164
+ }).toThrow('param[0] should be boolean, but got undefined');
165
+
166
+ expect(schema.validate([BigInt(1)])).toBe(false);
167
+ expect(() => {
168
+ typeAsserts(schema, [BigInt(1)]);
169
+ }).toThrow('param[0] should be boolean, but got a(n) bigint');
170
+
171
+ expect(schema.validate([{}])).toBe(false);
172
+ expect(() => {
173
+ typeAsserts(schema, [{}]);
174
+ }).toThrow('param[0] should be boolean, but got a(n) object');
175
+
176
+ expect(schema.validate([() => {}])).toBe(false);
177
+ expect(() => {
178
+ typeAsserts(schema, [() => {}]);
179
+ }).toThrow('param[0] should be boolean, but got a(n) function');
180
+ });
181
+
182
+ it('undefined array', () => {
183
+ expect.hasAssertions();
184
+ const schema = t.array(t.undefined());
185
+
186
+ expect(schema.validate([true])).toBe(false);
187
+ expect(() => {
188
+ typeAsserts(schema, [true]);
189
+ }).toThrow('param[0] should be undefined, but got true');
190
+
191
+ expect(schema.validate([undefined])).toBe(true);
192
+ expect(() => {
193
+ typeAsserts(schema, [undefined]);
194
+ }).not.toThrow();
195
+
196
+ expect(schema.validate([true])).toBe(false);
197
+ expect(() => {
198
+ typeAsserts(schema, [true]);
199
+ }).toThrow('param[0] should be undefined, but got true');
200
+
201
+ expect(schema.validate([false])).toBe(false);
202
+ expect(() => {
203
+ typeAsserts(schema, [false]);
204
+ }).toThrow('param[0] should be undefined, but got false');
205
+
206
+ expect(schema.validate([1])).toBe(false);
207
+ expect(() => {
208
+ typeAsserts(schema, [1]);
209
+ }).toThrow('param[0] should be undefined, but got 1');
210
+
211
+ expect(schema.validate(['str'])).toBe(false);
212
+ expect(() => {
213
+ typeAsserts(schema, ['str']);
214
+ }).toThrow('param[0] should be undefined, but got "str"');
215
+
216
+ expect(schema.validate([Symbol(1)])).toBe(false);
217
+ expect(() => {
218
+ typeAsserts(schema, [Symbol(1)]);
219
+ }).toThrow('param[0] should be undefined, but got a(n) symbol');
220
+
221
+ expect(schema.validate([null])).toBe(false);
222
+ expect(() => {
223
+ typeAsserts(schema, [null]);
224
+ }).toThrow('param[0] should be undefined, but got null');
225
+
226
+ expect(schema.validate([BigInt(1)])).toBe(false);
227
+ expect(() => {
228
+ typeAsserts(schema, [BigInt(1)]);
229
+ }).toThrow('param[0] should be undefined, but got a(n) bigint');
230
+
231
+ expect(schema.validate([{}])).toBe(false);
232
+ expect(() => {
233
+ typeAsserts(schema, [{}]);
234
+ }).toThrow('param[0] should be undefined, but got a(n) object');
235
+
236
+ expect(schema.validate([() => {}])).toBe(false);
237
+ expect(() => {
238
+ typeAsserts(schema, [() => {}]);
239
+ }).toThrow('param[0] should be undefined, but got a(n) function');
240
+ });
241
+
242
+ it('null array', () => {
243
+ expect.hasAssertions();
244
+ const schema = t.array(t.null());
245
+
246
+ expect(schema.validate([null])).toBe(true);
247
+ expect(() => {
248
+ typeAsserts(schema, [null]);
249
+ }).not.toThrow();
250
+
251
+ expect(schema.validate([true])).toBe(false);
252
+ expect(schema.validate([false])).toBe(false);
253
+ expect(schema.validate([1])).toBe(false);
254
+ expect(schema.validate(['str'])).toBe(false);
255
+ expect(schema.validate([Symbol(1)])).toBe(false);
256
+ expect(schema.validate([undefined])).toBe(false);
257
+ expect(schema.validate([BigInt(1)])).toBe(false);
258
+ expect(schema.validate([{}])).toBe(false);
259
+ expect(schema.validate([() => {}])).toBe(false);
260
+ });
261
+
262
+ it('object array', () => {
263
+ expect.hasAssertions();
264
+ const schema = t.array(t.object());
265
+
266
+ expect(schema.validate([{}])).toBe(true);
267
+ expect(() => {
268
+ typeAsserts(schema, [{}]);
269
+ }).not.toThrow();
270
+
271
+ expect(schema.validate([true])).toBe(false);
272
+ expect(schema.validate([false])).toBe(false);
273
+ expect(schema.validate([1])).toBe(false);
274
+ expect(schema.validate(['str'])).toBe(false);
275
+ expect(schema.validate([Symbol(1)])).toBe(false);
276
+ expect(schema.validate([undefined])).toBe(false);
277
+ expect(schema.validate([BigInt(1)])).toBe(false);
278
+ expect(schema.validate([null])).toBe(false);
279
+ expect(schema.validate([() => {}])).toBe(false);
280
+ });
281
+
282
+ it('object.property array', () => {
283
+ expect.hasAssertions();
284
+ const schema = t.array(
285
+ t.object({
286
+ a: t.string(),
287
+ b: t.number()
288
+ })
289
+ );
290
+
291
+ expect(schema.validate([{ a: 'str', b: 1 }])).toBe(true);
292
+ expect(() => {
293
+ typeAsserts(schema, [{ a: 'str', b: 1 }]);
294
+ }).not.toThrow();
295
+
296
+ expect(schema.validate([{}])).toBe(false);
297
+ expect(schema.validate([{ a: 'str' }])).toBe(false);
298
+ expect(schema.validate([{ b: 1 }])).toBe(false);
299
+ });
300
+
301
+ it('primitive item error message', () => {
302
+ expect.hasAssertions();
303
+ const schema = t.array(t.string());
304
+
305
+ expect(() => typeAsserts(schema, [1])).toThrow(`param[0] should be string, but got 1`);
306
+
307
+ expect(() => typeAsserts(schema, ['str', 1])).toThrow(`param[1] should be string, but got 1`);
308
+ });
309
+
310
+ it('object item error message', () => {
311
+ expect.hasAssertions();
312
+ const schema = t.array(
313
+ t.object({
314
+ a: t.object({
315
+ b: t.string()
316
+ })
317
+ })
318
+ );
319
+
320
+ expect(() => {
321
+ typeAsserts(schema, [{ a: { b: 123 } }]);
322
+ }).toThrow(`param[0].a.b should be string, but got 123`);
323
+
324
+ expect(() => typeAsserts(schema, [{ a: { b: 'str' } }, { a: { b: 123 } }])).toThrow(
325
+ `param[1].a.b should be string, but got 123`
326
+ );
327
+ });
328
+
329
+ it('minItems', () => {
330
+ expect.hasAssertions();
331
+ const schema = t.array(t.string()).minItems(3);
332
+
333
+ expect(schema.validate([])).toBe(false);
334
+ expect(schema.validate(['str'])).toBe(false);
335
+ expect(schema.validate(['str', 'str', 'str'])).toBe(true);
336
+ expect(schema.validate(['str', 'str', 'str', 'str'])).toBe(true);
337
+ });
338
+
339
+ it('maxItems', () => {
340
+ expect.hasAssertions();
341
+ const schema = t.array(t.string()).maxItems(13);
342
+
343
+ expect(schema.validate([])).toBe(true);
344
+ expect(schema.validate(['str'])).toBe(true);
345
+ expect(schema.validate(Array(13).fill('str'))).toBe(true);
346
+ expect(schema.validate(Array(14).fill('str'))).toBe(false);
347
+ });
348
+
349
+ it('optional', () => {
350
+ expect.hasAssertions();
351
+ const schema = t.array(t.string()).optional();
352
+ expect(schema.validate(undefined)).toBe(true);
353
+ expect(() => {
354
+ typeAsserts(schema, undefined);
355
+ }).not.toThrow();
356
+ });
357
+
358
+ it('item default', () => {
359
+ expect.hasAssertions();
360
+ const schema = t.array(t.string().default('default-string'));
361
+ const data: unknown[] = [undefined, undefined, 'str'];
362
+ schema.validate(data);
363
+ expect(data).toStrictEqual(['default-string', 'default-string', 'str']);
364
+ });
365
+
366
+ it('item fallback', () => {
367
+ expect.hasAssertions();
368
+ const schema = t.array(t.string().fallback('fallback-string'));
369
+ const data: unknown[] = [1, 1, 'str'];
370
+ expect(schema.validate(data)).toBe(true);
371
+ expect(data).toStrictEqual(['fallback-string', 'fallback-string', 'str']);
372
+ });
373
+
374
+ it('uniqueItems', () => {
375
+ expect.hasAssertions();
376
+ const schema = t.array(t.string()).uniqueItems();
377
+
378
+ const data: unknown = ['1', '2', '2', '1', '1'];
379
+ expect(schema.validate(data)).toBe(false);
380
+ expect(() => {
381
+ typeAsserts(schema, data);
382
+ }).toThrow(`param should NOT have duplicate items (param[1] and param[2] are identical)
383
+ param should NOT have duplicate items (param[0] and param[3] are identical)
384
+ param should NOT have duplicate items (param[0] and param[4] are identical)`);
385
+
386
+ const data2: unknown = ['1', '2'];
387
+ expect(() => typeAsserts(schema, data2)).not.toThrow();
388
+ expect(schema.validate(data2)).toBe(true);
389
+ });
390
+
391
+ it('length', () => {
392
+ expect.hasAssertions();
393
+ const schema = t.array().length(2);
394
+ expect(schema.validate(['ss', 'xx'])).toBe(true);
395
+ expect(schema.validate(['ss'])).toBe(false);
396
+ expect(schema.validate(['ss', 'xx', 'yy'])).toBe(false);
397
+ expect(schema.validate([])).toBe(false);
398
+ expect(() => typeAsserts(schema, [])).toThrow(`the length of param should be equal to 2`);
399
+
400
+ expect(() => typeAsserts(schema, [1, 2, 3])).toThrow(`the length of param should be equal to 2`);
401
+ });
402
+ });
@@ -0,0 +1,48 @@
1
+ import { t, typeAsserts } from '../../index';
2
+
3
+ describe('arrayBuffer', () => {
4
+ it('valid value', () => {
5
+ expect.hasAssertions();
6
+ const buffer = new ArrayBuffer(10);
7
+ const schema = t.arraybuffer();
8
+
9
+ expect(schema.validate(buffer)).toBe(true);
10
+ expect(() => {
11
+ typeAsserts(schema, buffer);
12
+ }).not.toThrow();
13
+
14
+ expect(schema.validate(123)).toBe(false);
15
+ expect(() => {
16
+ typeAsserts(schema, 123);
17
+ }).toThrow('param should be arraybuffer, but got 123');
18
+
19
+ expect(schema.validate('str')).toBe(false);
20
+ expect(() => {
21
+ typeAsserts(schema, 'str');
22
+ }).toThrow('param should be arraybuffer, but got "str"');
23
+
24
+ expect(schema.validate(true)).toBe(false);
25
+ expect(() => {
26
+ typeAsserts(schema, true);
27
+ }).toThrow('param should be arraybuffer, but got true');
28
+
29
+ expect(schema.validate({})).toBe(false);
30
+ expect(() => {
31
+ typeAsserts(schema, {});
32
+ }).toThrow('param should be arraybuffer, but got a(n) object');
33
+
34
+ expect(schema.validate([])).toBe(false);
35
+ expect(() => {
36
+ typeAsserts(schema, []);
37
+ }).toThrow('param should be arraybuffer, but got a(n) array');
38
+ });
39
+
40
+ it('optional optional', () => {
41
+ expect.hasAssertions();
42
+ const schema = t.arraybuffer().optional();
43
+ expect(schema.validate(undefined)).toBe(true);
44
+ expect(() => {
45
+ typeAsserts(schema, undefined);
46
+ }).not.toThrow();
47
+ });
48
+ });