feat: 升级midway,支持esm

This commit is contained in:
xiaojunnuo
2024-07-15 00:30:33 +08:00
parent 970c7fd8a0
commit 485e603b51
246 changed files with 3821 additions and 1532 deletions
+2 -1
View File
@@ -3,9 +3,10 @@
"module": "commonjs",
"lib": ["es6"],
"strict": true,
"noEmit": true,
"noEmit": false,
"esModuleInterop": true,
"baseUrl": ".",
"composite": true,
"paths": { "acme-client": ["."] }
}
}
+1 -1
View File
@@ -23,4 +23,4 @@ dist-ssr
*.sln
*.sw?
test/user.secret.ts
test/user.secret.*
+2
View File
@@ -0,0 +1,2 @@
link-workspace-packages=true
prefer-workspace-packages=true
@@ -0,0 +1,96 @@
import * as fs from "fs";
import * as path from "path";
// https://gist.github.com/lovasoa/8691344
async function* walk(dir) {
for await (const d of await fs.promises.opendir(dir)) {
const entry = path.join(dir, d.name);
if (d.isDirectory()) {
yield* walk(entry);
} else if (d.isFile()) {
yield entry;
}
}
}
function resolveImportPath(sourceFile, importPath, options) {
const sourceFileAbs = path.resolve(process.cwd(), sourceFile);
const root = path.dirname(sourceFileAbs);
const { moduleFilter = defaultModuleFilter } = options;
if (moduleFilter(importPath)) {
const importPathAbs = path.resolve(root, importPath);
let possiblePath = [path.resolve(importPathAbs, "./index.ts"), path.resolve(importPathAbs, "./index.js"), importPathAbs + ".ts", importPathAbs + ".js"];
if (possiblePath.length) {
for (let i = 0; i < possiblePath.length; i++) {
let entry = possiblePath[i];
if (fs.existsSync(entry)) {
const resolved = path.relative(root, entry.replace(/\.ts$/, ".js"));
if (!resolved.startsWith(".")) {
return "./" + resolved;
}
return resolved;
}
}
}
}
return null;
}
function replace(filePath, outFilePath, options) {
const code = fs.readFileSync(filePath).toString();
const newCode = code.replace(/(import|export) (.+?) from ('[^\n']+'|"[^\n"]+");/gs, function (found, action, imported, from) {
const importPath = from.slice(1, -1);
let resolvedPath = resolveImportPath(filePath, importPath, options);
if (resolvedPath) {
resolvedPath = resolvedPath.replaceAll("\\", "/");
console.log("\t", importPath, resolvedPath);
return `${action} ${imported} from "${resolvedPath}";`;
}
return found;
});
if (code !== newCode) {
fs.writeFileSync(outFilePath, newCode);
}
}
// Then, use it with a simple async for loop
async function run(srcDir, options = defaultOptions) {
const { sourceFileFilter = defaultSourceFileFilter } = options;
for await (const entry of walk(srcDir)) {
if (sourceFileFilter(entry)) {
console.log(entry);
replace(entry, entry, options);
}
}
}
const defaultSourceFileFilter = function (sourceFilePath) {
return /\.(js|ts)$/.test(sourceFilePath) && !/node_modules/.test(sourceFilePath);
};
const defaultModuleFilter = function (importedModule) {
return !path.isAbsolute(importedModule) && !importedModule.startsWith("@") && !importedModule.endsWith(".js");
};
const defaultOptions = {
sourceFileFilter: defaultSourceFileFilter,
moduleFilter: defaultModuleFilter,
};
// Switch this to test on one file or directly run on a directory.
const DEBUG = false;
if (DEBUG) {
replace("./src/index.ts", "./out.ts", defaultOptions);
} else {
await run("./src/", defaultOptions);
}
+9 -12
View File
@@ -2,22 +2,20 @@
"name": "@certd/pipeline",
"private": false,
"version": "1.21.0",
"main": "./src/index.ts",
"module": "./src/index.ts",
"types": "./src/index.ts",
"publishConfig": {
"main": "./dist/bundle.js",
"module": "./dist/bundle.mjs",
"types": "./dist/d/index.d.ts"
},
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"dev": "vite",
"build": "rollup -c",
"build": "tsc --skipLibCheck",
"build3": "rollup -c",
"build2": "vue-tsc --noEmit && vite build",
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.4.0",
"@types/lodash-es": "^4.17.12",
"axios": "^1.7.2",
"lodash-es": "^4.17.21",
"node-forge": "^1.3.1",
"nodemailer": "^6.9.3",
"qs": "^6.11.2"
@@ -30,7 +28,6 @@
"@rollup/plugin-terser": "^0.4.3",
"@rollup/plugin-typescript": "^11.0.0",
"@types/chai": "^4.3.5",
"@types/lodash": "^4.14.194",
"@types/mocha": "^10.0.1",
"@types/node-forge": "^1.3.2",
"@types/uuid": "^9.0.2",
@@ -43,7 +40,6 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.2.1",
"lodash": "^4.17.21",
"log4js": "^6.9.1",
"mocha": "^10.2.0",
"prettier": "^2.8.8",
@@ -52,6 +48,7 @@
"rollup-plugin-typescript2": "^0.34.1",
"rollup-plugin-visualizer": "^5.8.2",
"ts-node": "^10.9.1",
"tsc-esm-fix": "^3.0.0",
"tslib": "^2.5.2",
"typescript": "^5.0.4",
"vite": "^4.3.8",
+1 -1
View File
@@ -28,7 +28,7 @@ module.exports = {
],
external: [
"vue",
"lodash",
"lodash-es",
"dayjs",
"@certd/acme-client",
"@certd/pipeline",
+2 -2
View File
@@ -1,5 +1,5 @@
import { Registrable } from "../registry";
import { FormItemProps } from "../d.ts";
import { Registrable } from "../registry/index.js";
import { FormItemProps } from "../dt/index.js";
export type AccessInputDefine = FormItemProps & {
title: string;
@@ -1,8 +1,8 @@
// src/decorator/memoryCache.decorator.ts
import { AccessDefine, AccessInputDefine } from "./api";
import { Decorator } from "../decorator";
import _ from "lodash";
import { accessRegistry } from "./registry";
import { AccessDefine, AccessInputDefine } from "./api.js";
import { Decorator } from "../decorator/index.js";
import _ from "lodash-es";
import { accessRegistry } from "./registry.js";
// 提供一个唯一 key
export const ACCESS_CLASS_KEY = "pipeline:access";
+3 -3
View File
@@ -1,3 +1,3 @@
export * from "./api";
export * from "./registry";
export * from "./decorator";
export * from "./api.js";
export * from "./registry.js";
export * from "./decorator.js";
@@ -1,4 +1,4 @@
import { Registry } from "../registry";
import { Registry } from "../registry/index.js";
// @ts-ignore
export const accessRegistry = new Registry("access");
+1 -1
View File
@@ -1,5 +1,5 @@
import { AxiosInstance } from "axios";
import { IContext } from "../core";
import { IContext } from "../core/index.js";
export type HttpClient = AxiosInstance;
export type UserContext = IContext;
+1 -1
View File
@@ -1,4 +1,4 @@
import { IStorage, MemoryStorage } from "./storage";
import { IStorage, MemoryStorage } from "./storage.js";
const CONTEXT_VERSION_KEY = "contextVersion";
export interface IContext {
getInt(key: string): Promise<number>;
+31 -24
View File
@@ -1,18 +1,18 @@
import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../d.ts";
import _ from "lodash";
import { RunHistory, RunnableCollection } from "./run-history";
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext } from "../plugin";
import { ContextFactory, IContext } from "./context";
import { IStorage } from "./storage";
import { logger } from "../utils/util.log";
import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../dt/index.js";
import _ from "lodash-es";
import { RunHistory, RunnableCollection } from "./run-history.js";
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext } from "../plugin/index.js";
import { ContextFactory, IContext } from "./context.js";
import { IStorage } from "./storage.js";
import { logger } from "../utils/util.log.js";
import { Logger } from "log4js";
import { createAxiosService } from "../utils/util.request";
import { IAccessService } from "../access";
import { RegistryItem } from "../registry";
import { Decorator } from "../decorator";
import { IEmailService } from "../service";
import { FileStore } from "./file-store";
import { TimeoutPromise } from "../utils/util.promise";
import { createAxiosService } from "../utils/util.request.js";
import { IAccessService } from "../access/index.js";
import { RegistryItem } from "../registry/index.js";
import { Decorator } from "../decorator/index.js";
import { IEmailService } from "../service/index.js";
import { FileStore } from "./file-store.js";
// import { TimeoutPromise } from "../utils/util.promise.js";
export type ExecutorOptions = {
userId: any;
@@ -33,7 +33,7 @@ export class Executor {
lastRuntime!: RunHistory;
options: ExecutorOptions;
canceled = false;
onChanged: (history: RunHistory) => void;
onChanged: (history: RunHistory) => Promise<void>;
constructor(options: ExecutorOptions) {
this.options = options;
this.pipeline = _.cloneDeep(options.pipeline);
@@ -110,12 +110,13 @@ export class Executor {
const intervalFlushLogId = setInterval(async () => {
await this.onChanged(this.runtime);
}, 5000);
const timeout = runnable.timeout ?? 20 * 60 * 1000;
// const timeout = runnable.timeout ?? 20 * 60 * 1000;
try {
if (this.canceled) {
throw new Error("task canceled");
return ResultType.canceled;
}
await TimeoutPromise(run, timeout);
await run();
this.runtime.success(runnable);
return ResultType.success;
} catch (e: any) {
@@ -142,19 +143,25 @@ export class Executor {
async runStage(stage: Stage) {
const runnerList = [];
for (const task of stage.tasks) {
const runner = this.runWithHistory(task, "task", async () => {
await this.runTask(task);
});
const runner = async () => {
return this.runWithHistory(task, "task", async () => {
await this.runTask(task);
});
};
runnerList.push(runner);
}
let resList: ResultType[] = [];
if (stage.concurrency === ConcurrencyStrategy.Parallel) {
resList = await Promise.all(runnerList);
const pList = [];
for (const item of runnerList) {
pList.push(item());
}
resList = await Promise.all(pList);
} else {
for (let i = 0; i < runnerList.length; i++) {
const runner = runnerList[i];
resList[i] = await runner;
resList[i] = await runner();
}
}
return this.compositionResultType(resList);
@@ -239,7 +246,7 @@ export class Executor {
this.lastStatusMap.clear();
}
//输出到output context
_.forEach(define.output, (item, key) => {
_.forEach(define.output, (item: any, key: any) => {
step.status!.output[key] = instance[key];
const stepOutputKey = `step.${step.id}.${key}`;
this.runtime.context[stepOutputKey] = instance[key];
@@ -1,8 +1,8 @@
import { fileUtils } from "../utils";
import { fileUtils } from "../utils/index.js";
import dayjs from "dayjs";
import path from "path";
import fs from "fs";
import { logger } from "../utils";
import { logger } from "../utils/index.js";
export type FileStoreOptions = {
rootDir?: string;
+5 -5
View File
@@ -1,5 +1,5 @@
export * from "./executor";
export * from "./run-history";
export * from "./context";
export * from "./storage";
export * from "./file-store";
export * from "./executor.js";
export * from "./run-history.js";
export * from "./context.js";
export * from "./storage.js";
export * from "./file-store.js";
@@ -1,6 +1,6 @@
import { Context, HistoryResult, Pipeline, ResultType, Runnable, RunnableMap, Stage, Step, Task } from "../d.ts";
import _ from "lodash";
import { buildLogger } from "../utils/util.log";
import { Context, HistoryResult, Pipeline, ResultType, Runnable, RunnableMap, Stage, Step, Task } from "../dt/index.js";
import _ from "lodash-es";
import { buildLogger } from "../utils/util.log.js";
import { Logger } from "log4js";
export type HistoryStatus = {
+1 -1
View File
@@ -1,6 +1,6 @@
import fs from "fs";
import path from "path";
import { fileUtils } from "../utils/util.file";
import { fileUtils } from "../utils/util.file.js";
export interface IStorage {
get(scope: string, namespace: string, version: string, key: string): Promise<string | null>;
@@ -70,6 +70,7 @@ export type Runnable = {
default?: {
[key: string]: any;
};
context?: Context;
};
export type EmailOptions = {
@@ -1,4 +1,4 @@
import { Decorator } from "./index";
import { Decorator } from "./index.js";
export type AutowireProp = {
name?: string;
@@ -1,2 +1,2 @@
export * from "./utils";
export * from "./common";
export * from "./utils.js";
export * from "./common.js";
@@ -1,4 +1,4 @@
import _ from "lodash";
import _ from "lodash-es";
const propertyMap: any = {};
function attachProperty(target: any, propertyKey: string | symbol) {
@@ -25,7 +25,7 @@ function target(target: any, propertyKey?: string | symbol) {
}
function inject(define: any, instance: any, context: any, preHandler?: (item: any, key: string, instance: any, context: any) => void) {
_.forEach(define, (item, key) => {
_.forEach(define, (item: any, key: any) => {
if (preHandler) {
preHandler(item, key, instance, context);
}
+115
View File
@@ -0,0 +1,115 @@
/**
* [x]-col的配置
*/
export type ColProps = {
span?: number;
[props: string]: any;
};
export type FormItemProps = {
/**
* 字段label
*/
title?: string;
/**
* 表单字段组件配置
*/
component?: ComponentProps;
/**
* 表单字段 [a|el|n]-col的配置
* 一般用来配置跨列:{span:24} 占满一行
*/
col?: ColProps;
/**
* 默认值
*/
value?: any;
/**
* 帮助提示配置
*/
helper?: string | FormItemHelperProps;
/**
* 排序号
*/
order?: number;
/**
* 是否显示此字段
*/
show?: boolean;
/**
* 是否是空白占位栏
*/
blank?: boolean;
[key: string]: any;
};
/**
* 表单字段帮助说明配置
*/
export type FormItemHelperProps = {
/**
* 自定义渲染帮助说明
* @param scope
*/
render?: (scope: any) => any;
/**
* 帮助文本
*/
text?: string;
/**
* 帮助说明所在的位置,[ undefined | label]
*/
position?: string;
/**
* [a|el|n]-tooltip配置
*/
tooltip?: object;
[key: string]: any;
};
/**
* 组件配置
*/
export type ComponentProps = {
/**
* 组件的名称
*/
name?: string | object;
/**
* vmodel绑定的目标属性名
*/
vModel?: string;
/**
* 当原始组件名的参数被以上属性名占用时,可以配置在这里
* 例如:原始组件有一个叫name的属性,你想要配置它,则可以按如下配置
* ```
* component:{
* name:"组件的名称"
* props:{
* name:"组件的name属性" <-----------
* }
* }
* ```
*/
props?: {
[key: string]: any;
};
/**
* 组件事件监听
*/
on?: {
[key: string]: (context?: any) => void;
};
/**
* 组件其他参数
* 事件:onXxx:(event)=>void 组件原始事件监听
* on.onXxx:(context)=>void 组件事件监听(对原始事件包装)
* 样式:style、class等
*/
[key: string]: any;
};
+2
View File
@@ -0,0 +1,2 @@
export * from "./pipeline.js";
export * from "./fast-crud.js";
+139
View File
@@ -0,0 +1,139 @@
export enum RunStrategy {
AlwaysRun,
SkipWhenSucceed,
}
export enum ConcurrencyStrategy {
Serial,
Parallel,
}
export enum NextStrategy {
AllSuccess,
OneSuccess,
}
export enum HandlerType {
//清空后续任务的状态
ClearFollowStatus,
SendEmail,
}
export type EventHandler = {
type: HandlerType;
params: {
[key: string]: any;
};
};
export type RunnableStrategy = {
runStrategy?: RunStrategy;
onSuccess?: EventHandler[];
onError?: EventHandler[];
};
export type Step = Runnable & {
type: string; //插件类型
input: {
[key: string]: any;
};
};
export type Task = Runnable & {
steps: Step[];
};
export type Stage = Runnable & {
tasks: Task[];
concurrency: ConcurrencyStrategy;
next: NextStrategy;
};
export type Trigger = {
id: string;
title: string;
cron: string;
type: string;
};
export type FileItem = {
id: string;
filename: string;
path: string;
};
export type Runnable = {
id: string;
title: string;
strategy?: RunnableStrategy;
runnableType?: string; // pipeline, stage, task , step
status?: HistoryResult;
timeout?: number;
default?: {
[key: string]: any;
};
};
export type EmailOptions = {
receivers: string[];
};
export type NotificationWhen = "error" | "success" | "turnToSuccess" | "start";
export type NotificationType = "email" | "url";
export type Notification = {
type: NotificationType;
when: NotificationWhen[];
options: EmailOptions;
};
export type Pipeline = Runnable & {
version?: number;
userId: any;
stages: Stage[];
triggers: Trigger[];
notifications?: Notification[];
};
export type Context = {
[key: string]: any;
};
export type Log = {
title: string;
time: number;
level: string;
text: string;
};
export enum ResultType {
start = "start",
success = "success",
error = "error",
canceled = "canceled",
skip = "skip",
none = "none",
}
export type HistoryResultGroup = {
[key: string]: {
runnable: Runnable;
res: HistoryResult;
};
};
export type HistoryResult = {
input: any;
output: any;
files?: FileItem[];
/**
* 任务状态
*/
status: ResultType;
startTime: number;
endTime?: number;
/**
* 处理结果
*/
result?: ResultType; //success, error,skip
message?: string;
};
export type RunnableMap = {
[id: string]: Runnable;
};
+9 -9
View File
@@ -1,10 +1,10 @@
import "util";
export * from "./core";
export * from "./d.ts";
export * from "./access";
export * from "./registry";
export * from "./plugin";
export * from "./utils";
export * from "./context";
export * from "./decorator";
export * from "./service";
export * from "./core/index.js";
export * from "./dt/index.js";
export * from "./access/index.js";
export * from "./registry/index.js";
export * from "./plugin/index.js";
export * from "./utils/index.js";
export * from "./context/index.js";
export * from "./decorator/index.js";
export * from "./service/index.js";
+16 -9
View File
@@ -1,12 +1,12 @@
import { Registrable } from "../registry";
import { FileItem, FormItemProps, Pipeline, Runnable, Step } from "../d.ts";
import { FileStore } from "../core/file-store";
import { Registrable } from "../registry/index.js";
import { FileItem, FormItemProps, Pipeline, Runnable, Step } from "../dt/index.js";
import { FileStore } from "../core/file-store.js";
import { Logger } from "log4js";
import { IAccessService } from "../access";
import { IEmailService } from "../service";
import { IContext } from "../core";
import { IAccessService } from "../access/index.js";
import { IEmailService } from "../service/index.js";
import { IContext } from "../core/index.js";
import { AxiosInstance } from "axios";
import { logger } from "../utils";
import { logger } from "../utils/index.js";
export enum ContextScope {
global,
@@ -83,7 +83,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
return Math.random().toString(36).substring(2, 9);
}
linkFile(file: FileItem) {
this._result.files!.push({
this._result.files?.push({
...file,
id: this.randomFileId(),
});
@@ -91,13 +91,20 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
saveFile(filename: string, file: Buffer) {
const filePath = this.ctx.fileStore.writeFile(filename, file);
logger.info(`saveFile:${filePath}`);
this._result.files!.push({
this._result.files?.push({
id: this.randomFileId(),
filename,
path: filePath,
});
}
extendsFiles() {
if (this._result.files == null) {
this._result.files = [];
}
this._result.files.push(...(this.ctx.lastStatus?.status?.files || []));
}
get pipeline() {
return this.ctx.pipeline;
}
@@ -1,8 +1,8 @@
import _ from "lodash";
import { pluginRegistry } from "./registry";
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api";
import { Decorator } from "../decorator";
import { AUTOWIRE_KEY } from "../decorator";
import _ from "lodash-es";
import { pluginRegistry } from "./registry.js";
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api.js";
import { Decorator } from "../decorator/index.js";
import { AUTOWIRE_KEY } from "../decorator/index.js";
import "reflect-metadata";
// 提供一个唯一 key
export const PLUGIN_CLASS_KEY = "pipeline:plugin";
+3 -3
View File
@@ -1,3 +1,3 @@
export * from "./api";
export * from "./registry";
export * from "./decorator";
export * from "./api.js";
export * from "./registry.js";
export * from "./decorator.js";
@@ -1,4 +1,4 @@
import { Registry } from "../registry";
import { AbstractTaskPlugin } from "./api";
import { Registry } from "../registry/index.js";
import { AbstractTaskPlugin } from "./api.js";
export const pluginRegistry = new Registry<AbstractTaskPlugin>("plugin");
@@ -1,6 +1,5 @@
import { ITaskPlugin } from "../api";
import { IsTaskPlugin, TaskInput } from "../decorator";
import { Autowire } from "../../decorator";
import { ITaskPlugin } from "../api.js";
import { IsTaskPlugin, TaskInput } from "../decorator.js";
@IsTaskPlugin({
name: "EchoPlugin",
+1 -1
View File
@@ -1 +1 @@
export * from "./registry";
export * from "./registry.js";
@@ -1,4 +1,4 @@
import { logger } from "../utils";
import { logger } from "../utils/index.js";
export type Registrable = {
name: string;
+1 -1
View File
@@ -1 +1 @@
export * from "./email";
export * from "./email.js";
+4 -4
View File
@@ -1,7 +1,7 @@
import sleep from "./util.sleep";
import { request } from "./util.request";
export * from "./util.log";
export * from "./util.file";
import sleep from "./util.sleep.js";
import { request } from "./util.request.js";
export * from "./util.log.js";
export * from "./util.file.js";
export const utils = {
sleep,
http: request,
@@ -1,7 +1,7 @@
import axios from "axios";
// @ts-ignore
import qs from "qs";
import { logger } from "./util.log";
import { logger } from "./util.log.js";
import { Logger } from "log4js";
/**
* @description 创建请求实例
+33 -15
View File
@@ -1,23 +1,41 @@
{
"compileOnSave": true,
"compilerOptions": {
"importHelpers": false,
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"isolatedModules": true,
"moduleResolution": "node",
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
"skipLibCheck": true,
"experimentalDecorators": true,
"paths": {
"tslib" : ["./node_modules/tslib/tslib.d.ts"]
}
"emitDecoratorMetadata": true,
"inlineSourceMap":true,
"noImplicitThis": true,
"noUnusedLocals": true,
"stripInternal": true,
"skipLibCheck": true,
"pretty": true,
"declaration": true,
"forceConsistentCasingInFileNames": true,
"typeRoots": [ "./typings", "./node_modules/@types"],
"outDir": "dist",
"rootDir": "src",
"composite": true,
"useDefineForClassFields": true,
"strict": true,
// "sourceMap": true,
"resolveJsonModule": true,
"isolatedModules": false,
"lib": ["ESNext", "DOM"],
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue","test/**/*.ts","rollup.config.ts"],
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.json"
],
"exclude": [
"*.js",
"*.ts",
"dist",
"node_modules",
"test"
],
}
+1 -1
View File
@@ -24,7 +24,7 @@ export default defineConfig({
],
external: [
"vue",
"lodash",
"lodash-es",
"dayjs",
"@certd/acme-client",
"@certd/plugin-cert",