Merge branch 'release'

This commit is contained in:
Xu Chang 2025-08-18 15:13:49 +08:00
commit 171bb7ad96
13 changed files with 103 additions and 46 deletions

1
.npmrc Normal file
View File

@ -0,0 +1 @@
engine-strict=true

View File

@ -13,6 +13,7 @@ const clean_1 = tslib_1.__importDefault(require("./clean"));
const config_1 = require("./config"); const config_1 = require("./config");
const tip_style_1 = require("./tip-style"); const tip_style_1 = require("./tip-style");
const rename_1 = require("./rename"); const rename_1 = require("./rename");
const utils_1 = require("./utils");
/** /**
* @name 未知参数错误提示 * @name 未知参数错误提示
* @param {string} methodName * @param {string} methodName
@ -29,20 +30,7 @@ function enhanceErrorMessages(methodName, log) {
process.exit(-1); process.exit(-1);
}; };
} }
const currentNodeVersion = process.versions.node; (0, utils_1.checkNodeVersion)();
const semver = currentNodeVersion.split('.');
const major = semver[0];
const minNodeVersion = 16;
if (Number(major) < minNodeVersion) {
console.error('You are running Node ' +
currentNodeVersion +
'.\n' +
'Create React App requires Node ' +
minNodeVersion +
' or higher. \n' +
'Please update your version of Node.');
process.exit(-1);
}
commander_1.default.version(config_1.CLI_VERSION, '-v, --version').usage('<command> [options]'); commander_1.default.version(config_1.CLI_VERSION, '-v, --version').usage('<command> [options]');
commander_1.default commander_1.default
.command('make:domain') .command('make:domain')

View File

@ -5,4 +5,4 @@ import { Connector, EntityDict } from 'oak-domain/lib/types';
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain'; import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore'; import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
import { SyncContext } from 'oak-domain/lib/store/SyncRowStore'; import { SyncContext } from 'oak-domain/lib/store/SyncRowStore';
export declare function startup<ED extends EntityDict & BaseEntityDict, FrontCxt extends SyncContext<ED>, Cxt extends BackendRuntimeContext<ED>>(path: string, connector: Connector<ED, FrontCxt>, omitWatchers?: boolean, omitTimers?: boolean, routine?: (context: AsyncContext<ED>) => Promise<void>): Promise<(() => Promise<void>) | undefined>; export declare function startup<ED extends EntityDict & BaseEntityDict, FrontCxt extends SyncContext<ED>, Cxt extends BackendRuntimeContext<ED>>(path: string, connector: Connector<ED, FrontCxt>, omitWatchers?: boolean, omitTimers?: boolean, routine?: (context: AsyncContext<ED>) => Promise<void>): Promise<(() => Promise<any>) | any>;

View File

@ -23,6 +23,7 @@ const koa_mount_1 = tslib_1.__importDefault(require("koa-mount"));
const chalk_1 = tslib_1.__importDefault(require("chalk")); const chalk_1 = tslib_1.__importDefault(require("chalk"));
const utils_1 = require("../utils"); const utils_1 = require("../utils");
const bcryptjs_1 = tslib_1.__importDefault(require("bcryptjs")); const bcryptjs_1 = tslib_1.__importDefault(require("bcryptjs"));
(0, utils_1.checkNodeVersion)();
const socketAdminUI = (0, path_1.join)(__dirname, '../../ui/socket-admin'); const socketAdminUI = (0, path_1.join)(__dirname, '../../ui/socket-admin');
const DATA_SUBSCRIBE_NAMESPACE = '/dsn'; const DATA_SUBSCRIBE_NAMESPACE = '/dsn';
const SOCKET_NAMESPACE = '/sn'; const SOCKET_NAMESPACE = '/sn';
@ -147,7 +148,7 @@ async function startup(path, connector, omitWatchers, omitTimers, routine) {
auth: { auth: {
type: "basic", type: "basic",
username: ui?.username || "admin", username: ui?.username || "admin",
password: bcryptjs_1.default.hashSync(passwordForAdminUI, 10), // 使用 bcrypt 加密密码 password: bcryptjs_1.default.hashSync(passwordForAdminUI, 10), // 必须使用 bcrypt 加密之后的密码
}, },
mode: process.env.NODE_ENV === 'production' ? "production" : "development", // 根据环境设置模式 mode: process.env.NODE_ENV === 'production' ? "production" : "development", // 根据环境设置模式
}); });
@ -159,8 +160,9 @@ async function startup(path, connector, omitWatchers, omitTimers, routine) {
await appLoader.execStartRoutines(); await appLoader.execStartRoutines();
if (routine) { if (routine) {
// 如果传入了routine执行完成后就结束 // 如果传入了routine执行完成后就结束
await appLoader.execRoutine(routine); const result = await appLoader.execRoutine(routine);
return; await appLoader.unmount();
return result;
} }
// 否则启动服务器模式 // 否则启动服务器模式
koa.use(async (ctx, next) => { koa.use(async (ctx, next) => {

View File

@ -94,7 +94,8 @@ function packageJsonContent({ name, version, description, cliName, cliBinName, i
"server:init": "${serverInitScript}", "server:init": "${serverInitScript}",
"server:start": "${serverStartWatchScript}", "server:start": "${serverStartWatchScript}",
"server:ana": "cross-env ENABLE_TRACE=true cross-env NODE_ENV=development cross-env OAK_PLATFORM=server node --stack-size=65500 scripts/analysis.js", "server:ana": "cross-env ENABLE_TRACE=true cross-env NODE_ENV=development cross-env OAK_PLATFORM=server node --stack-size=65500 scripts/analysis.js",
"postinstall": "npm run make:dep" "postinstall": "npm run make:dep",
"upgrade:locale": "node scripts/upgradeI18n.js"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",

6
lib/utils.d.ts vendored
View File

@ -64,3 +64,9 @@ export declare function deWeight(arr: Array<any> | Set<any>, type: any): Set<any
* @returns {string} * @returns {string}
*/ */
export declare function randomString(length: number): string; export declare function randomString(length: number): string;
/**
* @name nodejs运行时版本
* @export
* @throws
*/
export declare function checkNodeVersion(): void;

