mythix-orm 1.6.2 → 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.
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter } from 'events';
2
- import { Moment } from 'moment';
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 | Moment): 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 defineTable(): Promise<any>;
149
- public defineConstraints(): Promise<any>;
150
- public defineIndexes(): Promise<any>;
151
- public renameTable(): Promise<any>;
152
- public renameColumn(): Promise<any>;
153
- public dropColumn(): Promise<any>;
154
- public alterColumn(): Promise<any>;
155
- public addColumn(): Promise<any>;
156
- public addConstraint(): Promise<any>;
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 moment = require('moment');
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 'DATE';
482
+ return 'TIMESTAMP';
483
483
  }
484
484
 
485
485
  // eslint-disable-next-line no-unused-vars
486
486
  _datetimeTypeToString(type) {
487
- return 'DATETIME';
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 (value instanceof Date || (value && value.constructor && value.constructor.name === 'Date'))
577
+ convertDateToDBTime(value, type) {
578
+ if (Nife.instanceOf(value, 'number'))
579
579
  return value;
580
- else if (moment.isMoment(value))
581
- return value.toDate();
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 renameTable() {
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 renameColumn() {
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 addConstraint() {
1136
- throw new Error(`${this.constructor.name}::addConstraint: This operation is not supported for this connection type.`);
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 addIndex() {
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
 
@@ -734,7 +734,7 @@ class QueryGeneratorBase {
734
734
  order = queryPart.value;
735
735
  }
736
736
 
737
- if (Nife.isEmpty(order)) {
737
+ if (order === undefined) {
738
738
  if (options && options.selectStatement === true)
739
739
  order = this.connection.getDefaultOrder(rootModel, options);
740
740
  }
package/lib/field.js CHANGED
@@ -243,6 +243,7 @@ class Field {
243
243
  this.allowNull = true;
244
244
  this.index = false;
245
245
  this.unique = false;
246
+ this.columnName = (fieldDefinition && fieldDefinition.fieldName);
246
247
 
247
248
  Object.assign(this, fieldDefinition || {});
248
249
  }
package/lib/model.d.ts CHANGED
@@ -146,16 +146,18 @@ export declare class Model {
146
146
  public static getWhereWithConnection(options?: { connection: ConnectionBase }): QueryEngine;
147
147
  public getWhereWithConnection(options?: { connection: ConnectionBase }): QueryEngine;
148
148
 
149
- public static create(models: Array<Model | GenericObject>, options?: GenericObject): Promise<Array<Model>>;
150
- public static create(models: Model | GenericObject, options?: GenericObject): Promise<Model>;
149
+ public static create<T extends Model = Model>(models: Array<T>, options?: GenericObject): Promise<Array<T>>;
150
+ public static create<T extends Model = Model>(models: T, options?: GenericObject): Promise<T>;
151
+ public static create<T extends Model = Model>(models: Array<GenericObject>, options?: GenericObject): Promise<Array<T>>;
152
+ public static create<T extends Model = Model>(models: GenericObject, options?: GenericObject): Promise<T>;
151
153
  public static count(options?: GenericObject): Promise<number>;
152
- public static all(options?: GenericObject): Promise<Array<Model>>;
153
- public static fetchAll(options?: GenericObject): AsyncGenerator<Model>;
154
- public static first(limit?: number, options?: GenericObject): Promise<Model | undefined>;
155
- public static last(limit?: number, options?: GenericObject): Promise<Model | undefined>;
154
+ public static all<T extends Model = Model>(options?: GenericObject): Promise<Array<T>>;
155
+ public static fetchAll<T extends Model = Model>(options?: GenericObject): AsyncGenerator<T>;
156
+ public static first<T extends Model = Model>(limit?: number, options?: GenericObject): Promise<T | undefined>;
157
+ public static last<T extends Model = Model>(limit?: number, options?: GenericObject): Promise<T | undefined>;
156
158
  public static pluck(fields: string | Array<string>, options?: GenericObject): Promise<Array<any>>;
157
159
 
158
- public constructor(data: GenericObject, _options?: ModelOptions);
160
+ public constructor(data?: GenericObject, _options?: ModelOptions);
159
161
  public getOptions(): ModelOptions;
160
162
  public _constructor(data?: GenericObject): void;
161
163
  public _constructFields(): void;
@@ -183,7 +185,7 @@ export declare class Model {
183
185
  public onAfterCreate(context: HookContext): Promise<any>;
184
186
  public onAfterUpdate(context: HookContext): Promise<any>;
185
187
  public onAfterSave(context: HookContext): Promise<any>;
186
- public save(options?: GenericObject): Promise<Model | boolean>;
188
+ public save(options?: GenericObject): Promise<this | boolean>;
187
189
  public reload(options?: GenericObject): Promise<void>;
188
190
  public destroy(options?: GenericObject): Promise<number>;
189
191
  public toString(): string;
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(findFieldName) {
1323
+ static getField(_findFieldName) {
1323
1324
  let fields = this.getFields();
1324
- if (!fields || !findFieldName)
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;
@@ -53,11 +53,11 @@ export declare class QueryEngine<T = ConnectionBase> {
53
53
  public unscoped(context?: GenericObject): QueryEngine;
54
54
  public toString(options?: GenericObject): string;
55
55
  public MERGE(queryEngine: QueryEngine): QueryEngine;
56
- public all(options?: GenericObject): Promise<Array<Model>>;
57
- public fetchAll(options?: GenericObject): AsyncGenerator<Model>;
58
- public first(limit?: number | null | undefined, options?: GenericObject): Promise<Model | undefined>;
59
- public last(limit?: number | null | undefined, options?: GenericObject): Promise<Model | undefined>;
60
- public update(attributes: Model | GenericObject, options?: GenericObject): Promise<number>;
56
+ public all<T extends Model = Model>(options?: GenericObject): Promise<Array<T>>;
57
+ public fetchAll<T extends Model = Model>(options?: GenericObject): AsyncGenerator<T>;
58
+ public first<T extends Model = Model>(limit?: number | null | undefined, options?: GenericObject): Promise<T | undefined>;
59
+ public last<T extends Model = Model>(limit?: number | null | undefined, options?: GenericObject): Promise<T | undefined>;
60
+ public update<T extends Model = Model>(attributes: T | GenericObject, options?: GenericObject): Promise<number>;
61
61
  public destroy(options?: GenericObject): Promise<number>;
62
62
  public average(field: Field | string, options?: GenericObject): Promise<number>;
63
63
  public count(field: Field | string, options?: GenericObject): Promise<number>;
@@ -78,51 +78,71 @@ export declare class QueryEngine<T = ConnectionBase> {
78
78
 
79
79
  declare public NOT: {
80
80
  (): QueryEngine;
81
+
82
+ name: QueryEngine;
81
83
  [ key: string ]: QueryEngine;
82
84
  };
83
85
 
84
86
  declare public AND: {
85
87
  (query: QueryEngine): QueryEngine;
88
+
89
+ name: QueryEngine;
86
90
  [ key: string ]: QueryEngine;
87
91
  };
88
92
 
89
93
  declare public OR: {
90
94
  (query: QueryEngine): QueryEngine;
95
+
96
+ name: QueryEngine;
91
97
  [ key: string ]: QueryEngine;
92
98
  };
93
99
 
94
100
  declare public DISTINCT: {
95
101
  (fullyQualifiedName: string | Field): QueryEngine;
102
+
103
+ name: QueryEngine;
96
104
  [ key: string ]: QueryEngine;
97
105
  };
98
106
 
99
107
  declare public INNER_JOIN: {
100
108
  (): QueryEngine;
109
+
110
+ name: QueryEngine;
101
111
  [ key: string ]: QueryEngine;
102
112
  };
103
113
 
104
114
  declare public LEFT_JOIN: {
105
115
  (): QueryEngine;
116
+
117
+ name: QueryEngine;
106
118
  [ key: string ]: QueryEngine;
107
119
  };
108
120
 
109
121
  declare public RIGHT_JOIN: {
110
122
  (): QueryEngine;
123
+
124
+ name: QueryEngine;
111
125
  [ key: string ]: QueryEngine;
112
126
  };
113
127
 
114
128
  declare public FULL_JOIN: {
115
129
  (): QueryEngine;
130
+
131
+ name: QueryEngine;
116
132
  [ key: string ]: QueryEngine;
117
133
  };
118
134
 
119
135
  declare public CROSS_JOIN: {
120
136
  (): QueryEngine;
137
+
138
+ name: QueryEngine;
121
139
  [ key: string ]: QueryEngine;
122
140
  };
123
141
 
124
142
  declare public JOIN: {
125
143
  (type: string | LiteralBase): QueryEngine;
144
+
145
+ name: QueryEngine;
126
146
  [ key: string ]: QueryEngine;
127
147
  };
128
148
 
@@ -137,6 +157,7 @@ export declare class QueryEngine<T = ConnectionBase> {
137
157
  public LIKE(value: string, options?: { caseSensitive: boolean }): QueryEngine;
138
158
  public NOT_LIKE(value: string, options?: { caseSensitive: boolean }): QueryEngine;
139
159
 
160
+ name: QueryEngine;
140
161
  [ key: string ]: any;
141
162
  }
142
163
 
@@ -1,11 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  const Nife = require('nife');
4
- const moment = require('moment');
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 [moment](https://momentjs.com/docs/) instance.
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('YYYY-MM-DD'),
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
- /// [moment](https://momentjs.com/docs/#/displaying/format/) docs
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 || 'YYYY-MM-DD';
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 [moment](https://momentjs.com/docs/)
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 [moment](https://momentjs.com/docs/) instance
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: moment | null | undefined
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
- /// `moment(value).isValid()`. If this check
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 [moment](https://momentjs.com/docs/) library documentation for more information.
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
- return moment(value).isValid();
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 `'DATE'`.
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
- : 'DATE';
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: moment
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(value, connection) {
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.format(this.format);
208
+ return value.toFormat(this.format || 'yyyy-MM-dd');
202
209
 
203
- return value.toISOString();
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 `moment`
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 `moment`
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 `moment` instances.
230
+ /// incoming values into `DateTime` instances.
224
231
  ///
225
- /// Return: moment
232
+ /// Return: DateTime
226
233
  ///
227
234
  /// Arguments:
228
- /// value: string | moment | null | undefined
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 = moment(_value, this.format);
250
+ value = MiscUtils.valueToDateTime(_value, this.format);
244
251
 
245
- if (!value.isValid())
246
- value = moment(_value);
252
+ if (!value.isValid)
253
+ value = MiscUtils.valueToDateTime(_value);
247
254
  } else {
248
- value = moment(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 moment = require('moment');
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 [moment](https://momentjs.com/docs/) instance.
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('YYYY-MM-DD HH:mm:ss'),
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
- /// [moment](https://momentjs.com/docs/#/displaying/format/) docs
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 [moment](https://momentjs.com/docs/)
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: moment | null | undefined
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
- /// `moment(value).isValid()`. If this check
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 [moment](https://momentjs.com/docs/) library documentation for more information.
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
- return moment(value).isValid();
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 `'DATETIME'`.
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
- : 'DATETIME';
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: moment
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 (!moment.isMoment(value))
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.format(this.format);
210
+ return value.toFormat(this.format);
208
211
 
209
- return value.toISOString();
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 `moment`
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 `moment`
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 `moment` instances.
232
+ /// incoming values into `DateTime` instances.
230
233
  ///
231
- /// Return: moment
234
+ /// Return: DateTime
232
235
  ///
233
236
  /// Arguments:
234
- /// value: string | moment | null | undefined
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 = moment(_value, this.format);
252
+ value = MiscUtils.valueToDateTime(_value, this.format);
250
253
 
251
- if (!value.isValid())
252
- value = moment(_value);
254
+ if (!value.isValid)
255
+ value = MiscUtils.valueToDateTime(_value);
253
256
  } else {
254
- value = moment(_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: boolean;
14
+ _initial?: boolean;
15
+ _static?: boolean;
15
16
  connection: ConnectionBase;
16
17
  data: GenericObject | undefined;
17
18
  field: Field;
@@ -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;
@@ -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
  };
@@ -64,7 +64,7 @@ export declare function createAndSaveAllRelatedModels(
64
64
  options?: GenericObject,
65
65
  ): Promise<Array<Model> | undefined>;
66
66
 
67
- export declare function setRelationalValues<T = Model>(
67
+ export declare function setRelationalValues<T extends Model = Model>(
68
68
  connection: ConnectionBase,
69
69
  TargetModel: ModelClass,
70
70
  targetModelInstance: T,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mythix-orm",
3
- "version": "1.6.2",
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
- "moment": "^2.29.4",
48
+ "luxon": "^3.0.4",
49
49
  "nife": "^1.12.1",
50
50
  "sqlstring": "^2.3.3",
51
51
  "uuid": "^9.0.0",