leoric 2.7.1 → 2.8.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/History.md CHANGED
@@ -1,3 +1,36 @@
1
+ 2.8.0 / 2022-08-30
2
+ ==================
3
+
4
+ ## What's Changed
5
+ * feat: refactor type definitions to export SequelizeBone, complete spell type definitions and fix index hints logic by @JimmyDaddy in https://github.com/cyjake/leoric/pull/337
6
+ * fix: throw error if token is not expected when parse expr by @cyjake in https://github.com/cyjake/leoric/pull/338
7
+
8
+
9
+ **Full Changelog**: https://github.com/cyjake/leoric/compare/v2.7.3...v2.8.0
10
+
11
+ 2.7.3 / 2022-08-25
12
+ ==================
13
+
14
+ ## What's Changed
15
+ * fix: should skip loading models that is loaded before by @cyjake in https://github.com/cyjake/leoric/pull/335
16
+
17
+
18
+ **Full Changelog**: https://github.com/cyjake/leoric/compare/v2.7.2...v2.7.3
19
+
20
+ 2.7.2 / 2022-08-24
21
+ ==================
22
+
23
+ ## What's Changed
24
+ * Update associations.md by @dxhuii in https://github.com/cyjake/leoric/pull/331
25
+ * refactor: refactor type definitions and fix unique not work in columnOptions by @JimmyDaddy in https://github.com/cyjake/leoric/pull/332
26
+ * fix: declare more exported functions such as isBone and heresql by @cyjake in https://github.com/cyjake/leoric/pull/333
27
+ * fix: INTEGER like data type and STRING extra options didn't work in polymorphism, fix decorators ColumnOptions.type to support invokable by @JimmyDaddy in https://github.com/cyjake/leoric/pull/334
28
+
29
+ ## New Contributors
30
+ * @dxhuii made their first contribution in https://github.com/cyjake/leoric/pull/331
31
+
32
+ **Full Changelog**: https://github.com/cyjake/leoric/compare/v2.7.1...v2.7.2
33
+
1
34
  2.7.1 / 2022-08-24
2
35
  ==================
3
36
 
