@nymphjs/server 1.0.0-beta.12 → 1.0.0-beta.120

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/src/index.test.ts CHANGED
@@ -1,14 +1,16 @@
1
1
  import express from 'express';
2
2
  import SQLite3Driver from '@nymphjs/driver-sqlite3';
3
3
  import { Nymph as NymphServer } from '@nymphjs/nymph';
4
- import { Nymph } from '@nymphjs/client-node';
5
- import { Entity } from '@nymphjs/client';
4
+ import { Nymph, Entity, HttpError } from '@nymphjs/client';
6
5
 
7
- import createServer from './index';
6
+ import createServer from './index.js';
8
7
  import {
9
8
  EmployeeModel as EmployeeModelClass,
10
9
  Employee as EmployeeClass,
11
- } from './testArtifacts';
10
+ RestrictedModel as RestrictedModelClass,
11
+ Restricted as RestrictedClass,
12
+ EmployeeData,
13
+ } from './testArtifacts.js';
12
14
 
13
15
  const sqliteConfig = {
14
16
  filename: ':memory:',
@@ -16,15 +18,18 @@ const sqliteConfig = {
16
18
 
17
19
  const nymphServer = new NymphServer({}, new SQLite3Driver(sqliteConfig));
18
20
  const EmployeeModel = nymphServer.addEntityClass(EmployeeModelClass);
21
+ const RestrictedModel = nymphServer.addEntityClass(RestrictedModelClass);
19
22
 
20
23
  const app = express();
21
24
  app.use('/test', createServer(nymphServer));
22
25
  const server = app.listen(5080);
23
26
 
27
+ const REST_URL = 'http://localhost:5080/test/';
24
28
  const nymph = new Nymph({
25
- restUrl: 'http://localhost:5080/test/',
29
+ restUrl: REST_URL,
26
30
  });
27
31
  const Employee = nymph.addEntityClass(EmployeeClass);
32
+ const Restricted = nymph.addEntityClass(RestrictedClass);
28
33
 
29
34
  describe('Nymph REST Server and Client', () => {
30
35
  async function createJane() {
@@ -129,7 +134,7 @@ describe('Nymph REST Server and Client', () => {
129
134
  {
130
135
  type: '&',
131
136
  ref: ['subordinates', jane],
132
- }
137
+ },
133
138
  );
134
139
 
135
140
  expect(checkSteve?.guid).toEqual(steve.guid);
@@ -142,7 +147,7 @@ describe('Nymph REST Server and Client', () => {
142
147
  'subordinates',
143
148
  [{ class: Employee }, { type: '&', guid: jane.guid }],
144
149
  ],
145
- }
150
+ },
146
151
  );
147
152
 
148
153
  expect(checkSteveQref?.guid).toEqual(steve.guid);
@@ -156,7 +161,7 @@ describe('Nymph REST Server and Client', () => {
156
161
  expect(entity.$hasTag('test', 'test2')).toEqual(true);
157
162
  entity.$addTag('test', 'test3', 'test4', 'test5', 'test6');
158
163
  expect(entity.$hasTag('test', 'test3', 'test4', 'test5', 'test6')).toEqual(
159
- true
164
+ true,
160
165
  );
161
166
  entity.$removeTag('test2');
162
167
  expect(!entity.$hasTag('test2')).toEqual(true);
@@ -178,10 +183,10 @@ describe('Nymph REST Server and Client', () => {
178
183
  'nymph_entity_reference',
179
184
  jane.guid,
180
185
  'Employee',
181
- ]);
182
- await entity.$ready();
186
+ ]) as EmployeeClass & EmployeeData;
187
+ await entity.$wake();
183
188
 
184
- expect(jane?.name).toEqual('Jane Doe');
189
+ expect(entity?.name).toEqual('Jane Doe');
185
190
  });
186
191
 
187
192
  it('change an entity', async () => {
@@ -232,13 +237,51 @@ describe('Nymph REST Server and Client', () => {
232
237
  {
233
238
  type: '&',
234
239
  equal: ['name', 'Jane Doe'],
235
- }
240
+ },
236
241
  );
237
242
 
238
243
  expect(jane).not.toBeNull();
239
244
  expect(jane?.guid).not.toBeNull();
240
245
  });
241
246
 
247
+ it('try to get a non-existent entity', async () => {
248
+ let error = { status: 200 };
249
+ try {
250
+ await nymph.getEntity(
251
+ {
252
+ class: Employee,
253
+ },
254
+ {
255
+ type: '&',
256
+ equal: ['name', 'Non Existent'],
257
+ },
258
+ );
259
+ } catch (e: any) {
260
+ error = e;
261
+ }
262
+ expect(error.status).toEqual(404);
263
+ });
264
+
265
+ it('try to get a non-existent entity without error', async () => {
266
+ const nymph = new Nymph({
267
+ restUrl: REST_URL,
268
+ returnNullOnNotFound: true,
269
+ });
270
+ const Employee = nymph.addEntityClass(EmployeeClass);
271
+
272
+ const nonexistent = await nymph.getEntity(
273
+ {
274
+ class: Employee,
275
+ },
276
+ {
277
+ type: '&',
278
+ equal: ['name', 'Non Existent'],
279
+ },
280
+ );
281
+
282
+ expect(nonexistent).toBeNull();
283
+ });
284
+
242
285
  it('get entities', async () => {
243
286
  for (let i = 0; i < 4; i++) {
244
287
  await createJane();
@@ -252,7 +295,7 @@ describe('Nymph REST Server and Client', () => {
252
295
  {
253
296
  type: '&',
254
297
  tag: ['employee'],
255
- }
298
+ },
256
299
  );
257
300
 
258
301
  expect(entities.length).toEqual(4);
@@ -278,13 +321,13 @@ describe('Nymph REST Server and Client', () => {
278
321
 
279
322
  const resultSelectors = await nymph.getEntities(
280
323
  { class: Employee },
281
- { type: '&', equal: ['name', 'Jane Doe'] }
324
+ { type: '&', equal: ['name', 'Jane Doe'] },
282
325
  );
283
326
 
284
327
  // Testing count return with selectors...
285
328
  const resultSelectorsCount = await nymph.getEntities(
286
329
  { class: Employee, return: 'count' },
287
- { type: '&', equal: ['name', 'Jane Doe'] }
330
+ { type: '&', equal: ['name', 'Jane Doe'] },
288
331
  );
289
332
  expect(resultSelectorsCount).toBeGreaterThanOrEqual(1);
290
333
  expect(resultSelectorsCount).toEqual(resultSelectors.length);
@@ -307,7 +350,7 @@ describe('Nymph REST Server and Client', () => {
307
350
  // Testing empty count...
308
351
  const resultSelectorsEmpty = await nymph.getEntities(
309
352
  { class: Employee, return: 'count' },
310
- { type: '&', tag: 'pickle' }
353
+ { type: '&', tag: 'pickle' },
311
354
  );
312
355
  expect(resultSelectorsEmpty).toEqual(0);
313
356
  });
@@ -326,7 +369,7 @@ describe('Nymph REST Server and Client', () => {
326
369
  {
327
370
  type: '&',
328
371
  tag: 'employee',
329
- }
372
+ },
330
373
  );
331
374
 
332
375
  expect(entities.length).toEqual(4);
@@ -352,7 +395,7 @@ describe('Nymph REST Server and Client', () => {
352
395
  {
353
396
  type: '&',
354
397
  like: ['name', '%Jane%'],
355
- }
398
+ },
356
399
  );
357
400
 
358
401
  expect(entities.length).toEqual(4);
@@ -378,7 +421,7 @@ describe('Nymph REST Server and Client', () => {
378
421
  type: '|',
379
422
  like: ['name', '%Jane%'],
380
423
  },
381
- }
424
+ },
382
425
  );
383
426
 
384
427
  expect(entities.length).toEqual(4);
@@ -413,7 +456,7 @@ describe('Nymph REST Server and Client', () => {
413
456
  },
414
457
  ],
415
458
  },
416
- }
459
+ },
417
460
  );
