mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-31 04:23:40 +00:00
chore: Update the types for changes that Matt wanted with sdk + examples
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
import type { DependencyKind } from "./DependencyKind";
|
|
||||||
|
|
||||||
export interface DependencyRequirement { id: string, kind: DependencyKind, healthChecks: string[], }
|
export type DependencyRequirement = { "kind": "running", id: string, healthChecks: string[], versionSpec: string, url: string, } | { "kind": "exists", id: string, versionSpec: string, url: string, };
|
||||||
@@ -412,7 +412,7 @@ pub struct StaticDependencyInfo {
|
|||||||
pub icon: DataUrl<'static>,
|
pub icon: DataUrl<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
#[serde(tag = "kind")]
|
#[serde(tag = "kind")]
|
||||||
pub enum CurrentDependencyInfo {
|
pub enum CurrentDependencyInfo {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
use std::net::Ipv4Addr;
|
||||||
use std::os::unix::process::CommandExt;
|
use std::os::unix::process::CommandExt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
|
|
||||||
use clap::builder::ValueParserFactory;
|
use clap::builder::ValueParserFactory;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
@@ -765,8 +765,8 @@ async fn get_configured(context: EffectContext, _: Empty) -> Result<Value, Error
|
|||||||
let package = peeked
|
let package = peeked
|
||||||
.as_public()
|
.as_public()
|
||||||
.as_package_data()
|
.as_package_data()
|
||||||
.as_idx(&package_id)
|
.as_idx(package_id)
|
||||||
.or_not_found(&package_id)?
|
.or_not_found(package_id)?
|
||||||
.as_status()
|
.as_status()
|
||||||
.as_configured()
|
.as_configured()
|
||||||
.de()?;
|
.de()?;
|
||||||
@@ -1070,28 +1070,39 @@ enum DependencyKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
|
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase", tag = "kind")]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
struct DependencyRequirement {
|
enum DependencyRequirement {
|
||||||
#[ts(type = "string")]
|
Running {
|
||||||
id: PackageId,
|
#[ts(type = "string")]
|
||||||
kind: DependencyKind,
|
id: PackageId,
|
||||||
#[serde(default)]
|
#[ts(type = "string[]")]
|
||||||
#[ts(type = "string[]")]
|
#[serde(rename = "healthChecks")]
|
||||||
health_checks: BTreeSet<HealthCheckId>,
|
health_checks: BTreeSet<HealthCheckId>,
|
||||||
|
#[serde(rename = "versionSpec")]
|
||||||
|
version_spec: String,
|
||||||
|
url: String,
|
||||||
|
},
|
||||||
|
Exists {
|
||||||
|
#[ts(type = "string")]
|
||||||
|
id: PackageId,
|
||||||
|
#[serde(rename = "versionSpec")]
|
||||||
|
version_spec: String,
|
||||||
|
url: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
// filebrowser:exists,bitcoind:running:foo+bar+baz
|
// filebrowser:exists,bitcoind:running:foo+bar+baz
|
||||||
impl FromStr for DependencyRequirement {
|
impl FromStr for DependencyRequirement {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s.split_once(':') {
|
match s.split_once(':') {
|
||||||
Some((id, "e")) | Some((id, "exists")) => Ok(Self {
|
Some((id, "e")) | Some((id, "exists")) => Ok(Self::Exists {
|
||||||
id: id.parse()?,
|
id: id.parse()?,
|
||||||
kind: DependencyKind::Exists,
|
url: "".to_string(),
|
||||||
health_checks: BTreeSet::new(),
|
version_spec: "*".to_string(),
|
||||||
}),
|
}),
|
||||||
Some((id, rest)) => {
|
Some((id, rest)) => {
|
||||||
let health_checks = match rest.split_once(":") {
|
let health_checks = match rest.split_once(':') {
|
||||||
Some(("r", rest)) | Some(("running", rest)) => rest
|
Some(("r", rest)) | Some(("running", rest)) => rest
|
||||||
.split('+')
|
.split('+')
|
||||||
.map(|id| id.parse().map_err(Error::from))
|
.map(|id| id.parse().map_err(Error::from))
|
||||||
@@ -1108,16 +1119,18 @@ impl FromStr for DependencyRequirement {
|
|||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
}?;
|
}?;
|
||||||
Ok(Self {
|
Ok(Self::Running {
|
||||||
id: id.parse()?,
|
id: id.parse()?,
|
||||||
kind: DependencyKind::Running,
|
|
||||||
health_checks,
|
health_checks,
|
||||||
|
url: "".to_string(),
|
||||||
|
version_spec: "*".to_string(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
None => Ok(Self {
|
None => Ok(Self::Running {
|
||||||
id: s.parse()?,
|
id: s.parse()?,
|
||||||
kind: DependencyKind::Running,
|
|
||||||
health_checks: BTreeSet::new(),
|
health_checks: BTreeSet::new(),
|
||||||
|
url: "".to_string(),
|
||||||
|
version_spec: "*".to_string(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1149,23 +1162,19 @@ async fn set_dependencies(
|
|||||||
let dependencies = CurrentDependencies(
|
let dependencies = CurrentDependencies(
|
||||||
dependencies
|
dependencies
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(
|
.map(|dependency| match dependency {
|
||||||
|DependencyRequirement {
|
DependencyRequirement::Exists {
|
||||||
id,
|
id,
|
||||||
kind,
|
url,
|
||||||
health_checks,
|
version_spec,
|
||||||
}| {
|
} => (id, CurrentDependencyInfo::Exists),
|
||||||
(
|
DependencyRequirement::Running {
|
||||||
id,
|
id,
|
||||||
match kind {
|
health_checks,
|
||||||
DependencyKind::Exists => CurrentDependencyInfo::Exists,
|
url,
|
||||||
DependencyKind::Running => {
|
version_spec,
|
||||||
CurrentDependencyInfo::Running { health_checks }
|
} => (id, CurrentDependencyInfo::Running { health_checks }),
|
||||||
}
|
})
|
||||||
},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
for (dep, entry) in db.as_public_mut().as_package_data_mut().as_entries_mut()? {
|
for (dep, entry) in db.as_public_mut().as_package_data_mut().as_entries_mut()? {
|
||||||
|
|||||||
18
sdk/lib/Dependency.ts
Normal file
18
sdk/lib/Dependency.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Checker } from "./emverLite/mod"
|
||||||
|
|
||||||
|
export class Dependency {
|
||||||
|
constructor(
|
||||||
|
readonly data:
|
||||||
|
| {
|
||||||
|
type: "running"
|
||||||
|
versionSpec: Checker
|
||||||
|
url: string
|
||||||
|
healthChecks: string[]
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: "exists"
|
||||||
|
versionSpec: Checker
|
||||||
|
url: string
|
||||||
|
},
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -50,7 +50,11 @@ import { Uninstall, UninstallFn, setupUninstall } from "./inits/setupUninstall"
|
|||||||
import { setupMain } from "./mainFn"
|
import { setupMain } from "./mainFn"
|
||||||
import { defaultTrigger } from "./trigger/defaultTrigger"
|
import { defaultTrigger } from "./trigger/defaultTrigger"
|
||||||
import { changeOnFirstSuccess, cooldownTrigger } from "./trigger"
|
import { changeOnFirstSuccess, cooldownTrigger } from "./trigger"
|
||||||
import setupConfig, { Read, Save } from "./config/setupConfig"
|
import setupConfig, {
|
||||||
|
DependenciesReceipt,
|
||||||
|
Read,
|
||||||
|
Save,
|
||||||
|
} from "./config/setupConfig"
|
||||||
import {
|
import {
|
||||||
InterfacesReceipt,
|
InterfacesReceipt,
|
||||||
SetInterfaces,
|
SetInterfaces,
|
||||||
@@ -72,6 +76,9 @@ import { getStore } from "./store/getStore"
|
|||||||
import { CommandOptions, MountOptions, Overlay } from "./util/Overlay"
|
import { CommandOptions, MountOptions, Overlay } from "./util/Overlay"
|
||||||
import { splitCommand } from "./util/splitCommand"
|
import { splitCommand } from "./util/splitCommand"
|
||||||
import { Mounts } from "./mainFn/Mounts"
|
import { Mounts } from "./mainFn/Mounts"
|
||||||
|
import { Dependency } from "./Dependency"
|
||||||
|
import * as T from "./types"
|
||||||
|
import { Checker, EmVer } from "./emverLite/mod"
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
type AnyNeverCond<T extends any[], Then, Else> =
|
type AnyNeverCond<T extends any[], Then, Else> =
|
||||||
@@ -104,6 +111,20 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
build(isReady: AnyNeverCond<[Manifest, Store], "Build not ready", true>) {
|
build(isReady: AnyNeverCond<[Manifest, Store], "Build not ready", true>) {
|
||||||
|
type DependencyType = {
|
||||||
|
[K in keyof {
|
||||||
|
[K in keyof Manifest["dependencies"]]: Manifest["dependencies"][K]["optional"] extends false
|
||||||
|
? K
|
||||||
|
: never
|
||||||
|
}]: Dependency
|
||||||
|
} & {
|
||||||
|
[K in keyof {
|
||||||
|
[K in keyof Manifest["dependencies"]]: Manifest["dependencies"][K]["optional"] extends true
|
||||||
|
? K
|
||||||
|
: never
|
||||||
|
}]?: Dependency
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serviceInterface: {
|
serviceInterface: {
|
||||||
getOwn: <E extends Effects>(effects: E, id: ServiceInterfaceId) =>
|
getOwn: <E extends Effects>(effects: E, id: ServiceInterfaceId) =>
|
||||||
@@ -233,6 +254,11 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
|||||||
HealthCheck: {
|
HealthCheck: {
|
||||||
of: healthCheck,
|
of: healthCheck,
|
||||||
},
|
},
|
||||||
|
Dependency: {
|
||||||
|
of(data: Dependency["data"]) {
|
||||||
|
return new Dependency({ ...data })
|
||||||
|
},
|
||||||
|
},
|
||||||
healthCheck: {
|
healthCheck: {
|
||||||
checkPortListening,
|
checkPortListening,
|
||||||
checkWebUrl,
|
checkWebUrl,
|
||||||
@@ -278,12 +304,48 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
|||||||
> | null
|
> | null
|
||||||
},
|
},
|
||||||
) => setupDependencyConfig<Store, Input, Manifest>(config, autoConfigs),
|
) => setupDependencyConfig<Store, Input, Manifest>(config, autoConfigs),
|
||||||
|
setupDependencies: <Input extends Record<string, any>>(
|
||||||
|
fn: (options: {
|
||||||
|
effects: Effects
|
||||||
|
input: Input | null
|
||||||
|
}) => Promise<DependencyType>,
|
||||||
|
) => {
|
||||||
|
return async (options: { effects: Effects; input: Input }) => {
|
||||||
|
const dependencyType = await fn(options)
|
||||||
|
return await options.effects.setDependencies({
|
||||||
|
dependencies: Object.entries(dependencyType).map(
|
||||||
|
([
|
||||||
|
id,
|
||||||
|
{
|
||||||
|
data: { versionSpec, ...x },
|
||||||
|
},
|
||||||
|
]) => ({
|
||||||
|
id,
|
||||||
|
...x,
|
||||||
|
...(x.type === "running"
|
||||||
|
? {
|
||||||
|
kind: "running",
|
||||||
|
healthChecks: x.healthChecks,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
kind: "exists",
|
||||||
|
}),
|
||||||
|
versionSpec: versionSpec.range,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
setupExports: (fn: SetupExports<Store>) => fn,
|
setupExports: (fn: SetupExports<Store>) => fn,
|
||||||
setupInit: (
|
setupInit: (
|
||||||
migrations: Migrations<Manifest, Store>,
|
migrations: Migrations<Manifest, Store>,
|
||||||
install: Install<Manifest, Store>,
|
install: Install<Manifest, Store>,
|
||||||
uninstall: Uninstall<Manifest, Store>,
|
uninstall: Uninstall<Manifest, Store>,
|
||||||
setInterfaces: SetInterfaces<Manifest, Store, any, any>,
|
setInterfaces: SetInterfaces<Manifest, Store, any, any>,
|
||||||
|
setDependencies: (options: {
|
||||||
|
effects: Effects
|
||||||
|
input: any
|
||||||
|
}) => Promise<DependenciesReceipt>,
|
||||||
setupExports: SetupExports<Store>,
|
setupExports: SetupExports<Store>,
|
||||||
) =>
|
) =>
|
||||||
setupInit<Manifest, Store>(
|
setupInit<Manifest, Store>(
|
||||||
@@ -292,6 +354,7 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
|||||||
uninstall,
|
uninstall,
|
||||||
setInterfaces,
|
setInterfaces,
|
||||||
setupExports,
|
setupExports,
|
||||||
|
setDependencies,
|
||||||
),
|
),
|
||||||
setupInstall: (fn: InstallFn<Manifest, Store>) => Install.of(fn),
|
setupInstall: (fn: InstallFn<Manifest, Store>) => Install.of(fn),
|
||||||
setupInterfaces: <
|
setupInterfaces: <
|
||||||
@@ -346,6 +409,9 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
|||||||
spec: Spec,
|
spec: Spec,
|
||||||
) => Config.of<Spec, Store>(spec),
|
) => Config.of<Spec, Store>(spec),
|
||||||
},
|
},
|
||||||
|
Checker: {
|
||||||
|
parse: Checker.parse,
|
||||||
|
},
|
||||||
Daemons: {
|
Daemons: {
|
||||||
of(config: {
|
of(config: {
|
||||||
effects: Effects
|
effects: Effects
|
||||||
@@ -360,13 +426,17 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
|||||||
LocalConfig extends Record<string, any>,
|
LocalConfig extends Record<string, any>,
|
||||||
RemoteConfig extends Record<string, any>,
|
RemoteConfig extends Record<string, any>,
|
||||||
>({
|
>({
|
||||||
localConfig,
|
localConfigSpec,
|
||||||
remoteConfig,
|
remoteConfigSpec,
|
||||||
dependencyConfig,
|
dependencyConfig,
|
||||||
update,
|
update,
|
||||||
}: {
|
}: {
|
||||||
localConfig: Config<LocalConfig, Store> | Config<LocalConfig, never>
|
localConfigSpec:
|
||||||
remoteConfig: Config<RemoteConfig, any> | Config<RemoteConfig, never>
|
| Config<LocalConfig, Store>
|
||||||
|
| Config<LocalConfig, never>
|
||||||
|
remoteConfigSpec:
|
||||||
|
| Config<RemoteConfig, any>
|
||||||
|
| Config<RemoteConfig, never>
|
||||||
dependencyConfig: (options: {
|
dependencyConfig: (options: {
|
||||||
effects: Effects
|
effects: Effects
|
||||||
localConfig: LocalConfig
|
localConfig: LocalConfig
|
||||||
@@ -381,6 +451,10 @@ export class StartSdk<Manifest extends SDKManifest, Store> {
|
|||||||
>(dependencyConfig, update)
|
>(dependencyConfig, update)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
EmVer: {
|
||||||
|
from: EmVer.from,
|
||||||
|
parse: EmVer.parse,
|
||||||
|
},
|
||||||
List: {
|
List: {
|
||||||
text: List.text,
|
text: List.text,
|
||||||
number: List.number,
|
number: List.number,
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ export class EmVer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
return `${this.values.join(".")}${this.extra ? `-${this.extra}` : ""}`
|
return `${this.values.join(".")}${this.extra ? `-${this.extra}` : ""}` as ValidEmVer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,6 +179,7 @@ export class Checker {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
static parse(range: string | Checker): Checker {
|
static parse(range: string | Checker): Checker {
|
||||||
|
console.log(`Parser (${range})`)
|
||||||
if (range instanceof Checker) {
|
if (range instanceof Checker) {
|
||||||
return range
|
return range
|
||||||
}
|
}
|
||||||
@@ -193,10 +194,12 @@ export class Checker {
|
|||||||
return new Checker((version) => {
|
return new Checker((version) => {
|
||||||
EmVer.from(version)
|
EmVer.from(version)
|
||||||
return true
|
return true
|
||||||
})
|
}, range)
|
||||||
}
|
}
|
||||||
|
if (range.startsWith("!!")) return Checker.parse(range.substring(2))
|
||||||
if (range.startsWith("!")) {
|
if (range.startsWith("!")) {
|
||||||
return Checker.parse(range.substring(1)).not()
|
const tempValue = Checker.parse(range.substring(1))
|
||||||
|
return new Checker((x) => !tempValue.check(x), range)
|
||||||
}
|
}
|
||||||
const starSubMatches = starSub.exec(range)
|
const starSubMatches = starSub.exec(range)
|
||||||
if (starSubMatches != null) {
|
if (starSubMatches != null) {
|
||||||
@@ -210,7 +213,7 @@ export class Checker {
|
|||||||
!v.greaterThan(emVarUpper) &&
|
!v.greaterThan(emVarUpper) &&
|
||||||
!v.equals(emVarUpper)
|
!v.equals(emVarUpper)
|
||||||
)
|
)
|
||||||
})
|
}, range)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (range.substring(0, 2)) {
|
switch (range.substring(0, 2)) {
|
||||||
@@ -219,14 +222,14 @@ export class Checker {
|
|||||||
return new Checker((version) => {
|
return new Checker((version) => {
|
||||||
const v = EmVer.from(version)
|
const v = EmVer.from(version)
|
||||||
return v.greaterThanOrEqual(emVar)
|
return v.greaterThanOrEqual(emVar)
|
||||||
})
|
}, range)
|
||||||
}
|
}
|
||||||
case "<=": {
|
case "<=": {
|
||||||
const emVar = EmVer.parse(range.substring(2))
|
const emVar = EmVer.parse(range.substring(2))
|
||||||
return new Checker((version) => {
|
return new Checker((version) => {
|
||||||
const v = EmVer.from(version)
|
const v = EmVer.from(version)
|
||||||
return v.lessThanOrEqual(emVar)
|
return v.lessThanOrEqual(emVar)
|
||||||
})
|
}, range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,21 +239,21 @@ export class Checker {
|
|||||||
return new Checker((version) => {
|
return new Checker((version) => {
|
||||||
const v = EmVer.from(version)
|
const v = EmVer.from(version)
|
||||||
return v.greaterThan(emVar)
|
return v.greaterThan(emVar)
|
||||||
})
|
}, range)
|
||||||
}
|
}
|
||||||
case "<": {
|
case "<": {
|
||||||
const emVar = EmVer.parse(range.substring(1))
|
const emVar = EmVer.parse(range.substring(1))
|
||||||
return new Checker((version) => {
|
return new Checker((version) => {
|
||||||
const v = EmVer.from(version)
|
const v = EmVer.from(version)
|
||||||
return v.lessThan(emVar)
|
return v.lessThan(emVar)
|
||||||
})
|
}, range)
|
||||||
}
|
}
|
||||||
case "=": {
|
case "=": {
|
||||||
const emVar = EmVer.parse(range.substring(1))
|
const emVar = EmVer.parse(range.substring(1))
|
||||||
return new Checker((version) => {
|
return new Checker((version) => {
|
||||||
const v = EmVer.from(version)
|
const v = EmVer.from(version)
|
||||||
return v.equals(emVar)
|
return v.equals(emVar)
|
||||||
})
|
}, `=${emVar.toString()}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Error("Couldn't parse range: " + range)
|
throw new Error("Couldn't parse range: " + range)
|
||||||
@@ -261,40 +264,53 @@ export class Checker {
|
|||||||
* a pattern
|
* a pattern
|
||||||
*/
|
*/
|
||||||
public readonly check: (value: ValidEmVer | EmVer) => boolean,
|
public readonly check: (value: ValidEmVer | EmVer) => boolean,
|
||||||
|
private readonly _range: string,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
get range() {
|
||||||
|
return this._range as ValidEmVerRange
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used when we want the `and` condition with another checker
|
* Used when we want the `and` condition with another checker
|
||||||
*/
|
*/
|
||||||
public and(...others: (Checker | string)[]): Checker {
|
public and(...others: (Checker | string)[]): Checker {
|
||||||
return new Checker((value) => {
|
const othersCheck = others.map(Checker.parse)
|
||||||
if (!this.check(value)) {
|
return new Checker(
|
||||||
return false
|
(value) => {
|
||||||
}
|
if (!this.check(value)) {
|
||||||
for (const other of others) {
|
|
||||||
if (!Checker.parse(other).check(value)) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
for (const other of othersCheck) {
|
||||||
return true
|
if (!other.check(value)) {
|
||||||
})
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
othersCheck.map((x) => x._range).join(" && "),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used when we want the `or` condition with another checker
|
* Used when we want the `or` condition with another checker
|
||||||
*/
|
*/
|
||||||
public or(...others: (Checker | string)[]): Checker {
|
public or(...others: (Checker | string)[]): Checker {
|
||||||
return new Checker((value) => {
|
const othersCheck = others.map(Checker.parse)
|
||||||
if (this.check(value)) {
|
return new Checker(
|
||||||
return true
|
(value) => {
|
||||||
}
|
if (this.check(value)) {
|
||||||
for (const other of others) {
|
|
||||||
if (Checker.parse(other).check(value)) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
for (const other of othersCheck) {
|
||||||
return false
|
if (other.check(value)) {
|
||||||
})
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
othersCheck.map((x) => x._range).join(" || "),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -302,6 +318,7 @@ export class Checker {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public not(): Checker {
|
public not(): Checker {
|
||||||
return new Checker((value) => !this.check(value))
|
let newRange = `!${this._range}`
|
||||||
|
return Checker.parse(newRange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
|
import { DependenciesReceipt } from "../config/setupConfig"
|
||||||
import { SetInterfaces } from "../interfaces/setupInterfaces"
|
import { SetInterfaces } from "../interfaces/setupInterfaces"
|
||||||
import { SDKManifest } from "../manifest/ManifestTypes"
|
import { SDKManifest } from "../manifest/ManifestTypes"
|
||||||
import { ExpectedExports, ExposeUiPaths, ExposeUiPathsAll } from "../types"
|
import {
|
||||||
|
Effects,
|
||||||
|
ExpectedExports,
|
||||||
|
ExposeUiPaths,
|
||||||
|
ExposeUiPathsAll,
|
||||||
|
} from "../types"
|
||||||
import { Migrations } from "./migrations/setupMigrations"
|
import { Migrations } from "./migrations/setupMigrations"
|
||||||
import { SetupExports } from "./setupExports"
|
import { SetupExports } from "./setupExports"
|
||||||
import { Install } from "./setupInstall"
|
import { Install } from "./setupInstall"
|
||||||
@@ -12,6 +18,10 @@ export function setupInit<Manifest extends SDKManifest, Store>(
|
|||||||
uninstall: Uninstall<Manifest, Store>,
|
uninstall: Uninstall<Manifest, Store>,
|
||||||
setInterfaces: SetInterfaces<Manifest, Store, any, any>,
|
setInterfaces: SetInterfaces<Manifest, Store, any, any>,
|
||||||
setupExports: SetupExports<Store>,
|
setupExports: SetupExports<Store>,
|
||||||
|
setDependencies: (options: {
|
||||||
|
effects: Effects
|
||||||
|
input: any
|
||||||
|
}) => Promise<DependenciesReceipt>,
|
||||||
): {
|
): {
|
||||||
init: ExpectedExports.init
|
init: ExpectedExports.init
|
||||||
uninit: ExpectedExports.uninit
|
uninit: ExpectedExports.uninit
|
||||||
@@ -27,6 +37,7 @@ export function setupInit<Manifest extends SDKManifest, Store>(
|
|||||||
const { services, ui } = await setupExports(opts)
|
const { services, ui } = await setupExports(opts)
|
||||||
await opts.effects.exposeForDependents({ paths: services })
|
await opts.effects.exposeForDependents({ paths: services })
|
||||||
await opts.effects.exposeUi(forExpose(ui))
|
await opts.effects.exposeUi(forExpose(ui))
|
||||||
|
await setDependencies({ effects: opts.effects, input: null })
|
||||||
},
|
},
|
||||||
uninit: async (opts) => {
|
uninit: async (opts) => {
|
||||||
await migrations.uninit(opts)
|
await migrations.uninit(opts)
|
||||||
|
|||||||
@@ -75,31 +75,13 @@ export type SDKManifest = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ManifestDependency {
|
export interface ManifestDependency {
|
||||||
/** The range of versions that would satisfy the dependency
|
|
||||||
*
|
|
||||||
* ie: >=3.4.5 <4.0.0
|
|
||||||
*/
|
|
||||||
version: string
|
|
||||||
/**
|
/**
|
||||||
* A human readable explanation on what the dependency is used for
|
* A human readable explanation on what the dependency is used for
|
||||||
*/
|
*/
|
||||||
description: string | null
|
description: string | null
|
||||||
requirement:
|
/**
|
||||||
| {
|
* Determines if the dependency is optional or not. Times that optional that are good include such situations
|
||||||
type: "opt-in"
|
* such as being able to toggle other services or to use a different service for the same purpose.
|
||||||
/**
|
*/
|
||||||
* The human readable explanation on how to opt-in to the dependency
|
optional: boolean
|
||||||
*/
|
|
||||||
how: string
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: "opt-out"
|
|
||||||
/**
|
|
||||||
* The human readable explanation on how to opt-out to the dependency
|
|
||||||
*/
|
|
||||||
how: string
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: "required"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -414,8 +414,7 @@ describe("values", () => {
|
|||||||
dependencies: {
|
dependencies: {
|
||||||
remoteTest: {
|
remoteTest: {
|
||||||
description: "",
|
description: "",
|
||||||
requirement: { how: "", type: "opt-in" },
|
optional: true,
|
||||||
version: "1.0",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -35,8 +35,7 @@ export const sdk = StartSdk.of()
|
|||||||
dependencies: {
|
dependencies: {
|
||||||
remoteTest: {
|
remoteTest: {
|
||||||
description: "",
|
description: "",
|
||||||
requirement: { how: "", type: "opt-in" },
|
optional: false,
|
||||||
version: "1.0",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ describe("setupDependencyConfig", () => {
|
|||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
const remoteTest = sdk.DependencyConfig.of({
|
const remoteTest = sdk.DependencyConfig.of({
|
||||||
localConfig: testConfig,
|
localConfigSpec: testConfig,
|
||||||
remoteConfig: testConfig2,
|
remoteConfigSpec: testConfig2,
|
||||||
dependencyConfig: async ({}) => {},
|
dependencyConfig: async ({}) => {},
|
||||||
})
|
})
|
||||||
sdk.setupDependencyConfig(testConfig, {
|
sdk.setupDependencyConfig(testConfig, {
|
||||||
|
|||||||
@@ -600,7 +600,8 @@ export type KnownError =
|
|||||||
|
|
||||||
export type Dependency = {
|
export type Dependency = {
|
||||||
id: PackageId
|
id: PackageId
|
||||||
kind: DependencyKind
|
versionSpec: string
|
||||||
|
url: string
|
||||||
} & ({ kind: "exists" } | { kind: "running"; healthChecks: string[] })
|
} & ({ kind: "exists" } | { kind: "running"; healthChecks: string[] })
|
||||||
export type Dependencies = Array<Dependency>
|
export type Dependencies = Array<Dependency>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user