View File

@ -1,6 +1,8 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.randomString = exports.deWeight = exports.formatJsonByFile = exports.union = exports.intersect = exports.difference = exports.getStr = exports.findJson = void 0; exports.checkNodeVersion = exports.randomString = exports.deWeight = exports.formatJsonByFile = exports.union = exports.intersect = exports.difference = exports.getStr = exports.findJson = void 0;
const tslib_1 = require("tslib");
const chalk_1 = tslib_1.__importDefault(require("chalk"));
/** /**
* @name 从一组路径里查找到所有json文件 * @name 从一组路径里查找到所有json文件
* @export * @export
@ -113,3 +115,24 @@ function randomString(length) {
return result; return result;
} }
exports.randomString = randomString; exports.randomString = randomString;
/**
* @name 检查当前nodejs运行时版本
* @export
* @throws 当版本不满足最低要求时抛出异常
*/
function checkNodeVersion() {
const currentNodeVersion = process.versions.node;
const semver = currentNodeVersion.split('.');
const major = semver[0];
const minNodeVersion = 20;
if (Number(major) < minNodeVersion) {
console.error(chalk_1.default.yellow('You are running Node ' +
currentNodeVersion + '.\n') +
chalk_1.default.red('Oak-cli requires Node ' +
minNodeVersion +
' or higher. \n' +
'Please update your version of Node.'));
process.exit(-1);
}
}
exports.checkNodeVersion = checkNodeVersion;

View File

