重构了后台启动的相关部分
This commit is contained in:
parent
066ff597e5
commit
f4b11e7fdf
|
|
@ -10,7 +10,7 @@ async function run(options) {
|
||||||
(0, tip_style_1.Success)(`${(0, tip_style_1.success)('初始化数据库中……')}`);
|
(0, tip_style_1.Success)(`${(0, tip_style_1.success)('初始化数据库中……')}`);
|
||||||
// ts-node scripts/build-app-domain & npm link ./app-domain
|
// ts-node scripts/build-app-domain & npm link ./app-domain
|
||||||
const drop = options.args.includes('drop') || false;
|
const drop = options.args.includes('drop') || false;
|
||||||
const result = cross_spawn_1.default.sync('ts-node', [require.resolve('../scripts/' + 'initialize-database.js'), `${drop}`], {
|
const result = cross_spawn_1.default.sync('ts-node', [require.resolve('../scripts/' + 'initialize-server.ts'), `${drop}`], {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: true,
|
shell: true,
|
||||||
});
|
});
|
||||||
|
|
@ -28,6 +28,7 @@ async function run(options) {
|
||||||
// ts-node scripts/build-app-domain & npm link ./app-domain
|
// ts-node scripts/build-app-domain & npm link ./app-domain
|
||||||
const result = cross_spawn_1.default.sync(`cross-env`, [
|
const result = cross_spawn_1.default.sync(`cross-env`, [
|
||||||
`NODE_ENV=${options.mode}`,
|
`NODE_ENV=${options.mode}`,
|
||||||
|
'OAK_PLATFORM=server',
|
||||||
'ts-node',
|
'ts-node',
|
||||||
require.resolve('../scripts/' + 'start-server.js'),
|
require.resolve('../scripts/' + 'start-server.js'),
|
||||||
], {
|
], {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
/// <reference path="../../src/typings/polyfill.d.ts" />
|
||||||
|
import { Context, EntityDict, RowStore } from 'oak-domain/lib/types';
|
||||||
|
export declare function initialize<ED extends EntityDict, Cxt extends Context<ED>>(path: string, contextBuilder: (scene?: string) => (store: RowStore<ED, Cxt>) => Cxt, dropIfExists?: boolean): Promise<void>;
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.initialize = void 0;
|
||||||
|
/// <reference path="../typings/polyfill.d.ts" />
|
||||||
|
const oak_backend_base_1 = require("oak-backend-base");
|
||||||
|
async function initialize(path, contextBuilder, dropIfExists) {
|
||||||
|
const appLoader = new oak_backend_base_1.AppLoader(path, contextBuilder);
|
||||||
|
await appLoader.mount();
|
||||||
|
await appLoader.initialize(dropIfExists);
|
||||||
|
await appLoader.unmount();
|
||||||
|
console.log('data initialized');
|
||||||
|
}
|
||||||
|
exports.initialize = initialize;
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
export declare type GenerateIdOption = {
|
||||||
|
shuffle?: boolean;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const uuid_1 = require("uuid");
|
||||||
|
async function generateNewId(option) {
|
||||||
|
if (option?.shuffle && process.env.NODE_ENV === 'development') {
|
||||||
|
return (0, uuid_1.v4)();
|
||||||
|
}
|
||||||
|
return (0, uuid_1.v1)();
|
||||||
|
}
|
||||||
|
Object.assign(global, {
|
||||||
|
generateNewId,
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
/// <reference path="../../src/typings/polyfill.d.ts" />
|
||||||
|
import './polyfill';
|
||||||
|
import { Connector, EntityDict, Context, RowStore } from 'oak-domain/lib/types';
|
||||||
|
export declare function startup<ED extends EntityDict, Cxt extends Context<ED>>(path: string, contextBuilder: (scene?: string) => (store: RowStore<ED, Cxt>) => Cxt, connector: Connector<ED, Cxt>): Promise<void>;
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
"use strict";
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.startup = void 0;
|
||||||
|
/// <reference path="../typings/polyfill.d.ts" />
|
||||||
|
require("./polyfill");
|
||||||
|
const koa_1 = __importDefault(require("koa"));
|
||||||
|
const koa_router_1 = __importDefault(require("koa-router"));
|
||||||
|
const koa_body_1 = __importDefault(require("koa-body"));
|
||||||
|
const oak_backend_base_1 = require("oak-backend-base");
|
||||||
|
const types_1 = require("oak-domain/lib/types");
|
||||||
|
async function startup(path, contextBuilder, connector) {
|
||||||
|
const appLoader = new oak_backend_base_1.AppLoader(path, contextBuilder);
|
||||||
|
await appLoader.mount();
|
||||||
|
const koa = new koa_1.default();
|
||||||
|
koa.use((0, koa_body_1.default)({
|
||||||
|
multipart: true,
|
||||||
|
}));
|
||||||
|
const router = new koa_router_1.default();
|
||||||
|
// 如果是开发环境,允许options
|
||||||
|
if (process.env.NODE_ENV = 'development') {
|
||||||
|
koa.use(async (ctx, next) => {
|
||||||
|
ctx.set('Access-Control-Allow-Origin', '*');
|
||||||
|
ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With, oak-cxt, oak-aspect');
|
||||||
|
ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
|
||||||
|
if (ctx.method == 'OPTIONS') {
|
||||||
|
ctx.body = 200;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
router.post(connector.getRouter(), async (ctx) => {
|
||||||
|
console.log('aspect called');
|
||||||
|
const { request } = ctx;
|
||||||
|
const { name, params, context } = connector.parseRequest(request.headers, request.body, appLoader.getStore());
|
||||||
|
await context.begin();
|
||||||
|
let result;
|
||||||
|
try {
|
||||||
|
result = await appLoader.execAspect(name, context, params);
|
||||||
|
await context.commit();
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
await context.rollback();
|
||||||
|
console.error(err);
|
||||||
|
const exception = err instanceof types_1.OakException ? err : new types_1.OakException('内部不可知错误');
|
||||||
|
const { body } = connector.serializeException(exception, request.headers, request.body);
|
||||||
|
ctx.response.body = body;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { body, headers } = connector.serializeResult(result, context, request.headers, request.body);
|
||||||
|
ctx.response.body = body;
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
koa.use(router.routes());
|
||||||
|
const serverConfig = require(`${path}/configuration/server.json`);
|
||||||
|
console.log(`server will listen on port ${serverConfig.port}`);
|
||||||
|
koa.on('error', (err) => {
|
||||||
|
console.error(err);
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
koa.listen(serverConfig.port);
|
||||||
|
}
|
||||||
|
exports.startup = startup;
|
||||||
11
package.json
11
package.json
|
|
@ -19,8 +19,10 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/cross-spawn": "^6.0.2",
|
"@types/cross-spawn": "^6.0.2",
|
||||||
"@types/inquirer": "^7.3.1",
|
"@types/inquirer": "^7.3.1",
|
||||||
|
"@types/koa-router": "^7.4.4",
|
||||||
"@types/node": "^12.0.27",
|
"@types/node": "^12.0.27",
|
||||||
"@types/shelljs": "^0.8.8",
|
"@types/shelljs": "^0.8.8",
|
||||||
|
"@types/uuid": "^8.3.4",
|
||||||
"@xmldom/xmldom": "^0.8.2",
|
"@xmldom/xmldom": "^0.8.2",
|
||||||
"stream-browserify": "^3.0.0",
|
"stream-browserify": "^3.0.0",
|
||||||
"typescript": "^4.6.3"
|
"typescript": "^4.6.3"
|
||||||
|
|
@ -66,17 +68,15 @@
|
||||||
"jest": "^27.4.3",
|
"jest": "^27.4.3",
|
||||||
"jest-resolve": "^27.4.2",
|
"jest-resolve": "^27.4.2",
|
||||||
"jest-watch-typeahead": "^1.0.0",
|
"jest-watch-typeahead": "^1.0.0",
|
||||||
|
"koa": "^2.13.4",
|
||||||
|
"koa-body": "^5.0.0",
|
||||||
|
"koa-router": "^11.0.1",
|
||||||
"less": "^4.1.2",
|
"less": "^4.1.2",
|
||||||
"less-loader": "^10.2.0",
|
"less-loader": "^10.2.0",
|
||||||
"loader-utils": "^3.2.0",
|
"loader-utils": "^3.2.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mini-css-extract-plugin": "^2.5.3",
|
"mini-css-extract-plugin": "^2.5.3",
|
||||||
"oak-common-aspect": "file:../oak-common-aspect",
|
|
||||||
"oak-domain": "file:../oak-domain",
|
"oak-domain": "file:../oak-domain",
|
||||||
"oak-external-sdk": "file:../oak-external-sdk",
|
|
||||||
"oak-frontend-base": "file:../oak-frontend-base",
|
|
||||||
"oak-general-business": "file:../oak-general-business",
|
|
||||||
"oak-memory-tree-store": "file:../oak-memory-tree-store",
|
|
||||||
"postcss": "^8.4.4",
|
"postcss": "^8.4.4",
|
||||||
"postcss-flexbugs-fixes": "^5.0.2",
|
"postcss-flexbugs-fixes": "^5.0.2",
|
||||||
"postcss-less": "^6.0.0",
|
"postcss-less": "^6.0.0",
|
||||||
|
|
@ -100,6 +100,7 @@
|
||||||
"tailwindcss": "^3.0.2",
|
"tailwindcss": "^3.0.2",
|
||||||
"terser-webpack-plugin": "^5.2.5",
|
"terser-webpack-plugin": "^5.2.5",
|
||||||
"ui-extract-webpack-plugin": "^1.0.0",
|
"ui-extract-webpack-plugin": "^1.0.0",
|
||||||
|
"uuid": "^8.3.2",
|
||||||
"webpack": "^5.72.0",
|
"webpack": "^5.72.0",
|
||||||
"webpack-dev-server": "^4.6.0",
|
"webpack-dev-server": "^4.6.0",
|
||||||
"webpack-manifest-plugin": "^4.0.2",
|
"webpack-manifest-plugin": "^4.0.2",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
const { initialize } = require('oak-backend-base');
|
|
||||||
const pwd = process.cwd();
|
|
||||||
|
|
||||||
const dropIfExists = process.argv[2];
|
|
||||||
|
|
||||||
initialize(pwd, dropIfExists)
|
|
||||||
.then(
|
|
||||||
() => process.exit(0)
|
|
||||||
);
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
const { startup } = require('oak-backend-base');
|
|
||||||
const pwd = process.cwd();
|
|
||||||
|
|
||||||
startup(pwd);
|
|
||||||
|
|
@ -15,7 +15,7 @@ export default async function run(options: any): Promise<void> {
|
||||||
const drop = options.args.includes('drop') || false;
|
const drop = options.args.includes('drop') || false;
|
||||||
const result = spawn.sync(
|
const result = spawn.sync(
|
||||||
'ts-node',
|
'ts-node',
|
||||||
[require.resolve('../scripts/' + 'initialize-database.js'), `${drop}`],
|
[require.resolve('../scripts/' + 'initialize-server.ts'), `${drop}`],
|
||||||
{
|
{
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
shell: true,
|
shell: true,
|
||||||
|
|
@ -37,6 +37,7 @@ export default async function run(options: any): Promise<void> {
|
||||||
`cross-env`,
|
`cross-env`,
|
||||||
[
|
[
|
||||||
`NODE_ENV=${options.mode}`,
|
`NODE_ENV=${options.mode}`,
|
||||||
|
'OAK_PLATFORM=server',
|
||||||
'ts-node',
|
'ts-node',
|
||||||
require.resolve('../scripts/' + 'start-server.js'),
|
require.resolve('../scripts/' + 'start-server.js'),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/// <reference path="../typings/polyfill.d.ts" />
|
||||||
|
import { AppLoader } from 'oak-backend-base';
|
||||||
|
import { Context, EntityDict, RowStore } from 'oak-domain/lib/types';
|
||||||
|
|
||||||
|
export async function initialize<ED extends EntityDict, Cxt extends Context<ED>>(path: string, contextBuilder: (scene?: string) => (store: RowStore<ED, Cxt>) => Cxt, dropIfExists?: boolean) {
|
||||||
|
const appLoader = new AppLoader(path, contextBuilder);
|
||||||
|
await appLoader.mount();
|
||||||
|
await appLoader.initialize(dropIfExists);
|
||||||
|
await appLoader.unmount();
|
||||||
|
console.log('data initialized');
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { v4, v1 } from 'uuid';
|
||||||
|
|
||||||
|
export type GenerateIdOption = {
|
||||||
|
shuffle?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
async function generateNewId(option?: GenerateIdOption) {
|
||||||
|
if (option?.shuffle && process.env.NODE_ENV === 'development') {
|
||||||
|
return v4();
|
||||||
|
}
|
||||||
|
return v1();
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(global, {
|
||||||
|
generateNewId,
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
/// <reference path="../typings/polyfill.d.ts" />
|
||||||
|
import './polyfill';
|
||||||
|
import Koa from 'koa';
|
||||||
|
import KoaRouter from 'koa-router';
|
||||||
|
import KoaBody from 'koa-body';
|
||||||
|
import { AppLoader, BackendContext } from 'oak-backend-base';
|
||||||
|
import { OakException, Connector, EntityDict, Context, RowStore } from 'oak-domain/lib/types';
|
||||||
|
|
||||||
|
export async function startup<ED extends EntityDict, Cxt extends Context<ED>>(path: string, contextBuilder: (scene?: string) => (store: RowStore<ED, Cxt>) => Cxt, connector: Connector<ED, Cxt>) {
|
||||||
|
const appLoader = new AppLoader(path, contextBuilder);
|
||||||
|
await appLoader.mount();
|
||||||
|
const koa = new Koa();
|
||||||
|
koa.use(KoaBody({
|
||||||
|
multipart: true,
|
||||||
|
}));
|
||||||
|
const router = new KoaRouter();
|
||||||
|
|
||||||
|
// 如果是开发环境,允许options
|
||||||
|
if (process.env.NODE_ENV = 'development') {
|
||||||
|
koa.use(async (ctx, next) => {
|
||||||
|
ctx.set('Access-Control-Allow-Origin', '*');
|
||||||
|
ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With, oak-cxt, oak-aspect');
|
||||||
|
ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
|
||||||
|
if (ctx.method == 'OPTIONS') {
|
||||||
|
ctx.body = 200;
|
||||||
|
} else {
|
||||||
|
await next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
router.post(connector.getRouter(), async (ctx) => {
|
||||||
|
console.log('aspect called');
|
||||||
|
const { request } = ctx;
|
||||||
|
const { name, params, context } = connector.parseRequest(request.headers, request.body, appLoader.getStore());
|
||||||
|
await context.begin();
|
||||||
|
let result: any;
|
||||||
|
try {
|
||||||
|
result = await appLoader.execAspect(name, context, params);
|
||||||
|
await context.commit();
|
||||||
|
}
|
||||||
|
catch (err: any) {
|
||||||
|
await context.rollback();
|
||||||
|
console.error(err);
|
||||||
|
const exception = err instanceof OakException ? err : new OakException('内部不可知错误');
|
||||||
|
const { body } = connector.serializeException(exception, request.headers, request.body);
|
||||||
|
ctx.response.body = body;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { body, headers } = connector.serializeResult(result, context, request.headers, request.body);
|
||||||
|
ctx.response.body = body;
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
koa.use(router.routes());
|
||||||
|
|
||||||
|
|
||||||
|
const serverConfig = require(`${path}/configuration/server.json`);
|
||||||
|
console.log(`server will listen on port ${serverConfig.port}`);
|
||||||
|
koa.on('error', (err) => {
|
||||||
|
console.error(err);
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
koa.listen(serverConfig.port);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { GenerateIdOption } from "oak-backend-base/src/polyfill";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
const generateNewId: (option?: GenerateIdOption) => Promise<string>;
|
||||||
|
const __DEV__: boolean;
|
||||||
|
}
|
||||||
|
export {}
|
||||||
|
|
@ -62,7 +62,8 @@
|
||||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||||
/* Advanced Options */
|
/* Advanced Options */
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"resolveJsonModule": true /* Disallow inconsistently-cased references to the same file. */
|
"resolveJsonModule": true, /* Disallow inconsistently-cased references to the same file. */
|
||||||
|
"experimentalDecorators": true
|
||||||
},
|
},
|
||||||
"include": [ "src/**/*" ],
|
"include": [ "src/**/*" ],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue