Showing the changes to apps/web/src/hooks/useT3ProjectFileScripts.ts (1 of 11 files). Show all
Unified · Split
| @@ -14,6 +14,41 @@ const decodeT3ProjectFile = Schema.decodeExit(T3ProjectFileFromJson); · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | const NO_SCRIPTS: ReadonlyArray<T3ProjectFileScript> = []; | 15 | const NO_SCRIPTS: ReadonlyArray<T3ProjectFileScript> = []; |
| 16 | 16 | ||
| 17 | export interface T3ProjectFileState { | ||
| 18 | /** | ||
| 19 | * - `valid`: t3.json exists and decoded. | ||
| 20 | * - `invalid`: t3.json exists but fails to decode (the server then ignores | ||
| 21 | * the whole file, including `iconPath` and every script). | ||
| 22 | * - `missing`: no readable t3.json at the workspace root. | ||
| 23 | * - `loading`: the file query has not settled yet. | ||
| 24 | */ | ||
| 25 | status: "loading" | "missing" | "invalid" | "valid"; | ||
| 26 | scripts: ReadonlyArray<T3ProjectFileScript>; | ||
| 27 | } | ||
| 28 | |||
| 29 | /** | ||
| 30 | * Decoded state of the project's checked-in `t3.json`, including whether the | ||
| 31 | * file exists but is broken — which the runtime otherwise swallows silently. | ||
| 32 | */ | ||
| 33 | export function useT3ProjectFileState( | ||
| 34 | environmentId: EnvironmentId, | ||
| 35 | cwd: string | null, | ||
| 36 | ): T3ProjectFileState { | ||
| 37 | const query = useProjectFileQuery(environmentId, cwd ?? "", T3_PROJECT_FILE_NAME, cwd !== null); | ||
| 38 | const contents = query.data && !query.data.truncated ? query.data.contents : null; | ||
| 39 | const isPending = query.isPending; | ||
| 40 | return useMemo(() => { | ||
| 41 | if (contents === null) { | ||
| 42 | return { status: isPending ? "loading" : "missing", scripts: NO_SCRIPTS } as const; | ||
| 43 | } | ||
| 44 | const decoded = decodeT3ProjectFile(contents); | ||
| 45 | if (Exit.isFailure(decoded)) { | ||
| 46 | return { status: "invalid", scripts: NO_SCRIPTS } as const; | ||
| 47 | } | ||
| 48 | return { status: "valid", scripts: decoded.value.scripts ?? NO_SCRIPTS } as const; | ||
| 49 | }, [contents, isPending]); | ||
| 50 | } | ||
| 51 | |||
| 17 | /** | 52 | /** |
| 18 | * Scripts declared in the project's checked-in `t3.json`, offered in the | 53 | * Scripts declared in the project's checked-in `t3.json`, offered in the |
| 19 | * scripts menu for import. Missing, truncated, or invalid files resolve to | 54 | * scripts menu for import. Missing, truncated, or invalid files resolve to |
| @@ -23,12 +58,5 @@ export function useT3ProjectFileScripts( · 3 unmodified lines | |||
| 23 | environmentId: EnvironmentId, | 58 | environmentId: EnvironmentId, |
| 24 | cwd: string | null, | 59 | cwd: string | null, |
| 25 | ): ReadonlyArray<T3ProjectFileScript> { | 60 | ): ReadonlyArray<T3ProjectFileScript> { |
| 26 | const query = useProjectFileQuery(environmentId, cwd ?? "", T3_PROJECT_FILE_NAME, cwd !== null); | 61 | return useT3ProjectFileState(environmentId, cwd).scripts; |
| 27 | const contents = query.data && !query.data.truncated ? query.data.contents : null; | ||
| 28 | return useMemo(() => { | ||
| 29 | if (contents === null) return NO_SCRIPTS; | ||
| 30 | const decoded = decodeT3ProjectFile(contents); | ||
| 31 | if (Exit.isFailure(decoded)) return NO_SCRIPTS; | ||
| 32 | return decoded.value.scripts ?? NO_SCRIPTS; | ||
| 33 | }, [contents]); | ||
| 34 | } | 62 | } |