feat: Support repository server - #237
Conversation
…pository-server # Conflicts: # .env # .env.production # src/lib/api/firmwareCDN.ts # src/lib/components/FirmwareChannelSelector.svelte # src/routes/(app)/hubs/[hubId=guid]/update/+page.svelte # src/routes/terminal/+page.svelte # src/routes/terminal/FirmwareBoardSelector.svelte # src/routes/terminal/FirmwareFlasher.svelte # svelte.config.js
There was a problem hiding this comment.
Pull request overview
This PR migrates the frontend’s firmware update/flash flow from the legacy firmware CDN endpoints to a new “repository server” API, and wires the new base URL through environment/config so different deployments can point at different firmware repositories.
Changes:
- Replace the firmware CDN client with a new
firmwareRepoAPI client (latest/version/history + artifact download + SHA-256 verification). - Update terminal flashing UI components to operate on a
FirmwareReleaseresponse (board extraction + artifact selection). - Make the firmware repository origin configurable via
PUBLIC_FIRMWARE_REPO_URLand include it in CSPconnect-src.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
vite.config.ts |
Adds firmware repo URL to CSP connect-src. |
src/routes/terminal/FirmwareFlasher.svelte |
Switches flashing to download/verify a selected artifact from the repo response. |
src/routes/terminal/FirmwareBoardSelector.svelte |
Derives board list from the fetched release metadata instead of fetching boards per version. |
src/routes/terminal/+page.svelte |
Plumbs latestResponse through the terminal flashing flow and updates component bindings. |
src/routes/(app)/hubs/[hubId=guid]/update/+page.svelte |
Updates firmware channel type import to the new module. |
src/lib/components/FirmwareChannelSelector.svelte |
Fetches latest firmware release per channel and caches responses. |
src/lib/api/firmwareRepo.ts |
Introduces repository server API client + artifact download/verification helpers. |
src/lib/api/firmwareCDN.ts |
Removes legacy firmware CDN implementation. |
.env.development |
Adds PUBLIC_FIRMWARE_REPO_URL for development. |
.env |
Adds PUBLIC_FIRMWARE_REPO_URL for default environment. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| dotenv.PUBLIC_GATEWAY_CSP_WILDCARD, | ||
| getWsUrlFromHttpUrl(dotenv.PUBLIC_GATEWAY_CSP_WILDCARD), | ||
| 'https://firmware.openshock.org', | ||
| dotenv.PUBLIC_FIRMWARE_REPO_URL, |
| // Capture the current channel to avoid race conditions if channel changes. | ||
| const currentChannel = channel; | ||
|
|
| changelog: string; | ||
| } | ||
|
|
||
| const BASE_URL = PUBLIC_FIRMWARE_REPO_URL.replace(/\/+$/, ''); |
| export async function DownloadAndVerifyArtifact(artifact: FirmwareArtifact): Promise<Uint8Array> { | ||
| const binary = await DownloadBinary(artifact.url); | ||
|
|
||
| const calculatedHash = await HashBuffer(binary.buffer as ArrayBuffer, 'SHA-256'); |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
openshock-app | d228ee3 | Aug 05 2026, 08:23 AM |
Deploying openshockapp with
|
| Latest commit: |
d228ee3
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://0e718dbe.openshockapp.pages.dev |
| Branch Preview URL: | https://feature-support-repository-s.openshockapp.pages.dev |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
src/lib/api/firmwareRepo.ts:35
FirmwareVersionSummary.channelis typed asstring, which is inconsistent with theFirmwareChanneltype used elsewhere and weakens type-safety for consumers.
channel: string;
src/lib/api/firmwareRepo.ts:22
FirmwareRelease.channelis currently typed asstring, which loses the stronger guarantee provided byFirmwareChanneland makes it easier for invalid values to leak into the UI. Since this value is expected to be one of the known channels, type it asFirmwareChannel.
This issue also appears on line 35 of the same file.
channel: string;
src/lib/components/FirmwareChannelSelector.svelte:60
- In the error path, the selector caches a null entry for the channel. Because the effect treats any defined cache entry (including null) as a hit, the component will never retry fetching for that channel (even after a transient outage) unless the page is reloaded.
.catch((error) => {
latestResponse = null;
version = null;
cache[currentChannel] = null;
handleApiError(error);
| async function DownloadBinary(url: string): Promise<Uint8Array> { | ||
| const response = await fetch(url); | ||
| if (!response.ok) | ||
| throw new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`); | ||
| return await response.bytes(); | ||
| } |
No description provided.