From 78f28f544edc5e9696786cb44abdd5a78992f03d Mon Sep 17 00:00:00 2001 From: BluJ Date: Wed, 10 May 2023 09:46:17 -0600 Subject: [PATCH 1/3] chore: Host with minor refactors --- lib/mainFn/Host.ts | 193 ++++++++++++++++++++++++++++++++------------- 1 file changed, 140 insertions(+), 53 deletions(-) diff --git a/lib/mainFn/Host.ts b/lib/mainFn/Host.ts index 5bccabb..622a88a 100644 --- a/lib/mainFn/Host.ts +++ b/lib/mainFn/Host.ts @@ -68,19 +68,45 @@ export type PortOptions = { preferredExternalPort: number addSsl: AddSslOptions | null } & Security -type PortOptionsByKnownProtocol = +type KnownProtocols = typeof knownProtocols +type SslProtocols = { + [K in keyof KnownProtocols]: KnownProtocols[K] extends { ssl: true } + ? K + : never +}[keyof KnownProtocols] +type NotSslProtocols = Exclude +type OldPortOptionsByKnownProtocol = (typeof knownProtocols)[T] extends { withSsl: KnownProtocol } ? BasePortOptions & ({ noAddSsl: true } | { addSsl?: Partial }) : BasePortOptions & { addSsl?: AddSslOptions | null } -type PortOptionsByProtocol = T extends KnownProtocol - ? PortOptionsByKnownProtocol +type OldPortOptionsByProtocol = T extends KnownProtocol + ? OldPortOptionsByKnownProtocol : PortOptions +type PortOptionsByKnownProtocol = + | ({ + protocol: SslProtocols + preferredExternalPort?: number + scheme?: Scheme + } & ({ noAddSsl: true } | { addSsl?: Partial })) + | { + protocol: NotSslProtocols + preferredExternalPort?: number + scheme?: Scheme + addSsl?: AddSslOptions | null + } +type PortOptionsByProtocol = PortOptionsByKnownProtocol | PortOptions + function isForKnownProtocol( - options: PortOptionsByProtocol | PortOptionsByProtocol, -): options is PortOptionsByProtocol { - return "protocol" in options && (options.protocol as string) in knownProtocols + options: PortOptionsByProtocol, +): options is PortOptionsByKnownProtocol { + return "protocol" in options && options.protocol in knownProtocols +} + +const TRUE_DEFAULT = { + preferredExternalPort: 443, + scheme: "https", } export class Host { @@ -92,60 +118,121 @@ export class Host { }, ) {} - async bindPort( + async bindPort( internalPort: number, - options: PortOptionsByProtocol, + options: PortOptionsByProtocol, ): Promise> { if (isForKnownProtocol(options)) { - const scheme = - options.scheme === undefined ? options.protocol : options.scheme - const protoInfo = knownProtocols[options.protocol] - const preferredExternalPort = - options.preferredExternalPort || - knownProtocols[options.protocol].defaultPort - const defaultAddSsl = - "noAddSsl" in options && options.noAddSsl - ? null - : "withSsl" in protoInfo - ? { - preferredExternalPort: - knownProtocols[protoInfo.withSsl].defaultPort, - scheme: protoInfo.withSsl, - } - : null - const addSsl = options.addSsl + return await this.bindPortForKnown(options, internalPort) + } else { + return await this.bindPortForUnknown(internalPort, options) + } + } + + private async bindPortForUnknown( + internalPort: number, + options: + | ({ + scheme: Scheme + preferredExternalPort: number + addSsl: AddSslOptions | null + } & { secure: false; ssl: false }) + | ({ + scheme: Scheme + preferredExternalPort: number + addSsl: AddSslOptions | null + } & { secure: true; ssl: boolean }), + ) { + await this.options.effects.bind({ + kind: this.kind, + id: this.options.id, + internalPort: internalPort, + ...options, + }) + + return new Origin(this, options) + } + + private async bindPortForKnown( + options: PortOptionsByKnownProtocol, + internalPort: number, + ) { + const scheme = + options.scheme === undefined ? options.protocol : options.scheme + const protoInfo = knownProtocols[options.protocol] + const preferredExternalPort = + options.preferredExternalPort || + knownProtocols[options.protocol].defaultPort + const defaultAddSsl = this.bindPortForKnownDefaulAddSsl(options, protoInfo) + const addSsl = + "addSsl" in options ? { ...defaultAddSsl, ...options.addSsl } : defaultAddSsl - const security = { - secure: protoInfo.secure, - ssl: protoInfo.ssl, - } as Security + const security: Security = !protoInfo.secure + ? { + secure: protoInfo.secure, + ssl: protoInfo.ssl, + } + : { secure: false, ssl: false } - const newOptions = { - scheme, - preferredExternalPort, - addSsl, - ...security, - } - - await this.options.effects.bind({ - kind: this.kind, - id: this.options.id, - internalPort: internalPort, - ...newOptions, - }) - - return new Origin(this, newOptions) - } else { - await this.options.effects.bind({ - kind: this.kind, - id: this.options.id, - internalPort: internalPort, - ...options, - }) - - return new Origin(this, options) + const newOptions = { + scheme, + preferredExternalPort, + addSsl, + ...security, } + + await this.options.effects.bind({ + kind: this.kind, + id: this.options.id, + internalPort, + ...newOptions, + }) + + return new Origin(this, newOptions) + } + + private bindPortForKnownDefaulAddSsl( + options: PortOptionsByKnownProtocol, + protoInfo: + | { + readonly secure: false + readonly ssl: false + readonly defaultPort: 80 + readonly withSsl: "https" + } + | { readonly secure: true; readonly ssl: true; readonly defaultPort: 443 } + | { + readonly secure: false + readonly ssl: false + readonly defaultPort: 80 + readonly withSsl: "wss" + } + | { readonly secure: true; readonly ssl: true; readonly defaultPort: 443 } + | { readonly secure: true; readonly ssl: false; readonly defaultPort: 22 } + | { + readonly secure: true + readonly ssl: false + readonly defaultPort: 8333 + } + | { + readonly secure: true + readonly ssl: true + readonly defaultPort: 50051 + } + | { + readonly secure: true + readonly ssl: false + readonly defaultPort: 53 + }, + ) { + if ("noAddSsl" in options && options.noAddSsl) return TRUE_DEFAULT + if ("withSsl" in protoInfo) + return { + preferredExternalPort: knownProtocols[protoInfo.withSsl].defaultPort, + scheme: protoInfo.withSsl, + } + return TRUE_DEFAULT } } From 7e74c4bfd1d8ce1dec9eebacbe5d855f3cc57825 Mon Sep 17 00:00:00 2001 From: BluJ Date: Wed, 10 May 2023 10:30:14 -0600 Subject: [PATCH 2/3] chore: Update types --- lib/mainFn/Host.ts | 42 ++---------------------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/lib/mainFn/Host.ts b/lib/mainFn/Host.ts index 622a88a..8b50f8c 100644 --- a/lib/mainFn/Host.ts +++ b/lib/mainFn/Host.ts @@ -75,14 +75,6 @@ type SslProtocols = { : never }[keyof KnownProtocols] type NotSslProtocols = Exclude -type OldPortOptionsByKnownProtocol = - (typeof knownProtocols)[T] extends { withSsl: KnownProtocol } - ? BasePortOptions & - ({ noAddSsl: true } | { addSsl?: Partial }) - : BasePortOptions & { addSsl?: AddSslOptions | null } -type OldPortOptionsByProtocol = T extends KnownProtocol - ? OldPortOptionsByKnownProtocol - : PortOptions type PortOptionsByKnownProtocol = | ({ @@ -194,40 +186,10 @@ export class Host { private bindPortForKnownDefaulAddSsl( options: PortOptionsByKnownProtocol, - protoInfo: - | { - readonly secure: false - readonly ssl: false - readonly defaultPort: 80 - readonly withSsl: "https" - } - | { readonly secure: true; readonly ssl: true; readonly defaultPort: 443 } - | { - readonly secure: false - readonly ssl: false - readonly defaultPort: 80 - readonly withSsl: "wss" - } - | { readonly secure: true; readonly ssl: true; readonly defaultPort: 443 } - | { readonly secure: true; readonly ssl: false; readonly defaultPort: 22 } - | { - readonly secure: true - readonly ssl: false - readonly defaultPort: 8333 - } - | { - readonly secure: true - readonly ssl: true - readonly defaultPort: 50051 - } - | { - readonly secure: true - readonly ssl: false - readonly defaultPort: 53 - }, + protoInfo: KnownProtocols[keyof KnownProtocols], ) { if ("noAddSsl" in options && options.noAddSsl) return TRUE_DEFAULT - if ("withSsl" in protoInfo) + if ("withSsl" in protoInfo && protoInfo.withSsl) return { preferredExternalPort: knownProtocols[protoInfo.withSsl].defaultPort, scheme: protoInfo.withSsl, From b07fda724b57e3f3120ddb7e7bd2db24e3a90670 Mon Sep 17 00:00:00 2001 From: BluJ Date: Wed, 10 May 2023 11:09:10 -0600 Subject: [PATCH 3/3] chore: Update the types --- lib/mainFn/Host.ts | 55 +++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/lib/mainFn/Host.ts b/lib/mainFn/Host.ts index 8b50f8c..64012b4 100644 --- a/lib/mainFn/Host.ts +++ b/lib/mainFn/Host.ts @@ -1,5 +1,5 @@ +import { object, string } from "ts-matches" import { Effects } from "../types" -import { AddressReceipt } from "./AddressReceipt" import { NetworkInterfaceBuilder } from "./NetworkInterfaceBuilder" import { Origin } from "./Origin" @@ -48,15 +48,8 @@ const knownProtocols = { }, } as const -type KnownProtocol = keyof typeof knownProtocols - type Scheme = string | null -type BasePortOptions = { - protocol: T - preferredExternalPort?: number - scheme?: Scheme -} type AddSslOptions = { preferredExternalPort: number scheme: Scheme @@ -69,37 +62,35 @@ export type PortOptions = { addSsl: AddSslOptions | null } & Security type KnownProtocols = typeof knownProtocols -type SslProtocols = { - [K in keyof KnownProtocols]: KnownProtocols[K] extends { ssl: true } +type ProtocolsWithSslVariants = { + [K in keyof KnownProtocols]: KnownProtocols[K] extends { + withSsl: string + } ? K : never }[keyof KnownProtocols] -type NotSslProtocols = Exclude +type NotProtocolsWithSslVariants = Exclude< + keyof KnownProtocols, + ProtocolsWithSslVariants +> type PortOptionsByKnownProtocol = | ({ - protocol: SslProtocols + protocol: ProtocolsWithSslVariants preferredExternalPort?: number scheme?: Scheme } & ({ noAddSsl: true } | { addSsl?: Partial })) | { - protocol: NotSslProtocols + protocol: NotProtocolsWithSslVariants preferredExternalPort?: number scheme?: Scheme addSsl?: AddSslOptions | null } type PortOptionsByProtocol = PortOptionsByKnownProtocol | PortOptions -function isForKnownProtocol( - options: PortOptionsByProtocol, -): options is PortOptionsByKnownProtocol { - return "protocol" in options && options.protocol in knownProtocols -} - -const TRUE_DEFAULT = { - preferredExternalPort: 443, - scheme: "https", -} +const hasStringProtocal = object({ + protocol: string, +}).test export class Host { constructor( @@ -114,7 +105,7 @@ export class Host { internalPort: number, options: PortOptionsByProtocol, ): Promise> { - if (isForKnownProtocol(options)) { + if (hasStringProtocal(options)) { return await this.bindPortForKnown(options, internalPort) } else { return await this.bindPortForUnknown(internalPort, options) @@ -155,11 +146,8 @@ export class Host { const preferredExternalPort = options.preferredExternalPort || knownProtocols[options.protocol].defaultPort - const defaultAddSsl = this.bindPortForKnownDefaulAddSsl(options, protoInfo) - const addSsl = - "addSsl" in options - ? { ...defaultAddSsl, ...options.addSsl } - : defaultAddSsl + const addSsl = this.getAddSsl(options, protoInfo) + const security: Security = !protoInfo.secure ? { secure: protoInfo.secure, @@ -184,17 +172,18 @@ export class Host { return new Origin(this, newOptions) } - private bindPortForKnownDefaulAddSsl( + private getAddSsl( options: PortOptionsByKnownProtocol, protoInfo: KnownProtocols[keyof KnownProtocols], - ) { - if ("noAddSsl" in options && options.noAddSsl) return TRUE_DEFAULT + ): AddSslOptions | null { + if ("noAddSsl" in options && options.noAddSsl) return null if ("withSsl" in protoInfo && protoInfo.withSsl) return { preferredExternalPort: knownProtocols[protoInfo.withSsl].defaultPort, scheme: protoInfo.withSsl, + ...("addSsl" in options ? options.addSsl : null), } - return TRUE_DEFAULT + return null } }