@acodeninja/persist 2.0.0 → 2.1.1
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/README.md +7 -0
- package/package.json +2 -1
- package/src/SchemaCompiler.js +14 -1
- package/src/type/Model.js +19 -4
- package/src/type/complex/ArrayType.js +3 -1
- package/src/type/index.js +18 -0
- package/src/type/simple/DateType.js +10 -0
package/README.md
CHANGED
@@ -17,6 +17,7 @@ export class SimpleModel extends Persist.Type.Model {
|
|
17
17
|
static boolean = Persist.Type.Boolean;
|
18
18
|
static string = Persist.Type.String;
|
19
19
|
static number = Persist.Type.Number;
|
20
|
+
static date = Persist.Type.Date;
|
20
21
|
}
|
21
22
|
```
|
22
23
|
|
@@ -29,6 +30,7 @@ export class SimpleModel extends Persist.Type.Model {
|
|
29
30
|
static requiredBoolean = Persist.Type.Boolean.required;
|
30
31
|
static requiredString = Persist.Type.String.required;
|
31
32
|
static requiredNumber = Persist.Type.Number.required;
|
33
|
+
static requiredDate = Persist.Type.Date.required;
|
32
34
|
}
|
33
35
|
```
|
34
36
|
|
@@ -41,6 +43,11 @@ export class SimpleModel extends Persist.Type.Model {
|
|
41
43
|
static arrayOfBooleans = Persist.Type.Array.of(Type.Boolean);
|
42
44
|
static arrayOfStrings = Persist.Type.Array.of(Type.String);
|
43
45
|
static arrayOfNumbers = Persist.Type.Array.of(Type.Number);
|
46
|
+
static arrayOfDates = Persist.Type.Array.of(Type.Date);
|
47
|
+
static requiredArrayOfBooleans = Persist.Type.Array.of(Type.Boolean).required;
|
48
|
+
static requiredArrayOfStrings = Persist.Type.Array.of(Type.String).required;
|
49
|
+
static requiredArrayOfNumbers = Persist.Type.Array.of(Type.Number).required;
|
50
|
+
static requiredArrayOfDates = Persist.Type.Array.of(Type.Date).required;
|
44
51
|
}
|
45
52
|
```
|
46
53
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@acodeninja/persist",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.1.1",
|
4
4
|
"description": "A JSON based data modelling and persistence module with alternate storage mechanisms.",
|
5
5
|
"type": "module",
|
6
6
|
"scripts": {
|
@@ -25,6 +25,7 @@
|
|
25
25
|
"dependencies": {
|
26
26
|
"ajv": "^8.16.0",
|
27
27
|
"ajv-errors": "^3.0.0",
|
28
|
+
"ajv-formats": "^3.0.1",
|
28
29
|
"lunr": "^2.3.9",
|
29
30
|
"slugify": "^1.6.6",
|
30
31
|
"ulid": "^2.3.0"
|
package/src/SchemaCompiler.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import Type from './type/index.js';
|
2
2
|
import ajv from 'ajv';
|
3
3
|
import ajvErrors from 'ajv-errors';
|
4
|
+
import ajvFormats from 'ajv-formats';
|
4
5
|
|
5
6
|
/**
|
6
7
|
* @class SchemaCompiler
|
@@ -15,6 +16,7 @@ export default class SchemaCompiler {
|
|
15
16
|
const validation = new ajv({allErrors: true});
|
16
17
|
|
17
18
|
ajvErrors(validation);
|
19
|
+
ajvFormats(validation);
|
18
20
|
|
19
21
|
const schema = {
|
20
22
|
type: 'object',
|
@@ -58,9 +60,17 @@ export default class SchemaCompiler {
|
|
58
60
|
|
59
61
|
schema.properties[name] = {type: property?._type};
|
60
62
|
|
63
|
+
if (property?._format) {
|
64
|
+
schema.properties[name].format = property._format;
|
65
|
+
}
|
66
|
+
|
61
67
|
if (property?._type === 'array') {
|
62
68
|
schema.properties[name].items = {type: property?._items._type};
|
63
69
|
|
70
|
+
if (property?._items?._format) {
|
71
|
+
schema.properties[name].items.format = property?._items._format;
|
72
|
+
}
|
73
|
+
|
64
74
|
if (Type.Model.isModel(property?._items)) {
|
65
75
|
schema.properties[name].items = {
|
66
76
|
type: 'object',
|
@@ -102,11 +112,14 @@ export class CompiledSchema {
|
|
102
112
|
* @throws {ValidationError}
|
103
113
|
*/
|
104
114
|
static validate(data) {
|
105
|
-
let inputData = data;
|
115
|
+
let inputData = Object.assign({}, data);
|
116
|
+
|
106
117
|
if (Type.Model.isModel(data)) {
|
107
118
|
inputData = data.toData();
|
108
119
|
}
|
120
|
+
|
109
121
|
const valid = this._validator?.(inputData);
|
122
|
+
|
110
123
|
if (valid) return valid;
|
111
124
|
|
112
125
|
throw new ValidationError(inputData, this._validator.errors);
|
package/src/type/Model.js
CHANGED
@@ -93,6 +93,17 @@ export default class Model {
|
|
93
93
|
|
94
94
|
for (const [name, value] of Object.entries(data)) {
|
95
95
|
if (this[name]?._resolved) continue;
|
96
|
+
|
97
|
+
if (this[name].name.endsWith('DateType')) {
|
98
|
+
model[name] = new Date(value);
|
99
|
+
continue;
|
100
|
+
}
|
101
|
+
|
102
|
+
if (this[name].name.endsWith('ArrayOf(Date)Type')) {
|
103
|
+
model[name] = data[name].map(d => new Date(d));
|
104
|
+
continue;
|
105
|
+
}
|
106
|
+
|
96
107
|
model[name] = value;
|
97
108
|
}
|
98
109
|
|
@@ -107,9 +118,13 @@ export default class Model {
|
|
107
118
|
}
|
108
119
|
|
109
120
|
static isDryModel(possibleDryModel) {
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
121
|
+
try {
|
122
|
+
return (
|
123
|
+
Object.keys(possibleDryModel).includes('id') &&
|
124
|
+
!!possibleDryModel.id.match(/[A-Za-z]+\/[A-Z0-9]+/)
|
125
|
+
);
|
126
|
+
} catch (_) {
|
127
|
+
return false;
|
128
|
+
}
|
114
129
|
}
|
115
130
|
}
|
@@ -7,7 +7,7 @@ export default class ArrayType {
|
|
7
7
|
static _items = type;
|
8
8
|
|
9
9
|
static toString() {
|
10
|
-
return `ArrayOf(${type})`;
|
10
|
+
return `ArrayOf(${type.toString()})`;
|
11
11
|
}
|
12
12
|
|
13
13
|
static get required() {
|
@@ -25,6 +25,8 @@ export default class ArrayType {
|
|
25
25
|
}
|
26
26
|
}
|
27
27
|
|
28
|
+
Object.defineProperty(ArrayOf, 'name', {value: `${ArrayOf.toString()}Type`});
|
29
|
+
|
28
30
|
return ArrayOf;
|
29
31
|
}
|
30
32
|
}
|
package/src/type/index.js
CHANGED
@@ -1,18 +1,36 @@
|
|
1
1
|
import ArrayType from './complex/ArrayType.js';
|
2
2
|
import BooleanType from './simple/BooleanType.js';
|
3
3
|
import CustomType from './complex/CustomType.js';
|
4
|
+
import DateType from './simple/DateType.js';
|
4
5
|
import Model from './Model.js';
|
5
6
|
import NumberType from './simple/NumberType.js';
|
6
7
|
import SlugType from './resolved/SlugType.js';
|
7
8
|
import StringType from './simple/StringType.js';
|
8
9
|
|
10
|
+
/**
|
11
|
+
* @class Type
|
12
|
+
* @property {StringType} String
|
13
|
+
* @property {NumberType} Number
|
14
|
+
* @property {BooleanType} Boolean
|
15
|
+
* @property {DateType} Date
|
16
|
+
* @property {ArrayType} Array
|
17
|
+
* @property {CustomType} Custom
|
18
|
+
* @property {ResolvedType} Resolved
|
19
|
+
* @property {Model} Model
|
20
|
+
*/
|
9
21
|
const Type = {};
|
10
22
|
|
11
23
|
Type.String = StringType;
|
12
24
|
Type.Number = NumberType;
|
13
25
|
Type.Boolean = BooleanType;
|
26
|
+
Type.Date = DateType;
|
14
27
|
Type.Array = ArrayType;
|
15
28
|
Type.Custom = CustomType;
|
29
|
+
|
30
|
+
/**
|
31
|
+
* @class ResolvedType
|
32
|
+
* @property {SlugType} Slug
|
33
|
+
*/
|
16
34
|
Type.Resolved = {Slug: SlugType};
|
17
35
|
Type.Model = Model;
|
18
36
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import SimpleType from './SimpleType.js';
|
2
|
+
|
3
|
+
export default class DateType extends SimpleType {
|
4
|
+
static _type = 'string';
|
5
|
+
static _format = 'iso-date-time';
|
6
|
+
|
7
|
+
static isDate(possibleDate) {
|
8
|
+
return possibleDate instanceof Date || !isNaN(new Date(possibleDate));
|
9
|
+
}
|
10
|
+
}
|