418
461
 
419
462
  expect(entities.length).toEqual(4);
@@ -438,7 +481,7 @@ describe('Nymph REST Server and Client', () => {
438
481
  {
439
482
  type: '&',
440
483
  guid,
441
- }
484
+ },
442
485
  );
443
486
 
444
487
  expect(check.length).toEqual(0);
@@ -461,7 +504,7 @@ describe('Nymph REST Server and Client', () => {
461
504
  {
462
505
  type: '|',
463
506
  guid: guids,
464
- }
507
+ },
465
508
  );
466
509
 
467
510
  expect(check.length).toEqual(0);
@@ -478,7 +521,7 @@ describe('Nymph REST Server and Client', () => {
478
521
  error = e;
479
522
  }
480
523
  expect(error.message).toEqual(
481
- "Can't use Entity class directly from the front end."
524
+ "Can't use Entity class directly from the front end.",
482
525
  );
483
526
  });
484
527
 
@@ -503,6 +546,25 @@ describe('Nymph REST Server and Client', () => {
503
546
  expect(error.error.name).toEqual('BadFunctionCallError');
504
547
  });
505
548
 
549
+ it('handle server side static iterator error', async () => {
550
+ let error: any = { status: 0, error: { name: '' } };
551
+ const data = await Employee.throwErrorStaticIterable();
552
+
553
+ let count = 0;
554
+ for await (let value of data) {
555
+ count++;
556
+ if (value instanceof Error) {
557
+ error = value;
558
+ } else {
559
+ expect(value).toEqual(count);
560
+ }
561
+ }
562
+
563
+ expect(count).toEqual(2);
564
+ expect(error.status).toEqual(500);
565
+ expect(error.error.name).toEqual('BadFunctionCallError');
566
+ });
567
+
506
568
  it('handle server side error', async () => {
507
569
  const jane = await createJane();
508
570
 
@@ -549,6 +611,28 @@ describe('Nymph REST Server and Client', () => {
549
611
  expect(data).toEqual(10);
550
612
  });
551
613
 
614
+ it('call a server side static iterator method', async () => {
615
+ const data = await Employee.testStaticIterable(5);
616
+
617
+ let count = 0;
618
+ for await (let value of data) {
619
+ count++;
620
+ expect(value).toEqual(5 + count);
621
+ }
622
+
623
+ expect(count).toEqual(3);
624
+ });
625
+
626
+ it('aborts a server side static iterator method', async () => {
627
+ const data = await Employee.testStaticIterableAbort();
628
+ data.abortController.abort();
629
+
630
+ // Wait 1 second to ensure server receives abort signal.
631
+ await new Promise((resolve) => setTimeout(resolve, 1000));
632
+
633
+ expect(true).toBeTruthy();
634
+ });
635
+
552
636
  it('call a stateless server side method', async () => {
553
637
  const jane = await createJane();
554
638
 
@@ -577,7 +661,7 @@ describe('Nymph REST Server and Client', () => {
577
661
  {
578
662
  class: Employee,
579
663
  },
580
- jane1.guid
664
+ jane1.guid,
581
665
  );
582
666
  if (jane1 == null || jane2 == null) {
583
667
  throw new Error('Entity is null.');
@@ -603,7 +687,7 @@ describe('Nymph REST Server and Client', () => {
603
687
  {
604
688
  class: Employee,
605
689
  },
606
- first.guid
690
+ first.guid,
607
691
  );
608
692
 
609
693
  if (second == null || second.guid == null) {
@@ -635,7 +719,7 @@ describe('Nymph REST Server and Client', () => {
635
719
  {
636
720
  class: Employee,
637
721
  },
638
- first.guid
722
+ first.guid,
639
723
  );
640
724
 
641
725
  if (second == null || second.guid == null) {
@@ -658,7 +742,7 @@ describe('Nymph REST Server and Client', () => {
658
742
  {
659
743
  type: '&',
660
744
  '!guid': first.guid,
661
- }
745
+ },
662
746
  );
663
747
 
664
748
  if (third == null || third.guid == null) {
@@ -668,6 +752,66 @@ describe('Nymph REST Server and Client', () => {
668
752
  expect(first.$is(third)).toEqual(false);
669
753
  });
670
754
 
755
+ it("doesn't allow creation of a restricted entity class", async () => {
756
+ const attempt = await Restricted.factory();
757
+ attempt.name = 'Jane Doe';
758
+
759
+ let error = null;
760
+
761
+ try {
762
+ await attempt.$save();
763
+ } catch (e: any) {
764
+ error = e;
765
+ }
766
+
767
+ expect(error).toBeInstanceOf(HttpError);
768
+ expect(error.status).toEqual(403);
769
+ });
770
+
771
+ it("doesn't allow search of a restricted entity class", async () => {
772
+ let error = null;
773
+
774
+ try {
775
+ await nymph.getEntity({
776
+ class: Restricted,
777
+ });
778
+ } catch (e: any) {
779
+ error = e;
780
+ }
781
+
782
+ expect(error).toBeInstanceOf(HttpError);
783
+ expect(error.status).toEqual(403);
784
+ });
785
+
786
+ it("doesn't allow methods of a restricted entity class", async () => {
787
+ const attempt = await Restricted.factory();
788
+ attempt.name = 'Jane Doe';
789
+
790
+ let error = null;
791
+
792
+ try {
793
+ await attempt.$testMethod(1);
794
+ } catch (e: any) {
795
+ error = e;
796
+ }
797
+
798
+ expect(error).toBeInstanceOf(HttpError);
799
+ expect(error.status).toEqual(403);
800
+ });
801
+
802
+ it("doesn't allow static methods of a restricted entity class", async () => {
803
+ let error = null;
804
+
805
+ try {
806
+ await Restricted.testStatic(1);
807
+ } catch (e: any) {
808
+ error = e;
809
+ }
810
+
811
+ expect(error).toBeInstanceOf(HttpError);
812
+ expect(error.status).toEqual(403);
813
+ });
814
+
671
815
  it('get a new UID', async () => {
672
816
  const uidValue = await nymph.newUID('employee');
673
817
  expect(typeof uidValue).toEqual('number');
package/src/index.ts CHANGED
@@ -1,7 +1,6 @@
1
- import { createServer } from './createServer';
1
+ import { createServer } from './createServer.js';
2
2
 
3
- export * from './HttpError';
4
- export * from './statusDescriptions';
5
- export * from './createServer';
3
+ export * from './statusDescriptions.js';
4
+ export * from './createServer.js';
6
5
 
7
6
  export default createServer;
@@ -1,8 +1,10 @@
1
- import { Entity as EntityServer, EntityInvalidDataError } from '@nymphjs/nymph';
1
+ import {
2
+ Entity as EntityServer,
3
+ EntityInvalidDataError,
4
+ HttpError,
5
+ } from '@nymphjs/nymph';
2
6
  import { Entity } from '@nymphjs/client';
3
7
 
4
- import { HttpError } from './HttpError';
5
-
6
8
  export type EmployeeBaseData<T> = {
7
9
  name?: string;
8
10
  id?: number;
@@ -39,7 +41,13 @@ export class EmployeeModel extends EntityServer<EmployeeModelData> {
39
41
  '$throwHttpError',
40
42
  '$throwHttpErrorWithDescription',
41
43
  ];
42
- public static clientEnabledStaticMethods = ['testStatic', 'throwErrorStatic'];
44
+ public static clientEnabledStaticMethods = [
45
+ 'testStatic',
46
+ 'testStaticIterable',
47
+ 'testStaticIterableAbort',
48
+ 'throwErrorStatic',
49
+ 'throwErrorStaticIterable',
50
+ ];
43
51
  protected $protectedTags = ['employee'];
44
52
  protected $allowlistTags? = ['boss', 'bigcheese'];
45
53
  protected $allowlistData? = [
@@ -57,37 +65,25 @@ export class EmployeeModel extends EntityServer<EmployeeModelData> {
57
65
  'building',
58
66
  ];
59
67
 
60
- static async factory(
61
- guid?: string
62
- ): Promise<EmployeeModel & EmployeeModelData> {
63
- return (await super.factory(guid)) as EmployeeModel & EmployeeModelData;
64
- }
65
-
66
- static factorySync(guid?: string): EmployeeModel & EmployeeModelData {
67
- return super.factorySync(guid) as EmployeeModel & EmployeeModelData;
68
- }
69
-
70
- constructor(guid?: string) {
71
- super(guid);
68
+ constructor() {
69
+ super();
72
70
 
73
- if (this.guid == null) {
74
- this.$addTag('employee');
75
- this.$data.current = true;
76
- this.$data.startDate = Date.now();
77
- this.$data.subordinates = [];
78
- if (!IS_MANAGER) {
79
- this.$privateData.push('salary');
80
- }
71
+ this.$addTag('employee');
72
+ this.$data.current = true;
73
+ this.$data.startDate = Date.now();
74
+ this.$data.subordinates = [];
75
+ if (!IS_MANAGER) {
76
+ this.$privateData.push('salary');
81
77
  }
82
78
  }
83
79
 
84
80
  public async $save() {
85
81
  // Validate employee data.
86
82
  const error = new EntityInvalidDataError('Invalid entity data.');
87
- if (this.$data.name == null || this.$data.name == '') {
83
+ if (this.$data.name == null || this.$data.name === '') {
88
84
  error.addField('name');
89
85
  }
90
- if (this.$data.title == null || this.$data.title == '') {
86
+ if (this.$data.title == null || this.$data.title === '') {
91
87
  error.addField('title');
92
88
  }
93
89
  if (this.$data.startDate == null) {
@@ -117,10 +113,33 @@ export class EmployeeModel extends EntityServer<EmployeeModelData> {
117
113
  return value * 2;
118
114
  }
119
115
 
116
+ public static *testStaticIterable(value: number) {
117
+ yield value + 1;
118
+ yield value + 2;
119
+ yield value + 3;
120
+ }
121
+
122
+ public static *testStaticIterableAbort(): Iterator<number, void, boolean> {
123
+ let aborted = yield 1;
124
+
125
+ if (!aborted) {
126
+ throw new Error(
127
+ "testStaticIterableAbort wasn't aborted after the first iteration.",
128
+ );
129
+ }
130
+ }
131
+
120
132
  public static throwErrorStatic() {
121
133
  throw new BadFunctionCallError('This function only throws errors.');
122
134
  }
123
135
 
136
+ public static *throwErrorStaticIterable() {
137
+ yield 1;
138
+ throw new BadFunctionCallError(
139
+ 'This function throws errors after the first iteration.',
140
+ );
141
+ }
142
+
124
143
  public $throwError() {
125
144
  throw new BadFunctionCallError('This function only throws errors.');
126
145
  }
@@ -151,22 +170,12 @@ export class Employee extends Entity<EmployeeData> {
151
170
  // The name of the server class
152
171
  public static class = 'Employee';
153
172
 
154
- constructor(guid?: string) {
155
- super(guid);
156
-
157
- if (guid == null) {
158
- this.$addTag('employee');
159
- this.$data.current = true;
160
- this.$data.subordinates = [];
161
- }
162
- }
163
-
164
- static async factory(guid?: string): Promise<Employee & EmployeeData> {
165
- return (await super.factory(guid)) as Employee & EmployeeData;
166
- }
173
+ constructor() {
174
+ super();
167
175
 
168
- static factorySync(guid?: string): Employee & EmployeeData {
169
- return super.factorySync(guid) as Employee & EmployeeData;
176
+ this.$addTag('employee');
177
+ this.$data.current = true;
178
+ this.$data.subordinates = [];
170
179
  }
171
180
 
172
181
  $testMethod(value: number) {
@@ -193,13 +202,133 @@ export class Employee extends Entity<EmployeeData> {
193
202
  return this.serverCallStatic('testStatic', [value]);
194
203
  }
195
204
 
205
+ static testStaticIterable(value: number) {
206
+ return this.serverCallStaticIterator('testStaticIterable', [value]);
207
+ }
208
+
209
+ static testStaticIterableAbort() {
210
+ return this.serverCallStaticIterator('testStaticIterableAbort', []);
211
+ }
212
+
196
213
  static throwErrorStatic() {
197
214
  return this.serverCallStatic('throwErrorStatic', []);
198
215
  }
199
216
 
217
+ static throwErrorStaticIterable() {
218
+ return this.serverCallStaticIterator('throwErrorStaticIterable', []);
219
+ }
220
+
200
221
  static inaccessibleMethod() {
201
222
  return this.serverCallStatic('inaccessibleMethod', []);
202
223
  }
203
224
  }
204
225
 
205
- export default Employee;
226
+ export type RestrictedModelData = {
227
+ name: string;
228
+ };
229
+
230
+ /**
231
+ * This class is a test class that extends the Entity class.
232
+ */
233
+ export class RestrictedModel extends EntityServer<RestrictedModelData> {
234
+ static ETYPE = 'restricted';
235
+ static class = 'Restricted';
236
+
237
+ public static restEnabled = false;
238
+
239
+ constructor() {
240
+ super();
241
+
242
+ this.$data.name = '';
243
+ }
244
+
245
+ public async $save() {
246
+ // Validate entity data.
247
+ const error = new EntityInvalidDataError('Invalid entity data.');
248
+ if (this.$data.name == null || this.$data.name === '') {
249
+ error.addField('name');
250
+ }
251
+ if (error.getFields().length) {
252
+ throw error;
253
+ }
254
+ return await super.$save();
255
+ }
256
+
257
+ $testMethod(value: string) {
258
+ return value;
259
+ }
260
+
261
+ public static testStatic(value: number) {
262
+ return value;
263
+ }
264
+ }
265
+
266
+ export type RestrictedData = {
267
+ name: string;
268
+ };
269
+
270
+ export class Restricted extends Entity<RestrictedData> {
271
+ // The name of the server class
272
+ public static class = 'Restricted';
273
+
274
+ constructor() {
275
+ super();
276
+
277
+ this.$data.name = '';
278
+ }
279
+
280
+ $testMethod(value: number) {
281
+ return this.$serverCall('$testMethod', [value]);
282
+ }
283
+
284
+ static testStatic(value: number) {
285
+ return this.serverCallStatic('testStatic', [value]);
286
+ }
287
+ }
288
+
289
+ export type PubSubDisabledModelData = {
290
+ name: string;
291
+ };
292
+
293
+ /**
294
+ * This class is a test class that extends the Entity class.
295
+ */
296
+ export class PubSubDisabledModel extends EntityServer<PubSubDisabledModelData> {
297
+ static ETYPE = 'pubsub_disabled';
298
+ static class = 'PubSubDisabled';
299
+
300
+ public static pubSubEnabled = false;
301
+
302
+ constructor() {
303
+ super();
304
+
305
+ this.$data.name = '';
306
+ }
307
+
308
+ public async $save() {
309
+ // Validate entity data.
310
+ const error = new EntityInvalidDataError('Invalid entity data.');
311
+ if (this.$data.name == null || this.$data.name === '') {
312
+ error.addField('name');
313
+ }
314
+ if (error.getFields().length) {
315
+ throw error;
316
+ }
317
+ return await super.$save();
318
+ }
319
+ }
320
+
321
+ export type PubSubDisabledData = {
322
+ name: string;
323
+ };
324
+
325
+ export class PubSubDisabled extends Entity<PubSubDisabledData> {
326
+ // The name of the server class
327
+ public static class = 'PubSubDisabled';
328
+
329
+ constructor() {
330
+ super();
331
+
332
+ this.$data.name = '';
333
+ }
334
+ }
package/tsconfig.json CHANGED
@@ -2,10 +2,13 @@
2
2
  "extends": "@tsconfig/recommended/tsconfig.json",
3
3
 
4
4
  "compilerOptions": {
5
- "lib": ["ES2021"],
6
- "target": "ES2021",
5
+ "types": ["node", "jest"],
6
+ "module": "nodenext",
7
+ "moduleResolution": "nodenext",
8
+ "lib": ["es2023"],
9
+ "target": "es2023",
7
10
  "noImplicitAny": true,
8
- "removeComments": true,
11
+ "removeComments": false,
9
12
  "sourceMap": true,
10
13
  "outDir": "dist",
11
14
  "resolveJsonModule": true,
package/typedoc.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": ["../../typedoc.base.json"],
3
+ "entryPoints": ["src/index.ts"]
4
+ }
@@ -1,5 +0,0 @@
1
- export declare class HttpError extends Error {
2
- status?: number;
3
- statusText?: string;
4
- constructor(message: string, status?: number, statusText?: string);
5
- }
package/dist/HttpError.js DELETED
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HttpError = void 0;
4
- class HttpError extends Error {
5
- constructor(message, status, statusText) {
6
- super(message);
7
- this.name = 'HttpError';
8
- this.status = status;
9
- this.statusText = statusText;
10
- }
11
- }
12
- exports.HttpError = HttpError;
13
- //# sourceMappingURL=HttpError.js.map