@nocobase/database 0.9.0-alpha.2 → 0.9.1-alpha.1
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-importer.js +1 -1
- package/lib/collection.d.ts +7 -1
- package/lib/collection.js +135 -61
- package/lib/database-utils/index.d.ts +8 -0
- package/lib/database-utils/index.js +59 -0
- package/lib/database.d.ts +26 -3
- package/lib/database.js +224 -61
- package/lib/fields/array-field.d.ts +1 -1
- package/lib/fields/array-field.js +2 -2
- package/lib/fields/belongs-to-many-field.js +1 -2
- package/lib/fields/field.d.ts +1 -0
- package/lib/fields/field.js +37 -15
- package/lib/fields/has-one-field.d.ts +1 -1
- package/lib/fields/has-one-field.js +9 -5
- package/lib/fields/number-field.d.ts +9 -6
- package/lib/fields/number-field.js +8 -6
- package/lib/fields/sort-field.js +15 -1
- package/lib/index.d.ts +6 -4
- package/lib/index.js +59 -36
- package/lib/mock-database.d.ts +2 -0
- package/lib/mock-database.js +3 -1
- package/lib/model.js +10 -1
- package/lib/options-parser.js +3 -0
- package/lib/relation-repository/belongs-to-many-repository.js +4 -2
- package/lib/repository.js +5 -2
- package/lib/sync-runner.d.ts +1 -1
- package/lib/sync-runner.js +28 -18
- package/lib/types.d.ts +7 -1
- package/lib/update-associations.js +17 -3
- package/lib/update-guard.d.ts +1 -0
- package/lib/update-guard.js +6 -0
- package/lib/utils.d.ts +5 -0
- package/lib/utils.js +68 -0
- package/lib/value-parsers/array-value-parser.d.ts +8 -0
- package/lib/value-parsers/array-value-parser.js +76 -0
- package/lib/value-parsers/base-value-parser.d.ts +12 -0
- package/lib/value-parsers/base-value-parser.js +59 -0
- package/lib/value-parsers/boolean-value-parser.d.ts +4 -0
- package/lib/value-parsers/boolean-value-parser.js +46 -0
- package/lib/value-parsers/date-value-parser.d.ts +5 -0
- package/lib/value-parsers/date-value-parser.js +91 -0
- package/lib/value-parsers/index.d.ts +12 -0
- package/lib/value-parsers/index.js +102 -0
- package/lib/value-parsers/json-value-parser.d.ts +4 -0
- package/lib/value-parsers/json-value-parser.js +37 -0
- package/lib/value-parsers/number-value-parser.d.ts +4 -0
- package/lib/value-parsers/number-value-parser.js +49 -0
- package/lib/value-parsers/string-value-parser.d.ts +8 -0
- package/lib/value-parsers/string-value-parser.js +76 -0
- package/lib/value-parsers/to-many-value-parser.d.ts +13 -0
- package/lib/value-parsers/to-many-value-parser.js +169 -0
- package/lib/value-parsers/to-one-value-parser.d.ts +4 -0
- package/lib/value-parsers/to-one-value-parser.js +49 -0
- package/package.json +4 -3
- package/src/__tests__/bigint.test.ts +1 -1
- package/src/__tests__/collection-importer.test.ts +13 -1
- package/src/__tests__/collection.test.ts +19 -9
- package/src/__tests__/database.test.ts +32 -0
- package/src/__tests__/fields/sort-field.test.ts +23 -0
- package/src/__tests__/inhertits/collection-inherits.test.ts +7 -5
- package/src/__tests__/percent2float.test.ts +14 -0
- package/src/__tests__/postgres/schema.test.ts +120 -0
- package/src/__tests__/underscored-options.test.ts +207 -0
- package/src/__tests__/update-associations-through.test.ts +73 -0
- package/src/__tests__/value-parsers/base.test.ts +20 -0
- package/src/__tests__/value-parsers/date.test.ts +67 -0
- package/src/__tests__/value-parsers/number.test.ts +46 -0
- package/src/__tests__/value-parsers/to-many.test.ts +206 -0
- package/src/__tests__/value-parsers/to-one.test.ts +60 -0
- package/src/collection-importer.ts +2 -2
- package/src/collection.ts +97 -15
- package/src/database-utils/index.ts +38 -0
- package/src/database.ts +171 -33
- package/src/fields/array-field.ts +1 -1
- package/src/fields/belongs-to-field.ts +1 -1
- package/src/fields/belongs-to-many-field.ts +0 -1
- package/src/fields/field.ts +45 -16
- package/src/fields/has-many-field.ts +1 -1
- package/src/fields/has-one-field.ts +11 -7
- package/src/fields/number-field.ts +10 -6
- package/src/fields/sort-field.ts +13 -1
- package/src/index.ts +7 -4
- package/src/inherited-collection.ts +1 -0
- package/src/mock-database.ts +3 -1
- package/src/model.ts +11 -2
- package/src/options-parser.ts +5 -0
- package/src/relation-repository/belongs-to-many-repository.ts +4 -2
- package/src/repository.ts +8 -3
- package/src/sync-runner.ts +33 -19
- package/src/types.ts +12 -1
- package/src/update-associations.ts +12 -5
- package/src/update-guard.ts +6 -0
- package/src/utils.ts +94 -0
- package/src/value-parsers/array-value-parser.ts +30 -0
- package/src/value-parsers/base-value-parser.ts +40 -0
- package/src/value-parsers/boolean-value-parser.ts +29 -0
- package/src/value-parsers/date-value-parser.ts +38 -0
- package/src/value-parsers/index.ts +46 -0
- package/src/value-parsers/json-value-parser.ts +19 -0
- package/src/value-parsers/number-value-parser.ts +29 -0
- package/src/value-parsers/string-value-parser.ts +31 -0
- package/src/value-parsers/to-many-value-parser.ts +85 -0
- package/src/value-parsers/to-one-value-parser.ts +20 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { Database, mockDatabase } from '@nocobase/database';
|
|
2
|
+
|
|
3
|
+
describe('underscored options', () => {
|
|
4
|
+
let db: Database;
|
|
5
|
+
|
|
6
|
+
beforeEach(async () => {
|
|
7
|
+
db = mockDatabase({
|
|
8
|
+
underscored: true,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
await db.clean({ drop: true });
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
afterEach(async () => {
|
|
15
|
+
await db.close();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should set two field with same type', async () => {
|
|
19
|
+
const collection = db.collection({
|
|
20
|
+
name: 'test',
|
|
21
|
+
fields: [
|
|
22
|
+
{
|
|
23
|
+
type: 'string',
|
|
24
|
+
name: 'test_field',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: 'string',
|
|
28
|
+
name: 'testField',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await db.sync();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should not set two field with difference type but same field name', async () => {
|
|
37
|
+
const collection = db.collection({
|
|
38
|
+
name: 'test',
|
|
39
|
+
fields: [
|
|
40
|
+
{
|
|
41
|
+
type: 'string',
|
|
42
|
+
name: 'test_field',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
expect(() => {
|
|
48
|
+
collection.addField('testField', { type: 'integer' });
|
|
49
|
+
}).toThrowError();
|
|
50
|
+
|
|
51
|
+
expect(() => {
|
|
52
|
+
collection.addField('test123', { type: 'integer', field: 'test_field' });
|
|
53
|
+
}).toThrowError();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should create index', async () => {
|
|
57
|
+
const collectionA = db.collection({
|
|
58
|
+
name: 'testCollection',
|
|
59
|
+
fields: [
|
|
60
|
+
{
|
|
61
|
+
type: 'string',
|
|
62
|
+
name: 'aField',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
type: 'string',
|
|
66
|
+
name: 'bField',
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
indexes: [
|
|
70
|
+
{
|
|
71
|
+
type: 'UNIQUE',
|
|
72
|
+
fields: ['aField', 'bField'],
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
await db.sync();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should use underscored option', async () => {
|
|
81
|
+
const collectionA = db.collection({
|
|
82
|
+
name: 'testCollection',
|
|
83
|
+
underscored: true,
|
|
84
|
+
fields: [
|
|
85
|
+
{
|
|
86
|
+
type: 'string',
|
|
87
|
+
name: 'testField',
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
await db.sync();
|
|
93
|
+
|
|
94
|
+
const tableName = collectionA.model.tableName;
|
|
95
|
+
|
|
96
|
+
expect(tableName.includes('test_collection')).toBeTruthy();
|
|
97
|
+
|
|
98
|
+
const repository = db.getRepository('testCollection');
|
|
99
|
+
|
|
100
|
+
await repository.create({
|
|
101
|
+
values: {
|
|
102
|
+
testField: 'test',
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const record = await repository.findOne({});
|
|
107
|
+
|
|
108
|
+
expect(record.get('testField')).toBe('test');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should use database options', async () => {
|
|
112
|
+
const collectionA = db.collection({
|
|
113
|
+
name: 'testCollection',
|
|
114
|
+
fields: [
|
|
115
|
+
{
|
|
116
|
+
type: 'string',
|
|
117
|
+
name: 'testField',
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
await db.sync();
|
|
123
|
+
|
|
124
|
+
const tableName = collectionA.model.tableName;
|
|
125
|
+
|
|
126
|
+
expect(tableName.includes('test_collection')).toBeTruthy();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('through table', async () => {
|
|
130
|
+
db.collection({
|
|
131
|
+
name: 'posts',
|
|
132
|
+
fields: [
|
|
133
|
+
{
|
|
134
|
+
type: 'string',
|
|
135
|
+
name: 'name',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: 'belongsToMany',
|
|
139
|
+
name: 'tags',
|
|
140
|
+
through: 'collectionCategory',
|
|
141
|
+
target: 'posts',
|
|
142
|
+
sourceKey: 'name',
|
|
143
|
+
foreignKey: 'postsName',
|
|
144
|
+
targetKey: 'name',
|
|
145
|
+
otherKey: 'tagsName',
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
db.collection({
|
|
151
|
+
name: 'tags',
|
|
152
|
+
fields: [
|
|
153
|
+
{
|
|
154
|
+
type: 'string',
|
|
155
|
+
name: 'name',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
type: 'belongsToMany',
|
|
159
|
+
name: 'posts',
|
|
160
|
+
target: 'posts',
|
|
161
|
+
through: 'collectionCategory',
|
|
162
|
+
sourceKey: 'name',
|
|
163
|
+
foreignKey: 'tagsName',
|
|
164
|
+
targetKey: 'name',
|
|
165
|
+
otherKey: 'postsName',
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
await db.sync();
|
|
171
|
+
|
|
172
|
+
const through = db.getCollection('collectionCategory');
|
|
173
|
+
|
|
174
|
+
expect(through.model.tableName.includes('collection_category')).toBeTruthy();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('db collectionExists', async () => {
|
|
178
|
+
const collectionA = db.collection({
|
|
179
|
+
name: 'testCollection',
|
|
180
|
+
underscored: true,
|
|
181
|
+
fields: [
|
|
182
|
+
{
|
|
183
|
+
type: 'string',
|
|
184
|
+
name: 'testField',
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
expect(await db.collectionExistsInDb('testCollection')).toBeFalsy();
|
|
190
|
+
|
|
191
|
+
await db.sync();
|
|
192
|
+
|
|
193
|
+
expect(await db.collectionExistsInDb('testCollection')).toBeTruthy();
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('should throw error when table names conflict', async () => {
|
|
197
|
+
db.collection({
|
|
198
|
+
name: 'b1_z',
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
expect(() => {
|
|
202
|
+
db.collection({
|
|
203
|
+
name: 'b1Z',
|
|
204
|
+
});
|
|
205
|
+
}).toThrowError();
|
|
206
|
+
});
|
|
207
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Database } from '../database';
|
|
2
|
+
import { mockDatabase } from './';
|
|
3
|
+
|
|
4
|
+
describe('update through', () => {
|
|
5
|
+
let db: Database;
|
|
6
|
+
beforeEach(async () => {
|
|
7
|
+
db = mockDatabase();
|
|
8
|
+
await db.clean({ drop: true });
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
afterEach(async () => {
|
|
12
|
+
await db.close();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should not be reset', async () => {
|
|
16
|
+
db.collection({
|
|
17
|
+
name: 'c',
|
|
18
|
+
autoGenId: true,
|
|
19
|
+
fields: [
|
|
20
|
+
{
|
|
21
|
+
name: 'id',
|
|
22
|
+
type: 'integer',
|
|
23
|
+
primaryKey: true,
|
|
24
|
+
autoIncrement: true,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
});
|
|
28
|
+
db.collection({
|
|
29
|
+
name: 'a',
|
|
30
|
+
fields: [
|
|
31
|
+
{
|
|
32
|
+
type: 'string',
|
|
33
|
+
name: 'name',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: 'belongsToMany',
|
|
37
|
+
name: 'b',
|
|
38
|
+
target: 'b',
|
|
39
|
+
through: 'c',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
});
|
|
43
|
+
db.collection({
|
|
44
|
+
name: 'b',
|
|
45
|
+
fields: [],
|
|
46
|
+
});
|
|
47
|
+
await db.sync();
|
|
48
|
+
const callback1 = jest.fn();
|
|
49
|
+
const callback2 = jest.fn();
|
|
50
|
+
db.on('c.afterCreate', callback1);
|
|
51
|
+
db.on('c.afterBulkCreate', callback2);
|
|
52
|
+
const b = await db.getRepository('b').create({
|
|
53
|
+
values: {},
|
|
54
|
+
});
|
|
55
|
+
const a = await db.getRepository('a').create({
|
|
56
|
+
values: {
|
|
57
|
+
b: [b.toJSON()],
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
const c1 = await db.getRepository('c').findOne();
|
|
61
|
+
await db.getRepository('a').update({
|
|
62
|
+
filterByTk: a.id,
|
|
63
|
+
values: {
|
|
64
|
+
b: [b.toJSON()],
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const c2 = await db.getRepository('c').findOne();
|
|
69
|
+
expect(c1.get('id')).toBe(c2.get('id'));
|
|
70
|
+
expect(callback1).toHaveBeenCalledTimes(1);
|
|
71
|
+
expect(callback2).toHaveBeenCalledTimes(1);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseValueParser as ValueParser } from '../../value-parsers';
|
|
2
|
+
|
|
3
|
+
describe('number value parser', () => {
|
|
4
|
+
let parser: ValueParser;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
parser = new ValueParser({}, {});
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('should be converted to an array', () => {
|
|
11
|
+
expect(parser.toArr('A/B', '/')).toEqual(['A', 'B']);
|
|
12
|
+
expect(parser.toArr('A,B')).toEqual(['A', 'B']);
|
|
13
|
+
expect(parser.toArr('A, B')).toEqual(['A', 'B']);
|
|
14
|
+
expect(parser.toArr('A, B')).toEqual(['A', 'B']);
|
|
15
|
+
expect(parser.toArr('A, B ')).toEqual(['A', 'B']);
|
|
16
|
+
expect(parser.toArr('A, B ')).toEqual(['A', 'B']);
|
|
17
|
+
expect(parser.toArr('A、 B')).toEqual(['A', 'B']);
|
|
18
|
+
expect(parser.toArr('A ,, B')).toEqual(['A', 'B']);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import moment from 'moment';
|
|
2
|
+
import { Database, mockDatabase } from '../..';
|
|
3
|
+
import { DateValueParser } from '../../value-parsers';
|
|
4
|
+
|
|
5
|
+
describe('number value parser', () => {
|
|
6
|
+
let parser: DateValueParser;
|
|
7
|
+
let db: Database;
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
db = mockDatabase();
|
|
11
|
+
db.collection({
|
|
12
|
+
name: 'tests',
|
|
13
|
+
fields: [
|
|
14
|
+
{
|
|
15
|
+
name: 'date',
|
|
16
|
+
type: 'date',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'dateOnly',
|
|
20
|
+
type: 'date',
|
|
21
|
+
uiSchema: {
|
|
22
|
+
['x-component-props']: {
|
|
23
|
+
showTime: false,
|
|
24
|
+
gmt: false,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'dateTime',
|
|
30
|
+
type: 'date',
|
|
31
|
+
uiSchema: {
|
|
32
|
+
['x-component-props']: {
|
|
33
|
+
showTime: true,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'dateTimeGmt',
|
|
39
|
+
type: 'date',
|
|
40
|
+
uiSchema: {
|
|
41
|
+
['x-component-props']: {
|
|
42
|
+
showTime: true,
|
|
43
|
+
gmt: true,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
});
|
|
49
|
+
parser = new DateValueParser({}, {});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const expectValue = (value, field = 'date') => {
|
|
53
|
+
const collection = db.getCollection('tests');
|
|
54
|
+
parser = new DateValueParser(collection.getField(field), {});
|
|
55
|
+
parser.setValue(value);
|
|
56
|
+
return expect(parser.getValue());
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
it('should be correct', () => {
|
|
60
|
+
expectValue(42510).toBe('2016-05-20T00:00:00.000Z');
|
|
61
|
+
expectValue('42510').toBe('2016-05-20T00:00:00.000Z');
|
|
62
|
+
expectValue('2016-05-20T00:00:00.000Z').toBe('2016-05-20T00:00:00.000Z');
|
|
63
|
+
expectValue('2016-05-20 04:22:22', 'dateOnly').toBe('2016-05-20T00:00:00.000Z');
|
|
64
|
+
expectValue('2016-05-20 01:00:00', 'dateTime').toBe(moment('2016-05-20 01:00:00').toISOString());
|
|
65
|
+
expectValue('2016-05-20 01:00:00', 'dateTimeGmt').toBe('2016-05-20T01:00:00.000Z');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { NumberValueParser } from '../../value-parsers';
|
|
2
|
+
|
|
3
|
+
describe('number value parser', () => {
|
|
4
|
+
let parser: NumberValueParser;
|
|
5
|
+
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
parser = new NumberValueParser({}, {});
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const expectValue = (value) => {
|
|
11
|
+
parser = new NumberValueParser({}, {});
|
|
12
|
+
parser.setValue(value);
|
|
13
|
+
return expect(parser.getValue());
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
it('should be number', () => {
|
|
17
|
+
expectValue(123).toBe(123);
|
|
18
|
+
expect(parser.errors.length === 0).toBeTruthy();
|
|
19
|
+
expectValue('123').toBe(123);
|
|
20
|
+
expect(parser.errors.length === 0).toBeTruthy();
|
|
21
|
+
expectValue('123%').toBe(1.23);
|
|
22
|
+
expect(parser.errors.length === 0).toBeTruthy();
|
|
23
|
+
expectValue('22.5507%').toBe(0.225507);
|
|
24
|
+
expect(parser.errors.length === 0).toBeTruthy();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should be null', () => {
|
|
28
|
+
expectValue('').toBe(null);
|
|
29
|
+
expect(parser.errors.length === 0).toBeTruthy();
|
|
30
|
+
expectValue('n/a').toBe(null);
|
|
31
|
+
expect(parser.errors.length === 0).toBeTruthy();
|
|
32
|
+
expectValue('-').toBe(null);
|
|
33
|
+
expect(parser.errors.length === 0).toBeTruthy();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should be errors', () => {
|
|
37
|
+
expectValue({}).toBe(null);
|
|
38
|
+
expect(parser.errors.length > 0).toBeTruthy();
|
|
39
|
+
expectValue('123a').toBe(null);
|
|
40
|
+
expect(parser.errors.length > 0).toBeTruthy();
|
|
41
|
+
expectValue('123a%').toBe(null);
|
|
42
|
+
expect(parser.errors.length > 0).toBeTruthy();
|
|
43
|
+
expectValue('aaa').toBe(null);
|
|
44
|
+
expect(parser.errors.length > 0).toBeTruthy();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { Database, mockDatabase } from '../..';
|
|
2
|
+
import { ToManyValueParser } from '../../value-parsers';
|
|
3
|
+
|
|
4
|
+
describe('number value parser', () => {
|
|
5
|
+
let parser: ToManyValueParser;
|
|
6
|
+
let db: Database;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
db = mockDatabase();
|
|
10
|
+
db.collection({
|
|
11
|
+
name: 'posts',
|
|
12
|
+
fields: [
|
|
13
|
+
{
|
|
14
|
+
type: 'belongsToMany',
|
|
15
|
+
name: 'tags',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
type: 'belongsToMany',
|
|
19
|
+
name: 'attachments',
|
|
20
|
+
interface: 'attachment',
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
});
|
|
24
|
+
db.collection({
|
|
25
|
+
name: 'attachments',
|
|
26
|
+
fields: [],
|
|
27
|
+
});
|
|
28
|
+
db.collection({
|
|
29
|
+
name: 'tags',
|
|
30
|
+
fields: [
|
|
31
|
+
{
|
|
32
|
+
type: 'string',
|
|
33
|
+
name: 'name',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
await db.sync();
|
|
38
|
+
const tag = db.getRepository('tags');
|
|
39
|
+
await tag.create({
|
|
40
|
+
values: { name: 'tag1' },
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
afterEach(async () => {
|
|
45
|
+
await db.close();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const setValue = async (value) => {
|
|
49
|
+
const post = db.getCollection('posts');
|
|
50
|
+
parser = new ToManyValueParser(post.getField('tags'), {
|
|
51
|
+
column: {
|
|
52
|
+
dataIndex: ['tags', 'name'],
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
await parser.setValue(value);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const setAttachment = async (value) => {
|
|
59
|
+
const post = db.getCollection('posts');
|
|
60
|
+
parser = new ToManyValueParser(post.getField('attachments'), {});
|
|
61
|
+
await parser.setValue(value);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
it('should be [1]', async () => {
|
|
65
|
+
await setValue('tag1');
|
|
66
|
+
expect(parser.errors.length).toBe(0);
|
|
67
|
+
expect(parser.getValue()).toEqual([1]);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should be null', async () => {
|
|
71
|
+
await setValue('tag2');
|
|
72
|
+
expect(parser.errors.length).toBe(1);
|
|
73
|
+
expect(parser.getValue()).toBeNull();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should be attachment', async () => {
|
|
77
|
+
await setAttachment('https://www.nocobase.com/images/logo.png');
|
|
78
|
+
expect(parser.errors.length).toBe(0);
|
|
79
|
+
expect(parser.getValue()).toMatchObject([
|
|
80
|
+
{
|
|
81
|
+
title: 'logo.png',
|
|
82
|
+
extname: '.png',
|
|
83
|
+
filename: 'logo.png',
|
|
84
|
+
url: 'https://www.nocobase.com/images/logo.png',
|
|
85
|
+
},
|
|
86
|
+
]);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe.only('china region', () => {
|
|
91
|
+
let parser: ToManyValueParser;
|
|
92
|
+
let db: Database;
|
|
93
|
+
|
|
94
|
+
beforeEach(async () => {
|
|
95
|
+
db = mockDatabase();
|
|
96
|
+
db.collection({
|
|
97
|
+
name: 'users',
|
|
98
|
+
fields: [
|
|
99
|
+
{
|
|
100
|
+
type: 'belongsToMany',
|
|
101
|
+
name: 'chinaRegion',
|
|
102
|
+
target: 'chinaRegions',
|
|
103
|
+
interface: 'chinaRegion',
|
|
104
|
+
targetKey: 'code',
|
|
105
|
+
sortBy: 'level',
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
});
|
|
109
|
+
db.collection({
|
|
110
|
+
name: 'chinaRegions',
|
|
111
|
+
autoGenId: false,
|
|
112
|
+
fields: [
|
|
113
|
+
{
|
|
114
|
+
name: 'code',
|
|
115
|
+
type: 'string',
|
|
116
|
+
// unique: true,
|
|
117
|
+
primaryKey: true,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'name',
|
|
121
|
+
type: 'string',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'parent',
|
|
125
|
+
type: 'belongsTo',
|
|
126
|
+
target: 'chinaRegions',
|
|
127
|
+
targetKey: 'code',
|
|
128
|
+
foreignKey: 'parentCode',
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: 'children',
|
|
132
|
+
type: 'hasMany',
|
|
133
|
+
target: 'chinaRegions',
|
|
134
|
+
sourceKey: 'code',
|
|
135
|
+
foreignKey: 'parentCode',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'level',
|
|
139
|
+
type: 'integer',
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
});
|
|
143
|
+
await db.sync();
|
|
144
|
+
const areas = require('china-division/dist/areas.json');
|
|
145
|
+
const cities = require('china-division/dist/cities.json');
|
|
146
|
+
const provinces = require('china-division/dist/provinces.json');
|
|
147
|
+
const ChinaRegion = db.getModel('chinaRegions');
|
|
148
|
+
await ChinaRegion.bulkCreate(
|
|
149
|
+
provinces.map((item) => ({
|
|
150
|
+
code: item.code,
|
|
151
|
+
name: item.name,
|
|
152
|
+
level: 1,
|
|
153
|
+
})),
|
|
154
|
+
);
|
|
155
|
+
await ChinaRegion.bulkCreate(
|
|
156
|
+
cities.map((item) => ({
|
|
157
|
+
code: item.code,
|
|
158
|
+
name: item.name,
|
|
159
|
+
level: 2,
|
|
160
|
+
parentCode: item.provinceCode,
|
|
161
|
+
})),
|
|
162
|
+
);
|
|
163
|
+
await ChinaRegion.bulkCreate(
|
|
164
|
+
areas.map((item) => ({
|
|
165
|
+
code: item.code,
|
|
166
|
+
name: item.name,
|
|
167
|
+
level: 3,
|
|
168
|
+
parentCode: item.cityCode,
|
|
169
|
+
})),
|
|
170
|
+
);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
afterEach(async () => {
|
|
174
|
+
await db.close();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const setValue = async (value) => {
|
|
178
|
+
const r = db.getCollection('users');
|
|
179
|
+
parser = new ToManyValueParser(r.getField('chinaRegion'), {});
|
|
180
|
+
await parser.setValue(value);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
it('should be correct', async () => {
|
|
184
|
+
await setValue('北京市/市辖区');
|
|
185
|
+
expect(parser.errors.length).toBe(0);
|
|
186
|
+
expect(parser.getValue()).toEqual(['11', '1101']);
|
|
187
|
+
|
|
188
|
+
await setValue('北京市 / 市辖区');
|
|
189
|
+
expect(parser.errors.length).toBe(0);
|
|
190
|
+
expect(parser.getValue()).toEqual(['11', '1101']);
|
|
191
|
+
|
|
192
|
+
await setValue('天津市 / 市辖区');
|
|
193
|
+
expect(parser.errors.length).toBe(0);
|
|
194
|
+
expect(parser.getValue()).toEqual(['12', '1201']);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('should be null', async () => {
|
|
198
|
+
await setValue('北京市2 / 市辖区');
|
|
199
|
+
expect(parser.errors.length).toBe(1);
|
|
200
|
+
expect(parser.getValue()).toBeNull();
|
|
201
|
+
|
|
202
|
+
await setValue('北京市 / 市辖区 2');
|
|
203
|
+
expect(parser.errors.length).toBe(1);
|
|
204
|
+
expect(parser.getValue()).toBeNull();
|
|
205
|
+
});
|
|
206
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Database, mockDatabase } from '../..';
|
|
2
|
+
import { ToManyValueParser } from '../../value-parsers';
|
|
3
|
+
|
|
4
|
+
describe('number value parser', () => {
|
|
5
|
+
let parser: ToManyValueParser;
|
|
6
|
+
let db: Database;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
db = mockDatabase();
|
|
10
|
+
db.collection({
|
|
11
|
+
name: 'posts',
|
|
12
|
+
fields: [
|
|
13
|
+
{
|
|
14
|
+
type: 'belongsTo',
|
|
15
|
+
name: 'user',
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
});
|
|
19
|
+
db.collection({
|
|
20
|
+
name: 'users',
|
|
21
|
+
fields: [
|
|
22
|
+
{
|
|
23
|
+
type: 'string',
|
|
24
|
+
name: 'name',
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
});
|
|
28
|
+
await db.sync();
|
|
29
|
+
const r = db.getRepository('users');
|
|
30
|
+
await r.create({
|
|
31
|
+
values: { name: 'user1' },
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(async () => {
|
|
36
|
+
await db.close();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const setValue = async (value) => {
|
|
40
|
+
const post = db.getCollection('posts');
|
|
41
|
+
parser = new ToManyValueParser(post.getField('user'), {
|
|
42
|
+
column: {
|
|
43
|
+
dataIndex: ['user', 'name'],
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
await parser.setValue(value);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
it('should be correct', async () => {
|
|
50
|
+
await setValue('user1');
|
|
51
|
+
expect(parser.errors.length).toBe(0);
|
|
52
|
+
expect(parser.getValue()).toEqual([1]);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should be null', async () => {
|
|
56
|
+
await setValue('user2');
|
|
57
|
+
expect(parser.errors.length).toBe(1);
|
|
58
|
+
expect(parser.getValue()).toBeNull();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { readdir } from 'fs/promises';
|
|
3
|
-
import { isPlainObject } from 'lodash';
|
|
3
|
+
import { cloneDeep, isPlainObject } from 'lodash';
|
|
4
4
|
import { requireModule } from '@nocobase/utils';
|
|
5
5
|
|
|
6
6
|
export type ImportFileExtension = 'js' | 'ts' | 'json';
|
|
@@ -36,6 +36,6 @@ export class ImporterReader {
|
|
|
36
36
|
return typeof mod === 'function' ? mod() : mod;
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
return (await Promise.all(modules)).filter((module) => isPlainObject(module));
|
|
39
|
+
return (await Promise.all(modules)).filter((module) => isPlainObject(module)).map((module) => cloneDeep(module));
|
|
40
40
|
}
|
|
41
41
|
}
|