@framers/agentos-ext-github 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +42 -8
  2. package/dist/__tests__/app.test.js +218 -1
  3. package/dist/__tests__/app.test.js.map +1 -1
  4. package/dist/__tests__/links.test.d.ts +8 -0
  5. package/dist/__tests__/links.test.d.ts.map +1 -0
  6. package/dist/__tests__/links.test.js +182 -0
  7. package/dist/__tests__/links.test.js.map +1 -0
  8. package/dist/__tests__/refs.test.d.ts +7 -0
  9. package/dist/__tests__/refs.test.d.ts.map +1 -0
  10. package/dist/__tests__/refs.test.js +420 -0
  11. package/dist/__tests__/refs.test.js.map +1 -0
  12. package/dist/app/installations.d.ts +57 -6
  13. package/dist/app/installations.d.ts.map +1 -1
  14. package/dist/app/installations.js +113 -14
  15. package/dist/app/installations.js.map +1 -1
  16. package/dist/app/reconcile.d.ts +20 -7
  17. package/dist/app/reconcile.d.ts.map +1 -1
  18. package/dist/app/reconcile.js +36 -14
  19. package/dist/app/reconcile.js.map +1 -1
  20. package/dist/documents/GitHubDocumentsConnector.d.ts +74 -17
  21. package/dist/documents/GitHubDocumentsConnector.d.ts.map +1 -1
  22. package/dist/documents/GitHubDocumentsConnector.js +118 -20
  23. package/dist/documents/GitHubDocumentsConnector.js.map +1 -1
  24. package/dist/documents/index.d.ts +21 -8
  25. package/dist/documents/index.d.ts.map +1 -1
  26. package/dist/documents/index.js +21 -8
  27. package/dist/documents/index.js.map +1 -1
  28. package/dist/documents/links.d.ts +50 -0
  29. package/dist/documents/links.d.ts.map +1 -0
  30. package/dist/documents/links.js +216 -0
  31. package/dist/documents/links.js.map +1 -0
  32. package/dist/documents/tree.d.ts +44 -0
  33. package/dist/documents/tree.d.ts.map +1 -1
  34. package/dist/documents/tree.js +68 -0
  35. package/dist/documents/tree.js.map +1 -1
  36. package/manifest.json +1 -1
  37. package/package.json +3 -3
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * @fileoverview What a user token reaches (the person, the app's installations they can access, and the repositories
3
- * of an installation they can read), the app's own installations, listed and removed with its JWT, and the repositories
4
- * an installation reaches, listed with an installation token. Each function takes `{ fetchImpl, apiBase, timeoutMs }`
5
- * last: `fetch`, GitHub's API and a 30-second deadline a call when absent.
3
+ * of an installation they can read), the app's own installations, listed, read one at a time and removed with its JWT,
4
+ * each with when it was suspended, and the repositories an installation reaches, listed with an installation token, and
5
+ * those of them a caller holds that it no longer reaches. Each function takes `{ fetchImpl, apiBase, timeoutMs }` last:
6
+ * `fetch`, GitHub's API and a 30-second deadline a call when absent.
6
7
  * @module agentos-ext-github/app/installations
7
8
  */
8
- import { arrayOf, discardBody, GITHUB_API_BASE, GitHubApiError, githubFetch, githubSend, numberIn, objectOf, pages, stringIn, } from './http.js';
9
+ import { arrayOf, discardBody, GITHUB_API_BASE, GitHubApiError, githubFetch, githubPages, githubSend, numberIn, objectOf, pages, stringIn, } from './http.js';
9
10
  /** An installation's account, as GitHub answers it and as a webhook event names it: a login, or an enterprise's slug, and an id. */
10
11
  export function accountOf(value) {
11
12
  const account = objectOf(value, "an installation's account");
@@ -21,6 +22,11 @@ function installationOf(value) {
21
22
  account: fields.account === null || fields.account === undefined ? null : accountOf(fields.account),
22
23
  };
23
24
  }
25
+ /** An installation as the app's own calls answer it: `suspended_at` a time, or null when GitHub sends none. */
26
+ function appInstallationOf(value) {
27
+ const fields = objectOf(value, 'an installation');
28
+ return { ...installationOf(fields), suspendedAt: typeof fields.suspended_at === 'string' ? fields.suspended_at : null };
29
+ }
24
30
  /** The repositories of a page of a repository listing: each one's id, full name and default branch. */
