@celsoft/platform 0.1.0 → 0.3.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 (44) hide show
  1. package/dist/adapters/cloudflare.d.ts +7 -1
  2. package/dist/adapters/cloudflare.js +39 -0
  3. package/dist/adapters/cloudflare.js.map +1 -1
  4. package/dist/adapters/process.d.ts +2 -0
  5. package/dist/adapters/process.js +35 -2
  6. package/dist/adapters/process.js.map +1 -1
  7. package/dist/adapters/resend.d.ts +14 -0
  8. package/dist/adapters/resend.js +50 -0
  9. package/dist/adapters/resend.js.map +1 -0
  10. package/dist/cli.js +42 -12
  11. package/dist/cli.js.map +1 -1
  12. package/dist/config.d.ts +6 -2
  13. package/dist/config.js +44 -9
  14. package/dist/config.js.map +1 -1
  15. package/dist/fakes.d.ts +47 -1
  16. package/dist/fakes.js +69 -2
  17. package/dist/fakes.js.map +1 -1
  18. package/dist/init.d.ts +6 -3
  19. package/dist/init.js +37 -10
  20. package/dist/init.js.map +1 -1
  21. package/dist/lifecycle.d.ts +4 -0
  22. package/dist/lifecycle.js +94 -3
  23. package/dist/lifecycle.js.map +1 -1
  24. package/dist/ports.d.ts +32 -0
  25. package/dist/runtime/auth.d.ts +15 -0
  26. package/dist/runtime/auth.js +35 -0
  27. package/dist/runtime/auth.js.map +1 -0
  28. package/dist/runtime/email.d.ts +15 -0
  29. package/dist/runtime/email.js +22 -0
  30. package/dist/runtime/email.js.map +1 -0
  31. package/dist/runtime/index.d.ts +11 -1
  32. package/dist/runtime/index.js +30 -1
  33. package/dist/runtime/index.js.map +1 -1
  34. package/dist/secrets.d.ts +3 -1
  35. package/dist/secrets.js +15 -8
  36. package/dist/secrets.js.map +1 -1
  37. package/dist/workflow.d.ts +3 -1
  38. package/dist/workflow.js +9 -5
  39. package/dist/workflow.js.map +1 -1
  40. package/dist/wrangler-config.d.ts +2 -1
  41. package/dist/wrangler-config.js +2 -1
  42. package/dist/wrangler-config.js.map +1 -1
  43. package/package.json +12 -3
  44. package/schema.json +50 -5
