From 7454f9a42ae4e863e25e4251ad4a9d83f4454eaa Mon Sep 17 00:00:00 2001 From: Blu-J Date: Wed, 31 May 2023 10:21:53 -0600 Subject: [PATCH] feat: Create a dynamic action --- lib/StartSdk.ts | 27 ++++++++++++++++++++++++++- lib/actions/createAction.ts | 26 ++++++++++++++++++-------- lib/actions/setupActions.ts | 20 +++++++++++++++----- lib/types.ts | 8 ++++---- 4 files changed, 63 insertions(+), 18 deletions(-) diff --git a/lib/StartSdk.ts b/lib/StartSdk.ts index a013d57..00f06fc 100644 --- a/lib/StartSdk.ts +++ b/lib/StartSdk.ts @@ -18,6 +18,7 @@ import { ActionResult, BackupOptions, DeepPartial, + MaybePromise, } from "./types" import * as patterns from "./util/patterns" import { Utils } from "./util/utils" @@ -91,7 +92,31 @@ export class StartSdk { utils: Utils input: Type }) => Promise, - ) => createAction(metaData, fn), + ) => { + const { input, ...rest } = metaData + return createAction(rest, fn, input) + }, + createDynamicAction: < + ConfigType extends + | Record + | Config + | Config, + Type extends Record = ExtractConfigType, + >( + metaData: (options: { + effects: Effects + utils: Utils + }) => MaybePromise>, + fn: (options: { + effects: Effects + utils: Utils + input: Type + }) => Promise, + input: Config | Config, + ) => { + return createAction(metaData, fn, input) + }, + HealthCheck: { of: healthCheck, }, diff --git a/lib/actions/createAction.ts b/lib/actions/createAction.ts index 086ebe3..2cea0d4 100644 --- a/lib/actions/createAction.ts +++ b/lib/actions/createAction.ts @@ -3,6 +3,12 @@ import { ActionMetadata, ActionResult, Effects, ExportedAction } from "../types" import { createUtils } from "../util" import { Utils } from "../util/utils" +export type MaybeFn = + | Value + | ((options: { + effects: Effects + utils: Utils + }) => Promise | Value) export class CreatedAction< Store, ConfigType extends @@ -12,7 +18,7 @@ export class CreatedAction< Type extends Record = ExtractConfigType, > { private constructor( - public readonly myMetaData: Omit, + public readonly myMetaData: MaybeFn>, readonly fn: (options: { effects: Effects utils: Utils @@ -30,20 +36,18 @@ export class CreatedAction< | Config, Type extends Record = ExtractConfigType, >( - metaData: Omit & { - input: Config | Config - }, + metaData: MaybeFn>, fn: (options: { effects: Effects utils: Utils input: Type }) => Promise, + inputConfig: Config | Config, ) { - const { input, ...rest } = metaData return new CreatedAction( - rest, + metaData, fn, - input as Config, + inputConfig as Config, ) } @@ -63,12 +67,18 @@ export class CreatedAction< }) } + async metaData(options: { effects: Effects; utils: Utils }) { + if (this.myMetaData instanceof Function) + return await this.myMetaData(options) + return this.myMetaData + } + async ActionMetadata(options: { effects: Effects utils: Utils }): Promise { return { - ...this.myMetaData, + ...(await this.metaData(options)), input: await this.input.build(options), } } diff --git a/lib/actions/setupActions.ts b/lib/actions/setupActions.ts index 735fe8e..615c490 100644 --- a/lib/actions/setupActions.ts +++ b/lib/actions/setupActions.ts @@ -1,24 +1,34 @@ import { Effects, ExpectedExports } from "../types" import { createUtils } from "../util" import { once } from "../util/once" +import { Utils } from "../util/utils" import { CreatedAction } from "./createAction" export function setupActions( ...createdActions: CreatedAction[] ) { - const myActions = once(() => { + const myActions = async (options: { + effects: Effects + utils: Utils + }) => { const actions: Record> = {} for (const action of createdActions) { - actions[action.myMetaData.id] = action + const actionMetadata = await action.metaData(options) + actions[actionMetadata.id] = action } return actions - }) + } const answer: { actions: ExpectedExports.actions actionsMetadata: ExpectedExports.actionsMetadata } = { - get actions() { - return myActions() + actions(options: { effects: Effects }) { + const utils = createUtils(options.effects) + + return myActions({ + ...options, + utils, + }) }, async actionsMetadata({ effects }: { effects: Effects }) { const utils = createUtils(effects) diff --git a/lib/types.ts b/lib/types.ts index 82dd78c..c10d47f 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -7,7 +7,7 @@ export type ExportedAction = (options: { effects: Effects input?: Record }) => Promise - +export type MaybePromise = A | Promise export namespace ExpectedExports { version: 1 /** Set configuration is called after we have modified and saved the configuration in the start9 ui. Use this to make a file for the docker to read from for configuration. */ @@ -39,12 +39,12 @@ export namespace ExpectedExports { * One old use case is to add a action where we add a file, that will then be run during the * service starting, and that file would indicate that it would rescan all the data. */ - export type actions = { + export type actions = (options: { effects: Effects }) => MaybePromise<{ [id: string]: { run: ExportedAction getConfig: (options: { effects: Effects }) => Promise } - } + }> export type actionsMetadata = (options: { effects: Effects @@ -160,7 +160,7 @@ export type ActionMetadata = { description: string id: string input: InputSpec - allowedStatuses: "only-running" | "only-stopped" | "any" + allowedStatuses: "only-running" | "only-stopped" | "any" | "disabled" /** * So the ordering of the actions is by alphabetical order of the group, then followed by the alphabetical of the actions */