@enbox/dwn-server 0.0.2 → 0.0.3

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 (146) hide show
  1. package/README.md +13 -13
  2. package/dist/esm/src/config.d.ts +2 -6
  3. package/dist/esm/src/config.d.ts.map +1 -1
  4. package/dist/esm/src/config.js +4 -8
  5. package/dist/esm/src/config.js.map +1 -1
  6. package/dist/esm/src/connection/connection-manager.d.ts +9 -9
  7. package/dist/esm/src/connection/connection-manager.d.ts.map +1 -1
  8. package/dist/esm/src/connection/connection-manager.js +5 -3
  9. package/dist/esm/src/connection/connection-manager.js.map +1 -1
  10. package/dist/esm/src/connection/socket-connection.d.ts +18 -17
  11. package/dist/esm/src/connection/socket-connection.d.ts.map +1 -1
  12. package/dist/esm/src/connection/socket-connection.js +26 -35
  13. package/dist/esm/src/connection/socket-connection.js.map +1 -1
  14. package/dist/esm/src/dwn-error.js.map +1 -1
  15. package/dist/esm/src/dwn-server.d.ts +5 -6
  16. package/dist/esm/src/dwn-server.d.ts.map +1 -1
  17. package/dist/esm/src/dwn-server.js +3 -14
  18. package/dist/esm/src/dwn-server.js.map +1 -1
  19. package/dist/esm/src/http-api.d.ts +9 -11
  20. package/dist/esm/src/http-api.d.ts.map +1 -1
  21. package/dist/esm/src/http-api.js +450 -375
  22. package/dist/esm/src/http-api.js.map +1 -1
  23. package/dist/esm/src/json-rpc-handlers/dwn/process-message.d.ts.map +1 -1
  24. package/dist/esm/src/json-rpc-handlers/dwn/process-message.js +3 -3
  25. package/dist/esm/src/json-rpc-handlers/dwn/process-message.js.map +1 -1
  26. package/dist/esm/src/json-rpc-handlers/subscription/close.d.ts.map +1 -1
  27. package/dist/esm/src/json-rpc-handlers/subscription/close.js.map +1 -1
  28. package/dist/esm/src/json-rpc-socket.d.ts +1 -1
  29. package/dist/esm/src/json-rpc-socket.d.ts.map +1 -1
  30. package/dist/esm/src/json-rpc-socket.js +1 -1
  31. package/dist/esm/src/json-rpc-socket.js.map +1 -1
  32. package/dist/esm/src/lib/json-rpc-router.d.ts +3 -4
  33. package/dist/esm/src/lib/json-rpc-router.d.ts.map +1 -1
  34. package/dist/esm/src/lib/json-rpc-router.js.map +1 -1
  35. package/dist/esm/src/lib/json-rpc.d.ts.map +1 -1
  36. package/dist/esm/src/lib/json-rpc.js.map +1 -1
  37. package/dist/esm/src/main.js +0 -0
  38. package/dist/esm/src/metrics.d.ts +1 -1
  39. package/dist/esm/src/metrics.js.map +1 -1
  40. package/dist/esm/src/registration/proof-of-work-manager.d.ts +1 -1
  41. package/dist/esm/src/registration/proof-of-work-manager.d.ts.map +1 -1
  42. package/dist/esm/src/registration/proof-of-work-manager.js +3 -3
  43. package/dist/esm/src/registration/proof-of-work-manager.js.map +1 -1
  44. package/dist/esm/src/registration/registration-manager.d.ts +3 -3
  45. package/dist/esm/src/registration/registration-manager.d.ts.map +1 -1
  46. package/dist/esm/src/registration/registration-manager.js +6 -6
  47. package/dist/esm/src/registration/registration-manager.js.map +1 -1
  48. package/dist/esm/src/registration/registration-store.d.ts +1 -1
  49. package/dist/esm/src/registration/registration-store.d.ts.map +1 -1
  50. package/dist/esm/src/registration/registration-store.js.map +1 -1
  51. package/dist/esm/src/storage.d.ts +2 -2
  52. package/dist/esm/src/storage.d.ts.map +1 -1
  53. package/dist/esm/src/storage.js +5 -4
  54. package/dist/esm/src/storage.js.map +1 -1
  55. package/dist/esm/src/web5-connect/sql-ttl-cache.d.ts.map +1 -1
  56. package/dist/esm/src/web5-connect/sql-ttl-cache.js +3 -2
  57. package/dist/esm/src/web5-connect/sql-ttl-cache.js.map +1 -1
  58. package/dist/esm/src/web5-connect/web5-connect-server.d.ts.map +1 -1
  59. package/dist/esm/src/web5-connect/web5-connect-server.js +2 -2
  60. package/dist/esm/src/web5-connect/web5-connect-server.js.map +1 -1
  61. package/dist/esm/src/ws-api.d.ts +2 -4
  62. package/dist/esm/src/ws-api.d.ts.map +1 -1
  63. package/dist/esm/src/ws-api.js +6 -17
  64. package/dist/esm/src/ws-api.js.map +1 -1
  65. package/dist/esm/tests/common-scenario-validator.d.ts.map +1 -1
  66. package/dist/esm/tests/common-scenario-validator.js +2 -3
  67. package/dist/esm/tests/common-scenario-validator.js.map +1 -1
  68. package/dist/esm/tests/connection/connection-manager.spec.js +11 -9
  69. package/dist/esm/tests/connection/connection-manager.spec.js.map +1 -1
  70. package/dist/esm/tests/connection/socket-connection.spec.js +40 -18
  71. package/dist/esm/tests/connection/socket-connection.spec.js.map +1 -1
  72. package/dist/esm/tests/cors/http-api.browser.js +1 -1
  73. package/dist/esm/tests/cors/http-api.browser.js.map +1 -1
  74. package/dist/esm/tests/dwn-process-message.spec.js +4 -4
  75. package/dist/esm/tests/dwn-process-message.spec.js.map +1 -1
  76. package/dist/esm/tests/dwn-server.spec.js +8 -9
  77. package/dist/esm/tests/dwn-server.spec.js.map +1 -1
  78. package/dist/esm/tests/http-api.spec.js +92 -85
  79. package/dist/esm/tests/http-api.spec.js.map +1 -1
  80. package/dist/esm/tests/json-rpc-socket.spec.js +11 -9
  81. package/dist/esm/tests/json-rpc-socket.spec.js.map +1 -1
  82. package/dist/esm/tests/plugins/data-store-sqlite.d.ts +2 -2
  83. package/dist/esm/tests/plugins/data-store-sqlite.js +2 -2
  84. package/dist/esm/tests/plugins/event-log-sqlite.d.ts +2 -2
  85. package/dist/esm/tests/plugins/event-log-sqlite.js +2 -2
  86. package/dist/esm/tests/plugins/event-stream-in-memory.d.ts +2 -2
  87. package/dist/esm/tests/plugins/event-stream-in-memory.d.ts.map +1 -1
  88. package/dist/esm/tests/plugins/event-stream-in-memory.js +1 -1
  89. package/dist/esm/tests/plugins/event-stream-in-memory.js.map +1 -1
  90. package/dist/esm/tests/plugins/message-store-sqlite.d.ts +2 -2
  91. package/dist/esm/tests/plugins/message-store-sqlite.d.ts.map +1 -1
  92. package/dist/esm/tests/plugins/message-store-sqlite.js +2 -2
  93. package/dist/esm/tests/plugins/message-store-sqlite.js.map +1 -1
  94. package/dist/esm/tests/plugins/resumable-task-store-sqlite.d.ts +2 -2
  95. package/dist/esm/tests/plugins/resumable-task-store-sqlite.d.ts.map +1 -1
  96. package/dist/esm/tests/plugins/resumable-task-store-sqlite.js +2 -2
  97. package/dist/esm/tests/plugins/resumable-task-store-sqlite.js.map +1 -1
  98. package/dist/esm/tests/process-handler.spec.js +6 -6
  99. package/dist/esm/tests/process-handler.spec.js.map +1 -1
  100. package/dist/esm/tests/registration/proof-of-work-manager.spec.js +3 -4
  101. package/dist/esm/tests/registration/proof-of-work-manager.spec.js.map +1 -1
  102. package/dist/esm/tests/rpc-subscribe-close.spec.js +1 -1
  103. package/dist/esm/tests/rpc-subscribe-close.spec.js.map +1 -1
  104. package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.js +11 -10
  105. package/dist/esm/tests/scenarios/dynamic-plugin-loading.spec.js.map +1 -1
  106. package/dist/esm/tests/scenarios/registration.spec.js +16 -12
  107. package/dist/esm/tests/scenarios/registration.spec.js.map +1 -1
  108. package/dist/esm/tests/scenarios/web5-connect.spec.js +12 -8
  109. package/dist/esm/tests/scenarios/web5-connect.spec.js.map +1 -1
  110. package/dist/esm/tests/test-dwn.d.ts.map +1 -1
  111. package/dist/esm/tests/test-dwn.js +9 -15
  112. package/dist/esm/tests/test-dwn.js.map +1 -1
  113. package/dist/esm/tests/utils.d.ts +3 -6
  114. package/dist/esm/tests/utils.d.ts.map +1 -1
  115. package/dist/esm/tests/utils.js +9 -18
  116. package/dist/esm/tests/utils.js.map +1 -1
  117. package/dist/esm/tests/ws-api.spec.js +28 -23
  118. package/dist/esm/tests/ws-api.spec.js.map +1 -1
  119. package/package.json +25 -44
  120. package/src/config.ts +15 -19
  121. package/src/connection/connection-manager.ts +18 -12
  122. package/src/connection/socket-connection.ts +52 -57
  123. package/src/dwn-error.ts +2 -2
  124. package/src/dwn-server.ts +17 -30
  125. package/src/http-api.ts +499 -396
  126. package/src/json-rpc-handlers/dwn/process-message.ts +9 -10
  127. package/src/json-rpc-handlers/subscription/close.ts +4 -4
  128. package/src/json-rpc-socket.ts +3 -2
  129. package/src/lib/json-rpc-router.ts +5 -6
  130. package/src/lib/json-rpc.ts +6 -6
  131. package/src/metrics.ts +7 -7
  132. package/src/process-handlers.ts +5 -5
  133. package/src/registration/proof-of-work-manager.ts +11 -10
  134. package/src/registration/registration-manager.ts +23 -21
  135. package/src/registration/registration-store.ts +8 -7
  136. package/src/storage.ts +15 -13
  137. package/src/web5-connect/sql-ttl-cache.ts +5 -4
  138. package/src/web5-connect/web5-connect-server.ts +9 -8
  139. package/src/ws-api.ts +11 -26
  140. package/dist/cjs/index.js +0 -6811
  141. package/dist/cjs/package.json +0 -1
  142. package/dist/esm/src/lib/http-server-shutdown-handler.d.ts +0 -10
  143. package/dist/esm/src/lib/http-server-shutdown-handler.d.ts.map +0 -1
  144. package/dist/esm/src/lib/http-server-shutdown-handler.js +0 -65
  145. package/dist/esm/src/lib/http-server-shutdown-handler.js.map +0 -1
  146. package/src/lib/http-server-shutdown-handler.ts +0 -79
