@acodeninja/persist 2.2.1 → 2.2.2
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/.deepsource.toml +10 -0
- package/package.json +1 -1
- package/src/Persist.js +3 -1
- package/src/Query.js +37 -16
- package/src/SchemaCompiler.js +68 -17
- package/src/engine/Engine.js +203 -36
- package/src/engine/FileEngine.js +118 -32
- package/src/engine/HTTPEngine.js +148 -26
- package/src/engine/S3Engine.js +131 -33
- package/src/type/Model.js +137 -22
- package/src/type/Type.js +42 -8
- package/src/type/complex/ArrayType.js +54 -1
- package/src/type/complex/CustomType.js +35 -1
- package/src/type/resolved/ResolvedType.js +39 -1
- package/src/type/resolved/SlugType.js +41 -1
- package/src/type/simple/BooleanType.js +16 -1
- package/src/type/simple/DateType.js +28 -1
- package/src/type/simple/NumberType.js +16 -1
- package/src/type/simple/SimpleType.js +11 -1
- package/src/type/simple/StringType.js +16 -1
package/src/engine/FileEngine.js
CHANGED
@@ -1,16 +1,36 @@
|
|
1
|
-
import Engine, {EngineError, MissConfiguredError} from './Engine.js';
|
2
|
-
import {dirname, join} from 'node:path';
|
1
|
+
import Engine, { EngineError, MissConfiguredError } from './Engine.js';
|
2
|
+
import { dirname, join } from 'node:path';
|
3
3
|
import fs from 'node:fs/promises';
|
4
4
|
|
5
|
+
/**
|
6
|
+
* Custom error class for FileEngine-related errors.
|
7
|
+
* Extends the base `EngineError` class.
|
8
|
+
*/
|
5
9
|
class FileEngineError extends EngineError {}
|
6
10
|
|
11
|
+
/**
|
12
|
+
* Error thrown when writing to a file fails in `FileEngine`.
|
13
|
+
* Extends the `FileEngineError` class.
|
14
|
+
*/
|
7
15
|
class FailedWriteFileEngineError extends FileEngineError {}
|
8
16
|
|
9
17
|
/**
|
18
|
+
* `FileEngine` class extends the base `Engine` class to implement
|
19
|
+
* file system-based storage and retrieval of model data.
|
20
|
+
*
|
10
21
|
* @class FileEngine
|
11
22
|
* @extends Engine
|
12
23
|
*/
|
13
|
-
|
24
|
+
class FileEngine extends Engine {
|
25
|
+
/**
|
26
|
+
* Configures the FileEngine with a given configuration object.
|
27
|
+
* Adds default `filesystem` configuration if not provided.
|
28
|
+
*
|
29
|
+
* @param {Object} configuration - Configuration settings for FileEngine.
|
30
|
+
* @param {Object} [configuration.filesystem] - Custom filesystem module (default: Node.js fs/promises).
|
31
|
+
* @param {Object} [configuration.path] - The absolute path on the filesystem to write models to.
|
32
|
+
* @returns {FileEngine} A configured instance of FileEngine.
|
33
|
+
*/
|
14
34
|
static configure(configuration) {
|
15
35
|
if (!configuration.filesystem) {
|
16
36
|
configuration.filesystem = fs;
|
@@ -18,42 +38,77 @@ export default class FileEngine extends Engine {
|
|
18
38
|
return super.configure(configuration);
|
19
39
|
}
|
20
40
|
|
41
|
+
/**
|
42
|
+
* Checks if the FileEngine has been configured correctly.
|
43
|
+
* Ensures that `path` and `filesystem` settings are present.
|
44
|
+
*
|
45
|
+
* @throws {MissConfiguredError} Throws if required configuration is missing.
|
46
|
+
*/
|
21
47
|
static checkConfiguration() {
|
22
|
-
if (
|
23
|
-
|
24
|
-
|
25
|
-
) throw new MissConfiguredError(this._configuration);
|
48
|
+
if (!this.configuration?.path || !this.configuration?.filesystem) {
|
49
|
+
throw new MissConfiguredError(this.configuration);
|
50
|
+
}
|
26
51
|
}
|
27
52
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
53
|
+
/**
|
54
|
+
* Retrieves a model by its ID from the file system.
|
55
|
+
*
|
56
|
+
* @param {string} id - The ID of the model to retrieve.
|
57
|
+
* @returns {Promise<Object>} The parsed model data.
|
58
|
+
* @throws {Error} Throws if the file cannot be read or parsed.
|
59
|
+
*/
|
60
|
+
static getById(id) {
|
61
|
+
return this.configuration.filesystem
|
62
|
+
.readFile(join(this.configuration.path, `${id}.json`))
|
63
|
+
.then((b) => b.toString())
|
64
|
+
.then(JSON.parse);
|
32
65
|
}
|
33
66
|
|
34
|
-
|
35
|
-
|
67
|
+
/**
|
68
|
+
* Retrieves the index for a given model from the file system.
|
69
|
+
*
|
70
|
+
* @param {Model.constructor?} model - The model for which the index is retrieved.
|
71
|
+
* @returns {Promise<Object>} The parsed index data.
|
72
|
+
* @throws {Error} Throws if the file cannot be read.
|
73
|
+
*/
|
74
|
+
static getIndex(model) {
|
75
|
+
return this.configuration.filesystem
|
76
|
+
.readFile(join(this.configuration.path, model.toString(), '_index.json'))
|
77
|
+
.then((b) => b.toString())
|
78
|
+
.catch(() => '{}')
|
79
|
+
.then(JSON.parse);
|
36
80
|
}
|
37
81
|
|
82
|
+
/**
|
83
|
+
* Saves a model to the file system.
|
84
|
+
*
|
85
|
+
* @param {Model} model - The model to save.
|
86
|
+
* @throws {FailedWriteFileEngineError} Throws if the model cannot be written to the file system.
|
87
|
+
*/
|
38
88
|
static async putModel(model) {
|
39
|
-
const filePath = join(this.
|
40
|
-
|
89
|
+
const filePath = join(this.configuration.path, `${model.id}.json`);
|
41
90
|
try {
|
42
|
-
await this.
|
43
|
-
await this.
|
91
|
+
await this.configuration.filesystem.mkdir(dirname(filePath), { recursive: true });
|
92
|
+
await this.configuration.filesystem.writeFile(filePath, JSON.stringify(model.toData()));
|
44
93
|
} catch (error) {
|
45
94
|
throw new FailedWriteFileEngineError(`Failed to put file://${filePath}`, error);
|
46
95
|
}
|
47
96
|
}
|
48
97
|
|
98
|
+
/**
|
99
|
+
* Saves the index for multiple models to the file system.
|
100
|
+
*
|
101
|
+
* @param {Object} index - An object where keys are locations and values are arrays of models.
|
102
|
+
* @throws {FailedWriteFileEngineError} Throws if the index cannot be written to the file system.
|
103
|
+
*/
|
49
104
|
static async putIndex(index) {
|
50
105
|
const processIndex = async (location, models) => {
|
51
|
-
const modelIndex = Object.fromEntries(models.map(m => [m.id, m.toIndexData()]));
|
52
|
-
const filePath = join(this.
|
53
|
-
const currentIndex = JSON.parse((await this.
|
106
|
+
const modelIndex = Object.fromEntries(models.map((m) => [m.id, m.toIndexData()]));
|
107
|
+
const filePath = join(this.configuration.path, location, '_index.json');
|
108
|
+
const currentIndex = JSON.parse((await this.configuration.filesystem.readFile(filePath).catch(() => '{}')).toString());
|
54
109
|
|
55
110
|
try {
|
56
|
-
await this.
|
111
|
+
await this.configuration.filesystem.writeFile(filePath, JSON.stringify({
|
57
112
|
...currentIndex,
|
58
113
|
...modelIndex,
|
59
114
|
}));
|
@@ -69,35 +124,66 @@ export default class FileEngine extends Engine {
|
|
69
124
|
await processIndex('', Object.values(index).flat());
|
70
125
|
}
|
71
126
|
|
72
|
-
|
73
|
-
|
74
|
-
|
127
|
+
/**
|
128
|
+
* Retrieves the compiled search index for a model from the file system.
|
129
|
+
*
|
130
|
+
* @param {Model.constructor} model - The model for which the search index is retrieved.
|
131
|
+
* @returns {Promise<Object>} The parsed compiled search index.
|
132
|
+
* @throws {Error} Throws if the file cannot be read.
|
133
|
+
*/
|
134
|
+
static getSearchIndexCompiled(model) {
|
135
|
+
return this.configuration.filesystem
|
136
|
+
.readFile(join(this.configuration.path, model.toString(), '_search_index.json'))
|
137
|
+
.then((b) => b.toString())
|
75
138
|
.then(JSON.parse);
|
76
139
|
}
|
77
140
|
|
78
|
-
|
79
|
-
|
80
|
-
|
141
|
+
/**
|
142
|
+
* Retrieves the raw search index for a model from the file system.
|
143
|
+
*
|
144
|
+
* @param {Model.constructor} model - The model for which the raw search index is retrieved.
|
145
|
+
* @returns {Promise<Object>} The parsed raw search index.
|
146
|
+
* @throws {Error} Throws if the file cannot be read.
|
147
|
+
*/
|
148
|
+
static getSearchIndexRaw(model) {
|
149
|
+
return this.configuration.filesystem
|
150
|
+
.readFile(join(this.configuration.path, model.toString(), '_search_index_raw.json'))
|
151
|
+
.then((b) => b.toString())
|
81
152
|
.then(JSON.parse)
|
82
153
|
.catch(() => ({}));
|
83
154
|
}
|
84
155
|
|
156
|
+
/**
|
157
|
+
* Saves the compiled search index for a model to the file system.
|
158
|
+
*
|
159
|
+
* @param {Model.constructor} model - The model for which the compiled search index is saved.
|
160
|
+
* @param {Object} compiledIndex - The compiled search index to save.
|
161
|
+
* @throws {FailedWriteFileEngineError} Throws if the compiled index cannot be written to the file system.
|
162
|
+
*/
|
85
163
|
static async putSearchIndexCompiled(model, compiledIndex) {
|
86
|
-
const filePath = join(this.
|
87
|
-
|
164
|
+
const filePath = join(this.configuration.path, model.toString(), '_search_index.json');
|
88
165
|
try {
|
89
|
-
await this.
|
166
|
+
await this.configuration.filesystem.writeFile(filePath, JSON.stringify(compiledIndex));
|
90
167
|
} catch (error) {
|
91
168
|
throw new FailedWriteFileEngineError(`Failed to put file://${filePath}`, error);
|
92
169
|
}
|
93
170
|
}
|
94
171
|
|
172
|
+
/**
|
173
|
+
* Saves the raw search index for a model to the file system.
|
174
|
+
*
|
175
|
+
* @param {Model.constructor} model - The model for which the raw search index is saved.
|
176
|
+
* @param {Object} rawIndex - The raw search index to save.
|
177
|
+
* @throws {FailedWriteFileEngineError} Throws if the raw index cannot be written to the file system.
|
178
|
+
*/
|
95
179
|
static async putSearchIndexRaw(model, rawIndex) {
|
96
|
-
const filePath = join(this.
|
180
|
+
const filePath = join(this.configuration.path, model.toString(), '_search_index_raw.json');
|
97
181
|
try {
|
98
|
-
await this.
|
182
|
+
await this.configuration.filesystem.writeFile(filePath, JSON.stringify(rawIndex));
|
99
183
|
} catch (error) {
|
100
184
|
throw new FailedWriteFileEngineError(`Failed to put file://${filePath}`, error);
|
101
185
|
}
|
102
186
|
}
|
103
187
|
}
|
188
|
+
|
189
|
+
export default FileEngine;
|
package/src/engine/HTTPEngine.js
CHANGED
@@ -1,8 +1,21 @@
|
|
1
1
|
import Engine, {EngineError, MissConfiguredError} from './Engine.js';
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
/**
|
4
|
+
* Represents an error specific to HTTP engine operations.
|
5
|
+
* @class HTTPEngineError
|
6
|
+
* @extends EngineError
|
7
|
+
*/
|
8
|
+
export class HTTPEngineError extends EngineError {}
|
5
9
|
|
10
|
+
/**
|
11
|
+
* Error indicating a failed HTTP request.
|
12
|
+
* @class HTTPRequestFailedError
|
13
|
+
* @extends HTTPEngineError
|
14
|
+
*
|
15
|
+
* @param {string} url - The URL of the failed request.
|
16
|
+
* @param {Object} options - The options used in the fetch request.
|
17
|
+
* @param {Response} response - The HTTP response object.
|
18
|
+
*/
|
6
19
|
export class HTTPRequestFailedError extends HTTPEngineError {
|
7
20
|
constructor(url, options, response) {
|
8
21
|
const method = options.method?.toLowerCase() || 'get';
|
@@ -13,7 +26,25 @@ export class HTTPRequestFailedError extends HTTPEngineError {
|
|
13
26
|
}
|
14
27
|
}
|
15
28
|
|
16
|
-
|
29
|
+
/**
|
30
|
+
* HTTPEngine is an extension of the Engine class that provides methods for interacting with HTTP-based APIs.
|
31
|
+
* It uses the Fetch API for sending and receiving data.
|
32
|
+
*
|
33
|
+
* @class HTTPEngine
|
34
|
+
* @extends Engine
|
35
|
+
*/
|
36
|
+
class HTTPEngine extends Engine {
|
37
|
+
|
38
|
+
/**
|
39
|
+
* Configures the HTTP engine with additional fetch options.
|
40
|
+
* Sets the Accept header to 'application/json' by default.
|
41
|
+
*
|
42
|
+
* @param {Object} configuration - Configuration object containing fetch options and other settings.
|
43
|
+
* @param {string} [configuration.host] - Hostname and protocol of the HTTP service to use (ie: https://example.com).
|
44
|
+
* @param {string?} [configuration.prefix] - The prefix on the host to perform operations against.
|
45
|
+
* @param {Object} [configuration.fetchOptions] - Fetch overrides to attach to all requests sent to the HTTP service.
|
46
|
+
* @returns {Object} The configured settings for the HTTP engine.
|
47
|
+
*/
|
17
48
|
static configure(configuration = {}) {
|
18
49
|
configuration.fetchOptions = {
|
19
50
|
...(configuration.fetchOptions ?? {}),
|
@@ -26,16 +57,30 @@ export default class HTTPEngine extends Engine {
|
|
26
57
|
return super.configure(configuration);
|
27
58
|
}
|
28
59
|
|
60
|
+
/**
|
61
|
+
* Validates the engine's configuration, ensuring that the host is defined.
|
62
|
+
*
|
63
|
+
* @throws {MissConfiguredError} Thrown if the configuration is missing a host.
|
64
|
+
*/
|
29
65
|
static checkConfiguration() {
|
30
|
-
if (
|
31
|
-
!this._configuration?.host
|
32
|
-
) throw new MissConfiguredError(this._configuration);
|
66
|
+
if (!this.configuration?.host) throw new MissConfiguredError(this.configuration);
|
33
67
|
}
|
34
68
|
|
69
|
+
/**
|
70
|
+
* Returns the fetch options for reading operations.
|
71
|
+
*
|
72
|
+
* @returns {Object} The fetch options for reading.
|
73
|
+
*/
|
35
74
|
static _getReadOptions() {
|
36
|
-
return this.
|
75
|
+
return this.configuration.fetchOptions;
|
37
76
|
}
|
38
77
|
|
78
|
+
/**
|
79
|
+
* Returns the fetch options for writing (PUT) operations.
|
80
|
+
* Sets the method to PUT and adds a Content-Type header of 'application/json'.
|
81
|
+
*
|
82
|
+
* @returns {Object} The fetch options for writing.
|
83
|
+
*/
|
39
84
|
static _getWriteOptions() {
|
40
85
|
return {
|
41
86
|
...this._getReadOptions(),
|
@@ -47,8 +92,18 @@ export default class HTTPEngine extends Engine {
|
|
47
92
|
};
|
48
93
|
}
|
49
94
|
|
95
|
+
/**
|
96
|
+
* Processes a fetch request with error handling. Throws an error if the response is not successful.
|
97
|
+
*
|
98
|
+
* @param {string|URL} url - The URL to fetch.
|
99
|
+
* @param {Object} options - The fetch options.
|
100
|
+
* @param {*} [defaultValue] - A default value to return if the fetch fails.
|
101
|
+
* @returns {Promise<Object>} The parsed JSON response.
|
102
|
+
*
|
103
|
+
* @throws {HTTPRequestFailedError} Thrown if the fetch request fails.
|
104
|
+
*/
|
50
105
|
static async _processFetch(url, options, defaultValue = undefined) {
|
51
|
-
return this.
|
106
|
+
return this.configuration.fetch(url, options)
|
52
107
|
.then(response => {
|
53
108
|
if (!response.ok) {
|
54
109
|
if (defaultValue !== undefined) {
|
@@ -63,22 +118,38 @@ export default class HTTPEngine extends Engine {
|
|
63
118
|
.then(r => r.json());
|
64
119
|
}
|
65
120
|
|
121
|
+
/**
|
122
|
+
* Retrieves an object by its ID from the server.
|
123
|
+
*
|
124
|
+
* @param {string} id - The ID of the object to retrieve.
|
125
|
+
* @returns {Promise<Object>} The retrieved object in JSON format.
|
126
|
+
*
|
127
|
+
* @throws {HTTPRequestFailedError} Thrown if the fetch request fails.
|
128
|
+
*/
|
66
129
|
static async getById(id) {
|
67
130
|
this.checkConfiguration();
|
68
131
|
|
69
132
|
const url = new URL([
|
70
|
-
this.
|
71
|
-
this.
|
133
|
+
this.configuration.host,
|
134
|
+
this.configuration.prefix,
|
72
135
|
`${id}.json`,
|
73
136
|
].filter(e => !!e).join('/'));
|
74
137
|
|
75
138
|
return await this._processFetch(url, this._getReadOptions());
|
76
139
|
}
|
77
140
|
|
141
|
+
/**
|
142
|
+
* Uploads (puts) a model object to the server.
|
143
|
+
*
|
144
|
+
* @param {Model} model - The model object to upload.
|
145
|
+
* @returns {Promise<Object>} The response from the server.
|
146
|
+
*
|
147
|
+
* @throws {HTTPRequestFailedError} Thrown if the PUT request fails.
|
148
|
+
*/
|
78
149
|
static async putModel(model) {
|
79
150
|
const url = new URL([
|
80
|
-
this.
|
81
|
-
this.
|
151
|
+
this.configuration.host,
|
152
|
+
this.configuration.prefix,
|
82
153
|
`${model.id}.json`,
|
83
154
|
].filter(e => !!e).join('/'));
|
84
155
|
|
@@ -88,12 +159,20 @@ export default class HTTPEngine extends Engine {
|
|
88
159
|
});
|
89
160
|
}
|
90
161
|
|
162
|
+
/**
|
163
|
+
* Uploads (puts) an index object to the server.
|
164
|
+
*
|
165
|
+
* @param {Object} index - The index data to upload, organized by location.
|
166
|
+
* @returns {Promise<void>}
|
167
|
+
*
|
168
|
+
* @throws {HTTPRequestFailedError} Thrown if the PUT request fails.
|
169
|
+
*/
|
91
170
|
static async putIndex(index) {
|
92
171
|
const processIndex = async (location, models) => {
|
93
172
|
const modelIndex = Object.fromEntries(models.map(m => [m.id, m.toIndexData()]));
|
94
173
|
const url = new URL([
|
95
|
-
this.
|
96
|
-
this.
|
174
|
+
this.configuration.host,
|
175
|
+
this.configuration.prefix,
|
97
176
|
location,
|
98
177
|
'_index.json',
|
99
178
|
].filter(e => !!e).join('/'));
|
@@ -114,16 +193,33 @@ export default class HTTPEngine extends Engine {
|
|
114
193
|
await processIndex(null, Object.values(index).flat());
|
115
194
|
}
|
116
195
|
|
117
|
-
|
118
|
-
|
196
|
+
/**
|
197
|
+
* Retrieves the index object from the server for the specified location.
|
198
|
+
*
|
199
|
+
* @param {Model.constructor?} model - The model in the host where the index is stored.
|
200
|
+
* @returns {Promise<Object>} The index data in JSON format.
|
201
|
+
*/
|
202
|
+
static async getIndex(model) {
|
203
|
+
const url = new URL([
|
204
|
+
this.configuration.host,
|
205
|
+
this.configuration.prefix,
|
206
|
+
model?.toString(),
|
207
|
+
'_index.json',
|
208
|
+
].filter(e => Boolean(e)).join('/'));
|
119
209
|
|
120
210
|
return await this._processFetch(url, this._getReadOptions(), {});
|
121
211
|
}
|
122
212
|
|
213
|
+
/**
|
214
|
+
* Retrieves the compiled search index for a model from the server.
|
215
|
+
*
|
216
|
+
* @param {Model.constructor} model - The model whose compiled search index to retrieve.
|
217
|
+
* @returns {Promise<Object>} The compiled search index in JSON format.
|
218
|
+
*/
|
123
219
|
static async getSearchIndexCompiled(model) {
|
124
220
|
const url = new URL([
|
125
|
-
this.
|
126
|
-
this.
|
221
|
+
this.configuration.host,
|
222
|
+
this.configuration.prefix,
|
127
223
|
model.toString(),
|
128
224
|
'_search_index.json',
|
129
225
|
].join('/'));
|
@@ -131,10 +227,16 @@ export default class HTTPEngine extends Engine {
|
|
131
227
|
return await this._processFetch(url, this._getReadOptions());
|
132
228
|
}
|
133
229
|
|
230
|
+
/**
|
231
|
+
* Retrieves the raw (uncompiled) search index for a model from the server.
|
232
|
+
*
|
233
|
+
* @param {Model.constructor} model - The model whose raw search index to retrieve.
|
234
|
+
* @returns {Promise<Object>} The raw search index in JSON format, or an empty object if not found.
|
235
|
+
*/
|
134
236
|
static async getSearchIndexRaw(model) {
|
135
237
|
const url = new URL([
|
136
|
-
this.
|
137
|
-
this.
|
238
|
+
this.configuration.host,
|
239
|
+
this.configuration.prefix,
|
138
240
|
model.toString(),
|
139
241
|
'_search_index_raw.json',
|
140
242
|
].join('/'));
|
@@ -142,11 +244,20 @@ export default class HTTPEngine extends Engine {
|
|
142
244
|
return await this._processFetch(url, this._getReadOptions()).catch(() => ({}));
|
143
245
|
}
|
144
246
|
|
247
|
+
/**
|
248
|
+
* Uploads (puts) a compiled search index for a model to the server.
|
249
|
+
*
|
250
|
+
* @param {Model.constructor} model - The model whose compiled search index to upload.
|
251
|
+
* @param {Object} compiledIndex - The compiled search index data.
|
252
|
+
* @returns {Promise<Object>} The response from the server.
|
253
|
+
*
|
254
|
+
* @throws {HTTPRequestFailedError} Thrown if the PUT request fails.
|
255
|
+
*/
|
145
256
|
static async putSearchIndexCompiled(model, compiledIndex) {
|
146
257
|
const url = new URL([
|
147
|
-
this.
|
148
|
-
this.
|
149
|
-
model.
|
258
|
+
this.configuration.host,
|
259
|
+
this.configuration.prefix,
|
260
|
+
model.toString(),
|
150
261
|
'_search_index.json',
|
151
262
|
].filter(e => !!e).join('/'));
|
152
263
|
|
@@ -156,11 +267,20 @@ export default class HTTPEngine extends Engine {
|
|
156
267
|
});
|
157
268
|
}
|
158
269
|
|
270
|
+
/**
|
271
|
+
* Uploads (puts) a raw search index for a model to the server.
|
272
|
+
*
|
273
|
+
* @param {Model.constructor} model - The model whose raw search index to upload.
|
274
|
+
* @param {Object} rawIndex - The raw search index data.
|
275
|
+
* @returns {Promise<Object>} The response from the server.
|
276
|
+
*
|
277
|
+
* @throws {HTTPRequestFailedError} Thrown if the PUT request fails.
|
278
|
+
*/
|
159
279
|
static async putSearchIndexRaw(model, rawIndex) {
|
160
280
|
const url = new URL([
|
161
|
-
this.
|
162
|
-
this.
|
163
|
-
model.
|
281
|
+
this.configuration.host,
|
282
|
+
this.configuration.prefix,
|
283
|
+
model.toString(),
|
164
284
|
'_search_index_raw.json',
|
165
285
|
].filter(e => !!e).join('/'));
|
166
286
|
|
@@ -170,3 +290,5 @@ export default class HTTPEngine extends Engine {
|
|
170
290
|
});
|
171
291
|
}
|
172
292
|
}
|
293
|
+
|
294
|
+
export default HTTPEngine;
|