@ -1,6 +1,6 @@
{ {
"name": "@xuchangzju/oak-cli", "name": "@xuchangzju/oak-cli",
"version": "4.0.24", "version": "4.0.25",
"description": "client for oak framework", "description": "client for oak framework",
"main": "lib/index.js", "main": "lib/index.js",
"scripts": { "scripts": {
@ -60,7 +60,7 @@
"babel-loader": "^8.2.3", "babel-loader": "^8.2.3",
"babel-plugin-named-asset-import": "^0.3.8", "babel-plugin-named-asset-import": "^0.3.8",
"babel-preset-react-app": "^10.0.1", "babel-preset-react-app": "^10.0.1",
"bcrypt": "^5.1.1", "bcryptjs": "^3.0.2",
"bfj": "^7.0.2", "bfj": "^7.0.2",
"browser-assert": "^1.2.1", "browser-assert": "^1.2.1",
"browserify-sign": "4.2.2", "browserify-sign": "4.2.2",
@ -112,7 +112,7 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mini-css-extract-plugin": "^2.5.3", "mini-css-extract-plugin": "^2.5.3",
"node-watch": "^0.7.4", "node-watch": "^0.7.4",
"oak-backend-base": "^4.1.20", "oak-backend-base": "^4.1.21",
"oak-domain": "^5.1.27", "oak-domain": "^5.1.27",
"oak-frontend-base": "^5.3.34", "oak-frontend-base": "^5.3.34",
"parse-asn1": "5.1.6", "parse-asn1": "5.1.6",
@ -154,5 +154,9 @@
"webpack-manifest-plugin": "^4.0.2", "webpack-manifest-plugin": "^4.0.2",
"webpackbar": "^7.0.0", "webpackbar": "^7.0.0",
"workbox-webpack-plugin": "^6.4.1" "workbox-webpack-plugin": "^6.4.1"
},
"engines": {
"node": ">=20.0.0",
"npm": ">=10.0.0"
} }
} }

View File

