diff --git a/lib/StartSDK.ts b/lib/StartSDK.ts new file mode 100644 index 0000000..56cfc32 --- /dev/null +++ b/lib/StartSDK.ts @@ -0,0 +1,248 @@ +import { AnyParser } from "ts-matches" +import { SDKManifest } from "./manifest/ManifestTypes" +import { RequiredDefault, Value } from "./config/builder/value" +import { Config, ExtractConfigType, LazyBuild } from "./config/builder/config" +import { + DefaultString, + Pattern, + RandomString, + ValueSpecDatetime, + ValueSpecText, +} from "./config/configTypes" +import { Variants } from "./config/builder/variants" +import { createAction } from "./actions/createAction" +import { ActionMetaData, Effects, ActionResult, Metadata } from "./types" +import { Utils } from "./util" + +// prettier-ignore +type AnyNeverCond = + T extends [] ? Else : + T extends [never, ...Array] ? Then : + T extends [any, ...infer U] ? AnyNeverCond : + never + +class StartSDK { + private constructor() {} + private anyOf( + a: A, + ): AnyNeverCond<[Manifest, Store], "Build not ready", A> { + return a as any + } + + static of() { + return new StartSDK() + } + withManifest() { + return new StartSDK() + } + withStore>() { + return new StartSDK() + } + + build() { + return this.anyOf({ + // TODO AutoConfig + // TODO Backup + // TODO Config + // TODO configConstants + // TODO configDependencies + createAction: < + Store, + ConfigType extends + | Record + | Config + | Config, + Type extends Record = ExtractConfigType, + >( + metaData: Omit & { + input: Config | Config + }, + fn: (options: { + effects: Effects + utils: Utils + input: Type + }) => Promise, + ) => createAction(metaData, fn), + // TODO Daemons + // TODO HealthCheck + // TODO healthCheckFns + // TODO List + // TODO mainNetwork + // TODO Migration + // TODO setupActions + // TODO setupAutoConfig + // TODO setupBackup + // TODO setupInit + // TODO setupInstall + // TODO setupMain + // TODO setupManifest + // TODO setupMigrations + // TODO setupUninstall + // TODO trigger changeOnFirstSuccess, cooldown, default + Value: { + toggle: Value.toggle, + text: Value.text, + textarea: Value.textarea, + number: Value.number, + color: Value.color, + datetime: Value.datetime, + select: Value.select, + multiselect: Value.multiselect, + object: Value.object, + union: Value.union, + list: Value.list, + dynamicToggle: ( + a: LazyBuild< + Store, + { + name: string + description?: string | null + warning?: string | null + default: boolean + disabled?: false | string + } + >, + ) => Value.dynamicToggle(a), + dynamicText: ( + getA: LazyBuild< + Store, + { + name: string + description?: string | null + warning?: string | null + required: RequiredDefault + + /** Default = false */ + masked?: boolean + placeholder?: string | null + minLength?: number | null + maxLength?: number | null + patterns?: Pattern[] + /** Default = 'text' */ + inputmode?: ValueSpecText["inputmode"] + generate?: null | RandomString + } + >, + ) => Value.dynamicText(getA), + dynamicTextarea: ( + getA: LazyBuild< + Store, + { + name: string + description?: string | null + warning?: string | null + required: boolean + minLength?: number | null + maxLength?: number | null + placeholder?: string | null + disabled?: false | string + generate?: null | RandomString + } + >, + ) => Value.dynamicTextarea(getA), + dynamicNumber: ( + getA: LazyBuild< + Store, + { + name: string + description?: string | null + warning?: string | null + required: RequiredDefault + min?: number | null + max?: number | null + /** Default = '1' */ + step?: string | null + integer: boolean + units?: string | null + placeholder?: string | null + disabled?: false | string + } + >, + ) => Value.dynamicNumber(getA), + dynamicColor: ( + getA: LazyBuild< + Store, + { + name: string + description?: string | null + warning?: string | null + required: RequiredDefault + + disabled?: false | string + } + >, + ) => Value.dynamicColor(getA), + dynamicDatetime: ( + getA: LazyBuild< + Store, + { + name: string + description?: string | null + warning?: string | null + required: RequiredDefault + /** Default = 'datetime-local' */ + inputmode?: ValueSpecDatetime["inputmode"] + min?: string | null + max?: string | null + step?: string | null + disabled?: false | string + } + >, + ) => Value.dynamicDatetime(getA), + dynamicSelect: ( + getA: LazyBuild< + Store, + { + name: string + description?: string | null + warning?: string | null + required: RequiredDefault + values: Record + disabled?: false | string + } + >, + ) => Value.dynamicSelect(getA), + dynamicMultiselect: ( + getA: LazyBuild< + Store, + { + name: string + description?: string | null + warning?: string | null + default: string[] + values: Record + minLength?: number | null + maxLength?: number | null + disabled?: false | string + } + >, + ) => Value.dynamicMultiselect(getA), + filteredUnion: < + Required extends RequiredDefault, + Type extends Record, + >( + getDisabledFn: LazyBuild, + a: { + name: string + description?: string | null + warning?: string | null + required: Required + }, + aVariants: Variants | Variants, + ) => + Value.filteredUnion( + getDisabledFn, + a, + aVariants, + ), + }, + // TODO Variants + }) + } +} +// TODO Test output.ts with sdk + +// const test = StartSDK.of() +// .withManifest() +// .withStore<{}>() +// .Value.dynamicToggle({} as any, {} as any) diff --git a/lib/actions/createAction.ts b/lib/actions/createAction.ts index 25591c3..0336807 100644 --- a/lib/actions/createAction.ts +++ b/lib/actions/createAction.ts @@ -1,56 +1,51 @@ import { Config, ExtractConfigType } from "../config/builder/config" import { ActionMetaData, ActionResult, Effects, ExportedAction } from "../types" import { Utils, createUtils, utils } from "../util" -import { WrapperDataContract } from "../wrapperData/wrapperDataContract" export class CreatedAction< - WD, - ConfigType extends Record | Config | Config, + Store, + ConfigType extends + | Record + | Config + | Config, Type extends Record = ExtractConfigType, > { private constructor( - readonly wrapperDataContract: WrapperDataContract, public readonly myMetaData: ActionMetaData, readonly fn: (options: { effects: Effects - utils: Utils + utils: Utils input: Type }) => Promise, - readonly input: Config | Config, + readonly input: Config | Config, ) {} public validator = this.input.validator static of< - WD, + Store, ConfigType extends | Record | Config | Config, Type extends Record = ExtractConfigType, >( - wrapperDataContract: WrapperDataContract, metaData: Omit & { - input: Config | Config + input: Config | Config }, fn: (options: { effects: Effects - utils: Utils + utils: Utils input: Type }) => Promise, ) { const { input, ...rest } = metaData - return new CreatedAction( - wrapperDataContract, - rest, - fn, - input, - ) + return new CreatedAction(rest, fn, input) } exportedAction: ExportedAction = ({ effects, input }) => { return this.fn({ effects, - utils: createUtils(this.wrapperDataContract, effects), + utils: createUtils(effects), input: this.validator.unsafeCast(input), }) } @@ -58,7 +53,7 @@ export class CreatedAction< run = async ({ effects, input }: { effects: Effects; input?: Type }) => { return this.fn({ effects, - utils: createUtils(this.wrapperDataContract, effects), + utils: createUtils(effects), input: this.validator.unsafeCast(input), }) } @@ -66,7 +61,7 @@ export class CreatedAction< async getConfig({ effects }: { effects: Effects }) { return this.input.build({ effects, - utils: createUtils(this.wrapperDataContract, effects) as any, + utils: createUtils(effects) as any, }) } } diff --git a/lib/config/builder/value.ts b/lib/config/builder/value.ts index ca81680..59e35fd 100644 --- a/lib/config/builder/value.ts +++ b/lib/config/builder/value.ts @@ -24,9 +24,8 @@ import { unknown, } from "ts-matches" import { once } from "../../util/once" -import { WrapperDataContract } from "../../wrapperData/wrapperDataContract" -type RequiredDefault = +export type RequiredDefault = | false | { default: A | null @@ -96,7 +95,7 @@ const username = Value.string({ ``` */ export class Value { - private constructor( + protected constructor( public build: LazyBuild, public validator: Parser, ) {} @@ -122,7 +121,6 @@ export class Value { ) } static dynamicToggle( - _wrapperDataContract: WrapperDataContract, a: LazyBuild< WD, { @@ -186,7 +184,6 @@ export class Value { ) } static dynamicText( - _wrapperDataContract: WrapperDataContract, getA: LazyBuild< WD, { @@ -258,7 +255,6 @@ export class Value { ) } static dynamicTextarea( - _wrapperDataContract: WrapperDataContract, getA: LazyBuild< WD, { @@ -325,7 +321,6 @@ export class Value { ) } static dynamicNumber( - _wrapperDataContract: WrapperDataContract, getA: LazyBuild< WD, { @@ -387,7 +382,6 @@ export class Value { } static dynamicColor( - _wrapperDataContract: WrapperDataContract, getA: LazyBuild< WD, { @@ -445,7 +439,6 @@ export class Value { ) } static dynamicDatetime( - _wrapperDataContract: WrapperDataContract, getA: LazyBuild< WD, { @@ -642,7 +635,6 @@ export class Value { Type extends Record, WD = never, >( - _wrapperDataContract: WrapperDataContract, getDisabledFn: LazyBuild, a: { name: string diff --git a/lib/config/constants.ts b/lib/config/configConstants.ts similarity index 100% rename from lib/config/constants.ts rename to lib/config/configConstants.ts diff --git a/lib/config/dependencies.ts b/lib/config/configDependencies.ts similarity index 73% rename from lib/config/dependencies.ts rename to lib/config/configDependencies.ts index b974160..6b31abc 100644 --- a/lib/config/dependencies.ts +++ b/lib/config/configDependencies.ts @@ -1,12 +1,14 @@ import { SDKManifest } from "../manifest/ManifestTypes" import { Dependency } from "../types" -export type Dependencies = { +export type ConfigDependencies = { exists(id: keyof T["dependencies"]): Dependency running(id: keyof T["dependencies"]): Dependency } -export const dependenciesSet = (): Dependencies => ({ +export const configDependenciesSet = < + T extends SDKManifest, +>(): ConfigDependencies => ({ exists(id: keyof T["dependencies"]) { return { id, diff --git a/lib/config/index.ts b/lib/config/index.ts index ab95a64..510dc1c 100644 --- a/lib/config/index.ts +++ b/lib/config/index.ts @@ -1,5 +1,5 @@ import "./builder" import "./setupConfig" -import "./dependencies" -import "./constants" +import "./configDependencies" +import "./configConstants" diff --git a/lib/config/setupConfig.ts b/lib/config/setupConfig.ts index f010402..4432004 100644 --- a/lib/config/setupConfig.ts +++ b/lib/config/setupConfig.ts @@ -1,6 +1,6 @@ import { Effects, ExpectedExports } from "../types" import { SDKManifest } from "../manifest/ManifestTypes" -import * as D from "./dependencies" +import * as D from "./configDependencies" import { Config, ExtractConfigType } from "./builder/config" import { Utils, utils } from "../util" import nullIfEmpty from "../util/nullIfEmpty" @@ -22,7 +22,7 @@ export type Save< effects: Effects input: ExtractConfigType & Record utils: Utils - dependencies: D.Dependencies + dependencies: D.ConfigDependencies }) => Promise<{ dependenciesReceipt: DependenciesReceipt restart: boolean @@ -70,7 +70,7 @@ export function setupConfig< input: JSON.parse(JSON.stringify(input)), effects, utils: utils(wrapperDataContract, effects), - dependencies: D.dependenciesSet(), + dependencies: D.configDependenciesSet(), }) if (restart) { await effects.restart() diff --git a/lib/index.ts b/lib/index.ts index 85c32e1..4553d8e 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -19,3 +19,5 @@ import "./inits" export * as matches from "ts-matches" export * as YAML from "yaml" export * as TOML from "@iarna/toml" + +export class \ No newline at end of file diff --git a/lib/test/output.wrapperData.ts b/lib/test/output.sdk.ts similarity index 100% rename from lib/test/output.wrapperData.ts rename to lib/test/output.sdk.ts diff --git a/lib/health/trigger/TriggerInput.ts b/lib/trigger/TriggerInput.ts similarity index 100% rename from lib/health/trigger/TriggerInput.ts rename to lib/trigger/TriggerInput.ts diff --git a/lib/health/trigger/changeOnFirstSuccess.ts b/lib/trigger/changeOnFirstSuccess.ts similarity index 100% rename from lib/health/trigger/changeOnFirstSuccess.ts rename to lib/trigger/changeOnFirstSuccess.ts diff --git a/lib/health/trigger/cooldownTrigger.ts b/lib/trigger/cooldownTrigger.ts similarity index 100% rename from lib/health/trigger/cooldownTrigger.ts rename to lib/trigger/cooldownTrigger.ts diff --git a/lib/health/trigger/defaultTrigger.ts b/lib/trigger/defaultTrigger.ts similarity index 100% rename from lib/health/trigger/defaultTrigger.ts rename to lib/trigger/defaultTrigger.ts diff --git a/lib/health/trigger/index.ts b/lib/trigger/index.ts similarity index 100% rename from lib/health/trigger/index.ts rename to lib/trigger/index.ts diff --git a/lib/util/index.ts b/lib/util/index.ts index d3e9c12..8f68a67 100644 --- a/lib/util/index.ts +++ b/lib/util/index.ts @@ -84,7 +84,6 @@ export type Utils = { nullIfEmpty: typeof nullIfEmpty } export const utils = ( - _wrapperDataContract: WrapperDataContract, effects: T.Effects, ): Utils => ({ createOrUpdateVault: async ({ diff --git a/lib/wrapperData/wrapperDataContract.ts b/lib/wrapperData/wrapperDataContract.ts deleted file mode 100644 index 14bb975..0000000 --- a/lib/wrapperData/wrapperDataContract.ts +++ /dev/null @@ -1,14 +0,0 @@ -export declare const wrapperDataContractType: unique symbol -export type WrapperDataContract = { - [wrapperDataContractType]: A -} -export const neverWrapperDataContract: WrapperDataContract = null as any -/** - * Used to indicate the type of the wrapper data. To be used in areas where - * we need to know the wrapper data value - */ -export function createWrapperDataContract(): A extends never - ? "Wrapper Data Contract must be created with a generic" - : WrapperDataContract { - return null as any -}