@smwb/onreel-git-mcp 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -6
- package/dist/{chunk-3YP22YLA.js → chunk-33ISKIW7.js} +2 -2
- package/dist/{chunk-6VQURMRA.js → chunk-AJOAZMU4.js} +2 -1
- package/dist/{chunk-4ZGRXIVA.js → chunk-D5QUOIRC.js} +5 -1
- package/dist/{chunk-4ZGRXIVA.js.map → chunk-D5QUOIRC.js.map} +1 -1
- package/dist/{chunk-VLTG7OKJ.js → chunk-OWLVTLYZ.js} +3 -3
- package/dist/contract/contract.schema.d.ts +12 -0
- package/dist/contract/contract.types.d.ts +2 -1
- package/dist/files/index.js +1 -1
- package/dist/git/index.js +4 -4
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.js +3 -3
- package/dist/tracker/declarative/declarative-call.lib.d.ts +28 -0
- package/dist/tracker/declarative/declarative-capabilities.lib.d.ts +20 -0
- package/dist/tracker/declarative/declarative-ci.lib.d.ts +4 -0
- package/dist/tracker/declarative/declarative-hint.const.d.ts +4 -0
- package/dist/tracker/declarative/declarative-issues.lib.d.ts +5 -0
- package/dist/tracker/declarative/declarative-model.const.d.ts +40 -0
- package/dist/tracker/declarative/declarative-model.types.d.ts +87 -0
- package/dist/tracker/declarative/declarative-parse.lib.d.ts +7 -0
- package/dist/tracker/declarative/declarative-pull.lib.d.ts +4 -0
- package/dist/tracker/declarative/declarative-request.lib.d.ts +49 -0
- package/dist/tracker/declarative/declarative-result.lib.d.ts +11 -0
- package/dist/tracker/declarative/declarative-rules.lib.d.ts +4 -0
- package/dist/tracker/declarative/declarative.const.d.ts +10 -0
- package/dist/tracker/declarative/declarative.lib.d.ts +19 -0
- package/dist/tracker/declarative/declarative.schema.d.ts +1324 -0
- package/dist/tracker/declarative/declarative.types.d.ts +22 -0
- package/dist/tracker/index.d.ts +5 -0
- package/dist/tracker/index.js +1968 -35
- package/dist/tracker/index.js.map +1 -1
- package/dist/tracker/registry.lib.d.ts +8 -1
- package/dist/tracker/secrets.lib.d.ts +14 -6
- package/dist/worktree/index.js +4 -4
- package/package.json +2 -1
- /package/dist/{chunk-3YP22YLA.js.map → chunk-33ISKIW7.js.map} +0 -0
- /package/dist/{chunk-6VQURMRA.js.map → chunk-AJOAZMU4.js.map} +0 -0
- /package/dist/{chunk-VLTG7OKJ.js.map → chunk-OWLVTLYZ.js.map} +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AdapterContext, JsonRequest, PageQuery, TrackerPage } from '../tracker.types.ts';
|
|
2
|
+
import type { TrackerConfig } from './declarative.schema.ts';
|
|
3
|
+
import type { ConfigCall, ConfigContext, ConfigSection, InputValues } from './declarative-model.types.ts';
|
|
4
|
+
/** Отказы по ответу: 404 сущности и статусы «переход сейчас невозможен». */
|
|
5
|
+
type CallOptions = Pick<JsonRequest, 'missing' | 'missingIsIssue' | 'conflictOn'>;
|
|
6
|
+
/** Контекст запросов адаптера: обязательные поля подключения заданы, адрес API разобран, заголовки собраны. */
|
|
7
|
+
export declare function contextOf(config: TrackerConfig, { connection, fetch }: AdapterContext): ConfigContext;
|
|
8
|
+
/** Операция раздела из конфига; нет — undefined. */
|
|
9
|
+
export declare function callOf(config: TrackerConfig, section: ConfigSection, name: string): ConfigCall | undefined;
|
|
10
|
+
/** Операция, которой может не быть: нет в конфиге — отказ unsupported с тем, чего трекер не умеет. */
|
|
11
|
+
export declare function requireCall(config: TrackerConfig, section: ConfigSection, name: string, what: string): ConfigCall;
|
|
12
|
+
/**
|
|
13
|
+
* Входы со значением, которых нет в шаблонах операции, — отказ unsupported до запроса: молча потерянная правка хуже
|
|
14
|
+
* отказа. false и пустой список не считаются значением: это «не просили» (черновик, удаление ветки, меток нет).
|
|
15
|
+
*/
|
|
16
|
+
export declare function assertUsed(subject: string, call: ConfigCall, inputs: InputValues): void;
|
|
17
|
+
/** Мс единой модели → ISO 8601 для шаблона; нет — нет. */
|
|
18
|
+
export declare function isoOf(value: number | undefined): string | undefined;
|
|
19
|
+
/** Входы сортировки: поле и направление (по умолчанию desc); сортировки нет — нет и входов. */
|
|
20
|
+
export declare function sortInputs(sort: {
|
|
21
|
+
field: string;
|
|
22
|
+
direction?: 'asc' | 'desc' | undefined;
|
|
23
|
+
} | undefined): InputValues;
|
|
24
|
+
/** Операция с одним элементом результата. */
|
|
25
|
+
export declare function single<T>(context: ConfigContext, call: ConfigCall, inputs: InputValues, options?: CallOptions, defaults?: Readonly<Record<string, unknown>>): Promise<T>;
|
|
26
|
+
/** Операция-список: страница элементов единой модели (не больше limit) и курсор следующей. */
|
|
27
|
+
export declare function list<T>(context: ConfigContext, call: ConfigCall, inputs: InputValues, page: PageQuery, options?: CallOptions, defaults?: Readonly<Record<string, unknown>>): Promise<TrackerPage<T>>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Issue, TrackerFeatures } from '../../contract/contract.types.ts';
|
|
2
|
+
import type { CiJob, CiRun } from '../ci.schema.ts';
|
|
3
|
+
import type { CiCapabilities, CiRunQuery } from '../ci.types.ts';
|
|
4
|
+
import type { PullRequest } from '../pull.schema.ts';
|
|
5
|
+
import type { PullRequestCapabilities, PullRequestQuery } from '../pull.types.ts';
|
|
6
|
+
import type { CommentCapabilities, IssueCapabilities, IssueQuery } from '../tracker.types.ts';
|
|
7
|
+
import type { TrackerConfig, TrackerConfigOperation } from './declarative.schema.ts';
|
|
8
|
+
export declare function commentsOf(operation: TrackerConfigOperation | undefined): CommentCapabilities;
|
|
9
|
+
export declare function issueCapabilitiesFrom(config: TrackerConfig): IssueCapabilities;
|
|
10
|
+
/** Что умеет трекер для интерфейса: операции есть — действия есть; поля — по входам create и update. */
|
|
11
|
+
export declare function featuresFrom(config: TrackerConfig): TrackerFeatures;
|
|
12
|
+
export declare function pullCapabilitiesFrom(config: TrackerConfig): PullRequestCapabilities | undefined;
|
|
13
|
+
export declare function ciCapabilitiesFrom(config: TrackerConfig): CiCapabilities | undefined;
|
|
14
|
+
/** Проверка страницы задач по фильтрам clientSide запроса. */
|
|
15
|
+
export declare function issueFilter(capabilities: IssueCapabilities, query: IssueQuery): (item: Issue) => boolean;
|
|
16
|
+
export declare function pullFilter(capabilities: PullRequestCapabilities, query: PullRequestQuery): (item: PullRequest) => boolean;
|
|
17
|
+
export declare function runFilter(capabilities: CiCapabilities, query: CiRunQuery): (item: CiRun) => boolean;
|
|
18
|
+
export declare function jobFilter(capabilities: CiCapabilities, query: {
|
|
19
|
+
status?: readonly string[] | undefined;
|
|
20
|
+
}): (item: CiJob) => boolean;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CiAdapter, CiCapabilities } from '../ci.types.ts';
|
|
2
|
+
import type { AdapterContext } from '../tracker.types.ts';
|
|
3
|
+
import type { TrackerConfig } from './declarative.schema.ts';
|
|
4
|
+
export declare function createCiAdapter(config: TrackerConfig, adapterContext: AdapterContext, capabilities: CiCapabilities): CiAdapter;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Пример конфига `format: 1`: задачи, pull request-ы и CI трекера в стиле Gitea. */
|
|
2
|
+
export declare const TRACKER_CONFIG_EXAMPLE = "format: 1\nkind: gitea\ntitle: Gitea\nfields:\n - { name: url, required: true, secret: false }\n - { name: target, required: true, secret: false }\n - { name: token, required: true, secret: true }\nhttp:\n base: \"{{url}}/api/v1\"\n auth: { kind: bearer }\n headers:\n Accept: application/json\n pagination: { style: page, page: page, size: limit, next: link }\nissues:\n list:\n path: \"/repos/{{target|path}}/issues\"\n query:\n type: issues\n state: \"{{status}}\"\n labels: \"{{labels}}\"\n q: \"{{search}}\"\n created_by: \"{{author}}\"\n since: \"{{updatedAfter}}\"\n before: \"{{updatedBefore}}\"\n inputs:\n status: { open: open, in_progress: open, done: closed, declined: closed, \"*\": all }\n result: &issue\n key: $.number\n title: $.title\n description: $.body\n status.category: { path: $.state, map: { open: open, closed: done } }\n labels: $.labels[*].name\n assignee: $.assignee.login\n url: $.html_url\n createdAt: $.created_at\n updatedAt: $.updated_at\n get:\n path: \"/repos/{{target|path}}/issues/{{key}}\"\n result: *issue\n create:\n method: POST\n path: \"/repos/{{target|path}}/issues\"\n body:\n title: \"{{title}}\"\n body: \"{{description}}\"\n assignee: \"{{assignee}}\"\n result: *issue\n update:\n method: PATCH\n path: \"/repos/{{target|path}}/issues/{{key}}\"\n body:\n title: \"{{title}}\"\n body: \"{{description}}\"\n state: \"{{status}}\"\n assignee: \"{{assignee}}\"\n inputs:\n status: { open: open, done: closed }\n result: *issue\n comments:\n path: \"/repos/{{target|path}}/issues/{{key}}/comments\"\n query:\n since: \"{{updatedAfter}}\"\n result: &comment\n id: $.id\n author: $.user.login\n body: $.body\n createdAt: $.created_at\n comment:\n method: POST\n path: \"/repos/{{target|path}}/issues/{{key}}/comments\"\n body:\n body: \"{{body}}\"\n result: *comment\npulls:\n list:\n path: \"/repos/{{target|path}}/pulls\"\n query:\n state: \"{{status}}\"\n inputs:\n status: { draft: open, open: open, merged: closed, closed: closed, \"*\": all }\n result: &pull\n key: $.number\n title: $.title\n description: $.body\n status.category: { path: $.state, map: { open: open, closed: closed } }\n merged: $.merged\n draft: $.draft\n author: $.user.login\n source: $.head.ref\n target: $.base.ref\n headSha: $.head.sha\n labels: $.labels[*].name\n url: $.html_url\n createdAt: $.created_at\n updatedAt: $.updated_at\n mergedAt: $.merged_at\n closedAt: $.closed_at\n get:\n path: \"/repos/{{target|path}}/pulls/{{key}}\"\n result: *pull\n create:\n method: POST\n path: \"/repos/{{target|path}}/pulls\"\n body:\n title: \"{{title}}\"\n body: \"{{description}}\"\n head: \"{{sourceBranch}}\"\n base: \"{{targetBranch}}\"\n result: *pull\n update:\n method: PATCH\n path: \"/repos/{{target|path}}/pulls/{{key}}\"\n body:\n title: \"{{title}}\"\n body: \"{{description}}\"\n base: \"{{targetBranch}}\"\n state: \"{{status}}\"\n inputs:\n status: { open: open, closed: closed }\n result: *pull\n merge:\n method: POST\n path: \"/repos/{{target|path}}/pulls/{{key}}/merge\"\n body:\n Do: \"{{method}}\"\n merge_message_field: \"{{message}}\"\n delete_branch_after_merge: \"{{deleteSource}}\"\n head_commit_id: \"{{headSha}}\"\n comments:\n path: \"/repos/{{target|path}}/issues/{{key}}/comments\"\n result: *comment\n comment:\n method: POST\n path: \"/repos/{{target|path}}/issues/{{key}}/comments\"\n body:\n body: \"{{body}}\"\n result: *comment\nci:\n workflows:\n path: \"/repos/{{target|path}}/actions/workflows\"\n items: $.workflows\n result:\n key: $.id\n name: $.name\n path: $.path\n enabled: { path: $.state, map: { active: true }, default: false }\n runs:\n path: \"/repos/{{target|path}}/actions/runs\"\n query:\n branch: \"{{ref}}\"\n event: \"{{event}}\"\n status: \"{{status}}\"\n actor: \"{{actor}}\"\n head_sha: \"{{sha}}\"\n inputs:\n event: { push: push, pull_request: pull_request, manual: workflow_dispatch, schedule: schedule }\n status: { queued: queued, waiting: waiting, running: in_progress, success: success, failed: failure, canceled: cancelled, skipped: skipped }\n items: $.workflow_runs\n result: &run\n key: $.id\n number: $.run_number\n workflows: $.path\n status.category: &state\n - { path: $.conclusion, map: { success: success, failure: failed, cancelled: canceled, skipped: skipped }, default: failed }\n - { path: $.status, map: { queued: queued, waiting: waiting, in_progress: running }, default: running }\n status.name: $.status\n event.category: { path: $.event, map: { push: push, pull_request: pull_request, workflow_dispatch: manual, schedule: schedule }, default: other }\n ref: $.head_branch\n sha: $.head_sha\n actor: $.actor.login\n attempt: $.run_attempt\n url: $.html_url\n createdAt: $.created_at\n startedAt: $.run_started_at\n finishedAt: $.completed_at\n updatedAt: $.updated_at\n run:\n path: \"/repos/{{target|path}}/actions/runs/{{key}}\"\n result: *run\n jobs:\n path: \"/repos/{{target|path}}/actions/runs/{{run}}/jobs\"\n items: $.jobs\n result: &job\n key: $.id\n runKey: $.run_id\n name: $.name\n status.category: *state\n status.name: $.status\n url: $.html_url\n startedAt: $.started_at\n finishedAt: $.completed_at\n job:\n path: \"/repos/{{target|path}}/actions/jobs/{{key}}\"\n result: *job\n log:\n path: \"/repos/{{target|path}}/actions/jobs/{{key}}/logs\"\n trigger:\n method: POST\n path: \"/repos/{{target|path}}/actions/workflows/{{workflow}}/dispatches\"\n body:\n ref: \"{{ref}}\"\n inputs: \"{{inputs}}\"\n rerun:\n method: POST\n path: \"/repos/{{target|path}}/actions/runs/{{key}}/rerun\"\n cancel:\n method: POST\n path: \"/repos/{{target|path}}/actions/runs/{{key}}/cancel\"\n";
|
|
3
|
+
/** Подсказка агенту: как написать конфиг своего трекера, правила безопасности и рабочий пример. */
|
|
4
|
+
export declare const TRACKER_CONFIG_HINT: string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TrackerFeatures } from '../../contract/contract.types.ts';
|
|
2
|
+
import type { AdapterContext, IssueCapabilities, TrackerAdapter } from '../tracker.types.ts';
|
|
3
|
+
import type { TrackerConfig } from './declarative.schema.ts';
|
|
4
|
+
/** Адаптер задач по разделу issues; раздела нет — каждый метод отказывает unsupported. */
|
|
5
|
+
export declare function createIssuesAdapter(config: TrackerConfig, adapterContext: AdapterContext, capabilities: IssueCapabilities, features: TrackerFeatures): TrackerAdapter;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ConfigSection, OperationSpec, ResultField, ResultModel } from './declarative-model.types.ts';
|
|
2
|
+
/** Плейсхолдер шаблона: `{{имя}}` — значение кодируется по месту, `{{имя|path}}` — путь из сегментов через «/». */
|
|
3
|
+
export declare const PLACEHOLDER: RegExp;
|
|
4
|
+
/** Поля подключения, которые подставляют шаблоны; токена среди них нет — его подставляет только http.auth. */
|
|
5
|
+
export declare const CONNECTION_PLACEHOLDERS: readonly ['url', 'target', 'user'];
|
|
6
|
+
/** Заголовки, которые задаёт сам клиент HTTP: в http.headers их нет. */
|
|
7
|
+
export declare const RESERVED_HEADERS: readonly ['host', 'content-length', 'content-type', 'transfer-encoding', 'connection', 'accept-encoding', 'te', 'upgrade', 'trailer'];
|
|
8
|
+
/** Ключи, которые не бывают именами в конфиге: они меняли бы прототип объекта. */
|
|
9
|
+
export declare const FORBIDDEN_KEYS: readonly ['__proto__', 'constructor', 'prototype'];
|
|
10
|
+
/** Сообщение «секрет в тексте конфига»: токен вводят в подключении, а не пишут в конфиг. */
|
|
11
|
+
export declare const SECRET_IN_CONFIG = "\u043F\u043E\u0445\u043E\u0436\u0435 \u043D\u0430 \u0441\u0435\u043A\u0440\u0435\u0442: \u0442\u043E\u043A\u0435\u043D \u043D\u0435 \u043F\u0438\u0448\u0443\u0442 \u0432 \u043A\u043E\u043D\u0444\u0438\u0433 \u2014 \u0435\u0433\u043E \u0432\u0432\u043E\u0434\u044F\u0442 \u0432 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0438 \u043F\u0440\u043E\u0435\u043A\u0442\u0430, \u0430 \u043F\u043E\u0434\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u0442 \u0442\u043E\u043B\u044C\u043A\u043E http.auth";
|
|
12
|
+
/** Ключ таблицы входа: значение для нескольких разных значений сразу (все статусы); только у фильтров списков. */
|
|
13
|
+
export declare const INPUT_ANY = "*";
|
|
14
|
+
/** Ключ таблицы входа для null: «без исполнителя» в фильтре и «снять исполнителя» в правке. */
|
|
15
|
+
export declare const INPUT_NULL = "null";
|
|
16
|
+
/**
|
|
17
|
+
* Операции разделов: входы, обязательные входы и что делать с ответом. Ветки PR во входах — sourceBranch и
|
|
18
|
+
* targetBranch: имя target занято полем подключения (репозиторий), а в модели PR они — source и target.
|
|
19
|
+
*/
|
|
20
|
+
export declare const OPERATIONS: Readonly<Record<ConfigSection, Readonly<Record<string, OperationSpec>>>>;
|
|
21
|
+
/** Операции, без которых раздела нет. */
|
|
22
|
+
export declare const REQUIRED_OPERATIONS: Readonly<Record<ConfigSection, readonly string[]>>;
|
|
23
|
+
/** Операции CI, которым нужны другие: лог читает состояние задания, перезапуск и отмена перечитывают прогон или задание. */
|
|
24
|
+
export declare const CI_OPERATION_NEEDS: Readonly<Record<string, readonly string[]>>;
|
|
25
|
+
/** Области значений входов: ключи таблиц `inputs` — только из них; вход без области таблицы не имеет (кроме null у assignee). */
|
|
26
|
+
export declare const INPUT_DOMAINS: Readonly<Record<ConfigSection, Readonly<Record<string, readonly string[]>>>>;
|
|
27
|
+
/** Входы-списки фильтров, у таблиц которых бывает ключ `*`: несколько разных значений сразу. */
|
|
28
|
+
export declare const WILDCARD_INPUTS: readonly ['status', 'event'];
|
|
29
|
+
/** Входы-словари: подставляются только целым значением тела (входы запуска CI). */
|
|
30
|
+
export declare const OBJECT_INPUTS: readonly ['inputs'];
|
|
31
|
+
/** Входы-времена (мс единой модели): в шаблон уходят строкой ISO 8601 UTC. */
|
|
32
|
+
export declare const TIME_INPUTS: readonly ["createdAfter", "createdBefore", "updatedAfter", "updatedBefore"];
|
|
33
|
+
/**
|
|
34
|
+
* Поля результата по моделям. Вложенные поля — через точку (`status.category`); url — первая ссылка links.
|
|
35
|
+
* У PR флаги merged и draft — не поля модели: merged (или время mergedAt) делает категорию merged, draft —
|
|
36
|
+
* draft у открытого PR, для API, где состояние — open/closed и отдельные флаги.
|
|
37
|
+
*/
|
|
38
|
+
export declare const RESULT_FIELDS: Readonly<Record<ResultModel, Readonly<Record<string, ResultField>>>>;
|
|
39
|
+
/** Поля результата, обязательные только у некоторых операций: задание само по себе должно знать свой прогон. */
|
|
40
|
+
export declare const OPERATION_REQUIRED_FIELDS: Readonly<Record<string, readonly string[]>>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { TrackerConfig, TrackerConfigOperation } from './declarative.schema.ts';
|
|
2
|
+
import type { TrackerConfigIssue } from './declarative.types.ts';
|
|
3
|
+
import type { TrackerFetch } from '../tracker.types.ts';
|
|
4
|
+
/** Раздел конфига: задачи, pull request-ы или CI. */
|
|
5
|
+
export type ConfigSection = 'issues' | 'pulls' | 'ci';
|
|
6
|
+
/** Модель результата операции: элемент единой модели, который собирает интерпретатор. */
|
|
7
|
+
export type ResultModel = 'issue' | 'comment' | 'pull' | 'run' | 'job' | 'workflow';
|
|
8
|
+
/** Вид значения поля единой модели в результате операции. */
|
|
9
|
+
export type ResultFieldType =
|
|
10
|
+
/** Идентификатор: строка или число ответа становится строкой. */
|
|
11
|
+
'id' | 'text'
|
|
12
|
+
/** Целое число от 0 (или от 1 при positive). */
|
|
13
|
+
| 'int' | 'flag'
|
|
14
|
+
/** Время ISO 8601 или число: меньше 10^11 — секунды Unix, иначе миллисекунды. */
|
|
15
|
+
| 'time'
|
|
16
|
+
/** Список строк: обычно путь с `[*]`. */
|
|
17
|
+
| 'list'
|
|
18
|
+
/** Адрес страницы http(s): становится первой ссылкой links. */
|
|
19
|
+
| 'link'
|
|
20
|
+
/** Значение из перечня единой модели, обычно через map. */
|
|
21
|
+
| 'enum'
|
|
22
|
+
/** Коммит: 7–64 hex, приводится к нижнему регистру. */
|
|
23
|
+
| 'sha';
|
|
24
|
+
export type ResultField = {
|
|
25
|
+
type: ResultFieldType;
|
|
26
|
+
/** Потолок длины строки (у list — каждого элемента): длиннее — обрезается. */
|
|
27
|
+
max?: number;
|
|
28
|
+
/** Потолок числа элементов list. */
|
|
29
|
+
count?: number;
|
|
30
|
+
values?: readonly string[];
|
|
31
|
+
/** Без этого поля элемент единой модели не собрать: правило конфига требует его в result. */
|
|
32
|
+
required?: boolean;
|
|
33
|
+
/** Пустая строка — значение (тело комментария), а не «нет поля». */
|
|
34
|
+
empty?: boolean;
|
|
35
|
+
positive?: boolean;
|
|
36
|
+
};
|
|
37
|
+
/** Что интерпретатор делает с ответом операции. */
|
|
38
|
+
export type OperationSpec = {
|
|
39
|
+
/** Входы операции — имена плейсхолдеров и таблиц значений. */
|
|
40
|
+
inputs: readonly string[];
|
|
41
|
+
/** Входы, без которых операция не имеет смысла: шаблоны обязаны их использовать. */
|
|
42
|
+
required: readonly string[];
|
|
43
|
+
/** Модель результата; нет — ответ — текст лога (log) или не читается (после неё элемент перечитывается). */
|
|
44
|
+
model?: ResultModel;
|
|
45
|
+
/** Ответ — список элементов со страницами. */
|
|
46
|
+
list?: boolean;
|
|
47
|
+
/** result: обязателен, по желанию (нет — элемент перечитывается) или запрещён. */
|
|
48
|
+
result: 'required' | 'optional' | 'forbidden';
|
|
49
|
+
/** Ответ — текст (лог задания CI). */
|
|
50
|
+
text?: boolean;
|
|
51
|
+
};
|
|
52
|
+
/** Значение входа операции: строка, число, флаг, список строк, словарь (входы запуска CI); null — «нет значения» API. */
|
|
53
|
+
export type InputValue = string | number | boolean | null | readonly string[] | Readonly<Record<string, string>> | undefined;
|
|
54
|
+
/** Входы вызова операции по именам. */
|
|
55
|
+
export type InputValues = Readonly<Record<string, InputValue>>;
|
|
56
|
+
/** Адрес API подключения: база без хвостовых «/», её origin и путь — все запросы остаются под ними. */
|
|
57
|
+
export type ConfigBase = {
|
|
58
|
+
base: string;
|
|
59
|
+
origin: string;
|
|
60
|
+
path: string;
|
|
61
|
+
};
|
|
62
|
+
/** Всё, что нужно запросам одного адаптера: конфиг, подключение, адрес базы, fetch и заголовки. */
|
|
63
|
+
export type ConfigContext = {
|
|
64
|
+
config: TrackerConfig;
|
|
65
|
+
connection: {
|
|
66
|
+
url?: string | undefined;
|
|
67
|
+
target?: string | undefined;
|
|
68
|
+
user?: string | undefined;
|
|
69
|
+
};
|
|
70
|
+
base: ConfigBase;
|
|
71
|
+
fetch: TrackerFetch;
|
|
72
|
+
/** Постоянные заголовки и авторизация, имена в нижнем регистре. */
|
|
73
|
+
headers: Record<string, string>;
|
|
74
|
+
};
|
|
75
|
+
/** Операция, которую вызывает адаптер: раздел и имя — для текстов ошибок, сама операция и её описание. */
|
|
76
|
+
export type ConfigCall = {
|
|
77
|
+
section: ConfigSection;
|
|
78
|
+
name: string;
|
|
79
|
+
operation: TrackerConfigOperation;
|
|
80
|
+
spec: OperationSpec;
|
|
81
|
+
};
|
|
82
|
+
/** Итог разбора входа: данные для схемы (нет — дальше проверять нечего) и ошибки; secret — среди ошибок секрет в тексте. */
|
|
83
|
+
export type ParsedInput = {
|
|
84
|
+
data?: unknown;
|
|
85
|
+
issues: TrackerConfigIssue[];
|
|
86
|
+
secret: boolean;
|
|
87
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TrackerConfigIssue } from './declarative.types.ts';
|
|
2
|
+
import type { ParsedInput } from './declarative-model.types.ts';
|
|
3
|
+
type Path = readonly (string | number)[];
|
|
4
|
+
export declare function issueAt(path: Path, message: string): TrackerConfigIssue;
|
|
5
|
+
/** Вход конфига: текст YAML (JSON — тоже YAML) или уже разобранный объект. */
|
|
6
|
+
export declare function parseConfigInput(input: unknown): ParsedInput;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PullRequestAdapter, PullRequestCapabilities } from '../pull.types.ts';
|
|
2
|
+
import type { AdapterContext } from '../tracker.types.ts';
|
|
3
|
+
import type { TrackerConfig } from './declarative.schema.ts';
|
|
4
|
+
export declare function createPullAdapter(config: TrackerConfig, adapterContext: AdapterContext, capabilities: PullRequestCapabilities): PullRequestAdapter;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { JsonRequest, JsonResponse, PageQuery, TextRequest, TextResponse } from '../tracker.types.ts';
|
|
2
|
+
import type { TrackerConfig, TrackerConfigPagination } from './declarative.schema.ts';
|
|
3
|
+
import type { TrackerConfigBodyValue } from './declarative.types.ts';
|
|
4
|
+
import type { ConfigBase, ConfigCall, ConfigContext, InputValues } from './declarative-model.types.ts';
|
|
5
|
+
/** Плейсхолдер шаблона: имя и модификатор (`path`). */
|
|
6
|
+
type Placeholder = {
|
|
7
|
+
name: string;
|
|
8
|
+
modifier: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
export declare function placeholdersOf(template: string): Placeholder[];
|
|
11
|
+
/** Шаблон — ровно один плейсхолдер без модификатора: в теле значение сохраняет тип (флаг, список, null, словарь). */
|
|
12
|
+
export declare function wholePlaceholder(template: string): string | undefined;
|
|
13
|
+
/** Шаблоны тела запроса (строки на любой глубине). */
|
|
14
|
+
export declare function bodyTemplates(value: TrackerConfigBodyValue | undefined): string[];
|
|
15
|
+
/** Имена всех плейсхолдеров операции: пути, query и тела. */
|
|
16
|
+
export declare function usedNames(operation: ConfigCall['operation'] | undefined): Set<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Адрес API подключения: http.base, где `{{url}}` в начале — url подключения без хвостовых «/». Правило конфига
|
|
19
|
+
* держит остальное литералом, начинающимся с «/»: url задаёт origin, конфиг — только путь под ним.
|
|
20
|
+
*/
|
|
21
|
+
export declare function baseOf(config: TrackerConfig, connection: {
|
|
22
|
+
url?: string | undefined;
|
|
23
|
+
}): ConfigBase;
|
|
24
|
+
/**
|
|
25
|
+
* Входы после таблиц значений операции: значение единой модели → значение API. Нет значения в таблице — отказ
|
|
26
|
+
* unsupported, а у фильтра списка с ключом `*` — значение `*` (лишнее отсеет проверка страницы). Список значений:
|
|
27
|
+
* одно после таблицы — оно, несколько — `*`, если он есть, иначе список. null — ключ таблицы `null`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function mapInputs(title: string, call: ConfigCall, inputs: InputValues): InputValues;
|
|
30
|
+
/** Заголовки подключения: постоянные из http.headers (имена в нижнем регистре) и авторизация токеном. */
|
|
31
|
+
export declare function headersOf(config: TrackerConfig, connection: ConfigContext['connection'] & {
|
|
32
|
+
token?: string | undefined;
|
|
33
|
+
}): Record<string, string>;
|
|
34
|
+
/** Одна операция с ответом JSON. */
|
|
35
|
+
export declare function callJson(context: ConfigContext, call: ConfigCall, inputs: InputValues, options?: Pick<JsonRequest, 'missing' | 'missingIsIssue' | 'conflictOn'> & {
|
|
36
|
+
params?: readonly (readonly [string, string])[];
|
|
37
|
+
}): Promise<JsonResponse>;
|
|
38
|
+
/** Одна операция с текстовым ответом (лог): accept — текстовый, а не постоянный заголовок конфига. */
|
|
39
|
+
export declare function callText(context: ConfigContext, call: ConfigCall, inputs: InputValues, options: Pick<TextRequest, 'skip' | 'keep' | 'missing'>): Promise<TextResponse>;
|
|
40
|
+
/** Постраничность операции: своя или http.pagination. */
|
|
41
|
+
export declare function paginationOf(context: ConfigContext, call: ConfigCall): TrackerConfigPagination;
|
|
42
|
+
/** Параметры страницы и номер (у style: page). Курсор не того вида — invalid_request. */
|
|
43
|
+
export declare function pageParams(title: string, pagination: TrackerConfigPagination, page: PageQuery): {
|
|
44
|
+
params: [string, string][];
|
|
45
|
+
number: number;
|
|
46
|
+
};
|
|
47
|
+
/** Курсор следующей страницы по ответу; нет — undefined. count — сколько элементов пришло (до проверки страницы). */
|
|
48
|
+
export declare function nextCursorOf(pagination: TrackerConfigPagination, page: PageQuery, number: number, count: number, response: JsonResponse): string | undefined;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TrackerError } from '../tracker.lib.ts';
|
|
2
|
+
import type { ConfigCall } from './declarative-model.types.ts';
|
|
3
|
+
/** Значение по пути JSON; путь с `[*]` даёт список найденного (без null), без него — одно значение или undefined. */
|
|
4
|
+
export declare function readPath(path: string, value: unknown): unknown;
|
|
5
|
+
/** Ошибка разбора ответа: failed с операцией и полем; текст без секретов. */
|
|
6
|
+
export declare function answerFailed(title: string, call: ConfigCall, detail: string): TrackerError;
|
|
7
|
+
/**
|
|
8
|
+
* Элемент ответа → объект единой модели по result операции, проверенный схемой модели. defaults — поля, которые
|
|
9
|
+
* знает вызов, а не ответ (runKey задания из списка заданий прогона).
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildItem(title: string, call: ConfigCall, element: unknown, defaults?: Readonly<Record<string, unknown>>): unknown;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TrackerConfig } from './declarative.schema.ts';
|
|
2
|
+
import type { TrackerConfigIssue } from './declarative.types.ts';
|
|
3
|
+
/** Правила конфига, которых не выражает схема; пусто — конфиг годен. */
|
|
4
|
+
export declare function configIssues(config: TrackerConfig): TrackerConfigIssue[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Предел размера конфига, байт: текста YAML в UTF-8 или JSON уже разобранного объекта. */
|
|
2
|
+
export declare const TRACKER_CONFIG_MAX_BYTES: number;
|
|
3
|
+
/** Сколько ошибок конфига отдаёт проверка: остальные отсекаются. */
|
|
4
|
+
export declare const TRACKER_CONFIG_ISSUES_MAX = 100;
|
|
5
|
+
/** Предел ссылок YAML на якоря: повтор блока допустим, «бомба» из вложенных ссылок — нет. */
|
|
6
|
+
export declare const TRACKER_CONFIG_YAML_ALIAS_MAX = 100;
|
|
7
|
+
/** Предел вложенности объектов и списков конфига. */
|
|
8
|
+
export declare const TRACKER_CONFIG_DEPTH_MAX = 16;
|
|
9
|
+
/** Виды встроенных трекеров библиотеки: конфиг их не занимает. */
|
|
10
|
+
export declare const BUILTIN_TRACKER_KINDS: readonly ['local', 'sourcecraft', 'github', 'gitlab', 'jira'];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TrackerConfigCheck, TrackerConfigIssue } from './declarative.types.ts';
|
|
2
|
+
import type { TrackerDefinition } from '../tracker.types.ts';
|
|
3
|
+
/** Конфиг не прошёл проверку: issues — ошибки с путями (не больше TRACKER_CONFIG_ISSUES_MAX). */
|
|
4
|
+
export declare class TrackerConfigError extends Error {
|
|
5
|
+
readonly issues: readonly TrackerConfigIssue[];
|
|
6
|
+
readonly secret: boolean;
|
|
7
|
+
constructor(issues: readonly TrackerConfigIssue[], secret: boolean);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Проверка конфига без побочных эффектов: размер, YAML, секреты в тексте, схема и правила. Все ошибки сразу —
|
|
11
|
+
* каждая с путём поля; secret — среди них секрет в тексте (такой конфиг не сохраняют, токен вводят в подключении).
|
|
12
|
+
*/
|
|
13
|
+
export declare function validateTrackerConfig(input: unknown): TrackerConfigCheck;
|
|
14
|
+
/**
|
|
15
|
+
* Определение трекера из конфига: descriptor с source 'user', возможности, выведенные из операций, разделы pulls
|
|
16
|
+
* и ci, если они описаны, и origin(connection) — origin http.base. Неверный конфиг — TrackerConfigError.
|
|
17
|
+
* Каждый ответ API проходит схему единой модели; запросы идут через requestJson/requestText с origin базы.
|
|
18
|
+
*/
|
|
19
|
+
export declare function definitionFromConfig(input: unknown): TrackerDefinition;
|