feat(web,ui): built-in codeberg.org gitea host and provider detectUrls
This commit is contained in:
@@ -167,26 +167,30 @@ export const GitPage: React.FC<GitPageProps> = (props) => {
|
||||
title={t('settings.page.git.title')}
|
||||
showSaveStatus
|
||||
>
|
||||
<div className="flex h-8 min-w-0">
|
||||
<SortableTabsStrip
|
||||
items={providerTabs}
|
||||
activeId={activeProviderTab}
|
||||
onSelect={(tabId) => setActiveProviderTab(tabId as GitProviderTabId)}
|
||||
layoutMode="fit"
|
||||
variant="active-pill"
|
||||
activePillButtonClassName="h-7"
|
||||
/>
|
||||
</div>
|
||||
<section className="overflow-hidden rounded-lg border border-[var(--interactive-border)] bg-[var(--surface-muted)]">
|
||||
<div className="border-b border-[var(--surface-subtle)] px-3 py-2">
|
||||
<div className="flex h-8 min-w-0">
|
||||
<SortableTabsStrip
|
||||
items={providerTabs}
|
||||
activeId={activeProviderTab}
|
||||
onSelect={(tabId) => setActiveProviderTab(tabId as GitProviderTabId)}
|
||||
layoutMode="fit"
|
||||
variant="active-pill"
|
||||
activePillButtonClassName="h-7"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div role="tabpanel" aria-label={t('settings.git.tabs.github')} hidden={activeProviderTab !== 'github'}>
|
||||
<GitHubSettings />
|
||||
</div>
|
||||
<div role="tabpanel" aria-label={t('settings.git.tabs.gitlab')} hidden={activeProviderTab !== 'gitlab'}>
|
||||
<GitLabSettings />
|
||||
</div>
|
||||
<div role="tabpanel" aria-label={t('settings.git.tabs.gitea')} hidden={activeProviderTab !== 'gitea'}>
|
||||
<GiteaSettings />
|
||||
</div>
|
||||
<div role="tabpanel" aria-label={t('settings.git.tabs.github')} hidden={activeProviderTab !== 'github'}>
|
||||
<GitHubSettings embedded />
|
||||
</div>
|
||||
<div role="tabpanel" aria-label={t('settings.git.tabs.gitlab')} hidden={activeProviderTab !== 'gitlab'}>
|
||||
<GitLabSettings embedded />
|
||||
</div>
|
||||
<div role="tabpanel" aria-label={t('settings.git.tabs.gitea')} hidden={activeProviderTab !== 'gitea'}>
|
||||
<GiteaSettings embedded />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<SettingsSection
|
||||
title={t('settings.gitIdentities.page.section.title')}
|
||||
|
||||
@@ -36,7 +36,7 @@ type DeviceFlowCompleteResponse =
|
||||
| { connected: true; user: GitHubUser; scope?: string }
|
||||
| { connected: false; status?: string; error?: string };
|
||||
|
||||
export const GitHubSettings: React.FC = () => {
|
||||
export const GitHubSettings: React.FC<{ embedded?: boolean }> = ({ embedded = false }) => {
|
||||
const { t } = useI18n();
|
||||
const { isMobile } = useDeviceInfo();
|
||||
const runtimeGitHub = getRegisteredRuntimeAPIs()?.github;
|
||||
@@ -271,14 +271,8 @@ export const GitHubSettings: React.FC = () => {
|
||||
? t('settings.github.page.accountSource.cli')
|
||||
: t('settings.github.page.accountSource.oauth');
|
||||
|
||||
return (
|
||||
const accountContent = (
|
||||
<>
|
||||
<SettingsSection
|
||||
title={t('settings.github.page.oauth.title')}
|
||||
divider={false}
|
||||
settingsItem="git.github-account"
|
||||
info={t('settings.github.page.tooltip.connectAccount')}
|
||||
>
|
||||
<div className="rounded-lg bg-[var(--surface-elevated)]/70 overflow-hidden flex flex-col">
|
||||
{connected ? (
|
||||
<div className={cn("px-4 py-3", isMobile ? "flex flex-col gap-3" : "flex items-center justify-between gap-4")}>
|
||||
@@ -447,65 +441,95 @@ export const GitHubSettings: React.FC = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col gap-4 pt-4">
|
||||
<div className={cn('flex flex-col gap-4', embedded ? 'border-t border-[var(--surface-subtle)] pt-4' : 'pt-4')}>
|
||||
<ProviderApiBaseUrlInput provider="github" />
|
||||
<ProviderDetectUrlsInput provider="github" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
</SettingsSection>
|
||||
|
||||
{ghCli?.available && !ghCli?.active && (!ghCli.user || ghCli.disabled) && (
|
||||
<SettingsSection title={t('settings.github.page.ghCli.title')}>
|
||||
<div className="rounded-lg bg-[var(--surface-elevated)]/70 overflow-hidden">
|
||||
<div className={cn("px-4 py-3", isMobile ? "flex flex-col gap-3" : "flex items-center justify-between gap-4")}>
|
||||
<div className={cn("flex min-w-0 items-center gap-4", isMobile ? "w-full" : undefined)}>
|
||||
{ghCli.user?.avatarUrl ? (
|
||||
<img
|
||||
src={ghCli.user.avatarUrl}
|
||||
alt={ghCli.user.login ? t('settings.github.page.avatarAlt.withLogin', { login: ghCli.user.login }) : t('settings.github.page.avatarAlt.fallback')}
|
||||
className="h-10 w-10 shrink-0 rounded-full border border-[var(--interactive-border)] bg-[var(--surface-muted)] object-cover"
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer"
|
||||
/>
|
||||
) : (
|
||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-[var(--interactive-border)] bg-[var(--surface-muted)]">
|
||||
<Icon name="github-fill" className="h-4 w-4 text-muted-foreground" />
|
||||
</div>
|
||||
)}
|
||||
<div className="min-w-0 flex-1">
|
||||
{!ghCli.disabled && ghCli.user && (
|
||||
<div className="typography-ui-label text-foreground truncate">
|
||||
{ghCli.user.name?.trim() || ghCli.user.login || 'GitHub'}
|
||||
</div>
|
||||
)}
|
||||
{!ghCli.disabled && ghCli.user?.login && (
|
||||
<div className={cn("flex items-center gap-2 typography-meta text-muted-foreground mt-0.5", isMobile ? "flex-wrap" : "truncate")}>
|
||||
<Icon name="github-fill" className="h-3.5 w-3.5 shrink-0" />
|
||||
<span className="font-mono">{ghCli.user.login}</span>
|
||||
{ghCli.user.email && <span className="opacity-50">•</span>}
|
||||
{ghCli.user.email && <span>{ghCli.user.email}</span>}
|
||||
</div>
|
||||
)}
|
||||
<div className={cn("typography-meta text-muted-foreground", ghCli.disabled ? "opacity-60" : undefined)}>
|
||||
{ghCli.disabled
|
||||
? t('settings.github.page.ghCli.disabledDescription')
|
||||
: t('settings.github.page.ghCli.fallbackDescription')}
|
||||
</div>
|
||||
</div>
|
||||
const ghCliContent = ghCli?.available && !ghCli?.active && (!ghCli.user || ghCli.disabled) ? (
|
||||
<div className="rounded-lg bg-[var(--surface-elevated)]/70 overflow-hidden">
|
||||
<div className={cn("px-4 py-3", isMobile ? "flex flex-col gap-3" : "flex items-center justify-between gap-4")}>
|
||||
<div className={cn("flex min-w-0 items-center gap-4", isMobile ? "w-full" : undefined)}>
|
||||
{ghCli.user?.avatarUrl ? (
|
||||
<img
|
||||
src={ghCli.user.avatarUrl}
|
||||
alt={ghCli.user.login ? t('settings.github.page.avatarAlt.withLogin', { login: ghCli.user.login }) : t('settings.github.page.avatarAlt.fallback')}
|
||||
className="h-10 w-10 shrink-0 rounded-full border border-[var(--interactive-border)] bg-[var(--surface-muted)] object-cover"
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer"
|
||||
/>
|
||||
) : (
|
||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full border border-[var(--interactive-border)] bg-[var(--surface-muted)]">
|
||||
<Icon name="github-fill" className="h-4 w-4 text-muted-foreground" />
|
||||
</div>
|
||||
)}
|
||||
<div className="min-w-0 flex-1">
|
||||
{!ghCli.disabled && ghCli.user && (
|
||||
<div className="typography-ui-label text-foreground truncate">
|
||||
{ghCli.user.name?.trim() || ghCli.user.login || 'GitHub'}
|
||||
</div>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => toggleGhCli(!ghCli.disabled)}
|
||||
disabled={isBusy}
|
||||
className={cn(isMobile ? "w-full" : undefined)}
|
||||
>
|
||||
{ghCli.disabled
|
||||
? t('settings.github.page.ghCli.actions.enable')
|
||||
: t('settings.github.page.ghCli.actions.disable')}
|
||||
</Button>
|
||||
)}
|
||||
{!ghCli.disabled && ghCli.user?.login && (
|
||||
<div className={cn("flex items-center gap-2 typography-meta text-muted-foreground mt-0.5", isMobile ? "flex-wrap" : "truncate")}>
|
||||
<Icon name="github-fill" className="h-3.5 w-3.5 shrink-0" />
|
||||
<span className="font-mono">{ghCli.user.login}</span>
|
||||
{ghCli.user.email && <span className="opacity-50">•</span>}
|
||||
{ghCli.user.email && <span>{ghCli.user.email}</span>}
|
||||
</div>
|
||||
)}
|
||||
<div className={cn("typography-meta text-muted-foreground", ghCli.disabled ? "opacity-60" : undefined)}>
|
||||
{ghCli.disabled
|
||||
? t('settings.github.page.ghCli.disabledDescription')
|
||||
: t('settings.github.page.ghCli.fallbackDescription')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => toggleGhCli(!ghCli.disabled)}
|
||||
disabled={isBusy}
|
||||
className={cn(isMobile ? "w-full" : undefined)}
|
||||
>
|
||||
{ghCli.disabled
|
||||
? t('settings.github.page.ghCli.actions.enable')
|
||||
: t('settings.github.page.ghCli.actions.disable')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
if (embedded) {
|
||||
return (
|
||||
<>
|
||||
<div data-settings-item="git.github-account" className="p-4">
|
||||
{accountContent}
|
||||
</div>
|
||||
{ghCliContent && (
|
||||
<div className="border-t border-[var(--surface-subtle)] px-4 py-4">
|
||||
{ghCliContent}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<SettingsSection
|
||||
title={t('settings.github.page.oauth.title')}
|
||||
divider={false}
|
||||
settingsItem="git.github-account"
|
||||
info={t('settings.github.page.tooltip.connectAccount')}
|
||||
>
|
||||
{accountContent}
|
||||
</SettingsSection>
|
||||
|
||||
{ghCliContent && (
|
||||
<SettingsSection title={t('settings.github.page.ghCli.title')}>
|
||||
{ghCliContent}
|
||||
</SettingsSection>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -24,7 +24,7 @@ const getBaseUrlHost = (baseUrl?: string | null): string => {
|
||||
}
|
||||
};
|
||||
|
||||
export const GitLabSettings: React.FC = () => {
|
||||
export const GitLabSettings: React.FC<{ embedded?: boolean }> = ({ embedded = false }) => {
|
||||
const { t } = useI18n();
|
||||
const { isMobile } = useDeviceInfo();
|
||||
const runtimeGitLab = getRegisteredRuntimeAPIs()?.gitlab;
|
||||
@@ -154,13 +154,8 @@ export const GitLabSettings: React.FC = () => {
|
||||
const currentAccount = accounts.find((account) => account.current) ?? (accounts.length > 0 ? accounts[0] : null);
|
||||
const currentBaseUrlHost = getBaseUrlHost(currentAccount?.baseUrl ?? status?.defaultBaseUrl);
|
||||
|
||||
return (
|
||||
<SettingsSection
|
||||
title={t('settings.gitlab.page.title')}
|
||||
description={t('settings.gitlab.page.description')}
|
||||
info={t('settings.gitlab.page.tooltip.connectAccount')}
|
||||
settingsItem="git.gitlab-account"
|
||||
>
|
||||
const sectionContent = (
|
||||
<>
|
||||
<div className="rounded-lg bg-[var(--surface-elevated)]/70 overflow-hidden flex flex-col">
|
||||
{connected ? (
|
||||
<div className={cn('px-4 py-3', isMobile ? 'flex flex-col gap-3' : 'flex items-center justify-between gap-4')}>
|
||||
@@ -296,10 +291,29 @@ export const GitLabSettings: React.FC = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 pt-4">
|
||||
<div className={cn('flex flex-col gap-4', embedded ? 'border-t border-[var(--surface-subtle)] pt-4' : 'pt-4')}>
|
||||
<ProviderApiBaseUrlInput provider="gitlab" />
|
||||
<ProviderDetectUrlsInput provider="gitlab" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
if (embedded) {
|
||||
return (
|
||||
<div data-settings-item="git.gitlab-account" className="p-4">
|
||||
{sectionContent}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsSection
|
||||
title={t('settings.gitlab.page.title')}
|
||||
description={t('settings.gitlab.page.description')}
|
||||
info={t('settings.gitlab.page.tooltip.connectAccount')}
|
||||
settingsItem="git.gitlab-account"
|
||||
>
|
||||
{sectionContent}
|
||||
</SettingsSection>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@ const getBaseUrlHost = (baseUrl?: string | null): string => {
|
||||
}
|
||||
};
|
||||
|
||||
export const GiteaSettings: React.FC = () => {
|
||||
export const GiteaSettings: React.FC<{ embedded?: boolean }> = ({ embedded = false }) => {
|
||||
const { t } = useI18n();
|
||||
const { isMobile } = useDeviceInfo();
|
||||
const runtimeGitea = getRegisteredRuntimeAPIs()?.gitea;
|
||||
@@ -159,13 +159,8 @@ export const GiteaSettings: React.FC = () => {
|
||||
const currentAccount = accounts.find((account) => account.current) ?? (accounts.length > 0 ? accounts[0] : null);
|
||||
const currentBaseUrlHost = getBaseUrlHost(currentAccount?.baseUrl);
|
||||
|
||||
return (
|
||||
<SettingsSection
|
||||
title={t('settings.gitea.page.title')}
|
||||
description={t('settings.gitea.page.description')}
|
||||
info={t('settings.gitea.page.tooltip.connectAccount')}
|
||||
settingsItem="git.gitea-account"
|
||||
>
|
||||
const sectionContent = (
|
||||
<>
|
||||
<div className="rounded-lg bg-[var(--surface-elevated)]/70 overflow-hidden flex flex-col">
|
||||
{connected ? (
|
||||
<div className={cn('px-4 py-3', isMobile ? 'flex flex-col gap-3' : 'flex items-center justify-between gap-4')}>
|
||||
@@ -306,10 +301,29 @@ export const GiteaSettings: React.FC = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 pt-4">
|
||||
<div className={cn('flex flex-col gap-4', embedded ? 'border-t border-[var(--surface-subtle)] pt-4' : 'pt-4')}>
|
||||
<ProviderApiBaseUrlInput provider="gitea" />
|
||||
<ProviderDetectUrlsInput provider="gitea" />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
if (embedded) {
|
||||
return (
|
||||
<div data-settings-item="git.gitea-account" className="p-4">
|
||||
{sectionContent}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsSection
|
||||
title={t('settings.gitea.page.title')}
|
||||
description={t('settings.gitea.page.description')}
|
||||
info={t('settings.gitea.page.tooltip.connectAccount')}
|
||||
settingsItem="git.gitea-account"
|
||||
>
|
||||
{sectionContent}
|
||||
</SettingsSection>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -88,8 +88,9 @@ describe('detectGitProvider', () => {
|
||||
expect(detectGitProvider(['ssh://git@[2001:db8::1]/owner/repo.git'], hosts)).toBe('gitea');
|
||||
});
|
||||
|
||||
test('does not classify codeberg.org as gitea without a configured host', () => {
|
||||
expect(detectGitProvider(['git@codeberg.org:owner/repo.git'], EMPTY_HOSTS)).toBe('other');
|
||||
test('classifies codeberg.org as gitea by default (built-in host)', () => {
|
||||
expect(detectGitProvider(['git@codeberg.org:owner/repo.git'], EMPTY_HOSTS)).toBe('gitea');
|
||||
expect(detectGitProvider(['https://codeberg.org/owner/repo.git'], EMPTY_HOSTS)).toBe('gitea');
|
||||
});
|
||||
|
||||
test('github wins over a configured gitea host when both remotes are present', () => {
|
||||
|
||||
@@ -15,8 +15,9 @@ export type GitProvider = 'github' | 'gitlab' | 'gitea' | 'other';
|
||||
/**
|
||||
* Per-provider hostname sets used for detection: custom user-configured
|
||||
* domains (from the domains store), account-derived base-URL hostnames, and the
|
||||
* configured api base host. Built-in defaults (github.com, gitlab.com) are
|
||||
* applied inside the detection logic and never need to be present here.
|
||||
* configured api base host. Built-in defaults (github.com, gitlab.com,
|
||||
* codeberg.org) are applied inside the detection logic and never need to be
|
||||
* present here.
|
||||
*/
|
||||
export type GitProviderHosts = {
|
||||
github: string[];
|
||||
@@ -91,10 +92,10 @@ export const buildGitProviderHosts = (input: {
|
||||
/**
|
||||
* Classify a repository by the hosts of its remotes. Returns null when there
|
||||
* are no remotes to inspect. Built-in defaults apply always: `github.com` is
|
||||
* GitHub and `gitlab.com` is GitLab (there is no built-in Gitea host). Custom
|
||||
* hosts from `hosts.{github,gitlab,gitea}` are then matched in precedence
|
||||
* order github -> gitlab -> gitea (first match wins). Anything else resolves
|
||||
* to 'other' so GitHub-branded UI is never offered for a non-GitHub repo.
|
||||
* GitHub, `gitlab.com` is GitLab, and `codeberg.org` is Gitea. Custom hosts
|
||||
* from `hosts.{github,gitlab,gitea}` are then matched in precedence order
|
||||
* github -> gitlab -> gitea (first match wins). Anything else resolves to
|
||||
* 'other' so GitHub-branded UI is never offered for a non-GitHub repo.
|
||||
*/
|
||||
export const detectGitProvider = (fetchUrls: string[], hosts: GitProviderHosts): GitProvider | null => {
|
||||
const remoteHosts = new Set<string>();
|
||||
@@ -110,7 +111,7 @@ export const detectGitProvider = (fetchUrls: string[], hosts: GitProviderHosts):
|
||||
|
||||
const githubHosts = new Set(['github.com', ...normalizeHostList(hosts.github)]);
|
||||
const gitlabHosts = new Set(['gitlab.com', ...normalizeHostList(hosts.gitlab)]);
|
||||
const giteaHosts = new Set(normalizeHostList(hosts.gitea));
|
||||
const giteaHosts = new Set(['codeberg.org', ...normalizeHostList(hosts.gitea)]);
|
||||
|
||||
for (const host of remoteHosts) {
|
||||
if (githubHosts.has(host)) {
|
||||
|
||||
@@ -1639,10 +1639,10 @@ export const settingsDict = {
|
||||
'settings.github.page.toast.ghCliDisabled': 'gh CLI Fallback deaktiviert',
|
||||
'settings.github.page.toast.ghCliUpdateFailed': 'Fehler beim Aktualisieren der gh CLI Einstellung',
|
||||
'settings.github.page.apiBaseUrl.label': 'API-Basis-URL',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://github.example.com/api/v3',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://api.github.com',
|
||||
'settings.github.page.apiBaseUrl.description': 'Standard-Basis-URL für API-Aufrufe. Für GitHub Enterprise verwende die Adresse deines Servers, z. B. https://github.example.com/api/v3.',
|
||||
'settings.github.page.detectUrls.label': 'Erkennungs-URLs',
|
||||
'settings.github.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.github.page.detectUrls.placeholder': 'github.com',
|
||||
'settings.github.page.detectUrls.description': 'Repositories, die per SSH oder HTTPS von diesen Hosts geklont wurden, werden als GitHub erkannt.',
|
||||
'settings.gitlab.page.title': 'GitLab Personal Access Token',
|
||||
'settings.gitlab.page.description': 'Fügen Sie ein GitLab Personal Access Token ein, um eine Verbindung herzustellen. Legen Sie die Basis-URL fest, wenn Sie eine selbst gehostete GitLab-Instanz verwenden.',
|
||||
@@ -1652,10 +1652,10 @@ export const settingsDict = {
|
||||
'settings.gitlab.page.baseUrl.label': 'Basis-URL (optional)',
|
||||
'settings.gitlab.page.baseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.label': 'API-Basis-URL',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.example.com',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.description': 'Standard-Basis-URL für API-Aufrufe. Für selbst gehostete Instanzen verwende die Adresse deines Servers, z. B. https://gitlab.example.com.',
|
||||
'settings.gitlab.page.detectUrls.label': 'Erkennungs-URLs',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'gitlab.com',
|
||||
'settings.gitlab.page.detectUrls.description': 'Repositories, die per SSH oder HTTPS von diesen Hosts geklont wurden, werden als GitLab erkannt.',
|
||||
'settings.gitlab.page.actions.connect': 'GitLab verbinden',
|
||||
'settings.gitlab.page.actions.disconnect': 'Trennen',
|
||||
@@ -1697,10 +1697,10 @@ export const settingsDict = {
|
||||
'settings.gitea.page.toast.accountSwitched': 'Gitea-Konto gewechselt',
|
||||
'settings.gitea.page.toast.accountSwitchFailed': 'Wechsel des Gitea-Kontos fehlgeschlagen',
|
||||
'settings.gitea.page.apiBaseUrl.label': 'API-Basis-URL',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://gitea.example.com',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://codeberg.org',
|
||||
'settings.gitea.page.apiBaseUrl.description': 'Standard-Basis-URL für API-Aufrufe. Für selbst gehostete Instanzen verwende die Adresse deines Servers, z. B. https://gitea.example.com.',
|
||||
'settings.gitea.page.detectUrls.label': 'Erkennungs-URLs',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'codeberg.org',
|
||||
'settings.gitea.page.detectUrls.description': 'Repositories, die per SSH oder HTTPS von diesen Hosts geklont wurden, werden als Gitea oder Forgejo erkannt.',
|
||||
'settings.gitProviders.detectUrls.add': 'Erkennungs-URL hinzufügen',
|
||||
'settings.gitProviders.detectUrls.remove': '{host} entfernen',
|
||||
|
||||
@@ -1705,10 +1705,10 @@ export const settingsDict = {
|
||||
'settings.github.page.toast.ghCliDisabled': 'gh CLI fallback disabled',
|
||||
'settings.github.page.toast.ghCliUpdateFailed': 'Failed to update gh CLI setting',
|
||||
'settings.github.page.apiBaseUrl.label': 'API base URL',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://github.example.com/api/v3',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://api.github.com',
|
||||
'settings.github.page.apiBaseUrl.description': 'Default base URL for API calls. For GitHub Enterprise, use your server address, e.g. https://github.example.com/api/v3.',
|
||||
'settings.github.page.detectUrls.label': 'Detection URLs',
|
||||
'settings.github.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.github.page.detectUrls.placeholder': 'github.com',
|
||||
'settings.github.page.detectUrls.description': 'Repos cloned over SSH or HTTPS from these hosts are recognized as GitHub.',
|
||||
'settings.gitlab.page.title': 'GitLab Personal Access Token',
|
||||
'settings.gitlab.page.description': 'Paste a GitLab personal access token to connect. Set the base URL when using a self-hosted GitLab instance.',
|
||||
@@ -1718,10 +1718,10 @@ export const settingsDict = {
|
||||
'settings.gitlab.page.baseUrl.label': 'Base URL (optional)',
|
||||
'settings.gitlab.page.baseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.label': 'API base URL',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.example.com',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.description': 'Default base URL for API calls. For self-hosted instances, use your server address, e.g. https://gitlab.example.com.',
|
||||
'settings.gitlab.page.detectUrls.label': 'Detection URLs',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'gitlab.com',
|
||||
'settings.gitlab.page.detectUrls.description': 'Repos cloned over SSH or HTTPS from these hosts are recognized as GitLab.',
|
||||
'settings.gitlab.page.actions.connect': 'Connect GitLab',
|
||||
'settings.gitlab.page.actions.disconnect': 'Disconnect',
|
||||
@@ -1763,10 +1763,10 @@ export const settingsDict = {
|
||||
'settings.gitea.page.toast.accountSwitched': 'Gitea account switched',
|
||||
'settings.gitea.page.toast.accountSwitchFailed': 'Failed to switch Gitea account',
|
||||
'settings.gitea.page.apiBaseUrl.label': 'API base URL',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://gitea.example.com',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://codeberg.org',
|
||||
'settings.gitea.page.apiBaseUrl.description': 'Default base URL for API calls. For self-hosted instances, use your server address, e.g. https://gitea.example.com.',
|
||||
'settings.gitea.page.detectUrls.label': 'Detection URLs',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'codeberg.org',
|
||||
'settings.gitea.page.detectUrls.description': 'Repos cloned over SSH or HTTPS from these hosts are recognized as Gitea or Forgejo.',
|
||||
'settings.gitProviders.detectUrls.add': 'Add a detection URL',
|
||||
'settings.gitProviders.detectUrls.remove': 'Remove {host}',
|
||||
|
||||
@@ -1682,10 +1682,10 @@ export const settingsDict = {
|
||||
"settings.github.page.toast.ghCliDisabled": "Respaldo de gh CLI desactivado",
|
||||
"settings.github.page.toast.ghCliUpdateFailed": "No se pudo actualizar la configuración de gh CLI",
|
||||
"settings.github.page.apiBaseUrl.label": "URL base de la API",
|
||||
"settings.github.page.apiBaseUrl.placeholder": "https://github.example.com/api/v3",
|
||||
"settings.github.page.apiBaseUrl.placeholder": "https://api.github.com",
|
||||
"settings.github.page.apiBaseUrl.description": "URL base por defecto para las llamadas a la API. Para GitHub Enterprise, usa la dirección de tu servidor, p. ej. https://github.example.com/api/v3.",
|
||||
"settings.github.page.detectUrls.label": "URL de detección",
|
||||
"settings.github.page.detectUrls.placeholder": "ssh://git@git.example.com:2222, https://git.example.com",
|
||||
"settings.github.page.detectUrls.placeholder": "github.com",
|
||||
"settings.github.page.detectUrls.description": "Los repositorios clonados por SSH o HTTPS desde estos hosts se reconocen como GitHub.",
|
||||
"settings.gitlab.page.title": "Token de acceso personal de GitLab",
|
||||
"settings.gitlab.page.description": "Pega un token de acceso personal de GitLab para conectarte. Establece la URL base cuando uses una instancia de GitLab autoalojada.",
|
||||
@@ -1695,10 +1695,10 @@ export const settingsDict = {
|
||||
"settings.gitlab.page.baseUrl.label": "URL base (opcional)",
|
||||
"settings.gitlab.page.baseUrl.placeholder": "https://gitlab.com",
|
||||
"settings.gitlab.page.apiBaseUrl.label": "URL base de la API",
|
||||
"settings.gitlab.page.apiBaseUrl.placeholder": "https://gitlab.example.com",
|
||||
"settings.gitlab.page.apiBaseUrl.placeholder": "https://gitlab.com",
|
||||
"settings.gitlab.page.apiBaseUrl.description": "URL base por defecto para las llamadas a la API. Para instancias autoalojadas, usa la dirección de tu servidor, p. ej. https://gitlab.example.com.",
|
||||
"settings.gitlab.page.detectUrls.label": "URL de detección",
|
||||
"settings.gitlab.page.detectUrls.placeholder": "ssh://git@git.example.com:2222, https://git.example.com",
|
||||
"settings.gitlab.page.detectUrls.placeholder": "gitlab.com",
|
||||
"settings.gitlab.page.detectUrls.description": "Los repositorios clonados por SSH o HTTPS desde estos hosts se reconocen como GitLab.",
|
||||
"settings.gitlab.page.actions.connect": "Conectar GitLab",
|
||||
"settings.gitlab.page.actions.disconnect": "Desconectar",
|
||||
@@ -1740,10 +1740,10 @@ export const settingsDict = {
|
||||
"settings.gitea.page.toast.accountSwitched": "Cuenta de Gitea cambiada",
|
||||
"settings.gitea.page.toast.accountSwitchFailed": "No se pudo cambiar la cuenta de Gitea",
|
||||
"settings.gitea.page.apiBaseUrl.label": "URL base de la API",
|
||||
"settings.gitea.page.apiBaseUrl.placeholder": "https://gitea.example.com",
|
||||
"settings.gitea.page.apiBaseUrl.placeholder": "https://codeberg.org",
|
||||
"settings.gitea.page.apiBaseUrl.description": "URL base por defecto para las llamadas a la API. Para instancias autoalojadas, usa la dirección de tu servidor, p. ej. https://gitea.example.com.",
|
||||
"settings.gitea.page.detectUrls.label": "URL de detección",
|
||||
"settings.gitea.page.detectUrls.placeholder": "ssh://git@git.example.com:2222, https://git.example.com",
|
||||
"settings.gitea.page.detectUrls.placeholder": "codeberg.org",
|
||||
"settings.gitea.page.detectUrls.description": "Los repositorios clonados por SSH o HTTPS desde estos hosts se reconocen como Gitea o Forgejo.",
|
||||
"settings.gitProviders.detectUrls.add": "Añadir una URL de detección",
|
||||
"settings.gitProviders.detectUrls.remove": "Quitar {host}",
|
||||
|
||||
@@ -1600,10 +1600,10 @@ export const settingsDict = {
|
||||
'settings.github.page.toast.ghCliDisabled': 'Solution de secours gh CLI désactivée',
|
||||
'settings.github.page.toast.ghCliUpdateFailed': 'Échec de la mise à jour du paramètre gh CLI',
|
||||
'settings.github.page.apiBaseUrl.label': 'URL de base de l’API',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://github.example.com/api/v3',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://api.github.com',
|
||||
'settings.github.page.apiBaseUrl.description': 'URL de base par défaut pour les appels API. Pour GitHub Enterprise, utilisez l’adresse de votre serveur, ex. https://github.example.com/api/v3.',
|
||||
'settings.github.page.detectUrls.label': 'URL de détection',
|
||||
'settings.github.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.github.page.detectUrls.placeholder': 'github.com',
|
||||
'settings.github.page.detectUrls.description': 'Les dépôts clonés en SSH ou HTTPS depuis ces hôtes sont reconnus comme GitHub.',
|
||||
'settings.gitlab.page.title': 'Jeton d\'accès personnel GitLab',
|
||||
'settings.gitlab.page.description': 'Collez un jeton d\'accès personnel GitLab pour vous connecter. Définissez l\'URL de base si vous utilisez une instance GitLab auto-hébergée.',
|
||||
@@ -1613,10 +1613,10 @@ export const settingsDict = {
|
||||
'settings.gitlab.page.baseUrl.label': 'URL de base (facultatif)',
|
||||
'settings.gitlab.page.baseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.label': 'URL de base de l’API',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.example.com',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.description': 'URL de base par défaut pour les appels API. Pour les instances auto-hébergées, utilisez l’adresse de votre serveur, ex. https://gitlab.example.com.',
|
||||
'settings.gitlab.page.detectUrls.label': 'URL de détection',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'gitlab.com',
|
||||
'settings.gitlab.page.detectUrls.description': 'Les dépôts clonés en SSH ou HTTPS depuis ces hôtes sont reconnus comme GitLab.',
|
||||
'settings.gitlab.page.actions.connect': 'Connecter GitLab',
|
||||
'settings.gitlab.page.actions.disconnect': 'Déconnecter',
|
||||
@@ -1658,10 +1658,10 @@ export const settingsDict = {
|
||||
'settings.gitea.page.toast.accountSwitched': 'Le compte Gitea a changé',
|
||||
'settings.gitea.page.toast.accountSwitchFailed': 'Échec du changement de compte Gitea',
|
||||
'settings.gitea.page.apiBaseUrl.label': 'URL de base de l’API',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://gitea.example.com',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://codeberg.org',
|
||||
'settings.gitea.page.apiBaseUrl.description': 'URL de base par défaut pour les appels API. Pour les instances auto-hébergées, utilisez l’adresse de votre serveur, ex. https://gitea.example.com.',
|
||||
'settings.gitea.page.detectUrls.label': 'URL de détection',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'codeberg.org',
|
||||
'settings.gitea.page.detectUrls.description': 'Les dépôts clonés en SSH ou HTTPS depuis ces hôtes sont reconnus comme Gitea ou Forgejo.',
|
||||
'settings.gitProviders.detectUrls.add': 'Ajouter une URL de détection',
|
||||
'settings.gitProviders.detectUrls.remove': 'Retirer {host}',
|
||||
|
||||
@@ -1715,10 +1715,10 @@ export const settingsDict = {
|
||||
'settings.github.page.toast.ghCliDisabled': 'gh CLI フォールバックを無効化しました',
|
||||
'settings.github.page.toast.ghCliUpdateFailed': 'gh CLI 設定の更新に失敗しました',
|
||||
'settings.github.page.apiBaseUrl.label': 'API ベース URL',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://github.example.com/api/v3',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://api.github.com',
|
||||
'settings.github.page.apiBaseUrl.description': 'API 呼び出しに使用する既定のベース URL です。GitHub Enterprise の場合はサーバーアドレスを指定します。例: https://github.example.com/api/v3。',
|
||||
'settings.github.page.detectUrls.label': '検出 URL',
|
||||
'settings.github.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.github.page.detectUrls.placeholder': 'github.com',
|
||||
'settings.github.page.detectUrls.description': 'これらのホストから SSH または HTTPS でクローンしたリポジトリは GitHub として認識されます。',
|
||||
'settings.gitlab.page.title': 'GitLab パーソナルアクセストークン',
|
||||
'settings.gitlab.page.description': 'GitLab パーソナルアクセストークンを貼り付けて接続します。セルフホストの GitLab インスタンスを使用する場合はベース URL を設定してください。',
|
||||
@@ -1728,10 +1728,10 @@ export const settingsDict = {
|
||||
'settings.gitlab.page.baseUrl.label': 'ベース URL(任意)',
|
||||
'settings.gitlab.page.baseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.label': 'API ベース URL',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.example.com',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.description': 'API 呼び出しに使用する既定のベース URL です。セルフホストインスタンスの場合はサーバーアドレスを指定します。例: https://gitlab.example.com。',
|
||||
'settings.gitlab.page.detectUrls.label': '検出 URL',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'gitlab.com',
|
||||
'settings.gitlab.page.detectUrls.description': 'これらのホストから SSH または HTTPS でクローンしたリポジトリは GitLab として認識されます。',
|
||||
'settings.gitlab.page.actions.connect': 'GitLab に接続',
|
||||
'settings.gitlab.page.actions.disconnect': '切断',
|
||||
@@ -1773,10 +1773,10 @@ export const settingsDict = {
|
||||
'settings.gitea.page.toast.accountSwitched': 'Gitea アカウントを切り替えました',
|
||||
'settings.gitea.page.toast.accountSwitchFailed': 'Gitea アカウントの切り替えに失敗しました',
|
||||
'settings.gitea.page.apiBaseUrl.label': 'API ベース URL',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://gitea.example.com',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://codeberg.org',
|
||||
'settings.gitea.page.apiBaseUrl.description': 'API 呼び出しに使用する既定のベース URL です。セルフホストインスタンスの場合はサーバーアドレスを指定します。例: https://gitea.example.com。',
|
||||
'settings.gitea.page.detectUrls.label': '検出 URL',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'codeberg.org',
|
||||
'settings.gitea.page.detectUrls.description': 'これらのホストから SSH または HTTPS でクローンしたリポジトリは Gitea または Forgejo として認識されます。',
|
||||
'settings.gitProviders.detectUrls.add': '検出 URL を追加',
|
||||
'settings.gitProviders.detectUrls.remove': '{host} を削除',
|
||||
|
||||
@@ -1682,10 +1682,10 @@ export const settingsDict = {
|
||||
'settings.github.page.toast.ghCliDisabled': 'gh CLI 대체 비활성화됨',
|
||||
'settings.github.page.toast.ghCliUpdateFailed': 'gh CLI 설정을 업데이트하지 못했습니다',
|
||||
'settings.github.page.apiBaseUrl.label': 'API 기본 URL',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://github.example.com/api/v3',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://api.github.com',
|
||||
'settings.github.page.apiBaseUrl.description': 'API 호출에 사용되는 기본 URL입니다. GitHub Enterprise를 사용하는 경우 서버 주소를 입력하세요(예: https://github.example.com/api/v3).',
|
||||
'settings.github.page.detectUrls.label': '감지 URL',
|
||||
'settings.github.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.github.page.detectUrls.placeholder': 'github.com',
|
||||
'settings.github.page.detectUrls.description': '이 호스트에서 SSH 또는 HTTPS로 복제한 저장소는 GitHub로 인식됩니다.',
|
||||
'settings.gitlab.page.title': 'GitLab 개인 액세스 토큰',
|
||||
'settings.gitlab.page.description': '연결하려면 GitLab 개인 액세스 토큰을 붙여넣으세요. 자체 호스팅 GitLab 인스턴스를 사용하는 경우 기본 URL을 설정하세요.',
|
||||
@@ -1695,10 +1695,10 @@ export const settingsDict = {
|
||||
'settings.gitlab.page.baseUrl.label': '기본 URL(선택 사항)',
|
||||
'settings.gitlab.page.baseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.label': 'API 기본 URL',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.example.com',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.description': 'API 호출에 사용되는 기본 URL입니다. 자체 호스팅 인스턴스의 경우 서버 주소를 입력하세요(예: https://gitlab.example.com).',
|
||||
'settings.gitlab.page.detectUrls.label': '감지 URL',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'gitlab.com',
|
||||
'settings.gitlab.page.detectUrls.description': '이 호스트에서 SSH 또는 HTTPS로 복제한 저장소는 GitLab으로 인식됩니다.',
|
||||
'settings.gitlab.page.actions.connect': 'GitLab 연결',
|
||||
'settings.gitlab.page.actions.disconnect': '연결 해제',
|
||||
@@ -1740,10 +1740,10 @@ export const settingsDict = {
|
||||
'settings.gitea.page.toast.accountSwitched': 'Gitea 계정이 전환되었습니다',
|
||||
'settings.gitea.page.toast.accountSwitchFailed': 'Gitea 계정을 전환하지 못했습니다',
|
||||
'settings.gitea.page.apiBaseUrl.label': 'API 기본 URL',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://gitea.example.com',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://codeberg.org',
|
||||
'settings.gitea.page.apiBaseUrl.description': 'API 호출에 사용되는 기본 URL입니다. 자체 호스팅 인스턴스의 경우 서버 주소를 입력하세요(예: https://gitea.example.com).',
|
||||
'settings.gitea.page.detectUrls.label': '감지 URL',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'codeberg.org',
|
||||
'settings.gitea.page.detectUrls.description': '이 호스트에서 SSH 또는 HTTPS로 복제한 저장소는 Gitea 또는 Forgejo로 인식됩니다.',
|
||||
'settings.gitProviders.detectUrls.add': '감지 URL 추가',
|
||||
'settings.gitProviders.detectUrls.remove': '{host} 제거',
|
||||
|
||||
@@ -322,10 +322,10 @@ export const settingsDict = {
|
||||
'settings.github.page.toast.ghCliDisabled': 'Rezerwa gh CLI wyłączona',
|
||||
'settings.github.page.toast.ghCliUpdateFailed': 'Nie udało się zaktualizować ustawienia gh CLI',
|
||||
'settings.github.page.apiBaseUrl.label': 'Adres URL API',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://github.example.com/api/v3',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://api.github.com',
|
||||
'settings.github.page.apiBaseUrl.description': 'Domyślny adres URL dla wywołań API. W przypadku GitHub Enterprise podaj adres swojego serwera, np. https://github.example.com/api/v3.',
|
||||
'settings.github.page.detectUrls.label': 'Adresy URL wykrywania',
|
||||
'settings.github.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.github.page.detectUrls.placeholder': 'github.com',
|
||||
'settings.github.page.detectUrls.description': 'Repozytoria klonowane przez SSH lub HTTPS z tych hostów są rozpoznawane jako GitHub.',
|
||||
'settings.github.page.oauth.title': 'Token OAuth GitHub',
|
||||
'settings.github.page.ghCli.title': 'Token CLI GitHub',
|
||||
@@ -343,10 +343,10 @@ export const settingsDict = {
|
||||
'settings.gitlab.page.baseUrl.label': 'Podstawowy URL (opcjonalnie)',
|
||||
'settings.gitlab.page.baseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.label': 'Adres URL API',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.example.com',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.description': 'Domyślny adres URL dla wywołań API. W przypadku instancji hostowanych samodzielnie podaj adres swojego serwera, np. https://gitlab.example.com.',
|
||||
'settings.gitlab.page.detectUrls.label': 'Adresy URL wykrywania',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'gitlab.com',
|
||||
'settings.gitlab.page.detectUrls.description': 'Repozytoria klonowane przez SSH lub HTTPS z tych hostów są rozpoznawane jako GitLab.',
|
||||
'settings.gitlab.page.actions.connect': 'Połącz GitLab',
|
||||
'settings.gitlab.page.actions.disconnect': 'Odłącz',
|
||||
@@ -388,10 +388,10 @@ export const settingsDict = {
|
||||
'settings.gitea.page.toast.accountSwitched': 'Konto Gitea zostało przełączone',
|
||||
'settings.gitea.page.toast.accountSwitchFailed': 'Nie udało się przełączyć konta Gitea',
|
||||
'settings.gitea.page.apiBaseUrl.label': 'Adres URL API',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://gitea.example.com',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://codeberg.org',
|
||||
'settings.gitea.page.apiBaseUrl.description': 'Domyślny adres URL dla wywołań API. W przypadku instancji hostowanych samodzielnie podaj adres swojego serwera, np. https://gitea.example.com.',
|
||||
'settings.gitea.page.detectUrls.label': 'Adresy URL wykrywania',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'codeberg.org',
|
||||
'settings.gitea.page.detectUrls.description': 'Repozytoria klonowane przez SSH lub HTTPS z tych hostów są rozpoznawane jako Gitea lub Forgejo.',
|
||||
'settings.gitProviders.detectUrls.add': 'Dodaj adres URL wykrywania',
|
||||
'settings.gitProviders.detectUrls.remove': 'Usuń {host}',
|
||||
|
||||
@@ -1682,10 +1682,10 @@ export const settingsDict = {
|
||||
"settings.github.page.toast.ghCliDisabled": "Alternativa gh CLI desativada",
|
||||
"settings.github.page.toast.ghCliUpdateFailed": "Falha ao atualizar configuração do gh CLI",
|
||||
"settings.github.page.apiBaseUrl.label": "URL base da API",
|
||||
"settings.github.page.apiBaseUrl.placeholder": "https://github.example.com/api/v3",
|
||||
"settings.github.page.apiBaseUrl.placeholder": "https://api.github.com",
|
||||
"settings.github.page.apiBaseUrl.description": "URL base padrão para chamadas de API. Para GitHub Enterprise, use o endereço do seu servidor, ex.: https://github.example.com/api/v3.",
|
||||
"settings.github.page.detectUrls.label": "URLs de detecção",
|
||||
"settings.github.page.detectUrls.placeholder": "ssh://git@git.example.com:2222, https://git.example.com",
|
||||
"settings.github.page.detectUrls.placeholder": "github.com",
|
||||
"settings.github.page.detectUrls.description": "Repositórios clonados via SSH ou HTTPS desses hosts são reconhecidos como GitHub.",
|
||||
"settings.gitlab.page.title": "Token de acesso pessoal do GitLab",
|
||||
"settings.gitlab.page.description": "Cole um token de acesso pessoal do GitLab para conectar. Defina a URL base ao usar uma instância GitLab auto-hospedada.",
|
||||
@@ -1695,10 +1695,10 @@ export const settingsDict = {
|
||||
"settings.gitlab.page.baseUrl.label": "URL base (opcional)",
|
||||
"settings.gitlab.page.baseUrl.placeholder": "https://gitlab.com",
|
||||
"settings.gitlab.page.apiBaseUrl.label": "URL base da API",
|
||||
"settings.gitlab.page.apiBaseUrl.placeholder": "https://gitlab.example.com",
|
||||
"settings.gitlab.page.apiBaseUrl.placeholder": "https://gitlab.com",
|
||||
"settings.gitlab.page.apiBaseUrl.description": "URL base padrão para chamadas de API. Para instâncias auto-hospedadas, use o endereço do seu servidor, ex.: https://gitlab.example.com.",
|
||||
"settings.gitlab.page.detectUrls.label": "URLs de detecção",
|
||||
"settings.gitlab.page.detectUrls.placeholder": "ssh://git@git.example.com:2222, https://git.example.com",
|
||||
"settings.gitlab.page.detectUrls.placeholder": "gitlab.com",
|
||||
"settings.gitlab.page.detectUrls.description": "Repositórios clonados via SSH ou HTTPS desses hosts são reconhecidos como GitLab.",
|
||||
"settings.gitlab.page.actions.connect": "Conectar GitLab",
|
||||
"settings.gitlab.page.actions.disconnect": "Desconectar",
|
||||
@@ -1740,10 +1740,10 @@ export const settingsDict = {
|
||||
"settings.gitea.page.toast.accountSwitched": "Conta do Gitea alterada",
|
||||
"settings.gitea.page.toast.accountSwitchFailed": "Falha ao alternar a conta do Gitea",
|
||||
"settings.gitea.page.apiBaseUrl.label": "URL base da API",
|
||||
"settings.gitea.page.apiBaseUrl.placeholder": "https://gitea.example.com",
|
||||
"settings.gitea.page.apiBaseUrl.placeholder": "https://codeberg.org",
|
||||
"settings.gitea.page.apiBaseUrl.description": "URL base padrão para chamadas de API. Para instâncias auto-hospedadas, use o endereço do seu servidor, ex.: https://gitea.example.com.",
|
||||
"settings.gitea.page.detectUrls.label": "URLs de detecção",
|
||||
"settings.gitea.page.detectUrls.placeholder": "ssh://git@git.example.com:2222, https://git.example.com",
|
||||
"settings.gitea.page.detectUrls.placeholder": "codeberg.org",
|
||||
"settings.gitea.page.detectUrls.description": "Repositórios clonados via SSH ou HTTPS desses hosts são reconhecidos como Gitea ou Forgejo.",
|
||||
"settings.gitProviders.detectUrls.add": "Adicionar uma URL de detecção",
|
||||
"settings.gitProviders.detectUrls.remove": "Remover {host}",
|
||||
|
||||
@@ -1682,10 +1682,10 @@ export const settingsDict = {
|
||||
"settings.github.page.toast.ghCliDisabled": "Резервний варіант gh CLI вимкнено",
|
||||
"settings.github.page.toast.ghCliUpdateFailed": "Не вдалося оновити налаштування gh CLI",
|
||||
"settings.github.page.apiBaseUrl.label": "Базова URL-адреса API",
|
||||
"settings.github.page.apiBaseUrl.placeholder": "https://github.example.com/api/v3",
|
||||
"settings.github.page.apiBaseUrl.placeholder": "https://api.github.com",
|
||||
"settings.github.page.apiBaseUrl.description": "Типова базова URL-адреса для викликів API. Для GitHub Enterprise вкажіть адресу свого сервера, напр. https://github.example.com/api/v3.",
|
||||
"settings.github.page.detectUrls.label": "URL-адреси виявлення",
|
||||
"settings.github.page.detectUrls.placeholder": "ssh://git@git.example.com:2222, https://git.example.com",
|
||||
"settings.github.page.detectUrls.placeholder": "github.com",
|
||||
"settings.github.page.detectUrls.description": "Репозиторії, клоновані через SSH або HTTPS із цих хостів, розпізнаються як GitHub.",
|
||||
"settings.gitlab.page.title": "Персональний токен доступу GitLab",
|
||||
"settings.gitlab.page.description": "Вставте персональний токен доступу GitLab, щоб підключитися. Вкажіть базову URL-адресу, якщо використовуєте самостійно розміщену інстанцію GitLab.",
|
||||
@@ -1695,10 +1695,10 @@ export const settingsDict = {
|
||||
"settings.gitlab.page.baseUrl.label": "Базова URL-адреса (необов'язково)",
|
||||
"settings.gitlab.page.baseUrl.placeholder": "https://gitlab.com",
|
||||
"settings.gitlab.page.apiBaseUrl.label": "Базова URL-адреса API",
|
||||
"settings.gitlab.page.apiBaseUrl.placeholder": "https://gitlab.example.com",
|
||||
"settings.gitlab.page.apiBaseUrl.placeholder": "https://gitlab.com",
|
||||
"settings.gitlab.page.apiBaseUrl.description": "Типова базова URL-адреса для викликів API. Для саморозміщених екземплярів вкажіть адресу свого сервера, напр. https://gitlab.example.com.",
|
||||
"settings.gitlab.page.detectUrls.label": "URL-адреси виявлення",
|
||||
"settings.gitlab.page.detectUrls.placeholder": "ssh://git@git.example.com:2222, https://git.example.com",
|
||||
"settings.gitlab.page.detectUrls.placeholder": "gitlab.com",
|
||||
"settings.gitlab.page.detectUrls.description": "Репозиторії, клоновані через SSH або HTTPS із цих хостів, розпізнаються як GitLab.",
|
||||
"settings.gitlab.page.actions.connect": "Підключити GitLab",
|
||||
"settings.gitlab.page.actions.disconnect": "Відключити",
|
||||
@@ -1740,10 +1740,10 @@ export const settingsDict = {
|
||||
"settings.gitea.page.toast.accountSwitched": "Обліковий запис Gitea перемкнено",
|
||||
"settings.gitea.page.toast.accountSwitchFailed": "Не вдалося перемкнути обліковий запис Gitea",
|
||||
"settings.gitea.page.apiBaseUrl.label": "Базова URL-адреса API",
|
||||
"settings.gitea.page.apiBaseUrl.placeholder": "https://gitea.example.com",
|
||||
"settings.gitea.page.apiBaseUrl.placeholder": "https://codeberg.org",
|
||||
"settings.gitea.page.apiBaseUrl.description": "Типова базова URL-адреса для викликів API. Для саморозміщених екземплярів вкажіть адресу свого сервера, напр. https://gitea.example.com.",
|
||||
"settings.gitea.page.detectUrls.label": "URL-адреси виявлення",
|
||||
"settings.gitea.page.detectUrls.placeholder": "ssh://git@git.example.com:2222, https://git.example.com",
|
||||
"settings.gitea.page.detectUrls.placeholder": "codeberg.org",
|
||||
"settings.gitea.page.detectUrls.description": "Репозиторії, клоновані через SSH або HTTPS із цих хостів, розпізнаються як Gitea або Forgejo.",
|
||||
"settings.gitProviders.detectUrls.add": "Додати URL-адресу виявлення",
|
||||
"settings.gitProviders.detectUrls.remove": "Видалити {host}",
|
||||
|
||||
@@ -1682,10 +1682,10 @@ export const settingsDict = {
|
||||
'settings.github.page.toast.ghCliDisabled': 'gh CLI 备用已禁用',
|
||||
'settings.github.page.toast.ghCliUpdateFailed': '更新 gh CLI 设置失败',
|
||||
'settings.github.page.apiBaseUrl.label': 'API 基础 URL',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://github.example.com/api/v3',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://api.github.com',
|
||||
'settings.github.page.apiBaseUrl.description': 'API 调用的默认基础 URL。GitHub Enterprise 用户可填写服务器地址,例如 https://github.example.com/api/v3。',
|
||||
'settings.github.page.detectUrls.label': '检测 URL',
|
||||
'settings.github.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.github.page.detectUrls.placeholder': 'github.com',
|
||||
'settings.github.page.detectUrls.description': '通过这些主机以 SSH 或 HTTPS 方式克隆的仓库将被识别为 GitHub。',
|
||||
'settings.gitlab.page.title': 'GitLab 个人访问令牌',
|
||||
'settings.gitlab.page.description': '粘贴 GitLab 个人访问令牌以连接。使用自托管 GitLab 实例时,请设置基础 URL。',
|
||||
@@ -1695,10 +1695,10 @@ export const settingsDict = {
|
||||
'settings.gitlab.page.baseUrl.label': '基础 URL(可选)',
|
||||
'settings.gitlab.page.baseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.label': 'API 基础 URL',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.example.com',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.description': 'API 调用的默认基础 URL。自托管实例请填写服务器地址,例如 https://gitlab.example.com。',
|
||||
'settings.gitlab.page.detectUrls.label': '检测 URL',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'gitlab.com',
|
||||
'settings.gitlab.page.detectUrls.description': '通过这些主机以 SSH 或 HTTPS 方式克隆的仓库将被识别为 GitLab。',
|
||||
'settings.gitlab.page.actions.connect': '连接 GitLab',
|
||||
'settings.gitlab.page.actions.disconnect': '断开连接',
|
||||
@@ -1740,10 +1740,10 @@ export const settingsDict = {
|
||||
'settings.gitea.page.toast.accountSwitched': 'Gitea 账户已切换',
|
||||
'settings.gitea.page.toast.accountSwitchFailed': '切换 Gitea 账户失败',
|
||||
'settings.gitea.page.apiBaseUrl.label': 'API 基础 URL',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://gitea.example.com',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://codeberg.org',
|
||||
'settings.gitea.page.apiBaseUrl.description': 'API 调用的默认基础 URL。自托管实例请填写服务器地址,例如 https://gitea.example.com。',
|
||||
'settings.gitea.page.detectUrls.label': '检测 URL',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'codeberg.org',
|
||||
'settings.gitea.page.detectUrls.description': '通过这些主机以 SSH 或 HTTPS 方式克隆的仓库将被识别为 Gitea 或 Forgejo。',
|
||||
'settings.gitProviders.detectUrls.add': '添加检测 URL',
|
||||
'settings.gitProviders.detectUrls.remove': '移除 {host}',
|
||||
|
||||
@@ -1589,10 +1589,10 @@ export const settingsDict = {
|
||||
'settings.github.page.toast.ghCliDisabled': 'gh CLI 備用已停用',
|
||||
'settings.github.page.toast.ghCliUpdateFailed': '更新 gh CLI 設定失敗',
|
||||
'settings.github.page.apiBaseUrl.label': 'API 基礎 URL',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://github.example.com/api/v3',
|
||||
'settings.github.page.apiBaseUrl.placeholder': 'https://api.github.com',
|
||||
'settings.github.page.apiBaseUrl.description': 'API 呼叫的預設基礎 URL。GitHub Enterprise 使用者可填寫伺服器位址,例如 https://github.example.com/api/v3。',
|
||||
'settings.github.page.detectUrls.label': '偵測 URL',
|
||||
'settings.github.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.github.page.detectUrls.placeholder': 'github.com',
|
||||
'settings.github.page.detectUrls.description': '透過這些主機以 SSH 或 HTTPS 方式複製的存放庫將識別為 GitHub。',
|
||||
'settings.gitlab.page.title': 'GitLab 個人存取權杖',
|
||||
'settings.gitlab.page.description': '貼上 GitLab 個人存取權杖以連線。使用自架 GitLab 執行個體時,請設定基礎 URL。',
|
||||
@@ -1602,10 +1602,10 @@ export const settingsDict = {
|
||||
'settings.gitlab.page.baseUrl.label': '基礎 URL(選用)',
|
||||
'settings.gitlab.page.baseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.label': 'API 基礎 URL',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.example.com',
|
||||
'settings.gitlab.page.apiBaseUrl.placeholder': 'https://gitlab.com',
|
||||
'settings.gitlab.page.apiBaseUrl.description': 'API 呼叫的預設基礎 URL。自架執行個體請填寫伺服器位址,例如 https://gitlab.example.com。',
|
||||
'settings.gitlab.page.detectUrls.label': '偵測 URL',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitlab.page.detectUrls.placeholder': 'gitlab.com',
|
||||
'settings.gitlab.page.detectUrls.description': '透過這些主機以 SSH 或 HTTPS 方式複製的存放庫將識別為 GitLab。',
|
||||
'settings.gitlab.page.actions.connect': '連線 GitLab',
|
||||
'settings.gitlab.page.actions.disconnect': '中斷連線',
|
||||
@@ -1647,10 +1647,10 @@ export const settingsDict = {
|
||||
'settings.gitea.page.toast.accountSwitched': 'Gitea 帳號已切換',
|
||||
'settings.gitea.page.toast.accountSwitchFailed': '切換 Gitea 帳號失敗',
|
||||
'settings.gitea.page.apiBaseUrl.label': 'API 基礎 URL',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://gitea.example.com',
|
||||
'settings.gitea.page.apiBaseUrl.placeholder': 'https://codeberg.org',
|
||||
'settings.gitea.page.apiBaseUrl.description': 'API 呼叫的預設基礎 URL。自架執行個體請填寫伺服器位址,例如 https://gitea.example.com。',
|
||||
'settings.gitea.page.detectUrls.label': '偵測 URL',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'ssh://git@git.example.com:2222, https://git.example.com',
|
||||
'settings.gitea.page.detectUrls.placeholder': 'codeberg.org',
|
||||
'settings.gitea.page.detectUrls.description': '透過這些主機以 SSH 或 HTTPS 方式複製的存放庫將識別為 Gitea 或 Forgejo。',
|
||||
'settings.gitProviders.detectUrls.add': '新增偵測 URL',
|
||||
'settings.gitProviders.detectUrls.remove': '移除 {host}',
|
||||
|
||||
@@ -11,12 +11,14 @@
|
||||
|
||||
## Public exports
|
||||
|
||||
- `GIT_PROVIDER_DEFAULTS`: `{ github: 'https://api.github.com', gitlab: 'https://gitlab.com', gitea: null }`. Built-in defaults are **not persisted**; they are applied at read time by getters.
|
||||
- `GIT_PROVIDER_DEFAULTS`: `{ github: 'https://api.github.com', gitlab: 'https://gitlab.com', gitea: 'https://codeberg.org' }`. Built-in defaults are **not persisted**; they are applied at read time by getters.
|
||||
- `GIT_PROVIDER_DEFAULT_DETECT_URLS`: `{ github: ['github.com'], gitlab: ['gitlab.com'], gitea: ['codeberg.org'] }`. Built-in detection hostnames; remotes on these hosts classify as the provider with no configuration (mirrors the client-side built-ins in `packages/ui/src/lib/gitProvider.ts`).
|
||||
- `normalizeBaseUrl(raw)`: normalize an API base URL (add `https://` when the scheme is missing, strip trailing slashes, preserve subpaths like `/gitlab`), `null` for empty/unparseable input.
|
||||
- `normalizeDetectionHost(raw)`: extract the bare lowercase hostname from any git remote/URL form (`https://`, `ssh://`, scp-like `git@host:path`, IPv6); mirrors `packages/ui/src/lib/gitHost.ts` `parseGitHost`.
|
||||
- `sanitizeGitProviders(payload)`: validate/normalize the `gitProviders` shape — only `github|gitlab|gitea` keys survive; `apiBaseUrl` via `normalizeBaseUrl`, `detectUrls` deduped bare hostnames; empty/absent values dropped; returns `undefined` when nothing valid remains.
|
||||
- `readGitProvidersConfig()`: read the `gitProviders` section from `settings.json` (`OPENCHAMBER_DATA_DIR` env override, else `~/.config/openchamber`); never throws, returns `{}` on missing/invalid data.
|
||||
- `getProviderApiBaseUrl(provider)`: configured value -> `GIT_PROVIDER_DEFAULTS[provider]` -> `null` (gitea).
|
||||
- `getProviderApiBaseUrl(provider)`: configured value -> `GIT_PROVIDER_DEFAULTS[provider]` -> `null`.
|
||||
- `getProviderDetectUrls(provider)`: effective detection hostnames — built-in default hosts plus configured `detectUrls`, deduped (the built-ins always apply).
|
||||
- `githubWebOriginFromApiBase(apiBase)`: GitHub web origin from an API base — `https://api.github.com` -> `https://github.com`; Enterprise `https://host/api[/v3]` -> `https://host` (trailing `/api`/`/api/v3` stripped, subpath prefixes kept); otherwise the URL origin; never throws, falls back to `https://github.com`.
|
||||
|
||||
## Settings shape
|
||||
|
||||
@@ -14,7 +14,17 @@ const GIT_PROVIDER_KEYS = ['github', 'gitlab', 'gitea'];
|
||||
export const GIT_PROVIDER_DEFAULTS = {
|
||||
github: 'https://api.github.com',
|
||||
gitlab: 'https://gitlab.com',
|
||||
gitea: null,
|
||||
gitea: 'https://codeberg.org',
|
||||
};
|
||||
|
||||
// Built-in detection hostnames: remotes on these hosts are recognized as the
|
||||
// provider even when the user configures nothing. Configured detectUrls extend
|
||||
// them — the built-ins always apply (mirrors the client-side detection in
|
||||
// packages/ui/src/lib/gitProvider.ts).
|
||||
export const GIT_PROVIDER_DEFAULT_DETECT_URLS = {
|
||||
github: ['github.com'],
|
||||
gitlab: ['gitlab.com'],
|
||||
gitea: ['codeberg.org'],
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -171,12 +181,23 @@ export function readGitProvidersConfig() {
|
||||
|
||||
/**
|
||||
* Effective API base URL for a provider: the configured settings.json value if
|
||||
* present, else the built-in default (null for gitea, which has none).
|
||||
* present, else the built-in default.
|
||||
*/
|
||||
export function getProviderApiBaseUrl(provider) {
|
||||
return readGitProvidersConfig()[provider]?.apiBaseUrl || GIT_PROVIDER_DEFAULTS[provider] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Effective detection hostnames for a provider: the built-in default hosts
|
||||
* plus any user-configured detectUrls, deduped. The built-ins always apply so
|
||||
* a default host (e.g. github.com) keeps classifying remotes even when custom
|
||||
* enterprise hosts are configured.
|
||||
*/
|
||||
export function getProviderDetectUrls(provider) {
|
||||
const configured = readGitProvidersConfig()[provider]?.detectUrls ?? [];
|
||||
return [...new Set([...(GIT_PROVIDER_DEFAULT_DETECT_URLS[provider] ?? []), ...configured])];
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive the GitHub web origin from an API base URL. The public API host
|
||||
* (`https://api.github.com`) maps to `https://github.com`; an Enterprise API
|
||||
|
||||
@@ -8,11 +8,13 @@ process.env.OPENCHAMBER_DATA_DIR = TEMP_DATA_DIR;
|
||||
|
||||
const {
|
||||
GIT_PROVIDER_DEFAULTS,
|
||||
GIT_PROVIDER_DEFAULT_DETECT_URLS,
|
||||
normalizeBaseUrl,
|
||||
normalizeDetectionHost,
|
||||
sanitizeGitProviders,
|
||||
readGitProvidersConfig,
|
||||
getProviderApiBaseUrl,
|
||||
getProviderDetectUrls,
|
||||
githubWebOriginFromApiBase,
|
||||
} = await import('./config.js');
|
||||
|
||||
@@ -126,7 +128,7 @@ describe('readGitProvidersConfig / getProviderApiBaseUrl', () => {
|
||||
expect(readGitProvidersConfig()).toEqual({});
|
||||
expect(getProviderApiBaseUrl('github')).toBe('https://api.github.com');
|
||||
expect(getProviderApiBaseUrl('gitlab')).toBe('https://gitlab.com');
|
||||
expect(getProviderApiBaseUrl('gitea')).toBeNull();
|
||||
expect(getProviderApiBaseUrl('gitea')).toBe('https://codeberg.org');
|
||||
});
|
||||
|
||||
test('reads the configured values from settings.json', () => {
|
||||
@@ -142,7 +144,7 @@ describe('readGitProvidersConfig / getProviderApiBaseUrl', () => {
|
||||
});
|
||||
expect(getProviderApiBaseUrl('github')).toBe('https://github.example.com/api/v3');
|
||||
expect(getProviderApiBaseUrl('gitlab')).toBe('https://gitlab.example.com');
|
||||
expect(getProviderApiBaseUrl('gitea')).toBeNull();
|
||||
expect(getProviderApiBaseUrl('gitea')).toBe('https://codeberg.org');
|
||||
});
|
||||
|
||||
test('never throws on a malformed settings file', () => {
|
||||
@@ -152,6 +154,26 @@ describe('readGitProvidersConfig / getProviderApiBaseUrl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getProviderDetectUrls', () => {
|
||||
test('returns the built-in default hosts when nothing is configured', () => {
|
||||
expect(getProviderDetectUrls('github')).toEqual(['github.com']);
|
||||
expect(getProviderDetectUrls('gitlab')).toEqual(['gitlab.com']);
|
||||
expect(getProviderDetectUrls('gitea')).toEqual(['codeberg.org']);
|
||||
expect(GIT_PROVIDER_DEFAULT_DETECT_URLS.gitea).toEqual(['codeberg.org']);
|
||||
});
|
||||
|
||||
test('keeps the built-in hosts and appends configured detectUrls', () => {
|
||||
fs.writeFileSync(SETTINGS_FILE, JSON.stringify({
|
||||
gitProviders: {
|
||||
github: { detectUrls: ['github.example.com'] },
|
||||
gitea: { detectUrls: ['gitea.example.com', 'codeberg.org'] },
|
||||
},
|
||||
}));
|
||||
expect(getProviderDetectUrls('github')).toEqual(['github.com', 'github.example.com']);
|
||||
expect(getProviderDetectUrls('gitea')).toEqual(['codeberg.org', 'gitea.example.com']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('githubWebOriginFromApiBase', () => {
|
||||
test('maps the public api host to github.com', () => {
|
||||
expect(githubWebOriginFromApiBase('https://api.github.com')).toBe('https://github.com');
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
- This module owns Gitea/Forgejo auth (Personal Access Token), raw REST v1 client access, remote-URL repo resolution, and Gitea issue / pull-request (PR) APIs for OpenChamber, including issue create/update and PR create/update/merge writes.
|
||||
- From a user perspective, this is the layer that lets the app show Gitea issues and pull requests for a local project, including comments and per-file diffs, and create, edit, and merge pull requests.
|
||||
- Gitea and Forgejo share the same GitHub-style REST v1 API, so this module serves both. Gitea calls remote work **pull requests** (PR), not merge requests. Gitea repos are flat `owner/repo` — there are no multi-segment namespaces.
|
||||
- The module mirrors `packages/web/server/lib/gitlab/` (PAT auth + raw-fetch client) but uses a **Personal Access Token** against the `Authorization: token <pat>` header and a **user-supplied base URL** (Gitea is self-hosted; there is no default instance).
|
||||
- The module mirrors `packages/web/server/lib/gitlab/` (PAT auth + raw-fetch client) but uses a **Personal Access Token** against the `Authorization: token <pat>` header and a **user-supplied base URL** (Gitea is self-hosted; codeberg.org is the only built-in default).
|
||||
|
||||
## Entrypoints and structure
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
- `clearGiteaAuth()`: remove the current account.
|
||||
- `normalizeBaseUrl(raw)`: add `https://` when a scheme is missing, strip trailing slash, return `null` for invalid input.
|
||||
- `GITEA_AUTH_FILE`: auth file path.
|
||||
- `getGiteaDefaultBaseUrl()`: effective default base URL — configured `gitProviders.gitea.apiBaseUrl` from `settings.json`, else `null`. Used to prefill the connect form and as the connect/status default; stored accounts still require an explicit base URL (there is no invented host).
|
||||
- There is **no built-in default base URL**: Gitea/Forgejo is self-hosted, so the instance URL is always user-provided.
|
||||
- `getGiteaDefaultBaseUrl()`: effective default base URL — configured `gitProviders.gitea.apiBaseUrl` from `settings.json`, else `https://codeberg.org`. Used to prefill the connect form and as the connect/status default; stored accounts still require an explicit base URL.
|
||||
- The only built-in default base URL is **codeberg.org** (a well-known public Forgejo instance); any other Gitea/Forgejo instance URL is user-provided.
|
||||
|
||||
### Client (`client.js`)
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
- Auth storage: `~/.config/openchamber/gitea-auth.json` (override with `OPENCHAMBER_DATA_DIR`).
|
||||
- Writes are atomic (tmp file + rename) and file mode is `0o600`.
|
||||
- Base URL resolution: the caller-supplied `baseUrl` (normalized) is the primary source — there is no built-in default instance. A configured `settings.json` `gitProviders.gitea.apiBaseUrl` acts as the connect-form default/fallback. Stored entries without a usable base URL are dropped.
|
||||
- Base URL resolution: the caller-supplied `baseUrl` (normalized) is the primary source, then the effective default (configured `settings.json` `gitProviders.gitea.apiBaseUrl`, else `https://codeberg.org`). Stored entries without a usable base URL are dropped.
|
||||
- Account id: `` `${host}:${username}` `` (e.g. `gitea.example.com:alice`), falling back to `token:<first8>` when the username is missing.
|
||||
- Auth header on every request: `Authorization: token <pat>`.
|
||||
- Gitea's `GET /user` uses `login`/`full_name`/`html_url`; `setGiteaAuth` accepts both that and the `username`/`web_url` variants.
|
||||
@@ -92,7 +92,7 @@
|
||||
|
||||
| Method | Path | Shape |
|
||||
|---|---|---|
|
||||
| GET | `/api/gitea/auth/status` | `{ connected, user?, accounts[], defaultBaseUrl? }` (`defaultBaseUrl` present when connected; the configured `gitProviders.gitea.apiBaseUrl`, else `null`) |
|
||||
| GET | `/api/gitea/auth/status` | `{ connected, user?, accounts[], defaultBaseUrl? }` (`defaultBaseUrl` present when connected; the effective default — configured `gitProviders.gitea.apiBaseUrl`, else `https://codeberg.org`) |
|
||||
| POST | `/api/gitea/auth/connect` | body `{ accessToken, baseUrl? }` -> `{ connected, user, accounts }`; `400` for missing/invalid token; `400` when neither a valid `baseUrl` nor a configured default exists |
|
||||
| POST | `/api/gitea/auth/activate` | body `{ accountId }` -> `{ connected, user, accounts }`; `404` unknown account |
|
||||
| DELETE | `/api/gitea/auth` | `{ removed }` |
|
||||
|
||||
@@ -10,13 +10,13 @@ const OPENCHAMBER_DATA_DIR = process.env.OPENCHAMBER_DATA_DIR
|
||||
const STORAGE_DIR = OPENCHAMBER_DATA_DIR;
|
||||
const STORAGE_FILE = path.join(STORAGE_DIR, 'gitea-auth.json');
|
||||
|
||||
// Gitea/Forgejo are self-hosted — there is deliberately NO built-in default
|
||||
// base URL. The instance URL is always user-provided (see `normalizeBaseUrl`);
|
||||
// auth.js never invents a host for a stored account. A configured
|
||||
// settings.json gitProviders.gitea.apiBaseUrl can act as the default for the
|
||||
// connect form, but stored accounts still require an explicit baseUrl.
|
||||
// Gitea/Forgejo are primarily self-hosted, but codeberg.org (a well-known
|
||||
// public Forgejo instance) acts as the built-in default base URL. The instance
|
||||
// URL is always user-provided when connecting to a different host (see
|
||||
// `normalizeBaseUrl`); auth.js never invents a host for a stored account. A
|
||||
// configured settings.json gitProviders.gitea.apiBaseUrl overrides the default.
|
||||
|
||||
/** Effective default Gitea base URL: configured settings.json value, else null (no built-in default). */
|
||||
/** Effective default Gitea base URL: configured settings.json value, else codeberg.org. */
|
||||
export function getGiteaDefaultBaseUrl() {
|
||||
return getProviderApiBaseUrl('gitea');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user