mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-30 20:24:47 +00:00
feat: add autoConfig/ better types for wrapperData
This commit is contained in:
@@ -1,70 +1,42 @@
|
||||
import deepmerge from "deepmerge";
|
||||
import { AutoConfigure, Effects } from "../types";
|
||||
import { Message, MaybePromise, ReadonlyDeep } from ".";
|
||||
import { AutoConfigure, Effects, ExpectedExports } from "../types";
|
||||
import { deepEqual, deepMerge } from "../util";
|
||||
|
||||
class AutoConfigBuilt<Config> implements AutoConfigure<Config> {
|
||||
constructor(private autoConfig: AutoConfig<Config>) {}
|
||||
|
||||
async check(effects: Effects, config: Config): Promise<void> {
|
||||
for (const [message, configure] of this.autoConfig.getConfigures()) {
|
||||
const value = await configure({ effects, config });
|
||||
if (value !== null) {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
/** This is called after we know that the dependency package needs a new configuration, this would be a transform for defaults */
|
||||
async autoConfigure(effects: Effects, config: Config): Promise<Config> {
|
||||
const input = { effects, config };
|
||||
const newOverwrites = (
|
||||
await Promise.all(this.autoConfig.getConfigures().map((x) => x[1](input)))
|
||||
).filter((x): x is NonNullable<typeof x> => x !== null);
|
||||
return deepmerge.all([config, ...newOverwrites]);
|
||||
}
|
||||
}
|
||||
export class AutoConfig<Config> {
|
||||
private constructor(
|
||||
private configures: Array<
|
||||
[
|
||||
Message,
|
||||
(
|
||||
options: Readonly<{ config: Config; effects: Effects }>
|
||||
) => MaybePromise<null | Partial<Config>>
|
||||
]
|
||||
>
|
||||
export type AutoConfigFrom = {
|
||||
[key: string]: (options: {
|
||||
effects: Effects;
|
||||
localConfig: unknown;
|
||||
remoteConfig: unknown;
|
||||
}) => Promise<void | Record<string, unknown>>;
|
||||
};
|
||||
export class AutoConfig {
|
||||
constructor(
|
||||
readonly configs: AutoConfigFrom,
|
||||
readonly path: keyof AutoConfigFrom,
|
||||
) {}
|
||||
getConfigures(): ReadonlyDeep<
|
||||
Array<
|
||||
[
|
||||
Message,
|
||||
(
|
||||
options: Readonly<{ config: Config; effects: Effects }>
|
||||
) => MaybePromise<null | Partial<Config>>
|
||||
]
|
||||
>
|
||||
> {
|
||||
return this.configures;
|
||||
}
|
||||
|
||||
static autoConfig<Config>(
|
||||
message: Message,
|
||||
configure: (
|
||||
options: Readonly<{ config: Config; effects: Effects }>
|
||||
) => MaybePromise<null | Partial<Config>>
|
||||
): AutoConfig<Config> {
|
||||
return new AutoConfig([[message, configure]]);
|
||||
async check(
|
||||
options: Parameters<AutoConfigure["check"]>[0],
|
||||
): ReturnType<AutoConfigure["check"]> {
|
||||
const origConfig = JSON.parse(JSON.stringify(options.localConfig));
|
||||
if (
|
||||
!deepEqual(
|
||||
origConfig,
|
||||
deepMerge(
|
||||
{},
|
||||
options.localConfig,
|
||||
await this.configs[this.path](options),
|
||||
),
|
||||
)
|
||||
)
|
||||
throw new Error(`Check failed for ${this.path}`);
|
||||
}
|
||||
autoConfig(
|
||||
message: Message,
|
||||
configure: (
|
||||
options: Readonly<{ config: Config; effects: Effects }>
|
||||
) => MaybePromise<null | Partial<Config>>
|
||||
): AutoConfig<Config> {
|
||||
this.configures.push([message, configure]);
|
||||
return this;
|
||||
}
|
||||
|
||||
build() {
|
||||
return new AutoConfigBuilt(this);
|
||||
async autoConfigure(
|
||||
options: Parameters<AutoConfigure["autoConfigure"]>[0],
|
||||
): ReturnType<AutoConfigure["autoConfigure"]> {
|
||||
return deepMerge(
|
||||
{},
|
||||
options.localConfig,
|
||||
await this.configs[this.path](options),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user