package/index.d.ts ADDED
@@ -0,0 +1,115 @@
1
+ import DataTypes, { DataType, AbstractDataType, LENGTH_VARIANTS } from './src/data_types';
2
+ import {
3
+ Hint, IndexHint, HintInterface,
4
+ INDEX_HINT_SCOPE_TYPE, INDEX_HINT_SCOPE, INDEX_HINT_TYPE
5
+ } from './src/hint';
6
+ import {
7
+ Literal, Validator,
8
+ Connection, QueryOptions,
9
+ Raw, ColumnMeta, AttributeMeta,
10
+ BeforeHooksType, AfterHooksType, Collection,
11
+ } from './src/types/common';
12
+ import { SpellMeta, Spell, SpellBookFormatResult } from './src/spell';
13
+ import Bone from './src/bone';
14
+ import { ConnectOptions, AbstractDriver } from './src/drivers';
15
+ import { RawQueryResult } from './src/types/abstract_bone';
16
+
17
+ export {
18
+ LENGTH_VARIANTS as LENGTH_VARIANTS,
19
+ DataTypes, Literal, Validator, Connection,
20
+ Hint, IndexHint, HintInterface, INDEX_HINT_SCOPE_TYPE, INDEX_HINT_SCOPE, INDEX_HINT_TYPE,
21
+ Bone, Raw, Collection,
22
+ SpellMeta, Spell, ColumnMeta, AttributeMeta, SpellBookFormatResult
23
+ };
24
+
25
+ export * from './src/decorators';
26
+ export * from './src/drivers';
27
+ export * from './src/adapters/sequelize';
28
+
29
+ interface InitOptions {
30
+ underscored?: boolean;
31
+ tableName?: string;
32
+ hooks?: {
33
+ [key in BeforeHooksType ]: (options: QueryOptions) => Promise<void>
34
+ } | {
35
+ [key in AfterHooksType ]: (instance: Bone, result: Object) => Promise<void>
36
+ };
37
+ }
38
+
39
+ interface SyncOptions {
40
+ force?: boolean;
41
+ alter?: boolean;
42
+ }
43
+
44
+ interface RawQueryOptions {
45
+ replacements?: { [key:string]: Literal | Literal[] };
46
+ model: Bone;
47
+ connection: Connection;
48
+ }
49
+
50
+ export default class Realm {
51
+ Bone: typeof Bone;
52
+ DataTypes: typeof DataTypes;
53
+ driver: AbstractDriver;
54
+ models: Record<string, Bone>;
55
+ connected?: boolean;
56
+
57
+ constructor(options: ConnectOptions);
58
+
59
+ connect(): Promise<Bone>;
60
+
61
+ /**
62
+ * disconnect manually
63
+ * @param callback
64
+ */
65
+ disconnect(callback?: Function): Promise<boolean | void>;
66
+
67
+ define(
68
+ name: string,
69
+ attributes: Record<string, AbstractDataType<DataType> | AttributeMeta>,
70
+ options?: InitOptions,
71
+ descriptors?: Record<string, Function>,
72
+ ): typeof Bone;
73
+
74
+ raw(sql: string): Raw;
75
+
76
+ escape(value: Literal): string;
77
+
78
+ query(sql: string, values?: Array<Literal>, options?: RawQueryOptions): RawQueryResult;
79
+
80
+ transaction(callback: GeneratorFunction): Promise<RawQueryResult>;
81
+ transaction(callback: (connection: Connection) => Promise<RawQueryResult>): Promise<RawQueryResult>;
82
+
83
+ sync(options?: SyncOptions): Promise<void>;
84
+ }
85
+
86
+ /**
87
+ * Connect models to database.
88
+ * @example
89
+ * connect({
90
+ * host: 'localhost',
91
+ * user: 'root',
92
+ * database: 'leoric',
93
+ * models: path.join(__dirname, 'models')
94
+ * })
95
+ */
96
+ export function connect(opts: ConnectOptions): Promise<Realm>;
97
+ export function disconnect(realm: Realm, callback?: Function): Promise<boolean | void>;
98
+
99
+ /**
100
+ * Check if cls is subclass of Bone
101
+ * @param cls
102
+ */
103
+ export function isBone(cls: any): boolean;
104
+
105
+ /**
106
+ * Concatenate multiline SQL into oneline
107
+ * @example
108
+ * heresql(`
109
+ * SELECT *
110
+ * FROM users
111
+ * WHERE age >= 35
112
+ * `)
113
+ * @param text
114
+ */
115
+ export function heresql(text): string;
package/index.js CHANGED
@@ -7,7 +7,7 @@ const Bone = require('./src/bone');
7
7
  const Collection = require('./src/collection');
8
8
  const { invokable: DataTypes, LENGTH_VARIANTS } = require('./src/data_types');
9
9
  const migrations = require('./src/migrations');
10
- const sequelize = require('./src/adapters/sequelize');
10
+ const { sequelize, SequelizeBone} = require('./src/adapters/sequelize');
11
11
  const { heresql } = require('./src/utils/string');
12
12
  const Hint = require('./src/hint');
13
13
  const Realm = require('./src/realm');
