Skip to content
Clone
main
158 lines 6.2 KB
/**
* Generated by orval 🍺
* Do not edit manually.
* gitdata api
*
* ## Conventions
*
* ### Response envelope
* Every JSON response uses the same envelope:
*
* | field | meaning |
* |---|---|
* | `code` | always equal to the HTTP status code |
* | `message` | human-readable result / error summary |
* | `data` | payload, `null` for errors and empty results |
* | `error` | field-level / technical detail (e.g. validation errors), may be `null` |
* | `error_code` | stable machine-readable code on 4xx (e.g. `conflict`, `rate_limited`), may be `null` |
* | `request_id` | correlation id, also returned as the `X-Request-Id` header |
*
* Successful `POST` creation returns `200` (not `201`); empty results use `200` with `data: null`.
* - `POST /auth/logout` is idempotent: repeating it always succeeds with `200`.
*
* ### Authentication
* - `session_cookie`: opaque session carried in the `session` cookie and stored in
* Redis. `GET /auth/login` redirects to the same-origin login page;
* `POST /auth/logout` revokes the session and clears the cookie.
*
* ### URL & parameter style
* - Paths are `kebab-case`, plural nouns, nesting expresses ownership.
* - Query/path/JSON field names are `snake_case`; enum values are `snake_case`.
* - All endpoints are versioned under `/api/v1`. `/api/v1/internal/*` is guarded
* by the `x-gitdata-service-key` header and is NOT documented here.
* - State-transition actions use `POST {resource}/{id}/{verb}` (close/reopen);
* idempotent whole-resource state uses `PUT` (default branch, pin, read-state);
* partial updates use `PATCH`.
*
* ### Pagination
* - 唯一 offset 风格:`?limit=&offset=`(`limit` 默认 50;`offset` 上限 5000),
* 分页响应的 `data` 恒为 `{ items, total, limit, offset }`,字段均为无符号整数。
* - `limit` 为 0、超过端点上限或 `offset` 超过 5000 时返回 400
* (`error_code: bad_request`),不会静默截断。
* - 排序参数为 `?sort=<field>&order=asc|desc`;`sort` 的取值按端点枚举校验,
* 未知值返回 400,未知参数同样返回 400。
* - chat 消息额外接受 `before_seq` / `after_seq` 作为筛选条件,响应仍是同一 `Page` 形状。
* - Git LFS 锁定列表的 `next_cursor` 是 LFS 协议字段,不适用本约定。
*
* ### PATCH semantics (three-state fields)
* Update commands use `Option<Option<T>>` for clearable fields:
* - field **absent** → unchanged
* - field `null` → cleared
* - field value → set
*
* Example: `{"milestone_id": null}` unassigns the milestone; omitting
* `milestone_id` leaves it untouched.
*
* ### 2FA
* TOTP enrollment, recovery codes and sensitive-operation verification are
* handled by identity; GitData only proxies the account-management endpoints.
*
* ### Operations
* - `GET /healthz` — liveness probe (no auth, outside `/api/v1`).
* - `GET /readyz` — readiness probe: database (primary) + redis live checks,
* rocketmq + s3 sampled every 10s, `503` when any is down.
* - Runtime metrics are pushed to the configured OTLP collector (30s interval);
* there is no scrape endpoint.
* - Cross-origin browser access is disabled by default; the API expects a
* same-origin reverse proxy. Enable `web.cors_allow_origins` to allowlist
* other origins.
*
* ### Abuse controls
* - Creation endpoints are subject to per-user rolling 24h quotas
* (`[quota]` config; 0 disables). Exceeding a quota returns `429`
* with `error_code: "rate_limited"`.
*
* ### Idempotency
* - `POST /chat/rooms/{room_id}/messages` accepts `nonce`: unique per room;
* retrying with the same nonce returns the original message instead of a duplicate.
*
* ### Resource references
* - User references in responses embed a `user` object (`UserDto`) wherever a
* single person is shown; raw uuid fields are named `*_id` consistently.
* - Viewer-specific state is embedded, not fetched separately: `RepoDto.me`
* carries `starred`/`watch_mode`, `IssueDto.viewer_watch` carries the caller
* watch mode. `PUT /repos/{space}/{repo}/star|unstar` style reads do not exist.
*
* ### Identifiers
* - Issues are addressable by UUID **or** board-scoped number
* (e.g. `/issues/{space}/boards/{board}/issues/123`).
* - Binary uploads use raw request bodies with a content-type header
* (e.g. `PUT /me/avatar` accepts `image/*` bytes, not base64 JSON).
*
* OpenAPI spec version: 1.0
*/
import type { EnvelopeRepoDto, UpdateRepoCmd } from "./update-repo.schemas";
export type updateRepoResponse200 = {
data: EnvelopeRepoDto;
status: 200;
};
export type updateRepoResponseSuccess = updateRepoResponse200 & {
headers: Headers;
};
export type updateRepoResponse = updateRepoResponseSuccess;
export const getUpdateRepoUrl = (spaceName: string, repoName: string) => {
return `/api/v1/repos/${spaceName}/${repoName}`;
};
/**
* 更新仓库描述、主页、可见性、LFS 和默认分支;仅空间所有者可操作。
*/
export const updateRepo = async (
spaceName: string,
repoName: string,
updateRepoCmd: UpdateRepoCmd,
options?: RequestInit,
): Promise<updateRepoResponse> => {
const getHeaders = (
h?: NonNullable<RequestInit["headers"]>,
): Record<string, string | readonly string[]> => {
if (!h) return {};
if (h instanceof Headers) return Object.fromEntries(h.entries());
if (Symbol.iterator in h) {
return Object.fromEntries(
Array.from(
h as Iterable<Iterable<string>>,
(entry) => Array.from(entry) as [string, string],
),
);
}
const headers: Record<string, string | readonly string[]> = {};
for (const [name, value] of Object.entries<
string | readonly string[] | undefined
>(h)) {
if (value !== undefined) headers[name] = value;
}
return headers;
};
const res = await fetch(getUpdateRepoUrl(spaceName, repoName), {
...options,
method: "PATCH",
headers: {
"Content-Type": "application/json",
...getHeaders(options?.headers),
},
body: JSON.stringify(updateRepoCmd),
});
const body = [204, 205, 304].includes(res.status) ? null : await res.text();
const data: updateRepoResponse["data"] = body ? JSON.parse(body) : {};
return {
data,
status: res.status,
headers: res.headers,
} as updateRepoResponse;
};