@heychunky/core 0.1.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 (118) hide show
  1. package/README.md +2 -0
  2. package/dist/admin/apps.d.ts +49 -0
  3. package/dist/admin/apps.d.ts.map +1 -0
  4. package/dist/admin/apps.js +97 -0
  5. package/dist/admin/apps.js.map +1 -0
  6. package/dist/admin/index.d.ts +26 -0
  7. package/dist/admin/index.d.ts.map +1 -0
  8. package/dist/admin/index.js +27 -0
  9. package/dist/admin/index.js.map +1 -0
  10. package/dist/admin/master.d.ts +9 -0
  11. package/dist/admin/master.d.ts.map +1 -0
  12. package/dist/admin/master.js +14 -0
  13. package/dist/admin/master.js.map +1 -0
  14. package/dist/admin/provision.d.ts +42 -0
  15. package/dist/admin/provision.d.ts.map +1 -0
  16. package/dist/admin/provision.js +157 -0
  17. package/dist/admin/provision.js.map +1 -0
  18. package/dist/admin/run.d.ts +89 -0
  19. package/dist/admin/run.d.ts.map +1 -0
  20. package/dist/admin/run.js +218 -0
  21. package/dist/admin/run.js.map +1 -0
  22. package/dist/admin/secrets/infisical.d.ts +45 -0
  23. package/dist/admin/secrets/infisical.d.ts.map +1 -0
  24. package/dist/admin/secrets/infisical.js +182 -0
  25. package/dist/admin/secrets/infisical.js.map +1 -0
  26. package/dist/admin/services/agentmail.d.ts +16 -0
  27. package/dist/admin/services/agentmail.d.ts.map +1 -0
  28. package/dist/admin/services/agentmail.js +43 -0
  29. package/dist/admin/services/agentmail.js.map +1 -0
  30. package/dist/admin/services/ai-gateway.d.ts +13 -0
  31. package/dist/admin/services/ai-gateway.d.ts.map +1 -0
  32. package/dist/admin/services/ai-gateway.js +32 -0
  33. package/dist/admin/services/ai-gateway.js.map +1 -0
  34. package/dist/admin/services/bunny.d.ts +16 -0
  35. package/dist/admin/services/bunny.d.ts.map +1 -0
  36. package/dist/admin/services/bunny.js +59 -0
  37. package/dist/admin/services/bunny.js.map +1 -0
  38. package/dist/admin/services/cloudflare.d.ts +42 -0
  39. package/dist/admin/services/cloudflare.d.ts.map +1 -0
  40. package/dist/admin/services/cloudflare.js +97 -0
  41. package/dist/admin/services/cloudflare.js.map +1 -0
  42. package/dist/admin/services/db.d.ts +16 -0
  43. package/dist/admin/services/db.d.ts.map +1 -0
  44. package/dist/admin/services/db.js +81 -0
  45. package/dist/admin/services/db.js.map +1 -0
  46. package/dist/admin/services/elevenlabs.d.ts +22 -0
  47. package/dist/admin/services/elevenlabs.d.ts.map +1 -0
  48. package/dist/admin/services/elevenlabs.js +45 -0
  49. package/dist/admin/services/elevenlabs.js.map +1 -0
  50. package/dist/admin/services/firecrawl.d.ts +13 -0
  51. package/dist/admin/services/firecrawl.d.ts.map +1 -0
  52. package/dist/admin/services/firecrawl.js +36 -0
  53. package/dist/admin/services/firecrawl.js.map +1 -0
  54. package/dist/admin/services/fireworks.d.ts +9 -0
  55. package/dist/admin/services/fireworks.d.ts.map +1 -0
  56. package/dist/admin/services/fireworks.js +31 -0
  57. package/dist/admin/services/fireworks.js.map +1 -0
  58. package/dist/admin/services/github.d.ts +26 -0
  59. package/dist/admin/services/github.d.ts.map +1 -0
  60. package/dist/admin/services/github.js +164 -0
  61. package/dist/admin/services/github.js.map +1 -0
  62. package/dist/admin/services/neon.d.ts +42 -0
  63. package/dist/admin/services/neon.d.ts.map +1 -0
  64. package/dist/admin/services/neon.js +157 -0
  65. package/dist/admin/services/neon.js.map +1 -0
  66. package/dist/admin/services/resend.d.ts +38 -0
  67. package/dist/admin/services/resend.d.ts.map +1 -0
  68. package/dist/admin/services/resend.js +81 -0
  69. package/dist/admin/services/resend.js.map +1 -0
  70. package/dist/admin/services/togetherai.d.ts +10 -0
  71. package/dist/admin/services/togetherai.d.ts.map +1 -0
  72. package/dist/admin/services/togetherai.js +36 -0
  73. package/dist/admin/services/togetherai.js.map +1 -0
  74. package/dist/admin/services/vercel.d.ts +66 -0
  75. package/dist/admin/services/vercel.d.ts.map +1 -0
  76. package/dist/admin/services/vercel.js +209 -0
  77. package/dist/admin/services/vercel.js.map +1 -0
  78. package/dist/admin/syncenv.d.ts +12 -0
  79. package/dist/admin/syncenv.d.ts.map +1 -0
  80. package/dist/admin/syncenv.js +114 -0
  81. package/dist/admin/syncenv.js.map +1 -0
  82. package/dist/admin/users.d.ts +27 -0
  83. package/dist/admin/users.d.ts.map +1 -0
  84. package/dist/admin/users.js +48 -0
  85. package/dist/admin/users.js.map +1 -0
  86. package/dist/config/environments.d.ts +50 -0
  87. package/dist/config/environments.d.ts.map +1 -0
  88. package/dist/config/environments.js +62 -0
  89. package/dist/config/environments.js.map +1 -0
  90. package/dist/config/names.d.ts +45 -0
  91. package/dist/config/names.d.ts.map +1 -0
  92. package/dist/config/names.js +75 -0
  93. package/dist/config/names.js.map +1 -0
  94. package/dist/http/errors.d.ts +45 -0
  95. package/dist/http/errors.d.ts.map +1 -0
  96. package/dist/http/errors.js +70 -0
  97. package/dist/http/errors.js.map +1 -0
  98. package/dist/http/request.d.ts +36 -0
  99. package/dist/http/request.d.ts.map +1 -0
  100. package/dist/http/request.js +73 -0
  101. package/dist/http/request.js.map +1 -0
  102. package/dist/index.d.ts +15 -0
  103. package/dist/index.d.ts.map +1 -0
  104. package/dist/index.js +15 -0
  105. package/dist/index.js.map +1 -0
  106. package/dist/registry.d.ts +66 -0
  107. package/dist/registry.d.ts.map +1 -0
  108. package/dist/registry.js +137 -0
  109. package/dist/registry.js.map +1 -0
  110. package/dist/secrets/store.d.ts +50 -0
  111. package/dist/secrets/store.d.ts.map +1 -0
  112. package/dist/secrets/store.js +71 -0
  113. package/dist/secrets/store.js.map +1 -0
  114. package/dist/services/types.d.ts +39 -0
  115. package/dist/services/types.d.ts.map +1 -0
  116. package/dist/services/types.js +28 -0
  117. package/dist/services/types.js.map +1 -0
  118. package/package.json +40 -0
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # heychunky-core
2
+ The Chunky Core Library
@@ -0,0 +1,49 @@
1
+ import type { RunContext } from "./run.ts";
2
+ export interface App {
3
+ id: string;
4
+ name: string;
5
+ owner_id: string;
6
+ org: string | null;
7
+ repo: string | null;
8
+ vercel_project: string | null;
9
+ neon_project: string | null;
10
+ created_at: string;
11
+ }
12
+ /** Refused because the owner already has as many apps as they may. */
13
+ export declare class AppLimitError extends Error {
14
+ readonly limit: number;
15
+ constructor(email: string, limit: number);
16
+ }
17
+ export interface AppRecord {
18
+ name: string;
19
+ owner: string;
20
+ org?: string | undefined;
21
+ repo?: string | undefined;
22
+ vercelProject?: string | undefined;
23
+ neonProject?: string | undefined;
24
+ }
25
+ /** The user id for an email, or the sole superadmin when none is named. */
26
+ export declare function ownerId(email: string | undefined, ctx: RunContext): Promise<string>;
27
+ /**
28
+ * Refuse before anything is created, if the owner is at their limit.
29
+ *
30
+ * Asked before provisioning rather than at the point of recording, because by
31
+ * then a repository, a database and a deployment target already exist and the
32
+ * limit has been passed rather than enforced.
33
+ *
34
+ * A count of what someone already has, against a number on their row. It is
35
+ * not billing — it is the thing that makes inviting someone a bounded
36
+ * decision, which is what lets invitations be given out at all.
37
+ */
38
+ export declare function assertCanCreate(owner: string, ctx: RunContext): Promise<void>;
39
+ /**
40
+ * Record an app, or update what is known about one.
41
+ *
42
+ * By name, because that is what is unique across the factory — a repository, a
43
+ * Vercel project and a database all carry it. Re-running provisioning fills in
44
+ * what a first, partial run could not, rather than making a second row.
45
+ */
46
+ export declare function recordApp(app: AppRecord, ctx: RunContext): Promise<App>;
47
+ /** Apps an owner has, or every app when none is named. */
48
+ export declare function listApps(owner: string | undefined, ctx: RunContext): Promise<App[]>;
49
+ //# sourceMappingURL=apps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.d.ts","sourceRoot":"","sources":["../../src/admin/apps.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,sEAAsE;AACtE,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBACX,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;CAKzC;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,2EAA2E;AAC3E,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAczF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAYnF;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAe7E;AAED,0DAA0D;AAC1D,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAUzF"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * The register of apps the factory has made.
3
+ *
4
+ * This used to be JSON files under ~/.heychunky/runs, which is exactly right
5
+ * for one operator on one machine and wrong for everything after: a second
6
+ * machine knows nothing, the worker cannot see what exists, and no row anywhere
7
+ * says whose an app is. It lives in the factory's own database now.
8
+ *
9
+ * `owner_id` is the tenancy boundary. Every question about what a developer may
10
+ * see is a `where owner_id = $1`, and superadmin is the role that omits it —
11
+ * which is why that column exists before there is a second user to put in it.
12
+ *
13
+ * The local history is not replaced by this: it records what a *run* did, step
14
+ * by step, and stays useful for exactly that. This records what an app *is*.
15
+ */
16
+ import { master } from "./master.js";
17
+ /** Refused because the owner already has as many apps as they may. */
18
+ export class AppLimitError extends Error {
19
+ limit;
20
+ constructor(email, limit) {
21
+ super(`${email} already has ${limit} app${limit === 1 ? "" : "s"}, which is their limit.`);
22
+ this.name = "AppLimitError";
23
+ this.limit = limit;
24
+ }
25
+ }
26
+ /** The user id for an email, or the sole superadmin when none is named. */
27
+ export async function ownerId(email, ctx) {
28
+ const conn = await master(ctx);
29
+ if (email) {
30
+ const { rows } = await conn.query("select id from users where lower(email) = lower($1)", [email]);
31
+ const id = rows[0]?.["id"];
32
+ if (!id)
33
+ throw new Error(`No user ${email}. An account is created before it owns anything.`);
34
+ return String(id);
35
+ }
36
+ // No owner named means the operator, and until the API can say who that is,
37
+ // the operator is the one account that can do everything.
38
+ const { rows } = await conn.query("select id from users where role = 'superadmin'");
39
+ const id = rows[0]?.["id"];
40
+ if (!id)
41
+ throw new Error("No superadmin, so an app has nobody to belong to.");
42
+ return String(id);
43
+ }
44
+ /**
45
+ * Refuse before anything is created, if the owner is at their limit.
46
+ *
47
+ * Asked before provisioning rather than at the point of recording, because by
48
+ * then a repository, a database and a deployment target already exist and the
49
+ * limit has been passed rather than enforced.
50
+ *
51
+ * A count of what someone already has, against a number on their row. It is
52
+ * not billing — it is the thing that makes inviting someone a bounded
53
+ * decision, which is what lets invitations be given out at all.
54
+ */
55
+ export async function assertCanCreate(owner, ctx) {
56
+ const conn = await master(ctx);
57
+ const { rows } = await conn.query(`select u.email, u.app_limit,
58
+ (select count(*) from apps a where a.owner_id = u.id) as owned
59
+ from users u where u.id = $1`, [owner]);
60
+ const row = rows[0];
61
+ if (!row)
62
+ throw new Error("No such owner.");
63
+ const limit = Number(row["app_limit"]);
64
+ if (Number(row["owned"]) >= limit)
65
+ throw new AppLimitError(String(row["email"]), limit);
66
+ }
67
+ /**
68
+ * Record an app, or update what is known about one.
69
+ *
70
+ * By name, because that is what is unique across the factory — a repository, a
71
+ * Vercel project and a database all carry it. Re-running provisioning fills in
72
+ * what a first, partial run could not, rather than making a second row.
73
+ */
74
+ export async function recordApp(app, ctx) {
75
+ const conn = await master(ctx);
76
+ const { rows } = await conn.write(`insert into apps (name, owner_id, org, repo, vercel_project, neon_project)
77
+ values ($1, $2, $3, $4, $5, $6)
78
+ on conflict (lower(name)) do update set
79
+ org = coalesce(excluded.org, apps.org),
80
+ repo = coalesce(excluded.repo, apps.repo),
81
+ vercel_project = coalesce(excluded.vercel_project, apps.vercel_project),
82
+ neon_project = coalesce(excluded.neon_project, apps.neon_project)
83
+ returning *`, [app.name, app.owner, app.org ?? null, app.repo ?? null,
84
+ app.vercelProject ?? null, app.neonProject ?? null]);
85
+ return rows[0];
86
+ }
87
+ /** Apps an owner has, or every app when none is named. */
88
+ export async function listApps(owner, ctx) {
89
+ const conn = await master(ctx);
90
+ const { rows } = owner
91
+ ? await conn.query(`select a.*, u.email as owner_email from apps a join users u on u.id = a.owner_id
92
+ where a.owner_id = $1 order by a.created_at`, [owner])
93
+ : await conn.query(`select a.*, u.email as owner_email from apps a join users u on u.id = a.owner_id
94
+ order by a.created_at`);
95
+ return rows;
96
+ }
97
+ //# sourceMappingURL=apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/admin/apps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @heychunky/core/admin — the operator side.
3
+ *
4
+ * Factory keys, provisioning, secret backends. Never imported by an app: the
5
+ * package's exports map keeps a bundler from reaching this path at all.
6
+ */
7
+ export * from "./secrets/infisical.ts";
8
+ export * from "./syncenv.ts";
9
+ export * from "./master.ts";
10
+ export * from "./apps.ts";
11
+ export * from "./users.ts";
12
+ export * from "./run.ts";
13
+ export * from "./provision.ts";
14
+ export * from "./services/github.ts";
15
+ export * from "./services/vercel.ts";
16
+ export * from "./services/neon.ts";
17
+ export * from "./services/cloudflare.ts";
18
+ export * from "./services/bunny.ts";
19
+ export * from "./services/resend.ts";
20
+ export * from "./services/agentmail.ts";
21
+ export * from "./services/elevenlabs.ts";
22
+ export * from "./services/ai-gateway.ts";
23
+ export * from "./services/togetherai.ts";
24
+ export * from "./services/fireworks.ts";
25
+ export * from "./services/firecrawl.ts";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAG/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @heychunky/core/admin — the operator side.
3
+ *
4
+ * Factory keys, provisioning, secret backends. Never imported by an app: the
5
+ * package's exports map keeps a bundler from reaching this path at all.
6
+ */
7
+ export * from "./secrets/infisical.js";
8
+ export * from "./syncenv.js";
9
+ export * from "./master.js";
10
+ export * from "./apps.js";
11
+ export * from "./users.js";
12
+ export * from "./run.js";
13
+ export * from "./provision.js";
14
+ // One file per service, matching the registry.
15
+ export * from "./services/github.js";
16
+ export * from "./services/vercel.js";
17
+ export * from "./services/neon.js";
18
+ export * from "./services/cloudflare.js";
19
+ export * from "./services/bunny.js";
20
+ export * from "./services/resend.js";
21
+ export * from "./services/agentmail.js";
22
+ export * from "./services/elevenlabs.js";
23
+ export * from "./services/ai-gateway.js";
24
+ export * from "./services/togetherai.js";
25
+ export * from "./services/fireworks.js";
26
+ export * from "./services/firecrawl.js";
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAE/B,+CAA+C;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { RunContext } from "./run.ts";
2
+ export declare const MASTER_DB = "infisical://heychunky-apps/production/heychunky-app/DATABASE_URL";
3
+ export declare const master: (ctx: RunContext) => Promise<{
4
+ query: (sql: string, params?: unknown[]) => Promise<import("./services/db.ts").Rows>;
5
+ write: (sql: string, params?: unknown[]) => Promise<import("./services/db.ts").Rows>;
6
+ tables(): Promise<string[]>;
7
+ columns(table: string): Promise<import("./services/db.ts").Column[]>;
8
+ }>;
9
+ //# sourceMappingURL=master.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master.d.ts","sourceRoot":"","sources":["../../src/admin/master.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,eAAO,MAAM,SAAS,qEAAqE,CAAC;AAE5F,eAAO,MAAM,MAAM,GAAU,KAAK,UAAU;;;;;EAAyC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The factory's own database.
3
+ *
4
+ * One register, named once. An app register or a user list that varied by
5
+ * environment would be several of each, and "which one is true" has no good
6
+ * answer — a developer's laptop, the worker and the API all read the same rows.
7
+ *
8
+ * It is heychunky-app's production database because that is what it is: the
9
+ * app is the factory's own app, and this is its data.
10
+ */
11
+ import { db } from "./services/db.js";
12
+ export const MASTER_DB = "infisical://heychunky-apps/production/heychunky-app/DATABASE_URL";
13
+ export const master = async (ctx) => db(await ctx.secrets.get(MASTER_DB));
14
+ //# sourceMappingURL=master.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master.js","sourceRoot":"","sources":["../../src/admin/master.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAGtC,MAAM,CAAC,MAAM,SAAS,GAAG,kEAAkE,CAAC;AAE5F,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,GAAe,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { type RunContext } from "./run.ts";
2
+ export interface AppSpec {
3
+ /** The app's name. Becomes the repository, the database and the project. */
4
+ name: string;
5
+ /** GitHub organisation. Omitted means the authenticated user's account. */
6
+ org?: string;
7
+ /** Give it a database. */
8
+ neon?: boolean;
9
+ /** Give it somewhere to deploy. */
10
+ vercel?: boolean;
11
+ }
12
+ export type StepState =
13
+ /** Already there. Nothing was done. */
14
+ "exists"
15
+ /** Made just now. */
16
+ | "created"
17
+ /** Would be made. Reported when planning. */
18
+ | "would-create"
19
+ /** Tried and could not. The run stops here. */
20
+ | "failed";
21
+ export interface StepResult {
22
+ step: string;
23
+ state: StepState;
24
+ detail: string;
25
+ }
26
+ export interface Run {
27
+ app: string;
28
+ /** True when nothing was created, because nothing was confirmed. */
29
+ planned: boolean;
30
+ steps: StepResult[];
31
+ /** Every step reached a good state. */
32
+ ok: boolean;
33
+ }
34
+ /**
35
+ * Run every wanted step, in order, stopping at the first failure.
36
+ *
37
+ * Returns rather than throws: a partial run is the normal outcome of
38
+ * provisioning against five providers, and the caller needs to see how far it
39
+ * got. A thrown error would lose exactly the steps that already succeeded.
40
+ */
41
+ export declare function provision(spec: AppSpec, ctx: RunContext): Promise<Run>;
42
+ //# sourceMappingURL=provision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision.d.ts","sourceRoot":"","sources":["../../src/admin/provision.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAGpD,MAAM,WAAW,OAAO;IACtB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,SAAS;AACnB,uCAAuC;AACrC,QAAQ;AACV,qBAAqB;GACnB,SAAS;AACX,6CAA6C;GAC3C,cAAc;AAChB,+CAA+C;GAC7C,QAAQ,CAAC;AAEb,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,GAAG;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,uCAAuC;IACvC,EAAE,EAAE,OAAO,CAAC;CACb;AA8GD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAgC5E"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Provisioning an app: repository, database, deployment target.
3
+ *
4
+ * This is the engine, and it has two callers by design. `heychunky new` runs it
5
+ * from a terminal; the API will run it from a job the worker picked up. Neither
6
+ * owns the logic, so neither can drift from the other.
7
+ *
8
+ * Two properties make the second caller possible, and both are worth the cost
9
+ * even while only the first exists:
10
+ *
11
+ * Every step asks before it acts. A step that finds its work already done
12
+ * reports `exists` and moves on, so a run that died halfway is safe to
13
+ * repeat — which is the only reason an unattended worker can retry at all.
14
+ *
15
+ * A failure stops the run rather than skipping past it. Later steps depend on
16
+ * earlier ones, and a Vercel project linked to a repository that was never
17
+ * created is a worse outcome than an honest halt.
18
+ *
19
+ * Without `confirmed` this plans: every step is looked up, nothing is created.
20
+ * That falls out of the gate model rather than being a separate dry-run path,
21
+ * so the plan can never disagree with the run.
22
+ */
23
+ import { github } from "./services/github.js";
24
+ import { vercel } from "./services/vercel.js";
25
+ import { neon } from "./services/neon.js";
26
+ import { KEY_FOR } from "./run.js";
27
+ import { BRANCHED, DEFAULT_BRANCH } from "../config/environments.js";
28
+ const STEPS = [
29
+ {
30
+ name: "github repo",
31
+ wanted: () => true,
32
+ async find(spec, { gh }, carry) {
33
+ // What would be created, replaced below by what actually exists — the
34
+ // repository may be named a variant of the app, and later steps must link
35
+ // to the real one rather than to the name we guessed.
36
+ const owner = spec.org ?? (await gh.login());
37
+ carry.repo = `${owner}/${spec.name}`;
38
+ const repo = await gh.findRepoFor(spec.name, spec.org);
39
+ if (!repo)
40
+ return undefined;
41
+ carry.repo = repo.full_name;
42
+ return `${repo.full_name} · ${repo.private ? "private" : "PUBLIC"}`;
43
+ },
44
+ async create(spec, { gh }, carry) {
45
+ const repo = await gh.createRepo(spec.name, { org: spec.org });
46
+ carry.repo = repo.full_name;
47
+ return `${repo.full_name} · private`;
48
+ },
49
+ },
50
+ {
51
+ name: "neon project",
52
+ wanted: (spec) => spec.neon !== false,
53
+ async find(spec, { nn }, carry) {
54
+ const p = await nn.findProject(spec.name);
55
+ if (!p)
56
+ return undefined;
57
+ carry.neonProject = p.id;
58
+ return `${p.name} · ${p.region_id} · pg${p.pg_version}`;
59
+ },
60
+ async create(spec, { nn }, carry) {
61
+ const p = await nn.createProject(spec.name);
62
+ carry.neonProject = p.id;
63
+ return `${p.name} · ${p.region_id} · pg${p.pg_version}`;
64
+ },
65
+ },
66
+ {
67
+ // One step rather than five, because five would say the same thing five
68
+ // times in every plan. It still creates only what is absent, so a run that
69
+ // died after three branches makes the other two and no more.
70
+ name: "neon branches",
71
+ wanted: (spec) => spec.neon !== false,
72
+ async find(spec, { nn }, carry) {
73
+ if (!carry.neonProject)
74
+ return undefined;
75
+ const have = new Set((await nn.branches(carry.neonProject)).map((b) => b.name));
76
+ const missing = BRANCHED.filter((e) => !have.has(e));
77
+ return missing.length ? undefined : BRANCHED.join(", ");
78
+ },
79
+ async create(spec, { nn }, carry) {
80
+ if (!carry.neonProject)
81
+ throw new Error("No Neon project to branch from");
82
+ const all = await nn.branches(carry.neonProject);
83
+ const parent = all.find((b) => b.default) ?? all.find((b) => b.name === DEFAULT_BRANCH);
84
+ if (!parent)
85
+ throw new Error("No default branch to branch from");
86
+ const have = new Set(all.map((b) => b.name));
87
+ const made = [];
88
+ // Serially: Neon rejects concurrent branch creation on one project, and a
89
+ // partial failure here should leave the branches it did make rather than
90
+ // an indeterminate half of five.
91
+ for (const env of BRANCHED.filter((e) => !have.has(e))) {
92
+ await nn.createBranch(carry.neonProject, env, parent.id);
93
+ made.push(env);
94
+ }
95
+ return `${made.join(", ")} ${made.length === BRANCHED.length ? "" : "· "}from ${parent.name}`;
96
+ },
97
+ },
98
+ {
99
+ name: "vercel project",
100
+ wanted: (spec) => spec.vercel !== false,
101
+ async find(spec, { vc }) {
102
+ const p = await vc.findProject(spec.name);
103
+ return p && p.name;
104
+ },
105
+ async create(spec, { vc }, carry) {
106
+ // Linked to the repository from step one, which is why a failure there
107
+ // must stop the run rather than let this one invent an unlinked project.
108
+ const p = await vc.createProject(spec.name, { repo: carry.repo });
109
+ return carry.repo ? `${p.name} · linked to ${carry.repo}` : p.name;
110
+ },
111
+ },
112
+ ];
113
+ async function clientsFor(ctx) {
114
+ const key = (service) => ctx.secrets.get(ctx.reference(KEY_FOR[service]));
115
+ const [g, v, n] = await Promise.all([key("github"), key("vercel"), key("neon")]);
116
+ return { gh: github(g), vc: vercel(v), nn: neon(n) };
117
+ }
118
+ /**
119
+ * Run every wanted step, in order, stopping at the first failure.
120
+ *
121
+ * Returns rather than throws: a partial run is the normal outcome of
122
+ * provisioning against five providers, and the caller needs to see how far it
123
+ * got. A thrown error would lose exactly the steps that already succeeded.
124
+ */
125
+ export async function provision(spec, ctx) {
126
+ const clients = await clientsFor(ctx);
127
+ const carry = {};
128
+ const steps = [];
129
+ for (const step of STEPS.filter((s) => s.wanted(spec))) {
130
+ try {
131
+ const found = await step.find(spec, clients, carry);
132
+ if (found !== undefined) {
133
+ steps.push({ step: step.name, state: "exists", detail: found });
134
+ continue;
135
+ }
136
+ if (!ctx.confirmed) {
137
+ steps.push({ step: step.name, state: "would-create", detail: spec.name });
138
+ continue;
139
+ }
140
+ steps.push({ step: step.name, state: "created", detail: await step.create(spec, clients, carry) });
141
+ }
142
+ catch (err) {
143
+ steps.push({
144
+ step: step.name, state: "failed",
145
+ detail: err instanceof Error ? err.message : String(err),
146
+ });
147
+ break;
148
+ }
149
+ }
150
+ return {
151
+ app: spec.name,
152
+ planned: !ctx.confirmed,
153
+ steps,
154
+ ok: steps.every((s) => s.state !== "failed"),
155
+ };
156
+ }
157
+ //# sourceMappingURL=provision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision.js","sourceRoot":"","sources":["../../src/admin/provision.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Execute one registry action.
3
+ *
4
+ * The registry says what exists and what it costs; this says how to perform it.
5
+ * They are separate so `registry.ts` stays isomorphic — an app, or a web UI,
6
+ * can list what the factory can do without pulling twelve Node clients into
7
+ * its bundle.
8
+ *
9
+ * Credentials are resolved here and handed to the client, never read from the
10
+ * environment inside one. That is what lets a worker run two apps at once.
11
+ */
12
+ import { type Action } from "../registry.ts";
13
+ import type { SecretStore } from "../secrets/store.ts";
14
+ import type { Environment } from "../config/environments.ts";
15
+ /** Which env var each service's factory key is stored under. */
16
+ export declare const KEY_FOR: Record<string, string>;
17
+ export interface RunContext {
18
+ /** Where credentials come from. */
19
+ secrets: SecretStore;
20
+ /** Turn an env var name into a reference the store understands. */
21
+ reference: (envVar: string) => string;
22
+ /** The caller has confirmed a gated action. */
23
+ confirmed?: boolean;
24
+ /**
25
+ * Whose data an `app`-tier action reaches.
26
+ *
27
+ * An `admin`-tier action acts on the factory's own key and needs none of
28
+ * this. An `app`-tier one reads and writes inside one app's database, in one
29
+ * environment, and must say which — there is no sensible default when the
30
+ * wrong guess writes to production.
31
+ */
32
+ app?: {
33
+ name: string;
34
+ environment: Environment;
35
+ };
36
+ /**
37
+ * The caller has opted in to changing production data specifically.
38
+ *
39
+ * Separate from `confirmed` on purpose. Confirming a write says "yes, run
40
+ * this statement"; this says "yes, against live data" — and someone who has
41
+ * typed --confirm all afternoon against their own branch should have to say
42
+ * the second thing out loud.
43
+ */
44
+ productionWrite?: boolean;
45
+ }
46
+ /** A write aimed at production without the separate opt-in. */
47
+ export declare class ProductionWriteError extends Error {
48
+ readonly action: Action;
49
+ constructor(action: Action);
50
+ }
51
+ export declare class GateError extends Error {
52
+ readonly action: Action;
53
+ constructor(action: Action);
54
+ }
55
+ export declare class UnknownActionError extends Error {
56
+ constructor(service: string, action: string);
57
+ }
58
+ /**
59
+ * Run an action, refusing anything gated that has not been confirmed.
60
+ *
61
+ * This is the *interface* guard — it lets a caller ask before failing. The
62
+ * guarantee is separate and lives in the clients, which refuse without an
63
+ * explicit flag whatever this decides.
64
+ */
65
+ export declare function runAction(service: string, action: string, args: string[], ctx: RunContext): Promise<unknown>;
66
+ /**
67
+ * What every key enables, in parallel.
68
+ *
69
+ * The evidence tier is the honest part: most providers will not say what a key
70
+ * may do, and rendering "it authenticated" the same as "these are its declared
71
+ * scopes" implies an assurance nobody obtained.
72
+ */
73
+ export declare function accessAll(ctx: RunContext): Promise<{
74
+ service: string;
75
+ ok: boolean;
76
+ evidence: string;
77
+ scopes?: string[];
78
+ can: string[];
79
+ notes: string[];
80
+ error?: string;
81
+ }[]>;
82
+ /** Every service's health, in parallel. */
83
+ export declare function statusAll(ctx: RunContext): Promise<{
84
+ service: string;
85
+ ok: boolean;
86
+ detail: string;
87
+ error?: string;
88
+ }[]>;
89
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/admin/run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAevD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,gEAAgE;AAChE,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAa1C,CAAC;AASF,MAAM,WAAW,UAAU;IACzB,mCAAmC;IACnC,OAAO,EAAE,WAAW,CAAC;IACrB,mEAAmE;IACnE,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,+CAA+C;IAC/C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,CAAC;IACjD;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,+DAA+D;AAC/D,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,MAAM,EAAE,MAAM;CAQ3B;AAED,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,MAAM,EAAE,MAAM;CAU3B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAI5C;AA6FD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,OAAO,CAAC,CAyBlB;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,UAAU;aAQ5B,MAAM;QAAM,OAAO;cAAY,MAAM;aACrC,MAAM,EAAE;SAAO,MAAM,EAAE;WAAS,MAAM,EAAE;YAAU,MAAM;KAU1E;AAED,2CAA2C;AAC3C,wBAAsB,SAAS,CAAC,GAAG,EAAE,UAAU;aAOD,MAAM;QAAM,OAAO;YAAU,MAAM;YAAU,MAAM;KAShG"}