@@ -52,6 +52,7 @@ Object.assign(Realm, {
52
52
  connect,
53
53
  disconnect,
54
54
  Bone,
55
+ SequelizeBone,
55
56
  Collection,
56
57
  DataTypes,
57
58
  Logger,
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "leoric",
3
- "version": "2.7.1",
3
+ "version": "2.8.0",
4
4
  "description": "JavaScript Object-relational mapping alchemy",
5
5
  "main": "index.js",
6
- "types": "types/index.d.ts",
6
+ "types": "index.d.ts",
7
7
  "files": [
8
- "index.js",
9
8
  "src",
10
- "types"
9
+ "index.js",
10
+ "index.d.ts"
11
11
  ],
12
12
  "scripts": {
13
13
  "jsdoc": "rm -rf docs/api && jsdoc -c .jsdoc.json -d docs/api -t node_modules/@cara/minami",
@@ -0,0 +1,190 @@
1
+ import {
2
+ Attributes, Literal, OperatorCondition,
3
+ BoneOptions, ResultSet, Raw,
4
+ SetOptions, BeforeHooksType, AfterHooksType,
5
+ QueryOptions, OrderOptions, QueryResult
6
+ } from '../types/common';
7
+ import { AbstractBone } from '../types/abstract_bone';
8
+ import { Spell } from '../spell';
9
+
10
+ type WhereConditions<T extends typeof SequelizeBone> = {
11
+ [Property in keyof Extract<InstanceType<T>, Literal>]?: Literal | Literal[] | OperatorCondition;
12
+ } | {
13
+ [key in '$and' | '$or']?: WhereConditions<T>[];
14
+ }
15
+
16
+ interface SequelizeDestroyOptions extends QueryOptions {
17
+ force?: boolean;
18
+ }
19
+
20
+ interface BaseSequelizeConditions<T extends typeof SequelizeBone> extends QueryOptions {
21
+ where?: WhereConditions<T>;
22
+ order?: OrderOptions<T>;
23
+ limit?: number;
24
+ attributes?: string | Raw | Array<[keyof Extract<InstanceType<T>, Literal>] | string | Raw> | [keyof Extract<InstanceType<T>, Literal>];
25
+ offset?: number;
26
+ }
27
+
28
+ interface SequelizeConditions<T extends typeof SequelizeBone> extends BaseSequelizeConditions<T> {
29
+ group?: string | string[] | Raw;
30
+ having?: WhereConditions<T> | string | { [key:string]: Literal | Literal[] } | Raw;
31
+ include?: string | Raw;
32
+ }
33
+
34
+ interface FindOrCreateOptions<T extends typeof SequelizeBone> extends BaseSequelizeConditions<T> {
35
+ defaults?: {
36
+ [Property in keyof Extract<InstanceType<T>, Literal>]?: Literal
37
+ }
38
+ }
39
+
40
+ interface FindOrBuildOptions<T extends typeof SequelizeBone> extends FindOrCreateOptions<T> {
41
+ raw?: boolean;
42
+ isNewRecord?: boolean;
43
+ validate?: boolean;
44
+ }
45
+
46
+ interface DestroyOptions<T extends typeof SequelizeBone> extends SequelizeConditions<T> {
47
+ force?: boolean;
48
+ }
49
+
50
+ type ScopeOptions = {
51
+ override?: boolean
52
+ }
53
+
54
+ type Values<T extends typeof SequelizeBone> = {
55
+ [Property in keyof Extract<InstanceType<T>, Literal>]?: Literal;
56
+ }
57
+
58
+ type aggregators = 'count' | 'COUNT' | 'average' | 'AVERAGE' | 'minimum' | 'MINIMUM' | 'maximum' | 'MAXIMUM' | 'sum' | 'SUM';
59
+
60
+ export class Collection<T extends SequelizeBone> extends Array<T> {
61
+ save(): Promise<void>;
62
+ toJSON(): Object[];
63
+ toObject(): Object[];
64
+ }
65
+
66
+ export class SequelizeBone extends AbstractBone {
67
+
68
+ static get sequelize(): boolean;
69
+
70
+ static get Instance(): SequelizeBone;
71
+
72
+ static get rawAttributes(): Attributes;
73
+
74
+ static getTableName(): boolean;
75
+
76
+ static removeAttribute(name: string): void;
77
+
78
+ /**
79
+ *
80
+ * @static
81
+ * @param {string} name before/after create|destroy|upsert|remove|update
82
+ * @param {string | Function} fnNameOrFun function name or function
83
+ * @param {Function} func hook function
84
+ */
85
+ static addHook(
86
+ name: BeforeHooksType | AfterHooksType | 'beforeDestroy' | 'afterDestroy' | 'beforeBulkDestroy' | 'afterBulkDestroy' | 'beforeBulkUpdate' | 'afterBulkUpdate',
87
+ fnNameOrFun: string | Function,
88
+ func?: Function,
89
+ ): void;
90
+
91
+ /**
92
+ * add scope see https://sequelize.org/master/class/lib/model.js~Model.html#static-method-addScope
93
+ * @deprecated scope is not recommended to use
94
+ * @param name
95
+ * @param scope
96
+ * @param opts
97
+ */
98
+ static addScope<T extends typeof SequelizeBone>(this: T, name: string, scope: ((...args: any[]) => SequelizeConditions<T>) | SequelizeConditions<T>, opts?: ScopeOptions): void;
99
+
100
+ /**
101
+ * @deprecated scope is not recommended to use
102
+ * @param name
103
+ * @param args
104
+ */
105
+ static scope<T extends typeof SequelizeBone>(this: T, name?: (string | ((...args: any[]) => SequelizeConditions<T>) | SequelizeConditions<T> | Array<SequelizeConditions<T>>), ...args: any[]): T;
106
+
107
+ static unscoped(): Spell<typeof SequelizeBone>;
108
+
109
+ /**
110
+ * @deprecated scope is not recommended to use
111
+ * @param name
112
+ * @param args
113
+ */
114
+ static setScope<T extends typeof SequelizeBone>(this: T, name: (string | ((...args: any[]) => SequelizeConditions<T>) | SequelizeConditions<T> | Array<SequelizeConditions<T>>), ...args: any[]): void;
115
+
116
+ static aggregate<T extends typeof SequelizeBone>(this: T, name: string, func: aggregators, options?: SequelizeConditions<T>): Spell<T, number>;
117
+
118
+ static build<T extends typeof SequelizeBone>(this: T, values: Values<T>, options?: BoneOptions): InstanceType<T>;
119
+
120
+ /**
121
+ * see https://github.com/sequelize/sequelize/blob/a729c4df41fa3a58fbecaf879265d2fb73d80e5f/src/model.js#L2299
122
+ * @param valueSets
123
+ * @param options
124
+ */
125
+ static bulkBuild<T extends typeof SequelizeBone>(this:T, valueSets: Array<Values<T>>, options?: BoneOptions): Array<InstanceType<T>>;
126
+
127
+ static count<T extends typeof SequelizeBone>(this: T, name?: string): Spell<T, ResultSet | number>;
128
+ static count<T extends typeof SequelizeBone>(this: T, conditions?: SequelizeConditions<T>): Spell<T, ResultSet | number>;
129
+
130
+ static decrement<T extends typeof SequelizeBone>(
131
+ this: T,
132
+ fields: string | Array<string> | { [Property in keyof Extract<InstanceType<T>, Literal>]?: number },
133
+ options?: SequelizeConditions<T>
134
+ ): Spell<T, QueryResult>;
135
+
136
+ static increment<T extends typeof SequelizeBone>(
137
+ this: T,
138
+ fields: string | Array<string> | { [Property in keyof Extract<InstanceType<T>, Literal>]?: number },
139
+ options?: SequelizeConditions<T>
140
+ ): Spell<T, QueryResult>;
141
+
142
+ static max<T extends typeof SequelizeBone>(this: T, filed: string, options?: SequelizeConditions<T>): Promise<Literal>;
143
+ static min<T extends typeof SequelizeBone>(this: T, filed: string, options?: SequelizeConditions<T>): Promise<Literal>;
144
+ static sum<T extends typeof SequelizeBone>(this: T, filed: string, options?: SequelizeConditions<T>): Promise<Literal>;
145
+
146
+ static destroy<T extends typeof SequelizeBone>(this: T, options?: DestroyOptions<T>): Promise<Array<number> | number>;
147
+ static bulkDestroy<T extends typeof SequelizeBone>(this: T, options?: DestroyOptions<T>): Spell<T, number>;
148
+
149
+ static findAll<T extends typeof SequelizeBone>(this: T, options?: SequelizeConditions<T>): Spell<T, Collection<InstanceType<T>>>;
150
+ static find<T extends typeof SequelizeBone>(this: T, options?: SequelizeConditions<T>): Spell<T, InstanceType<T> | null>;
151
+ static findAndCountAll<T extends typeof SequelizeBone>(this: T, options?: SequelizeConditions<T>): Promise<{
152
+ rows: Array<typeof SequelizeBone>,
153
+ count: number,
154
+ }>
155
+
156
+ static findByPk<T extends typeof SequelizeBone>(this:T, pk: number | bigint | string, options?: Pick<SequelizeConditions<T>, 'paranoid' | 'connection' | 'transaction' |'hint' | 'hints'>): Spell<T, InstanceType<T>>;
157
+
158
+ static findOne<T extends typeof SequelizeBone>(this: T, whereConditions: string, ...values: Literal[]): Spell<T, InstanceType<T>>;
159
+ static findOne<T extends typeof SequelizeBone>(this: T, primaryKey: number | number[] | bigint): Spell<T, InstanceType<T>>;
160
+ static findOne<T extends typeof SequelizeBone>(this: T, options?: SequelizeConditions<T>): Spell<T, InstanceType<T>>;
161
+
162
+ static findCreateFind<T extends typeof SequelizeBone>(this: T, options: FindOrCreateOptions<T>): Promise<InstanceType<T>>;
163
+ static findOrBuild<T extends typeof SequelizeBone>(this: T, options: FindOrBuildOptions<T>): Promise<[InstanceType<T>, boolean]>;
164
+ static findOrCreate<T extends typeof SequelizeBone>(this: T, options: FindOrBuildOptions<T>): Promise<[InstanceType<T>, boolean]>;
165
+
166
+ static restore<T extends typeof SequelizeBone>(this: T, options: BaseSequelizeConditions<T>): Spell<T, number>;
167
+
168
+ static update<T extends typeof SequelizeBone>(this: T, values: SetOptions<T>, options: BaseSequelizeConditions<T>): Promise<number>;
169
+ static bulkUpdate<T extends typeof SequelizeBone>(this: T, values: SetOptions<T>, options: BaseSequelizeConditions<T>): Spell<T, number>;
170
+
171
+ /**
172
+ * An alias of instance constructor. Some legacy code access model name from instance with `this.Model.name`.
173
+ */
174
+ get Model(): typeof SequelizeBone;
175
+ get dataValues(): { [key: string]: Literal };
176
+
177
+ where(): { [key: string]: number | bigint | string };
178
+ set(key: string, value: Literal | Literal[]): void;
179
+ get(key?: string): Literal | { [key: string]: Literal };
180
+ setDataValue(key: string, value: Literal | Literal[]): void;
181
+ getDataValue(key?: string): Literal | { [key: string]: Literal };
182
+ previous(key?: string): Literal | Literal[] | { [key: string]: Literal | Literal[] };
183
+ isSoftDeleted(): boolean;
184
+
185
+ increment(field: string | string[] | { [Property in keyof Extract<this, Literal>]?: number }, options?: QueryOptions): Spell<typeof SequelizeBone, QueryResult>;
186
+ decrement(field: string | string[] | { [Property in keyof Extract<this, Literal>]?: number }, options?: QueryOptions): Spell<typeof SequelizeBone, QueryResult>;
187
+ destroy(options?: SequelizeDestroyOptions): Promise<this| number>;
188
+ }
189
+
190
+ export const sequelize: (Bone: AbstractBone) => typeof SequelizeBone;
@@ -19,7 +19,7 @@ function translateOptions(spell, options) {
19
19
  if (having) spell.$having(having);
20
20
 
21
21
  if (order) {
22
- if (typeof order === 'string' || order instanceof Raw) {
22
+ if (typeof order === 'string' || order instanceof Raw || isPlainObject(order)) {
23
23
  spell.$order(order);
24
24
  } else if (Array.isArray(order) && order.length) {
25
25
  if (order.some(item => Array.isArray(item))) {
@@ -45,15 +45,7 @@ function translateOptions(spell, options) {
45
45
  }
46
46
 
47
47
  const setScopeToSpell = (scope) => (spell) => {
48
- if (scope.where) {
49
- spell.$where(scope.where);
50
- }
51
- if (scope.order) {
52
- spell.$order(scope.order);
53
- }
54
- if (scope.limit) {
55
- spell.$limit(scope.limit);
56
- }
48
+ translateOptions(spell, scope);
57
49
  };
58
50
 
59
51
  /**
@@ -78,7 +70,7 @@ function mergeScope(scopes) {
78
70
  }
79
71
  }
80
72
  return merged;
81
- };
73
+ }
82
74
 
83
75
  /**
84
76
  * parse scope
@@ -114,7 +106,7 @@ function filterOptions(options = {}) {
114
106
 
115
107
  // https://sequelize.org/master/class/lib/model.js~Model.html
116
108
  // https://sequelize.org/master/manual/model-querying-finders.html
117
- module.exports = Bone => {
109
+ exports.sequelize = Bone => {
118
110
  return class Spine extends Bone {
119
111
 
120
112
  /*
@@ -139,7 +131,7 @@ module.exports = Bone => {
139
131
 
140
132
  /**
141
133
  * add scope see https://sequelize.org/master/class/lib/model.js~Model.html#static-method-addScope
142
- *
134
+ * @deprecated scope is not recommended to use
143
135
  * @static
144
136
  * @param {string} name
145
137
  * @param {Object|Function} scope
@@ -156,20 +148,31 @@ module.exports = Bone => {
156
148
  }
157
149
  }
158
150
 
151
+ /**
152
+ * @deprecated scope is not recommended to use
153
+ * @param {string} name
154
+ * @param {...any} args
155
+ * @returns
156
+ */
159
157
  static scope(name, ...args) {
160
158
  const parentName = this.name;
161
159
  class ScopeClass extends this {
162
160
  static name = parentName;
163
- };
161
+ }
164
162
  ScopeClass.setScope(name, ...args);
165
163
  return ScopeClass;
166
164
  }
167
165
 
166
+ static get unscoped() {
167
+ return this.scope();
168
+ }
169
+
168
170
  static unscoped() {
169
171
  return this.scope();
170
172
  }
171
173
 
172
174
  /**
175
+ * @deprecated scope is not recommended to use
173
176
  * @static
174
177
  * @param {function|object|array} name
175
178
  */
@@ -274,12 +277,13 @@ module.exports = Bone => {
274
277
  // EXISTS
275
278
  // static bulkCreate() {}
276
279
 
277
- static async count(options = {}) {
280
+ static count(options = {}) {
281
+ if (typeof options === 'string') return spell.$count(options);
278
282
  const { where, col, group, paranoid } = options;
279
283
  let spell = super.find(where, filterOptions(options));
280
284
  if (Array.isArray(group)) spell.$group(...group);
281
285
  if (paranoid === false) spell = spell.unparanoid;
282
- return await spell.$count(col);
286
+ return spell.$count(col);
283
287
  }
284
288
 
285
289
  // EXISTS
@@ -562,7 +566,7 @@ module.exports = Bone => {
562
566
  // EXISTS
563
567
  // get isNewRecord() {}
564
568
 
565
- async decrement(fields, options = {}) {
569
+ decrement(fields, options = {}) {
566
570
  const Model = this.constructor;
567
571
  const { primaryKey } = Model;
568
572
  if (this[primaryKey] == null) {
@@ -735,3 +739,5 @@ module.exports = Bone => {
735
739
  }
736
740
  };
737
741
  };
742
+
743
+ exports.SequelizeBone = this.sequelize(require('../bone'));
package/src/bone.d.ts ADDED
@@ -0,0 +1,53 @@
1
+ import { Spell } from './spell';
2
+ import { AbstractBone } from './types/abstract_bone';
3
+ import { Collection, Literal, QueryOptions, ResultSet, WhereConditions } from './types/common';
4
+
5
+ export default class Bone extends AbstractBone {
6
+
7
+ /**
8
+ * SELECT rows
9
+ * @example
10
+ * Bone.find('foo = ?', 1)
11
+ * Bone.find({ foo: { $eq: 1 } })
12
+ */
13
+ static find<T extends typeof Bone>(this: T, whereConditions: WhereConditions<T>): Spell<T, Collection<InstanceType<T>>>;
14
+ static find<T extends typeof Bone>(this: T, whereConditions: string, ...values: Literal[]): Spell<T, Collection<InstanceType<T>>>;
15
+ static find<T extends typeof Bone>(this: T, primaryKey: number | number[] | bigint): Spell<T, Collection<InstanceType<T>>>;
16
+ static find<T extends typeof Bone>(this: T, ): Spell<T, Collection<InstanceType<T>>>;
17
+
18
+ /**
19
+ * SELECT rows LIMIT 1. Besides limiting the results to one rows, the type of the return value is different from {@link Bone.find} too. If no results were found, {@link Bone.findOne} returns null. If results were found, it returns the found record instead of wrapping them as a collection.
20
+ * @example
21
+ * Bone.findOne('foo = ?', 1)
22
+ * Bone.findOne({ foo: { $eq: 1 } })
23
+ */
24
+ static findOne<T extends typeof Bone>(this: T, whereConditions: WhereConditions<T>): Spell<T, InstanceType<T> | null>;
25
+ static findOne<T extends typeof Bone>(this: T, whereConditions: string, ...values: Literal[]): Spell<T, InstanceType<T> | null>;
26
+ static findOne<T extends typeof Bone>(this: T, primaryKey: number | number[] | bigint): Spell<T, InstanceType<T> | null>;
27
+ static findOne<T extends typeof Bone>(this: T, ): Spell<T, InstanceType<T> | null>;
28
+
29
+ static sum<T extends typeof Bone>(this: T, name?: string): Spell<T, ResultSet | number>;
30
+
31
+ /**
32
+ * restore rows
33
+ * @example
34
+ * Bone.restore({ title: 'aaa' })
35
+ * Bone.restore({ title: 'aaa' }, { hooks: false })
36
+ * @param conditions query conditions
37
+ * @param opts query options
38
+ */
39
+ static restore<T extends typeof Bone>(this: T, conditions: Object, opts?: QueryOptions): Spell<T, number>;
40
+
41
+ /**
42
+ * UPDATE rows.
43
+ */
44
+ static update<T extends typeof Bone>(this: T, whereConditions: WhereConditions<T>, values?: Object, opts?: QueryOptions): Spell<T, number>;
45
+
46
+ /**
47
+ * Discard all the applied scopes.
48
+ * @example
49
+ * Bone.all.unscoped // includes soft deleted rows
50
+ */
51
+ static unscoped: Spell<typeof Bone>;
52
+
53
+ }
package/src/bone.js CHANGED
@@ -1291,8 +1291,8 @@ class Bone {
1291
1291
  }
1292
1292
 
1293
1293
  for (const name in attributes) {
1294
- const { columnName } = attributes[name];
1295
- if (!(columnName in row)) {
1294
+ const attribute = attributes[name];
1295
+ if (!(attribute.columnName in row) && !attribute.virtual) {
1296
1296
  instance._getRawUnset().add(name);
1297
1297
  }
1298
1298
  }
package/src/data_types.js CHANGED
@@ -101,10 +101,12 @@ class VARBINARY extends BINARY {
101
101
  * @param {number} dataLength
102
102
  */
103
103
  class INTEGER extends DataType {
104
- constructor(dataLength) {
104
+ constructor(dataLength, unsigned, zerofill) {
105
105
  super();
106
106
  this.dataLength = dataLength;
107
107
  this.dataType = 'integer';
108
+ this.unsigned = unsigned;
109
+ this.zerofill = zerofill;
108
110
  }
109
111
  get UNSIGNED() {
110
112
  this.unsigned = true;
@@ -153,8 +155,8 @@ class INTEGER extends DataType {
153
155
  * @param {number} dataLength
154
156
  */
155
157
  class TINYINT extends INTEGER {
156
- constructor(dataLength) {
157
- super(dataLength);
158
+ constructor(dataLength, unsigned, zerofill) {
159
+ super(dataLength, unsigned, zerofill);
158
160
  this.dataType = 'tinyint';
159
161
  }
160
162
  }
@@ -167,8 +169,8 @@ class TINYINT extends INTEGER {
167
169
  * @param {number} dataLength
168
170
  */
169
171
  class SMALLINT extends INTEGER {
170
- constructor(dataLength) {
171
- super(dataLength);
172
+ constructor(dataLength, unsigned, zerofill) {
173
+ super(dataLength, unsigned, zerofill);
172
174
  this.dataType = 'smallint';
173
175
  }
174
176
  }
@@ -181,8 +183,8 @@ class SMALLINT extends INTEGER {
181
183
  * @param {number} dataLength
182
184
  */
183
185
  class MEDIUMINT extends INTEGER {
184
- constructor(dataLength) {
185
- super(dataLength);
186
+ constructor(dataLength, unsigned, zerofill) {
187
+ super(dataLength, unsigned, zerofill);
186
188
  this.dataType = 'mediumint';
187
189
  }
188
190
  }
@@ -195,8 +197,8 @@ class MEDIUMINT extends INTEGER {
195
197
  * @param {number} dataLength
196
198
  */
197
199
  class BIGINT extends INTEGER {
198
- constructor(dataLength) {
199
- super(dataLength);
200
+ constructor(dataLength, unsigned, zerofill) {
201
+ super(dataLength, unsigned, zerofill);
200
202
  this.dataType = 'bigint';
201
203
  }
202
204
  }