@@ -1,21 +1,17 @@
1
- // node.js 18 and earlier, needs globalThis.crypto polyfill
2
- import sinon from 'sinon';
3
- import { DataStream, DwnErrorCode, ProtocolsConfigure, RecordsQuery, TestDataGenerator, Time, } from '@enbox/dwn-sdk-js';
1
+ import { Convert } from '@enbox/common';
4
2
  import { expect } from 'chai';
5
- import fetch from 'node-fetch';
6
- import { webcrypto } from 'node:crypto';
7
- import { useFakeTimers } from 'sinon';
8
- import request from 'supertest';
3
+ import log from 'loglevel';
9
4
  import { v4 as uuidv4 } from 'uuid';
5
+ import { webcrypto } from 'node:crypto';
6
+ import { DataStream, DwnErrorCode, ProtocolsConfigure, RecordsQuery, TestDataGenerator, Time, } from '@enbox/dwn-sdk-js';
7
+ import sinon, { useFakeTimers } from 'sinon';
8
+ import CommonScenarioValidator from './common-scenario-validator.js';
10
9
  import { config } from '../src/config.js';
11
- import log from 'loglevel';
10
+ import { getTestDwn } from './test-dwn.js';
12
11
  import { HttpApi } from '../src/http-api.js';
12
+ import { RegistrationManager } from '../src/registration/registration-manager.js';
13
13
  import { createJsonRpcRequest, JsonRpcErrorCodes, } from '../src/lib/json-rpc.js';
