tachybase_todo/packages/core/server/src/helper.ts

110 lines
2.9 KiB
TypeScript
Raw Normal View History

import cors from '@koa/cors';
import Database from '@nocobase/database';
import Resourcer from '@nocobase/resourcer';
feat: application supervisor (#2353) * chore: skip sync localization-management plugin enable status * chore: unSyncPlugins array * chore: remove install at dev * chore: gateway and supervisor * chore: install command * chore: remove app manager * chore: share plugin * chore: wsserver * chore: websocket server * chore: websocket connection with app status * feat: socket server at gateway * chore: loading message * chore: ready status * chore: handle app error * feat: restart app at supervisor * feat: health check endpoint * chore: test * chore: test * chore: test * chore: test * chore: build * chore: test * chore: build * chore: application ready status * chore: error message * chore: handle application error * chore: handle error in load * chore: report error in websocket * chore: ws error * chore: ws error * chore: typo * chore: switch app ready status at install * chore: test * chore: test * chore: test * chore: test * feat: add WebSocket client * chore: start gateway * chore: start command in application * chore: code * chore: pm command * chore: run start after load sub app * feat: application fsm * refactor: server life cycle (#2402) * refactor: server life cycle * fix: test error * fix: test error * fix: test error * fix: app.start * fix: cronjob stop * fix: db.sync before upgrade * fix: pm.get * fix: test error * fix: test error * fix: test error * test: add test cases * fix: remove PluginType * chore: start application after install * chore: fsm * chore: working status * chore: working command * chore: remove swith app ready status * chore: switch status after working done * chore: ws status * chore: gateway error * chore: test * chore: stopping status * chore: test * chore: test * feat: app proxy * chore: application destory * chore: application message changed with status * chore: test * chore: test timeout * test: remove listener add by plugin * test: remove listener add by plugin * chore: test * feat: app maintaining * fix: add AppMaintainingDialog * feat: off * test: gateway http response * test: gateway with errors * chore: unkown error * chore: websocket message * chore: ws message * chore: code * chore: error format * chore: delay app load * feat: improve code * chore: application initializing status * chore: supervisor with app status * chore: command status response * chore: test * chore: ws message * chore: test * fix: command running message * feat: restart * chore: code * chore: status transition * chore: test * fix: improve code * fix: error * fix: restart * fix: command * chore: reset client app tag when app selector changed * chore: error report * fix: application status * fix: build * chore: disable help command dispatch * chore: test * test: multi apps test * fix: improve code * fix: test * fix: test * fix: multi apps single running * fix: improve code * fix: app status * chore: move plugin static file to gateway * feat: static file handler * chore: test * chore: enable plugins in share collection * chore: gateway serve upload files * fix: improve client * chore: ws nginx config * fix: gateway with naonoid * fix: db sync * fix: loading * fix: ping * fix: locale load * fix: yarn start --quickstart * fix: add debug log * chore: application started event * chore: running working message payload * chore: nginx log * chore: nginxconf * chore: working message log * feat: logs * feat: compression * fix: remove koa-send and koa-static * fix: remove -e * fix: remove nginx * fix: remove -e * fix: __appName * chore: delay install sub application * chore: sync plugin status * fix: boot sub app * fix: main app reload * fix: test * fix: app status * test: field.bind block event loop * feat: newrelic * feat: debug log * chore: upgrade * fix(file-manager): test error * fix: default app selector * fix: reload after maintained * chore: boot sub app * chore: application destroy command * chore: destroy command * chore: clean code * chore: package.json * chore: maintaining message * chore: test * fix: collection.sync * feat: add test cases * chore: application * fix: test error * feat: improve codes and add test cases * fix: test error * fix: pm enable and disable * fix: pm.disable * feat: update docs * chore: update dockerfile --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-08-24 17:47:45 +08:00
import { Command } from 'commander';
import i18next from 'i18next';
import bodyParser from 'koa-bodyparser';
import Application, { ApplicationOptions } from './application';
feat(parse-variables): support to parse variables in filter params (#1558) * fix: add field linkage on setting default datetime * fix: fix dateonly timezone problem * fix: improve test * docs(DatePicker): add demos * fix(DatePicker): should return the beginning of a second * feat(DatePicker): support non-UTC * refactor: rename * fix(RangePicker): get correct end date * test(mapDatePicker): add test * test(mapRangePicker): add test * feat(Filter): use non-UTC to filter * feat(FilterBlock): use non-UTC to filter * feat: add '$dateBetween' operator in datetime * feat: use RangePicker on toggled to 'dateBetween' operator * feat: set ranges for RangePicker * feat: backend support to parse 'dateBetween' operator * fix: fix build error * fix: adaptive content width * feat: support to use var on data scope * feat: add parse-variables plugin * feat: support to parse variables * feat: support only to set system variables * test: rename * feat: cover all * fix: fix build error * feat(RangePicker): extend more shortcut keys * feat(parse-variables): support more date var * feat: support user variables * feat: disable unmatched options * fix: use component name to filter option * fix: fix build error * feat: remove some operator of id * chore: remove useless operators * fix: built in plugin * refactor: move to core from plugin * refactor: remove code of plugin * refactor: remove useless code * fix: should after acl * Update server.ts * fix: compatible with old version * feat: test cases * refactor: rename to 'is between' * refactor: parse filter * fix: improve code * feat: test cases * fix: fix error * fix: improve parse date * fix: date variables * fix: day range * fix: test error * fix: typo * fix: test error * feat: $user variable * fix: toDate * fix: fix the value range of shortcuts * feat: add quarter and test * feat: support to use user's association fields to filter * refactor: use maxDepth * refactor: remove useless code * fix: make AssociationSelect.Designer to support variables * fix: getField * fix: parse utc * fix: remove only * fix: filter by ctx.db.getFieldByPath * fix: avoid error * fix: add translation * fix(RangePicker): can be set to empty * feat(utils): add hasEmptyValue * fix: should not save empty * fix: last few days should include today * fix: limit user variable type to display * fix: parse filter error * fix: empty * test: [skip ci] * fix: remove ';' * feat: improve code --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-03-30 23:49:57 +08:00
import { parseVariables } from './middlewares';
import { dateTemplate } from './middlewares/data-template';
import { dataWrapping } from './middlewares/data-wrapping';
import { db2resource } from './middlewares/db2resource';
import { i18n } from './middlewares/i18n';
export function createI18n(options: ApplicationOptions) {
const instance = i18next.createInstance();
instance.init({
lng: 'en-US',
resources: {},
keySeparator: false,
nsSeparator: false,
...options.i18n,
});
return instance;
}
export function createDatabase(options: ApplicationOptions) {
if (options.database instanceof Database) {
return options.database;
} else {
return new Database(options.database);
}
}
export function createResourcer(options: ApplicationOptions) {
return new Resourcer({ ...options.resourcer });
}
2021-12-06 21:23:34 +08:00
export function registerMiddlewares(app: Application, options: ApplicationOptions) {
app.use(
cors({
exposeHeaders: ['content-disposition'],
...options.cors,
}),
{
tag: 'cors',
after: 'bodyParser',
},
);
if (options.bodyParser !== false) {
app.use(
bodyParser({
...options.bodyParser,
}),
{
tag: 'bodyParser',
after: 'logger',
},
);
}
app.use(async (ctx, next) => {
2022-04-09 15:30:43 +08:00
ctx.getBearerToken = () => {
const token = ctx.get('Authorization').replace(/^Bearer\s+/gi, '');
return token || ctx.query.token;
2022-04-09 15:30:43 +08:00
};
await next();
});
app.use(i18n, { tag: 'i18n', after: 'cors' });
if (options.dataWrapping !== false) {
app.use(dataWrapping(), { tag: 'dataWrapping', after: 'i18n' });
}
feat(parse-variables): support to parse variables in filter params (#1558) * fix: add field linkage on setting default datetime * fix: fix dateonly timezone problem * fix: improve test * docs(DatePicker): add demos * fix(DatePicker): should return the beginning of a second * feat(DatePicker): support non-UTC * refactor: rename * fix(RangePicker): get correct end date * test(mapDatePicker): add test * test(mapRangePicker): add test * feat(Filter): use non-UTC to filter * feat(FilterBlock): use non-UTC to filter * feat: add '$dateBetween' operator in datetime * feat: use RangePicker on toggled to 'dateBetween' operator * feat: set ranges for RangePicker * feat: backend support to parse 'dateBetween' operator * fix: fix build error * fix: adaptive content width * feat: support to use var on data scope * feat: add parse-variables plugin * feat: support to parse variables * feat: support only to set system variables * test: rename * feat: cover all * fix: fix build error * feat(RangePicker): extend more shortcut keys * feat(parse-variables): support more date var * feat: support user variables * feat: disable unmatched options * fix: use component name to filter option * fix: fix build error * feat: remove some operator of id * chore: remove useless operators * fix: built in plugin * refactor: move to core from plugin * refactor: remove code of plugin * refactor: remove useless code * fix: should after acl * Update server.ts * fix: compatible with old version * feat: test cases * refactor: rename to 'is between' * refactor: parse filter * fix: improve code * feat: test cases * fix: fix error * fix: improve parse date * fix: date variables * fix: day range * fix: test error * fix: typo * fix: test error * feat: $user variable * fix: toDate * fix: fix the value range of shortcuts * feat: add quarter and test * feat: support to use user's association fields to filter * refactor: use maxDepth * refactor: remove useless code * fix: make AssociationSelect.Designer to support variables * fix: getField * fix: parse utc * fix: remove only * fix: filter by ctx.db.getFieldByPath * fix: avoid error * fix: add translation * fix(RangePicker): can be set to empty * feat(utils): add hasEmptyValue * fix: should not save empty * fix: last few days should include today * fix: limit user variable type to display * fix: parse filter error * fix: empty * test: [skip ci] * fix: remove ';' * feat: improve code --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-03-30 23:49:57 +08:00
app.resourcer.use(parseVariables, { tag: 'parseVariables', after: 'acl' });
app.resourcer.use(dateTemplate, { tag: 'dateTemplate', after: 'acl' });
feat(parse-variables): support to parse variables in filter params (#1558) * fix: add field linkage on setting default datetime * fix: fix dateonly timezone problem * fix: improve test * docs(DatePicker): add demos * fix(DatePicker): should return the beginning of a second * feat(DatePicker): support non-UTC * refactor: rename * fix(RangePicker): get correct end date * test(mapDatePicker): add test * test(mapRangePicker): add test * feat(Filter): use non-UTC to filter * feat(FilterBlock): use non-UTC to filter * feat: add '$dateBetween' operator in datetime * feat: use RangePicker on toggled to 'dateBetween' operator * feat: set ranges for RangePicker * feat: backend support to parse 'dateBetween' operator * fix: fix build error * fix: adaptive content width * feat: support to use var on data scope * feat: add parse-variables plugin * feat: support to parse variables * feat: support only to set system variables * test: rename * feat: cover all * fix: fix build error * feat(RangePicker): extend more shortcut keys * feat(parse-variables): support more date var * feat: support user variables * feat: disable unmatched options * fix: use component name to filter option * fix: fix build error * feat: remove some operator of id * chore: remove useless operators * fix: built in plugin * refactor: move to core from plugin * refactor: remove code of plugin * refactor: remove useless code * fix: should after acl * Update server.ts * fix: compatible with old version * feat: test cases * refactor: rename to 'is between' * refactor: parse filter * fix: improve code * feat: test cases * fix: fix error * fix: improve parse date * fix: date variables * fix: day range * fix: test error * fix: typo * fix: test error * feat: $user variable * fix: toDate * fix: fix the value range of shortcuts * feat: add quarter and test * feat: support to use user's association fields to filter * refactor: use maxDepth * refactor: remove useless code * fix: make AssociationSelect.Designer to support variables * fix: getField * fix: parse utc * fix: remove only * fix: filter by ctx.db.getFieldByPath * fix: avoid error * fix: add translation * fix(RangePicker): can be set to empty * feat(utils): add hasEmptyValue * fix: should not save empty * fix: last few days should include today * fix: limit user variable type to display * fix: parse filter error * fix: empty * test: [skip ci] * fix: remove ';' * feat: improve code --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-03-30 23:49:57 +08:00
app.use(db2resource, { tag: 'db2resource', after: 'dataWrapping' });
app.use(app.resourcer.restApiMiddleware(), { tag: 'restApi', after: 'db2resource' });
}
feat: application supervisor (#2353) * chore: skip sync localization-management plugin enable status * chore: unSyncPlugins array * chore: remove install at dev * chore: gateway and supervisor * chore: install command * chore: remove app manager * chore: share plugin * chore: wsserver * chore: websocket server * chore: websocket connection with app status * feat: socket server at gateway * chore: loading message * chore: ready status * chore: handle app error * feat: restart app at supervisor * feat: health check endpoint * chore: test * chore: test * chore: test * chore: test * chore: build * chore: test * chore: build * chore: application ready status * chore: error message * chore: handle application error * chore: handle error in load * chore: report error in websocket * chore: ws error * chore: ws error * chore: typo * chore: switch app ready status at install * chore: test * chore: test * chore: test * chore: test * feat: add WebSocket client * chore: start gateway * chore: start command in application * chore: code * chore: pm command * chore: run start after load sub app * feat: application fsm * refactor: server life cycle (#2402) * refactor: server life cycle * fix: test error * fix: test error * fix: test error * fix: app.start * fix: cronjob stop * fix: db.sync before upgrade * fix: pm.get * fix: test error * fix: test error * fix: test error * test: add test cases * fix: remove PluginType * chore: start application after install * chore: fsm * chore: working status * chore: working command * chore: remove swith app ready status * chore: switch status after working done * chore: ws status * chore: gateway error * chore: test * chore: stopping status * chore: test * chore: test * feat: app proxy * chore: application destory * chore: application message changed with status * chore: test * chore: test timeout * test: remove listener add by plugin * test: remove listener add by plugin * chore: test * feat: app maintaining * fix: add AppMaintainingDialog * feat: off * test: gateway http response * test: gateway with errors * chore: unkown error * chore: websocket message * chore: ws message * chore: code * chore: error format * chore: delay app load * feat: improve code * chore: application initializing status * chore: supervisor with app status * chore: command status response * chore: test * chore: ws message * chore: test * fix: command running message * feat: restart * chore: code * chore: status transition * chore: test * fix: improve code * fix: error * fix: restart * fix: command * chore: reset client app tag when app selector changed * chore: error report * fix: application status * fix: build * chore: disable help command dispatch * chore: test * test: multi apps test * fix: improve code * fix: test * fix: test * fix: multi apps single running * fix: improve code * fix: app status * chore: move plugin static file to gateway * feat: static file handler * chore: test * chore: enable plugins in share collection * chore: gateway serve upload files * fix: improve client * chore: ws nginx config * fix: gateway with naonoid * fix: db sync * fix: loading * fix: ping * fix: locale load * fix: yarn start --quickstart * fix: add debug log * chore: application started event * chore: running working message payload * chore: nginx log * chore: nginxconf * chore: working message log * feat: logs * feat: compression * fix: remove koa-send and koa-static * fix: remove -e * fix: remove nginx * fix: remove -e * fix: __appName * chore: delay install sub application * chore: sync plugin status * fix: boot sub app * fix: main app reload * fix: test * fix: app status * test: field.bind block event loop * feat: newrelic * feat: debug log * chore: upgrade * fix(file-manager): test error * fix: default app selector * fix: reload after maintained * chore: boot sub app * chore: application destroy command * chore: destroy command * chore: clean code * chore: package.json * chore: maintaining message * chore: test * fix: collection.sync * feat: add test cases * chore: application * fix: test error * feat: improve codes and add test cases * fix: test error * fix: pm enable and disable * fix: pm.disable * feat: update docs * chore: update dockerfile --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-08-24 17:47:45 +08:00
export const createAppProxy = (app: Application) => {
return new Proxy(app, {
get(target, prop, ...args) {
if (typeof prop === 'string' && ['on', 'once', 'addListener'].includes(prop)) {
return (eventName: string, listener: any) => {
listener['_reinitializable'] = true;
return target[prop](eventName, listener);
};
}
return Reflect.get(target, prop, ...args);
},
});
};
export const getCommandFullName = (command: Command) => {
const names = [];
names.push(command.name());
let parent = command?.parent;
while (parent) {
if (!parent?.parent) {
break;
}
names.unshift(parent.name());
parent = parent.parent;
}
return names.join('.');
};