chore: Add in some more files for the testing of the sdk and the rust interface

This commit is contained in:
J H
2024-03-13 16:23:24 -06:00
parent ba325b1581
commit b6fe0be1b2
46 changed files with 451 additions and 116 deletions

View File

@@ -173,7 +173,11 @@ container-runtime/node_modules: container-runtime/package.json container-runtime
npm --prefix container-runtime ci npm --prefix container-runtime ci
touch container-runtime/node_modules touch container-runtime/node_modules
sdk/dist: $(shell git ls-files sdk) core/startos/bindings: $(CORE_SRC) $(ENVIRONMENT_FILE) $(PLATFORM_FILE)
(cd core/ && cargo test)
touch core/startos/bindings
sdk/dist: $(shell git ls-files sdk) core/startos/bindings
(cd sdk && make bundle) (cd sdk && make bundle)
container-runtime/dist: container-runtime/node_modules $(shell git ls-files container-runtime/src) container-runtime/package.json container-runtime/tsconfig.json container-runtime/dist: container-runtime/node_modules $(shell git ls-files container-runtime/src) container-runtime/package.json container-runtime/tsconfig.json

31
core/Cargo.lock generated
View File

@@ -2,6 +2,12 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "Inflector"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
[[package]] [[package]]
name = "addr2line" name = "addr2line"
version = "0.21.0" version = "0.21.0"
@@ -2679,6 +2685,7 @@ dependencies = [
"tokio", "tokio",
"torut", "torut",
"tracing", "tracing",
"ts-rs",
"yasi", "yasi",
] ]
@@ -4723,6 +4730,7 @@ dependencies = [
"tracing-journald", "tracing-journald",
"tracing-subscriber", "tracing-subscriber",
"trust-dns-server", "trust-dns-server",
"ts-rs",
"typed-builder", "typed-builder",
"url", "url",
"urlencoding", "urlencoding",
@@ -5426,6 +5434,29 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "ts-rs"
version = "7.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2cae1fc5d05d47aa24b64f9a4f7cba24cdc9187a2084dd97ac57bef5eccae6"
dependencies = [
"thiserror",
"ts-rs-macros",
]
[[package]]
name = "ts-rs-macros"
version = "7.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73f7f9b821696963053a89a7bd8b292dc34420aea8294d7b225274d488f3ec92"
dependencies = [
"Inflector",
"proc-macro2",
"quote",
"syn 2.0.52",
"termcolor",
]
[[package]] [[package]]
name = "tungstenite" name = "tungstenite"
version = "0.21.0" version = "0.21.0"

View File

@@ -32,6 +32,7 @@ sqlx = { version = "0.7.2", features = [
"postgres", "postgres",
] } ] }
ssh-key = "0.6.2" ssh-key = "0.6.2"
ts-rs = "7"
thiserror = "1.0" thiserror = "1.0"
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
torut = { git = "https://github.com/Start9Labs/torut.git", branch = "update/dependencies" } torut = { git = "https://github.com/Start9Labs/torut.git", branch = "update/dependencies" }

View File