14
- import { getTestDwn } from './test-dwn.js';
15
14
  import { createRecordsWriteMessage, getDwnResponse, getFileAsReadStream, } from './utils.js';
16
- import { RegistrationManager } from '../src/registration/registration-manager.js';
17
- import CommonScenarioValidator from './common-scenario-validator.js';
18
- import { Convert } from '@enbox/common';
19
15
  if (!globalThis.crypto) {
20
16
  // @ts-ignore
21
17
  globalThis.crypto = webcrypto;
@@ -26,9 +22,11 @@ describe('http api', function () {
26
22
  let registrationManager;
27
23
  let dwn;
28
24
  let clock;
25
+ let baseUrl;
29
26
  before(async function () {
30
27
  clock = useFakeTimers({ shouldAdvanceTime: true });
31
- // TODO: Remove direct use of default config to avoid changes bleed/pollute between tests - https://github.com/TBD54566975/dwn-server/issues/144
28
+ // TODO: Remove direct use of default config to avoid changes bleed/pollute between tests - https://github.com/enboxorg/enbox/issues/144
29
+ config.packageJsonPath = './package.json'; // default is Docker path; override for local tests
32
30
  config.registrationStoreUrl = 'sqlite://';
33
31
  config.registrationProofOfWorkEnabled = true;
34
32
  config.termsOfServiceFilePath = './tests/fixtures/terms-of-service.txt';
@@ -43,7 +41,8 @@ describe('http api', function () {
43
41
  });
44
42
  beforeEach(async function () {
45
43
  sinon.restore();
46
- await httpApi.start(3000);
44
+ await httpApi.start(0);
45
+ baseUrl = `http://localhost:${httpApi.server.port}`;
47
46
  // generate a new persona for each test to avoid state pollution
48
47
  alice = await TestDataGenerator.generateDidKeyPersona();
49
48
  await registrationManager.recordTenantRegistration({ did: alice.did, termsOfServiceHash: registrationManager.getTermsOfServiceHash() });
@@ -57,19 +56,21 @@ describe('http api', function () {
57
56
  });
58
57
  describe('/ (rpc)', function () {
59
58
  it('responds with a 400 if no dwn-request header is provided', async function () {
60
- const response = await request(httpApi.api).post('/').send();
61
- expect(response.statusCode).to.equal(400);
62
- const body = response.body;
59
+ const response = await fetch(baseUrl, {
60
+ method: 'POST',
61
+ });
62
+ expect(response.status).to.equal(400);
63
+ const body = (await response.json());
63
64
  expect(body.error.code).to.equal(JsonRpcErrorCodes.BadRequest);
64
65
  expect(body.error.message).to.equal('request payload required.');
65
66
  });
66
67
  it('responds with a 400 if parsing dwn request fails', async function () {
67
- const response = await request(httpApi.api)
68
- .post('/')
69
- .set('dwn-request', ';;;;@!#@!$$#!@%')
70
- .send();
71
- expect(response.statusCode).to.equal(400);
72
- const body = response.body;
68
+ const response = await fetch(baseUrl, {
69
+ method: 'POST',
70
+ headers: { 'dwn-request': ';;;;@!#@!$$#!@%' },
71
+ });
72
+ expect(response.status).to.equal(400);
73
+ const body = (await response.json());
73
74
  expect(body.error.code).to.equal(JsonRpcErrorCodes.BadRequest);
74
75
  expect(body.error.message).to.include('JSON');
75
76
  });
@@ -85,7 +86,7 @@ describe('http api', function () {
85
86
  });
86
87
  const dataBytes = await DataStream.toBytes(dataStream);
87
88
  // Attempt an initial RecordsWrite with the invalid message to ensure the DWN returns an error.
88
- const responseInitialWrite = await fetch('http://localhost:3000', {
89
+ const responseInitialWrite = await fetch(baseUrl, {
89
90
  method: 'POST',
90
91
  headers: {
91
92
  'dwn-request': JSON.stringify(dwnRequest),
@@ -105,15 +106,17 @@ describe('http api', function () {
105
106
  // `access-control-expose-headers` returned in each HTTP response. This is necessary to enable applications
106
107
  // that have CORS enabled to read and parse DWeb Messages that are returned as Response headers, particularly
107
108
  // in the case of RecordsRead messages.
108
- // TODO: github.com/TBD54566975/dwn-server/issues/50
109
+ // TODO: github.com/enboxorg/enbox/issues/50
109
110
  // Consider replacing this test with a more robust method of testing, such as writing Playwright tests
110
111
  // that run in a browser to verify that the `dwn-response` header can be read from the `fetch()` response
111
112
  // when CORS mode is enabled.
112
- const response = await request(httpApi.api).post('/').send();
113
+ const response = await fetch(baseUrl, {
114
+ method: 'POST',
115
+ });
113
116
  // Check if the 'access-control-expose-headers' header is present
114
- expect(response.headers).to.have.property('access-control-expose-headers');
117
+ expect(response.headers.has('access-control-expose-headers')).to.be.true;
115
118
  // Check if the 'dwn-response' header is listed in 'access-control-expose-headers'
116
- const exposedHeaders = response.headers['access-control-expose-headers'];
119
+ const exposedHeaders = response.headers.get('access-control-expose-headers');
117
120
  expect(exposedHeaders).to.include('dwn-response');
118
121
  });
119
122
  it('works fine when no request body is provided', async function () {
@@ -128,19 +131,20 @@ describe('http api', function () {
128
131
  message: recordsQuery.toJSON(),
129
132
  target: alice.did,
130
133
  });
131
- const response = await request(httpApi.api)
132
- .post('/')
133
- .set('dwn-request', JSON.stringify(dwnRequest))
134
- .send();
135
- expect(response.statusCode).to.equal(200);
136
- expect(response.body.id).to.equal(requestId);
137
- expect(response.body.error).to.not.exist;
138
- expect(response.body.result.reply.status.code).to.equal(200);
134
+ const response = await fetch(baseUrl, {
135
+ method: 'POST',
136
+ headers: { 'dwn-request': JSON.stringify(dwnRequest) },
137
+ });
138
+ expect(response.status).to.equal(200);
139
+ const body = await response.json();
140
+ expect(body.id).to.equal(requestId);
141
+ expect(body.error).to.not.exist;
142
+ expect(body.result.reply.status.code).to.equal(200);
139
143
  });
140
144
  });
141
145
  describe('P0 Scenarios', function () {
142
146
  it('should be able to read and write a protocol record', async function () {
143
- await CommonScenarioValidator.sanityTestDwnReadWrite(config.baseUrl, alice);
147
+ await CommonScenarioValidator.sanityTestDwnReadWrite(baseUrl, alice);
144
148
  });
145
149
  });
146
150
  describe('RecordsWrite', function () {
@@ -153,7 +157,7 @@ describe('http api', function () {
153
157
  message: initialWrite.toJSON(),
154
158
  target: alice.did,
155
159
  });
156
- const responseInitialWrite = await fetch('http://localhost:3000', {
160
+ const responseInitialWrite = await fetch(baseUrl, {
157
161
  method: 'POST',
158
162
  headers: {
159
163
  'dwn-request': JSON.stringify(dwnRequest),
@@ -176,7 +180,7 @@ describe('http api', function () {
176
180
  message: overWrite.toJSON(),
177
181
  target: alice.did,
178
182
  });
179
- const responseOverwrite = await fetch('http://localhost:3000', {
183
+ const responseOverwrite = await fetch(baseUrl, {
180
184
  method: 'POST',
181
185
  headers: {
182
186
  'dwn-request': JSON.stringify(dwnRequest),
@@ -197,7 +201,7 @@ describe('http api', function () {
197
201
  message: tombstone.toJSON(),
198
202
  target: alice.did,
199
203
  });
200
- const responeTombstone = await fetch('http://localhost:3000', {
204
+ const responeTombstone = await fetch(baseUrl, {
201
205
  method: 'POST',
202
206
  headers: {
203
207
  'dwn-request': JSON.stringify(dwnRequest),
@@ -208,7 +212,7 @@ describe('http api', function () {
208
212
  });
209
213
  describe('health check', function () {
210
214
  it('returns a health check', async function () {
211
- const response = await fetch('http://localhost:3000/health', {
215
+ const response = await fetch(`${baseUrl}/health`, {
212
216
  method: 'GET',
213
217
  });
214
218
  expect(response.status).to.equal(200);
@@ -216,7 +220,7 @@ describe('http api', function () {
216
220
  });
217
221
  describe('default http get response', function () {
218
222
  it('returns returns a default message', async function () {
219
- const response = await fetch('http://localhost:3000/', {
223
+ const response = await fetch(`${baseUrl}/`, {
220
224
  method: 'GET',
221
225
  });
222
226
  expect(response.status).to.equal(200);
@@ -236,7 +240,7 @@ describe('http api', function () {
236
240
  message: recordsWrite.toJSON(),
237
241
  target: alice.did,
238
242
  });
239
- let response = await fetch('http://localhost:3000', {
243
+ let response = await fetch(baseUrl, {
240
244
  method: 'POST',
241
245
  headers: {
242
246
  'dwn-request': JSON.stringify(dwnRequest),
@@ -249,7 +253,7 @@ describe('http api', function () {
249
253
  expect(body.error).to.not.exist;
250
254
  const { reply } = body.result;
251
255
  expect(reply.status.code).to.equal(202);
252
- response = await fetch(`http://localhost:3000/${alice.did}/records/${recordsWrite.message.recordId}`);
256
+ response = await fetch(`${baseUrl}/${alice.did}/records/${recordsWrite.message.recordId}`);
253
257
  const blob = await response.blob();
254
258
  expect(blob.size).to.equal(size);
255
259
  });
@@ -265,7 +269,7 @@ describe('http api', function () {
265
269
  message: recordsWrite.toJSON(),
266
270
  target: alice.did,
267
271
  });
268
- let response = await fetch('http://localhost:3000', {
272
+ let response = await fetch(baseUrl, {
269
273
  method: 'POST',
270
274
  headers: {
271
275
  'dwn-request': JSON.stringify(dwnRequest),
@@ -278,22 +282,22 @@ describe('http api', function () {
278
282
  expect(body.error).to.not.exist;
279
283
  const { reply } = body.result;
280
284
  expect(reply.status.code).to.equal(202);
281
- response = await fetch(`http://localhost:3000/${alice.did}/records/${recordsWrite.message.recordId}`);
285
+ response = await fetch(`${baseUrl}/${alice.did}/records/${recordsWrite.message.recordId}`);
282
286
  expect(response.status).to.equal(404);
283
287
  });
284
288
  it('returns a 404 if record does not exist', async function () {
285
289
  const { recordsWrite } = await createRecordsWriteMessage(alice);
286
- const response = await fetch(`http://localhost:3000/${alice.did}/records/${recordsWrite.message.recordId}`);
290
+ const response = await fetch(`${baseUrl}/${alice.did}/records/${recordsWrite.message.recordId}`);
287
291
  expect(response.status).to.equal(404);
288
292
  });
289
293
  it('returns a 404 for invalid or unauthorized did', async function () {
290
294
  const unauthorized = await TestDataGenerator.generateDidKeyPersona();
291
295
  const { recordsWrite } = await createRecordsWriteMessage(unauthorized);
292
- const response = await fetch(`http://localhost:3000/${unauthorized.did}/records/${recordsWrite.message.recordId}`);
296
+ const response = await fetch(`${baseUrl}/${unauthorized.did}/records/${recordsWrite.message.recordId}`);
293
297
  expect(response.status).to.equal(404);
294
298
  });
295
299
  it('returns a 404 for invalid record id', async function () {
296
- const response = await fetch(`http://localhost:3000/${alice.did}/records/kaka`);
300
+ const response = await fetch(`${baseUrl}/${alice.did}/records/kaka`);
297
301
  expect(response.status).to.equal(404);
298
302
  });
299
303
  });
@@ -311,7 +315,7 @@ describe('http api', function () {
311
315
  message: recordsWrite.toJSON(),
312
316
  target: alice.did,
313
317
  });
314
- let response = await fetch('http://localhost:3000', {
318
+ let response = await fetch(baseUrl, {
315
319
  method: 'POST',
316
320
  headers: {
317
321
  'dwn-request': JSON.stringify(dwnRequest),
@@ -324,7 +328,7 @@ describe('http api', function () {
324
328
  expect(body.error).to.not.exist;
325
329
  const { reply } = body.result;
326
330
  expect(reply.status.code).to.equal(202);
327
- response = await fetch(`http://localhost:3000/${alice.did}/read/records/${recordsWrite.message.recordId}`);
331
+ response = await fetch(`${baseUrl}/${alice.did}/read/records/${recordsWrite.message.recordId}`);
328
332
  const blob = await response.blob();
329
333
  expect(blob.size).to.equal(size);
330
334
  });
@@ -340,7 +344,7 @@ describe('http api', function () {
340
344
  message: recordsWrite.toJSON(),
341
345
  target: alice.did,
342
346
  });
343
- let response = await fetch('http://localhost:3000', {
347
+ let response = await fetch(baseUrl, {
344
348
  method: 'POST',
345
349
  headers: {
346
350
  'dwn-request': JSON.stringify(dwnRequest),
@@ -353,22 +357,22 @@ describe('http api', function () {
353
357
  expect(body.error).to.not.exist;
354
358
  const { reply } = body.result;
355
359
  expect(reply.status.code).to.equal(202);
356
- response = await fetch(`http://localhost:3000/${alice.did}/read/records/${recordsWrite.message.recordId}`);
360
+ response = await fetch(`${baseUrl}/${alice.did}/read/records/${recordsWrite.message.recordId}`);
357
361
  expect(response.status).to.equal(404);
358
362
  });
359
363
  it('returns a 404 if record does not exist', async function () {
360
364
  const { recordsWrite } = await createRecordsWriteMessage(alice);
361
- const response = await fetch(`http://localhost:3000/${alice.did}/read/records/${recordsWrite.message.recordId}`);
365
+ const response = await fetch(`${baseUrl}/${alice.did}/read/records/${recordsWrite.message.recordId}`);
362
366
  expect(response.status).to.equal(404);
363
367
  });
364
368
  it('returns a 404 for invalid or unauthorized did', async function () {
365
369
  const unauthorized = await TestDataGenerator.generateDidKeyPersona();
366
370
  const { recordsWrite } = await createRecordsWriteMessage(unauthorized);
367
- const response = await fetch(`http://localhost:3000/${unauthorized.did}/read/records/${recordsWrite.message.recordId}`);
371
+ const response = await fetch(`${baseUrl}/${unauthorized.did}/read/records/${recordsWrite.message.recordId}`);
368
372
  expect(response.status).to.equal(404);
369
373
  });
370
374
  it('returns a 404 for invalid record id', async function () {
371
- const response = await fetch(`http://localhost:3000/${alice.did}/read/records/kaka`);
375
+ const response = await fetch(`${baseUrl}/${alice.did}/read/records/kaka`);
372
376
  expect(response.status).to.equal(404);
373
377
  });
374
378
  });
@@ -393,7 +397,7 @@ describe('http api', function () {
393
397
  message: protocolConfigure.toJSON(),
394
398
  target: alice.did,
395
399
  });
396
- const response = await fetch('http://localhost:3000', {
400
+ const response = await fetch(baseUrl, {
397
401
  method: 'POST',
398
402
  headers: {
399
403
  'dwn-request': JSON.stringify(dwnRequest),
@@ -402,7 +406,7 @@ describe('http api', function () {
402
406
  expect(response.status).to.equal(200);
403
407
  // Fetch the protocol definition using the HTTP API
404
408
  const base64urlEncodedProtocol = Convert.string(protocolConfigure.message.descriptor.definition.protocol).toBase64Url();
405
- const protocolUrl = `http://localhost:3000/${alice.did}/read/protocols/${base64urlEncodedProtocol}`;
409
+ const protocolUrl = `${baseUrl}/${alice.did}/read/protocols/${base64urlEncodedProtocol}`;
406
410
  const protocolQueryResponse = await fetch(protocolUrl);
407
411
  expect(protocolQueryResponse.status).to.equal(200);
408
412
  // get the JSON response
@@ -429,7 +433,7 @@ describe('http api', function () {
429
433
  message: protocolConfigure.toJSON(),
430
434
  target: alice.did,
431
435
  });
432
- const response = await fetch('http://localhost:3000', {
436
+ const response = await fetch(baseUrl, {
433
437
  method: 'POST',
434
438
  headers: {
435
439
  'dwn-request': JSON.stringify(dwnRequest),
@@ -438,12 +442,12 @@ describe('http api', function () {
438
442
  expect(response.status).to.equal(200);
439
443
  // Fetch the protocol definition using the HTTP API
440
444
  const base64urlEncodedProtocol = Convert.string(protocolConfigure.message.descriptor.definition.protocol).toBase64Url();
441
- const protocolUrl = `http://localhost:3000/${alice.did}/read/protocols/${base64urlEncodedProtocol}`;
445
+ const protocolUrl = `${baseUrl}/${alice.did}/read/protocols/${base64urlEncodedProtocol}`;
442
446
  const protocolQueryResponse = await fetch(protocolUrl);
443
447
  expect(protocolQueryResponse.status).to.equal(404);
444
448
  });
445
449
  it('returns a 400 if protocol is not base64url encoded', async function () {
446
- const protocolUrl = `http://localhost:3000/${alice.did}/read/protocols/invalid-protocol`;
450
+ const protocolUrl = `${baseUrl}/${alice.did}/read/protocols/invalid-protocol`;
447
451
  const protocolQueryResponse = await fetch(protocolUrl);
448
452
  expect(protocolQueryResponse.status).to.equal(400);
449
453
  expect(await protocolQueryResponse.text()).to.equal('Bad Request');
@@ -470,7 +474,7 @@ describe('http api', function () {
470
474
  message: protocolConfigurePublished.toJSON(),
471
475
  target: alice.did,
472
476
  });
473
- const response = await fetch('http://localhost:3000', {
477
+ const response = await fetch(baseUrl, {
474
478
  method: 'POST',
475
479
  headers: {
476
480
  'dwn-request': JSON.stringify(dwnRequest),
@@ -495,7 +499,7 @@ describe('http api', function () {
495
499
  message: protocolConfigureNotPublished.toJSON(),
496
500
  target: alice.did,
497
501
  });
498
- const response2 = await fetch('http://localhost:3000', {
502
+ const response2 = await fetch(baseUrl, {
499
503
  method: 'POST',
500
504
  headers: {
501
505
  'dwn-request': JSON.stringify(dwnRequest2),
@@ -503,7 +507,7 @@ describe('http api', function () {
503
507
  });
504
508
  expect(response2.status).to.equal(200);
505
509
  // now query for a list of protocols
506
- const protocolQueryUrl = `http://localhost:3000/${alice.did}/query/protocols`;
510
+ const protocolQueryUrl = `${baseUrl}/${alice.did}/query/protocols`;
507
511
  const protocolQueryResponse = await fetch(protocolQueryUrl);
508
512
  expect(protocolQueryResponse.status).to.equal(200);
509
513
  // get the JSON response
@@ -534,7 +538,7 @@ describe('http api', function () {
534
538
  message: protocolConfigure.toJSON(),
535
539
  target: alice.did,
536
540
  });
537
- const response = await fetch('http://localhost:3000', {
541
+ const response = await fetch(baseUrl, {
538
542
  method: 'POST',
539
543
  headers: {
540
544
  'dwn-request': JSON.stringify(dwnRequest),
@@ -556,7 +560,7 @@ describe('http api', function () {
556
560
  message: recordsWrite.toJSON(),
557
561
  target: alice.did,
558
562
  });
559
- const recordsWriteResponse = await fetch('http://localhost:3000', {
563
+ const recordsWriteResponse = await fetch(baseUrl, {
560
564
  method: 'POST',
561
565
  headers: {
562
566
  'dwn-request': JSON.stringify(recordsWriteDwnRequest),
@@ -568,7 +572,7 @@ describe('http api', function () {
568
572
  expect(responseJson.result.reply.status.code).to.equal(202);
569
573
  // Fetch the record using the HTTP API
570
574
  const base64urlEncodedProtocol = Convert.string(protocolConfigure.message.descriptor.definition.protocol).toBase64Url();
571
- const protocolUrl = `http://localhost:3000/${alice.did}/read/protocols/${base64urlEncodedProtocol}/foo`;
575
+ const protocolUrl = `${baseUrl}/${alice.did}/read/protocols/${base64urlEncodedProtocol}/foo`;
572
576
  const recordReadResponse = await fetch(protocolUrl);
573
577
  expect(recordReadResponse.status).to.equal(200);
574
578
  // get the data response
@@ -583,7 +587,7 @@ describe('http api', function () {
583
587
  it('removes the trailing slash from the protocol path', async function () {
584
588
  const recordsQueryCreateSpy = sinon.spy(RecordsQuery, 'create');
585
589
  const base64urlEncodedProtocol = Convert.string('http://example.com/protocol').toBase64Url();
586
- const protocolUrl = `http://localhost:3000/${alice.did}/read/protocols/${base64urlEncodedProtocol}/foo/`; // trailing slash
590
+ const protocolUrl = `${baseUrl}/${alice.did}/read/protocols/${base64urlEncodedProtocol}/foo/`; // trailing slash
587
591
  const recordReadResponse = await fetch(protocolUrl);
588
592
  expect(recordReadResponse.status).to.equal(404);
589
593
  expect(recordsQueryCreateSpy.calledOnce).to.be.true;
@@ -610,7 +614,7 @@ describe('http api', function () {
610
614
  message: protocolConfigure.toJSON(),
611
615
  target: alice.did,
612
616
  });
613
- const response = await fetch('http://localhost:3000', {
617
+ const response = await fetch(baseUrl, {
614
618
  method: 'POST',
615
619
  headers: {
616
620
  'dwn-request': JSON.stringify(dwnRequest),
@@ -632,7 +636,7 @@ describe('http api', function () {
632
636
  message: recordsWrite.toJSON(),
633
637
  target: alice.did,
634
638
  });
635
- const recordsWriteResponse = await fetch('http://localhost:3000', {
639
+ const recordsWriteResponse = await fetch(baseUrl, {
636
640
  method: 'POST',
637
641
  headers: {
638
642
  'dwn-request': JSON.stringify(recordsWriteDwnRequest),
@@ -644,20 +648,20 @@ describe('http api', function () {
644
648
  expect(responseJson.result.reply.status.code).to.equal(202);
645
649
  // Fetch the record using the HTTP API
646
650
  const base64urlEncodedProtocol = Convert.string(protocolConfigure.message.descriptor.definition.protocol).toBase64Url();
647
- const protocolUrl = `http://localhost:3000/${alice.did}/read/protocols/${base64urlEncodedProtocol}/foo`;
651
+ const protocolUrl = `${baseUrl}/${alice.did}/read/protocols/${base64urlEncodedProtocol}/foo`;
648
652
  const recordReadResponse = await fetch(protocolUrl);
649
653
  expect(recordReadResponse.status).to.equal(404);
650
654
  });
651
655
  it('returns a 400 if protocol path is not provided', async function () {
652
- // Fetch a protocol record without providing a protocol path
656
+ // Fetch a protocol record without providing a protocol path
653
657
  const base64urlEncodedProtocol = Convert.string('http://example.com/protocol').toBase64Url();
654
- const protocolUrl = `http://localhost:3000/${alice.did}/read/protocols/${base64urlEncodedProtocol}/`; // missing protocol path
658
+ const protocolUrl = `${baseUrl}/${alice.did}/read/protocols/${base64urlEncodedProtocol}/`; // missing protocol path
655
659
  const recordReadResponse = await fetch(protocolUrl);
656
660
  expect(recordReadResponse.status).to.equal(400);
657
661
  expect(await recordReadResponse.text()).to.equal('protocol path is required');
658
662
  });
659
663
  it('returns a 400 error if protocol cannot be base64url encoded', async function () {
660
- const protocolUrl = `http://localhost:3000/${alice.did}/read/protocols/invalid-protocol/foo`;
664
+ const protocolUrl = `${baseUrl}/${alice.did}/read/protocols/invalid-protocol/foo`;
661
665
  const recordReadResponse = await fetch(protocolUrl);
662
666
  expect(recordReadResponse.status).to.equal(400);
663
667
  expect(await recordReadResponse.text()).to.equal('Bad Request');
@@ -677,7 +681,7 @@ describe('http api', function () {
677
681
  message: recordsWrite.toJSON(),
678
682
  target: alice.did,
679
683
  });
680
- const response = await fetch('http://localhost:3000', {
684
+ const response = await fetch(baseUrl, {
681
685
  method: 'POST',
682
686
  headers: {
683
687
  'dwn-request': JSON.stringify(dwnRequest),
@@ -690,11 +694,11 @@ describe('http api', function () {
690
694
  expect(body.error).to.not.exist;
691
695
  const { reply } = body.result;
692
696
  expect(reply.status.code).to.equal(202);
693
- const { entries } = await fetch(`http://localhost:3000/${alice.did}/query?filter.recordId=${recordsWrite.message.recordId}&other.random.param=unused-value`).then(response => response.json());
697
+ const { entries } = await fetch(`${baseUrl}/${alice.did}/query?filter.recordId=${recordsWrite.message.recordId}&other.random.param=unused-value`).then(response => response.json());
694
698
  expect(entries?.length).to.equal(1);
695
699
  });
696
700
  it('should return 400 if user provide invalid query', async function () {
697
- const response = await fetch(`http://localhost:3000/${alice.did}/query?filter=invalid-filter`);
701
+ const response = await fetch(`${baseUrl}/${alice.did}/query?filter=invalid-filter`);
698
702
  expect(response.status).to.equal(400);
699
703
  const responseBody = await response.json();
700
704
  expect(responseBody.code).to.equal(DwnErrorCode.SchemaValidatorAdditionalPropertyNotAllowed);
@@ -702,7 +706,7 @@ describe('http api', function () {
702
706
  });
703
707
  describe('/info', function () {
704
708
  it('verify /info has some of the fields it is supposed to have', async function () {
705
- const resp = await fetch(`http://localhost:3000/info`);
709
+ const resp = await fetch(`${baseUrl}/info`);
706
710
  expect(resp.status).to.equal(200);
707
711
  const info = await resp.json();
708
712
  expect(info['url']).to.equal('http://localhost:3000');
@@ -711,7 +715,7 @@ describe('http api', function () {
711
715
  expect(info['registrationRequirements']).to.include('proof-of-work-sha256-v0');
712
716
  });
713
717
  it('verify /info signals websocket support', async function () {
714
- let resp = await fetch(`http://localhost:3000/info`);
718
+ let resp = await fetch(`${baseUrl}/info`);
715
719
  expect(resp.status).to.equal(200);
716
720
  let info = await resp.json();
717
721
  expect(info['server']).to.equal('@enbox/dwn-server');
@@ -720,8 +724,9 @@ describe('http api', function () {
720
724
  await httpApi.close();
721
725
  config.webSocketSupport = false;
722
726
  httpApi = await HttpApi.create(config, dwn, registrationManager);
723
- await httpApi.start(3000);
724
- resp = await fetch(`http://localhost:3000/info`);
727
+ await httpApi.start(0);
728
+ baseUrl = `http://localhost:${httpApi.server.port}`;
729
+ resp = await fetch(`${baseUrl}/info`);
725
730
  expect(resp.status).to.equal(200);
726
731
  info = await resp.json();
727
732
  expect(info['server']).to.equal('@enbox/dwn-server');
@@ -737,8 +742,9 @@ describe('http api', function () {
737
742
  const packageJsonConfig = config.packageJsonPath;
738
743
  config.packageJsonPath = '/some/invalid/file.json';
739
744
  httpApi = await HttpApi.create(config, dwn, registrationManager);
740
- await httpApi.start(3000);
741
- const resp = await fetch(`http://localhost:3000/info`);
745
+ await httpApi.start(0);
746
+ baseUrl = `http://localhost:${httpApi.server.port}`;
747
+ const resp = await fetch(`${baseUrl}/info`);
742
748
  const info = await resp.json();
743
749
  expect(resp.status).to.equal(200);
744
750
  // check that server name exists in the info object
@@ -758,8 +764,9 @@ describe('http api', function () {
758
764
  const serverName = config.serverName;
759
765
  config.serverName = '@enbox/dwn-server-2';
760
766
  httpApi = await HttpApi.create(config, dwn, registrationManager);
761
- await httpApi.start(3000);
762
- const resp = await fetch(`http://localhost:3000/info`);
767
+ await httpApi.start(0);
768
+ baseUrl = `http://localhost:${httpApi.server.port}`;
769
+ const resp = await fetch(`${baseUrl}/info`);
763
770
  const info = await resp.json();
764
771
  expect(resp.status).to.equal(200);
765
772
  // verify that the custom server name was passed to the info endpoint