@vibes.diy/api-svc 14.3.163 → 14.3.165

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 (42) hide show
  1. package/index.d.ts +1 -0
  2. package/index.js +1 -0
  3. package/index.js.map +1 -1
  4. package/intern/backend-github-callback.js +16 -20
  5. package/intern/backend-github-callback.js.map +1 -1
  6. package/intern/components/vibe-page.d.ts +1 -1
  7. package/intern/components/vibe-page.js +1 -1
  8. package/intern/components/vibe-page.js.map +1 -1
  9. package/intern/github-app-auth.d.ts +6 -2
  10. package/intern/github-app-auth.js +35 -9
  11. package/intern/github-app-auth.js.map +1 -1
  12. package/intern/is-unique-violation.d.ts +1 -0
  13. package/intern/is-unique-violation.js +13 -0
  14. package/intern/is-unique-violation.js.map +1 -0
  15. package/intern/open-turn-sweep.js +1 -12
  16. package/intern/open-turn-sweep.js.map +1 -1
  17. package/package.json +13 -13
  18. package/public/github-install-consent.html +5 -2
  19. package/public/github-install-pick-item.html +5 -0
  20. package/public/github-install-pick.html +25 -0
  21. package/public/github-install-signin.html +1 -1
  22. package/public/github-install.d.ts +2 -10
  23. package/public/github-install.js +21 -67
  24. package/public/github-install.js.map +1 -1
  25. package/public/github-repo-pick-item.html +7 -0
  26. package/public/github-repo-pick.html +28 -0
  27. package/public/github-repos.d.ts +3 -0
  28. package/public/github-repos.js +195 -0
  29. package/public/github-repos.js.map +1 -0
  30. package/public/github-setup.d.ts +63 -4
  31. package/public/github-setup.js +303 -92
  32. package/public/github-setup.js.map +1 -1
  33. package/public/github-templates.d.ts +22 -0
  34. package/public/github-templates.js +59 -0
  35. package/public/github-templates.js.map +1 -0
  36. package/public/github-webhook.d.ts +1 -0
  37. package/public/github-webhook.js +50 -15
  38. package/public/github-webhook.js.map +1 -1
  39. package/usage-report/backfill-hubspot-contacts.js +1 -1
  40. package/usage-report/backfill-hubspot-contacts.js.map +1 -1
  41. package/usage-report/inspect-db-report-template.js +1 -1
  42. package/usage-report/inspect-db-report-template.js.map +1 -1
@@ -0,0 +1,25 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Choose a GitHub account</title>
7
+ </head>
8
+ <body style="font-family: system-ui, sans-serif; max-width: 32rem; margin: 4rem auto; padding: 0 1rem; line-height: 1.5">
9
+ <main>
10
+ <h1 style="font-size: 1.4rem">Choose a GitHub account</h1>
11
+ <p>
12
+ Pick the GitHub account to connect to <strong>{{vibe}}</strong>. Next you choose which of its repositories this vibe gets:
13
+ each vibe gets only the repositories you choose for it.
14
+ </p>
15
+ <ul style="padding-left: 1.2rem">
16
+ {{choices}}
17
+ </ul>
18
+ <p>
19
+ Want another account? <a href="{{installUrl}}">Add the app on GitHub</a> and you'll come straight back to choose its
20
+ repositories. Changed an account's repositories on GitHub? Press the app's Connect button again to choose them here.
21
+ </p>
22
+ <p><a href="{{vibeHref}}">Back to {{vibe}}</a></p>
23
+ </main>
24
+ </body>
25
+ </html>
@@ -8,7 +8,7 @@
8
8
  <body style="font-family: system-ui, sans-serif; max-width: 32rem; margin: 4rem auto; padding: 0 1rem; line-height: 1.5">
9
9
  <main>
10
10
  <h1 style="font-size: 1.4rem">Sign in first</h1>
11
- <p>Sign in on vibes.diy first, then use the app's Connect GitHub link again.</p>
11
+ <p>Sign in on vibes.diy first, then press the app's Connect button again.</p>
12
12
  <p><a href="{{vibeHref}}">Back to {{vibe}}</a></p>
13
13
  </main>
