@atproto/xrpc-server 0.6.0 → 0.6.1-rc.0
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/package.json +3 -3
- package/tests/auth.test.ts +3 -4
- package/tests/bodies.test.ts +157 -9
- package/tests/errors.test.ts +5 -13
- package/tests/ipld.test.ts +3 -4
- package/tests/parameters.test.ts +3 -4
- package/tests/procedures.test.ts +3 -4
- package/tests/queries.test.ts +3 -4
- package/tests/rate-limiter.test.ts +3 -5
- package/tests/responses.test.ts +3 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/xrpc-server",
|
|
3
|
-
"version": "0.6.0",
|
|
3
|
+
"version": "0.6.1-rc.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "atproto HTTP API (XRPC) server library",
|
|
6
6
|
"keywords": [
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"uint8arrays": "3.0.0",
|
|
25
25
|
"ws": "^8.12.0",
|
|
26
26
|
"zod": "^3.23.8",
|
|
27
|
-
"@atproto/common": "^0.4.1",
|
|
28
27
|
"@atproto/crypto": "^0.4.0",
|
|
29
28
|
"@atproto/lexicon": "^0.4.0",
|
|
30
|
-
"@atproto/
|
|
29
|
+
"@atproto/common": "^0.4.1",
|
|
30
|
+
"@atproto/xrpc": "^0.5.1-rc.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/express": "^4.17.13",
|
package/tests/auth.test.ts
CHANGED
|
@@ -7,7 +7,7 @@ import * as ui8 from 'uint8arrays'
|
|
|
7
7
|
import { MINUTE } from '@atproto/common'
|
|
8
8
|
import { Secp256k1Keypair } from '@atproto/crypto'
|
|
9
9
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
10
|
-
import
|
|
10
|
+
import { XrpcClient, XRPCError } from '@atproto/xrpc'
|
|
11
11
|
import * as xrpcServer from '../src'
|
|
12
12
|
import {
|
|
13
13
|
createServer,
|
|
@@ -62,13 +62,12 @@ describe('Auth', () => {
|
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
})
|
|
65
|
-
xrpc.addLexicons(LEXICONS)
|
|
66
65
|
|
|
67
|
-
let client:
|
|
66
|
+
let client: XrpcClient
|
|
68
67
|
beforeAll(async () => {
|
|
69
68
|
const port = await getPort()
|
|
70
69
|
s = await createServer(port, server)
|
|
71
|
-
client =
|
|
70
|
+
client = new XrpcClient(`http://localhost:${port}`, LEXICONS)
|
|
72
71
|
})
|
|
73
72
|
|
|
74
73
|
afterAll(async () => {
|
package/tests/bodies.test.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { Readable } from 'stream'
|
|
|
3
3
|
import { gzipSync } from 'zlib'
|
|
4
4
|
import getPort from 'get-port'
|
|
5
5
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
6
|
+
import { XrpcClient } from '@atproto/xrpc'
|
|
7
|
+
import { cidForCbor } from '@atproto/common'
|
|
8
8
|
import { randomBytes } from '@atproto/crypto'
|
|
9
9
|
import { createServer, closeServer } from './_util'
|
|
10
10
|
import * as xrpcServer from '../src'
|
|
@@ -131,15 +131,14 @@ describe('Bodies', () => {
|
|
|
131
131
|
}
|
|
132
132
|
},
|
|
133
133
|
)
|
|
134
|
-
xrpc.addLexicons(LEXICONS)
|
|
135
134
|
|
|
136
|
-
let client:
|
|
135
|
+
let client: XrpcClient
|
|
137
136
|
let url: string
|
|
138
137
|
beforeAll(async () => {
|
|
139
138
|
const port = await getPort()
|
|
140
139
|
s = await createServer(port, server)
|
|
141
140
|
url = `http://localhost:${port}`
|
|
142
|
-
client =
|
|
141
|
+
client = new XrpcClient(url, LEXICONS)
|
|
143
142
|
})
|
|
144
143
|
afterAll(async () => {
|
|
145
144
|
await closeServer(s)
|
|
@@ -174,7 +173,65 @@ describe('Bodies', () => {
|
|
|
174
173
|
{ foo: 'hello', bar: 123 },
|
|
175
174
|
{ encoding: 'image/jpeg' },
|
|
176
175
|
),
|
|
176
|
+
).rejects.toThrow(`Unable to encode object as image/jpeg data`)
|
|
177
|
+
await expect(
|
|
178
|
+
client.call(
|
|
179
|
+
'io.example.validationTest',
|
|
180
|
+
{},
|
|
181
|
+
// Does not need to be a valid jpeg
|
|
182
|
+
new Blob([randomBytes(123)], { type: 'image/jpeg' }),
|
|
183
|
+
),
|
|
177
184
|
).rejects.toThrow(`Wrong request encoding (Content-Type): image/jpeg`)
|
|
185
|
+
await expect(
|
|
186
|
+
client.call(
|
|
187
|
+
'io.example.validationTest',
|
|
188
|
+
{},
|
|
189
|
+
(() => {
|
|
190
|
+
const formData = new FormData()
|
|
191
|
+
formData.append('foo', 'bar')
|
|
192
|
+
return formData
|
|
193
|
+
})(),
|
|
194
|
+
),
|
|
195
|
+
).rejects.toThrow(
|
|
196
|
+
`Wrong request encoding (Content-Type): multipart/form-data`,
|
|
197
|
+
)
|
|
198
|
+
await expect(
|
|
199
|
+
client.call(
|
|
200
|
+
'io.example.validationTest',
|
|
201
|
+
{},
|
|
202
|
+
new URLSearchParams([['foo', 'bar']]),
|
|
203
|
+
),
|
|
204
|
+
).rejects.toThrow(
|
|
205
|
+
`Wrong request encoding (Content-Type): application/x-www-form-urlencoded`,
|
|
206
|
+
)
|
|
207
|
+
await expect(
|
|
208
|
+
client.call(
|
|
209
|
+
'io.example.validationTest',
|
|
210
|
+
{},
|
|
211
|
+
new Blob([new Uint8Array([1])]),
|
|
212
|
+
),
|
|
213
|
+
).rejects.toThrow(
|
|
214
|
+
`Wrong request encoding (Content-Type): application/octet-stream`,
|
|
215
|
+
)
|
|
216
|
+
await expect(
|
|
217
|
+
client.call(
|
|
218
|
+
'io.example.validationTest',
|
|
219
|
+
{},
|
|
220
|
+
new ReadableStream({
|
|
221
|
+
pull(ctrl) {
|
|
222
|
+
ctrl.enqueue(new Uint8Array([1]))
|
|
223
|
+
ctrl.close()
|
|
224
|
+
},
|
|
225
|
+
}),
|
|
226
|
+
),
|
|
227
|
+
).rejects.toThrow(
|
|
228
|
+
`Wrong request encoding (Content-Type): application/octet-stream`,
|
|
229
|
+
)
|
|
230
|
+
await expect(
|
|
231
|
+
client.call('io.example.validationTest', {}, new Uint8Array([1])),
|
|
232
|
+
).rejects.toThrow(
|
|
233
|
+
`Wrong request encoding (Content-Type): application/octet-stream`,
|
|
234
|
+
)
|
|
178
235
|
|
|
179
236
|
// 500 responses don't include details, so we nab details from the logger.
|
|
180
237
|
let error: string | undefined
|
|
@@ -201,6 +258,86 @@ describe('Bodies', () => {
|
|
|
201
258
|
expect(bytesResponse.data.cid).toEqual(expectedCid.toString())
|
|
202
259
|
})
|
|
203
260
|
|
|
261
|
+
it('supports empty payload on procedues with encoding', async () => {
|
|
262
|
+
const bytes = new Uint8Array(0)
|
|
263
|
+
const expectedCid = await cidForCbor(bytes)
|
|
264
|
+
const bytesResponse = await client.call('io.example.blobTest', {}, bytes)
|
|
265
|
+
expect(bytesResponse.data.cid).toEqual(expectedCid.toString())
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
it('supports upload of empty txt file', async () => {
|
|
269
|
+
const txtFile = new Blob([], { type: 'text/plain' })
|
|
270
|
+
const expectedCid = await cidForCbor(await txtFile.arrayBuffer())
|
|
271
|
+
const fileResponse = await client.call('io.example.blobTest', {}, txtFile)
|
|
272
|
+
expect(fileResponse.data.cid).toEqual(expectedCid.toString())
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
// This does not work because the xrpc-server will add a json middleware
|
|
276
|
+
// regardless of the "input" definition. This is probably a behavior that
|
|
277
|
+
// should be fixed in the xrpc-server.
|
|
278
|
+
it.skip('supports upload of json data', async () => {
|
|
279
|
+
const jsonFile = new Blob([Buffer.from(`{"foo":"bar","baz":[3, null]}`)], {
|
|
280
|
+
type: 'application/json',
|
|
281
|
+
})
|
|
282
|
+
const expectedCid = await cidForCbor(await jsonFile.arrayBuffer())
|
|
283
|
+
const fileResponse = await client.call('io.example.blobTest', {}, jsonFile)
|
|
284
|
+
expect(fileResponse.data.cid).toEqual(expectedCid.toString())
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
it('supports ArrayBufferView', async () => {
|
|
288
|
+
const bytes = randomBytes(1024)
|
|
289
|
+
const expectedCid = await cidForCbor(bytes)
|
|
290
|
+
|
|
291
|
+
const bufferResponse = await client.call(
|
|
292
|
+
'io.example.blobTest',
|
|
293
|
+
{},
|
|
294
|
+
Buffer.from(bytes),
|
|
295
|
+
)
|
|
296
|
+
expect(bufferResponse.data.cid).toEqual(expectedCid.toString())
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
it('supports Blob', async () => {
|
|
300
|
+
const bytes = randomBytes(1024)
|
|
301
|
+
const expectedCid = await cidForCbor(bytes)
|
|
302
|
+
|
|
303
|
+
const blobResponse = await client.call(
|
|
304
|
+
'io.example.blobTest',
|
|
305
|
+
{},
|
|
306
|
+
new Blob([bytes], { type: 'application/octet-stream' }),
|
|
307
|
+
)
|
|
308
|
+
expect(blobResponse.data.cid).toEqual(expectedCid.toString())
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
it('supports Blob without explicit type', async () => {
|
|
312
|
+
const bytes = randomBytes(1024)
|
|
313
|
+
const expectedCid = await cidForCbor(bytes)
|
|
314
|
+
|
|
315
|
+
const blobResponse = await client.call(
|
|
316
|
+
'io.example.blobTest',
|
|
317
|
+
{},
|
|
318
|
+
new Blob([bytes]),
|
|
319
|
+
)
|
|
320
|
+
expect(blobResponse.data.cid).toEqual(expectedCid.toString())
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
it('supports ReadableStream', async () => {
|
|
324
|
+
const bytes = randomBytes(1024)
|
|
325
|
+
const expectedCid = await cidForCbor(bytes)
|
|
326
|
+
|
|
327
|
+
const streamResponse = await client.call(
|
|
328
|
+
'io.example.blobTest',
|
|
329
|
+
{},
|
|
330
|
+
// ReadableStream.from not available in node < 20
|
|
331
|
+
new ReadableStream({
|
|
332
|
+
pull(ctrl) {
|
|
333
|
+
ctrl.enqueue(bytes)
|
|
334
|
+
ctrl.close()
|
|
335
|
+
},
|
|
336
|
+
}),
|
|
337
|
+
)
|
|
338
|
+
expect(streamResponse.data.cid).toEqual(expectedCid.toString())
|
|
339
|
+
})
|
|
340
|
+
|
|
204
341
|
it('supports blobs and compression', async () => {
|
|
205
342
|
const bytes = randomBytes(1024)
|
|
206
343
|
const expectedCid = await cidForCbor(bytes)
|
|
@@ -230,10 +367,11 @@ describe('Bodies', () => {
|
|
|
230
367
|
})
|
|
231
368
|
|
|
232
369
|
it('supports empty payload', async () => {
|
|
233
|
-
const
|
|
370
|
+
const bytes = new Uint8Array(0)
|
|
371
|
+
const expectedCid = await cidForCbor(bytes)
|
|
234
372
|
|
|
235
373
|
// Using "undefined" as body to avoid encoding as lexicon { $bytes: "<base64>" }
|
|
236
|
-
const result = await client.call('io.example.blobTest', {},
|
|
374
|
+
const result = await client.call('io.example.blobTest', {}, bytes, {
|
|
237
375
|
encoding: 'text/plain',
|
|
238
376
|
})
|
|
239
377
|
|
|
@@ -264,7 +402,7 @@ describe('Bodies', () => {
|
|
|
264
402
|
await client.call(
|
|
265
403
|
'io.example.blobTest',
|
|
266
404
|
{},
|
|
267
|
-
|
|
405
|
+
bytesToReadableStream(bytes.slice(0, BLOB_LIMIT)),
|
|
268
406
|
{
|
|
269
407
|
encoding: 'application/octet-stream',
|
|
270
408
|
},
|
|
@@ -274,7 +412,7 @@ describe('Bodies', () => {
|
|
|
274
412
|
const promise = client.call(
|
|
275
413
|
'io.example.blobTest',
|
|
276
414
|
{},
|
|
277
|
-
|
|
415
|
+
bytesToReadableStream(bytes),
|
|
278
416
|
{
|
|
279
417
|
encoding: 'application/octet-stream',
|
|
280
418
|
},
|
|
@@ -310,3 +448,13 @@ describe('Bodies', () => {
|
|
|
310
448
|
})
|
|
311
449
|
})
|
|
312
450
|
})
|
|
451
|
+
|
|
452
|
+
const bytesToReadableStream = (bytes: Uint8Array): ReadableStream => {
|
|
453
|
+
// not using ReadableStream.from(), which lacks support in some contexts including nodejs v18.
|
|
454
|
+
return new ReadableStream({
|
|
455
|
+
pull(ctrl) {
|
|
456
|
+
ctrl.enqueue(bytes)
|
|
457
|
+
ctrl.close()
|
|
458
|
+
},
|
|
459
|
+
})
|
|
460
|
+
}
|
package/tests/errors.test.ts
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import * as http from 'http'
|
|
2
2
|
import getPort from 'get-port'
|
|
3
3
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
4
|
+
import { XRPCError, XRPCInvalidResponseError, XrpcClient } from '@atproto/xrpc'
|
|
4
5
|
import { createServer, closeServer } from './_util'
|
|
5
6
|
import * as xrpcServer from '../src'
|
|
6
|
-
import xrpc, {
|
|
7
|
-
Client,
|
|
8
|
-
ServiceClient,
|
|
9
|
-
XRPCError,
|
|
10
|
-
XRPCInvalidResponseError,
|
|
11
|
-
} from '@atproto/xrpc'
|
|
12
7
|
|
|
13
8
|
const LEXICONS: LexiconDoc[] = [
|
|
14
9
|
{
|
|
@@ -130,17 +125,14 @@ describe('Errors', () => {
|
|
|
130
125
|
server.method('io.example.procedure', () => {
|
|
131
126
|
return undefined
|
|
132
127
|
})
|
|
133
|
-
xrpc.addLexicons(LEXICONS)
|
|
134
|
-
const badXrpc = new Client()
|
|
135
|
-
badXrpc.addLexicons(MISMATCHED_LEXICONS)
|
|
136
128
|
|
|
137
|
-
let client:
|
|
138
|
-
let badClient:
|
|
129
|
+
let client: XrpcClient
|
|
130
|
+
let badClient: XrpcClient
|
|
139
131
|
beforeAll(async () => {
|
|
140
132
|
const port = await getPort()
|
|
141
133
|
s = await createServer(port, server)
|
|
142
|
-
client =
|
|
143
|
-
badClient =
|
|
134
|
+
client = new XrpcClient(`http://localhost:${port}`, LEXICONS)
|
|
135
|
+
badClient = new XrpcClient(`http://localhost:${port}`, MISMATCHED_LEXICONS)
|
|
144
136
|
})
|
|
145
137
|
afterAll(async () => {
|
|
146
138
|
await closeServer(s)
|
package/tests/ipld.test.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as http from 'http'
|
|
2
2
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
3
|
-
import
|
|
3
|
+
import { XrpcClient } from '@atproto/xrpc'
|
|
4
4
|
import { CID } from 'multiformats/cid'
|
|
5
5
|
import getPort from 'get-port'
|
|
6
6
|
import { createServer, closeServer } from './_util'
|
|
@@ -63,13 +63,12 @@ describe('Ipld vals', () => {
|
|
|
63
63
|
return { encoding: 'application/json', body: ctx.input?.body }
|
|
64
64
|
},
|
|
65
65
|
)
|
|
66
|
-
xrpc.addLexicons(LEXICONS)
|
|
67
66
|
|
|
68
|
-
let client:
|
|
67
|
+
let client: XrpcClient
|
|
69
68
|
beforeAll(async () => {
|
|
70
69
|
const port = await getPort()
|
|
71
70
|
s = await createServer(port, server)
|
|
72
|
-
client =
|
|
71
|
+
client = new XrpcClient(`http://localhost:${port}`, LEXICONS)
|
|
73
72
|
})
|
|
74
73
|
afterAll(async () => {
|
|
75
74
|
await closeServer(s)
|
package/tests/parameters.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as http from 'http'
|
|
2
2
|
import getPort from 'get-port'
|
|
3
3
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
4
|
-
import
|
|
4
|
+
import { XrpcClient } from '@atproto/xrpc'
|
|
5
5
|
import { createServer, closeServer } from './_util'
|
|
6
6
|
import * as xrpcServer from '../src'
|
|
7
7
|
|
|
@@ -41,13 +41,12 @@ describe('Parameters', () => {
|
|
|
41
41
|
body: ctx.params,
|
|
42
42
|
}),
|
|
43
43
|
)
|
|
44
|
-
xrpc.addLexicons(LEXICONS)
|
|
45
44
|
|
|
46
|
-
let client:
|
|
45
|
+
let client: XrpcClient
|
|
47
46
|
beforeAll(async () => {
|
|
48
47
|
const port = await getPort()
|
|
49
48
|
s = await createServer(port, server)
|
|
50
|
-
client =
|
|
49
|
+
client = new XrpcClient(`http://localhost:${port}`, LEXICONS)
|
|
51
50
|
})
|
|
52
51
|
afterAll(async () => {
|
|
53
52
|
await closeServer(s)
|
package/tests/procedures.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as http from 'http'
|
|
2
2
|
import { Readable } from 'stream'
|
|
3
3
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
4
|
-
import
|
|
4
|
+
import { XrpcClient } from '@atproto/xrpc'
|
|
5
5
|
import getPort from 'get-port'
|
|
6
6
|
import { createServer, closeServer } from './_util'
|
|
7
7
|
import * as xrpcServer from '../src'
|
|
@@ -121,13 +121,12 @@ describe('Procedures', () => {
|
|
|
121
121
|
}
|
|
122
122
|
},
|
|
123
123
|
)
|
|
124
|
-
xrpc.addLexicons(LEXICONS)
|
|
125
124
|
|
|
126
|
-
let client:
|
|
125
|
+
let client: XrpcClient
|
|
127
126
|
beforeAll(async () => {
|
|
128
127
|
const port = await getPort()
|
|
129
128
|
s = await createServer(port, server)
|
|
130
|
-
client =
|
|
129
|
+
client = new XrpcClient(`http://localhost:${port}`, LEXICONS)
|
|
131
130
|
})
|
|
132
131
|
afterAll(async () => {
|
|
133
132
|
await closeServer(s)
|
package/tests/queries.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as http from 'http'
|
|
2
2
|
import getPort from 'get-port'
|
|
3
3
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
4
|
-
import
|
|
4
|
+
import { XrpcClient } from '@atproto/xrpc'
|
|
5
5
|
import { createServer, closeServer } from './_util'
|
|
6
6
|
import * as xrpcServer from '../src'
|
|
7
7
|
|
|
@@ -89,13 +89,12 @@ describe('Queries', () => {
|
|
|
89
89
|
}
|
|
90
90
|
},
|
|
91
91
|
)
|
|
92
|
-
xrpc.addLexicons(LEXICONS)
|
|
93
92
|
|
|
94
|
-
let client:
|
|
93
|
+
let client: XrpcClient
|
|
95
94
|
beforeAll(async () => {
|
|
96
95
|
const port = await getPort()
|
|
97
96
|
s = await createServer(port, server)
|
|
98
|
-
client =
|
|
97
|
+
client = new XrpcClient(`http://localhost:${port}`, LEXICONS)
|
|
99
98
|
})
|
|
100
99
|
afterAll(async () => {
|
|
101
100
|
await closeServer(s)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as http from 'http'
|
|
2
2
|
import getPort from 'get-port'
|
|
3
3
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
4
|
-
import
|
|
4
|
+
import { XrpcClient } from '@atproto/xrpc'
|
|
5
5
|
import { createServer, closeServer } from './_util'
|
|
6
6
|
import * as xrpcServer from '../src'
|
|
7
7
|
import { RateLimiter } from '../src'
|
|
@@ -190,13 +190,11 @@ describe('Parameters', () => {
|
|
|
190
190
|
}),
|
|
191
191
|
})
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
let client: ServiceClient
|
|
193
|
+
let client: XrpcClient
|
|
196
194
|
beforeAll(async () => {
|
|
197
195
|
const port = await getPort()
|
|
198
196
|
s = await createServer(port, server)
|
|
199
|
-
client =
|
|
197
|
+
client = new XrpcClient(`http://localhost:${port}`, LEXICONS)
|
|
200
198
|
})
|
|
201
199
|
afterAll(async () => {
|
|
202
200
|
await closeServer(s)
|
package/tests/responses.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as http from 'http'
|
|
2
2
|
import getPort from 'get-port'
|
|
3
3
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
4
|
-
import
|
|
4
|
+
import { XrpcClient } from '@atproto/xrpc'
|
|
5
5
|
import { byteIterableToStream } from '@atproto/common'
|
|
6
6
|
import { createServer, closeServer } from './_util'
|
|
7
7
|
import * as xrpcServer from '../src'
|
|
@@ -47,15 +47,12 @@ describe('Responses', () => {
|
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
)
|
|
50
|
-
xrpc.addLexicons(LEXICONS)
|
|
51
50
|
|
|
52
|
-
let client:
|
|
53
|
-
let url: string
|
|
51
|
+
let client: XrpcClient
|
|
54
52
|
beforeAll(async () => {
|
|
55
53
|
const port = await getPort()
|
|
56
54
|
s = await createServer(port, server)
|
|
57
|
-
|
|
58
|
-
client = xrpc.service(url)
|
|
55
|
+
client = new XrpcClient(`http://localhost:${port}`, LEXICONS)
|
|
59
56
|
})
|
|
60
57
|
afterAll(async () => {
|
|
61
58
|
await closeServer(s)
|