From f300fd6ae90a2d105f6add28f5979ac59319ee05 Mon Sep 17 00:00:00 2001 From: chenos Date: Thu, 9 Sep 2021 23:58:01 +0800 Subject: [PATCH] refactor: users plugin --- packages/plugin-users/package.json | 7 +- .../plugin-users/src/__tests__/fields.test.ts | 168 +++++++----------- packages/plugin-users/src/__tests__/index.ts | 138 -------------- packages/plugin-users/src/actions/users.ts | 18 +- packages/plugin-users/src/fields/CreatedBy.ts | 10 +- packages/plugin-users/src/fields/UpdatedBy.ts | 19 +- .../src/hooks/collection-after-create.ts | 50 ------ .../src/hooks/fields-before-create.ts | 18 -- packages/plugin-users/src/hooks/index.ts | 12 -- packages/plugin-users/src/server.ts | 35 ++-- yarn.lock | 2 +- 11 files changed, 113 insertions(+), 364 deletions(-) delete mode 100644 packages/plugin-users/src/__tests__/index.ts delete mode 100644 packages/plugin-users/src/hooks/collection-after-create.ts delete mode 100644 packages/plugin-users/src/hooks/fields-before-create.ts delete mode 100644 packages/plugin-users/src/hooks/index.ts diff --git a/packages/plugin-users/package.json b/packages/plugin-users/package.json index fac72fab7..1d68ddba1 100644 --- a/packages/plugin-users/package.json +++ b/packages/plugin-users/package.json @@ -3,14 +3,13 @@ "version": "0.4.0-alpha.7", "main": "lib/index.js", "license": "MIT", - "devDependencies": { - "@nocobase/actions": "^0.4.0-alpha.7", - "@nocobase/server": "^0.4.0-alpha.7" - }, "dependencies": { "@nocobase/database": "^0.4.0-alpha.7", "@nocobase/resourcer": "^0.4.0-alpha.7", "crypto-random-string": "^3.3.0" }, + "devDependencies": { + "@nocobase/test": "^0.4.0-alpha.7" + }, "gitHead": "f0b335ac30f29f25c95d7d137655fa64d8d67f1e" } diff --git a/packages/plugin-users/src/__tests__/fields.test.ts b/packages/plugin-users/src/__tests__/fields.test.ts index 195e2fc27..af6bcc744 100644 --- a/packages/plugin-users/src/__tests__/fields.test.ts +++ b/packages/plugin-users/src/__tests__/fields.test.ts @@ -1,111 +1,96 @@ -import { getApp, getAgent } from '.'; +// @ts-nocheck +import Database from '@nocobase/database'; +import { mockServer, MockServer } from '@nocobase/test'; describe('user fields', () => { - let app; - let agent; - let db; + let api: MockServer; + let db: Database; beforeEach(async () => { - app = await getApp(); - agent = getAgent(app); - db = app.database; + api = mockServer(); + api.registerPlugin('users', require('../server').default); + await api.loadPlugins(); + db = api.database; }); afterEach(async () => { - await db.sync(); await db.close(); }); describe('model definition', () => { - it('add model without createdBy/updatedBy field', async () => { - const Collection = db.getModel('collections'); - await Collection.create({ name: 'posts', internal: true }); + it('createdBy=false/updatedBy=false', async () => { + db.table({ + name: 'posts', + createdBy: false, + updatedBy: false, + }); + await db.sync(); const Post = db.getModel('posts'); - const post = await Post.create(); expect(post.created_by_id).toBeUndefined(); expect(post.updated_by_id).toBeUndefined(); }); - it('add model without createdBy/updatedBy field', async () => { - const Collection = db.getModel('collections'); - await Collection.create({ name: 'posts' }); - const Post = db.getModel('posts'); - - const post = await Post.create(); - expect(post.created_by_id).toBeDefined(); - expect(post.updated_by_id).toBeDefined(); - }); - - it('add model with named createdBy/updatedBy field', async () => { - const Collection = db.getModel('collections'); - await Collection.create({ name: 'posts', createdBy: 'author', updatedBy: 'editor' }); - const Post = db.getModel('posts'); - - const post = await Post.create(); - expect(post.author_id).toBeDefined(); - expect(post.editor_id).toBeDefined(); - }); - - it('add model with named createdBy/updatedBy field and target', async () => { - const Collection = db.getModel('collections'); - await Collection.create({ + it('without createdBy/updatedBy', async () => { + db.table({ name: 'posts', - createdBy: { name: 'author', target: 'users' }, - updatedBy: { name: 'editor', target: 'users' } }); + await db.sync(); const Post = db.getModel('posts'); - - const post = await Post.create(); - expect(post.author_id).toBeDefined(); - expect(post.editor_id).toBeDefined(); - }); - - it('add model with boolean createdBy/updatedBy field', async () => { - const Collection = db.getModel('collections'); - await Collection.create({ name: 'posts', createdBy: true, updatedBy: true }); - const Post = db.getModel('posts'); - const post = await Post.create(); expect(post.created_by_id).toBeDefined(); expect(post.updated_by_id).toBeDefined(); }); - // TODO(bug): 重复添加字段不能与 fields 表同步,应做到同步 - it('add model and then add createdBy/updatedBy field', async () => { - const Collection = db.getModel('collections'); - const collection = await Collection.import({ + it('updatedBy=author/updatedBy=editor', async () => { + db.table({ + name: 'posts', + createdBy: 'author', + updatedBy: 'editor', + }); + await db.sync(); + const Post = db.getModel('posts'); + const post = await Post.create(); + expect(post.author_id).toBeDefined(); + expect(post.editor_id).toBeDefined(); + }); + + it('createdBy=true/updatedBy=true', async () => { + db.table({ name: 'posts', createdBy: true, updatedBy: true, + }); + await db.sync(); + const Post = db.getModel('posts'); + const post = await Post.create(); + expect(post.created_by_id).toBeDefined(); + expect(post.updated_by_id).toBeDefined(); + }); + + it('add model and then add createdBy/updatedBy field', async () => { + db.table({ + name: 'posts', fields: [ { - interface: 'createdBy', - title: '创建人1', type: 'createdBy', name: 'createdBy1', target: 'users', foreignKey: 'created_by_id', }, { - interface: 'updatedBy', - title: '更新人1', type: 'updatedBy', name: 'updatedBy1', target: 'users', foreignKey: 'updated_by_id', }, { - interface: 'createdBy', - title: '创建人2', type: 'createdBy', name: 'createdBy2', target: 'users', foreignKey: 'created_by_id', }, { - interface: 'updatedBy', - title: '更新人2', type: 'updatedBy', name: 'updatedBy2', target: 'users', @@ -113,8 +98,8 @@ describe('user fields', () => { }, ] }); - const table = db.getTable('posts'); - // console.log(table.getFields()); + + await db.sync(); const User = db.getModel('users'); const Post = db.getModel('posts'); @@ -150,41 +135,13 @@ describe('user fields', () => { expect(post2.createdBy2.id).toBe(user1.id); expect(post2.updatedBy1.id).toBe(user2.id); expect(post2.updatedBy2.id).toBe(user2.id); - - - // const Collection = db.getModel('collections'); - // const collection = await Collection.create({ - // name: 'posts' - // }); - // const createdByField = await collection.createField({ type: 'createdBy', name: 'author', target: 'users' }); - // const updatedByField = await collection.createField({ type: 'updatedBy', name: 'editor', target: 'users' }); - - // const postTable = db.getTable('posts'); - // const Post = db.getModel('posts'); - - // // create data should contain added fields - // const post = await Post.create(); - // expect(post[postTable.getField(createdByField.get('name')).options.foreignKey]).toBeDefined(); - // expect(post[postTable.getField(updatedByField.get('name')).options.foreignKey]).toBeDefined(); - - // // add same type field twice should get same field - // const createdByField2 = await collection.createField({ type: 'createdBy', target: 'users' }); - // expect(createdByField2.get('name')).toBe(createdByField.get('name')); - - // // add same type field twice with a new name should get same field name as before - // const updatedByField2 = await collection.createField({ type: 'updatedBy', name: 'proofreader', target: 'users' }); - // expect(updatedByField2.get('name')).toBe(updatedByField.get('name')); - - // // delete field data should not really remove the column in table - // await createdByField2.destroy(); - // expect(postTable.getField('author')).toBeDefined(); }); }); describe('createdBy field', () => { it('create data with createdBy/updatedBy field', async () => { - const Collection = db.getModel('collections'); - await Collection.create({ name: 'posts', createdBy: true, updatedBy: true }); + db.table({ name: 'posts', createdBy: true, updatedBy: true }); + await db.sync(); const User = db.getModel('users'); const currentUser = await User.create(); const user2 = await User.create(); @@ -193,20 +150,21 @@ describe('user fields', () => { const postWithoutUser = await Post.create(); expect(postWithoutUser.created_by_id).toBe(null); expect(postWithoutUser.updated_by_id).toBe(null); - + // @ts-ignore const postWithUser = await Post.create({}, { context: { state: { currentUser } } }); expect(postWithUser.created_by_id).toBe(currentUser.id); expect(postWithUser.updated_by_id).toBe(currentUser.id); // 更新数据 createdBy 数据不变 + // @ts-ignore await postWithUser.update({ title: 'title1' }, { context: { state: { currentUser: user2 } } }); expect(postWithUser.created_by_id).toBe(currentUser.id); expect(postWithUser.updated_by_id).toBe(user2.id); }); it('create data with value of createdBy/updatedBy field', async () => { - const Collection = db.getModel('collections'); - await Collection.create({ name: 'posts', createdBy: true, updatedBy: true }); + db.table({ name: 'posts', createdBy: true, updatedBy: true }); + await db.sync(); const User = db.getModel('users'); const user1 = await User.create(); const user2 = await User.create(); @@ -215,6 +173,7 @@ describe('user fields', () => { const post = await Post.create({ created_by_id: user1.id, updated_by_id: user1.id, + // @ts-ignore }, { context: { state: { currentUser: user2 } } }); expect(post.created_by_id).toBe(user1.id); expect(post.updated_by_id).toBe(user1.id); @@ -223,9 +182,9 @@ describe('user fields', () => { describe('updatedBy field', () => { it('update data ', async () => { - const Collection = db.getModel('collections'); - await Collection.create({ + db.table({ name: 'posts', + createdBy: false, updatedBy: true, fields: [ { @@ -234,20 +193,20 @@ describe('user fields', () => { } ] }); + await db.sync(); const User = db.getModel('users'); const currentUser = await User.create(); const Post = db.getModel('posts'); const post = await Post.create(); expect(post.updated_by_id).toBe(null); - + // @ts-ignore await post.update({ title: 'title' }, { context: { state: { currentUser } } }) expect(post.updated_by_id).toBe(currentUser.id); }); it('update data by different user', async () => { - const Collection = db.getModel('collections'); - await Collection.create({ + db.table({ name: 'posts', updatedBy: true, fields: [ @@ -257,6 +216,7 @@ describe('user fields', () => { } ] }); + await db.sync(); const User = db.getModel('users'); const user1 = await User.create(); const user2 = await User.create(); @@ -285,9 +245,10 @@ describe('user fields', () => { }); it('bulkUpdate', async () => { - const Collection = db.getModel('collections'); - const postCollection = await Collection.create({ name: 'posts', createdBy: false, updatedBy: true }); - await postCollection.updateAssociations({ + db.table({ + name: 'posts', + createdBy: false, + updatedBy: true, fields: [ { type: 'string', @@ -295,6 +256,7 @@ describe('user fields', () => { } ] }); + await db.sync(); const User = db.getModel('users'); const user1 = await User.create(); const user2 = await User.create(); diff --git a/packages/plugin-users/src/__tests__/index.ts b/packages/plugin-users/src/__tests__/index.ts deleted file mode 100644 index 11a178d0a..000000000 --- a/packages/plugin-users/src/__tests__/index.ts +++ /dev/null @@ -1,138 +0,0 @@ -import path from 'path'; -import qs from 'qs'; -import supertest from 'supertest'; -import bodyParser from 'koa-bodyparser'; -import { Dialect } from 'sequelize'; -import Database from '@nocobase/database'; -import { actions, middlewares } from '@nocobase/actions'; -import { Application, middleware } from '../../../server/src'; -import plugin from '../server'; - -function getTestKey() { - const { id } = require.main; - const key = id - .replace(`${process.env.PWD}/packages`, '') - .replace(/src\/__tests__/g, '') - .replace('.test.ts', '') - .replace(/[^\w]/g, '_') - .replace(/_+/g, '_'); - return key -} - -const config = { - username: process.env.DB_USER, - password: process.env.DB_PASSWORD, - database: process.env.DB_DATABASE, - host: process.env.DB_HOST, - port: Number.parseInt(process.env.DB_PORT, 10), - dialect: process.env.DB_DIALECT as Dialect, - define: { - hooks: { - beforeCreate(model, options) { - - }, - }, - }, - logging: process.env.DB_LOG_SQL === 'on', - sync: { - force: true, - alter: { - drop: true, - }, - }, -}; - -export async function getApp() { - const app = new Application({ - database: { - ...config, - hooks: { - beforeDefine(columns, model) { - model.tableName = `${getTestKey()}_${model.tableName || model.name.plural}`; - } - }, - }, - resourcer: { - prefix: '/api', - }, - }); - app.resourcer.use(middlewares.associated); - app.resourcer.registerActionHandlers({ ...actions.associate, ...actions.common }); - app.registerPlugin('collections', [path.resolve(__dirname, '../../../plugin-collections')]); - app.registerPlugin('users', [plugin]); - await app.loadPlugins(); - await app.database.sync(); - app.use(async (ctx, next) => { - ctx.db = app.database; - await next(); - }); - app.use(bodyParser()); - app.use(middleware({ - resourcer: app.resourcer, - database: app.database, - })); - return app; -} - -interface ActionParams { - resourceKey?: string | number; - // resourceName?: string; - // associatedName?: string; - associatedKey?: string | number; - fields?: any; - filter?: any; - values?: any; - [key: string]: any; -} - -interface Handler { - get: (params?: ActionParams) => Promise; - list: (params?: ActionParams) => Promise; - create: (params?: ActionParams) => Promise; - update: (params?: ActionParams) => Promise; - destroy: (params?: ActionParams) => Promise; - [name: string]: (params?: ActionParams) => Promise; -} - -export interface Agent { - resource: (name: string) => Handler; -} - -export function getAgent(app: Application): Agent { - const agent = supertest.agent(app.callback()); - return { - resource(name: string): any { - return new Proxy({}, { - get(target, method, receiver) { - return (params: ActionParams = {}) => { - const { associatedKey, resourceKey, values = {}, ...restParams } = params; - let url = `/api/${name}`; - if (associatedKey) { - url = `/api/${name.split('.').join(`/${associatedKey}/`)}`; - } - url += `:${method as string}`; - if (resourceKey) { - url += `/${resourceKey}`; - } - if (['list', 'get'].indexOf(method as string) !== -1) { - return agent.get(`${url}?${qs.stringify(restParams)}`); - } else { - return agent.post(`${url}?${qs.stringify(restParams)}`).send(values); - } - } - } - }); - } - }; -} - -export function getDatabase() { - return new Database({ - ...config, - hooks: { - beforeDefine(columns, model) { - model.tableName = `${getTestKey()}_${model.tableName || model.name.plural}`; - } - } - }); -}; diff --git a/packages/plugin-users/src/actions/users.ts b/packages/plugin-users/src/actions/users.ts index 6451d91f9..a63b1595e 100644 --- a/packages/plugin-users/src/actions/users.ts +++ b/packages/plugin-users/src/actions/users.ts @@ -1,8 +1,8 @@ -import { actions } from '@nocobase/actions'; +import { Context, Next } from '@nocobase/actions'; import { PASSWORD } from '@nocobase/database'; import cryptoRandomString from 'crypto-random-string'; -export async function check(ctx: actions.Context, next: actions.Next) { +export async function check(ctx: Context, next: Next) { if (ctx.state.currentUser) { const user = ctx.state.currentUser.toJSON(); delete user.password; @@ -13,7 +13,7 @@ export async function check(ctx: actions.Context, next: actions.Next) { } } -export async function login(ctx: actions.Context, next: actions.Next) { +export async function login(ctx: Context, next: Next) { const { uniqueField = 'email', values } = ctx.action.params; // console.log(values); if (!values[uniqueField]) { @@ -42,12 +42,12 @@ export async function login(ctx: actions.Context, next: actions.Next) { await next(); } -export async function logout(ctx: actions.Context, next: actions.Next) { +export async function logout(ctx: Context, next: Next) { ctx.body = {}; await next(); } -export async function register(ctx: actions.Context, next: actions.Next) { +export async function register(ctx: Context, next: Next) { const User = ctx.db.getModel('users'); const { values } = ctx.action.params; try { @@ -66,7 +66,7 @@ export async function register(ctx: actions.Context, next: actions.Next) { await next(); } -export async function lostpassword(ctx: actions.Context, next: actions.Next) { +export async function lostpassword(ctx: Context, next: Next) { const { values: { email } } = ctx.action.params; if (!email) { ctx.throw(401, '请填写邮箱账号'); @@ -86,7 +86,7 @@ export async function lostpassword(ctx: actions.Context, next: actions.Next) { await next(); } -export async function resetpassword(ctx: actions.Context, next: actions.Next) { +export async function resetpassword(ctx: Context, next: Next) { const { values: { email, password, reset_token } } = ctx.action.params; const User = ctx.db.getModel('users'); const user = await User.findOne({ @@ -106,7 +106,7 @@ export async function resetpassword(ctx: actions.Context, next: actions.Next) { await next(); } -export async function getUserByResetToken(ctx: actions.Context, next: actions.Next) { +export async function getUserByResetToken(ctx: Context, next: Next) { const { token } = ctx.action.params; const User = ctx.db.getModel('users'); const user = await User.findOne({ @@ -121,7 +121,7 @@ export async function getUserByResetToken(ctx: actions.Context, next: actions.Ne await next(); } -export async function updateProfile(ctx: actions.Context, next: actions.Next) { +export async function updateProfile(ctx: Context, next: Next) { const { values } = ctx.action.params; if (!ctx.state.currentUser) { ctx.throw(401, 'Unauthorized'); diff --git a/packages/plugin-users/src/fields/CreatedBy.ts b/packages/plugin-users/src/fields/CreatedBy.ts index f2cf93bce..b2b65d4d6 100644 --- a/packages/plugin-users/src/fields/CreatedBy.ts +++ b/packages/plugin-users/src/fields/CreatedBy.ts @@ -15,10 +15,14 @@ export default class CreatedBy extends BELONGSTO { constructor({ type, ...options }: CreatedByOptions, context: FieldContext) { super({ ...options, type: 'belongsTo' } as BelongsToOptions, context); - const Model = context.sourceTable.getModel(); + // const Model = context.sourceTable.getModel(); // TODO(feature): 可考虑策略模式,以在需要时对外提供接口 - Model.addHook('beforeCreate', setUserValue.bind(this)); - Model.addHook('beforeBulkCreate', CreatedBy.beforeBulkCreateHook.bind(this)); + // Model.addHook('beforeCreate', setUserValue.bind(this)); + // Model.addHook('beforeBulkCreate', CreatedBy.beforeBulkCreateHook.bind(this)); + const { sourceTable, database } = context; + const name = sourceTable.getName(); + database.on(`${name}.beforeCreate`, setUserValue.bind(this)); + database.on(`${name}.beforeBulkCreate`, CreatedBy.beforeBulkCreateHook.bind(this)); } public getDataType(): Function { diff --git a/packages/plugin-users/src/fields/UpdatedBy.ts b/packages/plugin-users/src/fields/UpdatedBy.ts index 62e38c76f..5f4627d24 100644 --- a/packages/plugin-users/src/fields/UpdatedBy.ts +++ b/packages/plugin-users/src/fields/UpdatedBy.ts @@ -27,13 +27,18 @@ export default class UpdatedBy extends BELONGSTO { constructor({ type, ...options }: UpdatedByOptions, context: FieldContext) { super({ ...options, type: 'belongsTo' } as BelongsToOptions, context); - const Model = context.sourceTable.getModel(); - // TODO(feature): 可考虑策略模式,以在需要时对外提供接口 - Model.addHook('beforeCreate', setUserValue.bind(this)); - Model.addHook('beforeBulkCreate', UpdatedBy.beforeBulkCreateHook.bind(this)); - - Model.addHook('beforeUpdate', setUserValue.bind(this)); - Model.addHook('beforeBulkUpdate', UpdatedBy.beforeBulkUpdateHook.bind(this)); + // const Model = context.sourceTable.getModel(); + // // TODO(feature): 可考虑策略模式,以在需要时对外提供接口 + // Model.addHook('beforeCreate', setUserValue.bind(this)); + // Model.addHook('beforeBulkCreate', UpdatedBy.beforeBulkCreateHook.bind(this)); + // Model.addHook('beforeUpdate', setUserValue.bind(this)); + // Model.addHook('beforeBulkUpdate', UpdatedBy.beforeBulkUpdateHook.bind(this)); + const { sourceTable, database } = context; + const name = sourceTable.getName(); + database.on(`${name}.beforeCreate`, setUserValue.bind(this)); + database.on(`${name}.beforeBulkCreate`, UpdatedBy.beforeBulkCreateHook.bind(this)); + database.on(`${name}.beforeUpdate`, setUserValue.bind(this)); + database.on(`${name}.beforeBulkUpdate`, UpdatedBy.beforeBulkUpdateHook.bind(this)); } public getDataType(): Function { diff --git a/packages/plugin-users/src/hooks/collection-after-create.ts b/packages/plugin-users/src/hooks/collection-after-create.ts deleted file mode 100644 index 11f6e3a2d..000000000 --- a/packages/plugin-users/src/hooks/collection-after-create.ts +++ /dev/null @@ -1,50 +0,0 @@ -export function makeOptions(type: string, options: any) { - if (!options) { - return; - } - let name = type; - let target = 'users'; - switch (typeof options) { - case 'string': - name = options; - break; - // 今后支持多账号体系时可以扩展配置 - case 'object': - name = options.name || name; - target = options.target || target; - break; - } - return { - type, - name, - target - }; -} - -export default async function (table) { - const { createdBy, updatedBy } = table.getOptions(); - const fieldsToMake = { createdBy, updatedBy }; - Object.keys(fieldsToMake) - .filter(type => Boolean(fieldsToMake[type])) - .map(type => table.addField(makeOptions(type, fieldsToMake[type]))); -} - -// export default async function(model, options) { -// const { database } = model; -// const tableName = model.get('name') as string; -// const table = database.getTable(tableName); -// const { createdBy, updatedBy } = table.getOptions(); -// const fieldsToMake = { createdBy, updatedBy }; -// const addedFields = Object.keys(fieldsToMake) -// .filter(type => Boolean(fieldsToMake[type])) -// .map(type => table.addField(makeOptions(type, fieldsToMake[type]))); - -// if (addedFields.length) { -// await table.sync({ -// force: false, -// alter: { -// drop: false, -// } -// }); -// } -// } diff --git a/packages/plugin-users/src/hooks/fields-before-create.ts b/packages/plugin-users/src/hooks/fields-before-create.ts deleted file mode 100644 index 9a82a9de2..000000000 --- a/packages/plugin-users/src/hooks/fields-before-create.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Model, getDataTypeKey, getField } from '@nocobase/database'; - -export default async function (model: Model, options) { - // const { database } = model; - // const { type, target, collection_name } = model.get(); - // const table = database.getTable(collection_name); - // const Type = getField(getDataTypeKey(type)); - // let Exist; - // for (const Field of table.getFields().values()) { - // if (Field instanceof Type && Field.options.target === target) { - // Exist = Field; - // break; - // } - // } - // if (Exist) { - // model.set('name', Exist.options.name); - // } -} diff --git a/packages/plugin-users/src/hooks/index.ts b/packages/plugin-users/src/hooks/index.ts deleted file mode 100644 index 273f30d70..000000000 --- a/packages/plugin-users/src/hooks/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Database from '@nocobase/database'; -import collectionsAfterCreate from './collection-after-create'; -import fieldsBeforeCreate from './fields-before-create'; - -export default function () { - const database: Database = this.database; - // TODO(feature): 应该通过新的插件机制暴露接口,而不是直接访问其他插件的底层代码 - database.getModel('collections').addHook('afterCreate', collectionsAfterCreate); - - // 由于创建字段不是同时完成的,可能要在不同的 hook 里处理才行 - database.getModel('fields').addHook('beforeCreate', fieldsBeforeCreate); -} diff --git a/packages/plugin-users/src/server.ts b/packages/plugin-users/src/server.ts index 9030873f3..42580c3f1 100644 --- a/packages/plugin-users/src/server.ts +++ b/packages/plugin-users/src/server.ts @@ -1,12 +1,8 @@ import path from 'path'; - -import Database, { registerFields } from '@nocobase/database'; +import Database, { registerFields, Table } from '@nocobase/database'; import Resourcer from '@nocobase/resourcer'; - import * as fields from './fields'; -// import hooks from './hooks'; import * as usersActions from './actions/users'; -import { makeOptions } from './hooks/collection-after-create'; import * as middlewares from './middlewares'; export default async function (options = {}) { @@ -15,21 +11,22 @@ export default async function (options = {}) { registerFields(fields); - database.addHook('afterTableInit', (table) => { - let { createdBy, updatedBy, internal } = table.getOptions(); - // 非内置表,默认创建 createdBy 和 updatedBy - if (!internal) { - if (typeof createdBy === 'undefined') { - createdBy = true; - } - if (typeof updatedBy === 'undefined') { - updatedBy = true; - } + database.on('afterTableInit', (table: Table) => { + let { createdBy, updatedBy } = table.getOptions(); + if (createdBy !== false) { + table.addField({ + type: 'createdBy', + name: typeof createdBy === 'string' ? createdBy : 'createdBy', + target: 'users', + }); + } + if (updatedBy !== false) { + table.addField({ + type: 'updatedBy', + name: typeof updatedBy === 'string' ? updatedBy : 'updatedBy', + target: 'users', + }); } - const fieldsToMake = { createdBy, updatedBy }; - Object.keys(fieldsToMake) - .filter(type => Boolean(fieldsToMake[type])) - .map(type => table.addField(makeOptions(type, fieldsToMake[type]))); }); database.import({ diff --git a/yarn.lock b/yarn.lock index 94497bb89..1424e4825 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17608,7 +17608,7 @@ sequelize-pool@^6.0.0: resolved "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-6.1.0.tgz#caaa0c1e324d3c2c3a399fed2c7998970925d668" integrity sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg== -sequelize@^6.3.3, sequelize@^6.3.4: +sequelize@^6.3.3: version "6.6.5" resolved "https://registry.npmjs.org/sequelize/-/sequelize-6.6.5.tgz#6f618e99f3df1fc81f28709e8a3139cec3ef1f0c" integrity sha512-QyRrJrDRiwuiILqTMHUA1yWOPIL12KlfmgZ3hnzQwbMvp2vJ6fzu9bYJQB+qPMosck4mBUggY4Cjoc6Et8FBIQ==