@rebasepro/server 0.21.0 → 0.21.1

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 (56) hide show
  1. package/README.md +29 -11
  2. package/dist/api/errors.d.ts +41 -0
  3. package/dist/auth/admin-user-ops.d.ts +23 -1
  4. package/dist/auth/auth-hooks.d.ts +4 -0
  5. package/dist/auth/reset-password-admin.d.ts +4 -0
  6. package/dist/auth/token-revocation.d.ts +39 -5
  7. package/dist/{auth-gzoRjnuh.js → auth-BS4WBA10.js} +1636 -1565
  8. package/dist/auth-BS4WBA10.js.map +1 -0
  9. package/dist/backup/backup-common.d.ts +2 -1
  10. package/dist/{backup-DGu0v9Ku.js → backup-DzI9jLwc.js} +38 -10
  11. package/dist/backup-DzI9jLwc.js.map +1 -0
  12. package/dist/collections/validate-config.d.ts +4 -2
  13. package/dist/{cron-routes-BamgO0Xr.js → cron-routes-B_wlLybo.js} +3 -3
  14. package/dist/{cron-routes-BamgO0Xr.js.map → cron-routes-B_wlLybo.js.map} +1 -1
  15. package/dist/{cron-scheduler-D47tdB9T.js → cron-scheduler-COPQxlEq.js} +59 -10
  16. package/dist/cron-scheduler-COPQxlEq.js.map +1 -0
  17. package/dist/{cron-store-yXOyIEmn.js → cron-store-Dp0X7zRB.js} +2 -2
  18. package/dist/{cron-store-yXOyIEmn.js.map → cron-store-Dp0X7zRB.js.map} +1 -1
  19. package/dist/ddl-bootstrap-CfNvxMuK.js.map +1 -1
  20. package/dist/deploy/pod-contract.d.ts +14 -0
  21. package/dist/{errors-DMImyqyR.js → errors-DWsX4yTd.js} +55 -18
  22. package/dist/errors-DWsX4yTd.js.map +1 -0
  23. package/dist/{function-routes-C4nB2h0z.js → function-routes-Chet4-lB.js} +2 -2
  24. package/dist/{function-routes-C4nB2h0z.js.map → function-routes-Chet4-lB.js.map} +1 -1
  25. package/dist/functions/index.js.map +1 -1
  26. package/dist/{history-recorder-hBGuXcZc.js → history-recorder-5VKT7nss.js} +2 -2
  27. package/dist/{history-recorder-hBGuXcZc.js.map → history-recorder-5VKT7nss.js.map} +1 -1
  28. package/dist/{history-store-C9EtGtoL.js → history-store-By2R_G1b.js} +2 -2
  29. package/dist/{history-store-C9EtGtoL.js.map → history-store-By2R_G1b.js.map} +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.es.js +286 -245
  32. package/dist/index.es.js.map +1 -1
  33. package/dist/init/middlewares.d.ts +19 -1
  34. package/dist/init/storage.d.ts +17 -0
  35. package/dist/init.d.ts +6 -2
  36. package/dist/{jobs-DZ8DLLcU.js → jobs-1IkI4Lle.js} +2 -2
  37. package/dist/{jobs-DZ8DLLcU.js.map → jobs-1IkI4Lle.js.map} +1 -1
  38. package/dist/{logs-routes-DnJINsMu.js → logs-routes-3EEzPjhl.js} +2 -2
  39. package/dist/{logs-routes-DnJINsMu.js.map → logs-routes-3EEzPjhl.js.map} +1 -1
  40. package/dist/{openapi-generator-CAFKF36E.js → openapi-generator-BDpoKZQ9.js} +2 -2
  41. package/dist/{openapi-generator-CAFKF36E.js.map → openapi-generator-BDpoKZQ9.js.map} +1 -1
  42. package/dist/{query-parser-uqzkZ82i.js → query-parser-C-rl30ce.js} +3 -3
  43. package/dist/{query-parser-uqzkZ82i.js.map → query-parser-C-rl30ce.js.map} +1 -1
  44. package/dist/{request-timeout-BR-OBwES.js → request-timeout-C_4C2BeR.js} +2 -2
  45. package/dist/{request-timeout-BR-OBwES.js.map → request-timeout-C_4C2BeR.js.map} +1 -1
  46. package/dist/{schema-editor-routes-BKOmdf4M.js → schema-editor-routes-DdLihzp0.js} +2 -2
  47. package/dist/{schema-editor-routes-BKOmdf4M.js.map → schema-editor-routes-DdLihzp0.js.map} +1 -1
  48. package/dist/src-Br6ARbs6.js.map +1 -1
  49. package/dist/{src-DW1cQ_28.js → src-Caz7nREj.js} +2 -3
  50. package/dist/src-Caz7nREj.js.map +1 -0
  51. package/package.json +5 -5
  52. package/dist/auth-gzoRjnuh.js.map +0 -1
  53. package/dist/backup-DGu0v9Ku.js.map +0 -1
  54. package/dist/cron-scheduler-D47tdB9T.js.map +0 -1
  55. package/dist/errors-DMImyqyR.js.map +0 -1
  56. package/dist/src-DW1cQ_28.js.map +0 -1
package/dist/index.es.js CHANGED
@@ -2,33 +2,33 @@ import { createRequire as __rebaseCreateRequire } from "module";
2
2
  import __rebaseProcess from "process";
3
3
  globalThis.process ??= __rebaseProcess;
4
4
  __rebaseCreateRequire(import.meta.url);
5
- import { A as createDataSourceRegistry, B as findRelation, D as restrictedFieldNames, E as effectiveAccess, F as getJunctionConfigForRelation, G as buildCompositeId, I as getEffectiveSecurityRules, J as suggestNearMiss, K as resolvePrimaryKeys, M as resolveDataSource, O as defaultUsersCollection, P as revokeInternalTableSql, R as securityRuleToConditions, S as cursorToStartAfter, T as canWriteField, U as resolveCollectionRelations, V as getTableName, W as enumToObjectEntries, X as unref, Y as toSnakeCase, c as collectAllPages, dt as GeoPoint, et as BATCH_REF_KEY, ft as Vector, g as topLevelIncludeNames, gt as unsupportedMethod, h as serializeInclude, ht as isUnsupported, j as isRelationalCollection, k as CollectionRegistry, l as paginateFind, lt as EntityReference, mt as RebaseClientError, n as buildSdkData, nt as hasFieldOperation, o as serializeFilter, ot as JUNCTION_PIVOT_KEY, p as mergeIncludeSpecs, pt as RebaseApiError, q as hydrateRegExp, rt as isFieldOperation, s as serializeLogicalCondition, st as isManyToMany, t as buildRoutedRebaseData, tt as FIELD_OPERATORS, u as resolveFindWindow, ut as EntityRelation, v as normalizeOrderBy, y as serializeOrderBy, z as fieldKeyForColumn } from "./src-DW1cQ_28.js";
5
+ import { A as createDataSourceRegistry, B as findRelation, D as restrictedFieldNames, E as effectiveAccess, F as getJunctionConfigForRelation, G as buildCompositeId, I as getEffectiveSecurityRules, J as suggestNearMiss, K as resolvePrimaryKeys, M as resolveDataSource, O as defaultUsersCollection, P as revokeInternalTableSql, R as securityRuleToConditions, S as cursorToStartAfter, T as canWriteField, U as resolveCollectionRelations, V as getTableName, W as enumToObjectEntries, X as unref, Y as toSnakeCase, c as collectAllPages, dt as GeoPoint, et as BATCH_REF_KEY, ft as Vector, g as topLevelIncludeNames, gt as unsupportedMethod, h as serializeInclude, ht as isUnsupported, j as isRelationalCollection, k as CollectionRegistry, l as paginateFind, lt as EntityReference, mt as RebaseClientError, n as buildSdkData, nt as hasFieldOperation, o as serializeFilter, ot as JUNCTION_PIVOT_KEY, p as mergeIncludeSpecs, pt as RebaseApiError, q as hydrateRegExp, rt as isFieldOperation, s as serializeLogicalCondition, st as isManyToMany, t as buildRoutedRebaseData, tt as FIELD_OPERATORS, u as resolveFindWindow, ut as EntityRelation, v as normalizeOrderBy, y as serializeOrderBy, z as fieldKeyForColumn } from "./src-Caz7nREj.js";
6
6
  import { E as DEFAULT_DATA_SOURCE_KEY, F as sortKeyToString, I as toCanonicalOp, P as parseRelationAggregateSort, S as getCollectionDataPath, _ as resourceKinds, a as resourceToStorageSource, b as RLS_UID_SQL, c as DEFAULT_STORAGE_SOURCE_KEY, d as DEFAULT_RESOURCE_KEY, f as buildResourceGraph, g as resourceKind, h as resourceKeyOf, i as resourceToDataSource, l as findStorageSuffixCollision, m as resourceEnvSuffix, n as declaredQueueConsumers, o as setQueueRuntime, p as resolveResourceRefs, r as declaredSubscriptions, s as setTopicRuntime, u as storageEnvSuffix, v as RLS_JWT_SQL, w as isPostgresCollectionConfig, y as RLS_ROLES_SQL } from "./src-Br6ARbs6.js";
7
7
  import { n as ADMIN_PROPERTY_KEYS, t as ADMIN_COLLECTION_KEYS } from "./admin_block-DxKLmdiv.js";
8
8
  import { a as isDuplicateObjectRace, i as isConcurrentDdlRace, n as createDdlBootstrapper, o as isSQLAdmin, s as isSchemaEditingAdmin, t as CONCURRENT_DDL_SQLSTATES } from "./ddl-bootstrap-CfNvxMuK.js";
9
+ import { i as parseEnvBoolean, r as validateCronExpression, t as CronScheduler } from "./cron-scheduler-COPQxlEq.js";
9
10
  import { i as SCHEMA_VERSION_HEADER, n as createContractRoutes, r as computeSchemaVersion } from "./contract-routes-eLxV0le1.js";
