From 09c42abdccbf3e46e309ab6d5754bb7491ea546a Mon Sep 17 00:00:00 2001 From: chenos Date: Thu, 16 Sep 2021 00:37:43 +0800 Subject: [PATCH] feat: add examples --- examples/collections/src/index.ts | 77 +++++++++++++++++ examples/index.ts | 4 + examples/middleware/src/index.ts | 0 examples/models/src/index.ts | 0 examples/plugins/src/index.ts | 0 examples/repositories/src/index.ts | 0 examples/resources/src/index.ts | 65 ++++++++++++++ examples/saas/src/index.ts | 134 +++++++++++++++++++++++++++++ examples/simple/src/index.ts | 63 ++++++++++++++ 9 files changed, 343 insertions(+) create mode 100644 examples/collections/src/index.ts create mode 100644 examples/index.ts create mode 100644 examples/middleware/src/index.ts create mode 100644 examples/models/src/index.ts create mode 100644 examples/plugins/src/index.ts create mode 100644 examples/repositories/src/index.ts create mode 100644 examples/resources/src/index.ts create mode 100644 examples/saas/src/index.ts create mode 100644 examples/simple/src/index.ts diff --git a/examples/collections/src/index.ts b/examples/collections/src/index.ts new file mode 100644 index 000000000..a17f2673a --- /dev/null +++ b/examples/collections/src/index.ts @@ -0,0 +1,77 @@ +import { Application } from '@nocobase/server/src'; +import path from 'path'; + +const keys = __dirname.split(path.sep); +const slug = keys[keys.length - 2]; + +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', + }, + hooks: { + beforeDefine(model, options) { + options.tableName = `examples_${slug}_${options.tableName || options.name.plural}`; + }, + }, + }, + resourcer: { + prefix: `/api/examples/${slug}`, + }, +}; + +console.log(options); + +const app = new Application(options); + +// 用户 +app.collection({ + name: 'users', + fields: [ + { type: 'string', name: 'username', unique: true }, + { type: 'password', name: 'password', unique: true }, + { type: 'hasMany', name: 'posts', foreignKey: 'author_id' }, + ], +}); + +// 文章 +app.collection({ + name: 'posts', + fields: [ + { type: 'string', name: 'title' }, + { type: 'text', name: 'content' }, + { type: 'belongsToMany', name: 'tags' }, + { type: 'hasMany', name: 'comments' }, + { type: 'belongsTo', name: 'author', target: 'users' }, + ], +}); + +// 标签 +app.collection({ + name: 'tags', + fields: [ + { type: 'string', name: 'name' }, + { type: 'belongsToMany', name: 'posts' }, + ], +}); + +// 评论 +app.collection({ + name: 'comments', + fields: [ + { type: 'text', name: 'content' }, + { type: 'belongsTo', name: 'user' }, + ], +}); + +app.parse(process.argv); + +// yarn examples collections db sync +// yarn examples collections start diff --git a/examples/index.ts b/examples/index.ts new file mode 100644 index 000000000..39fe5d95a --- /dev/null +++ b/examples/index.ts @@ -0,0 +1,4 @@ +const example = process.argv[2]; +process.argv.splice(2, 1); +console.log(process.argv); +require(`./${example}/src`); diff --git a/examples/middleware/src/index.ts b/examples/middleware/src/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/examples/models/src/index.ts b/examples/models/src/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/examples/plugins/src/index.ts b/examples/plugins/src/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/examples/repositories/src/index.ts b/examples/repositories/src/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/examples/resources/src/index.ts b/examples/resources/src/index.ts new file mode 100644 index 000000000..d1d51452f --- /dev/null +++ b/examples/resources/src/index.ts @@ -0,0 +1,65 @@ +import { Application } from '@nocobase/server/src'; +import path from 'path'; + +const keys = __dirname.split(path.sep); +const slug = keys[keys.length - 2]; + +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', + }, + hooks: { + beforeDefine(model, options) { + options.tableName = `examples_${slug}_${options.tableName || options.name.plural}`; + }, + }, + }, + resourcer: { + prefix: `/api/examples/${slug}`, + }, +}; + +console.log(options); + +const app = new Application(options); + +app.resource({ + name: 'server', + actions: { + async getTime(ctx, next) { + ctx.body = new Date(); + await next(); + } + }, +}); + +app.parse(process.argv); + +/* +根据配置生成相关数据表 +yarn examples simple db sync + +启动服务 +yarn examples simple start + +客户端发送请求 + +创建数据 +curl --location --request POST 'http://localhost:3000/api/examples/simple/users' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "username": "abc", + "password": "123456" +}' + +查看列表 +curl --location --request GET 'http://localhost:5051/api/examples/simple/users' +*/ diff --git a/examples/saas/src/index.ts b/examples/saas/src/index.ts new file mode 100644 index 000000000..2f705c6c2 --- /dev/null +++ b/examples/saas/src/index.ts @@ -0,0 +1,134 @@ +import { Application } from '@nocobase/server/src'; +import path from 'path'; +import mount from 'koa-mount'; +import compose from 'koa-compose'; + +const keys = __dirname.split(path.sep); +const slug = keys[keys.length - 2]; + +const apps = new Map(); + +function createApp(opts) { + const { name, prefix } = 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', + }, + hooks: { + beforeDefine(model, options) { + options.tableName = `examples_${slug}_${name}_${options.tableName || options.name.plural}`; + }, + }, + }, + resourcer: { + prefix, + }, + }; + console.log(options); + const app = new Application(options); + if (name) { + apps.set(name, app); + } + app.resource({ + name: 'server', + actions: { + async getInfo(ctx, next) { + ctx.body = name; + await next(); + } + }, + }); + app.collection({ + name: 'users', + fields: [ + { type: 'string', name: 'username' }, + { type: 'password', name: 'password' }, + ], + }); + return app; +} + +const app = createApp({ + name: 'main', + prefix: `/api/examples/${slug}/main` +}); + +app.collection({ + name: 'applications', + fields: [ + { type: 'string', name: 'name', unique: true }, + ], +}); + +app.command('app-create').argument('').action(async (appName) => { + const App = app.db.getModel('applications'); + const server = await App.create({ + name: appName, + }); + const api = createApp({ + name: appName, + prefix: `/api/examples/${slug}/${appName}`, + }); + await api.db.sync(); + await api.destroy(); + console.log(server.toJSON()); + await app.destroy(); +}); + +app.command('dbsync') + .option('-f, --force') + .option('--app [app]') + .action(async (...args) => { + const cli = args.pop(); + const force = cli.opts()?.force; + const appName = cli.opts()?.app; + console.log('ac ac', cli.opts()); + const api = apps.get(appName) || app; + await api.load(); + await api.db.sync( + force + ? { + force: true, + alter: { + drop: true, + }, + } + : {}, + ); + await api.destroy(); + }); + +app.use(async function(ctx, next) { + const appName = ctx.path.split('/')[4]; + if (appName === 'main') { + return next(); + } + const App = ctx.db.getModel('applications'); + const model = await App.findOne({ + where: { name: appName }, + }); + console.log({ appName, model }) + if (!model) { + return next(); + } + if (!apps.has(appName)) { + const app1 = createApp({ + name: appName, + prefix: `/api/examples/${slug}/${appName}` + }); + apps.set(appName, app1); + } + const server = apps.get(appName); + await compose(server.middleware)(ctx, next); +}); + +app.parse(process.argv); diff --git a/examples/simple/src/index.ts b/examples/simple/src/index.ts new file mode 100644 index 000000000..898617d82 --- /dev/null +++ b/examples/simple/src/index.ts @@ -0,0 +1,63 @@ +import { Application } from '@nocobase/server/src'; +import path from 'path'; + +const keys = __dirname.split(path.sep); +const slug = keys[keys.length - 2]; + +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', + }, + hooks: { + beforeDefine(model, options) { + options.tableName = `examples_${slug}_${options.tableName || options.name.plural}`; + }, + }, + }, + resourcer: { + prefix: `/api/examples/${slug}`, + }, +}; + +console.log(options); + +const app = new Application(options); + +app.collection({ + name: 'users', + fields: [ + { type: 'string', name: 'username' }, + { type: 'password', name: 'password' }, + ], +}); + +app.parse(process.argv); + +/* +根据配置生成相关数据表 +yarn examples simple db sync + +启动服务 +yarn examples simple start + +客户端发送请求 + +创建数据 +curl --location --request POST 'http://localhost:3000/api/examples/simple/users' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "username": "abc", + "password": "123456" +}' + +查看列表 +curl --location --request GET 'http://localhost:5051/api/examples/simple/users' +*/