@unveil/vk 1.0.0-beta.0 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/dist/index.d.mts +16 -8
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -33,11 +33,18 @@ console.log(eventsCount); // how many events we actually got back
|
|
|
33
33
|
|
|
34
34
|
```js
|
|
35
35
|
analyze(username, {
|
|
36
|
-
|
|
36
|
+
provider: "gitlab", // "github" (default), "gitlab", "codeberg" or "tangled"
|
|
37
|
+
token: "ghp_...", // provider token. Optional, but strongly recommended
|
|
37
38
|
showEvents: true, // return the raw events too. Off by default
|
|
38
39
|
});
|
|
39
40
|
```
|
|
40
41
|
|
|
42
|
+
`provider` picks where the account lives: `github` (api.github.com),
|
|
43
|
+
`gitlab` (gitlab.com), `codeberg` (codeberg.org) or `tangled` (resolved through
|
|
44
|
+
AT Protocol). Leave it out and it is GitHub. GitLab.com only returns a user's
|
|
45
|
+
sign-up date to authenticated requests, so `gitlab` needs a token. Tangled
|
|
46
|
+
records are public and no token is sent.
|
|
47
|
+
|
|
41
48
|
`token` is sent as `Authorization: Bearer`. Without it you are on the unauthenticated
|
|
42
49
|
rate limit, which is 60 requests per hour for the whole IP — and each `analyze`
|
|
43
50
|
call spends 4 of them. With a token you get 5000 per hour. The token needs no
|
|
@@ -75,7 +82,7 @@ analysis reports lower `confidence` to match.
|
|
|
75
82
|
|
|
76
83
|
`analyze` rejects instead of returning a partial result. A missing user, a
|
|
77
84
|
revoked token or an exhausted rate limit all come back as a plain `Error`
|
|
78
|
-
carrying
|
|
85
|
+
carrying the provider's own message, with the `status` and `url` of the failed request
|
|
79
86
|
attached to it:
|
|
80
87
|
|
|
81
88
|
```js
|
package/dist/index.d.mts
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
import { IdentifyResult } from "@unveil/identity";
|
|
2
|
+
import { CodebergActivity } from "@unveil/identity/providers/codeberg";
|
|
2
3
|
import { GitHubEvent } from "@unveil/identity/providers/github";
|
|
4
|
+
import { GitLabEvent } from "@unveil/identity/providers/gitlab";
|
|
5
|
+
import { TangledRecord } from "@unveil/identity/providers/tangled";
|
|
6
|
+
//#region src/http.d.ts
|
|
7
|
+
declare class ProviderError extends Error {
|
|
8
|
+
readonly status: number;
|
|
9
|
+
readonly url: string;
|
|
10
|
+
constructor(message: string, status: number, url: string);
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
3
13
|
//#region src/index.d.ts
|
|
14
|
+
type Provider = "github" | "gitlab" | "codeberg" | "tangled";
|
|
15
|
+
type ProviderEvent = GitHubEvent | GitLabEvent | CodebergActivity | TangledRecord;
|
|
4
16
|
type AnalyzeOptions = {
|
|
5
17
|
token?: string;
|
|
6
18
|
showEvents?: boolean;
|
|
19
|
+
provider?: Provider;
|
|
7
20
|
};
|
|
8
21
|
type AnalyzeReturn = {
|
|
9
22
|
analysis: IdentifyResult;
|
|
10
|
-
events:
|
|
23
|
+
events: ProviderEvent[];
|
|
11
24
|
eventsCount: number;
|
|
12
|
-
userId?: number;
|
|
25
|
+
userId?: number | string;
|
|
13
26
|
};
|
|
14
|
-
declare class GitHubError extends Error {
|
|
15
|
-
readonly status: number;
|
|
16
|
-
readonly url: string;
|
|
17
|
-
constructor(message: string, status: number, url: string);
|
|
18
|
-
}
|
|
19
27
|
declare function analyze(username: string, options?: AnalyzeOptions): Promise<AnalyzeReturn>;
|
|
20
28
|
//#endregion
|
|
21
|
-
export { AnalyzeOptions, AnalyzeReturn,
|
|
29
|
+
export { AnalyzeOptions, AnalyzeReturn, type CodebergActivity, type GitHubEvent, type GitLabEvent, type IdentifyResult, Provider, ProviderError, ProviderEvent, type TangledRecord, analyze };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{identify as e}from"@unveil/identity";import{
|
|
1
|
+
import{identify as e}from"@unveil/identity";import{fromCodeberg as t}from"@unveil/identity/providers/codeberg";import{fromGitHub as n}from"@unveil/identity/providers/github";import{fromGitLab as r}from"@unveil/identity/providers/gitlab";import{fromTangled as i}from"@unveil/identity/providers/tangled";function a(e,t){let n=new URLSearchParams;for(let[e,r]of Object.entries(t))n.set(e,String(r));return`${e}?${n}`}var o=class extends Error{status;url;constructor(e,t,n){super(e),this.name=`ProviderError`,this.status=t,this.url=n}};async function s(e){try{let t=await e.json();if(t?.message)return t.message}catch{}return`${e.status} ${e.statusText}`}async function c(e,t={}){let n=await fetch(e,{headers:t});if(!n.ok)throw new o(await s(n),n.status,e);return n}async function l(e,t){return await(await c(e,t)).json()}async function u(e,t,n){let r=Array.from({length:e},(e,r)=>l(t(r+1),n));return(await Promise.all(r)).flat()}function d(e,t={}){return e?{...t,Authorization:`Bearer ${e}`}:t}async function f(e,n){let r=encodeURIComponent(e),i=d(n),o=`https://codeberg.org/api/v1/users/${r}`,s=e=>a(`${o}/activities/feeds`,{"only-performed-by":!0,limit:50,page:e}),f=a(`${o}/repos`,{limit:1}),[p,m,h]=await Promise.all([l(o,i),u(6,s,i),c(f,i)]);return{input:t({user:p,events:m,publicRepos:Number(h.headers.get(`X-Total-Count`)??0)}),events:m,userId:p.id}}const p=`https://api.github.com`;async function m(e,t){let r=encodeURIComponent(e),i=d(t,{Accept:`application/vnd.github+json`,"X-GitHub-Api-Version":`2022-11-28`,"User-Agent":`unveil-vk`}),o=await l(`${p}/users/${r}`,i),s=await u(3,e=>a(`${p}/users/${r}/events/public`,{per_page:100,page:e}),i);return{input:n({user:o,events:s}),events:s,userId:o.id}}const h=`https://gitlab.com/api/v4`;function g(e){let t=new Set;for(let n of e)n.project_id&&t.add(n.project_id);return[...t]}async function _(e,t){try{return await l(`${h}/projects/${e}`,t)}catch(e){if(e instanceof o&&e.status===404)return;throw e}}async function v(e,t){let n=d(t),i=a(`${h}/users`,{username:e}),[s]=await l(i,n);if(!s)throw new o(`404 User Not Found`,404,i);let f=`${h}/users/${s.id}`,p=e=>a(`${f}/events`,{per_page:100,page:e}),m=a(`${f}/projects`,{per_page:1}),[v,y,b]=await Promise.all([l(f,n),u(3,p,n),c(m,n)]),x=g(y),S=await Promise.all(x.map(e=>_(e,n)));return{input:r({user:v,events:y,publicRepos:Number(b.headers.get(`X-Total`)??0),projects:S.filter(e=>e!==void 0)}),events:y,userId:v.id}}const y=`https://plc.directory`;function b(e){return e.startsWith(`did:plc:`)}async function x(e){return e.startsWith(`did:`)?e:(await l(a(`https://bsky.social/xrpc/com.atproto.identity.resolveHandle`,{handle:e}))).did}function S(e){return b(e)?`${y}/${e}`:`https://${e.replace(/^did:web:/,``)}/.well-known/did.json`}function C(e){return e.service?.find(e=>e.id.endsWith(`#atproto_pds`))?.serviceEndpoint}function w(e){return(e.alsoKnownAs?.[0])?.replace(/^at:\/\//,``)}async function T(e){return(await l(`${y}/${e}/log/audit`))[0]?.createdAt??``}async function E(e,t){return(await l(a(`${t}/xrpc/com.atproto.repo.getRecord`,{repo:e,collection:`app.bsky.actor.profile`,rkey:`self`}))).value.createdAt??``}async function D(e,t){return b(e)?T(e):E(e,t)}async function O(e,t,n,r){return(await l(a(`${t}/xrpc/com.atproto.repo.listRecords`,{repo:e,collection:n,limit:r}))).records}const k=[`repo`,`actor.profile`].map(e=>`sh.tangled.${e}`),A=[`repo.issue`,`repo.issue.state`,`repo.issue.comment`,`repo.pull`,`repo.pull.status`,`repo.pull.comment`,`feed.comment`,`feed.star`,`feed.reaction`,`graph.follow`,`repo.collaborator`,`string`].map(e=>`sh.tangled.${e}`);async function j(e,t,n){return(await Promise.all(n.map(n=>O(e,t,n,100)))).flat()}function M(e,t){return e.toSorted((e,t)=>{let n=e.value.createdAt??``;return(t.value.createdAt??``).localeCompare(n)}).slice(0,t)}async function N(e,t){let[n,r]=await Promise.all([j(e,t,k),j(e,t,A)]);return[...n,...M(r,300)]}async function P(e){let t=await x(e),n=S(t),r=await l(n),a=C(r);if(!a)throw new o(`No PDS found for this account`,404,n);let s=w(r)??e,[c,u]=await Promise.all([D(t,a),N(t,a)]);return{input:i({account:{did:t,handle:s,createdAt:c},records:u}),events:u,userId:t}}const F={github:m,gitlab:v,codeberg:f,tangled:P};async function I(t,n){let r=n?.provider??`github`,i=F[r],{input:a,events:o,userId:s}=await i(t,n?.token);return{analysis:e(a),userId:s,events:n?.showEvents?o:[],eventsCount:o.length}}export{o as ProviderError,I as analyze};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unveil/vk",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
4
|
"description": "Fetch GitHub account activity and analyze it for automation patterns",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@11.22.0",
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@biomejs/biome": "^2.5.6",
|
|
39
39
|
"@types/node": "^26.1.2",
|
|
40
|
-
"@unveil/identity": "3.0.0-beta.
|
|
40
|
+
"@unveil/identity": "3.0.0-beta.2",
|
|
41
41
|
"publint": "^0.3.22",
|
|
42
42
|
"tsdown": "^0.22.14",
|
|
43
43
|
"typescript": "^6.0.3",
|
|
44
44
|
"vitest": "^4.1.10"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@unveil/identity": "^3.0.0-beta.
|
|
47
|
+
"@unveil/identity": "^3.0.0-beta.2"
|
|
48
48
|
}
|
|
49
49
|
}
|