diff --git a/lib/config/dependencies.ts b/lib/config/dependencies.ts
new file mode 100644
index 0000000..ec24387
--- /dev/null
+++ b/lib/config/dependencies.ts
@@ -0,0 +1,15 @@
+import { Dependency, PackageId } from "../types";
+
+export function exists(id: PackageId) {
+ return {
+ id,
+ kind: "exists",
+ } as Dependency;
+}
+
+export function running(id: PackageId) {
+ return {
+ id,
+ kind: "running",
+ } as Dependency;
+}
diff --git a/lib/config/index.ts b/lib/config/index.ts
index 5f7c8d2..a54b7de 100644
--- a/lib/config/index.ts
+++ b/lib/config/index.ts
@@ -2,3 +2,4 @@ export * as configBuilder from "./builder";
export { setupConfigExports } from "./setupConfigExports";
export { specToBuilder, specToBuilderFile } from "./specToBuilder";
+export * as dependencies from './dependencies'
diff --git a/lib/config/setupConfigExports.ts b/lib/config/setupConfigExports.ts
index 40190aa..7347b18 100644
--- a/lib/config/setupConfigExports.ts
+++ b/lib/config/setupConfigExports.ts
@@ -1,5 +1,5 @@
import { Config } from "./builder";
-import { DeepPartial, DependsOn, Effects, ExpectedExports } from "../types";
+import { DeepPartial, Dependencies, DependsOn, Effects, ExpectedExports } from "../types";
import { InputSpec } from "./configTypes";
import { nullIfEmpty } from "../util";
import { TypeFromProps } from "../util/propertiesMatcher";
@@ -13,15 +13,8 @@ import { TypeFromProps } from "../util/propertiesMatcher";
*/
export function setupConfigExports(options: {
spec: Config;
- dependsOn: DependsOn;
- write(options: {
- effects: Effects;
- input: TypeFromProps;
- }): Promise;
- read(options: {
- effects: Effects;
- config: ConfigType;
- }): Promise>>;
+ write(options: { effects: Effects; input: TypeFromProps }): Promise<[ConfigType, Dependencies]>;
+ read(options: { effects: Effects; config: ConfigType }): Promise>>;
}) {
const validator = options.spec.validator();
return {
@@ -30,17 +23,15 @@ export function setupConfigExports(options: {
await effects.error(String(validator.errorMessage(input)));
return { error: "Set config type error for config" };
}
- const output = await options.write({ input, effects });
- if (output) {
- await effects.setWrapperData({ path: "config", value: output });
- }
+ const [output, dependencies] = await options.write({ input, effects });
+
+ await effects.setDependencies(dependencies);
+ await effects.setWrapperData({ path: "config", value: output });
}) as ExpectedExports.setConfig,
getConfig: (async ({ effects, config }) => {
return {
spec: options.spec.build(),
- config: nullIfEmpty(
- await options.read({ effects, config: config as ConfigType })
- ),
+ config: nullIfEmpty(await options.read({ effects, config: config as ConfigType })),
};
}) as ExpectedExports.getConfig,
};
diff --git a/lib/mainFn/LocalPort.ts b/lib/mainFn/LocalPort.ts
index 9a761ae..ce886f7 100644
--- a/lib/mainFn/LocalPort.ts
+++ b/lib/mainFn/LocalPort.ts
@@ -4,10 +4,12 @@ import { LocalBinding } from "./LocalBinding";
export class LocalPort {
constructor(readonly effects: Effects, readonly id: string) {}
async bindLan(internalPort: number) {
- const [localAddress, ipAddress] = await this.effects.bindLan({
+ const port = await this.effects.bindLan({
internalPort,
name: this.id,
});
+ const localAddress = `${await this.effects.getLocalHostname()}:${port}`;
+ const ipAddress = `${await this.effects.getIPHostname()}:${port}`;
return new LocalBinding(localAddress, ipAddress);
}
}
diff --git a/lib/mainFn/NetworkBuilder.ts b/lib/mainFn/NetworkBuilder.ts
index 4edbdac..d8fa424 100644
--- a/lib/mainFn/NetworkBuilder.ts
+++ b/lib/mainFn/NetworkBuilder.ts
@@ -14,4 +14,4 @@ export class NetworkBuilder {
getPort(id: string) {
return new LocalPort(this.effects, id);
}
-}
+}
\ No newline at end of file
diff --git a/lib/types.ts b/lib/types.ts
index 807418d..72c758a 100644
--- a/lib/types.ts
+++ b/lib/types.ts
@@ -5,29 +5,17 @@ import { ActionReceipt } from "./init";
export namespace ExpectedExports {
version: 1;
/** Set configuration is called after we have modified and saved the configuration in the embassy ui. Use this to make a file for the docker to read from for configuration. */
- export type setConfig = (options: {
- effects: Effects;
- input: Record;
- }) => Promise;
+ export type setConfig = (options: { effects: Effects; input: Record }) => Promise;
/** Get configuration returns a shape that describes the format that the embassy ui will generate, and later send to the set config */
- export type getConfig = (options: {
- effects: Effects;
- config: unknown;
- }) => Promise;
+ export type getConfig = (options: { effects: Effects; config: unknown }) => Promise;
// /** These are how we make sure the our dependency configurations are valid and if not how to fix them. */
// export type dependencies = Dependencies;
/** For backing up service data though the embassyOS UI */
- export type createBackup = (options: {
- effects: Effects;
- }) => Promise;
+ export type createBackup = (options: { effects: Effects }) => Promise;
/** For restoring service data that was previously backed up using the embassyOS UI create backup flow. Backup restores are also triggered via the embassyOS UI, or doing a system restore flow during setup. */
- export type restoreBackup = (options: {
- effects: Effects;
- }) => Promise;
+ export type restoreBackup = (options: { effects: Effects }) => Promise;
/** Properties are used to get values from the docker, like a username + password, what ports we are hosting from */
- export type properties = (options: {
- effects: Effects;
- }) => Promise;
+ export type properties = (options: { effects: Effects }) => Promise;
// /** Health checks are used to determine if the service is working properly after starting
// * A good use case is if we are using a web server, seeing if we can get to the web server.
@@ -43,43 +31,35 @@ export namespace ExpectedExports {
* service starting, and that file would indicate that it would rescan all the data.
*/
export type action = {
- [id: string]: (options: {
- effects: Effects;
- input?: Record;
- }) => Promise;
+ [id: string]: (options: { effects: Effects; input?: Record }) => Promise;
};
/**
* This is the entrypoint for the main container. Used to start up something like the service that the
* package represents, like running a bitcoind in a bitcoind-wrapper.
*/
- export type main = (options: {
- effects: Effects;
- started(onTerm: () => void): null;
- }) => Promise;
+ export type main = (options: { effects: Effects; started(onTerm: () => void): null }) => Promise;
+
+ /**
+ * After a shutdown, if we wanted to do any operations to clean up things, like
+ * set the action as unavailable or something.
+ */
+ export type afterShutdown = (options: { effects: Effects }) => Promise;
/**
* Every time a package completes an install, this function is called before the main.
* Can be used to do migration like things.
*/
- export type init = (options: {
- effects: Effects;
- previousVersion: null | string;
- }) => Promise;
+ export type init = (options: { effects: Effects; previousVersion: null | string }) => Promise;
/** This will be ran during any time a package is uninstalled, for example during a update
* this will be called.
*/
- export type uninit = (options: {
- effects: Effects;
- nextVersion: null | string;
- }) => Promise;
+ export type uninit = (options: { effects: Effects; nextVersion: null | string }) => Promise;
}
export type TimeMs = number;
export type VersionString = string;
-export type ValidIfNoStupidEscape = A extends
- | `${string}'"'"'${string}`
- | `${string}\\"${string}`
+export type ValidIfNoStupidEscape = A extends `${string}'"'"'${string}` | `${string}\\"${string}`
? never
: "" extends A & ""
? never
@@ -104,9 +84,7 @@ export type Daemon = {
export type HealthStatus = "passing" | "warning" | "failing" | "disabled";
-export type CommandType =
- | ValidIfNoStupidEscape
- | [string, ...string[]];
+export type CommandType = ValidIfNoStupidEscape | [string, ...string[]];
export type DaemonReturned = {
wait(): Promise;
@@ -116,11 +94,7 @@ export type DaemonReturned = {
/** Used to reach out from the pure js runtime */
export type Effects = {
/** Usable when not sandboxed */
- writeFile(input: {
- path: string;
- volumeId: string;
- toWrite: string;
- }): Promise;
+ writeFile(input: { path: string; volumeId: string; toWrite: string }): Promise;
readFile(input: { volumeId: string; path: string }): Promise;
metadata(input: { volumeId: string; path: string }): Promise;
/** Create a directory. Usable when not sandboxed */
@@ -132,17 +106,10 @@ export type Effects = {
removeFile(input: { volumeId: string; path: string }): Promise;
/** Write a json file into an object. Usable when not sandboxed */
- writeJsonFile(input: {
- volumeId: string;
- path: string;
- toWrite: Record;
- }): Promise;
+ writeJsonFile(input: { volumeId: string; path: string; toWrite: Record }): Promise;
/** Read a json file into an object */
- readJsonFile(input: {
- volumeId: string;
- path: string;
- }): Promise>;
+ readJsonFile(input: { volumeId: string; path: string }): Promise>;
runCommand(
command: ValidIfNoStupidEscape | [string, ...string[]],
@@ -154,9 +121,7 @@ export type Effects = {
wait(): Promise;
term(): Promise;
};
- runDaemon(
- command: ValidIfNoStupidEscape | [string, ...string[]]
- ): DaemonReturned;
+ runDaemon(command: ValidIfNoStupidEscape | [string, ...string[]]): DaemonReturned;
/** Uses the chown on the system */
chown(input: { volumeId: string; path: string; uid: string }): Promise;
@@ -181,14 +146,12 @@ export type Effects = {
/** Check that a file exists or not */
exists(input: { volumeId: string; path: string }): Promise;
- /** Declaring that we are opening a interface on some protocal for local network */
- bindLan(options: { internalPort: number; name: string }): Promise;
+ /** Declaring that we are opening a interface on some protocal for local network
+ * Returns the port exposed
+ */
+ bindLan(options: { internalPort: number; name: string }): Promise;
/** Declaring that we are opening a interface on some protocal for tor network */
- bindTor(options: {
- internalPort: number;
- name: string;
- externalPort: number;
- }): Promise;
+ bindTor(options: { internalPort: number; name: string; externalPort: number }): Promise;
/** Similar to the fetch api via the mdn, this is simplified but the point is
* to get something from some website, and return the response.
@@ -248,17 +211,11 @@ export type Effects = {
getLocalHostname(): Promise;
getIPHostname(): Promise;
/** Get the address for another service for tor interfaces */
- getServiceTorHostname(
- interfaceId: string,
- packageId?: string
- ): Promise;
+ getServiceTorHostname(interfaceId: string, packageId?: string): Promise;
/**
* Get the port address for another service
*/
- getServicePortForward(
- internalPort: number,
- packageId?: string
- ): Promise;
+ getServicePortForward(internalPort: number, packageId?: string): Promise;
/** When we want to create a link in the front end interfaces, and example is
* exposing a url to view a web service
@@ -328,21 +285,20 @@ export type Effects = {
*
* @returns PEM encoded fullchain (ecdsa)
*/
- getSslCertificate: (
- packageId: string,
- algorithm?: "ecdsa" | "ed25519"
- ) => [string, string, string];
+ getSslCertificate: (packageId: string, algorithm?: "ecdsa" | "ed25519") => [string, string, string];
/**
* @returns PEM encoded ssl key (ecdsa)
*/
getSslKey: (packageId: string, algorithm?: "ecdsa" | "ed25519") => string;
- setHealth(o: {
- name: string;
- status: HealthStatus;
- message?: string;
- }): Promise;
+ setHealth(o: { name: string; status: HealthStatus; message?: string }): Promise;
+ /** Set the dependencies of what the service needs, usually ran during the set config as a best practice */
+ setDependencies(dependencies: Dependencies): Promise;
+ /** Exists could be useful during the runtime to know if some service exists, option dep */
+ exists(packageId: PackageId): Promise;
+ /** Exists could be useful during the runtime to know if some service is running, option dep */
+ running(packageId: PackageId): Promise;
restart(): void;
shutdown(): void;
};
@@ -423,6 +379,10 @@ export type SetResult = {
"depends-on": DependsOn;
};
+export type PackageId = string;
+export type Message = string;
+export type DependencyKind = "running" | "exists";
+
export type DependsOn = {
[packageId: string]: string[];
};
@@ -463,16 +423,10 @@ export type Properties = {
data: PackagePropertiesV2;
};
-export type Dependencies = {
- /** Id is the id of the package, should be the same as the manifest */
- [id: string]: {
- /** Checks are called to make sure that our dependency is in the correct shape. If a known error is returned we know that the dependency needs modification */
- check(effects: Effects, input: InputSpec): Promise;
- /** This is called after we know that the dependency package needs a new configuration, this would be a transform for defaults */
- autoConfigure(effects: Effects, input: InputSpec): Promise;
- };
+export type Dependency = {
+ id: PackageId;
+ kind: DependencyKind;
};
+export type Dependencies = Array;
-export type DeepPartial = T extends {}
- ? { [P in keyof T]?: DeepPartial }
- : T;
+export type DeepPartial = T extends {} ? { [P in keyof T]?: DeepPartial } : T;