chore(database): merge fields arguments by path (#2331)
* feat: merge fields array arg * chore: test * chore: test * chore: test * fix: test
This commit is contained in:
parent
fd6d5ac2a6
commit
493965f848
@ -112,81 +112,115 @@ describe('option parser', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('option parser with fields option', async () => {
|
describe('options parser with fields option', () => {
|
||||||
let options: any = {
|
it('should handle field and association', () => {
|
||||||
|
const options: any = {
|
||||||
fields: ['id', 'posts'],
|
fields: ['id', 'posts'],
|
||||||
};
|
};
|
||||||
|
|
||||||
// 转换为 attributes: ['id'], include: [{association: 'posts'}]
|
// 转换为 attributes: ['id'], include: [{association: 'posts'}]
|
||||||
let parser = new OptionsParser(options, {
|
const parser = new OptionsParser(options, {
|
||||||
collection: User,
|
collection: User,
|
||||||
});
|
});
|
||||||
let params = parser.toSequelizeParams();
|
|
||||||
|
|
||||||
|
const params = parser.toSequelizeParams();
|
||||||
|
|
||||||
|
console.log(params);
|
||||||
expect(params['attributes']).toContain('id');
|
expect(params['attributes']).toContain('id');
|
||||||
expect(params['include'][0]['association']).toEqual('posts');
|
expect(params['include'][0]['association']).toEqual('posts');
|
||||||
|
});
|
||||||
|
|
||||||
// only appends
|
it('should handle field with association', () => {
|
||||||
options = {
|
const options = {
|
||||||
appends: ['posts'],
|
appends: ['posts'],
|
||||||
};
|
};
|
||||||
|
|
||||||
parser = new OptionsParser(options, {
|
const parser = new OptionsParser(options, {
|
||||||
collection: User,
|
collection: User,
|
||||||
});
|
});
|
||||||
params = parser.toSequelizeParams();
|
const params = parser.toSequelizeParams();
|
||||||
|
|
||||||
expect(params['attributes']['include']).toEqual([]);
|
expect(params['attributes']['include']).toEqual([]);
|
||||||
expect(params['include'][0]['association']).toEqual('posts');
|
expect(params['include'][0]['association']).toEqual('posts');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle field with association field', () => {
|
||||||
// fields with association field
|
// fields with association field
|
||||||
options = {
|
const options = {
|
||||||
fields: ['id', 'posts.title'],
|
fields: ['id', 'posts.title'],
|
||||||
};
|
};
|
||||||
|
|
||||||
parser = new OptionsParser(options, {
|
const parser = new OptionsParser(options, {
|
||||||
collection: User,
|
collection: User,
|
||||||
});
|
});
|
||||||
params = parser.toSequelizeParams();
|
|
||||||
|
const params = parser.toSequelizeParams();
|
||||||
expect(params['attributes']).toContain('id');
|
expect(params['attributes']).toContain('id');
|
||||||
expect(params['include'][0]['association']).toEqual('posts');
|
expect(params['include'][0]['association']).toEqual('posts');
|
||||||
expect(params['include'][0]['attributes']).toContain('title');
|
expect(params['include'][0]['attributes']).toContain('title');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle nested fields option', () => {
|
||||||
|
const options = {
|
||||||
|
fields: ['posts', 'posts.title'],
|
||||||
|
};
|
||||||
|
|
||||||
|
const parser = new OptionsParser(options, {
|
||||||
|
collection: User,
|
||||||
|
});
|
||||||
|
|
||||||
|
const params = parser.toSequelizeParams();
|
||||||
|
const postAssociationParams = params['include'][0];
|
||||||
|
expect(postAssociationParams['attributes']).toEqual({ include: [] });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle fields with association & association field', () => {
|
||||||
// fields with nested field
|
// fields with nested field
|
||||||
options = {
|
const options = {
|
||||||
fields: ['id', 'posts', 'posts.comments.content'],
|
fields: ['id', 'posts', 'posts.comments.content'],
|
||||||
};
|
};
|
||||||
|
|
||||||
parser = new OptionsParser(options, {
|
const parser = new OptionsParser(options, {
|
||||||
collection: User,
|
collection: User,
|
||||||
});
|
});
|
||||||
params = parser.toSequelizeParams();
|
|
||||||
expect(params['attributes']).toContain('id');
|
|
||||||
expect(params['include'][0]['association']).toEqual('posts');
|
|
||||||
expect(params['include'][0]['attributes']).toEqual({ include: [] });
|
|
||||||
expect(params['include'][0]['include'][0]['association']).toEqual('comments');
|
|
||||||
|
|
||||||
|
const params = parser.toSequelizeParams();
|
||||||
|
const postAssociationParams = params['include'][0];
|
||||||
|
|
||||||
|
expect(params['attributes']).toContain('id');
|
||||||
|
expect(postAssociationParams['association']).toEqual('posts');
|
||||||
|
expect(postAssociationParams['attributes']).toEqual({ include: [] });
|
||||||
|
expect(postAssociationParams['include'][0]['association']).toEqual('comments');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle except option', () => {
|
||||||
// fields with expect
|
// fields with expect
|
||||||
options = {
|
const options = {
|
||||||
except: ['id'],
|
except: ['id'],
|
||||||
};
|
};
|
||||||
parser = new OptionsParser(options, {
|
const parser = new OptionsParser(options, {
|
||||||
collection: User,
|
collection: User,
|
||||||
});
|
});
|
||||||
params = parser.toSequelizeParams();
|
|
||||||
expect(params['attributes']['exclude']).toContain('id');
|
|
||||||
|
|
||||||
|
const params = parser.toSequelizeParams();
|
||||||
|
expect(params['attributes']['exclude']).toContain('id');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle fields with except option', () => {
|
||||||
// expect with association
|
// expect with association
|
||||||
options = {
|
const options = {
|
||||||
fields: ['posts'],
|
fields: ['posts'],
|
||||||
except: ['posts.id'],
|
except: ['posts.id'],
|
||||||
};
|
};
|
||||||
|
|
||||||
parser = new OptionsParser(options, {
|
const parser = new OptionsParser(options, {
|
||||||
collection: User,
|
collection: User,
|
||||||
});
|
});
|
||||||
params = parser.toSequelizeParams();
|
const params = parser.toSequelizeParams();
|
||||||
|
|
||||||
expect(params['include'][0]['attributes']['exclude']).toContain('id');
|
expect(params['include'][0]['attributes']['exclude']).toContain('id');
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('option parser with multiple association', () => {
|
test('option parser with multiple association', () => {
|
||||||
// fields with association field
|
// fields with association field
|
||||||
|
@ -378,23 +378,33 @@ describe('repository find', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('find with fields', () => {
|
||||||
it('should only output filed in fields args', async () => {
|
it('should only output filed in fields args', async () => {
|
||||||
const resp = await User.model.findOne({
|
|
||||||
attributes: [],
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
association: 'profile',
|
|
||||||
attributes: ['salary'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
const users = await User.repository.find({
|
const users = await User.repository.find({
|
||||||
fields: ['profile', 'profile.salary', 'profile.id'],
|
fields: ['profile.salary'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const firstUser = users[0].toJSON();
|
const firstUser = users[0].toJSON();
|
||||||
expect(Object.keys(firstUser)).toEqual(['profile']);
|
expect(Object.keys(firstUser)).toEqual(['profile']);
|
||||||
|
expect(Object.keys(firstUser.profile)).toEqual(['salary']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should output all fields when field has relation field', async () => {
|
||||||
|
const users = await User.repository.find({
|
||||||
|
fields: ['profile.salary', 'profile'],
|
||||||
|
});
|
||||||
|
|
||||||
|
const firstUser = users[0].toJSON();
|
||||||
|
expect(Object.keys(firstUser)).toEqual(['profile']);
|
||||||
|
expect(Object.keys(firstUser.profile)).toEqual([
|
||||||
|
'id',
|
||||||
|
'createdAt',
|
||||||
|
'updatedAt',
|
||||||
|
'salary',
|
||||||
|
'userId',
|
||||||
|
'description',
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('append with associations', async () => {
|
it('append with associations', async () => {
|
||||||
|
@ -240,6 +240,9 @@ export class OptionsParser {
|
|||||||
protected parseAppends(appends: Appends, filterParams: any) {
|
protected parseAppends(appends: Appends, filterParams: any) {
|
||||||
if (!appends) return filterParams;
|
if (!appends) return filterParams;
|
||||||
|
|
||||||
|
// sort appends by path length
|
||||||
|
appends = lodash.sortBy(appends, (append) => append.split('.').length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set include params
|
* set include params
|
||||||
* @param model
|
* @param model
|
||||||
@ -287,6 +290,25 @@ export class OptionsParser {
|
|||||||
// if include from filter, remove fromFilter attribute
|
// if include from filter, remove fromFilter attribute
|
||||||
if (existIncludeIndex != -1) {
|
if (existIncludeIndex != -1) {
|
||||||
delete queryParams['include'][existIncludeIndex]['fromFilter'];
|
delete queryParams['include'][existIncludeIndex]['fromFilter'];
|
||||||
|
|
||||||
|
// set include attributes to all attributes
|
||||||
|
if (
|
||||||
|
Array.isArray(queryParams['include'][existIncludeIndex]['attributes']) &&
|
||||||
|
queryParams['include'][existIncludeIndex]['attributes'].length == 0
|
||||||
|
) {
|
||||||
|
queryParams['include'][existIncludeIndex]['attributes'] = {
|
||||||
|
include: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
lastLevel &&
|
||||||
|
existIncludeIndex != -1 &&
|
||||||
|
lodash.get(queryParams, ['include', existIncludeIndex, 'attributes', 'include'])?.length == 0
|
||||||
|
) {
|
||||||
|
// if append is last level and association exists, ignore it
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if association not exist, create it
|
// if association not exist, create it
|
||||||
|
Loading…
Reference in New Issue
Block a user