feat: rename resourceKey & associatedKey to resourceIndex & associatedIndex (#126)

* resourceIndex & associatedIndex

* resourceIndex & associatedIndex
This commit is contained in:
chenos 2021-12-04 16:28:52 +08:00 committed by GitHub
parent 62796f136c
commit c1b560e928
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 273 additions and 269 deletions

View File

@ -1,4 +1,6 @@
const path = require('path');
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig.jest.json');
module.exports = {
preset: 'ts-jest',
@ -10,6 +12,9 @@ module.exports = {
// '**/__tests__/**/*.[jt]s?(x)',
'**/?(*.)+(spec|test).[jt]s?(x)'
],
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
prefix: '<rootDir>/',
}),
modulePathIgnorePatterns: [
"<rootDir>/.dumi/",
"<rootDir>/packages/father-build/",

View File

@ -23,7 +23,7 @@ describe('create', () => {
],
});
await api.db.sync();
const response = await api.resource('tests').create({
const response = await api.agent().resource('tests').create({
values: { name: 'n1' },
});
expect(response.body.name).toBe('n1');
@ -45,7 +45,7 @@ describe('create', () => {
});
await api.db.sync();
const [Post, Comment] = api.db.getModels(['posts', 'comments']);
const response = await api.resource('posts').create({
const response = await api.agent().resource('posts').create({
values: {
title: 't1',
comments: [
@ -56,8 +56,8 @@ describe('create', () => {
});
expect(await Post.count()).toBe(1);
expect(await Comment.count()).toBe(2);
await api.resource('posts.comments').create({
associatedKey: response.body.id,
await api.agent().resource('posts.comments').create({
associatedIndex: response.body.id,
values: { content: 'c1' },
});
expect(await Comment.count()).toBe(3);

View File

@ -9,14 +9,14 @@ describe('destroy', () => {
dataWrapping: false,
});
registerActions(api);
api.db.table({
api.collection({
name: 'posts',
fields: [
{ type: 'string', name: 'title' },
{ type: 'hasMany', name: 'comments' },
],
});
api.db.table({
api.collection({
name: 'comments',
fields: [{ type: 'string', name: 'content' }],
});
@ -35,8 +35,8 @@ describe('destroy', () => {
where: { id: post.id },
}),
).toBe(1);
await api.resource('posts').destroy({
resourceKey: post.id,
await api.agent().resource('posts').destroy({
resourceIndex: post.id,
});
expect(
await Post.count({
@ -52,9 +52,9 @@ describe('destroy', () => {
await post.updateAssociations({
comments: [comment],
});
await api.resource('posts.comments').destroy({
resourceKey: comment.id,
associatedKey: post.id,
await api.agent().resource('posts.comments').destroy({
resourceIndex: comment.id,
associatedIndex: post.id,
});
const comment2 = await Comment.findByPk(comment.id);
expect(comment2).toBeNull();

View File

@ -32,8 +32,8 @@ describe('get', () => {
it('get', async () => {
const Post = api.db.getModel('posts');
const post = await Post.create({ title: 't1' });
const response = await api.resource('posts').get({
resourceKey: post.id,
const response = await api.agent().resource('posts').get({
resourceIndex: post.id,
fields: ['id', 'title']
});
expect(post.toJSON()).toMatchObject(response.body);
@ -46,9 +46,9 @@ describe('get', () => {
await post.updateAssociations({
comments: [comment]
});
const response = await api.resource('posts.comments').get({
resourceKey: comment.id,
associatedKey: post.id,
const response = await api.agent().resource('posts.comments').get({
resourceIndex: comment.id,
associatedIndex: post.id,
fields: ['id', 'post_id', 'content']
});
const comment2 = await Comment.findByPk(comment.id);

View File

@ -40,7 +40,7 @@ describe('list', () => {
describe('fields', () => {
it('fields', async () => {
const response = await api.resource('posts').list({
const response = await api.agent().resource('posts').list({
fields: ['title'],
filter: {
title: 't1',
@ -55,7 +55,7 @@ describe('list', () => {
});
it('fields#appends', async () => {
const response = await api.resource('posts').list({
const response = await api.agent().resource('posts').list({
fields: {
appends: ['comments'],
},
@ -89,7 +89,7 @@ describe('list', () => {
describe('filter', () => {
it('and', async () => {
const response = await api.resource('posts').list({
const response = await api.agent().resource('posts').list({
filter: {
and: [
{ title: 't1' },
@ -109,7 +109,7 @@ describe('list', () => {
});
});
it('or', async () => {
const response = await api.resource('posts').list({
const response = await api.agent().resource('posts').list({
filter: {
or: [
{ title: 't1' },

View File

@ -31,11 +31,11 @@ describe('sort', () => {
});
it('targetId', async () => {
await api.resource('tests').sort({
await api.agent().resource('tests').sort({
sourceId: 1,
targetId: 3,
});
const response = await api.resource('tests').list({
const response = await api.agent().resource('tests').list({
sort: ['sort'],
});
expect(response.body).toMatchObject({
@ -61,11 +61,11 @@ describe('sort', () => {
});
it('targetId', async () => {
await api.resource('tests').sort({
await api.agent().resource('tests').sort({
sourceId: 3,
targetId: 1,
});
const response = await api.resource('tests').list({
const response = await api.agent().resource('tests').list({
sort: ['sort'],
});
expect(response.body).toMatchObject({
@ -91,12 +91,12 @@ describe('sort', () => {
});
it('sortField', async () => {
await api.resource('tests').sort({
await api.agent().resource('tests').sort({
sortField: 'sort2',
sourceId: 1,
targetId: 3,
});
const response = await api.resource('tests').list({
const response = await api.agent().resource('tests').list({
sort: ['sort2'],
});
expect(response.body).toMatchObject({
@ -122,11 +122,11 @@ describe('sort', () => {
});
it('sticky', async () => {
await api.resource('tests').sort({
await api.agent().resource('tests').sort({
sourceId: 3,
sticky: true,
});
const response = await api.resource('tests').list({
const response = await api.agent().resource('tests').list({
sort: ['sort'],
});
expect(response.body).toMatchObject({
@ -183,11 +183,11 @@ describe('sort', () => {
});
it('targetId/1->6', async () => {
await api.resource('tests').sort({
await api.agent().resource('tests').sort({
sourceId: 1,
targetId: 6,
});
let response = await api.resource('tests').list({
let response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 1 },
});
@ -207,7 +207,7 @@ describe('sort', () => {
},
],
});
response = await api.resource('tests').list({
response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 2 },
});
@ -238,12 +238,12 @@ describe('sort', () => {
});
it('targetId/1->6 - method=insertAfter', async () => {
await api.resource('tests').sort({
await api.agent().resource('tests').sort({
sourceId: 1,
targetId: 6,
method: 'insertAfter',
});
let response = await api.resource('tests').list({
let response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 1 },
});
@ -263,7 +263,7 @@ describe('sort', () => {
},
],
});
response = await api.resource('tests').list({
response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 2 },
});
@ -294,11 +294,11 @@ describe('sort', () => {
});
it('targetId/6->2', async () => {
await api.resource('tests').sort({
await api.agent().resource('tests').sort({
sourceId: 6,
targetId: 2,
});
let response = await api.resource('tests').list({
let response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 1 },
});
@ -326,7 +326,7 @@ describe('sort', () => {
},
],
});
response = await api.resource('tests').list({
response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 2 },
});
@ -349,12 +349,12 @@ describe('sort', () => {
});
it('targetId/6->2 - method=insertAfter', async () => {
await api.resource('tests').sort({
await api.agent().resource('tests').sort({
sourceId: 6,
targetId: 2,
method: 'insertAfter',
});
let response = await api.resource('tests').list({
let response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 1 },
});
@ -382,7 +382,7 @@ describe('sort', () => {
},
],
});
response = await api.resource('tests').list({
response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 2 },
});
@ -405,13 +405,13 @@ describe('sort', () => {
});
it('targetScope', async () => {
await api.resource('tests').sort({
await api.agent().resource('tests').sort({
sourceId: 1,
targetScope: {
state: 2,
},
});
let response = await api.resource('tests').list({
let response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 1 },
});
@ -431,7 +431,7 @@ describe('sort', () => {
},
],
});
response = await api.resource('tests').list({
response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 2 },
});
@ -462,14 +462,14 @@ describe('sort', () => {
});
it('targetScope - method=prepend', async () => {
await api.resource('tests').sort({
await api.agent().resource('tests').sort({
sourceId: 1,
targetScope: {
state: 2,
},
method: 'prepend',
});
let response = await api.resource('tests').list({
let response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 1 },
});
@ -486,7 +486,7 @@ describe('sort', () => {
},
],
});
response = await api.resource('tests').list({
response = await api.agent().resource('tests').list({
sort: ['sort'],
filter: { state: 2 },
});

View File

@ -32,8 +32,8 @@ describe('update', () => {
it('update', async () => {
const Post = api.db.getModel('posts');
const post = await Post.create();
await api.resource('posts').update({
resourceKey: post.id,
await api.agent().resource('posts').update({
resourceIndex: post.id,
values: {
title: 't1',
},
@ -51,9 +51,9 @@ describe('update', () => {
await post.updateAssociations({
comments: [comment]
});
await api.resource('posts.comments').update({
resourceKey: comment.id,
associatedKey: post.id,
await api.agent().resource('posts.comments').update({
resourceIndex: comment.id,
associatedIndex: post.id,
values: {
content: 'c2',
},

View File

@ -28,7 +28,7 @@ export async function add(ctx: Context, next: Next) {
throw new Error(`${associatedName} associated model invalid`);
}
const { add: addAccessor } = resourceField.getAccessors();
const { resourceKey, resourceKeyAttribute, fields = [] } = ctx.action.params;
const { resourceIndex, resourceIndexAttribute, fields = [] } = ctx.action.params;
const TargetModel = ctx.db.getModel(resourceField.getTarget());
// const options = TargetModel.parseApiJson({
// fields,
@ -36,7 +36,7 @@ export async function add(ctx: Context, next: Next) {
const model = await TargetModel.findOne({
// ...options,
where: {
[resourceKeyAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceKey,
[resourceIndexAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceIndex,
},
// @ts-ignore
context: ctx,

View File

@ -27,8 +27,8 @@ export async function destroy(ctx: Context, next: Next) {
resourceField,
associatedName,
resourceName,
resourceKey,
resourceKeyAttribute,
resourceIndex,
resourceIndexAttribute,
filter,
} = ctx.action.params;
const transaction = await ctx.db.sequelize.transaction();
@ -58,11 +58,11 @@ export async function destroy(ctx: Context, next: Next) {
resourceField instanceof BELONGSTOMANY
) {
const primaryKey =
resourceKeyAttribute ||
resourceIndexAttribute ||
resourceField.options.targetKey ||
TargetModel.primaryKeyAttribute;
const models: Model[] = await associated[getAccessor]({
where: resourceKey ? { [primaryKey]: resourceKey } : where,
where: resourceIndex ? { [primaryKey]: resourceIndex } : where,
...commonOptions,
});
// TODO不能程序上解除关系直接通过 onDelete 触发,或者通过 afterDestroy 处理
@ -79,9 +79,9 @@ export async function destroy(ctx: Context, next: Next) {
} else {
const Model = ctx.db.getModel(resourceName);
const { where } = Model.parseApiJson({ filter, context: ctx });
const primaryKey = resourceKeyAttribute || Model.primaryKeyAttribute;
const primaryKey = resourceIndexAttribute || Model.primaryKeyAttribute;
count = await Model.destroy({
where: resourceKey ? { [primaryKey]: resourceKey } : where,
where: resourceIndex ? { [primaryKey]: resourceIndex } : where,
// @ts-ignore hooks 里添加 context
...commonOptions,
individualHooks: true,

View File

@ -20,8 +20,8 @@ export async function get(ctx: Context, next: Next) {
resourceField,
associatedName,
resourceName,
resourceKey,
resourceKeyAttribute,
resourceIndex,
resourceIndexAttribute,
fields = []
} = ctx.action.params;
if (associated && resourceField) {
@ -50,7 +50,7 @@ export async function get(ctx: Context, next: Next) {
const [model]: Model[] = await associated[getAccessor]({
...options,
where: {
[resourceKeyAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceKey,
[resourceIndexAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceIndex,
},
context: ctx,
});
@ -64,7 +64,7 @@ export async function get(ctx: Context, next: Next) {
const data = await Model.findOne({
...options,
where: {
[resourceKeyAttribute || Model.primaryKeyAttribute]: resourceKey,
[resourceIndexAttribute || Model.primaryKeyAttribute]: resourceIndex,
},
// @ts-ignore hooks 里添加 context
context: ctx,

View File

@ -33,7 +33,7 @@ export async function remove(ctx: Context, next: Next) {
throw new Error(`${associatedName} associated model invalid`);
}
const { get: getAccessor, remove: removeAccessor, set: setAccessor } = resourceField.getAccessors();
const { resourceKey, resourceKeyAttribute, fields = [] } = ctx.action.params;
const { resourceIndex, resourceIndexAttribute, fields = [] } = ctx.action.params;
const TargetModel = ctx.db.getModel(resourceField.getTarget());
const options = TargetModel.parseApiJson({
fields,
@ -44,7 +44,7 @@ export async function remove(ctx: Context, next: Next) {
const [model]: Model[] = await associated[getAccessor]({
...options,
where: {
[resourceKeyAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceKey,
[resourceIndexAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceIndex,
},
context: ctx,
});

View File

@ -33,14 +33,14 @@ export async function set(ctx: Context, next: Next) {
throw new Error(`${associatedName} associated model invalid`);
}
const { set: setAccessor } = resourceField.getAccessors();
const { resourceKey, resourceKeyAttribute, fields = [] } = ctx.action.params;
const { resourceIndex, resourceIndexAttribute, fields = [] } = ctx.action.params;
const TargetModel = ctx.db.getModel(resourceField.getTarget());
// const options = TargetModel.parseApiJson({
// fields,
// });
const model = await TargetModel.findOne({
where: {
[resourceKeyAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceKey,
[resourceIndexAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceIndex,
},
// @ts-ignore
context: ctx,

View File

@ -18,10 +18,10 @@ import {
export async function sort(ctx: Context, next: Next) {
const {
resourceName,
resourceKey,
resourceIndex,
resourceField,
associatedName,
associatedKey,
associatedIndex,
associated,
values = {},
...others
@ -41,7 +41,7 @@ export async function sort(ctx: Context, next: Next) {
const table = ctx.db.getTable(resourceName);
const { primaryKeyAttribute } = Model;
const sourceId = others.sourceId || resourceKey;
const sourceId = others.sourceId || resourceIndex;
const field = others.sortField || values?.sortField || values?.field || 'sort';
const targetId = others.targetId || values?.targetId || values?.target?.[primaryKeyAttribute];
const method = others.method || values?.method;
@ -70,7 +70,7 @@ export async function sort(ctx: Context, next: Next) {
const where = {};
if (associated && resourceField instanceof HASMANY) {
where[resourceField.options.foreignKey] = associatedKey;
where[resourceField.options.foreignKey] = associatedIndex;
}
// 找到操作对象

View File

@ -24,20 +24,20 @@ export async function toggle(ctx: Context, next: Next) {
throw new Error(`${associatedName} associated model invalid`);
}
const { get: getAccessor, remove: removeAccessor, set: setAccessor, add: addAccessor } = resourceField.getAccessors();
const { resourceKey, resourceKeyAttribute, fields = [] } = ctx.action.params;
const { resourceIndex, resourceIndexAttribute, fields = [] } = ctx.action.params;
const TargetModel = ctx.db.getModel(resourceField.getTarget());
const options = TargetModel.parseApiJson({
fields,
});
if (resourceField instanceof HASONE || resourceField instanceof BELONGSTO) {
const m1 = await associated[getAccessor]();
if (m1 && m1[resourceKeyAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute] == resourceKey) {
if (m1 && m1[resourceIndexAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute] == resourceIndex) {
ctx.body = await associated[setAccessor](null);
} else {
const m2 = await TargetModel.findOne({
// ...options,
where: {
[resourceKeyAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceKey,
[resourceIndexAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceIndex,
},
// @ts-ignore
context: ctx,
@ -48,7 +48,7 @@ export async function toggle(ctx: Context, next: Next) {
const [model]: Model[] = await associated[getAccessor]({
...options,
where: {
[resourceKeyAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceKey,
[resourceIndexAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceIndex,
},
context: ctx,
});
@ -58,7 +58,7 @@ export async function toggle(ctx: Context, next: Next) {
const m2 = await TargetModel.findOne({
// ...options,
where: {
[resourceKeyAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceKey,
[resourceIndexAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceIndex,
},
// @ts-ignore
context: ctx,

View File

@ -24,9 +24,9 @@ export async function update(ctx: Context, next: Next) {
associatedName,
resourceField,
resourceName,
resourceKey,
resourceIndex,
// TODO(question): 这个属性从哪设置的?
resourceKeyAttribute,
resourceIndexAttribute,
fields,
values: data
} = ctx.action.params;
@ -53,7 +53,7 @@ export async function update(ctx: Context, next: Next) {
const [model]: Model[] = await associated[getAccessor]({
...options,
where: {
[resourceKeyAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceKey,
[resourceIndexAttribute || resourceField.options.targetKey || TargetModel.primaryKeyAttribute]: resourceIndex,
}
});
@ -66,7 +66,7 @@ export async function update(ctx: Context, next: Next) {
const through = await ThroughModel.findOne({
where: {
[foreignKey]: associated[sourceKey],
[otherKey]: resourceKey,
[otherKey]: resourceIndex,
},
transaction
});
@ -88,7 +88,7 @@ export async function update(ctx: Context, next: Next) {
const model = await Model.findOne({
...options,
where: {
[resourceKeyAttribute || Model.primaryKeyAttribute]: resourceKey,
[resourceIndexAttribute || Model.primaryKeyAttribute]: resourceIndex,
}
});
// @ts-ignore

View File

@ -7,9 +7,9 @@ export async function associated(ctx: Context, next: Next) {
return next();
}
const { associated, associatedName, associatedKey, resourceName } = ctx.action.params;
const { associated, associatedName, associatedIndex, resourceName } = ctx.action.params;
if (!associatedName || !associatedKey) {
if (!associatedName || !associatedIndex) {
return next();
}
@ -37,7 +37,7 @@ export async function associated(ctx: Context, next: Next) {
if (key) {
const model = await Model.findOne({
where: {
[key]: associatedKey,
[key]: associatedIndex,
}
});
if (model) {

View File

@ -66,7 +66,7 @@ const useActionPermissionSubmit = () => {
const role = useContext(RoleContext);
const resource = useResourceRequest({
resourceName: 'roles',
resourceKey: role.name,
resourceIndex: role.name,
});
return {
async run() {
@ -134,7 +134,7 @@ const useDetailsResource = ({ onSuccess }) => {
const ctx = useContext(TableRowContext);
const resource = useResourceRequest({
resourceName: 'collections',
resourceKey: ctx.record[props.rowKey],
resourceIndex: ctx.record[props.rowKey],
});
const service = useRequest(
(params?: any) => {
@ -762,7 +762,7 @@ function EditFieldButton() {
const fieldInterface = interfaces.get(form.values?.interface);
fieldInterface?.initialize && fieldInterface?.initialize(form.values);
await resource.save(form.values, {
resourceKey: ctx.record.key,
resourceIndex: ctx.record.key,
});
setVisible(false);
await service.refresh();

View File

@ -66,7 +66,7 @@ const useFieldPermissions = () => {
};
const resource = useResourceRequest({
associatedName: 'collections',
associatedKey: ctx.record.name,
associatedIndex: ctx.record.name,
resourceName: 'fields',
});
const service = useRequest(

View File

@ -33,7 +33,7 @@ export const MenuPermissionTable = observer((props) => {
console.log('allUiSchemaKyes', allUiSchemaKyes);
const resource = useResourceRequest({
associatedName: 'roles',
associatedKey: role.name,
associatedIndex: role.name,
resourceName: 'ui_schemas',
});
useRequest(() => resource.list(), {
@ -44,7 +44,7 @@ export const MenuPermissionTable = observer((props) => {
});
const resource2 = useResourceRequest({
resourceName: 'roles',
resourceKey: role.name,
resourceIndex: role.name,
});
if (loading) {
return <Spin size={'large'} className={'nb-spin-center'} />;
@ -106,7 +106,7 @@ export const MenuPermissionTable = observer((props) => {
return [...prevUiSchemaKeys];
});
await resource.toggle({
resourceKey: value,
resourceIndex: value,
});
}}
/>

View File

@ -59,7 +59,7 @@ const useActionPermissionSubmit = () => {
const role = useContext(RoleContext);
const resource = useResourceRequest({
resourceName: 'roles',
resourceKey: role.name,
resourceIndex: role.name,
});
return {
async run() {
@ -127,7 +127,7 @@ const useDetailsResource = ({ onSuccess }) => {
const ctx = useContext(TableRowContext);
const resource = useResourceRequest({
resourceName: 'roles',
resourceKey: ctx.record[props.rowKey],
resourceIndex: ctx.record[props.rowKey],
});
const service = useRequest(
(params?: any) => {

View File

@ -10,12 +10,12 @@ export const SystemSettingsContext = createContext(null);
export function SystemSettingsProvider(props) {
const resource = useResourceRequest({
resourceName: 'system_settings',
resourceKey: 1,
resourceIndex: 1,
});
const service = useRequest(
() =>
resource.get({
resourceKey: 1,
resourceIndex: 1,
appends: ['logo'],
}),
{

View File

@ -152,13 +152,13 @@ const useAssociationResource = (options) => {
const collectionField = useContext(CollectionFieldContext);
const { collection } = useCollectionContext();
const ctx = useContext(TableRowContext);
const associatedKey = ctx?.record?.id;
const associatedIndex = ctx?.record?.id;
console.log('useAssociationResource', collection, collectionField, schema['x-component-props']);
const { associatedName, resourceName } = schema['x-component-props'] || {};
const resource = useResourceRequest({
associatedName,
resourceName,
associatedKey,
associatedIndex,
});
const service = useRequest((params) => resource.list(params), {
manual: schema['x-component'] === 'Form',

View File

@ -3,19 +3,19 @@ import { request as req } from './schemas';
export interface ResourceOptions {
resourceName: string;
associatedKey?: any;
associatedIndex?: any;
associatedName?: string;
resourceKey?: any;
resourceIndex?: any;
}
export interface GetOptions {
resourceKey?: any;
resourceIndex?: any;
defaultAppends?: any[];
appends?: string[];
}
export interface SaveOptions {
resourceKey?: any;
resourceIndex?: any;
}
export interface ListOptions {
@ -42,8 +42,8 @@ export class Resource {
sort(options) {
const { resourceName } = this.options;
const { resourceKey, target, field = 'sort' } = options;
return this.request(`${resourceName}:sort/${resourceKey}`, {
const { resourceIndex, target, field = 'sort' } = options;
return this.request(`${resourceName}:sort/${resourceIndex}`, {
method: 'post',
data: {
target,
@ -61,10 +61,10 @@ export class Resource {
pageSize,
...others
} = options;
const { associatedKey, associatedName, resourceName } = this.options;
const { associatedIndex, associatedName, resourceName } = this.options;
let url = `${resourceName}:list`;
if (associatedName && associatedKey) {
url = `${associatedName}/${associatedKey}/${resourceName}:list`;
if (associatedName && associatedIndex) {
url = `${associatedName}/${associatedIndex}/${resourceName}:list`;
}
return this.request(url, {
method: 'get',
@ -80,13 +80,13 @@ export class Resource {
}
get(options: GetOptions = {}) {
const resourceKey = options.resourceKey || this.options.resourceKey;
const resourceIndex = options.resourceIndex || this.options.resourceIndex;
const { resourceName } = this.options;
if (!resourceKey) {
if (!resourceIndex) {
return Promise.resolve({ data: {} });
}
const { defaultAppends = [], appends = [], ...others } = options;
return this.request(`${resourceName}:get/${resourceKey}`, {
return this.request(`${resourceName}:get/${resourceIndex}`, {
params: {
...others,
'fields[appends]': defaultAppends.concat(appends).join(','),
@ -95,10 +95,10 @@ export class Resource {
}
create(values: any) {
const { associatedKey, associatedName, resourceName } = this.options;
const { associatedIndex, associatedName, resourceName } = this.options;
let url = `${resourceName}:create`;
if (associatedKey && associatedName) {
url = `${associatedName}/${associatedKey}/${url}`;
if (associatedIndex && associatedName) {
url = `${associatedName}/${associatedIndex}/${url}`;
}
return this.request(url, {
method: 'post',
@ -107,13 +107,13 @@ export class Resource {
}
save(values: any, options: SaveOptions = {}) {
const resourceKey = options.resourceKey || this.options.resourceKey;
const { associatedKey, associatedName, resourceName } = this.options;
const resourceIndex = options.resourceIndex || this.options.resourceIndex;
const { associatedIndex, associatedName, resourceName } = this.options;
let url = `${resourceName}:${
resourceKey ? `update/${resourceKey}` : 'create'
resourceIndex ? `update/${resourceIndex}` : 'create'
}`;
if (associatedKey && associatedName) {
url = `${associatedName}/${associatedKey}/${url}`;
if (associatedIndex && associatedName) {
url = `${associatedName}/${associatedIndex}/${url}`;
}
return this.request(url, {
method: 'post',
@ -171,9 +171,9 @@ export class Resource {
}
toggle(options?: any) {
const { associatedKey, associatedName, resourceName } = this.options;
const { resourceKey } = options;
let url = `${associatedName}/${associatedKey}/${resourceName}:toggle/${resourceKey}`;
const { associatedIndex, associatedName, resourceName } = this.options;
const { resourceIndex } = options;
let url = `${associatedName}/${associatedIndex}/${resourceName}:toggle/${resourceIndex}`;
return this.request(url, {
method: 'post',
});

View File

@ -279,7 +279,7 @@ Calendar.useResource = ({ onSuccess }) => {
const record = useContext(RecordContext);
const resource = useResourceRequest({
resourceName: collection?.name || props.collectionName,
resourceKey: record['id'],
resourceIndex: record['id'],
});
console.log(
'collection?.name || props.collectionName',

View File

@ -294,11 +294,11 @@ const InternalKanban = observer((props: any) => {
[groupField.name]: overColumnId,
},
{
resourceKey: activeId,
resourceIndex: activeId,
},
);
await resource.sort({
resourceKey: activeId,
resourceIndex: activeId,
field: 'sort',
target: lastId
? {
@ -331,11 +331,11 @@ const InternalKanban = observer((props: any) => {
[groupField.name]: overColumnId,
},
{
resourceKey: activeId,
resourceIndex: activeId,
},
);
await resource.sort({
resourceKey: activeId,
resourceIndex: activeId,
field: 'sort',
target: {
id: overId,
@ -347,11 +347,11 @@ const InternalKanban = observer((props: any) => {
[groupField.name]: overId,
},
{
resourceKey: activeId,
resourceIndex: activeId,
},
);
await resource.sort({
resourceKey: activeId,
resourceIndex: activeId,
field: 'sort',
target: lastId
? {
@ -468,7 +468,7 @@ Kanban.useUpdateAction = () => {
return {
async run() {
await resource.save(omit(form.values, ['sort']), {
resourceKey: ctx.record.id,
resourceIndex: ctx.record.id,
});
setVisible(false);
await service.refresh();
@ -482,7 +482,7 @@ Kanban.useRowResource = ({ onSuccess }) => {
const ctx = useContext(KanbanCardContext);
const resource = useResourceRequest({
resourceName: collection?.name || props.collectionName,
resourceKey: ctx?.record?.id,
resourceIndex: ctx?.record?.id,
});
const service = useRequest(
(params?: any) => {
@ -524,7 +524,7 @@ Kanban.useSingleResource = ({ onSuccess }) => {
const resource = useResourceRequest({
resourceName: collection?.name || props.collectionName,
resourceKey: ctx?.record?.id,
resourceIndex: ctx?.record?.id,
});
const service = useRequest(
(params?: any) => {

View File

@ -1006,7 +1006,7 @@ Menu.DesignableBar = (props) => {
};
const resource = Resource.make({
associatedName: 'ui_schemas',
associatedKey: schema['key'],
associatedIndex: schema['key'],
resourceName: 'roles',
});
const uiSchemasRoles = await resource.list();
@ -1043,7 +1043,7 @@ Menu.DesignableBar = (props) => {
});
await Resource.make({
resourceName: 'ui_schemas',
resourceKey: schema['key'],
resourceIndex: schema['key'],
}).save(values);
}}
>

View File

@ -489,7 +489,7 @@ Select.Drawer.useResource = ({ onSuccess }) => {
const ctx = useContext(OptionTagContext);
const resource = useResourceRequest({
resourceName: collection?.name,
resourceKey: ctx.data.id,
resourceIndex: ctx.data.id,
});
console.log('OptionTagContext', ctx.data.id);
const { schema } = useDesignable();

View File

@ -43,7 +43,7 @@ export const TableMain = () => {
field.move(fromIndex, toIndex);
refresh();
await resource.sort({
resourceKey: fromId,
resourceIndex: fromId,
target: {
[rowKey]: toId,
},

View File

@ -11,7 +11,7 @@ export const useActionLogDetailsResource = ({ onSuccess }) => {
const ctx = useContext(TableRowContext);
const resource = useResourceRequest({
resourceName: 'action_logs',
resourceKey: ctx.record[props.rowKey],
resourceIndex: ctx.record[props.rowKey],
});
const service = useRequest(
(params?: any) => {

View File

@ -12,7 +12,7 @@ export const useResource = ({ onSuccess, manual = true }) => {
const ctx = useContext(TableRowContext);
const resource = useResourceRequest({
resourceName: collection?.name || props.collectionName,
resourceKey: ctx.record[props.rowKey],
resourceIndex: ctx.record[props.rowKey],
});
const { schema } = useDesignable();
const fieldFields = (schema: Schema) => {

View File

@ -20,7 +20,7 @@ export const useTableUpdateAction = () => {
async run() {
if (refreshRequestOnChange) {
await resource.save(form.values, {
resourceKey: ctx.record[rowKey],
resourceIndex: ctx.record[rowKey],
});
if (formService) {
await formService.refresh();

View File

@ -1,5 +1,4 @@
import Database from '@nocobase/database';
import { registerActions } from '@nocobase/actions';
import { mockServer, MockServer } from '@nocobase/test';
import logPlugin from '../server';
@ -9,13 +8,9 @@ describe('hook', () => {
beforeEach(async () => {
api = mockServer();
api.registerPlugin({
collections: require('@nocobase/plugin-collections/src/server').default,
users: require('@nocobase/plugin-users/src/server').default,
logs: logPlugin,
});
registerActions(api);
await api.loadPlugins();
api.plugin(require('@nocobase/plugin-users').default);
api.plugin(logPlugin);
await api.load();
db = api.db;
db.table({
name: 'posts',
@ -34,8 +29,7 @@ describe('hook', () => {
});
await db.sync();
const User = db.getModel('users');
const user = await User.create({ nickname: 'a', token: 'token1' });
api.agent().set('Authorization', `Bearer ${user.token}`);
await User.create({ nickname: 'a', token: 'token1' });
});
afterEach(async () => {
@ -53,15 +47,17 @@ describe('hook', () => {
});
it('resource', async () => {
const response = await api.resource('posts').create({
const agent = api.agent()
agent.set('Authorization', `Bearer token1`);
const response = await agent.resource('posts').create({
values: { title: 't1' },
});
await api.resource('posts').update({
resourceKey: response.body.data.id,
await agent.resource('posts').update({
resourceIndex: response.body.data.id,
values: { title: 't2' },
});
await api.resource('posts').destroy({
resourceKey: response.body.data.id,
await agent.resource('posts').destroy({
resourceIndex: response.body.data.id,
});
const ActionLog = db.getModel('action_logs');
const count = await ActionLog.count();

View File

@ -0,0 +1 @@
export { default } from './server';

View File

@ -85,10 +85,10 @@ export async function getApp() {
}
interface ActionParams {
resourceKey?: string | number;
resourceIndex?: string | number;
// resourceName?: string;
// associatedName?: string;
associatedKey?: string | number;
associatedIndex?: string | number;
fields?: any;
filter?: any;
values?: any;
@ -118,14 +118,14 @@ export function getAPI(agent) {
return new Proxy({}, {
get(target, method: string, receiver) {
return (params: ActionParams = {}) => {
const { associatedKey, resourceKey, values = {}, filePath, ...restParams } = params;
const { associatedIndex, resourceIndex, values = {}, filePath, ...restParams } = params;
let url = `/api/${name}`;
if (associatedKey) {
url = `/api/${name.split('.').join(`/${associatedKey}/`)}`;
if (associatedIndex) {
url = `/api/${name.split('.').join(`/${associatedIndex}/`)}`;
}
url += `:${method as string}`;
if (resourceKey) {
url += `/${resourceKey}`;
if (resourceIndex) {
url += `/${resourceIndex}`;
}
switch (method) {

View File

@ -243,7 +243,7 @@ export default {
// condition: "{{ $self.value }}",
schema: {
"x-component-props": {
"associatedKey": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}"
"associatedIndex": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}"
},
},
},
@ -253,7 +253,7 @@ export default {
// condition: "{{ $self.value }}",
schema: {
"x-component-props": {
"associatedKey": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}"
"associatedIndex": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}"
},
},
},
@ -263,7 +263,7 @@ export default {
// condition: "{{ $self.value }}",
schema: {
"x-component-props": {
"associatedKey": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}"
"associatedIndex": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}"
},
},
},
@ -273,7 +273,7 @@ export default {
// condition: "{{ $self.value }}",
schema: {
"x-component-props": {
"associatedKey": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}"
"associatedIndex": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}"
},
},
},
@ -406,7 +406,7 @@ export default {
condition: "{{ ($form.values.collection_name || $form.values.collection) && $self.value === 'customField' }}",
schema: {
"x-component-props": {
"associatedKey": "{{ $form.values.collection_name || $form.values.collection }}"
"associatedIndex": "{{ $form.values.collection_name || $form.values.collection }}"
},
},
},

View File

@ -84,7 +84,7 @@ export default {
// condition: "{{ $self.value }}",
schema: {
"x-component-props": {
"associatedKey": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}",
"associatedIndex": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}",
"sourceName": "{{ $form.values.automation ? $form.values.automation.collection_name : null }}"
},
},
@ -95,7 +95,7 @@ export default {
// condition: "{{ $self.value }}",
schema: {
"x-component-props": {
"associatedKey": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}",
"associatedIndex": "{{ typeof $self.value === 'string' ? $self.value : $form.values.collection_name }}",
"sourceName": "{{ $form.values.automation ? $form.values.automation.collection_name : null }}"
},
},

View File

@ -80,10 +80,10 @@ export async function getApp() {
}
interface ActionParams {
resourceKey?: string | number;
resourceIndex?: string | number;
// resourceName?: string;
// associatedName?: string;
associatedKey?: string | number;
associatedIndex?: string | number;
fields?: any;
filter?: any;
values?: any;
@ -110,14 +110,14 @@ export function getAgent(app: Application): Agent {
return new Proxy({}, {
get(target, method, receiver) {
return (params: ActionParams = {}) => {
const { associatedKey, resourceKey, values = {}, ...restParams } = params;
const { associatedIndex, resourceIndex, values = {}, ...restParams } = params;
let url = `/api/${name}`;
if (associatedKey) {
url = `/api/${name.split('.').join(`/${associatedKey}/`)}`;
if (associatedIndex) {
url = `/api/${name.split('.').join(`/${associatedIndex}/`)}`;
}
url += `:${method as string}`;
if (resourceKey) {
url += `/${resourceKey}`;
if (resourceIndex) {
url += `/${resourceIndex}`;
}
console.log(url);
if (['list', 'get'].indexOf(method as string) !== -1) {

View File

@ -94,21 +94,21 @@ describe('action', () => {
});
describe('belongsTo attachment', () => {
it('upload with associatedKey, fail as 400 because file mimetype does not match', async () => {
it('upload with associatedIndex, fail as 400 because file mimetype does not match', async () => {
const User = db.getModel('users');
const user = await User.create();
const response = await agent.resource('users.avatar').upload({
associatedKey: user.id,
associatedIndex: user.id,
file: path.resolve(__dirname, './files/text.txt')
});
expect(response.status).toBe(400);
});
it('upload with associatedKey', async () => {
it('upload with associatedIndex', async () => {
const User = db.getModel('users');
const user = await User.create();
const { body } = await agent.resource('users.avatar').upload({
associatedKey: user.id,
associatedIndex: user.id,
file: path.resolve(__dirname, './files/image.png'),
values: { width: 100, height: 100 }
});
@ -155,7 +155,7 @@ describe('action', () => {
const User = db.getModel('users');
const user = await User.create();
const { body } = await agent.resource('users.pubkeys').upload({
associatedKey: user.id,
associatedIndex: user.id,
file: path.resolve(__dirname, './files/text.txt'),
values: {}
});
@ -167,8 +167,8 @@ describe('action', () => {
expect(content.text).toBe('Hello world!\n');
});
// TODO(bug): 没有 associatedKey 时路径解析资源名称不对,无法进入 action
it.skip('upload without associatedKey', async () => {
// TODO(bug): 没有 associatedIndex 时路径解析资源名称不对,无法进入 action
it.skip('upload without associatedIndex', async () => {
const { body } = await agent.resource('users.avatar').upload({
file: path.resolve(__dirname, './files/image.png'),
values: { width: 100, height: 100 }

View File

@ -2,7 +2,7 @@ import path from 'path';
import supertest from 'supertest';
import { MockServer, mockServer } from '@nocobase/test';
import plugin from '../server';
import plugin from '../';
export async function getApp(options = {}): Promise<MockServer> {
const app = mockServer({

View File

@ -113,11 +113,11 @@ export async function action(ctx: Context, next: Next) {
// TODO(optimize): 应使用关联 accessors 获取
const result = await storage.createAttachment(data, { transaction });
const { associatedName, associatedKey, resourceField } = ctx.action.params;
if (associatedKey && resourceField) {
const { associatedName, associatedIndex, resourceField } = ctx.action.params;
if (associatedIndex && resourceField) {
const Attachment = ctx.db.getModel('attachments');
const SourceModel = ctx.db.getModel(associatedName);
const source = await SourceModel.findByPk(associatedKey, { transaction });
const source = await SourceModel.findByPk(associatedIndex, { transaction });
await source[resourceField.getAccessors().set](result[Attachment.primaryKeyAttribute], { transaction });
}

View File

@ -1 +1,2 @@
export * from './constants';
export { default } from './server';

View File

@ -14,14 +14,14 @@ export default {
const SystemSetting = database.getModel('system_settings');
resourcer.use(async (ctx, next) => {
const { actionName, resourceName, resourceKey } = ctx.action.params;
const { actionName, resourceName, resourceIndex } = ctx.action.params;
if (resourceName === 'system_settings' && actionName === 'get') {
let model = await SystemSetting.findOne();
if (!model) {
model = await SystemSetting.create();
}
ctx.action.mergeParams({
resourceKey: model.id,
resourceIndex: model.id,
});
}
await next();

View File

@ -80,10 +80,10 @@ export async function getApp() {
}
interface ActionParams {
resourceKey?: string | number;
resourceIndex?: string | number;
// resourceName?: string;
// associatedName?: string;
associatedKey?: string | number;
associatedIndex?: string | number;
fields?: any;
filter?: any;
values?: any;
@ -110,14 +110,14 @@ export function getAgent(app: Application): Agent {
return new Proxy({}, {
get(target, method, receiver) {
return (params: ActionParams = {}) => {
const { associatedKey, resourceKey, values = {}, ...restParams } = params;
const { associatedIndex, resourceIndex, values = {}, ...restParams } = params;
let url = `/api/${name}`;
if (associatedKey) {
url = `/api/${name.split('.').join(`/${associatedKey}/`)}`;
if (associatedIndex) {
url = `/api/${name.split('.').join(`/${associatedIndex}/`)}`;
}
url += `:${method as string}`;
if (resourceKey) {
url += `/${resourceKey}`;
if (resourceIndex) {
url += `/${resourceIndex}`;
}
console.log(url);
if (['list', 'get'].indexOf(method as string) !== -1) {

View File

@ -25,8 +25,8 @@ export const create = async (ctx: Context, next: Next) => {
const body = ctx.body;
ctx.action.mergeParams(
{
associatedKey: values.parentKey,
resourceKey: body.key,
associatedIndex: values.parentKey,
resourceIndex: body.key,
...(sticky
? {
sticky: true,
@ -70,8 +70,8 @@ export const update = async (ctx: Context, next: Next) => {
const body = ctx.body;
ctx.action.mergeParams(
{
associatedKey: values.parentKey,
resourceKey: body.key,
associatedIndex: values.parentKey,
resourceIndex: body.key,
...(sticky
? {
sticky: true,
@ -95,10 +95,10 @@ export const update = async (ctx: Context, next: Next) => {
};
export const getTree = async (ctx: Context, next: Next) => {
const { resourceKey, filter } = ctx.action.params;
const { resourceIndex, filter } = ctx.action.params;
const UISchema = ctx.db.getModel('ui_schemas');
if (resourceKey) {
const schema = await UISchema.findByPk(resourceKey);
if (resourceIndex) {
const schema = await UISchema.findByPk(resourceIndex);
const property = schema.toProperty();
const properties = await schema.getProperties();
if (Object.keys(properties).length) {

View File

@ -0,0 +1 @@
export { default } from './server';

View File

@ -271,11 +271,11 @@ describe('koa middleware', () => {
const response = await agent
.post('/resourcer/tests:update')
.send({
resourceKey: 1,
resourceIndex: 1,
values: { 'aa': 'aa' }
});
expect(response.body).toEqual({
resourceKey: 1,
resourceIndex: 1,
actionName: 'update',
resourceName: 'tests',
values: { col1: 'val1', aa: 'aa' }
@ -293,7 +293,7 @@ describe('koa middleware', () => {
.get('/users/1/settings');
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'settings',
actionName: 'get'
});
@ -303,7 +303,7 @@ describe('koa middleware', () => {
.post('/users/1/settings');
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'settings',
actionName: 'update'
});
@ -313,7 +313,7 @@ describe('koa middleware', () => {
.delete('/users/1/settings');
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'settings',
actionName: 'destroy'
});
@ -331,7 +331,7 @@ describe('koa middleware', () => {
.get('/users/1/posts');
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'posts',
actionName: 'list'
});
@ -341,9 +341,9 @@ describe('koa middleware', () => {
.get('/users/1/posts/1');
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'posts',
resourceKey: '1',
resourceIndex: '1',
actionName: 'get'
});
});
@ -352,7 +352,7 @@ describe('koa middleware', () => {
.post('/users/1/posts');
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'posts',
actionName: 'create'
});
@ -362,9 +362,9 @@ describe('koa middleware', () => {
.put('/users/1/posts/1');
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'posts',
resourceKey: '1',
resourceIndex: '1',
actionName: 'update'
});
});
@ -373,9 +373,9 @@ describe('koa middleware', () => {
.delete('/users/1/posts/1');
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'posts',
resourceKey: '1',
resourceIndex: '1',
actionName: 'destroy'
});
});
@ -392,7 +392,7 @@ describe('koa middleware', () => {
.get('/posts/1/user');
expect(response.body).toEqual({
associatedName: 'posts',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'user',
actionName: 'get'
});
@ -402,9 +402,9 @@ describe('koa middleware', () => {
.post('/posts/1/user/1');
expect(response.body).toEqual({
associatedName: 'posts',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'user',
resourceKey: '1',
resourceIndex: '1',
actionName: 'set'
});
});
@ -413,7 +413,7 @@ describe('koa middleware', () => {
.delete('/posts/1/user');
expect(response.body).toEqual({
associatedName: 'posts',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'user',
actionName: 'remove'
});
@ -431,7 +431,7 @@ describe('koa middleware', () => {
.get('/posts/1/tags');
expect(response.body).toEqual({
associatedName: 'posts',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'tags',
actionName: 'list'
});
@ -441,9 +441,9 @@ describe('koa middleware', () => {
.get('/posts/1/tags/1');
expect(response.body).toEqual({
associatedName: 'posts',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'tags',
resourceKey: '1',
resourceIndex: '1',
actionName: 'get'
});
});
@ -452,7 +452,7 @@ describe('koa middleware', () => {
.post('/posts/1/tags');
expect(response.body).toEqual({
associatedName: 'posts',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'tags',
actionName: 'set'
});
@ -462,9 +462,9 @@ describe('koa middleware', () => {
.post('/posts/1/tags/1');
expect(response.body).toEqual({
associatedName: 'posts',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'tags',
resourceKey: '1',
resourceIndex: '1',
actionName: 'add'
});
});
@ -473,9 +473,9 @@ describe('koa middleware', () => {
.put('/posts/1/tags/1');
expect(response.body).toEqual({
associatedName: 'posts',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'tags',
resourceKey: '1',
resourceIndex: '1',
actionName: 'update'
});
});
@ -484,9 +484,9 @@ describe('koa middleware', () => {
.delete('/posts/1/tags/1');
expect(response.body).toEqual({
associatedName: 'posts',
associatedKey: '1',
associatedIndex: '1',
resourceName: 'tags',
resourceKey: '1',
resourceIndex: '1',
actionName: 'remove'
});
});
@ -628,7 +628,7 @@ describe('koa middleware', () => {
});
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: 'name',
associatedIndex: 'name',
resourceName: 'posts',
actionName: 'list',
fields: { appends: ['rel1', 'rel2'] }
@ -640,7 +640,7 @@ describe('koa middleware', () => {
actions: {
list: {
async middleware(ctx, next) {
ctx.action.mergeParams({ filter: { user_name: ctx.action.params.associatedKey } });
ctx.action.mergeParams({ filter: { user_name: ctx.action.params.associatedIndex } });
await next();
},
},
@ -650,7 +650,7 @@ describe('koa middleware', () => {
.get('/users/name/posts');
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: 'name',
associatedIndex: 'name',
resourceName: 'posts',
actionName: 'list',
filter: { user_name: 'name' },
@ -662,7 +662,7 @@ describe('koa middleware', () => {
actions: {
list: {
async middleware(ctx, next) {
ctx.action.mergeParams({ fields: { only: [ctx.action.params.associatedKey] } }, { fields: 'append' });
ctx.action.mergeParams({ fields: { only: [ctx.action.params.associatedIndex] } }, { fields: 'append' });
await next();
},
},
@ -672,7 +672,7 @@ describe('koa middleware', () => {
.get('/users/name/posts');
expect(response.body).toEqual({
associatedName: 'users',
associatedKey: 'name',
associatedIndex: 'name',
resourceName: 'posts',
actionName: 'list',
fields: {

View File

@ -111,7 +111,7 @@ describe('utils', () => {
path: '/posts/1',
method: 'GET',
});
expect(params).toEqual({ resourceName: 'posts', resourceKey: '1', actionName: 'get' });
expect(params).toEqual({ resourceName: 'posts', resourceIndex: '1', actionName: 'get' });
});
it('update action', () => {
@ -119,7 +119,7 @@ describe('utils', () => {
path: '/posts/1',
method: 'PUT',
});
expect(params).toEqual({ resourceName: 'posts', resourceKey: '1', actionName: 'update' });
expect(params).toEqual({ resourceName: 'posts', resourceIndex: '1', actionName: 'update' });
});
it('update action', () => {
@ -127,7 +127,7 @@ describe('utils', () => {
path: '/posts/1',
method: 'PATCH',
});
expect(params).toEqual({ resourceName: 'posts', resourceKey: '1', actionName: 'update' });
expect(params).toEqual({ resourceName: 'posts', resourceIndex: '1', actionName: 'update' });
});
it('delete action', () => {
@ -135,7 +135,7 @@ describe('utils', () => {
path: '/posts/1',
method: 'delete',
});
expect(params).toEqual({ resourceName: 'posts', resourceKey: '1', actionName: 'destroy' });
expect(params).toEqual({ resourceName: 'posts', resourceIndex: '1', actionName: 'destroy' });
});
it('delete action', () => {
@ -143,7 +143,7 @@ describe('utils', () => {
path: '/posts/1,2,3,4,5,6',
method: 'delete',
});
expect(params).toEqual({ resourceName: 'posts', resourceKey: '1,2,3,4,5,6', actionName: 'destroy' });
expect(params).toEqual({ resourceName: 'posts', resourceIndex: '1,2,3,4,5,6', actionName: 'destroy' });
});
it('index action', () => {
@ -151,7 +151,7 @@ describe('utils', () => {
path: '/posts/1/comments',
method: 'GET',
});
expect(params).toEqual({ resourceName: 'comments', associatedName: 'posts', associatedKey: '1', actionName: 'list' });
expect(params).toEqual({ resourceName: 'comments', associatedName: 'posts', associatedIndex: '1', actionName: 'list' });
});
it('store action', () => {
@ -159,7 +159,7 @@ describe('utils', () => {
path: '/posts/1/comments',
method: 'POST',
});
expect(params).toEqual({ resourceName: 'comments', associatedName: 'posts', associatedKey: '1', actionName: 'create' });
expect(params).toEqual({ resourceName: 'comments', associatedName: 'posts', associatedIndex: '1', actionName: 'create' });
});
it('get action', () => {
@ -167,7 +167,7 @@ describe('utils', () => {
path: '/posts/1/comments/1',
method: 'GET',
});
expect(params).toEqual({ resourceName: 'comments', resourceKey: '1', associatedName: 'posts', associatedKey: '1', actionName: 'get' });
expect(params).toEqual({ resourceName: 'comments', resourceIndex: '1', associatedName: 'posts', associatedIndex: '1', actionName: 'get' });
});
it('update action', () => {
@ -175,7 +175,7 @@ describe('utils', () => {
path: '/posts/1/comments/1',
method: 'PUT',
});
expect(params).toEqual({ resourceName: 'comments', resourceKey: '1', associatedName: 'posts', associatedKey: '1', actionName: 'update' });
expect(params).toEqual({ resourceName: 'comments', resourceIndex: '1', associatedName: 'posts', associatedIndex: '1', actionName: 'update' });
});
it('update action', () => {
@ -183,7 +183,7 @@ describe('utils', () => {
path: '/posts/1/comments/1',
method: 'PATCH',
});
expect(params).toEqual({ resourceName: 'comments', resourceKey: '1', associatedName: 'posts', associatedKey: '1', actionName: 'update' });
expect(params).toEqual({ resourceName: 'comments', resourceIndex: '1', associatedName: 'posts', associatedIndex: '1', actionName: 'update' });
});
it('get action', () => {
@ -191,7 +191,7 @@ describe('utils', () => {
path: '/posts/1/comments/1',
method: 'delete',
});
expect(params).toEqual({ resourceName: 'comments', resourceKey: '1', associatedName: 'posts', associatedKey: '1', actionName: 'destroy' });
expect(params).toEqual({ resourceName: 'comments', resourceIndex: '1', associatedName: 'posts', associatedIndex: '1', actionName: 'destroy' });
});
it('export action', () => {
@ -215,7 +215,7 @@ describe('utils', () => {
path: '/posts:export/1',
method: 'POST',
});
expect(params).toEqual({ resourceName: 'posts', resourceKey: '1', actionName: 'export' });
expect(params).toEqual({ resourceName: 'posts', resourceIndex: '1', actionName: 'export' });
});
it('attach action', () => {
@ -225,8 +225,8 @@ describe('utils', () => {
});
expect(params).toEqual({
resourceName: 'tags',
resourceKey: '2',
associatedKey: '1',
resourceIndex: '2',
associatedIndex: '1',
associatedName: 'posts',
actionName: 'attach',
});

View File

@ -149,7 +149,7 @@ export interface ActionParams {
/**
*
*/
resourceKey?: string;
resourceIndex?: string;
/**
*
*/
@ -157,7 +157,7 @@ export interface ActionParams {
/**
*
*/
associatedKey?: string;
associatedIndex?: string;
/**
*
*/

View File

@ -26,9 +26,9 @@ export interface ParseOptions {
export interface ParsedParams {
actionName?: string;
resourceName?: string;
resourceKey?: string;
resourceIndex?: string;
associatedName?: string;
associatedKey?: string;
associatedIndex?: string;
// table: string;
// tableKey?: string | number;
// relatedTable?: string;
@ -76,18 +76,18 @@ export function parseRequest(request: ParseRequest, options: ParseOptions = {}):
post: accessors.create,
delete: accessors.delete
},
'/:resourceName/:resourceKey': {
'/:resourceName/:resourceIndex': {
get: accessors.get,
put: accessors.update,
patch: accessors.update,
delete: accessors.delete,
},
'/:associatedName/:associatedKey/:resourceName': {
'/:associatedName/:associatedIndex/:resourceName': {
get: accessors.list,
post: accessors.create,
delete: accessors.delete,
},
'/:associatedName/:associatedKey/:resourceName/:resourceKey': {
'/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {
get: accessors.get,
post: accessors.create,
put: accessors.update,
@ -96,7 +96,7 @@ export function parseRequest(request: ParseRequest, options: ParseOptions = {}):
},
},
hasOne: {
'/:associatedName/:associatedKey/:resourceName': {
'/:associatedName/:associatedIndex/:resourceName': {
get: accessors.get,
post: accessors.update,
put: accessors.update,
@ -105,12 +105,12 @@ export function parseRequest(request: ParseRequest, options: ParseOptions = {}):
},
},
hasMany: {
'/:associatedName/:associatedKey/:resourceName': {
'/:associatedName/:associatedIndex/:resourceName': {
get: accessors.list,
post: accessors.create,
delete: accessors.delete,
},
'/:associatedName/:associatedKey/:resourceName/:resourceKey': {
'/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {
get: accessors.get,
post: accessors.create,
put: accessors.update,
@ -119,20 +119,20 @@ export function parseRequest(request: ParseRequest, options: ParseOptions = {}):
},
},
belongsTo: {
'/:associatedName/:associatedKey/:resourceName': {
'/:associatedName/:associatedIndex/:resourceName': {
get: accessors.get,
delete: accessors.remove,
},
'/:associatedName/:associatedKey/:resourceName/:resourceKey': {
'/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {
post: accessors.set,
},
},
belongsToMany: {
'/:associatedName/:associatedKey/:resourceName': {
'/:associatedName/:associatedIndex/:resourceName': {
get: accessors.list,
post: accessors.set,
},
'/:associatedName/:associatedKey/:resourceName/:resourceKey': {
'/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {
get: accessors.get,
post: accessors.add,
put: accessors.update, // Many to Many 的 update 是针对 through

View File

@ -15,17 +15,17 @@ interface ActionParams {
perPage?: number;
values?: any;
resourceName?: string;
resourceKey?: string;
resourceIndex?: string;
associatedName?: string;
associatedKey?: string;
associatedIndex?: string;
[key: string]: any;
}
interface SortActionParams {
resourceName?: string;
resourceKey?: any;
resourceIndex?: any;
associatedName?: string;
associatedKey?: any;
associatedIndex?: any;
sourceId?: any;
targetId?: any;
sortField?: string;
@ -58,21 +58,21 @@ export class MockServer extends Application {
get(target, method: string, receiver) {
return (params: ActionParams = {}) => {
const {
associatedKey,
resourceKey,
associatedIndex,
resourceIndex,
values = {},
file,
...restParams
} = params;
let url = prefix;
if (keys.length > 1) {
url = `/${keys[0]}/${associatedKey}/${keys[1]}`
url = `/${keys[0]}/${associatedIndex}/${keys[1]}`
} else {
url = `/${name}`;
}
url += `:${method as string}`;
if (resourceKey) {
url += `/${resourceKey}`;
if (resourceIndex) {
url += `/${resourceIndex}`;
}
switch (method) {