@rainbow-o23/n1 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +11 -0
- package/.eslintrc +23 -0
- package/README.md +233 -0
- package/index.cjs +760 -0
- package/index.d.ts +3 -0
- package/index.js +732 -0
- package/lib/pipeline/envs.d.ts +1 -0
- package/lib/pipeline/index.d.ts +6 -0
- package/lib/pipeline/pipeline-execution.d.ts +38 -0
- package/lib/pipeline/pipeline-step.d.ts +41 -0
- package/lib/pipeline/pipeline.d.ts +47 -0
- package/lib/pipeline/step-helpers-utils.d.ts +41 -0
- package/lib/pipeline/step-helpers.d.ts +31 -0
- package/lib/repo/index.d.ts +1 -0
- package/lib/repo/pipeline-repository.d.ts +11 -0
- package/lib/utils/config.d.ts +16 -0
- package/lib/utils/error.d.ts +21 -0
- package/lib/utils/index.d.ts +4 -0
- package/lib/utils/logger.d.ts +50 -0
- package/lib/utils/types.d.ts +7 -0
- package/package.json +41 -0
- package/rollup.config.base.js +30 -0
- package/rollup.config.ci.js +3 -0
- package/rollup.config.js +3 -0
- package/src/index.ts +4 -0
- package/src/lib/pipeline/envs.ts +20 -0
- package/src/lib/pipeline/index.ts +7 -0
- package/src/lib/pipeline/pipeline-execution.ts +137 -0
- package/src/lib/pipeline/pipeline-step.ts +79 -0
- package/src/lib/pipeline/pipeline.ts +148 -0
- package/src/lib/pipeline/step-helpers-utils.ts +143 -0
- package/src/lib/pipeline/step-helpers.ts +77 -0
- package/src/lib/repo/index.ts +1 -0
- package/src/lib/repo/pipeline-repository.ts +53 -0
- package/src/lib/utils/config.ts +110 -0
- package/src/lib/utils/error.ts +41 -0
- package/src/lib/utils/index.ts +6 -0
- package/src/lib/utils/logger.ts +292 -0
- package/src/lib/utils/types.ts +11 -0
- package/tsconfig.json +36 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Config, Logger } from '../utils';
|
|
2
|
+
import { PipelineOptions } from './pipeline';
|
|
3
|
+
import { PipelineStep, PipelineStepData } from './pipeline-step';
|
|
4
|
+
export interface PerformanceExecutionOptions {
|
|
5
|
+
exec: 'PIPELINE' | 'STEP';
|
|
6
|
+
traceId: string;
|
|
7
|
+
start: bigint;
|
|
8
|
+
print: (message: () => any) => void;
|
|
9
|
+
}
|
|
10
|
+
export type MeasuredFunction<T> = () => Promise<T>;
|
|
11
|
+
export declare class PerformanceExecution {
|
|
12
|
+
private readonly options;
|
|
13
|
+
constructor(options: PerformanceExecutionOptions);
|
|
14
|
+
execute<T>(measured: MeasuredFunction<T>): Promise<T>;
|
|
15
|
+
}
|
|
16
|
+
export interface PipelineExecutionOptions {
|
|
17
|
+
config?: Config;
|
|
18
|
+
logger?: Logger;
|
|
19
|
+
}
|
|
20
|
+
export declare class AbstractPipelineExecution {
|
|
21
|
+
protected readonly _config: Config;
|
|
22
|
+
protected readonly _logger: Logger;
|
|
23
|
+
protected readonly _performanceLogEnabled: boolean;
|
|
24
|
+
protected readonly _debugLogEnabled: boolean;
|
|
25
|
+
constructor(options?: PipelineOptions);
|
|
26
|
+
getConfig(): Config;
|
|
27
|
+
getLogger(): Logger;
|
|
28
|
+
protected isDebugLogEnabled(): boolean;
|
|
29
|
+
protected debug(message: any, ...optionsParams: Array<any>): void;
|
|
30
|
+
protected traceRequest<T>(traceId: string, data: T): T;
|
|
31
|
+
protected traceResponse<T>(traceId: string, data: T): T;
|
|
32
|
+
protected traceStepIn(traceId: string, step: PipelineStep, data: any): void;
|
|
33
|
+
protected traceStepOut(traceId: string, step: PipelineStep, data: any): void;
|
|
34
|
+
protected isPerformanceLogEnabled(): boolean;
|
|
35
|
+
protected debugPerformance(message: () => any): void;
|
|
36
|
+
protected measurePerformance(traceId: string, exec: 'PIPELINE' | 'STEP'): PerformanceExecution;
|
|
37
|
+
protected returnOrContinueOrClear(request: PipelineStepData, response: PipelineStepData): PipelineStepData;
|
|
38
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Config, Logger } from '../utils';
|
|
2
|
+
import { AbstractPipelineExecution, PipelineExecutionOptions } from './pipeline-execution';
|
|
3
|
+
import { PipelineStepHelpers } from './step-helpers';
|
|
4
|
+
export type PipelineStepCode = string;
|
|
5
|
+
export type PipelineStepPayload = any;
|
|
6
|
+
export interface PipelineStepContext {
|
|
7
|
+
traceId?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface PipelineStepData<C = PipelineStepPayload, CTX = PipelineStepContext> {
|
|
10
|
+
$context?: CTX;
|
|
11
|
+
content: C;
|
|
12
|
+
}
|
|
13
|
+
export interface PipelineStep<In = any, Out = any> {
|
|
14
|
+
getName(): string;
|
|
15
|
+
perform(request: PipelineStepData<In>): Promise<PipelineStepData<Out>>;
|
|
16
|
+
}
|
|
17
|
+
export interface PipelineStepOptions extends PipelineExecutionOptions {
|
|
18
|
+
name?: string;
|
|
19
|
+
config?: Config;
|
|
20
|
+
logger?: Logger;
|
|
21
|
+
}
|
|
22
|
+
export interface PipelineStepType<S = PipelineStep> extends Function {
|
|
23
|
+
new (options?: PipelineStepOptions): S;
|
|
24
|
+
}
|
|
25
|
+
export declare abstract class AbstractPipelineStep<In = PipelineStepPayload, Out = PipelineStepPayload> extends AbstractPipelineExecution implements PipelineStep<In, Out> {
|
|
26
|
+
private _$helpers;
|
|
27
|
+
protected readonly _name?: string;
|
|
28
|
+
constructor(options?: PipelineStepOptions);
|
|
29
|
+
getName(): string;
|
|
30
|
+
getHelpers(): PipelineStepHelpers;
|
|
31
|
+
protected getHelpersVariableNames(): Array<string>;
|
|
32
|
+
abstract perform(request: PipelineStepData<In>): Promise<PipelineStepData<Out>>;
|
|
33
|
+
}
|
|
34
|
+
export interface PipelineStepBuilder {
|
|
35
|
+
create(options?: PipelineStepOptions): Promise<PipelineStep>;
|
|
36
|
+
}
|
|
37
|
+
export declare class DefaultPipelineStepBuilder implements PipelineStepBuilder {
|
|
38
|
+
protected readonly step: PipelineStepType;
|
|
39
|
+
constructor(step: PipelineStepType);
|
|
40
|
+
create(options?: PipelineStepOptions): Promise<PipelineStep>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Config, Logger } from '../utils';
|
|
2
|
+
import { AbstractPipelineExecution, PipelineExecutionOptions } from './pipeline-execution';
|
|
3
|
+
import { PipelineStep, PipelineStepBuilder, PipelineStepData, PipelineStepOptions, PipelineStepType } from './pipeline-step';
|
|
4
|
+
export type PipelineRequestPayload = any;
|
|
5
|
+
export interface PipelineRequest<C = PipelineRequestPayload> {
|
|
6
|
+
payload: C;
|
|
7
|
+
traceId?: string;
|
|
8
|
+
}
|
|
9
|
+
export type PipelineResponsePayload = any;
|
|
10
|
+
export interface PipelineResponse<C = PipelineResponsePayload> {
|
|
11
|
+
payload: C;
|
|
12
|
+
}
|
|
13
|
+
export type PipelineCode = string;
|
|
14
|
+
export interface Pipeline<In = any, Out = any> {
|
|
15
|
+
getCode(): PipelineCode;
|
|
16
|
+
perform(request: PipelineRequest<In>): Promise<PipelineResponse<Out>>;
|
|
17
|
+
}
|
|
18
|
+
export interface PipelineOptions extends PipelineExecutionOptions {
|
|
19
|
+
config?: Config;
|
|
20
|
+
logger?: Logger;
|
|
21
|
+
}
|
|
22
|
+
export interface PipelineType<P = Pipeline> extends Function {
|
|
23
|
+
new (options?: PipelineOptions): P;
|
|
24
|
+
}
|
|
25
|
+
export declare abstract class AbstractPipeline<In = any, Out = any> extends AbstractPipelineExecution implements Pipeline<In, Out> {
|
|
26
|
+
constructor(options?: PipelineOptions);
|
|
27
|
+
abstract getCode(): PipelineCode;
|
|
28
|
+
protected abstract getStepBuilders(): Array<PipelineStepBuilder>;
|
|
29
|
+
protected buildStepOptions(): Pick<PipelineStepOptions, 'config' | 'logger'>;
|
|
30
|
+
createSteps(): Promise<Array<PipelineStep>>;
|
|
31
|
+
convertRequestToPipelineData<I, FirstStepIn>(request: PipelineRequest<I>): PipelineStepData<FirstStepIn>;
|
|
32
|
+
convertPipelineDataToResponse<LastStepOut, O>(result: PipelineStepData<LastStepOut>): PipelineResponse<O>;
|
|
33
|
+
protected createTraceId(request: PipelineRequest<In>): string;
|
|
34
|
+
perform(request: PipelineRequest<In>): Promise<PipelineResponse<Out>>;
|
|
35
|
+
}
|
|
36
|
+
export declare abstract class AbstractStaticPipeline<In = any, Out = any> extends AbstractPipeline<In, Out> {
|
|
37
|
+
protected abstract getStepTypes(): Array<PipelineStepType>;
|
|
38
|
+
protected getStepBuilders(): Array<PipelineStepBuilder>;
|
|
39
|
+
}
|
|
40
|
+
export interface PipelineBuilder {
|
|
41
|
+
create(options?: PipelineOptions): Promise<Pipeline>;
|
|
42
|
+
}
|
|
43
|
+
export declare class DefaultPipelineBuilder implements PipelineBuilder {
|
|
44
|
+
protected readonly pipeline: PipelineType;
|
|
45
|
+
constructor(pipeline: PipelineType);
|
|
46
|
+
create(options?: PipelineOptions): Promise<Pipeline>;
|
|
47
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { PipelineStepHelpers } from './index';
|
|
3
|
+
export interface PipelineStepErrorOptions {
|
|
4
|
+
status: number;
|
|
5
|
+
code: string;
|
|
6
|
+
reason: string;
|
|
7
|
+
}
|
|
8
|
+
export interface PipelineStepFileOptions {
|
|
9
|
+
name?: string;
|
|
10
|
+
type?: string;
|
|
11
|
+
content: string | Buffer;
|
|
12
|
+
}
|
|
13
|
+
export declare const PIPELINE_STEP_FILE_SYMBOL: unique symbol;
|
|
14
|
+
export declare const PIPELINE_STEP_RETURN_NULL: unique symbol;
|
|
15
|
+
export interface PipelineStepFile {
|
|
16
|
+
$file: typeof PIPELINE_STEP_FILE_SYMBOL;
|
|
17
|
+
name?: string;
|
|
18
|
+
type?: string;
|
|
19
|
+
content: Buffer;
|
|
20
|
+
}
|
|
21
|
+
export declare class StepHelpersUtils {
|
|
22
|
+
private static asciiNanoId;
|
|
23
|
+
private static OBJECT_PROTOTYPE;
|
|
24
|
+
private constructor();
|
|
25
|
+
static $nano(size?: number): string;
|
|
26
|
+
static $ascii(size?: number): string;
|
|
27
|
+
static createCatchableError: (options: Omit<PipelineStepErrorOptions, 'status'>) => never;
|
|
28
|
+
static createExposedUncatchableError: (options: PipelineStepErrorOptions) => never;
|
|
29
|
+
static createUncatchableError: (options: Omit<PipelineStepErrorOptions, 'status'>) => never;
|
|
30
|
+
static readonly $errors: PipelineStepHelpers['$errors'];
|
|
31
|
+
static createFile(options: PipelineStepFileOptions): PipelineStepFile;
|
|
32
|
+
static $clearContextData(): typeof PIPELINE_STEP_RETURN_NULL;
|
|
33
|
+
static isPrototype(value: any): boolean;
|
|
34
|
+
static isLength(value: any): boolean;
|
|
35
|
+
static isArrayLike(value: any): boolean;
|
|
36
|
+
static isEmpty(value: any): boolean;
|
|
37
|
+
static isNotEmpty(value: any): boolean;
|
|
38
|
+
static isBlank(value: any): boolean;
|
|
39
|
+
static isNotBlank(value: any): boolean;
|
|
40
|
+
static trim(value: any): string;
|
|
41
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import { Config, DateTime, Logger } from '../utils';
|
|
3
|
+
import { PIPELINE_STEP_RETURN_NULL, PipelineStepErrorOptions, PipelineStepFile, PipelineStepFileOptions } from './step-helpers-utils';
|
|
4
|
+
export declare class PipelineStepDateHelper {
|
|
5
|
+
private readonly _dateTimeFormat;
|
|
6
|
+
constructor(config: Config);
|
|
7
|
+
getDateTimeFormat(): string;
|
|
8
|
+
now(): DateTime;
|
|
9
|
+
get dayjs(): typeof dayjs;
|
|
10
|
+
}
|
|
11
|
+
export interface PipelineStepHelpers {
|
|
12
|
+
$config?: Config;
|
|
13
|
+
$logger?: Logger;
|
|
14
|
+
$date: PipelineStepDateHelper;
|
|
15
|
+
$nano: (size?: number) => string;
|
|
16
|
+
$ascii: (size?: number) => string;
|
|
17
|
+
$error: (options: PipelineStepErrorOptions) => never;
|
|
18
|
+
$errors: {
|
|
19
|
+
catchable: (options: Omit<PipelineStepErrorOptions, 'status'>) => never;
|
|
20
|
+
exposed: (options: PipelineStepErrorOptions) => never;
|
|
21
|
+
uncatchable: (options: Omit<PipelineStepErrorOptions, 'status'>) => never;
|
|
22
|
+
};
|
|
23
|
+
$file: (options: PipelineStepFileOptions) => PipelineStepFile;
|
|
24
|
+
$clearContextData: () => typeof PIPELINE_STEP_RETURN_NULL;
|
|
25
|
+
isEmpty: (value: any) => boolean;
|
|
26
|
+
isNotEmpty: (value: any) => boolean;
|
|
27
|
+
isBlank: (value: any) => boolean;
|
|
28
|
+
isNotBlank: (value: any) => boolean;
|
|
29
|
+
trim: (value: any) => string;
|
|
30
|
+
}
|
|
31
|
+
export declare const createStepHelpers: (config: Config, logger: Logger) => PipelineStepHelpers;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './pipeline-repository';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Pipeline, PipelineBuilder, PipelineCode, PipelineOptions, PipelineStepBuilder, PipelineStepCode } from '../pipeline';
|
|
2
|
+
import { Undefinable } from '../utils';
|
|
3
|
+
export declare class PipelineRepository {
|
|
4
|
+
private static readonly PIPELINE_BUILDERS;
|
|
5
|
+
private static readonly STEP_BUILDERS;
|
|
6
|
+
private constructor();
|
|
7
|
+
static findPipeline(code: PipelineCode, options: PipelineOptions): Promise<Undefinable<Pipeline>>;
|
|
8
|
+
static putPipeline(builders: Record<PipelineCode, PipelineBuilder>): Record<PipelineCode, PipelineBuilder>;
|
|
9
|
+
static findStep(code: PipelineStepCode): Promise<Undefinable<PipelineStepBuilder>>;
|
|
10
|
+
static putStep(builders: Record<PipelineStepCode, PipelineStepBuilder>): Record<PipelineStepCode, PipelineStepBuilder>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Logger } from './logger';
|
|
2
|
+
import { Undefinable } from './types';
|
|
3
|
+
export declare class Config {
|
|
4
|
+
private _logger;
|
|
5
|
+
private valueCache;
|
|
6
|
+
constructor(_logger: Logger);
|
|
7
|
+
getLogger(): Logger;
|
|
8
|
+
setLogger(value: Logger): void;
|
|
9
|
+
protected generateKey(name: string): string;
|
|
10
|
+
protected getFromCache<T>(name: string, read: () => Undefinable<T>, defaultValue?: T): Undefinable<T>;
|
|
11
|
+
getString(name: string, defaultValue?: string): Undefinable<string>;
|
|
12
|
+
getBoolean(name: string, defaultValue?: boolean): Undefinable<boolean>;
|
|
13
|
+
getNumber(name: string, defaultValue?: number): Undefinable<number>;
|
|
14
|
+
getJson(name: string, defaultValue?: any): Undefinable<any>;
|
|
15
|
+
}
|
|
16
|
+
export declare const createConfig: (logger?: Logger) => Config;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type O23ReservedErrorCode = `O${number}-${number}`;
|
|
2
|
+
export type O23ExternalErrorCode = `O${Uppercase<string>}-${number}`;
|
|
3
|
+
export type O23ErrorCode = O23ReservedErrorCode | O23ExternalErrorCode;
|
|
4
|
+
export declare const ERR_PIPELINE_NOT_FOUND: O23ReservedErrorCode;
|
|
5
|
+
export declare const ERR_TRIM_NON_STRING: O23ReservedErrorCode;
|
|
6
|
+
export declare const ERR_UNKNOWN: O23ReservedErrorCode;
|
|
7
|
+
export declare class CatchableError extends Error {
|
|
8
|
+
private readonly _code;
|
|
9
|
+
constructor(_code: string, message: string);
|
|
10
|
+
getCode(): string;
|
|
11
|
+
}
|
|
12
|
+
export declare class UncatchableError extends Error {
|
|
13
|
+
private readonly _code;
|
|
14
|
+
constructor(_code: string, message: string);
|
|
15
|
+
getCode(): string;
|
|
16
|
+
}
|
|
17
|
+
export declare class ExposedUncatchableError extends UncatchableError {
|
|
18
|
+
private readonly _status;
|
|
19
|
+
constructor(status: number, code: string, message: string);
|
|
20
|
+
getStatus(): number;
|
|
21
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export type LoggerLevel = 'debug' | 'verbose' | 'log' | 'warn' | 'error';
|
|
2
|
+
export type LoggerName = `${string}.${LoggerLevel}`;
|
|
3
|
+
export type LoggerEnablement = Record<LoggerName, boolean>;
|
|
4
|
+
export interface Logger {
|
|
5
|
+
log(message: any, ...optionalParams: any[]): any;
|
|
6
|
+
error(message: any, ...optionalParams: any[]): any;
|
|
7
|
+
warn(message: any, ...optionalParams: any[]): any;
|
|
8
|
+
debug?(message: any, ...optionalParams: any[]): any;
|
|
9
|
+
verbose?(message: any, ...optionalParams: any[]): any;
|
|
10
|
+
}
|
|
11
|
+
export declare class EnhancedLogger implements Logger {
|
|
12
|
+
private static ENABLED_LEVELS;
|
|
13
|
+
private static ENABLEMENTS;
|
|
14
|
+
private _logger;
|
|
15
|
+
constructor(logger: Logger);
|
|
16
|
+
getInternalLogger(): Logger;
|
|
17
|
+
static enableLevel(level: LoggerLevel): void;
|
|
18
|
+
static disableLevel(level: LoggerLevel): void;
|
|
19
|
+
static isLevelEnabled(level: LoggerLevel): boolean;
|
|
20
|
+
static enable(name: LoggerName | string): void;
|
|
21
|
+
static disable(name: LoggerName | string): void;
|
|
22
|
+
static isEnabled(name: LoggerName): boolean;
|
|
23
|
+
takeover(to: Logger): void;
|
|
24
|
+
restore(): void;
|
|
25
|
+
debug(message: any, ...optionalParams: any[]): any;
|
|
26
|
+
verbose(message: any, ...optionalParams: any[]): any;
|
|
27
|
+
log(message: any, ...optionalParams: any[]): any;
|
|
28
|
+
warn(message: any, ...optionalParams: any[]): any;
|
|
29
|
+
error(message: any, ...optionalParams: any[]): any;
|
|
30
|
+
}
|
|
31
|
+
export declare class ConsoleLogger implements Logger {
|
|
32
|
+
private buildPrefix;
|
|
33
|
+
debug(message: any, ...optionalParams: any[]): any;
|
|
34
|
+
verbose(message: any, ...optionalParams: any[]): any;
|
|
35
|
+
log(message: any, ...optionalParams: any[]): any;
|
|
36
|
+
warn(message: any, ...optionalParams: any[]): any;
|
|
37
|
+
error(message: any, ...optionalParams: any[]): any;
|
|
38
|
+
}
|
|
39
|
+
export declare const createLogger: (logger?: Logger) => EnhancedLogger;
|
|
40
|
+
export declare class LoggerPerformanceSaver {
|
|
41
|
+
private readonly message;
|
|
42
|
+
constructor(message: () => string);
|
|
43
|
+
get [Symbol.toStringTag](): string;
|
|
44
|
+
}
|
|
45
|
+
export declare const saveLoggerPerformance: (message: () => string) => LoggerPerformanceSaver;
|
|
46
|
+
export declare class LoggerUtils {
|
|
47
|
+
private constructor();
|
|
48
|
+
static stringifyObject(given: any): string;
|
|
49
|
+
static normalizeObject(given: any): any;
|
|
50
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type Nullable<T> = T | null | undefined;
|
|
2
|
+
export type Undefinable<T> = T | undefined;
|
|
3
|
+
export type DateTime = string;
|
|
4
|
+
export interface Type<T = any> extends Function {
|
|
5
|
+
new (...args: any[]): T;
|
|
6
|
+
}
|
|
7
|
+
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rainbow-o23/n1",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "o23 interfaces",
|
|
5
|
+
"main": "index.cjs",
|
|
6
|
+
"module": "index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "rollup -c",
|
|
11
|
+
"build:ci": "rollup -c rollup.config.ci.js",
|
|
12
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
13
|
+
},
|
|
14
|
+
"license": "UNLICENSED",
|
|
15
|
+
"author": "Rainbow Team",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"dayjs": "^1.11.8",
|
|
18
|
+
"nanoid": "3.3.6"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@babel/core": "^7.20.5",
|
|
22
|
+
"@babel/preset-env": "^7.20.2",
|
|
23
|
+
"@babel/preset-typescript": "^7.18.6",
|
|
24
|
+
"@rollup/plugin-babel": "^6.0.4",
|
|
25
|
+
"@rollup/plugin-eslint": "^9.0.3",
|
|
26
|
+
"@types/events": "^3.0.1",
|
|
27
|
+
"@types/node": "18.16.12",
|
|
28
|
+
"@typescript-eslint/eslint-plugin": "^5.46.0",
|
|
29
|
+
"@typescript-eslint/parser": "^5.46.0",
|
|
30
|
+
"eslint": "^8.29.0",
|
|
31
|
+
"rollup": "^3.7.0",
|
|
32
|
+
"rollup-plugin-tslint": "^0.2.2",
|
|
33
|
+
"rollup-plugin-typescript2": "^0.34.1",
|
|
34
|
+
"tslib": "^2.4.1",
|
|
35
|
+
"typescript": "5.1.6"
|
|
36
|
+
},
|
|
37
|
+
"volta": {
|
|
38
|
+
"node": "18.19.0",
|
|
39
|
+
"yarn": "1.22.21"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {babel} from '@rollup/plugin-babel';
|
|
2
|
+
import eslint from '@rollup/plugin-eslint';
|
|
3
|
+
import typescript from 'rollup-plugin-typescript2';
|
|
4
|
+
|
|
5
|
+
export const buildConfig = (lint) => {
|
|
6
|
+
// ['./index.d.ts', './index.js', './index.cjs', './lib'].forEach(f => {
|
|
7
|
+
// const cwd = path.resolve(process.cwd(), f);
|
|
8
|
+
// if (fs.existsSync(cwd)) {
|
|
9
|
+
// fs.rmSync(cwd, {recursive: true, force: true});
|
|
10
|
+
// }
|
|
11
|
+
// });
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
input: './src/index.ts',
|
|
15
|
+
output: [
|
|
16
|
+
{format: 'es', dir: '.'},
|
|
17
|
+
{format: 'cjs', file: './index.cjs'}
|
|
18
|
+
],
|
|
19
|
+
plugins: [
|
|
20
|
+
lint ? eslint({exclude: ['../node_modules/**', 'node_modules/**']}) : null,
|
|
21
|
+
// lint ? tslint({exclude: ['../node_modules/**', 'node_modules/**']}) : null,
|
|
22
|
+
typescript({clean: true}),
|
|
23
|
+
babel({babelHelpers: 'bundled'})
|
|
24
|
+
].filter(x => x != null),
|
|
25
|
+
external(id) {
|
|
26
|
+
return ["dayjs/plugin/"].some(scope => id.startsWith(scope))
|
|
27
|
+
|| ['nanoid', 'dayjs'].includes(id);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
};
|
package/rollup.config.js
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import ArraySupport from 'dayjs/plugin/arraySupport.js';
|
|
3
|
+
import CustomParseFormat from 'dayjs/plugin/customParseFormat.js';
|
|
4
|
+
import Duration from 'dayjs/plugin/duration.js';
|
|
5
|
+
import IsToday from 'dayjs/plugin/isToday.js';
|
|
6
|
+
import ObjectSupport from 'dayjs/plugin/objectSupport.js';
|
|
7
|
+
import QuarterOfYear from 'dayjs/plugin/quarterOfYear.js';
|
|
8
|
+
import RelativeTime from 'dayjs/plugin/relativeTime.js';
|
|
9
|
+
import UTC from 'dayjs/plugin/utc.js';
|
|
10
|
+
import WeekOfYear from 'dayjs/plugin/weekOfYear.js';
|
|
11
|
+
|
|
12
|
+
dayjs.extend(WeekOfYear);
|
|
13
|
+
dayjs.extend(QuarterOfYear);
|
|
14
|
+
dayjs.extend(Duration);
|
|
15
|
+
dayjs.extend(IsToday);
|
|
16
|
+
dayjs.extend(RelativeTime);
|
|
17
|
+
dayjs.extend(ArraySupport);
|
|
18
|
+
dayjs.extend(ObjectSupport);
|
|
19
|
+
dayjs.extend(CustomParseFormat);
|
|
20
|
+
dayjs.extend(UTC);
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {Config, createConfig, createLogger, Logger, LoggerUtils} from '../utils';
|
|
2
|
+
import {PipelineOptions} from './pipeline';
|
|
3
|
+
import {PipelineStep, PipelineStepData} from './pipeline-step';
|
|
4
|
+
import {PIPELINE_STEP_RETURN_NULL} from './step-helpers-utils';
|
|
5
|
+
|
|
6
|
+
export interface PerformanceExecutionOptions {
|
|
7
|
+
exec: 'PIPELINE' | 'STEP';
|
|
8
|
+
traceId: string;
|
|
9
|
+
start: bigint;
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
+
print: (message: () => any) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type MeasuredFunction<T> = () => Promise<T>;
|
|
15
|
+
|
|
16
|
+
export class PerformanceExecution {
|
|
17
|
+
public constructor(private readonly options: PerformanceExecutionOptions) {
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public async execute<T>(measured: MeasuredFunction<T>): Promise<T> {
|
|
21
|
+
try {
|
|
22
|
+
return await measured();
|
|
23
|
+
} finally {
|
|
24
|
+
this.options.print(() => {
|
|
25
|
+
return {
|
|
26
|
+
exec: this.options.exec, ptraceId: this.options.traceId,
|
|
27
|
+
spent: Number((process.hrtime.bigint() - this.options.start) / 1000000n)
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface PipelineExecutionOptions {
|
|
35
|
+
config?: Config;
|
|
36
|
+
logger?: Logger;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class AbstractPipelineExecution {
|
|
40
|
+
protected readonly _config: Config;
|
|
41
|
+
protected readonly _logger: Logger;
|
|
42
|
+
protected readonly _performanceLogEnabled: boolean;
|
|
43
|
+
protected readonly _debugLogEnabled: boolean;
|
|
44
|
+
|
|
45
|
+
// noinspection TypeScriptAbstractClassConstructorCanBeMadeProtected
|
|
46
|
+
public constructor(options?: PipelineOptions) {
|
|
47
|
+
const {config, logger} = options ?? {};
|
|
48
|
+
this._logger = logger ?? createLogger();
|
|
49
|
+
this._config = config ?? createConfig(this._logger);
|
|
50
|
+
this._debugLogEnabled = this._config.getBoolean('pipeline.debug.log.enabled', false);
|
|
51
|
+
this._performanceLogEnabled = this._debugLogEnabled || this._config.getBoolean('pipeline.performance.log.enabled', false);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public getConfig(): Config {
|
|
55
|
+
return this._config;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public getLogger(): Logger {
|
|
59
|
+
return this._logger;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
protected isDebugLogEnabled(): boolean {
|
|
63
|
+
return this._debugLogEnabled;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* must check {@link isDebugLogEnabled} first
|
|
68
|
+
*/
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
+
protected debug(message: any, ...optionsParams: Array<any>): void {
|
|
71
|
+
if (this.isDebugLogEnabled()) {
|
|
72
|
+
message = typeof message === 'function' ? message() : message;
|
|
73
|
+
message = Array.isArray(message) ? message : [message];
|
|
74
|
+
const [first, ...rest] = [...message, ...optionsParams.map(m => typeof m === 'function' ? m() : m)];
|
|
75
|
+
this.getLogger().debug(first ?? '', ...rest, this.constructor.name);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
protected traceRequest<T>(traceId: string, data: T): T {
|
|
80
|
+
this.debug(() => ({exec: 'PIPELINE', ptraceId: traceId, request: LoggerUtils.normalizeObject(data)}));
|
|
81
|
+
return data;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
|
+
protected traceResponse<T>(traceId: string, data: T): T {
|
|
86
|
+
this.debug(() => ({exec: 'PIPELINE', ptraceId: traceId, response: LoggerUtils.normalizeObject(data)}));
|
|
87
|
+
return data;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
91
|
+
protected traceStepIn(traceId: string, step: PipelineStep, data: any) {
|
|
92
|
+
this.debug(() => ({
|
|
93
|
+
exec: 'STEP', name: step.getName(), ptraceId: traceId, in: LoggerUtils.normalizeObject(data)
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
98
|
+
protected traceStepOut(traceId: string, step: PipelineStep, data: any) {
|
|
99
|
+
this.debug(() => ({
|
|
100
|
+
exec: 'STEP', name: step.getName(), ptraceId: traceId, out: LoggerUtils.normalizeObject(data)
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
protected isPerformanceLogEnabled(): boolean {
|
|
105
|
+
return this._performanceLogEnabled;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
109
|
+
protected debugPerformance(message: () => any): void {
|
|
110
|
+
if (this.isPerformanceLogEnabled()) {
|
|
111
|
+
this.getLogger().debug(message(), this.constructor.name);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
protected measurePerformance(traceId: string, exec: 'PIPELINE' | 'STEP'): PerformanceExecution {
|
|
116
|
+
return new PerformanceExecution({
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
118
|
+
exec, traceId, start: process.hrtime.bigint(), print: (message: () => any) => this.debugPerformance(message)
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* check given response's content
|
|
124
|
+
* 1. is {@link PIPELINE_STEP_RETURN_NULL}, return directly, identify as clear
|
|
125
|
+
* 2. is null, continue using request
|
|
126
|
+
* 3. return directly
|
|
127
|
+
*/
|
|
128
|
+
protected returnOrContinueOrClear(request: PipelineStepData, response: PipelineStepData): PipelineStepData {
|
|
129
|
+
if (response.content === PIPELINE_STEP_RETURN_NULL) {
|
|
130
|
+
return response;
|
|
131
|
+
} else if (response.content == null) {
|
|
132
|
+
return request;
|
|
133
|
+
} else {
|
|
134
|
+
return response;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {Config, Logger} from '../utils';
|
|
2
|
+
import {AbstractPipelineExecution, PipelineExecutionOptions} from './pipeline-execution';
|
|
3
|
+
import {createStepHelpers, PipelineStepHelpers} from './step-helpers';
|
|
4
|
+
|
|
5
|
+
export type PipelineStepCode = string;
|
|
6
|
+
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
|
+
export type PipelineStepPayload = any;
|
|
9
|
+
|
|
10
|
+
export interface PipelineStepContext {
|
|
11
|
+
traceId?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface PipelineStepData<C = PipelineStepPayload, CTX = PipelineStepContext> {
|
|
15
|
+
/** this is runtime context */
|
|
16
|
+
$context?: CTX;
|
|
17
|
+
content: C;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
export interface PipelineStep<In = any, Out = any> {
|
|
22
|
+
getName(): string;
|
|
23
|
+
|
|
24
|
+
perform(request: PipelineStepData<In>): Promise<PipelineStepData<Out>>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface PipelineStepOptions extends PipelineExecutionOptions {
|
|
28
|
+
name?: string;
|
|
29
|
+
config?: Config;
|
|
30
|
+
logger?: Logger;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
34
|
+
export interface PipelineStepType<S = PipelineStep> extends Function {
|
|
35
|
+
new(options?: PipelineStepOptions): S;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export abstract class AbstractPipelineStep<In = PipelineStepPayload, Out = PipelineStepPayload>
|
|
39
|
+
extends AbstractPipelineExecution implements PipelineStep<In, Out> {
|
|
40
|
+
private _$helpers: PipelineStepHelpers;
|
|
41
|
+
protected readonly _name?: string;
|
|
42
|
+
|
|
43
|
+
// noinspection TypeScriptAbstractClassConstructorCanBeMadeProtected
|
|
44
|
+
public constructor(options?: PipelineStepOptions) {
|
|
45
|
+
super(options);
|
|
46
|
+
this._name = options?.name;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public getName(): string {
|
|
50
|
+
return (this._name == null || this._name.trim().length === 0) ? this.constructor.name : this._name;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public getHelpers(): PipelineStepHelpers {
|
|
54
|
+
if (this._$helpers == null) {
|
|
55
|
+
this._$helpers = createStepHelpers(this.getConfig(), this.getLogger());
|
|
56
|
+
}
|
|
57
|
+
return this._$helpers;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
protected getHelpersVariableNames(): Array<string> {
|
|
61
|
+
return ['$helpers', '$'];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public abstract perform(request: PipelineStepData<In>): Promise<PipelineStepData<Out>>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface PipelineStepBuilder {
|
|
68
|
+
create(options?: PipelineStepOptions): Promise<PipelineStep>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export class DefaultPipelineStepBuilder implements PipelineStepBuilder {
|
|
72
|
+
public constructor(protected readonly step: PipelineStepType) {
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public async create(options?: PipelineStepOptions): Promise<PipelineStep> {
|
|
76
|
+
return new this.step(options);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|