From 8db2ab9777f3d65be80f1143d52b0e048f2cb3d1 Mon Sep 17 00:00:00 2001 From: dawn Date: Sun, 30 Aug 2026 10:07:36 +0900 Subject: [PATCH] lexicons,api,web: add repo blame schema and bindings Signed-off-by: dawn --- api/tangled/repoblame.go | 69 ++++++++ lexicons/repo/blame.json | 156 ++++++++++++++++++ web/src/lib/api/lexicons/index.ts | 1 + .../lexicons/types/sh/tangled/repo/blame.ts | 113 +++++++++++++ 4 files changed, 339 insertions(+) create mode 100644 api/tangled/repoblame.go create mode 100644 lexicons/repo/blame.json create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/blame.ts diff --git a/api/tangled/repoblame.go b/api/tangled/repoblame.go new file mode 100644 index 000000000..669e2a590 --- /dev/null +++ b/api/tangled/repoblame.go @@ -0,0 +1,69 @@ +// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT. + +package tangled + +// schema: sh.tangled.repo.blame + +import ( + "context" + + "github.com/bluesky-social/indigo/lex/util" +) + +const ( + RepoBlameNSID = "sh.tangled.repo.blame" +) + +// RepoBlame_Author is a "author" in the sh.tangled.repo.blame schema. +type RepoBlame_Author struct { + Email string `json:"email" cborgen:"email"` + Name string `json:"name" cborgen:"name"` +} + +// RepoBlame_Commit is a "commit" in the sh.tangled.repo.blame schema. +type RepoBlame_Commit struct { + Author *RepoBlame_Author `json:"author" cborgen:"author"` + // authoredAt: Git author timestamp + AuthoredAt string `json:"authoredAt" cborgen:"authoredAt"` + Sha string `json:"sha" cborgen:"sha"` + Subject string `json:"subject" cborgen:"subject"` +} + +// RepoBlame_Output is the output of a sh.tangled.repo.blame call. +type RepoBlame_Output struct { + // commit: The resolved git commit object ID + Commit string `json:"commit" cborgen:"commit"` + // commits: Unique commits referenced by blame runs + Commits []*RepoBlame_Commit `json:"commits" cborgen:"commits"` + // runs: Complete, gap-free one-based line ranges sorted by start + Runs []*RepoBlame_Run `json:"runs" cborgen:"runs"` +} + +// RepoBlame_Run is a "run" in the sh.tangled.repo.blame schema. +type RepoBlame_Run struct { + // commit: SHA of the commit in the output commits array + Commit string `json:"commit" cborgen:"commit"` + // count: Number of consecutive lines in this run + Count int64 `json:"count" cborgen:"count"` + // start: First one-based line in this run + Start int64 `json:"start" cborgen:"start"` +} + +// RepoBlame calls the XRPC method "sh.tangled.repo.blame". +// +// path: Path to the file within the repository +// ref: Git reference (branch, tag, or commit SHA) +// repo: AT-URI of the sh.tangled.repo record +func RepoBlame(ctx context.Context, c util.LexClient, path string, ref string, repo string) (*RepoBlame_Output, error) { + var out RepoBlame_Output + + params := map[string]interface{}{} + params["path"] = path + params["ref"] = ref + params["repo"] = repo + if err := c.LexDo(ctx, util.Query, "", "sh.tangled.repo.blame", params, nil, &out); err != nil { + return nil, err + } + + return &out, nil +} diff --git a/lexicons/repo/blame.json b/lexicons/repo/blame.json new file mode 100644 index 000000000..5f7066dbb --- /dev/null +++ b/lexicons/repo/blame.json @@ -0,0 +1,156 @@ +{ + "lexicon": 1, + "id": "sh.tangled.repo.blame", + "defs": { + "main": { + "type": "query", + "parameters": { + "type": "params", + "required": [ + "repo", + "ref", + "path" + ], + "properties": { + "repo": { + "type": "string", + "format": "at-uri", + "description": "AT-URI of the sh.tangled.repo record" + }, + "ref": { + "type": "string", + "description": "Git reference (branch, tag, or commit SHA)" + }, + "path": { + "type": "string", + "description": "Path to the file within the repository" + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": [ + "commit", + "commits", + "runs" + ], + "properties": { + "commit": { + "type": "string", + "description": "The resolved git commit object ID" + }, + "commits": { + "type": "array", + "description": "Unique commits referenced by blame runs", + "items": { + "type": "ref", + "ref": "#commit" + } + }, + "runs": { + "type": "array", + "description": "Complete, gap-free one-based line ranges sorted by start", + "items": { + "type": "ref", + "ref": "#run" + } + } + } + } + }, + "errors": [ + { + "name": "RepoNotFound", + "description": "Repository not found or access denied" + }, + { + "name": "RefNotFound", + "description": "Git reference not found" + }, + { + "name": "FileNotFound", + "description": "File not found at the specified path" + }, + { + "name": "BlameTooLarge", + "description": "Blame exceeds file byte, line, or run limits" + }, + { + "name": "BlameTimeout", + "description": "Blame exceeded its computation time budget" + }, + { + "name": "InvalidRequest", + "description": "Invalid request parameters" + } + ] + }, + "run": { + "type": "object", + "required": [ + "start", + "count", + "commit" + ], + "properties": { + "start": { + "type": "integer", + "minimum": 1, + "description": "First one-based line in this run" + }, + "count": { + "type": "integer", + "minimum": 1, + "description": "Number of consecutive lines in this run" + }, + "commit": { + "type": "string", + "description": "SHA of the commit in the output commits array" + } + } + }, + "commit": { + "type": "object", + "required": [ + "sha", + "subject", + "authoredAt", + "author" + ], + "properties": { + "sha": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "author": { + "type": "ref", + "ref": "#author" + }, + "authoredAt": { + "type": "string", + "format": "datetime", + "description": "Git author timestamp" + } + } + }, + "author": { + "type": "object", + "required": [ + "name", + "email" + ], + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } +} diff --git a/web/src/lib/api/lexicons/index.ts b/web/src/lib/api/lexicons/index.ts index c00b6b3a2..a0349c6e6 100644 --- a/web/src/lib/api/lexicons/index.ts +++ b/web/src/lib/api/lexicons/index.ts @@ -172,6 +172,7 @@ export * as ShTangledRepoAddCollaborator from "./types/sh/tangled/repo/addCollab export * as ShTangledRepoAddSecret from "./types/sh/tangled/repo/addSecret.js"; export * as ShTangledRepoArchive from "./types/sh/tangled/repo/archive.js"; export * as ShTangledRepoArtifact from "./types/sh/tangled/repo/artifact.js"; +export * as ShTangledRepoBlame from "./types/sh/tangled/repo/blame.js"; export * as ShTangledRepoBlob from "./types/sh/tangled/repo/blob.js"; export * as ShTangledRepoBranch from "./types/sh/tangled/repo/branch.js"; export * as ShTangledRepoBranches from "./types/sh/tangled/repo/branches.js"; diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/blame.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/blame.ts new file mode 100644 index 000000000..f06dc3f2c --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/blame.ts @@ -0,0 +1,113 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _authorSchema = /*#__PURE__*/ v.object({ + $type: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.literal("sh.tangled.repo.blame#author"), + ), + email: /*#__PURE__*/ v.string(), + name: /*#__PURE__*/ v.string(), +}); +const _commitSchema = /*#__PURE__*/ v.object({ + $type: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.literal("sh.tangled.repo.blame#commit"), + ), + get author() { + return authorSchema; + }, + /** + * Git author timestamp + */ + authoredAt: /*#__PURE__*/ v.datetimeString(), + sha: /*#__PURE__*/ v.string(), + subject: /*#__PURE__*/ v.string(), +}); +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.blame", { + params: /*#__PURE__*/ v.object({ + /** + * Path to the file within the repository + */ + path: /*#__PURE__*/ v.string(), + /** + * Git reference (branch, tag, or commit SHA) + */ + ref: /*#__PURE__*/ v.string(), + /** + * AT-URI of the sh.tangled.repo record + */ + repo: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * The resolved git commit object ID + */ + commit: /*#__PURE__*/ v.string(), + /** + * Unique commits referenced by blame runs + */ + get commits() { + return /*#__PURE__*/ v.array(commitSchema); + }, + /** + * Complete, gap-free one-based line ranges sorted by start + */ + get runs() { + return /*#__PURE__*/ v.array(runSchema); + }, + }), + }, +}); +const _runSchema = /*#__PURE__*/ v.object({ + $type: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.literal("sh.tangled.repo.blame#run"), + ), + /** + * SHA of the commit in the output commits array + */ + commit: /*#__PURE__*/ v.string(), + /** + * Number of consecutive lines in this run + * @minimum 1 + */ + count: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ + /*#__PURE__*/ v.integerRange(1), + ]), + /** + * First one-based line in this run + * @minimum 1 + */ + start: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ + /*#__PURE__*/ v.integerRange(1), + ]), +}); + +type author$schematype = typeof _authorSchema; +type commit$schematype = typeof _commitSchema; +type main$schematype = typeof _mainSchema; +type run$schematype = typeof _runSchema; + +export interface authorSchema extends author$schematype {} +export interface commitSchema extends commit$schematype {} +export interface mainSchema extends main$schematype {} +export interface runSchema extends run$schematype {} + +export const authorSchema = _authorSchema as authorSchema; +export const commitSchema = _commitSchema as commitSchema; +export const mainSchema = _mainSchema as mainSchema; +export const runSchema = _runSchema as runSchema; + +export interface Author extends v.InferInput {} +export interface Commit extends v.InferInput {} +export interface Run extends v.InferInput {} + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.blame": mainSchema; + } +} -- 2.51.2