@@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use crate::{Id, InvalidId}; use crate::{Id, InvalidId};
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, ts_rs::TS)]
pub struct ActionId(Id); pub struct ActionId(Id);
impl FromStr for ActionId { impl FromStr for ActionId {
type Err = InvalidId; type Err = InvalidId;

View File

@@ -4,7 +4,7 @@ use serde::{Deserialize, Deserializer, Serialize};
use crate::Id; use crate::Id;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, ts_rs::TS)]
pub struct HealthCheckId(Id); pub struct HealthCheckId(Id);
impl std::fmt::Display for HealthCheckId { impl std::fmt::Display for HealthCheckId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

View File

@@ -6,7 +6,7 @@ use serde::{Deserialize, Deserializer, Serialize};
use crate::{Id, InvalidId, PackageId, Version}; use crate::{Id, InvalidId, PackageId, Version};
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, ts_rs::TS)]
pub struct ImageId(Id); pub struct ImageId(Id);
impl AsRef<Path> for ImageId { impl AsRef<Path> for ImageId {
fn as_ref(&self) -> &Path { fn as_ref(&self) -> &Path {

View File

@@ -27,12 +27,12 @@ lazy_static::lazy_static! {
pub static ref SYSTEM_ID: Id = Id(InternedString::intern("x_system")); pub static ref SYSTEM_ID: Id = Id(InternedString::intern("x_system"));
} }
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default, ts_rs::TS)]
pub struct Id(InternedString); pub struct Id(#[ts(type = "string")] InternedString);
impl TryFrom<InternedString> for Id { impl TryFrom<InternedString> for Id {
type Error = InvalidId; type Error = InvalidId;
fn try_from(value: InternedString) -> Result<Self, Self::Error> { fn try_from(value: InternedString) -> Result<Self, Self::Error> {
if ID_REGEX.is_match(&*value) { if ID_REGEX.is_match(&value) {
Ok(Id(value)) Ok(Id(value))
} else { } else {
Err(InvalidId) Err(InvalidId)
@@ -52,7 +52,7 @@ impl TryFrom<String> for Id {
impl TryFrom<&str> for Id { impl TryFrom<&str> for Id {
type Error = InvalidId; type Error = InvalidId;
fn try_from(value: &str) -> Result<Self, Self::Error> { fn try_from(value: &str) -> Result<Self, Self::Error> {
if ID_REGEX.is_match(&value) { if ID_REGEX.is_match(value) {
Ok(Id(InternedString::intern(value))) Ok(Id(InternedString::intern(value)))
} else { } else {
Err(InvalidId) Err(InvalidId)
@@ -67,7 +67,7 @@ impl From<Id> for InternedString {
impl std::ops::Deref for Id { impl std::ops::Deref for Id {
type Target = str; type Target = str;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&*self.0 &self.0
} }
} }
impl std::fmt::Display for Id { impl std::fmt::Display for Id {
@@ -77,7 +77,7 @@ impl std::fmt::Display for Id {
} }
impl AsRef<str> for Id { impl AsRef<str> for Id {
fn as_ref(&self) -> &str { fn as_ref(&self) -> &str {
&*self.0 &self.0
} }
} }
impl Borrow<str> for Id { impl Borrow<str> for Id {
@@ -99,7 +99,7 @@ impl Serialize for Id {
where where
Ser: Serializer, Ser: Serializer,
{ {
serializer.serialize_str(&*self) serializer.serialize_str(self)
} }
} }
impl<'q> sqlx::Encode<'q, sqlx::Postgres> for Id { impl<'q> sqlx::Encode<'q, sqlx::Postgres> for Id {

View File

@@ -3,6 +3,7 @@ use std::path::Path;
use std::str::FromStr; use std::str::FromStr;
use serde::{Deserialize, Serialize, Serializer}; use serde::{Deserialize, Serialize, Serializer};
use ts_rs::TS;
use yasi::InternedString; use yasi::InternedString;
use crate::{Id, InvalidId, SYSTEM_ID}; use crate::{Id, InvalidId, SYSTEM_ID};
@@ -10,7 +11,7 @@ use crate::{Id, InvalidId, SYSTEM_ID};
lazy_static::lazy_static! { lazy_static::lazy_static! {
pub static ref SYSTEM_PACKAGE_ID: PackageId = PackageId(SYSTEM_ID.clone()); pub static ref SYSTEM_PACKAGE_ID: PackageId = PackageId(SYSTEM_ID.clone());
} }
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, TS)]
pub struct PackageId(Id); pub struct PackageId(Id);
impl FromStr for PackageId { impl FromStr for PackageId {
type Err = InvalidId; type Err = InvalidId;
@@ -36,7 +37,7 @@ impl From<PackageId> for InternedString {
impl std::ops::Deref for PackageId { impl std::ops::Deref for PackageId {
type Target = str; type Target = str;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&*self.0 &self.0
} }
} }
impl AsRef<PackageId> for PackageId { impl AsRef<PackageId> for PackageId {

View File

@@ -174,6 +174,7 @@ tracing-futures = "0.2.5"
tracing-journald = "0.3.0" tracing-journald = "0.3.0"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
trust-dns-server = "0.23.1" trust-dns-server = "0.23.1"
ts-rs = "7.1.1"
typed-builder = "0.18.0" typed-builder = "0.18.0"
url = { version = "2.4.1", features = ["serde"] } url = { version = "2.4.1", features = ["serde"] }
urlencoding = "2.1.3" urlencoding = "2.1.3"

3
core/startos/Effects.ts Normal file
View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export interface SetStoreParams { value: any, path: string, }

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export interface AddSslOptions { scheme: string | null, preferredExternalPort: number, addXForwardedHeaders: boolean | null, }

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Algorithm = "ecdsa" | "ed25519";

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type BindKind = "static" | "single" | "multi";

View File

@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AddSslOptions } from "./AddSslOptions";
import type { BindKind } from "./BindKind";
export interface BindParams { kind: BindKind, id: string, internalPort: number, scheme: string, preferredExternalPort: number, addSsl: AddSslOptions | null, secure: boolean, ssl: boolean, }

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Callback = () => void;

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export interface ChrootParams { env: string | null, workdir: string | null, user: string | null, path: string, command: string, args: string[], }

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ImageId } from "./ImageId";
export interface CreateOverlayedImageParams { imageId: ImageId, }

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ImageId } from "./ImageId";
export interface DestroyOverlayedImageParams { imageId: ImageId, guid: string, }

View File

@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ActionId } from "./ActionId";
import type { PackageId } from "./PackageId";
export interface ExecuteAction { serviceId: PackageId | null, actionId: ActionId, input: any, }

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export interface ExposeForDependentsParams { paths: string[], }

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ExposedUI } from "./ExposedUI";
export interface ExposeUiParams { paths: Array<ExposedUI>, }

View File

@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Callback } from "./Callback";
import type { GetHostInfoParamsKind } from "./GetHostInfoParamsKind";
export interface GetHostInfoParams { kind: GetHostInfoParamsKind | null, serviceInterfaceId: string, packageId: string | null, callback: Callback, }

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type GetHostInfoParamsKind = "multi";

View File

@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Callback } from "./Callback";
import type { PackageId } from "./PackageId";
export interface GetServiceInterfaceParams { packageId: PackageId | null, serviceInterfaceId: string, callback: Callback, }

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Algorithm } from "./Algorithm";
export interface GetSslCertificateParams { packageId: string | null, hostId: string, algorithm: Algorithm | null, }

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Algorithm } from "./Algorithm";
export interface GetSslKeyParams { packageId: string | null, hostId: string, algorithm: Algorithm | null, }

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { PackageId } from "./PackageId";
export interface GetStoreParams { packageId: PackageId | null, path: string, }

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { PackageId } from "./PackageId";
export interface ParamsMaybePackageId { packageId: PackageId | null, }

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { PackageId } from "./PackageId";
export interface ParamsPackageId { packageId: PackageId, }

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export interface SetConfigured { configured: boolean, }

View File

@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { HealthCheckId } from "./HealthCheckId";
import type { HealthCheckString } from "./HealthCheckString";
export interface SetHealth { name: HealthCheckId, status: HealthCheckString, message: string | null, }

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Status } from "./Status";
export interface SetMainStatus { status: Status, }

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export interface SetStoreParams { value: any, path: string, }

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Status = "running" | "stopped";

View File

@@ -529,9 +529,10 @@ pub struct ExposedDependent {
copyable: Option<bool>, copyable: Option<bool>,
qr: Option<bool>, qr: Option<bool>,
} }
#[derive(Clone, Debug, Deserialize, Serialize, HasModel)] #[derive(Clone, Debug, Deserialize, Serialize, HasModel, ts_rs::TS)]
#[model = "Model<Self>"] #[model = "Model<Self>"]
pub struct ExposedUI { pub struct ExposedUI {
#[ts(type = "string")]
pub path: JsonPointer, pub path: JsonPointer,
pub title: String, pub title: String,
pub description: Option<String>, pub description: Option<String>,

View File

@@ -11,6 +11,7 @@ use models::{ActionId, HealthCheckId, ImageId, PackageId};
use patch_db::json_ptr::JsonPointer; use patch_db::json_ptr::JsonPointer;
use rpc_toolkit::{from_fn, from_fn_async, AnyContext, Context, Empty, HandlerExt, ParentHandler}; use rpc_toolkit::{from_fn, from_fn_async, AnyContext, Context, Empty, HandlerExt, ParentHandler};
use tokio::process::Command; use tokio::process::Command;
use ts_rs::TS;
use crate::db::model::ExposedUI; use crate::db::model::ExposedUI;
use crate::disk::mount::filesystem::idmapped::IdMapped; use crate::disk::mount::filesystem::idmapped::IdMapped;
@@ -127,36 +128,103 @@ pub fn service_effect_handler() -> ParentHandler {
"getServiceInterface", "getServiceInterface",
from_fn_async(get_service_interface).no_cli(), from_fn_async(get_service_interface).no_cli(),
) )
.subcommand("clearBindings", from_fn_async(clear_bindings).no_cli())
.subcommand("bind", from_fn_async(bind).no_cli())
.subcommand("getHostInfo", from_fn_async(get_host_info).no_cli())
// TODO @DrBonez when we get the new api for 4.0 // TODO @DrBonez when we get the new api for 4.0
// .subcommand("setDependencies",from_fn(set_dependencies)) // .subcommand("setDependencies",from_fn_async(set_dependencies).no_cli())
// .subcommand("embassyGetInterface",from_fn(embassy_get_interface)) // .subcommand("embassyGetInterface",from_fn_async(embassy_get_interface).no_cli())
// .subcommand("mount",from_fn(mount)) // .subcommand("mount",from_fn_async(mount).no_cli())
// .subcommand("removeAction",from_fn(remove_action)) // .subcommand("removeAction",from_fn_async(remove_action).no_cli())
// .subcommand("removeAddress",from_fn(remove_address)) // .subcommand("removeAddress",from_fn_async(remove_address).no_cli())
// .subcommand("exportAction",from_fn(export_action)) // .subcommand("exportAction",from_fn_async(export_action).no_cli())
// .subcommand("bind",from_fn(bind)) // .subcommand("clearServiceInterfaces",from_fn_async(clear_network_interfaces).no_cli())
// .subcommand("clearServiceInterfaces",from_fn(clear_network_interfaces)) // .subcommand("exportServiceInterface",from_fn_async(export_network_interface).no_cli())
// .subcommand("exportServiceInterface",from_fn(export_network_interface)) // .subcommand("getHostnames",from_fn_async(get_hostnames).no_cli())
// .subcommand("clearBindings",from_fn(clear_bindings)) // .subcommand("getInterface",from_fn_async(get_interface).no_cli())
// .subcommand("getHostnames",from_fn(get_hostnames)) // .subcommand("listInterface",from_fn_async(list_interface).no_cli())
// .subcommand("getInterface",from_fn(get_interface)) // .subcommand("getIPHostname",from_fn_async(get_ip_hostname).no_cli())
// .subcommand("listInterface",from_fn(list_interface)) // .subcommand("getContainerIp",from_fn_async(get_container_ip).no_cli())
// .subcommand("getIPHostname",from_fn(get_ip_hostname)) // .subcommand("getLocalHostname",from_fn_async(get_local_hostname).no_cli())
// .subcommand("getContainerIp",from_fn(get_container_ip)) // .subcommand("getPrimaryUrl",from_fn_async(get_primary_url).no_cli())
// .subcommand("getLocalHostname",from_fn(get_local_hostname)) // .subcommand("getServicePortForward",from_fn_async(get_service_port_forward).no_cli())
// .subcommand("getPrimaryUrl",from_fn(get_primary_url)) // .subcommand("getServiceTorHostname",from_fn_async(get_service_tor_hostname).no_cli())
// .subcommand("getServicePortForward",from_fn(get_service_port_forward)) // .subcommand("getSystemSmtp",from_fn_async(get_system_smtp).no_cli())
// .subcommand("getServiceTorHostname",from_fn(get_service_tor_hostname)) // .subcommand("reverseProxy",from_fn_async(reverse_proxy).no_cli())
// .subcommand("getSystemSmtp",from_fn(get_system_smtp))
// .subcommand("reverseProxy",from_fn(reverse_pro)xy)
// TODO Callbacks // TODO Callbacks
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser)]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
struct Callback(#[ts(type = "() => void")] i64);
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
enum GetHostInfoParamsKind {
Multi,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
struct GetHostInfoParams {
kind: Option<GetHostInfoParamsKind>,
service_interface_id: String,
package_id: Option<String>,
callback: Callback,
}
async fn get_host_info(
_: AnyContext,
GetHostInfoParams { .. }: GetHostInfoParams,
) -> Result<Value, Error> {
todo!()
}
async fn clear_bindings(context: EffectContext, _: Empty) -> Result<Value, Error> {
todo!()
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
enum BindKind {
Static,
Single,
Multi,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
struct AddSslOptions {
scheme: Option<String>,
preferred_external_port: u32,
add_x_forwarded_headers: Option<bool>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
struct BindParams {
kind: BindKind,
id: String,
internal_port: u32,
scheme: String,
preferred_external_port: u32,
add_ssl: Option<AddSslOptions>,
secure: bool,
ssl: bool,
}
async fn bind(_: AnyContext, BindParams { .. }: BindParams) -> Result<Value, Error> {
todo!()
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
struct GetServiceInterfaceParams { struct GetServiceInterfaceParams {
package_id: Option<PackageId>, package_id: Option<PackageId>,
service_interface_id: String, service_interface_id: String,
callback: String, callback: Callback,
} }
async fn get_service_interface( async fn get_service_interface(
_: AnyContext, _: AnyContext,
@@ -190,8 +258,9 @@ async fn get_service_interface(
})) }))
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
struct ChrootParams { struct ChrootParams {
#[arg(short = 'e', long = "env")] #[arg(short = 'e', long = "env")]
env: Option<PathBuf>, env: Option<PathBuf>,
@@ -200,7 +269,9 @@ struct ChrootParams {
#[arg(short = 'u', long = "user")] #[arg(short = 'u', long = "user")]
user: Option<String>, user: Option<String>,
path: PathBuf, path: PathBuf,
#[ts(type = "string")]
command: OsString, command: OsString,
#[ts(type = "string[]")]
args: Vec<OsString>, args: Vec<OsString>,
} }
fn chroot( fn chroot(
@@ -250,11 +321,22 @@ fn chroot(
cmd.args(args); cmd.args(args);
Err(cmd.exec().into()) Err(cmd.exec().into())
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
enum Algorithm {
Ecdsa,
Ed25519,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
struct GetSslCertificateParams { struct GetSslCertificateParams {
package_id: Option<String>, package_id: Option<String>,
algorithm: Option<String>, //"ecdsa" | "ed25519" host_id: String,
algorithm: Option<Algorithm>, //"ecdsa" | "ed25519"
} }
async fn get_ssl_certificate( async fn get_ssl_certificate(
@@ -262,33 +344,39 @@ async fn get_ssl_certificate(
GetSslCertificateParams { GetSslCertificateParams {
package_id, package_id,
algorithm, algorithm,
host_id,
}: GetSslCertificateParams, }: GetSslCertificateParams,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
let fake = include_str!("./fake.cert.pem"); let fake = include_str!("./fake.cert.pem");
Ok(json!([fake, fake, fake])) Ok(json!([fake, fake, fake]))
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
struct GetSslKeyParams { struct GetSslKeyParams {
package_id: Option<String>, package_id: Option<String>,
algorithm: Option<String>, //"ecdsa" | "ed25519" host_id: String,
algorithm: Option<Algorithm>,
} }
async fn get_ssl_key( async fn get_ssl_key(
context: EffectContext, context: EffectContext,
GetSslKeyParams { GetSslKeyParams {
package_id, package_id,
host_id,
algorithm, algorithm,
}: GetSslKeyParams, }: GetSslKeyParams,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
let fake = include_str!("./fake.cert.key"); let fake = include_str!("./fake.cert.key");
Ok(json!(fake)) Ok(json!(fake))
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
struct GetStoreParams { struct GetStoreParams {
package_id: Option<PackageId>, package_id: Option<PackageId>,
#[ts(type = "string")]
path: JsonPointer, path: JsonPointer,
} }
@@ -311,10 +399,13 @@ async fn get_store(
.ok_or_else(|| Error::new(eyre!("Did not find value at path"), ErrorKind::NotFound))? .ok_or_else(|| Error::new(eyre!("Did not find value at path"), ErrorKind::NotFound))?
.clone()) .clone())
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
struct SetStoreParams { struct SetStoreParams {
#[ts(type = "any")]
value: Value, value: Value,
#[ts(type = "string")]
path: JsonPointer, path: JsonPointer,
} }
@@ -344,9 +435,11 @@ async fn set_store(
Ok(()) Ok(())
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
struct ExposeForDependentsParams { struct ExposeForDependentsParams {
#[ts(type = "string[]")]
paths: Vec<JsonPointer>, paths: Vec<JsonPointer>,
} }
@@ -372,8 +465,9 @@ async fn expose_for_dependents(
.await?; .await?;
Ok(()) Ok(())
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
struct ExposeUiParams { struct ExposeUiParams {
paths: Vec<ExposedUI>, paths: Vec<ExposedUI>,
} }
@@ -400,13 +494,16 @@ async fn expose_ui(
.await?; .await?;
Ok(()) Ok(())
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
struct ParamsPackageId { struct ParamsPackageId {
package: PackageId, package_id: PackageId,
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "camelCase")] #[command(rename_all = "camelCase")]
#[ts(export)]
struct ParamsMaybePackageId { struct ParamsMaybePackageId {
package_id: Option<PackageId>, package_id: Option<PackageId>,
} }
@@ -417,16 +514,18 @@ async fn exists(context: EffectContext, params: ParamsPackageId) -> Result<Value
let package = peeked let package = peeked
.as_public() .as_public()
.as_package_data() .as_package_data()
.as_idx(&params.package) .as_idx(&params.package_id)
.is_some(); .is_some();
Ok(json!(package)) Ok(json!(package))
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
struct ExecuteAction { struct ExecuteAction {
service_id: Option<PackageId>, service_id: Option<PackageId>,
action_id: ActionId, action_id: ActionId,
#[ts(type = "any")]
input: Value, input: Value,
} }
async fn execute_action( async fn execute_action(
@@ -529,9 +628,10 @@ async fn shutdown(context: EffectContext, _: Empty) -> Result<Value, Error> {
Ok(json!(())) Ok(json!(()))
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "camelCase")] #[command(rename_all = "camelCase")]
#[ts(export)]
struct SetConfigured { struct SetConfigured {
configured: bool, configured: bool,
} }
@@ -556,8 +656,9 @@ async fn set_configured(context: EffectContext, params: SetConfigured) -> Result
Ok(json!(())) Ok(json!(()))
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
enum Status { enum Status {
Running, Running,
Stopped, Stopped,
@@ -579,9 +680,10 @@ impl ValueParserFactory for Status {
} }
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "camelCase")] #[command(rename_all = "camelCase")]
#[ts(export)]
struct SetMainStatus { struct SetMainStatus {
status: Status, status: Status,
} }
@@ -595,8 +697,9 @@ async fn set_main_status(context: EffectContext, params: SetMainStatus) -> Resul
Ok(Value::Null) Ok(Value::Null)
} }
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[ts(export)]
struct SetHealth { struct SetHealth {
name: HealthCheckId, name: HealthCheckId,
status: HealthCheckString, status: HealthCheckString,
@@ -663,11 +766,13 @@ async fn set_health(
.await?; .await?;
Ok(json!(())) Ok(json!(()))
} }
#[derive(serde::Deserialize, serde::Serialize, Parser)] #[derive(serde::Deserialize, serde::Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "camelCase")] #[command(rename_all = "camelCase")]
#[ts(export)]
pub struct DestroyOverlayedImageParams { pub struct DestroyOverlayedImageParams {
image_id: ImageId, image_id: ImageId,
#[ts(type = "string")]
guid: InternedString, guid: InternedString,
} }
@@ -689,9 +794,10 @@ pub async fn destroy_overlayed_image(
} }
Ok(()) Ok(())
} }
#[derive(serde::Deserialize, serde::Serialize, Parser)] #[derive(serde::Deserialize, serde::Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[command(rename_all = "camelCase")] #[command(rename_all = "camelCase")]
#[ts(export)]
pub struct CreateOverlayedImageParams { pub struct CreateOverlayedImageParams {
image_id: ImageId, image_id: ImageId,
} }

View File

@@ -23,7 +23,7 @@ impl std::fmt::Display for HealthCheckResult {
} }
} }
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, ts_rs::TS)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum HealthCheckString { pub enum HealthCheckString {
Passing, Passing,

View File

@@ -60,6 +60,6 @@ function asMessage(e: unknown) {
if (typeof e === "object" && e != null && "message" in e) if (typeof e === "object" && e != null && "message" in e)
return String(e.message) return String(e.message)
const value = String(e) const value = String(e)
if (value.length == null) return undefined if (value.length == null) return null
return value return value
} }

View File

@@ -2,5 +2,5 @@ import { HealthStatus } from "../../types"
export type CheckResult = { export type CheckResult = {
status: HealthStatus status: HealthStatus
message?: string message: string | null
} }

View File

@@ -57,7 +57,7 @@ export type Scheme = string | null
type AddSslOptions = { type AddSslOptions = {
scheme: Scheme scheme: Scheme
preferredExternalPort: number preferredExternalPort: number
addXForwardedHeaders?: boolean /** default: false */ addXForwardedHeaders: boolean | null /** default: false */
} }
type Security = { secure: false; ssl: false } | { secure: true; ssl: boolean } type Security = { secure: false; ssl: false } | { secure: true; ssl: boolean }
export type BindOptions = { export type BindOptions = {
@@ -82,13 +82,13 @@ type BindOptionsByKnownProtocol =
| ({ | ({
protocol: ProtocolsWithSslVariants protocol: ProtocolsWithSslVariants
preferredExternalPort?: number preferredExternalPort?: number
scheme?: Scheme scheme: Scheme | null
} & ({ noAddSsl: true } | { addSsl?: Partial<AddSslOptions> })) } & ({ noAddSsl: true } | { addSsl?: Partial<AddSslOptions> }))
| { | {
protocol: NotProtocolsWithSslVariants protocol: NotProtocolsWithSslVariants
preferredExternalPort?: number preferredExternalPort?: number
scheme?: Scheme scheme: Scheme | null
addSsl?: AddSslOptions | null addSsl: AddSslOptions | null
} }
type BindOptionsByProtocol = BindOptionsByKnownProtocol | BindOptions type BindOptionsByProtocol = BindOptionsByKnownProtocol | BindOptions
@@ -185,6 +185,7 @@ export class Host {
if ("noAddSsl" in options && options.noAddSsl) return null if ("noAddSsl" in options && options.noAddSsl) return null
if ("withSsl" in protoInfo && protoInfo.withSsl) if ("withSsl" in protoInfo && protoInfo.withSsl)
return { return {
addXForwardedHeaders: null,
preferredExternalPort: knownProtocols[protoInfo.withSsl].defaultPort, preferredExternalPort: knownProtocols[protoInfo.withSsl].defaultPort,
scheme: protoInfo.withSsl, scheme: protoInfo.withSsl,
...("addSsl" in options ? options.addSsl : null), ...("addSsl" in options ? options.addSsl : null),

View File

@@ -7,7 +7,10 @@ describe("host", () => {
async function test(effects: Effects) { async function test(effects: Effects) {
const utils = createUtils<never, never>(effects) const utils = createUtils<never, never>(effects)
const foo = utils.host.multi("foo") const foo = utils.host.multi("foo")
const fooOrigin = await foo.bindPort(80, { protocol: "http" as const }) const fooOrigin = await foo.bindPort(80, {
protocol: "http" as const,
scheme: null,
})
const fooInterface = new ServiceInterfaceBuilder({ const fooInterface = new ServiceInterfaceBuilder({
effects, effects,
name: "Foo", name: "Foo",

View File

@@ -0,0 +1,75 @@
import { Effects } from "../types"
import { ExecuteAction } from "../../../core/startos/bindings/ExecuteAction"
import { CreateOverlayedImageParams } from "../../../core/startos/bindings/CreateOverlayedImageParams"
import { DestroyOverlayedImageParams } from "../../../core/startos/bindings/DestroyOverlayedImageParams"
import { BindParams } from "../../../core/startos/bindings/BindParams"
import { GetHostInfoParams } from "../../../core/startos/bindings/GetHostInfoParams"
import { ParamsPackageId } from "../../../core/startos/bindings/ParamsPackageId"
import { ParamsMaybePackageId } from "../../../core/startos/bindings/ParamsMaybePackageId"
import { SetConfigured } from "../../../core/startos/bindings/SetConfigured"
import { SetHealth } from "../../../core/startos/bindings/SetHealth"
import { ExposeForDependentsParams } from "../../../core/startos/bindings/ExposeForDependentsParams"
import { ExposeUiParams } from "../../../core/startos/bindings/ExposeUiParams"
import { GetSslCertificateParams } from "../../../core/startos/bindings/GetSslCertificateParams"
import { GetSslKeyParams } from "../../../core/startos/bindings/GetSslKeyParams"
import { GetServiceInterfaceParams } from "../../../core/startos/bindings/GetServiceInterfaceParams"
function typeEquality<ExpectedType>(_a: ExpectedType) {}
describe("startosTypeValidation ", () => {
test(`checking the params match`, () => {
const testInput: any = {}
typeEquality<{
[K in keyof Effects &
(
| "gitInfo"
| "echo"
| "chroot"
| "exists"
| "executeAction"
| "getConfigured"
| "stopped"
| "running"
| "restart"
| "shutdown"
| "setConfigured"
| "setMainStatus"
| "setHealth"
| "getStore"
| "setStore"
| "exposeForDependents"
| "exposeUi"
| "createOverlayedImage"
| "destroyOverlayedImage"
| "getSslCertificate"
| "getSslKey"
| "getServiceInterface"
| "clearBindings"
| "bind"
| "getHostInfo"
)]: Effects[K] extends Function ? Parameters<Effects[K]>[0] : never
}>({
executeAction: {} as ExecuteAction,
createOverlayedImage: {} as CreateOverlayedImageParams,
destroyOverlayedImage: {} as DestroyOverlayedImageParams,
clearBindings: undefined,
bind: {} as BindParams,
getHostInfo: {} as GetHostInfoParams,
exists: {} as ParamsPackageId,
getConfigured: undefined,
stopped: {} as ParamsMaybePackageId,
running: {} as ParamsMaybePackageId,
restart: undefined,
shutdown: undefined,
setConfigured: {} as SetConfigured,
setHealth: {} as SetHealth,
exposeForDependents: {} as ExposeForDependentsParams,
exposeUi: {} as ExposeUiParams,
getSslCertificate: {} as GetSslCertificateParams,
getSslKey: {} as GetSslKeyParams,
getServiceInterface: {} as GetServiceInterfaceParams,
})
typeEquality<Parameters<Effects["executeAction"]>[0]>(
testInput as ExecuteAction,
)
})
})

View File

@@ -1,7 +1,8 @@
export * as configTypes from "./config/configTypes" export * as configTypes from "./config/configTypes"
import { AddSslOptions } from "../../core/startos/bindings/AddSslOptions"
import { InputSpec } from "./config/configTypes" import { InputSpec } from "./config/configTypes"
import { DependenciesReceipt } from "./config/setupConfig" import { DependenciesReceipt } from "./config/setupConfig"
import { BindOptions } from "./interfaces/Host" import { BindOptions, Scheme } from "./interfaces/Host"
import { Daemons } from "./mainFn/Daemons" import { Daemons } from "./mainFn/Daemons"
import { UrlString } from "./util/getServiceInterface" import { UrlString } from "./util/getServiceInterface"
import { ServiceInterfaceType, Signals } from "./util/utils" import { ServiceInterfaceType, Signals } from "./util/utils"
@@ -247,6 +248,7 @@ export type ServiceInterfaceWithHostInfo = ServiceInterface & {
// prettier-ignore // prettier-ignore
export type ExposeAllServicePaths<Store, PreviousPath extends string = ""> = export type ExposeAllServicePaths<Store, PreviousPath extends string = ""> =
Store extends never ? string :
Store extends Record<string, unknown> ? {[K in keyof Store & string]: ExposeAllServicePaths<Store[K], `${PreviousPath}/${K & string}`>}[keyof Store & string] : Store extends Record<string, unknown> ? {[K in keyof Store & string]: ExposeAllServicePaths<Store[K], `${PreviousPath}/${K & string}`>}[keyof Store & string] :
PreviousPath PreviousPath
// prettier-ignore // prettier-ignore
@@ -254,10 +256,10 @@ export type ExposeAllUiPaths<Store, PreviousPath extends string = ""> =
Store extends Record<string, unknown> ? {[K in keyof Store & string]: ExposeAllUiPaths<Store[K], `${PreviousPath}/${K & string}`>}[keyof Store & string] : Store extends Record<string, unknown> ? {[K in keyof Store & string]: ExposeAllUiPaths<Store[K], `${PreviousPath}/${K & string}`>}[keyof Store & string] :
Store extends string ? PreviousPath : Store extends string ? PreviousPath :
never never
export type ExposeServicePaths<Store> = Array<{ export type ExposeServicePaths<Store = never> = {
/** The path to the value in the Store. [JsonPath](https://jsonpath.com/) */ /** The path to the value in the Store. [JsonPath](https://jsonpath.com/) */
path: ExposeAllServicePaths<Store> paths: Store extends never ? string[] : ExposeAllServicePaths<Store>[]
}> }
export type ExposeUiPaths<Store> = Array<{ export type ExposeUiPaths<Store> = Array<{
/** The path to the value in the Store. [JsonPath](https://jsonpath.com/) */ /** The path to the value in the Store. [JsonPath](https://jsonpath.com/) */
@@ -292,24 +294,28 @@ export type Effects = {
/** Removes all network bindings */ /** Removes all network bindings */
clearBindings(): Promise<void> clearBindings(): Promise<void>
/** Creates a host connected to the specified port with the provided options */ /** Creates a host connected to the specified port with the provided options */
bind( bind(options: {
options: { kind: "static" | "single" | "multi"
kind: "static" | "single" | "multi" id: string
id: string internalPort: number
internalPort: number
} & BindOptions, scheme: Scheme
): Promise<void> preferredExternalPort: number
addSsl: AddSslOptions | null
secure: boolean
ssl: boolean
}): Promise<void>
/** Retrieves the current hostname(s) associated with a host id */ /** Retrieves the current hostname(s) associated with a host id */
// getHostInfo(options: {
// kind: "static" | "single"
// serviceInterfaceId: string
// packageId: string | null
// callback: () => void
// }): Promise<SingleHost>
getHostInfo(options: { getHostInfo(options: {
kind: "static" | "single" kind: "multi" | null
serviceInterfaceId: string serviceInterfaceId: string
packageId?: string packageId: string | null
callback: () => void
}): Promise<SingleHost>
getHostInfo(options: {
kind?: "multi"
serviceInterfaceId: string
packageId?: string
callback: () => void callback: () => void
}): Promise<MultiHost> }): Promise<MultiHost>
@@ -368,12 +374,17 @@ export type Effects = {
*/ */
exportServiceInterface(options: ServiceInterface): Promise<string> exportServiceInterface(options: ServiceInterface): Promise<string>
exposeForDependents<Store = never>( exposeForDependents(options: { paths: string[] }): Promise<void>
options: ExposeServicePaths<Store>,
): Promise<void>
exposeUi<Store = never>(options: { exposeUi<Store = never>(options: {
paths: ExposeUiPaths<Store> paths: {
path: string
title: string
description?: string | undefined
masked?: boolean | undefined
copyable?: boolean | undefined
qr?: boolean | undefined
}[]
}): Promise<void> }): Promise<void>
/** /**
* There are times that we want to see the addresses that where exported * There are times that we want to see the addresses that where exported
@@ -382,7 +393,7 @@ export type Effects = {
* Note: any auth should be filtered out already * Note: any auth should be filtered out already
*/ */
getServiceInterface(options: { getServiceInterface(options: {
packageId?: PackageId packageId: PackageId | null
serviceInterfaceId: ServiceInterfaceId serviceInterfaceId: ServiceInterfaceId
callback: () => void callback: () => void
}): Promise<ServiceInterface> }): Promise<ServiceInterface>
@@ -392,7 +403,7 @@ export type Effects = {
* @param options * @param options
*/ */
getPrimaryUrl(options: { getPrimaryUrl(options: {
packageId?: PackageId packageId: PackageId | null
serviceInterfaceId: ServiceInterfaceId serviceInterfaceId: ServiceInterfaceId
callback: () => void callback: () => void
}): Promise<UrlString | null> }): Promise<UrlString | null>
@@ -404,7 +415,7 @@ export type Effects = {
* Note: any auth should be filtered out already * Note: any auth should be filtered out already
*/ */
listServiceInterfaces(options: { listServiceInterfaces(options: {
packageId?: PackageId packageId: PackageId | null
callback: () => void callback: () => void
}): Promise<ServiceInterface[]> }): Promise<ServiceInterface[]>
@@ -429,38 +440,38 @@ export type Effects = {
* This called after a valid set config as well as during init. * This called after a valid set config as well as during init.
* @param configured * @param configured
*/ */
setConfigured(configured: boolean): Promise<void> setConfigured(options: { configured: boolean }): Promise<void>
/** /**
* *
* @returns PEM encoded fullchain (ecdsa) * @returns PEM encoded fullchain (ecdsa)
*/ */
getSslCertificate: ( getSslCertificate: (options: {
packageId: string | null, packageId: string | null
hostId: string, hostId: string
algorithm?: "ecdsa" | "ed25519", algorithm: "ecdsa" | "ed25519" | null
) => Promise<[string, string, string]> }) => Promise<[string, string, string]>
/** /**
* @returns PEM encoded ssl key (ecdsa) * @returns PEM encoded ssl key (ecdsa)
*/ */
getSslKey: ( getSslKey: (options: {
packageId: string | null, packageId: string | null
hostId: string, hostId: string
algorithm?: "ecdsa" | "ed25519", algorithm: "ecdsa" | "ed25519" | null
) => Promise<string> }) => Promise<string>
setHealth(o: { setHealth(o: {
name: string name: string
status: HealthStatus status: HealthStatus
message?: string message: string | null
}): 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<DependenciesReceipt> 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(options: { 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 */
running(packageId: PackageId): Promise<boolean> running(options: { packageId: PackageId }): Promise<boolean>
/** Instead of creating proxies with nginx, we have a utility to create and maintain a proxy in the lifetime of this running. */ /** Instead of creating proxies with nginx, we have a utility to create and maintain a proxy in the lifetime of this running. */
reverseProxy(options: { reverseProxy(options: {
@@ -494,7 +505,7 @@ export type Effects = {
} }
}): Promise<string> }): Promise<string>
stopped(packageId?: string): Promise<boolean> stopped(options: { packageId: string | null }): Promise<boolean>
} }
// prettier-ignore // prettier-ignore

View File

@@ -185,7 +185,7 @@ const makeInterfaceFilled = async ({
}: { }: {
effects: Effects effects: Effects
id: string id: string
packageId: string | undefined packageId: string | null
callback: () => void callback: () => void
}) => { }) => {
const serviceInterfaceValue = await effects.getServiceInterface({ const serviceInterfaceValue = await effects.getServiceInterface({
@@ -195,6 +195,7 @@ const makeInterfaceFilled = async ({
}) })
const hostInfo = await effects.getHostInfo({ const hostInfo = await effects.getHostInfo({
packageId, packageId,
kind: null,
serviceInterfaceId: serviceInterfaceValue.id, serviceInterfaceId: serviceInterfaceValue.id,
callback, callback,
}) })
@@ -220,7 +221,7 @@ const makeInterfaceFilled = async ({
export class GetServiceInterface { export class GetServiceInterface {
constructor( constructor(
readonly effects: Effects, readonly effects: Effects,
readonly opts: { id: string; packageId?: string }, readonly opts: { id: string; packageId: string | null },
) {} ) {}
/** /**
@@ -276,7 +277,7 @@ export class GetServiceInterface {
} }
export function getServiceInterface( export function getServiceInterface(
effects: Effects, effects: Effects,
opts: { id: string; packageId?: string }, opts: { id: string; packageId: string | null },
) { ) {
return new GetServiceInterface(effects, opts) return new GetServiceInterface(effects, opts)
} }

View File

@@ -11,7 +11,7 @@ const makeManyInterfaceFilled = async ({
callback, callback,
}: { }: {
effects: Effects effects: Effects
packageId: string | undefined packageId: string | null
callback: () => void callback: () => void
}) => { }) => {
const serviceInterfaceValues = await effects.listServiceInterfaces({ const serviceInterfaceValues = await effects.listServiceInterfaces({
@@ -25,6 +25,7 @@ const makeManyInterfaceFilled = async ({
[ [
id, id,
await effects.getHostInfo({ await effects.getHostInfo({
kind: null,
packageId, packageId,
serviceInterfaceId: id, serviceInterfaceId: id,
callback, callback,
@@ -37,6 +38,7 @@ const makeManyInterfaceFilled = async ({
const serviceInterfacesFilled: ServiceInterfaceFilled[] = await Promise.all( const serviceInterfacesFilled: ServiceInterfaceFilled[] = await Promise.all(
serviceInterfaceValues.map(async (serviceInterfaceValue) => { serviceInterfaceValues.map(async (serviceInterfaceValue) => {
const hostInfo = await effects.getHostInfo({ const hostInfo = await effects.getHostInfo({
kind: null,
packageId, packageId,
serviceInterfaceId: serviceInterfaceValue.id, serviceInterfaceId: serviceInterfaceValue.id,
callback, callback,
@@ -64,7 +66,7 @@ const makeManyInterfaceFilled = async ({
export class GetServiceInterfaces { export class GetServiceInterfaces {
constructor( constructor(
readonly effects: Effects, readonly effects: Effects,
readonly opts: { packageId?: string }, readonly opts: { packageId: string | null },
) {} ) {}
/** /**
@@ -119,7 +121,7 @@ export class GetServiceInterfaces {
} }
export function getServiceInterfaces( export function getServiceInterfaces(
effects: Effects, effects: Effects,
opts: { packageId?: string }, opts: { packageId: string | null },
) { ) {
return new GetServiceInterfaces(effects, opts) return new GetServiceInterfaces(effects, opts)
} }

View File

@@ -177,14 +177,17 @@ export const createUtils = <
serviceInterface: { serviceInterface: {
getOwn: (id: ServiceInterfaceId) => getOwn: (id: ServiceInterfaceId) =>
getServiceInterface(effects, { id }) as GetServiceInterface & getServiceInterface(effects, {
WrapperOverWrite, id,
packageId: null,
}) as GetServiceInterface & WrapperOverWrite,
get: (opts: { id: ServiceInterfaceId; packageId: PackageId }) => get: (opts: { id: ServiceInterfaceId; packageId: PackageId }) =>
getServiceInterface(effects, opts) as GetServiceInterface & getServiceInterface(effects, opts) as GetServiceInterface &
WrapperOverWrite, WrapperOverWrite,
getAllOwn: () => getAllOwn: () =>
getServiceInterfaces(effects, {}) as GetServiceInterfaces & getServiceInterfaces(effects, {
WrapperOverWrite, packageId: null,
}) as GetServiceInterfaces & WrapperOverWrite,
getAll: (opts: { packageId: PackageId }) => getAll: (opts: { packageId: PackageId }) =>
getServiceInterfaces(effects, opts) as GetServiceInterfaces & getServiceInterfaces(effects, opts) as GetServiceInterfaces &
WrapperOverWrite, WrapperOverWrite,