void 0.20.0 → 0.20.2

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 (93) hide show
  1. package/README.md +5 -1
  2. package/dist/{auth-W9WII-mN.mjs → auth-DPl6kck4.mjs} +46 -26
  3. package/dist/{auth-cmd-CYVhSNFy.mjs → auth-cmd-gniL2fNt.mjs} +5 -4
  4. package/dist/auth-link-NZdjCmSc.mjs +28 -0
  5. package/dist/{build-cmd-CkVD1uOh.mjs → build-cmd-sI18tX_O.mjs} +3 -3
  6. package/dist/{cache-QcUfR-ff.mjs → cache-IHn5MwBC.mjs} +3 -3
  7. package/dist/{cancel-deploy-DsvWKFTe.mjs → cancel-deploy-C5qTOdLi.mjs} +3 -3
  8. package/dist/cf-access-DRsQRe6k.mjs +75 -0
  9. package/dist/cli/cli.mjs +364 -1883
  10. package/dist/cli/env-schema-probe.mjs +11 -2
  11. package/dist/{client-CyCHWSO_.mjs → client-dHfSJvAN.mjs} +336 -58
  12. package/dist/{cloudflare-auth-DRkGe7-s.mjs → cloudflare-auth-6M5llVPC.mjs} +53 -6
  13. package/dist/{cloudflare-cmd-D3ME2GAe.mjs → cloudflare-cmd-4RPGN3KB.mjs} +2 -2
  14. package/dist/{cloudflare-connect-BivMefMA.mjs → cloudflare-connect-t1UU5svD.mjs} +2 -2
  15. package/dist/{cloudflare-operations-CPTpRW6d.mjs → cloudflare-operations-BzWnlC1_.mjs} +1 -1
  16. package/dist/{config-BQFq7QvD.mjs → config-uNGuFsI2.mjs} +1 -1
  17. package/dist/{connect-D9Yr-T5f.mjs → connect-Bfk31O_8.mjs} +6 -6
  18. package/dist/{create-project-DMV-csEm.mjs → create-project-Bk9Z0-Jg.mjs} +6 -5
  19. package/dist/{db-BxoUWL0F.mjs → db-BkRoptAt.mjs} +75 -48
  20. package/dist/{delete-iJOqxBz1.mjs → delete-DouASY9P.mjs} +3 -3
  21. package/dist/{deploy-CcDoeBIf.mjs → deploy-DTaWUS1S.mjs} +137 -128
  22. package/dist/{dev-inbox-DkgRWLkW.mjs → dev-inbox-P0u4tM8Y.mjs} +1 -1
  23. package/dist/{domain-gu_iaHmn.mjs → domain-1RhhOVrC.mjs} +4 -4
  24. package/dist/email-C-lGh51B.mjs +795 -0
  25. package/dist/{env-D4Emu-M_.mjs → env-DBKmK4vc.mjs} +1 -0
  26. package/dist/{env-DmU2To0C.mjs → env-DJHsPE7Z.mjs} +5 -5
  27. package/dist/{env-validation-ENpMy6Ez.mjs → env-validation-CF6KvTRf.mjs} +3 -1
  28. package/dist/{gen-BKw6qHIg.mjs → gen-B_wPnVTK.mjs} +3 -3
  29. package/dist/generate-RTK8_kK1.mjs +47 -0
  30. package/dist/{github-cmd-DJS5Ab-H.mjs → github-cmd-PW7ZnWTp.mjs} +3 -3
  31. package/dist/{headers-D8QfRX9Y.mjs → headers-BAHwgHdW.mjs} +1 -1
  32. package/dist/help-CwOX-zmI.mjs +2216 -0
  33. package/dist/{inbound-BJ70in1n.d.mts → inbound-CH5Mksyy.d.mts} +37 -42
  34. package/dist/{inbound-CNKxb3FY.mjs → inbound-aVHEUhKo.mjs} +143 -101
  35. package/dist/index.mjs +69 -30
  36. package/dist/{init-Dx5cgKqK.mjs → init-BWZ7q5Z4.mjs} +11 -11
  37. package/dist/{link-D_rm5sRH.mjs → link-Rmvu2Wl_.mjs} +4 -4
  38. package/dist/{list-M8XShti7.mjs → list-DEE2S6mY.mjs} +4 -4
  39. package/dist/{local-d1-BE8KBbMy.mjs → local-d1-D2I6Ox5F.mjs} +1 -1
  40. package/dist/{login-C8-UuLnp.mjs → login-Uvferzmm.mjs} +28 -10
  41. package/dist/{logs-DwFU7dMW.mjs → logs-27FenuiC.mjs} +4 -4
  42. package/dist/{mime-BJD7d_qL.mjs → mime-D5Nmdzf7.mjs} +23 -9
  43. package/dist/{node-BkaXcpAc.mjs → node-Ez5KW5rn.mjs} +3 -3
  44. package/dist/operator-auth-B3e08unv.mjs +52 -0
  45. package/dist/operator-client-LUZnlnYk.mjs +82 -0
  46. package/dist/{operator-cmd-DYWRbWUA.mjs → operator-cmd-CjOTmAYE.mjs} +35 -55
  47. package/dist/{output-tFQLLj26.mjs → output-B0cfNSx5.mjs} +316 -2
  48. package/dist/pages/index.mjs +2 -2
  49. package/dist/platform-auth-config-DrbQXXiW.mjs +368 -0
  50. package/dist/platform-auth-protection-Bhtvp0B_.mjs +219 -0
  51. package/dist/platform-auth-recovery-CeOKGVeJ.mjs +310 -0
  52. package/dist/{platform-cmd-BEOVv1PN.mjs → platform-cmd-BFhieCdV.mjs} +16 -6
  53. package/dist/{platform-domain-BszUfiS8.mjs → platform-domain-C74PULqV.mjs} +4 -4
  54. package/dist/{platform-lifecycle-CjSr6xf0.mjs → platform-lifecycle-BwAIgz-t.mjs} +1667 -191
  55. package/dist/{platform-management-W30iCaTL.mjs → platform-management-COogu_Se.mjs} +33 -7
  56. package/dist/{platform-recovery-pHHv4ZSg.mjs → platform-recovery-ewqLefp1.mjs} +6 -5
  57. package/dist/{prepare-CBetXvsN.mjs → prepare-CtDJjoOj.mjs} +2 -2
  58. package/dist/{prepare-BfJvFUtJ.mjs → prepare-blNRQvQl.mjs} +2 -2
  59. package/dist/prerender-render.d.mts +11 -0
  60. package/dist/prerender-render.mjs +111 -0
  61. package/dist/{project-cmd-DCpk1cDt.mjs → project-cmd-DmZK9Hxf.mjs} +32 -14
  62. package/dist/project-team-D8jOJMUJ.mjs +130 -0
  63. package/dist/project-token-DA34bf-C.mjs +75 -0
  64. package/dist/{provision-Blnstcm2.mjs → provision-CSJOjjQk.mjs} +2 -0
  65. package/dist/{requests-Dn8Vheh1.mjs → requests-CUExwGQQ.mjs} +3 -3
  66. package/dist/{rollback-CtlPXEBi.mjs → rollback-CDNGU1gr.mjs} +4 -4
  67. package/dist/{runner-mysql-CgRFl3s6.mjs → runner-mysql-7BPUNGmL.mjs} +1 -1
  68. package/dist/{runner-pg-DCkWPsWS.mjs → runner-pg-BkEza-dX.mjs} +1 -1
  69. package/dist/runtime/ai.mjs +3 -2
  70. package/dist/runtime/email/testing.d.mts +1 -1
  71. package/dist/runtime/email/testing.mjs +3 -3
  72. package/dist/runtime/email-protocol.d.mts +15 -0
  73. package/dist/runtime/email-protocol.mjs +70 -0
  74. package/dist/runtime/email.d.mts +2 -2
  75. package/dist/runtime/email.mjs +189 -96
  76. package/dist/runtime/remote/index.mjs +5 -3
  77. package/dist/{secret-BqTxGqki.mjs → secret-Bzzi2e9E.mjs} +5 -5
  78. package/dist/{skills-Q46GZMO-.mjs → skills-C0RvGjeE.mjs} +1 -1
  79. package/dist/sqlite-validation-BzKMWnO4.mjs +25 -0
  80. package/dist/{subcommand-prompt-WfySCQ7S.mjs → subcommand-prompt-Bmyn5Rlc.mjs} +1 -1
  81. package/dist/{validate-Bihr8WBi.mjs → validate-tBBN_dXH.mjs} +1 -0
  82. package/package.json +12 -7
  83. package/skills/void/SKILL.md +35 -4
  84. package/skills/void/docs/guide/deployment.md +2 -0
  85. package/skills/void/docs/guide/email.md +121 -98
  86. package/skills/void/docs/guide/platform-administration.md +214 -2
  87. package/skills/void/docs/guide/platform-development.md +93 -2
  88. package/skills/void/docs/guide/project-collaboration.md +94 -0
  89. package/skills/void/docs/guide/self-hosted-platform.md +184 -30
  90. package/skills/void/docs/reference/cli.md +294 -15
  91. package/dist/cf-access-AJ1ehiFR.mjs +0 -42
  92. package/dist/cf-access-DsSsZUPr.mjs +0 -67
  93. package/dist/email-r6DHJyAB.mjs +0 -262