10
- import { $ as RawHtml, A as defaultAuthLimiter, B as resolveEmailLinkBase, C as providerVerifiedEmail, Ct as httpMethodToOperation, D as DEFAULT_FUNCTIONS_ANONYMOUS_LIMIT, E as isBootstrapWindowOpen, Et as isPublicStoragePath, F as extractLinks, G as generateSecurePassword, H as hashPassword, I as registerDevEmailSink, J as getMagicLinkTemplate, K as getEmailOtpTemplate, L as SMTPEmailService, M as activeDevEmailSink, N as clearActiveDevEmailSink, O as createDataRateLimiter, P as createDevEmailSink, Q as resolveEmailBranding, R as createEmailService, S as pkceTokenParams, St as supportsRlsScoping, T as createBuiltinAuthAdapter, Tt as PUBLIC_STORAGE_PREFIX, U as validatePasswordStrength, V as resolveAuthHooks, W as verifyPassword, X as getUserInvitationTemplate, Y as getPasswordResetTemplate, Z as getWelcomeEmailTemplate, _ as verifyOidcIdToken, _t as validateApiKey, a as resolveRateLimitStoreKind, at as createRequireAuth, b as createGoogleProvider, bt as SERVICE_IDENTITY, c as createSlackProvider, ct as optionalAuth, d as createDiscordProvider, dt as requireAdmin, et as escapeHtml, f as createTwitterProvider, ft as requireAuth, g as tryVerifyOidcIdToken, gt as isApiKeyToken, h as createMicrosoftProvider, ht as createStorageApiKeyGuard, i as createApiKeyStore, it as createAuthMiddleware, j as MemoryRateLimitStore, k as createRateLimiter, l as createBitbucketProvider, lt as publicObjectAuth, m as createAppleProvider, mt as createFunctionApiKeyGuard, n as createCustomAuthAdapter, nt as raw, o as createSqlRateLimitStore, ot as extractUserFromToken, p as createFacebookProvider, pt as createApiKeyPreAuth, q as getEmailVerificationTemplate, r as createApiKeyRoutes, rt as createAdapterAuthMiddleware, s as createSpotifyProvider, st as fileTokenAuth, tt as html, u as createGitLabProvider, ut as queryTokenAuth, v as createGitHubProvider, vt as extractBearerToken, w as createJwksRoutes, wt as isOperationAllowed, x as oauthCodeFlowSchema, xt as scopeDataDriver, y as createLinkedinProvider, yt as safeCompare, z as assertEmailLinkBases } from "./auth-gzoRjnuh.js";
11
+ import { $ as requireAdmin, A as defaultAuthLimiter, B as resolveEmailLinkBase, C as providerVerifiedEmail, Ct as raw, D as DEFAULT_FUNCTIONS_ANONYMOUS_LIMIT, Dt as isPublicStoragePath, E as isBootstrapWindowOpen, Et as PUBLIC_STORAGE_PREFIX, F as extractLinks, G as createAdapterAuthMiddleware, H as hashPassword, I as registerDevEmailSink, J as extractUserFromToken, K as createAuthMiddleware, L as SMTPEmailService, M as activeDevEmailSink, N as clearActiveDevEmailSink, O as createDataRateLimiter, P as createDevEmailSink, Q as queryTokenAuth, R as createEmailService, S as pkceTokenParams, St as html, T as createBuiltinAuthAdapter, Tt as isOperationAllowed, U as validatePasswordStrength, V as resolveAuthHooks, W as verifyPassword, X as optionalAuth, Y as fileTokenAuth, Z as publicObjectAuth, _ as verifyOidcIdToken, _t as getUserInvitationTemplate, a as resolveRateLimitStoreKind, at as validateApiKey, b as createGoogleProvider, bt as RawHtml, c as createSlackProvider, ct as SERVICE_IDENTITY, d as createDiscordProvider, dt as completeUserCreation, et as requireAuth, f as createTwitterProvider, ft as generateSecurePassword, g as tryVerifyOidcIdToken, gt as getPasswordResetTemplate, h as createMicrosoftProvider, ht as getMagicLinkTemplate, i as createApiKeyStore, it as isApiKeyToken, j as MemoryRateLimitStore, k as createRateLimiter, l as createBitbucketProvider, lt as scopeDataDriver, m as createAppleProvider, mt as getEmailVerificationTemplate, n as createCustomAuthAdapter, nt as createFunctionApiKeyGuard, o as createSqlRateLimitStore, ot as extractBearerToken, p as createFacebookProvider, pt as getEmailOtpTemplate, q as createRequireAuth, r as createApiKeyRoutes, rt as createStorageApiKeyGuard, s as createSpotifyProvider, st as safeCompare, tt as createApiKeyPreAuth, u as createGitLabProvider, ut as supportsRlsScoping, v as createGitHubProvider, vt as getWelcomeEmailTemplate, w as createJwksRoutes, wt as httpMethodToOperation, x as oauthCodeFlowSchema, xt as escapeHtml, y as createLinkedinProvider, yt as resolveEmailBranding, z as assertEmailLinkBases } from "./auth-BS4WBA10.js";
11
12
  import { i as rawQueryLoggingEnabled, n as describeCauseChain, o as setLogLevel, r as logger, s as hostEnv } from "./logger-DO2PZc4i.js";
12
- import { n as errorHandler, r as schemaDriftRemedy, t as ApiError } from "./errors-DMImyqyR.js";
13
- import { a as resolveListLimitParam, c as HARD_DELETE_QUERY_PARAM, i as parseQueryOptions, l as parseHardDelete, n as parseAggregateSelect, o as assertReadableFields, r as parseGroupBy, s as requestViewer, t as orderByEntriesToTuples } from "./query-parser-uqzkZ82i.js";
13
+ import { i as schemaDriftRemedy, n as declaredErrorAnswer, r as errorHandler, t as ApiError } from "./errors-DWsX4yTd.js";
14
+ import { a as resolveListLimitParam, c as HARD_DELETE_QUERY_PARAM, i as parseQueryOptions, l as parseHardDelete, n as parseAggregateSelect, o as assertReadableFields, r as parseGroupBy, s as requestViewer, t as orderByEntriesToTuples } from "./query-parser-C-rl30ce.js";
14
15
  import { D as sha256Bytes, O as sha256Hex, S as normalizePemFromEnv, T as randomHex, _ as verifyAccessToken, a as generateMcpAccessToken, f as hasAsymmetricSigningKey, g as signPurposeToken, i as generateDownloadToken, l as getJwks, m as isJwtConfigured, n as configureJwt, w as constantTimeEqual, x as verifyPurposeToken, y as verifyMcpAccessToken } from "./jwt-C4OW-DNq.js";
15
16
  import { a as canonicalStorageKey, i as canonicalStorageId, n as InvalidStorageKeyError, r as canonicalStorageBucket, t as InvalidStorageBucketError } from "./keys-Qfc4XieN.js";
16
- import { t as logMiddleware } from "./logs-routes-DnJINsMu.js";
17
+ import { t as logMiddleware } from "./logs-routes-3EEzPjhl.js";
17
18
  import { n as DOCUMENT_MIME_TYPES, r as IMAGE_MIME_TYPES, t as DEFAULT_MAX_FILE_SIZE } from "./types-BfKcm9do.js";
18
19
  import { t as S3StorageController } from "./S3StorageController-Dcuf8lMA.js";
19
20
  import { t as GCSStorageController } from "./GCSStorageController-CLIJXwGS.js";
20
21
  import { n as loadFunctionsFromDirectory, r as loadFunctionsWithDiagnostics } from "./function-loader-xnbDAPfa.js";
21
- import { a as getDriver, c as getUser, d as identityResolved, f as isAdmin, i as getApiKey, l as getUserId, m as requireDriver, o as getRequestId, p as isAuthenticated, r as requireRole, s as getRoles, t as createFunctionRoutes, u as hasRole } from "./function-routes-C4nB2h0z.js";
22
+ import { a as getDriver, c as getUser, d as identityResolved, f as isAdmin, i as getApiKey, l as getUserId, m as requireDriver, o as getRequestId, p as isAuthenticated, r as requireRole, s as getRoles, t as createFunctionRoutes, u as hasRole } from "./function-routes-Chet4-lB.js";
22
23
  import "./proxy-Czngl3p9.js";
23
- import "./request-timeout-BR-OBwES.js";
24
+ import "./request-timeout-C_4C2BeR.js";
24
25
  import { t as FunctionSelectionError } from "./selection-CRpqKUbt.js";
25
26
  import { n as loadCronJobsFromDirectory, r as loadCronJobsWithDiagnostics } from "./cron-loader-CQjvjpEw.js";
26
- import { r as validateCronExpression, t as CronScheduler } from "./cron-scheduler-D47tdB9T.js";
27
- import { t as createCronRoutes } from "./cron-routes-BamgO0Xr.js";
28
- import { t as createCronStore } from "./cron-store-yXOyIEmn.js";
29
- import { a as parseBackupTimestamp, i as parseBackupDestination, n as createBackupRoutes, o as readBackupBytes, r as listBackupObjects } from "./backup-DGu0v9Ku.js";
30
- import { a as currentAmbientTransaction, i as createJobStore, n as createJobQueue, r as defaultBackoff } from "./jobs-DZ8DLLcU.js";
31
- import { t as METRIC_SERIES } from "./history-store-C9EtGtoL.js";
27
+ import { t as createCronRoutes } from "./cron-routes-B_wlLybo.js";
28
+ import { t as createCronStore } from "./cron-store-Dp0X7zRB.js";
29
+ import { a as parseBackupTimestamp, i as parseBackupDestination, n as createBackupRoutes, o as readBackupBytes, r as listBackupObjects } from "./backup-DzI9jLwc.js";
30
+ import { a as currentAmbientTransaction, i as createJobStore, n as createJobQueue, r as defaultBackoff } from "./jobs-1IkI4Lle.js";
31
+ import { t as METRIC_SERIES } from "./history-store-By2R_G1b.js";
32
32
  import { createHash, createSign, randomBytes } from "node:crypto";
33
33
  import * as fs$3 from "fs";
34
34
  import fs, { existsSync } from "fs";
