feat: improve code

This commit is contained in:
chenos 2021-09-09 23:57:01 +08:00
parent 99d33a0241
commit 336e0b17b8
17 changed files with 59 additions and 240 deletions

View File

@ -1,9 +1,10 @@
import Server from '@nocobase/server';
import { registerActions } from '@nocobase/actions';
import dotenv from 'dotenv';
import path from 'path';
const start = Date.now();
console.log('startAt', new Date().toUTCString());
console.log('starting... ', new Date().toUTCString());
dotenv.config({
path: path.resolve(__dirname, '../../../../.env'),
@ -39,11 +40,17 @@ const api = new Server({
resourcer: {
prefix: '/api',
},
dataWrapping: true,
});
console.log(`@nocobase/preset-nocobase/${__filename.endsWith('.ts') ? 'src' : 'lib'}/index`);
registerActions(api);
api.registerPlugin('@nocobase/preset-nocobase', require(`@nocobase/preset-nocobase/${__filename.endsWith('.ts') ? 'src' : 'lib'}/index`).default);
const file = `${__filename.endsWith('.ts') ? 'src' : 'lib'}/index`;
api.registerPlugin(
'@nocobase/preset-nocobase',
require(`@nocobase/preset-nocobase/${file}`).default,
);
if (process.argv.length < 3) {
process.argv.push('start', '--port', '2000');

View File

@ -461,36 +461,10 @@ type HookType =
*
*/
public async close() {
this.removeAllListeners();
return this.sequelize.close();
}
/**
* hook
*
* @param hookType
* @param fn
*/
public addHook(hookType: HookType | string, fn: Function) {
const hooks = this.hooks[hookType] || [];
hooks.push(fn);
this.hooks[hookType] = hooks;
}
/**
* hook
*
* @param hookType
* @param args
*/
public async runHooks(hookType: HookType | string, ...args) {
const hooks = this.hooks[hookType] || [];
for (const hook of hooks) {
if (typeof hook === 'function') {
await hook(...args);
}
}
}
public getFieldByPath(fieldPath: string) {
const [tableName, fieldName] = fieldPath.split('.');
return this.getTable(tableName).getField(fieldName);

View File

@ -221,7 +221,8 @@ export type ColumnOptions = AbstractFieldOptions
| JsonOptions
| VirtualOptions
| FormulaOptions
| ReferenceOptions;
| ReferenceOptions
| SortOptions;
export type ElementOptions = BooleanOptions
| IntegerOptions
@ -236,7 +237,8 @@ export type ElementOptions = BooleanOptions
| DateOnlyOptions
| ArrayOptions
| JsonOptions
| VirtualOptions;
| VirtualOptions
| SortOptions;
export type RelationOptions = HasOneOptions | HasManyOptions | BelongsToOptions | BelongsToManyOptions;

View File

@ -530,7 +530,7 @@ export abstract class Model extends SequelizeModel {
});
}
await this.database.runHooks('afterUpdateAssociations', this, {
await this.database.emitAsync('afterUpdateAssociations', this, {
...options,
transaction,
});

View File

@ -139,7 +139,7 @@ export class Table {
constructor(options: TableOptions, context: TabelContext) {
const { database } = context;
database.runHooks('beforeTableInit', options);
database.emit('beforeTableInit', options);
const {
model,
fields = [],
@ -157,7 +157,7 @@ export class Table {
// this.modelInit('modelOnly');
this.setFields(fields);
this.initSortable();
database.runHooks('afterTableInit', this);
database.emit('afterTableInit', this);
}
public initSortable() {
@ -312,7 +312,7 @@ export class Table {
* @param reinitialize
*/
public addField(options: FieldOptions, reinitialize: Reinitialize = true) {
this.database.runHooks('beforeAddField', options, this);
this.database.emit('beforeAddField', options, this);
const { name, index } = options;
const field = buildField(options, {
sourceTable: this,
@ -348,7 +348,7 @@ export class Table {
this.modelAttributes[name] = field.getAttributeOptions();
}
this.modelInit(reinitialize);
this.database.runHooks('afterAddField', field, this);
this.database.emit('afterAddField', field, this);
return field;
}

View File

@ -9,7 +9,7 @@
},
"devDependencies": {
"@nocobase/actions": "^0.4.0-alpha.7",
"@nocobase/server": "^0.4.0-alpha.7"
"@nocobase/test": "^0.4.0-alpha.7"
},
"gitHead": "f0b335ac30f29f25c95d7d137655fa64d8d67f1e"
}

View File

@ -1,15 +1,22 @@
import Database from '@nocobase/database';
import Application from '@nocobase/server';
import { getApp, getAPI, getAgent } from '.';
import { registerActions } from '@nocobase/actions';
import { mockServer, MockServer } from '@nocobase/test';
import logPlugin from '../server';
describe('hook', () => {
let app: Application;
let api: MockServer;
let db: Database;
let api;
beforeEach(async () => {
app = await getApp();
db = app.database;
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();
db = api.database;
db.table({
name: 'posts',
logging: true,
@ -28,14 +35,11 @@ describe('hook', () => {
await db.sync();
const User = db.getModel('users');
const user = await User.create({ nickname: 'a', token: 'token1' });
console.log('beforeEach', user);
const userAgent = getAgent(app);
userAgent.set('Authorization', `Bearer ${user.token}`);
api = getAPI(userAgent);
api.agent().set('Authorization', `Bearer ${user.token}`);
});
afterEach(async () => {
await db.close();
await api.destroy();
});
it('database', async () => {

View File

@ -1,122 +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 } from '@nocobase/server';
import middleware from '@nocobase/server/src/middleware';
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,
logging: process.env.DB_LOG_SQL === 'on',
sync: {
force: true,
alter: {
drop: true,
},
},
hooks: {
beforeDefine(columns, model) {
model.tableName = `${getTestKey()}_${model.tableName || model.name.plural}`;
}
},
};
export function getDatabase() {
return new Database(config);
};
export async function getApp(): Promise<Application> {
const app = new Application({
database: config,
resourcer: {
prefix: '/api',
},
});
app.registerPlugin({
collections: path.resolve(__dirname, '../../../plugin-collections'),
users: path.resolve(__dirname, '../../../plugin-users'),
logs: plugin
});
await app.loadPlugins();
await app.database.sync();
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<supertest.Response>;
list: (params?: ActionParams) => Promise<supertest.Response>;
create: (params?: ActionParams) => Promise<supertest.Response>;
update: (params?: ActionParams) => Promise<supertest.Response>;
destroy: (params?: ActionParams) => Promise<supertest.Response>;
[name: string]: (params?: ActionParams) => Promise<supertest.Response>;
}
export interface Agent {
resource: (name: string) => Handler;
}
export function getAgent(app: Application) {
return supertest.agent(app.callback());
}
export function getAPI(agent) {
return {
resource(name: string): any {
return new Proxy({}, {
get(target, method: string, receiver) {
return (params: ActionParams = {}) => {
const { associatedKey, resourceKey, values = {}, filePath, ...restParams } = params;
let url = `/api/${name}`;
if (associatedKey) {
url = `/api/${name.split('.').join(`/${associatedKey}/`)}`;
}
url += `:${method as string}`;
if (resourceKey) {
url += `/${resourceKey}`;
}
switch (method) {
case 'list':
case 'get':
return agent.get(`${url}?${qs.stringify(restParams)}`);
default:
return agent.post(`${url}?${qs.stringify(restParams)}`).send(values);
}
}
}
});
}
};
}

View File

@ -1,15 +0,0 @@
import { TableOptions } from "@nocobase/database";
export default {
name: 'comments',
fields: [
{
type: 'string',
name: 'content',
},
{
type: 'belongsTo',
name: 'post',
},
]
} as TableOptions;

View File

@ -1,22 +0,0 @@
import { TableOptions } from "@nocobase/database";
export default {
name: 'posts',
// 目前默认就带了
// createdBy: true,
fields: [
{
type: 'string',
name: 'title',
},
{
type: 'string',
name: 'status',
defaultValue: 'draft',
},
{
type: 'hasMany',
name: 'comments',
}
]
} as TableOptions;

View File

@ -12,18 +12,18 @@ export default {
type: 'belongsTo',
name: 'log',
target: 'action_logs',
foreignKey: 'log_id',
foreignKey: 'action_log_id',
},
{
type: 'jsonb',
type: 'json',
name: 'field',
},
{
type: 'jsonb',
type: 'json',
name: 'before',
},
{
type: 'jsonb',
type: 'json',
name: 'after',
}
],

View File

@ -18,12 +18,16 @@ export default {
target: 'users',
},
{
type: 'belongsTo',
name: 'collection',
target: 'collections',
targetKey: 'name',
constraints: false,
type: 'string',
name: 'collection_name',
},
// {
// type: 'belongsTo',
// name: 'collection',
// target: 'collections',
// targetKey: 'name',
// constraints: false,
// },
{
type: 'string',
name: 'type',
@ -36,7 +40,7 @@ export default {
type: 'hasMany',
name: 'changes',
target: 'action_changes',
foreignKey: 'log_id',
foreignKey: 'action_log_id',
}
],
} as TableOptions;

View File

@ -1,7 +0,0 @@
import { extend } from '@nocobase/database';
// TODO(bug): collections 表创建关联字段有问题
export default extend({
name: 'collections',
logging: false
});

View File

@ -1,10 +1,7 @@
import { Model, ModelCtor } from '@nocobase/database';
import { actions, middlewares } from '@nocobase/actions';
import { sort } from '@nocobase/actions/src/actions/common';
import { cloneDeep, omit } from 'lodash';
import { actions, Context, Next } from '@nocobase/actions';
export const create = async (ctx: actions.Context, next: actions.Next) => {
await actions.common.create(ctx, async () => {});
export const create = async (ctx: Context, next: Next) => {
await actions.create(ctx, async () => {});
const { associated } = ctx.action.params;
await ctx.body.generateReverseField();
await associated.migrate();

View File

@ -1,9 +1,6 @@
import { Model, ModelCtor } from '@nocobase/database';
import { actions, middlewares } from '@nocobase/actions';
import { sort } from '@nocobase/actions/src/actions/common';
import { cloneDeep, omit } from 'lodash';
import { actions, Context, Next } from '@nocobase/actions';
export const findAll = async (ctx: actions.Context, next: actions.Next) => {
export const findAll = async (ctx: Context, next: Next) => {
const Collection = ctx.db.getModel('collections');
const collections = await Collection.findAll(Collection.parseApiJson({
sort: 'sort',
@ -16,7 +13,7 @@ export const findAll = async (ctx: actions.Context, next: actions.Next) => {
await next();
}
export const createOrUpdate = async (ctx: actions.Context, next: actions.Next) => {
export const createOrUpdate = async (ctx: Context, next: Next) => {
const { values } = ctx.action.params;
const Collection = ctx.db.getModel('collections');
let collection;
@ -55,4 +52,5 @@ export const createOrUpdate = async (ctx: actions.Context, next: actions.Next) =
throw error;
}
ctx.body = collection;
await next();
}

View File

@ -11,8 +11,8 @@ export default async function (this: Application, options = {}) {
database.import({
directory: path.resolve(__dirname, 'collections'),
});
this.on('server.beforeStart', async () => {
console.log('server.beforeStart');
this.on('plugins.afterLoad', async () => {
console.log('plugins.afterLoad');
await database.getModel('collections').load();
});
const [Collection, Field] = database.getModels(['collections', 'fields']);

View File

@ -10,7 +10,6 @@ import _ from 'lodash';
export interface ResourcerContext {
resourcer?: Resourcer;
action?: Action;
params?: ParsedParams;
[key: string]: any;
}