@acodeninja/persist 2.4.1-next.2 → 3.0.0-next.10
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/SchemaCompiler.js +6 -2
- package/src/engine/StorageEngine.js +517 -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/Model.js +35 -2
- 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.10",
|
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;
|
package/src/SchemaCompiler.js
CHANGED
@@ -79,7 +79,11 @@ class SchemaCompiler {
|
|
79
79
|
schema.properties[name].items.format = property?._items._format;
|
80
80
|
}
|
81
81
|
|
82
|
-
|
82
|
+
const prop = typeof property?._items === 'function' &&
|
83
|
+
!/^class/.test(Function.prototype.toString.call(property?._items)) ?
|
84
|
+
property?._items() : property?._items;
|
85
|
+
|
86
|
+
if (Type.Model.isModel(prop)) {
|
83
87
|
schema.properties[name].items = {
|
84
88
|
type: 'object',
|
85
89
|
additionalProperties: false,
|
@@ -87,7 +91,7 @@ class SchemaCompiler {
|
|
87
91
|
properties: {
|
88
92
|
id: {
|
89
93
|
type: 'string',
|
90
|
-
pattern: `^${
|
94
|
+
pattern: `^${prop.toString()}/[A-Z0-9]+$`,
|
91
95
|
},
|
92
96
|
},
|
93
97
|
};
|