command-action
Advanced tools
Comparing version 0.0.4 to 0.0.5
// import './examples/success-flow' | ||
// import './examples/error-flow' | ||
import './examples/force-fail-flow' | ||
// import './examples/force-fail-flow' | ||
import { NotifyShippingCompanyAction } from './actions/NotifyShippingCompanyAction' | ||
// const result = await NotifyShippingCompanyAction.run<typeof NotifyShippingCompanyAction>({ | ||
// }) | ||
// result. | ||
// Define a generic type parameter for the class | ||
class BaseClass<T = any> { | ||
// Constructor that takes a value of type T | ||
constructor(public value: T) {} | ||
// Static method with a generic type parameter U that extends BaseClass<T> | ||
// The method takes a value of type T and creates an instance of U | ||
// static createInstance<U extends BaseClass<V>, V>(this: new (value: V) => U, value: ConstructorParameters<typeof this>['0']): U { | ||
// // Create a new instance of the class that calls this method | ||
// return new this(value); | ||
// } | ||
// static createInstance(this: new (value: any) => any, value: ConstructorParameters<typeof this>) { | ||
// return new this(value); | ||
// } | ||
static createInstance<C extends new (...args: any) => any>(param: ConstructorParameters<C>[0]): InstanceType<C> { | ||
return new this(param) as InstanceType<C> | ||
} | ||
} | ||
// Subclass that specifies the generic type as string | ||
class ChildClass extends BaseClass<number> { | ||
// Optionally, you can add more properties or methods here | ||
} | ||
// Subclass that specifies the generic type as number | ||
class AnotherChildClass extends BaseClass<number> { | ||
// Optionally, you can add more properties or methods here | ||
} | ||
// Call the static method from the child classes, passing the required value | ||
const stringInstance = ChildClass.createInstance<typeof ChildClass>(11); | ||
console.log(stringInstance.value); // Outputs: "Hello, World!" | ||
const numberInstance = AnotherChildClass.createInstance(42); | ||
console.log(numberInstance.value); // Outputs: 42 |
import { ActionInstance, Context, PropsType, ActionMethod, ActionHook } from '../types'; | ||
declare abstract class Action<Props extends PropsType = {}, Result extends Props = Props, Provider extends PropsType = {}> implements ActionInstance { | ||
protected context: Context<Props & Result>; | ||
context: Context<Props & Result>; | ||
protected readonly provider: Provider; | ||
@@ -9,4 +9,4 @@ protected beforeHooks: ActionHook[]; | ||
private hook; | ||
protected constructor(context: Context<Props> | Props, provider: Provider); | ||
static run<Props extends PropsType = {}, Result extends Props = Props>(context: Props): Promise<Context<Result>>; | ||
constructor(context: Props, provider: Provider); | ||
static run<C extends new (...args: any) => Action>(param: ConstructorParameters<C>[0]): Promise<InstanceType<C>['context']>; | ||
static method<Props extends PropsType = {}, Result extends Props = Props>(): ActionMethod<Props, Result>; | ||
@@ -13,0 +13,0 @@ protected abstract run(): Promise<void>; |
@@ -24,6 +24,11 @@ "use strict"; | ||
} | ||
static run(context) { | ||
// public static async run<Props extends PropsType = {}, Result extends Props = Props>(context: Props) { | ||
// const Klass: any = this | ||
// const action: Action<Props, Result> = new Klass(context, Command.provider) | ||
// await action.exec() | ||
// return action.context as Context<Result> | ||
// } | ||
static run(param) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const Klass = this; | ||
const action = new Klass(context, instance_1.Command.provider); | ||
const action = new this(param, instance_1.Command.provider); | ||
yield action.exec(); | ||
@@ -34,2 +39,3 @@ return action.context; | ||
static method() { | ||
// @ts-ignore | ||
return this.run.bind(this); | ||
@@ -42,2 +48,3 @@ } | ||
try { | ||
yield instance_1.Command._runMiddlewares(this, this.context); | ||
yield this.hook.runBeforeHooks(); | ||
@@ -44,0 +51,0 @@ yield this.run(); |
@@ -0,2 +1,5 @@ | ||
import { Action } from '../Action'; | ||
import { Sequence } from '../Sequence'; | ||
import { ActionMethod, CommandActionConfig, Context, PropsType } from '../types'; | ||
export type Middleware = (action: Action | Sequence, context: Context<PropsType>, provider: PropsType | null) => Promise<void>; | ||
declare class Command { | ||
@@ -6,6 +9,9 @@ private static command; | ||
config: CommandActionConfig; | ||
private middlewares; | ||
registerMiddleware(middleware: Middleware): void; | ||
static instance(): Command; | ||
settings(config: Partial<CommandActionConfig>): this; | ||
runWithProvider<Props extends PropsType, Result extends Props = Props>(action: ActionMethod<Props, Result>, props: (Parameters<typeof action>)[0], provider: PropsType): Promise<Context<Result>>; | ||
_runMiddlewares(action: Action | Sequence, context: Context<PropsType>): Promise<void>; | ||
} | ||
export default Command; |
@@ -18,3 +18,7 @@ "use strict"; | ||
}; | ||
this.middlewares = []; | ||
} | ||
registerMiddleware(middleware) { | ||
this.middlewares.push(middleware); | ||
} | ||
static instance() { | ||
@@ -38,4 +42,11 @@ if (!this.command) { | ||
} | ||
_runMiddlewares(action, context) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
for (const middleware of this.middlewares) { | ||
yield middleware(action, context, this.provider); | ||
} | ||
}); | ||
} | ||
} | ||
Command.command = null; | ||
exports.default = Command; |
@@ -23,2 +23,3 @@ import { PropsType, ActionInstance } from '../types'; | ||
_rollback(): Promise<boolean>; | ||
toJSON(): Omit<this, "fail" | "_executed" | "_rollback" | "_sequence" | "isSuccess" | "isFailure" | "failure" | "skip" | "toJSON" | "_actions" | "_rolledback">; | ||
private _setSequence; | ||
@@ -25,0 +26,0 @@ private _removeSequence; |
@@ -86,2 +86,6 @@ "use strict"; | ||
} | ||
toJSON() { | ||
const _a = this, { _actions, _rolledback, _sequence, _executed } = _a, rest = __rest(_a, ["_actions", "_rolledback", "_sequence", "_executed"]); | ||
return rest; | ||
} | ||
_setSequence(sequence) { | ||
@@ -88,0 +92,0 @@ this._sequence = sequence; |
import { ActionClass, ActionMethod, Context, PropsType } from '../types'; | ||
declare class Sequence<Props extends PropsType, Result extends Props = Props> { | ||
declare class Sequence<Props extends PropsType = PropsType, Result extends Props = Props> { | ||
protected actions: ActionClass[]; | ||
@@ -4,0 +4,0 @@ skip: boolean; |
@@ -13,2 +13,3 @@ "use strict"; | ||
const Context_1 = require("../Context"); | ||
const instance_1 = require("../instance"); | ||
class Sequence { | ||
@@ -33,2 +34,3 @@ constructor() { | ||
context._setSequence(this); | ||
yield instance_1.Command._runMiddlewares(this, context); | ||
for (let action of this.actions) { | ||
@@ -35,0 +37,0 @@ context = yield action.run(context); |
@@ -10,3 +10,3 @@ import { ContextClass } from './Context'; | ||
export type ActionClass = { | ||
run: <Props extends PropsType, Result extends Props = Props>(context: Context<Props> | Props) => Promise<Context<Result>>; | ||
run: <C extends new (...args: any) => any>(param: ConstructorParameters<C>[0]) => Promise<InstanceType<C>['context']>; | ||
}; | ||
@@ -13,0 +13,0 @@ export declare enum FailureType { |
@@ -7,2 +7,2 @@ "use strict"; | ||
FailureType["Standard"] = "Standard"; | ||
})(FailureType = exports.FailureType || (exports.FailureType = {})); | ||
})(FailureType || (exports.FailureType = FailureType = {})); |
{ | ||
"name": "command-action", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "", | ||
@@ -8,3 +8,3 @@ "main": "lib/index.js", | ||
"build": "rm -rf ./lib && tsc", | ||
"demo": "ts-node ./demos/index.ts" | ||
"demo": "tsx ./demos/index.ts" | ||
}, | ||
@@ -14,7 +14,2 @@ "directories": { | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^18.15.11", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^5.0.3" | ||
}, | ||
"repository": { | ||
@@ -35,3 +30,7 @@ "type": "git", | ||
}, | ||
"homepage": "https://github.com/nemes-zoltan/command-action#readme" | ||
"homepage": "https://github.com/nemes-zoltan/command-action#readme", | ||
"devDependencies": { | ||
"tsx": "^4.19.0", | ||
"typescript": "^5.5.4" | ||
} | ||
} |
# Interactor | ||
Inspired by https://github.com/collectiveidea/interactor | ||
Todo upadte readme |
@@ -8,3 +8,3 @@ import { Command } from '../instance' | ||
abstract class Action<Props extends PropsType = {}, Result extends Props = Props, Provider extends PropsType = {}> implements ActionInstance { | ||
protected context!: Context<Props & Result> | ||
public context!: Context<Props & Result> | ||
protected readonly provider!: Provider | ||
@@ -16,3 +16,3 @@ protected beforeHooks: ActionHook[] = [] | ||
protected constructor(context: Context<Props> | Props, provider: Provider) { | ||
constructor(context: Props, provider: Provider) { | ||
this._context = ContextClass.build<Props>(context) | ||
@@ -23,10 +23,18 @@ this.context = this._context as unknown as Context<Props & Result> | ||
public static async run<Props extends PropsType = {}, Result extends Props = Props>(context: Props) { | ||
const Klass: any = this | ||
const action: Action<Props, Result> = new Klass(context, Command.provider) | ||
// public static async run<Props extends PropsType = {}, Result extends Props = Props>(context: Props) { | ||
// const Klass: any = this | ||
// const action: Action<Props, Result> = new Klass(context, Command.provider) | ||
// await action.exec() | ||
// return action.context as Context<Result> | ||
// } | ||
public static async run<C extends new (...args: any) => Action>(param: ConstructorParameters<C>[0]): Promise<InstanceType<C>['context']> { | ||
const action = new (this as unknown as C)(param, Command.provider) as InstanceType<C> | ||
await action.exec() | ||
return action.context as Context<Result> | ||
return action.context | ||
} | ||
public static method<Props extends PropsType = {}, Result extends Props = Props>(): ActionMethod<Props, Result> { | ||
// @ts-ignore | ||
return this.run.bind(this) | ||
@@ -42,2 +50,3 @@ } | ||
try { | ||
await Command._runMiddlewares(this, this.context) | ||
await this.hook.runBeforeHooks() | ||
@@ -56,3 +65,3 @@ await this.run() | ||
} | ||
if (error instanceof ForcedActionError) { | ||
@@ -68,2 +77,1 @@ throw error | ||
export default Action | ||
@@ -0,3 +1,7 @@ | ||
import { Action } from '../Action' | ||
import { Sequence } from '../Sequence' | ||
import { ActionMethod, CommandActionConfig, Context, PropsType } from '../types' | ||
export type Middleware = (action: Action | Sequence, context: Context<PropsType>, provider: PropsType | null) => Promise<void> | ||
class Command { | ||
@@ -9,3 +13,8 @@ private static command: Command | null = null | ||
} | ||
private middlewares: Middleware[] = [] | ||
public registerMiddleware(middleware: Middleware) { | ||
this.middlewares.push(middleware) | ||
} | ||
public static instance() { | ||
@@ -37,4 +46,10 @@ if (!this.command) { | ||
} | ||
public async _runMiddlewares(action: Action | Sequence, context: Context<PropsType>) { | ||
for (const middleware of this.middlewares) { | ||
await middleware(action, context, this.provider) | ||
} | ||
} | ||
} | ||
export default Command |
@@ -58,3 +58,3 @@ import { Command } from '../instance' | ||
} | ||
if (force) { | ||
@@ -92,2 +92,8 @@ throw new ForcedActionError<Props>(this) | ||
public toJSON() { | ||
const { _actions, _rolledback, _sequence, _executed, ...rest } = this | ||
return rest | ||
} | ||
private _setSequence(sequence: Sequence<Props>) { | ||
@@ -103,2 +109,1 @@ this._sequence = sequence | ||
export default Context | ||
import { ContextClass } from '../Context' | ||
import { Command } from '../instance' | ||
import { ActionClass, ActionMethod, Context, PropsType } from '../types' | ||
class Sequence<Props extends PropsType, Result extends Props = Props> { | ||
class Sequence<Props extends PropsType = PropsType, Result extends Props = Props> { | ||
protected actions: ActionClass[] = [] | ||
@@ -21,2 +22,3 @@ public skip: boolean = false | ||
context._setSequence(this) | ||
await Command._runMiddlewares(this, context as Context<PropsType>) | ||
for (let action of this.actions) { | ||
@@ -23,0 +25,0 @@ context = await action.run(context) |
@@ -10,11 +10,14 @@ import { ContextClass } from './Context' | ||
export type Context<Props extends PropsType> = | ||
export type Context<Props extends PropsType> = | ||
Omit<ContextClass<Props>, '_executed' | '_rollback' | '_sequence'> & Props & Record<string, any> | ||
export type ActionInstance = { | ||
rollback(): Promise<void> | void | ||
} | ||
} | ||
export type ActionClass = { | ||
run: <Props extends PropsType, Result extends Props = Props>(context: Context<Props> | Props) => Promise<Context<Result>> | ||
// run: <Props extends PropsType, Result extends Props = Props>(context: Context<Props> | Props) => Promise<Context<Result>> | ||
run: <C extends new (...args: any) => any>(param: ConstructorParameters<C>[0]) => Promise<InstanceType<C>['context']> | ||
} | ||
@@ -21,0 +24,0 @@ |
43179
2
1127
6