package/dist/fakes.js CHANGED
@@ -27,6 +27,8 @@ export class FakeCloudflare {
27
27
  zones = [{ id: "zone-1", name: "example.com" }];
28
28
  hyperdrives = [];
29
29
  workers = new Set();
30
+ workerSecrets = new Map();
31
+ records = [];
30
32
  next = 1;
31
33
  async accountId() {
32
34
  return "acct-1";
@@ -56,34 +58,99 @@ export class FakeCloudflare {
56
58
  }
57
59
  async deleteWorker(name) {
58
60
  this.workers.delete(name);
61
+ this.workerSecrets.delete(name);
62
+ }
63
+ async workerSecretNames(worker) {
64
+ return [...(this.workerSecrets.get(worker) ?? [])];
65
+ }
66
+ async dnsRecords(_zoneId, name) {
67
+ return this.records.filter((r) => r.name === name);
68
+ }
69
+ async managedDnsRecords() {
70
+ return this.records.filter((r) => r.managed);
71
+ }
72
+ async deleteDnsRecord(_zoneId, id) {
73
+ this.records = this.records.filter((r) => r.id !== id);
74
+ }
75
+ async createDnsRecord(_zoneId, record) {
76
+ this.records.push({ ...record, id: `rec-${this.next++}`, managed: true });
77
+ }
78
+ }
79
+ export class FakeMail {
80
+ domains = [];
81
+ keys = [];
82
+ next = 1;
83
+ async findDomain(name) {
84
+ return this.domains.find((d) => d.name === name);
85
+ }
86
+ async createDomain(name) {
87
+ const domain = {
88
+ id: `dom-${this.next++}`,
89
+ name,
90
+ verified: false,
91
+ records: [
92
+ { type: "TXT", name: `resend._domainkey.${name.split(".")[0]}`, content: "p=KEY" },
93
+ { type: "MX", name: `send.${name.split(".")[0]}`, content: "feedback-smtp.example.net", priority: 10 },
94
+ ],
95
+ };
96
+ this.domains.push(domain);
97
+ return domain;
98
+ }
99
+ async verifyDomain(id) {
100
+ this.domains.find((d) => d.id === id).verified = true;
101
+ }
102
+ async findApiKey(name) {
103
+ return this.keys.find((k) => k.name === name)?.id;
104
+ }
105
+ async createSendKey(name, domainId) {
106
+ const id = `key-${this.next++}`;
107
+ this.keys.push({ id, name, domainId });
108
+ return `re_${id}`;
109
+ }
110
+ async deleteApiKey(id) {
111
+ this.keys = this.keys.filter((k) => k.id !== id);
59
112
  }
60
113
  }
61
114
  export class FakeWrangler {
62
115
  cloudflare;
63
116
  deploys = [];
117
+ devRuns = [];
64
118
  constructor(cloudflare) {
65
119
  this.cloudflare = cloudflare;
66
120
  }
121
+ async dev(config, secrets, databaseUrl) {
122
+ this.devRuns.push({ config: config, secrets, databaseUrl });
123
+ }
67
124
  async deploy(config, secrets) {
68
125
  const c = config;
126
+ const name = c.name;
69
127
  this.deploys.push({ config: c, secrets });
70
- this.cloudflare.workers.add(c.name);
128
+ this.cloudflare.workers.add(name);
129
+ const stored = this.cloudflare.workerSecrets.get(name) ?? new Set();
130
+ for (const key of Object.keys(secrets))
131
+ stored.add(key);
132
+ this.cloudflare.workerSecrets.set(name, stored);
71
133
  }
72
134
  }
73
135
  export class FakeMigrator {
74
136
  runs = [];
137
+ authRuns = [];
75
138
  failWith;
76
139
  async migrate(_command, databaseUrl) {
77
140
  if (this.failWith)
78
141
  throw this.failWith;
79
142
  this.runs.push(databaseUrl);
80
143
  }
144
+ async migrateAuth(databaseUrl) {
145
+ this.authRuns.push(databaseUrl);
146
+ }
81
147
  }
82
148
  export function fakePorts() {
83
149
  const neon = new FakeNeon();
84
150
  const cloudflare = new FakeCloudflare();
151
+ const mail = new FakeMail();
85
152
  const wrangler = new FakeWrangler(cloudflare);
86
153
  const migrator = new FakeMigrator();
87
- return { neon, cloudflare, wrangler, migrator };
154
+ return { neon, cloudflare, mail, wrangler, migrator };
88
155
  }
89
156
  //# sourceMappingURL=fakes.js.map
package/dist/fakes.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fakes.js","sourceRoot":"","sources":["../src/fakes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fakes.js","sourceRoot":"","sources":["../src/fakes.ts"],"names":[],"mappings":"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"}
package/dist/init.d.ts CHANGED
@@ -1,17 +1,20 @@
1
1
  import type { Config } from "./config.js";
2
- import type { Cloudflare, GitHub, Neon } from "./ports.js";
2
+ import type { Cloudflare, GitHub, Mail, Neon } from "./ports.js";
3
3
  import type { Run } from "./run.js";
4
4
  export declare const TOKEN_HELP: Record<string, string>;
5
5
  export interface InitInput {
6
6
  repoRoot: string;
7
7
  appDir: string;
8
8
  config: Config;
9
+ variables: Record<string, string>;
9
10
  run: Run;
10
11
  connect: (tokens: Record<string, string>) => {
11
12
  cloudflare: Cloudflare;
12
13
  neon: Neon;
14
+ mail: Mail;
13
15
  github: GitHub;
14
16
  };
15
17
  }
16
- export declare function init({ repoRoot, appDir, config, run, connect }: InitInput): Promise<void>;
17
- export declare function checkWorkflow(repoRoot: string, appDir: string): Promise<void>;
18
+ export declare function tokenNames(config: Config): string[];
19
+ export declare function init({ repoRoot, appDir, config, variables, run, connect }: InitInput): Promise<void>;
20
+ export declare function checkWorkflow(repoRoot: string, appDir: string, config: Config, variables: string[]): Promise<void>;
package/dist/init.js CHANGED
@@ -1,16 +1,22 @@
1
1
  import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { dirname, join, relative } from "node:path";
3
3
  import { PreflightError } from "./lifecycle.js";
4
- import { parseDotenv, SECRETS_FILE } from "./secrets.js";
4
+ import { parseDotenv, SECRETS_FILE, VARS_FILE } from "./secrets.js";
5
5
  import { renderWorkflow, WORKFLOW_PATH } from "./workflow.js";
6
6
  export const TOKEN_HELP = {
7
7
  CLOUDFLARE_API_TOKEN: "Cloudflare API token; see SETUP.md or the platform README for its permissions",
8
8
  NEON_API_KEY: "Neon API key scoped to the app's Neon project",
9
+ RESEND_API_KEY: "Resend API key with full access, so the platform can add sending domains",
9
10
  };
10
- export async function init({ repoRoot, appDir, config, run, connect }) {
11
- const names = config.database ? ["CLOUDFLARE_API_TOKEN", "NEON_API_KEY"] : ["CLOUDFLARE_API_TOKEN"];
11
+ export function tokenNames(config) {
12
+ return ["CLOUDFLARE_API_TOKEN", ...(config.database ? ["NEON_API_KEY"] : []), ...(config.email ? ["RESEND_API_KEY"] : [])];
13
+ }
14
+ export async function init({ repoRoot, appDir, config, variables, run, connect }) {
15
+ const names = tokenNames(config);
12
16
  const tokens = await prepareSecretsFile(repoRoot, names, run);
13
- const { cloudflare, neon, github } = connect(tokens);
17
+ if (Object.keys(variables).length > 0)
18
+ await ensureIgnored(repoRoot, VARS_FILE, run);
19
+ const { cloudflare, neon, mail, github } = connect(tokens);
14
20
  await cloudflare.accountId();
15
21
  const zone = await cloudflare.findZone(config.hostname);
16
22
  if (!zone)
@@ -20,13 +26,23 @@ export async function init({ repoRoot, appDir, config, run, connect }) {
20
26
  await neon.defaultBranch(config.database.neonProject);
21
27
  run.note(`✓ Neon project ${config.database.neonProject}`);
22
28
  }
29
+ if (config.email) {
30
+ // Listing domains needs the same full access that adding the app's sending domain does.
31
+ await mail.findDomain(config.hostname).catch((error) => {
32
+ throw new PreflightError(`the Resend API key cannot manage domains (${error.message}); create one with Full access`);
33
+ });
34
+ run.note("✓ Resend API key can manage sending domains");
35
+ }
23
36
  for (const name of names) {
24
37
  await run.mutate(`store ${name} as a GitHub secret`, () => github.setSecret(name, tokens[name]), undefined);
25
38
  }
39
+ for (const [name, value] of Object.entries(variables)) {
40
+ await run.mutate(`store ${name} as a GitHub secret, so logs hide it`, () => github.setSecret(name, value), undefined);
41
+ }
26
42
  for (const environment of ["production", "preview"]) {
27
43
  await run.mutate(`ensure GitHub Environment ${environment}`, () => github.ensureEnvironment(environment), undefined);
28
44
  }
29
- const workflow = renderWorkflow({ appDir: relative(repoRoot, appDir) || ".", packageManager: await packageManager(repoRoot) });
45
+ const workflow = await expectedWorkflow(repoRoot, appDir, config, Object.keys(variables));
30
46
  const path = join(repoRoot, WORKFLOW_PATH);
31
47
  if ((await readOptional(path)) !== workflow) {
32
48
  await run.mutate(`write ${WORKFLOW_PATH}`, async () => {
@@ -38,17 +54,20 @@ export async function init({ repoRoot, appDir, config, run, connect }) {
38
54
  run.note(`✓ ${WORKFLOW_PATH}`);
39
55
  }
40
56
  }
41
- export async function checkWorkflow(repoRoot, appDir) {
42
- const expected = renderWorkflow({ appDir: relative(repoRoot, appDir) || ".", packageManager: await packageManager(repoRoot) });
57
+ export async function checkWorkflow(repoRoot, appDir, config, variables) {
58
+ const expected = await expectedWorkflow(repoRoot, appDir, config, variables);
43
59
  if ((await readOptional(join(repoRoot, WORKFLOW_PATH))) !== expected) {
44
60
  throw new PreflightError(`${WORKFLOW_PATH} differs from what this platform version writes; run \`platform init\` and commit the result`);
45
61
  }
46
62
  }
47
- async function prepareSecretsFile(repoRoot, names, run) {
63
+ async function ensureIgnored(repoRoot, file, run) {
48
64
  const gitignore = join(repoRoot, ".gitignore");
49
- const ignored = (await readOptional(gitignore))?.split(/\r?\n/).some((line) => line.trim() === SECRETS_FILE || line.trim() === `/${SECRETS_FILE}`);
65
+ const ignored = (await readOptional(gitignore))?.split(/\r?\n/).some((line) => line.trim() === file || line.trim() === `/${file}`);
50
66
  if (!ignored)
51
- await run.mutate(`add ${SECRETS_FILE} to .gitignore`, () => appendFile(gitignore, `\n${SECRETS_FILE}\n`), undefined);
67
+ await run.mutate(`add ${file} to .gitignore`, () => appendFile(gitignore, `\n${file}\n`), undefined);
68
+ }
69
+ async function prepareSecretsFile(repoRoot, names, run) {
70
+ await ensureIgnored(repoRoot, SECRETS_FILE, run);
52
71
  const path = join(repoRoot, SECRETS_FILE);
53
72
  const text = (await readOptional(path)) ?? "";
54
73
  const declared = new Set([...text.matchAll(/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/gm)].map((m) => m[1]));
@@ -63,6 +82,14 @@ async function prepareSecretsFile(repoRoot, names, run) {
63
82
  }
64
83
  return values;
65
84
  }
85
+ async function expectedWorkflow(repoRoot, appDir, config, variables) {
86
+ return renderWorkflow({
87
+ appDir: relative(repoRoot, appDir) || ".",
88
+ packageManager: await packageManager(repoRoot),
89
+ secrets: [...tokenNames(config), ...config.secrets],
90
+ variables,
91
+ });
92
+ }
66
93
  async function packageManager(repoRoot) {
67
94
  return (await readOptional(join(repoRoot, "pnpm-lock.yaml"))) !== undefined ? "pnpm" : "npm";
68
95
  }
package/dist/init.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,10 @@ export declare class PreflightError extends Error {
14
14
  export declare function deploy(ctx: Context, target: Target): Promise<{
15
15
  hostname: string;
16
16
  }>;
17
+ export declare const DEV_BRANCH = "dev";
18
+ export declare const DEV_URL = "http://localhost:8787";
19
+ export declare function dev(ctx: Context): Promise<void>;
20
+ export declare const MANAGED_COMMENT = "managed by @celsoft/platform";
17
21
  export declare function cleanup(ctx: Context, pr: number): Promise<void>;
18
22
  export declare const BACKUP_PREFIX = "backup-";
19
23
  export declare const BACKUPS_KEPT = 3;
package/dist/lifecycle.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { randomBytes } from "node:crypto";
1
2
  import { names, originOf, previewHostname } from "./target.js";
2
3
  import { wranglerConfig } from "./wrangler-config.js";
3
4
  export class PreflightError extends Error {
@@ -22,6 +23,9 @@ export async function deploy(ctx, target) {
22
23
  await backup(ctx, project, prod);
23
24
  const uri = run.dryRun && branch.id === "(new)" ? undefined : await ports.neon.connectionUri(project, branch.id);
24
25
  if (uri) {
26
+ // Auth tables first, so the app's own migrations can reference them.
27
+ if (config.auth)
28
+ await run.mutate(`update auth tables on ${branch.name}`, () => ports.migrator.migrateAuth(uri), undefined);
25
29
  await run.mutate(`run migrations on ${branch.name}`, () => ports.migrator.migrate(config.database.migrate, uri), undefined);
26
30
  }
27
31
  else {
@@ -29,10 +33,97 @@ export async function deploy(ctx, target) {
29
33
  }
30
34
  hyperdriveId = await ensureHyperdrive(ctx, n.hyperdrive, uri);
31
35
  }
32
- const wrangler = wranglerConfig({ config, worker: n.worker, hostname, accountId, hyperdriveId });
33
- await run.mutate(`deploy Worker ${n.worker} at https://${hostname}`, () => ports.wrangler.deploy(wrangler, secrets), undefined);
36
+ const existingSecrets = await ports.cloudflare.workerSecretNames(n.worker);
37
+ const generated = {};
38
+ if (config.auth && !existingSecrets.includes("BETTER_AUTH_SECRET")) {
39
+ generated.BETTER_AUTH_SECRET = randomBytes(32).toString("base64url");
40
+ run.note(`generate BETTER_AUTH_SECRET for ${n.worker}`);
41
+ }
42
+ const sending = config.email && target.kind === "prod";
43
+ if (sending) {
44
+ const domain = await ensureMailDomain(ctx, hostname, zone);
45
+ if (!existingSecrets.includes("EMAIL_API_KEY")) {
46
+ const key = await sendKey(ctx, hostname, domain.id);
47
+ if (key)
48
+ generated.EMAIL_API_KEY = key;
49
+ }
50
+ }
51
+ const vars = { APP_URL: `https://${hostname}` };
52
+ if (config.email) {
53
+ Object.assign(vars, { EMAIL_MODE: sending ? "send" : "capture", EMAIL_FROM: `noreply@${hostname}` });
54
+ }
55
+ const wrangler = wranglerConfig({ config, worker: n.worker, hostname, accountId, hyperdriveId, vars });
56
+ await run.mutate(`deploy Worker ${n.worker} at https://${hostname}`, () => ports.wrangler.deploy(wrangler, { ...secrets, ...generated }), undefined);
34
57
  return { hostname };
35
58
  }
59
+ export const DEV_BRANCH = "dev";
60
+ export const DEV_URL = "http://localhost:8787";
61
+ // Runs the app locally against its own Neon branch, copied from prod once and kept between runs.
62
+ export async function dev(ctx) {
63
+ const { config, ports, run } = ctx;
64
+ const secrets = requireSecrets(config, ctx.secrets);
65
+ let uri;
66
+ if (config.database) {
67
+ const project = config.database.neonProject;
68
+ const prod = await ports.neon.defaultBranch(project);
69
+ const branch = await run.ensure(`Neon branch ${DEV_BRANCH}`, () => ports.neon.findBranch(project, DEV_BRANCH), () => ports.neon.createBranch(project, DEV_BRANCH, prod.id, true), { id: "(new)", name: DEV_BRANCH });
70
+ uri = await ports.neon.connectionUri(project, branch.id);
71
+ if (config.auth)
72
+ await run.mutate(`update auth tables on ${DEV_BRANCH}`, () => ports.migrator.migrateAuth(uri), undefined);
73
+ await run.mutate(`run migrations on ${DEV_BRANCH}`, () => ports.migrator.migrate(config.database.migrate, uri), undefined);
74
+ }
75
+ const vars = { APP_URL: DEV_URL, ...(config.email && { EMAIL_MODE: "capture", EMAIL_FROM: "noreply@localhost" }) };
76
+ const { routes: _routes, account_id: _account, ...local } = wranglerConfig({
77
+ config,
78
+ worker: `${config.name}-dev`,
79
+ hostname: "localhost",
80
+ accountId: "",
81
+ hyperdriveId: config.database ? "local" : undefined,
82
+ vars,
83
+ });
84
+ const devSecrets = { ...secrets, ...(config.auth && { BETTER_AUTH_SECRET: "local-development-only" }) };
85
+ run.note(`serving at ${DEV_URL}; email is captured to this terminal`);
86
+ await ports.wrangler.dev(local, devSecrets, uri);
87
+ }
88
+ export const MANAGED_COMMENT = "managed by @celsoft/platform";
89
+ // The app sends from its own hostname: Resend's DKIM and bounce records sit on names below it,
90
+ // so the zone's existing mail records are never touched.
91
+ async function ensureMailDomain({ ports, run }, hostname, zone) {
92
+ const domain = await run.ensure(`Resend sending domain ${hostname}`, () => ports.mail.findDomain(hostname), () => ports.mail.createDomain(hostname), { id: "(new)", name: hostname, verified: false, records: [] });
93
+ // Resend names records relative to the zone, not to the sending hostname.
94
+ const wanted = domain.records.map((record) => ({ ...record, name: `${record.name}.${zone.name}` }));
95
+ const label = (name) => name.slice(0, -(hostname.length + 1)) || name;
96
+ for (const record of wanted) {
97
+ const existing = await ports.cloudflare.dnsRecords(zone.id, record.name);
98
+ if (existing.some((e) => e.type === record.type && unquote(e.content) === unquote(record.content))) {
99
+ run.note(`✓ ${record.type} record ${label(record.name)}`);
100
+ continue;
101
+ }
102
+ if (existing.some((e) => e.type === record.type && !e.managed)) {
103
+ throw new PreflightError(`${label(record.name)} below the app hostname already has a ${record.type} record the platform did not create; remove it or send email from another hostname`);
104
+ }
105
+ await run.mutate(`create ${record.type} record ${label(record.name)}`, () => ports.cloudflare.createDnsRecord(zone.id, record), undefined);
106
+ }
107
+ const stale = (await ports.cloudflare.managedDnsRecords(zone.id)).filter((e) => e.name.endsWith(`.${hostname}`) && !wanted.some((w) => w.type === e.type && w.name === e.name));
108
+ for (const record of stale) {
109
+ await run.mutate(`delete stale ${record.type} record ${label(record.name)}`, () => ports.cloudflare.deleteDnsRecord(zone.id, record.id), undefined);
110
+ }
111
+ if (!domain.verified) {
112
+ await run.mutate(`ask Resend to verify ${hostname}; email sends once it does, usually within minutes`, () => ports.mail.verifyDomain(domain.id), undefined);
113
+ }
114
+ return domain;
115
+ }
116
+ // A Resend key is only readable when created, so a Worker missing its key gets a fresh one.
117
+ async function sendKey({ ports, run }, hostname, domainId) {
118
+ const name = `platform ${hostname}`;
119
+ const old = await ports.mail.findApiKey(name);
120
+ if (old)
121
+ await run.mutate(`replace Resend sending key for ${hostname}`, () => ports.mail.deleteApiKey(old), undefined);
122
+ return run.mutate(`create Resend sending key for ${hostname}`, () => ports.mail.createSendKey(name, domainId), undefined);
123
+ }
124
+ function unquote(value) {
125
+ return value.replace(/^"|"$/g, "");
126
+ }
36
127
  export async function cleanup(ctx, pr) {
37
128
  const { config, ports, run } = ctx;
38
129
  const n = names(config, { kind: "preview", pr });
@@ -72,7 +163,7 @@ async function ensureHyperdrive({ ports, run }, name, uri) {
72
163
  return (await run.mutate(`create Hyperdrive config ${name}`, () => ports.cloudflare.createHyperdrive(name, uri), { id: "(new)", name, origin: "", cached: false })).id;
73
164
  }
74
165
  if (existing.origin !== originOf(uri) || existing.cached) {
75
- await run.mutate(`update Hyperdrive config ${name}: ${originOf(uri)}, query caching off`, () => ports.cloudflare.updateHyperdrive(existing.id, uri), existing);
166
+ await run.mutate(`update Hyperdrive config ${name} (new origin or caching on)`, () => ports.cloudflare.updateHyperdrive(existing.id, uri), existing);
76
167
  }
77
168
  else {
78
169
  run.note(`✓ Hyperdrive config ${name}`);
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
package/dist/ports.d.ts CHANGED
@@ -20,6 +20,16 @@ export interface Hyperdrive {
20
20
  origin: string;
21
21
  cached: boolean;
22
22
  }
23
+ export interface DnsRecord {
24
+ type: string;
25
+ name: string;
26
+ content: string;
27
+ priority?: number;
28
+ }
29
+ export interface ZoneRecord extends DnsRecord {
30
+ id: string;
31
+ managed: boolean;
32
+ }
23
33
  export interface Cloudflare {
24
34
  accountId(): Promise<string>;
25
35
  findZone(hostname: string): Promise<Zone | undefined>;
@@ -29,12 +39,33 @@ export interface Cloudflare {
29
39
  deleteHyperdrive(id: string): Promise<void>;
30
40
  findWorker(name: string): Promise<boolean>;
31
41
  deleteWorker(name: string): Promise<void>;
42
+ workerSecretNames(worker: string): Promise<string[]>;
43
+ dnsRecords(zoneId: string, name: string): Promise<ZoneRecord[]>;
44
+ createDnsRecord(zoneId: string, record: DnsRecord): Promise<void>;
45
+ managedDnsRecords(zoneId: string): Promise<ZoneRecord[]>;
46
+ deleteDnsRecord(zoneId: string, id: string): Promise<void>;
47
+ }
48
+ export interface MailDomain {
49
+ id: string;
50
+ name: string;
51
+ verified: boolean;
52
+ records: DnsRecord[];
53
+ }
54
+ export interface Mail {
55
+ findDomain(name: string): Promise<MailDomain | undefined>;
56
+ createDomain(name: string): Promise<MailDomain>;
57
+ verifyDomain(id: string): Promise<void>;
58
+ findApiKey(name: string): Promise<string | undefined>;
59
+ createSendKey(name: string, domainId: string): Promise<string>;
60
+ deleteApiKey(id: string): Promise<void>;
32
61
  }
33
62
  export interface Wrangler {
34
63
  deploy(wranglerConfig: object, secrets: Record<string, string>): Promise<void>;
64
+ dev(wranglerConfig: object, secrets: Record<string, string>, databaseUrl: string | undefined): Promise<void>;
35
65
  }
36
66
  export interface Migrator {
37
67
  migrate(command: string, databaseUrl: string): Promise<void>;
68
+ migrateAuth(databaseUrl: string): Promise<void>;
38
69
  }
39
70
  export interface GitHub {
40
71
  setSecret(name: string, value: string): Promise<void>;
@@ -43,6 +74,7 @@ export interface GitHub {
43
74
  export interface Ports {
44
75
  neon: Neon;
45
76
  cloudflare: Cloudflare;
77
+ mail: Mail;
46
78
  wrangler: Wrangler;
47
79
  migrator: Migrator;
48
80
  }
@@ -0,0 +1,15 @@
1
+ import { type BetterAuthOptions } from "better-auth";
2
+ import { Pool } from "pg";
3
+ import type { Email } from "./email.js";
4
+ export declare const AUTH_PATH = "/api/auth";
5
+ export interface AuthSettings {
6
+ pool: Pool;
7
+ secret: string;
8
+ baseURL: string;
9
+ email: Email;
10
+ requireVerification: boolean;
11
+ }
12
+ export declare function authPool(connectionString: string): Pool;
13
+ export declare function authOptions({ pool, secret, baseURL, email, requireVerification }: AuthSettings): BetterAuthOptions;
14
+ export declare function createAuth(settings: AuthSettings): import("better-auth").Auth<BetterAuthOptions>;
15
+ export type Auth = ReturnType<typeof createAuth>;
@@ -0,0 +1,35 @@
1
+ import { betterAuth } from "better-auth";
2
+ import { Pool } from "pg";
3
+ export const AUTH_PATH = "/api/auth";
4
+ // Better Auth gets its own pg pool: sharing the app's postgres.js client through a Kysely
5
+ // dialect stalls on Workers, while pg is the driver Cloudflare documents for Hyperdrive.
6
+ export function authPool(connectionString) {
7
+ return new Pool({ connectionString, max: 1 });
8
+ }
9
+ // Shared by the Worker and by `platform deploy`, which creates the auth tables from it.
10
+ export function authOptions({ pool, secret, baseURL, email, requireVerification }) {
11
+ return {
12
+ secret,
13
+ baseURL,
14
+ basePath: AUTH_PATH,
15
+ database: pool,
16
+ emailAndPassword: {
17
+ enabled: true,
18
+ requireEmailVerification: requireVerification,
19
+ sendResetPassword: async ({ user, url }) => {
20
+ await email.send({ to: user.email, subject: "Reset your password", text: `Reset your password:\n\n${url}\n\nIf you did not ask for this, ignore this email.` });
21
+ },
22
+ },
23
+ emailVerification: {
24
+ sendOnSignUp: true,
25
+ autoSignInAfterVerification: true,
26
+ sendVerificationEmail: async ({ user, url }) => {
27
+ await email.send({ to: user.email, subject: "Confirm your email", text: `Confirm your email address:\n\n${url}` });
28
+ },
29
+ },
30
+ };
31
+ }
32
+ export function createAuth(settings) {
33
+ return betterAuth(authOptions(settings));
34
+ }
35
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/runtime/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA0B,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG1B,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAC;AAUrC,0FAA0F;AAC1F,yFAAyF;AACzF,MAAM,UAAU,QAAQ,CAAC,gBAAwB;IAC/C,OAAO,IAAI,IAAI,CAAC,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAgB;IAC7F,OAAO;QACL,MAAM;QACN,OAAO;QACP,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,IAAI;QACd,gBAAgB,EAAE;YAChB,OAAO,EAAE,IAAI;YACb,wBAAwB,EAAE,mBAAmB;YAC7C,iBAAiB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;gBACzC,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,IAAI,EAAE,2BAA2B,GAAG,qDAAqD,EAAE,CAAC,CAAC;YAClK,CAAC;SACF;QACD,iBAAiB,EAAE;YACjB,YAAY,EAAE,IAAI;YAClB,2BAA2B,EAAE,IAAI;YACjC,qBAAqB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE;gBAC7C,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,IAAI,EAAE,kCAAkC,GAAG,EAAE,EAAE,CAAC,CAAC;YACrH,CAAC;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAsB;IAC/C,OAAO,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,15 @@
1
+ export interface EmailMessage {
2
+ to: string;
3
+ subject: string;
4
+ text: string;
5
+ html?: string;
6
+ }
7
+ export interface EmailBindings {
8
+ EMAIL_MODE?: "send" | "capture";
9
+ EMAIL_FROM?: string;
10
+ EMAIL_API_KEY?: string;
11
+ }
12
+ export interface Email {
13
+ send(message: EmailMessage): Promise<void>;
14
+ }
15
+ export declare function createEmail(env: EmailBindings, fetcher?: typeof fetch): Email;
@@ -0,0 +1,22 @@
1
+ // Previews capture instead of sending, so a copy of prod data never emails real users;
2
+ // captured messages land in the Worker's logs.
3
+ export function createEmail(env, fetcher = fetch) {
4
+ return {
5
+ async send(message) {
6
+ if (!env.EMAIL_MODE)
7
+ throw new Error("this app has no email; add `email` to platform.jsonc");
8
+ if (env.EMAIL_MODE === "capture") {
9
+ console.log(`[email captured] to=${message.to} subject=${JSON.stringify(message.subject)}\n${message.text}`);
10
+ return;
11
+ }
12
+ const response = await fetcher("https://api.resend.com/emails", {
13
+ method: "POST",
14
+ headers: { authorization: `Bearer ${env.EMAIL_API_KEY}`, "content-type": "application/json" },
15
+ body: JSON.stringify({ from: env.EMAIL_FROM, ...message }),
16
+ });
17
+ if (!response.ok)
18
+ throw new Error(`sending email failed: ${response.status} ${await response.text()}`);
19
+ },
20
+ };
21
+ }
22
+ //# sourceMappingURL=email.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.js","sourceRoot":"","sources":["../../src/runtime/email.ts"],"names":[],"mappings":"AAiBA,uFAAuF;AACvF,+CAA+C;AAC/C,MAAM,UAAU,WAAW,CAAC,GAAkB,EAAE,OAAO,GAAiB,KAAK;IAC3E,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,OAAO;YAChB,IAAI,CAAC,GAAG,CAAC,UAAU;gBAAE,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC7F,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,CAAC,EAAE,YAAY,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC7G,OAAO;YACT,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,+BAA+B,EAAE;gBAC9D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,GAAG,CAAC,aAAa,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC7F,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,OAAO,EAAE,CAAC;aAC3D,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,CAAC,MAAM,IAAI,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACzG,CAAC;KACF,CAAC;AACJ,CAAC"}