@ -10,6 +10,7 @@ import clean from './clean';
import { CLI_VERSION, CLI_NAME } from './config'; import { CLI_VERSION, CLI_NAME } from './config';
import { error, warn } from './tip-style'; import { error, warn } from './tip-style';
import { rename } from './rename'; import { rename } from './rename';
import { checkNodeVersion } from './utils';
/** /**
* @name * @name
@ -28,23 +29,7 @@ function enhanceErrorMessages(methodName: string, log: Function) {
}; };
} }
const currentNodeVersion = process.versions.node; checkNodeVersion()
const semver = currentNodeVersion.split('.');
const major = semver[0];
const minNodeVersion = 16;
if (Number(major) < minNodeVersion) {
console.error(
'You are running Node ' +
currentNodeVersion +
'.\n' +
'Create React App requires Node ' +
minNodeVersion +
' or higher. \n' +
'Please update your version of Node.'
);
process.exit(-1);
}
program.version(CLI_VERSION, '-v, --version').usage('<command> [options]'); program.version(CLI_VERSION, '-v, --version').usage('<command> [options]');

View File

@ -23,9 +23,11 @@ import { instrument } from "@socket.io/admin-ui";
import serve from 'koa-static'; import serve from 'koa-static';
import mount from 'koa-mount'; import mount from 'koa-mount';
import chalk from 'chalk'; import chalk from 'chalk';
import { randomString } from '../utils'; import { checkNodeVersion, randomString } from '../utils';
import bcrypt from 'bcryptjs'; import bcrypt from 'bcryptjs';
checkNodeVersion()
const socketAdminUI = join(__dirname, '../../ui/socket-admin'); const socketAdminUI = join(__dirname, '../../ui/socket-admin');
const DATA_SUBSCRIBE_NAMESPACE = '/dsn'; const DATA_SUBSCRIBE_NAMESPACE = '/dsn';
@ -33,6 +35,7 @@ const SOCKET_NAMESPACE = '/sn';
const SERVER_SUBSCRIBER_NAMESPACE = process.env.OAK_SSUB_NAMESPACE || '/ssub'; const SERVER_SUBSCRIBER_NAMESPACE = process.env.OAK_SSUB_NAMESPACE || '/ssub';
const ExceptionMask = '内部不可知错误'; const ExceptionMask = '内部不可知错误';
function concat(...paths: string[]) { function concat(...paths: string[]) {
return paths.reduce( return paths.reduce(
(prev, current) => { (prev, current) => {
@ -50,7 +53,7 @@ export async function startup<ED extends EntityDict & BaseEntityDict, FrontCxt e
omitWatchers?: boolean, omitWatchers?: boolean,
omitTimers?: boolean, omitTimers?: boolean,
routine?: (context: AsyncContext<ED>) => Promise<void>, routine?: (context: AsyncContext<ED>) => Promise<void>,
): Promise<(() => Promise<void>) | undefined> { ): Promise<(() => Promise<any>) | any> {
const serverConfiguration: ServerConfiguration = require(join( const serverConfiguration: ServerConfiguration = require(join(
path, path,
'lib', 'lib',
@ -172,7 +175,7 @@ export async function startup<ED extends EntityDict & BaseEntityDict, FrontCxt e
auth: { auth: {
type: "basic", // 使用基本认证,生产建议关闭或换成自定义 auth type: "basic", // 使用基本认证,生产建议关闭或换成自定义 auth
username: ui?.username || "admin", username: ui?.username || "admin",
password: bcrypt.hashSync(passwordForAdminUI, 10), // 使用 bcrypt 加密密码 password: bcrypt.hashSync(passwordForAdminUI, 10), // 必须使用 bcrypt 加密之后的密码
}, },
mode: process.env.NODE_ENV === 'production' ? "production" : "development", // 根据环境设置模式 mode: process.env.NODE_ENV === 'production' ? "production" : "development", // 根据环境设置模式
}); });
@ -196,8 +199,9 @@ export async function startup<ED extends EntityDict & BaseEntityDict, FrontCxt e
await appLoader.execStartRoutines(); await appLoader.execStartRoutines();
if (routine) { if (routine) {
// 如果传入了routine执行完成后就结束 // 如果传入了routine执行完成后就结束
await appLoader.execRoutine(routine); const result = await appLoader.execRoutine(routine);
return; await appLoader.unmount();
return result;
} }
// 否则启动服务器模式 // 否则启动服务器模式

View File

@ -111,7 +111,8 @@ export function packageJsonContent({
"server:init": "${serverInitScript}", "server:init": "${serverInitScript}",
"server:start": "${serverStartWatchScript}", "server:start": "${serverStartWatchScript}",
"server:ana": "cross-env ENABLE_TRACE=true cross-env NODE_ENV=development cross-env OAK_PLATFORM=server node --stack-size=65500 scripts/analysis.js", "server:ana": "cross-env ENABLE_TRACE=true cross-env NODE_ENV=development cross-env OAK_PLATFORM=server node --stack-size=65500 scripts/analysis.js",
"postinstall": "npm run make:dep" "postinstall": "npm run make:dep",
"upgrade:locale": "node scripts/upgradeI18n.js"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",

View File

@ -1,4 +1,6 @@
import chalk from "chalk"
/** /**
* @name json文件 * @name json文件
* @export * @export
@ -111,4 +113,32 @@ export function randomString(length: number): string {
result += chars[randomIndex]; result += chars[randomIndex];
} }
return result; return result;
}
/**
* @name nodejs运行时版本
* @export
* @throws
*/
export function checkNodeVersion(){
const currentNodeVersion = process.versions.node;
const semver = currentNodeVersion.split('.');
const major = semver[0];
const minNodeVersion = 20;
if (Number(major) < minNodeVersion) {
console.error(
chalk.yellow(
'You are running Node ' +
currentNodeVersion + '.\n'
) +
chalk.red(
'Oak-cli requires Node ' +
minNodeVersion +
' or higher. \n' +
'Please update your version of Node.'
)
);
process.exit(-1);
}
} }

View File

@ -0,0 +1,12 @@
const { checkI18n, checkAndUpdateI18n } = require('oak-backend-base/lib/routines/i18n.js');
const { startup } = require('@xuchangzju/oak-cli/lib/server/start');
const simpleConnector = require('../lib/config/connector').default;
const pwd = process.cwd();
startup(pwd, simpleConnector, true, true, checkAndUpdateI18n)
.then(
(result) => {
process.exit(0);
}
);