package/dist/index.mjs CHANGED
@@ -1,26 +1,27 @@
1
1
  import { r as __toESM } from "./rolldown-runtime-rQ84J-ij.mjs";
2
2
  import { c as relative, l as resolve, n as dirname, o as join } from "./dist-BrsS7cai.mjs";
3
- import { st as require_picocolors } from "./output-tFQLLj26.mjs";
4
- import { D as resolveAssetRoutingPolicy, E as hasDocumentRoutes, T as hasApiRoutes, _ as scanDurableObjectModules, c as resolveDistDir, d as generateQueueResolverSource, f as prerenderPages, g as hasRevalidate, h as collectRevalidate, l as resolveWorkerDirName, m as collectPages, p as prerenderPagesNode, v as SEND_EMAIL_BINDING } from "./deploy-CcDoeBIf.mjs";
3
+ import { H as ensurePlatformProxyAccess, ft as require_picocolors } from "./output-B0cfNSx5.mjs";
4
+ import { D as resolveAssetRoutingPolicy, E as hasDocumentRoutes, T as hasApiRoutes, _ as scanDurableObjectModules, c as resolveDistDir, d as generateQueueResolverSource, f as prerenderPages, g as hasRevalidate, h as collectRevalidate, l as resolveWorkerDirName, m as collectPages, p as prerenderPagesNode, v as SEND_EMAIL_BINDING } from "./deploy-DTaWUS1S.mjs";
5
5
  import { i as resolveProjectPaths, n as readProjectPaths, t as assertNoRootSourceConventionConflicts } from "./project-paths-SK8nMHPp.mjs";
6
6
  import { a as scanQueuesSync, c as loadVoidAuthConfig, i as scanWebSocketRoutesSync, n as scanRoutePatternsSync, o as scanJobsSync, r as scanRoutes, s as findVoidAuthConfig, t as scanMiddlewareSync } from "./scan-BMH4rzlv.mjs";
7
- import { a as getApiUrl, b as readDeploymentPlatform, c as getToken, o as getProxyUrl, u as isStagingMode, x as readProjectConfig } from "./auth-W9WII-mN.mjs";
7
+ import { r as scopedAccessCredentials } from "./cf-access-DRsQRe6k.mjs";
8
+ import { S as readProjectConfig, d as isStagingMode, l as getToken, o as getApiUrl, s as getProxyUrl, x as readDeploymentPlatform } from "./auth-DPl6kck4.mjs";
8
9
  import { C as readWranglerWebSocketTombstones, D as syncWranglerWebSockets, E as syncWranglerDurableObjects, M as isSandboxEnabled, P as resolveSandboxConfig, T as syncWranglerBindings, a as LIVE_MIGRATION_TAG, d as ensureWranglerNodejsAlsFlag, g as readExistingLiveBindingConfig, h as normalizeWranglerCompatibilityFlags, j as SANDBOX_MIGRATION_TAG, l as ensureWranglerCompat, m as nextDurableObjectMigrationTag, p as hasDurableObjectSqliteMigration, u as ensureWranglerCompatibilityDate, w as resolveLiveBindingConfig, y as readWranglerCompat } from "./wrangler--imS8n0d.mjs";
9
- import { c as getDatabaseDialect, f as readConfig, l as isNodeTarget, p as resolveBindingNames } from "./config-BQFq7QvD.mjs";
10
+ import { c as getDatabaseDialect, f as readConfig, l as isNodeTarget, p as resolveBindingNames } from "./config-uNGuFsI2.mjs";
10
11
  import { i as voidWarn, n as voidError, r as voidLog, t as setShowTimestamp } from "./log-ChfPKsVd.mjs";
11
- import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-D8QfRX9Y.mjs";
12
+ import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-BAHwgHdW.mjs";
12
13
  import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-Ql2XsSQp.mjs";
13
14
  import { a as inferBindingsFromSource, i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, o as walk, r as detectFramework, t as DEFAULT_SCAN_DIRS } from "./plugin-inference-BDRfZngg.mjs";
14
15
  import { a as validateSsrEntries, c as isIdentifier, l as isLiteral, n as SSR_SERVER_ENTRY_RELATIVE_PATHS, o as validateSsrEntry, t as SSR_CLIENT_ENTRY_RELATIVE_PATHS, u as isMemberExpression } from "./entry-DU3oDoQ3.mjs";
15
- import { n as writeLocalD1PersistState, t as resolveLocalD1Target } from "./local-d1-BE8KBbMy.mjs";
16
+ import { n as writeLocalD1PersistState, t as resolveLocalD1Target } from "./local-d1-D2I6Ox5F.mjs";
16
17
  import { n as parseDotenvFile } from "./dotenv-VQxupEUv.mjs";
17
18
  import { i as generateVoidAuthDrizzleSchema, n as generateQueueTypes, o as DRIZZLE_OPERATORS, r as generateVoidAuthDatabaseModule, s as generateDbDts, t as generateRouteTypes } from "./route-types-Da-DpyUp.mjs";
18
19
  import { t as discoverSchema } from "./discover-xvfrgJeo.mjs";
19
- import { _ as parseCapturedMessage, a as DEV_INBOX_ENV_VAR, c as DEV_INBOX_TOKEN_ENV_VAR, f as clearDevBuffer, g as listDevMessages, l as DEV_INBOX_TOKEN_HEADER, m as findDevMessage, n as DEV_INBOX_ACK_VALUE, o as DEV_INBOX_MAX_CAPTURE_BYTES, s as DEV_INBOX_PREFIX, t as DEV_INBOX_ACK_HEADER, u as DEV_INBOX_TOKEN_QUERY, v as pushToDevBuffer, y as registerEmailSink } from "./dev-inbox-DkgRWLkW.mjs";
20
+ import { _ as parseCapturedMessage, a as DEV_INBOX_ENV_VAR, c as DEV_INBOX_TOKEN_ENV_VAR, f as clearDevBuffer, g as listDevMessages, l as DEV_INBOX_TOKEN_HEADER, m as findDevMessage, n as DEV_INBOX_ACK_VALUE, o as DEV_INBOX_MAX_CAPTURE_BYTES, s as DEV_INBOX_PREFIX, t as DEV_INBOX_ACK_HEADER, u as DEV_INBOX_TOKEN_QUERY, v as pushToDevBuffer, y as registerEmailSink } from "./dev-inbox-P0u4tM8Y.mjs";
20
21
  import { t as MagicString } from "./dist-BR1quN_w.mjs";
21
22
  import { n as findEnvFileForPaths, r as generateEnvTypes, t as findEnvFile } from "./env-types-BNPhro-M.mjs";
