@nocobase/database 0.8.0-alpha.9 → 0.8.1-alpha.4
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/collection.d.ts +7 -3
- package/lib/collection.js +126 -22
- package/lib/database.d.ts +13 -7
- package/lib/database.js +39 -8
- package/lib/decorators/must-have-filter-decorator.js +4 -0
- package/lib/decorators/transaction-decorator.js +1 -0
- package/lib/features/ReferencesMap.js +14 -9
- package/lib/field-repository/array-field-repository.d.ts +28 -0
- package/lib/field-repository/array-field-repository.js +208 -0
- package/lib/fields/array-field.d.ts +1 -1
- package/lib/fields/array-field.js +15 -11
- package/lib/fields/belongs-to-field.d.ts +9 -1
- package/lib/fields/belongs-to-field.js +21 -7
- package/lib/fields/belongs-to-many-field.d.ts +4 -0
- package/lib/fields/belongs-to-many-field.js +24 -0
- package/lib/fields/field.d.ts +3 -2
- package/lib/fields/field.js +19 -13
- package/lib/fields/has-many-field.d.ts +2 -1
- package/lib/fields/has-many-field.js +18 -10
- package/lib/fields/has-one-field.d.ts +1 -0
- package/lib/fields/has-one-field.js +22 -10
- package/lib/fields/index.d.ts +3 -3
- package/lib/fields/index.js +14 -34
- package/lib/fields/relation-field.d.ts +2 -1
- package/lib/fields/relation-field.js +16 -0
- package/lib/fields/set-field.d.ts +10 -0
- package/lib/fields/set-field.js +35 -0
- package/lib/fields/sort-field.d.ts +1 -1
- package/lib/fields/sort-field.js +1 -1
- package/lib/filter-match.d.ts +1 -0
- package/lib/filter-match.js +84 -0
- package/lib/filter-parser.d.ts +2 -2
- package/lib/index.d.ts +5 -1
- package/lib/index.js +56 -0
- package/lib/inherited-collection.d.ts +13 -0
- package/lib/inherited-collection.js +210 -0
- package/lib/inherited-map.d.ts +21 -0
- package/lib/inherited-map.js +203 -0
- package/lib/model-hook.d.ts +1 -1
- package/lib/model.d.ts +1 -0
- package/lib/model.js +47 -0
- package/lib/operators/array.d.ts +1 -25
- package/lib/operators/association.d.ts +1 -9
- package/lib/operators/boolean.d.ts +1 -12
- package/lib/operators/date.d.ts +1 -33
- package/lib/operators/empty.d.ts +2 -25
- package/lib/operators/ne.d.ts +1 -13
- package/lib/operators/notIn.d.ts +1 -9
- package/lib/options-parser.d.ts +3 -2
- package/lib/options-parser.js +16 -1
- package/lib/relation-repository/relation-repository.d.ts +2 -2
- package/lib/relation-repository/single-relation-repository.js +2 -2
- package/lib/repository.d.ts +18 -10
- package/lib/repository.js +172 -38
- package/lib/sync-runner.d.ts +4 -0
- package/lib/sync-runner.js +181 -0
- package/lib/types.d.ts +2 -2
- package/lib/update-associations.d.ts +1 -0
- package/lib/update-associations.js +21 -2
- package/lib/update-guard.d.ts +3 -3
- package/lib/utils.js +5 -0
- package/package.json +4 -4
- package/src/__tests__/bigint.test.ts +48 -0
- package/src/__tests__/collection.test.ts +48 -13
- package/src/__tests__/database.test.ts +10 -0
- package/src/__tests__/field-repository/array-field-repository.test.ts +94 -0
- package/src/__tests__/fields/set.test.ts +37 -0
- package/src/__tests__/filter-match.test.ts +52 -0
- package/src/__tests__/inhertits/collection-inherits-sync.test.ts +38 -0
- package/src/__tests__/inhertits/collection-inherits.test.ts +994 -0
- package/src/__tests__/inhertits/helper.ts +3 -0
- package/src/__tests__/inhertits/inherited-map.test.ts +27 -0
- package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +2 -0
- package/src/__tests__/relation-repository/has-many-repository.test.ts +1 -1
- package/src/__tests__/repository/destroy.test.ts +122 -1
- package/src/__tests__/repository/update-many.test.ts +57 -0
- package/src/__tests__/update-association-values.test.ts +232 -0
- package/src/__tests__/update-associations.test.ts +6 -1
- package/src/collection.ts +90 -8
- package/src/database.ts +53 -14
- package/src/decorators/must-have-filter-decorator.ts +4 -0
- package/src/decorators/transaction-decorator.ts +1 -0
- package/src/features/ReferencesMap.ts +20 -9
- package/src/features/referential-integrity-check.ts +1 -0
- package/src/field-repository/array-field-repository.ts +155 -0
- package/src/fields/array-field.ts +4 -4
- package/src/fields/belongs-to-field.ts +26 -10
- package/src/fields/belongs-to-many-field.ts +34 -0
- package/src/fields/field.ts +26 -13
- package/src/fields/has-many-field.ts +17 -9
- package/src/fields/has-one-field.ts +23 -9
- package/src/fields/index.ts +5 -5
- package/src/fields/relation-field.ts +16 -0
- package/src/fields/set-field.ts +25 -0
- package/src/fields/sort-field.ts +5 -4
- package/src/filter-match.ts +49 -0
- package/src/filter-parser.ts +2 -2
- package/src/index.ts +5 -2
- package/src/inherited-collection.ts +112 -0
- package/src/inherited-map.ts +97 -0
- package/src/model-hook.ts +2 -3
- package/src/model.ts +43 -3
- package/src/operators/array.ts +1 -1
- package/src/operators/association.ts +1 -1
- package/src/operators/boolean.ts +1 -1
- package/src/operators/date.ts +1 -1
- package/src/operators/empty.ts +1 -1
- package/src/operators/ne.ts +1 -1
- package/src/operators/notIn.ts +2 -1
- package/src/options-parser.ts +20 -4
- package/src/relation-repository/relation-repository.ts +2 -2
- package/src/relation-repository/single-relation-repository.ts +2 -2
- package/src/repository.ts +144 -30
- package/src/sync-runner.ts +162 -0
- package/src/types.ts +2 -2
- package/src/update-associations.ts +23 -7
- package/src/update-guard.ts +3 -3
- package/src/utils.ts +5 -1
- package/lib/fields/sequence-field.d.ts +0 -32
- package/lib/fields/sequence-field.js +0 -300
- package/src/__tests__/fields/sequence-field.test.ts +0 -480
- package/src/fields/sequence-field.ts +0 -202
package/src/utils.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
|
-
import { Model } from './model';
|
|
3
2
|
import { IdentifierError } from './errors/identifier-error';
|
|
3
|
+
import { Model } from './model';
|
|
4
4
|
|
|
5
5
|
type HandleAppendsQueryOptions = {
|
|
6
6
|
templateModel: any;
|
|
@@ -10,6 +10,10 @@ type HandleAppendsQueryOptions = {
|
|
|
10
10
|
export async function handleAppendsQuery(options: HandleAppendsQueryOptions) {
|
|
11
11
|
const { templateModel, queryPromises } = options;
|
|
12
12
|
|
|
13
|
+
if (!templateModel) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
const primaryKey = templateModel.constructor.primaryKeyAttribute;
|
|
14
18
|
|
|
15
19
|
const results = await Promise.all(queryPromises);
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { DataTypes } from 'sequelize';
|
|
2
|
-
import { Registry } from '@nocobase/utils';
|
|
3
|
-
import { Model } from '..';
|
|
4
|
-
import { BaseColumnFieldOptions, Field, FieldContext } from './field';
|
|
5
|
-
interface Pattern {
|
|
6
|
-
validate?(options: any): string | null;
|
|
7
|
-
generate(this: SequenceField, instance: Model, index: number): string;
|
|
8
|
-
getLength(options: any): number;
|
|
9
|
-
getMatcher(options: any): string;
|
|
10
|
-
}
|
|
11
|
-
export declare const sequencePatterns: Registry<Pattern>;
|
|
12
|
-
interface PatternConfig {
|
|
13
|
-
type: string;
|
|
14
|
-
title?: string;
|
|
15
|
-
options?: any;
|
|
16
|
-
}
|
|
17
|
-
export interface SequenceFieldOptions extends BaseColumnFieldOptions {
|
|
18
|
-
type: 'sequence';
|
|
19
|
-
patterns: PatternConfig[];
|
|
20
|
-
}
|
|
21
|
-
export declare class SequenceField extends Field {
|
|
22
|
-
matcher: RegExp;
|
|
23
|
-
get dataType(): DataTypes.StringDataTypeConstructor;
|
|
24
|
-
constructor(options: SequenceFieldOptions, context: FieldContext);
|
|
25
|
-
setValue: (instance: Model, options: any) => Promise<void>;
|
|
26
|
-
setLast: (instance: Model, options: any) => void;
|
|
27
|
-
match(value: any): RegExpMatchArray;
|
|
28
|
-
parse(value: string, patternIndex: number): string;
|
|
29
|
-
bind(): void;
|
|
30
|
-
unbind(): void;
|
|
31
|
-
}
|
|
32
|
-
export {};
|
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.sequencePatterns = exports.SequenceField = void 0;
|
|
7
|
-
|
|
8
|
-
function _sequelize() {
|
|
9
|
-
const data = require("sequelize");
|
|
10
|
-
|
|
11
|
-
_sequelize = function _sequelize() {
|
|
12
|
-
return data;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
return data;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function _cronParser() {
|
|
19
|
-
const data = _interopRequireDefault(require("cron-parser"));
|
|
20
|
-
|
|
21
|
-
_cronParser = function _cronParser() {
|
|
22
|
-
return data;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
return data;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function _moment() {
|
|
29
|
-
const data = _interopRequireDefault(require("moment"));
|
|
30
|
-
|
|
31
|
-
_moment = function _moment() {
|
|
32
|
-
return data;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
return data;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function _lodash() {
|
|
39
|
-
const data = require("lodash");
|
|
40
|
-
|
|
41
|
-
_lodash = function _lodash() {
|
|
42
|
-
return data;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
return data;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function _utils() {
|
|
49
|
-
const data = require("@nocobase/utils");
|
|
50
|
-
|
|
51
|
-
_utils = function _utils() {
|
|
52
|
-
return data;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return data;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
var _field = require("./field");
|
|
59
|
-
|
|
60
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
61
|
-
|
|
62
|
-
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
63
|
-
|
|
64
|
-
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
65
|
-
|
|
66
|
-
const sequencePatterns = new (_utils().Registry)();
|
|
67
|
-
exports.sequencePatterns = sequencePatterns;
|
|
68
|
-
sequencePatterns.register('string', {
|
|
69
|
-
validate(options) {
|
|
70
|
-
if (!(options === null || options === void 0 ? void 0 : options.value)) {
|
|
71
|
-
return 'options.value should be configured as a non-empty string';
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return null;
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
generate(instance, index) {
|
|
78
|
-
const options = this.options.patterns[index].options;
|
|
79
|
-
return options.value;
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
getLength(options) {
|
|
83
|
-
return options.value.length;
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
getMatcher(options) {
|
|
87
|
-
return (0, _lodash().escapeRegExp)(options.value);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
});
|
|
91
|
-
sequencePatterns.register('integer', {
|
|
92
|
-
generate(instance, index) {
|
|
93
|
-
const _this$options$pattern = this.options.patterns[index].options,
|
|
94
|
-
options = _this$options$pattern === void 0 ? {} : _this$options$pattern;
|
|
95
|
-
const _options$digits = options.digits,
|
|
96
|
-
digits = _options$digits === void 0 ? 1 : _options$digits,
|
|
97
|
-
_options$start = options.start,
|
|
98
|
-
start = _options$start === void 0 ? 0 : _options$start,
|
|
99
|
-
_options$base = options.base,
|
|
100
|
-
base = _options$base === void 0 ? 10 : _options$base,
|
|
101
|
-
cycle = options.cycle;
|
|
102
|
-
const max = Math.pow(base, digits) - 1;
|
|
103
|
-
const _this$options$lastRec = this.options.lastRecord,
|
|
104
|
-
lastRecord = _this$options$lastRec === void 0 ? null : _this$options$lastRec;
|
|
105
|
-
|
|
106
|
-
if (typeof options.current === 'undefined') {
|
|
107
|
-
if (lastRecord && lastRecord.get(this.options.name)) {
|
|
108
|
-
// if match current pattern
|
|
109
|
-
const matcher = this.match(lastRecord.get(this.options.name));
|
|
110
|
-
|
|
111
|
-
if (matcher) {
|
|
112
|
-
const lastNumber = Number.parseInt(matcher[index + 1], base);
|
|
113
|
-
options.current = Number.isNaN(lastNumber) ? start : lastNumber + 1;
|
|
114
|
-
} else {
|
|
115
|
-
options.current = start;
|
|
116
|
-
}
|
|
117
|
-
} else {
|
|
118
|
-
options.current = start;
|
|
119
|
-
}
|
|
120
|
-
} else {
|
|
121
|
-
options.current += 1;
|
|
122
|
-
} // cycle as cron string
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (cycle && lastRecord) {
|
|
126
|
-
const interval = _cronParser().default.parseExpression(cycle, {
|
|
127
|
-
currentDate: lastRecord.get('createdAt')
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
const next = interval.next();
|
|
131
|
-
|
|
132
|
-
if (instance.get('createdAt').getTime() >= next.getTime()) {
|
|
133
|
-
options.current = start;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (options.current > max) {
|
|
138
|
-
options.current = start;
|
|
139
|
-
} // update options
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
Object.assign(this.options.patterns[index], {
|
|
143
|
-
options
|
|
144
|
-
});
|
|
145
|
-
return options.current.toString(base).padStart(digits, '0');
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
getLength({
|
|
149
|
-
digits = 1
|
|
150
|
-
} = {}) {
|
|
151
|
-
return digits;
|
|
152
|
-
},
|
|
153
|
-
|
|
154
|
-
getMatcher(options = {}) {
|
|
155
|
-
const _options$digits2 = options.digits,
|
|
156
|
-
digits = _options$digits2 === void 0 ? 1 : _options$digits2,
|
|
157
|
-
_options$start2 = options.start,
|
|
158
|
-
start = _options$start2 === void 0 ? 0 : _options$start2,
|
|
159
|
-
_options$base2 = options.base,
|
|
160
|
-
base = _options$base2 === void 0 ? 10 : _options$base2;
|
|
161
|
-
const startLen = start ? start.toString(base).length : 1;
|
|
162
|
-
const chars = '0123456789abcdefghijklmnopqrstuvwxyz'.slice(0, base);
|
|
163
|
-
return `[${chars}]{${digits}}`;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
});
|
|
167
|
-
sequencePatterns.register('date', {
|
|
168
|
-
generate(instance, index) {
|
|
169
|
-
var _options$field, _options$format;
|
|
170
|
-
|
|
171
|
-
const options = this.options.patterns[index].options;
|
|
172
|
-
return (0, _moment().default)(instance.get((_options$field = options === null || options === void 0 ? void 0 : options.field) !== null && _options$field !== void 0 ? _options$field : 'createdAt')).format((_options$format = options === null || options === void 0 ? void 0 : options.format) !== null && _options$format !== void 0 ? _options$format : 'YYYYMMDD');
|
|
173
|
-
},
|
|
174
|
-
|
|
175
|
-
getLength(options) {
|
|
176
|
-
var _options$format$lengt, _options$format2;
|
|
177
|
-
|
|
178
|
-
return (_options$format$lengt = (_options$format2 = options.format) === null || _options$format2 === void 0 ? void 0 : _options$format2.length) !== null && _options$format$lengt !== void 0 ? _options$format$lengt : 8;
|
|
179
|
-
},
|
|
180
|
-
|
|
181
|
-
getMatcher(options = {}) {
|
|
182
|
-
var _options$format$lengt2, _options$format3;
|
|
183
|
-
|
|
184
|
-
return `.{${(_options$format$lengt2 = options === null || options === void 0 ? void 0 : (_options$format3 = options.format) === null || _options$format3 === void 0 ? void 0 : _options$format3.length) !== null && _options$format$lengt2 !== void 0 ? _options$format$lengt2 : 8}}`;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
class SequenceField extends _field.Field {
|
|
190
|
-
get dataType() {
|
|
191
|
-
return _sequelize().DataTypes.STRING;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
constructor(_options, context) {
|
|
195
|
-
var _this;
|
|
196
|
-
|
|
197
|
-
super(_options, context);
|
|
198
|
-
_this = this;
|
|
199
|
-
this.matcher = void 0;
|
|
200
|
-
|
|
201
|
-
this.setValue = /*#__PURE__*/function () {
|
|
202
|
-
var _ref = _asyncToGenerator(function* (instance, options) {
|
|
203
|
-
const _this$options = _this.options,
|
|
204
|
-
name = _this$options.name,
|
|
205
|
-
patterns = _this$options.patterns; // NOTE: only load when value is not set, if null stand for no last record
|
|
206
|
-
|
|
207
|
-
if (typeof _this.options.lastRecord === 'undefined') {
|
|
208
|
-
const model = instance.constructor;
|
|
209
|
-
_this.options.lastRecord = yield model.findOne({
|
|
210
|
-
attributes: [model.primaryKeyAttribute, _this.options.name, 'createdAt'],
|
|
211
|
-
order: [['createdAt', 'DESC'], // TODO(bug): will cause problem if no auto-increment id
|
|
212
|
-
[model.primaryKeyAttribute, 'DESC']],
|
|
213
|
-
transaction: options.transaction
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const results = patterns.reduce((result, p, i) => {
|
|
218
|
-
const item = sequencePatterns.get(p.type).generate.call(_this, instance, i, options);
|
|
219
|
-
return result.concat(item);
|
|
220
|
-
}, []);
|
|
221
|
-
instance.set(name, results.join(''));
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
return function (_x, _x2) {
|
|
225
|
-
return _ref.apply(this, arguments);
|
|
226
|
-
};
|
|
227
|
-
}();
|
|
228
|
-
|
|
229
|
-
this.setLast = (instance, options) => {
|
|
230
|
-
this.options.lastRecord = instance;
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
if (!_options.patterns || !_options.patterns.length) {
|
|
234
|
-
throw new Error('at least one pattern should be defined for sequence type');
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
_options.patterns.forEach(pattern => {
|
|
238
|
-
const P = sequencePatterns.get(pattern.type);
|
|
239
|
-
|
|
240
|
-
if (!P) {
|
|
241
|
-
throw new Error(`pattern type ${pattern.type} is not registered`);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (P.validate) {
|
|
245
|
-
const error = P.validate(pattern.options);
|
|
246
|
-
|
|
247
|
-
if (error) {
|
|
248
|
-
throw new Error(error);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
const _patterns = _options.patterns.map(({
|
|
254
|
-
type,
|
|
255
|
-
options
|
|
256
|
-
}) => sequencePatterns.get(type).getMatcher(options));
|
|
257
|
-
|
|
258
|
-
this.matcher = new RegExp(`^${_patterns.map(p => `(${p})`).join('')}$`, 'i');
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
match(value) {
|
|
262
|
-
return typeof value === 'string' ? value.match(this.matcher) : null;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
parse(value, patternIndex) {
|
|
266
|
-
for (let i = 0, index = 0; i < this.options.patterns.length; i += 1) {
|
|
267
|
-
const _this$options$pattern2 = this.options.patterns[i],
|
|
268
|
-
type = _this$options$pattern2.type,
|
|
269
|
-
options = _this$options$pattern2.options;
|
|
270
|
-
|
|
271
|
-
const _sequencePatterns$get = sequencePatterns.get(type),
|
|
272
|
-
getLength = _sequencePatterns$get.getLength;
|
|
273
|
-
|
|
274
|
-
const length = getLength(options);
|
|
275
|
-
|
|
276
|
-
if (i === patternIndex) {
|
|
277
|
-
return value.substring(index, index + length);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
index += length;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return '';
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
bind() {
|
|
287
|
-
super.bind();
|
|
288
|
-
this.on('beforeCreate', this.setValue);
|
|
289
|
-
this.on('afterCreate', this.setLast);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
unbind() {
|
|
293
|
-
super.unbind();
|
|
294
|
-
this.off('beforeCreate', this.setValue);
|
|
295
|
-
this.off('afterCreate', this.setLast);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
exports.SequenceField = SequenceField;
|