| author | |
| committer | |
| log | cc69aef4dd140703762282ea207e0bcae7f9d9a1 |
| tree | 2b1958308586e1fc2487ab9fe29257eb7f1328c2 |
| parent | 71608142c27136a5ba0551fe9ed52ceeaad22ee4 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: codex <codex@users.noreply.github.com>2 files changed, 46 insertions(+), 1 deletions(-)
infra/relay/src/deploymentConfig.test.ts+27| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | import { describe, expect, it } from "vite-plus/test"; |
| 2 | import * as Schema from "effect/Schema"; | |
| 2 | 3 | |
| 3 | 4 | import { |
| 4 | 5 | managedEndpointDigestInput, |
| ... | ... | @@ -7,11 +8,14 @@ import { |
| 7 | 8 | isManagedEndpointHostname, |
| 8 | 9 | managedEndpointTunnelName, |
| 9 | 10 | relayOwnsManagedEndpointZone, |
| 11 | RelayPublicDomainLabelTooLongError, | |
| 10 | 12 | relayPublicDomainForStage, |
| 11 | 13 | relayResourceNameForStage, |
| 12 | 14 | relayStageSlug, |
| 13 | 15 | } from "./deploymentConfig.ts"; |
| 14 | 16 | |
| 17 | const isRelayPublicDomainLabelTooLongError = Schema.is(RelayPublicDomainLabelTooLongError); | |
| 18 | ||
| 15 | 19 | describe("relayStageSlug", () => { |
| 16 | 20 | it("matches Alchemy physical-name sanitization for default developer stages", () => { |
| 17 | 21 | expect(relayStageSlug("dev_julius")).toBe("dev-julius"); |
| ... | ... | @@ -28,6 +32,29 @@ describe("relayPublicDomainForStage", () => { |
| 28 | 32 | "relay-dev-julius.example.com", |
| 29 | 33 | ); |
| 30 | 34 | }); |
| 35 | ||
| 36 | it("reports the stage and derived DNS label when the label is too long", () => { | |
| 37 | const stage = `dev_${"x".repeat(60)}`; | |
| 38 | let error: unknown; | |
| 39 | ||
| 40 | try { | |
| 41 | relayPublicDomainForStage(stage, "example.com"); | |
| 42 | } catch (cause) { | |
| 43 | error = cause; | |
| 44 | } | |
| 45 | ||
| 46 | if (!isRelayPublicDomainLabelTooLongError(error)) { | |
| 47 | throw error; | |
| 48 | } | |
| 49 | expect(error).toMatchObject({ | |
| 50 | stage, | |
| 51 | label: `relay-dev-${"x".repeat(60)}`, | |
| 52 | maxLength: 63, | |
| 53 | }); | |
| 54 | expect(error.message).toBe( | |
| 55 | `Relay stage '${stage}' produces custom domain label 'relay-dev-${"x".repeat(60)}' (70 characters), exceeding the DNS label limit of 63.`, | |
| 56 | ); | |
| 57 | }); | |
| 31 | 58 | }); |
| 32 | 59 | |
| 33 | 60 | describe("relayOwnsManagedEndpointZone", () => { |
infra/relay/src/deploymentConfig.ts+19-1| ... | ... | @@ -1,10 +1,24 @@ |
| 1 | 1 | import type { RelayManagedEndpoint } from "@t3tools/contracts/relay"; |
| 2 | import * as Schema from "effect/Schema"; | |
| 2 | 3 | |
| 3 | 4 | const DNS_LABEL_MAX_LENGTH = 63; |
| 4 | 5 | const MANAGED_ENDPOINT_HASH_LENGTH = 16; |
| 5 | 6 | const MANAGED_ENDPOINT_TUNNEL_PREFIX = "t3coderelay-managedendpoint"; |
| 6 | 7 | export const MANAGED_ENDPOINT_ZONE_OWNER_STAGE = "prod"; |
| 7 | 8 | |
| 9 | export class RelayPublicDomainLabelTooLongError extends Schema.TaggedErrorClass<RelayPublicDomainLabelTooLongError>()( | |
| 10 | "RelayPublicDomainLabelTooLongError", | |
| 11 | { | |
| 12 | stage: Schema.String, | |
| 13 | label: Schema.String, | |
| 14 | maxLength: Schema.Number, | |
| 15 | }, | |
| 16 | ) { | |
| 17 | override get message(): string { | |
| 18 | return `Relay stage '${this.stage}' produces custom domain label '${this.label}' (${this.label.length} characters), exceeding the DNS label limit of ${this.maxLength}.`; | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 8 | 22 | function normalizeZoneName(zoneName: string): string { |
| 9 | 23 | return zoneName |
| 10 | 24 | .trim() |
| ... | ... | @@ -62,7 +76,11 @@ export function relayPublicDomainForStage(stage: string, zoneName: string): stri |
| 62 | 76 | const stageSlug = relayStageSlug(stage); |
| 63 | 77 | const relayLabel = stage === "prod" ? "relay" : `relay-${stageSlug}`; |
| 64 | 78 | if (relayLabel.length > DNS_LABEL_MAX_LENGTH) { |
| 65 | throw new Error(`Relay stage is too long for a custom domain: ${stage}`); | |
| 79 | throw new RelayPublicDomainLabelTooLongError({ | |
| 80 | stage, | |
| 81 | label: relayLabel, | |
| 82 | maxLength: DNS_LABEL_MAX_LENGTH, | |
| 83 | }); | |
| 66 | 84 | } |
| 67 | 85 | return `${relayLabel}.${normalizeZoneName(zoneName)}`; |
| 68 | 86 | } |