diff --git a/apps/desktop/src/lib/ai/butlerClient.ts b/apps/desktop/src/lib/ai/butlerClient.ts index 8dbe79560d..95b79af5ad 100644 --- a/apps/desktop/src/lib/ai/butlerClient.ts +++ b/apps/desktop/src/lib/ai/butlerClient.ts @@ -7,7 +7,7 @@ import { import { ModelKind, type AIClient, type AIEvalOptions, type Prompt } from '$lib/ai/types'; import { andThenAsync, ok, wrapAsync, type Result } from '$lib/result'; import { stringStreamGenerator } from '$lib/utils/promise'; -import type { HttpClient } from '@gitbutler/shared/httpClient'; +import type { HttpClient } from '@gitbutler/shared/network/httpClient'; function splitPromptMessagesIfNecessary( modelKind: ModelKind, diff --git a/apps/desktop/src/lib/ai/service.test.ts b/apps/desktop/src/lib/ai/service.test.ts index 870b66f6e7..a37f494337 100644 --- a/apps/desktop/src/lib/ai/service.test.ts +++ b/apps/desktop/src/lib/ai/service.test.ts @@ -24,7 +24,7 @@ import { import { buildFailureFromAny, ok, unwrap, type Result } from '$lib/result'; import { TokenMemoryService } from '$lib/stores/tokenMemoryService'; import { Hunk } from '$lib/vbranches/types'; -import { HttpClient } from '@gitbutler/shared/httpClient'; +import { HttpClient } from '@gitbutler/shared/network/httpClient'; import { plainToInstance } from 'class-transformer'; import { get } from 'svelte/store'; import { expect, test, describe, vi } from 'vitest'; diff --git a/apps/desktop/src/lib/ai/service.ts b/apps/desktop/src/lib/ai/service.ts index fd5c46c776..d32c092381 100644 --- a/apps/desktop/src/lib/ai/service.ts +++ b/apps/desktop/src/lib/ai/service.ts @@ -21,7 +21,7 @@ import { get } from 'svelte/store'; import type { GitConfigService } from '$lib/backend/gitConfigService'; import type { SecretsService } from '$lib/secrets/secretsService'; import type { TokenMemoryService } from '$lib/stores/tokenMemoryService'; -import type { HttpClient } from '@gitbutler/shared/httpClient'; +import type { HttpClient } from '@gitbutler/shared/network/httpClient'; const maxDiffLengthLimitForAPI = 5000; const prDescriptionTokenLimit = 4096; diff --git a/apps/desktop/src/lib/backend/projectCloudSync.svelte.ts b/apps/desktop/src/lib/backend/projectCloudSync.svelte.ts index 439a9493b7..4513aecc92 100644 --- a/apps/desktop/src/lib/backend/projectCloudSync.svelte.ts +++ b/apps/desktop/src/lib/backend/projectCloudSync.svelte.ts @@ -2,7 +2,7 @@ import { registerInterest } from '@gitbutler/shared/interest/registerInterestFun import { projectsSelectors } from '@gitbutler/shared/organizations/projectsSlice'; import { readableToReactive } from '@gitbutler/shared/reactiveUtils.svelte'; import type { ProjectService, ProjectsService } from '$lib/backend/projects'; -import type { HttpClient } from '@gitbutler/shared/httpClient'; +import type { HttpClient } from '@gitbutler/shared/network/httpClient'; import type { ProjectService as CloudProjectService } from '@gitbutler/shared/organizations/projectService'; import type { AppProjectsState } from '@gitbutler/shared/redux/store.svelte'; diff --git a/apps/desktop/src/lib/backend/projects.ts b/apps/desktop/src/lib/backend/projects.ts index 29669657d9..b11ffbb5b6 100644 --- a/apps/desktop/src/lib/backend/projects.ts +++ b/apps/desktop/src/lib/backend/projects.ts @@ -6,7 +6,7 @@ import { persisted } from '@gitbutler/shared/persisted'; import { open } from '@tauri-apps/plugin-dialog'; import { plainToInstance } from 'class-transformer'; import { derived, get, writable, type Readable } from 'svelte/store'; -import type { HttpClient } from '@gitbutler/shared/httpClient'; +import type { HttpClient } from '@gitbutler/shared/network/httpClient'; import { goto } from '$app/navigation'; export type KeyType = 'gitCredentialsHelper' | 'local' | 'systemExecutable'; diff --git a/apps/desktop/src/lib/components/ShareIssueModal.svelte b/apps/desktop/src/lib/components/ShareIssueModal.svelte index ec9659ff2e..4b3ecf2384 100644 --- a/apps/desktop/src/lib/components/ShareIssueModal.svelte +++ b/apps/desktop/src/lib/components/ShareIssueModal.svelte @@ -4,7 +4,7 @@ import { User } from '$lib/stores/user'; import * as toasts from '$lib/utils/toasts'; import { getContext, getContextStore } from '@gitbutler/shared/context'; - import { HttpClient } from '@gitbutler/shared/httpClient'; + import { HttpClient } from '@gitbutler/shared/network/httpClient'; import Button from '@gitbutler/ui/Button.svelte'; import Checkbox from '@gitbutler/ui/Checkbox.svelte'; import Modal from '@gitbutler/ui/Modal.svelte'; diff --git a/apps/desktop/src/lib/stores/user.ts b/apps/desktop/src/lib/stores/user.ts index 6eaa6b9cad..83fb8f6527 100644 --- a/apps/desktop/src/lib/stores/user.ts +++ b/apps/desktop/src/lib/stores/user.ts @@ -4,7 +4,7 @@ import { showError } from '$lib/notifications/toasts'; import { copyToClipboard } from '$lib/utils/clipboard'; import { sleep } from '$lib/utils/sleep'; import { openExternalUrl } from '$lib/utils/url'; -import { type HttpClient } from '@gitbutler/shared/httpClient'; +import { type HttpClient } from '@gitbutler/shared/network/httpClient'; import { plainToInstance } from 'class-transformer'; import { derived, writable } from 'svelte/store'; import type { PostHogWrapper } from '$lib/analytics/posthog'; diff --git a/apps/desktop/src/routes/+layout.svelte b/apps/desktop/src/routes/+layout.svelte index 6c2548ffc7..db39bfca8a 100644 --- a/apps/desktop/src/routes/+layout.svelte +++ b/apps/desktop/src/routes/+layout.svelte @@ -39,7 +39,7 @@ import * as events from '$lib/utils/events'; import { unsubscribe } from '$lib/utils/unsubscribe'; import { FeedService } from '@gitbutler/shared/feeds/service'; - import { HttpClient } from '@gitbutler/shared/httpClient'; + import { HttpClient } from '@gitbutler/shared/network/httpClient'; import { OrganizationService } from '@gitbutler/shared/organizations/organizationService'; import { ProjectService as CloudProjectService } from '@gitbutler/shared/organizations/projectService'; import { AppDispatch, AppState } from '@gitbutler/shared/redux/store.svelte'; diff --git a/apps/desktop/src/routes/+layout.ts b/apps/desktop/src/routes/+layout.ts index 50ac87faeb..c279613451 100644 --- a/apps/desktop/src/routes/+layout.ts +++ b/apps/desktop/src/routes/+layout.ts @@ -14,7 +14,7 @@ import { RemotesService } from '$lib/remotes/service'; import { RustSecretService } from '$lib/secrets/secretsService'; import { TokenMemoryService } from '$lib/stores/tokenMemoryService'; import { UserService } from '$lib/stores/user'; -import { HttpClient } from '@gitbutler/shared/httpClient'; +import { HttpClient } from '@gitbutler/shared/network/httpClient'; import { LineManagerFactory } from '@gitbutler/ui/commitLines/lineManager'; import { LineManagerFactory as StackingLineManagerFactory } from '@gitbutler/ui/commitLines/lineManager'; import lscache from 'lscache'; diff --git a/apps/desktop/src/routes/[projectId]/+layout.svelte b/apps/desktop/src/routes/[projectId]/+layout.svelte index c1d3477822..182c3430ae 100644 --- a/apps/desktop/src/routes/[projectId]/+layout.svelte +++ b/apps/desktop/src/routes/[projectId]/+layout.svelte @@ -36,7 +36,7 @@ import { VirtualBranchService } from '$lib/vbranches/virtualBranch'; import { CloudBranchesService } from '@gitbutler/shared/cloud/stacks/service'; import { getContext } from '@gitbutler/shared/context'; - import { HttpClient } from '@gitbutler/shared/httpClient'; + import { HttpClient } from '@gitbutler/shared/network/httpClient'; import { ProjectService as CloudProjectService } from '@gitbutler/shared/organizations/projectService'; import { AppState } from '@gitbutler/shared/redux/store.svelte'; import { DesktopRoutesService, getRoutesService } from '@gitbutler/shared/sharedRoutes'; diff --git a/apps/desktop/src/routes/settings/organizations/+page.svelte b/apps/desktop/src/routes/settings/organizations/+page.svelte index 332ecf0de4..4ce7cbb43e 100644 --- a/apps/desktop/src/routes/settings/organizations/+page.svelte +++ b/apps/desktop/src/routes/settings/organizations/+page.svelte @@ -1,8 +1,9 @@ + +{#if loadable?.type === 'found'} + {@render children(loadable.value)} +{:else if loadable?.type === 'loading'} +
Loading...
+{:else if loadable?.type === 'not-found'} +Not found
+{:else if loadable?.type === 'error'} +{loadable.error.message}
+{:else} +Organization uninitialized
+{/if} diff --git a/packages/shared/src/lib/httpClient.ts b/packages/shared/src/lib/network/httpClient.ts similarity index 95% rename from packages/shared/src/lib/httpClient.ts rename to packages/shared/src/lib/network/httpClient.ts index 60ea55af6d..60803e11a2 100644 --- a/packages/shared/src/lib/httpClient.ts +++ b/packages/shared/src/lib/network/httpClient.ts @@ -1,3 +1,4 @@ +import { ApiError } from '$lib/network/types'; import { derived, get, type Readable } from 'svelte/store'; export const DEFAULT_HEADERS = { @@ -100,7 +101,7 @@ async function parseResponseJSON(response: Response) { if (response.status === 204 || response.status === 205) { return null; } else if (response.status >= 400) { - throw new Error(`HTTP Error ${response.statusText}: ${await response.text()}`); + throw new ApiError(`HTTP Error ${response.statusText}: ${await response.text()}`, response); } else { return await response.json(); } diff --git a/packages/shared/src/lib/network/loadable.ts b/packages/shared/src/lib/network/loadable.ts new file mode 100644 index 0000000000..66f93f6e87 --- /dev/null +++ b/packages/shared/src/lib/network/loadable.ts @@ -0,0 +1,4 @@ +export type LoadableDataInvite code:
-{user.user?.name}
-{project?.name}
-Invite code:
+{user?.name}
+{project?.name}
+