@strapi/database 4.3.2 → 4.3.5
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/jest.config.js +1 -1
- package/lib/__tests__/lifecycles.test.js +1 -1
- package/lib/connection.js +4 -4
- package/lib/dialects/dialect.js +8 -2
- package/lib/dialects/index.js +2 -2
- package/lib/dialects/mysql/index.js +2 -2
- package/lib/dialects/mysql/schema-inspector.js +12 -16
- package/lib/dialects/postgresql/index.js +2 -2
- package/lib/dialects/postgresql/schema-inspector.js +30 -25
- package/lib/dialects/sqlite/index.js +1 -1
- package/lib/dialects/sqlite/schema-inspector.js +5 -5
- package/lib/entity-manager.js +29 -61
- package/lib/entity-repository.js +1 -1
- package/lib/errors/database.js +12 -0
- package/lib/errors/index.js +15 -0
- package/lib/errors/invalid-date.js +14 -0
- package/lib/errors/invalid-datetime.js +14 -0
- package/lib/errors/invalid-time.js +14 -0
- package/lib/errors/not-null.js +15 -0
- package/lib/fields/biginteger.js +17 -0
- package/lib/fields/boolean.js +39 -0
- package/lib/fields/date.js +16 -0
- package/lib/fields/datetime.js +19 -0
- package/lib/fields/field.js +17 -0
- package/lib/{fields.d.ts → fields/index.d.ts} +0 -0
- package/lib/fields/index.js +49 -0
- package/lib/fields/json.js +16 -0
- package/lib/fields/number.js +23 -0
- package/lib/fields/shared/parsers.js +69 -0
- package/lib/fields/string.js +17 -0
- package/lib/fields/time.js +17 -0
- package/lib/fields/timestamp.js +19 -0
- package/lib/index.js +1 -1
- package/lib/lifecycles/index.js +2 -2
- package/lib/lifecycles/subscribers/models-lifecycles.js +1 -1
- package/lib/lifecycles/subscribers/timestamps.js +2 -2
- package/lib/metadata/index.js +2 -2
- package/lib/metadata/relations.js +12 -15
- package/lib/migrations/index.js +5 -5
- package/lib/migrations/storage.js +4 -11
- package/lib/query/helpers/join.js +5 -5
- package/lib/query/helpers/order-by.js +1 -1
- package/lib/query/helpers/populate.js +43 -51
- package/lib/query/helpers/search.js +5 -5
- package/lib/query/helpers/transform.js +2 -2
- package/lib/query/helpers/where.js +17 -17
- package/lib/query/query-builder.js +17 -17
- package/lib/schema/builder.js +16 -14
- package/lib/schema/diff.js +16 -16
- package/lib/schema/index.js +1 -2
- package/lib/schema/schema.js +4 -4
- package/lib/schema/storage.js +3 -6
- package/lib/types/index.js +6 -6
- package/lib/utils/content-types.js +3 -3
- package/package.json +3 -3
- package/lib/errors.js +0 -56
- package/lib/fields.js +0 -231
package/lib/schema/diff.js
CHANGED
|
@@ -14,36 +14,36 @@ const statuses = {
|
|
|
14
14
|
|
|
15
15
|
const helpers = {
|
|
16
16
|
hasTable(schema, tableName) {
|
|
17
|
-
return schema.tables.findIndex(table => table.name === tableName) !== -1;
|
|
17
|
+
return schema.tables.findIndex((table) => table.name === tableName) !== -1;
|
|
18
18
|
},
|
|
19
19
|
findTable(schema, tableName) {
|
|
20
|
-
return schema.tables.find(table => table.name === tableName);
|
|
20
|
+
return schema.tables.find((table) => table.name === tableName);
|
|
21
21
|
},
|
|
22
22
|
|
|
23
23
|
hasColumn(table, columnName) {
|
|
24
|
-
return table.columns.findIndex(column => column.name === columnName) !== -1;
|
|
24
|
+
return table.columns.findIndex((column) => column.name === columnName) !== -1;
|
|
25
25
|
},
|
|
26
26
|
findColumn(table, columnName) {
|
|
27
|
-
return table.columns.find(column => column.name === columnName);
|
|
27
|
+
return table.columns.find((column) => column.name === columnName);
|
|
28
28
|
},
|
|
29
29
|
|
|
30
30
|
hasIndex(table, columnName) {
|
|
31
|
-
return table.indexes.findIndex(column => column.name === columnName) !== -1;
|
|
31
|
+
return table.indexes.findIndex((column) => column.name === columnName) !== -1;
|
|
32
32
|
},
|
|
33
33
|
findIndex(table, columnName) {
|
|
34
|
-
return table.indexes.find(column => column.name === columnName);
|
|
34
|
+
return table.indexes.find((column) => column.name === columnName);
|
|
35
35
|
},
|
|
36
36
|
|
|
37
37
|
hasForeignKey(table, columnName) {
|
|
38
|
-
return table.foreignKeys.findIndex(column => column.name === columnName) !== -1;
|
|
38
|
+
return table.foreignKeys.findIndex((column) => column.name === columnName) !== -1;
|
|
39
39
|
},
|
|
40
40
|
findForeignKey(table, columnName) {
|
|
41
|
-
return table.foreignKeys.find(column => column.name === columnName);
|
|
41
|
+
return table.foreignKeys.find((column) => column.name === columnName);
|
|
42
42
|
},
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
module.exports = db => {
|
|
46
|
-
const hasChangedStatus = diff => diff.status === statuses.CHANGED;
|
|
45
|
+
module.exports = (db) => {
|
|
46
|
+
const hasChangedStatus = (diff) => diff.status === statuses.CHANGED;
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Compares two indexes info
|
|
@@ -53,7 +53,7 @@ module.exports = db => {
|
|
|
53
53
|
const diffIndexes = (oldIndex, index) => {
|
|
54
54
|
const changes = [];
|
|
55
55
|
|
|
56
|
-
if (_.
|
|
56
|
+
if (!_.isEqual(oldIndex.columns, index.columns)) {
|
|
57
57
|
changes.push('columns');
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -117,7 +117,7 @@ module.exports = db => {
|
|
|
117
117
|
|
|
118
118
|
const diffDefault = (oldColumn, column) => {
|
|
119
119
|
const oldDefaultTo = oldColumn.defaultTo;
|
|
120
|
-
const defaultTo = column
|
|
120
|
+
const { defaultTo } = column;
|
|
121
121
|
|
|
122
122
|
if (oldDefaultTo === null || _.toLower(oldDefaultTo) === 'null') {
|
|
123
123
|
return _.isNil(defaultTo) || _.toLower(defaultTo) === 'null';
|
|
@@ -197,7 +197,7 @@ module.exports = db => {
|
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
const hasChanged = [addedColumns, updatedColumns, removedColumns].some(arr => arr.length > 0);
|
|
200
|
+
const hasChanged = [addedColumns, updatedColumns, removedColumns].some((arr) => arr.length > 0);
|
|
201
201
|
|
|
202
202
|
return {
|
|
203
203
|
status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED,
|
|
@@ -237,7 +237,7 @@ module.exports = db => {
|
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
const hasChanged = [addedIndexes, updatedIndexes, removedIndexes].some(arr => arr.length > 0);
|
|
240
|
+
const hasChanged = [addedIndexes, updatedIndexes, removedIndexes].some((arr) => arr.length > 0);
|
|
241
241
|
|
|
242
242
|
return {
|
|
243
243
|
status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED,
|
|
@@ -290,7 +290,7 @@ module.exports = db => {
|
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
const hasChanged = [addedForeignKeys, updatedForeignKeys, removedForeignKeys].some(
|
|
293
|
-
arr => arr.length > 0
|
|
293
|
+
(arr) => arr.length > 0
|
|
294
294
|
);
|
|
295
295
|
|
|
296
296
|
return {
|
|
@@ -353,7 +353,7 @@ module.exports = db => {
|
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
355
|
|
|
356
|
-
const hasChanged = [addedTables, updatedTables, removedTables].some(arr => arr.length > 0);
|
|
356
|
+
const hasChanged = [addedTables, updatedTables, removedTables].some((arr) => arr.length > 0);
|
|
357
357
|
|
|
358
358
|
return {
|
|
359
359
|
status: hasChanged ? statuses.CHANGED : statuses.UNCHANGED,
|
package/lib/schema/index.js
CHANGED
|
@@ -10,7 +10,7 @@ const { metadataToSchema } = require('./schema');
|
|
|
10
10
|
/**
|
|
11
11
|
* @type {import('.').default}
|
|
12
12
|
*/
|
|
13
|
-
const createSchemaProvider = db => {
|
|
13
|
+
const createSchemaProvider = (db) => {
|
|
14
14
|
const schema = metadataToSchema(db.metadata);
|
|
15
15
|
|
|
16
16
|
return {
|
|
@@ -87,7 +87,6 @@ const createSchemaProvider = db => {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
debug('Schema unchanged');
|
|
90
|
-
return;
|
|
91
90
|
},
|
|
92
91
|
};
|
|
93
92
|
};
|
package/lib/schema/schema.js
CHANGED
|
@@ -17,7 +17,7 @@ const createColumn = (name, attribute) => {
|
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
const createTable = meta => {
|
|
20
|
+
const createTable = (meta) => {
|
|
21
21
|
const table = {
|
|
22
22
|
name: meta.tableName,
|
|
23
23
|
indexes: meta.indexes || [],
|
|
@@ -96,7 +96,7 @@ const createTable = meta => {
|
|
|
96
96
|
return table;
|
|
97
97
|
};
|
|
98
98
|
|
|
99
|
-
const getColumnType = attribute => {
|
|
99
|
+
const getColumnType = (attribute) => {
|
|
100
100
|
if (attribute.columnType) {
|
|
101
101
|
return attribute.columnType;
|
|
102
102
|
}
|
|
@@ -182,7 +182,7 @@ const getColumnType = attribute => {
|
|
|
182
182
|
}
|
|
183
183
|
};
|
|
184
184
|
|
|
185
|
-
const metadataToSchema = metadata => {
|
|
185
|
+
const metadataToSchema = (metadata) => {
|
|
186
186
|
const schema = {
|
|
187
187
|
tables: [],
|
|
188
188
|
addTable(table) {
|
|
@@ -191,7 +191,7 @@ const metadataToSchema = metadata => {
|
|
|
191
191
|
},
|
|
192
192
|
};
|
|
193
193
|
|
|
194
|
-
metadata.forEach(metadata => {
|
|
194
|
+
metadata.forEach((metadata) => {
|
|
195
195
|
schema.addTable(createTable(metadata));
|
|
196
196
|
});
|
|
197
197
|
|
package/lib/schema/storage.js
CHANGED
|
@@ -4,11 +4,11 @@ const crypto = require('crypto');
|
|
|
4
4
|
|
|
5
5
|
const TABLE_NAME = 'strapi_database_schema';
|
|
6
6
|
|
|
7
|
-
module.exports = db => {
|
|
7
|
+
module.exports = (db) => {
|
|
8
8
|
const hasSchemaTable = () => db.getSchemaConnection().hasTable(TABLE_NAME);
|
|
9
9
|
|
|
10
10
|
const createSchemaTable = () => {
|
|
11
|
-
return db.getSchemaConnection().createTable(TABLE_NAME, t => {
|
|
11
|
+
return db.getSchemaConnection().createTable(TABLE_NAME, (t) => {
|
|
12
12
|
t.increments('id');
|
|
13
13
|
t.json('schema');
|
|
14
14
|
t.datetime('time', { useTz: false });
|
|
@@ -46,10 +46,7 @@ module.exports = db => {
|
|
|
46
46
|
},
|
|
47
47
|
|
|
48
48
|
hashSchema(schema) {
|
|
49
|
-
return crypto
|
|
50
|
-
.createHash('md5')
|
|
51
|
-
.update(JSON.stringify(schema))
|
|
52
|
-
.digest('hex');
|
|
49
|
+
return crypto.createHash('md5').update(JSON.stringify(schema)).digest('hex');
|
|
53
50
|
},
|
|
54
51
|
|
|
55
52
|
async add(schema) {
|
package/lib/types/index.js
CHANGED
|
@@ -25,10 +25,10 @@ const STRING_TYPES = ['string', 'text', 'uid', 'email', 'enumeration', 'richtext
|
|
|
25
25
|
const NUMBER_TYPES = ['biginteger', 'integer', 'decimal', 'float'];
|
|
26
26
|
|
|
27
27
|
module.exports = {
|
|
28
|
-
isString: type => STRING_TYPES.includes(type),
|
|
29
|
-
isNumber: type => NUMBER_TYPES.includes(type),
|
|
30
|
-
isScalar: type => SCALAR_TYPES.includes(type),
|
|
31
|
-
isComponent: type => type === 'component',
|
|
32
|
-
isDynamicZone: type => type === 'dynamiczone',
|
|
33
|
-
isRelation: type => type === 'relation',
|
|
28
|
+
isString: (type) => STRING_TYPES.includes(type),
|
|
29
|
+
isNumber: (type) => NUMBER_TYPES.includes(type),
|
|
30
|
+
isScalar: (type) => SCALAR_TYPES.includes(type),
|
|
31
|
+
isComponent: (type) => type === 'component',
|
|
32
|
+
isDynamicZone: (type) => type === 'dynamiczone',
|
|
33
|
+
isRelation: (type) => type === 'relation',
|
|
34
34
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const transformAttribute = attribute => {
|
|
3
|
+
const transformAttribute = (attribute) => {
|
|
4
4
|
switch (attribute.type) {
|
|
5
5
|
case 'media': {
|
|
6
6
|
return {
|
|
@@ -17,8 +17,8 @@ const transformAttribute = attribute => {
|
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
// TODO: model logic outside DB
|
|
20
|
-
const transformContentTypes = contentTypes => {
|
|
21
|
-
return contentTypes.map(contentType => {
|
|
20
|
+
const transformContentTypes = (contentTypes) => {
|
|
21
|
+
return contentTypes.map((contentType) => {
|
|
22
22
|
const model = {
|
|
23
23
|
...contentType,
|
|
24
24
|
// reuse new model def
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/database",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.5",
|
|
4
4
|
"description": "Strapi's database layer",
|
|
5
5
|
"homepage": "https://strapi.io",
|
|
6
6
|
"bugs": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"test:unit": "jest --verbose"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"date-fns": "2.
|
|
34
|
+
"date-fns": "2.29.2",
|
|
35
35
|
"debug": "4.3.1",
|
|
36
36
|
"fs-extra": "10.0.0",
|
|
37
37
|
"knex": "1.0.7",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"node": ">=14.19.1 <=16.x.x",
|
|
43
43
|
"npm": ">=6.0.0"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "a52b0535513ff35b4ef46c9daf7be48f2ba71737"
|
|
46
46
|
}
|
package/lib/errors.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/* DatabaseError */
|
|
4
|
-
class DatabaseError extends Error {
|
|
5
|
-
constructor(message, details = {}) {
|
|
6
|
-
super();
|
|
7
|
-
this.name = 'DatabaseError';
|
|
8
|
-
this.message = message || 'A database error occured';
|
|
9
|
-
this.details = details;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
class NotNullConstraint extends DatabaseError {
|
|
14
|
-
constructor({ column = '' } = {}) {
|
|
15
|
-
super();
|
|
16
|
-
this.name = 'NotNullConstraint';
|
|
17
|
-
this.message = `Not null constraint violation${column ? ` on column ${column}` : ''}.`;
|
|
18
|
-
this.details = { column };
|
|
19
|
-
this.stack = '';
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
class InvalidTimeError extends DatabaseError {
|
|
24
|
-
constructor(message) {
|
|
25
|
-
super();
|
|
26
|
-
this.name = 'InvalidTimeFormat';
|
|
27
|
-
this.message = message || 'Invalid time format, expected HH:mm:ss.SSS';
|
|
28
|
-
this.details = {};
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
class InvalidDateError extends DatabaseError {
|
|
33
|
-
constructor(message) {
|
|
34
|
-
super();
|
|
35
|
-
this.name = 'InvalidTimeFormat';
|
|
36
|
-
this.message = message || 'Invalid date format, expected YYYY-MM-DD';
|
|
37
|
-
this.details = {};
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
class InvalidDateTimeError extends DatabaseError {
|
|
42
|
-
constructor(message) {
|
|
43
|
-
super();
|
|
44
|
-
this.name = 'InvalidTimeFormat';
|
|
45
|
-
this.message = message || 'Invalid datetime format, expected a timestamp or an ISO date';
|
|
46
|
-
this.details = {};
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
module.exports = {
|
|
51
|
-
DatabaseError,
|
|
52
|
-
NotNullConstraint,
|
|
53
|
-
InvalidTimeError,
|
|
54
|
-
InvalidDateError,
|
|
55
|
-
InvalidDateTimeError,
|
|
56
|
-
};
|
package/lib/fields.js
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const _ = require('lodash/fp');
|
|
4
|
-
const dateFns = require('date-fns');
|
|
5
|
-
const { InvalidTimeError, InvalidDateError, InvalidDateTimeError } = require('./errors');
|
|
6
|
-
|
|
7
|
-
class Field {
|
|
8
|
-
constructor(config) {
|
|
9
|
-
this.config = config;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
toDB(value) {
|
|
13
|
-
return value;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
fromDB(value) {
|
|
17
|
-
return value;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
class StringField extends Field {
|
|
22
|
-
toDB(value) {
|
|
23
|
-
return _.toString(value);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
fromDB(value) {
|
|
27
|
-
return _.toString(value);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
class JSONField extends Field {
|
|
32
|
-
toDB(value) {
|
|
33
|
-
return JSON.stringify(value);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
fromDB(value) {
|
|
37
|
-
if (typeof value === 'string') return JSON.parse(value);
|
|
38
|
-
return value;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
class BooleanField extends Field {
|
|
43
|
-
toDB(value) {
|
|
44
|
-
if (typeof value === 'boolean') return value;
|
|
45
|
-
|
|
46
|
-
if (['true', 't', '1', 1].includes(value)) {
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (['false', 'f', '0', 0].includes(value)) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return Boolean(value);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
fromDB(value) {
|
|
58
|
-
if (typeof value === 'boolean') {
|
|
59
|
-
return value;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const strVal = _.toString(value);
|
|
63
|
-
|
|
64
|
-
if (strVal === '1') {
|
|
65
|
-
return true;
|
|
66
|
-
} else if (strVal === '0') {
|
|
67
|
-
return false;
|
|
68
|
-
} else {
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
class NumberField extends Field {
|
|
75
|
-
toDB(value) {
|
|
76
|
-
const numberValue = _.toNumber(value);
|
|
77
|
-
|
|
78
|
-
if (Number.isNaN(numberValue)) {
|
|
79
|
-
throw new Error(`Expected a valid Number, got ${value}`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return numberValue;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
fromDB(value) {
|
|
86
|
-
return _.toNumber(value);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
class BigIntegerField extends NumberField {
|
|
91
|
-
toDB(value) {
|
|
92
|
-
return _.toString(value);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
fromDB(value) {
|
|
96
|
-
return _.toString(value);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const timeRegex = new RegExp('^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]{1,3})?$');
|
|
101
|
-
const dateRegex = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;
|
|
102
|
-
const partialDateRegex = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])/g;
|
|
103
|
-
|
|
104
|
-
const parseTime = value => {
|
|
105
|
-
if (dateFns.isDate(value)) return dateFns.format(value, 'HH:mm:ss.SSS');
|
|
106
|
-
|
|
107
|
-
if (typeof value !== 'string') {
|
|
108
|
-
throw new InvalidTimeError(`Expected a string, got a ${typeof value}`);
|
|
109
|
-
}
|
|
110
|
-
const result = value.match(timeRegex);
|
|
111
|
-
|
|
112
|
-
if (result === null) {
|
|
113
|
-
throw new InvalidTimeError('Invalid time format, expected HH:mm:ss.SSS');
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const [, hours, minutes, seconds, fraction = '.000'] = result;
|
|
117
|
-
const fractionPart = _.padCharsEnd('0', 3, fraction.slice(1));
|
|
118
|
-
|
|
119
|
-
return `${hours}:${minutes}:${seconds}.${fractionPart}`;
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
const parseDate = value => {
|
|
123
|
-
const found = _.isString(value) ? value.match(partialDateRegex) || [] : [];
|
|
124
|
-
const extractedValue = found[0];
|
|
125
|
-
|
|
126
|
-
if (extractedValue && !dateRegex.test(value)) {
|
|
127
|
-
// TODO V5: throw an error when format yyyy-MM-dd is not respected
|
|
128
|
-
// throw new InvalidDateError(`Invalid format, expected yyyy-MM-dd`);
|
|
129
|
-
process.emitWarning(
|
|
130
|
-
`[deprecated] Using a date format other than YYYY-MM-DD will be removed in future versions. Date received: ${value}. Date stored: ${extractedValue}.`
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
let date = dateFns.parseISO(extractedValue);
|
|
135
|
-
if (!dateFns.isValid(date)) {
|
|
136
|
-
throw new InvalidDateError(`Invalid date`);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return extractedValue;
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const parseDateTimeOrTimestamp = value => {
|
|
143
|
-
if (dateFns.isDate(value)) return value;
|
|
144
|
-
try {
|
|
145
|
-
const date = dateFns.parseISO(value);
|
|
146
|
-
if (dateFns.isValid(date)) return date;
|
|
147
|
-
|
|
148
|
-
const milliUnixDate = dateFns.parse(value, 'T', new Date());
|
|
149
|
-
if (dateFns.isValid(milliUnixDate)) return milliUnixDate;
|
|
150
|
-
|
|
151
|
-
throw new InvalidDateTimeError(`Invalid format, expected a timestamp or an ISO date`);
|
|
152
|
-
} catch (error) {
|
|
153
|
-
throw new InvalidDateTimeError(`Invalid format, expected a timestamp or an ISO date`);
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
class DateField extends Field {
|
|
158
|
-
toDB(value) {
|
|
159
|
-
return parseDate(value);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
fromDB(value) {
|
|
163
|
-
return value;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
class DatetimeField extends Field {
|
|
167
|
-
toDB(value) {
|
|
168
|
-
return parseDateTimeOrTimestamp(value);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
fromDB(value) {
|
|
172
|
-
const cast = new Date(value);
|
|
173
|
-
return dateFns.isValid(cast) ? cast.toISOString() : null;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
class TimeField extends Field {
|
|
178
|
-
toDB(value) {
|
|
179
|
-
return parseTime(value);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
fromDB(value) {
|
|
183
|
-
// make sure that's a string with valid format ?
|
|
184
|
-
return value;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
class TimestampField extends Field {
|
|
188
|
-
toDB(value) {
|
|
189
|
-
return parseDateTimeOrTimestamp(value);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
fromDB(value) {
|
|
193
|
-
const cast = new Date(value);
|
|
194
|
-
return dateFns.isValid(cast) ? dateFns.format(cast, 'T') : null;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const typeToFieldMap = {
|
|
199
|
-
increments: Field,
|
|
200
|
-
password: StringField,
|
|
201
|
-
email: StringField,
|
|
202
|
-
string: StringField,
|
|
203
|
-
uid: StringField,
|
|
204
|
-
richtext: StringField,
|
|
205
|
-
text: StringField,
|
|
206
|
-
enumeration: StringField,
|
|
207
|
-
json: JSONField,
|
|
208
|
-
biginteger: BigIntegerField,
|
|
209
|
-
integer: NumberField,
|
|
210
|
-
float: NumberField,
|
|
211
|
-
decimal: NumberField,
|
|
212
|
-
date: DateField,
|
|
213
|
-
time: TimeField,
|
|
214
|
-
datetime: DatetimeField,
|
|
215
|
-
timestamp: TimestampField,
|
|
216
|
-
boolean: BooleanField,
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
const createField = attribute => {
|
|
220
|
-
const { type } = attribute;
|
|
221
|
-
|
|
222
|
-
if (_.has(type, typeToFieldMap)) {
|
|
223
|
-
return new typeToFieldMap[type]({});
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
throw new Error(`Undefined field for type ${type}`);
|
|
227
|
-
};
|
|
228
|
-
|
|
229
|
-
module.exports = {
|
|
230
|
-
createField,
|
|
231
|
-
};
|