| author | |
| committer | |
| log | f3b43a148b9e39192be5d43415289ac06eca1443 |
| tree | fc64290a0de808a540049bc73aa28323870ecbb5 |
| parent | 8331511b972242301bdaec328148a88b9b6cfa6c |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: codex <codex@users.noreply.github.com>4 files changed, 51 insertions(+), 4 deletions(-)
apps/mobile/src/features/cloud/publicConfig.test.ts+12-1| ... | ... | @@ -1,6 +1,11 @@ |
| 1 | 1 | import { describe, expect, it, vi } from "vite-plus/test"; |
| 2 | 2 | |
| 3 | import { hasTracingPublicConfig, resolveCloudPublicConfig } from "./publicConfig"; | |
| 3 | import { | |
| 4 | CloudPublicConfigMissingError, | |
| 5 | hasTracingPublicConfig, | |
| 6 | resolveCloudPublicConfig, | |
| 7 | resolveRelayClerkTokenOptions, | |
| 8 | } from "./publicConfig"; | |
| 4 | 9 | |
| 5 | 10 | vi.mock("expo-constants", () => ({ |
| 6 | 11 | default: { |
| ... | ... | @@ -11,6 +16,12 @@ vi.mock("expo-constants", () => ({ |
| 11 | 16 | })); |
| 12 | 17 | |
| 13 | 18 | describe("resolveCloudPublicConfig", () => { |
| 19 | it("reports the missing Clerk JWT template as structured configuration", () => { | |
| 20 | expect(() => resolveRelayClerkTokenOptions()).toThrowError( | |
| 21 | new CloudPublicConfigMissingError({ key: "T3CODE_CLERK_JWT_TEMPLATE" }), | |
| 22 | ); | |
| 23 | }); | |
| 24 | ||
| 14 | 25 | it("returns no cloud configuration for an unconfigured build", () => { |
| 15 | 26 | expect(resolveCloudPublicConfig({})).toEqual({ |
| 16 | 27 | clerk: { |
apps/mobile/src/features/cloud/publicConfig.ts+13-1| ... | ... | @@ -1,6 +1,18 @@ |
| 1 | 1 | import Constants from "expo-constants"; |
| 2 | 2 | import { relayClerkTokenOptions } from "@t3tools/shared/relayAuth"; |
| 3 | 3 | import { normalizeSecureRelayUrl } from "@t3tools/shared/relayUrl"; |
| 4 | import * as Schema from "effect/Schema"; | |
| 5 | ||
| 6 | export class CloudPublicConfigMissingError extends Schema.TaggedErrorClass<CloudPublicConfigMissingError>()( | |
| 7 | "CloudPublicConfigMissingError", | |
| 8 | { | |
| 9 | key: Schema.Literal("T3CODE_CLERK_JWT_TEMPLATE"), | |
| 10 | }, | |
| 11 | ) { | |
| 12 | override get message(): string { | |
| 13 | return `${this.key} is not configured.`; | |
| 14 | } | |
| 15 | } | |
| 4 | 16 | |
| 5 | 17 | export interface CloudPublicConfig { |
| 6 | 18 | readonly clerk: { |
| ... | ... | @@ -87,7 +99,7 @@ export function hasTracingPublicConfig( |
| 87 | 99 | export function resolveRelayClerkTokenOptions() { |
| 88 | 100 | const { jwtTemplate } = resolveCloudPublicConfig().clerk; |
| 89 | 101 | if (!jwtTemplate) { |
| 90 | throw new Error("T3CODE_CLERK_JWT_TEMPLATE is not configured."); | |
| 102 | throw new CloudPublicConfigMissingError({ key: "T3CODE_CLERK_JWT_TEMPLATE" }); | |
| 91 | 103 | } |
| 92 | 104 | return relayClerkTokenOptions(jwtTemplate); |
| 93 | 105 | } |
apps/web/src/cloud/publicConfig.test.ts+13-1| ... | ... | @@ -1,6 +1,10 @@ |
| 1 | 1 | import { afterEach, describe, expect, it, vi } from "vite-plus/test"; |
| 2 | 2 | |
| 3 | import { hasCloudPublicConfig } from "./publicConfig.ts"; | |
| 3 | import { | |
| 4 | CloudPublicConfigMissingError, | |
| 5 | hasCloudPublicConfig, | |
| 6 | resolveRelayClerkTokenOptions, | |
| 7 | } from "./publicConfig.ts"; | |
| 4 | 8 | |
| 5 | 9 | afterEach(() => { |
| 6 | 10 | vi.unstubAllEnvs(); |
| ... | ... | @@ -30,4 +34,12 @@ describe("hasCloudPublicConfig", () => { |
| 30 | 34 | |
| 31 | 35 | expect(hasCloudPublicConfig()).toBe(false); |
| 32 | 36 | }); |
| 37 | ||
| 38 | it("reports the missing Clerk JWT template as structured configuration", () => { | |
| 39 | vi.stubEnv("VITE_CLERK_JWT_TEMPLATE", ""); | |
| 40 | ||
| 41 | expect(() => resolveRelayClerkTokenOptions()).toThrowError( | |
| 42 | new CloudPublicConfigMissingError({ key: "T3CODE_CLERK_JWT_TEMPLATE" }), | |
| 43 | ); | |
| 44 | }); | |
| 33 | 45 | }); |
apps/web/src/cloud/publicConfig.ts+13-1| ... | ... | @@ -1,5 +1,17 @@ |
| 1 | 1 | import { relayClerkTokenOptions } from "@t3tools/shared/relayAuth"; |
| 2 | 2 | import { normalizeSecureRelayUrl } from "@t3tools/shared/relayUrl"; |
| 3 | import * as Schema from "effect/Schema"; | |
| 4 | ||
| 5 | export class CloudPublicConfigMissingError extends Schema.TaggedErrorClass<CloudPublicConfigMissingError>()( | |
| 6 | "CloudPublicConfigMissingError", | |
| 7 | { | |
| 8 | key: Schema.Literal("T3CODE_CLERK_JWT_TEMPLATE"), | |
| 9 | }, | |
| 10 | ) { | |
| 11 | override get message(): string { | |
| 12 | return `${this.key} is not configured.`; | |
| 13 | } | |
| 14 | } | |
| 3 | 15 | |
| 4 | 16 | export interface CloudPublicConfig { |
| 5 | 17 | readonly clerkPublishableKey: string | null; |
| ... | ... | @@ -65,7 +77,7 @@ export function hasCloudPublicConfig(): boolean { |
| 65 | 77 | export function resolveRelayClerkTokenOptions() { |
| 66 | 78 | const { clerkJwtTemplate } = resolveCloudPublicConfig(); |
| 67 | 79 | if (!clerkJwtTemplate) { |
| 68 | throw new Error("T3CODE_CLERK_JWT_TEMPLATE is not configured."); | |
| 80 | throw new CloudPublicConfigMissingError({ key: "T3CODE_CLERK_JWT_TEMPLATE" }); | |
| 69 | 81 | } |
| 70 | 82 | return relayClerkTokenOptions(clerkJwtTemplate); |
| 71 | 83 | } |