@acodeninja/persist 2.4.1-next.2 → 3.0.0-next.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/docs/code-quirks.md +3 -3
- package/docs/search-queries.md +2 -2
- package/docs/storage-engines.md +12 -12
- package/docs/structured-queries.md +8 -8
- package/docs/transactions.md +3 -3
- package/exports/engine/storage/file.js +3 -0
- package/exports/engine/storage/http.js +3 -0
- package/exports/engine/storage/s3.js +3 -0
- package/jest.config.cjs +26 -0
- package/package.json +7 -10
- package/src/Query.js +2 -2
- package/src/engine/StorageEngine.js +250 -0
- package/src/engine/{FileEngine.js → storage/FileStorageEngine.js} +30 -23
- package/src/engine/{HTTPEngine.js → storage/HTTPStorageEngine.js} +16 -10
- package/src/engine/{S3Engine.js → storage/S3StorageEngine.js} +26 -19
- package/src/engine/{Engine.js → storage/StorageEngine.js} +44 -9
- package/src/type/index.js +11 -16
- package/src/type/simple/BooleanType.js +4 -4
- package/src/type/simple/DateType.js +4 -4
- package/src/type/simple/NumberType.js +4 -4
- package/src/type/simple/StringType.js +4 -4
- package/exports/engine/file.js +0 -3
- package/exports/engine/http.js +0 -3
- package/exports/engine/s3.js +0 -3
- package/src/type/simple/SimpleType.js +0 -14
package/docs/code-quirks.md
CHANGED
@@ -54,15 +54,15 @@ export class Address extends Persist.Type.Model {
|
|
54
54
|
|
55
55
|
By doing this, you ensure that model references are evaluated lazily, after all models have been initialized, preventing `ReferenceError` issues.
|
56
56
|
|
57
|
-
## Using `HTTP`
|
57
|
+
## Using `HTTP` StorageEngine in Browser
|
58
58
|
|
59
59
|
When implementing thee `HTTP` engine for code that runs in the web browser, you must pass `fetch` into the engine configuration and bind it to the `window` object.
|
60
60
|
|
61
61
|
```javascript
|
62
62
|
import Persist from "@acodeninja/persist";
|
63
|
-
import
|
63
|
+
import HTTPStorageEngine from "@acodeninja/persist/engine/storage/http";
|
64
64
|
|
65
|
-
Persist.addEngine('remote',
|
65
|
+
Persist.addEngine('remote', HTTPStorageEngine, {
|
66
66
|
host: 'https://api.example.com',
|
67
67
|
fetch: fetch.bind(window),
|
68
68
|
});
|
package/docs/search-queries.md
CHANGED
@@ -37,9 +37,9 @@ To search for any `Person` who lives on station road, the following search query
|
|
37
37
|
```javascript
|
38
38
|
import Persist from "@acodeninja/persist";
|
39
39
|
import Person from "./Person";
|
40
|
-
import
|
40
|
+
import FileStorageEngine from "@acodeninja/persist/engine/storage/file"
|
41
41
|
|
42
|
-
|
42
|
+
FileStorageEngine
|
43
43
|
.configure(configuration)
|
44
44
|
.search(Person, 'station road');
|
45
45
|
```
|
package/docs/storage-engines.md
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Persist makes several storage engines available for use with the library
|
4
4
|
|
5
|
-
## Filesystem Storage
|
5
|
+
## Filesystem Storage StorageEngine
|
6
6
|
|
7
7
|
To store models using the local file system, use the `File` storage engine.
|
8
8
|
|
9
9
|
```javascript
|
10
10
|
import Persist from "@acodeninja/persist";
|
11
|
-
import
|
11
|
+
import FileStorageEngine from "@acodeninja/persist/engine/storage/file";
|
12
12
|
|
13
|
-
Persist.addEngine('local',
|
13
|
+
Persist.addEngine('local', FileStorageEngine, {
|
14
14
|
path: '/app/storage',
|
15
15
|
});
|
16
16
|
|
@@ -18,18 +18,18 @@ export class Tag extends Persist.Type.Model {
|
|
18
18
|
static tag = Persist.Type.String.required;
|
19
19
|
}
|
20
20
|
|
21
|
-
await Persist.getEngine('local',
|
21
|
+
await Persist.getEngine('local', FileStorageEngine).put(new Tag({tag: 'documentation'}));
|
22
22
|
```
|
23
23
|
|
24
|
-
## HTTP Storage
|
24
|
+
## HTTP Storage StorageEngine
|
25
25
|
|
26
26
|
To store models using an HTTP server, use the `HTTP` storage engine. When using the `HTTP` engine in the browser, refer to [code quirks](./code-quirks.md#using-http-engine-in-browser).
|
27
27
|
|
28
28
|
```javascript
|
29
29
|
import Persist from "@acodeninja/persist";
|
30
|
-
import
|
30
|
+
import HTTPStorageEngine from "@acodeninja/persist/engine/storage/http";
|
31
31
|
|
32
|
-
Persist.addEngine('remote',
|
32
|
+
Persist.addEngine('remote', HTTPStorageEngine, {
|
33
33
|
host: 'https://api.example.com',
|
34
34
|
});
|
35
35
|
|
@@ -37,18 +37,18 @@ export class Tag extends Persist.Type.Model {
|
|
37
37
|
static tag = Persist.Type.String.required;
|
38
38
|
}
|
39
39
|
|
40
|
-
await Persist.getEngine('remote',
|
40
|
+
await Persist.getEngine('remote', HTTPStorageEngine).put(new Tag({tag: 'documentation'}));
|
41
41
|
```
|
42
42
|
|
43
|
-
## S3 Storage
|
43
|
+
## S3 Storage StorageEngine
|
44
44
|
|
45
45
|
To store models using an S3 Bucket, use the `S3` storage engine. To use the `S3` engine you must also add the `@aws-sdk/client-s3` dependency to your `package.json` file.
|
46
46
|
|
47
47
|
```javascript
|
48
48
|
import Persist from "@acodeninja/persist";
|
49
|
-
import
|
49
|
+
import S3StorageEngine from "@acodeninja/persist/engine/storage/s3";
|
50
50
|
|
51
|
-
Persist.addEngine('remote',
|
51
|
+
Persist.addEngine('remote', S3StorageEngine, {
|
52
52
|
bucket: 'test-bucket',
|
53
53
|
client: new S3Client(),
|
54
54
|
});
|
@@ -57,5 +57,5 @@ export class Tag extends Persist.Type.Model {
|
|
57
57
|
static tag = Persist.Type.String.required;
|
58
58
|
}
|
59
59
|
|
60
|
-
await Persist.getEngine('remote',
|
60
|
+
await Persist.getEngine('remote', S3StorageEngine).put(new Tag({tag: 'documentation'}));
|
61
61
|
```
|
@@ -40,9 +40,9 @@ To query for a `Person` called `Joe Bloggs` an exact query can be written:
|
|
40
40
|
```javascript
|
41
41
|
import Persist from "@acodeninja/persist";
|
42
42
|
import Person from "./Person";
|
43
|
-
import
|
43
|
+
import FileStorageEngine from "@acodeninja/persist/engine/storage/file"
|
44
44
|
|
45
|
-
|
45
|
+
FileStorageEngine
|
46
46
|
.configure(configuration)
|
47
47
|
.find(Person, {
|
48
48
|
name: {$is: 'Joe Bloggs'},
|
@@ -56,9 +56,9 @@ To query for a `Person` with name `Joe` a contains query can be written:
|
|
56
56
|
```javascript
|
57
57
|
import Persist from "@acodeninja/persist";
|
58
58
|
import Person from "./Person";
|
59
|
-
import
|
59
|
+
import FileStorageEngine from "@acodeninja/persist/engine/storage/file"
|
60
60
|
|
61
|
-
|
61
|
+
FileStorageEngine
|
62
62
|
.configure(configuration)
|
63
63
|
.find(Person, {
|
64
64
|
name: {$contains: 'Joe'},
|
@@ -72,9 +72,9 @@ To query for a `Person` who lives at `SW1 1AA` a combination of contains and exa
|
|
72
72
|
```javascript
|
73
73
|
import Persist from "@acodeninja/persist";
|
74
74
|
import Person from "./Person";
|
75
|
-
import
|
75
|
+
import FileStorageEngine from "@acodeninja/persist/engine/storage/file"
|
76
76
|
|
77
|
-
|
77
|
+
FileStorageEngine
|
78
78
|
.configure(configuration)
|
79
79
|
.find(Person, {
|
80
80
|
address: {
|
@@ -92,9 +92,9 @@ To query for anyone called `Joe Bloggs` who lives in the `SW1` postcode area, we
|
|
92
92
|
```javascript
|
93
93
|
import Persist from "@acodeninja/persist";
|
94
94
|
import Person from "./Person";
|
95
|
-
import
|
95
|
+
import FileStorageEngine from "@acodeninja/persist/engine/storage/file"
|
96
96
|
|
97
|
-
|
97
|
+
FileStorageEngine
|
98
98
|
.configure(configuration)
|
99
99
|
.find(Person, {
|
100
100
|
name: {$is: 'Joe Bloggs'},
|
package/docs/transactions.md
CHANGED
@@ -4,9 +4,9 @@ Create transactions to automatically roll back on failure.
|
|
4
4
|
|
5
5
|
```javascript
|
6
6
|
import Persist from "@acodeninja/persist";
|
7
|
-
import
|
7
|
+
import S3StorageEngine from "@acodeninja/persist/engine/storage/s3";
|
8
8
|
|
9
|
-
Persist.addEngine('remote',
|
9
|
+
Persist.addEngine('remote', S3StorageEngine, {
|
10
10
|
bucket: 'test-bucket',
|
11
11
|
client: new S3Client(),
|
12
12
|
transactions: true,
|
@@ -16,7 +16,7 @@ export class Tag extends Persist.Type.Model {
|
|
16
16
|
static tag = Persist.Type.String.required;
|
17
17
|
}
|
18
18
|
|
19
|
-
const transaction = Persist.getEngine('remote',
|
19
|
+
const transaction = Persist.getEngine('remote', S3StorageEngine).start();
|
20
20
|
|
21
21
|
await transaction.put(new Tag({tag: 'documentation'}));
|
22
22
|
await transaction.commit();
|
package/jest.config.cjs
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
/** @type {import('jest').Config} */
|
2
|
+
const config = {
|
3
|
+
coveragePathIgnorePatterns: [
|
4
|
+
'node_modules',
|
5
|
+
'test/fixtures',
|
6
|
+
'test/mocks',
|
7
|
+
'test/scripts',
|
8
|
+
],
|
9
|
+
coverageThreshold: {
|
10
|
+
global: {
|
11
|
+
branches: 100,
|
12
|
+
functions: 100,
|
13
|
+
lines: 100,
|
14
|
+
statements: 100,
|
15
|
+
},
|
16
|
+
},
|
17
|
+
testMatch: [
|
18
|
+
'**/*.test.js',
|
19
|
+
],
|
20
|
+
watchPathIgnorePatterns: [
|
21
|
+
'coverage/',
|
22
|
+
'test/fixtures/minified',
|
23
|
+
],
|
24
|
+
};
|
25
|
+
|
26
|
+
module.exports = config;
|
package/package.json
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
{
|
2
2
|
"name": "@acodeninja/persist",
|
3
|
-
"version": "
|
3
|
+
"version": "3.0.0-next.2",
|
4
4
|
"description": "A JSON based data modelling and persistence module with alternate storage mechanisms.",
|
5
5
|
"type": "module",
|
6
6
|
"scripts": {
|
7
|
-
"test": "
|
8
|
-
"test:watch": "
|
9
|
-
"test:coverage": "
|
10
|
-
"test:coverage:report": "c8 --experimental-monocart --100 --lcov --reporter=console-details --reporter=v8 ava",
|
7
|
+
"test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" npx jest",
|
8
|
+
"test:watch": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" npx jest --watch",
|
9
|
+
"test:coverage": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" npx jest --collect-coverage",
|
11
10
|
"lint": "eslint ./",
|
12
11
|
"prepare": "husky"
|
13
12
|
},
|
@@ -38,14 +37,12 @@
|
|
38
37
|
"@commitlint/cli": "^19.6.1",
|
39
38
|
"@commitlint/config-conventional": "^19.6.0",
|
40
39
|
"@eslint/js": "^9.19.0",
|
40
|
+
"@jest/globals": "^29.7.0",
|
41
41
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
42
|
-
"ava": "^6.2.0",
|
43
|
-
"c8": "^10.1.3",
|
44
42
|
"eslint": "^9.19.0",
|
45
43
|
"globals": "^15.14.0",
|
46
44
|
"husky": "^9.1.7",
|
47
|
-
"
|
48
|
-
"semantic-release": "^24.2.1"
|
49
|
-
"sinon": "^19.0.2"
|
45
|
+
"jest": "^29.7.0",
|
46
|
+
"semantic-release": "^24.2.1"
|
50
47
|
}
|
51
48
|
}
|
package/src/Query.js
CHANGED
@@ -69,10 +69,10 @@ class Query {
|
|
69
69
|
*
|
70
70
|
* @private
|
71
71
|
* @param {*} subject - The subject to be matched.
|
72
|
-
* @param {Object}
|
72
|
+
* @param {Object} inputQuery - The query to match against.
|
73
73
|
* @returns {boolean} True if the subject matches the query, otherwise false.
|
74
74
|
*/
|
75
|
-
_matchesQuery(subject, inputQuery
|
75
|
+
_matchesQuery(subject, inputQuery) {
|
76
76
|
if (['string', 'number', 'boolean'].includes(typeof inputQuery)) return subject === inputQuery;
|
77
77
|
|
78
78
|
if (inputQuery?.$is !== undefined && subject === inputQuery.$is) return true;
|
@@ -0,0 +1,250 @@
|
|
1
|
+
import Type from '../type/index.js';
|
2
|
+
import _ from 'lodash';
|
3
|
+
|
4
|
+
export default class StorageEngine {
|
5
|
+
/**
|
6
|
+
* @param {Object} configuration
|
7
|
+
* @param {Array<Type.Model.constructor>?} models
|
8
|
+
*/
|
9
|
+
constructor(configuration = {}, models = null) {
|
10
|
+
this.configuration = configuration;
|
11
|
+
this.models = Object.fromEntries((models ?? []).map(model => [model.name, model]));
|
12
|
+
}
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Persists a model if it has changed, and updates all related models and their indexes
|
16
|
+
* @param {Type.Model} model
|
17
|
+
* @return {Promise<void>}
|
18
|
+
*/
|
19
|
+
async put(model) {
|
20
|
+
const processedModels = [];
|
21
|
+
const modelsToPut = [];
|
22
|
+
const modelsToReindex = {};
|
23
|
+
|
24
|
+
/**
|
25
|
+
* @param {Type.Model} modelToProcess
|
26
|
+
* @return {Promise<void>}
|
27
|
+
*/
|
28
|
+
const processModel = async (modelToProcess) => {
|
29
|
+
if (processedModels.includes(modelToProcess.id)) return;
|
30
|
+
|
31
|
+
processedModels.push(modelToProcess.id);
|
32
|
+
|
33
|
+
if (!Object.keys(this.models).includes(modelToProcess.constructor.name)) throw new ModelNotRegisteredStorageEngineError(modelToProcess, this);
|
34
|
+
|
35
|
+
modelToProcess.validate();
|
36
|
+
const currentModel = await this.get(modelToProcess.id).catch(() => null);
|
37
|
+
|
38
|
+
const modelToProcessHasChanged = (JSON.stringify(currentModel?.toData() || {}) !== JSON.stringify(modelToProcess.toData()));
|
39
|
+
|
40
|
+
if (modelToProcessHasChanged) modelsToPut.push(modelToProcess);
|
41
|
+
|
42
|
+
if (
|
43
|
+
Boolean(modelToProcess.constructor.indexedProperties().length) &&
|
44
|
+
this._indexedFieldsHaveChanged(currentModel, modelToProcess)
|
45
|
+
) {
|
46
|
+
const modelToProcessConstructor = this.getModelConstructorFromId(modelToProcess.id);
|
47
|
+
modelsToReindex[modelToProcessConstructor] = modelsToReindex[modelToProcessConstructor] || [];
|
48
|
+
modelsToReindex[modelToProcessConstructor].push(modelToProcess);
|
49
|
+
}
|
50
|
+
|
51
|
+
for (const [field, value] of Object.entries(modelToProcess)) {
|
52
|
+
if (Type.Model.isModel(value)) {
|
53
|
+
await processModel(modelToProcess[field]);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
};
|
57
|
+
|
58
|
+
await processModel(model);
|
59
|
+
|
60
|
+
await Promise.all(modelsToPut.map(m => this._putModel(m.toData())));
|
61
|
+
await Promise.all(Object.entries(modelsToReindex).map(async ([constructor, models]) => {
|
62
|
+
const modelConstructor = this.models[constructor];
|
63
|
+
const index = await this._getIndex(modelConstructor);
|
64
|
+
|
65
|
+
await this._putIndex(modelConstructor, {
|
66
|
+
...index || {},
|
67
|
+
...Object.fromEntries(models.map(m => [m.id, m.toIndexData()])),
|
68
|
+
});
|
69
|
+
}));
|
70
|
+
}
|
71
|
+
|
72
|
+
/**
|
73
|
+
* Decide if two models indexable fields have changed
|
74
|
+
* @param {Type.Model} currentModel
|
75
|
+
* @param {Type.Model} modelToProcess
|
76
|
+
* @return {boolean}
|
77
|
+
* @private
|
78
|
+
*/
|
79
|
+
_indexedFieldsHaveChanged(currentModel, modelToProcess) {
|
80
|
+
return !currentModel || Boolean(
|
81
|
+
modelToProcess.constructor.indexedProperties()
|
82
|
+
.filter(field => JSON.stringify(_.get(currentModel, field)) !== JSON.stringify(_.get(modelToProcess, field)))
|
83
|
+
.length,
|
84
|
+
);
|
85
|
+
}
|
86
|
+
|
87
|
+
/**
|
88
|
+
* Get a model by its id
|
89
|
+
* @param {string} modelId
|
90
|
+
* @return {Promise<void>}
|
91
|
+
*/
|
92
|
+
get(modelId) {
|
93
|
+
try {
|
94
|
+
this.getModelConstructorFromId(modelId);
|
95
|
+
} catch (e) {
|
96
|
+
return Promise.reject(e);
|
97
|
+
}
|
98
|
+
return this._getModel(modelId);
|
99
|
+
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Get the model constructor from a model id
|
103
|
+
* @param {string} modelId
|
104
|
+
* @return {Model.constructor}
|
105
|
+
*/
|
106
|
+
getModelConstructorFromId(modelId) {
|
107
|
+
const modelName = modelId.split('/')[0];
|
108
|
+
const constructor = this.models[modelName];
|
109
|
+
|
110
|
+
if (!constructor) throw new ModelNotRegisteredStorageEngineError(modelName, this);
|
111
|
+
|
112
|
+
return constructor;
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* Get model classes that are directly linked to the given model in either direction
|
117
|
+
* @param {Type.Model.constructor} model
|
118
|
+
* @return {Record<string, Record<string, Type.Model.constructor>>}
|
119
|
+
*/
|
120
|
+
getLinksFor(model) {
|
121
|
+
return Object.fromEntries(
|
122
|
+
Object.entries(this.getAllModelLinks())
|
123
|
+
.filter(([modelName, links]) =>
|
124
|
+
model.name === modelName ||
|
125
|
+
Object.values(links).some((link) => link.name === model.name),
|
126
|
+
),
|
127
|
+
);
|
128
|
+
}
|
129
|
+
|
130
|
+
/**
|
131
|
+
* Get all model links
|
132
|
+
* @return {Record<string, Record<string, Type.Model.constructor>>}
|
133
|
+
*/
|
134
|
+
getAllModelLinks() {
|
135
|
+
return Object.entries(this.models)
|
136
|
+
.map(([registeredModelName, registeredModelClass]) =>
|
137
|
+
Object.entries(registeredModelClass)
|
138
|
+
.map(([propertyName, propertyType]) => [
|
139
|
+
registeredModelName,
|
140
|
+
propertyName,
|
141
|
+
typeof propertyType === 'function' && !Type.Model.isModel(propertyType) ? propertyType() : propertyType,
|
142
|
+
])
|
143
|
+
.filter(([_m, _p, type]) => Type.Model.isModel(type))
|
144
|
+
.map(([containingModel, propertyName, propertyType]) => ({
|
145
|
+
containingModel,
|
146
|
+
propertyName,
|
147
|
+
propertyType,
|
148
|
+
})),
|
149
|
+
)
|
150
|
+
.flat()
|
151
|
+
.reduce((accumulator, {containingModel, propertyName, propertyType}) => ({
|
152
|
+
...accumulator,
|
153
|
+
[containingModel]: {
|
154
|
+
...accumulator[containingModel] || {},
|
155
|
+
[propertyName]: propertyType,
|
156
|
+
},
|
157
|
+
}), {});
|
158
|
+
}
|
159
|
+
|
160
|
+
/**
|
161
|
+
* Update a model
|
162
|
+
* @param {Model} _model
|
163
|
+
* @throws MethodNotImplementedStorageEngineError
|
164
|
+
* @return Promise<void>
|
165
|
+
*/
|
166
|
+
_putModel(_model) {
|
167
|
+
return Promise.reject(new MethodNotImplementedStorageEngineError('_putModel', this));
|
168
|
+
}
|
169
|
+
|
170
|
+
/**
|
171
|
+
* Get a model
|
172
|
+
* @param {string} _id
|
173
|
+
* @throws MethodNotImplementedStorageEngineError
|
174
|
+
* @throws ModelNotFoundStorageEngineError
|
175
|
+
* @return Promise<void>
|
176
|
+
*/
|
177
|
+
_getModel(_id) {
|
178
|
+
return Promise.reject(new MethodNotImplementedStorageEngineError('_getModel', this));
|
179
|
+
}
|
180
|
+
|
181
|
+
/**
|
182
|
+
* Get a model's index data
|
183
|
+
* @param {Model.constructor} _modelConstructor
|
184
|
+
* @throws MethodNotImplementedStorageEngineError
|
185
|
+
* @return Promise<void>
|
186
|
+
*/
|
187
|
+
_getIndex(_modelConstructor) {
|
188
|
+
return Promise.reject(new MethodNotImplementedStorageEngineError('_getIndex', this));
|
189
|
+
}
|
190
|
+
|
191
|
+
/**
|
192
|
+
* Put a model's index data
|
193
|
+
* @param {Model.constructor} _modelConstructor
|
194
|
+
* @param {object} _data
|
195
|
+
* @throws MethodNotImplementedStorageEngineError
|
196
|
+
* @return Promise<void>
|
197
|
+
*/
|
198
|
+
_putIndex(_modelConstructor, _data) {
|
199
|
+
return Promise.reject(new MethodNotImplementedStorageEngineError('_putIndex', this));
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
/**
|
204
|
+
* @class StorageEngineError
|
205
|
+
* @extends Error
|
206
|
+
*/
|
207
|
+
export class StorageEngineError extends Error {
|
208
|
+
}
|
209
|
+
|
210
|
+
/**
|
211
|
+
* @class ModelNotRegisteredStorageEngineError
|
212
|
+
* @extends StorageEngineError
|
213
|
+
*/
|
214
|
+
export class ModelNotRegisteredStorageEngineError extends StorageEngineError {
|
215
|
+
/**
|
216
|
+
* @param {Type.Model} model
|
217
|
+
* @param {StorageEngine} storageEngine
|
218
|
+
*/
|
219
|
+
constructor(model, storageEngine) {
|
220
|
+
const modelName = typeof model === 'string' ? model : model.constructor.name;
|
221
|
+
super(`The model ${modelName} is not registered in the storage engine ${storageEngine.constructor.name}`);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
/**
|
226
|
+
* @class MethodNotImplementedStorageEngineError
|
227
|
+
* @extends StorageEngineError
|
228
|
+
*/
|
229
|
+
export class MethodNotImplementedStorageEngineError extends StorageEngineError {
|
230
|
+
/**
|
231
|
+
* @param {string} method
|
232
|
+
* @param {StorageEngine} storageEngine
|
233
|
+
*/
|
234
|
+
constructor(method, storageEngine) {
|
235
|
+
super(`The method ${method} is not implemented in the storage engine ${storageEngine.constructor.name}`);
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
/**
|
240
|
+
* @class ModelNotFoundStorageEngineError
|
241
|
+
* @extends StorageEngineError
|
242
|
+
*/
|
243
|
+
export class ModelNotFoundStorageEngineError extends StorageEngineError {
|
244
|
+
/**
|
245
|
+
* @param {string} modelId
|
246
|
+
*/
|
247
|
+
constructor(modelId) {
|
248
|
+
super(`The model ${modelId} was not found`);
|
249
|
+
}
|
250
|
+
}
|
@@ -1,35 +1,35 @@
|
|
1
|
-
import
|
1
|
+
import StorageEngine, { EngineError, MissConfiguredError } from './StorageEngine.js';
|
2
2
|
import { dirname, join } from 'node:path';
|
3
3
|
import fs from 'node:fs/promises';
|
4
4
|
|
5
5
|
/**
|
6
|
-
* Custom error class for
|
6
|
+
* Custom error class for FileStorageEngine-related errors.
|
7
7
|
* Extends the base `EngineError` class.
|
8
8
|
*/
|
9
|
-
class
|
9
|
+
class FileStorageEngineError extends EngineError {}
|
10
10
|
|
11
11
|
/**
|
12
|
-
* Error thrown when writing to a file fails in `
|
13
|
-
* Extends the `
|
12
|
+
* Error thrown when writing to a file fails in `FileStorageEngine`.
|
13
|
+
* Extends the `FileStorageEngineError` class.
|
14
14
|
*/
|
15
|
-
class
|
15
|
+
class FailedWriteFileStorageEngineError extends FileStorageEngineError {}
|
16
16
|
|
17
17
|
/**
|
18
|
-
* `
|
18
|
+
* `FileStorageEngine` class extends the base `StorageEngine` class to implement
|
19
19
|
* file system-based storage and retrieval of model data.
|
20
20
|
*
|
21
|
-
* @class
|
22
|
-
* @extends
|
21
|
+
* @class FileStorageEngine
|
22
|
+
* @extends StorageEngine
|
23
23
|
*/
|
24
|
-
class
|
24
|
+
class FileStorageEngine extends StorageEngine {
|
25
25
|
/**
|
26
|
-
* Configures the
|
26
|
+
* Configures the FileStorageEngine with a given configuration object.
|
27
27
|
* Adds default `filesystem` configuration if not provided.
|
28
28
|
*
|
29
|
-
* @param {Object} configuration - Configuration settings for
|
29
|
+
* @param {Object} configuration - Configuration settings for FileStorageEngine.
|
30
30
|
* @param {Object} [configuration.filesystem] - Custom filesystem module (default: Node.js fs/promises).
|
31
31
|
* @param {Object} [configuration.path] - The absolute path on the filesystem to write models to.
|
32
|
-
* @returns {
|
32
|
+
* @returns {FileStorageEngine} A configured instance of FileStorageEngine.
|
33
33
|
*/
|
34
34
|
static configure(configuration) {
|
35
35
|
if (!configuration.filesystem) {
|
@@ -39,7 +39,7 @@ class FileEngine extends Engine {
|
|
39
39
|
}
|
40
40
|
|
41
41
|
/**
|
42
|
-
* Checks if the
|
42
|
+
* Checks if the FileStorageEngine has been configured correctly.
|
43
43
|
* Ensures that `path` and `filesystem` settings are present.
|
44
44
|
*
|
45
45
|
* @throws {MissConfiguredError} Throws if required configuration is missing.
|
@@ -94,7 +94,7 @@ class FileEngine extends Engine {
|
|
94
94
|
* Saves a model to the file system.
|
95
95
|
*
|
96
96
|
* @param {Model} model - The model to save.
|
97
|
-
* @throws {
|
97
|
+
* @throws {FailedWriteFileStorageEngineError} Throws if the model cannot be written to the file system.
|
98
98
|
*/
|
99
99
|
static async putModel(model) {
|
100
100
|
const filePath = join(this.configuration.path, `${model.id}.json`);
|
@@ -102,7 +102,7 @@ class FileEngine extends Engine {
|
|
102
102
|
await this.configuration.filesystem.mkdir(dirname(filePath), { recursive: true });
|
103
103
|
await this.configuration.filesystem.writeFile(filePath, JSON.stringify(model.toData()));
|
104
104
|
} catch (error) {
|
105
|
-
throw new
|
105
|
+
throw new FailedWriteFileStorageEngineError(`Failed to put file://${filePath}`, error);
|
106
106
|
}
|
107
107
|
}
|
108
108
|
|
@@ -110,9 +110,16 @@ class FileEngine extends Engine {
|
|
110
110
|
* Saves the index for multiple models to the file system.
|
111
111
|
*
|
112
112
|
* @param {Object} index - An object where keys are locations and values are key value pairs of models and their ids.
|
113
|
-
* @throws {
|
113
|
+
* @throws {FailedWriteFileStorageEngineError} Throws if the index cannot be written to the file system.
|
114
114
|
*/
|
115
115
|
static async putIndex(index) {
|
116
|
+
/**
|
117
|
+
* Process an index of models
|
118
|
+
* @param {string} location
|
119
|
+
* @param {Array<Model>} models
|
120
|
+
* @throws FailedWriteFileStorageEngineError
|
121
|
+
* @return {Promise<void>}
|
122
|
+
*/
|
116
123
|
const processIndex = async (location, models) => {
|
117
124
|
const filePath = join(this.configuration.path, location, '_index.json');
|
118
125
|
const currentIndex = JSON.parse((await this.configuration.filesystem.readFile(filePath).catch(() => '{}')).toString());
|
@@ -125,7 +132,7 @@ class FileEngine extends Engine {
|
|
125
132
|
),
|
126
133
|
}));
|
127
134
|
} catch (error) {
|
128
|
-
throw new
|
135
|
+
throw new FailedWriteFileStorageEngineError(`Failed to put file://${filePath}`, error);
|
129
136
|
}
|
130
137
|
};
|
131
138
|
|
@@ -175,14 +182,14 @@ class FileEngine extends Engine {
|
|
175
182
|
*
|
176
183
|
* @param {Model.constructor} model - The model for which the compiled search index is saved.
|
177
184
|
* @param {Object} compiledIndex - The compiled search index to save.
|
178
|
-
* @throws {
|
185
|
+
* @throws {FailedWriteFileStorageEngineError} Throws if the compiled index cannot be written to the file system.
|
179
186
|
*/
|
180
187
|
static async putSearchIndexCompiled(model, compiledIndex) {
|
181
188
|
const filePath = join(this.configuration.path, model.toString(), '_search_index.json');
|
182
189
|
try {
|
183
190
|
await this.configuration.filesystem.writeFile(filePath, JSON.stringify(compiledIndex));
|
184
191
|
} catch (error) {
|
185
|
-
throw new
|
192
|
+
throw new FailedWriteFileStorageEngineError(`Failed to put file://${filePath}`, error);
|
186
193
|
}
|
187
194
|
}
|
188
195
|
|
@@ -191,16 +198,16 @@ class FileEngine extends Engine {
|
|
191
198
|
*
|
192
199
|
* @param {Model.constructor} model - The model for which the raw search index is saved.
|
193
200
|
* @param {Object} rawIndex - The raw search index to save.
|
194
|
-
* @throws {
|
201
|
+
* @throws {FailedWriteFileStorageEngineError} Throws if the raw index cannot be written to the file system.
|
195
202
|
*/
|
196
203
|
static async putSearchIndexRaw(model, rawIndex) {
|
197
204
|
const filePath = join(this.configuration.path, model.toString(), '_search_index_raw.json');
|
198
205
|
try {
|
199
206
|
await this.configuration.filesystem.writeFile(filePath, JSON.stringify(rawIndex));
|
200
207
|
} catch (error) {
|
201
|
-
throw new
|
208
|
+
throw new FailedWriteFileStorageEngineError(`Failed to put file://${filePath}`, error);
|
202
209
|
}
|
203
210
|
}
|
204
211
|
}
|
205
212
|
|
206
|
-
export default
|
213
|
+
export default FileStorageEngine;
|
@@ -1,22 +1,22 @@
|
|
1
|
-
import
|
1
|
+
import StorageEngine, {EngineError, MissConfiguredError} from './StorageEngine.js';
|
2
2
|
|
3
3
|
/**
|
4
4
|
* Represents an error specific to HTTP engine operations.
|
5
|
-
* @class
|
5
|
+
* @class HTTPStorageEngineError
|
6
6
|
* @extends EngineError
|
7
7
|
*/
|
8
|
-
export class
|
8
|
+
export class HTTPStorageEngineError extends EngineError {}
|
9
9
|
|
10
10
|
/**
|
11
11
|
* Error indicating a failed HTTP request.
|
12
12
|
* @class HTTPRequestFailedError
|
13
|
-
* @extends
|
13
|
+
* @extends HTTPStorageEngineError
|
14
14
|
*
|
15
15
|
* @param {string} url - The URL of the failed request.
|
16
16
|
* @param {Object} options - The options used in the fetch request.
|
17
17
|
* @param {Response} response - The HTTP response object.
|
18
18
|
*/
|
19
|
-
export class HTTPRequestFailedError extends
|
19
|
+
export class HTTPRequestFailedError extends HTTPStorageEngineError {
|
20
20
|
constructor(url, options, response) {
|
21
21
|
const method = options.method?.toLowerCase() || 'get';
|
22
22
|
super(`Failed to ${method} ${url}`);
|
@@ -27,13 +27,13 @@ export class HTTPRequestFailedError extends HTTPEngineError {
|
|
27
27
|
}
|
28
28
|
|
29
29
|
/**
|
30
|
-
*
|
30
|
+
* HTTPStorageEngine is an extension of the StorageEngine class that provides methods for interacting with HTTP-based APIs.
|
31
31
|
* It uses the Fetch API for sending and receiving data.
|
32
32
|
*
|
33
|
-
* @class
|
34
|
-
* @extends
|
33
|
+
* @class HTTPStorageEngine
|
34
|
+
* @extends StorageEngine
|
35
35
|
*/
|
36
|
-
class
|
36
|
+
class HTTPStorageEngine extends StorageEngine {
|
37
37
|
|
38
38
|
/**
|
39
39
|
* Configures the HTTP engine with additional fetch options.
|
@@ -186,6 +186,12 @@ class HTTPEngine extends Engine {
|
|
186
186
|
* @throws {HTTPRequestFailedError} Thrown if the PUT request fails.
|
187
187
|
*/
|
188
188
|
static async putIndex(index) {
|
189
|
+
/**
|
190
|
+
* Process an index of models
|
191
|
+
* @param {string} location
|
192
|
+
* @param {Array<Model>} models
|
193
|
+
* @return {Promise<void>}
|
194
|
+
*/
|
189
195
|
const processIndex = async (location, models) => {
|
190
196
|
const url = new URL([
|
191
197
|
this.configuration.host,
|
@@ -315,4 +321,4 @@ class HTTPEngine extends Engine {
|
|
315
321
|
}
|
316
322
|
}
|
317
323
|
|
318
|
-
export default
|
324
|
+
export default HTTPStorageEngine;
|
@@ -1,28 +1,28 @@
|
|
1
1
|
import {DeleteObjectCommand, GetObjectCommand, PutObjectCommand} from '@aws-sdk/client-s3';
|
2
|
-
import
|
2
|
+
import StorageEngine, {EngineError, MissConfiguredError} from './StorageEngine.js';
|
3
3
|
|
4
4
|
/**
|
5
5
|
* Represents an error specific to the S3 engine operations.
|
6
|
-
* @class
|
6
|
+
* @class S3StorageEngineError
|
7
7
|
* @extends EngineError
|
8
8
|
*/
|
9
|
-
class
|
9
|
+
class S3StorageEngineError extends EngineError {}
|
10
10
|
|
11
11
|
/**
|
12
12
|
* Error indicating a failure when putting an object to S3.
|
13
|
-
* @class
|
14
|
-
* @extends
|
13
|
+
* @class FailedPutS3StorageEngineError
|
14
|
+
* @extends S3StorageEngineError
|
15
15
|
*/
|
16
|
-
class
|
16
|
+
class FailedPutS3StorageEngineError extends S3StorageEngineError {}
|
17
17
|
|
18
18
|
/**
|
19
|
-
*
|
19
|
+
* S3StorageEngine is an extension of the StorageEngine class that provides methods for interacting with AWS S3.
|
20
20
|
* It allows for storing, retrieving, and managing model data in an S3 bucket.
|
21
21
|
*
|
22
|
-
* @class
|
23
|
-
* @extends
|
22
|
+
* @class S3StorageEngine
|
23
|
+
* @extends StorageEngine
|
24
24
|
*/
|
25
|
-
class
|
25
|
+
class S3StorageEngine extends StorageEngine {
|
26
26
|
/**
|
27
27
|
* Configures the S3 engine with additional options.
|
28
28
|
*
|
@@ -92,7 +92,7 @@ class S3Engine extends Engine {
|
|
92
92
|
* @param {Model} model - The model object to upload.
|
93
93
|
* @returns {Promise<void>}
|
94
94
|
*
|
95
|
-
* @throws {
|
95
|
+
* @throws {FailedPutS3StorageEngineError} Thrown if there is an error during the S3 PutObject operation.
|
96
96
|
*/
|
97
97
|
static async putModel(model) {
|
98
98
|
const Key = [this.configuration.prefix, `${model.id}.json`].join('/');
|
@@ -105,7 +105,7 @@ class S3Engine extends Engine {
|
|
105
105
|
ContentType: 'application/json',
|
106
106
|
}));
|
107
107
|
} catch (error) {
|
108
|
-
throw new
|
108
|
+
throw new FailedPutS3StorageEngineError(`Failed to put s3://${this.configuration.bucket}/${Key}`, error);
|
109
109
|
}
|
110
110
|
}
|
111
111
|
|
@@ -133,9 +133,16 @@ class S3Engine extends Engine {
|
|
133
133
|
*
|
134
134
|
* @param {Object} index - An object where keys are locations and values are key value pairs of models and their ids.
|
135
135
|
* @returns {Promise<void>}
|
136
|
-
* @throws {
|
136
|
+
* @throws {FailedPutS3StorageEngineError} Thrown if there is an error during the S3 PutObject operation.
|
137
137
|
*/
|
138
138
|
static async putIndex(index) {
|
139
|
+
/**
|
140
|
+
* Process an index of models
|
141
|
+
* @param {string} location
|
142
|
+
* @param {Array<Model>} models
|
143
|
+
* @throws FailedPutS3StorageEngineError
|
144
|
+
* @return {Promise<void>}
|
145
|
+
*/
|
139
146
|
const processIndex = async (location, models) => {
|
140
147
|
const Key = [this.configuration.prefix, location, '_index.json'].filter(e => Boolean(e)).join('/');
|
141
148
|
const currentIndex = await this.getIndex(location);
|
@@ -153,7 +160,7 @@ class S3Engine extends Engine {
|
|
153
160
|
}),
|
154
161
|
}));
|
155
162
|
} catch (error) {
|
156
|
-
throw new
|
163
|
+
throw new FailedPutS3StorageEngineError(`Failed to put s3://${this.configuration.bucket}/${Key}`, error);
|
157
164
|
}
|
158
165
|
};
|
159
166
|
|
@@ -205,7 +212,7 @@ class S3Engine extends Engine {
|
|
205
212
|
* @param {Object} compiledIndex - The compiled search index data.
|
206
213
|
* @returns {Promise<void>}
|
207
214
|
*
|
208
|
-
* @throws {
|
215
|
+
* @throws {FailedPutS3StorageEngineError} Thrown if there is an error during the S3 PutObject operation.
|
209
216
|
*/
|
210
217
|
static async putSearchIndexCompiled(model, compiledIndex) {
|
211
218
|
const Key = [this.configuration.prefix, model.toString(), '_search_index.json'].join('/');
|
@@ -218,7 +225,7 @@ class S3Engine extends Engine {
|
|
218
225
|
ContentType: 'application/json',
|
219
226
|
}));
|
220
227
|
} catch (error) {
|
221
|
-
throw new
|
228
|
+
throw new FailedPutS3StorageEngineError(`Failed to put s3://${this.configuration.bucket}/${Key}`, error);
|
222
229
|
}
|
223
230
|
}
|
224
231
|
|
@@ -229,7 +236,7 @@ class S3Engine extends Engine {
|
|
229
236
|
* @param {Object} rawIndex - The raw search index data.
|
230
237
|
* @returns {Promise<void>}
|
231
238
|
*
|
232
|
-
* @throws {
|
239
|
+
* @throws {FailedPutS3StorageEngineError} Thrown if there is an error during the S3 PutObject operation.
|
233
240
|
*/
|
234
241
|
static async putSearchIndexRaw(model, rawIndex) {
|
235
242
|
const Key = [this.configuration.prefix, model.toString(), '_search_index_raw.json'].join('/');
|
@@ -242,9 +249,9 @@ class S3Engine extends Engine {
|
|
242
249
|
ContentType: 'application/json',
|
243
250
|
}));
|
244
251
|
} catch (error) {
|
245
|
-
throw new
|
252
|
+
throw new FailedPutS3StorageEngineError(`Failed to put s3://${this.configuration.bucket}/${Key}`, error);
|
246
253
|
}
|
247
254
|
}
|
248
255
|
}
|
249
256
|
|
250
|
-
export default
|
257
|
+
export default S3StorageEngine;
|
@@ -1,14 +1,14 @@
|
|
1
|
-
import Query from '
|
2
|
-
import Type from '
|
1
|
+
import Query from '../../Query.js';
|
2
|
+
import Type from '../../type/index.js';
|
3
3
|
import lunr from 'lunr';
|
4
4
|
|
5
5
|
/**
|
6
|
-
* The `
|
6
|
+
* The `StorageEngine` class provides a base interface for implementing data storage and retrieval engines.
|
7
7
|
* It includes methods for handling models, indexes, and search functionality.
|
8
8
|
*
|
9
|
-
* @class
|
9
|
+
* @class StorageEngine
|
10
10
|
*/
|
11
|
-
class
|
11
|
+
class StorageEngine {
|
12
12
|
static configuration = undefined;
|
13
13
|
static _searchCache = undefined;
|
14
14
|
|
@@ -186,6 +186,11 @@ class Engine {
|
|
186
186
|
const uploadedModels = [];
|
187
187
|
const indexUpdates = {};
|
188
188
|
|
189
|
+
/**
|
190
|
+
* Process a model, putting updates to the model and all linked models.
|
191
|
+
* @param {Model} m
|
192
|
+
* @return {Promise<void>}
|
193
|
+
*/
|
189
194
|
const processModel = async (m) => {
|
190
195
|
if (!uploadedModels.includes(m.id)) {
|
191
196
|
m.validate();
|
@@ -389,6 +394,11 @@ class Engine {
|
|
389
394
|
this.checkConfiguration();
|
390
395
|
const hydratedModels = {};
|
391
396
|
|
397
|
+
/**
|
398
|
+
* Hydrate a model
|
399
|
+
* @param {Model} modelToProcess
|
400
|
+
* @return {Promise<Model>}
|
401
|
+
*/
|
392
402
|
const hydrateModel = async (modelToProcess) => {
|
393
403
|
hydratedModels[modelToProcess.id] = modelToProcess;
|
394
404
|
|
@@ -405,6 +415,13 @@ class Engine {
|
|
405
415
|
return modelToProcess;
|
406
416
|
};
|
407
417
|
|
418
|
+
/**
|
419
|
+
* Hydrate a dry sub model
|
420
|
+
* @param property
|
421
|
+
* @param modelToProcess
|
422
|
+
* @param name
|
423
|
+
* @return {Promise<Model>}
|
424
|
+
*/
|
408
425
|
const hydrateSubModel = async (property, modelToProcess, name) => {
|
409
426
|
if (hydratedModels[property.id]) {
|
410
427
|
return hydratedModels[property.id];
|
@@ -418,6 +435,13 @@ class Engine {
|
|
418
435
|
return hydratedSubModel;
|
419
436
|
};
|
420
437
|
|
438
|
+
/**
|
439
|
+
* Hydrate an array of dry models
|
440
|
+
* @param property
|
441
|
+
* @param modelToProcess
|
442
|
+
* @param name
|
443
|
+
* @return {Promise<Awaited<*>[]>}
|
444
|
+
*/
|
421
445
|
const hydrateModelList = async (property, modelToProcess, name) => {
|
422
446
|
const subModelClass = getSubModelClass(modelToProcess, name, true);
|
423
447
|
|
@@ -440,6 +464,13 @@ class Engine {
|
|
440
464
|
}));
|
441
465
|
};
|
442
466
|
|
467
|
+
/**
|
468
|
+
* Get the class of a sub model
|
469
|
+
* @param modelToProcess
|
470
|
+
* @param name
|
471
|
+
* @param isArray
|
472
|
+
* @return {Model.constructor|Type}
|
473
|
+
*/
|
443
474
|
function getSubModelClass(modelToProcess, name, isArray = false) {
|
444
475
|
const constructorField = modelToProcess.constructor[name];
|
445
476
|
|
@@ -457,9 +488,13 @@ class Engine {
|
|
457
488
|
* Configures the engine with specific settings.
|
458
489
|
*
|
459
490
|
* @param {Object} configuration - The configuration settings for the engine.
|
460
|
-
* @returns {
|
491
|
+
* @returns {StorageEngine} A new engine instance with the applied configuration.
|
461
492
|
*/
|
462
493
|
static configure(configuration) {
|
494
|
+
/**
|
495
|
+
* @class ConfiguredStore
|
496
|
+
* @extends StorageEngine
|
497
|
+
*/
|
463
498
|
class ConfiguredStore extends this {
|
464
499
|
static configuration = configuration;
|
465
500
|
}
|
@@ -476,7 +511,7 @@ class Engine {
|
|
476
511
|
* @abstract
|
477
512
|
*/
|
478
513
|
static checkConfiguration() {
|
479
|
-
// Implemented in extending
|
514
|
+
// Implemented in extending StorageEngine class
|
480
515
|
}
|
481
516
|
|
482
517
|
/**
|
@@ -568,9 +603,9 @@ export class MissConfiguredError extends EngineError {
|
|
568
603
|
* @param {Object} configuration - The configuration object that caused the misconfiguration.
|
569
604
|
*/
|
570
605
|
constructor(configuration) {
|
571
|
-
super('
|
606
|
+
super('StorageEngine is miss-configured');
|
572
607
|
this.configuration = configuration;
|
573
608
|
}
|
574
609
|
}
|
575
610
|
|
576
|
-
export default
|
611
|
+
export default StorageEngine;
|
package/src/type/index.js
CHANGED
@@ -15,23 +15,18 @@ import StringType from './simple/StringType.js';
|
|
15
15
|
* @property {DateType} Date
|
16
16
|
* @property {ArrayType} Array
|
17
17
|
* @property {CustomType} Custom
|
18
|
-
* @property {
|
18
|
+
* @property {{Slug: SlugType}} Resolved
|
19
19
|
* @property {Model} Model
|
20
20
|
*/
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
* @class ResolvedType
|
32
|
-
* @property {SlugType} Slug
|
33
|
-
*/
|
34
|
-
Type.Resolved = {Slug: SlugType};
|
35
|
-
Type.Model = Model;
|
21
|
+
class Type {
|
22
|
+
static Model = Model;
|
23
|
+
static String = StringType;
|
24
|
+
static Number = NumberType;
|
25
|
+
static Boolean = BooleanType;
|
26
|
+
static Date = DateType;
|
27
|
+
static Array = ArrayType;
|
28
|
+
static Custom = CustomType;
|
29
|
+
static Resolved = {Slug: SlugType};
|
30
|
+
}
|
36
31
|
|
37
32
|
export default Type;
|
@@ -1,15 +1,15 @@
|
|
1
|
-
import
|
1
|
+
import Type from '../Type.js';
|
2
2
|
|
3
3
|
/**
|
4
4
|
* Class representing a boolean type.
|
5
5
|
*
|
6
6
|
* This class is used to define and handle data of the boolean type.
|
7
|
-
* It extends the {@link
|
7
|
+
* It extends the {@link Type} class to represent string-specific behavior.
|
8
8
|
*
|
9
9
|
* @class BooleanType
|
10
|
-
* @extends
|
10
|
+
* @extends Type
|
11
11
|
*/
|
12
|
-
class BooleanType extends
|
12
|
+
class BooleanType extends Type {
|
13
13
|
static {
|
14
14
|
/**
|
15
15
|
* @static
|
@@ -1,15 +1,15 @@
|
|
1
|
-
import
|
1
|
+
import Type from '../Type.js';
|
2
2
|
|
3
3
|
/**
|
4
4
|
* Class representing a date type with ISO date-time format.
|
5
5
|
*
|
6
6
|
* This class is used to define and handle data of the date type.
|
7
|
-
* It extends the {@link
|
7
|
+
* It extends the {@link Type} class to represent string-specific behavior.
|
8
8
|
*
|
9
9
|
* @class DateType
|
10
|
-
* @extends
|
10
|
+
* @extends Type
|
11
11
|
*/
|
12
|
-
class DateType extends
|
12
|
+
class DateType extends Type {
|
13
13
|
static {
|
14
14
|
/**
|
15
15
|
* @static
|
@@ -1,15 +1,15 @@
|
|
1
|
-
import
|
1
|
+
import Type from '../Type.js';
|
2
2
|
|
3
3
|
/**
|
4
4
|
* Class representing a number type.
|
5
5
|
*
|
6
6
|
* This class is used to define and handle data of the number type.
|
7
|
-
* It extends the {@link
|
7
|
+
* It extends the {@link Type} class to represent string-specific behavior.
|
8
8
|
*
|
9
9
|
* @class NumberType
|
10
|
-
* @extends
|
10
|
+
* @extends Type
|
11
11
|
*/
|
12
|
-
class NumberType extends
|
12
|
+
class NumberType extends Type {
|
13
13
|
static {
|
14
14
|
/**
|
15
15
|
* @static
|
@@ -1,15 +1,15 @@
|
|
1
|
-
import
|
1
|
+
import Type from '../Type.js';
|
2
2
|
|
3
3
|
/**
|
4
4
|
* Class representing a string type.
|
5
5
|
*
|
6
6
|
* This class is used to define and handle data of the string type.
|
7
|
-
* It extends the {@link
|
7
|
+
* It extends the {@link Type} class to represent string-specific behavior.
|
8
8
|
*
|
9
9
|
* @class StringType
|
10
|
-
* @extends
|
10
|
+
* @extends Type
|
11
11
|
*/
|
12
|
-
class StringType extends
|
12
|
+
class StringType extends Type {
|
13
13
|
static {
|
14
14
|
/**
|
15
15
|
* @static
|
package/exports/engine/file.js
DELETED
package/exports/engine/http.js
DELETED
package/exports/engine/s3.js
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
import Type from '../Type.js';
|
2
|
-
|
3
|
-
/**
|
4
|
-
* Class representing a simple type.
|
5
|
-
*
|
6
|
-
* This serves as a base class for primitive or simple types such as string, number, or boolean.
|
7
|
-
*
|
8
|
-
* @class SimpleType
|
9
|
-
* @extends Type
|
10
|
-
*/
|
11
|
-
class SimpleType extends Type {
|
12
|
-
}
|
13
|
-
|
14
|
-
export default SimpleType;
|