@@ -116,26 +116,19 @@ var CollectionConfigError = class extends Error {
116
116
  /**
117
117
  * Read the unknown-key policy from the environment.
118
118
  *
119
- * `REBASE_STRICT_COLLECTION_CONFIG` accepts `error`/`strict`/`1`/`true` to
120
- * escalate, `off`/`0`/`false` to silence, and anything else warns.
119
+ * `REBASE_STRICT_COLLECTION_CONFIG` accepts `error`/`strict` or any spelling of
120
+ * yes to escalate, `none` or any spelling of no to silence, and anything else
121
+ * warns. Yes and no are {@link parseEnvBoolean}'s, the same as every other
122
+ * variable's.
121
123
  */
122
124
  function unknownKeyPolicyFromEnv(env = process.env) {
123
125
  const raw = env.REBASE_STRICT_COLLECTION_CONFIG?.trim().toLowerCase();
124
126
  if (!raw) return "warn";
125
- if ([
126
- "error",
127
- "strict",
128
- "1",
129
- "true",
130
- "yes"
131
- ].includes(raw)) return "error";
132
- if ([
133
- "off",
134
- "0",
135
- "false",
136
- "no",
137
- "none"
138
- ].includes(raw)) return "off";
127
+ if (raw === "error" || raw === "strict") return "error";
128
+ if (raw === "none") return "off";
129
+ const flag = parseEnvBoolean(raw);
130
+ if (flag === true) return "error";
131
+ if (flag === false) return "off";
139
132
  return "warn";
140
133
  }
141
134
  var COLLECTION_KEYS = /* @__PURE__ */ new Set([
@@ -2031,11 +2024,11 @@ function createRoutedRealtimeService(opts) {
2031
2024
  }
2032
2025
  await fallback().handleClientMessage(clientId, message, authContext);
2033
2026
  },
2034
- subscribeToCollection(subscriptionId, config, callback) {
2035
- forPath(config.path).subscribeToCollection(subscriptionId, config, callback);
2027
+ subscribeToCollection(...args) {
2028
+ forPath(args[1].path).subscribeToCollection(...args);
2036
2029
  },
2037
- subscribeToOne(subscriptionId, config, callback) {
2038
- forPath(config.path).subscribeToOne(subscriptionId, config, callback);
2030
+ subscribeToOne(...args) {
2031
+ forPath(args[1].path).subscribeToOne(...args);
2039
2032
  },
2040
2033
  unsubscribe(subscriptionId) {
2041
2034
  for (const p of all()) p.unsubscribe(subscriptionId);
@@ -4002,19 +3995,15 @@ var RestApiGenerator = class {
4002
3995
  collection: resolvedCollection,
4003
3996
  status: "new"
4004
3997
  });
4005
- const result = prepared.hookHandledEmail ? {
4006
- temporaryPassword: prepared.clearPassword,
4007
- invitationSent: prepared.invitationSent
4008
- } : this.authAdapter.finalizeUserCreation ? await this.authAdapter.finalizeUserCreation({
3998
+ const finalize = this.authAdapter.finalizeUserCreation?.bind(this.authAdapter);
3999
+ const delivery = await completeUserCreation(prepared, finalize && ((clearPassword) => finalize({
4009
4000
  id: entity.id,
4010
4001
  values: entity
4011
- }, prepared.clearPassword) : { invitationSent: false };
4002
+ }, clearPassword)));
4012
4003
  const response = this.formatResponse(entity);
4013
4004
  return c.json({
4014
4005
  ...response,
4015
- invitationSent: result.invitationSent,
4016
- ...result.temporaryPassword ? { temporaryPassword: result.temporaryPassword } : {},
4017
- ..."emailDeliveryFailed" in result && result.emailDeliveryFailed ? { emailDeliveryFailed: true } : {}
4006
+ ...delivery
4018
4007
  }, 201);
4019
4008
  }
4020
4009
  return this.runIdempotent(c, body, async () => {
@@ -4123,8 +4112,7 @@ var RestApiGenerator = class {
4123
4112
  hard: parseHardDelete(c.req.query(HARD_DELETE_QUERY_PARAM)),
4124
4113
  row: {
4125
4114
  id: String(id),
4126
- path: getCollectionDataPath(collection),
4127
- values: existingEntity
4115
+ path: getCollectionDataPath(collection)
4128
4116
  },
4129
4117
  collection: resolvedCollection
4130
4118
  });
@@ -4276,18 +4264,16 @@ var RestApiGenerator = class {
4276
4264
  const driver = this.getScopedDriver(c);
4277
4265
  this.enforceSubcollectionApiKeyPermission(c, parsed.collectionPath);
4278
4266
  const hardDelete = parseHardDelete(c.req.query(HARD_DELETE_QUERY_PARAM));
4279
- const existingEntity = await driver.fetchOne({
4267
+ if (!await driver.fetchOne({
4280
4268
  path: parsed.collectionPath,
4281
4269
  id: parsed.id,
4282
4270
  withDeleted: hardDelete ? true : void 0
4283
- });
4284
- if (!existingEntity) throw this.entityNotFound(parsed.collectionPath, parsed.id);
4271
+ })) throw this.entityNotFound(parsed.collectionPath, parsed.id);
4285
4272
  await driver.delete({
4286
4273
  hard: hardDelete,
4287
4274
  row: {
4288
4275
  id: parsed.id,
4289
- path: parsed.collectionPath,
4290
- values: existingEntity
4276
+ path: parsed.collectionPath
4291
4277
  }
4292
4278
  });
4293
4279
  return new Response(null, { status: 204 });
@@ -4653,19 +4639,190 @@ function requestLogger(options) {
4653
4639
  };
4654
4640
  }
4655
4641
  //#endregion
4642
+ //#region src/deploy/pod-contract.ts
4643
+ /**
4644
+ * What every deployment of this runtime must get right about the pod.
4645
+ *
4646
+ * There are two things that place a Rebase runtime in Kubernetes — the Helm
4647
+ * chart in `infra/charts/rebase`, for self-hosting, and the control plane's
4648
+ * `buildManagedContainer`, for cloud tenants — and they were written months
4649
+ * apart by people solving different problems. Rendering both for the same unit
4650
+ * and diffing them (2026-08-22) turned up four disagreements, and in three of
4651
+ * them the chart was doing the thing this runtime's own source warns against.
4652
+ *
4653
+ * The disagreements were not in the parts that *should* differ. A managed pod
4654
+ * takes its environment from a tenant Secret and a self-hosted one takes it from
4655
+ * a values file; a managed pod is scheduled onto spot capacity its plan sold it
4656
+ * and a self-hosted one goes where the operator says. Those are different jobs
4657
+ * and they produce different manifests, correctly.
4658
+ *
4659
+ * What must not differ is anything that is really a statement about *this
4660
+ * process*: which endpoint answers what, which variables decide the topology,
4661
+ * where the bundle is mounted. Those are not deployment preferences. They are
4662
+ * facts about the runtime, and a deployment that gets one wrong produces a
4663
+ * cluster that looks healthy — which is why they are stated here, in the
4664
+ * runtime, rather than twice in the things that deploy it.
4665
+ *
4666
+ * The chart cannot import this module. `tooling/scripts/check-chart.mjs` renders the
4667
+ * chart and asserts it against these values instead, so the chart conforms by
4668
+ * gate where the control plane conforms by construction.
4669
+ */
4670
+ /**
4671
+ * Endpoints this runtime guarantees on every role, and what each one means.
4672
+ *
4673
+ * `/livez` is dependency-free — it answers "this process is running" and
4674
+ * nothing else. `/health` opens the default driver and every configured
4675
+ * secondary, and **answers 503 when any of them is unreachable**
4676
+ * (`boot.ts`, the `healthPaths` handler).
4677
+ *
4678
+ * That difference is the whole reason both exist, and it is stated at the
4679
+ * `/livez` registration in `boot.ts`: "`/health` touches the database, so a
4680
+ * database blip would make an orchestrator kill an otherwise healthy process."
4681
+ */
4682
+ var RUNTIME_HEALTH_PATH = "/health";
4683
+ var RUNTIME_LIVENESS_PATH = "/livez";
4684
+ /**
4685
+ * Which endpoint each Kubernetes probe must target.
4686
+ *
4687
+ * The rule follows from what the probe *does* when it fails:
4688
+ *
4689
+ * - **liveness** restarts the container. A database outage must therefore never
4690
+ * fail it, or an unreachable database turns into a cluster-wide restart loop
4691
+ * that clears the moment the database returns and looks, in the logs, like
4692
+ * the application crashed. `/livez`.
4693
+ * - **readiness** removes the pod from its Service. That is exactly what should
4694
+ * happen when the database is unreachable — the pod cannot serve. `/health`.
4695
+ * - **startup** decides when the other two begin. Its job is "has this process
4696
+ * finished booting", and booting may include fetching a bundle, installing
4697
+ * dependencies and checking the schema. It must not also require the database
4698
+ * to be *up*, or a cold database is indistinguishable from a broken image:
4699
+ * the pod never passes startup, liveness never gets to run, and the pod
4700
+ * CrashLoops with nothing in its output about a database. `/livez`.
4701
+ *
4702
+ * A probe targeting the wrong one of these fails silently in the direction that
4703
+ * looks like an application bug, which is why this is a contract and not a
4704
+ * default.
4705
+ */
4706
+ var RUNTIME_PROBE_PATHS = {
4707
+ liveness: RUNTIME_LIVENESS_PATH,
4708
+ readiness: RUNTIME_HEALTH_PATH,
4709
+ startup: RUNTIME_LIVENESS_PATH
4710
+ };
4711
+ /**
4712
+ * Environment variables that decide *topology* — which surfaces a process
4713
+ * mounts, which singletons it owns, where it forwards.
4714
+ *
4715
+ * These are the platform's or the operator's decision expressed by the thing
4716
+ * doing the deploying, and they must never be settable by whoever supplies the
4717
+ * project's own environment. The cloud learned this the expensive way: a tenant
4718
+ * who set `REBASE_ROLE=worker` in their project variables got a pod that served
4719
+ * no HTTP at all, and because `/health` answers on **every** role the readiness
4720
+ * probe passed, the rollout reported success, and every request 404'd.
4721
+ *
4722
+ * Kubernetes only lets `env` shadow `envFrom` for names it **lists**, so
4723
+ * neutralising one of these means naming it explicitly. An empty value is read
4724
+ * by the runtime as unset, which is why the cloud pins most of them to `""`
4725
+ * rather than to a value: the entry exists to take the decision away from the
4726
+ * project, not to make it here.
4727
+ */
4728
+ var TOPOLOGY_ENV_VARS = [
4729
+ "REBASE_ROLE",
4730
+ "REBASE_FUNCTIONS_ONLY",
4731
+ "REBASE_FUNCTIONS_EXCLUDE",
4732
+ "REBASE_FUNCTIONS_UPSTREAM",
4733
+ "REBASE_CRON_SCHEDULER",
4734
+ "REBASE_JOB_WORKERS",
4735
+ "REBASE_RLS_AUDIT",
4736
+ "REBASE_MCP_ENABLED",
4737
+ "REBASE_MIGRATE_ON_BOOT",
4738
+ "TRUSTED_PROXY_HOPS",
4739
+ "REBASE_RATE_LIMIT_STORE",
4740
+ "REBASE_REQUIRE_SCHEMA_MATCH"
4741
+ ];
4742
+ /** Whether a variable name is one the deployer owns rather than the project. */
4743
+ function isTopologyEnvVar(name) {
4744
+ return TOPOLOGY_ENV_VARS.includes(name);
4745
+ }
4746
+ /**
4747
+ * Seconds to keep answering after Kubernetes decides to remove this pod.
4748
+ *
4749
+ * `installShutdownHandlers` drains on SIGTERM — it stops the scheduler, tears
4750
+ * down realtime and closes the HTTP server, finishing what is in flight. What
4751
+ * it cannot do is stop *new* requests arriving: kubelet sends SIGTERM and the
4752
+ * endpoint controller removes the pod from its Service **concurrently**, so for
4753
+ * as long as endpoint removal takes to propagate, the ingress is still routing
4754
+ * to a process that has already stopped accepting connections.
4755
+ *
4756
+ * A `preStop` sleep is the only thing that orders those two. The pod keeps
4757
+ * serving for this long *before* SIGTERM is sent, which is time the ingress
4758
+ * uses to stop sending it anything.
4759
+ *
4760
+ * Anything greater than zero fixes the ordering; five seconds is what the
4761
+ * control plane has run in production.
4762
+ */
4763
+ var RUNTIME_PRESTOP_DRAIN_SECONDS = 5;
4764
+ /**
4765
+ * The floor for `terminationGracePeriodSeconds`.
4766
+ *
4767
+ * The pod must outlive `preStop` *plus* the drain that follows it, or kubelet
4768
+ * SIGKILLs mid-drain and the graceful shutdown was decoration. The drain's own
4769
+ * default is 15s (`ShutdownHandlerOptions.timeoutMs`), and Kubernetes' default
4770
+ * grace period is 30s — so the stock configuration has room, and this exists to
4771
+ * say how much before someone raises the drain.
4772
+ */
4773
+ var RUNTIME_MIN_TERMINATION_GRACE_SECONDS = 20;
4774
+ /**
4775
+ * How long a deployment must let this runtime take to answer for the first time.
4776
+ *
4777
+ * Nothing answers until boot is finished. `runFromBundle` binds the socket
4778
+ * **last** — after the bundle is read, the drivers connect and, on the process
4779
+ * that owns it, the schema DDL runs (`boot.ts`, "schema DDL happens during
4780
+ * boot, above"). So the gap between the container starting and `/livez`
4781
+ * answering is a whole provisioning run, not a framework warming up.
4782
+ *
4783
+ * A deployment with no startup probe measures that gap with its *liveness*
4784
+ * probe instead, and liveness restarts the container. On the control plane's
4785
+ * settings that is 20s of grace plus three 20s failures — 80 seconds — after
4786
+ * which a slow first boot is killed and retried, and each retry starts from the
4787
+ * beginning. It does not converge; it loops, and the logs show a pod that never
4788
+ * finished starting rather than a database that was slow.
4789
+ *
4790
+ * So a startup probe is not optional here, and its budget is this. A healthy
4791
+ * pod passes it on the first check and nothing is spent.
4792
+ */
4793
+ var RUNTIME_STARTUP_BUDGET_SECONDS = 300;
4794
+ /** Where a bundle is mounted, and what the runtime is told to read. */
4795
+ var RUNTIME_BUNDLE_MOUNT = "/bundle";
4796
+ /**
4797
+ * The request-body limit every API route has by default (`maxBodySize`,
4798
+ * `REBASE_MAX_BODY_SIZE`), in bytes.
4799
+ *
4800
+ * It is not the largest body the runtime accepts. `POST /storage/upload` is
4801
+ * exempt from it and meets the storage config's `maxFileSize` instead, whose
4802
+ * default is `DEFAULT_MAX_FILE_SIZE` (`storage/types.ts`), 50 MB. A proxy in
4803
+ * front of the runtime has to allow more than the larger of the two. Otherwise
4804
+ * it refuses uploads the runtime would accept, with its own error page in
4805
+ * place of the runtime's JSON 413. The chart's ingress was left at 12m after
4806
+ * the upload route got its own limit, and admin-panel uploads between 12 and
4807
+ * 50 MB failed that way.
4808
+ */
4809
+ var RUNTIME_DEFAULT_MAX_BODY_SIZE = 10 * 1024 * 1024;
4810
+ //#endregion
4656
4811
  //#region src/init/middlewares.ts
4657
4812
  function configureMiddlewares(app, basePath, isProduction, config) {
4813
+ const carriesOwnBodyLimit = /* @__PURE__ */ new Set();
4658
4814
  app.use(`${basePath}/*`, requestId());
4659
4815
  if (config.compression !== false) {
4660
4816
  app.use(`${basePath}/*`, responseCompression());
4661
4817
  logger.debug("Response compression enabled");
4662
4818
  }
4663
- const maxBodySize = config.maxBodySize ?? 10 * 1024 * 1024;
4819
+ const maxBodySize = config.maxBodySize ?? 10485760;
4664
4820
  if (maxBodySize > 0) {
4665
- app.use(`${basePath}/*`, bodyLimit({
4821
+ const limitBody = bodyLimit({
4666
4822
  maxSize: maxBodySize,
4667
4823
  onError: (c) => errorHandler(new ApiError(413, "PAYLOAD_TOO_LARGE", `Request body too large. Maximum size is ${Math.round(maxBodySize / 1024 / 1024)}MB.`), c)
4668
- }));
4824
+ });
4825
+ app.use(`${basePath}/*`, (c, next) => carriesOwnBodyLimit.has(c.req.path) ? next() : limitBody(c, next));
4669
4826
  logger.debug("Request body limit configured", { maxSizeMB: Math.round(maxBodySize / 1024 / 1024) });
4670
4827
  }
4671
4828
  if (config.csrf?.origin) {
@@ -4675,6 +4832,9 @@ function configureMiddlewares(app, basePath, isProduction, config) {
4675
4832
  if (!config.corsHandled && !process.env.CORS_ORIGINS && !process.env.FRONTEND_URL) logger.warn((isProduction ? "[PRODUCTION] " : "") + "No CORS configuration detected (CORS_ORIGINS / FRONTEND_URL not set). If your app does not install its own CORS middleware, the API may accept requests from any origin. Set CORS_ORIGINS to restrict access.");
4676
4833
  app.use(`${basePath}/*`, requestLogger());
4677
4834
  app.use(`${basePath}/*`, logMiddleware({ ignorePaths: [`${basePath}/logs/stream`] }));
4835
+ return { exemptFromBodyLimit: (path) => {
4836
+ carriesOwnBodyLimit.add(path);
4837
+ } };
4678
4838
  }
4679
4839
  //#endregion
4680
4840
  //#region src/storage/LocalStorageController.ts
@@ -7013,6 +7173,25 @@ async function createStorageController(config) {
7013
7173
  }
7014
7174
  //#endregion
7015
7175
  //#region src/init/storage.ts
7176
+ /**
7177
+ * Whether `FORCE_LOCAL_STORAGE` says a durable volume is mounted, so a `local`
7178
+ * backend may serve in production.
7179
+ *
7180
+ * The one reader of the variable: this guard and the `bucket` resolver that
7181
+ * `rebase status` asks both call it, so status cannot promise a backend boot
7182
+ * is about to drop. It used to be `!process.env.FORCE_LOCAL_STORAGE` in both,
7183
+ * which is a test for "set", not for "true" — `FORCE_LOCAL_STORAGE=false` and
7184
+ * `=0` read as forced, and the guard stood down for the operator who had just
7185
+ * said there was no volume.
7186
+ *
7187
+ * Only an explicit yes forces. `loadEnv` parses the variable to the same
7188
+ * boolean and refuses a value outside `true`/`false`/blank before storage is
7189
+ * initialised; this reads the raw environment because a backend assembled
7190
+ * without `loadEnv` still has to get the same answer.
7191
+ */
7192
+ function localStorageForced(env = process.env) {
7193
+ return parseEnvBoolean(env.FORCE_LOCAL_STORAGE) === true;
7194
+ }
7016
7195
  async function initializeStorage(storageConfig, isProduction) {
7017
7196
  if (!storageConfig) return {};
7018
7197
  logger.debug("Configuring storage");
@@ -7020,7 +7199,7 @@ async function initializeStorage(storageConfig, isProduction) {
7020
7199
  const toController = async (entry, label) => {
7021
7200
  if (typeof entry.putObject === "function") return entry;
7022
7201
  const conf = entry;
7023
- if (isProduction && conf.type === "local" && !process.env.FORCE_LOCAL_STORAGE) {
7202
+ if (isProduction && conf.type === "local" && !localStorageForced()) {
7024
7203
  logger.error(`Storage backend "${label}" is set to "local" in production — DISABLED. Local storage is the container filesystem, so uploaded files would be destroyed on the next restart or redeploy. File uploads will be refused until storage is configured: set S3-compatible storage (STORAGE_TYPE=s3) or GCS (STORAGE_TYPE=gcs), or pass a custom StorageController. If this deployment really does have a durable volume mounted at the storage path, set FORCE_LOCAL_STORAGE=true.`);
7025
7204
  return;
7026
7205
  }
@@ -7200,7 +7379,7 @@ async function mountOpenApiDocs(app, basePath, enableSwagger, serverCollections,
7200
7379
  basePath,
7201
7380
  requireAuth
7202
7381
  }));
7203
- const { generateOpenApiSpec } = await import("./openapi-generator-CAFKF36E.js");
7382
+ const { generateOpenApiSpec } = await import("./openapi-generator-BDpoKZQ9.js");
7204
7383
  generateOpenApiSpecFn = generateOpenApiSpec;
7205
7384
  if (isPublic) app.get(`${basePath}/docs`, (c) => spec(c));
7206
7385
  else app.get(`${basePath}/docs`, createRequireAuth({}), requireAdmin, (c) => spec(c));
@@ -8688,7 +8867,7 @@ var HANDLER_SLOT = Symbol.for("@rebasepro/server:unhandled-rejection-handler");
8688
8867
  * was installed.
8689
8868
  */
8690
8869
  function installUnhandledRejectionHandler() {
8691
- if (process.env.REBASE_EXIT_ON_UNHANDLED_REJECTION === "1") return void 0;
8870
+ if (parseEnvBoolean(process.env.REBASE_EXIT_ON_UNHANDLED_REJECTION) === true) return void 0;
8692
8871
  const slot = globalThis;
8693
8872
  if (slot[HANDLER_SLOT]) return void 0;
8694
8873
  const handler = (reason) => {
@@ -13039,6 +13218,20 @@ function extractMessageError(message) {
13039
13218
  };
13040
13219
  }
13041
13220
  /**
13221
+ * The error an `ERROR` frame describes, with the server's `details` when it
13222
+ * sent them — `{ stage, path }` for a collection-callback refusal, the object
13223
+ * the REST envelope carries for the same veto. `status` stays `undefined`:
13224
+ * a frame is not an HTTP response (see `RebaseErrorInit.status`).
13225
+ */
13226
+ function frameError(message) {
13227
+ const { errorMessage, errorCode } = extractMessageError(message);
13228
+ const errPayload = message.payload?.error;
13229
+ return new RebaseApiError(errorMessage, {
13230
+ code: errorCode,
13231
+ details: typeof errPayload === "object" && errPayload !== null ? errPayload.details : void 0
13232
+ });
13233
+ }
13234
+ /**
13042
13235
  * Broadcast and presence frames.
13043
13236
  *
13044
13237
  * Fire-and-forget (the server sends no response envelope), and exempt from the
@@ -13432,8 +13625,7 @@ var RebaseWebSocketClient = class {
13432
13625
  else this.sendEntitySubscribe(subscriptionKey);
13433
13626
  return;
13434
13627
  }
13435
- const { errorMessage, errorCode } = extractMessageError(message);
13436
- const error = new RebaseApiError(errorMessage, { code: errorCode });
13628
+ const error = frameError(message);
13437
13629
  if (messageType === "subscribe_collection") this.failCollectionSubscription(subscriptionKey, error);
13438
13630
  else this.failEntitySubscription(subscriptionKey, error);
13439
13631
  }).catch((err) => {
@@ -13450,17 +13642,13 @@ var RebaseWebSocketClient = class {
13450
13642
  this.pendingRequests.delete(requestId);
13451
13643
  this.handleAuthFailure().then((refreshed) => {
13452
13644
  if (refreshed && pendingReq.message) this.doSendMessage(pendingReq.message, pendingReq.resolve, pendingReq.reject).catch(pendingReq.reject);
13453
- else {
13454
- const { errorMessage, errorCode } = extractMessageError(message);
13455
- pendingReq.reject(new RebaseApiError(errorMessage, { code: errorCode }));
13456
- }
13645
+ else pendingReq.reject(frameError(message));
13457
13646
  }).catch((err) => {
13458
13647
  pendingReq.reject(err);
13459
13648
  });
13460
13649
  } else {
13461
13650
  this.pendingRequests.delete(requestId);
13462
- const { errorMessage, errorCode } = extractMessageError(message);
13463
- pendingReq.reject(new RebaseApiError(errorMessage, { code: errorCode }));
13651
+ pendingReq.reject(frameError(message));
13464
13652
  }
13465
13653
  else {
13466
13654
  this.pendingRequests.delete(requestId);
@@ -13544,8 +13732,7 @@ var RebaseWebSocketClient = class {
13544
13732
  if (collectionSub.subscribeTimeout) clearTimeout(collectionSub.subscribeTimeout);
13545
13733
  collectionSub.subscribeTimeout = void 0;
13546
13734
  collectionSub.subscribeInFlight = false;
13547
- const { errorMessage, errorCode } = extractMessageError(message);
13548
- const error = new RebaseApiError(errorMessage, { code: errorCode });
13735
+ const error = frameError(message);
13549
13736
  collectionSub.callbacks.forEach((callback) => {
13550
13737
  if (callback.onError) callback.onError(error);
13551
13738
  });
@@ -13563,8 +13750,7 @@ var RebaseWebSocketClient = class {
13563
13750
  if (entitySub.subscribeTimeout) clearTimeout(entitySub.subscribeTimeout);
13564
13751
  entitySub.subscribeTimeout = void 0;
13565
13752
  entitySub.subscribeInFlight = false;
13566
- const { errorMessage, errorCode } = extractMessageError(message);
13567
- const error = new RebaseApiError(errorMessage, { code: errorCode });
13753
+ const error = frameError(message);
13568
13754
  entitySub.callbacks.forEach((callback) => {
13569
13755
  if (callback.onError) callback.onError(error);
13570
13756
  });
@@ -18005,10 +18191,16 @@ function readAccountVar(env, base, suffix, accountSuffix) {
18005
18191
  if (own !== void 0 || accountSuffix === void 0) return own;
18006
18192
  return readVar(env, base, accountSuffix);
18007
18193
  }
18194
+ /**
18195
+ * A boolean binding, spelled the way every other variable is.
18196
+ *
18197
+ * `undefined` when unset or unrecognised, which the S3 controller reads as
18198
+ * "decide from the endpoint". An exact `=== "true"` used to turn `=1` into an
18199
+ * explicit `false`, switching path-style off for a MinIO endpoint whose
18200
+ * default would have switched it on.
18201
+ */
18008
18202
  function readAccountBool(env, base, suffix, accountSuffix) {
18009
- const raw = readAccountVar(env, base, suffix, accountSuffix);
18010
- if (raw === void 0) return void 0;
18011
- return raw === "true";
18203
+ return parseEnvBoolean(readAccountVar(env, base, suffix, accountSuffix));
18012
18204
  }
18013
18205
  /**
18014
18206
  * Guard against two distinct keys collapsing onto the same variable name.
@@ -18330,7 +18522,7 @@ var bucketResolver = {
18330
18522
  standsIn: config.standsInFor,
18331
18523
  detail: `${config.standsInFor} declared and unbound; a local directory stands in, in development only`
18332
18524
  };
18333
- if (config.type === "local") return context.production && !env.FORCE_LOCAL_STORAGE ? {
18525
+ if (config.type === "local") return context.production && !localStorageForced(env) ? {
18334
18526
  state: "unbound",
18335
18527
  detail: "local storage is dropped in production — a container's filesystem is erased on restart. Bind an object store, or set FORCE_LOCAL_STORAGE=true on a durable volume."
18336
18528
  } : {
@@ -18649,7 +18841,7 @@ async function _initializeRebaseBackend(config) {
18649
18841
  });
18650
18842
  installRootErrorHandler(config.app);
18651
18843
  installUnmatchedApiEnvelope(config.app, basePath);
18652
- configureMiddlewares(config.app, basePath, isProduction, config);
18844
+ const middlewares = configureMiddlewares(config.app, basePath, isProduction, config);
18653
18845
  const collectionRegistry = new BackendCollectionRegistry();
18654
18846
  const dataSourceRegistry = createDataSourceRegistry(declaredDataSources.length > 0 ? declaredDataSources : void 0);
18655
18847
  collectionRegistry.setDataSources(dataSourceRegistry);
@@ -18979,7 +19171,7 @@ async function _initializeRebaseBackend(config) {
18979
19171
  ]) {
18980
19172
  const providerConfig = safeAuthConfig[key];
18981
19173
  if (providerConfig && requiredFields.every((f) => Boolean(providerConfig[f]))) {
18982
- const createFn = (await import("./auth-gzoRjnuh.js").then((n) => n.t))[factory];
19174
+ const createFn = (await import("./auth-BS4WBA10.js").then((n) => n.t))[factory];
18983
19175
  oauthProviders.push(createFn(providerConfig));
18984
19176
  }
18985
19177
  }
@@ -19070,7 +19262,7 @@ async function _initializeRebaseBackend(config) {
19070
19262
  publicUrl,
19071
19263
  mcpPath,
19072
19264
  authBasePath: `${basePath}/auth`,
19073
- allowDynamicRegistration: process.env.REBASE_MCP_OPEN_REGISTRATION !== "false"
19265
+ allowDynamicRegistration: parseEnvBoolean(process.env.REBASE_MCP_OPEN_REGISTRATION) !== false
19074
19266
  }));
19075
19267
  logger.info(`MCP endpoint mounted at ${publicUrl}${mcpPath} (OAuth at ${oauthBasePath})`);
19076
19268
  }
@@ -19134,7 +19326,7 @@ async function _initializeRebaseBackend(config) {
19134
19326
  let schemaEditorOff = schemaEditorUnavailable();
19135
19327
  let schemaEditorRoutes;
19136
19328
  if (!schemaEditorOff && config.collectionsDir) try {
19137
- schemaEditorRoutes = (await import("./schema-editor-routes-BKOmdf4M.js")).createSchemaEditorRoutes(config.collectionsDir);
19329
+ schemaEditorRoutes = (await import("./schema-editor-routes-DdLihzp0.js")).createSchemaEditorRoutes(config.collectionsDir);
19138
19330
  } catch (err) {
19139
19331
  if (err?.code === "ERR_MODULE_NOT_FOUND") {
19140
19332
  schemaEditorOff = {
@@ -19182,7 +19374,7 @@ async function _initializeRebaseBackend(config) {
19182
19374
  commitPaths,
19183
19375
  sourceEditingOff: schemaEditorOff,
19184
19376
  usesVersionedMigrations: collectionsDir ? () => usesVersionedMigrations(collectionsDir) : void 0,
19185
- policy: { allowMachineApply: config.liveSchema?.allowMachineApply ?? process.env.REBASE_LIVE_SCHEMA_ALLOW_MACHINE_APPLY === "true" },
19377
+ policy: { allowMachineApply: config.liveSchema?.allowMachineApply ?? parseEnvBoolean(process.env.REBASE_LIVE_SCHEMA_ALLOW_MACHINE_APPLY) === true },
19186
19378
  getCollections: () => collectionRegistry.getRawCollections(),
19187
19379
  getAdmin: () => defaultDriver.admin,
19188
19380
  getRepository: (author) => {
@@ -19247,7 +19439,7 @@ async function _initializeRebaseBackend(config) {
19247
19439
  }
19248
19440
  const storageAuthorizeData = {};
19249
19441
  if (storageController) {
19250
- const storageMaxSize = (config.storage && typeof config.storage === "object" && "type" in config.storage ? config.storage.maxFileSize : void 0) ?? 50 * 1024 * 1024;
19442
+ const storageMaxSize = (config.storage && typeof config.storage === "object" && "type" in config.storage ? config.storage.maxFileSize : void 0) ?? 52428800;
19251
19443
  const storageAccessControl = resolveStorageAccessControl({
19252
19444
  storagePolicies: config.storagePolicies,
19253
19445
  storageAuthorize: config.storageAuthorize,
@@ -19275,12 +19467,16 @@ async function _initializeRebaseBackend(config) {
19275
19467
  const storageRouter = new Hono();
19276
19468
  if (apiKeyPreAuth) storageRouter.use("/*", apiKeyPreAuth, createStorageApiKeyGuard());
19277
19469
  if (rateLimitConfig) storageRouter.use("/*", createDataRateLimiter(rateLimitConfig));
19278
- storageRouter.use("/upload", bodyLimit({
19470
+ const uploadPath = "/upload";
19471
+ storageRouter.use(uploadPath, bodyLimit({
19279
19472
  maxSize: storageMaxSize,
19280
19473
  onError: (c) => errorHandler(new ApiError(413, "PAYLOAD_TOO_LARGE", `File too large. Maximum upload size is ${Math.round(storageMaxSize / 1024 / 1024)}MB.`), c)
19281
19474
  }));
19282
19475
  storageRouter.route("/", storageRoutes);
19283
- if (surfaces.storage) config.app.route(`${basePath}/storage`, storageRouter);
19476
+ if (surfaces.storage) {
19477
+ config.app.route(`${basePath}/storage`, storageRouter);
19478
+ middlewares.exemptFromBodyLimit(`${basePath}/storage${uploadPath}`);
19479
+ }
19284
19480
  } else {
19285
19481
  const storageStub = new Hono();
19286
19482
  storageStub.all("/*", (c) => c.json({ error: {
@@ -19424,8 +19620,8 @@ async function _initializeRebaseBackend(config) {
19424
19620
  injectCallbackClient(driverResults.values(), serverClient);
19425
19621
  if (config.functionsDir && surfaces.functions) {
19426
19622
  const { loadFunctionsWithDiagnostics } = await import("./function-loader-xnbDAPfa.js").then((n) => n.t);
19427
- const { createFunctionRoutes } = await import("./function-routes-C4nB2h0z.js").then((n) => n.n);
19428
- const { createFunctionsRequestTimeout, resolveFunctionsTimeoutMs } = await import("./request-timeout-BR-OBwES.js").then((n) => n.t);
19623
+ const { createFunctionRoutes } = await import("./function-routes-Chet4-lB.js").then((n) => n.n);
19624
+ const { createFunctionsRequestTimeout, resolveFunctionsTimeoutMs } = await import("./request-timeout-C_4C2BeR.js").then((n) => n.t);
19429
19625
  const { functions: allFunctions, problems } = await loadFunctionsWithDiagnostics(config.functionsDir);
19430
19626
  const { selectFunctions } = await import("./selection-CRpqKUbt.js").then((n) => n.n);
19431
19627
  const loadedFunctions = selectFunctions(allFunctions, config.functionsSelection);
@@ -19479,9 +19675,9 @@ async function _initializeRebaseBackend(config) {
19479
19675
  let cronScheduler;
19480
19676
  if (surfaces.cron || config.cronsDir && ownership.cronScheduler) {
19481
19677
  const { loadCronJobsWithDiagnostics } = await import("./cron-loader-CQjvjpEw.js").then((n) => n.t);
19482
- const { CronScheduler } = await import("./cron-scheduler-D47tdB9T.js").then((n) => n.n);
19483
- const { createCronRoutes } = await import("./cron-routes-BamgO0Xr.js").then((n) => n.n);
19484
- const { createCronStore } = await import("./cron-store-yXOyIEmn.js").then((n) => n.n);
19678
+ const { CronScheduler } = await import("./cron-scheduler-COPQxlEq.js").then((n) => n.n);
19679
+ const { createCronRoutes } = await import("./cron-routes-B_wlLybo.js").then((n) => n.n);
19680
+ const { createCronStore } = await import("./cron-store-Dp0X7zRB.js").then((n) => n.n);
19485
19681
  const { jobs: loadedCronJobs, problems: cronProblems } = config.cronsDir ? await loadCronJobsWithDiagnostics(config.cronsDir) : {
19486
19682
  jobs: [],
19487
19683
  problems: []
@@ -19538,7 +19734,7 @@ async function _initializeRebaseBackend(config) {
19538
19734
  }
19539
19735
  let metricsHistory;
19540
19736
  try {
19541
- const { createMetricsHistory } = await import("./history-recorder-hBGuXcZc.js");
19737
+ const { createMetricsHistory } = await import("./history-recorder-5VKT7nss.js");
19542
19738
  metricsHistory = createMetricsHistory(defaultDriver);
19543
19739
  if (metricsHistory) {
19544
19740
  await metricsHistory.ensure();
@@ -19550,7 +19746,7 @@ async function _initializeRebaseBackend(config) {
19550
19746
  }
19551
19747
  let jobQueue;
19552
19748
  if (config.jobs?.enabled) {
19553
- const { createJobStore, createJobQueue } = await import("./jobs-DZ8DLLcU.js").then((n) => n.t);
19749
+ const { createJobStore, createJobQueue } = await import("./jobs-1IkI4Lle.js").then((n) => n.t);
19554
19750
  const store = createJobStore(defaultDriver);
19555
19751
  if (store) {
19556
19752
  await store.ensureTable();
@@ -19576,7 +19772,7 @@ Use a driver that supports the job queue, or remove the declarations. Refusing t
19576
19772
  }
19577
19773
  let rlsAudit;
19578
19774
  if (surfaces.admin) {
19579
- const { createBackupRoutes, parseBackupDestination } = await import("./backup-DGu0v9Ku.js").then((n) => n.t);
19775
+ const { createBackupRoutes, parseBackupDestination } = await import("./backup-DzI9jLwc.js").then((n) => n.t);
19580
19776
  const backupRouter = new Hono();
19581
19777
  applyAdminGate(backupRouter, "Backup");
19582
19778
  backupRouter.route("/", createBackupRoutes({
@@ -19624,7 +19820,7 @@ Use a driver that supports the job queue, or remove the declarations. Refusing t
19624
19820
  logger.debug("Development mailbox admin routes mounted", { path: `${basePath}/admin/dev/emails` });
19625
19821
  }
19626
19822
  if (surfaces.admin) {
19627
- const { default: logsRoutes } = await import("./logs-routes-DnJINsMu.js").then((n) => n.n);
19823
+ const { default: logsRoutes } = await import("./logs-routes-3EEzPjhl.js").then((n) => n.n);
19628
19824
  const logsRouter = new Hono();
19629
19825
  applyAdminGate(logsRouter, "Logs");
19630
19826
  logsRouter.route("/", logsRoutes);
@@ -20860,7 +21056,7 @@ function listenWithPortRetry(server, startPort, options) {
20860
21056
  const host = options?.host ?? "0.0.0.0";
20861
21057
  const maxAttempts = options?.maxAttempts ?? MAX_PORT_ATTEMPTS;
20862
21058
  const portFileDir = options?.portFileDir;
20863
- const explicit = options?.explicit ?? process.env.REBASE_DEV_PORT_EXPLICIT === "true";
21059
+ const explicit = options?.explicit ?? parseEnvBoolean(process.env.REBASE_DEV_PORT_EXPLICIT) === true;
20864
21060
  if (process.env.NODE_ENV === "production") return new Promise((resolve, reject) => {
20865
21061
  const onError = (err) => {
20866
21062
  reject(err);
@@ -23291,7 +23487,7 @@ async function bootStaticApp(bundle, devRoot, options) {
23291
23487
  const isProduction = process.env.NODE_ENV === "production";
23292
23488
  const requestedPort = Number(process.env.PORT ?? "3001") || 3001;
23293
23489
  const basePath = process.env.REBASE_BASE_PATH || "/api";
23294
- const metricsEnabled = process.env.REBASE_METRICS === "true";
23490
+ const metricsEnabled = parseEnvBoolean(process.env.REBASE_METRICS) === true;
23295
23491
  const metricsToken = process.env.REBASE_METRICS_TOKEN;
23296
23492
  const app = new Hono();
23297
23493
  installRootErrorHandler(app);
@@ -23511,161 +23707,6 @@ function warnOnUnusableBundleShape(bundle) {
23511
23707
  logger.warn(`This bundle declares collections at "${bundle.manifest.entry.collections}", but that directory did not resolve, so no collections were loaded and no tables will be created. Rebuild with \`rebase build\`.`);
23512
23708
  }
23513
23709
  //#endregion
23514
- //#region src/deploy/pod-contract.ts
23515
- /**
23516
- * What every deployment of this runtime must get right about the pod.
23517
- *
23518
- * There are two things that place a Rebase runtime in Kubernetes — the Helm
23519
- * chart in `infra/charts/rebase`, for self-hosting, and the control plane's
23520
- * `buildManagedContainer`, for cloud tenants — and they were written months
23521
- * apart by people solving different problems. Rendering both for the same unit
23522
- * and diffing them (2026-08-22) turned up four disagreements, and in three of
23523
- * them the chart was doing the thing this runtime's own source warns against.
23524
- *
23525
- * The disagreements were not in the parts that *should* differ. A managed pod
23526
- * takes its environment from a tenant Secret and a self-hosted one takes it from
23527
- * a values file; a managed pod is scheduled onto spot capacity its plan sold it
23528
- * and a self-hosted one goes where the operator says. Those are different jobs
23529
- * and they produce different manifests, correctly.
23530
- *
23531
- * What must not differ is anything that is really a statement about *this
23532
- * process*: which endpoint answers what, which variables decide the topology,
23533
- * where the bundle is mounted. Those are not deployment preferences. They are
23534
- * facts about the runtime, and a deployment that gets one wrong produces a
23535
- * cluster that looks healthy — which is why they are stated here, in the
23536
- * runtime, rather than twice in the things that deploy it.
23537
- *
23538
- * The chart cannot import this module. `tooling/scripts/check-chart.mjs` renders the
23539
- * chart and asserts it against these values instead, so the chart conforms by
23540
- * gate where the control plane conforms by construction.
23541
- */
23542
- /**
23543
- * Endpoints this runtime guarantees on every role, and what each one means.
23544
- *
23545
- * `/livez` is dependency-free — it answers "this process is running" and
23546
- * nothing else. `/health` opens the default driver and every configured
23547
- * secondary, and **answers 503 when any of them is unreachable**
23548
- * (`boot.ts`, the `healthPaths` handler).
23549
- *
23550
- * That difference is the whole reason both exist, and it is stated at the
23551
- * `/livez` registration in `boot.ts`: "`/health` touches the database, so a
23552
- * database blip would make an orchestrator kill an otherwise healthy process."
23553
- */
23554
- var RUNTIME_HEALTH_PATH = "/health";
23555
- var RUNTIME_LIVENESS_PATH = "/livez";
23556
- /**
23557
- * Which endpoint each Kubernetes probe must target.
23558
- *
23559
- * The rule follows from what the probe *does* when it fails:
23560
- *
23561
- * - **liveness** restarts the container. A database outage must therefore never
23562
- * fail it, or an unreachable database turns into a cluster-wide restart loop
23563
- * that clears the moment the database returns and looks, in the logs, like
23564
- * the application crashed. `/livez`.
23565
- * - **readiness** removes the pod from its Service. That is exactly what should
23566
- * happen when the database is unreachable — the pod cannot serve. `/health`.
23567
- * - **startup** decides when the other two begin. Its job is "has this process
23568
- * finished booting", and booting may include fetching a bundle, installing
23569
- * dependencies and checking the schema. It must not also require the database
23570
- * to be *up*, or a cold database is indistinguishable from a broken image:
23571
- * the pod never passes startup, liveness never gets to run, and the pod
23572
- * CrashLoops with nothing in its output about a database. `/livez`.
23573
- *
23574
- * A probe targeting the wrong one of these fails silently in the direction that
23575
- * looks like an application bug, which is why this is a contract and not a
23576
- * default.
23577
- */
23578
- var RUNTIME_PROBE_PATHS = {
23579
- liveness: RUNTIME_LIVENESS_PATH,
23580
- readiness: RUNTIME_HEALTH_PATH,
23581
- startup: RUNTIME_LIVENESS_PATH
23582
- };
23583
- /**
23584
- * Environment variables that decide *topology* — which surfaces a process
23585
- * mounts, which singletons it owns, where it forwards.
23586
- *
23587
- * These are the platform's or the operator's decision expressed by the thing
23588
- * doing the deploying, and they must never be settable by whoever supplies the
23589
- * project's own environment. The cloud learned this the expensive way: a tenant
23590
- * who set `REBASE_ROLE=worker` in their project variables got a pod that served
23591
- * no HTTP at all, and because `/health` answers on **every** role the readiness
23592
- * probe passed, the rollout reported success, and every request 404'd.
23593
- *
23594
- * Kubernetes only lets `env` shadow `envFrom` for names it **lists**, so
23595
- * neutralising one of these means naming it explicitly. An empty value is read
23596
- * by the runtime as unset, which is why the cloud pins most of them to `""`
23597
- * rather than to a value: the entry exists to take the decision away from the
23598
- * project, not to make it here.
23599
- */
23600
- var TOPOLOGY_ENV_VARS = [
23601
- "REBASE_ROLE",
23602
- "REBASE_FUNCTIONS_ONLY",
23603
- "REBASE_FUNCTIONS_EXCLUDE",
23604
- "REBASE_FUNCTIONS_UPSTREAM",
23605
- "REBASE_CRON_SCHEDULER",
23606
- "REBASE_JOB_WORKERS",
23607
- "REBASE_RLS_AUDIT",
23608
- "REBASE_MCP_ENABLED",
23609
- "REBASE_MIGRATE_ON_BOOT",
23610
- "TRUSTED_PROXY_HOPS",
23611
- "REBASE_RATE_LIMIT_STORE",
23612
- "REBASE_REQUIRE_SCHEMA_MATCH"
23613
- ];
23614
- /** Whether a variable name is one the deployer owns rather than the project. */
23615
- function isTopologyEnvVar(name) {
23616
- return TOPOLOGY_ENV_VARS.includes(name);
23617
- }
23618
- /**
23619
- * Seconds to keep answering after Kubernetes decides to remove this pod.
23620
- *
23621
- * `installShutdownHandlers` drains on SIGTERM — it stops the scheduler, tears
23622
- * down realtime and closes the HTTP server, finishing what is in flight. What
23623
- * it cannot do is stop *new* requests arriving: kubelet sends SIGTERM and the
23624
- * endpoint controller removes the pod from its Service **concurrently**, so for
23625
- * as long as endpoint removal takes to propagate, the ingress is still routing
23626
- * to a process that has already stopped accepting connections.
23627
- *
23628
- * A `preStop` sleep is the only thing that orders those two. The pod keeps
23629
- * serving for this long *before* SIGTERM is sent, which is time the ingress
23630
- * uses to stop sending it anything.
23631
- *
23632
- * Anything greater than zero fixes the ordering; five seconds is what the
23633
- * control plane has run in production.
23634
- */
23635
- var RUNTIME_PRESTOP_DRAIN_SECONDS = 5;
23636
- /**
23637
- * The floor for `terminationGracePeriodSeconds`.
23638
- *
23639
- * The pod must outlive `preStop` *plus* the drain that follows it, or kubelet
23640
- * SIGKILLs mid-drain and the graceful shutdown was decoration. The drain's own
23641
- * default is 15s (`ShutdownHandlerOptions.timeoutMs`), and Kubernetes' default
23642
- * grace period is 30s — so the stock configuration has room, and this exists to
23643
- * say how much before someone raises the drain.
23644
- */
23645
- var RUNTIME_MIN_TERMINATION_GRACE_SECONDS = 20;
23646
- /**
23647
- * How long a deployment must let this runtime take to answer for the first time.
23648
- *
23649
- * Nothing answers until boot is finished. `runFromBundle` binds the socket
23650
- * **last** — after the bundle is read, the drivers connect and, on the process
23651
- * that owns it, the schema DDL runs (`boot.ts`, "schema DDL happens during
23652
- * boot, above"). So the gap between the container starting and `/livez`
23653
- * answering is a whole provisioning run, not a framework warming up.
23654
- *
23655
- * A deployment with no startup probe measures that gap with its *liveness*
23656
- * probe instead, and liveness restarts the container. On the control plane's
23657
- * settings that is 20s of grace plus three 20s failures — 80 seconds — after
23658
- * which a slow first boot is killed and retried, and each retry starts from the
23659
- * beginning. It does not converge; it loops, and the logs show a pod that never
23660
- * finished starting rather than a database that was slow.
23661
- *
23662
- * So a startup probe is not optional here, and its budget is this. A healthy
23663
- * pod passes it on the first check and nothing is spent.
23664
- */
23665
- var RUNTIME_STARTUP_BUDGET_SECONDS = 300;
23666
- /** Where a bundle is mounted, and what the runtime is told to read. */
23667
- var RUNTIME_BUNDLE_MOUNT = "/bundle";
23668
- //#endregion
23669
- export { ACCOUNT_SCOPED_STORAGE_BASES, ApiError, BATCH_REF_KEY, BlockedUrlError, BundleError, CONCURRENT_DDL_SQLSTATES, CollectionConfigError, CronScheduler, DEFAULT_DRIVER_ID, DEFAULT_MAX_FILE_SIZE, DEFAULT_STORAGE_ID, DOCUMENT_MIME_TYPES, DefaultDriverRegistry, DefaultStorageRegistry, ETAG_HEADER, FIELD_OPERATORS, GCSStorageController, IF_MATCH_HEADER, IMAGE_MIME_TYPES, LocalStorageController, MetricsRegistry, RUNTIME_BUNDLE_MOUNT, RUNTIME_HEALTH_PATH, RUNTIME_LIVENESS_PATH, RUNTIME_MIN_TERMINATION_GRACE_SECONDS, RUNTIME_PRESTOP_DRAIN_SECONDS, RUNTIME_PROBE_PATHS, RUNTIME_STARTUP_BUDGET_SECONDS, RawHtml, S3StorageController, SMTPEmailService, StoragePolicyError, TOPOLOGY_ENV_VARS, TransformCache, TusHandler, UPLOAD_COLLECTION_FIELD, UPLOAD_PROPERTY_FIELD, UnknownStorageSourceError, WEBHOOK_DELIVERY_TASK, WebhookDispatcher, _resetRebaseMock, _setRebaseMock, activeDevEmailSink, applyCollectionDefaults, assertAllowedOutboundUrl, assertCollectionConfigs, assertDistinctSuffixes, assertEmailLinkBases, assertEveryKindBindable, assertFieldOpsValid, assertIfMatch, assertNoFieldOpsOnCreate, assertUploadWithinPropertyLimits, assertWriteRequestValid, authJwt, authRoles, authUid, blockedAddressReason, bootFromBundle, classifySurface, cleanupDevPortFile, clearActiveDevEmailSink, compileStoragePolicies, configureJwt, createAppleProvider, createBackupRoutes, createBitbucketProvider, createBuiltinAuthAdapter, createContractRoutes, createCronRoutes, createCronStore, createCustomAuthAdapter, createDdlBootstrapper, createDevEmailSink, createDiscordProvider, createEmailService, createFacebookProvider, createFunctionRoutes, createGitHubProvider, createGitLabProvider, createGoogleProvider, createHistoryRoutes, createJobQueue, createJobStore, createJwksRoutes, createLinkedinProvider, createMetricsMiddleware, createMetricsRoutes, createMicrosoftProvider, createRlsAudit, createSlackProvider, createSourceBundle, createSpotifyProvider, createStorageController, createStorageRoutes, createTwitterProvider, createUnconfiguredEmailService, createUploadConstraintResolver, declaredUniqueTargets, defaultBackoff, defineCron, defineFunction, drainBackgroundWork, envSuffixForKey, errorHandler, escapeHtml, extractLinks, extractUserFromToken, fileTokenAuth, findCollectionConfigProblems, generateSecurePassword, getApiKey, getDriver, getEmailOtpTemplate, getEmailVerificationTemplate, getEnv, getJwks, getMagicLinkTemplate, getPasswordResetTemplate, getRequestId, getRoles, getUser, getUserId, getUserInvitationTemplate, getWelcomeEmailTemplate, hasAsymmetricSigningKey, hasFieldOps, hasRole, hashPassword, html, httpMethodToOperation, identityResolved, implicitDeclaration, initializeDataSource, initializeDataSources, initializeRebaseBackend, installShutdownHandlers, isAcceptedFile, isAdmin, isApiKeyToken, isAuthAdapter, isAuthenticated, isConcurrentDdlRace, isDatabaseAdapter, isDuplicateObjectRace, isLocalhostOrigin, isNodeRuntime, isOperationAllowed, isTopologyEnvVar, isTransformableImage, isUncountedPath, lazyResource, listBackupObjects, listenWithPortRetry, loadBootEnv, loadBundle, loadBundleConfigExports, loadBundleSchema, loadCollectionsFromDirectory, loadCronJobsFromDirectory, loadCronJobsWithDiagnostics, loadEnv, loadFunctionsFromDirectory, loadFunctionsWithDiagnostics, loadUsersCollection, logger, looksLikeFieldOp, oauthCodeFlowSchema, optionalAuth, parseBackupDestination, parseBackupTimestamp, parseFieldOp, parseTransformOptions, pendingBackgroundWork, pkceTokenParams, providerVerifiedEmail, queryTokenAuth, raw, rawQueryLoggingEnabled, readBackupBytes, readBundleManifest, readUploadPropertyContext, rebase, registerDevEmailSink, registerResourceResolver, requireAdmin, requireAuth, requireDriver, requireEnv, requireRole, resolveAuthHooks, resolveAuthOptions, resolveBatchRefs, resolveConflictTarget, resolveCorsOrigin, resolveDataSources, resolveEmailBranding, resolveEmailLinkBase, resolveEmailOptions, resolveRequireAuth, resolveStorageAccessControl, resolveStorageBackend, resolveStorageSources, resourceResolver, resourceResolvers, rowETag, runFromBundle, runtimeKey, safeCompare, schemaDriftRemedy, serveSPA, splitFieldOps, summarize as summarizeRlsScan, transformImage, tryVerifyOidcIdToken, unbindableKinds, unknownKeyPolicyFromEnv, validateApiKey, validateCronExpression, validatePasswordStrength, verifyOidcIdToken, verifyPassword, versionProperty, waitUntil, z };
23710
+ export { ACCOUNT_SCOPED_STORAGE_BASES, ApiError, BATCH_REF_KEY, BlockedUrlError, BundleError, CONCURRENT_DDL_SQLSTATES, CollectionConfigError, CronScheduler, DEFAULT_DRIVER_ID, DEFAULT_MAX_FILE_SIZE, DEFAULT_STORAGE_ID, DOCUMENT_MIME_TYPES, DefaultDriverRegistry, DefaultStorageRegistry, ETAG_HEADER, FIELD_OPERATORS, GCSStorageController, IF_MATCH_HEADER, IMAGE_MIME_TYPES, LocalStorageController, MetricsRegistry, RUNTIME_BUNDLE_MOUNT, RUNTIME_DEFAULT_MAX_BODY_SIZE, RUNTIME_HEALTH_PATH, RUNTIME_LIVENESS_PATH, RUNTIME_MIN_TERMINATION_GRACE_SECONDS, RUNTIME_PRESTOP_DRAIN_SECONDS, RUNTIME_PROBE_PATHS, RUNTIME_STARTUP_BUDGET_SECONDS, RawHtml, S3StorageController, SMTPEmailService, StoragePolicyError, TOPOLOGY_ENV_VARS, TransformCache, TusHandler, UPLOAD_COLLECTION_FIELD, UPLOAD_PROPERTY_FIELD, UnknownStorageSourceError, WEBHOOK_DELIVERY_TASK, WebhookDispatcher, _resetRebaseMock, _setRebaseMock, activeDevEmailSink, applyCollectionDefaults, assertAllowedOutboundUrl, assertCollectionConfigs, assertDistinctSuffixes, assertEmailLinkBases, assertEveryKindBindable, assertFieldOpsValid, assertIfMatch, assertNoFieldOpsOnCreate, assertUploadWithinPropertyLimits, assertWriteRequestValid, authJwt, authRoles, authUid, blockedAddressReason, bootFromBundle, classifySurface, cleanupDevPortFile, clearActiveDevEmailSink, compileStoragePolicies, configureJwt, createAppleProvider, createBackupRoutes, createBitbucketProvider, createBuiltinAuthAdapter, createContractRoutes, createCronRoutes, createCronStore, createCustomAuthAdapter, createDdlBootstrapper, createDevEmailSink, createDiscordProvider, createEmailService, createFacebookProvider, createFunctionRoutes, createGitHubProvider, createGitLabProvider, createGoogleProvider, createHistoryRoutes, createJobQueue, createJobStore, createJwksRoutes, createLinkedinProvider, createMetricsMiddleware, createMetricsRoutes, createMicrosoftProvider, createRlsAudit, createSlackProvider, createSourceBundle, createSpotifyProvider, createStorageController, createStorageRoutes, createTwitterProvider, createUnconfiguredEmailService, createUploadConstraintResolver, declaredErrorAnswer, declaredUniqueTargets, defaultBackoff, defineCron, defineFunction, drainBackgroundWork, envSuffixForKey, errorHandler, escapeHtml, extractLinks, extractUserFromToken, fileTokenAuth, findCollectionConfigProblems, generateSecurePassword, getApiKey, getDriver, getEmailOtpTemplate, getEmailVerificationTemplate, getEnv, getJwks, getMagicLinkTemplate, getPasswordResetTemplate, getRequestId, getRoles, getUser, getUserId, getUserInvitationTemplate, getWelcomeEmailTemplate, hasAsymmetricSigningKey, hasFieldOps, hasRole, hashPassword, html, httpMethodToOperation, identityResolved, implicitDeclaration, initializeDataSource, initializeDataSources, initializeRebaseBackend, installShutdownHandlers, isAcceptedFile, isAdmin, isApiKeyToken, isAuthAdapter, isAuthenticated, isConcurrentDdlRace, isDatabaseAdapter, isDuplicateObjectRace, isLocalhostOrigin, isNodeRuntime, isOperationAllowed, isTopologyEnvVar, isTransformableImage, isUncountedPath, lazyResource, listBackupObjects, listenWithPortRetry, loadBootEnv, loadBundle, loadBundleConfigExports, loadBundleSchema, loadCollectionsFromDirectory, loadCronJobsFromDirectory, loadCronJobsWithDiagnostics, loadEnv, loadFunctionsFromDirectory, loadFunctionsWithDiagnostics, loadUsersCollection, logger, looksLikeFieldOp, oauthCodeFlowSchema, optionalAuth, parseBackupDestination, parseBackupTimestamp, parseFieldOp, parseTransformOptions, pendingBackgroundWork, pkceTokenParams, providerVerifiedEmail, queryTokenAuth, raw, rawQueryLoggingEnabled, readBackupBytes, readBundleManifest, readUploadPropertyContext, rebase, registerDevEmailSink, registerResourceResolver, requireAdmin, requireAuth, requireDriver, requireEnv, requireRole, resolveAuthHooks, resolveAuthOptions, resolveBatchRefs, resolveConflictTarget, resolveCorsOrigin, resolveDataSources, resolveEmailBranding, resolveEmailLinkBase, resolveEmailOptions, resolveRequireAuth, resolveStorageAccessControl, resolveStorageBackend, resolveStorageSources, resourceResolver, resourceResolvers, rowETag, runFromBundle, runtimeKey, safeCompare, schemaDriftRemedy, serveSPA, splitFieldOps, summarize as summarizeRlsScan, transformImage, tryVerifyOidcIdToken, unbindableKinds, unknownKeyPolicyFromEnv, validateApiKey, validateCronExpression, validatePasswordStrength, verifyOidcIdToken, verifyPassword, versionProperty, waitUntil, z };
23670
23711
 
23671
23712
  //# sourceMappingURL=index.es.js.map