25
31
  function repositoriesOfPage(page) {
26
32
  return arrayOf(objectOf(page, 'a page of repositories').repositories, 'a page of repositories').map((value) => {
@@ -48,6 +54,35 @@ export async function installationsOfUser(token, { fetchImpl = fetch, apiBase =
48
54
  export async function repositoriesOfUser(token, installationId, { fetchImpl = fetch, apiBase = GITHUB_API_BASE, timeoutMs } = {}) {
49
55
  return pages(fetchImpl, `${apiBase}/user/installations/${installationId}/repositories?per_page=100`, { token, timeoutMs }, repositoriesOfPage);
50
56
  }
57
+ /** The reads of an installation's repositories made before {@link GitHubListingChanged} is thrown. */
58
+ const LISTING_READS = 3;
59
+ /**
60
+ * An installation's repositories changed while each of {@link LISTING_READS} reads of its listing was read (its pages
61
+ * disagreed on GitHub's `total_count`), so no read is whole. The message names nothing of the installation.
62
+ */
63
+ export class GitHubListingChanged extends Error {
64
+ constructor() {
65
+ super("The installation's repositories changed while their listing was read");
66
+ this.name = 'GitHubListingChanged';
67
+ }
68
+ }
69
+ /**
70
+ * Reads `GET /installation/repositories` once, every page, keeping each page's `total_count`: a repository added to or
71
+ * taken off the installation between two pages changes it, and the read is not settled.
72
+ */
73
+ async function readInstallationListing(fetchImpl, url, token, timeoutMs) {
74
+ const repositories = [];
75
+ let count = null;
76
+ let settled = true;
77
+ for await (const page of githubPages(fetchImpl, url, { token, timeoutMs })) {
78
+ const total = numberIn(objectOf(page, 'a page of repositories'), 'total_count', 'a page of repositories');
79
+ if (count !== null && total !== count)
80
+ settled = false;
81
+ count = total;
82
+ repositories.push(...repositoriesOfPage(page));
83
+ }
84
+ return { repositories, settled };
85
+ }
51
86
  /**
52
87
  * Every repository an installation reaches (`GET /installation/repositories`), across every page, read with an
53
88
  * installation token that reads their metadata and nothing else (`credential.metadataToken`): the whole of what the
@@ -55,24 +90,88 @@ export async function repositoriesOfUser(token, installationId, { fetchImpl = fe
55
90
  * made is missing from it. The token is minted with the credential's own fetch; the pages are read with `fetchImpl`. A
56
91
  * held token GitHub refuses (401, as it refuses every token of an installation it no longer has) is dropped and one
57
92
  * new token asked for, once. A refused token request throws `GitHubApiError` (404 for an installation GitHub no longer
58
- * has), so a lost installation never reads as one that reaches no repository.
93
+ * has), so a lost installation never reads as one that reaches no repository. The listing is read a page at a time, and
94
+ * a repository added to or taken off the installation between two pages changes GitHub's `total_count` and can move
95
+ * another one past a page's end: a read whose pages disagree on that count is read again, up to three reads, and then
96
+ * {@link GitHubListingChanged} is thrown. An addition and a removal between the same two pages leave the count as it
97
+ * was and can still move one past a page's end, so {@link repositoriesLost} reads the listing twice before it answers a
98
+ * repository lost.
59
99
  */
60
100
  export async function repositoriesOfInstallation(credential, installationId, { fetchImpl = fetch, apiBase = GITHUB_API_BASE, timeoutMs } = {}) {
61
101
  const url = `${apiBase}/installation/repositories?per_page=100`;
102
+ const read = async () => {
103
+ try {
104
+ return await readInstallationListing(fetchImpl, url, await credential.metadataToken(installationId, { timeoutMs }), timeoutMs);
105
+ }
106
+ catch (error) {
107
+ if (!(error instanceof GitHubApiError) || error.status !== 401)
108
+ throw error;
109
+ credential.forget(installationId);
110
+ return readInstallationListing(fetchImpl, url, await credential.metadataToken(installationId, { timeoutMs }), timeoutMs);
111
+ }
112
+ };
113
+ for (let attempt = 1; attempt <= LISTING_READS; attempt += 1) {
114
+ const listing = await read();
115
+ if (listing.settled)
116
+ return listing.repositories;
117
+ }
118
+ throw new GitHubListingChanged();
119
+ }
120
+ /**
121
+ * Which of the repositories `held` an installation no longer reaches: those missing from its listing
122
+ * (`repositoriesOfInstallation`, each read one whose pages agree on GitHub's count) read twice, the second listing read
123
+ * only when the first misses one. An addition and a removal between the same two pages of a listing leave the count as
124
+ * it was and can move a repository the installation still reaches past a page's end, so a repository missing from one
125
+ * listing alone is not answered lost; one missing from both is. Answers in the order of `held`, each id once, and makes
126
+ * no request for an empty `held`. A refused listing, and one that kept changing (`GitHubListingChanged`), throws, so a
127
+ * failure never answers a repository lost.
128
+ *
129
+ * @param credential The app's credential, whose metadata token the listings are read with.
130
+ * @param installationId The installation.
131
+ * @param held The repositories the caller holds for the installation.
132
+ * @param options Where calls go.
133
+ */
134
+ export async function repositoriesLost(credential, installationId, held, options = {}) {
135
+ const missingFrom = (listed, among) => {
136
+ const reached = new Set(listed.map((repository) => repository.id));
137
+ return among.filter((id) => !reached.has(id));
138
+ };
139
+ const asked = [...new Set(held)];
140
+ if (asked.length === 0)
141
+ return [];
142
+ const first = missingFrom(await repositoriesOfInstallation(credential, installationId, options), asked);
143
+ if (first.length === 0)
144
+ return [];
145
+ return missingFrom(await repositoriesOfInstallation(credential, installationId, options), first);
146
+ }
147
+ /**
148
+ * Every installation of the app (`GET /app/installations`, with its JWT), across every page, each with when GitHub
149
+ * suspended it. The listing is read a page at a time, so an installation removed while it is read can move another one
150
+ * past a page's end, and that one is missing from the answer: `reconcileInstallations` asks for each linked
151
+ * installation it misses by its own address (`getInstallation`) before it answers one gone.
152
+ */
153
+ export async function listInstallations(credential, { fetchImpl = fetch, apiBase = GITHUB_API_BASE, timeoutMs } = {}) {
154
+ return pages(fetchImpl, `${apiBase}/app/installations?per_page=100`, { token: credential.jwt(), timeoutMs }, (page) => arrayOf(page, 'a page of installations').map(appInstallationOf));
155
+ }
156
+ /**
157
+ * One installation of the app (`GET /app/installations/{installation_id}`, with its JWT), with when GitHub suspended
158
+ * it, or null when GitHub no longer has it (404). Any other refusal throws {@link GitHubApiError}, and a call that gets
159
+ * no answer throws `GitHubNoAnswer`, so an installation is never answered gone on a failure.
160
+ *
161
+ * @param credential The app's credential.
162
+ * @param installationId The installation.
163
+ * @param options Where calls go.
164
+ */
165
+ export async function getInstallation(credential, installationId, { fetchImpl = fetch, apiBase = GITHUB_API_BASE, timeoutMs } = {}) {
62
166
  try {
63
- return await pages(fetchImpl, url, { token: await credential.metadataToken(installationId, { timeoutMs }), timeoutMs }, repositoriesOfPage);
167
+ return appInstallationOf(await githubFetch(fetchImpl, `${apiBase}/app/installations/${installationId}`, { token: credential.jwt(), timeoutMs }));
64
168
  }
65
169
  catch (error) {
66
- if (!(error instanceof GitHubApiError) || error.status !== 401)
67
- throw error;
68
- credential.forget(installationId);
69
- return pages(fetchImpl, url, { token: await credential.metadataToken(installationId, { timeoutMs }), timeoutMs }, repositoriesOfPage);
170
+ if (error instanceof GitHubApiError && error.status === 404)
171
+ return null;
172
+ throw error;
70
173
  }
71
174
  }
72
- /** Every installation of the app (`GET /app/installations`, with its JWT), across every page. */
73
- export async function listInstallations(credential, { fetchImpl = fetch, apiBase = GITHUB_API_BASE, timeoutMs } = {}) {
74
- return pages(fetchImpl, `${apiBase}/app/installations?per_page=100`, { token: credential.jwt(), timeoutMs }, (page) => arrayOf(page, 'a page of installations').map(installationOf));
75
- }
76
175
  /**
77
176
  * Uninstalls the app from an account (`DELETE /app/installations/{installation_id}`, with its JWT). Answers without an
78
177
  * error on a 2xx (202 at the pinned API version, where GitHub has taken the removal and does it in the background; 204
@@ -1 +1 @@
1
- {"version":3,"file":"installations.js","sourceRoot":"","sources":["../../src/app/installations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"installations.js","sourceRoot":"","sources":["../../src/app/installations.ts"],"names":[],"mappings":"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"}
@@ -60,8 +60,17 @@ export interface DeliveriesOutcome {
60
60
  }
61
61
  /** What the reconcile found and did. */
62
62
  export interface ReconcileOutcome {
63
- /** Installations the app no longer has: their links and documents go. */
63
+ /**
64
+ * Installations the app no longer has: their links and documents go. Each one missing from the installations listing
65
+ * is asked for by its own address, and answered gone only when GitHub answers that 404.
66
+ */
64
67
  gone: number[];
68
+ /**
69
+ * The linked installations GitHub has suspended, each once, in the order of the links: none of their repositories is
70
+ * read, since GitHub blocks a suspended installation's access to the API, and a linked installation not here nor in
71
+ * `gone` is not suspended, whatever a missed `suspend` or `unsuspend` delivery would have said.
72
+ */
73
+ suspended: number[];
65
74
  /** Repositories to compare by tree, as a push to their default branch is. */
66
75
  moved: MovedRepository[];
67
76
  /** Deliveries asked for again. */
@@ -78,8 +87,11 @@ export interface ReconcileOutcome {
78
87
  retryAt: number | null;
79
88
  }
80
89
  /**
81
- * Reconciles a GitHub App's links with GitHub: an installation that `GET /app/installations` no longer lists is
82
- * answered gone; each repository of the other links has its default branch's head read by the repository's id
90
+ * Reconciles a GitHub App's links with GitHub: an installation that `GET /app/installations` no longer lists is asked
91
+ * for by its own address (`GET /app/installations/{installation_id}`, since the listing is read a page at a time and an
92
+ * installation removed meanwhile can move another past a page's end) and answered gone when GitHub answers that 404; an
93
+ * installation GitHub has suspended is answered suspended, its repositories not read; each repository of the other
94
+ * links has its default branch's head read by the repository's id
83
95
  * (`/repositories/<id>/branches/<branch>`, never by its name, which can come to mean another repository) with an
84
96
  * installation token narrowed to it, and is answered moved when the head differs from the one last read, or unreadable
85
97
  * with GitHub's status; and the app's failed deliveries since `since` are asked for again
@@ -95,10 +107,11 @@ export interface ReconcileOutcome {
95
107
  *
96
108
  * A call GitHub refuses for a rate limit ends the reconcile: no call follows it (GitHub may ban an integration that
97
109
  * keeps calling while it is rate limited), `retryAt` says when to run it again, and the outcome holds what was found
98
- * before the refusal. The gone installations are always whole, since they need no call past the listing; a repository
99
- * whose head read was refused for a rate limit is not unreadable, and the repositories after it and the deliveries
100
- * step wait for the next run. A rate limit on `GET /app/installations` itself throws `GitHubApiError` with its
101
- * `retryAt`, as any refusal of that listing does, before anything is found.
110
+ * before the refusal. The gone and the suspended installations are always whole, since they are settled before any
111
+ * head is read; a repository whose head read was refused for a rate limit is not unreadable, and the repositories after
112
+ * it and the deliveries step wait for the next run. A rate limit on `GET /app/installations` itself, or on an
113
+ * installation's own address, throws `GitHubApiError` with its `retryAt`, as any other refusal of those calls does
114
+ * (an installation's own address answering 404 apart), before anything is found.
102
115
  *
103
116
  * @param credential The app's credential.
104
117
  * @param links The links to check.
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/app/reconcile.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAYL,KAAK,gBAAgB,EACtB,MAAM,WAAW,CAAC;AAGnB,2GAA2G;AAC3G,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,mGAAmG;IACnG,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC9C;AAED,+DAA+D;AAC/D,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,iFAAiF;IACjF,KAAK,EAAE,IAAI,CAAC;CACb;AAED,uEAAuE;AACvE,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sFAAsF;AACtF,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;OAGG;IACH,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,6EAA6E;IAC7E,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,kCAAkC;IAClC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,uDAAuD;IACvD,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,kFAAkF;IAClF,UAAU,EAAE,iBAAiB,CAAC;IAC9B;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAyFD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,mBAAmB,EAC/B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,EAAE,KAAK,EAAE,SAAiB,EAAE,OAAyB,EAAE,SAAS,EAAE,EAAE,gBAAgB,GACnF,OAAO,CAAC,gBAAgB,CAAC,CA0B3B"}
1
+ {"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/app/reconcile.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAYL,KAAK,gBAAgB,EACtB,MAAM,WAAW,CAAC;AAGnB,2GAA2G;AAC3G,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,mGAAmG;IACnG,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC9C;AAED,+DAA+D;AAC/D,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,iFAAiF;IACjF,KAAK,EAAE,IAAI,CAAC;CACb;AAED,uEAAuE;AACvE,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sFAAsF;AACtF,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;OAGG;IACH,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;;OAIG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,6EAA6E;IAC7E,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,kCAAkC;IAClC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,uDAAuD;IACvD,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,kFAAkF;IAClF,UAAU,EAAE,iBAAiB,CAAC;IAC9B;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAyFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,mBAAmB,EAC/B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,EAAE,KAAK,EAAE,SAAiB,EAAE,OAAyB,EAAE,SAAS,EAAE,EAAE,gBAAgB,GACnF,OAAO,CAAC,gBAAgB,CAAC,CA8C3B"}
@@ -4,7 +4,7 @@
4
4
  * @module agentos-ext-github/app/reconcile
5
5
  */
6
6
  import { arrayOf, discardBody, GITHUB_API_BASE, GitHubApiError, githubFetch, githubPages, githubSend, numberIn, objectOf, repositoryPath, stringIn, } from './http.js';
7
- import { listInstallations } from './installations.js';
7
+ import { getInstallation, listInstallations } from './installations.js';
8
8
  /** Epoch milliseconds before which a call is not made again after GitHub refused it for a rate limit. */
9
9
  function rateLimitEnd(error) {
10
10
  // A rate limit always carries its time; a minute on, GitHub's own floor, should one ever come without it.
@@ -84,8 +84,11 @@ async function redeliverFailures(credential, since, fetchImpl, apiBase, timeoutM
84
84
  return { redelivered, deliveries: { listingStatus: null, refused }, retryAt: null };
85
85
  }
86
86
  /**
87
- * Reconciles a GitHub App's links with GitHub: an installation that `GET /app/installations` no longer lists is
88
- * answered gone; each repository of the other links has its default branch's head read by the repository's id
87
+ * Reconciles a GitHub App's links with GitHub: an installation that `GET /app/installations` no longer lists is asked
88
+ * for by its own address (`GET /app/installations/{installation_id}`, since the listing is read a page at a time and an
89
+ * installation removed meanwhile can move another past a page's end) and answered gone when GitHub answers that 404; an
90
+ * installation GitHub has suspended is answered suspended, its repositories not read; each repository of the other
91
+ * links has its default branch's head read by the repository's id
89
92
  * (`/repositories/<id>/branches/<branch>`, never by its name, which can come to mean another repository) with an
90
93
  * installation token narrowed to it, and is answered moved when the head differs from the one last read, or unreadable
91
94
  * with GitHub's status; and the app's failed deliveries since `since` are asked for again
@@ -101,25 +104,44 @@ async function redeliverFailures(credential, since, fetchImpl, apiBase, timeoutM
101
104
  *
102
105
  * A call GitHub refuses for a rate limit ends the reconcile: no call follows it (GitHub may ban an integration that
103
106
  * keeps calling while it is rate limited), `retryAt` says when to run it again, and the outcome holds what was found
104
- * before the refusal. The gone installations are always whole, since they need no call past the listing; a repository
105
- * whose head read was refused for a rate limit is not unreadable, and the repositories after it and the deliveries
106
- * step wait for the next run. A rate limit on `GET /app/installations` itself throws `GitHubApiError` with its
107
- * `retryAt`, as any refusal of that listing does, before anything is found.
107
+ * before the refusal. The gone and the suspended installations are always whole, since they are settled before any
108
+ * head is read; a repository whose head read was refused for a rate limit is not unreadable, and the repositories after
109
+ * it and the deliveries step wait for the next run. A rate limit on `GET /app/installations` itself, or on an
110
+ * installation's own address, throws `GitHubApiError` with its `retryAt`, as any other refusal of those calls does
111
+ * (an installation's own address answering 404 apart), before anything is found.
108
112
  *
109
113
  * @param credential The app's credential.
110
114
  * @param links The links to check.
111
115
  * @param options The window's start, and where calls go.
112
116
  */
113
117
  export async function reconcileInstallations(credential, links, { since, fetchImpl = fetch, apiBase = GITHUB_API_BASE, timeoutMs }) {
114
- const listed = new Set((await listInstallations(credential, { fetchImpl, apiBase, timeoutMs })).map((installation) => installation.id));
118
+ const listed = new Map((await listInstallations(credential, { fetchImpl, apiBase, timeoutMs })).map((installation) => [installation.id, installation]));
115
119
  const gone = [];
116
- for (const link of links)
117
- if (!listed.has(link.installationId) && !gone.includes(link.installationId))
118
- gone.push(link.installationId);
120
+ const suspended = [];
121
+ const settled = new Set();
122
+ for (const link of links) {
123
+ const installationId = link.installationId;
124
+ if (settled.has(installationId))
125
+ continue;
126
+ settled.add(installationId);
127
+ let installation = listed.get(installationId);
128
+ if (installation === undefined) {
129
+ // Missing from a listing read a page at a time is not gone: an installation removed meanwhile moves another past
130
+ // a page's end. GitHub's 404 at the installation's own address is.
131
+ const found = await getInstallation(credential, installationId, { fetchImpl, apiBase, timeoutMs });
132
+ if (found === null) {
133
+ gone.push(installationId);
134
+ continue;
135
+ }
136
+ installation = found;
137
+ }
138
+ if (installation.suspendedAt !== null)
139
+ suspended.push(installationId);
140
+ }
119
141
  const moved = [];
120
142
  const unreadable = [];
121
143
  for (const link of links) {
122
- if (!listed.has(link.installationId))
144
+ if (gone.includes(link.installationId) || suspended.includes(link.installationId))
123
145
  continue;
124
146
  for (const repository of link.repositories) {
125
147
  try {
@@ -134,13 +156,13 @@ export async function reconcileInstallations(credential, links, { since, fetchIm
134
156
  if (!(error instanceof GitHubApiError))
135
157
  throw error;
136
158
  if (error.rateLimited) {
137
- return { gone, moved, redelivered: [], unreadable, deliveries: { listingStatus: null, refused: [] }, retryAt: rateLimitEnd(error) };
159
+ return { gone, suspended, moved, redelivered: [], unreadable, deliveries: { listingStatus: null, refused: [] }, retryAt: rateLimitEnd(error) };
138
160
  }
139
161
  unreadable.push({ installationId: link.installationId, repositoryId: repository.id, status: error.status });
140
162
  }
141
163
  }
142
164
  }
143
165
  const { redelivered, deliveries, retryAt } = await redeliverFailures(credential, since.getTime(), fetchImpl, apiBase, timeoutMs);
144
- return { gone, moved, redelivered, unreadable, deliveries, retryAt };
166
+ return { gone, suspended, moved, redelivered, unreadable, deliveries, retryAt };
145
167
  }
146
168
  //# sourceMappingURL=reconcile.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/app/reconcile.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,OAAO,EACP,WAAW,EACX,eAAe,EACf,cAAc,EACd,WAAW,EACX,WAAW,EACX,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,QAAQ,GAET,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAkFvD,yGAAyG;AACzG,SAAS,YAAY,CAAC,KAAqB;IACzC,0GAA0G;IAC1G,OAAO,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;AAC9C,CAAC;AAUD,sFAAsF;AACtF,MAAM,yBAAyB,GAAwB,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAE3E,SAAS,UAAU,CAAC,KAAc;IAChC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC7C,OAAO;QACL,EAAE,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC;QACxC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC;QAC5C,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;QACvE,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,YAAY,CAAC;KAC1D,CAAC;AACJ,CAAC;AAED,oDAAoD;AACpD,SAAS,SAAS,CAAC,OAAiB;IAClC,OAAO,OAAO,CAAC,UAAU,IAAI,GAAG,IAAI,OAAO,CAAC,UAAU,GAAG,GAAG,CAAC;AAC/D,CAAC;AAED,wGAAwG;AACxG,SAAS,cAAc,CAAC,OAAiB;IACvC,OAAO,OAAO,CAAC,UAAU,IAAI,GAAG,IAAI,OAAO,CAAC,UAAU,GAAG,GAAG,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AACrH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,iBAAiB,CAC9B,UAA+B,EAC/B,KAAa,EACb,SAAuB,EACvB,OAAe,EACf,SAA6B;IAE7B,MAAM,cAAc,GAAG,IAAI,GAAG,EAAsB,CAAC;IACrD,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,WAAW,CAAC,SAAS,EAAE,GAAG,OAAO,mCAAmC,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;YACvI,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACzE,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;gBAClC,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,IAAI,KAAK,CAAC;oBAAE,SAAS;gBAC/C,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACnD,IAAI,QAAQ,KAAK,SAAS;oBAAE,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;;oBACrE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/B,CAAC;YACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,IAAI,KAAK,CAAC,CAAC;gBAAE,MAAM;QACxG,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,cAAc,CAAC;YAAE,MAAM,KAAK,CAAC;QACpD,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChJ,CAAC;IACD,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,KAAK,MAAM,QAAQ,IAAI,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC;QAC/C,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,SAAS;QACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACnH,IAAI,cAAc,CAAC,MAAM,CAAC;YAAE,SAAS;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,GAAG,OAAO,wBAAwB,MAAM,CAAC,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAC3J,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7B,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,CAAC,KAAK,YAAY,cAAc,CAAC;gBAAE,MAAM,KAAK,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YACtD,IAAI,KAAK,CAAC,WAAW;gBAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5H,CAAC;IACH,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACtF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,UAA+B,EAC/B,KAA+B,EAC/B,EAAE,KAAK,EAAE,SAAS,GAAG,KAAK,EAAE,OAAO,GAAG,eAAe,EAAE,SAAS,EAAoB;IAEpF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,iBAAiB,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC;IACxI,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACtI,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC;YAAE,SAAS;QAC/C,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;gBACtG,MAAM,OAAO,GAAG,GAAG,OAAO,IAAI,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC,aAAa,kBAAkB,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;gBACvH,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;gBACjG,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAAE,KAAK,EAAE,mBAAmB,CAAC,CAAC;gBAChG,IAAI,IAAI,KAAK,UAAU,CAAC,UAAU;oBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7H,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,CAAC,KAAK,YAAY,cAAc,CAAC;oBAAE,MAAM,KAAK,CAAC;gBACpD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;oBACtB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtI,CAAC;gBACD,UAAU,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YAC9G,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,MAAM,iBAAiB,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACjI,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;AACvE,CAAC"}
1
+ {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/app/reconcile.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * @fileoverview A repository's documentation as account sources, read through a GitHub App's installation: each
3
- * repository read by its id, its tree read once a commit within a request budget, the documentation kept by a filter,
4
- * each file read as raw bytes under a cap, and a push compared by the tree at its `after` commit. A selection, an item
5
- * or a call it cannot answer whole is refused before any request.
3
+ * repository read by its id at its default branch or at a named branch or commit, its tree read once a commit within a
4
+ * request budget, the documentation kept by a filter, each file read as raw bytes under a cap, a push compared by the
5
+ * tree at its `after` commit, and a link's ref settled where a branch name holds a slash. A selection, an item or a
6
+ * call it cannot answer whole is refused before any request.
6
7
  * @module agentos-ext-github/documents/GitHubDocumentsConnector
7
8
  */
8
9
  import { type AccountSourceConnector, type SourceChanges, type SourceGone, type SourceItem, type SourceRead, type SourceSelection } from '@framers/agentos-ext-account-sources';
@@ -16,17 +17,40 @@ export interface LinkedRepository {
16
17
  fullName: string;
17
18
  defaultBranch: string;
18
19
  }
20
+ /** What `list` reads: the repositories (`ids`), and the branch or commit a listing is made at. */
21
+ export interface GitHubListSelection extends SourceSelection {
22
+ /**
23
+ * A branch name, or a commit as 40 hexadecimal characters in either case, the listing is made at: the branch's head,
24
+ * or the commit itself. The default branch's head when absent. Given, the selection names one repository.
25
+ */
26
+ at?: string;
27
+ }
19
28
  /**
20
- * What `changesSince` compares: one repository (`ids` holds its id alone), and from a push its `after` commit and its
21
- * `ref`, with the listing at `after` when the caller holds it.
29
+ * What `changesSince` compares: one repository (`ids` holds its id alone), the branch or commit the comparison follows
30
+ * (`at`), and from a push its `after` commit and its `ref`, with the listing at `after` when the caller holds it.
22
31
  */
23
- export interface GitHubChangesSelection extends SourceSelection {
24
- /** The commit to compare at; the default branch's head when absent. */
32
+ export interface GitHubChangesSelection extends GitHubListSelection {
33
+ /** The commit to compare at; the head of the branch `at` names when absent, or `at` itself when it is a commit. */
25
34
  after?: string;
26
- /** The push's ref, such as `refs/heads/main`; a push to another branch than the default changes nothing. */
35
+ /** The push's ref, such as `refs/heads/main`; a push to another branch than the one followed changes nothing. */
27
36
  ref?: string;
28
37
  /** The documentation's listing at `after`, which spares the tree's read; taken only with the `after` it was read at. */
29
38
  listing?: readonly TreeBlob[];
39
+ /**
40
+ * A branch name, or a commit as 40 hexadecimal characters, the listing and the comparison are made at; the default
41
+ * branch's head when absent. A push's `ref` is read against `refs/heads/<at>` when `at` is a branch; a commit never
42
+ * changes, so a push answers no change and an `after` naming another commit is refused.
43
+ */
44
+ at?: string;
45
+ }
46
+ /** The ref and the path a link's `<ref>/<path>` text names, as `resolveRef` settles them. */
47
+ export interface ResolvedRef {
48
+ /** The branch's name, or the commit in lower case. */
49
+ ref: string;
50
+ /** The path under the ref, with no leading or trailing slash; `''` for the ref's root. */
51
+ path: string;
52
+ /** True when `ref` is a commit, which never moves. */
53
+ commit: boolean;
30
54
  }
31
55
  /**
32
56
  * A repository's documentation as account sources: an item's id is `<repositoryId>:<path>`, its version
@@ -34,8 +58,13 @@ export interface GitHubChangesSelection extends SourceSelection {
34
58
  * read. A repository id is a positive integer in decimal. A call whose signal is already aborted throws
35
59
  * `GitHubNoAnswer` (`cancelled`) before it checks anything else. What a call cannot answer whole then throws before any
36
60
  * request: a `TypeError` for an id that is not a repository id, a repository named twice, an item id that names no
37
- * file or a change set of other than one repository, and an `Error` for a repository outside the link. An
38
- * installation is removed by the app's own call (`uninstallInstallation`), never by a link's connector.
61
+ * file, a change set of other than one repository, an `at` that is neither a branch name nor a commit or that names
62
+ * other than one repository, and a link's text with an empty, `.` or `..` segment, and an `Error` for a repository
63
+ * outside the link. An installation is removed by the app's own call (`uninstallInstallation`), never by a link's
64
+ * connector.
65
+ *
66
+ * A listing and a comparison follow the default branch, or the branch or commit a selection's `at` names: a branch's
67
+ * head is read when the call is made, a commit is read as it is and never changes.
39
68
  *
40
69
  * Every read addresses a linked repository by its id (`/repositories/<id>/...`, where GitHub's own redirects for a
41
70
  * renamed or moved repository lead), never by its name. A name can come to mean another repository (a renamed
@@ -67,8 +96,16 @@ export declare class GitHubDocumentsConnector implements AccountSourceConnector
67
96
  private token;
68
97
  /** A linked repository's address under the API, by its id. */
69
98
  private address;
99
+ /** The head commit of a branch of a linked repository, its name encoded as one segment of the address. */
100
+ private branchHead;
70
101
  /** The head commit of a repository's default branch. */
71
102
  head(repositoryId: number, signal?: AbortSignal): Promise<string>;
103
+ /**
104
+ * The head commit of the branch `at` names, the default branch's when `at` is undefined; for a commit of 40
105
+ * hexadecimal characters, the commit itself in lower case, with no request. An `at` that is neither throws a
106
+ * `TypeError` before any request; a branch the repository does not have throws GitHub's 404 as `GitHubApiError`.
107
+ */
108
+ head(repositoryId: number, at: string | undefined, signal?: AbortSignal): Promise<string>;
72
109
  /**
73
110
  * The documentation files of a repository at a commit: its tree read once within the request budget, never walking
74
111
  * a skipped folder, then filtered. A caller keeps it for that commit and hands it to `changesSince` with that commit
@@ -76,11 +113,14 @@ export declare class GitHubDocumentsConnector implements AccountSourceConnector
76
113
  */
77
114
  listing(repositoryId: number, commit: string, signal?: AbortSignal): Promise<TreeBlob[]>;
78
115
  /**
79
- * The documentation of each selected repository (its id in `ids`) at its default branch's head. Every id is checked
80
- * before any repository is read, so a selection is listed whole or not at all: an id that is not a repository id, or
81
- * a repository named twice, throws a `TypeError`, and a repository outside the link an `Error`.
116
+ * The documentation of each selected repository (its id in `ids`) at its default branch's head, or of one repository
117
+ * at the branch or commit `at` names: the branch's head, or the commit itself with no branch read. Every id and `at`
118
+ * are checked before any repository is read, so a selection is listed whole or not at all: an id that is not a
119
+ * repository id, a repository named twice, an `at` that is neither a branch name nor a commit, and an `at` beside
120
+ * other than one repository throw a `TypeError`, and a repository outside the link an `Error`. A selection's other
121
+ * fields are `changesSince`'s, and a listing reads none of them.
82
122
  */
83
- list(selection: SourceSelection, signal?: AbortSignal): Promise<{
123
+ list(selection: GitHubListSelection, signal?: AbortSignal): Promise<{
84
124
  items: SourceItem[];
85
125
  gone: SourceGone[];
86
126
  }>;
@@ -101,11 +141,28 @@ export declare class GitHubDocumentsConnector implements AccountSourceConnector
101
141
  * none) against the blobs read before (`cursor`: the JSON of each path's blob). A push's own commit lists are never
102
142
  * read, so a force push, or a push of more commits than its event lists, is read like any other. A cursor this
103
143
  * connector did not answer throws a `TypeError` before any request, whatever the push's branch, and so does a
104
- * selection of other than one repository, or a `listing` without the `after` commit it was read at: call it once
105
- * per repository, each with that repository's cursor. A push to another branch than the default answers no change
106
- * and the cursor it was given.
144
+ * selection of other than one repository, a `listing` without the `after` commit it was read at, or an `at` that is
145
+ * neither a branch name nor a commit: call it once per repository, each with that repository's cursor.
146
+ *
147
+ * The comparison follows the default branch, or the branch or commit `at` names. Without `after` it is made at the
148
+ * followed branch's head, or at the commit. A push to another branch than the one followed answers no change and the
149
+ * cursor it was given, and so does any push when `at` is a commit, which never changes; without a push, an `after`
150
+ * naming another commit than `at`'s throws a `TypeError` before any request.
107
151
  */
108
152
  changesSince(cursor: string | null, selection: GitHubChangesSelection, signal?: AbortSignal): Promise<SourceChanges>;
153
+ /**
154
+ * The ref and the path of a folder's or a file's `<ref>/<path>` text (`parseGitHubLink`'s `refAndPath`), whose
155
+ * branch name may hold a slash. A first segment of 40 hexadecimal characters is a commit, in lower case, and `HEAD`
156
+ * the default branch (git names no branch `HEAD`), each settled with no request. Otherwise one request to GitHub's
157
+ * matching references (`/repositories/<id>/git/matching-refs/heads/<first segment>`, under an installation token
158
+ * narrowed to the repository), which answers every branch whose name starts with that segment
159
+ * (https://docs.github.com/en/rest/git/refs#list-matching-references): the longest branch name that is the text, or
160
+ * starts it at a slash, is the ref and the rest the path, and the first segment alone when none is longer. A first
161
+ * segment no branch has is answered as the ref all the same, and a listing at it then answers GitHub's 404. A text
162
+ * with an empty, `.` or `..` segment throws a `TypeError` that quotes none of it, before any request; GitHub's
163
+ * refusal of the read, such as 409 for a repository with no commit, throws `GitHubApiError`.
164
+ */
165
+ resolveRef(repositoryId: number, refAndPath: string, signal?: AbortSignal): Promise<ResolvedRef>;
109
166
  /** Nothing to end here: an installation is removed by the app's own call (`uninstallInstallation`). */
110
167
  revoke(): Promise<void>;
111
168
  }
@@ -1 +1 @@
1
- {"version":3,"file":"GitHubDocumentsConnector.d.ts","sourceRoot":"","sources":["../../src/documents/GitHubDocumentsConnector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,UAAU,EAEf,KAAK,eAAe,EACrB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,OAAO,EAA8E,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvI,gCAAgC;AAChC,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,EAAE,EAAE,MAAM,CAAC;IACX,mFAAmF;IACnF,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAuB,SAAQ,eAAe;IAC7D,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4GAA4G;IAC5G,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wHAAwH;IACxH,OAAO,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CAC/B;AAoED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,wBAAyB,YAAW,sBAAsB;IAYnE,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAhB1B,QAAQ,CAAC,IAAI,YAAY;IAEzB;;;;;;;OAOG;gBAEgB,UAAU,EAAE,mBAAmB,EAC/B,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,SAAS,gBAAgB,EAAE,EACzC,MAAM,GAAE,UAAe,EACvB,SAAS,GAAE,OAAO,KAAa,EAC/B,OAAO,SAAkB;IAG5C,mEAAmE;IACnE,OAAO,CAAC,UAAU;IAMlB,kGAAkG;IAClG,OAAO,CAAC,KAAK;IAIb,8DAA8D;IAC9D,OAAO,CAAC,OAAO;IAIf,wDAAwD;IAClD,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAQvE;;;;OAIG;IACG,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAW9F;;;;OAIG;IACG,IAAI,CAAC,SAAS,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAAC,IAAI,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;IAelH;;;;;;;;;;OAUG;IACG,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;IAoCpF;;;;;;;;OAQG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IAuB1H,uGAAuG;IACjG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAG9B"}
1
+ {"version":3,"file":"GitHubDocumentsConnector.d.ts","sourceRoot":"","sources":["../../src/documents/GitHubDocumentsConnector.ts"],"names":[],"mappings":"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"}