mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-30 20:24:47 +00:00
feat: Add in the features for the utils.networkInterface.get
This commit is contained in:
@@ -64,8 +64,8 @@ export class Variants<Type, Store, Vault> {
|
|||||||
spec: Config<any, Store, Vault> | Config<any, never, never>
|
spec: Config<any, Store, Vault> | Config<any, never, never>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Store,
|
Store = never,
|
||||||
Vault,
|
Vault = never,
|
||||||
>(a: VariantValues) {
|
>(a: VariantValues) {
|
||||||
const validator = anyOf(
|
const validator = anyOf(
|
||||||
...Object.entries(a).map(([name, { spec }]) =>
|
...Object.entries(a).map(([name, { spec }]) =>
|
||||||
|
|||||||
@@ -42,11 +42,11 @@ export class NetworkInterfaceBuilder {
|
|||||||
const { name, description, id, ui, username, path, search } = this.options
|
const { name, description, id, ui, username, path, search } = this.options
|
||||||
|
|
||||||
const addresses = Array.from(origins).map((o) =>
|
const addresses = Array.from(origins).map((o) =>
|
||||||
o.build({ username, path, search }),
|
o.build({ username, path, search, scheme: null }),
|
||||||
)
|
)
|
||||||
|
|
||||||
await this.options.effects.exportNetworkInterface({
|
await this.options.effects.exportNetworkInterface({
|
||||||
id,
|
interfaceId: id,
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
addresses,
|
addresses,
|
||||||
|
|||||||
@@ -18,11 +18,13 @@ export class Origin<T extends Host> {
|
|||||||
options: this.options,
|
options: this.options,
|
||||||
suffix: `${path}${qp}`,
|
suffix: `${path}${qp}`,
|
||||||
username,
|
username,
|
||||||
|
scheme: this.options.scheme,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type BuildOptions = {
|
type BuildOptions = {
|
||||||
|
scheme: string | null
|
||||||
username: string | null
|
username: string | null
|
||||||
path: string
|
path: string
|
||||||
search: Record<string, string>
|
search: Record<string, string>
|
||||||
|
|||||||
54
lib/types.ts
54
lib/types.ts
@@ -166,17 +166,21 @@ export type ActionMetadata = {
|
|||||||
*/
|
*/
|
||||||
group?: string
|
group?: string
|
||||||
}
|
}
|
||||||
|
export declare const hostName: unique symbol
|
||||||
|
export type HostName = string & { [hostName]: never }
|
||||||
/** ${scheme}://${username}@${host}:${externalPort}${suffix} */
|
/** ${scheme}://${username}@${host}:${externalPort}${suffix} */
|
||||||
export type Address = {
|
export type Address = {
|
||||||
username: string | null
|
username: string | null
|
||||||
hostId: string
|
hostId: string
|
||||||
options: PortOptions
|
options: PortOptions
|
||||||
suffix: string
|
suffix: string
|
||||||
|
scheme: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type InterfaceId = string
|
||||||
|
|
||||||
export type NetworkInterface = {
|
export type NetworkInterface = {
|
||||||
id: string
|
interfaceId: InterfaceId
|
||||||
/** The title of this field to be displayed */
|
/** The title of this field to be displayed */
|
||||||
name: string
|
name: string
|
||||||
/** Human readable description, used as tooltip usually */
|
/** Human readable description, used as tooltip usually */
|
||||||
@@ -188,19 +192,6 @@ export type NetworkInterface = {
|
|||||||
*/
|
*/
|
||||||
ui?: boolean
|
ui?: boolean
|
||||||
}
|
}
|
||||||
export type NetworkInterfaceOut = {
|
|
||||||
id: string
|
|
||||||
/** The title of this field to be displayed */
|
|
||||||
name: string
|
|
||||||
/** Human readable description, used as tooltip usually */
|
|
||||||
description: string
|
|
||||||
/** All URIs */
|
|
||||||
addresses: string[]
|
|
||||||
/** Defaults to false, but describes if this address can be opened in a browser as an
|
|
||||||
* ui interface
|
|
||||||
*/
|
|
||||||
ui?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Used to reach out from the pure js runtime */
|
/** Used to reach out from the pure js runtime */
|
||||||
export type Effects = {
|
export type Effects = {
|
||||||
@@ -240,11 +231,18 @@ export type Effects = {
|
|||||||
} & PortOptions,
|
} & PortOptions,
|
||||||
): Promise<void>
|
): Promise<void>
|
||||||
/** Retrieves the current hostname(s) associated with a host id */
|
/** Retrieves the current hostname(s) associated with a host id */
|
||||||
getHostNames(options: {
|
getHostnames(options: {
|
||||||
kind: "static" | "single"
|
kind: "static" | "single"
|
||||||
id: string
|
hostId: string
|
||||||
}): Promise<[string]>
|
packageId?: string
|
||||||
getHostNames(options: { kind: "multi"; id: string }): Promise<string[]>
|
callback: () => void
|
||||||
|
}): Promise<[HostName]>
|
||||||
|
getHostnames(options: {
|
||||||
|
kind?: "multi"
|
||||||
|
packageId?: string
|
||||||
|
hostId: string
|
||||||
|
callback: () => void
|
||||||
|
}): Promise<[HostName, ...HostName[]]>
|
||||||
|
|
||||||
/** Similar to the fetch api via the mdn, this is simplified but the point is
|
/** 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.
|
* to get something from some website, and return the response.
|
||||||
@@ -310,7 +308,7 @@ export type Effects = {
|
|||||||
getIPHostname(): Promise<string[]>
|
getIPHostname(): Promise<string[]>
|
||||||
/** Get the address for another service for tor interfaces */
|
/** Get the address for another service for tor interfaces */
|
||||||
getServiceTorHostname(
|
getServiceTorHostname(
|
||||||
interfaceId: string,
|
interfaceId: InterfaceId,
|
||||||
packageId?: string,
|
packageId?: string,
|
||||||
): Promise<string>
|
): Promise<string>
|
||||||
/** Get the IP address of the container */
|
/** Get the IP address of the container */
|
||||||
@@ -338,8 +336,20 @@ export type Effects = {
|
|||||||
*/
|
*/
|
||||||
getInterface(options: {
|
getInterface(options: {
|
||||||
packageId?: PackageId
|
packageId?: PackageId
|
||||||
interfaceId: string
|
interfaceId: InterfaceId
|
||||||
}): Promise<NetworkInterfaceOut>
|
callback: () => void
|
||||||
|
}): Promise<NetworkInterface>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There are times that we want to see the addresses that where exported
|
||||||
|
* @param options.addressId If we want to filter the address id
|
||||||
|
*
|
||||||
|
* Note: any auth should be filtered out already
|
||||||
|
*/
|
||||||
|
listInterface(options: {
|
||||||
|
packageId?: PackageId
|
||||||
|
callback: () => void
|
||||||
|
}): Promise<NetworkInterface[]>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Remove an address that was exported. Used problably during main or during setConfig.
|
*Remove an address that was exported. Used problably during main or during setConfig.
|
||||||
|
|||||||
284
lib/util/getNetworkInterface.ts
Normal file
284
lib/util/getNetworkInterface.ts
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
import {
|
||||||
|
Address,
|
||||||
|
Effects,
|
||||||
|
EnsureStorePath,
|
||||||
|
HostName,
|
||||||
|
NetworkInterface,
|
||||||
|
hostName,
|
||||||
|
} from "../types"
|
||||||
|
import * as regexes from "./regexes"
|
||||||
|
|
||||||
|
export type UrlString = string
|
||||||
|
export type HostId = string
|
||||||
|
|
||||||
|
export type Filled = {
|
||||||
|
hostnames: HostName[]
|
||||||
|
onionHostnames: HostName[]
|
||||||
|
localHostnames: HostName[]
|
||||||
|
ipHostnames: HostName[]
|
||||||
|
ipv4Hostnames: HostName[]
|
||||||
|
ipv6Hostnames: HostName[]
|
||||||
|
nonIpHostnames: HostName[]
|
||||||
|
allHostnames: HostName[]
|
||||||
|
|
||||||
|
urls: UrlString[]
|
||||||
|
onionUrls: UrlString[]
|
||||||
|
localUrls: UrlString[]
|
||||||
|
ipUrls: UrlString[]
|
||||||
|
ipv4Urls: UrlString[]
|
||||||
|
ipv6Urls: UrlString[]
|
||||||
|
nonIpUrls: UrlString[]
|
||||||
|
allUrls: UrlString[]
|
||||||
|
}
|
||||||
|
export type FilledAddress = Address & Filled
|
||||||
|
export type NetworkInterfaceFilled = {
|
||||||
|
interfaceId: string
|
||||||
|
/** The title of this field to be displayed */
|
||||||
|
name: string
|
||||||
|
/** Human readable description, used as tooltip usually */
|
||||||
|
description: string
|
||||||
|
/** All URIs */
|
||||||
|
addresses: FilledAddress[]
|
||||||
|
/** Defaults to false, but describes if this address can be opened in a browser as an
|
||||||
|
* ui interface
|
||||||
|
*/
|
||||||
|
ui?: boolean
|
||||||
|
} & Filled
|
||||||
|
const either =
|
||||||
|
<A>(...args: ((a: A) => boolean)[]) =>
|
||||||
|
(a: A) =>
|
||||||
|
args.some((x) => x(a))
|
||||||
|
const negate =
|
||||||
|
<A>(fn: (a: A) => boolean) =>
|
||||||
|
(a: A) =>
|
||||||
|
!fn(a)
|
||||||
|
const unique = <A>(values: A[]) => Array.from(new Set(values))
|
||||||
|
const addressHostToUrl = (
|
||||||
|
{ scheme, username, suffix }: Address,
|
||||||
|
host: HostName,
|
||||||
|
): UrlString =>
|
||||||
|
`${scheme ? `${scheme}//` : ""}${
|
||||||
|
username ? `${username}@` : ""
|
||||||
|
}${host}${suffix}`
|
||||||
|
export const filledAddress = (
|
||||||
|
mapHostnames: {
|
||||||
|
[hostId: string]: HostName[]
|
||||||
|
},
|
||||||
|
address: Address,
|
||||||
|
): FilledAddress => {
|
||||||
|
const toUrl = addressHostToUrl.bind(null, address)
|
||||||
|
const hostnames = mapHostnames[address.hostId] ?? []
|
||||||
|
return {
|
||||||
|
...address,
|
||||||
|
hostnames,
|
||||||
|
get onionHostnames() {
|
||||||
|
return hostnames.filter(regexes.onionHost.test)
|
||||||
|
},
|
||||||
|
get localHostnames() {
|
||||||
|
return hostnames.filter(regexes.localHost.test)
|
||||||
|
},
|
||||||
|
get ipHostnames() {
|
||||||
|
return hostnames.filter(either(regexes.ipv4.test, regexes.ipv6.test))
|
||||||
|
},
|
||||||
|
get ipv4Hostnames() {
|
||||||
|
return hostnames.filter(regexes.ipv4.test)
|
||||||
|
},
|
||||||
|
get ipv6Hostnames() {
|
||||||
|
return hostnames.filter(regexes.ipv6.test)
|
||||||
|
},
|
||||||
|
get nonIpHostnames() {
|
||||||
|
return hostnames.filter(
|
||||||
|
negate(either(regexes.ipv4.test, regexes.ipv6.test)),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
allHostnames: hostnames,
|
||||||
|
get urls() {
|
||||||
|
return hostnames.map(toUrl)
|
||||||
|
},
|
||||||
|
get onionUrls() {
|
||||||
|
return hostnames.filter(regexes.onionHost.test).map(toUrl)
|
||||||
|
},
|
||||||
|
get localUrls() {
|
||||||
|
return hostnames.filter(regexes.localHost.test).map(toUrl)
|
||||||
|
},
|
||||||
|
get ipUrls() {
|
||||||
|
return hostnames
|
||||||
|
.filter(either(regexes.ipv4.test, regexes.ipv6.test))
|
||||||
|
.map(toUrl)
|
||||||
|
},
|
||||||
|
get ipv4Urls() {
|
||||||
|
return hostnames.filter(regexes.ipv4.test).map(toUrl)
|
||||||
|
},
|
||||||
|
get ipv6Urls() {
|
||||||
|
return hostnames.filter(regexes.ipv6.test).map(toUrl)
|
||||||
|
},
|
||||||
|
get nonIpUrls() {
|
||||||
|
return hostnames
|
||||||
|
.filter(negate(either(regexes.ipv4.test, regexes.ipv6.test)))
|
||||||
|
.map(toUrl)
|
||||||
|
},
|
||||||
|
get allUrls() {
|
||||||
|
return hostnames.map(toUrl)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const networkInterfaceFilled = (
|
||||||
|
interfaceValue: NetworkInterface,
|
||||||
|
addresses: FilledAddress[],
|
||||||
|
): NetworkInterfaceFilled => {
|
||||||
|
return {
|
||||||
|
...interfaceValue,
|
||||||
|
addresses,
|
||||||
|
get hostnames() {
|
||||||
|
return unique(addresses.flatMap((x) => x.hostnames))
|
||||||
|
},
|
||||||
|
get onionHostnames() {
|
||||||
|
return unique(addresses.flatMap((x) => x.onionHostnames))
|
||||||
|
},
|
||||||
|
get localHostnames() {
|
||||||
|
return unique(addresses.flatMap((x) => x.localHostnames))
|
||||||
|
},
|
||||||
|
get ipHostnames() {
|
||||||
|
return unique(addresses.flatMap((x) => x.ipHostnames))
|
||||||
|
},
|
||||||
|
get ipv4Hostnames() {
|
||||||
|
return unique(addresses.flatMap((x) => x.ipv4Hostnames))
|
||||||
|
},
|
||||||
|
get ipv6Hostnames() {
|
||||||
|
return unique(addresses.flatMap((x) => x.ipv6Hostnames))
|
||||||
|
},
|
||||||
|
get nonIpHostnames() {
|
||||||
|
return unique(addresses.flatMap((x) => x.nonIpHostnames))
|
||||||
|
},
|
||||||
|
get allHostnames() {
|
||||||
|
return unique(addresses.flatMap((x) => x.allHostnames))
|
||||||
|
},
|
||||||
|
get urls() {
|
||||||
|
return unique(addresses.flatMap((x) => x.urls))
|
||||||
|
},
|
||||||
|
get onionUrls() {
|
||||||
|
return unique(addresses.flatMap((x) => x.onionUrls))
|
||||||
|
},
|
||||||
|
get localUrls() {
|
||||||
|
return unique(addresses.flatMap((x) => x.localUrls))
|
||||||
|
},
|
||||||
|
get ipUrls() {
|
||||||
|
return unique(addresses.flatMap((x) => x.ipUrls))
|
||||||
|
},
|
||||||
|
get ipv4Urls() {
|
||||||
|
return unique(addresses.flatMap((x) => x.ipv4Urls))
|
||||||
|
},
|
||||||
|
get ipv6Urls() {
|
||||||
|
return unique(addresses.flatMap((x) => x.ipv6Urls))
|
||||||
|
},
|
||||||
|
get nonIpUrls() {
|
||||||
|
return unique(addresses.flatMap((x) => x.nonIpUrls))
|
||||||
|
},
|
||||||
|
get allUrls() {
|
||||||
|
return unique(addresses.flatMap((x) => x.allUrls))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const makeInterfaceFilled = async ({
|
||||||
|
effects,
|
||||||
|
interfaceId,
|
||||||
|
packageId,
|
||||||
|
callback,
|
||||||
|
}: {
|
||||||
|
effects: Effects
|
||||||
|
interfaceId: string
|
||||||
|
packageId: string | undefined
|
||||||
|
callback: () => void
|
||||||
|
}) => {
|
||||||
|
const interfaceValue = await effects.getInterface({
|
||||||
|
interfaceId,
|
||||||
|
packageId,
|
||||||
|
callback,
|
||||||
|
})
|
||||||
|
const hostIdsRecord: { [hostId: HostId]: HostName[] } = Object.fromEntries(
|
||||||
|
await Promise.all(
|
||||||
|
unique(interfaceValue.addresses.map((x) => x.hostId)).map(
|
||||||
|
async (hostId) => [
|
||||||
|
hostId,
|
||||||
|
effects.getHostnames({
|
||||||
|
packageId,
|
||||||
|
hostId,
|
||||||
|
callback,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
const fillAddress = filledAddress.bind(null, hostIdsRecord)
|
||||||
|
const interfaceFilled: NetworkInterfaceFilled = networkInterfaceFilled(
|
||||||
|
interfaceValue,
|
||||||
|
interfaceValue.addresses.map(fillAddress),
|
||||||
|
)
|
||||||
|
return interfaceFilled
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GetNetworkInterface {
|
||||||
|
constructor(
|
||||||
|
readonly effects: Effects,
|
||||||
|
readonly opts: { interfaceId: string; packageId?: string },
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of Store at the provided path. Restart the service if the value changes
|
||||||
|
*/
|
||||||
|
async const() {
|
||||||
|
const { interfaceId, packageId } = this.opts
|
||||||
|
const callback = this.effects.restart
|
||||||
|
const interfaceFilled: NetworkInterfaceFilled = await makeInterfaceFilled({
|
||||||
|
effects: this.effects,
|
||||||
|
interfaceId,
|
||||||
|
packageId,
|
||||||
|
callback,
|
||||||
|
})
|
||||||
|
|
||||||
|
return interfaceFilled
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the value of NetworkInterfacesFilled at the provided path. Does nothing if the value changes
|
||||||
|
*/
|
||||||
|
async once() {
|
||||||
|
const { interfaceId, packageId } = this.opts
|
||||||
|
const callback = () => {}
|
||||||
|
const interfaceFilled: NetworkInterfaceFilled = await makeInterfaceFilled({
|
||||||
|
effects: this.effects,
|
||||||
|
interfaceId,
|
||||||
|
packageId,
|
||||||
|
callback,
|
||||||
|
})
|
||||||
|
|
||||||
|
return interfaceFilled
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watches the value of NetworkInterfacesFilled at the provided path. Takes a custom callback function to run whenever the value changes
|
||||||
|
*/
|
||||||
|
async *watch() {
|
||||||
|
const { interfaceId, packageId } = this.opts
|
||||||
|
while (true) {
|
||||||
|
let callback: () => void = () => {}
|
||||||
|
const waitForNext = new Promise<void>((resolve) => {
|
||||||
|
callback = resolve
|
||||||
|
})
|
||||||
|
yield await makeInterfaceFilled({
|
||||||
|
effects: this.effects,
|
||||||
|
interfaceId,
|
||||||
|
packageId,
|
||||||
|
callback,
|
||||||
|
})
|
||||||
|
await waitForNext
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export function getNetworkInterface(
|
||||||
|
effects: Effects,
|
||||||
|
opts: { interfaceId: string; packageId?: string },
|
||||||
|
) {
|
||||||
|
return new GetNetworkInterface(effects, opts)
|
||||||
|
}
|
||||||
112
lib/util/getNetworkInterfaces.ts
Normal file
112
lib/util/getNetworkInterfaces.ts
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
import { Address, Effects, EnsureStorePath, HostName, hostName } from "../types"
|
||||||
|
import * as regexes from "./regexes"
|
||||||
|
import {
|
||||||
|
HostId,
|
||||||
|
NetworkInterfaceFilled,
|
||||||
|
filledAddress,
|
||||||
|
networkInterfaceFilled,
|
||||||
|
} from "./getNetworkInterface"
|
||||||
|
|
||||||
|
const makeManyInterfaceFilled = async ({
|
||||||
|
effects,
|
||||||
|
packageId,
|
||||||
|
callback,
|
||||||
|
}: {
|
||||||
|
effects: Effects
|
||||||
|
packageId: string | undefined
|
||||||
|
callback: () => void
|
||||||
|
}) => {
|
||||||
|
const interfaceValues = await effects.listInterface({
|
||||||
|
packageId,
|
||||||
|
callback,
|
||||||
|
})
|
||||||
|
const hostIdsRecord: { [hostId: HostId]: HostName[] } = Object.fromEntries(
|
||||||
|
await Promise.all(
|
||||||
|
Array.from(
|
||||||
|
new Set(
|
||||||
|
interfaceValues.flatMap((x) => x.addresses).map((x) => x.hostId),
|
||||||
|
),
|
||||||
|
).map(async (hostId) => [
|
||||||
|
hostId,
|
||||||
|
effects.getHostnames({
|
||||||
|
packageId,
|
||||||
|
hostId,
|
||||||
|
callback,
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
const fillAddress = filledAddress.bind(null, hostIdsRecord)
|
||||||
|
|
||||||
|
const interfacesFilled: NetworkInterfaceFilled[] = interfaceValues.map(
|
||||||
|
(interfaceValue) =>
|
||||||
|
networkInterfaceFilled(
|
||||||
|
interfaceValue,
|
||||||
|
interfaceValue.addresses.map(fillAddress),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return interfacesFilled
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GetNetworkInterfaces {
|
||||||
|
constructor(
|
||||||
|
readonly effects: Effects,
|
||||||
|
readonly opts: { packageId?: string },
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of Store at the provided path. Restart the service if the value changes
|
||||||
|
*/
|
||||||
|
async const() {
|
||||||
|
const { packageId } = this.opts
|
||||||
|
const callback = this.effects.restart
|
||||||
|
const interfaceFilled: NetworkInterfaceFilled[] =
|
||||||
|
await makeManyInterfaceFilled({
|
||||||
|
effects: this.effects,
|
||||||
|
packageId,
|
||||||
|
callback,
|
||||||
|
})
|
||||||
|
|
||||||
|
return interfaceFilled
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the value of NetworkInterfacesFilled at the provided path. Does nothing if the value changes
|
||||||
|
*/
|
||||||
|
async once() {
|
||||||
|
const { packageId } = this.opts
|
||||||
|
const callback = () => {}
|
||||||
|
const interfaceFilled: NetworkInterfaceFilled[] =
|
||||||
|
await makeManyInterfaceFilled({
|
||||||
|
effects: this.effects,
|
||||||
|
packageId,
|
||||||
|
callback,
|
||||||
|
})
|
||||||
|
|
||||||
|
return interfaceFilled
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watches the value of NetworkInterfacesFilled at the provided path. Takes a custom callback function to run whenever the value changes
|
||||||
|
*/
|
||||||
|
async *watch() {
|
||||||
|
const { packageId } = this.opts
|
||||||
|
while (true) {
|
||||||
|
let callback: () => void = () => {}
|
||||||
|
const waitForNext = new Promise<void>((resolve) => {
|
||||||
|
callback = resolve
|
||||||
|
})
|
||||||
|
yield await makeManyInterfaceFilled({
|
||||||
|
effects: this.effects,
|
||||||
|
packageId,
|
||||||
|
callback,
|
||||||
|
})
|
||||||
|
await waitForNext
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export function getNetworkInterfaces(
|
||||||
|
effects: Effects,
|
||||||
|
opts: { packageId?: string },
|
||||||
|
) {
|
||||||
|
return new GetNetworkInterfaces(effects, opts)
|
||||||
|
}
|
||||||
@@ -13,9 +13,12 @@ export const url =
|
|||||||
export const local =
|
export const local =
|
||||||
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.local\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/
|
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.local\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/
|
||||||
|
|
||||||
|
export const localHost = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.local/
|
||||||
|
|
||||||
export const onion =
|
export const onion =
|
||||||
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.onion\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/
|
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.onion\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/
|
||||||
|
|
||||||
|
export const onionHost = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.onion/
|
||||||
// https://ihateregex.io/expr/ascii/
|
// https://ihateregex.io/expr/ascii/
|
||||||
export const ascii = /^[ -~]*$/
|
export const ascii = /^[ -~]*$/
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import * as T from "../types"
|
|
||||||
import FileHelper from "./fileHelper"
|
import FileHelper from "./fileHelper"
|
||||||
import nullIfEmpty from "./nullIfEmpty"
|
import nullIfEmpty from "./nullIfEmpty"
|
||||||
import {
|
import {
|
||||||
@@ -6,7 +5,13 @@ import {
|
|||||||
checkPortListening,
|
checkPortListening,
|
||||||
checkWebUrl,
|
checkWebUrl,
|
||||||
} from "../health/checkFns"
|
} from "../health/checkFns"
|
||||||
import { ExtractStore } from "../types"
|
import {
|
||||||
|
Effects,
|
||||||
|
EnsureStorePath,
|
||||||
|
ExtractStore,
|
||||||
|
InterfaceId,
|
||||||
|
PackageId,
|
||||||
|
} from "../types"
|
||||||
import { GetSystemSmtp } from "./GetSystemSmtp"
|
import { GetSystemSmtp } from "./GetSystemSmtp"
|
||||||
import { DefaultString } from "../config/configTypes"
|
import { DefaultString } from "../config/configTypes"
|
||||||
import { getDefaultString } from "./getDefaultString"
|
import { getDefaultString } from "./getDefaultString"
|
||||||
@@ -24,6 +29,11 @@ import {
|
|||||||
} from "../dependency/setupDependencyMounts"
|
} from "../dependency/setupDependencyMounts"
|
||||||
import { Host, MultiHost, SingleHost, StaticHost } from "../interfaces/Host"
|
import { Host, MultiHost, SingleHost, StaticHost } from "../interfaces/Host"
|
||||||
import { NetworkInterfaceBuilder } from "../interfaces/NetworkInterfaceBuilder"
|
import { NetworkInterfaceBuilder } from "../interfaces/NetworkInterfaceBuilder"
|
||||||
|
import { GetNetworkInterface, getNetworkInterface } from "./getNetworkInterface"
|
||||||
|
import {
|
||||||
|
GetNetworkInterfaces,
|
||||||
|
getNetworkInterfaces,
|
||||||
|
} from "./getNetworkInterfaces"
|
||||||
|
|
||||||
export type Utils<Store, Vault, WrapperOverWrite = { const: never }> = {
|
export type Utils<Store, Vault, WrapperOverWrite = { const: never }> = {
|
||||||
checkPortListening(
|
checkPortListening(
|
||||||
@@ -73,18 +83,29 @@ export type Utils<Store, Vault, WrapperOverWrite = { const: never }> = {
|
|||||||
>(
|
>(
|
||||||
value: In,
|
value: In,
|
||||||
) => Promise<MountDependenciesOut<In>>
|
) => Promise<MountDependenciesOut<In>>
|
||||||
|
networkInterface: {
|
||||||
|
getOwn: (interfaceId: InterfaceId) => GetNetworkInterface & WrapperOverWrite
|
||||||
|
get: (opts: {
|
||||||
|
interfaceId: InterfaceId
|
||||||
|
packageId: PackageId
|
||||||
|
}) => GetNetworkInterface & WrapperOverWrite
|
||||||
|
getAllOwn: () => GetNetworkInterfaces & WrapperOverWrite
|
||||||
|
getAll: (opts: {
|
||||||
|
packageId: PackageId
|
||||||
|
}) => GetNetworkInterfaces & WrapperOverWrite
|
||||||
|
}
|
||||||
nullIfEmpty: typeof nullIfEmpty
|
nullIfEmpty: typeof nullIfEmpty
|
||||||
readFile: <A>(fileHelper: FileHelper<A>) => ReturnType<FileHelper<A>["read"]>
|
readFile: <A>(fileHelper: FileHelper<A>) => ReturnType<FileHelper<A>["read"]>
|
||||||
store: {
|
store: {
|
||||||
get: <Path extends string>(
|
get: <Path extends string>(
|
||||||
packageId: string,
|
packageId: string,
|
||||||
path: T.EnsureStorePath<Store, Path>,
|
path: EnsureStorePath<Store, Path>,
|
||||||
) => GetStore<Store, Path> & WrapperOverWrite
|
) => GetStore<Store, Path> & WrapperOverWrite
|
||||||
getOwn: <Path extends string>(
|
getOwn: <Path extends string>(
|
||||||
path: T.EnsureStorePath<Store, Path>,
|
path: EnsureStorePath<Store, Path>,
|
||||||
) => GetStore<Store, Path> & WrapperOverWrite
|
) => GetStore<Store, Path> & WrapperOverWrite
|
||||||
setOwn: <Path extends string | never>(
|
setOwn: <Path extends string | never>(
|
||||||
path: T.EnsureStorePath<Store, Path>,
|
path: EnsureStorePath<Store, Path>,
|
||||||
value: ExtractStore<Store, Path>,
|
value: ExtractStore<Store, Path>,
|
||||||
) => Promise<void>
|
) => Promise<void>
|
||||||
}
|
}
|
||||||
@@ -102,7 +123,7 @@ export const utils = <
|
|||||||
Vault = never,
|
Vault = never,
|
||||||
WrapperOverWrite = { const: never },
|
WrapperOverWrite = { const: never },
|
||||||
>(
|
>(
|
||||||
effects: T.Effects,
|
effects: Effects,
|
||||||
): Utils<Store, Vault, WrapperOverWrite> => ({
|
): Utils<Store, Vault, WrapperOverWrite> => ({
|
||||||
createOrUpdateVault: async ({
|
createOrUpdateVault: async ({
|
||||||
key,
|
key,
|
||||||
@@ -147,18 +168,33 @@ export const utils = <
|
|||||||
writeFile: <A>(fileHelper: FileHelper<A>, data: A) =>
|
writeFile: <A>(fileHelper: FileHelper<A>, data: A) =>
|
||||||
fileHelper.write(data, effects),
|
fileHelper.write(data, effects),
|
||||||
nullIfEmpty,
|
nullIfEmpty,
|
||||||
|
|
||||||
|
networkInterface: {
|
||||||
|
getOwn: (interfaceId: InterfaceId) =>
|
||||||
|
getNetworkInterface(effects, { interfaceId }) as GetNetworkInterface &
|
||||||
|
WrapperOverWrite,
|
||||||
|
get: (opts: { interfaceId: InterfaceId; packageId: PackageId }) =>
|
||||||
|
getNetworkInterface(effects, opts) as GetNetworkInterface &
|
||||||
|
WrapperOverWrite,
|
||||||
|
getAllOwn: () =>
|
||||||
|
getNetworkInterfaces(effects, {}) as GetNetworkInterfaces &
|
||||||
|
WrapperOverWrite,
|
||||||
|
getAll: (opts: { packageId: PackageId }) =>
|
||||||
|
getNetworkInterfaces(effects, opts) as GetNetworkInterfaces &
|
||||||
|
WrapperOverWrite,
|
||||||
|
},
|
||||||
store: {
|
store: {
|
||||||
get: <Path extends string = never>(
|
get: <Path extends string = never>(
|
||||||
packageId: string,
|
packageId: string,
|
||||||
path: T.EnsureStorePath<Store, Path>,
|
path: EnsureStorePath<Store, Path>,
|
||||||
) =>
|
) =>
|
||||||
getStore<Store, Path>(effects, path as any, {
|
getStore<Store, Path>(effects, path as any, {
|
||||||
packageId,
|
packageId,
|
||||||
}) as any,
|
}) as any,
|
||||||
getOwn: <Path extends string>(path: T.EnsureStorePath<Store, Path>) =>
|
getOwn: <Path extends string>(path: EnsureStorePath<Store, Path>) =>
|
||||||
getStore<Store, Path>(effects, path as any) as any,
|
getStore<Store, Path>(effects, path as any) as any,
|
||||||
setOwn: <Path extends string | never>(
|
setOwn: <Path extends string | never>(
|
||||||
path: T.EnsureStorePath<Store, Path>,
|
path: EnsureStorePath<Store, Path>,
|
||||||
value: ExtractStore<Store, Path>,
|
value: ExtractStore<Store, Path>,
|
||||||
) => effects.store.set<Store, Path>({ value, path: path as any }),
|
) => effects.store.set<Store, Path>({ value, path: path as any }),
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user