mythix-orm 1.6.3 → 1.7.0
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/lib/connection/connection-base.d.ts +17 -12
- package/lib/connection/connection-base.js +20 -18
- package/lib/connection/query-generator-base.js +1 -1
- package/lib/field.js +1 -0
- package/lib/model.js +12 -2
- package/lib/types/concrete/date-type.js +39 -32
- package/lib/types/concrete/datetime-type.js +33 -30
- package/lib/types/helpers/default-helpers.d.ts +2 -1
- package/lib/utils/index.js +2 -0
- package/lib/utils/misc-utils.d.ts +2 -0
- package/lib/utils/misc-utils.js +26 -0
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import {
|
|
2
|
+
import { DateTime } from 'luxon';
|
|
3
3
|
import { Literals } from '.';
|
|
4
4
|
import Field from '../field';
|
|
5
5
|
import { GenericObject } from '../interfaces/common';
|
|
@@ -120,7 +120,7 @@ declare class ConnectionBase extends EventEmitter {
|
|
|
120
120
|
public _uuidV5TypeToString(type: UUIDV5Type): string;
|
|
121
121
|
public _xidTypeToString(type: XIDType): string;
|
|
122
122
|
public typeToString(type: Type, options?: GenericObject): string;
|
|
123
|
-
public convertDateToDBTime(value: Date |
|
|
123
|
+
public convertDateToDBTime(value: Date | DateTime, type: Type): Date;
|
|
124
124
|
public ensureAllModelsAreInstances(Model: ModelClass, models: Array<Model | GenericObject> | PreparedModels, options?: GenericObject): Array<Model>;
|
|
125
125
|
public prepareAllModelsForOperation(Model: ModelClass, models: Array<Model | GenericObject> | PreparedModels, options?: GenericObject): PreparedModels;
|
|
126
126
|
public splitModelAndSubModels(Model: ModelClass, primaryModel: Model, relationMap?: Map<string, Set<Model>>): Map<string, Set<Model>>;
|
|
@@ -141,20 +141,24 @@ declare class ConnectionBase extends EventEmitter {
|
|
|
141
141
|
public stop(): Promise<void>;
|
|
142
142
|
|
|
143
143
|
public runSaveHooks(Model: ModelClass, models: Array<Model>, operationHookName: string, saveHookName: string, options: GenericObject): Promise<Array<any>>;
|
|
144
|
+
|
|
145
|
+
public defineTable(): Promise<any>;
|
|
146
|
+
public defineConstraints(): Promise<any>;
|
|
147
|
+
public defineIndexes(): Promise<any>;
|
|
148
|
+
|
|
144
149
|
public dropTable(Model: ModelClass, options?: GenericObject): Promise<any>;
|
|
145
150
|
public dropTables(Models: Models, options?: GenericObject): Promise<Array<any>>;
|
|
146
151
|
public createTable(Model: ModelClass, options?: GenericObject): Promise<any>;
|
|
147
152
|
public createTables(Models: Models, options?: GenericObject): Promise<Array<any>>;
|
|
148
|
-
public
|
|
149
|
-
|
|
150
|
-
public
|
|
151
|
-
public
|
|
152
|
-
public
|
|
153
|
-
|
|
154
|
-
public
|
|
155
|
-
public
|
|
156
|
-
|
|
157
|
-
public addIndex(): Promise<any>;
|
|
153
|
+
public alterTable(Model: ModelClass, newModelAttributes: GenericObject, options?: GenericObject): Promise<void>;
|
|
154
|
+
|
|
155
|
+
public dropColumn(Field: Field, options?: GenericObject): Promise<void>;
|
|
156
|
+
public alterColumn(Field: Field, newFieldAttributes: GenericObject, options?: GenericObject): Promise<void>;
|
|
157
|
+
public addColumn(Field: Field, options?: GenericObject): Promise<void>;
|
|
158
|
+
|
|
159
|
+
public addIndex(Model: ModelClass, indexFieldNames?: Array<string>, options?: GenericObject): Promise<void>;
|
|
160
|
+
public dropIndex(Model: ModelClass, indexFieldNames?: Array<string>, options?: GenericObject): Promise<void>;
|
|
161
|
+
|
|
158
162
|
public insert(Model: ModelClass, models: Array<Model | GenericObject> | Model | GenericObject, options?: GenericObject): Promise<Array<Models> | undefined>;
|
|
159
163
|
public upsert(Model: ModelClass, models: Array<Model | GenericObject> | Model | GenericObject, options?: GenericObject): Promise<Array<Models> | undefined>;
|
|
160
164
|
public update(Model: ModelClass, models: Array<Model | GenericObject> | Model | GenericObject, options?: GenericObject): Promise<Array<Models> | undefined>;
|
|
@@ -171,6 +175,7 @@ declare class ConnectionBase extends EventEmitter {
|
|
|
171
175
|
public pluck(queryEngine: QueryEngine, fields: Array<Field> | Array<string> | Field | string, options?: GenericObject): Promise<Array<any> | Array<Array<any>>>;
|
|
172
176
|
public exists(queryEngine: QueryEngine, options?: GenericObject): Promise<boolean>;
|
|
173
177
|
public truncate(Model: ModelClass, options?: GenericObject): Promise<void>;
|
|
178
|
+
|
|
174
179
|
public query(sql: string | GenericObject, options?: GenericObject): Promise<any>;
|
|
175
180
|
public transaction(callback: (connection: ConnectionBase) => any, options?: GenericObject): Promise<any>;
|
|
176
181
|
public getDefaultFieldValue(type: string | LiteralBase, context: DefaultValueContext): Promise<any>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { DateTime } = require('luxon');
|
|
4
4
|
const EventEmitter = require('events');
|
|
5
5
|
const Nife = require('nife');
|
|
6
6
|
const SqlString = require('sqlstring');
|
|
@@ -479,12 +479,12 @@ class ConnectionBase extends EventEmitter {
|
|
|
479
479
|
|
|
480
480
|
// eslint-disable-next-line no-unused-vars
|
|
481
481
|
_dateTypeToString(type) {
|
|
482
|
-
return '
|
|
482
|
+
return 'TIMESTAMP';
|
|
483
483
|
}
|
|
484
484
|
|
|
485
485
|
// eslint-disable-next-line no-unused-vars
|
|
486
486
|
_datetimeTypeToString(type) {
|
|
487
|
-
return '
|
|
487
|
+
return 'TIMESTAMP';
|
|
488
488
|
}
|
|
489
489
|
|
|
490
490
|
// eslint-disable-next-line no-unused-vars
|
|
@@ -574,11 +574,17 @@ class ConnectionBase extends EventEmitter {
|
|
|
574
574
|
throw new Error(`${this.constructor.name}::typeToString: Unsupported type ${type}.`);
|
|
575
575
|
}
|
|
576
576
|
|
|
577
|
-
convertDateToDBTime(value) {
|
|
578
|
-
if (
|
|
577
|
+
convertDateToDBTime(value, type) {
|
|
578
|
+
if (Nife.instanceOf(value, 'number'))
|
|
579
579
|
return value;
|
|
580
|
-
else if (
|
|
581
|
-
return value.
|
|
580
|
+
else if (Nife.instanceOf(value, 'bigint'))
|
|
581
|
+
return Number(value).valueOf();
|
|
582
|
+
else if (DateTime.isDateTime(value))
|
|
583
|
+
return value.toMillis();
|
|
584
|
+
else if (value instanceof Date || (value && value.constructor && value.constructor.name === 'Date'))
|
|
585
|
+
return value.valueOf();
|
|
586
|
+
else if (Nife.instanceOf(value, 'string'))
|
|
587
|
+
return DateTime.fromISO(value).toMillis();
|
|
582
588
|
|
|
583
589
|
return value;
|
|
584
590
|
}
|
|
@@ -1112,31 +1118,27 @@ class ConnectionBase extends EventEmitter {
|
|
|
1112
1118
|
|
|
1113
1119
|
// Alter operations
|
|
1114
1120
|
|
|
1115
|
-
async
|
|
1121
|
+
async alterTable(Model, newModelAttributes, options) {
|
|
1116
1122
|
throw new Error(`${this.constructor.name}::renameTable: This operation is not supported for this connection type.`);
|
|
1117
1123
|
}
|
|
1118
1124
|
|
|
1119
|
-
async
|
|
1120
|
-
throw new Error(`${this.constructor.name}::renameColumn: This operation is not supported for this connection type.`);
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
async dropColumn() {
|
|
1125
|
+
async dropColumn(Field, options) {
|
|
1124
1126
|
throw new Error(`${this.constructor.name}::dropColumn: This operation is not supported for this connection type.`);
|
|
1125
1127
|
}
|
|
1126
1128
|
|
|
1127
|
-
async alterColumn() {
|
|
1129
|
+
async alterColumn(Field, newFieldAttributes, options) {
|
|
1128
1130
|
throw new Error(`${this.constructor.name}::alterColumn: This operation is not supported for this connection type.`);
|
|
1129
1131
|
}
|
|
1130
1132
|
|
|
1131
|
-
async addColumn() {
|
|
1133
|
+
async addColumn(Field, options) {
|
|
1132
1134
|
throw new Error(`${this.constructor.name}::addColumn: This operation is not supported for this connection type.`);
|
|
1133
1135
|
}
|
|
1134
1136
|
|
|
1135
|
-
async
|
|
1136
|
-
throw new Error(`${this.constructor.name}::
|
|
1137
|
+
async addIndex(Model, indexFields, options) {
|
|
1138
|
+
throw new Error(`${this.constructor.name}::addIndex: This operation is not supported for this connection type.`);
|
|
1137
1139
|
}
|
|
1138
1140
|
|
|
1139
|
-
async
|
|
1141
|
+
async dropIndex(Model, indexFields, options) {
|
|
1140
1142
|
throw new Error(`${this.constructor.name}::addIndex: This operation is not supported for this connection type.`);
|
|
1141
1143
|
}
|
|
1142
1144
|
|
package/lib/field.js
CHANGED
package/lib/model.js
CHANGED
|
@@ -5,6 +5,7 @@ const Inflection = require('inflection');
|
|
|
5
5
|
const Type = require('./types/type');
|
|
6
6
|
const DefaultHelpers = require('./types/helpers/default-helpers');
|
|
7
7
|
const Field = require('./field');
|
|
8
|
+
const ModelUtils = require('./utils/model-utils');
|
|
8
9
|
|
|
9
10
|
/// Used as a unique key for cache.
|
|
10
11
|
/// Caches will generally be stored in
|
|
@@ -1319,13 +1320,22 @@ class Model {
|
|
|
1319
1320
|
/// Arguments:
|
|
1320
1321
|
/// fieldName: string
|
|
1321
1322
|
/// The specified field name to find. This **is not** the `columnName` of the field.
|
|
1322
|
-
static getField(
|
|
1323
|
+
static getField(_findFieldName) {
|
|
1323
1324
|
let fields = this.getFields();
|
|
1324
|
-
if (!fields || !
|
|
1325
|
+
if (!fields || !_findFieldName)
|
|
1325
1326
|
return;
|
|
1326
1327
|
|
|
1327
1328
|
let foundField;
|
|
1329
|
+
let def = ModelUtils.parseQualifiedName(_findFieldName);
|
|
1330
|
+
if (def.modelName && Nife.isEmpty(def.fieldNames)) {
|
|
1331
|
+
def.fieldNames = [ def.modelName ];
|
|
1332
|
+
def.modelName = undefined;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
if (def.modelName && def.modelName !== this.getModelName())
|
|
1336
|
+
throw new Error(`Model::getField: Can't find a field from another model. Field requested: "${_findFieldName}".`);
|
|
1328
1337
|
|
|
1338
|
+
let findFieldName = def.fieldNames[0];
|
|
1329
1339
|
this.iterateFields(({ field, fieldName, stop }) => {
|
|
1330
1340
|
if (fieldName === findFieldName) {
|
|
1331
1341
|
foundField = field;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const Nife = require('nife');
|
|
4
|
-
const
|
|
4
|
+
const { DateTime } = require('luxon');
|
|
5
5
|
const Type = require('../type');
|
|
6
6
|
const { DATE_NOW } = require('../helpers/default-helpers');
|
|
7
|
-
|
|
8
|
-
moment.suppressDeprecationWarnings = true;
|
|
7
|
+
const MiscUtils = require('../../utils/misc-utils');
|
|
9
8
|
|
|
10
9
|
/// `DATE` type.
|
|
11
10
|
///
|
|
@@ -13,7 +12,7 @@ moment.suppressDeprecationWarnings = true;
|
|
|
13
12
|
/// in the underlying database.
|
|
14
13
|
///
|
|
15
14
|
/// Client-side storage for this field will be backed by
|
|
16
|
-
/// a [
|
|
15
|
+
/// a Luxon [DateTime](https://moment.github.io/luxon/#/) instance.
|
|
17
16
|
///
|
|
18
17
|
/// You can optionally provide a `format` argument when constructing
|
|
19
18
|
/// this type. **This is a client-side format only**. It doesn't
|
|
@@ -24,7 +23,7 @@ moment.suppressDeprecationWarnings = true;
|
|
|
24
23
|
/// Example:
|
|
25
24
|
/// class Dates extends Model {
|
|
26
25
|
/// static fields = {
|
|
27
|
-
/// date1: Types.DATE('
|
|
26
|
+
/// date1: Types.DATE('yyyy-MM-dd'),
|
|
28
27
|
/// date2: new Types.DateType(),
|
|
29
28
|
/// };
|
|
30
29
|
/// }
|
|
@@ -66,8 +65,8 @@ class DateType extends Type {
|
|
|
66
65
|
/// Construct a new `DATE` type.
|
|
67
66
|
///
|
|
68
67
|
/// The `format` argument will specify the
|
|
69
|
-
/// date format for this field. See the
|
|
70
|
-
/// [
|
|
68
|
+
/// date format for this field. See the Luxon
|
|
69
|
+
/// [DateTime](https://moment.github.io/luxon/#/formatting?id=table-of-tokens) docs
|
|
71
70
|
/// for a reference on this format.
|
|
72
71
|
///
|
|
73
72
|
/// This format **is not** the format that will be used
|
|
@@ -86,16 +85,16 @@ class DateType extends Type {
|
|
|
86
85
|
constructor(format) {
|
|
87
86
|
super(format);
|
|
88
87
|
|
|
89
|
-
this.format = format || '
|
|
88
|
+
this.format = format || 'yyyy-MM-dd';
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
/// Cast provided value to underlying type.
|
|
93
92
|
///
|
|
94
93
|
/// This will cast the incoming value to the
|
|
95
|
-
/// underlying type of this field, a [
|
|
94
|
+
/// underlying type of this field, a Luxon [DateTime](https://moment.github.io/luxon/#/)
|
|
96
95
|
/// instance. If the provided value results in
|
|
97
96
|
/// an invalid date, then an exception will be thrown.
|
|
98
|
-
/// Once a valid [
|
|
97
|
+
/// Once a valid Luxon [DateTime](https://moment.github.io/luxon/#/) instance
|
|
99
98
|
/// is constructed from the value provided,
|
|
100
99
|
/// `dateTime.startOf('day')` is returned, forcing
|
|
101
100
|
/// this `DATE` type to zero its time (start at the
|
|
@@ -104,7 +103,7 @@ class DateType extends Type {
|
|
|
104
103
|
/// See <see>Type.castToType</see> for a more
|
|
105
104
|
/// detailed description.
|
|
106
105
|
///
|
|
107
|
-
/// Return:
|
|
106
|
+
/// Return: DateTime | null | undefined
|
|
108
107
|
/// Return the incoming `value`, cast to this
|
|
109
108
|
/// type. `null` and `undefined` are simply
|
|
110
109
|
/// returned without casting.
|
|
@@ -116,7 +115,7 @@ class DateType extends Type {
|
|
|
116
115
|
return value;
|
|
117
116
|
|
|
118
117
|
let dateTime = this.deserialize(value, connection);
|
|
119
|
-
if (!dateTime.isValid
|
|
118
|
+
if (!dateTime || !dateTime.isValid)
|
|
120
119
|
throw new TypeError(`DateType::castToType: Value provided ("${value}") can not be cast into a date.`);
|
|
121
120
|
|
|
122
121
|
return dateTime.startOf('day');
|
|
@@ -126,11 +125,11 @@ class DateType extends Type {
|
|
|
126
125
|
///
|
|
127
126
|
/// This will check if the provided value is
|
|
128
127
|
/// a valid date. It does so by calling
|
|
129
|
-
/// `
|
|
128
|
+
/// `DateTime.isValid`. If this check
|
|
130
129
|
/// results in `true`, then this method will
|
|
131
130
|
/// return `true`, otherwise it will return `false`.
|
|
132
131
|
///
|
|
133
|
-
/// See the [
|
|
132
|
+
/// See the Luxon [DateTime](https://moment.github.io/luxon/#/) library documentation for more information.
|
|
134
133
|
///
|
|
135
134
|
/// Return: boolean
|
|
136
135
|
///
|
|
@@ -138,7 +137,11 @@ class DateType extends Type {
|
|
|
138
137
|
/// value: any
|
|
139
138
|
/// The value to check.
|
|
140
139
|
isValidValue(value) {
|
|
141
|
-
|
|
140
|
+
try {
|
|
141
|
+
return (MiscUtils.valueToDateTime(value)).isValid;
|
|
142
|
+
} catch (error) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
/// Stringify the type itself.
|
|
@@ -148,7 +151,7 @@ class DateType extends Type {
|
|
|
148
151
|
/// for the underlying database. If no connection is
|
|
149
152
|
/// provided, then a "standard" SQL type will be returned
|
|
150
153
|
/// for this type instead. The "standard" type returned
|
|
151
|
-
/// when no `connection` is provided is `'
|
|
154
|
+
/// when no `connection` is provided is `'TIMESTAMP'`.
|
|
152
155
|
///
|
|
153
156
|
/// Return: string
|
|
154
157
|
///
|
|
@@ -163,7 +166,7 @@ class DateType extends Type {
|
|
|
163
166
|
toString(connection) {
|
|
164
167
|
return (connection)
|
|
165
168
|
? this.toConnectionType(connection)
|
|
166
|
-
: '
|
|
169
|
+
: 'TIMESTAMP';
|
|
167
170
|
}
|
|
168
171
|
|
|
169
172
|
/// Serialize the field value.
|
|
@@ -184,31 +187,35 @@ class DateType extends Type {
|
|
|
184
187
|
/// Return: string | null | undefined
|
|
185
188
|
///
|
|
186
189
|
/// Arguments:
|
|
187
|
-
/// value:
|
|
190
|
+
/// value: DateTime
|
|
188
191
|
/// The date value to serialize.
|
|
189
192
|
/// connection?: <see>Connection</see>
|
|
190
193
|
/// A connection instance, which if provided, will
|
|
191
194
|
/// proxy serialization to the underlying database connection
|
|
192
195
|
/// via the <see>connection.convertDateToDBTime</see> method.
|
|
193
|
-
serialize(
|
|
196
|
+
serialize(_value, connection) {
|
|
197
|
+
let value = _value;
|
|
194
198
|
if (value == null)
|
|
195
199
|
return (connection) ? null : value;
|
|
196
200
|
|
|
201
|
+
if (!DateTime.isDateTime(value))
|
|
202
|
+
value = this.deserialize(value);
|
|
203
|
+
|
|
197
204
|
if (connection)
|
|
198
|
-
return connection.convertDateToDBTime(value);
|
|
205
|
+
return connection.convertDateToDBTime(value, this);
|
|
199
206
|
|
|
200
207
|
if (this.format)
|
|
201
|
-
return value.
|
|
208
|
+
return value.toFormat(this.format || 'yyyy-MM-dd');
|
|
202
209
|
|
|
203
|
-
return value.
|
|
210
|
+
return value.toISO();
|
|
204
211
|
}
|
|
205
212
|
|
|
206
213
|
/// Deserialize the field value.
|
|
207
214
|
///
|
|
208
215
|
/// This method is used to deserialize a provided
|
|
209
|
-
/// field value. If the value provided is a `
|
|
216
|
+
/// field value. If the value provided is a `DateTime`
|
|
210
217
|
/// instance, then simply return it. Otherwise,
|
|
211
|
-
/// if a string is provided, convert it to a `
|
|
218
|
+
/// if a string is provided, convert it to a `DateTime`
|
|
212
219
|
/// instance, using the `format` provided (if any).
|
|
213
220
|
///
|
|
214
221
|
/// The `connection` argument is not used by this
|
|
@@ -220,12 +227,12 @@ class DateType extends Type {
|
|
|
220
227
|
///
|
|
221
228
|
/// Note:
|
|
222
229
|
/// This method is called by `castToType` to cast
|
|
223
|
-
/// incoming values into `
|
|
230
|
+
/// incoming values into `DateTime` instances.
|
|
224
231
|
///
|
|
225
|
-
/// Return:
|
|
232
|
+
/// Return: DateTime
|
|
226
233
|
///
|
|
227
234
|
/// Arguments:
|
|
228
|
-
/// value: string |
|
|
235
|
+
/// value: DateTime | Date | string | number | BigInt | null | undefined
|
|
229
236
|
/// The value to deserialize.
|
|
230
237
|
/// connection?: <see>Connection</see>
|
|
231
238
|
/// An optional connection that might be provided
|
|
@@ -240,15 +247,15 @@ class DateType extends Type {
|
|
|
240
247
|
return value;
|
|
241
248
|
|
|
242
249
|
if (Nife.instanceOf(value, 'string') && this.format) {
|
|
243
|
-
value =
|
|
250
|
+
value = MiscUtils.valueToDateTime(_value, this.format);
|
|
244
251
|
|
|
245
|
-
if (!value.isValid
|
|
246
|
-
value =
|
|
252
|
+
if (!value.isValid)
|
|
253
|
+
value = MiscUtils.valueToDateTime(_value);
|
|
247
254
|
} else {
|
|
248
|
-
value =
|
|
255
|
+
value = MiscUtils.valueToDateTime(_value);
|
|
249
256
|
}
|
|
250
257
|
|
|
251
|
-
if (!value.isValid
|
|
258
|
+
if (!value.isValid)
|
|
252
259
|
throw new TypeError(`DateType::deserialize: Value provided ("${_value}") can not be cast into a date.`);
|
|
253
260
|
|
|
254
261
|
return value;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const Nife = require('nife');
|
|
4
|
-
const
|
|
4
|
+
const { DateTime } = require('luxon');
|
|
5
5
|
const Type = require('../type');
|
|
6
6
|
const { DATETIME_NOW } = require('../helpers/default-helpers');
|
|
7
|
-
|
|
8
|
-
moment.suppressDeprecationWarnings = true;
|
|
7
|
+
const MiscUtils = require('../../utils/misc-utils');
|
|
9
8
|
|
|
10
9
|
/// `DATETIME` type.
|
|
11
10
|
///
|
|
@@ -13,7 +12,7 @@ moment.suppressDeprecationWarnings = true;
|
|
|
13
12
|
/// in the underlying database.
|
|
14
13
|
///
|
|
15
14
|
/// Client-side storage for this field will be backed by
|
|
16
|
-
/// a [
|
|
15
|
+
/// a Luxon [DateTime](https://moment.github.io/luxon/#/) instance.
|
|
17
16
|
///
|
|
18
17
|
/// You can optionally provide a `format` argument when constructing
|
|
19
18
|
/// this type. **This is a client-side format only**. It doesn't
|
|
@@ -24,7 +23,7 @@ moment.suppressDeprecationWarnings = true;
|
|
|
24
23
|
/// Example:
|
|
25
24
|
/// class DatesWithTimes extends Model {
|
|
26
25
|
/// static fields = {
|
|
27
|
-
/// dateTime1: Types.DATETIME('
|
|
26
|
+
/// dateTime1: Types.DATETIME('yyyy-MM-dd HH:mm:ss'),
|
|
28
27
|
/// dateTime2: new Types.DateTimeType(),
|
|
29
28
|
/// };
|
|
30
29
|
/// }
|
|
@@ -66,8 +65,8 @@ class DateTimeType extends Type {
|
|
|
66
65
|
/// Construct a new `DATETIME` type.
|
|
67
66
|
///
|
|
68
67
|
/// The `format` argument will specify the
|
|
69
|
-
/// date format for this field. See the
|
|
70
|
-
/// [
|
|
68
|
+
/// date format for this field. See the Luxon
|
|
69
|
+
/// [DateTime](https://moment.github.io/luxon/#/formatting?id=table-of-tokens) docs
|
|
71
70
|
/// for a reference on this format.
|
|
72
71
|
///
|
|
73
72
|
/// This format **is not** the format that will be used
|
|
@@ -99,14 +98,14 @@ class DateTimeType extends Type {
|
|
|
99
98
|
/// Cast provided value to underlying type.
|
|
100
99
|
///
|
|
101
100
|
/// This will cast the incoming value to the
|
|
102
|
-
/// underlying type of this field, a [
|
|
101
|
+
/// underlying type of this field, a Luxon [DateTime](https://moment.github.io/luxon/#/)
|
|
103
102
|
/// instance. If the provided value results in
|
|
104
103
|
/// an invalid date, then an exception will be thrown.
|
|
105
104
|
///
|
|
106
105
|
/// See <see>Type.castToType</see> for a more
|
|
107
106
|
/// detailed description.
|
|
108
107
|
///
|
|
109
|
-
/// Return:
|
|
108
|
+
/// Return: DateTime | null | undefined
|
|
110
109
|
/// Return the incoming `value`, cast to this
|
|
111
110
|
/// type. `null` and `undefined` are simply
|
|
112
111
|
/// returned without casting.
|
|
@@ -118,7 +117,7 @@ class DateTimeType extends Type {
|
|
|
118
117
|
return value;
|
|
119
118
|
|
|
120
119
|
let dateTime = this.deserialize(value, connection);
|
|
121
|
-
if (!dateTime.isValid
|
|
120
|
+
if (!dateTime || !dateTime.isValid)
|
|
122
121
|
throw new TypeError(`DateTimeType::castToType: Value provided ("${value}") can not be cast into a date.`);
|
|
123
122
|
|
|
124
123
|
return dateTime;
|
|
@@ -128,11 +127,11 @@ class DateTimeType extends Type {
|
|
|
128
127
|
///
|
|
129
128
|
/// This will check if the provided value is
|
|
130
129
|
/// a valid date. It does so by calling
|
|
131
|
-
/// `
|
|
130
|
+
/// `DateTime.isValid`. If this check
|
|
132
131
|
/// results in `true`, then this method will
|
|
133
132
|
/// return `true`, otherwise it will return `false`.
|
|
134
133
|
///
|
|
135
|
-
/// See the [
|
|
134
|
+
/// See the Luxon [DateTime](https://moment.github.io/luxon/#/) library documentation for more information.
|
|
136
135
|
///
|
|
137
136
|
/// Return: boolean
|
|
138
137
|
///
|
|
@@ -140,7 +139,11 @@ class DateTimeType extends Type {
|
|
|
140
139
|
/// value: any
|
|
141
140
|
/// The value to check.
|
|
142
141
|
isValidValue(value) {
|
|
143
|
-
|
|
142
|
+
try {
|
|
143
|
+
return (MiscUtils.valueToDateTime(value)).isValid;
|
|
144
|
+
} catch (error) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
144
147
|
}
|
|
145
148
|
|
|
146
149
|
/// Stringify the type itself.
|
|
@@ -150,7 +153,7 @@ class DateTimeType extends Type {
|
|
|
150
153
|
/// for the underlying database. If no connection is
|
|
151
154
|
/// provided, then a "standard" SQL type will be returned
|
|
152
155
|
/// for this type instead. The "standard" type returned
|
|
153
|
-
/// when no `connection` is provided is `'
|
|
156
|
+
/// when no `connection` is provided is `'TIMESTAMP'`.
|
|
154
157
|
///
|
|
155
158
|
/// Return: string
|
|
156
159
|
///
|
|
@@ -165,7 +168,7 @@ class DateTimeType extends Type {
|
|
|
165
168
|
toString(connection) {
|
|
166
169
|
return (connection)
|
|
167
170
|
? this.toConnectionType(connection)
|
|
168
|
-
: '
|
|
171
|
+
: 'TIMESTAMP';
|
|
169
172
|
}
|
|
170
173
|
|
|
171
174
|
/// Serialize the field value.
|
|
@@ -186,7 +189,7 @@ class DateTimeType extends Type {
|
|
|
186
189
|
/// Return: string | null | undefined
|
|
187
190
|
///
|
|
188
191
|
/// Arguments:
|
|
189
|
-
/// value:
|
|
192
|
+
/// value: DateTime
|
|
190
193
|
/// The date value to serialize.
|
|
191
194
|
/// connection?: <see>Connection</see>
|
|
192
195
|
/// A connection instance, which if provided, will
|
|
@@ -197,24 +200,24 @@ class DateTimeType extends Type {
|
|
|
197
200
|
if (value == null)
|
|
198
201
|
return (connection) ? null : value;
|
|
199
202
|
|
|
200
|
-
if (!
|
|
203
|
+
if (!DateTime.isDateTime(value))
|
|
201
204
|
value = this.deserialize(value);
|
|
202
205
|
|
|
203
206
|
if (connection)
|
|
204
|
-
return connection.convertDateToDBTime(value);
|
|
207
|
+
return connection.convertDateToDBTime(value, this);
|
|
205
208
|
|
|
206
209
|
if (this.format)
|
|
207
|
-
return value.
|
|
210
|
+
return value.toFormat(this.format);
|
|
208
211
|
|
|
209
|
-
return value.
|
|
212
|
+
return value.toISO();
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
/// Deserialize the field value.
|
|
213
216
|
///
|
|
214
217
|
/// This method is used to deserialize a provided
|
|
215
|
-
/// field value. If the value provided is a `
|
|
218
|
+
/// field value. If the value provided is a `DateTime`
|
|
216
219
|
/// instance, then simply return it. Otherwise,
|
|
217
|
-
/// if a string is provided, convert it to a `
|
|
220
|
+
/// if a string is provided, convert it to a `DateTime`
|
|
218
221
|
/// instance, using the `format` provided (if any).
|
|
219
222
|
///
|
|
220
223
|
/// The `connection` argument is not used by this
|
|
@@ -226,12 +229,12 @@ class DateTimeType extends Type {
|
|
|
226
229
|
///
|
|
227
230
|
/// Note:
|
|
228
231
|
/// This method is called by `castToType` to cast
|
|
229
|
-
/// incoming values into `
|
|
232
|
+
/// incoming values into `DateTime` instances.
|
|
230
233
|
///
|
|
231
|
-
/// Return:
|
|
234
|
+
/// Return: DateTime
|
|
232
235
|
///
|
|
233
236
|
/// Arguments:
|
|
234
|
-
/// value: string |
|
|
237
|
+
/// value: DateTime | Date | string | number | BigInt | null | undefined
|
|
235
238
|
/// The value to deserialize.
|
|
236
239
|
/// connection?: <see>Connection</see>
|
|
237
240
|
/// An optional connection that might be provided
|
|
@@ -246,15 +249,15 @@ class DateTimeType extends Type {
|
|
|
246
249
|
return value;
|
|
247
250
|
|
|
248
251
|
if (Nife.instanceOf(value, 'string') && this.format) {
|
|
249
|
-
value =
|
|
252
|
+
value = MiscUtils.valueToDateTime(_value, this.format);
|
|
250
253
|
|
|
251
|
-
if (!value.isValid
|
|
252
|
-
value =
|
|
254
|
+
if (!value.isValid)
|
|
255
|
+
value = MiscUtils.valueToDateTime(_value);
|
|
253
256
|
} else {
|
|
254
|
-
value =
|
|
257
|
+
value = MiscUtils.valueToDateTime(_value);
|
|
255
258
|
}
|
|
256
259
|
|
|
257
|
-
if (!value.isValid
|
|
260
|
+
if (!value.isValid)
|
|
258
261
|
throw new TypeError(`DateType::deserialize: Value provided ("${_value}") can not be cast into a date.`);
|
|
259
262
|
|
|
260
263
|
return value;
|
|
@@ -11,7 +11,8 @@ export const FLAG_LITERAL: number;
|
|
|
11
11
|
export const FLAG_REMOTE: number;
|
|
12
12
|
|
|
13
13
|
export declare interface DefaultValueContext {
|
|
14
|
-
_initial
|
|
14
|
+
_initial?: boolean;
|
|
15
|
+
_static?: boolean;
|
|
15
16
|
connection: ConnectionBase;
|
|
16
17
|
data: GenericObject | undefined;
|
|
17
18
|
field: Field;
|
package/lib/utils/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const QueryUtils = require('./query-utils');
|
|
|
7
7
|
const {
|
|
8
8
|
collect,
|
|
9
9
|
objectAssignSpecial,
|
|
10
|
+
valueToDateTime,
|
|
10
11
|
} = MiscUtils;
|
|
11
12
|
|
|
12
13
|
const {
|
|
@@ -39,6 +40,7 @@ module.exports = {
|
|
|
39
40
|
// MiscUtils
|
|
40
41
|
collect,
|
|
41
42
|
objectAssignSpecial,
|
|
43
|
+
valueToDateTime,
|
|
42
44
|
|
|
43
45
|
// ModelUtils
|
|
44
46
|
assignRelatedModels,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { DateTime } from 'luxon';
|
|
1
2
|
import { GenericObject } from '../interfaces/common';
|
|
2
3
|
|
|
3
4
|
declare function collect(iterator: AsyncIterator<any>): Promise<Array<any>>;
|
|
4
5
|
declare function objectAssignSpecial(obj: GenericObject, proto?: GenericObject | null, skipKeys?: Array<string> | GenericObject): GenericObject;
|
|
6
|
+
declare function valueToDateTime(value: DateTime | Date | number | BigInt | string, format?: string): DateTime;
|
package/lib/utils/misc-utils.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const Nife = require('nife');
|
|
4
|
+
const { DateTime } = require('luxon');
|
|
5
|
+
|
|
3
6
|
async function collect(iterator) {
|
|
4
7
|
let items = [];
|
|
5
8
|
|
|
@@ -32,7 +35,30 @@ function objectAssignSpecial(obj, proto, skipKeys) {
|
|
|
32
35
|
return newObj;
|
|
33
36
|
}
|
|
34
37
|
|
|
38
|
+
function valueToDateTime(value, format) {
|
|
39
|
+
if (DateTime.isDateTime(value)) {
|
|
40
|
+
return value;
|
|
41
|
+
} else if (Nife.instanceOf(value, 'number')) {
|
|
42
|
+
return DateTime.fromMillis(value);
|
|
43
|
+
} else if (Nife.instanceOf(value, 'bigint')) {
|
|
44
|
+
return DateTime.fromMillis(Number(value).valueOf());
|
|
45
|
+
} else if (value instanceof Date || (value && value.constructor && value.constructor.name === 'Date')) {
|
|
46
|
+
return DateTime.fromJSDate(value);
|
|
47
|
+
} else if (Nife.instanceOf(value, 'string')) {
|
|
48
|
+
if ((/^\d+$/).test(value))
|
|
49
|
+
return DateTime.fromMillis(parseInt(value, 10));
|
|
50
|
+
|
|
51
|
+
if (Nife.isNotEmpty(format))
|
|
52
|
+
return DateTime.fromFormat(value, format);
|
|
53
|
+
|
|
54
|
+
return DateTime.fromISO(value);
|
|
55
|
+
} else {
|
|
56
|
+
throw new Error(`MiscUtils::valueToDateTime: Invalid value provided: "${value}"`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
35
60
|
module.exports = {
|
|
36
61
|
collect,
|
|
37
62
|
objectAssignSpecial,
|
|
63
|
+
valueToDateTime,
|
|
38
64
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mythix-orm",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "ORM for Mythix framework",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"events": "^3.3.0",
|
|
47
47
|
"inflection": "^1.13.2",
|
|
48
|
-
"
|
|
48
|
+
"luxon": "^3.0.4",
|
|
49
49
|
"nife": "^1.12.1",
|
|
50
50
|
"sqlstring": "^2.3.3",
|
|
51
51
|
"uuid": "^9.0.0",
|