From fbc7adbb68f56315b850d302c0c65b4cbe14b5c8 Mon Sep 17 00:00:00 2001 From: dawn Date: Fri, 24 Jul 2026 23:02:35 +0300 Subject: [PATCH] web: add the repo index page Signed-off-by: dawn --- web/.storybook/StoryAuthProvider.svelte | 22 + web/eslint.config.js | 2 +- web/lex.config.ts | 2 + web/src/lib/api/count.ts | 10 +- web/src/lib/api/graph.ts | 19 + web/src/lib/api/index.ts | 1 + web/src/lib/api/lexicons/index.ts | 54 ++ .../types/sh/tangled/actor/getProfile.ts | 38 + .../types/sh/tangled/actor/getProfiles.ts | 56 ++ .../types/sh/tangled/ci/queryPipelines.ts | 8 + .../types/sh/tangled/feed/countComments.ts | 42 ++ .../types/sh/tangled/feed/countCommentsBy.ts | 42 ++ .../types/sh/tangled/feed/countReactions.ts | 42 ++ .../types/sh/tangled/feed/countReactionsBy.ts | 42 ++ .../types/sh/tangled/feed/countStars.ts | 42 ++ .../types/sh/tangled/feed/countStarsBy.ts | 42 ++ .../types/sh/tangled/feed/listComments.ts | 2 +- .../types/sh/tangled/git/countRefUpdates.ts | 42 ++ .../types/sh/tangled/git/countRefUpdatesBy.ts | 42 ++ .../types/sh/tangled/graph/countFollows.ts | 42 ++ .../types/sh/tangled/graph/countFollowsBy.ts | 42 ++ .../types/sh/tangled/graph/countVouches.ts | 42 ++ .../types/sh/tangled/graph/countVouchesBy.ts | 42 ++ .../types/sh/tangled/knot/countKnots.ts | 42 ++ .../types/sh/tangled/knot/countMembers.ts | 42 ++ .../types/sh/tangled/knot/countMembersBy.ts | 42 ++ .../sh/tangled/label/countDefinitions.ts | 42 ++ .../types/sh/tangled/label/countOps.ts | 42 ++ .../types/sh/tangled/label/countOpsBy.ts | 42 ++ .../sh/tangled/pipeline/countPipelines.ts | 45 ++ .../sh/tangled/pipeline/countPipelinesBy.ts | 45 ++ .../sh/tangled/pipeline/countStatuses.ts | 42 ++ .../sh/tangled/pipeline/countStatusesBy.ts | 45 ++ .../types/sh/tangled/publicKey/countKeys.ts | 42 ++ .../sh/tangled/publicKey/getPublicKey.ts | 38 + .../types/sh/tangled/repo/countArtifacts.ts | 42 ++ .../types/sh/tangled/repo/countArtifactsBy.ts | 42 ++ .../sh/tangled/repo/countCollaborators.ts | 45 ++ .../sh/tangled/repo/countCollaboratorsBy.ts | 45 ++ .../types/sh/tangled/repo/countForks.ts | 42 ++ .../types/sh/tangled/repo/countIssues.ts | 52 ++ .../types/sh/tangled/repo/countIssuesBy.ts | 42 ++ .../types/sh/tangled/repo/countPulls.ts | 52 ++ .../types/sh/tangled/repo/countPullsBy.ts | 42 ++ .../types/sh/tangled/repo/countRepos.ts | 42 ++ .../types/sh/tangled/repo/forkSync.ts | 4 + .../types/sh/tangled/repo/getIssue.ts | 38 + .../types/sh/tangled/repo/getIssues.ts | 56 ++ .../lexicons/types/sh/tangled/repo/getPull.ts | 38 + .../types/sh/tangled/repo/getPulls.ts | 56 ++ .../lexicons/types/sh/tangled/repo/getRepo.ts | 38 + .../types/sh/tangled/repo/getRepoByName.ts | 42 ++ .../types/sh/tangled/repo/getRepoByRepoDid.ts | 38 + .../types/sh/tangled/repo/getRepos.ts | 56 ++ .../sh/tangled/repo/issue/countStates.ts | 42 ++ .../sh/tangled/repo/issue/countStatesBy.ts | 45 ++ .../lexicons/types/sh/tangled/repo/merge.ts | 4 + .../types/sh/tangled/repo/mergeCheck.ts | 4 + .../sh/tangled/repo/pull/countStatuses.ts | 45 ++ .../sh/tangled/repo/pull/countStatusesBy.ts | 45 ++ .../lexicons/types/sh/tangled/search/query.ts | 98 +++ .../types/sh/tangled/spindle/countMembers.ts | 42 ++ .../sh/tangled/spindle/countMembersBy.ts | 42 ++ .../types/sh/tangled/spindle/countSpindles.ts | 42 ++ .../types/sh/tangled/string/countStrings.ts | 42 ++ .../types/sh/tangled/string/getString.ts | 38 + web/src/lib/api/records.ts | 7 + web/src/lib/api/repo.test.ts | 207 ++++++ web/src/lib/api/repo.ts | 232 ++++++ web/src/lib/api/repoIndex.test.ts | 34 + web/src/lib/api/repoIndex.ts | 249 +++++++ .../components/repo/BranchList.stories.svelte | 39 + web/src/lib/components/repo/BranchList.svelte | 57 ++ .../repo/CloneDropdown.stories.svelte | 51 ++ .../lib/components/repo/CloneDropdown.svelte | 128 ++++ .../components/repo/CommitList.stories.svelte | 57 ++ web/src/lib/components/repo/CommitList.svelte | 69 ++ .../components/repo/EmptyRepo.stories.svelte | 36 + web/src/lib/components/repo/EmptyRepo.svelte | 56 ++ web/src/lib/components/repo/FileTree.svelte | 70 ++ .../repo/LanguageBar.stories.svelte | 40 ++ .../lib/components/repo/LanguageBar.svelte | 44 ++ .../repo/PanelHeader.stories.svelte | 16 + .../lib/components/repo/PanelHeader.svelte | 29 + web/src/lib/components/repo/Readme.svelte | 22 + .../repo/RefSelector.stories.svelte | 22 + .../lib/components/repo/RefSelector.svelte | 56 ++ .../components/repo/RepoHeader.stories.svelte | 47 ++ web/src/lib/components/repo/RepoHeader.svelte | 130 ++++ .../repo/RepoIndexView.stories.svelte | 99 +++ .../lib/components/repo/RepoIndexView.svelte | 140 ++++ .../components/repo/RepoTabs.stories.svelte | 31 + web/src/lib/components/repo/RepoTabs.svelte | 39 + .../components/repo/TagList.stories.svelte | 31 + web/src/lib/components/repo/TagList.svelte | 39 + .../lib/components/repo/language-colors.ts | 672 ++++++++++++++++++ web/src/lib/components/repo/types.ts | 42 ++ web/src/lib/components/ui/Checkbox.svelte | 10 +- web/src/lib/components/ui/Dropdown.svelte | 130 ++-- .../lib/components/ui/TimeAgo.stories.svelte | 25 + web/src/lib/components/ui/TimeAgo.svelte | 18 + web/src/routes/[handle]/[repo]/+layout.ts | 116 +++ .../routes/[handle]/[repo]/+layout@.svelte | 43 ++ web/src/routes/[handle]/[repo]/+page.svelte | 163 +++++ web/src/routes/[handle]/[repo]/+page.ts | 96 +++ 105 files changed, 5853 insertions(+), 67 deletions(-) create mode 100644 web/.storybook/StoryAuthProvider.svelte create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/actor/getProfile.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/actor/getProfiles.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/feed/countComments.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/feed/countCommentsBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/feed/countReactions.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/feed/countReactionsBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/feed/countStars.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/feed/countStarsBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/git/countRefUpdates.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/git/countRefUpdatesBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/graph/countFollows.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/graph/countFollowsBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/graph/countVouches.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/graph/countVouchesBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/knot/countKnots.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/knot/countMembers.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/knot/countMembersBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/label/countDefinitions.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/label/countOps.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/label/countOpsBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/pipeline/countPipelines.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/pipeline/countPipelinesBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/pipeline/countStatuses.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/pipeline/countStatusesBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/publicKey/countKeys.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/publicKey/getPublicKey.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/countArtifacts.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/countArtifactsBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/countCollaborators.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/countCollaboratorsBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/countForks.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/countIssues.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/countIssuesBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/countPulls.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/countPullsBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/countRepos.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/getIssue.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/getIssues.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/getPull.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/getPulls.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/getRepo.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/getRepoByName.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/getRepoByRepoDid.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/getRepos.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/issue/countStates.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/issue/countStatesBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/pull/countStatuses.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/repo/pull/countStatusesBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/search/query.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/spindle/countMembers.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/spindle/countMembersBy.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/spindle/countSpindles.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/string/countStrings.ts create mode 100644 web/src/lib/api/lexicons/types/sh/tangled/string/getString.ts create mode 100644 web/src/lib/api/repo.test.ts create mode 100644 web/src/lib/api/repo.ts create mode 100644 web/src/lib/api/repoIndex.test.ts create mode 100644 web/src/lib/api/repoIndex.ts create mode 100644 web/src/lib/components/repo/BranchList.stories.svelte create mode 100644 web/src/lib/components/repo/BranchList.svelte create mode 100644 web/src/lib/components/repo/CloneDropdown.stories.svelte create mode 100644 web/src/lib/components/repo/CloneDropdown.svelte create mode 100644 web/src/lib/components/repo/CommitList.stories.svelte create mode 100644 web/src/lib/components/repo/CommitList.svelte create mode 100644 web/src/lib/components/repo/EmptyRepo.stories.svelte create mode 100644 web/src/lib/components/repo/EmptyRepo.svelte create mode 100644 web/src/lib/components/repo/FileTree.svelte create mode 100644 web/src/lib/components/repo/LanguageBar.stories.svelte create mode 100644 web/src/lib/components/repo/LanguageBar.svelte create mode 100644 web/src/lib/components/repo/PanelHeader.stories.svelte create mode 100644 web/src/lib/components/repo/PanelHeader.svelte create mode 100644 web/src/lib/components/repo/Readme.svelte create mode 100644 web/src/lib/components/repo/RefSelector.stories.svelte create mode 100644 web/src/lib/components/repo/RefSelector.svelte create mode 100644 web/src/lib/components/repo/RepoHeader.stories.svelte create mode 100644 web/src/lib/components/repo/RepoHeader.svelte create mode 100644 web/src/lib/components/repo/RepoIndexView.stories.svelte create mode 100644 web/src/lib/components/repo/RepoIndexView.svelte create mode 100644 web/src/lib/components/repo/RepoTabs.stories.svelte create mode 100644 web/src/lib/components/repo/RepoTabs.svelte create mode 100644 web/src/lib/components/repo/TagList.stories.svelte create mode 100644 web/src/lib/components/repo/TagList.svelte create mode 100644 web/src/lib/components/repo/language-colors.ts create mode 100644 web/src/lib/components/repo/types.ts create mode 100644 web/src/lib/components/ui/TimeAgo.stories.svelte create mode 100644 web/src/lib/components/ui/TimeAgo.svelte create mode 100644 web/src/routes/[handle]/[repo]/+layout.ts create mode 100644 web/src/routes/[handle]/[repo]/+layout@.svelte create mode 100644 web/src/routes/[handle]/[repo]/+page.svelte create mode 100644 web/src/routes/[handle]/[repo]/+page.ts diff --git a/web/.storybook/StoryAuthProvider.svelte b/web/.storybook/StoryAuthProvider.svelte new file mode 100644 index 00000000..a7e81b24 --- /dev/null +++ b/web/.storybook/StoryAuthProvider.svelte @@ -0,0 +1,22 @@ + + +{@render children()} diff --git a/web/eslint.config.js b/web/eslint.config.js index 24f2ce15..721622da 100644 --- a/web/eslint.config.js +++ b/web/eslint.config.js @@ -29,7 +29,7 @@ export default defineConfig( files: ["**/*.svelte", "**/*.svelte.ts", "**/*.svelte.js"], languageOptions: { parserOptions: { - projectService: true, + projectService: { allowDefaultProject: [".storybook/StoryAuthProvider.svelte"] }, extraFileExtensions: [".svelte"], parser: ts.parser } diff --git a/web/lex.config.ts b/web/lex.config.ts index 2ef052c9..68057e7d 100644 --- a/web/lex.config.ts +++ b/web/lex.config.ts @@ -19,9 +19,11 @@ export default defineLexiconConfig({ "../lexicons/label/**/*.json", "../lexicons/markup/**/*.json", "../lexicons/pipeline/**/*.json", + "../lexicons/publicKey/**/*.json", "../lexicons/pulls/**/*.json", "../lexicons/query/**/*.json", "../lexicons/repo/**/*.json", + "../lexicons/search/**/*.json", "../lexicons/spindle/**/*.json", "../lexicons/string/**/*.json", "../lexicons/sync/**/*.json", diff --git a/web/src/lib/api/count.ts b/web/src/lib/api/count.ts index 401b5ad5..a862b924 100644 --- a/web/src/lib/api/count.ts +++ b/web/src/lib/api/count.ts @@ -30,6 +30,7 @@ export type CountName = | "sh.tangled.repo.countArtifactsBy" | "sh.tangled.repo.countCollaborators" | "sh.tangled.repo.countCollaboratorsBy" + | "sh.tangled.repo.countForks" | "sh.tangled.repo.countIssues" | "sh.tangled.repo.countIssuesBy" | "sh.tangled.repo.countPulls" @@ -49,9 +50,16 @@ export interface CountResult { distinctAuthors: number; } +export interface CountFilter { + author?: string; + state?: "open" | "closed"; + status?: "open" | "closed" | "merged"; +} + export const count = ( ctx: BobbinContext, name: CountName, subject: string, + filter: CountFilter = {}, init?: XrpcRequestInit -): Promise => jsonGet(ctx, name, { subject }, init); +): Promise => jsonGet(ctx, name, { subject, ...filter }, init); diff --git a/web/src/lib/api/graph.ts b/web/src/lib/api/graph.ts index 75e3e2c9..48116cdb 100644 --- a/web/src/lib/api/graph.ts +++ b/web/src/lib/api/graph.ts @@ -8,6 +8,7 @@ import { ClientResponseError, type BobbinContext } from "./client"; import { jsonGet } from "./_request"; import { httpStatusFor } from "./load"; import { rkeyFromUri } from "./uri"; +import type * as ShTangledFeedGetStar from "./lexicons/types/sh/tangled/feed/getStar"; import type * as ShTangledGraphFollow from "./lexicons/types/sh/tangled/graph/follow"; import type * as ShTangledGraphGetFollow from "./lexicons/types/sh/tangled/graph/getFollow"; import type * as ShTangledGraphVouch from "./lexicons/types/sh/tangled/graph/vouch"; @@ -37,6 +38,24 @@ export const getFollowRkey = async ( } }; +// 404 means no star exists, other errors propagate +export const getStarRkey = async ( + ctx: BobbinContext, + actor: string, + subject: string +): Promise => { + try { + const { uri } = await jsonGet(ctx, "sh.tangled.feed.getStar", { + actor: actor as Did, + subject + } satisfies ShTangledFeedGetStar.$params); + return rkeyFromUri(uri); + } catch (cause) { + if (cause instanceof ClientResponseError && httpStatusFor(cause) === 404) return null; + throw cause; + } +}; + const createGenericRecord = async ( agent: OAuthUserAgent, collection: Nsid, diff --git a/web/src/lib/api/index.ts b/web/src/lib/api/index.ts index 9e6eb371..ef778d15 100644 --- a/web/src/lib/api/index.ts +++ b/web/src/lib/api/index.ts @@ -9,3 +9,4 @@ export * from "./identity"; export * from "./load"; export * from "./uri"; export * from "./graph"; +export * from "./repo"; diff --git a/web/src/lib/api/lexicons/index.ts b/web/src/lib/api/lexicons/index.ts index bea826a2..4814a9e1 100644 --- a/web/src/lib/api/lexicons/index.ts +++ b/web/src/lib/api/lexicons/index.ts @@ -1,3 +1,5 @@ +export * as ShTangledActorGetProfile from "./types/sh/tangled/actor/getProfile.js"; +export * as ShTangledActorGetProfiles from "./types/sh/tangled/actor/getProfiles.js"; export * as ShTangledActorProfile from "./types/sh/tangled/actor/profile.js"; export * as ShTangledCiCancelPipeline from "./types/sh/tangled/ci/cancelPipeline.js"; export * as ShTangledCiGetPipeline from "./types/sh/tangled/ci/getPipeline.js"; @@ -7,6 +9,12 @@ export * as ShTangledCiSubscribePipelineLogs from "./types/sh/tangled/ci/subscri export * as ShTangledCiTrigger from "./types/sh/tangled/ci/trigger.js"; export * as ShTangledCiTriggerPipeline from "./types/sh/tangled/ci/triggerPipeline.js"; export * as ShTangledFeedComment from "./types/sh/tangled/feed/comment.js"; +export * as ShTangledFeedCountComments from "./types/sh/tangled/feed/countComments.js"; +export * as ShTangledFeedCountCommentsBy from "./types/sh/tangled/feed/countCommentsBy.js"; +export * as ShTangledFeedCountReactions from "./types/sh/tangled/feed/countReactions.js"; +export * as ShTangledFeedCountReactionsBy from "./types/sh/tangled/feed/countReactionsBy.js"; +export * as ShTangledFeedCountStars from "./types/sh/tangled/feed/countStars.js"; +export * as ShTangledFeedCountStarsBy from "./types/sh/tangled/feed/countStarsBy.js"; export * as ShTangledFeedGetStar from "./types/sh/tangled/feed/getStar.js"; export * as ShTangledFeedListComments from "./types/sh/tangled/feed/listComments.js"; export * as ShTangledFeedListCommentsBy from "./types/sh/tangled/feed/listCommentsBy.js"; @@ -16,6 +24,8 @@ export * as ShTangledFeedListStars from "./types/sh/tangled/feed/listStars.js"; export * as ShTangledFeedListStarsBy from "./types/sh/tangled/feed/listStarsBy.js"; export * as ShTangledFeedReaction from "./types/sh/tangled/feed/reaction.js"; export * as ShTangledFeedStar from "./types/sh/tangled/feed/star.js"; +export * as ShTangledGitCountRefUpdates from "./types/sh/tangled/git/countRefUpdates.js"; +export * as ShTangledGitCountRefUpdatesBy from "./types/sh/tangled/git/countRefUpdatesBy.js"; export * as ShTangledGitListRefUpdates from "./types/sh/tangled/git/listRefUpdates.js"; export * as ShTangledGitListRefUpdatesBy from "./types/sh/tangled/git/listRefUpdatesBy.js"; export * as ShTangledGitListRefs from "./types/sh/tangled/git/listRefs.js"; @@ -35,6 +45,10 @@ export * as ShTangledGitTempListBranches from "./types/sh/tangled/git/temp/listB export * as ShTangledGitTempListCommits from "./types/sh/tangled/git/temp/listCommits.js"; export * as ShTangledGitTempListLanguages from "./types/sh/tangled/git/temp/listLanguages.js"; export * as ShTangledGitTempListTags from "./types/sh/tangled/git/temp/listTags.js"; +export * as ShTangledGraphCountFollows from "./types/sh/tangled/graph/countFollows.js"; +export * as ShTangledGraphCountFollowsBy from "./types/sh/tangled/graph/countFollowsBy.js"; +export * as ShTangledGraphCountVouches from "./types/sh/tangled/graph/countVouches.js"; +export * as ShTangledGraphCountVouchesBy from "./types/sh/tangled/graph/countVouchesBy.js"; export * as ShTangledGraphFollow from "./types/sh/tangled/graph/follow.js"; export * as ShTangledGraphGetFollow from "./types/sh/tangled/graph/getFollow.js"; export * as ShTangledGraphListFollows from "./types/sh/tangled/graph/listFollows.js"; @@ -44,6 +58,9 @@ export * as ShTangledGraphListVouchesBy from "./types/sh/tangled/graph/listVouch export * as ShTangledGraphVouch from "./types/sh/tangled/graph/vouch.js"; export * as ShTangledKnot from "./types/sh/tangled/knot.js"; export * as ShTangledKnotAddMember from "./types/sh/tangled/knot/addMember.js"; +export * as ShTangledKnotCountKnots from "./types/sh/tangled/knot/countKnots.js"; +export * as ShTangledKnotCountMembers from "./types/sh/tangled/knot/countMembers.js"; +export * as ShTangledKnotCountMembersBy from "./types/sh/tangled/knot/countMembersBy.js"; export * as ShTangledKnotListKeys from "./types/sh/tangled/knot/listKeys.js"; export * as ShTangledKnotListKnots from "./types/sh/tangled/knot/listKnots.js"; export * as ShTangledKnotListMembers from "./types/sh/tangled/knot/listMembers.js"; @@ -52,6 +69,9 @@ export * as ShTangledKnotMember from "./types/sh/tangled/knot/member.js"; export * as ShTangledKnotRemoveMember from "./types/sh/tangled/knot/removeMember.js"; export * as ShTangledKnotSubscribeRepos from "./types/sh/tangled/knot/subscribeRepos.js"; export * as ShTangledKnotVersion from "./types/sh/tangled/knot/version.js"; +export * as ShTangledLabelCountDefinitions from "./types/sh/tangled/label/countDefinitions.js"; +export * as ShTangledLabelCountOps from "./types/sh/tangled/label/countOps.js"; +export * as ShTangledLabelCountOpsBy from "./types/sh/tangled/label/countOpsBy.js"; export * as ShTangledLabelDefinition from "./types/sh/tangled/label/definition.js"; export * as ShTangledLabelListDefinitions from "./types/sh/tangled/label/listDefinitions.js"; export * as ShTangledLabelListOps from "./types/sh/tangled/label/listOps.js"; @@ -61,12 +81,18 @@ export * as ShTangledMarkupMarkdown from "./types/sh/tangled/markup/markdown.js" export * as ShTangledOwner from "./types/sh/tangled/owner.js"; export * as ShTangledPipeline from "./types/sh/tangled/pipeline.js"; export * as ShTangledPipelineCancelPipeline from "./types/sh/tangled/pipeline/cancelPipeline.js"; +export * as ShTangledPipelineCountPipelines from "./types/sh/tangled/pipeline/countPipelines.js"; +export * as ShTangledPipelineCountPipelinesBy from "./types/sh/tangled/pipeline/countPipelinesBy.js"; +export * as ShTangledPipelineCountStatuses from "./types/sh/tangled/pipeline/countStatuses.js"; +export * as ShTangledPipelineCountStatusesBy from "./types/sh/tangled/pipeline/countStatusesBy.js"; export * as ShTangledPipelineListPipelines from "./types/sh/tangled/pipeline/listPipelines.js"; export * as ShTangledPipelineListPipelinesBy from "./types/sh/tangled/pipeline/listPipelinesBy.js"; export * as ShTangledPipelineListStatuses from "./types/sh/tangled/pipeline/listStatuses.js"; export * as ShTangledPipelineListStatusesBy from "./types/sh/tangled/pipeline/listStatusesBy.js"; export * as ShTangledPipelineStatus from "./types/sh/tangled/pipeline/status.js"; export * as ShTangledPublicKey from "./types/sh/tangled/publicKey.js"; +export * as ShTangledPublicKeyCountKeys from "./types/sh/tangled/publicKey/countKeys.js"; +export * as ShTangledPublicKeyGetPublicKey from "./types/sh/tangled/publicKey/getPublicKey.js"; export * as ShTangledPublicKeyListKeys from "./types/sh/tangled/publicKey/listKeys.js"; export * as ShTangledQueryEnrichResponse from "./types/sh/tangled/query/enrichResponse.js"; export * as ShTangledRepo from "./types/sh/tangled/repo.js"; @@ -79,6 +105,16 @@ export * as ShTangledRepoBranch from "./types/sh/tangled/repo/branch.js"; export * as ShTangledRepoBranches from "./types/sh/tangled/repo/branches.js"; export * as ShTangledRepoCollaborator from "./types/sh/tangled/repo/collaborator.js"; export * as ShTangledRepoCompare from "./types/sh/tangled/repo/compare.js"; +export * as ShTangledRepoCountArtifacts from "./types/sh/tangled/repo/countArtifacts.js"; +export * as ShTangledRepoCountArtifactsBy from "./types/sh/tangled/repo/countArtifactsBy.js"; +export * as ShTangledRepoCountCollaborators from "./types/sh/tangled/repo/countCollaborators.js"; +export * as ShTangledRepoCountCollaboratorsBy from "./types/sh/tangled/repo/countCollaboratorsBy.js"; +export * as ShTangledRepoCountForks from "./types/sh/tangled/repo/countForks.js"; +export * as ShTangledRepoCountIssues from "./types/sh/tangled/repo/countIssues.js"; +export * as ShTangledRepoCountIssuesBy from "./types/sh/tangled/repo/countIssuesBy.js"; +export * as ShTangledRepoCountPulls from "./types/sh/tangled/repo/countPulls.js"; +export * as ShTangledRepoCountPullsBy from "./types/sh/tangled/repo/countPullsBy.js"; +export * as ShTangledRepoCountRepos from "./types/sh/tangled/repo/countRepos.js"; export * as ShTangledRepoCreate from "./types/sh/tangled/repo/create.js"; export * as ShTangledRepoDelete from "./types/sh/tangled/repo/delete.js"; export * as ShTangledRepoDeleteBranch from "./types/sh/tangled/repo/deleteBranch.js"; @@ -87,10 +123,20 @@ export * as ShTangledRepoDiff from "./types/sh/tangled/repo/diff.js"; export * as ShTangledRepoForkStatus from "./types/sh/tangled/repo/forkStatus.js"; export * as ShTangledRepoForkSync from "./types/sh/tangled/repo/forkSync.js"; export * as ShTangledRepoGetDefaultBranch from "./types/sh/tangled/repo/getDefaultBranch.js"; +export * as ShTangledRepoGetIssue from "./types/sh/tangled/repo/getIssue.js"; +export * as ShTangledRepoGetIssues from "./types/sh/tangled/repo/getIssues.js"; +export * as ShTangledRepoGetPull from "./types/sh/tangled/repo/getPull.js"; +export * as ShTangledRepoGetPulls from "./types/sh/tangled/repo/getPulls.js"; +export * as ShTangledRepoGetRepo from "./types/sh/tangled/repo/getRepo.js"; +export * as ShTangledRepoGetRepoByName from "./types/sh/tangled/repo/getRepoByName.js"; +export * as ShTangledRepoGetRepoByRepoDid from "./types/sh/tangled/repo/getRepoByRepoDid.js"; +export * as ShTangledRepoGetRepos from "./types/sh/tangled/repo/getRepos.js"; export * as ShTangledRepoGetReposByRepoDids from "./types/sh/tangled/repo/getReposByRepoDids.js"; export * as ShTangledRepoHiddenRef from "./types/sh/tangled/repo/hiddenRef.js"; export * as ShTangledRepoIssue from "./types/sh/tangled/repo/issue.js"; export * as ShTangledRepoIssueComment from "./types/sh/tangled/repo/issue/comment.js"; +export * as ShTangledRepoIssueCountStates from "./types/sh/tangled/repo/issue/countStates.js"; +export * as ShTangledRepoIssueCountStatesBy from "./types/sh/tangled/repo/issue/countStatesBy.js"; export * as ShTangledRepoIssueListStates from "./types/sh/tangled/repo/issue/listStates.js"; export * as ShTangledRepoIssueListStatesBy from "./types/sh/tangled/repo/issue/listStatesBy.js"; export * as ShTangledRepoIssueState from "./types/sh/tangled/repo/issue/state.js"; @@ -112,6 +158,8 @@ export * as ShTangledRepoMerge from "./types/sh/tangled/repo/merge.js"; export * as ShTangledRepoMergeCheck from "./types/sh/tangled/repo/mergeCheck.js"; export * as ShTangledRepoPull from "./types/sh/tangled/repo/pull.js"; export * as ShTangledRepoPullComment from "./types/sh/tangled/repo/pull/comment.js"; +export * as ShTangledRepoPullCountStatuses from "./types/sh/tangled/repo/pull/countStatuses.js"; +export * as ShTangledRepoPullCountStatusesBy from "./types/sh/tangled/repo/pull/countStatusesBy.js"; export * as ShTangledRepoPullListStatuses from "./types/sh/tangled/repo/pull/listStatuses.js"; export * as ShTangledRepoPullListStatusesBy from "./types/sh/tangled/repo/pull/listStatusesBy.js"; export * as ShTangledRepoPullStatus from "./types/sh/tangled/repo/pull/status.js"; @@ -124,12 +172,18 @@ export * as ShTangledRepoSetDefaultBranch from "./types/sh/tangled/repo/setDefau export * as ShTangledRepoTag from "./types/sh/tangled/repo/tag.js"; export * as ShTangledRepoTags from "./types/sh/tangled/repo/tags.js"; export * as ShTangledRepoTree from "./types/sh/tangled/repo/tree.js"; +export * as ShTangledSearchQuery from "./types/sh/tangled/search/query.js"; export * as ShTangledSpindle from "./types/sh/tangled/spindle.js"; +export * as ShTangledSpindleCountMembers from "./types/sh/tangled/spindle/countMembers.js"; +export * as ShTangledSpindleCountMembersBy from "./types/sh/tangled/spindle/countMembersBy.js"; +export * as ShTangledSpindleCountSpindles from "./types/sh/tangled/spindle/countSpindles.js"; export * as ShTangledSpindleListMembers from "./types/sh/tangled/spindle/listMembers.js"; export * as ShTangledSpindleListMembersBy from "./types/sh/tangled/spindle/listMembersBy.js"; export * as ShTangledSpindleListSpindles from "./types/sh/tangled/spindle/listSpindles.js"; export * as ShTangledSpindleMember from "./types/sh/tangled/spindle/member.js"; export * as ShTangledString from "./types/sh/tangled/string.js"; +export * as ShTangledStringCountStrings from "./types/sh/tangled/string/countStrings.js"; +export * as ShTangledStringGetString from "./types/sh/tangled/string/getString.js"; export * as ShTangledStringListStrings from "./types/sh/tangled/string/listStrings.js"; export * as ShTangledSyncListRepos from "./types/sh/tangled/sync/listRepos.js"; export * as ShTangledSyncRequestCrawl from "./types/sh/tangled/sync/requestCrawl.js"; diff --git a/web/src/lib/api/lexicons/types/sh/tangled/actor/getProfile.ts b/web/src/lib/api/lexicons/types/sh/tangled/actor/getProfile.ts new file mode 100644 index 00000000..c039c64a --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/actor/getProfile.ts @@ -0,0 +1,38 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.actor.getProfile", { + params: /*#__PURE__*/ v.object({ + /** + * AT-URI of the sh.tangled.actor.profile record to fetch. + */ + actor: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.actor.profile record. + */ + value: /*#__PURE__*/ v.unknown(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.actor.getProfile": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/actor/getProfiles.ts b/web/src/lib/api/lexicons/types/sh/tangled/actor/getProfiles.ts new file mode 100644 index 00000000..8d684df2 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/actor/getProfiles.ts @@ -0,0 +1,56 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.actor.getProfiles", { + params: /*#__PURE__*/ v.object({ + /** + * AT-URIs of the sh.tangled.actor.profile records to fetch. At most 50 per request. + * @minLength 1 + * @maxLength 50 + */ + actors: /*#__PURE__*/ v.constrain( + /*#__PURE__*/ v.array(/*#__PURE__*/ v.resourceUriString()), + [/*#__PURE__*/ v.arrayLength(1, 50)], + ), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + get items() { + return /*#__PURE__*/ v.array(recordViewSchema); + }, + }), + }, +}); +const _recordViewSchema = /*#__PURE__*/ v.object({ + $type: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.literal("sh.tangled.actor.getProfiles#recordView"), + ), + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.actor.profile record. + */ + value: /*#__PURE__*/ v.unknown(), +}); + +type main$schematype = typeof _mainSchema; +type recordView$schematype = typeof _recordViewSchema; + +export interface mainSchema extends main$schematype {} +export interface recordViewSchema extends recordView$schematype {} + +export const mainSchema = _mainSchema as mainSchema; +export const recordViewSchema = _recordViewSchema as recordViewSchema; + +export interface RecordView extends v.InferInput {} + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.actor.getProfiles": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/ci/queryPipelines.ts b/web/src/lib/api/lexicons/types/sh/tangled/ci/queryPipelines.ts index 78e1819f..7b702b02 100644 --- a/web/src/lib/api/lexicons/types/sh/tangled/ci/queryPipelines.ts +++ b/web/src/lib/api/lexicons/types/sh/tangled/ci/queryPipelines.ts @@ -15,6 +15,14 @@ const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.ci.queryPipelines", { * Pagination cursor */ cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), + /** + * Filter pipelines by trigger kind. When provided, pipelines matching any listed kind are returned; when omitted, every kind is returned. + */ + kinds: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.array( + /*#__PURE__*/ v.literalEnum(["manual", "pull_request", "push"]), + ), + ), /** * Maximum number of pipelines to return * @minimum 1 diff --git a/web/src/lib/api/lexicons/types/sh/tangled/feed/countComments.ts b/web/src/lib/api/lexicons/types/sh/tangled/feed/countComments.ts new file mode 100644 index 00000000..0a0642b9 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/feed/countComments.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.feed.countComments", { + params: /*#__PURE__*/ v.object({ + /** + * Record AT-URI the comments attach to. + */ + subject: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.feed.countComments": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/feed/countCommentsBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/feed/countCommentsBy.ts new file mode 100644 index 00000000..63b5906d --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/feed/countCommentsBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.feed.countCommentsBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose comment authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.feed.countCommentsBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/feed/countReactions.ts b/web/src/lib/api/lexicons/types/sh/tangled/feed/countReactions.ts new file mode 100644 index 00000000..8a089613 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/feed/countReactions.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.feed.countReactions", { + params: /*#__PURE__*/ v.object({ + /** + * Record AT-URI the reactions target. + */ + subject: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.feed.countReactions": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/feed/countReactionsBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/feed/countReactionsBy.ts new file mode 100644 index 00000000..48ad63e0 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/feed/countReactionsBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.feed.countReactionsBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose reaction authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.feed.countReactionsBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/feed/countStars.ts b/web/src/lib/api/lexicons/types/sh/tangled/feed/countStars.ts new file mode 100644 index 00000000..f4700104 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/feed/countStars.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.feed.countStars", { + params: /*#__PURE__*/ v.object({ + /** + * Repo DID to list star edges for. + */ + subject: /*#__PURE__*/ v.string(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.feed.countStars": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/feed/countStarsBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/feed/countStarsBy.ts new file mode 100644 index 00000000..6b27d401 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/feed/countStarsBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.feed.countStarsBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose star authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.feed.countStarsBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/feed/listComments.ts b/web/src/lib/api/lexicons/types/sh/tangled/feed/listComments.ts index 739d4136..2b11e76a 100644 --- a/web/src/lib/api/lexicons/types/sh/tangled/feed/listComments.ts +++ b/web/src/lib/api/lexicons/types/sh/tangled/feed/listComments.ts @@ -39,7 +39,7 @@ const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.feed.listComments", { "desc", ), /** - * Record AT-URI the comments are attached to. + * Record AT-URI the comments attach to. */ subject: /*#__PURE__*/ v.resourceUriString(), }), diff --git a/web/src/lib/api/lexicons/types/sh/tangled/git/countRefUpdates.ts b/web/src/lib/api/lexicons/types/sh/tangled/git/countRefUpdates.ts new file mode 100644 index 00000000..8306704d --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/git/countRefUpdates.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.git.countRefUpdates", { + params: /*#__PURE__*/ v.object({ + /** + * Repo DID whose ref-update records to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.git.countRefUpdates": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/git/countRefUpdatesBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/git/countRefUpdatesBy.ts new file mode 100644 index 00000000..77c3c5dd --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/git/countRefUpdatesBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.git.countRefUpdatesBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose ref-update authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.git.countRefUpdatesBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/graph/countFollows.ts b/web/src/lib/api/lexicons/types/sh/tangled/graph/countFollows.ts new file mode 100644 index 00000000..59aa02db --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/graph/countFollows.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.graph.countFollows", { + params: /*#__PURE__*/ v.object({ + /** + * Followee DID whose inbound follows to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.graph.countFollows": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/graph/countFollowsBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/graph/countFollowsBy.ts new file mode 100644 index 00000000..99722df2 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/graph/countFollowsBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.graph.countFollowsBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose follow authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.graph.countFollowsBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/graph/countVouches.ts b/web/src/lib/api/lexicons/types/sh/tangled/graph/countVouches.ts new file mode 100644 index 00000000..af1d300f --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/graph/countVouches.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.graph.countVouches", { + params: /*#__PURE__*/ v.object({ + /** + * Vouchee DID whose inbound vouches to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.graph.countVouches": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/graph/countVouchesBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/graph/countVouchesBy.ts new file mode 100644 index 00000000..b9b8345a --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/graph/countVouchesBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.graph.countVouchesBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose vouch authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.graph.countVouchesBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/knot/countKnots.ts b/web/src/lib/api/lexicons/types/sh/tangled/knot/countKnots.ts new file mode 100644 index 00000000..7dc290c4 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/knot/countKnots.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.knot.countKnots", { + params: /*#__PURE__*/ v.object({ + /** + * Owner DID whose knot records to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.knot.countKnots": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/knot/countMembers.ts b/web/src/lib/api/lexicons/types/sh/tangled/knot/countMembers.ts new file mode 100644 index 00000000..9fb265be --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/knot/countMembers.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.knot.countMembers", { + params: /*#__PURE__*/ v.object({ + /** + * Knot identifier whose member records to list. + */ + subject: /*#__PURE__*/ v.string(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.knot.countMembers": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/knot/countMembersBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/knot/countMembersBy.ts new file mode 100644 index 00000000..f4cd5023 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/knot/countMembersBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.knot.countMembersBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose knot-member authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.knot.countMembersBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/label/countDefinitions.ts b/web/src/lib/api/lexicons/types/sh/tangled/label/countDefinitions.ts new file mode 100644 index 00000000..52c4a6fe --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/label/countDefinitions.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.label.countDefinitions", { + params: /*#__PURE__*/ v.object({ + /** + * Scope identifier whose label definitions to list. + */ + subject: /*#__PURE__*/ v.string(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.label.countDefinitions": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/label/countOps.ts b/web/src/lib/api/lexicons/types/sh/tangled/label/countOps.ts new file mode 100644 index 00000000..6cd3cc96 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/label/countOps.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.label.countOps", { + params: /*#__PURE__*/ v.object({ + /** + * Scope identifier whose label op records to list. + */ + subject: /*#__PURE__*/ v.string(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.label.countOps": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/label/countOpsBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/label/countOpsBy.ts new file mode 100644 index 00000000..4910901f --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/label/countOpsBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.label.countOpsBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose label-op authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.label.countOpsBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countPipelines.ts b/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countPipelines.ts new file mode 100644 index 00000000..224204a0 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countPipelines.ts @@ -0,0 +1,45 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query( + "sh.tangled.pipeline.countPipelines", + { + params: /*#__PURE__*/ v.object({ + /** + * Repo or spindle identifier whose pipeline records to list. + */ + subject: /*#__PURE__*/ v.string(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, + }, +); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.pipeline.countPipelines": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countPipelinesBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countPipelinesBy.ts new file mode 100644 index 00000000..1613a3a4 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countPipelinesBy.ts @@ -0,0 +1,45 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query( + "sh.tangled.pipeline.countPipelinesBy", + { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose pipeline authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, + }, +); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.pipeline.countPipelinesBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countStatuses.ts b/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countStatuses.ts new file mode 100644 index 00000000..dc6b0b92 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countStatuses.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.pipeline.countStatuses", { + params: /*#__PURE__*/ v.object({ + /** + * Pipeline AT-URI whose status records to list. + */ + subject: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.pipeline.countStatuses": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countStatusesBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countStatusesBy.ts new file mode 100644 index 00000000..ee021cef --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/pipeline/countStatusesBy.ts @@ -0,0 +1,45 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query( + "sh.tangled.pipeline.countStatusesBy", + { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose pipeline-status authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, + }, +); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.pipeline.countStatusesBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/publicKey/countKeys.ts b/web/src/lib/api/lexicons/types/sh/tangled/publicKey/countKeys.ts new file mode 100644 index 00000000..effa7846 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/publicKey/countKeys.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.publicKey.countKeys", { + params: /*#__PURE__*/ v.object({ + /** + * Owner DID whose public-key records to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.publicKey.countKeys": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/publicKey/getPublicKey.ts b/web/src/lib/api/lexicons/types/sh/tangled/publicKey/getPublicKey.ts new file mode 100644 index 00000000..75a16d22 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/publicKey/getPublicKey.ts @@ -0,0 +1,38 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.publicKey.getPublicKey", { + params: /*#__PURE__*/ v.object({ + /** + * AT-URI of the sh.tangled.publicKey record to fetch. + */ + publicKey: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.publicKey record. + */ + value: /*#__PURE__*/ v.unknown(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.publicKey.getPublicKey": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/countArtifacts.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/countArtifacts.ts new file mode 100644 index 00000000..293b4238 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/countArtifacts.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.countArtifacts", { + params: /*#__PURE__*/ v.object({ + /** + * Repo or release identifier whose artifacts to list. + */ + subject: /*#__PURE__*/ v.string(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.countArtifacts": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/countArtifactsBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/countArtifactsBy.ts new file mode 100644 index 00000000..b3bd9df1 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/countArtifactsBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.countArtifactsBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose artifact authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.countArtifactsBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/countCollaborators.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/countCollaborators.ts new file mode 100644 index 00000000..cfa3e497 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/countCollaborators.ts @@ -0,0 +1,45 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query( + "sh.tangled.repo.countCollaborators", + { + params: /*#__PURE__*/ v.object({ + /** + * Repo DID whose collaborator records to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, + }, +); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.countCollaborators": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/countCollaboratorsBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/countCollaboratorsBy.ts new file mode 100644 index 00000000..b3dcb204 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/countCollaboratorsBy.ts @@ -0,0 +1,45 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query( + "sh.tangled.repo.countCollaboratorsBy", + { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose collaborator authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, + }, +); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.countCollaboratorsBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/countForks.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/countForks.ts new file mode 100644 index 00000000..740e177c --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/countForks.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.countForks", { + params: /*#__PURE__*/ v.object({ + /** + * Repo DID to count forks of. Repos that never got a DID cannot be counted. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.countForks": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/countIssues.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/countIssues.ts new file mode 100644 index 00000000..86c54368 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/countIssues.ts @@ -0,0 +1,52 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.countIssues", { + params: /*#__PURE__*/ v.object({ + /** + * Restrict to issues authored by this user DID. + */ + author: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), + /** + * Restrict to issues whose latest derived state matches. + */ + state: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.string<"closed" | "open" | (string & {})>(), + ), + /** + * Repo DID to list issues for + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.countIssues": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/countIssuesBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/countIssuesBy.ts new file mode 100644 index 00000000..5f1cb186 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/countIssuesBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.countIssuesBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose issue authorings to list + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.countIssuesBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/countPulls.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/countPulls.ts new file mode 100644 index 00000000..d94a129e --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/countPulls.ts @@ -0,0 +1,52 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.countPulls", { + params: /*#__PURE__*/ v.object({ + /** + * Restrict to pulls authored by this user DID. + */ + author: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), + /** + * Restrict to pulls whose latest derived status matches. + */ + status: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.string<"closed" | "merged" | "open" | (string & {})>(), + ), + /** + * Repo DID to list pulls for + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.countPulls": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/countPullsBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/countPullsBy.ts new file mode 100644 index 00000000..ea54429c --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/countPullsBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.countPullsBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose pull authorings to list + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.countPullsBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/countRepos.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/countRepos.ts new file mode 100644 index 00000000..a9a87e86 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/countRepos.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.countRepos", { + params: /*#__PURE__*/ v.object({ + /** + * Owner DID whose repo records to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.countRepos": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/forkSync.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/forkSync.ts index 49ca762e..361aa4a1 100644 --- a/web/src/lib/api/lexicons/types/sh/tangled/repo/forkSync.ts +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/forkSync.ts @@ -19,6 +19,10 @@ const _mainSchema = /*#__PURE__*/ v.procedure("sh.tangled.repo.forkSync", { * Name of the forked repository */ name: /*#__PURE__*/ v.string(), + /** + * DID of the repository + */ + repo: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), /** * AT-URI of the source repository */ diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/getIssue.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/getIssue.ts new file mode 100644 index 00000000..3d379c80 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/getIssue.ts @@ -0,0 +1,38 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.getIssue", { + params: /*#__PURE__*/ v.object({ + /** + * AT-URI of the sh.tangled.repo.issue record to fetch. + */ + issue: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.repo.issue record. + */ + value: /*#__PURE__*/ v.unknown(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.getIssue": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/getIssues.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/getIssues.ts new file mode 100644 index 00000000..cf59e77c --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/getIssues.ts @@ -0,0 +1,56 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.getIssues", { + params: /*#__PURE__*/ v.object({ + /** + * AT-URIs of the sh.tangled.repo.issue records to fetch. At most 50 per request. + * @minLength 1 + * @maxLength 50 + */ + issues: /*#__PURE__*/ v.constrain( + /*#__PURE__*/ v.array(/*#__PURE__*/ v.resourceUriString()), + [/*#__PURE__*/ v.arrayLength(1, 50)], + ), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + get items() { + return /*#__PURE__*/ v.array(recordViewSchema); + }, + }), + }, +}); +const _recordViewSchema = /*#__PURE__*/ v.object({ + $type: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.literal("sh.tangled.repo.getIssues#recordView"), + ), + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.repo.issue record. + */ + value: /*#__PURE__*/ v.unknown(), +}); + +type main$schematype = typeof _mainSchema; +type recordView$schematype = typeof _recordViewSchema; + +export interface mainSchema extends main$schematype {} +export interface recordViewSchema extends recordView$schematype {} + +export const mainSchema = _mainSchema as mainSchema; +export const recordViewSchema = _recordViewSchema as recordViewSchema; + +export interface RecordView 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.getIssues": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/getPull.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/getPull.ts new file mode 100644 index 00000000..185ae9eb --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/getPull.ts @@ -0,0 +1,38 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.getPull", { + params: /*#__PURE__*/ v.object({ + /** + * AT-URI of the sh.tangled.repo.pull record to fetch. + */ + pull: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.repo.pull record. + */ + value: /*#__PURE__*/ v.unknown(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.getPull": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/getPulls.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/getPulls.ts new file mode 100644 index 00000000..b2db612b --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/getPulls.ts @@ -0,0 +1,56 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.getPulls", { + params: /*#__PURE__*/ v.object({ + /** + * AT-URIs of the sh.tangled.repo.pull records to fetch. At most 50 per request. + * @minLength 1 + * @maxLength 50 + */ + pulls: /*#__PURE__*/ v.constrain( + /*#__PURE__*/ v.array(/*#__PURE__*/ v.resourceUriString()), + [/*#__PURE__*/ v.arrayLength(1, 50)], + ), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + get items() { + return /*#__PURE__*/ v.array(recordViewSchema); + }, + }), + }, +}); +const _recordViewSchema = /*#__PURE__*/ v.object({ + $type: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.literal("sh.tangled.repo.getPulls#recordView"), + ), + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.repo.pull record. + */ + value: /*#__PURE__*/ v.unknown(), +}); + +type main$schematype = typeof _mainSchema; +type recordView$schematype = typeof _recordViewSchema; + +export interface mainSchema extends main$schematype {} +export interface recordViewSchema extends recordView$schematype {} + +export const mainSchema = _mainSchema as mainSchema; +export const recordViewSchema = _recordViewSchema as recordViewSchema; + +export interface RecordView 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.getPulls": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepo.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepo.ts new file mode 100644 index 00000000..ae2ba692 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepo.ts @@ -0,0 +1,38 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.getRepo", { + params: /*#__PURE__*/ v.object({ + /** + * AT-URI of the sh.tangled.repo record to fetch. + */ + repo: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.repo record. + */ + value: /*#__PURE__*/ v.unknown(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.getRepo": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepoByName.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepoByName.ts new file mode 100644 index 00000000..003dcc99 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepoByName.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.getRepoByName", { + params: /*#__PURE__*/ v.object({ + /** + * Name of the repo as it appears in its url. Repos without a name are reachable by their rkey. + */ + name: /*#__PURE__*/ v.string(), + /** + * DID of the account that owns the repo. + */ + owner: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.repo record. + */ + value: /*#__PURE__*/ v.unknown(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.getRepoByName": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepoByRepoDid.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepoByRepoDid.ts new file mode 100644 index 00000000..f9e4f3af --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepoByRepoDid.ts @@ -0,0 +1,38 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.getRepoByRepoDid", { + params: /*#__PURE__*/ v.object({ + /** + * Repo DID whose sh.tangled.repo record to fetch. + */ + repoDid: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.repo record. + */ + value: /*#__PURE__*/ v.unknown(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.getRepoByRepoDid": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepos.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepos.ts new file mode 100644 index 00000000..340d3afb --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/getRepos.ts @@ -0,0 +1,56 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.getRepos", { + params: /*#__PURE__*/ v.object({ + /** + * AT-URIs of the sh.tangled.repo records to fetch. At most 50 per request. + * @minLength 1 + * @maxLength 50 + */ + repos: /*#__PURE__*/ v.constrain( + /*#__PURE__*/ v.array(/*#__PURE__*/ v.resourceUriString()), + [/*#__PURE__*/ v.arrayLength(1, 50)], + ), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + get items() { + return /*#__PURE__*/ v.array(recordViewSchema); + }, + }), + }, +}); +const _recordViewSchema = /*#__PURE__*/ v.object({ + $type: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.literal("sh.tangled.repo.getRepos#recordView"), + ), + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.repo record. + */ + value: /*#__PURE__*/ v.unknown(), +}); + +type main$schematype = typeof _mainSchema; +type recordView$schematype = typeof _recordViewSchema; + +export interface mainSchema extends main$schematype {} +export interface recordViewSchema extends recordView$schematype {} + +export const mainSchema = _mainSchema as mainSchema; +export const recordViewSchema = _recordViewSchema as recordViewSchema; + +export interface RecordView 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.getRepos": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/issue/countStates.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/issue/countStates.ts new file mode 100644 index 00000000..e5e6c992 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/issue/countStates.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.repo.issue.countStates", { + params: /*#__PURE__*/ v.object({ + /** + * Issue AT-URI whose state records to list. + */ + subject: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.issue.countStates": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/issue/countStatesBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/issue/countStatesBy.ts new file mode 100644 index 00000000..8f9d1062 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/issue/countStatesBy.ts @@ -0,0 +1,45 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query( + "sh.tangled.repo.issue.countStatesBy", + { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose issue-state authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, + }, +); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.issue.countStatesBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/merge.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/merge.ts index 3fc74527..0ae78e58 100644 --- a/web/src/lib/api/lexicons/types/sh/tangled/repo/merge.ts +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/merge.ts @@ -39,6 +39,10 @@ const _mainSchema = /*#__PURE__*/ v.procedure("sh.tangled.repo.merge", { * Patch content to merge */ patch: /*#__PURE__*/ v.string(), + /** + * DID of the repository + */ + repo: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), }), }, output: null, diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/mergeCheck.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/mergeCheck.ts index 8030dd76..b3fad025 100644 --- a/web/src/lib/api/lexicons/types/sh/tangled/repo/mergeCheck.ts +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/mergeCheck.ts @@ -36,6 +36,10 @@ const _mainSchema = /*#__PURE__*/ v.procedure("sh.tangled.repo.mergeCheck", { * Patch or pull request to check for merge conflicts */ patch: /*#__PURE__*/ v.string(), + /** + * DID of the repository + */ + repo: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), }), }, output: { diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/pull/countStatuses.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/pull/countStatuses.ts new file mode 100644 index 00000000..6f16b59c --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/pull/countStatuses.ts @@ -0,0 +1,45 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query( + "sh.tangled.repo.pull.countStatuses", + { + params: /*#__PURE__*/ v.object({ + /** + * Pull AT-URI whose status records to list. + */ + subject: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, + }, +); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.pull.countStatuses": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/repo/pull/countStatusesBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/repo/pull/countStatusesBy.ts new file mode 100644 index 00000000..2894f328 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/repo/pull/countStatusesBy.ts @@ -0,0 +1,45 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query( + "sh.tangled.repo.pull.countStatusesBy", + { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose pull-status authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, + }, +); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.repo.pull.countStatusesBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/search/query.ts b/web/src/lib/api/lexicons/types/sh/tangled/search/query.ts new file mode 100644 index 00000000..5cb619e3 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/search/query.ts @@ -0,0 +1,98 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _hitSchema = /*#__PURE__*/ v.object({ + $type: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.literal("sh.tangled.search.query#hit"), + ), + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + /** + * Collection of the matched record. + */ + nsid: /*#__PURE__*/ v.nsidString(), + /** + * Relevance score of the hit, a floating-point number where higher ranks first. + */ + score: /*#__PURE__*/ v.unknown(), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded matched record. + */ + value: /*#__PURE__*/ v.unknown(), +}); +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.search.query", { + params: /*#__PURE__*/ v.object({ + /** + * Restrict to records authored by this DID. + */ + author: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), + /** + * Pagination cursor + */ + cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), + /** + * @minimum 1 + * @maximum 1000 + * @default 50 + */ + limit: /*#__PURE__*/ v.optional( + /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.integer(), [ + /*#__PURE__*/ v.integerRange(1, 1000), + ]), + 50, + ), + /** + * Restrict to records of this collection. + */ + nsid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.nsidString()), + /** + * Full-text search query. + * @minLength 1 + */ + q: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ + /*#__PURE__*/ v.stringLength(1), + ]), + /** + * Restrict to records under this repo DID. + */ + repo: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.didString()), + /** + * Restrict to records created at or after this time. + */ + since: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.datetimeString()), + /** + * Restrict to records created at or before this time. + */ + until: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.datetimeString()), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), + get hits() { + return /*#__PURE__*/ v.array(hitSchema); + }, + }), + }, +}); + +type hit$schematype = typeof _hitSchema; +type main$schematype = typeof _mainSchema; + +export interface hitSchema extends hit$schematype {} +export interface mainSchema extends main$schematype {} + +export const hitSchema = _hitSchema as hitSchema; +export const mainSchema = _mainSchema as mainSchema; + +export interface Hit extends v.InferInput {} + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.search.query": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/spindle/countMembers.ts b/web/src/lib/api/lexicons/types/sh/tangled/spindle/countMembers.ts new file mode 100644 index 00000000..29cda375 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/spindle/countMembers.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.spindle.countMembers", { + params: /*#__PURE__*/ v.object({ + /** + * Spindle identifier whose member records to list. + */ + subject: /*#__PURE__*/ v.string(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.spindle.countMembers": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/spindle/countMembersBy.ts b/web/src/lib/api/lexicons/types/sh/tangled/spindle/countMembersBy.ts new file mode 100644 index 00000000..3e709aa6 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/spindle/countMembersBy.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.spindle.countMembersBy", { + params: /*#__PURE__*/ v.object({ + /** + * Actor DID whose spindle-member authorings to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.spindle.countMembersBy": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/spindle/countSpindles.ts b/web/src/lib/api/lexicons/types/sh/tangled/spindle/countSpindles.ts new file mode 100644 index 00000000..28ba7841 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/spindle/countSpindles.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.spindle.countSpindles", { + params: /*#__PURE__*/ v.object({ + /** + * Owner DID whose spindle records to list. + */ + subject: /*#__PURE__*/ v.didString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.spindle.countSpindles": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/string/countStrings.ts b/web/src/lib/api/lexicons/types/sh/tangled/string/countStrings.ts new file mode 100644 index 00000000..d3a56975 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/string/countStrings.ts @@ -0,0 +1,42 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.string.countStrings", { + params: /*#__PURE__*/ v.object({ + /** + * Scope identifier whose string records to list. + */ + subject: /*#__PURE__*/ v.string(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + /** + * Total number of matching records. + * @minimum 0 + */ + count: /*#__PURE__*/ v.integer(), + /** + * Number of distinct authors among the matching records. + * @minimum 0 + */ + distinctAuthors: /*#__PURE__*/ v.integer(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.string.countStrings": mainSchema; + } +} diff --git a/web/src/lib/api/lexicons/types/sh/tangled/string/getString.ts b/web/src/lib/api/lexicons/types/sh/tangled/string/getString.ts new file mode 100644 index 00000000..3d1b4531 --- /dev/null +++ b/web/src/lib/api/lexicons/types/sh/tangled/string/getString.ts @@ -0,0 +1,38 @@ +import type {} from "@atcute/lexicons"; +import * as v from "@atcute/lexicons/validations"; +import type {} from "@atcute/lexicons/ambient"; + +const _mainSchema = /*#__PURE__*/ v.query("sh.tangled.string.getString", { + params: /*#__PURE__*/ v.object({ + /** + * AT-URI of the sh.tangled.string record to fetch. + */ + string: /*#__PURE__*/ v.resourceUriString(), + }), + output: { + type: "lex", + schema: /*#__PURE__*/ v.object({ + cid: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidString()), + uri: /*#__PURE__*/ v.resourceUriString(), + /** + * Embedded sh.tangled.string record. + */ + value: /*#__PURE__*/ v.unknown(), + }), + }, +}); + +type main$schematype = typeof _mainSchema; + +export interface mainSchema extends main$schematype {} + +export const mainSchema = _mainSchema as mainSchema; + +export interface $params extends v.InferInput {} +export interface $output extends v.InferXRPCBodyInput {} + +declare module "@atcute/lexicons/ambient" { + interface XRPCQueries { + "sh.tangled.string.getString": mainSchema; + } +} diff --git a/web/src/lib/api/records.ts b/web/src/lib/api/records.ts index 06bd8120..7adf8a5c 100644 --- a/web/src/lib/api/records.ts +++ b/web/src/lib/api/records.ts @@ -30,6 +30,13 @@ export const getRepo = (ctx: BobbinContext, repo: string, init?: XrpcRequestInit export const getRepoByRepoDid = (ctx: BobbinContext, repoDid: string, init?: XrpcRequestInit) => jsonGet>(ctx, "sh.tangled.repo.getRepoByRepoDid", { repoDid }, init); +export const getRepoByName = ( + ctx: BobbinContext, + owner: string, + name: string, + init?: XrpcRequestInit +) => jsonGet>(ctx, "sh.tangled.repo.getRepoByName", { owner, name }, init); + export const getProfile = (ctx: BobbinContext, did: string, init?: XrpcRequestInit) => jsonGet>( ctx, diff --git a/web/src/lib/api/repo.test.ts b/web/src/lib/api/repo.test.ts new file mode 100644 index 00000000..7786b910 --- /dev/null +++ b/web/src/lib/api/repo.test.ts @@ -0,0 +1,207 @@ +import { describe, expect, it, vi } from "vitest"; +import { + repoNameOf, + resolveRepoByName, + sortTreeEntries, + toBranchSummary, + toCommitSummary, + toTagSummary, + toTreeEntrySummary, + treeEntryKind, + type BranchEntry, + type LogCommit, + type TagEntry, + type TreeEntrySummary +} from "./repo"; +import { ClientResponseError, createBobbinClient, type BobbinContext } from "./client"; +import type { RecordView, RepoRecord } from "./records"; + +const jsonResponse = (body: unknown): Response => + new Response(JSON.stringify(body), { + status: 200, + headers: { "content-type": "application/json" } + }); + +const makeCtx = (fetchMock: typeof globalThis.fetch): BobbinContext => + createBobbinClient({ serviceUrl: "https://bobbin.test", fetch: fetchMock }); + +describe("repoNameOf", () => { + const view = (uri: string, name?: string): RecordView => ({ + uri: uri as RecordView["uri"], + value: { $type: "sh.tangled.repo", createdAt: "", knot: "knot.test", name } + }); + + it("prefers the record's cosmetic name over a tid rkey", () => { + expect(repoNameOf(view("at://did:plc:o/sh.tangled.repo/3lzg6enurmo22", "infra"))).toBe("infra"); + }); + + it("falls back to the rkey for unnamed records", () => { + expect(repoNameOf(view("at://did:plc:o/sh.tangled.repo/infra"))).toBe("infra"); + }); +}); + +describe("treeEntryKind", () => { + it("maps git file modes to entry kinds", () => { + expect(treeEntryKind("0040000")).toBe("directory"); + expect(treeEntryKind("040000")).toBe("directory"); + expect(treeEntryKind("0100644")).toBe("file"); + expect(treeEntryKind("0100755")).toBe("file"); + expect(treeEntryKind("0120000")).toBe("symlink"); + expect(treeEntryKind("0160000")).toBe("submodule"); + }); +}); + +describe("sortTreeEntries", () => { + it("puts directories and submodules before files, then sorts by name", () => { + const entry = (name: string, kind: TreeEntrySummary["kind"]): TreeEntrySummary => ({ + name, + kind, + size: 0 + }); + const sorted = sortTreeEntries([ + entry("readme.md", "file"), + entry("src", "directory"), + entry(".gitignore", "file"), + entry("vendor", "submodule") + ]); + expect(sorted.map((item) => item.name)).toEqual(["src", "vendor", ".gitignore", "readme.md"]); + }); +}); + +describe("toCommitSummary", () => { + // `this` is where the hex hash lives, `hash` is a byte array on the wire + const commit: LogCommit = { + this: "0c4d0e9b07940033721395a434b5873f0fb9e6c8", + author: { Name: "Ada", Email: "ada@example.com", When: "2026-07-01T10:00:00Z" }, + committer: { Name: "Ada", Email: "ada@example.com", When: "2026-07-02T10:00:00Z" }, + message: "web: add repo index\n\nWith a longer body.\n", + change_id: "abc123" + }; + + it("splits the subject from the body and shortens the hash", () => { + const summary = toCommitSummary(commit); + expect(summary).toMatchObject({ + hash: "0c4d0e9b07940033721395a434b5873f0fb9e6c8", + shortHash: "0c4d0e9b", + subject: "web: add repo index", + body: "With a longer body.", + authorName: "Ada", + when: "2026-07-02T10:00:00Z", + changeId: "abc123" + }); + }); + + it("leaves the body empty for single-line messages", () => { + const summary = toCommitSummary({ ...commit, message: "one liner\n" }); + expect(summary.body).toBe(""); + expect(summary.subject).toBe("one liner"); + }); +}); + +describe("toBranchSummary", () => { + it("reads the nested reference and the go-git commit fields", () => { + const branch: BranchEntry = { + reference: { name: "master", hash: "ff3a3678" }, + commit: { Committer: { Name: "Ada", Email: "a@b.c", When: "2026-07-02T10:00:00Z" } }, + is_default: true + }; + expect(toBranchSummary(branch)).toEqual({ + name: "master", + hash: "ff3a3678", + when: "2026-07-02T10:00:00Z", + isDefault: true + }); + }); + + it("treats a missing is_default as not default", () => { + expect(toBranchSummary({ reference: { name: "topic", hash: "abc" } }).isDefault).toBe(false); + }); +}); + +describe("toTagSummary", () => { + // an annotated tag's own hash is the tag object, the commit is in Target + it("reads the inlined reference and follows an annotated tag to its commit", () => { + const tag: TagEntry = { + name: "v1.0.0", + hash: "63fa1d4b", + message: "release", + tag: { + Tagger: { Name: "Ada", Email: "a@b.c", When: "2026-07-01T10:00:00Z" }, + Target: [75, 78, 254, 37] + } + }; + expect(toTagSummary(tag)).toEqual({ + name: "v1.0.0", + hash: "63fa1d4b", + commitHash: "4b4efe25", + when: "2026-07-01T10:00:00Z", + message: "release" + }); + }); + + it("a lightweight tag is its own commit", () => { + const summary = toTagSummary({ name: "v1.0.0", hash: "eebb477b" }); + expect(summary.commitHash).toBe("eebb477b"); + }); +}); + +describe("toTreeEntrySummary", () => { + it("carries the last commit over from snake_case", () => { + expect( + toTreeEntrySummary({ + name: "flake.nix", + mode: "0100644", + size: 213, + last_commit: { hash: "f0b11b85", message: "init", when: "2026-07-01T10:00:00Z" } + }) + ).toEqual({ + name: "flake.nix", + kind: "file", + size: 213, + lastCommitHash: "f0b11b85", + lastCommitWhen: "2026-07-01T10:00:00Z", + lastCommitMessage: "init" + }); + }); +}); + +describe("resolveRepoByName", () => { + const owner = "did:plc:owner"; + + it("asks bobbin for the owner and name", async () => { + const fetchMock = vi.fn().mockResolvedValue( + jsonResponse({ + uri: `at://${owner}/sh.tangled.repo/3lzg6enurmo22`, + value: { $type: "sh.tangled.repo", knot: "knot.test", name: "infra" } + }) + ); + const view = await resolveRepoByName(makeCtx(fetchMock), owner, "infra"); + expect(view?.uri).toBe(`at://${owner}/sh.tangled.repo/3lzg6enurmo22`); + const url = new URL(String(fetchMock.mock.calls[0][0])); + expect(url.pathname).toBe("/xrpc/sh.tangled.repo.getRepoByName"); + expect(url.searchParams.get("owner")).toBe(owner); + expect(url.searchParams.get("name")).toBe("infra"); + }); + + it("returns null when the owner has no such repo", async () => { + const fetchMock = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ error: "RecordNotFound" }), { + status: 404, + headers: { "content-type": "application/json" } + }) + ); + expect(await resolveRepoByName(makeCtx(fetchMock), owner, "missing")).toBeNull(); + }); + + it("propagates anything that is not a miss", async () => { + const fetchMock = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ error: "UpstreamFailed" }), { + status: 502, + headers: { "content-type": "application/json" } + }) + ); + await expect(resolveRepoByName(makeCtx(fetchMock), owner, "infra")).rejects.toBeInstanceOf( + ClientResponseError + ); + }); +}); diff --git a/web/src/lib/api/repo.ts b/web/src/lib/api/repo.ts new file mode 100644 index 00000000..930e09f9 --- /dev/null +++ b/web/src/lib/api/repo.ts @@ -0,0 +1,232 @@ +import { ClientResponseError, type BobbinContext, type XrpcRequestInit } from "./client"; +import { getRepoByName, type RecordView, type RepoRecord } from "./records"; +import { branches as knotBranches, log as knotLog, tags as knotTags } from "./knot"; +import { httpStatusFor } from "./load"; +import { rkeyFromUri } from "./uri"; +import type * as Tree from "./lexicons/types/sh/tangled/repo/tree"; + +// log, branches and tags are `*/*` in the lexicons, so these shapes are copied +// from core/types by hand. anything go-git touches keeps its go field names and +// writes hashes as byte arrays, so the hex comes from a sibling field + +export interface GitSignature { + Name: string; + Email: string; + When: string; +} + +export interface GitCommit { + Author?: GitSignature; + Committer?: GitSignature; + Message?: string; +} + +// `this` and `parent` are the hex hashes, `hash` is the byte array +export interface LogCommit { + this?: string; + parent?: string; + author?: GitSignature; + committer?: GitSignature; + message?: string; + tree?: string; + change_id?: string; +} + +export interface LogResponse { + commits?: LogCommit[]; + ref?: string; + total?: number; + page?: number; +} + +export interface GitReference { + name: string; + hash: string; +} + +export interface BranchEntry { + reference: GitReference; + commit?: GitCommit; + is_default?: boolean; +} + +export interface BranchesResponse { + branches?: BranchEntry[]; + total?: number; +} + +export interface TagEntry { + name: string; + hash: string; + message?: string; + tag?: { + Tagger?: GitSignature; + Message?: string; + /** the commit an annotated tag points at, bytes like every go-git hash */ + Target?: number[]; + }; +} + +export interface TagsResponse { + tags?: TagEntry[]; + total?: number; +} + +// newer repos get tid rkeys and keep their display name in the record +export const repoNameOf = (view: RecordView): string => + view.value.name ?? rkeyFromUri(view.uri); + +// a repo bobbin has never indexed is a miss, not an error +export const resolveRepoByName = async ( + ctx: BobbinContext, + ownerDid: string, + name: string, + init?: XrpcRequestInit +): Promise | null> => { + try { + return await getRepoByName(ctx, ownerDid, name, init); + } catch (cause) { + if (cause instanceof ClientResponseError && httpStatusFor(cause) === 404) return null; + throw cause; + } +}; + +export interface CommitSummary { + hash: string; + shortHash: string; + subject: string; + body: string; + authorName: string; + authorEmail: string; + when: string; + changeId?: string; +} + +const splitMessage = (message: string): [string, string] => { + const separator = message.indexOf("\n\n"); + if (separator === -1) return [message.trim(), ""]; + return [message.slice(0, separator).trim(), message.slice(separator + 2).trim()]; +}; + +export const toCommitSummary = (commit: LogCommit): CommitSummary => { + const [subject, body] = splitMessage(commit.message ?? ""); + const hash = commit.this ?? ""; + return { + hash, + shortHash: hash.slice(0, 8), + subject, + body, + authorName: commit.author?.Name ?? "", + authorEmail: commit.author?.Email ?? "", + when: commit.committer?.When ?? commit.author?.When ?? "", + changeId: commit.change_id + }; +}; + +export interface BranchSummary { + name: string; + hash: string; + when?: string; + isDefault: boolean; +} + +export const toBranchSummary = (branch: BranchEntry): BranchSummary => ({ + name: branch.reference.name, + hash: branch.reference.hash, + when: branch.commit?.Committer?.When ?? branch.commit?.Author?.When, + isDefault: branch.is_default === true +}); + +export interface TagSummary { + name: string; + hash: string; + /** an annotated tag has its own hash, this is the commit it points at */ + commitHash: string; + when?: string; + message?: string; +} + +const hexFromBytes = (bytes: number[]): string => + bytes.map((byte) => byte.toString(16).padStart(2, "0")).join(""); + +export const toTagSummary = (tag: TagEntry): TagSummary => { + const target = tag.tag?.Target; + return { + name: tag.name, + hash: tag.hash, + commitHash: target?.length ? hexFromBytes(target) : tag.hash, + when: tag.tag?.Tagger?.When, + message: tag.message ?? tag.tag?.Message + }; +}; + +export type TreeEntryKind = "file" | "directory" | "symlink" | "submodule"; + +// modes come back octal and zero padded +export const treeEntryKind = (mode: string): TreeEntryKind => { + switch (mode.replace(/^0+/, "").padStart(6, "0")) { + case "040000": + return "directory"; + case "120000": + return "symlink"; + case "160000": + return "submodule"; + default: + return "file"; + } +}; + +export interface TreeEntrySummary { + name: string; + kind: TreeEntryKind; + size: number; + lastCommitHash?: string; + lastCommitWhen?: string; + lastCommitMessage?: string; +} + +export const toTreeEntrySummary = (entry: Tree.TreeEntry): TreeEntrySummary => ({ + name: entry.name, + kind: treeEntryKind(entry.mode), + size: entry.size, + lastCommitHash: entry.last_commit?.hash, + lastCommitWhen: entry.last_commit?.when, + lastCommitMessage: entry.last_commit?.message +}); + +export const tagsByCommitHash = ( + commits: CommitSummary[], + tags: TagSummary[] +): Record => { + const shown = new Set(commits.map((commit) => commit.hash)); + return tags.reduce>((acc, tag) => { + if (shown.has(tag.commitHash)) (acc[tag.commitHash] ??= []).push(tag.name); + return acc; + }, {}); +}; + +export const sortTreeEntries = (entries: TreeEntrySummary[]): TreeEntrySummary[] => + [...entries].sort((a, b) => { + const aDir = a.kind === "directory" || a.kind === "submodule"; + const bDir = b.kind === "directory" || b.kind === "submodule"; + if (aDir !== bDir) return aDir ? -1 : 1; + return a.name.localeCompare(b.name); + }); + +export const logFor = ( + ctx: BobbinContext, + repo: string, + ref: string, + limit: number, + init?: XrpcRequestInit +) => knotLog(ctx, { repo, ref, limit }, init); + +export const branchesFor = ( + ctx: BobbinContext, + repo: string, + limit: number, + init?: XrpcRequestInit +) => knotBranches(ctx, { repo, limit }, init); + +export const tagsFor = (ctx: BobbinContext, repo: string, limit: number, init?: XrpcRequestInit) => + knotTags(ctx, { repo, limit }, init); diff --git a/web/src/lib/api/repoIndex.test.ts b/web/src/lib/api/repoIndex.test.ts new file mode 100644 index 00000000..8da78ef6 --- /dev/null +++ b/web/src/lib/api/repoIndex.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "vitest"; +import { ClientResponseError } from "./client"; +import { classifyRepoAvailability } from "./repoIndex"; + +const unsupported = () => + new ClientResponseError({ status: 404, data: { error: "XRPCNotSupported" } }); + +describe("classifyRepoAvailability", () => { + it("recognizes a legacy knot that does not expose repository endpoints", () => { + const result = classifyRepoAvailability( + [unsupported(), unsupported(), unsupported()].map((cause) => ({ value: null, error: cause })) + ); + + expect(result).toEqual({ needsUpgrade: true, knotUnreachable: false }); + }); + + it("keeps transport failures as unreachable", () => { + const result = classifyRepoAvailability( + ["tree", "log", "branches"].map(() => ({ value: null, error: new TypeError("offline") })) + ); + + expect(result).toEqual({ needsUpgrade: false, knotUnreachable: true }); + }); + + it("does not mistake a missing ref for an unavailable knot", () => { + const result = classifyRepoAvailability([ + { value: null, error: unsupported() }, + { value: null, error: unsupported() }, + { value: { branches: [] }, error: null } + ]); + + expect(result).toEqual({ needsUpgrade: false, knotUnreachable: false }); + }); +}); diff --git a/web/src/lib/api/repoIndex.ts b/web/src/lib/api/repoIndex.ts new file mode 100644 index 00000000..49ff046e --- /dev/null +++ b/web/src/lib/api/repoIndex.ts @@ -0,0 +1,249 @@ +import { error } from "@sveltejs/kit"; +import { ClientResponseError, createBobbinClient } from "$lib/api/client"; +import { languages as knotLanguages, tree as knotTree } from "$lib/api/knot"; +import { + branches as knotMirrorBranches, + createKnotMirrorClient, + languages as knotMirrorLanguages, + log as knotMirrorLog, + tags as knotMirrorTags, + tree as knotMirrorTree +} from "$lib/api/knotmirror"; +import { parallel } from "$lib/api/load"; +import { + branchesFor, + logFor, + sortTreeEntries, + tagsByCommitHash, + tagsFor, + toBranchSummary, + toCommitSummary, + toTagSummary, + toTreeCommitSummary, + toTreeEntrySummary +} from "$lib/api/repo"; +import { renderDocument } from "$lib/markup"; +import type { LanguageSlice, RepoInfo } from "$lib/components/repo/types"; +import type * as Tree from "./lexicons/types/sh/tangled/repo/tree"; + +// `/tree/{ref}` is this same page at another ref, so they share a load + +const COMMIT_LIMIT = 10; +const BRANCH_LIMIT = 5; +const TAG_LIMIT = 5; +// a knot only ever lists 100 refs, so any total we get is really a minimum +const REF_LIMIT = 100; + +export interface RepoParent { + publicConfig: { bobbinUrl: string; knotMirrorUrl: string; camoEnabled: boolean }; + repo: RepoInfo; +} + +export interface RepoLoadEvent { + fetch: typeof globalThis.fetch; + url: URL; +} + +interface RepoDataSource { + tree: (ref: string, path?: string) => Promise; + log: (ref: string, limit: number) => Promise>>; + branches: (limit: number) => Promise>>; + tags: (limit: number) => Promise>>; + languages: (ref: string) => Promise<{ languages?: { name: string; size: number }[] }>; +} + +const orNull = (promise: Promise): Promise => promise.catch(() => null); + +interface Attempt { + value: T | null; + error: unknown | null; +} + +const attempt = (promise: Promise): Promise> => + promise.then( + (value) => ({ value, error: null }), + (error) => ({ value: null, error }) + ); + +const isUnsupported = (cause: unknown): boolean => + cause instanceof ClientResponseError && cause.status === 404; + +export const classifyRepoAvailability = ( + attempts: readonly { value: unknown | null; error: unknown | null }[] +) => { + const needsUpgrade = attempts.every( + (result) => result.value === null && isUnsupported(result.error) + ); + return { + needsUpgrade, + knotUnreachable: !needsUpgrade && attempts.every((result) => result.value === null) + }; +}; + +const toLanguageSlices = (languages: { name: string; size: number }[]): LanguageSlice[] => { + const sized = languages.filter((language) => language.size > 0); + const total = sized.reduce((sum, language) => sum + language.size, 0); + if (total === 0) return []; + + const slices = sized.map((language) => { + const share = (language.size / total) * 100; + return { name: language.name, share, percentage: Math.floor(share) }; + }); + + const short = 100 - slices.reduce((sum, slice) => sum + slice.percentage, 0); + [...slices] + .sort((a, b) => (b.share % 1) - (a.share % 1) || b.share - a.share) + .slice(0, Math.max(0, short)) + .forEach((slice) => { + slice.percentage += 1; + }); + + return slices.sort((a, b) => b.share - a.share); +}; + +const refNames = (branches: { name: string }[], tags: { name: string }[]) => ({ + branches: branches.map((branch) => branch.name), + tags: tags.map((tag) => tag.name), + capped: branches.length >= REF_LIMIT || tags.length >= REF_LIMIT +}); + +const renderReadme = ( + readme: { filename: string; contents: string } | null, + parent: RepoParent, + event: RepoLoadEvent, + ref: string, + dir?: string +) => + readme + ? renderDocument(readme.filename, readme.contents, { + repo: `${parent.repo.ownerHandle}/${parent.repo.name}`, + ref, + dir, + host: event.url.host, + camo: parent.publicConfig.camoEnabled + }) + : Promise.resolve(null); + +// the knot sends a readme with empty fields when a directory has none +const readmeOf = (tree: { readme?: { filename: string; contents: string } } | null) => { + const readme = tree?.readme; + return readme?.filename ? readme : null; +}; + +const repoDataSource = (event: RepoLoadEvent, parent: RepoParent): RepoDataSource => { + if (parent.publicConfig.knotMirrorUrl && parent.repo.repoDid) { + const ctx = createKnotMirrorClient(parent.publicConfig.knotMirrorUrl, event.fetch); + const repo = parent.repo.repoDid; + return { + tree: (ref, path) => knotMirrorTree(ctx, { repo, ref, path }), + log: (ref, limit) => knotMirrorLog(ctx, { repo, ref, limit }), + branches: (limit) => knotMirrorBranches(ctx, { repo, limit }), + tags: (limit) => knotMirrorTags(ctx, { repo, limit }), + languages: (ref) => knotMirrorLanguages(ctx, { repo, ref }) + }; + } + + const ctx = createBobbinClient({ serviceUrl: parent.publicConfig.bobbinUrl, fetch: event.fetch }); + const repo = parent.repo.uri; + return { + tree: (ref, path) => knotTree(ctx, { repo, ref, path }), + log: (ref, limit) => logFor(ctx, repo, ref, limit), + branches: (limit) => branchesFor(ctx, repo, limit), + tags: (limit) => tagsFor(ctx, repo, limit), + languages: (ref) => knotLanguages(ctx, { repo, ref }) + }; +}; + +export interface RepoIndexOptions { + requireRef?: boolean; +} + +export const loadRepoIndex = async ( + event: RepoLoadEvent, + parent: RepoParent, + ref: string, + // a ref from the url has to resolve or a typo looks like a repo with no + // files. the default branch renders whatever the knot managed to answer + { requireRef = false }: RepoIndexOptions = {} +) => { + const source = repoDataSource(event, parent); + + // each list falls back on its own, so half a page still renders + const results = await parallel({ + tree: attempt(source.tree(ref)), + log: attempt(source.log(ref, COMMIT_LIMIT)), + branches: attempt(source.branches(REF_LIMIT)), + tags: attempt(source.tags(REF_LIMIT)), + languages: attempt(source.languages(ref)) + }); + + const branches = (results.branches.value?.branches ?? []).map(toBranchSummary); + const tags = (results.tags.value?.tags ?? []).map(toTagSummary); + const commits = (results.log.value?.commits ?? []).map(toCommitSummary); + const files = sortTreeEntries((results.tree.value?.files ?? []).map(toTreeEntrySummary)); + + const languages = toLanguageSlices(results.languages.value?.languages ?? []); + + const readme = readmeOf(results.tree.value); + const readmeHtml = await renderReadme(readme, parent, event, ref); + + const contentAttempts = [results.tree, results.log, results.branches]; + const { needsUpgrade, knotUnreachable } = classifyRepoAvailability(contentAttempts); + const isEmpty = !knotUnreachable && files.length === 0 && branches.length === 0; + + // there are refs but not this one, so it is not a real ref. an empty repo has + // no refs at all and still gets a page + if (requireRef && results.tree.value === null && branches.length > 0) { + error(404, `${ref} does not exist in this repository`); + } + + return { + ref, + isEmpty, + needsUpgrade, + knotUnreachable, + files, + readme, + readmeHtml, + commits, + tagsByCommit: tagsByCommitHash(commits, tags), + totalCommits: results.log.value?.total ?? commits.length, + branches: branches.slice(0, BRANCH_LIMIT), + totalBranches: branches.length, + tags: tags.slice(0, TAG_LIMIT), + totalTags: tags.length, + // the switcher needs every ref, not just the visible slice + refs: refNames(branches, tags), + languages + }; +}; + +export const loadRepoTree = async ( + event: RepoLoadEvent, + parent: RepoParent, + ref: string, + path: string +) => { + const source = repoDataSource(event, parent); + + // the tree is the whole page here, so a miss is just a 404 + const tree = await orNull(source.tree(ref, path)); + const files = sortTreeEntries((tree?.files ?? []).map(toTreeEntrySummary)); + // git cannot store an empty directory. so nothing here means the path is a + // file, or was never there + if (tree === null || files.length === 0) { + error(404, `${path} does not exist at ${ref}`); + } + + const readme = readmeOf(tree); + const readmeHtml = await renderReadme(readme, parent, event, ref, path); + + return { + ref, + path, + files, + readme, + readmeHtml, + lastCommit: tree.lastCommit ? toTreeCommitSummary(tree.lastCommit) : null + }; +}; diff --git a/web/src/lib/components/repo/BranchList.stories.svelte b/web/src/lib/components/repo/BranchList.stories.svelte new file mode 100644 index 00000000..3afc24ab --- /dev/null +++ b/web/src/lib/components/repo/BranchList.stories.svelte @@ -0,0 +1,39 @@ + + + + + + diff --git a/web/src/lib/components/repo/BranchList.svelte b/web/src/lib/components/repo/BranchList.svelte new file mode 100644 index 00000000..6c0b47af --- /dev/null +++ b/web/src/lib/components/repo/BranchList.svelte @@ -0,0 +1,57 @@ + + +
+ {#each branches as branch (branch.name)} +
+
+ + {branch.name} + + {#if branch.when} + + + {/if} + {#if branch.isDefault} + Default + {/if} +
+ {#if branch.name !== currentRef} + + + {/if} +
+ {/each} +
diff --git a/web/src/lib/components/repo/CloneDropdown.stories.svelte b/web/src/lib/components/repo/CloneDropdown.stories.svelte new file mode 100644 index 00000000..11d333aa --- /dev/null +++ b/web/src/lib/components/repo/CloneDropdown.stories.svelte @@ -0,0 +1,51 @@ + + + + + + diff --git a/web/src/lib/components/repo/CloneDropdown.svelte b/web/src/lib/components/repo/CloneDropdown.svelte new file mode 100644 index 00000000..a56b0fb4 --- /dev/null +++ b/web/src/lib/components/repo/CloneDropdown.svelte @@ -0,0 +1,128 @@ + + + + {#snippet trigger()} + diff --git a/web/src/lib/components/repo/CommitList.stories.svelte b/web/src/lib/components/repo/CommitList.stories.svelte new file mode 100644 index 00000000..178d6ce1 --- /dev/null +++ b/web/src/lib/components/repo/CommitList.stories.svelte @@ -0,0 +1,57 @@ + + + + + diff --git a/web/src/lib/components/repo/CommitList.svelte b/web/src/lib/components/repo/CommitList.svelte new file mode 100644 index 00000000..323b4335 --- /dev/null +++ b/web/src/lib/components/repo/CommitList.svelte @@ -0,0 +1,69 @@ + + +
+ {#each commits as commit (commit.hash)} +
+
+ + {commit.subject} + + {#if commit.body} + + {/if} +
+ + {#if commit.body && expanded[commit.hash]} +

{commit.body}

+ {/if} + +
+ + {commit.shortHash} + + {#if commit.authorName} + {commit.authorName} + {/if} + {#if commit.when} + + + {/if} + {#each tagsByCommit[commit.hash] ?? [] as name (name)} + {name} + {/each} +
+
+ {/each} +
diff --git a/web/src/lib/components/repo/EmptyRepo.stories.svelte b/web/src/lib/components/repo/EmptyRepo.stories.svelte new file mode 100644 index 00000000..a4439408 --- /dev/null +++ b/web/src/lib/components/repo/EmptyRepo.stories.svelte @@ -0,0 +1,36 @@ + + + + + + + + + + + + diff --git a/web/src/lib/components/repo/EmptyRepo.svelte b/web/src/lib/components/repo/EmptyRepo.svelte new file mode 100644 index 00000000..5879e878 --- /dev/null +++ b/web/src/lib/components/repo/EmptyRepo.svelte @@ -0,0 +1,56 @@ + + +{#snippet bullet(n: number)} + + {n} + +{/snippet} + +{#if isOwner} +
+
+

This is an empty repository. To get started:

+

+ {@render bullet(1)}First, generate a new + SSH key pair. +

+

+ {@render bullet(2)}Then add the public key from the + keys page in your settings. +

+

+ {@render bullet(3)}Configure your remote to + {remote} +

+

{@render bullet(4)}Push!

+
+
+{:else} +

This is an empty repository.

+{/if} diff --git a/web/src/lib/components/repo/FileTree.svelte b/web/src/lib/components/repo/FileTree.svelte new file mode 100644 index 00000000..4ad36ad4 --- /dev/null +++ b/web/src/lib/components/repo/FileTree.svelte @@ -0,0 +1,70 @@ + + +
+ {#each entries as entry (entry.name)} + {@const Glyph = iconFor(entry)} +
+ + +
+ {#if entry.lastCommitHash && entry.lastCommitWhen} + + + + {/if} +
+
+ {/each} +
diff --git a/web/src/lib/components/repo/LanguageBar.stories.svelte b/web/src/lib/components/repo/LanguageBar.stories.svelte new file mode 100644 index 00000000..5118d308 --- /dev/null +++ b/web/src/lib/components/repo/LanguageBar.stories.svelte @@ -0,0 +1,40 @@ + + + + + + diff --git a/web/src/lib/components/repo/LanguageBar.svelte b/web/src/lib/components/repo/LanguageBar.svelte new file mode 100644 index 00000000..9d6d508d --- /dev/null +++ b/web/src/lib/components/repo/LanguageBar.svelte @@ -0,0 +1,44 @@ + + +
+ + {#each languages as language (language.name)} +
+ {/each} +
+
+ {#each languages as language (language.name)} +
+ + + {language.name} + {percent(language)}% + +
+ {/each} +
+
diff --git a/web/src/lib/components/repo/PanelHeader.stories.svelte b/web/src/lib/components/repo/PanelHeader.stories.svelte new file mode 100644 index 00000000..ad99ac0a --- /dev/null +++ b/web/src/lib/components/repo/PanelHeader.stories.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/web/src/lib/components/repo/PanelHeader.svelte b/web/src/lib/components/repo/PanelHeader.svelte new file mode 100644 index 00000000..c14a300d --- /dev/null +++ b/web/src/lib/components/repo/PanelHeader.svelte @@ -0,0 +1,29 @@ + + + + diff --git a/web/src/lib/components/repo/Readme.svelte b/web/src/lib/components/repo/Readme.svelte new file mode 100644 index 00000000..284f400a --- /dev/null +++ b/web/src/lib/components/repo/Readme.svelte @@ -0,0 +1,22 @@ + + +
+
+ + +
+
+
{contents}
+
+
diff --git a/web/src/lib/components/repo/RefSelector.stories.svelte b/web/src/lib/components/repo/RefSelector.stories.svelte new file mode 100644 index 00000000..ac18f8f3 --- /dev/null +++ b/web/src/lib/components/repo/RefSelector.stories.svelte @@ -0,0 +1,22 @@ + + + + + + diff --git a/web/src/lib/components/repo/RefSelector.svelte b/web/src/lib/components/repo/RefSelector.svelte new file mode 100644 index 00000000..9e290826 --- /dev/null +++ b/web/src/lib/components/repo/RefSelector.svelte @@ -0,0 +1,56 @@ + + +
+
+ + +
+ + +
diff --git a/web/src/lib/components/repo/RepoHeader.stories.svelte b/web/src/lib/components/repo/RepoHeader.stories.svelte new file mode 100644 index 00000000..aac58e37 --- /dev/null +++ b/web/src/lib/components/repo/RepoHeader.stories.svelte @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + diff --git a/web/src/lib/components/repo/RepoHeader.svelte b/web/src/lib/components/repo/RepoHeader.svelte new file mode 100644 index 00000000..9231ea99 --- /dev/null +++ b/web/src/lib/components/repo/RepoHeader.svelte @@ -0,0 +1,130 @@ + + +
+
+
+ + + {#if repo.source} + + {/if} +
+ +
+ {#if signedIn} + + {:else} + + + {/if} + +
+ + +
+
+
+ +
+ {#if repo.description} + {repo.description} + {:else} + This repository has no description + {/if} + + {#if repo.website} + + + {/if} + + {#if repo.topics?.length} +
+ {#each repo.topics as topic (topic)} + {topic} + {/each} +
+ {/if} +
+
diff --git a/web/src/lib/components/repo/RepoIndexView.stories.svelte b/web/src/lib/components/repo/RepoIndexView.stories.svelte new file mode 100644 index 00000000..e0d8481d --- /dev/null +++ b/web/src/lib/components/repo/RepoIndexView.stories.svelte @@ -0,0 +1,99 @@ + + + + + + + + + + + diff --git a/web/src/lib/components/repo/RepoIndexView.svelte b/web/src/lib/components/repo/RepoIndexView.svelte new file mode 100644 index 00000000..00df70c6 --- /dev/null +++ b/web/src/lib/components/repo/RepoIndexView.svelte @@ -0,0 +1,140 @@ + + +
+ {#if data.needsUpgrade} +
+
+ + +

+ This repository is currently unavailable. + Read the upgrade guide +

+
+
+ {:else if data.knotUnreachable} +
+ + +
+ {:else if data.isEmpty} + + {:else} + {#if data.languages.length > 0} + + {/if} + + + +
+
+ +
+ + +
+ {/if} +
+ +{#if data.readme} + +{/if} diff --git a/web/src/lib/components/repo/RepoTabs.stories.svelte b/web/src/lib/components/repo/RepoTabs.stories.svelte new file mode 100644 index 00000000..5cae6f35 --- /dev/null +++ b/web/src/lib/components/repo/RepoTabs.stories.svelte @@ -0,0 +1,31 @@ + + + + + + diff --git a/web/src/lib/components/repo/RepoTabs.svelte b/web/src/lib/components/repo/RepoTabs.svelte new file mode 100644 index 00000000..0e927d0b --- /dev/null +++ b/web/src/lib/components/repo/RepoTabs.svelte @@ -0,0 +1,39 @@ + + + diff --git a/web/src/lib/components/repo/TagList.stories.svelte b/web/src/lib/components/repo/TagList.stories.svelte new file mode 100644 index 00000000..0aad46a4 --- /dev/null +++ b/web/src/lib/components/repo/TagList.stories.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/web/src/lib/components/repo/TagList.svelte b/web/src/lib/components/repo/TagList.svelte new file mode 100644 index 00000000..56c0a3e7 --- /dev/null +++ b/web/src/lib/components/repo/TagList.svelte @@ -0,0 +1,39 @@ + + +
+ {#each tags as tag, index (tag.name)} +
+ +
+ {#if tag.when} + + {/if} + {#if index === 0} + Latest + {/if} +
+
+ {/each} +
diff --git a/web/src/lib/components/repo/language-colors.ts b/web/src/lib/components/repo/language-colors.ts new file mode 100644 index 00000000..6caa51a8 --- /dev/null +++ b/web/src/lib/components/repo/language-colors.ts @@ -0,0 +1,672 @@ +// language colours as the appview renders them, ported from go-enry's +// LanguagesColor, itself extracted from github/linguist 537297cdae3a +// the knot names languages with enry too, so these keys line up + +export const LANGUAGE_COLORS: Record = { + "1C Enterprise": "#814CCC", + "2-Dimensional Array": "#38761D", + "4D": "#004289", + ABAP: "#E8274B", + "ABAP CDS": "#555e25", + "AGS Script": "#B9D9FF", + AIDL: "#34EB6B", + AL: "#3AA2B5", + ALGOL: "#D1E0DB", + AMPL: "#E6EFBB", + ANTLR: "#9DC3FF", + "API Blueprint": "#2ACCA8", + APL: "#5A8164", + "ASP.NET": "#9400ff", + ATS: "#1ac620", + ActionScript: "#882B0F", + Ada: "#02f88c", + "Adblock Filter List": "#800000", + "Adobe Font Metrics": "#fa0f00", + Agda: "#315665", + Aiken: "#640ff8", + Alloy: "#64C800", + "Alpine Abuild": "#0D597F", + "Altium Designer": "#A89663", + AngelScript: "#C7D7DC", + "Answer Set Programming": "#A9CC29", + "Ant Build System": "#A9157E", + Antlers: "#ff269e", + ApacheConf: "#d12127", + Apex: "#1797c0", + "Apollo Guidance Computer": "#0B3D91", + AppleScript: "#101F1F", + Arc: "#aa2afe", + AsciiDoc: "#73a0c5", + AspectJ: "#a957b0", + Assembly: "#6E4C13", + Astro: "#ff5a03", + Asymptote: "#ff0000", + Augeas: "#9CC134", + AutoHotkey: "#6594b9", + AutoIt: "#1C3552", + "Avro IDL": "#0040FF", + Awk: "#c30e9b", + "B (Formal Method)": "#8aa8c5", + B4X: "#00e4ff", + BASIC: "#ff0000", + BQN: "#2b7067", + Ballerina: "#FF5000", + Batchfile: "#C1F12E", + Beef: "#a52f4e", + Berry: "#15A13C", + BibTeX: "#778899", + Bicep: "#519aba", + Bikeshed: "#5562ac", + Bison: "#6A463F", + BitBake: "#00bce4", + Blade: "#f7523f", + BlitzBasic: "#00FFAE", + BlitzMax: "#cd6400", + Bluespec: "#12223c", + "Bluespec BH": "#12223c", + Boo: "#d4bec1", + Boogie: "#c80fa0", + Brainfuck: "#2F2530", + BrighterScript: "#66AABB", + Brightscript: "#662D91", + Browserslist: "#ffd539", + Bru: "#F4AA41", + BuildStream: "#006bff", + C: "#555555", + "C#": "#178600", + "C++": "#f34b7d", + C3: "#2563eb", + "CAP CDS": "#0092d1", + CLIPS: "#00A300", + CMake: "#DA3434", + COLLADA: "#F1A42B", + CQL: "#006091", + CSON: "#244776", + CSS: "#663399", + CSV: "#237346", + CUE: "#5886E1", + CWeb: "#00007a", + "Cabal Config": "#483465", + Caddyfile: "#22b638", + Cadence: "#00ef8b", + Cairo: "#ff4a48", + "Cairo Zero": "#ff4a48", + CameLIGO: "#3be133", + Cangjie: "#00868B", + "Cap'n Proto": "#c42727", + Carbon: "#222222", + Ceylon: "#dfa535", + Chapel: "#8dc63f", + ChucK: "#3f8000", + Circom: "#707575", + Cirru: "#ccccff", + Clarion: "#db901e", + Clarity: "#5546ff", + "Classic ASP": "#6a40fd", + Clean: "#3F85AF", + Click: "#E4E6F3", + Clojure: "#db5855", + "Closure Templates": "#0d948f", + "Cloud Firestore Security Rules": "#FFA000", + Clue: "#0009b5", + CodeQL: "#140f46", + CoffeeScript: "#244776", + ColdFusion: "#ed2cd6", + "ColdFusion CFC": "#ed2cd6", + "Common Lisp": "#3fb68b", + "Common Workflow Language": "#B5314C", + "Component Pascal": "#B0CE4E", + Cooklang: "#E15A29", + Crystal: "#000100", + Csound: "#1a1a1a", + "Csound Document": "#1a1a1a", + "Csound Score": "#1a1a1a", + Cuda: "#3A4E3A", + Curry: "#531242", + Cylc: "#00b3fd", + Cypher: "#34c0eb", + Cython: "#fedf5b", + D: "#ba595e", + D2: "#526ee8", + DM: "#447265", + Dafny: "#FFEC25", + "Darcs Patch": "#8eff23", + Dart: "#00B4AB", + Daslang: "#d3d3d3", + DataWeave: "#003a52", + "Debian Package Control File": "#D70751", + DenizenScript: "#FBEE96", + Dhall: "#dfafff", + "DirectX 3D File": "#aace60", + Dockerfile: "#384d54", + Dogescript: "#cca760", + Dotenv: "#e5d559", + Dune: "#89421e", + Dylan: "#6c616e", + E: "#ccce35", + ECL: "#8a1267", + ECLiPSe: "#001d9d", + EJS: "#a91e50", + EQ: "#a78649", + Earthly: "#2af0ff", + Easybuild: "#069406", + "Ecere Projects": "#913960", + Ecmarkup: "#eb8131", + Edge: "#0dffe0", + EdgeQL: "#31A7FF", + EditorConfig: "#fff1f2", + Eiffel: "#4d6977", + Elixir: "#6e4a7e", + Elm: "#60B5CC", + Elvish: "#55BB55", + "Elvish Transcript": "#55BB55", + "Emacs Lisp": "#c065db", + EmberScript: "#FFF4F3", + Erlang: "#B83998", + Euphoria: "#FF790B", + "F#": "#b845fc", + "F*": "#572e30", + "FIGlet Font": "#FFDDBB", + FIRRTL: "#2f632f", + FLUX: "#88ccff", + Factor: "#636746", + Fancy: "#7b9db4", + Fantom: "#14253c", + Faust: "#c37240", + Fennel: "#fff3d7", + "Filebench WML": "#F6B900", + FlatBuffers: "#ed284a", + Flix: "#d44a45", + Fluent: "#ffcc33", + Forth: "#341708", + Fortran: "#4d41b1", + "Fortran Free Form": "#4d41b1", + FreeBASIC: "#141AC9", + FreeMarker: "#0050b2", + Frege: "#00cafe", + Futhark: "#5f021f", + "G-code": "#D08CF2", + GAML: "#FFC766", + GAMS: "#f49a22", + GAP: "#0000cc", + "GCC Machine Description": "#FFCFAB", + GDScript: "#355570", + GDShader: "#478CBF", + GEDCOM: "#003058", + GLSL: "#5686a5", + GSC: "#FF6800", + "Game Maker Language": "#71b417", + "Gemfile.lock": "#701516", + Gemini: "#ff6900", + "Genero 4gl": "#63408e", + "Genero per": "#d8df39", + Genie: "#fb855d", + Genshi: "#951531", + "Gentoo Ebuild": "#9400ff", + "Gentoo Eclass": "#9400ff", + "Gerber Image": "#d20b00", + Gherkin: "#5B2063", + "Git Attributes": "#F44D27", + "Git Commit": "#F44D27", + "Git Config": "#F44D27", + "Git Revision List": "#F44D27", + Gleam: "#ffaff3", + "Glimmer JS": "#F5835F", + "Glimmer TS": "#3178c6", + Glyph: "#c1ac7f", + Gnuplot: "#f0a9f0", + Go: "#00ADD8", + "Go Checksums": "#00ADD8", + "Go Module": "#00ADD8", + "Go Template": "#00ADD8", + "Go Workspace": "#00ADD8", + "Godot Resource": "#355570", + Golo: "#88562A", + Gosu: "#82937f", + Grace: "#615f8b", + Gradle: "#02303a", + "Gradle Kotlin DSL": "#02303a", + "Grammatical Framework": "#ff0000", + GraphQL: "#e10098", + "Graphviz (DOT)": "#2596be", + Groovy: "#4298b8", + "Groovy Server Pages": "#4298b8", + HAProxy: "#106da9", + HCL: "#844FBA", + HIP: "#4F3A4F", + HLSL: "#aace60", + HOCON: "#9ff8ee", + HTML: "#e34c26", + "HTML+ECR": "#2e1052", + "HTML+EEX": "#6e4a7e", + "HTML+ERB": "#701516", + "HTML+PHP": "#4f5d95", + "HTML+Razor": "#512be4", + HTTP: "#005C9C", + HXML: "#f68712", + Hack: "#878787", + Haml: "#ece2a9", + Handlebars: "#f7931e", + Harbour: "#0e60e3", + Hare: "#9d7424", + Haskell: "#5e5086", + Haxe: "#df7900", + HiveQL: "#dce200", + HolyC: "#ffefaf", + "Hosts File": "#308888", + Hurl: "#FF0288", + Hy: "#7790B2", + IDL: "#a3522f", + "IGOR Pro": "#0000cc", + INI: "#d1dbe0", + ISPC: "#2D68B1", + Idris: "#b30000", + "Ignore List": "#000000", + "ImageJ Macro": "#99AAFF", + Imba: "#16cec6", + "Inno Setup": "#264b99", + Io: "#a9188d", + Ioke: "#078193", + Isabelle: "#FEFE00", + "Isabelle ROOT": "#FEFE00", + J: "#9EEDFF", + "JAR Manifest": "#b07219", + JCL: "#d90e09", + JFlex: "#DBCA00", + JSON: "#292929", + "JSON with Comments": "#292929", + JSON5: "#267CB9", + JSONLD: "#0c479c", + JSONiq: "#40d47e", + Jac: "#FC792D", + Jai: "#ab8b4b", + Janet: "#0886a5", + Jasmin: "#d03600", + Java: "#b07219", + "Java Properties": "#2A6277", + "Java Server Pages": "#2A6277", + "Java Template Engine": "#2A6277", + JavaScript: "#f1e05a", + "JavaScript+ERB": "#f1e05a", + "Jest Snapshot": "#15c213", + "JetBrains MPS": "#21D789", + Jinja: "#a52a22", + Jison: "#56b3cb", + "Jison Lex": "#56b3cb", + Jolie: "#843179", + Jsonnet: "#0064bd", + Julia: "#a270ba", + "Julia REPL": "#a270ba", + "Jupyter Notebook": "#DA5B0B", + Just: "#384d54", + KCL: "#7ABABF", + KDL: "#ffb3b3", + KFramework: "#4195c5", + KRL: "#28430A", + "Kaitai Struct": "#773b37", + KakouneScript: "#6f8042", + KerboScript: "#41adf0", + "KiCad Layout": "#2f4aab", + "KiCad Legacy Layout": "#2f4aab", + "KiCad Schematic": "#2f4aab", + "KoLmafia ASH": "#B9D9B9", + Koka: "#215166", + Kotlin: "#A97BFF", + LFE: "#4C3023", + LLVM: "#185619", + LOLCODE: "#cc9900", + LSL: "#3d9970", + LabVIEW: "#fede06", + Lambdapi: "#8027a3", + Langium: "#2c8c87", + Lark: "#2980B9", + Lasso: "#999999", + Latte: "#f2a542", + Leo: "#C4FFC2", + Less: "#1d365d", + Lex: "#DBCA00", + LigoLANG: "#0e74ff", + LilyPond: "#9ccc7c", + Liquid: "#67b8de", + Liquidsoap: "#990066", + "Literate Agda": "#315665", + "Literate CoffeeScript": "#244776", + "Literate Haskell": "#5e5086", + "LiveCode Script": "#0c5ba5", + LiveScript: "#499886", + Logtalk: "#295b9a", + LookML: "#652B81", + Lua: "#000080", + Luau: "#00A2FF", + M3U: "#179C7D", + MATLAB: "#e16737", + MAXScript: "#00a6a6", + MDX: "#fcb32c", + MLIR: "#5EC8DB", + MQL4: "#62A8D6", + MQL5: "#4A76B8", + MTML: "#b7e1f4", + Macaulay2: "#d8ffff", + Makefile: "#427819", + Mako: "#7e858d", + Markdown: "#083fa1", + Marko: "#42bff2", + Mask: "#f97732", + "Mathematical Programming System": "#0530ad", + Max: "#c4a79c", + MeTTa: "#6a5acd", + Mercury: "#ff2b2b", + Mermaid: "#ff3670", + Meson: "#007800", + Metal: "#8f14e9", + MiniYAML: "#ff1111", + MiniZinc: "#06a9e6", + Mint: "#02b046", + Mirah: "#c7a938", + Modelica: "#de1d31", + "Modula-2": "#10253f", + "Modula-3": "#223388", + Mojo: "#ff4c1f", + "Monkey C": "#8D6747", + MoonBit: "#b92381", + MoonScript: "#ff4585", + Motoko: "#fbb03b", + "Motorola 68K Assembly": "#005daa", + Move: "#4a137a", + Mustache: "#724b3b", + NCL: "#28431f", + NMODL: "#00356B", + "NPM Config": "#cb3837", + NWScript: "#111522", + Nasal: "#1d2c4e", + Nearley: "#990000", + Nemerle: "#3d3c6e", + NetLinx: "#0aa0ff", + "NetLinx+ERB": "#747faa", + NetLogo: "#ff6375", + NewLisp: "#87AED7", + Nextflow: "#3ac486", + Nginx: "#009639", + Nickel: "#E0C3FC", + Nim: "#ffc200", + Nit: "#009917", + Nix: "#7e7eff", + Noir: "#2f1f49", + Nu: "#c9df40", + NumPy: "#9C8AF9", + Nunjucks: "#3d8137", + Nushell: "#4E9906", + "OASv2-json": "#85ea2d", + "OASv2-yaml": "#85ea2d", + "OASv3-json": "#85ea2d", + "OASv3-yaml": "#85ea2d", + OCaml: "#ef7a08", + "OMNeT++ MSG": "#a0e0a0", + "OMNeT++ NED": "#08607c", + ObjectScript: "#424893", + "Objective-C": "#438eff", + "Objective-C++": "#6866fb", + "Objective-J": "#ff0c5a", + Odin: "#60AFFE", + Omgrofl: "#cabbff", + Opal: "#f7ede0", + "Open Policy Agent": "#7d9199", + "OpenAPI Specification v2": "#85ea2d", + "OpenAPI Specification v3": "#85ea2d", + OpenCL: "#ed2e2d", + "OpenEdge ABL": "#5ce600", + OpenQASM: "#AA70FF", + OpenSCAD: "#e5cd45", + "Option List": "#476732", + Org: "#77aa99", + OverpassQL: "#cce2aa", + Oxygene: "#cdd0e3", + Oz: "#fab738", + P4: "#7055b5", + PDDL: "#0d00ff", + "PEG.js": "#234d6b", + PHP: "#4F5D95", + PLSQL: "#dad8d8", + PLpgSQL: "#336790", + "POV-Ray SDL": "#6bac65", + Pact: "#F7A8B8", + Pan: "#cc0000", + Papyrus: "#6600cc", + Parrot: "#f3ca0a", + Pascal: "#E3F171", + Pawn: "#dbb284", + Pep8: "#C76F5B", + Perl: "#0298c3", + PicoLisp: "#6067af", + PigLatin: "#fcd7de", + Pike: "#005390", + "Pip Requirements": "#FFD343", + Pkl: "#6b9543", + PlantUML: "#fbbd16", + PogoScript: "#d80074", + Polar: "#ae81ff", + Portugol: "#f8bd00", + PostCSS: "#dc3a0c", + PostScript: "#da291c", + PowerBuilder: "#8f0f8d", + PowerShell: "#012456", + Praat: "#c8506d", + Prisma: "#0c344b", + Processing: "#0096D8", + Procfile: "#3B2F63", + Prolog: "#74283c", + Promela: "#de0000", + "Propeller Spin": "#7fa2a7", + Pug: "#a86454", + Puppet: "#302B6D", + PureBasic: "#5a6986", + PureScript: "#1D222D", + Pyret: "#ee1e10", + Python: "#3572A5", + "Python console": "#3572A5", + "Python traceback": "#3572A5", + "Q#": "#fed659", + QML: "#44a51c", + "Qt Script": "#00b841", + Quake: "#882233", + QuakeC: "#975777", + QuickBASIC: "#008080", + R: "#198CE7", + RAML: "#77d9fb", + RAScript: "#2C97FA", + RBS: "#701516", + RDoc: "#701516", + REXX: "#d90e09", + RMarkdown: "#198ce7", + RON: "#a62c00", + "ROS Interface": "#22314e", + RPGLE: "#2BDE21", + RUNOFF: "#665a4e", + Racket: "#3c5caa", + Ragel: "#9d5200", + Raku: "#0000fb", + Rascal: "#fffaa0", + ReScript: "#ed5051", + Reason: "#ff5847", + ReasonLIGO: "#ff5847", + Rebol: "#358a5b", + "Record Jar": "#0673ba", + Red: "#f50000", + "Regular Expression": "#009a00", + "Ren'Py": "#ff7f7f", + Rez: "#FFDAB3", + Ring: "#2D54CB", + Riot: "#A71E49", + RobotFramework: "#00c0b5", + Roc: "#7c38f5", + "Rocq Prover": "#d0b68c", + Roff: "#ecdebe", + "Roff Manpage": "#ecdebe", + Rouge: "#cc0088", + "RouterOS Script": "#DE3941", + Ruby: "#701516", + Rust: "#dea584", + SAS: "#B34936", + SCSS: "#c6538c", + SPARQL: "#0C4597", + SQF: "#3F3F3F", + SQL: "#e38c00", + SQLPL: "#e38c00", + "SRecode Template": "#348a34", + STL: "#373b5e", + SVG: "#ff9900", + Sail: "#259dd5", + SaltStack: "#646464", + Sass: "#a53b70", + Scala: "#c22d40", + Scaml: "#bd181a", + Scenic: "#fdc700", + Scheme: "#1e4aec", + Scilab: "#ca0f21", + Self: "#0579aa", + ShaderLab: "#222c37", + Shell: "#89e051", + "ShellCheck Config": "#cecfcb", + Shen: "#120F14", + "Simple File Verification": "#C9BFED", + Singularity: "#64E6AD", + Slang: "#1fbec9", + Slash: "#007eff", + Slice: "#003fa2", + Slim: "#2b2b2b", + Slint: "#2379F4", + SmPL: "#c94949", + Smalltalk: "#596706", + Smarty: "#f0c040", + Smithy: "#c44536", + Snakemake: "#419179", + Solidity: "#AA6746", + SourcePawn: "#f69e1d", + Squirrel: "#800000", + Stan: "#b2011d", + "Standard ML": "#dc566d", + Starlark: "#76d275", + Stata: "#1a5f91", + StringTemplate: "#3fb34f", + Stylus: "#ff6347", + "SubRip Text": "#9e0101", + SugarSS: "#2fcc9f", + SuperCollider: "#46390b", + SurrealQL: "#ff00a0", + "Survex data": "#ffcc99", + Svelte: "#ff3e00", + Sway: "#00F58C", + Sweave: "#198ce7", + Swift: "#F05138", + SystemVerilog: "#DAE1C2", + "TI Program": "#A0AA87", + "TL-Verilog": "#C40023", + TLA: "#4b0079", + TMDL: "#f0c913", + TOML: "#9c4221", + TSQL: "#e38c00", + TSV: "#237346", + TSX: "#3178c6", + TXL: "#0178b8", + Tact: "#48b5ff", + Talon: "#333333", + Tcl: "#e4cc98", + TeX: "#3D6117", + Teal: "#00B1BC", + Terra: "#00004c", + "Terraform Template": "#7b42bb", + TextGrid: "#c8506d", + "TextMate Properties": "#df66e4", + Textile: "#ffe7ac", + Thrift: "#D12127", + Toit: "#c2c9fb", + "Tor Config": "#59316b", + "Tree-sitter Query": "#8ea64c", + Turing: "#cf142b", + Twig: "#c1d026", + TypeScript: "#3178c6", + TypeSpec: "#4A3665", + Typst: "#239dad", + "Unified Parallel C": "#4e3617", + "Unity3D Asset": "#222c37", + Uno: "#9933cc", + UnrealScript: "#a54c4d", + "Untyped Plutus Core": "#36adbd", + UrWeb: "#ccccee", + V: "#4f87c4", + VBA: "#867db1", + VBScript: "#15dcdc", + VCL: "#148AA8", + VHDL: "#adb2cb", + Vala: "#a56de2", + "Valve Data Format": "#f26025", + "Velocity Template Language": "#507cff", + Vento: "#ff0080", + Verilog: "#b2b7f8", + "Vim Help File": "#199f4b", + "Vim Script": "#199f4b", + "Vim Snippet": "#199f4b", + "Visual Basic .NET": "#945db7", + "Visual Basic 6.0": "#2c6353", + Volt: "#1F1F1F", + Vue: "#41b883", + Vyper: "#9F4CF2", + WDL: "#42f1f4", + WGSL: "#1a5e9a", + "Web Ontology Language": "#5b70bd", + WebAssembly: "#04133b", + "WebAssembly Interface Type": "#6250e7", + Whiley: "#d5c397", + Wikitext: "#fc5757", + "Windows Registry Entries": "#52d5ff", + "Witcher Script": "#ff0000", + "Wolfram Language": "#dd1100", + Wollok: "#a23738", + "World of Warcraft Addon Data": "#f7e43f", + Wren: "#383838", + X10: "#4B6BEF", + XC: "#99DA07", + XML: "#0060ac", + "XML Property List": "#0060ac", + XQuery: "#5232e7", + XSLT: "#EB8CEB", + Xmake: "#22a079", + Xojo: "#81bd41", + Xonsh: "#285EEF", + Xtend: "#24255d", + YAML: "#cb171e", + YARA: "#220000", + YASnippet: "#32AB90", + Yacc: "#4B6C4B", + Yul: "#794932", + ZAP: "#0d665e", + ZIL: "#dc75e5", + ZenScript: "#00BCD1", + Zephir: "#118f9e", + Zig: "#ec915c", + Zimpl: "#d67711", + Zmodel: "#ff7100", + crontab: "#ead7ac", + eC: "#913960", + fish: "#4aae47", + hoon: "#00b171", + iCalendar: "#ec564c", + jq: "#c7254e", + kvlang: "#1da6e0", + "mIRC Script": "#3d57c3", + mcfunction: "#E22837", + mdsvex: "#5f9ea0", + mupad: "#244963", + nanorc: "#2d004d", + nesC: "#94B0C7", + ooc: "#b0b77e", + q: "#0040cd", + reStructuredText: "#141414", + sed: "#64b970", + templ: "#66D0DD", + vCard: "#ee2647", + wisp: "#7582D1", + xBase: "#403a40" +}; + +export const LANGUAGE_COLOR_FALLBACK = "#cccccc"; diff --git a/web/src/lib/components/repo/types.ts b/web/src/lib/components/repo/types.ts new file mode 100644 index 00000000..03f283ef --- /dev/null +++ b/web/src/lib/components/repo/types.ts @@ -0,0 +1,42 @@ +import type { BranchSummary, CommitSummary, TagSummary, TreeEntrySummary } from "$lib/api/repo"; + +export type { BranchSummary, CommitSummary, TagSummary, TreeEntrySummary }; + +/** the repo every page under [handle]/[repo] is scoped to */ +export interface RepoInfo { + uri: string; + rkey: string; + name: string; + ownerDid: string; + ownerHandle: string; + ownerAvatar?: string; + repoDid?: string; + knot: string; + spindle?: string; + description?: string; + website?: string; + topics?: string[]; + source?: RepoSource; + defaultBranch: string; +} + +/** the repo this one was forked from */ +export interface RepoSource { + ownerHandle: string; + name: string; +} + +export interface RepoCounts { + stars: number; + /** open only, same as the appview's tabs. drop the filter for the total */ + issues: number; + /** open only, so neither merged nor closed */ + pulls: number; + forks: number; +} + +export interface LanguageSlice { + name: string; + percentage: number; + share: number; +} diff --git a/web/src/lib/components/ui/Checkbox.svelte b/web/src/lib/components/ui/Checkbox.svelte index 51ce765b..56c5c734 100644 --- a/web/src/lib/components/ui/Checkbox.svelte +++ b/web/src/lib/components/ui/Checkbox.svelte @@ -27,22 +27,22 @@ const inputClasses = [ "peer size-4 shrink-0 appearance-none rounded border border-border-default bg-background-default", - "transition-colors duration-150", + "transition-colors duration-150 checked:transition-none indeterminate:transition-none", "hover:cursor-pointer hover:bg-background-inset", - "checked:border-foreground-default checked:bg-foreground-default checked:hover:bg-gray-700", - "indeterminate:border-foreground-default indeterminate:bg-foreground-default indeterminate:hover:bg-gray-700", + "checked:border-foreground-default checked:bg-foreground-default checked:hover:bg-foreground-default", + "indeterminate:border-foreground-default indeterminate:bg-foreground-default indeterminate:hover:bg-foreground-default", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-foreground-default", "disabled:hover:pointer-events-none disabled:hover:bg-background-default" ].join(" "); const checkClasses = [ - "pointer-events-none absolute inset-0 m-auto hidden size-3.5 text-foreground-on-emphasis", + "pointer-events-none absolute inset-0 m-auto hidden size-3.5 text-background-default", "peer-checked:block peer-indeterminate:hidden", "peer-disabled:text-foreground-disabled peer-disabled:hover:cursor-default" ].join(" "); const minusClasses = [ - "pointer-events-none absolute inset-0 m-auto hidden size-3.5 text-foreground-on-emphasis", + "pointer-events-none absolute inset-0 m-auto hidden size-3.5 text-background-default", "peer-indeterminate:block", "peer-disabled:text-foreground-disabled peer-disabled:hover:cursor-default" ].join(" "); diff --git a/web/src/lib/components/ui/Dropdown.svelte b/web/src/lib/components/ui/Dropdown.svelte index 622e2876..e7a23751 100644 --- a/web/src/lib/components/ui/Dropdown.svelte +++ b/web/src/lib/components/ui/Dropdown.svelte @@ -7,29 +7,16 @@ root: "relative inline-block", plainTrigger: "flex cursor-pointer items-center gap-1 border-0 bg-transparent p-0 text-inherit", - menu: "absolute z-50 mt-2 w-56 divide-y divide-border-default overflow-hidden rounded border border-border-default bg-background-default text-sm shadow-menu" + menu: "dropdown-menu fixed z-50 m-0 max-h-[calc(100dvh-1rem)] w-56 max-w-[calc(100vw-1rem)] divide-y divide-border-default overflow-auto rounded border border-border-default bg-background-default text-sm shadow-menu" }, variants: { align: { - left: { - menu: "left-0" - }, - right: { - menu: "right-0" - } - }, - open: { - true: { - menu: "block" - }, - false: { - menu: "hidden" - } + left: {}, + right: {} } }, defaultVariants: { - align: "left", - open: false + align: "left" } }); @@ -63,46 +50,62 @@ -
+
{#if variant === "button"}