@nextplus/js-sdk 0.0.9 → 0.0.11
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 +404 -35
- package/dist/{chunk-TU3VOZVD.js → chunk-7J2MXBSD.js} +9 -1
- package/dist/{chunk-VAV5HKXV.js → chunk-QDNBVWJS.js} +1001 -73
- package/dist/{index-DESgEWKO.d.ts → index-kKTFUHzJ.d.cts} +211 -9
- package/dist/{index-KyIl4y18.d.cts → index-nch-cTLb.d.ts} +211 -9
- package/dist/index.cjs +1395 -154
- package/dist/index.d.cts +41 -27
- package/dist/index.d.ts +41 -27
- package/dist/index.js +348 -36
- package/dist/sdk/index.cjs +1003 -72
- package/dist/sdk/index.d.cts +1 -1
- package/dist/sdk/index.d.ts +1 -1
- package/dist/sdk/index.js +10 -2
- package/dist/sdk/sdk.gen.cjs +1003 -72
- package/dist/sdk/sdk.gen.d.cts +1 -1
- package/dist/sdk/sdk.gen.d.ts +1 -1
- package/dist/sdk/sdk.gen.js +9 -1
- package/dist/{sdk.gen-D4UJVxtf.d.cts → sdk.gen-I8-kzcmn.d.cts} +1616 -57
- package/dist/{sdk.gen-aOku7-zB.d.ts → sdk.gen-uXRPSDo0.d.ts} +1616 -57
- package/package.json +12 -4
- package/src/index.ts +256 -76
- package/src/sdk/schemas.gen.ts +265 -42
- package/src/sdk/sdk.gen.ts +1430 -36
- package/src/sdk/transformers.gen.ts +325 -0
- package/src/sdk/types.gen.ts +1628 -49
- package/src/smoke.ts +582 -71
package/src/smoke.ts
CHANGED
|
@@ -1,83 +1,594 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
// @ts-ignore - Node test runner types may not be available
|
|
2
|
+
import { test, describe } from 'node:test';
|
|
3
|
+
// @ts-ignore - Node assert types may not be available
|
|
4
|
+
import assert from 'node:assert/strict';
|
|
5
|
+
import { configure, TableService, UserModelService } from './index';
|
|
6
|
+
|
|
7
|
+
const BASE_URL = 'http://127.0.0.1:3000/api';
|
|
8
|
+
const TEST_EMAIL = 'operator@operator.com';
|
|
9
|
+
const TEST_USERNAME = 'operator';
|
|
10
|
+
const TEST_PASSWORD = 'operator@operator.com';
|
|
11
|
+
|
|
12
|
+
describe('NextPlus SDK', () => {
|
|
13
|
+
describe('Credential-Based Authentication', () => {
|
|
14
|
+
test('should configure with email and returnType: data', async () => {
|
|
15
|
+
const sdk = configure({
|
|
16
|
+
baseURL: BASE_URL,
|
|
17
|
+
email: TEST_EMAIL,
|
|
18
|
+
password: TEST_PASSWORD,
|
|
19
|
+
returnType: 'data',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const tables = await sdk.TableService.find({
|
|
23
|
+
query: {
|
|
24
|
+
filter: JSON.stringify({
|
|
25
|
+
limit: 10,
|
|
26
|
+
order: 'created DESC',
|
|
27
|
+
fields: {
|
|
28
|
+
id: true,
|
|
29
|
+
name: true,
|
|
30
|
+
created: true,
|
|
31
|
+
},
|
|
32
|
+
where: {
|
|
33
|
+
name: 'no-such-table!',
|
|
34
|
+
},
|
|
35
|
+
}),
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
assert.ok(Array.isArray(tables), 'Response should be an array');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('should handle validation errors with email auth', async () => {
|
|
43
|
+
const sdk = configure({
|
|
44
|
+
baseURL: BASE_URL,
|
|
45
|
+
email: TEST_EMAIL,
|
|
46
|
+
password: TEST_PASSWORD,
|
|
47
|
+
returnType: 'data',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
await assert.rejects(
|
|
51
|
+
async () => {
|
|
52
|
+
await sdk.TableService.create({ body: {} } as any);
|
|
53
|
+
},
|
|
54
|
+
(error: any) => {
|
|
55
|
+
assert.ok(error.message, 'Error should have a message');
|
|
56
|
+
return true;
|
|
57
|
+
},
|
|
58
|
+
'Should throw validation error',
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('should configure with username and returnType: raw', async () => {
|
|
63
|
+
const sdk = configure({
|
|
64
|
+
baseURL: BASE_URL,
|
|
65
|
+
username: TEST_USERNAME,
|
|
66
|
+
password: TEST_PASSWORD,
|
|
67
|
+
returnType: 'raw',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const tablesRaw = await sdk.TableService.find({
|
|
71
|
+
query: {
|
|
72
|
+
filter: JSON.stringify({
|
|
73
|
+
where: {
|
|
74
|
+
name: 'test',
|
|
75
|
+
},
|
|
76
|
+
limit: 5,
|
|
77
|
+
}),
|
|
78
|
+
},
|
|
79
|
+
});
|
|
11
80
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
81
|
+
assert.ok('data' in tablesRaw, 'Response should have data property');
|
|
82
|
+
assert.ok(
|
|
83
|
+
'request' in tablesRaw,
|
|
84
|
+
'Response should have request property',
|
|
85
|
+
);
|
|
86
|
+
assert.ok(
|
|
87
|
+
'response' in tablesRaw,
|
|
88
|
+
'Response should have response property',
|
|
89
|
+
);
|
|
90
|
+
assert.ok(Array.isArray(tablesRaw.data), 'Data should be an array');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('should handle validation errors with username auth (raw mode)', async () => {
|
|
94
|
+
const sdk = configure({
|
|
95
|
+
baseURL: BASE_URL,
|
|
96
|
+
username: TEST_USERNAME,
|
|
97
|
+
password: TEST_PASSWORD,
|
|
98
|
+
returnType: 'raw',
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// In raw mode, errors are returned in the response object, not thrown
|
|
102
|
+
const response = await sdk.TableService.create({ body: {} } as any);
|
|
103
|
+
assert.ok('error' in response, 'Response should have error property');
|
|
104
|
+
assert.ok(response.error, 'Error should be present');
|
|
105
|
+
});
|
|
31
106
|
});
|
|
32
107
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
108
|
+
describe('Token-Based Authentication', () => {
|
|
109
|
+
let accessToken: string;
|
|
110
|
+
|
|
111
|
+
test('should obtain access token via login', async () => {
|
|
112
|
+
const loginSdk = configure({
|
|
113
|
+
baseURL: BASE_URL,
|
|
114
|
+
email: TEST_EMAIL,
|
|
115
|
+
password: TEST_PASSWORD,
|
|
116
|
+
returnType: 'raw',
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Manually login to get the token
|
|
120
|
+
const loginResponse = await UserModelService.login({
|
|
121
|
+
client: loginSdk.client,
|
|
122
|
+
body: {
|
|
123
|
+
email: TEST_EMAIL,
|
|
124
|
+
password: TEST_PASSWORD,
|
|
125
|
+
forceLogin: true,
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
accessToken = (loginResponse.data as any)?.id;
|
|
130
|
+
assert.ok(accessToken, 'Should receive access token');
|
|
131
|
+
assert.ok(
|
|
132
|
+
typeof accessToken === 'string',
|
|
133
|
+
'Access token should be a string',
|
|
134
|
+
);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test('should configure and make requests with access token', async () => {
|
|
138
|
+
// Get token first using credential-based SDK
|
|
139
|
+
const loginSdk = configure({
|
|
140
|
+
baseURL: BASE_URL,
|
|
141
|
+
email: TEST_EMAIL,
|
|
142
|
+
password: TEST_PASSWORD,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const loginResponse = await UserModelService.login({
|
|
146
|
+
client: loginSdk.client,
|
|
147
|
+
body: {
|
|
148
|
+
email: TEST_EMAIL,
|
|
149
|
+
password: TEST_PASSWORD,
|
|
150
|
+
forceLogin: true,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const token = (loginResponse.data as any)?.id;
|
|
155
|
+
assert.ok(token, 'Should receive access token');
|
|
156
|
+
|
|
157
|
+
// Use token
|
|
158
|
+
const tokenSdk = configure({
|
|
159
|
+
baseURL: BASE_URL,
|
|
160
|
+
accessToken: token,
|
|
161
|
+
returnType: 'data',
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const tables = await tokenSdk.TableService.find({
|
|
165
|
+
query: {
|
|
166
|
+
filter: JSON.stringify({
|
|
167
|
+
limit: 5,
|
|
168
|
+
fields: {
|
|
169
|
+
name: true,
|
|
170
|
+
},
|
|
171
|
+
}),
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
assert.ok(Array.isArray(tables), 'Response should be an array');
|
|
176
|
+
});
|
|
52
177
|
});
|
|
53
178
|
|
|
54
|
-
|
|
179
|
+
describe('Tree-Shakeable Service Imports', () => {
|
|
180
|
+
test('should throw errors with throwOnError: true', async () => {
|
|
181
|
+
// Get token first
|
|
182
|
+
const loginSdk = configure({
|
|
183
|
+
baseURL: BASE_URL,
|
|
184
|
+
email: TEST_EMAIL,
|
|
185
|
+
password: TEST_PASSWORD,
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
const loginResponse = await UserModelService.login({
|
|
189
|
+
client: loginSdk.client,
|
|
190
|
+
body: {
|
|
191
|
+
email: TEST_EMAIL,
|
|
192
|
+
password: TEST_PASSWORD,
|
|
193
|
+
forceLogin: true,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const token = (loginResponse.data as any)?.id;
|
|
198
|
+
assert.ok(token, 'Should receive access token');
|
|
199
|
+
|
|
200
|
+
// Configure with throwOnError: true
|
|
201
|
+
configure({
|
|
202
|
+
baseURL: BASE_URL,
|
|
203
|
+
accessToken: token,
|
|
204
|
+
throwOnError: true,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Should throw on validation error
|
|
208
|
+
await assert.rejects(
|
|
209
|
+
async () => {
|
|
210
|
+
await TableService.create({ body: {} } as any);
|
|
211
|
+
},
|
|
212
|
+
(error: any) => {
|
|
213
|
+
assert.ok(error, 'Should throw error');
|
|
214
|
+
return true;
|
|
215
|
+
},
|
|
216
|
+
'Should throw error for invalid request',
|
|
217
|
+
);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test('should work with global default client (no client parameter at all)', async () => {
|
|
221
|
+
// Get token first
|
|
222
|
+
const loginSdk = configure({
|
|
223
|
+
baseURL: BASE_URL,
|
|
224
|
+
email: TEST_EMAIL,
|
|
225
|
+
password: TEST_PASSWORD,
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
const loginResponse = await UserModelService.login({
|
|
229
|
+
client: loginSdk.client,
|
|
230
|
+
body: {
|
|
231
|
+
email: TEST_EMAIL,
|
|
232
|
+
password: TEST_PASSWORD,
|
|
233
|
+
forceLogin: true,
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const token = (loginResponse.data as any)?.id;
|
|
238
|
+
assert.ok(token, 'Should receive access token');
|
|
239
|
+
|
|
240
|
+
// configure() automatically sets global default client!
|
|
241
|
+
configure({
|
|
242
|
+
baseURL: BASE_URL,
|
|
243
|
+
accessToken: token,
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// Use TableService without any client parameter at all!
|
|
247
|
+
const response = await TableService.find({
|
|
248
|
+
query: {
|
|
249
|
+
filter: JSON.stringify({
|
|
250
|
+
limit: 5,
|
|
251
|
+
fields: {
|
|
252
|
+
name: true,
|
|
253
|
+
},
|
|
254
|
+
}),
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
assert.ok('data' in response, 'Response should have data');
|
|
259
|
+
assert.ok(
|
|
260
|
+
Array.isArray(response.data),
|
|
261
|
+
'Response data should be an array',
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
// Make another call - still no client needed
|
|
265
|
+
const response2 = await TableService.find({
|
|
266
|
+
query: {
|
|
267
|
+
filter: JSON.stringify({
|
|
268
|
+
limit: 1,
|
|
269
|
+
}),
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
assert.ok('data' in response2, 'Second call should also work');
|
|
274
|
+
assert.ok(response2.data, 'Second call should have data');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
test('should work with token auth and imported TableService only', async () => {
|
|
278
|
+
// Get token first
|
|
279
|
+
const loginSdk = configure({
|
|
280
|
+
baseURL: BASE_URL,
|
|
281
|
+
email: TEST_EMAIL,
|
|
282
|
+
password: TEST_PASSWORD,
|
|
283
|
+
});
|
|
55
284
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
285
|
+
const loginResponse = await UserModelService.login({
|
|
286
|
+
client: loginSdk.client,
|
|
287
|
+
body: {
|
|
288
|
+
email: TEST_EMAIL,
|
|
289
|
+
password: TEST_PASSWORD,
|
|
290
|
+
forceLogin: true,
|
|
62
291
|
},
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
const token = (loginResponse.data as any)?.id;
|
|
295
|
+
assert.ok(token, 'Should receive access token');
|
|
296
|
+
|
|
297
|
+
// Configure with token only
|
|
298
|
+
const sdk = configure({
|
|
299
|
+
baseURL: BASE_URL,
|
|
300
|
+
accessToken: token,
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// Import and use TableService directly - tree-shakeable!
|
|
304
|
+
// This means UserModelService and other services won't be in the bundle
|
|
305
|
+
const response = await TableService.find({
|
|
306
|
+
client: sdk.client,
|
|
307
|
+
query: {
|
|
308
|
+
filter: JSON.stringify({
|
|
309
|
+
limit: 5,
|
|
310
|
+
fields: {
|
|
311
|
+
name: true,
|
|
312
|
+
},
|
|
313
|
+
}),
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
assert.ok('data' in response, 'Response should have data');
|
|
318
|
+
assert.ok(response.data, 'Response data should exist');
|
|
319
|
+
assert.ok(
|
|
320
|
+
Array.isArray(response.data),
|
|
321
|
+
'Response data should be an array',
|
|
322
|
+
);
|
|
323
|
+
if (response.data) {
|
|
324
|
+
assert.ok(response.data.length <= 5, 'Should respect limit');
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
test('should work with sdk.service() helper (no client parameter needed)', async () => {
|
|
329
|
+
// Get token first
|
|
330
|
+
const loginSdk = configure({
|
|
331
|
+
baseURL: BASE_URL,
|
|
332
|
+
email: TEST_EMAIL,
|
|
333
|
+
password: TEST_PASSWORD,
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
const loginResponse = await UserModelService.login({
|
|
337
|
+
client: loginSdk.client,
|
|
338
|
+
body: {
|
|
339
|
+
email: TEST_EMAIL,
|
|
340
|
+
password: TEST_PASSWORD,
|
|
341
|
+
forceLogin: true,
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
const token = (loginResponse.data as any)?.id;
|
|
346
|
+
assert.ok(token, 'Should receive access token');
|
|
347
|
+
|
|
348
|
+
// Use configure() and bind services
|
|
349
|
+
const sdk = configure({
|
|
350
|
+
baseURL: BASE_URL,
|
|
351
|
+
accessToken: token,
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
// Bind the service - no need to pass client on every call!
|
|
355
|
+
const Tables = sdk.service(TableService);
|
|
356
|
+
|
|
357
|
+
const tablesResponse = await Tables.find({
|
|
358
|
+
query: {
|
|
359
|
+
filter: JSON.stringify({
|
|
360
|
+
limit: 3,
|
|
361
|
+
fields: {
|
|
362
|
+
name: true,
|
|
363
|
+
},
|
|
364
|
+
}),
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// When using bound services, response is in raw format
|
|
369
|
+
assert.ok('data' in tablesResponse, 'Response should have data');
|
|
370
|
+
assert.ok(
|
|
371
|
+
Array.isArray(tablesResponse.data),
|
|
372
|
+
'Response data should be an array',
|
|
373
|
+
);
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
test('should work with sdk.client for manual control', async () => {
|
|
377
|
+
// Get token first
|
|
378
|
+
const loginSdk = configure({
|
|
379
|
+
baseURL: BASE_URL,
|
|
380
|
+
email: TEST_EMAIL,
|
|
381
|
+
password: TEST_PASSWORD,
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
const loginResponse = await UserModelService.login({
|
|
385
|
+
client: loginSdk.client,
|
|
386
|
+
body: {
|
|
387
|
+
email: TEST_EMAIL,
|
|
388
|
+
password: TEST_PASSWORD,
|
|
389
|
+
forceLogin: true,
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
const token = (loginResponse.data as any)?.id;
|
|
394
|
+
assert.ok(token, 'Should receive access token');
|
|
395
|
+
|
|
396
|
+
// Use configure() and access the client for tree-shakeable imports
|
|
397
|
+
const sdk = configure({
|
|
398
|
+
baseURL: BASE_URL,
|
|
399
|
+
accessToken: token,
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
const tablesWithClient = await TableService.find({
|
|
403
|
+
client: sdk.client,
|
|
404
|
+
query: {
|
|
405
|
+
filter: JSON.stringify({
|
|
406
|
+
limit: 3,
|
|
407
|
+
fields: {
|
|
408
|
+
name: true,
|
|
409
|
+
},
|
|
410
|
+
}),
|
|
411
|
+
},
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
// When using sdk.client with individual service imports,
|
|
415
|
+
// the response is in raw format (not affected by returnType)
|
|
416
|
+
assert.ok('data' in tablesWithClient, 'Response should have data');
|
|
417
|
+
assert.ok(
|
|
418
|
+
Array.isArray(tablesWithClient.data),
|
|
419
|
+
'Response data should be an array',
|
|
420
|
+
);
|
|
421
|
+
});
|
|
66
422
|
});
|
|
67
423
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
424
|
+
describe('Interceptors', () => {
|
|
425
|
+
test('should allow adding request interceptors with tree-shakeable imports', async () => {
|
|
426
|
+
const sdk = configure({
|
|
427
|
+
baseURL: BASE_URL,
|
|
428
|
+
email: TEST_EMAIL,
|
|
429
|
+
password: TEST_PASSWORD,
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// Track if interceptor was called
|
|
433
|
+
let interceptorCalled = false;
|
|
434
|
+
let requestUrl = '';
|
|
435
|
+
|
|
436
|
+
sdk.client.interceptors.request.use((request: Request) => {
|
|
437
|
+
interceptorCalled = true;
|
|
438
|
+
requestUrl = request.url;
|
|
439
|
+
return request;
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// Use with full SDK
|
|
443
|
+
await sdk.TableService.find({
|
|
444
|
+
query: {
|
|
445
|
+
filter: JSON.stringify({ limit: 1 }),
|
|
446
|
+
},
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
assert.ok(interceptorCalled, 'Request interceptor should be called');
|
|
450
|
+
assert.ok(
|
|
451
|
+
requestUrl.includes('/Tables'),
|
|
452
|
+
'Request URL should be captured',
|
|
453
|
+
);
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
test('should allow adding response interceptors', async () => {
|
|
457
|
+
const sdk = configure({
|
|
458
|
+
baseURL: BASE_URL,
|
|
459
|
+
email: TEST_EMAIL,
|
|
460
|
+
password: TEST_PASSWORD,
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
let responseInterceptorCalled = false;
|
|
464
|
+
let responseStatus = 0;
|
|
465
|
+
|
|
466
|
+
sdk.client.interceptors.response.use((response: Response) => {
|
|
467
|
+
responseInterceptorCalled = true;
|
|
468
|
+
responseStatus = response.status;
|
|
469
|
+
return response;
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
await sdk.TableService.find({
|
|
473
|
+
query: {
|
|
474
|
+
filter: JSON.stringify({ limit: 1 }),
|
|
475
|
+
},
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
assert.ok(
|
|
479
|
+
responseInterceptorCalled,
|
|
480
|
+
'Response interceptor should be called',
|
|
481
|
+
);
|
|
482
|
+
assert.strictEqual(responseStatus, 200, 'Response status should be 200');
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
test('should work with bound services (sdk.service)', async () => {
|
|
486
|
+
const sdk = configure({
|
|
487
|
+
baseURL: BASE_URL,
|
|
488
|
+
email: TEST_EMAIL,
|
|
489
|
+
password: TEST_PASSWORD,
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
let interceptorCount = 0;
|
|
493
|
+
|
|
494
|
+
sdk.client.interceptors.request.use((request: Request) => {
|
|
495
|
+
interceptorCount++;
|
|
496
|
+
return request;
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
// Bind service
|
|
500
|
+
const Tables = sdk.service(TableService);
|
|
501
|
+
|
|
502
|
+
// Make request with bound service
|
|
503
|
+
await Tables.find({
|
|
504
|
+
query: {
|
|
505
|
+
filter: JSON.stringify({ limit: 1 }),
|
|
506
|
+
},
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
assert.ok(
|
|
510
|
+
interceptorCount > 0,
|
|
511
|
+
'Interceptor should work with bound services',
|
|
512
|
+
);
|
|
513
|
+
});
|
|
73
514
|
});
|
|
74
515
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
516
|
+
describe('Configuration Validation', () => {
|
|
517
|
+
test('should throw error when both token and credentials provided', () => {
|
|
518
|
+
assert.throws(
|
|
519
|
+
() => {
|
|
520
|
+
configure({
|
|
521
|
+
baseURL: BASE_URL,
|
|
522
|
+
accessToken: 'token',
|
|
523
|
+
email: 'test@test.com',
|
|
524
|
+
password: 'password',
|
|
525
|
+
} as any);
|
|
526
|
+
},
|
|
527
|
+
(error: any) => {
|
|
528
|
+
assert.ok(
|
|
529
|
+
error.message.includes('either accessToken or credentials'),
|
|
530
|
+
'Error message should mention mutual exclusivity',
|
|
531
|
+
);
|
|
532
|
+
return true;
|
|
533
|
+
},
|
|
534
|
+
'Should throw error for both token and credentials',
|
|
535
|
+
);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
test('should throw error when neither token nor credentials provided', () => {
|
|
539
|
+
assert.throws(
|
|
540
|
+
() => {
|
|
541
|
+
configure({
|
|
542
|
+
baseURL: BASE_URL,
|
|
543
|
+
returnType: 'data',
|
|
544
|
+
} as any);
|
|
545
|
+
},
|
|
546
|
+
(error: any) => {
|
|
547
|
+
assert.ok(
|
|
548
|
+
error.message.includes('Either accessToken or credentials'),
|
|
549
|
+
'Error message should mention missing auth',
|
|
550
|
+
);
|
|
551
|
+
return true;
|
|
552
|
+
},
|
|
553
|
+
'Should throw error for missing authentication',
|
|
554
|
+
);
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
test('should throw error when password provided without email or username', () => {
|
|
558
|
+
assert.throws(
|
|
559
|
+
() => {
|
|
560
|
+
configure({
|
|
561
|
+
baseURL: BASE_URL,
|
|
562
|
+
password: 'password',
|
|
563
|
+
} as any);
|
|
564
|
+
},
|
|
565
|
+
(error: any) => {
|
|
566
|
+
assert.ok(error.message, 'Should have error message');
|
|
567
|
+
return true;
|
|
568
|
+
},
|
|
569
|
+
'Should throw error for password without email/username',
|
|
570
|
+
);
|
|
571
|
+
});
|
|
82
572
|
|
|
83
|
-
|
|
573
|
+
test('should throw error when both email and username provided', () => {
|
|
574
|
+
assert.throws(
|
|
575
|
+
() => {
|
|
576
|
+
configure({
|
|
577
|
+
baseURL: BASE_URL,
|
|
578
|
+
email: 'test@test.com',
|
|
579
|
+
username: 'testuser',
|
|
580
|
+
password: 'password',
|
|
581
|
+
} as any);
|
|
582
|
+
},
|
|
583
|
+
(error: any) => {
|
|
584
|
+
assert.ok(
|
|
585
|
+
error.message.includes('either email or username'),
|
|
586
|
+
'Error message should mention mutual exclusivity',
|
|
587
|
+
);
|
|
588
|
+
return true;
|
|
589
|
+
},
|
|
590
|
+
'Should throw error for both email and username',
|
|
591
|
+
);
|
|
592
|
+
});
|
|
593
|
+
});
|
|
594
|
+
});
|