14
14
  </body>
@@ -1,9 +1,8 @@
1
- import { Result } from "@adviser/cement";
2
1
  import { CFEnv } from "@vibes.diy/api-types";
3
2
  import type { VibesApiSQLCtx } from "../types.js";
4
3
  import { type GithubDeclLoader, type GithubSetupSql, type VerifySessionToken } from "./github-setup.js";
5
- export type GithubInstallTemplate = "github-install-consent.html" | "github-install-signin.html";
6
- export type GithubInstallTemplateLoader = (name: GithubInstallTemplate) => Promise<Result<string>>;
4
+ import { type GithubInstallTemplateLoader } from "./github-templates.js";
5
+ export { escapeHtml, fillFragments, fillTemplate, githubInstallTemplates, resetGithubInstallTemplatesForTests, type GithubInstallTemplate, type GithubInstallTemplateLoader, type TemplateValue, type TrustedHtml, } from "./github-templates.js";
7
6
  export interface GithubInstallDeps {
8
7
  readonly verifySessionToken: VerifySessionToken;
9
8
  readonly githubDecl: GithubDeclLoader;
@@ -13,11 +12,4 @@ export interface GithubInstallDeps {
13
12
  readonly nowMs?: number;
14
13
  }
15
14
  export declare function githubDeclFromVctx(vctx: VibesApiSQLCtx): GithubDeclLoader;
16
- export declare function resetGithubInstallTemplatesForTests(): void;
17
- export declare function githubInstallTemplates(src: {
18
- readonly workspace: string;
19
- readonly fetchAsset: (url: string) => Promise<Result<ReadableStream<Uint8Array>>>;
20
- }): GithubInstallTemplateLoader;
21
- export declare function escapeHtml(text: string): string;
22
- export declare function fillTemplate(template: string, values: Readonly<Record<string, string>>): string;
23
15
  export declare function handleGithubInstall(request: Request, env: CFEnv, deps: GithubInstallDeps): Promise<Response>;
@@ -1,8 +1,8 @@
1
- import { BuildURI, KeyedResolvOnce, loadAsset, URI } from "@adviser/cement";
2
- import { getAppHtmlUrl } from "../intern/github-app-auth.js";
1
+ import { URI } from "@adviser/cement";
3
2
  import { loadSelectedBackend } from "../intern/load-selected-backend.js";
4
- import { createPromptAssetFetch } from "../intern/prompt-asset-fetch.js";
5
- import { appExists, GITHUB_CONSENT_STATE_TTL_MS, GITHUB_SETUP_STATE_RE, htmlPage, ownsHandle, recordGithubConsent, sessionTokenFrom, signGithubConsentState, sqlFor, stateSecret, } from "./github-setup.js";
3
+ import { appExists, GITHUB_CONSENT_STATE_TTL_MS, GITHUB_SETUP_STATE_RE, githubAuthorizeUrl, ownsHandle, recordGithubConsent, sessionTokenFrom, sqlFor, githubOAuthReady, } from "./github-setup.js";
4
+ import { flowRedirect, htmlPage, templatePage } from "./github-templates.js";
5
+ export { escapeHtml, fillFragments, fillTemplate, githubInstallTemplates, resetGithubInstallTemplatesForTests, } from "./github-templates.js";
6
6
  export function githubDeclFromVctx(vctx) {
7
7
  return async function loadGithubDecl(owner, slug) {
8
8
  const loaded = await loadSelectedBackend(vctx, owner, slug);
@@ -15,51 +15,6 @@ export function githubDeclFromVctx(vctx) {
15
15
  return loaded.parsed.github;
16
16
  };
17
17
  }
18
- const templateOnce = new KeyedResolvOnce();
19
- export function resetGithubInstallTemplatesForTests() {
20
- templateOnce.reset();
21
- }
22
- export function githubInstallTemplates(src) {
23
- const fetchImpl = createPromptAssetFetch({ fetchAsset: (url) => src.fetchAsset(url) });
24
- const fallBackUrl = BuildURI.from(src.workspace).appendRelative("@vibes.diy/api-svc/public/").toString();
25
- return async function loadTemplate(name) {
26
- const r = await templateOnce
27
- .get(name)
28
- .once(() => loadAsset(`./${name}`, { fallBackUrl, basePath: () => import.meta.url, mock: { fetch: fetchImpl } }));
29
- if (r.isErr())
30
- templateOnce.unget(name);
31
- return r;
32
- };
33
- }
34
- export function escapeHtml(text) {
35
- return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
36
- }
37
- export function fillTemplate(template, values) {
38
- return template.replace(/\{\{(\w+)\}\}/g, (match, key) => Object.prototype.hasOwnProperty.call(values, key) ? escapeHtml(values[key]) : match);
39
- }
40
- async function templatePage(deps, page, values) {
41
- const rTemplate = await deps.templates(page.name);
42
- if (rTemplate.isErr()) {
43
- console.error(`[github-install] template ${page.name} unreadable:`, rTemplate.Err().message);
44
- return htmlPage("Not available", "This page could not be shown right now. Try again in a moment.", 503);
45
- }
46
- return new Response(fillTemplate(rTemplate.Ok(), values), {
47
- status: page.status,
48
- headers: {
49
- "Content-Type": "text/html; charset=utf-8",
50
- "Cache-Control": "no-store",
51
- "X-Frame-Options": "DENY",
52
- "Content-Security-Policy": "default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'none'",
53
- },
54
- });
55
- }
56
- function installUrlFor(htmlUrl, state) {
57
- const base = URI.from(htmlUrl);
58
- return BuildURI.from(htmlUrl)
59
- .pathname(`${base.pathname.replace(/\/+$/, "")}/installations/new`)
60
- .setParam("state", state)
61
- .toString();
62
- }
63
18
  export async function handleGithubInstall(request, env, deps) {
64
19
  const appId = env.VIBES_GH_APP_ID ?? "";
65
20
  const privateKeyPem = env.VIBES_GH_APP_PRIVATE_KEY ?? "";
@@ -75,7 +30,7 @@ export async function handleGithubInstall(request, env, deps) {
75
30
  const token = sessionTokenFrom(request);
76
31
  const userId = token === undefined ? undefined : await deps.verifySessionToken(token);
77
32
  if (userId === undefined) {
78
- return templatePage(deps, { name: "github-install-signin.html", status: 401 }, { vibe, vibeHref });
33
+ return templatePage(deps.templates, { name: "github-install-signin.html", status: 401 }, { vibe, vibeHref });
79
34
  }
80
35
  const sql = sqlFor(env, deps);
81
36
  if (!(await appExists(sql, owner, slug))) {
@@ -87,23 +42,22 @@ export async function handleGithubInstall(request, env, deps) {
87
42
  return htmlPage("Not open to visitors", "This app has not asked visitors to connect their GitHub repositories, so only its author can connect one.", 403);
88
43
  }
89
44
  const nowMs = deps.nowMs ?? Date.now();
90
- const secret = stateSecret(env);
91
- if (decl?.bind === "anyone" && secret === undefined) {
92
- return htmlPage("Not available", "Connecting GitHub is not fully set up on this environment yet.", 503);
93
- }
94
- const rHtmlUrl = await getAppHtmlUrl({ appId, privateKeyPem, nowMs, fetchImpl: deps.fetchImpl });
95
- if (rHtmlUrl.isErr()) {
96
- console.error("[github-install] could not resolve the App's install URL:", rHtmlUrl.Err().message);
97
- return htmlPage("GitHub said no", "We could not reach GitHub to start the install. Try again in a moment.", 502);
98
- }
99
- if (decl?.bind === "anyone" && secret !== undefined) {
45
+ const ready = githubOAuthReady(env);
46
+ if (ready.ok === false)
47
+ return ready.refusal;
48
+ if (decl?.bind === "anyone") {
100
49
  const id = await recordGithubConsent(sql, { userId, owner, slug, nowMs });
101
- const consent = await signGithubConsentState(secret, { id, owner, slug, userId, exp: nowMs + GITHUB_CONSENT_STATE_TTL_MS });
102
- return templatePage(deps, { name: "github-install-consent.html", status: 200 }, { vibe, why: decl.why, installUrl: installUrlFor(rHtmlUrl.Ok(), consent), vibeHref });
103
- }
104
- return new Response(null, {
105
- status: 302,
106
- headers: { Location: installUrlFor(rHtmlUrl.Ok(), vibe), "Cache-Control": "no-store" },
107
- });
50
+ const authorize = await githubAuthorizeUrl(env, {
51
+ owner,
52
+ slug,
53
+ exp: nowMs + GITHUB_CONSENT_STATE_TTL_MS,
54
+ consent: { id, userId },
55
+ });
56
+ if (authorize.ok === false)
57
+ return authorize.refusal;
58
+ return templatePage(deps.templates, { name: "github-install-consent.html", status: 200 }, { vibe, why: decl.why, continueUrl: authorize.url, vibeHref });
59
+ }
60
+ const authorize = await githubAuthorizeUrl(env, { owner, slug, exp: nowMs + GITHUB_CONSENT_STATE_TTL_MS });
61
+ return authorize.ok ? flowRedirect(authorize.url) : authorize.refusal;
108
62
  }
109
63
  //# sourceMappingURL=github-install.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"github-install.js","sourceRoot":"","sources":["../../jsr/public/github-install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"github-install.js","sourceRoot":"","sources":["../../jsr/public/github-install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ <li style="margin: 0.4rem 0">
2
+ <label>
3
+ <input type="checkbox" name="repo" value="{{repo}}" {{checked}} {{disabled}} />
4
+ <span style="font-weight: 600">{{repo}}</span>
5
+ </label>
6
+ <span style="color: #666">{{note}}</span>
7
+ </li>
@@ -0,0 +1,28 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Choose repositories</title>
7
+ </head>
8
+ <body style="font-family: system-ui, sans-serif; max-width: 32rem; margin: 4rem auto; padding: 0 1rem; line-height: 1.5">
9
+ <main>
10
+ <h1 style="font-size: 1.4rem">Choose repositories</h1>
11
+ <p>
12
+ Tick the repositories <strong>{{vibe}}</strong> gets. Each vibe hears only the repositories you choose for it, so your other
13
+ vibes keep exactly what they have. Untick one to take it off this vibe.
14
+ </p>
15
+ <form method="post" action="{{action}}">
16
+ <input type="hidden" name="state" value="{{state}}" />
17
+ <ul style="list-style: none; padding-left: 0">
18
+ {{rows}}
19
+ </ul>
20
+ <p style="display: flex; gap: 1rem; flex-wrap: wrap; align-items: center">
21
+ <button type="submit" style="font-weight: 600">Save</button>
22
+ <a href="{{vibeHref}}">Back to {{vibe}}</a>
23
+ </p>
24
+ </form>
25
+ <p>Missing a repository? Add it to the vibes.diy app on GitHub, then press the app's Connect button again.</p>
26
+ </main>
27
+ </body>
28
+ </html>
@@ -0,0 +1,3 @@
1
+ import { CFEnv } from "@vibes.diy/api-types";
2
+ import { type GithubSetupDeps } from "./github-setup.js";
3
+ export declare function handleGithubRepos(request: Request, env: CFEnv, deps: GithubSetupDeps): Promise<Response>;
@@ -0,0 +1,195 @@
1
+ import { exception2Result, Result } from "@adviser/cement";
2
+ import { and, eq, inArray, ne, or } from "drizzle-orm/sql/expressions";
3
+ import { isUniqueViolation } from "../intern/is-unique-violation.js";
4
+ import { appExists, claimGithubConsent, consentUsedPage, GITHUB_REPO_PICK_PROVIDER, githubConsentUnspent, mayBindVibe, notProvisionedPage, notYourVibePage, ownsHandle, sessionTokenFrom, sqlFor, stateSecret, verifyGithubRepoPickState, } from "./github-setup.js";
5
+ import { flowRedirect, htmlPage } from "./github-templates.js";
6
+ import { GITHUB_REPO_MAX_VIBES } from "./github-webhook.js";
7
+ function pickUsedPage() {
8
+ return htmlPage("Choice already saved", "That page has already saved a choice of repositories. Open the app and press its Connect button again to change it.", 403);
9
+ }
10
+ function pickExpiredPage() {
11
+ return htmlPage("Link expired", "That choice of repositories is no longer valid. Open the app and press its Connect button again.", 400);
12
+ }
13
+ async function claimPick(sql, pick, nowMs) {
14
+ const t = sql.tables.connectionApprovals;
15
+ const claimed = await sql.db
16
+ .update(t)
17
+ .set({ consumedAt: new Date(nowMs).toISOString() })
18
+ .where(and(eq(t.id, pick.id), eq(t.consumedAt, ""), eq(t.userId, pick.userId), eq(t.provider, GITHUB_REPO_PICK_PROVIDER), eq(t.ownerHandle, pick.owner), eq(t.appSlug, pick.slug)))
19
+ .returning({ id: t.id });
20
+ return claimed.length > 0;
21
+ }
22
+ async function bindOne(input) {
23
+ const { sql, pick, repoFullName, accountLogin, now } = input;
24
+ const t = sql.tables.githubRepoRoutes;
25
+ const rApplied = await exception2Result(() => sql.db
26
+ .insert(t)
27
+ .values({
28
+ installationId: pick.installationId,
29
+ repoFullName,
30
+ ownerHandle: pick.owner,
31
+ appSlug: pick.slug,
32
+ accountLogin,
33
+ installedByUserId: pick.userId,
34
+ created: now,
35
+ updated: now,
36
+ removedAt: "",
37
+ })
38
+ .onConflictDoUpdate({
39
+ target: [t.installationId, t.repoFullName, t.ownerHandle, t.appSlug],
40
+ set: { accountLogin, installedByUserId: pick.userId, updated: now, removedAt: "" },
41
+ setWhere: or(eq(t.installedByUserId, pick.userId), ne(t.removedAt, "")),
42
+ })
43
+ .returning({ repoFullName: t.repoFullName }));
44
+ if (rApplied.isOk())
45
+ return Result.Ok(rApplied.Ok().length > 0 ? "bound" : "held-here");
46
+ if (isUniqueViolation(rApplied.Err()) === false)
47
+ return Result.Err(rApplied.Err());
48
+ const reused = await sql.db
49
+ .update(t)
50
+ .set({
51
+ ownerHandle: pick.owner,
52
+ appSlug: pick.slug,
53
+ accountLogin,
54
+ installedByUserId: pick.userId,
55
+ updated: now,
56
+ removedAt: "",
57
+ })
58
+ .where(and(eq(t.installationId, pick.installationId), eq(t.repoFullName, repoFullName), ne(t.removedAt, "")))
59
+ .returning({ repoFullName: t.repoFullName });
60
+ return Result.Ok(reused.length > 0 ? "bound" : "held-elsewhere");
61
+ }
62
+ async function inChunks(items, fn) {
63
+ const out = [];
64
+ for (let i = 0; i < items.length; i = i + IN_ARRAY_CHUNK) {
65
+ out.push(...(await fn(items.slice(i, i + IN_ARRAY_CHUNK))));
66
+ }
67
+ return out;
68
+ }
69
+ const IN_ARRAY_CHUNK = 50;
70
+ async function otherVibesFed(input) {
71
+ const t = input.sql.tables.githubRepoRoutes;
72
+ const rows = await input.sql.db
73
+ .select({ ownerHandle: t.ownerHandle, appSlug: t.appSlug })
74
+ .from(t)
75
+ .where(and(eq(t.installationId, input.pick.installationId), eq(t.repoFullName, input.repoFullName), eq(t.removedAt, "")))
76
+ .limit(GITHUB_REPO_MAX_VIBES + 1);
77
+ return rows.filter((r) => r.ownerHandle !== input.pick.owner || r.appSlug !== input.pick.slug).length;
78
+ }
79
+ export async function handleGithubRepos(request, env, deps) {
80
+ const signingKey = stateSecret(env);
81
+ if (signingKey === undefined)
82
+ return notProvisionedPage();
83
+ const rForm = await exception2Result(() => request.formData());
84
+ if (rForm.isErr())
85
+ return pickExpiredPage();
86
+ const form = rForm.Ok();
87
+ const rawState = form.get("state");
88
+ const nowMs = deps.nowMs ?? Date.now();
89
+ const pick = typeof rawState === "string" ? await verifyGithubRepoPickState(signingKey, rawState, nowMs) : undefined;
90
+ if (pick === undefined)
91
+ return pickExpiredPage();
92
+ const token = sessionTokenFrom(request);
93
+ const sessionUserId = token === undefined ? undefined : await deps.verifySessionToken(token);
94
+ if (sessionUserId !== undefined && sessionUserId !== pick.userId) {
95
+ console.error(`[github-repos] pick state for clerk user ${pick.userId} presented by ${sessionUserId}; refusing`);
96
+ return pickExpiredPage();
97
+ }
98
+ const userId = pick.userId;
99
+ const sql = sqlFor(env, deps);
100
+ const isOwner = await ownsHandle(sql, userId, pick.owner);
101
+ if (isOwner === false) {
102
+ if (pick.consentId === undefined ||
103
+ (await mayBindVibe(sql, { userId, owner: pick.owner, slug: pick.slug }, deps.githubDecl)) === false) {
104
+ return notYourVibePage();
105
+ }
106
+ if ((await githubConsentUnspent(sql, { id: pick.consentId, userId, owner: pick.owner, slug: pick.slug })) === false) {
107
+ return consentUsedPage();
108
+ }
109
+ }
110
+ if ((await appExists(sql, pick.owner, pick.slug)) === false) {
111
+ return htmlPage("Vibe not found", "That vibe does not exist. Publish it first, then connect the repository.", 404);
112
+ }
113
+ const offered = new Map(pick.repos.map((r) => [r.fullName, r]));
114
+ const ticked = new Set();
115
+ for (const value of form.getAll("repo")) {
116
+ if (typeof value !== "string")
117
+ continue;
118
+ const name = value.toLowerCase();
119
+ if (offered.has(name))
120
+ ticked.add(name);
121
+ }
122
+ const t = sql.tables.githubRepoRoutes;
123
+ const offeredNames = [...offered.keys()];
124
+ const removable = (await inChunks(offeredNames, (names) => sql.db
125
+ .select({ repoFullName: t.repoFullName, installedByUserId: t.installedByUserId })
126
+ .from(t)
127
+ .where(and(eq(t.installationId, pick.installationId), eq(t.ownerHandle, pick.owner), eq(t.appSlug, pick.slug), eq(t.removedAt, ""), inArray(t.repoFullName, [...names])))))
128
+ .filter((row) => ticked.has(row.repoFullName) === false && (isOwner || row.installedByUserId === userId))
129
+ .map((row) => row.repoFullName);
130
+ if (ticked.size === 0 && removable.length === 0) {
131
+ return htmlPage("No repositories chosen", "Tick at least one repository for this vibe, then save. Go back to choose.", 400);
132
+ }
133
+ if ((await claimPick(sql, pick, nowMs)) === false)
134
+ return pickUsedPage();
135
+ if (pick.consentId !== undefined &&
136
+ isOwner === false &&
137
+ (await claimGithubConsent(sql, { id: pick.consentId, userId, owner: pick.owner, slug: pick.slug, nowMs })) === false) {
138
+ return consentUsedPage();
139
+ }
140
+ const now = new Date(nowMs).toISOString();
141
+ await inChunks(removable, async (names) => {
142
+ await sql.db
143
+ .delete(t)
144
+ .where(and(eq(t.installationId, pick.installationId), eq(t.ownerHandle, pick.owner), eq(t.appSlug, pick.slug), eq(t.removedAt, ""), inArray(t.repoFullName, [...names]), ...(isOwner ? [] : [eq(t.installedByUserId, userId)])));
145
+ return [];
146
+ });
147
+ let bound = 0;
148
+ let heldHere = 0;
149
+ let heldElsewhere = 0;
150
+ let atCapacity = 0;
151
+ for (const name of ticked) {
152
+ const repo = offered.get(name);
153
+ if (repo === undefined)
154
+ continue;
155
+ if ((await otherVibesFed({ sql, pick, repoFullName: name })) >= GITHUB_REPO_MAX_VIBES) {
156
+ atCapacity = atCapacity + 1;
157
+ console.warn(`[github-repos] installation ${pick.installationId} repo ${name} already feeds ${GITHUB_REPO_MAX_VIBES} vibes; ` +
158
+ `not adding ${pick.owner}/${pick.slug} (clerk user ${userId})`);
159
+ continue;
160
+ }
161
+ const rOutcome = await bindOne({ sql, pick, repoFullName: name, accountLogin: repo.accountLogin, now });
162
+ if (rOutcome.isErr()) {
163
+ console.error(`[github-repos] bind of ${name} to ${pick.owner}/${pick.slug} failed:`, rOutcome.Err().message);
164
+ return htmlPage("Not saved", "We could not save your choice of repositories. Open the app and press its Connect button again.", 500);
165
+ }
166
+ switch (rOutcome.Ok()) {
167
+ case "bound":
168
+ bound = bound + 1;
169
+ break;
170
+ case "held-here":
171
+ heldHere = heldHere + 1;
172
+ console.warn(`[github-repos] installation ${pick.installationId} repo ${name} is connected to ${pick.owner}/${pick.slug} by ` +
173
+ `another clerk user; leaving it theirs (clerk user ${userId} asked)`);
174
+ break;
175
+ case "held-elsewhere":
176
+ heldElsewhere = heldElsewhere + 1;
177
+ console.warn(`[github-repos] installation ${pick.installationId} repo ${name} already feeds another vibe; the one-vibe ` +
178
+ `index holds until schema step 3 (clerk user ${userId}, ${pick.owner}/${pick.slug})`);
179
+ break;
180
+ }
181
+ }
182
+ if (atCapacity > 0) {
183
+ return htmlPage("That repository is popular", `One repository can feed up to ${GITHUB_REPO_MAX_VIBES} vibes, and one you chose already feeds ${GITHUB_REPO_MAX_VIBES} vibes, so ` +
184
+ "it was not added here. The rest of your choice is saved.", 409);
185
+ }
186
+ if (heldElsewhere > 0) {
187
+ return htmlPage("Switching on shortly", "Connecting one repository to more than one vibe is switching on shortly, so one of the repositories you chose " +
188
+ "could not be added here yet; please try again soon. The rest of your choice is saved.", 409);
189
+ }
190
+ if (ticked.size > 0 && bound === 0 && heldHere > 0 && removable.length === 0) {
191
+ return htmlPage("Already connected", "Those repositories are already connected to this vibe by someone else, so they stay theirs.", 409);
192
+ }
193
+ return flowRedirect(`/vibe/${pick.owner}/${pick.slug}`);
194
+ }
195
+ //# sourceMappingURL=github-repos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-repos.js","sourceRoot":"","sources":["../../jsr/public/github-repos.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import { CFEnv } from "@vibes.diy/api-types";
2
2
  import { cfDrizzle, VibesApiTables } from "@vibes.diy/api-sql";
3
3
  import type { BackendGithubDecl } from "@vibes.diy/vibe-runtime/parse-backend-config.js";
4
+ import { type GithubInstallTemplateLoader } from "./github-templates.js";
5
+ export { htmlPage } from "./github-templates.js";
4
6
  export interface GithubSetupSql {
5
7
  db: ReturnType<typeof cfDrizzle>["db"];
6
8
  tables: VibesApiTables;
@@ -12,10 +14,10 @@ export interface GithubSetupDeps {
12
14
  readonly fetchImpl?: typeof fetch;
13
15
  readonly nowMs?: number;
14
16
  readonly githubDecl?: GithubDeclLoader;
17
+ readonly templates?: GithubInstallTemplateLoader;
15
18
  }
16
19
  export type GithubDeclLoader = (owner: string, slug: string) => Promise<BackendGithubDecl | undefined>;
17
20
  export declare const GITHUB_SETUP_STATE_RE: RegExp;
18
- export declare function htmlPage(title: string, body: string, status: number): Response;
19
21
  export declare function sessionCookieTokenFrom(request: Request): string | undefined;
20
22
  export declare function sessionTokenFrom(request: Request): string | undefined;
21
23
  export declare const GITHUB_SETUP_OAUTH_STATE_TTL_MS: number;
@@ -23,10 +25,10 @@ export declare const GITHUB_OAUTH_AUTHORIZE_URL = "https://github.com/login/oaut
23
25
  export declare const USER_AGENT = "vibes.diy-github-app";
24
26
  export declare const GITHUB_SETUP_MAX_REPOS = 200;
25
27
  export declare function stateSecret(env: CFEnv): string | undefined;
26
- interface SetupOAuthState {
28
+ export interface SetupOAuthState {
27
29
  readonly owner: string;
28
30
  readonly slug: string;
29
- readonly installationId: string;
31
+ readonly installationId?: string;
30
32
  readonly exp: number;
31
33
  readonly consent?: {
32
34
  readonly id: string;
@@ -44,6 +46,11 @@ export declare function exchangeOAuthCode(input: {
44
46
  code: string;
45
47
  fetchImpl: typeof fetch;
46
48
  }): Promise<string | undefined>;
49
+ export interface UserInstallation {
50
+ readonly id: string;
51
+ readonly accountLogin: string;
52
+ readonly settingsUrl?: string;
53
+ }
47
54
  export declare function sqlFor(env: CFEnv, deps: {
48
55
  readonly sql?: GithubSetupSql;
49
56
  }): GithubSetupSql;
@@ -73,4 +80,56 @@ export declare function recordGithubConsent(sql: GithubSetupSql, input: {
73
80
  readonly slug: string;
74
81
  readonly nowMs: number;
75
82
  }): Promise<string>;
76
- export {};
83
+ interface ConsentRowKey {
84
+ readonly id: string;
85
+ readonly userId: string;
86
+ readonly owner: string;
87
+ readonly slug: string;
88
+ }
89
+ export declare function githubConsentUnspent(sql: GithubSetupSql, key: ConsentRowKey): Promise<boolean>;
90
+ export declare function claimGithubConsent(sql: GithubSetupSql, key: ConsentRowKey & {
91
+ readonly nowMs: number;
92
+ }): Promise<boolean>;
93
+ export declare function notYourVibePage(): Response;
94
+ export declare const GITHUB_SETUP_PATH = "/github/setup";
95
+ export declare function notProvisionedPage(): Response;
96
+ export declare function consentUsedPage(): Response;
97
+ export type GithubAuthorizeUrl = {
98
+ readonly ok: true;
99
+ readonly url: string;
100
+ } | {
101
+ readonly ok: false;
102
+ readonly refusal: Response;
103
+ };
104
+ export type GithubOAuthReady = {
105
+ readonly ok: true;
106
+ readonly signingKey: string;
107
+ readonly clientId: string;
108
+ readonly redirectUri: string;
109
+ } | {
110
+ readonly ok: false;
111
+ readonly refusal: Response;
112
+ };
113
+ export declare function githubOAuthReady(env: CFEnv): GithubOAuthReady;
114
+ export declare function githubAuthorizeUrl(env: CFEnv, state: SetupOAuthState): Promise<GithubAuthorizeUrl>;
115
+ export declare function installUrlFor(htmlUrl: string, state: string): string;
116
+ export declare const GITHUB_REPOS_PATH = "/github/repos";
117
+ export declare const GITHUB_REPO_PICK_STATE_PREFIX = "r1.";
118
+ export declare const GITHUB_REPO_PICK_STATE_TTL_MS: number;
119
+ export declare const GITHUB_REPO_PICK_PROVIDER = "github-app-repos";
120
+ export interface PickedRepo {
121
+ readonly fullName: string;
122
+ readonly accountLogin: string;
123
+ }
124
+ export interface GithubRepoPickState {
125
+ readonly id: string;
126
+ readonly owner: string;
127
+ readonly slug: string;
128
+ readonly installationId: string;
129
+ readonly userId: string;
130
+ readonly repos: readonly PickedRepo[];
131
+ readonly consentId?: string;
132
+ readonly exp: number;
133
+ }
134
+ export declare function signGithubRepoPickState(secret: string, state: GithubRepoPickState): Promise<string>;
135
+ export declare function verifyGithubRepoPickState(secret: string, signed: string, nowMs: number): Promise<GithubRepoPickState | undefined>;