22
- import { h as loadUserEnvFile } from "./env-validation-ENpMy6Ez.mjs";
23
- import { a as loadLocalEnv, o as resolveRemoteMode, r as findLegacyEnvFiles, s as stripInternalEnvKeys, t as CLIENT_ENV_PREFIX$2 } from "./env-D4Emu-M_.mjs";
23
+ import { h as loadUserEnvFile } from "./env-validation-CF6KvTRf.mjs";
24
+ import { a as loadLocalEnv, o as resolveRemoteMode, r as findLegacyEnvFiles, s as stripInternalEnvKeys, t as CLIENT_ENV_PREFIX$2 } from "./env-DBKmK4vc.mjs";
24
25
  import { i as resolveLayoutIds, o as isRouteEnabledForEnvironment } from "./scan-CpK-57ug.mjs";
25
26
  import { a as scanEmailHandlersSync, r as hasEmailHandlers } from "./email-Ce6SQq-i.mjs";
26
27
  import { n as INTERNAL_BINDING_PREFIXES, t as INTERNAL_BINDING_EXACT_NAMES } from "./env-raw-Cx8ElDdj.mjs";
@@ -701,7 +702,7 @@ export function createDb(d1) {
701
702
  const migrationsDir = paths.migrationsDir;
702
703
  if (!(existsSync(migrationsDir) && readdirSync(migrationsDir).some((f) => f.endsWith(".sql")))) {
703
704
  if (dialect === "sqlite") {
704
- const { getApplicationTables, getMiniflareDatabasePath } = await import("./local-d1-BE8KBbMy.mjs").then((n) => n.i);
705
+ const { getApplicationTables, getMiniflareDatabasePath } = await import("./local-d1-D2I6Ox5F.mjs").then((n) => n.i);
705
706
  if ((await getApplicationTables(getMiniflareDatabasePath(options.localD1PersistRoot ?? join(root, ".void"), options.localD1DatabaseId ?? "local")).catch(() => [])).length > 0) return;
706
707
  }
707
708
  voidWarn(`Schema found but no migrations in ${paths.sourceRelative("db/migrations")}/.\n \`void db push\` syncs the schema to your local DB without creating migration files.
@@ -1982,10 +1983,10 @@ function migrationPlugin(root, dialect, databaseId = "local", persistRoot = join
1982
1983
  else warn();
1983
1984
  return;
1984
1985
  }
1985
- const { collectMigrations } = await import("./validate-Bihr8WBi.mjs").then((n) => n.l);
1986
- const { validateMigrations } = await import("./validate-Bihr8WBi.mjs").then((n) => n.i);
1986
+ const { collectMigrations } = await import("./validate-tBBN_dXH.mjs").then((n) => n.l);
1987
+ const { validateMigrations } = await import("./validate-tBBN_dXH.mjs").then((n) => n.i);
1987
1988
  const allMigrations = collectMigrations(migrationsDir);
1988
- const appliedNames = dialect === "mysql" ? await import("./runner-mysql-CgRFl3s6.mjs").then((n) => n.n).then((runner) => runner.getMySqlAppliedMigrations(url)) : await import("./runner-pg-DCkWPsWS.mjs").then((n) => n.n).then((runner) => runner.getPgAppliedMigrations(url));
1989
+ const appliedNames = dialect === "mysql" ? await import("./runner-mysql-7BPUNGmL.mjs").then((n) => n.n).then((runner) => runner.getMySqlAppliedMigrations(url)) : await import("./runner-pg-BkEza-dX.mjs").then((n) => n.n).then((runner) => runner.getPgAppliedMigrations(url));
1989
1990
  const appliedSet = new Set(appliedNames);
1990
1991
  const pending = allMigrations.filter((migration) => !appliedSet.has(migration.name));
1991
1992
  if (pending.length > 0) try {
@@ -1993,12 +1994,12 @@ function migrationPlugin(root, dialect, databaseId = "local", persistRoot = join
1993
1994
  } catch (err) {
1994
1995
  voidWarn(err instanceof Error ? err.message : String(err));
1995
1996
  }
1996
- const applied = dialect === "mysql" ? await import("./runner-mysql-CgRFl3s6.mjs").then((n) => n.n).then((runner) => runner.runMySqlMigrations(migrationsDir, url)) : await import("./runner-pg-DCkWPsWS.mjs").then((n) => n.n).then((runner) => runner.runPgMigrations(migrationsDir, url));
1997
+ const applied = dialect === "mysql" ? await import("./runner-mysql-7BPUNGmL.mjs").then((n) => n.n).then((runner) => runner.runMySqlMigrations(migrationsDir, url)) : await import("./runner-pg-BkEza-dX.mjs").then((n) => n.n).then((runner) => runner.runPgMigrations(migrationsDir, url));
1997
1998
  if (applied.length > 0) voidLog(`Applied ${applied.length} migration(s): ${applied.join(", ")}`);
1998
1999
  } else if (hasSqlMigrations) {
1999
- const { runMigrations, getMiniflareDatabasePath, getAppliedMigrations } = await import("./local-d1-BE8KBbMy.mjs").then((n) => n.i);
2000
- const { collectMigrations } = await import("./validate-Bihr8WBi.mjs").then((n) => n.l);
2001
- const { validateMigrations } = await import("./validate-Bihr8WBi.mjs").then((n) => n.i);
2000
+ const { runMigrations, getMiniflareDatabasePath, getAppliedMigrations } = await import("./local-d1-D2I6Ox5F.mjs").then((n) => n.i);
2001
+ const { collectMigrations } = await import("./validate-tBBN_dXH.mjs").then((n) => n.l);
2002
+ const { validateMigrations } = await import("./validate-tBBN_dXH.mjs").then((n) => n.i);
2002
2003
  const dbPath = getMiniflareDatabasePath(persistRoot, databaseId);
2003
2004
  const allMigrations = collectMigrations(migrationsDir);
2004
2005
  const appliedRows = await getAppliedMigrations(dbPath);
@@ -2013,7 +2014,7 @@ function migrationPlugin(root, dialect, databaseId = "local", persistRoot = join
2013
2014
  if (applied.length > 0) voidLog(`Applied ${applied.length} migration(s): ${applied.join(", ")}`);
2014
2015
  }
2015
2016
  if (auth?.enabled) {
2016
- const { runLocalVoidAuthMigrations } = await import("./node-BkaXcpAc.mjs");
2017
+ const { runLocalVoidAuthMigrations } = await import("./node-Ez5KW5rn.mjs");
2017
2018
  await runLocalVoidAuthMigrations(root, dialect, persistRoot, databaseId, auth.configPath);
2018
2019
  voidLog("Applied Better Auth migrations");
2019
2020
  }
@@ -4116,6 +4117,7 @@ ${renderBlock}
4116
4117
  }`;
4117
4118
  const internalRouteHelper = `async function __handleInternal(request, env, ctx) {
4118
4119
  const url = new URL(request.url);
4120
+ ${hasEmail ? `if (url.pathname === "/__void/email/receipt/v1") return __handleEmailReceipt(request, env, ctx);` : ""}
4119
4121
  // Readiness probe — platform polls this to confirm the worker is live after WfP upload.
4120
4122
  // Handled here (before app.fetch) so user middleware cannot block it.
4121
4123
  if (request.method === "GET" && url.pathname === "/__void/ready") {
@@ -4144,11 +4146,12 @@ ${envValidateCall}${isrDeploymentStamp} const userEnv = __filterInternalBinding
4144
4146
  }`;
4145
4147
  const emailImport = hasEmail ? ", __emailHandler" : "";
4146
4148
  const emailRuntimePath = runtimeEmailPath ?? deriveEmailRuntimePath(runtimeEnvPath);
4147
- const emailProxyImport = hasEmail ? `import { createMessageProxy as __createMessageProxy, enactEmailActions as __enactEmailActions, isForwardableEmailMessage as __isForwardableEmailMessage } from ${JSON.stringify(emailRuntimePath)};\n` : "";
4149
+ const emailProxyImport = hasEmail ? `import { createMessageProxy as __createMessageProxy, enactEmailActions as __enactEmailActions, isForwardableEmailMessage as __isForwardableEmailMessage } from ${JSON.stringify(emailRuntimePath)};\nimport { EMAIL_PROTOCOL_VERSION as __EMAIL_PROTOCOL_VERSION, encodeEmailActions as __encodeEmailActions, readEmailEnvelope as __readEmailEnvelope, verifyEmailReceiptThroughProxy as __verifyEmailReceiptThroughProxy } from "void/_email-protocol";\n` : "";
4148
4150
  const emailHandler = hasEmail ? remotePath ? `async function handleEmail(envelope, env, ctx) {
4149
4151
  ${envValidateCall} if (env.__VOID_REMOTE === "1") env = ${createRemoteEnvCall};
4150
4152
  const userEnv = __filterInternalBindings(env);
4151
- const __slug = typeof env.__VOID_PROJECT_SLUG === "string" && env.__VOID_PROJECT_SLUG.length > 0 ? env.__VOID_PROJECT_SLUG : undefined;
4153
+ const __relayed = typeof envelope.viaDomain === "string" && envelope.viaDomain.length > 0;
4154
+ const __slug = __relayed ? undefined : (typeof env.__VOID_PROJECT_SLUG === "string" && env.__VOID_PROJECT_SLUG.length > 0 ? env.__VOID_PROJECT_SLUG : undefined);
4152
4155
  const { message, getActions } = __createMessageProxy(envelope, { slug: __slug });
4153
4156
  await __withRawEnv(env, () => withRuntimeEnv(env, () => __emailHandler(message, userEnv, ctx, { slug: __slug })));
4154
4157
  const __actions = getActions();
@@ -4156,25 +4159,55 @@ ${envValidateCall} if (env.__VOID_REMOTE === "1") env = ${createRemoteEnvCall};
4156
4159
  return __actions;
4157
4160
  }` : `async function handleEmail(envelope, env, ctx) {
4158
4161
  ${envValidateCall} const userEnv = __filterInternalBindings(env);
4159
- const __slug = typeof env.__VOID_PROJECT_SLUG === "string" && env.__VOID_PROJECT_SLUG.length > 0 ? env.__VOID_PROJECT_SLUG : undefined;
4162
+ const __relayed = typeof envelope.viaDomain === "string" && envelope.viaDomain.length > 0;
4163
+ const __slug = __relayed ? undefined : (typeof env.__VOID_PROJECT_SLUG === "string" && env.__VOID_PROJECT_SLUG.length > 0 ? env.__VOID_PROJECT_SLUG : undefined);
4160
4164
  const { message, getActions } = __createMessageProxy(envelope, { slug: __slug });
4161
4165
  await __withRawEnv(env, () => withRuntimeEnv(env, () => __emailHandler(message, userEnv, ctx, { slug: __slug })));
4162
4166
  const __actions = getActions();
4163
4167
  if (__isForwardableEmailMessage(envelope)) await __enactEmailActions(envelope, __actions);
4164
4168
  return __actions;
4169
+ }` : "";
4170
+ const emailReceiptHandler = hasEmail ? `async function __handleEmailReceipt(request, env, ctx) {
4171
+ if (request.method !== "POST" || request.headers.get("content-encoding")) return new Response(null, { status: 404 });
4172
+ const __token = request.headers.get("x-void-email-receipt");
4173
+ const __recipient = request.headers.get("x-void-email-recipient");
4174
+ if (!__token || __token.length > 1536 || !__recipient || __recipient.length > 320 ||
4175
+ !env.__VOID_PROXY_TOKEN || !env.__PROJECT_ID || !env.__VOID_EMAIL_DEPLOYMENT_ID || !env.__VOID_PROXY) {
4176
+ return new Response(null, { status: 404 });
4177
+ }
4178
+ const __verified = await __verifyEmailReceiptThroughProxy(env.__VOID_PROXY, env.__VOID_PROXY_TOKEN, {
4179
+ receipt: __token, projectId: env.__PROJECT_ID,
4180
+ deploymentId: env.__VOID_EMAIL_DEPLOYMENT_ID, recipient: __recipient,
4181
+ });
4182
+ if (!__verified) return new Response(null, { status: 404 });
4183
+ let __envelope;
4184
+ try { __envelope = await __readEmailEnvelope(request.body); }
4185
+ catch { return new Response(null, { status: 400 }); }
4186
+ if (__envelope.to !== __recipient) return new Response(null, { status: 400 });
4187
+ const __actions = await handleEmail(__envelope, env, ctx);
4188
+ return new Response(__encodeEmailActions(__actions), {
4189
+ headers: { "content-type": "application/vnd.void.email-actions; version=" + __EMAIL_PROTOCOL_VERSION,
4190
+ "cache-control": "no-store" },
4191
+ });
4165
4192
  }` : "";
4166
4193
  const entryImport = `import { WorkerEntrypoint } from "cloudflare:workers";\n`;
4167
4194
  const fetchDeclaration = `const __voidFetch = ${fetchHandler};`;
4168
4195
  const entryClass = `export default class extends WorkerEntrypoint {
4169
4196
  async fetch(request) { return __voidFetch(request, this.env, this.ctx); }
4170
4197
  async scheduled(controller) { return handleScheduled(controller, this.env, this.ctx); }
4171
- ${hasQueues ? ` async queue(batch) { return __voidQueue(batch, this.env, this.ctx); }\n` : ""}${hasEmail ? ` async email(envelope) { return handleEmail(envelope, this.env, this.ctx); }\n` : ""}}`;
4198
+ ${hasQueues ? ` async queue(batch) { return __voidQueue(batch, this.env, this.ctx); }\n` : ""}${hasEmail ? ` async email(message) {
4199
+ if (this.env.__VOID_EMAIL_DEPLOYMENT_ID || !__isForwardableEmailMessage(message)) {
4200
+ throw new TypeError("Native email event required");
4201
+ }
4202
+ await handleEmail(message, this.env, this.ctx);
4203
+ }\n` : ""}}`;
4172
4204
  if (hasQueues) return `${sandboxImport}${entryImport}${liveRuntimeImport}import app, { scheduled, __voidCollectPrerenderPaths, __voidHandleInternalRoute, __withRawEnv, __processQueue${emailImport}${webSocketClasses.length > 0 ? `, ${webSocketClasses.join(", ")}` : ""}${liveRouteImport} } from 'virtual:void-routes';
4173
4205
  ${durableObjectImports}\n${runtimeEnvImport}${emailProxyImport}${envSchemaImport}${remoteImport}${isrImport}${filterBindingsHelper}${assetHelper}
4174
4206
  ${internalRouteHelper}
4175
4207
  ${fetchDeclaration}
4176
4208
  ${scheduledHandler}
4177
4209
  ${emailHandler}
4210
+ ${emailReceiptHandler}
4178
4211
  async function __voidQueue(batch, env, ctx) {
4179
4212
  ${envValidateCall}${remotePath ? ` if (env.__VOID_REMOTE === "1") env = ${createRemoteEnvCall};\n` : ""}${isrDeploymentStamp} const userEnv = __filterInternalBindings(env);
4180
4213
  const messages = [...batch.messages].map(m => ({
@@ -4207,6 +4240,7 @@ ${internalRouteHelper}
4207
4240
  ${fetchDeclaration}
4208
4241
  ${scheduledHandler}
4209
4242
  ${emailHandler}
4243
+ ${emailReceiptHandler}
4210
4244
  ${webSocketClasses.map((name) => `export { ${name} };`).join("\n")}
4211
4245
  ${liveExport}
4212
4246
  ${sandboxExport}
@@ -4995,8 +5029,8 @@ function routingPlugin(root, options) {
4995
5029
  if (!options.target) {
4996
5030
  const migrationsDir = paths.migrationsDir;
4997
5031
  if (existsSync(migrationsDir) || compileOptions.auth) {
4998
- const { collectMigrations } = await import("./validate-Bihr8WBi.mjs").then((n) => n.l);
4999
- const { buildMigrationPlanBundle } = await import("./validate-Bihr8WBi.mjs").then((n) => n.s);
5032
+ const { collectMigrations } = await import("./validate-tBBN_dXH.mjs").then((n) => n.l);
5033
+ const { buildMigrationPlanBundle } = await import("./validate-tBBN_dXH.mjs").then((n) => n.s);
5000
5034
  const migrations = existsSync(migrationsDir) ? collectMigrations(migrationsDir) : [];
5001
5035
  const dialect = getDatabaseDialect(readConfig(root));
5002
5036
  compileOptions.migrationHandlerPath = resolveFile(dialect === "postgresql" ? "#self/runtime/migration-handler-pg" : dialect === "mysql" ? "#self/runtime/migration-handler-mysql" : "#self/runtime/migration-handler");
@@ -5521,11 +5555,14 @@ function readVoidDevCredentials(root) {
5521
5555
  token,
5522
5556
  staging
5523
5557
  };
5558
+ const proxyUrl = getProxyUrl(root);
5559
+ ensurePlatformProxyAccess(apiUrl, proxyUrl);
5524
5560
  return {
5525
5561
  status: "ok",
5526
5562
  token,
5527
5563
  projectId: project.projectId,
5528
- proxyUrl: getProxyUrl(root),
5564
+ proxyUrl,
5565
+ accessCredentials: scopedAccessCredentials(process.env, proxyUrl),
5529
5566
  staging
5530
5567
  };
5531
5568
  }
@@ -5535,9 +5572,9 @@ function readVoidDevCredentials(root) {
5535
5572
  * block the server. On completion, writes project.json and restarts the server.
5536
5573
  */
5537
5574
  async function runAiSetupPrompt(root, token, apiUrl, server) {
5538
- const { select, text, isCancel, log } = await import("./output-tFQLLj26.mjs").then((n) => n.T);
5539
- const { PlatformClient } = await import("./client-CyCHWSO_.mjs").then((n) => n.r);
5540
- const { attachSelectedPlatform, writeProjectConfig } = await import("./auth-W9WII-mN.mjs").then((n) => n.y);
5575
+ const { select, text, isCancel, log } = await import("./output-B0cfNSx5.mjs").then((n) => n.T);
5576
+ const { PlatformClient } = await import("./client-dHfSJvAN.mjs").then((n) => n.r);
5577
+ const { attachSelectedPlatform, writeProjectConfig } = await import("./auth-DPl6kck4.mjs").then((n) => n.b);
5541
5578
  const { inferDefaultSlug } = await import("./resolve-project--Vxawf7z.mjs").then((n) => n.i);
5542
5579
  const client = new PlatformClient(token, apiUrl);
5543
5580
  let projects;
@@ -5564,8 +5601,8 @@ async function runAiSetupPrompt(root, token, apiUrl, server) {
5564
5601
  let projectId;
5565
5602
  let slug;
5566
5603
  if (result === "__create__") {
5567
- const { validateProjectSlug } = await import("./create-project-DMV-csEm.mjs").then((n) => n.a);
5568
- const { createProjectWithSlugRetry } = await import("./create-project-DMV-csEm.mjs").then((n) => n.t);
5604
+ const { validateProjectSlug } = await import("./create-project-Bk9Z0-Jg.mjs").then((n) => n.a);
5605
+ const { createProjectWithSlugRetry } = await import("./create-project-Bk9Z0-Jg.mjs").then((n) => n.t);
5569
5606
  let created;
5570
5607
  try {
5571
5608
  created = await createProjectWithSlugRetry(client, inferDefaultSlug(root), async (defaultSlug) => {
@@ -6032,6 +6069,7 @@ function voidPlugin(options) {
6032
6069
  vars.__VOID_TOKEN = credentials.token;
6033
6070
  vars.__VOID_PROJECT_ID = credentials.projectId;
6034
6071
  vars.__VOID_PROXY_URL = credentials.proxyUrl;
6072
+ if (credentials.accessCredentials) vars.__VOID_ACCESS_CREDENTIALS = credentials.accessCredentials;
6035
6073
  if (credentials.staging) vars.__VOID_STAGING = "1";
6036
6074
  result.vars = vars;
6037
6075
  }
@@ -6041,6 +6079,7 @@ function voidPlugin(options) {
6041
6079
  if (credentials.status === "ok") {
6042
6080
  const vars = result.vars ?? {};
6043
6081
  vars.__VOID_PROXY_URL = credentials.proxyUrl;
6082
+ if (credentials.accessCredentials) vars.__VOID_ACCESS_CREDENTIALS = credentials.accessCredentials;
6044
6083
  vars.__VOID_TOKEN = credentials.token;
6045
6084
  vars.__VOID_PROJECT_ID = credentials.projectId;
6046
6085
  vars.__VOID_REMOTE = "1";
@@ -1,20 +1,20 @@
1
1
  import { a as isAbsolute, c as relative, l as resolve, n as dirname, o as join, t as basename } from "./dist-BrsS7cai.mjs";
2
- import { C as cancel, D as log, E as intro, F as isCancel, N as text, O as note, f as detectAgents, j as select, k as outro, p as getPackageDir, r as cliTitle, w as confirm } from "./output-tFQLLj26.mjs";
2
+ import { A as outro, C as cancel, D as log, E as intro, I as isCancel, M as select, P as text, f as detectAgents, k as note, p as getPackageDir, r as cliTitle, w as confirm } from "./output-B0cfNSx5.mjs";
3
3
  import { n as readProjectPaths } from "./project-paths-SK8nMHPp.mjs";
4
- import { C as writeDeploymentPlatform, T as writeProjectConfig, b as readDeploymentPlatform, c as getToken, u as isStagingMode, v as attachSelectedPlatform, x as readProjectConfig } from "./auth-W9WII-mN.mjs";
4
+ import { E as writeProjectConfig, S as readProjectConfig, d as isStagingMode, l as getToken, w as writeDeploymentPlatform, x as readDeploymentPlatform, y as attachSelectedPlatform } from "./auth-DPl6kck4.mjs";
5
5
  import { i as LATEST_KNOWN_COMPAT_DATE, k as writeProvisionedWranglerConfig } from "./wrangler--imS8n0d.mjs";
6
- import { c as getDatabaseDialect, f as readConfig } from "./config-BQFq7QvD.mjs";
6
+ import { c as getDatabaseDialect, f as readConfig } from "./config-uNGuFsI2.mjs";
7
7
  import { n as ensureProjectTsconfig, t as createProjectTsconfig } from "./project-tsconfig-Ql2XsSQp.mjs";
8
8
  import { r as detectFramework } from "./plugin-inference-BDRfZngg.mjs";
9
9
  import { n as parseDotenvFile, t as expandDotenv } from "./dotenv-VQxupEUv.mjs";
10
10
  import { t as MagicString } from "./dist-BR1quN_w.mjs";
11
11
  import { n as writeDrizzleConfig } from "./config-NOG_U1aK.mjs";
12
- import { n as PlatformClient } from "./client-CyCHWSO_.mjs";
12
+ import { n as PlatformClient } from "./client-dHfSJvAN.mjs";
13
13
  import { r as formatProjectCommand } from "./preset-lAy0B0BQ.mjs";
14
- import { n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-DMV-csEm.mjs";
15
- import { t as promptForLoginToken } from "./login-C8-UuLnp.mjs";
16
- import { t as connectCloudflare } from "./cloudflare-connect-BivMefMA.mjs";
17
- import { discoverPlatform, saveDiscoveredPlatform } from "./platform-cmd-BEOVv1PN.mjs";
14
+ import { n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-Bk9Z0-Jg.mjs";
15
+ import { n as promptForLoginToken } from "./login-Uvferzmm.mjs";
16
+ import { discoverPlatform, saveDiscoveredPlatform } from "./platform-cmd-BFhieCdV.mjs";
17
+ import { t as connectCloudflare } from "./cloudflare-connect-t1UU5svD.mjs";
18
18
  import { n as findInstalledYarnPnpRuntime, r as hasLocalLockfile, t as buildDrizzleKitSpawnEnv } from "./yarn-pnp-DxSInkzL.mjs";
19
19
  import { createRequire } from "node:module";
20
20
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmdirSync, unlinkSync, writeFileSync } from "node:fs";
@@ -1822,7 +1822,7 @@ async function ensureVoidPlatformConnection(root) {
1822
1822
  let selectedApiUrl = null;
1823
1823
  let promptedForPlatform = false;
1824
1824
  try {
1825
- const { getApiUrl, getSiteDomain } = await import("./auth-W9WII-mN.mjs").then((n) => n.t);
1825
+ const { getApiUrl, getSiteDomain } = await import("./auth-DPl6kck4.mjs").then((n) => n.t);
1826
1826
  selectedApiUrl = getApiUrl(root);
1827
1827
  getSiteDomain(root);
1828
1828
  } catch (error) {
@@ -2831,7 +2831,7 @@ async function runInitCommand(root, initArgs) {
2831
2831
  injectAgentBlock(root);
2832
2832
  const agents = detectAgents(root);
2833
2833
  if (agents.length > 0) {
2834
- const { linkSkillsForSpecificAgents } = await import("./skills-Q46GZMO-.mjs");
2834
+ const { linkSkillsForSpecificAgents } = await import("./skills-C0RvGjeE.mjs");
2835
2835
  linkSkillsForSpecificAgents(root, agents);
2836
2836
  } else log.info("No coding agent detected; read the bundled docs linked in AGENTS.md");
2837
2837
  }
@@ -2865,7 +2865,7 @@ async function runInitCommand(root, initArgs) {
2865
2865
  let shouldSetupGithub = targeted ? initArgs?.github === true : deploymentPlatform !== "none";
2866
2866
  if (shouldSetupGithub && !githubStepSkipForSubpackage && deploymentPlatform !== "cloudflare" && deploymentPlatform !== "none") {
2867
2867
  if (!voidPlatformDiscovery) {
2868
- const { getApiUrl } = await import("./auth-W9WII-mN.mjs").then((n) => n.t);
2868
+ const { getApiUrl } = await import("./auth-DPl6kck4.mjs").then((n) => n.t);
2869
2869
  voidPlatformDiscovery = await discoverPlatform(getApiUrl(root));
2870
2870
  }
2871
2871
  if (!voidPlatformDiscovery.capabilities.githubActions) {
@@ -1,7 +1,7 @@
1
- import { C as cancel, D as log, E as intro, c as import_picocolors, k as outro, r as cliTitle } from "./output-tFQLLj26.mjs";
2
- import { T as writeProjectConfig, c as getToken, s as getSiteDomain, v as attachSelectedPlatform, x as readProjectConfig } from "./auth-W9WII-mN.mjs";
3
- import { n as PlatformClient } from "./client-CyCHWSO_.mjs";
4
- import { n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-DMV-csEm.mjs";
1
+ import { A as outro, C as cancel, D as log, E as intro, c as import_picocolors, r as cliTitle } from "./output-B0cfNSx5.mjs";
2
+ import { E as writeProjectConfig, S as readProjectConfig, c as getSiteDomain, l as getToken, y as attachSelectedPlatform } from "./auth-DPl6kck4.mjs";
3
+ import { n as PlatformClient } from "./client-dHfSJvAN.mjs";
4
+ import { n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-Bk9Z0-Jg.mjs";
5
5
  import { r as resolveProjectBySlug } from "./resolve-project--Vxawf7z.mjs";
6
6
  //#region src/cli/link.ts
7
7
  function projectLabel(slug, root, url) {
@@ -1,6 +1,6 @@
1
- import { D as log, E as intro, a as dim, c as import_picocolors, k as outro, o as ensureUtc, r as cliTitle, u as tablePrefix } from "./output-tFQLLj26.mjs";
2
- import { b as readDeploymentPlatform, c as getToken, x as readProjectConfig } from "./auth-W9WII-mN.mjs";
3
- import { n as PlatformClient } from "./client-CyCHWSO_.mjs";
1
+ import { A as outro, D as log, E as intro, a as dim, c as import_picocolors, o as ensureUtc, r as cliTitle, u as tablePrefix } from "./output-B0cfNSx5.mjs";
2
+ import { S as readProjectConfig, l as getToken, x as readDeploymentPlatform } from "./auth-DPl6kck4.mjs";
3
+ import { n as PlatformClient } from "./client-dHfSJvAN.mjs";
4
4
  import { r as resolveProjectBySlug } from "./resolve-project--Vxawf7z.mjs";
5
5
  //#region src/cli/list.ts
6
6
  async function runListCommand(root, slug) {
@@ -41,7 +41,7 @@ async function runListCommand(root, slug) {
41
41
  }
42
42
  async function showCloudflareDeployments(root, slug) {
43
43
  if (slug) throw new Error("project: A project name selects a Void platform project and is not used for direct Cloudflare apps.");
44
- const { readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-CPTpRW6d.mjs").then((n) => n.t);
44
+ const { readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-BzWnlC1_.mjs").then((n) => n.t);
45
45
  const status = await readCloudflareWorkerStatus(resolveCloudflareOperationContext(root));
46
46
  if (status.versions.length === 0) {
47
47
  outro(`No deployments for ${status.workerName}.`);
@@ -2,7 +2,7 @@ import { n as __exportAll } from "./rolldown-runtime-rQ84J-ij.mjs";
2
2
  import { a as isAbsolute, l as resolve, n as dirname, o as join } from "./dist-BrsS7cai.mjs";
3
3
  import { v as readRootWranglerConfig } from "./wrangler--imS8n0d.mjs";
4
4
  import { n as hasPackageDependency, r as readNearestPackageJson } from "./package-json-CPoWX79C.mjs";
5
- import { c as collectMigrations, o as classifyMigration } from "./validate-Bihr8WBi.mjs";
5
+ import { c as collectMigrations, o as classifyMigration } from "./validate-tBBN_dXH.mjs";
6
6
  import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
7
7
  import { createHash, createHmac } from "node:crypto";
8
8
  //#region src/migrations/runner.ts
@@ -1,22 +1,40 @@
1
- import { C as cancel, D as log, E as intro, F as isCancel, c as import_picocolors, i as createSpinner, j as select, k as outro, r as cliTitle } from "./output-tFQLLj26.mjs";
2
- import { _ as saveToken, c as getToken, g as savePlatformToken, h as runPlatformLogin, l as getTokenSource, m as runLogin, p as removeToken, u as isStagingMode } from "./auth-W9WII-mN.mjs";
3
- import { a as isExpiredTokenError, n as PlatformClient } from "./client-CyCHWSO_.mjs";
1
+ import { n as __exportAll } from "./rolldown-runtime-rQ84J-ij.mjs";
2
+ import { A as outro, C as cancel, D as log, E as intro, I as isCancel, M as select, c as import_picocolors, i as createSpinner, r as cliTitle } from "./output-B0cfNSx5.mjs";
3
+ import { _ as savePlatformToken, d as isStagingMode, g as runPlatformLogin, h as runLogin, l as getToken, m as removeToken, o as getApiUrl, u as getTokenSource, v as saveToken } from "./auth-DPl6kck4.mjs";
4
+ import { a as isExpiredTokenError, n as PlatformClient } from "./client-dHfSJvAN.mjs";
4
5
  //#region src/cli/login.ts
5
- async function promptForLoginToken(root = process.cwd(), platform) {
6
+ var login_exports = /* @__PURE__ */ __exportAll({
7
+ promptForLoginToken: () => promptForLoginToken,
8
+ runLoginCommand: () => runLoginCommand,
9
+ selectPlatformLoginMethod: () => selectPlatformLoginMethod
10
+ });
11
+ async function selectPlatformLoginMethod(platform, requestedId) {
6
12
  const providers = platform?.authenticationProviders ?? ["github", "google"];
7
- if (providers.length === 0) throw new Error("auth: This platform has no login providers.");
13
+ const methods = platform?.authentication?.methods ?? providers.map((id) => ({
14
+ id,
15
+ label: id === "github" ? "GitHub" : id === "google" ? "Google" : id
16
+ }));
17
+ if (providers.length === 0) throw new Error(platform?.authentication?.setupPending ? "auth: The platform administrator must finish initial setup." : "auth: This platform has no login providers.");
18
+ if (requestedId) {
19
+ const selected = methods.find((method) => method.id === requestedId);
20
+ if (!selected) throw new Error(`auth: Login method ${requestedId} is not enabled on this platform.`);
21
+ return selected;
22
+ }
8
23
  const provider = providers.length === 1 ? providers[0] : await select({
9
24
  message: "Choose a login provider:",
10
- options: providers.map((value) => ({
11
- value,
12
- label: value === "github" ? "GitHub" : "Google"
25
+ options: methods.map(({ id, label }) => ({
26
+ value: id,
27
+ label
13
28
  }))
14
29
  });
15
30
  if (isCancel(provider) || typeof provider === "symbol") {
16
31
  cancel("Login cancelled.");
17
32
  process.exit(0);
18
33
  }
19
- const providerName = provider === "github" ? "GitHub" : "Google";
34
+ return methods.find((method) => method.id === provider);
35
+ }
36
+ async function promptForLoginToken(root = process.cwd(), platform) {
37
+ const { id: provider, label: providerName } = await selectPlatformLoginMethod(platform ?? await import("./platform-cmd-BFhieCdV.mjs").then(({ discoverPlatform }) => discoverPlatform(getApiUrl(root))));
20
38
  const s = createSpinner();
21
39
  s.start(`Opening browser for ${providerName} login...`);
22
40
  try {
@@ -70,4 +88,4 @@ async function runLoginCommand(root = process.cwd()) {
70
88
  outro(isStagingMode(root) ? "Staging token saved." : "Token saved.");
71
89
  }
72
90
  //#endregion
73
- export { runLoginCommand as n, promptForLoginToken as t };
91
+ export { selectPlatformLoginMethod as i, promptForLoginToken as n, runLoginCommand as r, login_exports as t };
@@ -1,13 +1,13 @@
1
- import { D as log, E as intro, a as dim, c as import_picocolors, k as outro, r as cliTitle } from "./output-tFQLLj26.mjs";
2
- import { b as readDeploymentPlatform, c as getToken, x as readProjectConfig } from "./auth-W9WII-mN.mjs";
3
- import { n as PlatformClient } from "./client-CyCHWSO_.mjs";
1
+ import { A as outro, D as log, E as intro, a as dim, c as import_picocolors, r as cliTitle } from "./output-B0cfNSx5.mjs";
2
+ import { S as readProjectConfig, l as getToken, x as readDeploymentPlatform } from "./auth-DPl6kck4.mjs";
3
+ import { n as PlatformClient } from "./client-dHfSJvAN.mjs";
4
4
  //#region src/cli/logs.ts
5
5
  async function runLogsCommand(root, filter, range, deployment, level) {
6
6
  console.log();
7
7
  intro(cliTitle("project logs"));
8
8
  const platform = readDeploymentPlatform(root);
9
9
  if (platform === "cloudflare") {
10
- const { resolveCloudflareOperationContext, tailCloudflareWorker } = await import("./cloudflare-operations-CPTpRW6d.mjs").then((n) => n.t);
10
+ const { resolveCloudflareOperationContext, tailCloudflareWorker } = await import("./cloudflare-operations-BzWnlC1_.mjs").then((n) => n.t);
11
11
  if (range !== "1h") log.warn("Cloudflare tail streams live logs; --range does not select historical entries.");
12
12
  if (level && level !== "all" && level !== "error") log.warn("Cloudflare tail cannot filter individual console levels; showing all invocation logs.");
13
13
  await tailCloudflareWorker(resolveCloudflareOperationContext(root), {
@@ -7,8 +7,8 @@ import { validate } from "email-validator";
7
7
  * and multipart/mixed for attachments — covering >95% of transactional sends.
8
8
  * Inline images use multipart/related when both attachments and html are present.
9
9
  */
10
- /** Cloudflare Email Workers reject messages larger than ~10 MB after base64 expansion. */
11
- const MAX_MESSAGE_BYTES = 10485760;
10
+ /** Encoded outbound MIME ceiling, separate from the 10 MiB inbound limit. */
11
+ const MAX_MESSAGE_BYTES = 5242880;
12
12
  /**
13
13
  * Upper bound on the TOTAL attachment bytes `normalizeEmail` will materialize.
14
14
  *
@@ -35,6 +35,8 @@ const MAX_MESSAGE_BYTES = 10485760;
35
35
  * on.
36
36
  */
37
37
  const MAX_ATTACHMENT_BYTES_TOTAL = Math.floor(MAX_MESSAGE_BYTES * 3 / 4);
38
+ /** Maximum serialized size of app-defined top-level MIME fields. */
39
+ const MAX_CUSTOM_HEADER_BYTES = 16384;
38
40
  const CRLF = "\r\n";
39
41
  const ASCII_PRINTABLE = /^[\x20-\x7e]*$/;
40
42
  const HEADER_NAME = /^[!-9;-~]+$/;
@@ -455,13 +457,25 @@ async function normalizeAttachment(att) {
455
457
  async function normalizeEmail(opts) {
456
458
  if (!opts.text && !opts.html) throw new MimeError("MIME_ERROR", "email: at least one of 'text' or 'html' is required.");
457
459
  if (opts.subject !== void 0) rejectCRLF("subject", opts.subject);
458
- if (opts.headers) for (const [name, value] of Object.entries(opts.headers)) {
459
- if (!HEADER_NAME.test(name)) throw new MimeError("MIME_ERROR", `headers: '${name}' is not a valid RFC 5322 header name.`);
460
- if (name.length + HEADER_NAME_LINE_OVERHEAD > MAX_LINE_OCTETS) throw new MimeError("MIME_ERROR", `headers: a header name is ${name.length} characters; a field name cannot be folded, so its line would exceed the ${MAX_LINE_OCTETS}-octet limit in RFC 5322 §2.1.1. Shorten the name.`);
461
- rejectCRLF(`header '${name}'`, value);
460
+ if (opts.headers) {
461
+ let headerInputBytes = 0;
462
+ let headerBytes = 0;
463
+ const encoder = new TextEncoder();
464
+ for (const [name, value] of Object.entries(opts.headers)) {
465
+ if (!HEADER_NAME.test(name)) throw new MimeError("MIME_ERROR", `headers: '${name}' is not a valid RFC 5322 header name.`);
466
+ if (name.length + HEADER_NAME_LINE_OVERHEAD > MAX_LINE_OCTETS) throw new MimeError("MIME_ERROR", `headers: a header name is ${name.length} characters; a field name cannot be folded, so its line would exceed the ${MAX_LINE_OCTETS}-octet limit in RFC 5322 §2.1.1. Shorten the name.`);
467
+ if (headerInputBytes + name.length + value.length + 4 > MAX_CUSTOM_HEADER_BYTES) throw new MimeError("MIME_ERROR", "email: custom headers exceed the 16 KiB limit.");
468
+ headerInputBytes += name.length + encoder.encode(value).byteLength + 4;
469
+ if (headerInputBytes > MAX_CUSTOM_HEADER_BYTES) throw new MimeError("MIME_ERROR", "email: custom headers exceed the 16 KiB limit.");
470
+ rejectCRLF(`header '${name}'`, value);
471
+ if (RESERVED_HEADERS.has(name.toLowerCase())) continue;
472
+ if (headerBytes + name.length + CUSTOM_HEADER_FRAMING_OCTETS + minHeaderValueOctets(value) > MAX_CUSTOM_HEADER_BYTES) throw new MimeError("MIME_ERROR", "email: custom headers exceed the 16 KiB limit.");
473
+ headerBytes += foldHeader(name, encodeWord(value)).length + 2;
474
+ if (headerBytes > MAX_CUSTOM_HEADER_BYTES) throw new MimeError("MIME_ERROR", "email: custom headers exceed the 16 KiB limit.");
475
+ }
462
476
  }
463
477
  const recipientCount = countRecipients(opts.to) + countRecipients(opts.cc) + countRecipients(opts.bcc);
464
- if (recipientCount > 100) throw new MimeError("INVALID_TO", `email: too many recipients (max 100, got ${recipientCount}) across 'to', 'cc' and 'bcc'.`);
478
+ if (recipientCount > 50) throw new MimeError("INVALID_TO", `email: too many recipients (max 50, got ${recipientCount}) across 'to', 'cc' and 'bcc'.`);
465
479
  const from = parseAddress(opts.from, "from");
466
480
  const to = parseAddresses(opts.to, "to");
467
481
  if (to.length === 0) throw new MimeError("INVALID_TO", "email: 'to' must include at least one recipient.");
@@ -1171,7 +1185,7 @@ function generateMessageId(fromEmail) {
1171
1185
  */
1172
1186
  function buildMime(email) {
1173
1187
  const projected = minHeaderOctets(email) + (email.text ? minBodyOctets(email.text) : 0) + (email.html ? minBodyOctets(email.html) : 0) + email.attachments.reduce((sum, a) => sum + base64Octets(a.bytes.byteLength), 0);
1174
- if (projected > 10485760) throw new MimeError("MIME_ERROR", `email: message is at least ${projected} bytes once encoded, which exceeds Cloudflare limit of ${MAX_MESSAGE_BYTES} bytes.`);
1188
+ if (projected > 5242880) throw new MimeError("MIME_ERROR", `email: message is at least ${projected} bytes once encoded, which exceeds Cloudflare limit of ${MAX_MESSAGE_BYTES} bytes.`);
1175
1189
  const messageId = generateMessageId(email.from.email);
1176
1190
  const topHeaders = [
1177
1191
  ["Date", (/* @__PURE__ */ new Date()).toUTCString().replace("GMT", "+0000")],
@@ -1206,7 +1220,7 @@ function buildMime(email) {
1206
1220
  const raw = new TextEncoder().encode(rawText);
1207
1221
  const overlong = findOverlongLine(rawText);
1208
1222
  if (overlong !== void 0) throw new MimeError("MIME_ERROR", `email: header line ${overlong.index + 1} is ${overlong.octets} octets, over the ${MAX_LINE_OCTETS}-octet limit in RFC 5322 §2.1.1. A value with no whitespace cannot be folded — shorten it, or move it into the body.`);
1209
- if (raw.byteLength > 10485760) throw new MimeError("MIME_ERROR", `email: message size ${raw.byteLength} bytes exceeds Cloudflare limit of ${MAX_MESSAGE_BYTES} bytes.`);
1223
+ if (raw.byteLength > 5242880) throw new MimeError("MIME_ERROR", `email: message size ${raw.byteLength} bytes exceeds Cloudflare limit of ${MAX_MESSAGE_BYTES} bytes.`);
1210
1224
  return {
1211
1225
  raw,
1212
1226
  messageId
@@ -1,9 +1,9 @@
1
1
  import { o as join } from "./dist-BrsS7cai.mjs";
2
2
  import { c as loadVoidAuthConfig, s as findVoidAuthConfig } from "./scan-BMH4rzlv.mjs";
3
- import { f as readConfig } from "./config-BQFq7QvD.mjs";
4
- import { r as getMiniflareDatabasePath } from "./local-d1-BE8KBbMy.mjs";
3
+ import { f as readConfig } from "./config-uNGuFsI2.mjs";
4
+ import { r as getMiniflareDatabasePath } from "./local-d1-D2I6Ox5F.mjs";
5
5
  import { a as resolveVoidAuthMigrationSchema } from "./route-types-Da-DpyUp.mjs";
6
- import { a as loadLocalEnv } from "./env-D4Emu-M_.mjs";
6
+ import { a as loadLocalEnv } from "./env-DBKmK4vc.mjs";
7
7
  import { n as applyPgAuthMigrations, r as applySqliteAuthMigrations, t as applyMySqlAuthMigrations } from "./auth-migrations-9vif1uj8.mjs";
8
8
  //#region src/auth/node.ts
9
9
  async function runLocalVoidAuthMigrations(root, dialect, persistRoot = join(root, ".void"), databaseId = "local", configPath = findVoidAuthConfig(root)) {
@@ -0,0 +1,52 @@
1
+ import { K as getActivePlatformConnection, X as normalizePlatformApiUrl, Y as listPlatformConnections, Z as platformCredentialAccount, dt as writeKeyringPassword, lt as deleteKeyringPassword, ut as readKeyringPassword } from "./output-B0cfNSx5.mjs";
2
+ import { n as OperatorClient, r as OperatorClientError } from "./operator-client-LUZnlnYk.mjs";
3
+ /** Operator authority never comes from repository-controlled metadata. */
4
+ function resolveOperatorOrigin(connection = "") {
5
+ if (connection) {
6
+ let normalized = null;
7
+ try {
8
+ normalized = normalizePlatformApiUrl(connection);
9
+ } catch {}
10
+ const matches = listPlatformConnections().filter((entry) => entry.id === connection || entry.installationId === connection || entry.apiUrl === normalized);
11
+ if (matches.length !== 1) throw new OperatorClientError("Select a registered platform connection ID or URL. Run `void connect <url> --no-login` to register it first.", "invalid_connection");
12
+ return matches[0].apiUrl;
13
+ }
14
+ if (process.env.VOID_API_URL) return normalizePlatformApiUrl(process.env.VOID_API_URL);
15
+ if (process.env.VOID_OPERATOR_TOKEN) throw new OperatorClientError("VOID_OPERATOR_TOKEN requires an explicit --connection or VOID_API_URL to select its recipient.", "explicit_origin_required");
16
+ const active = getActivePlatformConnection();
17
+ if (!active) throw new OperatorClientError("No default platform connection. Run `void connect <url>` or specify --connection.", "connection_required");
18
+ return active.apiUrl;
19
+ }
20
+ function readOperatorToken(origin) {
21
+ const token = process.env.VOID_OPERATOR_TOKEN || readKeyringPassword("dev.void.cli.operator", platformCredentialAccount(origin));
22
+ if (!token) throw new OperatorClientError("No operator session. Run `void platform auth login` or set VOID_OPERATOR_TOKEN with an explicit origin.", "authentication_required");
23
+ return token;
24
+ }
25
+ function saveOperatorToken(origin, token) {
26
+ if (!writeKeyringPassword("dev.void.cli.operator", platformCredentialAccount(origin), token)) throw new OperatorClientError("The system keychain is unavailable. Use `void platform auth token --token-stdin` with a full API session to obtain a token for VOID_OPERATOR_TOKEN; plaintext credential storage is disabled.", "keychain_unavailable");
27
+ }
28
+ function removeOperatorToken(origin) {
29
+ const account = platformCredentialAccount(origin);
30
+ if (readKeyringPassword("dev.void.cli.operator", account) && !deleteKeyringPassword("dev.void.cli.operator", account)) throw new OperatorClientError("The operator session was revoked, but its local keychain entry could not be removed.", "keychain_unavailable");
31
+ }
32
+ async function readOperatorApiTokenStdin() {
33
+ if (process.stdin.isTTY) throw new OperatorClientError("--token-stdin requires an API session token piped on standard input.", "invalid_token_input");
34
+ let input = "";
35
+ for await (const chunk of process.stdin) {
36
+ input += String(chunk);
37
+ if (input.length > 32768) throw new OperatorClientError("API session token input is too large.", "invalid_token_input");
38
+ }
39
+ const token = input.trim();
40
+ if (!token || token.length > 32768 || /\s/.test(token)) throw new OperatorClientError("Standard input must contain one API session token.", "invalid_token_input");
41
+ return token;
42
+ }
43
+ async function exchangeOperatorSession(origin, apiToken) {
44
+ const session = await new OperatorClient(origin, apiToken).request("/session", {
45
+ method: "POST",
46
+ body: {}
47
+ });
48
+ if (typeof session.token !== "string" || !session.token || session.apiVersion !== 1 || typeof session.expiresAt !== "string") throw new OperatorClientError("Operator API returned an invalid session.", "invalid_response");
49
+ return session;
50
+ }
51
+ //#endregion
52
+ export { resolveOperatorOrigin as a, removeOperatorToken as i, readOperatorApiTokenStdin as n, saveOperatorToken as o, readOperatorToken as r, exchangeOperatorSession as t };