mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-26 02:11:56 +00:00
feat: Making the auto config
This commit is contained in:
@@ -18,9 +18,10 @@ import {
|
|||||||
ActionResult,
|
ActionResult,
|
||||||
Metadata,
|
Metadata,
|
||||||
BackupOptions,
|
BackupOptions,
|
||||||
|
DeepPartial,
|
||||||
} from "./types"
|
} from "./types"
|
||||||
import { Utils } from "./util/utils"
|
import { Utils } from "./util/utils"
|
||||||
import { AutoConfig, AutoConfigFrom } from "./autoconfig/AutoConfig"
|
import { AutoConfig } from "./autoconfig/AutoConfig"
|
||||||
import { BackupSet, Backups } from "./backup/Backups"
|
import { BackupSet, Backups } from "./backup/Backups"
|
||||||
import { smtpConfig } from "./config/configConstants"
|
import { smtpConfig } from "./config/configConstants"
|
||||||
import { Daemons } from "./mainFn/Daemons"
|
import { Daemons } from "./mainFn/Daemons"
|
||||||
@@ -75,10 +76,29 @@ export class StartSdk<Manifest extends SDKManifest, Store, Vault> {
|
|||||||
isReady: AnyNeverCond<[Manifest, Store, Vault], "Build not ready", true>,
|
isReady: AnyNeverCond<[Manifest, Store, Vault], "Build not ready", true>,
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
AutoConfig: <Input, NestedConfigs extends Record<string, any>>(
|
AutoConfig: {
|
||||||
configs: AutoConfigFrom<Store, Vault, Input, NestedConfigs>,
|
of<
|
||||||
path: keyof AutoConfigFrom<Store, Vault, Input, NestedConfigs>,
|
LocalConfig extends Record<string, any>,
|
||||||
) => new AutoConfig<Store, Vault, Input, NestedConfigs>(configs, path),
|
RemoteConfig extends Record<string, any>,
|
||||||
|
>({
|
||||||
|
localConfig,
|
||||||
|
remoteConfig,
|
||||||
|
autoconfig,
|
||||||
|
}: {
|
||||||
|
localConfig: Config<LocalConfig, Store, Vault>
|
||||||
|
remoteConfig: Config<RemoteConfig, any, any>
|
||||||
|
autoconfig: (options: {
|
||||||
|
effects: Effects
|
||||||
|
localConfig: LocalConfig
|
||||||
|
remoteConfig: RemoteConfig
|
||||||
|
utils: Utils<Store, Vault>
|
||||||
|
}) => Promise<void | DeepPartial<RemoteConfig>>
|
||||||
|
}) {
|
||||||
|
return new AutoConfig<Store, Vault, LocalConfig, RemoteConfig>(
|
||||||
|
autoconfig,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
Backups: {
|
Backups: {
|
||||||
volumes: (...volumeNames: Array<keyof Manifest["volumes"] & string>) =>
|
volumes: (...volumeNames: Array<keyof Manifest["volumes"] & string>) =>
|
||||||
Backups.volumes<Manifest>(...volumeNames),
|
Backups.volumes<Manifest>(...volumeNames),
|
||||||
@@ -209,19 +229,17 @@ export class StartSdk<Manifest extends SDKManifest, Store, Vault> {
|
|||||||
},
|
},
|
||||||
setupActions: (...createdActions: CreatedAction<any, any, any>[]) =>
|
setupActions: (...createdActions: CreatedAction<any, any, any>[]) =>
|
||||||
setupActions<Store, Vault>(...createdActions),
|
setupActions<Store, Vault>(...createdActions),
|
||||||
setupAutoConfig: <
|
setupAutoConfig: <Input extends Record<string, any>>(
|
||||||
Input extends Record<string, any>,
|
|
||||||
NestedConfigs extends {
|
|
||||||
[key in keyof Manifest["dependencies"]]: unknown
|
|
||||||
},
|
|
||||||
>(
|
|
||||||
config: Config<Input, Store, Vault>,
|
config: Config<Input, Store, Vault>,
|
||||||
autoConfigs: AutoConfigFrom<Store, Vault, Input, NestedConfigs>,
|
autoConfigs: {
|
||||||
) =>
|
[K in keyof Manifest["dependencies"]]: AutoConfig<
|
||||||
setupAutoConfig<Store, Vault, Input, Manifest, NestedConfigs>(
|
Store,
|
||||||
config,
|
Vault,
|
||||||
autoConfigs,
|
Input,
|
||||||
),
|
any
|
||||||
|
>
|
||||||
|
},
|
||||||
|
) => setupAutoConfig<Store, Vault, Input, Manifest>(config, autoConfigs),
|
||||||
setupBackups: (...args: SetupBackupsParams<Manifest>) =>
|
setupBackups: (...args: SetupBackupsParams<Manifest>) =>
|
||||||
setupBackups<Manifest>(...args),
|
setupBackups<Manifest>(...args),
|
||||||
setupConfig: <
|
setupConfig: <
|
||||||
|
|||||||
@@ -4,31 +4,19 @@ import { deepEqual } from "../util/deepEqual"
|
|||||||
import { deepMerge } from "../util/deepMerge"
|
import { deepMerge } from "../util/deepMerge"
|
||||||
import { Config } from "../config/builder/config"
|
import { Config } from "../config/builder/config"
|
||||||
|
|
||||||
export type AutoConfigFrom<
|
|
||||||
Store,
|
|
||||||
Vault,
|
|
||||||
Input,
|
|
||||||
NestedConfigs extends Record<string, any>,
|
|
||||||
> = {
|
|
||||||
[key in keyof NestedConfigs & string]: {
|
|
||||||
serviceConfig: Config<NestedConfigs[key], Store, Vault>
|
|
||||||
autoConfig: (options: {
|
|
||||||
effects: Effects
|
|
||||||
localConfig: Input
|
|
||||||
remoteConfig: NestedConfigs[key]
|
|
||||||
utils: Utils<Store, Vault>
|
|
||||||
}) => Promise<void | DeepPartial<NestedConfigs[key]>>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export class AutoConfig<
|
export class AutoConfig<
|
||||||
Store,
|
Store,
|
||||||
Vault,
|
Vault,
|
||||||
Input,
|
Input extends Record<string, any>,
|
||||||
NestedConfigs extends Record<string, any>,
|
RemoteConfig extends Record<string, any>,
|
||||||
> {
|
> {
|
||||||
constructor(
|
constructor(
|
||||||
readonly configs: AutoConfigFrom<Store, Vault, Input, NestedConfigs>,
|
readonly autoconfig: (options: {
|
||||||
readonly path: keyof AutoConfigFrom<Store, Vault, Input, NestedConfigs>,
|
effects: Effects
|
||||||
|
localConfig: Input
|
||||||
|
remoteConfig: RemoteConfig
|
||||||
|
utils: Utils<Store, Vault>
|
||||||
|
}) => Promise<void | DeepPartial<RemoteConfig>>,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async check(
|
async check(
|
||||||
@@ -39,19 +27,15 @@ export class AutoConfig<
|
|||||||
...options,
|
...options,
|
||||||
utils: utils<Store, Vault>(options.effects),
|
utils: utils<Store, Vault>(options.effects),
|
||||||
localConfig: options.localConfig as Input,
|
localConfig: options.localConfig as Input,
|
||||||
remoteConfig: options.remoteConfig as any,
|
remoteConfig: options.remoteConfig as RemoteConfig,
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
!deepEqual(
|
!deepEqual(
|
||||||
origConfig,
|
origConfig,
|
||||||
deepMerge(
|
deepMerge({}, options.localConfig, await this.autoconfig(newOptions)),
|
||||||
{},
|
|
||||||
options.localConfig,
|
|
||||||
await this.configs[this.path].autoConfig(newOptions),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
throw new Error(`Check failed for ${this.path}`)
|
throw new Error(`Check failed`)
|
||||||
}
|
}
|
||||||
async autoConfigure(
|
async autoConfigure(
|
||||||
options: Parameters<AutoConfigure["autoConfigure"]>[0],
|
options: Parameters<AutoConfigure["autoConfigure"]>[0],
|
||||||
@@ -64,8 +48,8 @@ export class AutoConfig<
|
|||||||
}
|
}
|
||||||
return deepMerge(
|
return deepMerge(
|
||||||
{},
|
{},
|
||||||
options.localConfig,
|
options.remoteConfig,
|
||||||
await this.configs[this.path].autoConfig(newOptions),
|
await this.autoconfig(newOptions),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,22 @@
|
|||||||
import { Config } from "../config/builder/config"
|
import { Config } from "../config/builder/config"
|
||||||
import { SDKManifest } from "../manifest/ManifestTypes"
|
import { SDKManifest } from "../manifest/ManifestTypes"
|
||||||
import { AutoConfig, AutoConfigFrom } from "./AutoConfig"
|
import { AutoConfig } from "./AutoConfig"
|
||||||
|
|
||||||
export function setupAutoConfig<
|
export function setupAutoConfig<
|
||||||
Store,
|
Store,
|
||||||
Vault,
|
Vault,
|
||||||
Input extends Record<string, any>,
|
Input extends Record<string, any>,
|
||||||
Manifest extends SDKManifest,
|
Manifest extends SDKManifest,
|
||||||
NestedConfigs extends {
|
|
||||||
[key in keyof Manifest["dependencies"]]: unknown
|
|
||||||
},
|
|
||||||
>(
|
>(
|
||||||
_config: Config<Input, Store, Vault>,
|
_config: Config<Input, Store, Vault>,
|
||||||
autoConfigs: AutoConfigFrom<Store, Vault, Input, NestedConfigs>,
|
autoConfigs: {
|
||||||
) {
|
[key in keyof Manifest["dependencies"] & string]: AutoConfig<
|
||||||
type C = typeof autoConfigs
|
|
||||||
const answer = { ...autoConfigs } as unknown as {
|
|
||||||
[k in keyof C]: AutoConfig<Store, Vault, Input, NestedConfigs>
|
|
||||||
}
|
|
||||||
for (const key in autoConfigs) {
|
|
||||||
answer[key as keyof typeof autoConfigs] = new AutoConfig<
|
|
||||||
Store,
|
Store,
|
||||||
Vault,
|
Vault,
|
||||||
Input,
|
Input,
|
||||||
NestedConfigs
|
any
|
||||||
>(autoConfigs, key as keyof typeof autoConfigs)
|
>
|
||||||
}
|
},
|
||||||
return answer
|
) {
|
||||||
|
return autoConfigs
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,49 @@
|
|||||||
import { StartSdk } from "../StartSdk"
|
import { StartSdk } from "../StartSdk"
|
||||||
|
import { setupManifest } from "../manifest/setupManifest"
|
||||||
|
|
||||||
export type Manifest = any
|
export type Manifest = any
|
||||||
export const sdk = StartSdk.of()
|
export const sdk = StartSdk.of()
|
||||||
.withManifest({} as any)
|
.withManifest(
|
||||||
|
setupManifest({
|
||||||
|
id: "testOutput",
|
||||||
|
title: "",
|
||||||
|
version: "1.0",
|
||||||
|
releaseNotes: "",
|
||||||
|
license: "",
|
||||||
|
replaces: [],
|
||||||
|
wrapperRepo: "",
|
||||||
|
upstreamRepo: "",
|
||||||
|
supportSite: "",
|
||||||
|
marketingSite: "",
|
||||||
|
donationUrl: null,
|
||||||
|
description: {
|
||||||
|
short: "",
|
||||||
|
long: "",
|
||||||
|
},
|
||||||
|
assets: {
|
||||||
|
icon: "",
|
||||||
|
instructions: "",
|
||||||
|
license: "",
|
||||||
|
},
|
||||||
|
containers: {},
|
||||||
|
volumes: {},
|
||||||
|
alerts: {
|
||||||
|
install: null,
|
||||||
|
update: null,
|
||||||
|
uninstall: null,
|
||||||
|
restore: null,
|
||||||
|
start: null,
|
||||||
|
stop: null,
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
remoteTest: {
|
||||||
|
description: "",
|
||||||
|
requirement: { how: "", type: "opt-in" },
|
||||||
|
version: "1.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
.withStore<{ storeRoot: { storeLeaf: "value" } }>()
|
.withStore<{ storeRoot: { storeLeaf: "value" } }>()
|
||||||
.withVault<{ vaultRoot: "value" }>()
|
.withVault<{ vaultRoot: "value" }>()
|
||||||
.build(true)
|
.build(true)
|
||||||
|
|||||||
27
lib/test/setupAutoConfig.test.ts
Normal file
27
lib/test/setupAutoConfig.test.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { sdk } from "./output.sdk"
|
||||||
|
|
||||||
|
describe("setupAutoConfig", () => {
|
||||||
|
test("test", () => {
|
||||||
|
const testConfig = sdk.Config.of({
|
||||||
|
test: sdk.Value.text({
|
||||||
|
name: "testValue",
|
||||||
|
required: false,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
const testConfig2 = sdk.Config.of({
|
||||||
|
test2: sdk.Value.text({
|
||||||
|
name: "testValue2",
|
||||||
|
required: false,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
const remoteTest = sdk.AutoConfig.of({
|
||||||
|
localConfig: testConfig,
|
||||||
|
remoteConfig: testConfig2,
|
||||||
|
autoconfig: async ({}) => {},
|
||||||
|
})
|
||||||
|
sdk.setupAutoConfig(testConfig, {
|
||||||
|
remoteTest,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -27,11 +27,6 @@ import {
|
|||||||
Path,
|
Path,
|
||||||
} from "../dependency/setupDependencyMounts"
|
} from "../dependency/setupDependencyMounts"
|
||||||
|
|
||||||
// prettier-ignore
|
|
||||||
type skipFirstParam<A> =
|
|
||||||
A extends [any, ...infer B] ? B :
|
|
||||||
A extends [] ? [] :
|
|
||||||
never
|
|
||||||
export type Utils<Store, Vault, WrapperOverWrite = { const: never }> = {
|
export type Utils<Store, Vault, WrapperOverWrite = { const: never }> = {
|
||||||
createOrUpdateVault: (opts: {
|
createOrUpdateVault: (opts: {
|
||||||
key: string
|
key: string
|
||||||
|
|||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -20,7 +20,7 @@
|
|||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"tsc-multi": "^0.6.1",
|
"tsc-multi": "^0.6.1",
|
||||||
"tsconfig-paths": "^3.14.2",
|
"tsconfig-paths": "^3.14.2",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.4",
|
||||||
"vitest": "^0.29.2"
|
"vitest": "^0.29.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user