mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-30 04:11:57 +00:00
chore: Update the types for autoconfig
This commit is contained in:
@@ -1,30 +1,36 @@
|
|||||||
import { AutoConfigure, Effects, ExpectedExports } from "../types";
|
import { AutoConfigure, Effects, ExpectedExports } from "../types";
|
||||||
import { deepEqual, deepMerge } from "../util";
|
import { Utils, deepEqual, deepMerge, utils } from "../util";
|
||||||
|
|
||||||
export type AutoConfigFrom = {
|
export type AutoConfigFrom<WD, Input> = {
|
||||||
[key: string]: (options: {
|
[key: string]: (options: {
|
||||||
effects: Effects;
|
effects: Effects;
|
||||||
localConfig: unknown;
|
localConfig: Input;
|
||||||
remoteConfig: unknown;
|
remoteConfig: unknown;
|
||||||
|
utils: Utils<WD>;
|
||||||
}) => Promise<void | Record<string, unknown>>;
|
}) => Promise<void | Record<string, unknown>>;
|
||||||
};
|
};
|
||||||
export class AutoConfig {
|
export class AutoConfig<WD, Input> {
|
||||||
constructor(
|
constructor(
|
||||||
readonly configs: AutoConfigFrom,
|
readonly configs: AutoConfigFrom<WD, Input>,
|
||||||
readonly path: keyof AutoConfigFrom,
|
readonly path: keyof AutoConfigFrom<WD, Input>,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async check(
|
async check(
|
||||||
options: Parameters<AutoConfigure["check"]>[0],
|
options: Parameters<AutoConfigure["check"]>[0],
|
||||||
): ReturnType<AutoConfigure["check"]> {
|
): ReturnType<AutoConfigure["check"]> {
|
||||||
const origConfig = JSON.parse(JSON.stringify(options.localConfig));
|
const origConfig = JSON.parse(JSON.stringify(options.localConfig));
|
||||||
|
const newOptions = {
|
||||||
|
...options,
|
||||||
|
utils: utils<WD>(options.effects),
|
||||||
|
localConfig: options.localConfig as Input,
|
||||||
|
};
|
||||||
if (
|
if (
|
||||||
!deepEqual(
|
!deepEqual(
|
||||||
origConfig,
|
origConfig,
|
||||||
deepMerge(
|
deepMerge(
|
||||||
{},
|
{},
|
||||||
options.localConfig,
|
options.localConfig,
|
||||||
await this.configs[this.path](options),
|
await this.configs[this.path](newOptions),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -33,10 +39,15 @@ export class AutoConfig {
|
|||||||
async autoConfigure(
|
async autoConfigure(
|
||||||
options: Parameters<AutoConfigure["autoConfigure"]>[0],
|
options: Parameters<AutoConfigure["autoConfigure"]>[0],
|
||||||
): ReturnType<AutoConfigure["autoConfigure"]> {
|
): ReturnType<AutoConfigure["autoConfigure"]> {
|
||||||
|
const newOptions = {
|
||||||
|
...options,
|
||||||
|
utils: utils<WD>(options.effects),
|
||||||
|
localConfig: options.localConfig as Input,
|
||||||
|
};
|
||||||
return deepMerge(
|
return deepMerge(
|
||||||
{},
|
{},
|
||||||
options.localConfig,
|
options.localConfig,
|
||||||
await this.configs[this.path](options),
|
await this.configs[this.path](newOptions),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { AutoConfig, AutoConfigFrom } from "./AutoConfig";
|
import { AutoConfig, AutoConfigFrom } from "./AutoConfig";
|
||||||
|
|
||||||
export function setupAutoConfig<C extends AutoConfigFrom>(configs: C) {
|
export function setupAutoConfig<WD, Input>(configs: AutoConfigFrom<WD, Input>) {
|
||||||
const answer = { ...configs } as unknown as { [k in keyof C]: AutoConfig };
|
type C = typeof configs;
|
||||||
|
const answer = { ...configs } as unknown as {
|
||||||
|
[k in keyof C]: AutoConfig<WD, Input>;
|
||||||
|
};
|
||||||
for (const key in configs) {
|
for (const key in configs) {
|
||||||
answer[key] = new AutoConfig(configs, key);
|
answer[key] = new AutoConfig<WD, Input>(configs, key);
|
||||||
}
|
}
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export * as configBuilder from "./builder";
|
export * as configBuilder from "./builder";
|
||||||
|
|
||||||
export { setupConfig as setupConfigExports } from "./setupConfig";
|
export { setupConfig } from "./setupConfig";
|
||||||
export { specToBuilder, specToBuilderFile } from "./specToBuilder";
|
export { specToBuilder, specToBuilderFile } from "./specToBuilder";
|
||||||
export * as dependencies from "./dependencies";
|
export * as dependencies from "./dependencies";
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
import { Config } from "./builder";
|
import { Config } from "./builder";
|
||||||
import { DeepPartial, Dependencies, Effects, ExpectedExports } from "../types";
|
import { DeepPartial, Dependencies, Effects, ExpectedExports } from "../types";
|
||||||
import { InputSpec } from "./configTypes";
|
import { InputSpec } from "./configTypes";
|
||||||
import { nullIfEmpty } from "../util";
|
import { Utils, nullIfEmpty, utils } from "../util";
|
||||||
import { TypeFromProps } from "../util/propertiesMatcher";
|
import { TypeFromProps } from "../util/propertiesMatcher";
|
||||||
|
|
||||||
export type Write<A> = (options: {
|
declare const dependencyProof: unique symbol;
|
||||||
|
export type DependenciesReceipt = void & {
|
||||||
|
[dependencyProof]: never;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Save<WD, A> = (options: {
|
||||||
effects: Effects;
|
effects: Effects;
|
||||||
input: TypeFromProps<A>;
|
input: A;
|
||||||
}) => Promise<void>;
|
utils: Utils<WD>;
|
||||||
export type Read<A> = (options: {
|
}) => Promise<DependenciesReceipt>;
|
||||||
|
export type Read<WD, A> = (options: {
|
||||||
effects: Effects;
|
effects: Effects;
|
||||||
}) => Promise<null | DeepPartial<TypeFromProps<A>>>;
|
utils: Utils<WD>;
|
||||||
export type DependenciesFn<A> = (options: {
|
}) => Promise<null | DeepPartial<A>>;
|
||||||
effects: Effects;
|
|
||||||
input: TypeFromProps<A>;
|
|
||||||
}) => Promise<Dependencies | void>;
|
|
||||||
/**
|
/**
|
||||||
* We want to setup a config export with a get and set, this
|
* We want to setup a config export with a get and set, this
|
||||||
* is going to be the default helper to setup config, because it will help
|
* is going to be the default helper to setup config, because it will help
|
||||||
@@ -22,11 +25,10 @@ export type DependenciesFn<A> = (options: {
|
|||||||
* @param options
|
* @param options
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function setupConfig<A extends InputSpec>(
|
export function setupConfig<WD, A extends Config<InputSpec>>(
|
||||||
spec: Config<A>,
|
spec: A,
|
||||||
write: Write<A>,
|
write: Save<WD, TypeFromProps<A>>,
|
||||||
read: Read<A>,
|
read: Read<WD, TypeFromProps<A>>,
|
||||||
dependencies: DependenciesFn<A>,
|
|
||||||
) {
|
) {
|
||||||
const validator = spec.validator();
|
const validator = spec.validator();
|
||||||
return {
|
return {
|
||||||
@@ -38,14 +40,13 @@ export function setupConfig<A extends InputSpec>(
|
|||||||
await write({
|
await write({
|
||||||
input: JSON.parse(JSON.stringify(input)),
|
input: JSON.parse(JSON.stringify(input)),
|
||||||
effects,
|
effects,
|
||||||
|
utils: utils<WD>(effects),
|
||||||
});
|
});
|
||||||
const dependenciesToSet = (await dependencies({ effects, input })) || [];
|
|
||||||
await effects.setDependencies(dependenciesToSet);
|
|
||||||
}) as ExpectedExports.setConfig,
|
}) as ExpectedExports.setConfig,
|
||||||
getConfig: (async ({ effects, config }) => {
|
getConfig: (async ({ effects, config }) => {
|
||||||
return {
|
return {
|
||||||
spec: spec.build(),
|
spec: spec.build(),
|
||||||
config: nullIfEmpty(await read({ effects })),
|
config: nullIfEmpty(await read({ effects, utils: utils<WD>(effects) })),
|
||||||
};
|
};
|
||||||
}) as ExpectedExports.getConfig,
|
}) as ExpectedExports.getConfig,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export * as configTypes from "./config/configTypes";
|
export * as configTypes from "./config/configTypes";
|
||||||
import { InputSpec } from "./config/configTypes";
|
import { InputSpec } from "./config/configTypes";
|
||||||
|
import { DependenciesReceipt } from "./config/setupConfig";
|
||||||
import { ActionReceipt } from "./init";
|
import { ActionReceipt } from "./init";
|
||||||
|
|
||||||
export type ExportedAction = (options: {
|
export type ExportedAction = (options: {
|
||||||
@@ -382,7 +383,7 @@ export type Effects = {
|
|||||||
}): Promise<void>;
|
}): Promise<void>;
|
||||||
|
|
||||||
/** Set the dependencies of what the service needs, usually ran during the set config as a best practice */
|
/** Set the dependencies of what the service needs, usually ran during the set config as a best practice */
|
||||||
setDependencies(dependencies: Dependencies): Promise<void>;
|
setDependencies(dependencies: Dependencies): Promise<DependenciesReceipt>;
|
||||||
/** Exists could be useful during the runtime to know if some service exists, option dep */
|
/** Exists could be useful during the runtime to know if some service exists, option dep */
|
||||||
exists(packageId: PackageId): Promise<boolean>;
|
exists(packageId: PackageId): Promise<boolean>;
|
||||||
/** Exists could be useful during the runtime to know if some service is running, option dep */
|
/** Exists could be useful during the runtime to know if some service is running, option dep */
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
ValueSpec as ValueSpecAny,
|
ValueSpec as ValueSpecAny,
|
||||||
InputSpec,
|
InputSpec,
|
||||||
} from "../config/configTypes";
|
} from "../config/configTypes";
|
||||||
|
import { Config } from "../config/builder/config";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
string,
|
string,
|
||||||
@@ -110,6 +111,7 @@ export type GuardAll<A> = GuardNumber<A> &
|
|||||||
GuardDatetime<A>;
|
GuardDatetime<A>;
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
export type TypeFromProps<A> =
|
export type TypeFromProps<A> =
|
||||||
|
A extends Config<infer B> ? TypeFromProps<B> :
|
||||||
A extends Record<string, unknown> ? { [K in keyof A & string]: _<GuardAll<A[K]>> } :
|
A extends Record<string, unknown> ? { [K in keyof A & string]: _<GuardAll<A[K]>> } :
|
||||||
unknown;
|
unknown;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user