/* tslint:disable */ /* eslint-disable */ /** * gitdata api - version 1.0 * * ## 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` / `log_id` | correlation ids, also returned as `X-Request-Id` / `X-Log-Id` headers | 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`: primary web session auth (cookie `gitdata_session`). - `basic_access_key`: HTTP Basic auth with an access key created via `POST /auth/access-keys` (id as user, secret as password). **Scope: git repository endpoints only** (`/repos/*`, `/graphql`); it is NOT accepted by chat/issues/space/user endpoints. ### 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/*` requires a session belonging to a configured platform admin 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 style: `?limit=&offset=` (default 50, max 100 unless stated), response `data` is `{ items, total, limit, offset }`. - Cursor style (chat message/sequence data): `?before_seq=&after_seq=&limit=`, response contains `has_more`. ### 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 login exchange `POST /auth/login` responds with `needs_2fa` and an opaque one-time `challenge` string; pass it to `POST /auth/login/2fa` together with the TOTP/recovery code. The challenge is single-use and short-lived. ### Operations - `GET /healthz` — liveness probe (no auth, outside `/api/v1`). - `GET /readyz` — readiness probe: database + redis check, `503` when 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 version: 3.1.0 * * * NOTE: This file is auto generated by the alova's vscode plugin. * * https://alova.js.org/devtools/vscode * * **Do not edit the file manually.** */ import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from 'alova'; import { Method } from 'alova'; import apiDefinitions from './apiDefinitions'; const cache = Object.create(null); const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova, configMap: any) => { const apiPathKey = array.join('.') as keyof typeof apiDefinitions; if (cache[apiPathKey]) { return cache[apiPathKey]; } // create a new proxy instance const proxy = new Proxy(function () {}, { get(_, property) { // record the target property, so that it can get the completed accessing paths const newArray = [...array, property]; // always return a new proxy to continue recording accessing paths. return createFunctionalProxy(newArray, alovaInstance, configMap); }, apply(_, __, [config]) { const apiItem = apiDefinitions[apiPathKey]; if (!apiItem) { throw new Error(`the api path of \`${apiPathKey}\` is not found`); } const mergedConfig = { ...configMap[apiPathKey], ...config }; const [method, url] = apiItem; const pathParams = mergedConfig.pathParams; const urlReplaced = url!.replace(/\{([^}]+)\}/g, (_, key) => { const pathParam = pathParams[key]; return pathParam; }); delete mergedConfig.pathParams; let data = mergedConfig.data; if (Object.prototype.toString.call(data) === '[object Object]' && typeof FormData !== 'undefined') { let hasBlobData = false; const formData = new FormData(); for (const key in data) { if (Array.isArray(data[key])) { for (const ele of data[key]) { formData.append(key, ele); if (ele instanceof Blob) { hasBlobData = true; } } } else { formData.append(key, data[key]); if (data[key] instanceof Blob) { hasBlobData = true; } } } data = hasBlobData ? formData : data; } return new Method(method!.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data); } }); cache[apiPathKey] = proxy; return proxy; }; export const createApis = (alovaInstance: Alova, configMap: any) => { const Apis = new Proxy({} as Apis, { get(_, property) { return createFunctionalProxy([property], alovaInstance, configMap); } }); return Apis; }; export const mountApis = (Apis: Apis) => { // define global variable `Apis` (globalThis as any).Apis = Apis; }; type MethodConfig = AlovaMethodCreateConfig< (typeof import('./index'))['alovaInstance'] extends Alova ? AG : any, any, T >; type APISofParameters = Tag extends keyof Apis ? Url extends keyof Apis[Tag] ? Apis[Tag][Url] extends (...args: any) => any ? Parameters : any : any : any; type MethodsConfigMap = { [P in keyof typeof import('./apiDefinitions').default]?: MethodConfig< P extends `${infer Tag}.${infer Url}` ? Parameters[0]>['transform']>[0] : any >; }; export const withConfigType = (config: Config) => config;