tachybase_todo/examples/saas/src/index.ts
2021-09-16 15:57:21 +08:00

155 lines
3.3 KiB
TypeScript

import { Application } from '@nocobase/server/src';
import path from 'path';
import compose from 'koa-compose';
const keys = __dirname.split(path.sep);
const slug = keys[keys.length - 2];
function createApp(opts) {
const { name } = opts;
const options = {
database: {
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
host: process.env.DB_HOST,
port: process.env.DB_PORT as any,
dialect: process.env.DB_DIALECT as any,
dialectOptions: {
charset: 'utf8mb4',
collate: 'utf8mb4_unicode_ci',
},
appName: name,
hooks: {
beforeDefine(model, options) {
options.tableName = `examples_${slug}_${name}_${
options.tableName || options.name.plural
}`;
},
},
},
resourcer: {
prefix: `/api/examples/${slug}/${name}`,
},
};
const app = new Application(options);
app.resource({
name: 'saas',
actions: {
async getInfo(ctx, next) {
ctx.body = ctx.db.options;
await next();
},
},
});
app.collection({
name: 'users',
fields: [
{ type: 'string', name: 'username' },
{ type: 'password', name: 'password' },
],
});
return app;
}
const saas = createApp({
name: 'main',
});
saas['apps'] = new Map<string, Application>();
saas.collection({
name: 'applications',
fields: [
{ type: 'string', name: 'name', unique: true },
],
});
saas
.command('app:create')
.argument('<appName>')
.action(async (appName) => {
const App = saas.db.getModel('applications');
const model = await App.create({
name: appName,
});
const app = createApp({
name: appName,
});
await app.db.sync();
await app.destroy();
await saas.destroy();
console.log(model.toJSON());
});
saas
.command('db:sync')
.option('-f, --force')
.option('--app [app]')
.action(async (...args) => {
const cli = args.pop();
const force = cli.opts()?.force;
const appName = cli.opts()?.app;
const app = !appName
? saas
: createApp({
name: appName,
});
await app.load();
await app.db.sync(
force
? {
force: true,
alter: {
drop: true,
},
}
: {},
);
await app.destroy();
await saas.destroy();
});
function multiApps({ getAppName }) {
return async function (ctx, next) {
const appName = getAppName(ctx);
if (!appName) {
return next();
}
const App = ctx.db.getModel('applications');
const model = await App.findOne({
where: { name: appName },
});
console.log({ appName, model });
if (!model) {
return next();
}
const apps = ctx.app.apps;
if (!apps.has(appName)) {
const app = createApp({
name: appName,
});
apps.set(appName, app);
}
const saas = apps.get(appName);
await compose(saas.middleware)(ctx, async () => {});
};
}
saas.use(
multiApps({
getAppName(ctx) {
const appName = ctx.path.split('/')[4];
return appName === 'main' ? null : appName;
},
}),
);
// saas.use(async (ctx, next) => {
// ctx.body = 'aaaaa';
// console.log(ctx.db.options);
// await next();
// });
saas.parse(process.argv);