@playcademy/sandbox 0.6.1-beta.5 → 0.6.1-beta.7

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.
package/dist/cli.js CHANGED
@@ -311,7 +311,7 @@ var init_timeback2 = __esm(() => {
311
311
  });
312
312
 
313
313
  // ../constants/src/cloudflare.ts
314
- var WORKER_NAMING, MAX_WORKER_NAME_LENGTH = 63, SECRETS_PREFIX = "secrets_", CLOUDFLARE_COMPATIBILITY_DATE = "2025-10-11";
314
+ var WORKER_NAMING, MAX_WORKER_NAME_LENGTH = 63, SECRETS_PREFIX = "secrets_", CLOUDFLARE_COMPATIBILITY_DATE = "2025-10-11", D1_TIME_TRAVEL_RETENTION_DAYS = 30;
315
315
  var init_cloudflare = __esm(() => {
316
316
  WORKER_NAMING = {
317
317
  STAGING_PREFIX: "staging-",
@@ -1084,7 +1084,7 @@ var package_default;
1084
1084
  var init_package = __esm(() => {
1085
1085
  package_default = {
1086
1086
  name: "@playcademy/sandbox",
1087
- version: "0.6.1-beta.5",
1087
+ version: "0.6.1-beta.7",
1088
1088
  description: "Local development server for Playcademy game development",
1089
1089
  type: "module",
1090
1090
  exports: {
@@ -1153,6 +1153,16 @@ var init_package = __esm(() => {
1153
1153
  });
1154
1154
 
1155
1155
  // ../api-core/src/errors/domain.error.ts
1156
+ function deployErrorCode(error) {
1157
+ if (!(error instanceof DomainError)) {
1158
+ return null;
1159
+ }
1160
+ const details = error.details;
1161
+ if (typeof details !== "object" || details === null || !("code" in details)) {
1162
+ return null;
1163
+ }
1164
+ return typeof details.code === "string" ? details.code : null;
1165
+ }
1156
1166
  var DomainError, BadRequestError, UnauthorizedError, AccessDeniedError, NotFoundError, ConflictError, AlreadyExistsError, ValidationError, RateLimitError, InternalError, ServiceUnavailableError, TimeoutError;
1157
1167
  var init_domain_error = __esm(() => {
1158
1168
  DomainError = class DomainError extends Error {
@@ -1235,6 +1245,158 @@ var init_domain_error = __esm(() => {
1235
1245
  };
1236
1246
  });
1237
1247
 
1248
+ // ../types/src/game.ts
1249
+ var DEPLOY_ERROR_CODES, REFUSAL_CODES, DEPLOY_REFUSAL_CODES, DELETED_ACCOUNT_LABEL = "(deleted account)";
1250
+ var init_game2 = __esm(() => {
1251
+ DEPLOY_ERROR_CODES = {
1252
+ deployIdPayloadMismatch: "deploy-id-payload-mismatch",
1253
+ stateConflict: "deployment-state-conflict",
1254
+ stateDrift: "deployment-state-drift",
1255
+ destructiveSchema: "destructive-schema-changes",
1256
+ upgradeRequired: "deploy-upgrade-required",
1257
+ checksumMismatch: "migration-checksum-mismatch",
1258
+ journalDivergence: "migration-journal-divergence",
1259
+ outOfOrder: "migration-out-of-order",
1260
+ migrationFailed: "migration-failed",
1261
+ strategyMismatch: "strategy-mismatch",
1262
+ pushFailed: "push-failed",
1263
+ pruneUnmanagedSecrets: "secrets-prune-unmanaged",
1264
+ baselineLedgerNotEmpty: "baseline-ledger-not-empty",
1265
+ baselineDatabaseEmpty: "baseline-database-empty",
1266
+ baselineAlreadyAdopted: "baseline-already-adopted",
1267
+ baselineClaimRejected: "baseline-claim-rejected",
1268
+ restoreUnsupported: "restore-unsupported",
1269
+ restoreIncomplete: "restore-incomplete",
1270
+ restoreBlockedByDeploy: "restore-blocked-by-deploy",
1271
+ restoreExpired: "restore-expired"
1272
+ };
1273
+ REFUSAL_CODES = [
1274
+ DEPLOY_ERROR_CODES.deployIdPayloadMismatch,
1275
+ DEPLOY_ERROR_CODES.stateConflict,
1276
+ DEPLOY_ERROR_CODES.stateDrift,
1277
+ DEPLOY_ERROR_CODES.destructiveSchema,
1278
+ DEPLOY_ERROR_CODES.upgradeRequired,
1279
+ DEPLOY_ERROR_CODES.checksumMismatch,
1280
+ DEPLOY_ERROR_CODES.journalDivergence,
1281
+ DEPLOY_ERROR_CODES.outOfOrder,
1282
+ DEPLOY_ERROR_CODES.strategyMismatch,
1283
+ DEPLOY_ERROR_CODES.pruneUnmanagedSecrets,
1284
+ DEPLOY_ERROR_CODES.baselineLedgerNotEmpty,
1285
+ DEPLOY_ERROR_CODES.baselineDatabaseEmpty,
1286
+ DEPLOY_ERROR_CODES.baselineAlreadyAdopted,
1287
+ DEPLOY_ERROR_CODES.baselineClaimRejected
1288
+ ];
1289
+ DEPLOY_REFUSAL_CODES = new Set(REFUSAL_CODES);
1290
+ });
1291
+
1292
+ // ../api-core/src/errors/deploy.error.ts
1293
+ var DeployIdConflictError, DeploymentStateConflictError, DeploymentStateDriftError, LegacySchemaUpgradeRequiredError, DestructiveSchemaError, MigrationChecksumMismatchError, MigrationJournalDivergenceError, MigrationOrderError, SecretsPruneUnmanagedError, BaselineLedgerNotEmptyError, BaselineDatabaseEmptyError, BaselineAlreadyAdoptedError, BaselineClaimRejectedError, MigrationExecutionError, PushExecutionError;
1294
+ var init_deploy_error = __esm(() => {
1295
+ init_game2();
1296
+ init_domain_error();
1297
+ DeployIdConflictError = class DeployIdConflictError extends ConflictError {
1298
+ constructor(deployId, existingJobId) {
1299
+ super(`Deploy '${deployId}' was already created with a different payload — ` + "generate a fresh deployId for a new deploy", { code: DEPLOY_ERROR_CODES.deployIdPayloadMismatch, deployId, existingJobId });
1300
+ this.name = "DeployIdConflictError";
1301
+ }
1302
+ };
1303
+ DeploymentStateConflictError = class DeploymentStateConflictError extends ConflictError {
1304
+ constructor(payload) {
1305
+ super("Deployment state conflict: the schema baseline changed since this deploy was " + "prepared — refetch the deployment state, re-diff, and retry", { code: DEPLOY_ERROR_CODES.stateConflict, ...payload });
1306
+ this.name = "DeploymentStateConflictError";
1307
+ }
1308
+ };
1309
+ DeploymentStateDriftError = class DeploymentStateDriftError extends ConflictError {
1310
+ constructor(payload) {
1311
+ super("Deployment state drift: the live database schema does not match the recorded " + "fingerprint (out-of-band change or partial prior apply) — repair the " + "database state before deploying", { code: DEPLOY_ERROR_CODES.stateDrift, ...payload });
1312
+ this.name = "DeploymentStateDriftError";
1313
+ }
1314
+ };
1315
+ LegacySchemaUpgradeRequiredError = class LegacySchemaUpgradeRequiredError extends ValidationError {
1316
+ constructor() {
1317
+ super("This game's database state is server-managed; the legacy schema payload is no " + "longer accepted — update the Playcademy CLI and redeploy", { code: DEPLOY_ERROR_CODES.upgradeRequired });
1318
+ this.name = "LegacySchemaUpgradeRequiredError";
1319
+ }
1320
+ };
1321
+ DestructiveSchemaError = class DestructiveSchemaError extends ValidationError {
1322
+ constructor(statements) {
1323
+ super(`Push contains ${statements.length} destructive statement(s) that can drop data — ` + "review them and re-run with --accept-data-loss to proceed", { code: DEPLOY_ERROR_CODES.destructiveSchema, statements });
1324
+ this.name = "DestructiveSchemaError";
1325
+ }
1326
+ };
1327
+ MigrationChecksumMismatchError = class MigrationChecksumMismatchError extends ConflictError {
1328
+ constructor(mismatches) {
1329
+ const tags = mismatches.map((mismatch) => mismatch.tag).join(", ");
1330
+ super(`Applied migration(s) ${tags} no longer match their recorded checksums.`, {
1331
+ code: DEPLOY_ERROR_CODES.checksumMismatch,
1332
+ mismatches
1333
+ });
1334
+ this.name = "MigrationChecksumMismatchError";
1335
+ }
1336
+ };
1337
+ MigrationJournalDivergenceError = class MigrationJournalDivergenceError extends ConflictError {
1338
+ constructor(tags) {
1339
+ super(`The database ledger records applied migration(s) missing from the deploy's ` + `journal: ${tags.join(", ")}. Restore the missing migration files (or resolve ` + "the ledger) before deploying", { code: DEPLOY_ERROR_CODES.journalDivergence, tags });
1340
+ this.name = "MigrationJournalDivergenceError";
1341
+ }
1342
+ };
1343
+ MigrationOrderError = class MigrationOrderError extends ValidationError {
1344
+ constructor(tags) {
1345
+ super(`Out-of-order migration(s): ${tags.join(", ")} are ordered before migrations that ` + "already applied. This usually means a branch merged with older-numbered " + "migrations — regenerate them after the applied ones and redeploy", { code: DEPLOY_ERROR_CODES.outOfOrder, tags });
1346
+ this.name = "MigrationOrderError";
1347
+ }
1348
+ };
1349
+ SecretsPruneUnmanagedError = class SecretsPruneUnmanagedError extends ValidationError {
1350
+ constructor(keys) {
1351
+ super(`Cannot prune secret(s) not managed by the platform: ${keys.join(", ")}. ` + "Only keys the platform previously pushed can be pruned", { code: DEPLOY_ERROR_CODES.pruneUnmanagedSecrets, keys });
1352
+ this.name = "SecretsPruneUnmanagedError";
1353
+ }
1354
+ };
1355
+ BaselineLedgerNotEmptyError = class BaselineLedgerNotEmptyError extends ConflictError {
1356
+ constructor(tags) {
1357
+ super(`Cannot baseline: the migration ledger already records ${tags.length} applied ` + "migration(s) — this database is already server-managed. Just deploy", { code: DEPLOY_ERROR_CODES.baselineLedgerNotEmpty, tags });
1358
+ this.name = "BaselineLedgerNotEmptyError";
1359
+ }
1360
+ };
1361
+ BaselineDatabaseEmptyError = class BaselineDatabaseEmptyError extends ValidationError {
1362
+ constructor() {
1363
+ super("Cannot baseline an empty database — there is no applied history to claim. " + "An empty database needs no baseline: deploy directly and the full " + "journal (or schema) applies fresh.", { code: DEPLOY_ERROR_CODES.baselineDatabaseEmpty });
1364
+ this.name = "BaselineDatabaseEmptyError";
1365
+ }
1366
+ };
1367
+ BaselineAlreadyAdoptedError = class BaselineAlreadyAdoptedError extends ConflictError {
1368
+ constructor(baselineSource) {
1369
+ super("Cannot baseline: deployment state already records a schema baseline" + `${baselineSource ? ` (source: ${baselineSource})` : ""} — ` + "use realign/resolve to repair drift instead", { code: DEPLOY_ERROR_CODES.baselineAlreadyAdopted, baselineSource });
1370
+ this.name = "BaselineAlreadyAdoptedError";
1371
+ }
1372
+ };
1373
+ BaselineClaimRejectedError = class BaselineClaimRejectedError extends ConflictError {
1374
+ constructor(details) {
1375
+ const [first] = details.contradictions;
1376
+ super(first ? `Cannot baseline: the claim contradicts the live database — ${first.tag} ${first.detail ?? ""}` : "Cannot baseline: the claim includes migrations that cannot be verified against the live database — " + "pass --allow-unverified to record them anyway", { code: DEPLOY_ERROR_CODES.baselineClaimRejected, ...details });
1377
+ this.name = "BaselineClaimRejectedError";
1378
+ }
1379
+ };
1380
+ MigrationExecutionError = class MigrationExecutionError extends ValidationError {
1381
+ tag;
1382
+ offset;
1383
+ constructor(input) {
1384
+ super(`Migration '${input.tag}' failed and rolled back: ${input.d1Message}. ` + "Fix the migration SQL and redeploy — the deploy resumes from this migration", { code: DEPLOY_ERROR_CODES.migrationFailed, ...input });
1385
+ this.name = "MigrationExecutionError";
1386
+ this.tag = input.tag;
1387
+ this.offset = input.offset;
1388
+ }
1389
+ };
1390
+ PushExecutionError = class PushExecutionError extends ValidationError {
1391
+ offset;
1392
+ constructor(input) {
1393
+ super(`Push schema changes failed and rolled back: ${input.d1Message}. ` + "Fix the schema and redeploy — nothing was applied", { code: DEPLOY_ERROR_CODES.pushFailed, ...input });
1394
+ this.name = "PushExecutionError";
1395
+ this.offset = input.offset;
1396
+ }
1397
+ };
1398
+ });
1399
+
1238
1400
  // ../api-core/src/errors/api.error.ts
1239
1401
  var STATUS_MAP, ApiError;
1240
1402
  var init_api_error = __esm(() => {
@@ -1334,6 +1496,7 @@ var init_api_error = __esm(() => {
1334
1496
  // ../api-core/src/errors/index.ts
1335
1497
  var init_errors = __esm(() => {
1336
1498
  init_domain_error();
1499
+ init_deploy_error();
1337
1500
  init_api_error();
1338
1501
  });
1339
1502
 
@@ -5688,7 +5851,16 @@ var init_schema = __esm(() => {
5688
5851
  ltiTestMode: exports_external.boolean().default(false),
5689
5852
  platformServiceJwt: platformServiceJwtConfigSchema.optional(),
5690
5853
  uploadBucket: exports_external.string().optional(),
5691
- queueIngressSecret: exports_external.string().optional()
5854
+ queueIngressSecret: exports_external.string().optional(),
5855
+ secretsManifestPepper: exports_external.string().optional()
5856
+ }).superRefine((config2, ctx) => {
5857
+ if (config2.isLocal && !config2.baseUrl) {
5858
+ ctx.addIssue({
5859
+ code: exports_external.ZodIssueCode.custom,
5860
+ path: ["baseUrl"],
5861
+ message: "baseUrl is required when isLocal is true"
5862
+ });
5863
+ }
5692
5864
  });
5693
5865
  });
5694
5866
 
@@ -11209,7 +11381,7 @@ var init_table4 = __esm(() => {
11209
11381
  });
11210
11382
 
11211
11383
  // ../data/src/domains/game/table.ts
11212
- var gamePlatformEnum, gameTypeEnum, gameVisibilityEnum, games, gameMemberRoleEnum, gameMembers, gameMembersRelations, gameDashboardUserRoleEnum, gameDashboardUsers, gameDashboardUsersRelations, deploymentProviderEnum, deploymentTargetEnum, deployJobStatusEnum, gameDeployments, gameDeployJobs, customHostnameStatusEnum, customHostnameSslStatusEnum, customHostnameEnvironmentEnum, gameCustomHostnames;
11384
+ var gamePlatformEnum, gameTypeEnum, gameVisibilityEnum, games, gameMemberRoleEnum, gameMembers, gameMembersRelations, gameDashboardUserRoleEnum, gameDashboardUsers, gameDashboardUsersRelations, deploymentProviderEnum, deploymentTargetEnum, deployJobStatusEnum, gameDeployments, gameDeployJobs, gameDeployEvents, gameDeploymentState, customHostnameStatusEnum, customHostnameSslStatusEnum, customHostnameEnvironmentEnum, gameCustomHostnames;
11213
11385
  var init_table5 = __esm(() => {
11214
11386
  init_drizzle_orm();
11215
11387
  init_pg_core();
@@ -11298,15 +11470,20 @@ var init_table5 = __esm(() => {
11298
11470
  target: deploymentTargetEnum("target").notNull().default("game"),
11299
11471
  url: text("url").notNull(),
11300
11472
  codeHash: text("code_hash"),
11473
+ schemaHash: text("schema_hash"),
11474
+ schemaFingerprint: text("schema_fingerprint"),
11475
+ timeTravelBookmark: text("time_travel_bookmark"),
11476
+ bookmarkCapturedAt: timestamp("bookmark_captured_at", { withTimezone: true }),
11301
11477
  isActive: boolean("is_active").notNull().default(false),
11302
11478
  resources: jsonb("resources").$type(),
11303
11479
  deployedAt: timestamp("deployed_at", { withTimezone: true }).notNull().defaultNow()
11304
- });
11480
+ }, (table3) => [index("game_deployments_game_target_idx").on(table3.gameId, table3.target)]);
11305
11481
  gameDeployJobs = pgTable("game_deploy_jobs", {
11306
11482
  id: uuid("id").primaryKey().defaultRandom(),
11307
11483
  gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
11308
- userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
11484
+ userId: text("user_id").references(() => users.id, { onDelete: "set null" }),
11309
11485
  status: deployJobStatusEnum("status").notNull().default("pending"),
11486
+ deployId: text("deploy_id"),
11310
11487
  request: jsonb("request").$type().notNull(),
11311
11488
  events: jsonb("events").$type().notNull().default([]),
11312
11489
  error: text("error"),
@@ -11320,6 +11497,27 @@ var init_table5 = __esm(() => {
11320
11497
  createdAt: timestamp("created_at", { mode: "date", withTimezone: true }).notNull().defaultNow(),
11321
11498
  startedAt: timestamp("started_at", { mode: "date", withTimezone: true }),
11322
11499
  completedAt: timestamp("completed_at", { mode: "date", withTimezone: true })
11500
+ }, (table3) => [uniqueIndex("game_deploy_jobs_game_deploy_id_idx").on(table3.gameId, table3.deployId)]);
11501
+ gameDeployEvents = pgTable("game_deploy_events", {
11502
+ id: uuid("id").primaryKey().defaultRandom(),
11503
+ gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
11504
+ userId: text("user_id").references(() => users.id, { onDelete: "set null" }),
11505
+ kind: text("kind").$type().notNull(),
11506
+ payload: jsonb("payload").$type().notNull(),
11507
+ createdAt: timestamp("created_at", { mode: "date", withTimezone: true }).notNull().defaultNow()
11508
+ }, (table3) => [index("game_deploy_events_game_idx").on(table3.gameId, table3.createdAt)]);
11509
+ gameDeploymentState = pgTable("game_deployment_state", {
11510
+ id: uuid("id").primaryKey().defaultRandom(),
11511
+ gameId: uuid("game_id").notNull().unique().references(() => games.id, { onDelete: "cascade" }),
11512
+ schemaHash: text("schema_hash"),
11513
+ schemaSnapshot: jsonb("schema_snapshot"),
11514
+ schemaFingerprint: text("schema_fingerprint"),
11515
+ secretsManifest: jsonb("secrets_manifest").$type(),
11516
+ integrationsHash: text("integrations_hash"),
11517
+ buildHash: text("build_hash"),
11518
+ compatibilityDate: text("compatibility_date"),
11519
+ baselineSource: text("baseline_source").$type(),
11520
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
11323
11521
  });
11324
11522
  customHostnameStatusEnum = pgEnum("custom_hostname_status", [
11325
11523
  "pending",
@@ -11482,7 +11680,9 @@ __export(exports_tables_index, {
11482
11680
  gameMembers: () => gameMembers,
11483
11681
  gameMemberRoleEnum: () => gameMemberRoleEnum,
11484
11682
  gameDeployments: () => gameDeployments,
11683
+ gameDeploymentState: () => gameDeploymentState,
11485
11684
  gameDeployJobs: () => gameDeployJobs,
11685
+ gameDeployEvents: () => gameDeployEvents,
11486
11686
  gameDashboardUsersRelations: () => gameDashboardUsersRelations,
11487
11687
  gameDashboardUsers: () => gameDashboardUsers,
11488
11688
  gameDashboardUserRoleEnum: () => gameDashboardUserRoleEnum,
@@ -22497,7 +22697,112 @@ var init_zip = __esm(() => {
22497
22697
  import_jszip = __toESM(require_lib3(), 1);
22498
22698
  });
22499
22699
 
22700
+ // ../utils/src/stages.ts
22701
+ function isPreviewStage(stage) {
22702
+ return PREVIEW_STAGE_PATTERN.test(stage);
22703
+ }
22704
+ var PREVIEW_STAGE_PATTERN;
22705
+ var init_stages = __esm(() => {
22706
+ PREVIEW_STAGE_PATTERN = /^pr-\d+$/;
22707
+ });
22708
+
22709
+ // ../api-core/src/utils/deployment.util.ts
22710
+ function deployJobInstant() {
22711
+ return sql`COALESCE(${gameDeployJobs.completedAt}, ${gameDeployJobs.createdAt})`;
22712
+ }
22713
+ async function findLastSuccessfulDeploy(db2, gameId) {
22714
+ const job = await db2.query.gameDeployJobs.findFirst({
22715
+ where: and(eq(gameDeployJobs.gameId, gameId), eq(gameDeployJobs.status, "succeeded")),
22716
+ orderBy: desc(deployJobInstant()),
22717
+ columns: { userId: true, createdAt: true, completedAt: true }
22718
+ });
22719
+ if (!job) {
22720
+ return null;
22721
+ }
22722
+ return { userId: job.userId, at: job.completedAt ?? job.createdAt };
22723
+ }
22724
+ async function findLastSuccessfulDeployWithEmail(db2, gameId) {
22725
+ const lastDeploy = await findLastSuccessfulDeploy(db2, gameId);
22726
+ if (!lastDeploy) {
22727
+ return null;
22728
+ }
22729
+ const deployer = lastDeploy.userId ? await db2.query.users.findFirst({
22730
+ where: eq(users.id, lastDeploy.userId),
22731
+ columns: { email: true }
22732
+ }) : null;
22733
+ return { ...lastDeploy, email: deployer?.email ?? null };
22734
+ }
22735
+ function getGameDeploymentId(gameSlug, sstStage) {
22736
+ if (sstStage === "production") {
22737
+ return gameSlug;
22738
+ }
22739
+ if (sstStage === "dev" || isPreviewStage(sstStage)) {
22740
+ return `${WORKER_NAMING.STAGING_PREFIX}${gameSlug}`;
22741
+ }
22742
+ return `${WORKER_NAMING.LOCAL_PREFIX}${sstStage}-${gameSlug}`;
22743
+ }
22744
+ function getDashboardDeploymentId(gameSlug, sstStage) {
22745
+ return `${getGameDeploymentId(gameSlug, sstStage)}${DASHBOARD_WORKER_SUFFIX}`;
22746
+ }
22747
+ function getGameWorkerApiKeyName(slug) {
22748
+ return `${GAME_WORKER_KEY_PREFIX}${slug}`.substring(0, 32);
22749
+ }
22750
+ function getDashboardWorkerApiKeyName(slug) {
22751
+ return `${DASHBOARD_WORKER_KEY_PREFIX}${slug}`;
22752
+ }
22753
+ function toBindingName(queueKey) {
22754
+ return `${queueKey.replace(/-/g, "_").toUpperCase()}_QUEUE`;
22755
+ }
22756
+ function isSchemaAdopted(state) {
22757
+ if (!state) {
22758
+ return false;
22759
+ }
22760
+ return state.schemaHash !== null || state.schemaFingerprint !== null || state.schemaSnapshot !== null;
22761
+ }
22762
+ function isPushAdopted(state) {
22763
+ return Boolean(state?.schemaHash);
22764
+ }
22765
+ function isMigrateManaged(state) {
22766
+ return Boolean(state?.schemaFingerprint) && !state?.schemaHash;
22767
+ }
22768
+ function generateDeploymentHash(code) {
22769
+ return sha256Hex(code);
22770
+ }
22771
+ function computeDeployPayloadFingerprint(payload) {
22772
+ return sha256Hex(canonicalJson(payload));
22773
+ }
22774
+ function canonicalJson(value) {
22775
+ if (value === null || typeof value !== "object") {
22776
+ return JSON.stringify(value) ?? "null";
22777
+ }
22778
+ if (Array.isArray(value)) {
22779
+ return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
22780
+ }
22781
+ const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== undefined).toSorted(([a], [b]) => compareKeys(a, b)).map(([key, entryValue]) => `${JSON.stringify(key)}:${canonicalJson(entryValue)}`);
22782
+ return `{${entries.join(",")}}`;
22783
+ }
22784
+ function compareKeys(a, b) {
22785
+ if (a < b) {
22786
+ return -1;
22787
+ }
22788
+ if (a > b) {
22789
+ return 1;
22790
+ }
22791
+ return 0;
22792
+ }
22793
+ var GAME_WORKER_KEY_PREFIX = "game-worker-", DASHBOARD_WORKER_KEY_PREFIX = "dash-worker-";
22794
+ var init_deployment_util = __esm(() => {
22795
+ init_drizzle_orm();
22796
+ init_src();
22797
+ init_tables_index();
22798
+ init_stages();
22799
+ });
22800
+
22500
22801
  // ../api-core/src/services/deploy-job.service.ts
22802
+ function isEventDetails(value) {
22803
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22804
+ }
22805
+
22501
22806
  class DeployJobService {
22502
22807
  deps;
22503
22808
  constructor(deps) {
@@ -22510,6 +22815,9 @@ class DeployJobService {
22510
22815
  if (leaseLost) {
22511
22816
  return "lease_lost";
22512
22817
  }
22818
+ if (DEPLOY_REFUSAL_CODES.has(deployErrorCode(error) ?? "")) {
22819
+ return "refused";
22820
+ }
22513
22821
  if (error instanceof DomainError) {
22514
22822
  return "domain_error";
22515
22823
  }
@@ -22589,13 +22897,28 @@ class DeployJobService {
22589
22897
  const bucketName = this.getUploadBucket();
22590
22898
  this.deps.storage.deleteObject(bucketName, codeUploadToken).catch(catchAttrs("deploy_job.temp_cleanup"));
22591
22899
  }
22592
- sanitizeRequestForPersistence(request) {
22593
- const sanitized = { ...request };
22900
+ async sanitizeRequestForPersistence(request) {
22901
+ const sanitized = {
22902
+ ...request
22903
+ };
22594
22904
  delete sanitized._headers;
22595
22905
  delete sanitized.code;
22596
22906
  delete sanitized.codeUploadToken;
22907
+ const codeFingerprint = await this.computeCodeFingerprint(request);
22908
+ if (codeFingerprint) {
22909
+ sanitized.codeFingerprint = codeFingerprint;
22910
+ }
22597
22911
  return sanitized;
22598
22912
  }
22913
+ async computeCodeFingerprint(request) {
22914
+ if (request.codeUploadToken) {
22915
+ return `upload:${request.codeUploadToken}`;
22916
+ }
22917
+ if (request.code) {
22918
+ return `sha256:${await generateDeploymentHash(request.code)}`;
22919
+ }
22920
+ return;
22921
+ }
22599
22922
  getLeaseExpiry() {
22600
22923
  return new Date(Date.now() + DEPLOY_JOB_LEASE_MS);
22601
22924
  }
@@ -22628,8 +22951,36 @@ class DeployJobService {
22628
22951
  heartbeatAt: null
22629
22952
  }).where(and(eq(gameDeployJobs.id, jobId), eq(gameDeployJobs.leaseId, leaseId)));
22630
22953
  }
22954
+ async findByDeployId(gameId, deployId) {
22955
+ const job = await this.deps.db.query.gameDeployJobs.findFirst({
22956
+ where: and(eq(gameDeployJobs.gameId, gameId), eq(gameDeployJobs.deployId, deployId))
22957
+ });
22958
+ return job ?? null;
22959
+ }
22960
+ async resolveIdempotentReplay(existing, request) {
22961
+ const [incoming, stored] = await Promise.all([
22962
+ this.sanitizeRequestForPersistence(request).then(computeDeployPayloadFingerprint),
22963
+ computeDeployPayloadFingerprint(existing.request)
22964
+ ]);
22965
+ if (incoming !== stored) {
22966
+ setAttribute("app.deploy_job.idempotency", "payload_mismatch");
22967
+ throw new DeployIdConflictError(request.deployId, existing.id);
22968
+ }
22969
+ setAttributes({
22970
+ "app.deploy_job.idempotency": "replayed",
22971
+ "app.deploy_job.id": existing.id,
22972
+ "app.deploy_job.status": existing.status
22973
+ });
22974
+ return this.toResponse(existing);
22975
+ }
22631
22976
  async create(slug, request, user) {
22632
22977
  const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
22978
+ if (request.deployId) {
22979
+ const existing = await this.findByDeployId(game2.id, request.deployId);
22980
+ if (existing) {
22981
+ return this.resolveIdempotentReplay(existing, request);
22982
+ }
22983
+ }
22633
22984
  const jobId = crypto.randomUUID();
22634
22985
  let codeSource = "none";
22635
22986
  if (request.code) {
@@ -22645,7 +22996,7 @@ class DeployJobService {
22645
22996
  request.code = await this.loadUploadedCode(request.codeUploadToken, game2.id);
22646
22997
  }
22647
22998
  setAttribute("app.deploy_job.code_bundle_size", request.code?.length ?? 0);
22648
- const sanitizedRequest = this.sanitizeRequestForPersistence(request);
22999
+ const sanitizedRequest = await this.sanitizeRequestForPersistence(request);
22649
23000
  if (request.code) {
22650
23001
  await this.storeCodeBundle(jobId, request.code);
22651
23002
  }
@@ -22655,6 +23006,7 @@ class DeployJobService {
22655
23006
  id: jobId,
22656
23007
  gameId: game2.id,
22657
23008
  userId: user.id,
23009
+ deployId: request.deployId ?? null,
22658
23010
  request: sanitizedRequest,
22659
23011
  events: [
22660
23012
  {
@@ -22666,6 +23018,12 @@ class DeployJobService {
22666
23018
  }).returning();
22667
23019
  } catch (error) {
22668
23020
  await this.deleteCodeBundle(jobId);
23021
+ if (request.deployId) {
23022
+ const winner = await this.findByDeployId(game2.id, request.deployId);
23023
+ if (winner) {
23024
+ return this.resolveIdempotentReplay(winner, request);
23025
+ }
23026
+ }
22669
23027
  throw error;
22670
23028
  }
22671
23029
  if (!job) {
@@ -22780,7 +23138,11 @@ class DeployJobService {
22780
23138
  "app.deploy_job.error_status": errorClassification?.errorStatus
22781
23139
  });
22782
23140
  if (!effectiveLeaseLost) {
22783
- await this.addStatusEvent(jobId, "Deployment failed", { error: message });
23141
+ const structuredDetails = error instanceof DomainError && isEventDetails(error.details) ? error.details : undefined;
23142
+ await this.addStatusEvent(jobId, "Deployment failed", {
23143
+ error: message,
23144
+ ...structuredDetails
23145
+ });
22784
23146
  const failed = await this.markFailed(jobId, leaseId, message, errorClassification);
22785
23147
  if (!failed) {
22786
23148
  await this.clearLease(jobId, leaseId);
@@ -22793,18 +23155,21 @@ class DeployJobService {
22793
23155
  displayName: game2.displayName,
22794
23156
  error: message,
22795
23157
  target,
22796
- developer: { id: user.id, email: user.email }
23158
+ developer: { id: user.id, email: user.email },
23159
+ errorCode: deployErrorCode(error)
22797
23160
  });
22798
23161
  }
22799
23162
  await this.deleteCodeBundle(jobId);
22800
23163
  }
22801
23164
  async loadJobActors(job, jobId, leaseId, onMissing) {
22802
- const game2 = await this.deps.db.query.games.findFirst({
22803
- where: eq(games.id, job.gameId)
22804
- });
22805
- const user = await this.deps.db.query.users.findFirst({
22806
- where: eq(users.id, job.userId)
22807
- });
23165
+ const [game2, user] = await Promise.all([
23166
+ this.deps.db.query.games.findFirst({
23167
+ where: eq(games.id, job.gameId)
23168
+ }),
23169
+ job.userId ? this.deps.db.query.users.findFirst({
23170
+ where: eq(users.id, job.userId)
23171
+ }) : undefined
23172
+ ]);
22808
23173
  if (!game2 || !user) {
22809
23174
  const message = !game2 ? "Deploy job game no longer exists" : "Deploy job user no longer exists";
22810
23175
  onMissing();
@@ -22890,7 +23255,8 @@ class DeployJobService {
22890
23255
  for await (const step of this.deps.runDeploy(game2.slug, request, user, uploadDeps, extractZipToDirectory)) {
22891
23256
  assertLease();
22892
23257
  if (step.type === "status" && "message" in step.data && typeof step.data.message === "string") {
22893
- await this.addStatusEvent(jobId, step.data.message);
23258
+ const details = "details" in step.data && isEventDetails(step.data.details) ? step.data.details : undefined;
23259
+ await this.addStatusEvent(jobId, step.data.message, details);
22894
23260
  }
22895
23261
  }
22896
23262
  assertLease();
@@ -22948,8 +23314,10 @@ var init_deploy_job_service = __esm(() => {
22948
23314
  init_helpers_index();
22949
23315
  init_tables_index();
22950
23316
  init_spans();
23317
+ init_game2();
22951
23318
  init_zip();
22952
23319
  init_errors();
23320
+ init_deployment_util();
22953
23321
  STATUS_MAP2 = {
22954
23322
  BAD_REQUEST: 400,
22955
23323
  UNAUTHORIZED: 401,
@@ -22971,8 +23339,153 @@ var init_deploy_job_service = __esm(() => {
22971
23339
  DEPLOY_JOB_LEASE_MS = 2 * 60 * 1000;
22972
23340
  DEPLOY_JOB_HEARTBEAT_MS = 30 * 1000;
22973
23341
  });
23342
+ // ../cloudflare/src/utils/schema.ts
23343
+ function normalizeSqlForChecksum(sql4) {
23344
+ const unified = sql4.replace(/\r\n/g, `
23345
+ `).replace(/\r/g, `
23346
+ `);
23347
+ const stripped = stripSqlComments(unified);
23348
+ return stripped.split(`
23349
+ `).map((line3) => line3.replace(/\s+$/, "")).filter((line3) => line3 !== "").join(`
23350
+ `);
23351
+ }
23352
+ function stripSqlComments(sql4) {
23353
+ let output = "";
23354
+ let i2 = 0;
23355
+ while (i2 < sql4.length) {
23356
+ const char3 = sql4[i2];
23357
+ const next = sql4[i2 + 1];
23358
+ if (char3 === "-" && next === "-") {
23359
+ i2 = skipLineComment(sql4, i2);
23360
+ } else if (char3 === "/" && next === "*") {
23361
+ output += " ";
23362
+ i2 = skipBlockComment(sql4, i2);
23363
+ } else if (char3 === "'" || char3 === '"' || char3 === "`") {
23364
+ const quoted = copyQuoted(sql4, i2, char3);
23365
+ output += quoted.text;
23366
+ i2 = quoted.end;
23367
+ } else if (char3 === "[") {
23368
+ const bracketed = copyBracketed(sql4, i2);
23369
+ output += bracketed.text;
23370
+ i2 = bracketed.end;
23371
+ } else {
23372
+ output += char3;
23373
+ i2++;
23374
+ }
23375
+ }
23376
+ return output;
23377
+ }
23378
+ function skipLineComment(sql4, start2) {
23379
+ let i2 = start2 + 2;
23380
+ while (i2 < sql4.length && sql4[i2] !== `
23381
+ `) {
23382
+ i2++;
23383
+ }
23384
+ return i2;
23385
+ }
23386
+ function skipBlockComment(sql4, start2) {
23387
+ let i2 = start2 + 2;
23388
+ while (i2 < sql4.length && !(sql4[i2] === "*" && sql4[i2 + 1] === "/")) {
23389
+ i2++;
23390
+ }
23391
+ return i2 + 2;
23392
+ }
23393
+ function copyQuoted(sql4, start2, quote) {
23394
+ let text3 = quote;
23395
+ let i2 = start2 + 1;
23396
+ while (i2 < sql4.length) {
23397
+ text3 += sql4[i2];
23398
+ if (sql4[i2] !== quote) {
23399
+ i2++;
23400
+ } else if (sql4[i2 + 1] === quote) {
23401
+ text3 += quote;
23402
+ i2 += 2;
23403
+ } else {
23404
+ i2++;
23405
+ break;
23406
+ }
23407
+ }
23408
+ return { text: text3, end: i2 };
23409
+ }
23410
+ function copyBracketed(sql4, start2) {
23411
+ let text3 = "[";
23412
+ let i2 = start2 + 1;
23413
+ while (i2 < sql4.length) {
23414
+ text3 += sql4[i2];
23415
+ i2++;
23416
+ if (sql4[i2 - 1] === "]") {
23417
+ break;
23418
+ }
23419
+ }
23420
+ return { text: text3, end: i2 };
23421
+ }
23422
+ function findOversizedStatement(statements) {
23423
+ for (const [index2, statement] of statements.entries()) {
23424
+ const byteLength = Buffer.byteLength(statement, "utf8");
23425
+ if (byteLength > D1_MAX_STATEMENT_BYTES) {
23426
+ return { index: index2, byteLength };
23427
+ }
23428
+ }
23429
+ return null;
23430
+ }
23431
+ var MIGRATION_LEDGER_TABLE = "_playcademy_migrations", MIGRATION_CHECKSUM_ALGO = "sha256-v1", D1_MAX_STATEMENT_BYTES;
23432
+ var init_schema3 = __esm(() => {
23433
+ D1_MAX_STATEMENT_BYTES = 100 * 1024;
23434
+ });
23435
+
22974
23436
  // ../cloudflare/src/core/namespaces/d1.ts
22975
- var init_d1 = () => {};
23437
+ function parseD1ErrorOffset(message) {
23438
+ const match = message.match(/at offset (\d+)/);
23439
+ return match ? Number(match[1]) : null;
23440
+ }
23441
+ var MIGRATION_LEDGER_DDL, D1StatementTooLargeError, D1BatchError, D1MigrationError;
23442
+ var init_d1 = __esm(() => {
23443
+ init_schema3();
23444
+ MIGRATION_LEDGER_DDL = `CREATE TABLE IF NOT EXISTS ${MIGRATION_LEDGER_TABLE} (
23445
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
23446
+ tag TEXT NOT NULL UNIQUE,
23447
+ checksum TEXT NOT NULL,
23448
+ checksum_algo TEXT NOT NULL DEFAULT 'sha256-v1',
23449
+ deploy_id TEXT NOT NULL,
23450
+ applied_by TEXT,
23451
+ applied_at TEXT NOT NULL,
23452
+ source TEXT NOT NULL DEFAULT 'deploy',
23453
+ statements_total INTEGER
23454
+ )`;
23455
+ D1StatementTooLargeError = class D1StatementTooLargeError extends Error {
23456
+ name = "D1StatementTooLargeError";
23457
+ statementIndex;
23458
+ byteLength;
23459
+ constructor(tag, statementIndex, byteLength) {
23460
+ super(`Migration '${tag}' statement ${statementIndex} is ${byteLength} bytes — ` + `over D1's ${D1_MAX_STATEMENT_BYTES / 1024} KB per-statement limit. ` + "Split the statement or reduce its size.");
23461
+ this.statementIndex = statementIndex;
23462
+ this.byteLength = byteLength;
23463
+ }
23464
+ };
23465
+ D1BatchError = class D1BatchError extends Error {
23466
+ name = "D1BatchError";
23467
+ d1Message;
23468
+ offset;
23469
+ constructor(d1Message, cause) {
23470
+ super(`Failed to execute batch: ${d1Message}`, { cause });
23471
+ this.d1Message = d1Message;
23472
+ this.offset = parseD1ErrorOffset(d1Message);
23473
+ }
23474
+ };
23475
+ D1MigrationError = class D1MigrationError extends Error {
23476
+ name = "D1MigrationError";
23477
+ tag;
23478
+ d1Message;
23479
+ offset;
23480
+ constructor(tag, d1Message, cause) {
23481
+ super(`Migration '${tag}' failed and rolled back: ${d1Message}`, { cause });
23482
+ this.tag = tag;
23483
+ this.d1Message = d1Message;
23484
+ this.offset = parseD1ErrorOffset(d1Message);
23485
+ }
23486
+ };
23487
+ });
23488
+
22976
23489
  // ../cloudflare/src/core/namespaces/kv.ts
22977
23490
  var init_kv = () => {};
22978
23491
 
@@ -22989,6 +23502,160 @@ var init_assets = __esm(() => {
22989
23502
  init_mime();
22990
23503
  });
22991
23504
 
23505
+ // ../cloudflare/src/utils/journal.ts
23506
+ function findOutOfOrderTags(orderedTags, applied) {
23507
+ let lastAppliedIndex = -1;
23508
+ orderedTags.forEach((tag, index2) => {
23509
+ if (applied.has(tag)) {
23510
+ lastAppliedIndex = index2;
23511
+ }
23512
+ });
23513
+ return orderedTags.filter((tag, index2) => index2 < lastAppliedIndex && !applied.has(tag));
23514
+ }
23515
+
23516
+ // ../cloudflare/src/utils/sql.ts
23517
+ function detectDestructiveStatements(statements) {
23518
+ return statements.filter((statement) => {
23519
+ const scannable = blankStringLiterals(normalizeSqlForChecksum(statement));
23520
+ return DESTRUCTIVE_SQL_PATTERNS.some((pattern) => pattern.test(scannable));
23521
+ });
23522
+ }
23523
+ function splitSqlStatements(sql4) {
23524
+ const statements = [];
23525
+ let current = "";
23526
+ let i2 = 0;
23527
+ while (i2 < sql4.length) {
23528
+ const char3 = sql4[i2];
23529
+ const next = sql4[i2 + 1];
23530
+ if (char3 === ";") {
23531
+ statements.push(current);
23532
+ current = "";
23533
+ i2++;
23534
+ } else if (char3 === "-" && next === "-") {
23535
+ const end = scanLineCommentEnd(sql4, i2);
23536
+ current += sql4.slice(i2, end);
23537
+ i2 = end;
23538
+ } else if (char3 === "/" && next === "*") {
23539
+ const end = scanBlockCommentEnd(sql4, i2);
23540
+ current += sql4.slice(i2, end);
23541
+ i2 = end;
23542
+ } else if (char3 === "'" || char3 === '"' || char3 === "`") {
23543
+ const end = scanQuoteEnd(sql4, i2, char3);
23544
+ current += sql4.slice(i2, end);
23545
+ i2 = end;
23546
+ } else if (char3 === "[") {
23547
+ const end = scanBracketEnd(sql4, i2);
23548
+ current += sql4.slice(i2, end);
23549
+ i2 = end;
23550
+ } else {
23551
+ current += char3;
23552
+ i2++;
23553
+ }
23554
+ }
23555
+ statements.push(current);
23556
+ return statements.map((statement) => statement.trim()).filter((statement) => normalizeSqlForChecksum(statement).trim() !== "");
23557
+ }
23558
+ function blankStringLiterals(sql4) {
23559
+ let output = "";
23560
+ let i2 = 0;
23561
+ while (i2 < sql4.length) {
23562
+ const char3 = sql4[i2];
23563
+ if (char3 === "'") {
23564
+ output += "''";
23565
+ i2 = scanQuoteEnd(sql4, i2, char3);
23566
+ } else if (char3 === '"' || char3 === "`") {
23567
+ const end = scanQuoteEnd(sql4, i2, char3);
23568
+ output += sql4.slice(i2, end);
23569
+ i2 = end;
23570
+ } else if (char3 === "[") {
23571
+ const end = scanBracketEnd(sql4, i2);
23572
+ output += sql4.slice(i2, end);
23573
+ i2 = end;
23574
+ } else {
23575
+ output += char3;
23576
+ i2++;
23577
+ }
23578
+ }
23579
+ return output;
23580
+ }
23581
+ function scanLineCommentEnd(sql4, start2) {
23582
+ let i2 = start2 + 2;
23583
+ while (i2 < sql4.length && sql4[i2] !== `
23584
+ `) {
23585
+ i2++;
23586
+ }
23587
+ return i2;
23588
+ }
23589
+ function scanBlockCommentEnd(sql4, start2) {
23590
+ let i2 = start2 + 2;
23591
+ while (i2 < sql4.length && !(sql4[i2] === "*" && sql4[i2 + 1] === "/")) {
23592
+ i2++;
23593
+ }
23594
+ return Math.min(i2 + 2, sql4.length);
23595
+ }
23596
+ function scanQuoteEnd(sql4, start2, quote) {
23597
+ let i2 = start2 + 1;
23598
+ while (i2 < sql4.length) {
23599
+ if (sql4[i2] !== quote) {
23600
+ i2++;
23601
+ } else if (sql4[i2 + 1] === quote) {
23602
+ i2 += 2;
23603
+ } else {
23604
+ return i2 + 1;
23605
+ }
23606
+ }
23607
+ return i2;
23608
+ }
23609
+ function scanBracketEnd(sql4, start2) {
23610
+ let i2 = start2 + 1;
23611
+ while (i2 < sql4.length) {
23612
+ if (sql4[i2] === "]") {
23613
+ return i2 + 1;
23614
+ }
23615
+ i2++;
23616
+ }
23617
+ return i2;
23618
+ }
23619
+ function isAlreadyExistsSqlError(message) {
23620
+ return /already exists|duplicate column/i.test(message);
23621
+ }
23622
+ function readIdentifier(groups) {
23623
+ return groups.find((group) => group !== undefined) ?? "";
23624
+ }
23625
+ function extractCreatedObjects(statements) {
23626
+ const tables = [];
23627
+ const columns2 = [];
23628
+ for (const statement of statements) {
23629
+ const scannable = blankStringLiterals(normalizeSqlForChecksum(statement));
23630
+ for (const match of scannable.matchAll(CREATE_TABLE_RE)) {
23631
+ const name2 = readIdentifier(match.slice(1, 5));
23632
+ if (name2 && !name2.startsWith("__new_")) {
23633
+ tables.push(name2);
23634
+ }
23635
+ }
23636
+ for (const match of scannable.matchAll(ADD_COLUMN_RE)) {
23637
+ const table8 = readIdentifier(match.slice(1, 5));
23638
+ const column2 = readIdentifier(match.slice(5, 9));
23639
+ if (table8 && column2 && !table8.startsWith("__new_")) {
23640
+ columns2.push({ table: table8, column: column2 });
23641
+ }
23642
+ }
23643
+ }
23644
+ return { tables, columns: columns2 };
23645
+ }
23646
+ var DESTRUCTIVE_SQL_PATTERNS, IDENTIFIER_SOURCE, CREATE_TABLE_RE, ADD_COLUMN_RE;
23647
+ var init_sql3 = __esm(() => {
23648
+ init_schema3();
23649
+ DESTRUCTIVE_SQL_PATTERNS = [
23650
+ /\bDROP\s+TABLE\b/i,
23651
+ /\bALTER\s+TABLE\b[\s\S]*\bDROP\b/i,
23652
+ /\bCREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["'`[]?__new_/i
23653
+ ];
23654
+ IDENTIFIER_SOURCE = String.raw`(?:"([^"]+)"|\`([^\`]+)\`|\[([^\]]+)\]|([A-Za-z_][\w$]*))`;
23655
+ CREATE_TABLE_RE = new RegExp(String.raw`\bCREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?${IDENTIFIER_SOURCE}`, "gi");
23656
+ ADD_COLUMN_RE = new RegExp(String.raw`\bALTER\s+TABLE\s+${IDENTIFIER_SOURCE}\s+ADD\s+(?:COLUMN\s+)?${IDENTIFIER_SOURCE}`, "gi");
23657
+ });
23658
+
22992
23659
  // ../../node_modules/.bun/@fastify+busboy@3.2.0/node_modules/@fastify/busboy/deps/streamsearch/sbmh.js
22993
23660
  var require_sbmh = __commonJS((exports, module2) => {
22994
23661
  var { EventEmitter } = __require("node:events");
@@ -24918,6 +25585,8 @@ var init_multipart = __esm(() => {
24918
25585
  var init_utils5 = __esm(() => {
24919
25586
  init_hostname();
24920
25587
  init_assets();
25588
+ init_schema3();
25589
+ init_sql3();
24921
25590
  init_multipart();
24922
25591
  });
24923
25592
 
@@ -25072,6 +25741,14 @@ var init_core = __esm(() => {
25072
25741
  init_client();
25073
25742
  });
25074
25743
 
25744
+ // ../cloudflare/src/index.ts
25745
+ var init_src4 = __esm(() => {
25746
+ init_core();
25747
+ init_namespaces();
25748
+ init_utils5();
25749
+ init_utils5();
25750
+ });
25751
+
25075
25752
  // ../cloudflare/src/playcademy/constants.ts
25076
25753
  var CUSTOM_DOMAINS_KV_NAME = "cademy-custom-domains", QUEUE_NAME_PREFIX = "playcademy", GAME_WORKER_DOMAIN_PRODUCTION, GAME_WORKER_DOMAIN_STAGING;
25077
25754
  var init_constants2 = __esm(() => {
@@ -27520,68 +28197,390 @@ var init_playcademy = __esm(() => {
27520
28197
  });
27521
28198
 
27522
28199
  // ../utils/src/tunnel.ts
27523
- async function getTunnelUrl() {
27524
- let response;
28200
+ function servicePort(service) {
28201
+ if (!service) {
28202
+ return null;
28203
+ }
27525
28204
  try {
27526
- response = await fetch(`${METRICS_BASE}/config`);
28205
+ const url = new URL(service);
28206
+ return url.port || (url.protocol === "https:" ? "443" : "80");
27527
28207
  } catch {
27528
- throw new Error("Local tunnel is not running. Start it with `bun dev` or `bun scripts/infra/tunnel.ts`.");
28208
+ return null;
27529
28209
  }
27530
- if (!response.ok) {
27531
- throw new Error(`Tunnel metrics endpoint returned ${response.status}`);
28210
+ }
28211
+ async function readTunnelIngress(port) {
28212
+ try {
28213
+ const response = await fetch(`http://127.0.0.1:${port}/config`, {
28214
+ signal: AbortSignal.timeout(1000)
28215
+ });
28216
+ if (!response.ok) {
28217
+ return null;
28218
+ }
28219
+ const data = await response.json();
28220
+ return data.config?.ingress ?? [];
28221
+ } catch {
28222
+ return null;
28223
+ }
28224
+ }
28225
+ function matchingHostname(rules, expectedPort) {
28226
+ for (const rule of rules ?? []) {
28227
+ if (rule.hostname && servicePort(rule.service) === expectedPort) {
28228
+ return rule.hostname;
28229
+ }
28230
+ }
28231
+ return null;
28232
+ }
28233
+ async function getTunnelUrl(platformBaseUrl) {
28234
+ const expectedPort = servicePort(platformBaseUrl);
28235
+ if (!expectedPort) {
28236
+ throw new Error(`Cannot resolve a tunnel for unparseable platform URL '${platformBaseUrl}'`);
28237
+ }
28238
+ const cachedPort = matchedPorts.get(expectedPort);
28239
+ if (cachedPort !== undefined) {
28240
+ const hostname = matchingHostname(await readTunnelIngress(cachedPort), expectedPort);
28241
+ if (hostname) {
28242
+ return `https://${hostname}`;
28243
+ }
28244
+ matchedPorts.delete(expectedPort);
28245
+ }
28246
+ const ports = Array.from({ length: TUNNEL_METRICS_PORT_RANGE }, (_, offset) => TUNNEL_METRICS_PORT + offset);
28247
+ const results = await Promise.all(ports.map(async (port) => ({ port, rules: await readTunnelIngress(port) })));
28248
+ for (const { port, rules } of results) {
28249
+ const hostname = matchingHostname(rules, expectedPort);
28250
+ if (hostname) {
28251
+ matchedPorts.set(expectedPort, port);
28252
+ return `https://${hostname}`;
28253
+ }
27532
28254
  }
27533
- const data = await response.json();
27534
- const hostname = data.config.ingress.find((r) => r.hostname)?.hostname;
27535
- if (!hostname) {
27536
- throw new Error("Tunnel is running but no hostname found in ingress config");
28255
+ const foreign = results.flatMap(({ rules }) => (rules ?? []).filter((rule) => rule.hostname).map((rule) => `${rule.hostname} -> ${rule.service}`));
28256
+ if (foreign.length > 0) {
28257
+ throw new Error(`A local tunnel is running, but none route to the platform at ${platformBaseUrl} (found: ${foreign.join(", ")}). ${TUNNEL_START_HINT}`);
27537
28258
  }
27538
- return `https://${hostname}`;
28259
+ throw new Error(`Local tunnel is not running. ${TUNNEL_START_HINT}`);
27539
28260
  }
27540
- var TUNNEL_METRICS_PORT = 20241, METRICS_BASE;
28261
+ var TUNNEL_METRICS_PORT = 20241, TUNNEL_METRICS_PORT_RANGE = 10, TUNNEL_START_HINT = "Start this platform's tunnel with `bun dev` or `bun run tunnel`.", matchedPorts;
27541
28262
  var init_tunnel = __esm(() => {
27542
- METRICS_BASE = `http://127.0.0.1:${TUNNEL_METRICS_PORT}`;
27543
- });
27544
-
27545
- // ../utils/src/stages.ts
27546
- function isPreviewStage(stage) {
27547
- return PREVIEW_STAGE_PATTERN.test(stage);
28263
+ matchedPorts = new Map;
28264
+ });
28265
+
28266
+ // ../api-core/src/utils/baseline-validation.util.ts
28267
+ function assertBaselineClaimValid(args2) {
28268
+ const validation = validateBaselineClaim(args2);
28269
+ const blocked = validation.contradictions.length > 0 || validation.unverified.length > 0 && !args2.allowUnverified;
28270
+ if (blocked) {
28271
+ addEvent("deployment_state.baseline_claim_rejected", {
28272
+ "app.game.id": args2.gameId,
28273
+ "app.deployment_state.baseline_claim_source": args2.source,
28274
+ "app.deployment_state.baseline_contradictions": validation.contradictions.length,
28275
+ "app.deployment_state.baseline_unverified": validation.unverified.length,
28276
+ "app.deployment_state.baseline_suggested_tag": validation.suggestedTag ?? "none"
28277
+ });
28278
+ throw new BaselineClaimRejectedError({
28279
+ contradictions: validation.contradictions,
28280
+ unverified: validation.unverified,
28281
+ suggestedTag: validation.suggestedTag,
28282
+ claimedTag: args2.claimedTag
28283
+ });
28284
+ }
28285
+ if (validation.unverified.length > 0) {
28286
+ addEvent("deployment_state.baseline_unverified_overridden", {
28287
+ "app.game.id": args2.gameId,
28288
+ "app.user.id": args2.userId,
28289
+ "app.deployment_state.baseline_overridden_tags": validation.unverified.map((entry) => entry.tag).join(",")
28290
+ });
28291
+ }
28292
+ }
28293
+ function validateBaselineClaim(args2) {
28294
+ const { claimedTag, evidence, tables, indexes: indexes2, views, lastDeployAt } = args2;
28295
+ const claimedIndex = evidence.findIndex((entry) => entry.tag === claimedTag);
28296
+ const verdicts = [];
28297
+ const unverified = [];
28298
+ evidence.forEach((entry, index2) => {
28299
+ if (claimedIndex === -1 || index2 > claimedIndex) {
28300
+ verdicts.push(judgeBeyond(entry, tables, indexes2, views));
28301
+ return;
28302
+ }
28303
+ const judged = judgeClaimed(entry, tables, lastDeployAt);
28304
+ verdicts.push(judged.verdict);
28305
+ if (judged.unverifiable) {
28306
+ unverified.push(judged.verdict);
28307
+ }
28308
+ });
28309
+ return {
28310
+ verdicts,
28311
+ contradictions: verdicts.filter((verdict) => verdict.verdict === "contradicted"),
28312
+ unverified,
28313
+ suggestedTag: suggestTag(evidence, tables)
28314
+ };
27548
28315
  }
27549
- var PREVIEW_STAGE_PATTERN;
27550
- var init_stages = __esm(() => {
27551
- PREVIEW_STAGE_PATTERN = /^pr-\d+$/;
28316
+ function judgeClaimed(entry, tables, lastDeployAt) {
28317
+ if (!hasSignal(entry)) {
28318
+ const generated = new Date(entry.generatedAt);
28319
+ if (lastDeployAt && generated > lastDeployAt) {
28320
+ return {
28321
+ verdict: {
28322
+ tag: entry.tag,
28323
+ verdict: "no-signal",
28324
+ detail: `no schema footprint to verify, and it was generated after the last deploy (${lastDeployAt.toISOString()})`
28325
+ },
28326
+ unverifiable: true
28327
+ };
28328
+ }
28329
+ return { verdict: { tag: entry.tag, verdict: "no-signal" }, unverifiable: false };
28330
+ }
28331
+ for (const table8 of entry.createsTables) {
28332
+ const columns2 = tables.get(table8.name);
28333
+ if (!columns2) {
28334
+ return {
28335
+ verdict: {
28336
+ tag: entry.tag,
28337
+ verdict: "contradicted",
28338
+ detail: `creates table \`${table8.name}\`, which is not in the live database`
28339
+ },
28340
+ unverifiable: false
28341
+ };
28342
+ }
28343
+ const missing = table8.columns.filter((column2) => !columns2.includes(column2));
28344
+ if (missing.length > 0) {
28345
+ return {
28346
+ verdict: {
28347
+ tag: entry.tag,
28348
+ verdict: "contradicted",
28349
+ detail: `table \`${table8.name}\` exists but is missing column(s) ${missing.map((column2) => `\`${column2}\``).join(", ")} this migration defines`
28350
+ },
28351
+ unverifiable: false
28352
+ };
28353
+ }
28354
+ }
28355
+ for (const added of entry.addsColumns) {
28356
+ const columns2 = tables.get(added.table);
28357
+ if (columns2 && !columns2.includes(added.column)) {
28358
+ return {
28359
+ verdict: {
28360
+ tag: entry.tag,
28361
+ verdict: "contradicted",
28362
+ detail: `adds column \`${added.column}\` to \`${added.table}\`, which the live table does not have`
28363
+ },
28364
+ unverifiable: false
28365
+ };
28366
+ }
28367
+ }
28368
+ return { verdict: { tag: entry.tag, verdict: "verified" }, unverifiable: false };
28369
+ }
28370
+ function judgeBeyond(entry, tables, indexes2, views) {
28371
+ for (const table8 of entry.createsTables) {
28372
+ if (tables.has(table8.name)) {
28373
+ return {
28374
+ tag: entry.tag,
28375
+ verdict: "contradicted",
28376
+ detail: `is beyond the claim, but the table it creates (\`${table8.name}\`) already exists in the live database — the claim looks too old`
28377
+ };
28378
+ }
28379
+ }
28380
+ for (const added of entry.addsColumns) {
28381
+ const columns2 = tables.get(added.table);
28382
+ if (columns2?.includes(added.column)) {
28383
+ return {
28384
+ tag: entry.tag,
28385
+ verdict: "contradicted",
28386
+ detail: `is beyond the claim, but the column it adds (\`${added.table}.${added.column}\`) already exists — the claim looks too old`
28387
+ };
28388
+ }
28389
+ }
28390
+ for (const index2 of entry.createsIndexes) {
28391
+ if (indexes2.has(index2)) {
28392
+ return {
28393
+ tag: entry.tag,
28394
+ verdict: "contradicted",
28395
+ detail: `is beyond the claim, but the index it creates (\`${index2}\`) already exists — the claim looks too old`
28396
+ };
28397
+ }
28398
+ }
28399
+ for (const view2 of entry.createsViews) {
28400
+ if (views.has(view2)) {
28401
+ return {
28402
+ tag: entry.tag,
28403
+ verdict: "contradicted",
28404
+ detail: `is beyond the claim, but the view it creates (\`${view2}\`) already exists — the claim looks too old`
28405
+ };
28406
+ }
28407
+ }
28408
+ return { tag: entry.tag, verdict: "verified" };
28409
+ }
28410
+ function suggestTag(evidence, tables) {
28411
+ let presentPrefix = 0;
28412
+ while (presentPrefix < evidence.length && evidence[presentPrefix].createsTables.every((table8) => tables.has(table8.name))) {
28413
+ presentPrefix++;
28414
+ }
28415
+ let absentFrom = evidence.length;
28416
+ while (absentFrom > 0 && evidence[absentFrom - 1].createsTables.every((table8) => !tables.has(table8.name))) {
28417
+ absentFrom--;
28418
+ }
28419
+ const candidate = presentPrefix - 1;
28420
+ return candidate >= 0 && candidate >= absentFrom - 1 ? evidence[candidate].tag : null;
28421
+ }
28422
+ function hasSignal(entry) {
28423
+ return entry.createsTables.length > 0 || entry.addsColumns.length > 0 || entry.createsIndexes.length > 0 || entry.createsViews.length > 0;
28424
+ }
28425
+ var init_baseline_validation_util = __esm(() => {
28426
+ init_spans();
28427
+ init_errors();
27552
28428
  });
27553
28429
 
27554
- // ../api-core/src/utils/deployment.util.ts
27555
- function getGameDeploymentId(gameSlug, sstStage) {
27556
- if (sstStage === "production") {
27557
- return gameSlug;
28430
+ // ../api-core/src/utils/baseline.util.ts
28431
+ function sliceJournalToTag(journal, lastAppliedMigrationTag) {
28432
+ const index2 = journal.findIndex((entry) => entry.tag === lastAppliedMigrationTag);
28433
+ return index2 === -1 ? null : journal.slice(0, index2 + 1);
28434
+ }
28435
+ function evaluateBaselineGuardrails(input) {
28436
+ if (input.ledgerTags.length > 0) {
28437
+ return "ledger-not-empty";
27558
28438
  }
27559
- if (sstStage === "dev" || isPreviewStage(sstStage)) {
27560
- return `${WORKER_NAMING.STAGING_PREFIX}${gameSlug}`;
28439
+ if (input.liveTables.length === 0) {
28440
+ return "database-empty";
27561
28441
  }
27562
- return `${WORKER_NAMING.LOCAL_PREFIX}${sstStage}-${gameSlug}`;
28442
+ return "ok";
27563
28443
  }
27564
- function getDashboardDeploymentId(gameSlug, sstStage) {
27565
- return `${getGameDeploymentId(gameSlug, sstStage)}${DASHBOARD_WORKER_SUFFIX}`;
28444
+
28445
+ // ../api-core/src/utils/migration.util.ts
28446
+ function planMigrations(journal, ledger) {
28447
+ const ledgerByTag = new Map(ledger.map((row) => [row.tag, row]));
28448
+ const journalTags = new Set(journal.map((entry) => entry.tag));
28449
+ const pendingTags = [];
28450
+ const checksumMismatches = [];
28451
+ for (const entry of journal) {
28452
+ const applied = ledgerByTag.get(entry.tag);
28453
+ if (!applied) {
28454
+ pendingTags.push(entry.tag);
28455
+ } else {
28456
+ const comparable = applied.checksumAlgo === MIGRATION_CHECKSUM_ALGO;
28457
+ if (comparable && applied.checksum !== entry.checksum) {
28458
+ checksumMismatches.push({
28459
+ tag: entry.tag,
28460
+ ledgerChecksum: applied.checksum,
28461
+ journalChecksum: entry.checksum
28462
+ });
28463
+ }
28464
+ }
28465
+ }
28466
+ const outOfOrderTags = findOutOfOrderTags(journal.map((entry) => entry.tag), new Set(ledgerByTag.keys()));
28467
+ const missingFromJournalTags = ledger.filter((row) => !journalTags.has(row.tag)).map((row) => row.tag);
28468
+ return { pendingTags, checksumMismatches, outOfOrderTags, missingFromJournalTags };
27566
28469
  }
27567
- function getGameWorkerApiKeyName(slug) {
27568
- return `${GAME_WORKER_KEY_PREFIX}${slug}`.substring(0, 32);
28470
+ function assessMigrationAlreadyApplied(statements, liveTables) {
28471
+ const created = extractCreatedObjects(statements);
28472
+ const present = [];
28473
+ const missing = [];
28474
+ for (const table8 of created.tables) {
28475
+ (liveTables.has(table8) ? present : missing).push(`table ${table8}`);
28476
+ }
28477
+ for (const added of created.columns) {
28478
+ const live = Boolean(liveTables.get(added.table)?.includes(added.column));
28479
+ (live ? present : missing).push(`column ${added.table}.${added.column}`);
28480
+ }
28481
+ if (present.length === 0) {
28482
+ return { verdict: "no-signal", present, missing };
28483
+ }
28484
+ return {
28485
+ verdict: missing.length === 0 ? "all-present" : "partial",
28486
+ present,
28487
+ missing
28488
+ };
27569
28489
  }
27570
- function getDashboardWorkerApiKeyName(slug) {
27571
- return `${DASHBOARD_WORKER_KEY_PREFIX}${slug}`;
28490
+ function parseMigrationFailure(events) {
28491
+ if (!events) {
28492
+ return null;
28493
+ }
28494
+ for (let i2 = events.length - 1;i2 >= 0; i2--) {
28495
+ const event = events[i2];
28496
+ const failure = event ? parseFailureEvent(event) : null;
28497
+ if (failure) {
28498
+ return failure;
28499
+ }
28500
+ }
28501
+ return null;
27572
28502
  }
27573
- function toBindingName(queueKey) {
27574
- return `${queueKey.replace(/-/g, "_").toUpperCase()}_QUEUE`;
28503
+ function parseFailureEvent(event) {
28504
+ const details = event.details;
28505
+ if (!details) {
28506
+ return null;
28507
+ }
28508
+ const { code, tag, statementIndex, error, d1Message } = details;
28509
+ if (code !== DEPLOY_ERROR_CODES.migrationFailed || typeof tag !== "string") {
28510
+ return null;
28511
+ }
28512
+ return {
28513
+ tag,
28514
+ error: failureMessage(error, d1Message),
28515
+ statementIndex: typeof statementIndex === "number" ? statementIndex : null,
28516
+ at: event.createdAt
28517
+ };
27575
28518
  }
27576
- function generateDeploymentHash(code) {
27577
- return sha256Hex(code);
28519
+ function failureMessage(error, d1Message) {
28520
+ if (typeof error === "string") {
28521
+ return error;
28522
+ }
28523
+ if (typeof d1Message === "string") {
28524
+ return d1Message;
28525
+ }
28526
+ return "Migration failed";
27578
28527
  }
27579
- var GAME_WORKER_KEY_PREFIX = "game-worker-", DASHBOARD_WORKER_KEY_PREFIX = "dash-worker-";
27580
- var init_deployment_util = __esm(() => {
27581
- init_src();
27582
- init_stages();
28528
+ var init_migration_util = __esm(() => {
28529
+ init_src4();
28530
+ init_errors();
27583
28531
  });
27584
28532
 
28533
+ // ../api-core/src/utils/secrets-manifest.util.ts
28534
+ async function deriveSecretsManifestPepper(platformSecret) {
28535
+ const encoder = new TextEncoder;
28536
+ const keyMaterial = await crypto.subtle.importKey("raw", encoder.encode(platformSecret), "HKDF", false, ["deriveBits"]);
28537
+ const bits = await crypto.subtle.deriveBits({
28538
+ name: "HKDF",
28539
+ hash: "SHA-256",
28540
+ salt: new Uint8Array(32),
28541
+ info: encoder.encode(SECRETS_MANIFEST_HKDF_INFO)
28542
+ }, keyMaterial, 256);
28543
+ return new Uint8Array(bits);
28544
+ }
28545
+ async function computeSecretDigest(pepper, input) {
28546
+ const key = await crypto.subtle.importKey("raw", new Uint8Array(pepper), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
28547
+ const message = JSON.stringify([input.gameId, input.key, input.value]);
28548
+ const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(message));
28549
+ return [...new Uint8Array(signature)].map((b) => b.toString(16).padStart(2, "0")).join("");
28550
+ }
28551
+ function computeSecretsDiff(input) {
28552
+ const { localDigests, manifest, remoteKeys } = input;
28553
+ const added = [];
28554
+ const changed = [];
28555
+ const unchanged = [];
28556
+ for (const [key, digest] of Object.entries(localDigests)) {
28557
+ const recorded = manifest[key];
28558
+ if (recorded === undefined) {
28559
+ added.push(key);
28560
+ } else if (recorded === digest) {
28561
+ unchanged.push(key);
28562
+ } else {
28563
+ changed.push(key);
28564
+ }
28565
+ }
28566
+ const localKeys = new Set(Object.keys(localDigests));
28567
+ const managedKeys = new Set(Object.keys(manifest));
28568
+ const remoteOnlyManaged = [...managedKeys].filter((key) => !localKeys.has(key));
28569
+ const remoteOnlyUnmanaged = remoteKeys.filter((key) => !managedKeys.has(key) && !localKeys.has(key));
28570
+ return {
28571
+ added: added.toSorted(),
28572
+ changed: changed.toSorted(),
28573
+ unchanged: unchanged.toSorted(),
28574
+ remoteOnlyManaged: remoteOnlyManaged.toSorted(),
28575
+ remoteOnlyUnmanaged: remoteOnlyUnmanaged.toSorted()
28576
+ };
28577
+ }
28578
+ function findUnmanagedPruneKeys(pruneSecrets, manifest) {
28579
+ const managed = new Set(Object.keys(manifest ?? {}));
28580
+ return pruneSecrets.filter((key) => !managed.has(key));
28581
+ }
28582
+ var SECRETS_MANIFEST_HKDF_INFO = "playcademy:secrets-manifest:v1";
28583
+
27585
28584
  // ../api-core/src/utils/worker-keys.util.ts
27586
28585
  async function sweepDashboardWorkerKeys(deleteApiKeysByName, slug) {
27587
28586
  try {
@@ -27599,6 +28598,9 @@ var init_worker_keys_util = __esm(() => {
27599
28598
  });
27600
28599
 
27601
28600
  // ../api-core/src/services/deploy.service.ts
28601
+ function hasBinding(binding) {
28602
+ return binding === true || Array.isArray(binding) && binding.length > 0;
28603
+ }
27602
28604
  function readDashboardTheme(config2) {
27603
28605
  const theme = config2?.dashboard?.theme;
27604
28606
  return {
@@ -27666,7 +28668,7 @@ class DeployService {
27666
28668
  data: { message: hasBackend ? "Deploying backend code" : "Deploying to platform" }
27667
28669
  };
27668
28670
  const keepAssets = hasBackend && !hasFrontend;
27669
- const deploymentOptions = this.mapGameBindingsToOptions(deploymentId, request.bindings, request.schema);
28671
+ const deploymentOptions = this.mapGameBindingsToOptions(deploymentId, request.bindings);
27670
28672
  const bindings = deploymentOptions?.bindings;
27671
28673
  setAttributes({
27672
28674
  "app.deploy.has_d1": Boolean(bindings?.d1?.length),
@@ -27675,13 +28677,49 @@ class DeployService {
27675
28677
  "app.deploy.queue_count": bindings?.queues?.length ?? 0,
27676
28678
  "app.deploy.dead_letter_queue_count": DeployService.countDeadLetterQueues(bindings)
27677
28679
  });
27678
- const activeDeployment = await db2.query.gameDeployments.findFirst({
27679
- where: activeDeploymentWhere(game2.id, "game"),
27680
- columns: { resources: true }
27681
- });
27682
- if (deploymentOptions?.bindings?.d1?.length) {
28680
+ const [activeDeployment, deploymentState] = await Promise.all([
28681
+ db2.query.gameDeployments.findFirst({
28682
+ where: activeDeploymentWhere(game2.id, "game"),
28683
+ columns: { resources: true }
28684
+ }),
28685
+ db2.query.gameDeploymentState.findFirst({
28686
+ where: eq(gameDeploymentState.gameId, game2.id)
28687
+ })
28688
+ ]);
28689
+ if (request.pruneSecrets?.length) {
28690
+ const unmanaged = findUnmanagedPruneKeys(request.pruneSecrets, deploymentState?.secretsManifest);
28691
+ if (unmanaged.length > 0) {
28692
+ throw new SecretsPruneUnmanagedError(unmanaged);
28693
+ }
28694
+ }
28695
+ let state = deploymentState;
28696
+ if (request.baseline) {
28697
+ if (isSchemaAdopted(state)) {
28698
+ addEvent("deploy.baseline_skipped", {
28699
+ "app.deploy.baseline_source": state?.baselineSource ?? "unknown"
28700
+ });
28701
+ } else {
28702
+ state = yield* this.adoptClientBaseline({
28703
+ game: game2,
28704
+ request,
28705
+ user,
28706
+ deploymentId,
28707
+ baseline: request.baseline,
28708
+ existingResources: activeDeployment?.resources ?? undefined
28709
+ });
28710
+ }
28711
+ }
28712
+ if (deploymentOptions?.bindings?.d1?.length && !isSchemaAdopted(state)) {
27683
28713
  await this.cleanupOrphanD1Databases(cf, deploymentOptions.bindings.d1, slug, game2.id);
27684
28714
  }
28715
+ const databaseOutcome = yield* this.executeDatabaseStep({
28716
+ game: game2,
28717
+ request,
28718
+ user,
28719
+ deploymentId,
28720
+ state,
28721
+ existingResources: activeDeployment?.resources ?? undefined
28722
+ });
27685
28723
  const result = await this.deployToCloudflare({
27686
28724
  deploymentId,
27687
28725
  code: request.code,
@@ -27689,6 +28727,7 @@ class DeployService {
27689
28727
  tempDir,
27690
28728
  options: {
27691
28729
  ...deploymentOptions,
28730
+ ...databaseOutcome.legacySchema && { schema: databaseOutcome.legacySchema },
27692
28731
  compatibilityDate: request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
27693
28732
  compatibilityFlags: request.compatibilityFlags,
27694
28733
  existingResources: activeDeployment?.resources ?? undefined,
@@ -27704,8 +28743,12 @@ class DeployService {
27704
28743
  result,
27705
28744
  request,
27706
28745
  user,
27707
- flags: flags2
28746
+ flags: flags2,
28747
+ database: databaseOutcome
27708
28748
  });
28749
+ if (request.pruneSecrets?.length) {
28750
+ yield* this.pruneManagedSecretsStep(game2.id, result.deploymentId, request.pruneSecrets);
28751
+ }
27709
28752
  yield { type: "complete", data: updatedGame };
27710
28753
  }
27711
28754
  async* deployDashboard(context2) {
@@ -27832,7 +28875,10 @@ class DeployService {
27832
28875
  "app.deploy.code_size": request.code?.length ?? 0,
27833
28876
  "app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
27834
28877
  "app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0,
27835
- "app.deploy.has_schema": Boolean(request.schema)
28878
+ "app.deploy.has_schema": Boolean(request.schema),
28879
+ "app.deploy.has_database_payload": Boolean(request.database),
28880
+ "app.deploy.has_baseline": Boolean(request.baseline),
28881
+ "app.deploy.prune_secret_count": request.pruneSecrets?.length ?? 0
27836
28882
  });
27837
28883
  if (!hasBackend && !hasFrontend && !hasMetadata) {
27838
28884
  throw new ValidationError("Must provide at least one of: uploadToken (frontend), code (backend), or metadata");
@@ -27869,18 +28915,18 @@ class DeployService {
27869
28915
  }
27870
28916
  return "metadata_only";
27871
28917
  }
27872
- mapGameBindingsToOptions(deploymentId, bindings, schema2) {
27873
- if (!bindings && !schema2) {
28918
+ mapGameBindingsToOptions(deploymentId, bindings) {
28919
+ if (!bindings) {
27874
28920
  return;
27875
28921
  }
27876
28922
  const workerBindings = {};
27877
- if (bindings?.database) {
28923
+ if (hasBinding(bindings.database)) {
27878
28924
  workerBindings.d1 = [deploymentId];
27879
28925
  }
27880
- if (bindings?.keyValue) {
28926
+ if (hasBinding(bindings.keyValue)) {
27881
28927
  workerBindings.kv = [deploymentId];
27882
28928
  }
27883
- if (bindings?.bucket) {
28929
+ if (hasBinding(bindings.bucket)) {
27884
28930
  workerBindings.r2 = [deploymentId];
27885
28931
  }
27886
28932
  if (bindings?.queues) {
@@ -27909,10 +28955,7 @@ class DeployService {
27909
28955
  });
27910
28956
  }
27911
28957
  const hasBindings = workerBindings.d1?.length || workerBindings.kv?.length || workerBindings.r2?.length || workerBindings.queues?.length;
27912
- return {
27913
- ...hasBindings && { bindings: workerBindings },
27914
- ...schema2 && { schema: schema2 }
27915
- };
28958
+ return hasBindings ? { bindings: workerBindings } : undefined;
27916
28959
  }
27917
28960
  static countDeadLetterQueues(bindings) {
27918
28961
  return bindings?.queues?.filter((queue) => Boolean(queue.deadLetterQueue)).length ?? 0;
@@ -27936,6 +28979,473 @@ class DeployService {
27936
28979
  }
27937
28980
  }
27938
28981
  }
28982
+ async* executeDatabaseStep(context2) {
28983
+ const { game: game2, request, user, deploymentId, state } = context2;
28984
+ if (request.schema) {
28985
+ if (isSchemaAdopted(state)) {
28986
+ throw new LegacySchemaUpgradeRequiredError;
28987
+ }
28988
+ const legacyDbId = context2.existingResources?.d1?.find((db2) => db2.name === deploymentId)?.id;
28989
+ if (legacyDbId) {
28990
+ const ledger = await this.getCloudflare().d1.readMigrationLedger(legacyDbId);
28991
+ if (ledger.length > 0) {
28992
+ throw new LegacySchemaUpgradeRequiredError;
28993
+ }
28994
+ }
28995
+ setAttribute("app.deploy.db_mode", "legacy");
28996
+ return { ...NO_DATABASE_WORK, legacySchema: request.schema };
28997
+ }
28998
+ const database = request.database;
28999
+ if (!database) {
29000
+ return NO_DATABASE_WORK;
29001
+ }
29002
+ if (!hasBinding(request.bindings?.database)) {
29003
+ throw new ValidationError("The database payload requires a database binding");
29004
+ }
29005
+ if (!request.deployId) {
29006
+ throw new ValidationError("deployId is required when a database payload is present");
29007
+ }
29008
+ setAttribute("app.deploy.db_mode", database.mode);
29009
+ const cf = this.getCloudflare();
29010
+ const persistedId = context2.existingResources?.d1?.find((db2) => db2.name === deploymentId)?.id;
29011
+ const databaseId = persistedId ?? await cf.d1.create(deploymentId);
29012
+ if (database.mode === "migrate") {
29013
+ return yield* this.runMigrateMode({
29014
+ game: game2,
29015
+ user,
29016
+ deployId: request.deployId,
29017
+ databaseId,
29018
+ migrations: database.migrations,
29019
+ state
29020
+ });
29021
+ }
29022
+ return yield* this.runPushMode({ game: game2, databaseId, payload: database, state });
29023
+ }
29024
+ async* runMigrateMode(args2) {
29025
+ const { game: game2, user, deployId, databaseId, migrations, state } = args2;
29026
+ const cf = this.getCloudflare();
29027
+ yield { type: "status", data: { message: "Preparing database migrations" } };
29028
+ await this.assertNoSchemaDrift(databaseId, state);
29029
+ await cf.d1.ensureMigrationLedger(databaseId);
29030
+ const ledger = await cf.d1.readMigrationLedger(databaseId);
29031
+ const plan = planMigrations(migrations.map((migration) => ({ tag: migration.tag, checksum: migration.checksum })), ledger.map((row) => ({
29032
+ tag: row.tag,
29033
+ checksum: row.checksum,
29034
+ checksumAlgo: row.checksum_algo
29035
+ })));
29036
+ setAttributes({
29037
+ "app.deploy.migrations_total": migrations.length,
29038
+ "app.deploy.migrations_applied_before": ledger.length,
29039
+ "app.deploy.migrations_pending": plan.pendingTags.length
29040
+ });
29041
+ if (plan.checksumMismatches.length > 0) {
29042
+ throw new MigrationChecksumMismatchError(plan.checksumMismatches);
29043
+ }
29044
+ if (plan.missingFromJournalTags.length > 0) {
29045
+ throw new MigrationJournalDivergenceError(plan.missingFromJournalTags);
29046
+ }
29047
+ if (plan.outOfOrderTags.length > 0) {
29048
+ throw new MigrationOrderError(plan.outOfOrderTags);
29049
+ }
29050
+ if (plan.pendingTags.length === 0) {
29051
+ yield { type: "status", data: { message: "Database schema is up to date" } };
29052
+ if (ledger.length > 0 && !state?.schemaFingerprint) {
29053
+ const fingerprint2 = await cf.d1.fingerprintSchema(databaseId);
29054
+ await this.persistDeploymentState(game2.id, {
29055
+ schemaFingerprint: fingerprint2.fingerprint
29056
+ });
29057
+ return {
29058
+ ...NO_DATABASE_WORK,
29059
+ schemaFingerprint: fingerprint2.fingerprint
29060
+ };
29061
+ }
29062
+ return {
29063
+ ...NO_DATABASE_WORK,
29064
+ schemaFingerprint: state?.schemaFingerprint ?? null
29065
+ };
29066
+ }
29067
+ const capture = yield* this.captureBookmarkStep(databaseId);
29068
+ const migrationsByTag = new Map(migrations.map((migration) => [migration.tag, migration]));
29069
+ let appliedCount = 0;
29070
+ for (const tag of plan.pendingTags) {
29071
+ const migration = migrationsByTag.get(tag);
29072
+ const count = migration.statements.length;
29073
+ yield {
29074
+ type: "status",
29075
+ data: { message: `Applying ${tag} (${count} statement${count === 1 ? "" : "s"})` }
29076
+ };
29077
+ const startedAt = Date.now();
29078
+ try {
29079
+ await withSpan("deploy.apply_migration", () => cf.d1.applyMigration(databaseId, {
29080
+ tag,
29081
+ statements: migration.statements,
29082
+ checksum: migration.checksum,
29083
+ deployId,
29084
+ appliedBy: user.id
29085
+ }));
29086
+ } catch (error) {
29087
+ if (appliedCount > 0) {
29088
+ await this.recordAppliedPrefixFingerprint(game2.id, databaseId);
29089
+ }
29090
+ throw await this.toMigrationStepError(databaseId, error, migration);
29091
+ }
29092
+ appliedCount++;
29093
+ const seconds = ((Date.now() - startedAt) / 1000).toFixed(1);
29094
+ yield { type: "status", data: { message: `Applied ${tag} (${seconds}s)` } };
29095
+ }
29096
+ setAttribute("app.deploy.migrations_applied", plan.pendingTags.length);
29097
+ const fingerprint = await cf.d1.fingerprintSchema(databaseId);
29098
+ await this.persistDeploymentState(game2.id, {
29099
+ schemaFingerprint: fingerprint.fingerprint,
29100
+ schemaHash: null,
29101
+ schemaSnapshot: null
29102
+ });
29103
+ return {
29104
+ schemaHash: null,
29105
+ schemaFingerprint: fingerprint.fingerprint,
29106
+ timeTravelBookmark: capture?.bookmark ?? null,
29107
+ bookmarkCapturedAt: capture?.capturedAt ?? null
29108
+ };
29109
+ }
29110
+ async* runPushMode(args2) {
29111
+ const { game: game2, databaseId, payload, state } = args2;
29112
+ const cf = this.getCloudflare();
29113
+ yield { type: "status", data: { message: "Verifying database schema state" } };
29114
+ if (typeof payload.baselineHash !== "string" && payload.baselineHash !== null) {
29115
+ throw new ValidationError("Push deploys require baselineHash (null on first deploy)");
29116
+ }
29117
+ if (isMigrateManaged(state)) {
29118
+ const ledger = await cf.d1.readMigrationLedger(databaseId);
29119
+ throw new ValidationError(`This database is migrate-managed (${ledger.length} applied ` + "migration(s)) and does not accept push-mode SQL.", { code: DEPLOY_ERROR_CODES.strategyMismatch });
29120
+ }
29121
+ const storedHash = state?.schemaHash ?? null;
29122
+ if (payload.baselineHash !== storedHash) {
29123
+ throw await this.buildStateConflictError(game2.id, payload.baselineHash);
29124
+ }
29125
+ const statements = splitSqlStatements(payload.sql);
29126
+ const oversized = findOversizedStatement(statements);
29127
+ if (oversized) {
29128
+ throw new ValidationError(`Push statement ${oversized.index} is ${oversized.byteLength} bytes — over ` + `D1's ${D1_MAX_STATEMENT_BYTES / 1024} KB per-statement limit. Split the ` + "statement or reduce its size.", {
29129
+ code: DEPLOY_ERROR_CODES.pushFailed,
29130
+ statementIndex: oversized.index,
29131
+ offset: null
29132
+ });
29133
+ }
29134
+ const destructive = detectDestructiveStatements(statements);
29135
+ setAttributes({
29136
+ "app.deploy.push_statement_count": statements.length,
29137
+ "app.deploy.push_destructive_count": destructive.length,
29138
+ "app.deploy.push_accept_data_loss": Boolean(payload.acceptDataLoss)
29139
+ });
29140
+ if (destructive.length > 0 && !payload.acceptDataLoss) {
29141
+ throw new DestructiveSchemaError(destructive);
29142
+ }
29143
+ await this.assertNoSchemaDrift(databaseId, state);
29144
+ const reserved = await this.persistPushDeploymentState(game2.id, payload.baselineHash, {
29145
+ schemaFingerprint: PUSH_RESERVATION_FINGERPRINT,
29146
+ schemaHash: payload.nextHash,
29147
+ schemaSnapshot: payload.nextSnapshot
29148
+ });
29149
+ if (!reserved) {
29150
+ throw await this.buildStateConflictError(game2.id, payload.baselineHash);
29151
+ }
29152
+ let capture = null;
29153
+ if (statements.length > 0) {
29154
+ capture = yield* this.captureBookmarkStep(databaseId);
29155
+ yield {
29156
+ type: "status",
29157
+ data: {
29158
+ message: `Applying database schema changes (${statements.length} statements)`
29159
+ }
29160
+ };
29161
+ try {
29162
+ await cf.d1.batch(databaseId, [
29163
+ { sql: "PRAGMA defer_foreign_keys = on" },
29164
+ ...statements.map((statement) => ({ sql: statement })),
29165
+ { sql: "PRAGMA defer_foreign_keys = off" }
29166
+ ]);
29167
+ } catch (error) {
29168
+ await this.persistPushDeploymentState(game2.id, payload.nextHash, {
29169
+ schemaFingerprint: state?.schemaFingerprint ?? null,
29170
+ schemaHash: state?.schemaHash ?? null,
29171
+ schemaSnapshot: state?.schemaSnapshot ?? null
29172
+ });
29173
+ throw this.toPushStepError(error);
29174
+ }
29175
+ }
29176
+ const fingerprint = await cf.d1.fingerprintSchema(databaseId);
29177
+ await this.persistDeploymentState(game2.id, {
29178
+ schemaFingerprint: fingerprint.fingerprint
29179
+ });
29180
+ return {
29181
+ schemaHash: payload.nextHash,
29182
+ schemaFingerprint: fingerprint.fingerprint,
29183
+ timeTravelBookmark: capture?.bookmark ?? null,
29184
+ bookmarkCapturedAt: capture?.capturedAt ?? null
29185
+ };
29186
+ }
29187
+ async* captureBookmarkStep(databaseId) {
29188
+ const cf = this.getCloudflare();
29189
+ const bookmark = await cf.d1.captureBookmark(databaseId);
29190
+ const capturedAt = new Date;
29191
+ setAttribute("app.deploy.db_bookmark_captured", bookmark.captured);
29192
+ if (!bookmark.captured) {
29193
+ yield {
29194
+ type: "status",
29195
+ data: { message: `Time Travel bookmark unavailable (${bookmark.error})` }
29196
+ };
29197
+ return null;
29198
+ }
29199
+ yield {
29200
+ type: "status",
29201
+ data: {
29202
+ message: "Captured Time Travel bookmark",
29203
+ details: { bookmark: bookmark.bookmark }
29204
+ }
29205
+ };
29206
+ return { bookmark: bookmark.bookmark, capturedAt };
29207
+ }
29208
+ async toMigrationStepError(databaseId, error, migration) {
29209
+ if (error instanceof D1StatementTooLargeError) {
29210
+ return new ValidationError(error.message, {
29211
+ code: DEPLOY_ERROR_CODES.migrationFailed,
29212
+ tag: migration.tag,
29213
+ statementIndex: error.statementIndex,
29214
+ offset: null,
29215
+ d1Message: error.message
29216
+ });
29217
+ }
29218
+ if (error instanceof D1MigrationError) {
29219
+ addEvent("deploy.migration_failed", {
29220
+ "app.d1.migration_tag": migration.tag,
29221
+ "app.error.message": error.d1Message,
29222
+ ...error.offset !== null && { "app.d1.error_offset": error.offset }
29223
+ });
29224
+ const alreadyApplied = isAlreadyExistsSqlError(error.d1Message) ? await this.assessAlreadyApplied(databaseId, migration.statements) : null;
29225
+ return new MigrationExecutionError({
29226
+ tag: migration.tag,
29227
+ d1Message: error.d1Message,
29228
+ offset: error.offset,
29229
+ ...alreadyApplied ? { alreadyApplied } : {}
29230
+ });
29231
+ }
29232
+ return error;
29233
+ }
29234
+ async assessAlreadyApplied(databaseId, statements) {
29235
+ try {
29236
+ const cf = this.getCloudflare();
29237
+ const live = await cf.d1.fingerprintSchema(databaseId);
29238
+ const tables = await cf.d1.readTableColumns(databaseId, live.tables);
29239
+ const assessment = assessMigrationAlreadyApplied(statements, tables);
29240
+ addEvent("deploy.already_applied_assessment", {
29241
+ "app.deploy.already_applied_verdict": assessment.verdict,
29242
+ "app.deploy.already_applied_present": assessment.present.length,
29243
+ "app.deploy.already_applied_missing": assessment.missing.length
29244
+ });
29245
+ return assessment.verdict === "no-signal" ? null : assessment;
29246
+ } catch (assessError) {
29247
+ addEvent("deploy.already_applied_check_failed", {
29248
+ "app.error.message": errorMessage(assessError)
29249
+ });
29250
+ return null;
29251
+ }
29252
+ }
29253
+ toPushStepError(error) {
29254
+ if (error instanceof D1BatchError) {
29255
+ addEvent("deploy.push_failed", {
29256
+ "app.error.message": error.d1Message,
29257
+ ...error.offset !== null && { "app.d1.error_offset": error.offset }
29258
+ });
29259
+ return new PushExecutionError({ d1Message: error.d1Message, offset: error.offset });
29260
+ }
29261
+ return error;
29262
+ }
29263
+ async assertNoSchemaDrift(databaseId, state) {
29264
+ if (!state?.schemaFingerprint) {
29265
+ return;
29266
+ }
29267
+ const live = await this.getCloudflare().d1.fingerprintSchema(databaseId);
29268
+ if (live.fingerprint !== state.schemaFingerprint) {
29269
+ addEvent("deploy.state_drift", {
29270
+ "app.deploy.expected_fingerprint": state.schemaFingerprint,
29271
+ "app.deploy.actual_fingerprint": live.fingerprint
29272
+ });
29273
+ throw new DeploymentStateDriftError({
29274
+ expectedFingerprint: state.schemaFingerprint,
29275
+ actualFingerprint: live.fingerprint
29276
+ });
29277
+ }
29278
+ }
29279
+ async buildStateConflictError(gameId, claimedHash) {
29280
+ const [row, lastDeploy] = await Promise.all([
29281
+ this.deps.db.query.gameDeploymentState.findFirst({
29282
+ where: eq(gameDeploymentState.gameId, gameId),
29283
+ columns: { schemaHash: true }
29284
+ }),
29285
+ findLastSuccessfulDeployWithEmail(this.deps.db, gameId)
29286
+ ]);
29287
+ const currentHash = row?.schemaHash ?? null;
29288
+ addEvent("deploy.state_conflict", {
29289
+ "app.deploy.baseline_hash": claimedHash ?? "null",
29290
+ "app.deploy.current_hash": currentHash ?? "null"
29291
+ });
29292
+ return new DeploymentStateConflictError({
29293
+ currentHash,
29294
+ lastDeployAt: lastDeploy?.at.toISOString() ?? null,
29295
+ lastDeployBy: lastDeploy?.email ?? lastDeploy?.userId ?? null
29296
+ });
29297
+ }
29298
+ async recordAppliedPrefixFingerprint(gameId, databaseId) {
29299
+ try {
29300
+ const fingerprint = await this.getCloudflare().d1.fingerprintSchema(databaseId);
29301
+ await this.persistDeploymentState(gameId, {
29302
+ schemaFingerprint: fingerprint.fingerprint
29303
+ });
29304
+ } catch (error) {
29305
+ addEvent("deploy.fingerprint_persist_failed", {
29306
+ "exception.type": errorType(error),
29307
+ "app.error.message": errorMessage(error)
29308
+ });
29309
+ }
29310
+ }
29311
+ async persistDeploymentState(gameId, patch) {
29312
+ const set = {
29313
+ ...patch,
29314
+ updatedAt: new Date
29315
+ };
29316
+ await this.deps.db.insert(gameDeploymentState).values({ gameId, baselineSource: "deploy", ...set }).onConflictDoUpdate({ target: gameDeploymentState.gameId, set });
29317
+ }
29318
+ async persistArtifactHashes(gameId, patch) {
29319
+ const set = {
29320
+ ...patch.buildHash !== undefined && { buildHash: patch.buildHash },
29321
+ ...patch.integrationsHash !== undefined && {
29322
+ integrationsHash: patch.integrationsHash
29323
+ }
29324
+ };
29325
+ if (Object.keys(set).length === 0) {
29326
+ return;
29327
+ }
29328
+ await this.deps.db.insert(gameDeploymentState).values({ gameId, ...set, updatedAt: new Date }).onConflictDoUpdate({
29329
+ target: gameDeploymentState.gameId,
29330
+ set: { ...set, updatedAt: new Date }
29331
+ });
29332
+ }
29333
+ async persistPushDeploymentState(gameId, baselineHash, patch) {
29334
+ const set = { ...patch, updatedAt: new Date };
29335
+ if (baselineHash === null) {
29336
+ const claimed2 = await this.deps.db.insert(gameDeploymentState).values({ gameId, baselineSource: "deploy", ...set }).onConflictDoUpdate({
29337
+ target: gameDeploymentState.gameId,
29338
+ set,
29339
+ setWhere: isNull(gameDeploymentState.schemaHash)
29340
+ }).returning({ gameId: gameDeploymentState.gameId });
29341
+ return claimed2.length > 0;
29342
+ }
29343
+ const claimed = await this.deps.db.update(gameDeploymentState).set(set).where(and(eq(gameDeploymentState.gameId, gameId), eq(gameDeploymentState.schemaHash, baselineHash))).returning({ gameId: gameDeploymentState.gameId });
29344
+ return claimed.length > 0;
29345
+ }
29346
+ async* adoptClientBaseline(context2) {
29347
+ const { game: game2, request, user, deploymentId, baseline } = context2;
29348
+ const cf = this.getCloudflare();
29349
+ const persistedId = context2.existingResources?.d1?.find((db2) => db2.name === deploymentId)?.id;
29350
+ const databaseId = persistedId ?? (hasBinding(request.bindings?.database) ? await cf.d1.create(deploymentId) : null);
29351
+ if (baseline.lastAppliedMigrationTag && !databaseId) {
29352
+ throw new ValidationError("Baseline claims applied migrations, but the deploy has no database binding");
29353
+ }
29354
+ const live = databaseId ? await cf.d1.fingerprintSchema(databaseId) : null;
29355
+ let recordedRows = 0;
29356
+ if (databaseId && baseline.lastAppliedMigrationTag) {
29357
+ if (live.tables.length === 0) {
29358
+ throw new BaselineDatabaseEmptyError;
29359
+ }
29360
+ const slice = sliceJournalToTag(baseline.journal ?? [], baseline.lastAppliedMigrationTag);
29361
+ if (!slice) {
29362
+ throw new ValidationError(`Baseline lastAppliedMigrationTag '${baseline.lastAppliedMigrationTag}' ` + "is not in the submitted journal");
29363
+ }
29364
+ if (baseline.evidence?.length) {
29365
+ const [tables, lastDeploy] = await Promise.all([
29366
+ cf.d1.readTableColumns(databaseId, live.tables),
29367
+ findLastSuccessfulDeploy(this.deps.db, game2.id)
29368
+ ]);
29369
+ assertBaselineClaimValid({
29370
+ claimedTag: baseline.lastAppliedMigrationTag,
29371
+ evidence: baseline.evidence,
29372
+ tables,
29373
+ indexes: new Set(live.indexes),
29374
+ views: new Set(live.views),
29375
+ lastDeployAt: lastDeploy?.at ?? null,
29376
+ allowUnverified: false,
29377
+ source: "seed",
29378
+ gameId: game2.id,
29379
+ userId: user.id
29380
+ });
29381
+ }
29382
+ await cf.d1.ensureMigrationLedger(databaseId);
29383
+ const ledger = await cf.d1.readMigrationLedger(databaseId);
29384
+ const plan = planMigrations(slice, ledger.map((row) => ({
29385
+ tag: row.tag,
29386
+ checksum: row.checksum,
29387
+ checksumAlgo: row.checksum_algo
29388
+ })));
29389
+ if (plan.checksumMismatches.length > 0) {
29390
+ throw new MigrationChecksumMismatchError(plan.checksumMismatches);
29391
+ }
29392
+ if (plan.missingFromJournalTags.length > 0) {
29393
+ throw new MigrationJournalDivergenceError(plan.missingFromJournalTags);
29394
+ }
29395
+ if (plan.outOfOrderTags.length > 0) {
29396
+ throw new MigrationOrderError(plan.outOfOrderTags);
29397
+ }
29398
+ const checksumByTag = new Map(slice.map((entry) => [entry.tag, entry.checksum]));
29399
+ const rows = plan.pendingTags.map((tag) => ({
29400
+ tag,
29401
+ checksum: checksumByTag.get(tag)
29402
+ }));
29403
+ if (rows.length > 0) {
29404
+ await cf.d1.recordLedgerRows(databaseId, {
29405
+ rows,
29406
+ deployId: `baseline:${request.deployId ?? crypto.randomUUID()}`,
29407
+ appliedBy: user.id,
29408
+ source: "baseline"
29409
+ });
29410
+ }
29411
+ recordedRows = rows.length;
29412
+ }
29413
+ const fingerprint = live?.fingerprint ?? null;
29414
+ const set = {
29415
+ ...baseline.schemaHash !== undefined && { schemaHash: baseline.schemaHash },
29416
+ ...baseline.schemaSnapshot !== undefined && {
29417
+ schemaSnapshot: baseline.schemaSnapshot
29418
+ },
29419
+ ...baseline.integrationsHash !== undefined && {
29420
+ integrationsHash: baseline.integrationsHash
29421
+ },
29422
+ ...baseline.buildHash !== undefined && { buildHash: baseline.buildHash },
29423
+ ...fingerprint !== null && { schemaFingerprint: fingerprint },
29424
+ baselineSource: "client-baseline",
29425
+ updatedAt: new Date
29426
+ };
29427
+ await this.deps.db.insert(gameDeploymentState).values({ gameId: game2.id, ...set }).onConflictDoUpdate({ target: gameDeploymentState.gameId, set });
29428
+ setAttributes({
29429
+ "app.deploy.baseline_adopted": true,
29430
+ "app.deploy.baseline_ledger_rows": recordedRows,
29431
+ "app.deploy.baseline_has_snapshot": baseline.schemaSnapshot !== undefined
29432
+ });
29433
+ yield {
29434
+ type: "status",
29435
+ data: {
29436
+ message: "Adopted deployment state from client baseline",
29437
+ details: {
29438
+ ledgerRows: recordedRows,
29439
+ ...baseline.lastAppliedMigrationTag && {
29440
+ lastAppliedMigrationTag: baseline.lastAppliedMigrationTag
29441
+ }
29442
+ }
29443
+ }
29444
+ };
29445
+ return this.deps.db.query.gameDeploymentState.findFirst({
29446
+ where: eq(gameDeploymentState.gameId, game2.id)
29447
+ });
29448
+ }
27939
29449
  async applyGameMetadata(gameId, request, hasFrontend, hasMetadata, deploymentUrl) {
27940
29450
  const updates = { updatedAt: new Date };
27941
29451
  if (hasFrontend) {
@@ -27961,7 +29471,8 @@ class DeployService {
27961
29471
  result,
27962
29472
  request,
27963
29473
  user,
27964
- flags: flags2
29474
+ flags: flags2,
29475
+ database
27965
29476
  }) {
27966
29477
  const { hasBackend, hasFrontend, hasMetadata } = flags2;
27967
29478
  const db2 = this.deps.db;
@@ -27971,9 +29482,17 @@ class DeployService {
27971
29482
  deploymentId: result.deploymentId,
27972
29483
  url: result.url,
27973
29484
  codeHash,
29485
+ schemaHash: database.schemaHash,
29486
+ schemaFingerprint: database.schemaFingerprint,
29487
+ timeTravelBookmark: database.timeTravelBookmark,
29488
+ bookmarkCapturedAt: database.bookmarkCapturedAt,
27974
29489
  resources: result.resources,
27975
29490
  target: "game"
27976
29491
  });
29492
+ await this.persistArtifactHashes(game2.id, {
29493
+ buildHash: hasFrontend ? request.buildHash : undefined,
29494
+ integrationsHash: request.integrationsHash
29495
+ });
27977
29496
  if (hasBackend) {
27978
29497
  await withSpan("deploy.configure_worker_secrets", async () => {
27979
29498
  await this.ensureWorkerApiKeyOnWorker(user, DeployService.gameWorkerKeySpec(slug), result.deploymentId);
@@ -28110,6 +29629,29 @@ class DeployService {
28110
29629
  const cf = this.getCloudflare();
28111
29630
  await cf.setSecrets(deploymentId, { QUEUE_INGRESS_SECRET: secret });
28112
29631
  }
29632
+ async* pruneManagedSecretsStep(gameId, deploymentId, pruneSecrets) {
29633
+ const cf = this.getCloudflare();
29634
+ const keys = [...new Set(pruneSecrets)];
29635
+ yield {
29636
+ type: "status",
29637
+ data: {
29638
+ message: `Pruning ${keys.length} managed secret(s)`,
29639
+ details: { keys }
29640
+ }
29641
+ };
29642
+ await withSpan("deploy.prune_secrets", async () => {
29643
+ const existing = await cf.listSecrets(deploymentId);
29644
+ for (const key of keys) {
29645
+ const prefixedKey = `${SECRETS_PREFIX}${key}`;
29646
+ if (existing.includes(prefixedKey)) {
29647
+ await cf.deleteSecret(deploymentId, prefixedKey);
29648
+ }
29649
+ }
29650
+ const pruned = keys.reduce((expr, key) => sql`${expr} - ${key}::text`, sql`coalesce(${gameDeploymentState.secretsManifest}, '{}'::jsonb)`);
29651
+ await this.deps.db.update(gameDeploymentState).set({ secretsManifest: pruned, updatedAt: new Date }).where(eq(gameDeploymentState.gameId, gameId));
29652
+ });
29653
+ setAttribute("app.deploy.pruned_secret_count", keys.length);
29654
+ }
28113
29655
  async ensureDashboardSessionSecret(deploymentId, existingSecrets, hasPriorDeployment) {
28114
29656
  if (existingSecrets === null && hasPriorDeployment) {
28115
29657
  setAttribute("app.deploy.session_secret_outcome", "check_failed_kept");
@@ -28183,13 +29725,13 @@ class DeployService {
28183
29725
  return this.deps.config.baseUrl;
28184
29726
  }
28185
29727
  try {
28186
- return await getTunnelUrl();
28187
- } catch {
29728
+ return await getTunnelUrl(this.deps.config.baseUrl);
29729
+ } catch (error) {
28188
29730
  setAttributes({
28189
29731
  "app.deploy.tunnel_available": false,
28190
29732
  "app.deploy.failure_kind": "local_tunnel_unavailable"
28191
29733
  });
28192
- throw new ValidationError("Local tunnel is not running. Ensure cloudflared is installed (`brew install cloudflared`) and the tunnel DevCommand started successfully.");
29734
+ throw new ValidationError(errorMessage(error));
28193
29735
  }
28194
29736
  }
28195
29737
  async deployToCloudflare(args2) {
@@ -28214,6 +29756,10 @@ class DeployService {
28214
29756
  target: record.target,
28215
29757
  url: record.url,
28216
29758
  codeHash: record.codeHash,
29759
+ schemaHash: record.schemaHash ?? null,
29760
+ schemaFingerprint: record.schemaFingerprint ?? null,
29761
+ timeTravelBookmark: record.timeTravelBookmark ?? null,
29762
+ bookmarkCapturedAt: record.bookmarkCapturedAt ?? null,
28217
29763
  resources: record.resources,
28218
29764
  isActive: true
28219
29765
  });
@@ -28223,8 +29769,10 @@ class DeployService {
28223
29769
  await this.deps.alerts.notifyDeploymentFailure(failure).catch(catchAttrs("alerts.delivery", { "app.alerts.type": "deployment_failure" }));
28224
29770
  }
28225
29771
  }
29772
+ var PUSH_RESERVATION_FINGERPRINT = "reserved:push-in-flight", NO_DATABASE_WORK;
28226
29773
  var init_deploy_service = __esm(() => {
28227
29774
  init_drizzle_orm();
29775
+ init_src4();
28228
29776
  init_playcademy();
28229
29777
  init_src();
28230
29778
  init_helpers_index();
@@ -28232,9 +29780,17 @@ var init_deploy_service = __esm(() => {
28232
29780
  init_spans();
28233
29781
  init_tunnel();
28234
29782
  init_errors();
29783
+ init_baseline_validation_util();
28235
29784
  init_dashboard_util();
28236
29785
  init_deployment_util();
29786
+ init_migration_util();
28237
29787
  init_worker_keys_util();
29788
+ NO_DATABASE_WORK = {
29789
+ schemaHash: null,
29790
+ schemaFingerprint: null,
29791
+ timeTravelBookmark: null,
29792
+ bookmarkCapturedAt: null
29793
+ };
28238
29794
  });
28239
29795
 
28240
29796
  // ../api-core/src/services/developer.service.ts
@@ -29688,7 +31244,7 @@ function createGameServices(deps) {
29688
31244
  }
29689
31245
  };
29690
31246
  }
29691
- var init_game2 = __esm(() => {
31247
+ var init_game3 = __esm(() => {
29692
31248
  init_dashboard_service();
29693
31249
  init_deploy_job_service();
29694
31250
  init_deploy_service();
@@ -29887,16 +31443,37 @@ class AlertsService {
29887
31443
  await this.sendAlert(discord, embed.build());
29888
31444
  }
29889
31445
  async notifyDeploymentFailure(failure) {
29890
- const discord = this.recordAlert("deployment_failure");
31446
+ const refused = DEPLOY_REFUSAL_CODES.has(failure.errorCode ?? "");
31447
+ const discord = this.recordAlert(refused ? "deployment_blocked" : "deployment_failure");
29891
31448
  if (!discord) {
29892
31449
  return;
29893
31450
  }
29894
- const [title, subject] = failure.target === "dashboard" ? ["Dashboard Deployment Failed", "Dashboard deployment"] : ["Deployment Failed", "Deployment"];
29895
- const embed = new DiscordEmbedBuilder().setTitle(title).setDescription(`${subject} failed for **${failure.displayName || failure.slug}** (**${this.getEnvironment()}**).`).setColor(DiscordColors.RED).addField("Slug", failure.slug, true);
31451
+ const [noun, subject] = failure.target === "dashboard" ? ["Dashboard Deployment", "Dashboard deployment"] : ["Deployment", "Deployment"];
31452
+ const title = refused ? `\uD83D\uDEA7 ${noun} Blocked` : `❌ ${noun} Failed`;
31453
+ const verb = refused ? "was blocked" : "failed";
31454
+ const embed = new DiscordEmbedBuilder().setTitle(title).setDescription(`${subject} ${verb} for **${failure.displayName || failure.slug}** (**${this.getEnvironment()}**).`).setColor(refused ? DiscordColors.YELLOW : DiscordColors.RED).addField("Slug", failure.slug, true);
29896
31455
  if (failure.developer) {
29897
31456
  embed.addField("Developer", failure.developer.email || failure.developer.id, true);
29898
31457
  }
29899
- embed.addField("Error", failure.error, false).setFooter("Playcademy Developer Platform").setTimestamp();
31458
+ embed.addField(refused ? "Reason" : "Error", failure.error, false);
31459
+ if (refused) {
31460
+ embed.addField("Next step", "The developer received repair guidance in their terminal", false);
31461
+ }
31462
+ embed.setFooter("Playcademy Developer Platform").setTimestamp();
31463
+ await this.sendAlert(discord, embed.build());
31464
+ }
31465
+ async notifyDeployBlocked(blocked) {
31466
+ const discord = this.recordAlert("deployment_blocked");
31467
+ if (!discord) {
31468
+ return;
31469
+ }
31470
+ const embed = new DiscordEmbedBuilder().setTitle("\uD83D\uDEA7 Deployment Blocked").setDescription(`Deployment was blocked for **${blocked.displayName || blocked.slug}** (**${this.getEnvironment()}**).`).setColor(DiscordColors.YELLOW).addField("Slug", blocked.slug, true);
31471
+ if (blocked.developer) {
31472
+ embed.addField("Developer", blocked.developer.email || blocked.developer.id, true);
31473
+ }
31474
+ embed.addField("Reason", blocked.reason, false);
31475
+ embed.addField("Next step", "The developer received repair guidance in their terminal", false);
31476
+ embed.setFooter("Playcademy Developer Platform").setTimestamp();
29900
31477
  await this.sendAlert(discord, embed.build());
29901
31478
  }
29902
31479
  async notifyGameDeletion(game2) {
@@ -29957,6 +31534,7 @@ var DISCORD_FIELD_LIMIT = 1024;
29957
31534
  var init_alerts_service = __esm(() => {
29958
31535
  init_discord();
29959
31536
  init_spans();
31537
+ init_game2();
29960
31538
  });
29961
31539
 
29962
31540
  // ../api-core/src/services/kv-backup.service.ts
@@ -30389,6 +31967,15 @@ class DatabaseService {
30389
31967
  constructor(deps) {
30390
31968
  this.deps = deps;
30391
31969
  }
31970
+ static remapD1Resource(resources, d1ResourceName, databaseId) {
31971
+ return {
31972
+ resources: {
31973
+ ...resources,
31974
+ d1: resources.d1?.map((dbResource) => dbResource.name === d1ResourceName ? { ...dbResource, id: databaseId } : dbResource)
31975
+ },
31976
+ timeTravelBookmark: null
31977
+ };
31978
+ }
30392
31979
  getD1() {
30393
31980
  const d1 = this.deps.cloudflare?.d1;
30394
31981
  if (!d1) {
@@ -30407,11 +31994,7 @@ class DatabaseService {
30407
31994
  try {
30408
31995
  await this.deps.cloudflare.updateD1Binding(dashboardDeployment.deploymentId, databaseId);
30409
31996
  if (dashboardDeployment.resources?.d1?.length) {
30410
- const updatedResources = {
30411
- ...dashboardDeployment.resources,
30412
- d1: dashboardDeployment.resources.d1.map((dbResource) => dbResource.name === d1ResourceName ? { ...dbResource, id: databaseId } : dbResource)
30413
- };
30414
- await this.deps.db.update(gameDeployments).set({ resources: updatedResources }).where(eq(gameDeployments.id, dashboardDeployment.id));
31997
+ await this.deps.db.update(gameDeployments).set(DatabaseService.remapD1Resource(dashboardDeployment.resources, d1ResourceName, databaseId)).where(eq(gameDeployments.id, dashboardDeployment.id));
30415
31998
  }
30416
31999
  setAttribute("app.database.dashboard_binding", "updated");
30417
32000
  } catch (error) {
@@ -30422,20 +32005,36 @@ class DatabaseService {
30422
32005
  });
30423
32006
  }
30424
32007
  }
30425
- async reset(slug, user, schema2) {
32008
+ async reset(slug, user, request = {}) {
32009
+ const { schema: schema2, database } = request;
30426
32010
  setAttributes({
30427
32011
  "app.database.operation": "reset",
32012
+ "app.database.mode": database?.mode ?? (schema2 ? "legacy" : "none"),
30428
32013
  "app.database.schema_size": schema2?.sql.length,
30429
32014
  "app.database.schema_version": schema2?.hash
30430
32015
  });
30431
32016
  const d1 = this.getD1();
30432
32017
  const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32018
+ const state = await this.deps.db.query.gameDeploymentState.findFirst({
32019
+ where: eq(gameDeploymentState.gameId, game2.id)
32020
+ });
32021
+ if (isSchemaAdopted(state) && !database) {
32022
+ if (schema2) {
32023
+ throw new LegacySchemaUpgradeRequiredError;
32024
+ }
32025
+ throw new ValidationError("This game's database state is server-managed: resetting it requires " + "the mode-aware rebuild payload so the recorded state matches the " + "new database. Run the reset through the Playcademy CLI.");
32026
+ }
30433
32027
  const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
32028
+ let resetDatabaseId = null;
30434
32029
  try {
30435
32030
  const databaseId = await d1.reset(deploymentId);
32031
+ resetDatabaseId = databaseId;
30436
32032
  setAttribute("app.database.id", databaseId);
30437
32033
  let schemaPushed = false;
30438
- if (schema2?.sql) {
32034
+ if (database) {
32035
+ await this.rebuildDatabase(databaseId, database, game2.id, user);
32036
+ schemaPushed = true;
32037
+ } else if (schema2?.sql) {
30439
32038
  await d1.executeSchema(databaseId, schema2);
30440
32039
  schemaPushed = true;
30441
32040
  }
@@ -30451,11 +32050,7 @@ class DatabaseService {
30451
32050
  });
30452
32051
  setAttribute("app.database.active_deployment_found", Boolean(activeDeployment));
30453
32052
  if (activeDeployment?.resources?.d1?.length) {
30454
- const updatedResources = {
30455
- ...activeDeployment.resources,
30456
- d1: activeDeployment.resources.d1.map((dbResource) => dbResource.name === deploymentId ? { ...dbResource, id: databaseId } : dbResource)
30457
- };
30458
- await this.deps.db.update(gameDeployments).set({ resources: updatedResources }).where(eq(gameDeployments.id, activeDeployment.id));
32053
+ await this.deps.db.update(gameDeployments).set(DatabaseService.remapD1Resource(activeDeployment.resources, deploymentId, databaseId)).where(eq(gameDeployments.id, activeDeployment.id));
30459
32054
  }
30460
32055
  await this.syncDashboardD1Binding(game2.id, deploymentId, databaseId);
30461
32056
  setAttributes({
@@ -30469,18 +32064,81 @@ class DatabaseService {
30469
32064
  schemaPushed
30470
32065
  };
30471
32066
  } catch (error) {
32067
+ if (database && resetDatabaseId) {
32068
+ await this.recordLiveFingerprint(game2.id, resetDatabaseId);
32069
+ }
30472
32070
  this.deps.alerts.notifyDatabaseResetFailure({
30473
32071
  slug,
30474
32072
  displayName: game2.displayName,
30475
32073
  error: errorMessage(error),
30476
32074
  developer: { id: user.id, email: user.email }
30477
32075
  }).catch(catchAttrs("alerts.delivery", { "app.alerts.type": "database_reset" }));
32076
+ if (error instanceof DomainError) {
32077
+ throw error;
32078
+ }
30478
32079
  throw new ValidationError(`Database reset failed: ${errorMessage(error)}`);
30479
32080
  }
30480
32081
  }
32082
+ async rebuildDatabase(databaseId, payload, gameId, user) {
32083
+ const d1 = this.getD1();
32084
+ if (payload.mode === "migrate") {
32085
+ const deployId = `reset:${crypto.randomUUID()}`;
32086
+ await d1.ensureMigrationLedger(databaseId);
32087
+ for (const migration of payload.migrations) {
32088
+ await d1.applyMigration(databaseId, {
32089
+ tag: migration.tag,
32090
+ statements: migration.statements,
32091
+ checksum: migration.checksum,
32092
+ deployId,
32093
+ appliedBy: user.id
32094
+ });
32095
+ }
32096
+ setAttribute("app.database.migrations_replayed", payload.migrations.length);
32097
+ const fingerprint2 = await d1.fingerprintSchema(databaseId);
32098
+ await this.persistDeploymentState(gameId, {
32099
+ schemaFingerprint: fingerprint2.fingerprint,
32100
+ schemaHash: null,
32101
+ schemaSnapshot: null
32102
+ });
32103
+ return;
32104
+ }
32105
+ const statements = splitSqlStatements(payload.sql);
32106
+ if (statements.length > 0) {
32107
+ await d1.batch(databaseId, [
32108
+ { sql: "PRAGMA defer_foreign_keys = on" },
32109
+ ...statements.map((statement) => ({ sql: statement })),
32110
+ { sql: "PRAGMA defer_foreign_keys = off" }
32111
+ ]);
32112
+ }
32113
+ setAttribute("app.database.push_statement_count", statements.length);
32114
+ const fingerprint = await d1.fingerprintSchema(databaseId);
32115
+ await this.persistDeploymentState(gameId, {
32116
+ schemaFingerprint: fingerprint.fingerprint,
32117
+ schemaHash: payload.nextHash,
32118
+ schemaSnapshot: payload.nextSnapshot
32119
+ });
32120
+ }
32121
+ async persistDeploymentState(gameId, patch) {
32122
+ const set = { ...patch, updatedAt: new Date };
32123
+ await this.deps.db.insert(gameDeploymentState).values({ gameId, baselineSource: "deploy", ...set }).onConflictDoUpdate({ target: gameDeploymentState.gameId, set });
32124
+ }
32125
+ async recordLiveFingerprint(gameId, databaseId) {
32126
+ try {
32127
+ const fingerprint = await this.getD1().fingerprintSchema(databaseId);
32128
+ await this.persistDeploymentState(gameId, {
32129
+ schemaFingerprint: fingerprint.fingerprint
32130
+ });
32131
+ } catch (error) {
32132
+ addEvent("database.fingerprint_persist_failed", {
32133
+ "exception.type": errorType(error),
32134
+ "app.error.message": errorMessage(error)
32135
+ });
32136
+ }
32137
+ }
30481
32138
  }
30482
32139
  var init_database_service = __esm(() => {
30483
32140
  init_drizzle_orm();
32141
+ init_src4();
30484
32142
  init_helpers_index();
30485
32143
  init_tables_index();
30486
32144
  init_spans();
@@ -30488,6 +32146,527 @@ var init_database_service = __esm(() => {
30488
32146
  init_deployment_util();
30489
32147
  });
30490
32148
 
32149
+ // ../api-core/src/utils/secrets.util.ts
32150
+ async function listUserSecretKeys(cloudflare2, deploymentId) {
32151
+ try {
32152
+ const allKeys = await cloudflare2.listSecrets(deploymentId);
32153
+ return allKeys.filter((key) => key.startsWith(SECRETS_PREFIX)).map((key) => key.slice(SECRETS_PREFIX.length));
32154
+ } catch (error) {
32155
+ const message = errorMessage(error);
32156
+ if (message.includes("not found") || message.includes("10007")) {
32157
+ return null;
32158
+ }
32159
+ throw error;
32160
+ }
32161
+ }
32162
+ var init_secrets_util = __esm(() => {
32163
+ init_src();
32164
+ });
32165
+
32166
+ // ../api-core/src/services/deployment-state.service.ts
32167
+ function historyEventEntry(event) {
32168
+ const base = { at: event.createdAt.toISOString(), by: event.email ?? DELETED_ACCOUNT_LABEL };
32169
+ if (event.kind === "restore" && "restoredTo" in event.payload) {
32170
+ return [{ kind: "restore", ...base, restoredTo: event.payload.restoredTo }];
32171
+ }
32172
+ if (event.kind === "blocked" && "code" in event.payload) {
32173
+ return [
32174
+ { kind: "blocked", ...base, code: event.payload.code, reason: event.payload.reason }
32175
+ ];
32176
+ }
32177
+ return [];
32178
+ }
32179
+ function databaseIdFromResources(resources, deploymentId) {
32180
+ const database = resources?.d1?.find((db2) => db2.name === deploymentId) ?? resources?.d1?.[0];
32181
+ return database?.id ?? null;
32182
+ }
32183
+ function restorePointCapturedAt(row) {
32184
+ return row.bookmarkCapturedAt ?? row.deployedAt;
32185
+ }
32186
+
32187
+ class DeploymentStateService {
32188
+ deps;
32189
+ constructor(deps) {
32190
+ this.deps = deps;
32191
+ }
32192
+ async partitionSecretKeys(slug, manifest) {
32193
+ const managedKeys = Object.keys(manifest ?? {});
32194
+ if (!this.deps.cloudflare) {
32195
+ addEvent("deployment_state.secret_keys_unavailable", {
32196
+ "app.error.message": "Cloudflare provider not configured"
32197
+ });
32198
+ return { managedKeys, unmanagedKeys: null };
32199
+ }
32200
+ const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
32201
+ const remoteKeys = await listUserSecretKeys(this.deps.cloudflare, deploymentId);
32202
+ if (remoteKeys === null) {
32203
+ return { managedKeys, unmanagedKeys: [] };
32204
+ }
32205
+ const managed = new Set(managedKeys);
32206
+ return {
32207
+ managedKeys,
32208
+ unmanagedKeys: remoteKeys.filter((key) => !managed.has(key))
32209
+ };
32210
+ }
32211
+ async readAppliedMigrations(slug, resources) {
32212
+ if (!this.deps.cloudflare || !resources?.d1?.length) {
32213
+ return null;
32214
+ }
32215
+ const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
32216
+ const databaseId = databaseIdFromResources(resources, deploymentId);
32217
+ if (!databaseId) {
32218
+ return null;
32219
+ }
32220
+ const ledger = await this.deps.cloudflare.d1.readMigrationLedger(databaseId);
32221
+ setAttributes({ "app.deployment_state.applied_migrations": ledger.length });
32222
+ return ledger.map((row) => ({
32223
+ tag: row.tag,
32224
+ checksum: row.checksum,
32225
+ checksumAlgo: row.checksum_algo
32226
+ }));
32227
+ }
32228
+ async get(slug, user, options = {}) {
32229
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32230
+ const [state, gameDeployment, dashboardDeployment, lastSucceededJob, lastFailedJob] = await Promise.all([
32231
+ this.deps.db.query.gameDeploymentState.findFirst({
32232
+ where: eq(gameDeploymentState.gameId, game2.id)
32233
+ }),
32234
+ this.deps.db.query.gameDeployments.findFirst({
32235
+ where: activeDeploymentWhere(game2.id, "game"),
32236
+ columns: { codeHash: true, url: true, deployedAt: true, resources: true }
32237
+ }),
32238
+ this.deps.db.query.gameDeployments.findFirst({
32239
+ where: activeDeploymentWhere(game2.id, "dashboard"),
32240
+ columns: { url: true, deployedAt: true }
32241
+ }),
32242
+ findLastSuccessfulDeployWithEmail(this.deps.db, game2.id),
32243
+ this.deps.db.query.gameDeployJobs.findFirst({
32244
+ where: and(eq(gameDeployJobs.gameId, game2.id), eq(gameDeployJobs.status, "failed")),
32245
+ orderBy: desc(deployJobInstant()),
32246
+ columns: { events: true }
32247
+ })
32248
+ ]);
32249
+ const [secrets, appliedMigrations] = await Promise.all([
32250
+ this.partitionSecretKeys(slug, state?.secretsManifest ?? null),
32251
+ this.readAppliedMigrations(slug, gameDeployment?.resources ?? null)
32252
+ ]);
32253
+ setAttributes({
32254
+ "app.deployment_state.seeded": Boolean(state),
32255
+ "app.deployment_state.game_deployed": Boolean(gameDeployment),
32256
+ "app.deployment_state.dashboard_deployed": Boolean(dashboardDeployment)
32257
+ });
32258
+ return {
32259
+ gameId: game2.id,
32260
+ seeded: Boolean(state),
32261
+ game: gameDeployment ? {
32262
+ codeHash: gameDeployment.codeHash,
32263
+ buildHash: state?.buildHash ?? null,
32264
+ url: gameDeployment.url,
32265
+ deployedAt: gameDeployment.deployedAt.toISOString()
32266
+ } : null,
32267
+ dashboard: dashboardDeployment ? {
32268
+ url: dashboardDeployment.url,
32269
+ deployedAt: dashboardDeployment.deployedAt.toISOString()
32270
+ } : null,
32271
+ database: {
32272
+ appliedMigrations,
32273
+ lastFailure: parseMigrationFailure(lastFailedJob?.events ?? null),
32274
+ schemaHash: state?.schemaHash ?? null,
32275
+ schemaFingerprint: state?.schemaFingerprint ?? null,
32276
+ ...options.includeSchemaSnapshot && {
32277
+ schemaSnapshot: state?.schemaSnapshot ?? null
32278
+ }
32279
+ },
32280
+ secrets,
32281
+ integrationsHash: state?.integrationsHash ?? null,
32282
+ compatibilityDate: state?.compatibilityDate ?? null,
32283
+ lastDeploy: lastSucceededJob ? {
32284
+ at: lastSucceededJob.at.toISOString(),
32285
+ by: lastSucceededJob.email ?? DELETED_ACCOUNT_LABEL
32286
+ } : null
32287
+ };
32288
+ }
32289
+ requireCloudflare() {
32290
+ if (!this.deps.cloudflare) {
32291
+ throw new ValidationError("Deployment-state operations are not available in this environment");
32292
+ }
32293
+ return this.deps.cloudflare;
32294
+ }
32295
+ async resolveDatabaseId(slug, gameId) {
32296
+ const databaseId = await this.findDatabaseId(slug, gameId);
32297
+ if (!databaseId) {
32298
+ throw new ValidationError("Game has no deployed database — deploy with a database binding first");
32299
+ }
32300
+ return databaseId;
32301
+ }
32302
+ findSchemaHashState(gameId) {
32303
+ return this.deps.db.query.gameDeploymentState.findFirst({
32304
+ where: eq(gameDeploymentState.gameId, gameId),
32305
+ columns: { schemaHash: true }
32306
+ });
32307
+ }
32308
+ async findDatabaseId(slug, gameId) {
32309
+ const deployment = await this.deps.db.query.gameDeployments.findFirst({
32310
+ where: activeDeploymentWhere(gameId, "game"),
32311
+ columns: { resources: true }
32312
+ });
32313
+ return databaseIdFromResources(deployment?.resources, getGameDeploymentId(slug, this.deps.config.sstStage));
32314
+ }
32315
+ async baseline(slug, input, user) {
32316
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32317
+ const cf = this.requireCloudflare();
32318
+ const state = await this.deps.db.query.gameDeploymentState.findFirst({
32319
+ where: eq(gameDeploymentState.gameId, game2.id)
32320
+ });
32321
+ const schemaAdopted = isSchemaAdopted(state);
32322
+ const migrateOnlyClaim = Boolean(input.lastAppliedMigrationTag) && input.schemaHash === undefined && input.schemaSnapshot === undefined;
32323
+ if (schemaAdopted && !migrateOnlyClaim) {
32324
+ throw new BaselineAlreadyAdoptedError(state?.baselineSource ?? null);
32325
+ }
32326
+ const databaseId = await this.resolveDatabaseId(slug, game2.id);
32327
+ const [ledger, live] = await Promise.all([
32328
+ cf.d1.readMigrationLedger(databaseId),
32329
+ cf.d1.fingerprintSchema(databaseId)
32330
+ ]);
32331
+ const verdict = evaluateBaselineGuardrails({
32332
+ ledgerTags: ledger.map((row) => row.tag),
32333
+ liveTables: live.tables
32334
+ });
32335
+ if (verdict === "ledger-not-empty") {
32336
+ throw new BaselineLedgerNotEmptyError(ledger.map((row) => row.tag));
32337
+ }
32338
+ if (verdict === "database-empty") {
32339
+ throw new BaselineDatabaseEmptyError;
32340
+ }
32341
+ if (schemaAdopted && state?.schemaFingerprint && live.fingerprint !== state.schemaFingerprint) {
32342
+ throw new DeploymentStateDriftError({
32343
+ expectedFingerprint: state.schemaFingerprint,
32344
+ actualFingerprint: live.fingerprint
32345
+ });
32346
+ }
32347
+ if (input.lastAppliedMigrationTag && input.evidence?.length) {
32348
+ const [tables, lastDeploy] = await Promise.all([
32349
+ cf.d1.readTableColumns(databaseId, live.tables),
32350
+ findLastSuccessfulDeploy(this.deps.db, game2.id)
32351
+ ]);
32352
+ assertBaselineClaimValid({
32353
+ claimedTag: input.lastAppliedMigrationTag,
32354
+ evidence: input.evidence,
32355
+ tables,
32356
+ indexes: new Set(live.indexes),
32357
+ views: new Set(live.views),
32358
+ lastDeployAt: lastDeploy?.at ?? null,
32359
+ allowUnverified: Boolean(input.allowUnverified),
32360
+ source: "manual",
32361
+ gameId: game2.id,
32362
+ userId: user.id
32363
+ });
32364
+ }
32365
+ let recordedTags = [];
32366
+ if (input.lastAppliedMigrationTag) {
32367
+ const slice = sliceJournalToTag(input.journal ?? [], input.lastAppliedMigrationTag);
32368
+ if (!slice) {
32369
+ throw new ValidationError(`lastAppliedMigrationTag '${input.lastAppliedMigrationTag}' is not in the ` + "submitted journal");
32370
+ }
32371
+ await cf.d1.ensureMigrationLedger(databaseId);
32372
+ await cf.d1.recordLedgerRows(databaseId, {
32373
+ rows: slice,
32374
+ deployId: `baseline:${crypto.randomUUID()}`,
32375
+ appliedBy: user.id,
32376
+ source: "baseline"
32377
+ });
32378
+ recordedTags = slice.map((entry) => entry.tag);
32379
+ }
32380
+ const graduating = migrateOnlyClaim && isPushAdopted(state);
32381
+ const set = {
32382
+ ...graduating ? { schemaHash: null, schemaSnapshot: null } : {
32383
+ ...input.schemaHash !== undefined && { schemaHash: input.schemaHash },
32384
+ ...input.schemaSnapshot !== undefined && {
32385
+ schemaSnapshot: input.schemaSnapshot
32386
+ }
32387
+ },
32388
+ schemaFingerprint: live.fingerprint,
32389
+ baselineSource: "manual-baseline",
32390
+ updatedAt: new Date
32391
+ };
32392
+ await this.persistDeploymentState(game2.id, set);
32393
+ addEvent("deployment_state.baseline_recorded", {
32394
+ "app.game.id": game2.id,
32395
+ "app.deployment_state.baseline_source": "manual-baseline",
32396
+ "app.deployment_state.baseline_ledger_rows": recordedTags.length,
32397
+ "app.deployment_state.baseline_has_snapshot": input.schemaSnapshot !== undefined,
32398
+ "app.deployment_state.baseline_graduated_from_push": graduating
32399
+ });
32400
+ return this.get(slug, user);
32401
+ }
32402
+ async realignMigration(slug, tag, checksum, user) {
32403
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32404
+ const cf = this.requireCloudflare();
32405
+ const databaseId = await this.resolveDatabaseId(slug, game2.id);
32406
+ const ledger = await cf.d1.readMigrationLedger(databaseId);
32407
+ if (!ledger.some((row) => row.tag === tag)) {
32408
+ throw new NotFoundError("Applied migration", tag);
32409
+ }
32410
+ const updated = await cf.d1.updateLedgerChecksum(databaseId, { tag, checksum });
32411
+ if (!updated) {
32412
+ throw new NotFoundError("Applied migration", tag);
32413
+ }
32414
+ addEvent("deployment_state.migration_realigned", {
32415
+ "app.game.id": game2.id,
32416
+ "app.d1.migration_tag": tag,
32417
+ "app.user.id": user.id
32418
+ });
32419
+ return { tag, checksum, checksumAlgo: MIGRATION_CHECKSUM_ALGO };
32420
+ }
32421
+ async persistDeploymentState(gameId, set) {
32422
+ await this.deps.db.insert(gameDeploymentState).values({ gameId, ...set }).onConflictDoUpdate({ target: gameDeploymentState.gameId, set });
32423
+ }
32424
+ async updateDeploymentState(gameId, set) {
32425
+ const updated = await this.deps.db.update(gameDeploymentState).set(set).where(eq(gameDeploymentState.gameId, gameId)).returning({ gameId: gameDeploymentState.gameId });
32426
+ return updated.length > 0;
32427
+ }
32428
+ async resolveMigration(slug, tag, input, user) {
32429
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32430
+ const cf = this.requireCloudflare();
32431
+ const databaseId = await this.resolveDatabaseId(slug, game2.id);
32432
+ const [ledger, live] = await Promise.all([
32433
+ cf.d1.readMigrationLedger(databaseId),
32434
+ cf.d1.fingerprintSchema(databaseId)
32435
+ ]);
32436
+ const exists2 = ledger.some((row) => row.tag === tag);
32437
+ if (input.resolution === "applied") {
32438
+ if (!input.checksum) {
32439
+ throw new ValidationError("Resolving a migration as 'applied' requires its checksum");
32440
+ }
32441
+ if (exists2) {
32442
+ throw new AlreadyExistsError(`Migration '${tag}' is already recorded as applied`);
32443
+ }
32444
+ await cf.d1.ensureMigrationLedger(databaseId);
32445
+ await cf.d1.recordLedgerRows(databaseId, {
32446
+ rows: [{ tag, checksum: input.checksum }],
32447
+ deployId: `resolve:${crypto.randomUUID()}`,
32448
+ appliedBy: user.id,
32449
+ source: "resolve"
32450
+ });
32451
+ } else {
32452
+ if (!exists2) {
32453
+ throw new NotFoundError("Migration ledger row", tag);
32454
+ }
32455
+ await cf.d1.deleteLedgerRow(databaseId, tag);
32456
+ }
32457
+ const fingerprintRecorded = await this.updateDeploymentState(game2.id, {
32458
+ schemaFingerprint: live.fingerprint,
32459
+ updatedAt: new Date
32460
+ });
32461
+ addEvent("deployment_state.migration_resolved", {
32462
+ "app.game.id": game2.id,
32463
+ "app.d1.migration_tag": tag,
32464
+ "app.deployment_state.resolution": input.resolution,
32465
+ "app.deployment_state.fingerprint_rerecorded": fingerprintRecorded,
32466
+ "app.user.id": user.id
32467
+ });
32468
+ return {
32469
+ tag,
32470
+ resolution: input.resolution,
32471
+ schemaFingerprint: live.fingerprint,
32472
+ fingerprintRecorded
32473
+ };
32474
+ }
32475
+ async history(slug, user, options = {}) {
32476
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32477
+ const limit = options.limit ?? 20;
32478
+ const [jobs, events] = await Promise.all([
32479
+ this.deps.db.select({
32480
+ status: gameDeployJobs.status,
32481
+ createdAt: gameDeployJobs.createdAt,
32482
+ completedAt: gameDeployJobs.completedAt,
32483
+ deployId: gameDeployJobs.deployId,
32484
+ error: gameDeployJobs.error,
32485
+ email: users.email
32486
+ }).from(gameDeployJobs).leftJoin(users, eq(gameDeployJobs.userId, users.id)).where(eq(gameDeployJobs.gameId, game2.id)).orderBy(desc(deployJobInstant())).limit(limit),
32487
+ this.deps.db.select({
32488
+ kind: gameDeployEvents.kind,
32489
+ payload: gameDeployEvents.payload,
32490
+ createdAt: gameDeployEvents.createdAt,
32491
+ email: users.email
32492
+ }).from(gameDeployEvents).leftJoin(users, eq(gameDeployEvents.userId, users.id)).where(eq(gameDeployEvents.gameId, game2.id)).orderBy(desc(gameDeployEvents.createdAt)).limit(limit)
32493
+ ]);
32494
+ setAttributes({
32495
+ "app.deployment_state.history_jobs": jobs.length,
32496
+ "app.deployment_state.history_events": events.length
32497
+ });
32498
+ const deploys = jobs.map((job) => ({
32499
+ kind: "deploy",
32500
+ status: job.status,
32501
+ at: (job.completedAt ?? job.createdAt).toISOString(),
32502
+ completedAt: job.completedAt?.toISOString() ?? null,
32503
+ by: job.email ?? DELETED_ACCOUNT_LABEL,
32504
+ deployId: job.deployId,
32505
+ error: job.error
32506
+ }));
32507
+ const merged = [...deploys, ...events.flatMap(historyEventEntry)].toSorted((a, b) => a.at < b.at ? 1 : -1).slice(0, limit);
32508
+ return { deploys: merged };
32509
+ }
32510
+ async restorePoints(slug, user) {
32511
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32512
+ const retentionCutoff = new Date(Date.now() - D1_TIME_TRAVEL_RETENTION_DAYS * 24 * 60 * 60 * 1000);
32513
+ const [currentDatabaseId, rows, state] = await Promise.all([
32514
+ this.findDatabaseId(slug, game2.id),
32515
+ this.deps.db.query.gameDeployments.findMany({
32516
+ where: and(eq(gameDeployments.gameId, game2.id), eq(gameDeployments.target, "game"), isNotNull(gameDeployments.timeTravelBookmark), gte(gameDeployments.deployedAt, retentionCutoff)),
32517
+ orderBy: desc(gameDeployments.deployedAt),
32518
+ limit: 100,
32519
+ columns: {
32520
+ id: true,
32521
+ deployedAt: true,
32522
+ bookmarkCapturedAt: true,
32523
+ isActive: true,
32524
+ resources: true
32525
+ }
32526
+ }),
32527
+ this.findSchemaHashState(game2.id)
32528
+ ]);
32529
+ if (isPushAdopted(state)) {
32530
+ return { restorePoints: [], restoreUnsupported: true };
32531
+ }
32532
+ if (!currentDatabaseId) {
32533
+ return { restorePoints: [], restoreUnsupported: false };
32534
+ }
32535
+ const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
32536
+ const restorable = rows.filter((row) => databaseIdFromResources(row.resources, deploymentId) === currentDatabaseId && restorePointCapturedAt(row) >= retentionCutoff).slice(0, 20);
32537
+ setAttributes({ "app.deployment_state.restore_points": restorable.length });
32538
+ return {
32539
+ restorePoints: restorable.map((row) => ({
32540
+ id: row.id,
32541
+ capturedAt: restorePointCapturedAt(row).toISOString(),
32542
+ active: row.isActive
32543
+ })),
32544
+ restoreUnsupported: false
32545
+ };
32546
+ }
32547
+ async restoreToBookmark(slug, input, user) {
32548
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32549
+ const cf = this.requireCloudflare();
32550
+ const [row, state, currentDatabaseId, runningJob] = await Promise.all([
32551
+ this.deps.db.query.gameDeployments.findFirst({
32552
+ where: and(eq(gameDeployments.id, input.restorePointId), eq(gameDeployments.gameId, game2.id), eq(gameDeployments.target, "game")),
32553
+ columns: {
32554
+ id: true,
32555
+ timeTravelBookmark: true,
32556
+ deployedAt: true,
32557
+ bookmarkCapturedAt: true,
32558
+ resources: true
32559
+ }
32560
+ }),
32561
+ this.findSchemaHashState(game2.id),
32562
+ this.findDatabaseId(slug, game2.id),
32563
+ this.deps.db.query.gameDeployJobs.findFirst({
32564
+ where: and(eq(gameDeployJobs.gameId, game2.id), or(eq(gameDeployJobs.status, "pending"), and(eq(gameDeployJobs.status, "running"), gt(gameDeployJobs.leaseExpiresAt, new Date)))),
32565
+ columns: { id: true }
32566
+ })
32567
+ ]);
32568
+ if (!row?.timeTravelBookmark) {
32569
+ throw new NotFoundError("Bookmark", input.restorePointId);
32570
+ }
32571
+ if (isPushAdopted(state)) {
32572
+ throw new ValidationError("Restore is not supported for push-mode projects: rewinding the " + "database would leave future push deploys diffing against the " + "wrong schema.", { code: DEPLOY_ERROR_CODES.restoreUnsupported });
32573
+ }
32574
+ if (!currentDatabaseId) {
32575
+ throw new ValidationError("Game has no deployed database — deploy with a database binding first");
32576
+ }
32577
+ const databaseId = currentDatabaseId;
32578
+ const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
32579
+ if (databaseIdFromResources(row.resources, deploymentId) !== databaseId) {
32580
+ throw new ValidationError("This bookmark was captured on a previous database (a reset replaced " + "it since) and can no longer be restored");
32581
+ }
32582
+ const retentionCutoff = new Date(Date.now() - D1_TIME_TRAVEL_RETENTION_DAYS * 24 * 60 * 60 * 1000);
32583
+ if (restorePointCapturedAt(row) < retentionCutoff) {
32584
+ throw new ValidationError(`This bookmark is older than Time Travel's ${D1_TIME_TRAVEL_RETENTION_DAYS}-day ` + "retention window and can no longer be restored.", { code: DEPLOY_ERROR_CODES.restoreExpired });
32585
+ }
32586
+ if (runningJob) {
32587
+ throw new ValidationError("A deploy is currently running for this game. Wait for it to finish, " + "then restore.", { code: DEPLOY_ERROR_CODES.restoreBlockedByDeploy });
32588
+ }
32589
+ const restored = await cf.d1.restoreBookmark(databaseId, row.timeTravelBookmark);
32590
+ const restoredTo = restorePointCapturedAt(row).toISOString();
32591
+ let live;
32592
+ let fingerprintRecorded;
32593
+ try {
32594
+ live = await cf.d1.fingerprintSchema(databaseId);
32595
+ fingerprintRecorded = await this.updateDeploymentState(game2.id, {
32596
+ schemaFingerprint: live.fingerprint,
32597
+ updatedAt: new Date
32598
+ });
32599
+ await this.deps.db.insert(gameDeployEvents).values({
32600
+ gameId: game2.id,
32601
+ userId: user.id,
32602
+ kind: "restore",
32603
+ payload: { restoredTo, previousBookmark: restored.previousBookmark }
32604
+ });
32605
+ } catch (error) {
32606
+ throw new ValidationError("The database WAS restored, but re-recording its schema " + `fingerprint failed (${errorMessage(error)}). Run the same ` + "restore again to complete it.", { code: DEPLOY_ERROR_CODES.restoreIncomplete });
32607
+ }
32608
+ addEvent("deployment_state.bookmark_restored", {
32609
+ "app.game.id": game2.id,
32610
+ "app.deployment_state.restore_point": row.id,
32611
+ "app.deployment_state.fingerprint_rerecorded": fingerprintRecorded,
32612
+ "app.user.id": user.id
32613
+ });
32614
+ return {
32615
+ restorePointId: row.id,
32616
+ restoredTo,
32617
+ schemaFingerprint: live.fingerprint,
32618
+ fingerprintRecorded,
32619
+ previousBookmark: restored.previousBookmark
32620
+ };
32621
+ }
32622
+ async reportDeployBlocked(slug, user, report) {
32623
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32624
+ const recent = await this.deps.db.query.gameDeployEvents.findMany({
32625
+ where: and(eq(gameDeployEvents.gameId, game2.id), eq(gameDeployEvents.kind, "blocked"), gt(gameDeployEvents.createdAt, new Date(Date.now() - BLOCKED_ALERT_DEDUP_MS))),
32626
+ orderBy: desc(gameDeployEvents.createdAt),
32627
+ limit: 10,
32628
+ columns: { payload: true }
32629
+ });
32630
+ const duplicate = recent.some((event) => ("code" in event.payload) && event.payload.code === report.code);
32631
+ await this.deps.db.insert(gameDeployEvents).values({
32632
+ gameId: game2.id,
32633
+ userId: user.id,
32634
+ kind: "blocked",
32635
+ payload: { code: report.code, reason: report.reason }
32636
+ });
32637
+ addEvent("deployment_state.deploy_blocked", {
32638
+ "app.game.id": game2.id,
32639
+ "app.deploy.blocked_code": report.code,
32640
+ "app.user.id": user.id,
32641
+ "app.alerts.deduped": duplicate
32642
+ });
32643
+ if (!duplicate) {
32644
+ await this.deps.alerts.notifyDeployBlocked({
32645
+ slug,
32646
+ displayName: game2.displayName,
32647
+ reason: report.reason,
32648
+ developer: { id: user.id, email: user.email ?? null }
32649
+ });
32650
+ }
32651
+ }
32652
+ }
32653
+ var BLOCKED_ALERT_DEDUP_MS;
32654
+ var init_deployment_state_service = __esm(() => {
32655
+ init_drizzle_orm();
32656
+ init_src4();
32657
+ init_src();
32658
+ init_helpers_index();
32659
+ init_tables_index();
32660
+ init_spans();
32661
+ init_game2();
32662
+ init_errors();
32663
+ init_baseline_validation_util();
32664
+ init_deployment_util();
32665
+ init_migration_util();
32666
+ init_secrets_util();
32667
+ BLOCKED_ALERT_DEDUP_MS = 10 * 60 * 1000;
32668
+ });
32669
+
30491
32670
  // ../api-core/src/services/domain.service.ts
30492
32671
  class DomainService {
30493
32672
  deps;
@@ -30854,6 +33033,7 @@ var init_kv_service = __esm(() => {
30854
33033
  // ../api-core/src/services/secrets.service.ts
30855
33034
  class SecretsService {
30856
33035
  deps;
33036
+ pepperPromise = null;
30857
33037
  constructor(deps) {
30858
33038
  this.deps = deps;
30859
33039
  }
@@ -30866,36 +33046,69 @@ class SecretsService {
30866
33046
  getGameDeploymentId(slug) {
30867
33047
  return getGameDeploymentId(slug, this.deps.config.sstStage);
30868
33048
  }
30869
- async listKeys(slug, user) {
30870
- await this.deps.validateDeveloperAccessBySlug(user, slug);
30871
- const cf = this.getCloudflare();
30872
- const deploymentId = this.getGameDeploymentId(slug);
30873
- try {
30874
- const allKeys = await cf.listSecrets(deploymentId);
30875
- const userKeys = allKeys.filter((k) => k.startsWith(SECRETS_PREFIX)).map((k) => k.slice(SECRETS_PREFIX.length));
30876
- setAttributes({
30877
- "app.secrets.operation": "list",
30878
- "app.secrets.count": userKeys.length,
30879
- "app.secrets.game_deployed": true
30880
- });
30881
- return userKeys;
30882
- } catch (error) {
30883
- const message = errorMessage(error);
30884
- if (message.includes("not found") || message.includes("10007")) {
33049
+ getPepper() {
33050
+ const pepperSecret = this.deps.config.secretsManifestPepper;
33051
+ if (!pepperSecret) {
33052
+ throw new ValidationError("Secrets manifest is not configured (missing manifest pepper secret)");
33053
+ }
33054
+ this.pepperPromise ??= deriveSecretsManifestPepper(pepperSecret);
33055
+ return this.pepperPromise;
33056
+ }
33057
+ async computeManifestEntries(gameId, secrets) {
33058
+ const pepper = await this.getPepper();
33059
+ const entries = {};
33060
+ for (const [key, value] of Object.entries(secrets)) {
33061
+ entries[key] = await computeSecretDigest(pepper, { gameId, key, value });
33062
+ }
33063
+ return entries;
33064
+ }
33065
+ async readManifest(gameId) {
33066
+ const state = await this.deps.db.query.gameDeploymentState.findFirst({
33067
+ where: eq(gameDeploymentState.gameId, gameId),
33068
+ columns: { secretsManifest: true }
33069
+ });
33070
+ return state?.secretsManifest ?? {};
33071
+ }
33072
+ async upsertManifestEntries(gameId, entries) {
33073
+ const merged = sql`coalesce(${gameDeploymentState.secretsManifest}, '{}'::jsonb) || ${JSON.stringify(entries)}::jsonb`;
33074
+ await this.deps.db.insert(gameDeploymentState).values({ gameId, secretsManifest: entries, updatedAt: new Date }).onConflictDoUpdate({
33075
+ target: gameDeploymentState.gameId,
33076
+ set: { secretsManifest: merged, updatedAt: new Date }
33077
+ });
33078
+ }
33079
+ async removeManifestKey(gameId, key) {
33080
+ await this.deps.db.update(gameDeploymentState).set({
33081
+ secretsManifest: sql`coalesce(${gameDeploymentState.secretsManifest}, '{}'::jsonb) - ${key}::text`,
33082
+ updatedAt: new Date
33083
+ }).where(eq(gameDeploymentState.gameId, gameId));
33084
+ }
33085
+ assertNoReservedKeys(keys, operation) {
33086
+ for (const key of keys) {
33087
+ if (INTERNAL_SECRET_KEYS.includes(key)) {
30885
33088
  setAttributes({
30886
- "app.secrets.operation": "list",
30887
- "app.secrets.count": 0,
30888
- "app.secrets.game_deployed": false
33089
+ "app.secrets.operation": operation,
33090
+ "app.secrets.reserved_key_rejected": true
30889
33091
  });
30890
- return [];
33092
+ throw new ValidationError(operation === "set" ? `Cannot set reserved secret "${key}"` : `Reserved secret "${key}" cannot be managed — remove it locally`);
30891
33093
  }
30892
- throw error;
30893
33094
  }
30894
33095
  }
30895
- async setSecrets(slug, newSecrets, user) {
33096
+ async listKeys(slug, user) {
30896
33097
  await this.deps.validateDeveloperAccessBySlug(user, slug);
30897
33098
  const cf = this.getCloudflare();
30898
33099
  const deploymentId = this.getGameDeploymentId(slug);
33100
+ const userKeys = await listUserSecretKeys(cf, deploymentId);
33101
+ setAttributes({
33102
+ "app.secrets.operation": "list",
33103
+ "app.secrets.count": userKeys?.length ?? 0,
33104
+ "app.secrets.game_deployed": userKeys !== null
33105
+ });
33106
+ return userKeys ?? [];
33107
+ }
33108
+ async setSecrets(slug, newSecrets, user) {
33109
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
33110
+ const cf = this.getCloudflare();
33111
+ const deploymentId = this.getGameDeploymentId(slug);
30899
33112
  const secretKeys = Object.keys(newSecrets);
30900
33113
  if (secretKeys.length === 0) {
30901
33114
  throw new ValidationError("At least one secret must be provided");
@@ -30904,14 +33117,9 @@ class SecretsService {
30904
33117
  if (typeof value !== "string") {
30905
33118
  throw new ValidationError(`Secret value for "${key}" must be a string`);
30906
33119
  }
30907
- if (INTERNAL_SECRET_KEYS.includes(key)) {
30908
- setAttributes({
30909
- "app.secrets.operation": "set",
30910
- "app.secrets.reserved_key_rejected": true
30911
- });
30912
- throw new ValidationError(`Cannot set reserved secret "${key}"`);
30913
- }
30914
33120
  }
33121
+ this.assertNoReservedKeys(secretKeys, "set");
33122
+ const manifestEntries = await this.computeManifestEntries(game2.id, newSecrets);
30915
33123
  try {
30916
33124
  const prefixedSecrets = {};
30917
33125
  for (const [key, value] of Object.entries(newSecrets)) {
@@ -30924,8 +33132,6 @@ class SecretsService {
30924
33132
  "app.secrets.game_deployed": true,
30925
33133
  "app.secrets.reserved_key_rejected": false
30926
33134
  });
30927
- const allKeys = await cf.listSecrets(deploymentId);
30928
- return allKeys.filter((k) => k.startsWith(SECRETS_PREFIX)).map((k) => k.slice(SECRETS_PREFIX.length));
30929
33135
  } catch (error) {
30930
33136
  const message = errorMessage(error);
30931
33137
  if (message.includes("not found") || message.includes("10007")) {
@@ -30937,6 +33143,9 @@ class SecretsService {
30937
33143
  }
30938
33144
  throw error;
30939
33145
  }
33146
+ await this.upsertManifestEntries(game2.id, manifestEntries);
33147
+ const allKeys = await cf.listSecrets(deploymentId);
33148
+ return allKeys.filter((k) => k.startsWith(SECRETS_PREFIX)).map((k) => k.slice(SECRETS_PREFIX.length));
30940
33149
  }
30941
33150
  async deleteSecret(slug, key, user) {
30942
33151
  if (INTERNAL_SECRET_KEYS.includes(key)) {
@@ -30946,19 +33155,25 @@ class SecretsService {
30946
33155
  });
30947
33156
  throw new ValidationError(`Cannot delete reserved secret "${key}"`);
30948
33157
  }
30949
- await this.deps.validateDeveloperAccessBySlug(user, slug);
33158
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
30950
33159
  const cf = this.getCloudflare();
30951
33160
  const deploymentId = this.getGameDeploymentId(slug);
33161
+ const manifest = await this.readManifest(game2.id);
33162
+ const managed = key in manifest;
30952
33163
  try {
30953
33164
  const prefixedKey = `${SECRETS_PREFIX}${key}`;
30954
33165
  const existingKeys = await cf.listSecrets(deploymentId);
30955
- if (!existingKeys.includes(prefixedKey)) {
33166
+ const onWorker = existingKeys.includes(prefixedKey);
33167
+ if (!onWorker && !managed) {
30956
33168
  throw new NotFoundError("Secret", key);
30957
33169
  }
30958
- await cf.deleteSecret(deploymentId, prefixedKey);
33170
+ if (onWorker) {
33171
+ await cf.deleteSecret(deploymentId, prefixedKey);
33172
+ }
30959
33173
  setAttributes({
30960
33174
  "app.secrets.operation": "delete",
30961
33175
  "app.secrets.game_deployed": true,
33176
+ "app.secrets.managed": managed,
30962
33177
  "app.secrets.reserved_key_rejected": false
30963
33178
  });
30964
33179
  } catch (error) {
@@ -30975,14 +33190,45 @@ class SecretsService {
30975
33190
  }
30976
33191
  throw error;
30977
33192
  }
33193
+ if (managed) {
33194
+ await this.removeManifestKey(game2.id, key);
33195
+ }
33196
+ }
33197
+ async diff(slug, localSecrets, user) {
33198
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
33199
+ const deploymentId = this.getGameDeploymentId(slug);
33200
+ this.assertNoReservedKeys(Object.keys(localSecrets), "diff");
33201
+ const [manifest, remoteKeys, localDigests] = await Promise.all([
33202
+ this.readManifest(game2.id),
33203
+ this.deps.cloudflare ? listUserSecretKeys(this.deps.cloudflare, deploymentId) : null,
33204
+ this.computeManifestEntries(game2.id, localSecrets)
33205
+ ]);
33206
+ const verdicts = computeSecretsDiff({
33207
+ localDigests,
33208
+ manifest,
33209
+ remoteKeys: remoteKeys ?? []
33210
+ });
33211
+ setAttributes({
33212
+ "app.secrets.operation": "diff",
33213
+ "app.secrets.game_deployed": remoteKeys !== null,
33214
+ "app.secrets.diff_added": verdicts.added.length,
33215
+ "app.secrets.diff_changed": verdicts.changed.length,
33216
+ "app.secrets.diff_unchanged": verdicts.unchanged.length,
33217
+ "app.secrets.diff_remote_only_managed": verdicts.remoteOnlyManaged.length,
33218
+ "app.secrets.diff_remote_only_unmanaged": verdicts.remoteOnlyUnmanaged.length
33219
+ });
33220
+ return verdicts;
30978
33221
  }
30979
33222
  }
30980
33223
  var INTERNAL_SECRET_KEYS;
30981
33224
  var init_secrets_service = __esm(() => {
33225
+ init_drizzle_orm();
30982
33226
  init_src();
33227
+ init_tables_index();
30983
33228
  init_spans();
30984
33229
  init_errors();
30985
33230
  init_deployment_util();
33231
+ init_secrets_util();
30986
33232
  INTERNAL_SECRET_KEYS = ["PLAYCADEMY_API_KEY", "GAME_ID", "PLAYCADEMY_BASE_URL"];
30987
33233
  });
30988
33234
  // ../edge-play/src/game/setup.ts
@@ -31520,7 +33766,10 @@ var init_emoji = __esm(() => {
31520
33766
  });
31521
33767
 
31522
33768
  // ../data/src/domains/game/schemas.ts
31523
- var HttpUrlSchema, GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, AddGameDashboardUserSchema, VerifyGameDashboardLoginSchema, AcceptGameDashboardInviteSchema, AcceptGameDashboardResetSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SeedRequestSchema, SchemaInfoSchema, DatabaseResetRequestSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployRequestSchema;
33769
+ function requestsBinding(binding) {
33770
+ return binding === true || Array.isArray(binding) && binding.length > 0;
33771
+ }
33772
+ var HttpUrlSchema, GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, InsertGameDeploymentStateSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, AddGameDashboardUserSchema, VerifyGameDashboardLoginSchema, AcceptGameDashboardInviteSchema, AcceptGameDashboardResetSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SecretsDiffRequestSchema, SeedRequestSchema, SchemaInfoSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployMigrationSchema, DeployDatabaseSchema, DatabaseResetDatabaseSchema, DatabaseResetRequestSchema, BaselineEvidenceSchema, DeployBaselineSchema, DeploymentStateBaselineSchema, MigrationRealignSchema, MigrationResolveSchema, DatabaseRestoreSchema, DeployBlockedReportSchema, DeployRequestSchema;
31524
33773
  var init_schemas2 = __esm(() => {
31525
33774
  init_drizzle_zod();
31526
33775
  init_esm();
@@ -31599,6 +33848,9 @@ var init_schemas2 = __esm(() => {
31599
33848
  InsertGameDeployJobSchema = createInsertSchema(gameDeployJobs, {
31600
33849
  status: exports_external.enum(deployJobStatusEnum.enumValues)
31601
33850
  });
33851
+ InsertGameDeploymentStateSchema = createInsertSchema(gameDeploymentState, {
33852
+ secretsManifest: exports_external.record(exports_external.string(), exports_external.string()).nullable().optional()
33853
+ });
31602
33854
  UpsertGameMetadataSchema = exports_external.object({
31603
33855
  displayName: exports_external.string().min(1),
31604
33856
  platform: exports_external.enum(gamePlatformEnum.enumValues),
@@ -31656,6 +33908,9 @@ var init_schemas2 = __esm(() => {
31656
33908
  hostname: exports_external.string().min(1).max(255)
31657
33909
  });
31658
33910
  SetSecretsRequestSchema = exports_external.record(exports_external.string().min(1), exports_external.string());
33911
+ SecretsDiffRequestSchema = exports_external.object({
33912
+ secrets: exports_external.record(exports_external.string().min(1), exports_external.string())
33913
+ });
31659
33914
  SeedRequestSchema = exports_external.object({
31660
33915
  code: exports_external.string().min(1, "Seed code is required"),
31661
33916
  secrets: exports_external.record(exports_external.string(), exports_external.string()).optional()
@@ -31664,9 +33919,6 @@ var init_schemas2 = __esm(() => {
31664
33919
  sql: exports_external.string(),
31665
33920
  hash: exports_external.string()
31666
33921
  });
31667
- DatabaseResetRequestSchema = exports_external.object({
31668
- schema: SchemaInfoSchema.optional()
31669
- });
31670
33922
  VerifyTokenSchema = exports_external.object({
31671
33923
  token: exports_external.string().min(1, "Token is required")
31672
33924
  });
@@ -31678,8 +33930,119 @@ var init_schemas2 = __esm(() => {
31678
33930
  metadata: exports_external.record(exports_external.unknown()).optional()
31679
33931
  }))
31680
33932
  });
33933
+ DeployMigrationSchema = exports_external.object({
33934
+ tag: exports_external.string().min(1),
33935
+ statements: exports_external.array(exports_external.string().min(1)).min(1),
33936
+ checksum: exports_external.string().min(1)
33937
+ });
33938
+ DeployDatabaseSchema = exports_external.discriminatedUnion("mode", [
33939
+ exports_external.object({
33940
+ mode: exports_external.literal("push"),
33941
+ sql: exports_external.string(),
33942
+ baselineHash: exports_external.string().nullable(),
33943
+ nextSnapshot: exports_external.record(exports_external.string(), exports_external.unknown()),
33944
+ nextHash: exports_external.string().min(1),
33945
+ acceptDataLoss: exports_external.boolean().optional()
33946
+ }),
33947
+ exports_external.object({
33948
+ mode: exports_external.literal("migrate"),
33949
+ migrations: exports_external.array(DeployMigrationSchema)
33950
+ })
33951
+ ]);
33952
+ DatabaseResetDatabaseSchema = exports_external.discriminatedUnion("mode", [
33953
+ exports_external.object({
33954
+ mode: exports_external.literal("push"),
33955
+ sql: exports_external.string(),
33956
+ nextSnapshot: exports_external.record(exports_external.string(), exports_external.unknown()),
33957
+ nextHash: exports_external.string().min(1)
33958
+ }),
33959
+ exports_external.object({
33960
+ mode: exports_external.literal("migrate"),
33961
+ migrations: exports_external.array(DeployMigrationSchema)
33962
+ })
33963
+ ]);
33964
+ DatabaseResetRequestSchema = exports_external.object({
33965
+ schema: SchemaInfoSchema.optional(),
33966
+ database: DatabaseResetDatabaseSchema.optional()
33967
+ }).refine((data) => !(data.schema && data.database), {
33968
+ message: "Send either the database payload or the legacy schema field, not both",
33969
+ path: ["database"]
33970
+ });
33971
+ BaselineEvidenceSchema = exports_external.array(exports_external.object({
33972
+ tag: exports_external.string().min(1),
33973
+ generatedAt: exports_external.string().min(1),
33974
+ createsTables: exports_external.array(exports_external.object({
33975
+ name: exports_external.string().min(1),
33976
+ columns: exports_external.array(exports_external.string())
33977
+ })),
33978
+ addsColumns: exports_external.array(exports_external.object({
33979
+ table: exports_external.string().min(1),
33980
+ column: exports_external.string().min(1)
33981
+ })),
33982
+ createsIndexes: exports_external.array(exports_external.string()),
33983
+ createsViews: exports_external.array(exports_external.string())
33984
+ })).optional();
33985
+ DeployBaselineSchema = exports_external.object({
33986
+ lastAppliedMigrationTag: exports_external.string().min(1).optional(),
33987
+ journal: exports_external.array(exports_external.object({
33988
+ tag: exports_external.string().min(1),
33989
+ checksum: exports_external.string().min(1)
33990
+ })).optional(),
33991
+ evidence: BaselineEvidenceSchema,
33992
+ schemaSnapshot: exports_external.unknown().optional(),
33993
+ schemaHash: exports_external.string().min(1).optional(),
33994
+ integrationsHash: exports_external.string().min(1).optional(),
33995
+ buildHash: exports_external.string().min(1).optional()
33996
+ }).refine((data) => !data.lastAppliedMigrationTag === !data.journal, {
33997
+ message: "lastAppliedMigrationTag and journal must be provided together",
33998
+ path: ["journal"]
33999
+ }).refine((data) => data.schemaSnapshot === undefined === !data.schemaHash, {
34000
+ message: "schemaSnapshot and schemaHash must be provided together",
34001
+ path: ["schemaHash"]
34002
+ }).refine((data) => Boolean(data.lastAppliedMigrationTag || data.schemaHash || data.integrationsHash || data.buildHash), {
34003
+ message: "A baseline must claim something — migration history, a schema snapshot, or artifact hashes",
34004
+ path: ["lastAppliedMigrationTag"]
34005
+ });
34006
+ DeploymentStateBaselineSchema = exports_external.object({
34007
+ lastAppliedMigrationTag: exports_external.string().min(1).optional(),
34008
+ journal: exports_external.array(exports_external.object({
34009
+ tag: exports_external.string().min(1),
34010
+ checksum: exports_external.string().min(1)
34011
+ })).optional(),
34012
+ schemaSnapshot: exports_external.unknown().optional(),
34013
+ schemaHash: exports_external.string().min(1).optional(),
34014
+ evidence: BaselineEvidenceSchema,
34015
+ allowUnverified: exports_external.boolean().optional()
34016
+ }).refine((data) => !data.lastAppliedMigrationTag === !data.journal, {
34017
+ message: "lastAppliedMigrationTag and journal must be provided together",
34018
+ path: ["journal"]
34019
+ }).refine((data) => data.schemaSnapshot === undefined === !data.schemaHash, {
34020
+ message: "schemaSnapshot and schemaHash must be provided together",
34021
+ path: ["schemaHash"]
34022
+ }).refine((data) => Boolean(data.lastAppliedMigrationTag) || Boolean(data.schemaHash), {
34023
+ message: "A baseline needs a migration claim, a schema snapshot, or both",
34024
+ path: ["lastAppliedMigrationTag"]
34025
+ });
34026
+ MigrationRealignSchema = exports_external.object({
34027
+ checksum: exports_external.string().min(1)
34028
+ });
34029
+ MigrationResolveSchema = exports_external.object({
34030
+ resolution: exports_external.enum(["applied", "rolled-back"]),
34031
+ checksum: exports_external.string().min(1).optional()
34032
+ }).refine((data) => data.resolution !== "applied" || Boolean(data.checksum), {
34033
+ message: "Resolving a migration as 'applied' requires its checksum",
34034
+ path: ["checksum"]
34035
+ });
34036
+ DatabaseRestoreSchema = exports_external.object({
34037
+ restorePointId: exports_external.string().uuid()
34038
+ });
34039
+ DeployBlockedReportSchema = exports_external.object({
34040
+ code: exports_external.string().regex(/^blocked:[a-z-]+$/).max(64),
34041
+ reason: exports_external.string().min(1).max(2000)
34042
+ });
31681
34043
  DeployRequestSchema = exports_external.object({
31682
34044
  target: exports_external.enum(deploymentTargetEnum.enumValues).optional().default("game"),
34045
+ deployId: exports_external.string().min(1).optional(),
31683
34046
  uploadToken: exports_external.string().optional(),
31684
34047
  code: exports_external.string().optional(),
31685
34048
  codeUploadToken: exports_external.string().optional(),
@@ -31706,6 +34069,11 @@ var init_schemas2 = __esm(() => {
31706
34069
  sql: exports_external.string(),
31707
34070
  hash: exports_external.string()
31708
34071
  }).optional(),
34072
+ database: DeployDatabaseSchema.optional(),
34073
+ baseline: DeployBaselineSchema.optional(),
34074
+ buildHash: exports_external.string().min(1).optional(),
34075
+ integrationsHash: exports_external.string().min(1).optional(),
34076
+ pruneSecrets: exports_external.array(exports_external.string().min(1)).optional(),
31709
34077
  metadata: exports_external.object({
31710
34078
  displayName: exports_external.string().optional(),
31711
34079
  description: exports_external.string().optional(),
@@ -31715,9 +34083,24 @@ var init_schemas2 = __esm(() => {
31715
34083
  }).refine((data) => !(data.code && data.codeUploadToken), {
31716
34084
  message: "Specify either code or codeUploadToken, not both",
31717
34085
  path: ["codeUploadToken"]
31718
- }).refine((data) => !(data.target === "dashboard" && (data.schema || data.bindings)), {
31719
- message: "Dashboard deployments cannot include schema or bindings — they attach to the game deployment’s existing resources",
34086
+ }).refine((data) => !(data.target === "dashboard" && (data.schema || data.bindings || data.database)), {
34087
+ message: "Dashboard deployments cannot include schema, database, or bindings — they attach to the game deployment’s existing resources",
31720
34088
  path: ["target"]
34089
+ }).refine((data) => !(data.target === "dashboard" && (data.baseline || data.pruneSecrets)), {
34090
+ message: "Dashboard deployments cannot adopt a baseline or prune secrets",
34091
+ path: ["target"]
34092
+ }).refine((data) => !(data.database && !data.deployId), {
34093
+ message: "deployId is required when a database payload is present",
34094
+ path: ["deployId"]
34095
+ }).refine((data) => !(data.database && data.schema), {
34096
+ message: "Send either the database payload or the legacy schema field, not both",
34097
+ path: ["database"]
34098
+ }).refine((data) => !(data.baseline && data.schema), {
34099
+ message: "The legacy schema field cannot ride a baseline-adopting deploy",
34100
+ path: ["baseline"]
34101
+ }).refine((data) => !(data.database && !requestsBinding(data.bindings?.database)), {
34102
+ message: "The database payload requires a database binding",
34103
+ path: ["database"]
31721
34104
  });
31722
34105
  });
31723
34106
 
@@ -75455,7 +77838,7 @@ var init_pure = __esm(() => {
75455
77838
  });
75456
77839
 
75457
77840
  // ../utils/src/index.ts
75458
- var init_src4 = __esm(() => {
77841
+ var init_src5 = __esm(() => {
75459
77842
  init_pure();
75460
77843
  });
75461
77844
 
@@ -77412,7 +79795,7 @@ var init_dist5 = __esm(async () => {
77412
79795
  init_spans();
77413
79796
  init_src();
77414
79797
  init_spans();
77415
- init_src4();
79798
+ init_src5();
77416
79799
  init_src();
77417
79800
  init_spans();
77418
79801
  init_spans();
@@ -77991,7 +80374,7 @@ function selectTimebackMetricDiscrepancyQueueItems(candidates, options) {
77991
80374
  }
77992
80375
  var DATE_INPUT_RE;
77993
80376
  var init_timeback_discrepancy_queue_util = __esm(() => {
77994
- init_src4();
80377
+ init_src5();
77995
80378
  init_timeback_util();
77996
80379
  DATE_INPUT_RE = /^\d{4}-\d{2}-\d{2}$/;
77997
80380
  });
@@ -80510,7 +82893,7 @@ var init_timeback_admin_service = __esm(async () => {
80510
82893
  init_constants3();
80511
82894
  init_types2();
80512
82895
  init_utils6();
80513
- init_src4();
82896
+ init_src5();
80514
82897
  init_timeback3();
80515
82898
  init_errors();
80516
82899
  init_timeback_admin_metrics_util();
@@ -82966,8 +85349,15 @@ function createPlatformServices(deps) {
82966
85349
  validateDeveloperAccess
82967
85350
  });
82968
85351
  const kv = new KVService({ db: db2, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
82969
- const secrets = new SecretsService({ config: config4, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
85352
+ const secrets = new SecretsService({ db: db2, config: config4, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
82970
85353
  const domain3 = new DomainService({ db: db2, cloudflare: cloudflare2, corsKvs, validateDeveloperAccessBySlug });
85354
+ const deploymentState = new DeploymentStateService({
85355
+ db: db2,
85356
+ config: config4,
85357
+ cloudflare: cloudflare2,
85358
+ alerts,
85359
+ validateDeveloperAccessBySlug
85360
+ });
82971
85361
  const database = new DatabaseService({
82972
85362
  db: db2,
82973
85363
  config: config4,
@@ -83006,6 +85396,7 @@ function createPlatformServices(deps) {
83006
85396
  kv,
83007
85397
  secrets,
83008
85398
  domain: domain3,
85399
+ deploymentState,
83009
85400
  database,
83010
85401
  seed,
83011
85402
  timeback: timeback2,
@@ -83016,6 +85407,7 @@ function createPlatformServices(deps) {
83016
85407
  var init_platform2 = __esm(async () => {
83017
85408
  init_bucket_service();
83018
85409
  init_database_service();
85410
+ init_deployment_state_service();
83019
85411
  init_domain_service();
83020
85412
  init_kv_service();
83021
85413
  init_secrets_service();
@@ -83748,7 +86140,7 @@ function createServices(ctx) {
83748
86140
  };
83749
86141
  }
83750
86142
  var init_factory = __esm(async () => {
83751
- init_game2();
86143
+ init_game3();
83752
86144
  init_infra2();
83753
86145
  init_player();
83754
86146
  init_standalone();
@@ -84055,6 +86447,7 @@ function buildConfig(options) {
84055
86447
  gameDomain: "localhost",
84056
86448
  uploadBucket: "sandbox-uploads",
84057
86449
  ltiTestMode: true,
86450
+ secretsManifestPepper: "sandbox-secrets-manifest-pepper",
84058
86451
  ...options.config
84059
86452
  });
84060
86453
  }
@@ -100996,7 +103389,7 @@ var __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf2,
100996
103389
  __defProp2(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
100997
103390
  }
100998
103391
  return to;
100999
- }, __toESM5 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod)), __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value), ANSI_BACKGROUND_OFFSET, wrapAnsi16, wrapAnsi256, wrapAnsi16m, styles2, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default, init_ansi_styles, env, flagForceColor, supportsColor, supports_color_default, init_supports_color, init_utilities, stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles22, applyOptions, chalkFactory, getModelAnsi, usedModels, proto, createStyler, createBuilder, applyStyle, chalk, chalkStderr, source_default, init_source, require_old, require_fs, require_path, require_balanced_match, require_brace_expansion, require_minimatch, require_inherits_browser2, require_inherits2, require_common3, require_sync, require_wrappy, require_once, require_inflight, require_glob, require_readline, require_src3, require_utils4, require_lodash, require_hanji, originUUID, snapshotVersion, mapValues, mapKeys, mapEntries, customMapEntries, init_global2, util3, objectUtil2, ZodParsedType2, getParsedType4, init_util4, ZodIssueCode4, ZodError5, init_ZodError2, errorMap2, en_default4, init_en4, overrideErrorMap2, init_errors9, makeIssue2, ParseStatus2, INVALID3, DIRTY2, OK2, isAborted2, isDirty2, isValid2, isAsync2, init_parseUtil2, init_typeAliases2, errorUtil2, init_errorUtil2, ParseInputLazyPath2, handleResult2, ZodType4, cuidRegex2, cuid2Regex2, ulidRegex2, uuidRegex2, nanoidRegex2, jwtRegex2, durationRegex2, emailRegex2, _emojiRegex2, emojiRegex2, ipv4Regex2, ipv4CidrRegex2, ipv6Regex2, ipv6CidrRegex2, base64Regex2, base64urlRegex2, dateRegexSource2, dateRegex2, ZodString4, ZodNumber4, ZodBigInt4, ZodBoolean4, ZodDate4, ZodSymbol4, ZodUndefined4, ZodNull4, ZodAny4, ZodUnknown4, ZodNever4, ZodVoid4, ZodArray4, ZodObject4, ZodUnion4, getDiscriminator2, ZodDiscriminatedUnion4, ZodIntersection4, ZodTuple4, ZodRecord4, ZodMap4, ZodSet4, ZodFunction3, ZodLazy4, ZodLiteral4, ZodEnum4, ZodNativeEnum2, ZodPromise4, ZodEffects2, ZodOptional4, ZodNullable4, ZodDefault4, ZodCatch4, ZodNaN4, BRAND2, ZodBranded2, ZodPipeline2, ZodReadonly4, late2, ZodFirstPartyTypeKind3, stringType2, numberType2, nanType2, bigIntType2, booleanType2, dateType2, symbolType2, undefinedType2, nullType2, anyType2, unknownType2, neverType2, voidType2, arrayType2, objectType2, strictObjectType2, unionType2, discriminatedUnionType2, intersectionType2, tupleType2, recordType2, mapType2, setType2, functionType2, lazyType2, literalType2, enumType2, nativeEnumType2, promiseType2, effectsType2, optionalType2, nullableType2, preprocessType2, pipelineType2, coerce2, init_types5, init_external4, init_v32, init_esm2, enumSchema, enumSchemaV1, indexColumn, index2, fk, sequenceSchema, roleSchema, sequenceSquashed, column2, checkConstraint, columnSquashed, compositePK, uniqueConstraint, policy, policySquashed, viewWithOption, matViewWithOption, mergedViewWithOption, view2, table8, schemaHash, kitInternals, gelSchemaExternal, gelSchemaInternal, tableSquashed, gelSchemaSquashed, gelSchema, dryGel, init_gelSchema, index22, fk2, column22, tableV3, compositePK2, uniqueConstraint2, checkConstraint2, tableV4, table22, viewMeta, view22, kitInternals2, dialect2, schemaHash2, schemaInternalV3, schemaInternalV4, schemaInternalV5, schemaInternal, schemaV3, schemaV4, schemaV5, schema2, tableSquashedV4, tableSquashed2, viewSquashed, schemaSquashed, schemaSquashedV4, MySqlSquasher, squashMysqlScheme, mysqlSchema, mysqlSchemaV5, mysqlSchemaSquashed, backwardCompatibleMysqlSchema, dryMySql, init_mysqlSchema, indexV2, columnV2, tableV2, enumSchemaV12, enumSchema2, pgSchemaV2, references, columnV1, tableV1, pgSchemaV1, indexColumn2, index3, indexV4, indexV5, indexV6, fk3, sequenceSchema2, roleSchema2, sequenceSquashed2, columnV7, column3, checkConstraint3, columnSquashed2, tableV32, compositePK3, uniqueConstraint3, policy2, policySquashed2, viewWithOption2, matViewWithOption2, mergedViewWithOption2, view3, tableV42, tableV5, tableV6, tableV7, table32, schemaHash3, kitInternals3, pgSchemaInternalV3, pgSchemaInternalV4, pgSchemaInternalV5, pgSchemaInternalV6, pgSchemaExternal, pgSchemaInternalV7, pgSchemaInternal, tableSquashed3, tableSquashedV42, pgSchemaSquashedV4, pgSchemaSquashedV6, pgSchemaSquashed, pgSchemaV3, pgSchemaV4, pgSchemaV5, pgSchemaV6, pgSchemaV7, pgSchema, backwardCompatiblePgSchema, PgSquasher, squashPgScheme, dryPg, init_pgSchema, index4, column4, compositePK4, uniqueConstraint4, table42, viewMeta2, kitInternals4, dialect22, schemaHash4, schemaInternal2, schema22, tableSquashed4, schemaSquashed2, SingleStoreSquasher, squashSingleStoreScheme, singlestoreSchema, singlestoreSchemaSquashed, backwardCompatibleSingleStoreSchema, drySingleStore, init_singlestoreSchema, index5, fk4, compositePK5, column5, tableV33, uniqueConstraint5, checkConstraint4, table52, view4, dialect3, schemaHash5, schemaInternalV32, schemaInternalV42, schemaInternalV52, kitInternals5, latestVersion, schemaInternal3, schemaV32, schemaV42, schemaV52, schema3, tableSquashed5, schemaSquashed3, SQLiteSquasher, squashSqliteScheme, drySQLite, sqliteSchemaV5, sqliteSchema, SQLiteSchemaSquashed, backwardCompatibleSqliteSchema, init_sqliteSchema, copy, prepareMigrationMeta, schemaRenameKey, tableRenameKey, columnRenameKey, init_utils7, import_hanji, warning, error88, isRenamePromptItem, ResolveColumnSelect, tableKey, ResolveSelectNamed, ResolveSelect, ResolveSchemasSelect, Spinner2, ProgressView, init_views, glob, init_serializer, fillPgSnapshot, init_migrationPreparator, require_heap, require_heap2, require_difflib, require_difflib2, require_util2, require_styles, require_has_flag2, require_supports_colors, require_trap, require_zalgo, require_america, require_zebra, require_rainbow, require_random, require_colors, require_safe, require_colorize, require_lib4, import_json_diff, mapArraysDiff, findAlternationsInTable, alternationsInColumn, init_jsonDiffer, parseType, Convertor, PgCreateRoleConvertor, PgDropRoleConvertor, PgRenameRoleConvertor, PgAlterRoleConvertor, PgCreatePolicyConvertor, PgDropPolicyConvertor, PgRenamePolicyConvertor, PgAlterPolicyConvertor, PgCreateIndPolicyConvertor, PgDropIndPolicyConvertor, PgRenameIndPolicyConvertor, PgAlterIndPolicyConvertor, PgEnableRlsConvertor, PgDisableRlsConvertor, PgCreateTableConvertor, MySqlCreateTableConvertor, SingleStoreCreateTableConvertor, SQLiteCreateTableConvertor, PgCreateViewConvertor, MySqlCreateViewConvertor, SqliteCreateViewConvertor, PgDropViewConvertor, MySqlDropViewConvertor, SqliteDropViewConvertor, MySqlAlterViewConvertor, PgRenameViewConvertor, MySqlRenameViewConvertor, PgAlterViewSchemaConvertor, PgAlterViewAddWithOptionConvertor, PgAlterViewDropWithOptionConvertor, PgAlterViewAlterTablespaceConvertor, PgAlterViewAlterUsingConvertor, PgAlterTableAlterColumnSetGenerated, PgAlterTableAlterColumnDropGenerated, PgAlterTableAlterColumnAlterGenerated, PgAlterTableAddUniqueConstraintConvertor, PgAlterTableDropUniqueConstraintConvertor, PgAlterTableAddCheckConstraintConvertor, PgAlterTableDeleteCheckConstraintConvertor, MySQLAlterTableAddUniqueConstraintConvertor, MySQLAlterTableDropUniqueConstraintConvertor, MySqlAlterTableAddCheckConstraintConvertor, SingleStoreAlterTableAddUniqueConstraintConvertor, SingleStoreAlterTableDropUniqueConstraintConvertor, MySqlAlterTableDeleteCheckConstraintConvertor, CreatePgSequenceConvertor, DropPgSequenceConvertor, RenamePgSequenceConvertor, MovePgSequenceConvertor, AlterPgSequenceConvertor, CreateTypeEnumConvertor, DropTypeEnumConvertor, AlterTypeAddValueConvertor, AlterTypeSetSchemaConvertor, AlterRenameTypeConvertor, AlterTypeDropValueConvertor, PgDropTableConvertor, MySQLDropTableConvertor, SingleStoreDropTableConvertor, SQLiteDropTableConvertor, PgRenameTableConvertor, SqliteRenameTableConvertor, MySqlRenameTableConvertor, SingleStoreRenameTableConvertor, PgAlterTableRenameColumnConvertor, MySqlAlterTableRenameColumnConvertor, SingleStoreAlterTableRenameColumnConvertor, SQLiteAlterTableRenameColumnConvertor, PgAlterTableDropColumnConvertor, MySqlAlterTableDropColumnConvertor, SingleStoreAlterTableDropColumnConvertor, SQLiteAlterTableDropColumnConvertor, PgAlterTableAddColumnConvertor, MySqlAlterTableAddColumnConvertor, SingleStoreAlterTableAddColumnConvertor, SQLiteAlterTableAddColumnConvertor, PgAlterTableAlterColumnSetTypeConvertor, PgAlterTableAlterColumnSetDefaultConvertor, PgAlterTableAlterColumnDropDefaultConvertor, PgAlterTableAlterColumnDropGeneratedConvertor, PgAlterTableAlterColumnSetExpressionConvertor, PgAlterTableAlterColumnAlterrGeneratedConvertor, SqliteAlterTableAlterColumnDropGeneratedConvertor, SqliteAlterTableAlterColumnSetExpressionConvertor, SqliteAlterTableAlterColumnAlterGeneratedConvertor, MySqlAlterTableAlterColumnAlterrGeneratedConvertor, MySqlAlterTableAddPk, MySqlAlterTableDropPk, LibSQLModifyColumn, MySqlModifyColumn, SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor, SingleStoreAlterTableAddPk, SingleStoreAlterTableDropPk, SingleStoreModifyColumn, PgAlterTableCreateCompositePrimaryKeyConvertor, PgAlterTableDeleteCompositePrimaryKeyConvertor, PgAlterTableAlterCompositePrimaryKeyConvertor, MySqlAlterTableCreateCompositePrimaryKeyConvertor, MySqlAlterTableDeleteCompositePrimaryKeyConvertor, MySqlAlterTableAlterCompositePrimaryKeyConvertor, PgAlterTableAlterColumnSetPrimaryKeyConvertor, PgAlterTableAlterColumnDropPrimaryKeyConvertor, PgAlterTableAlterColumnSetNotNullConvertor, PgAlterTableAlterColumnDropNotNullConvertor, PgCreateForeignKeyConvertor, LibSQLCreateForeignKeyConvertor, MySqlCreateForeignKeyConvertor, PgAlterForeignKeyConvertor, PgDeleteForeignKeyConvertor, MySqlDeleteForeignKeyConvertor, CreatePgIndexConvertor, CreateMySqlIndexConvertor, CreateSingleStoreIndexConvertor, CreateSqliteIndexConvertor, PgDropIndexConvertor, PgCreateSchemaConvertor, PgRenameSchemaConvertor, PgDropSchemaConvertor, PgAlterTableSetSchemaConvertor, PgAlterTableSetNewSchemaConvertor, PgAlterTableRemoveFromSchemaConvertor, SqliteDropIndexConvertor, MySqlDropIndexConvertor, SingleStoreDropIndexConvertor, SQLiteRecreateTableConvertor, LibSQLRecreateTableConvertor, SingleStoreRecreateTableConvertor, convertors, init_sqlgenerator, _moveDataStatements, getOldTableName, getNewTableName, logSuggestionsAndReturn, init_sqlitePushUtils, preparePgCreateTableJson, prepareMySqlCreateTableJson, prepareSingleStoreCreateTableJson, prepareSQLiteCreateTable, prepareDropTableJson, prepareRenameTableJson, prepareCreateEnumJson, prepareAddValuesToEnumJson, prepareDropEnumValues, prepareDropEnumJson, prepareMoveEnumJson, prepareRenameEnumJson, prepareCreateSequenceJson, prepareAlterSequenceJson, prepareDropSequenceJson, prepareMoveSequenceJson, prepareRenameSequenceJson, prepareCreateRoleJson, prepareAlterRoleJson, prepareDropRoleJson, prepareRenameRoleJson, prepareCreateSchemasJson, prepareRenameSchemasJson, prepareDeleteSchemasJson, prepareRenameColumns, _prepareDropColumns, _prepareAddColumns, _prepareSqliteAddColumns, prepareAlterColumnsMysql, preparePgAlterColumns, prepareSqliteAlterColumns, prepareRenamePolicyJsons, prepareRenameIndPolicyJsons, prepareCreatePolicyJsons, prepareCreateIndPolicyJsons, prepareDropPolicyJsons, prepareDropIndPolicyJsons, prepareAlterPolicyJson, prepareAlterIndPolicyJson, preparePgCreateIndexesJson, prepareCreateIndexesJson, prepareCreateReferencesJson, prepareLibSQLCreateReferencesJson, prepareDropReferencesJson, prepareLibSQLDropReferencesJson, prepareAlterReferencesJson, prepareDropIndexesJson, prepareAddCompositePrimaryKeySqlite, prepareDeleteCompositePrimaryKeySqlite, prepareAlterCompositePrimaryKeySqlite, prepareAddCompositePrimaryKeyPg, prepareDeleteCompositePrimaryKeyPg, prepareAlterCompositePrimaryKeyPg, prepareAddUniqueConstraintPg, prepareDeleteUniqueConstraintPg, prepareAddCheckConstraint, prepareDeleteCheckConstraint, prepareAddCompositePrimaryKeyMySql, prepareDeleteCompositePrimaryKeyMySql, prepareAlterCompositePrimaryKeyMySql, preparePgCreateViewJson, prepareMySqlCreateViewJson, prepareSqliteCreateViewJson, prepareDropViewJson, prepareRenameViewJson, preparePgAlterViewAlterSchemaJson, preparePgAlterViewAddWithOptionJson, preparePgAlterViewDropWithOptionJson, preparePgAlterViewAlterTablespaceJson, preparePgAlterViewAlterUsingJson, prepareMySqlAlterView, init_jsonStatements, prepareLibSQLRecreateTable, prepareSQLiteRecreateTable, libSQLCombineStatements, sqliteCombineStatements, prepareSingleStoreRecreateTable, singleStoreCombineStatements, init_statementCombiner, snapshotsDiffer_exports, makeChanged, makeSelfOrChanged, makePatched, makeSelfOrPatched, columnSchema, alteredColumnSchema, enumSchema3, changedEnumSchema, tableScheme, alteredTableScheme, alteredViewCommon, alteredPgViewSchema, alteredMySqlViewSchema, diffResultScheme, diffResultSchemeMysql, diffResultSchemeSingleStore, diffResultSchemeSQLite, schemaChangeFor, nameChangeFor, nameSchemaChangeFor, columnChangeFor, applyPgSnapshotsDiff, applyMysqlSnapshotsDiff, applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff, applyLibSQLSnapshotsDiff, init_snapshotsDiffer, init_words, dialects, dialect4, commonSquashedSchema, commonSchema, init_schemaValidator, sqliteDriversLiterals, postgresqlDriversLiterals, prefixes, prefix, casingTypes, casingType, sqliteDriver, postgresDriver, driver2, configMigrations, configCommonSchema, casing, introspectParams, configIntrospectCliSchema, configGenerateSchema, configPushSchema, init_common2, withStyle, init_outputs, import_hanji2, schemasResolver, tablesResolver, viewsResolver, mySqlViewsResolver, sqliteViewsResolver, sequencesResolver, roleResolver, policyResolver, indPolicyResolver, enumsResolver, columnsResolver, promptColumnsConflicts, promptNamedConflict, promptNamedWithSchemasConflict, promptSchemasConflict, BREAKPOINT, init_migrate, posixClasses, braceEscape, regexpEscape, rangesToString, parseClass, init_brace_expressions, escape, init_escape, unescape, init_unescape, import_brace_expansion, minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path, sep2, GLOBSTAR, plTypes, qmark, star, twoStarDot, twoStarNoDot, charSet, reSpecials, addPatternStartSet, filter, ext, defaults, braceExpand, MAX_PATTERN_LENGTH, assertValidPattern, makeRe, match2, globUnescape, globMagic, regExpEscape, Minimatch, init_mjs, entityKind2, hasOwnEntityKind2, init_entity2, _a3, Column2, init_column2, _a22, ColumnBuilder2, init_column_builder2, TableName2, init_table_utils2, _a32, ForeignKeyBuilder2, _a4, ForeignKey2, init_foreign_keys2, init_tracing_utils2, _a5, UniqueConstraintBuilder, _a6, UniqueOnConstraintBuilder, _a7, UniqueConstraint, init_unique_constraint2, init_array2, _a8, _b, PgColumnBuilder2, _a9, _b2, PgColumn2, _a10, _b3, ExtraConfigColumn2, _a11, IndexedColumn2, _a12, _b4, PgArrayBuilder2, _a13, _b5, _PgArray, PgArray2, init_common22, _a14, _b6, PgEnumObjectColumnBuilder2, _a15, _b7, PgEnumObjectColumn2, isPgEnumSym2, _a16, _b8, PgEnumColumnBuilder2, _a17, _b9, PgEnumColumn2, init_enum2, _a18, Subquery2, _a19, _b10, WithSubquery2, init_subquery2, version4, init_version2, otel2, rawTracer2, tracer2, init_tracing2, ViewBaseConfig2, init_view_common3, Schema2, Columns2, ExtraConfigColumns2, OriginalName2, BaseName2, IsAlias2, ExtraConfigBuilder2, IsDrizzleTable2, _a20, _b11, _c, _d, _e3, _f, _g, _h, _i, _j, Table2, init_table8, _a21, FakePrimitiveParam, _a222, StringChunk2, _a23, _SQL, SQL2, _a24, Name2, noopDecoder2, noopEncoder2, noopMapper2, _a25, Param2, _a26, Placeholder2, IsDrizzleView2, _a27, _b12, _c2, View3, init_sql3, _a28, ColumnAliasProxyHandler2, _a29, TableAliasProxyHandler2, _a30, RelationTableAliasProxyHandler, init_alias3, _a31, _b13, DrizzleError2, DrizzleQueryError, _a322, _b14, TransactionRollbackError2, init_errors22, _a33, ConsoleLogWriter2, _a34, DefaultLogger2, _a35, NoopLogger2, init_logger3, init_operations, _a36, _b15, QueryPromise2, init_query_promise2, textDecoder, init_utils22, _a37, _b16, PgIntColumnBaseBuilder2, init_int_common2, _a38, _b17, PgBigInt53Builder2, _a39, _b18, PgBigInt532, _a40, _b19, PgBigInt64Builder2, _a41, _b20, PgBigInt642, init_bigint2, _a42, _b21, PgBigSerial53Builder2, _a43, _b22, PgBigSerial532, _a44, _b23, PgBigSerial64Builder2, _a45, _b24, PgBigSerial642, init_bigserial2, _a46, _b25, PgBooleanBuilder2, _a47, _b26, PgBoolean2, init_boolean2, _a48, _b27, PgCharBuilder2, _a49, _b28, PgChar2, init_char2, _a50, _b29, PgCidrBuilder2, _a51, _b30, PgCidr2, init_cidr2, _a52, _b31, PgCustomColumnBuilder2, _a53, _b32, PgCustomColumn2, init_custom2, _a54, _b33, PgDateColumnBaseBuilder2, init_date_common2, _a55, _b34, PgDateBuilder2, _a56, _b35, PgDate2, _a57, _b36, PgDateStringBuilder2, _a58, _b37, PgDateString2, init_date2, _a59, _b38, PgDoublePrecisionBuilder2, _a60, _b39, PgDoublePrecision2, init_double_precision2, _a61, _b40, PgInetBuilder2, _a62, _b41, PgInet2, init_inet2, _a63, _b42, PgIntegerBuilder2, _a64, _b43, PgInteger2, init_integer2, _a65, _b44, PgIntervalBuilder2, _a66, _b45, PgInterval2, init_interval2, _a67, _b46, PgJsonBuilder2, _a68, _b47, PgJson2, init_json2, _a69, _b48, PgJsonbBuilder2, _a70, _b49, PgJsonb2, init_jsonb2, _a71, _b50, PgLineBuilder2, _a72, _b51, PgLineTuple2, _a73, _b52, PgLineABCBuilder2, _a74, _b53, PgLineABC2, init_line2, _a75, _b54, PgMacaddrBuilder2, _a76, _b55, PgMacaddr2, init_macaddr2, _a77, _b56, PgMacaddr8Builder2, _a78, _b57, PgMacaddr82, init_macaddr82, _a79, _b58, PgNumericBuilder2, _a80, _b59, PgNumeric2, _a81, _b60, PgNumericNumberBuilder2, _a82, _b61, PgNumericNumber2, _a83, _b62, PgNumericBigIntBuilder2, _a84, _b63, PgNumericBigInt2, init_numeric2, _a85, _b64, PgPointTupleBuilder2, _a86, _b65, PgPointTuple2, _a87, _b66, PgPointObjectBuilder2, _a88, _b67, PgPointObject2, init_point2, init_utils32, _a89, _b68, PgGeometryBuilder2, _a90, _b69, PgGeometry2, _a91, _b70, PgGeometryObjectBuilder2, _a92, _b71, PgGeometryObject2, init_geometry2, _a93, _b72, PgRealBuilder2, _a94, _b73, PgReal2, init_real2, _a95, _b74, PgSerialBuilder2, _a96, _b75, PgSerial2, init_serial2, _a97, _b76, PgSmallIntBuilder2, _a98, _b77, PgSmallInt2, init_smallint2, _a99, _b78, PgSmallSerialBuilder2, _a100, _b79, PgSmallSerial2, init_smallserial2, _a101, _b80, PgTextBuilder2, _a102, _b81, PgText2, init_text2, _a103, _b82, PgTimeBuilder2, _a104, _b83, PgTime2, init_time2, _a105, _b84, PgTimestampBuilder2, _a106, _b85, PgTimestamp2, _a107, _b86, PgTimestampStringBuilder2, _a108, _b87, PgTimestampString2, init_timestamp2, _a109, _b88, PgUUIDBuilder2, _a110, _b89, PgUUID2, init_uuid3, _a111, _b90, PgVarcharBuilder2, _a112, _b91, PgVarchar2, init_varchar2, _a113, _b92, PgBinaryVectorBuilder2, _a114, _b93, PgBinaryVector2, init_bit2, _a115, _b94, PgHalfVectorBuilder2, _a116, _b95, PgHalfVector2, init_halfvec2, _a117, _b96, PgSparseVectorBuilder2, _a118, _b97, PgSparseVector2, init_sparsevec2, _a119, _b98, PgVectorBuilder2, _a120, _b99, PgVector2, init_vector3, init_all2, InlineForeignKeys2, EnableRLS2, _a121, _b100, _c3, _d2, _e22, _f2, PgTable2, pgTable2, init_table22, _a122, PrimaryKeyBuilder2, _a123, PrimaryKey2, init_primary_keys2, eq2, ne4, gt3, gte2, lt4, lte2, init_conditions2, init_select3, init_expressions2, _a124, Relation2, _a125, Relations2, _a126, _b101, _One, One2, _a127, _b102, _Many, Many2, init_relations2, init_aggregate2, init_vector22, init_functions2, init_sql22, dist_exports, init_dist9, init_alias22, _a128, CheckBuilder, _a129, Check, init_checks6, init_columns2, _a130, _SelectionProxyHandler, SelectionProxyHandler2, init_selection_proxy2, _a131, IndexBuilderOn2, _a132, IndexBuilder2, _a133, Index2, init_indexes2, _a134, PgPolicy, init_policies2, PgViewConfig2, init_view_common22, _a135, CasingCache2, init_casing2, _a136, _b103, PgViewBase2, init_view_base2, _a137, PgDialect2, init_dialect2, _a138, TypedQueryBuilder2, init_query_builder3, _a139, PgSelectBuilder2, _a140, _b104, PgSelectQueryBuilderBase2, _a141, _b105, PgSelectBase2, getPgSetOperators2, union22, unionAll2, intersect2, intersectAll2, except2, exceptAll2, init_select22, _a142, QueryBuilder2, init_query_builder22, _a143, DefaultViewBuilderCore, _a144, _b106, ViewBuilder, _a145, _b107, ManualViewBuilder, _a146, MaterializedViewBuilderCore, _a147, _b108, MaterializedViewBuilder, _a148, _b109, ManualMaterializedViewBuilder, _a149, _b110, _c4, PgView2, PgMaterializedViewConfig2, _a150, _b111, _c5, PgMaterializedView, init_view2, init_utils42, _a151, _b112, PgDeleteBase2, init_delete2, _a152, PgInsertBuilder2, _a153, _b113, PgInsertBase2, init_insert2, _a154, _b114, PgRefreshMaterializedView2, init_refresh_materialized_view2, init_select_types, _a155, PgUpdateBuilder2, _a156, _b115, PgUpdateBase2, init_update2, init_query_builders2, _a157, _b116, _c6, _PgCountBuilder, PgCountBuilder2, init_count2, _a158, RelationalQueryBuilder2, _a159, _b117, PgRelationalQuery2, init_query2, _a160, _b118, PgRaw2, init_raw2, _a161, PgDatabase2, init_db2, _a162, PgRole, init_roles2, _a163, PgSequence, init_sequence2, _a164, PgSchema5, init_schema3, _a165, Cache, _a166, _b119, NoopCache, init_cache, _a167, PgPreparedQuery2, _a168, PgSession2, _a169, _b120, PgTransaction2, init_session3, init_subquery22, init_utils52, init_pg_core2, vectorOps, init_vector32, sqlToStr, init_utils62, indexName, generatePgSnapshot, trimChar, fromDatabase, defaultForColumn, getColumnsInfoQuery, init_pgSerializer, import_hanji4, Select, init_selector_ui, init_alias32, _a170, CheckBuilder2, _a171, Check2, init_checks22, _a172, ForeignKeyBuilder22, _a173, ForeignKey22, init_foreign_keys22, _a174, UniqueConstraintBuilder2, _a175, UniqueOnConstraintBuilder2, _a176, UniqueConstraint2, init_unique_constraint22, _a177, _b121, SQLiteColumnBuilder, _a178, _b122, SQLiteColumn, init_common3, _a179, _b123, SQLiteBigIntBuilder, _a180, _b124, SQLiteBigInt, _a181, _b125, SQLiteBlobJsonBuilder, _a182, _b126, SQLiteBlobJson, _a183, _b127, SQLiteBlobBufferBuilder, _a184, _b128, SQLiteBlobBuffer, init_blob, _a185, _b129, SQLiteCustomColumnBuilder, _a186, _b130, SQLiteCustomColumn, init_custom22, _a187, _b131, SQLiteBaseIntegerBuilder, _a188, _b132, SQLiteBaseInteger, _a189, _b133, SQLiteIntegerBuilder, _a190, _b134, SQLiteInteger, _a191, _b135, SQLiteTimestampBuilder, _a192, _b136, SQLiteTimestamp, _a193, _b137, SQLiteBooleanBuilder, _a194, _b138, SQLiteBoolean, init_integer22, _a195, _b139, SQLiteNumericBuilder, _a196, _b140, SQLiteNumeric, _a197, _b141, SQLiteNumericNumberBuilder, _a198, _b142, SQLiteNumericNumber, _a199, _b143, SQLiteNumericBigIntBuilder, _a200, _b144, SQLiteNumericBigInt, init_numeric22, _a201, _b145, SQLiteRealBuilder, _a202, _b146, SQLiteReal, init_real22, _a203, _b147, SQLiteTextBuilder, _a204, _b148, SQLiteText, _a205, _b149, SQLiteTextJsonBuilder, _a206, _b150, SQLiteTextJson, init_text22, init_columns22, init_all22, InlineForeignKeys22, _a207, _b151, _c7, _d3, _e32, SQLiteTable, sqliteTable, init_table32, _a208, IndexBuilderOn22, _a209, IndexBuilder22, _a210, Index4, init_indexes22, _a211, PrimaryKeyBuilder22, _a212, PrimaryKey22, init_primary_keys22, init_utils72, _a213, _b152, SQLiteDeleteBase, init_delete22, _a214, _b153, SQLiteViewBase, init_view_base22, _a215, SQLiteDialect, _a216, _b154, SQLiteSyncDialect, _a217, _b155, SQLiteAsyncDialect, init_dialect22, _a218, SQLiteSelectBuilder, _a219, _b156, SQLiteSelectQueryBuilderBase, _a220, _b157, SQLiteSelectBase, getSQLiteSetOperators, union32, unionAll22, intersect22, except22, init_select32, _a221, QueryBuilder22, init_query_builder32, _a2222, SQLiteInsertBuilder, _a223, _b158, SQLiteInsertBase, init_insert22, init_select_types2, _a224, SQLiteUpdateBuilder, _a225, _b159, SQLiteUpdateBase, init_update22, init_query_builders22, _a226, _b160, _c8, _SQLiteCountBuilder, SQLiteCountBuilder, init_count22, _a227, RelationalQueryBuilder22, _a228, _b161, SQLiteRelationalQuery, _a229, _b162, SQLiteSyncRelationalQuery, init_query22, _a230, _b163, SQLiteRaw, init_raw22, _a231, BaseSQLiteDatabase, init_db22, _a232, _b164, ExecuteResultSync, _a233, SQLitePreparedQuery, _a234, SQLiteSession, _a235, _b165, SQLiteTransaction, init_session22, init_subquery3, _a236, ViewBuilderCore, _a237, _b166, ViewBuilder2, _a238, _b167, ManualViewBuilder2, _a239, _b168, SQLiteView2, init_view22, init_sqlite_core, generateSqliteSnapshot, fromDatabase2, init_sqliteSerializer, getTablesFilterByExtensions, init_getTablesFilterByExtensions, init_alias4, _a240, CheckBuilder3, _a241, Check3, init_checks32, _a242, ForeignKeyBuilder3, _a243, ForeignKey3, init_foreign_keys3, _a244, UniqueConstraintBuilder3, _a245, UniqueOnConstraintBuilder3, _a246, UniqueConstraint3, init_unique_constraint3, _a247, _b169, MySqlColumnBuilder, _a248, _b170, MySqlColumn, _a249, _b171, MySqlColumnBuilderWithAutoIncrement, _a250, _b172, MySqlColumnWithAutoIncrement, init_common4, _a251, _b173, MySqlBigInt53Builder, _a252, _b174, MySqlBigInt53, _a253, _b175, MySqlBigInt64Builder, _a254, _b176, MySqlBigInt64, init_bigint22, _a255, _b177, MySqlBinaryBuilder, _a256, _b178, MySqlBinary, init_binary, _a257, _b179, MySqlBooleanBuilder, _a258, _b180, MySqlBoolean, init_boolean22, _a259, _b181, MySqlCharBuilder, _a260, _b182, MySqlChar, init_char22, _a261, _b183, MySqlCustomColumnBuilder, _a262, _b184, MySqlCustomColumn, init_custom3, _a263, _b185, MySqlDateBuilder, _a264, _b186, MySqlDate, _a265, _b187, MySqlDateStringBuilder, _a266, _b188, MySqlDateString, init_date22, _a267, _b189, MySqlDateTimeBuilder, _a268, _b190, MySqlDateTime, _a269, _b191, MySqlDateTimeStringBuilder, _a270, _b192, MySqlDateTimeString, init_datetime, _a271, _b193, MySqlDecimalBuilder, _a272, _b194, MySqlDecimal, _a273, _b195, MySqlDecimalNumberBuilder, _a274, _b196, MySqlDecimalNumber, _a275, _b197, MySqlDecimalBigIntBuilder, _a276, _b198, MySqlDecimalBigInt, init_decimal, _a277, _b199, MySqlDoubleBuilder, _a278, _b200, MySqlDouble, init_double, _a279, _b201, MySqlEnumColumnBuilder, _a280, _b202, MySqlEnumColumn, _a281, _b203, MySqlEnumObjectColumnBuilder, _a282, _b204, MySqlEnumObjectColumn, init_enum22, _a283, _b205, MySqlFloatBuilder, _a284, _b206, MySqlFloat, init_float, _a285, _b207, MySqlIntBuilder, _a286, _b208, MySqlInt, init_int, _a287, _b209, MySqlJsonBuilder, _a288, _b210, MySqlJson, init_json22, _a289, _b211, MySqlMediumIntBuilder, _a290, _b212, MySqlMediumInt, init_mediumint, _a291, _b213, MySqlRealBuilder, _a292, _b214, MySqlReal, init_real3, _a293, _b215, MySqlSerialBuilder, _a294, _b216, MySqlSerial, init_serial22, _a295, _b217, MySqlSmallIntBuilder, _a296, _b218, MySqlSmallInt, init_smallint22, _a297, _b219, MySqlTextBuilder, _a298, _b220, MySqlText, init_text3, _a299, _b221, MySqlTimeBuilder, _a300, _b222, MySqlTime, init_time22, _a301, _b223, MySqlDateColumnBaseBuilder, _a302, _b224, MySqlDateBaseColumn, init_date_common22, _a303, _b225, MySqlTimestampBuilder, _a304, _b226, MySqlTimestamp, _a305, _b227, MySqlTimestampStringBuilder, _a306, _b228, MySqlTimestampString, init_timestamp22, _a307, _b229, MySqlTinyIntBuilder, _a308, _b230, MySqlTinyInt, init_tinyint, _a309, _b231, MySqlVarBinaryBuilder, _a310, _b232, MySqlVarBinary, init_varbinary, _a311, _b233, MySqlVarCharBuilder, _a312, _b234, MySqlVarChar, init_varchar22, _a313, _b235, MySqlYearBuilder, _a314, _b236, MySqlYear, init_year, init_columns3, _a315, _b237, _c9, _MySqlCountBuilder, MySqlCountBuilder, init_count3, _a316, IndexBuilderOn3, _a317, IndexBuilder3, _a318, Index5, init_indexes3, init_all3, InlineForeignKeys3, _a319, _b238, _c10, _d4, _e4, MySqlTable, mysqlTable, init_table42, _a320, PrimaryKeyBuilder3, _a321, PrimaryKey3, init_primary_keys3, MySqlViewConfig, init_view_common32, init_utils8, _a3222, _b239, MySqlDeleteBase, init_delete3, _a323, _b240, MySqlViewBase, init_view_base3, _a324, MySqlDialect, init_dialect3, _a325, MySqlSelectBuilder, _a326, _b241, MySqlSelectQueryBuilderBase, _a327, _b242, MySqlSelectBase, getMySqlSetOperators, union4, unionAll3, intersect3, intersectAll22, except3, exceptAll22, init_select4, _a328, QueryBuilder3, init_query_builder4, _a329, MySqlInsertBuilder, _a330, _b243, MySqlInsertBase, init_insert3, init_select_types3, _a331, MySqlUpdateBuilder, _a332, _b244, MySqlUpdateBase, init_update3, init_query_builders3, _a333, RelationalQueryBuilder3, _a334, _b245, MySqlRelationalQuery, init_query3, _a335, MySqlDatabase, init_db3, _a336, ViewBuilderCore2, _a337, _b246, ViewBuilder3, _a338, _b247, ManualViewBuilder3, _a339, _b248, _c11, MySqlView2, init_view3, _a340, MySqlSchema5, init_schema22, _a341, MySqlPreparedQuery, _a342, MySqlSession, _a343, _b249, MySqlTransaction, init_session32, init_subquery4, init_mysql_core, handleEnumType, generateMySqlSnapshot, fromDatabase3, init_mysqlSerializer, cliConfigGenerate, pushParams, pullParams, configCheck, cliConfigCheck, init_cli, gelCredentials, init_gel, libSQLCredentials, init_libsql, mysqlCredentials, init_mysql, postgresCredentials, init_postgres, singlestoreCredentials, init_singlestore, sqliteCredentials, init_sqlite, credentials, studioCliParams, studioConfig, init_studio, es5_exports, _3, es5_default, init_es5, import_hanji7, assertES5, safeRegister, migrateConfig, init_utils9, prepareFromExports, init_pgImports, init_alias5, _a344, UniqueConstraintBuilder4, _a345, UniqueOnConstraintBuilder4, _a346, UniqueConstraint4, init_unique_constraint4, _a347, _b250, SingleStoreColumnBuilder, _a348, _b251, SingleStoreColumn, _a349, _b252, SingleStoreColumnBuilderWithAutoIncrement, _a350, _b253, SingleStoreColumnWithAutoIncrement, init_common5, _a351, _b254, SingleStoreBigInt53Builder, _a352, _b255, SingleStoreBigInt53, _a353, _b256, SingleStoreBigInt64Builder, _a354, _b257, SingleStoreBigInt64, init_bigint3, _a355, _b258, SingleStoreBinaryBuilder, _a356, _b259, SingleStoreBinary, init_binary2, _a357, _b260, SingleStoreBooleanBuilder, _a358, _b261, SingleStoreBoolean, init_boolean3, _a359, _b262, SingleStoreCharBuilder, _a360, _b263, SingleStoreChar, init_char3, _a361, _b264, SingleStoreCustomColumnBuilder, _a362, _b265, SingleStoreCustomColumn, init_custom4, _a363, _b266, SingleStoreDateBuilder, _a364, _b267, SingleStoreDate, _a365, _b268, SingleStoreDateStringBuilder, _a366, _b269, SingleStoreDateString, init_date3, _a367, _b270, SingleStoreDateTimeBuilder, _a368, _b271, SingleStoreDateTime, _a369, _b272, SingleStoreDateTimeStringBuilder, _a370, _b273, SingleStoreDateTimeString, init_datetime2, _a371, _b274, SingleStoreDecimalBuilder, _a372, _b275, SingleStoreDecimal, _a373, _b276, SingleStoreDecimalNumberBuilder, _a374, _b277, SingleStoreDecimalNumber, _a375, _b278, SingleStoreDecimalBigIntBuilder, _a376, _b279, SingleStoreDecimalBigInt, init_decimal2, _a377, _b280, SingleStoreDoubleBuilder, _a378, _b281, SingleStoreDouble, init_double2, _a379, _b282, SingleStoreEnumColumnBuilder, _a380, _b283, SingleStoreEnumColumn, init_enum3, _a381, _b284, SingleStoreFloatBuilder, _a382, _b285, SingleStoreFloat, init_float2, _a383, _b286, SingleStoreIntBuilder, _a384, _b287, SingleStoreInt, init_int2, _a385, _b288, SingleStoreJsonBuilder, _a386, _b289, SingleStoreJson, init_json3, _a387, _b290, SingleStoreMediumIntBuilder, _a388, _b291, SingleStoreMediumInt, init_mediumint2, _a389, _b292, SingleStoreRealBuilder, _a390, _b293, SingleStoreReal, init_real4, _a391, _b294, SingleStoreSerialBuilder, _a392, _b295, SingleStoreSerial, init_serial3, _a393, _b296, SingleStoreSmallIntBuilder, _a394, _b297, SingleStoreSmallInt, init_smallint3, _a395, _b298, SingleStoreTextBuilder, _a396, _b299, SingleStoreText, init_text4, _a397, _b300, SingleStoreTimeBuilder, _a398, _b301, SingleStoreTime, init_time3, _a399, _b302, SingleStoreDateColumnBaseBuilder, _a400, _b303, SingleStoreDateBaseColumn, init_date_common3, _a401, _b304, SingleStoreTimestampBuilder, _a402, _b305, SingleStoreTimestamp, _a403, _b306, SingleStoreTimestampStringBuilder, _a404, _b307, SingleStoreTimestampString, init_timestamp3, _a405, _b308, SingleStoreTinyIntBuilder, _a406, _b309, SingleStoreTinyInt, init_tinyint2, _a407, _b310, SingleStoreVarBinaryBuilder, _a408, _b311, SingleStoreVarBinary, init_varbinary2, _a409, _b312, SingleStoreVarCharBuilder, _a410, _b313, SingleStoreVarChar, init_varchar3, _a411, _b314, SingleStoreVectorBuilder, _a412, _b315, SingleStoreVector, init_vector4, _a413, _b316, SingleStoreYearBuilder, _a414, _b317, SingleStoreYear, init_year2, init_columns4, _a415, _b318, _c12, _SingleStoreCountBuilder, SingleStoreCountBuilder, init_count4, _a416, IndexBuilderOn4, _a417, IndexBuilder4, _a418, Index6, init_indexes4, init_all4, _a419, _b319, _c13, _d5, SingleStoreTable, init_table52, _a420, PrimaryKeyBuilder4, _a421, PrimaryKey4, init_primary_keys4, init_utils10, _a422, _b320, SingleStoreDeleteBase, init_delete4, _a423, SingleStoreInsertBuilder, _a424, _b321, SingleStoreInsertBase, init_insert4, _a425, SingleStoreDialect, init_dialect4, _a426, SingleStoreSelectBuilder, _a427, _b322, SingleStoreSelectQueryBuilderBase, _a428, _b323, SingleStoreSelectBase, getSingleStoreSetOperators, union5, unionAll4, intersect4, except4, minus, init_select5, _a429, QueryBuilder4, init_query_builder5, init_select_types4, _a430, SingleStoreUpdateBuilder, _a431, _b324, SingleStoreUpdateBase, init_update4, init_query_builders4, _a432, SingleStoreDatabase, init_db4, _a433, SingleStoreSchema5, init_schema32, _a434, SingleStorePreparedQuery, _a435, SingleStoreSession, _a436, _b325, SingleStoreTransaction, init_session4, init_subquery5, init_singlestore_core, dialect5, generateSingleStoreSnapshot, fromDatabase4, init_singlestoreSerializer, sqliteImports_exports, prepareFromExports2, prepareFromSqliteImports, init_sqliteImports, mysqlImports_exports, prepareFromExports3, prepareFromMySqlImports, init_mysqlImports, mysqlPushUtils_exports, import_hanji8, filterStatements, logSuggestionsAndReturn2, init_mysqlPushUtils, mysqlIntrospect_exports, import_hanji9, mysqlPushIntrospect, init_mysqlIntrospect, singlestoreImports_exports, prepareFromExports4, prepareFromSingleStoreImports, init_singlestoreImports, singlestorePushUtils_exports, import_hanji10, filterStatements2, logSuggestionsAndReturn3, init_singlestorePushUtils, singlestoreIntrospect_exports, import_hanji11, singlestorePushIntrospect, init_singlestoreIntrospect, import_hanji3, pgPushIntrospect = async (db2, filters, schemaFilters, entities, tsSchema) => {
103392
+ }, __toESM5 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod)), __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value), ANSI_BACKGROUND_OFFSET, wrapAnsi16, wrapAnsi256, wrapAnsi16m, styles2, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default, init_ansi_styles, env, flagForceColor, supportsColor, supports_color_default, init_supports_color, init_utilities, stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles22, applyOptions, chalkFactory, getModelAnsi, usedModels, proto, createStyler, createBuilder, applyStyle, chalk, chalkStderr, source_default, init_source, require_old, require_fs, require_path, require_balanced_match, require_brace_expansion, require_minimatch, require_inherits_browser2, require_inherits2, require_common3, require_sync, require_wrappy, require_once, require_inflight, require_glob, require_readline, require_src3, require_utils4, require_lodash, require_hanji, originUUID, snapshotVersion, mapValues, mapKeys, mapEntries, customMapEntries, init_global2, util3, objectUtil2, ZodParsedType2, getParsedType4, init_util4, ZodIssueCode4, ZodError5, init_ZodError2, errorMap2, en_default4, init_en4, overrideErrorMap2, init_errors9, makeIssue2, ParseStatus2, INVALID3, DIRTY2, OK2, isAborted2, isDirty2, isValid2, isAsync2, init_parseUtil2, init_typeAliases2, errorUtil2, init_errorUtil2, ParseInputLazyPath2, handleResult2, ZodType4, cuidRegex2, cuid2Regex2, ulidRegex2, uuidRegex2, nanoidRegex2, jwtRegex2, durationRegex2, emailRegex2, _emojiRegex2, emojiRegex2, ipv4Regex2, ipv4CidrRegex2, ipv6Regex2, ipv6CidrRegex2, base64Regex2, base64urlRegex2, dateRegexSource2, dateRegex2, ZodString4, ZodNumber4, ZodBigInt4, ZodBoolean4, ZodDate4, ZodSymbol4, ZodUndefined4, ZodNull4, ZodAny4, ZodUnknown4, ZodNever4, ZodVoid4, ZodArray4, ZodObject4, ZodUnion4, getDiscriminator2, ZodDiscriminatedUnion4, ZodIntersection4, ZodTuple4, ZodRecord4, ZodMap4, ZodSet4, ZodFunction3, ZodLazy4, ZodLiteral4, ZodEnum4, ZodNativeEnum2, ZodPromise4, ZodEffects2, ZodOptional4, ZodNullable4, ZodDefault4, ZodCatch4, ZodNaN4, BRAND2, ZodBranded2, ZodPipeline2, ZodReadonly4, late2, ZodFirstPartyTypeKind3, stringType2, numberType2, nanType2, bigIntType2, booleanType2, dateType2, symbolType2, undefinedType2, nullType2, anyType2, unknownType2, neverType2, voidType2, arrayType2, objectType2, strictObjectType2, unionType2, discriminatedUnionType2, intersectionType2, tupleType2, recordType2, mapType2, setType2, functionType2, lazyType2, literalType2, enumType2, nativeEnumType2, promiseType2, effectsType2, optionalType2, nullableType2, preprocessType2, pipelineType2, coerce2, init_types5, init_external4, init_v32, init_esm2, enumSchema, enumSchemaV1, indexColumn, index2, fk, sequenceSchema, roleSchema, sequenceSquashed, column2, checkConstraint, columnSquashed, compositePK, uniqueConstraint, policy, policySquashed, viewWithOption, matViewWithOption, mergedViewWithOption, view2, table8, schemaHash, kitInternals, gelSchemaExternal, gelSchemaInternal, tableSquashed, gelSchemaSquashed, gelSchema, dryGel, init_gelSchema, index22, fk2, column22, tableV3, compositePK2, uniqueConstraint2, checkConstraint2, tableV4, table22, viewMeta, view22, kitInternals2, dialect2, schemaHash2, schemaInternalV3, schemaInternalV4, schemaInternalV5, schemaInternal, schemaV3, schemaV4, schemaV5, schema2, tableSquashedV4, tableSquashed2, viewSquashed, schemaSquashed, schemaSquashedV4, MySqlSquasher, squashMysqlScheme, mysqlSchema, mysqlSchemaV5, mysqlSchemaSquashed, backwardCompatibleMysqlSchema, dryMySql, init_mysqlSchema, indexV2, columnV2, tableV2, enumSchemaV12, enumSchema2, pgSchemaV2, references, columnV1, tableV1, pgSchemaV1, indexColumn2, index3, indexV4, indexV5, indexV6, fk3, sequenceSchema2, roleSchema2, sequenceSquashed2, columnV7, column3, checkConstraint3, columnSquashed2, tableV32, compositePK3, uniqueConstraint3, policy2, policySquashed2, viewWithOption2, matViewWithOption2, mergedViewWithOption2, view3, tableV42, tableV5, tableV6, tableV7, table32, schemaHash3, kitInternals3, pgSchemaInternalV3, pgSchemaInternalV4, pgSchemaInternalV5, pgSchemaInternalV6, pgSchemaExternal, pgSchemaInternalV7, pgSchemaInternal, tableSquashed3, tableSquashedV42, pgSchemaSquashedV4, pgSchemaSquashedV6, pgSchemaSquashed, pgSchemaV3, pgSchemaV4, pgSchemaV5, pgSchemaV6, pgSchemaV7, pgSchema, backwardCompatiblePgSchema, PgSquasher, squashPgScheme, dryPg, init_pgSchema, index4, column4, compositePK4, uniqueConstraint4, table42, viewMeta2, kitInternals4, dialect22, schemaHash4, schemaInternal2, schema22, tableSquashed4, schemaSquashed2, SingleStoreSquasher, squashSingleStoreScheme, singlestoreSchema, singlestoreSchemaSquashed, backwardCompatibleSingleStoreSchema, drySingleStore, init_singlestoreSchema, index5, fk4, compositePK5, column5, tableV33, uniqueConstraint5, checkConstraint4, table52, view4, dialect3, schemaHash5, schemaInternalV32, schemaInternalV42, schemaInternalV52, kitInternals5, latestVersion, schemaInternal3, schemaV32, schemaV42, schemaV52, schema3, tableSquashed5, schemaSquashed3, SQLiteSquasher, squashSqliteScheme, drySQLite, sqliteSchemaV5, sqliteSchema, SQLiteSchemaSquashed, backwardCompatibleSqliteSchema, init_sqliteSchema, copy, prepareMigrationMeta, schemaRenameKey, tableRenameKey, columnRenameKey, init_utils7, import_hanji, warning, error88, isRenamePromptItem, ResolveColumnSelect, tableKey, ResolveSelectNamed, ResolveSelect, ResolveSchemasSelect, Spinner2, ProgressView, init_views, glob, init_serializer, fillPgSnapshot, init_migrationPreparator, require_heap, require_heap2, require_difflib, require_difflib2, require_util2, require_styles, require_has_flag2, require_supports_colors, require_trap, require_zalgo, require_america, require_zebra, require_rainbow, require_random, require_colors, require_safe, require_colorize, require_lib4, import_json_diff, mapArraysDiff, findAlternationsInTable, alternationsInColumn, init_jsonDiffer, parseType, Convertor, PgCreateRoleConvertor, PgDropRoleConvertor, PgRenameRoleConvertor, PgAlterRoleConvertor, PgCreatePolicyConvertor, PgDropPolicyConvertor, PgRenamePolicyConvertor, PgAlterPolicyConvertor, PgCreateIndPolicyConvertor, PgDropIndPolicyConvertor, PgRenameIndPolicyConvertor, PgAlterIndPolicyConvertor, PgEnableRlsConvertor, PgDisableRlsConvertor, PgCreateTableConvertor, MySqlCreateTableConvertor, SingleStoreCreateTableConvertor, SQLiteCreateTableConvertor, PgCreateViewConvertor, MySqlCreateViewConvertor, SqliteCreateViewConvertor, PgDropViewConvertor, MySqlDropViewConvertor, SqliteDropViewConvertor, MySqlAlterViewConvertor, PgRenameViewConvertor, MySqlRenameViewConvertor, PgAlterViewSchemaConvertor, PgAlterViewAddWithOptionConvertor, PgAlterViewDropWithOptionConvertor, PgAlterViewAlterTablespaceConvertor, PgAlterViewAlterUsingConvertor, PgAlterTableAlterColumnSetGenerated, PgAlterTableAlterColumnDropGenerated, PgAlterTableAlterColumnAlterGenerated, PgAlterTableAddUniqueConstraintConvertor, PgAlterTableDropUniqueConstraintConvertor, PgAlterTableAddCheckConstraintConvertor, PgAlterTableDeleteCheckConstraintConvertor, MySQLAlterTableAddUniqueConstraintConvertor, MySQLAlterTableDropUniqueConstraintConvertor, MySqlAlterTableAddCheckConstraintConvertor, SingleStoreAlterTableAddUniqueConstraintConvertor, SingleStoreAlterTableDropUniqueConstraintConvertor, MySqlAlterTableDeleteCheckConstraintConvertor, CreatePgSequenceConvertor, DropPgSequenceConvertor, RenamePgSequenceConvertor, MovePgSequenceConvertor, AlterPgSequenceConvertor, CreateTypeEnumConvertor, DropTypeEnumConvertor, AlterTypeAddValueConvertor, AlterTypeSetSchemaConvertor, AlterRenameTypeConvertor, AlterTypeDropValueConvertor, PgDropTableConvertor, MySQLDropTableConvertor, SingleStoreDropTableConvertor, SQLiteDropTableConvertor, PgRenameTableConvertor, SqliteRenameTableConvertor, MySqlRenameTableConvertor, SingleStoreRenameTableConvertor, PgAlterTableRenameColumnConvertor, MySqlAlterTableRenameColumnConvertor, SingleStoreAlterTableRenameColumnConvertor, SQLiteAlterTableRenameColumnConvertor, PgAlterTableDropColumnConvertor, MySqlAlterTableDropColumnConvertor, SingleStoreAlterTableDropColumnConvertor, SQLiteAlterTableDropColumnConvertor, PgAlterTableAddColumnConvertor, MySqlAlterTableAddColumnConvertor, SingleStoreAlterTableAddColumnConvertor, SQLiteAlterTableAddColumnConvertor, PgAlterTableAlterColumnSetTypeConvertor, PgAlterTableAlterColumnSetDefaultConvertor, PgAlterTableAlterColumnDropDefaultConvertor, PgAlterTableAlterColumnDropGeneratedConvertor, PgAlterTableAlterColumnSetExpressionConvertor, PgAlterTableAlterColumnAlterrGeneratedConvertor, SqliteAlterTableAlterColumnDropGeneratedConvertor, SqliteAlterTableAlterColumnSetExpressionConvertor, SqliteAlterTableAlterColumnAlterGeneratedConvertor, MySqlAlterTableAlterColumnAlterrGeneratedConvertor, MySqlAlterTableAddPk, MySqlAlterTableDropPk, LibSQLModifyColumn, MySqlModifyColumn, SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor, SingleStoreAlterTableAddPk, SingleStoreAlterTableDropPk, SingleStoreModifyColumn, PgAlterTableCreateCompositePrimaryKeyConvertor, PgAlterTableDeleteCompositePrimaryKeyConvertor, PgAlterTableAlterCompositePrimaryKeyConvertor, MySqlAlterTableCreateCompositePrimaryKeyConvertor, MySqlAlterTableDeleteCompositePrimaryKeyConvertor, MySqlAlterTableAlterCompositePrimaryKeyConvertor, PgAlterTableAlterColumnSetPrimaryKeyConvertor, PgAlterTableAlterColumnDropPrimaryKeyConvertor, PgAlterTableAlterColumnSetNotNullConvertor, PgAlterTableAlterColumnDropNotNullConvertor, PgCreateForeignKeyConvertor, LibSQLCreateForeignKeyConvertor, MySqlCreateForeignKeyConvertor, PgAlterForeignKeyConvertor, PgDeleteForeignKeyConvertor, MySqlDeleteForeignKeyConvertor, CreatePgIndexConvertor, CreateMySqlIndexConvertor, CreateSingleStoreIndexConvertor, CreateSqliteIndexConvertor, PgDropIndexConvertor, PgCreateSchemaConvertor, PgRenameSchemaConvertor, PgDropSchemaConvertor, PgAlterTableSetSchemaConvertor, PgAlterTableSetNewSchemaConvertor, PgAlterTableRemoveFromSchemaConvertor, SqliteDropIndexConvertor, MySqlDropIndexConvertor, SingleStoreDropIndexConvertor, SQLiteRecreateTableConvertor, LibSQLRecreateTableConvertor, SingleStoreRecreateTableConvertor, convertors, init_sqlgenerator, _moveDataStatements, getOldTableName, getNewTableName, logSuggestionsAndReturn, init_sqlitePushUtils, preparePgCreateTableJson, prepareMySqlCreateTableJson, prepareSingleStoreCreateTableJson, prepareSQLiteCreateTable, prepareDropTableJson, prepareRenameTableJson, prepareCreateEnumJson, prepareAddValuesToEnumJson, prepareDropEnumValues, prepareDropEnumJson, prepareMoveEnumJson, prepareRenameEnumJson, prepareCreateSequenceJson, prepareAlterSequenceJson, prepareDropSequenceJson, prepareMoveSequenceJson, prepareRenameSequenceJson, prepareCreateRoleJson, prepareAlterRoleJson, prepareDropRoleJson, prepareRenameRoleJson, prepareCreateSchemasJson, prepareRenameSchemasJson, prepareDeleteSchemasJson, prepareRenameColumns, _prepareDropColumns, _prepareAddColumns, _prepareSqliteAddColumns, prepareAlterColumnsMysql, preparePgAlterColumns, prepareSqliteAlterColumns, prepareRenamePolicyJsons, prepareRenameIndPolicyJsons, prepareCreatePolicyJsons, prepareCreateIndPolicyJsons, prepareDropPolicyJsons, prepareDropIndPolicyJsons, prepareAlterPolicyJson, prepareAlterIndPolicyJson, preparePgCreateIndexesJson, prepareCreateIndexesJson, prepareCreateReferencesJson, prepareLibSQLCreateReferencesJson, prepareDropReferencesJson, prepareLibSQLDropReferencesJson, prepareAlterReferencesJson, prepareDropIndexesJson, prepareAddCompositePrimaryKeySqlite, prepareDeleteCompositePrimaryKeySqlite, prepareAlterCompositePrimaryKeySqlite, prepareAddCompositePrimaryKeyPg, prepareDeleteCompositePrimaryKeyPg, prepareAlterCompositePrimaryKeyPg, prepareAddUniqueConstraintPg, prepareDeleteUniqueConstraintPg, prepareAddCheckConstraint, prepareDeleteCheckConstraint, prepareAddCompositePrimaryKeyMySql, prepareDeleteCompositePrimaryKeyMySql, prepareAlterCompositePrimaryKeyMySql, preparePgCreateViewJson, prepareMySqlCreateViewJson, prepareSqliteCreateViewJson, prepareDropViewJson, prepareRenameViewJson, preparePgAlterViewAlterSchemaJson, preparePgAlterViewAddWithOptionJson, preparePgAlterViewDropWithOptionJson, preparePgAlterViewAlterTablespaceJson, preparePgAlterViewAlterUsingJson, prepareMySqlAlterView, init_jsonStatements, prepareLibSQLRecreateTable, prepareSQLiteRecreateTable, libSQLCombineStatements, sqliteCombineStatements, prepareSingleStoreRecreateTable, singleStoreCombineStatements, init_statementCombiner, snapshotsDiffer_exports, makeChanged, makeSelfOrChanged, makePatched, makeSelfOrPatched, columnSchema, alteredColumnSchema, enumSchema3, changedEnumSchema, tableScheme, alteredTableScheme, alteredViewCommon, alteredPgViewSchema, alteredMySqlViewSchema, diffResultScheme, diffResultSchemeMysql, diffResultSchemeSingleStore, diffResultSchemeSQLite, schemaChangeFor, nameChangeFor, nameSchemaChangeFor, columnChangeFor, applyPgSnapshotsDiff, applyMysqlSnapshotsDiff, applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff, applyLibSQLSnapshotsDiff, init_snapshotsDiffer, init_words, dialects, dialect4, commonSquashedSchema, commonSchema, init_schemaValidator, sqliteDriversLiterals, postgresqlDriversLiterals, prefixes, prefix, casingTypes, casingType, sqliteDriver, postgresDriver, driver2, configMigrations, configCommonSchema, casing, introspectParams, configIntrospectCliSchema, configGenerateSchema, configPushSchema, init_common2, withStyle, init_outputs, import_hanji2, schemasResolver, tablesResolver, viewsResolver, mySqlViewsResolver, sqliteViewsResolver, sequencesResolver, roleResolver, policyResolver, indPolicyResolver, enumsResolver, columnsResolver, promptColumnsConflicts, promptNamedConflict, promptNamedWithSchemasConflict, promptSchemasConflict, BREAKPOINT, init_migrate, posixClasses, braceEscape, regexpEscape, rangesToString, parseClass, init_brace_expressions, escape, init_escape, unescape, init_unescape, import_brace_expansion, minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path, sep2, GLOBSTAR, plTypes, qmark, star, twoStarDot, twoStarNoDot, charSet, reSpecials, addPatternStartSet, filter, ext, defaults, braceExpand, MAX_PATTERN_LENGTH, assertValidPattern, makeRe, match2, globUnescape, globMagic, regExpEscape, Minimatch, init_mjs, entityKind2, hasOwnEntityKind2, init_entity2, _a3, Column2, init_column2, _a22, ColumnBuilder2, init_column_builder2, TableName2, init_table_utils2, _a32, ForeignKeyBuilder2, _a4, ForeignKey2, init_foreign_keys2, init_tracing_utils2, _a5, UniqueConstraintBuilder, _a6, UniqueOnConstraintBuilder, _a7, UniqueConstraint, init_unique_constraint2, init_array2, _a8, _b, PgColumnBuilder2, _a9, _b2, PgColumn2, _a10, _b3, ExtraConfigColumn2, _a11, IndexedColumn2, _a12, _b4, PgArrayBuilder2, _a13, _b5, _PgArray, PgArray2, init_common22, _a14, _b6, PgEnumObjectColumnBuilder2, _a15, _b7, PgEnumObjectColumn2, isPgEnumSym2, _a16, _b8, PgEnumColumnBuilder2, _a17, _b9, PgEnumColumn2, init_enum2, _a18, Subquery2, _a19, _b10, WithSubquery2, init_subquery2, version4, init_version2, otel2, rawTracer2, tracer2, init_tracing2, ViewBaseConfig2, init_view_common3, Schema2, Columns2, ExtraConfigColumns2, OriginalName2, BaseName2, IsAlias2, ExtraConfigBuilder2, IsDrizzleTable2, _a20, _b11, _c, _d, _e3, _f, _g, _h, _i, _j, Table2, init_table8, _a21, FakePrimitiveParam, _a222, StringChunk2, _a23, _SQL, SQL2, _a24, Name2, noopDecoder2, noopEncoder2, noopMapper2, _a25, Param2, _a26, Placeholder2, IsDrizzleView2, _a27, _b12, _c2, View3, init_sql4, _a28, ColumnAliasProxyHandler2, _a29, TableAliasProxyHandler2, _a30, RelationTableAliasProxyHandler, init_alias3, _a31, _b13, DrizzleError2, DrizzleQueryError, _a322, _b14, TransactionRollbackError2, init_errors22, _a33, ConsoleLogWriter2, _a34, DefaultLogger2, _a35, NoopLogger2, init_logger3, init_operations, _a36, _b15, QueryPromise2, init_query_promise2, textDecoder, init_utils22, _a37, _b16, PgIntColumnBaseBuilder2, init_int_common2, _a38, _b17, PgBigInt53Builder2, _a39, _b18, PgBigInt532, _a40, _b19, PgBigInt64Builder2, _a41, _b20, PgBigInt642, init_bigint2, _a42, _b21, PgBigSerial53Builder2, _a43, _b22, PgBigSerial532, _a44, _b23, PgBigSerial64Builder2, _a45, _b24, PgBigSerial642, init_bigserial2, _a46, _b25, PgBooleanBuilder2, _a47, _b26, PgBoolean2, init_boolean2, _a48, _b27, PgCharBuilder2, _a49, _b28, PgChar2, init_char2, _a50, _b29, PgCidrBuilder2, _a51, _b30, PgCidr2, init_cidr2, _a52, _b31, PgCustomColumnBuilder2, _a53, _b32, PgCustomColumn2, init_custom2, _a54, _b33, PgDateColumnBaseBuilder2, init_date_common2, _a55, _b34, PgDateBuilder2, _a56, _b35, PgDate2, _a57, _b36, PgDateStringBuilder2, _a58, _b37, PgDateString2, init_date2, _a59, _b38, PgDoublePrecisionBuilder2, _a60, _b39, PgDoublePrecision2, init_double_precision2, _a61, _b40, PgInetBuilder2, _a62, _b41, PgInet2, init_inet2, _a63, _b42, PgIntegerBuilder2, _a64, _b43, PgInteger2, init_integer2, _a65, _b44, PgIntervalBuilder2, _a66, _b45, PgInterval2, init_interval2, _a67, _b46, PgJsonBuilder2, _a68, _b47, PgJson2, init_json2, _a69, _b48, PgJsonbBuilder2, _a70, _b49, PgJsonb2, init_jsonb2, _a71, _b50, PgLineBuilder2, _a72, _b51, PgLineTuple2, _a73, _b52, PgLineABCBuilder2, _a74, _b53, PgLineABC2, init_line2, _a75, _b54, PgMacaddrBuilder2, _a76, _b55, PgMacaddr2, init_macaddr2, _a77, _b56, PgMacaddr8Builder2, _a78, _b57, PgMacaddr82, init_macaddr82, _a79, _b58, PgNumericBuilder2, _a80, _b59, PgNumeric2, _a81, _b60, PgNumericNumberBuilder2, _a82, _b61, PgNumericNumber2, _a83, _b62, PgNumericBigIntBuilder2, _a84, _b63, PgNumericBigInt2, init_numeric2, _a85, _b64, PgPointTupleBuilder2, _a86, _b65, PgPointTuple2, _a87, _b66, PgPointObjectBuilder2, _a88, _b67, PgPointObject2, init_point2, init_utils32, _a89, _b68, PgGeometryBuilder2, _a90, _b69, PgGeometry2, _a91, _b70, PgGeometryObjectBuilder2, _a92, _b71, PgGeometryObject2, init_geometry2, _a93, _b72, PgRealBuilder2, _a94, _b73, PgReal2, init_real2, _a95, _b74, PgSerialBuilder2, _a96, _b75, PgSerial2, init_serial2, _a97, _b76, PgSmallIntBuilder2, _a98, _b77, PgSmallInt2, init_smallint2, _a99, _b78, PgSmallSerialBuilder2, _a100, _b79, PgSmallSerial2, init_smallserial2, _a101, _b80, PgTextBuilder2, _a102, _b81, PgText2, init_text2, _a103, _b82, PgTimeBuilder2, _a104, _b83, PgTime2, init_time2, _a105, _b84, PgTimestampBuilder2, _a106, _b85, PgTimestamp2, _a107, _b86, PgTimestampStringBuilder2, _a108, _b87, PgTimestampString2, init_timestamp2, _a109, _b88, PgUUIDBuilder2, _a110, _b89, PgUUID2, init_uuid3, _a111, _b90, PgVarcharBuilder2, _a112, _b91, PgVarchar2, init_varchar2, _a113, _b92, PgBinaryVectorBuilder2, _a114, _b93, PgBinaryVector2, init_bit2, _a115, _b94, PgHalfVectorBuilder2, _a116, _b95, PgHalfVector2, init_halfvec2, _a117, _b96, PgSparseVectorBuilder2, _a118, _b97, PgSparseVector2, init_sparsevec2, _a119, _b98, PgVectorBuilder2, _a120, _b99, PgVector2, init_vector3, init_all2, InlineForeignKeys2, EnableRLS2, _a121, _b100, _c3, _d2, _e22, _f2, PgTable2, pgTable2, init_table22, _a122, PrimaryKeyBuilder2, _a123, PrimaryKey2, init_primary_keys2, eq2, ne4, gt3, gte2, lt4, lte2, init_conditions2, init_select3, init_expressions2, _a124, Relation2, _a125, Relations2, _a126, _b101, _One, One2, _a127, _b102, _Many, Many2, init_relations2, init_aggregate2, init_vector22, init_functions2, init_sql22, dist_exports, init_dist9, init_alias22, _a128, CheckBuilder, _a129, Check, init_checks6, init_columns2, _a130, _SelectionProxyHandler, SelectionProxyHandler2, init_selection_proxy2, _a131, IndexBuilderOn2, _a132, IndexBuilder2, _a133, Index2, init_indexes2, _a134, PgPolicy, init_policies2, PgViewConfig2, init_view_common22, _a135, CasingCache2, init_casing2, _a136, _b103, PgViewBase2, init_view_base2, _a137, PgDialect2, init_dialect2, _a138, TypedQueryBuilder2, init_query_builder3, _a139, PgSelectBuilder2, _a140, _b104, PgSelectQueryBuilderBase2, _a141, _b105, PgSelectBase2, getPgSetOperators2, union22, unionAll2, intersect2, intersectAll2, except2, exceptAll2, init_select22, _a142, QueryBuilder2, init_query_builder22, _a143, DefaultViewBuilderCore, _a144, _b106, ViewBuilder, _a145, _b107, ManualViewBuilder, _a146, MaterializedViewBuilderCore, _a147, _b108, MaterializedViewBuilder, _a148, _b109, ManualMaterializedViewBuilder, _a149, _b110, _c4, PgView2, PgMaterializedViewConfig2, _a150, _b111, _c5, PgMaterializedView, init_view2, init_utils42, _a151, _b112, PgDeleteBase2, init_delete2, _a152, PgInsertBuilder2, _a153, _b113, PgInsertBase2, init_insert2, _a154, _b114, PgRefreshMaterializedView2, init_refresh_materialized_view2, init_select_types, _a155, PgUpdateBuilder2, _a156, _b115, PgUpdateBase2, init_update2, init_query_builders2, _a157, _b116, _c6, _PgCountBuilder, PgCountBuilder2, init_count2, _a158, RelationalQueryBuilder2, _a159, _b117, PgRelationalQuery2, init_query2, _a160, _b118, PgRaw2, init_raw2, _a161, PgDatabase2, init_db2, _a162, PgRole, init_roles2, _a163, PgSequence, init_sequence2, _a164, PgSchema5, init_schema4, _a165, Cache, _a166, _b119, NoopCache, init_cache, _a167, PgPreparedQuery2, _a168, PgSession2, _a169, _b120, PgTransaction2, init_session3, init_subquery22, init_utils52, init_pg_core2, vectorOps, init_vector32, sqlToStr, init_utils62, indexName, generatePgSnapshot, trimChar, fromDatabase, defaultForColumn, getColumnsInfoQuery, init_pgSerializer, import_hanji4, Select, init_selector_ui, init_alias32, _a170, CheckBuilder2, _a171, Check2, init_checks22, _a172, ForeignKeyBuilder22, _a173, ForeignKey22, init_foreign_keys22, _a174, UniqueConstraintBuilder2, _a175, UniqueOnConstraintBuilder2, _a176, UniqueConstraint2, init_unique_constraint22, _a177, _b121, SQLiteColumnBuilder, _a178, _b122, SQLiteColumn, init_common3, _a179, _b123, SQLiteBigIntBuilder, _a180, _b124, SQLiteBigInt, _a181, _b125, SQLiteBlobJsonBuilder, _a182, _b126, SQLiteBlobJson, _a183, _b127, SQLiteBlobBufferBuilder, _a184, _b128, SQLiteBlobBuffer, init_blob, _a185, _b129, SQLiteCustomColumnBuilder, _a186, _b130, SQLiteCustomColumn, init_custom22, _a187, _b131, SQLiteBaseIntegerBuilder, _a188, _b132, SQLiteBaseInteger, _a189, _b133, SQLiteIntegerBuilder, _a190, _b134, SQLiteInteger, _a191, _b135, SQLiteTimestampBuilder, _a192, _b136, SQLiteTimestamp, _a193, _b137, SQLiteBooleanBuilder, _a194, _b138, SQLiteBoolean, init_integer22, _a195, _b139, SQLiteNumericBuilder, _a196, _b140, SQLiteNumeric, _a197, _b141, SQLiteNumericNumberBuilder, _a198, _b142, SQLiteNumericNumber, _a199, _b143, SQLiteNumericBigIntBuilder, _a200, _b144, SQLiteNumericBigInt, init_numeric22, _a201, _b145, SQLiteRealBuilder, _a202, _b146, SQLiteReal, init_real22, _a203, _b147, SQLiteTextBuilder, _a204, _b148, SQLiteText, _a205, _b149, SQLiteTextJsonBuilder, _a206, _b150, SQLiteTextJson, init_text22, init_columns22, init_all22, InlineForeignKeys22, _a207, _b151, _c7, _d3, _e32, SQLiteTable, sqliteTable, init_table32, _a208, IndexBuilderOn22, _a209, IndexBuilder22, _a210, Index4, init_indexes22, _a211, PrimaryKeyBuilder22, _a212, PrimaryKey22, init_primary_keys22, init_utils72, _a213, _b152, SQLiteDeleteBase, init_delete22, _a214, _b153, SQLiteViewBase, init_view_base22, _a215, SQLiteDialect, _a216, _b154, SQLiteSyncDialect, _a217, _b155, SQLiteAsyncDialect, init_dialect22, _a218, SQLiteSelectBuilder, _a219, _b156, SQLiteSelectQueryBuilderBase, _a220, _b157, SQLiteSelectBase, getSQLiteSetOperators, union32, unionAll22, intersect22, except22, init_select32, _a221, QueryBuilder22, init_query_builder32, _a2222, SQLiteInsertBuilder, _a223, _b158, SQLiteInsertBase, init_insert22, init_select_types2, _a224, SQLiteUpdateBuilder, _a225, _b159, SQLiteUpdateBase, init_update22, init_query_builders22, _a226, _b160, _c8, _SQLiteCountBuilder, SQLiteCountBuilder, init_count22, _a227, RelationalQueryBuilder22, _a228, _b161, SQLiteRelationalQuery, _a229, _b162, SQLiteSyncRelationalQuery, init_query22, _a230, _b163, SQLiteRaw, init_raw22, _a231, BaseSQLiteDatabase, init_db22, _a232, _b164, ExecuteResultSync, _a233, SQLitePreparedQuery, _a234, SQLiteSession, _a235, _b165, SQLiteTransaction, init_session22, init_subquery3, _a236, ViewBuilderCore, _a237, _b166, ViewBuilder2, _a238, _b167, ManualViewBuilder2, _a239, _b168, SQLiteView2, init_view22, init_sqlite_core, generateSqliteSnapshot, fromDatabase2, init_sqliteSerializer, getTablesFilterByExtensions, init_getTablesFilterByExtensions, init_alias4, _a240, CheckBuilder3, _a241, Check3, init_checks32, _a242, ForeignKeyBuilder3, _a243, ForeignKey3, init_foreign_keys3, _a244, UniqueConstraintBuilder3, _a245, UniqueOnConstraintBuilder3, _a246, UniqueConstraint3, init_unique_constraint3, _a247, _b169, MySqlColumnBuilder, _a248, _b170, MySqlColumn, _a249, _b171, MySqlColumnBuilderWithAutoIncrement, _a250, _b172, MySqlColumnWithAutoIncrement, init_common4, _a251, _b173, MySqlBigInt53Builder, _a252, _b174, MySqlBigInt53, _a253, _b175, MySqlBigInt64Builder, _a254, _b176, MySqlBigInt64, init_bigint22, _a255, _b177, MySqlBinaryBuilder, _a256, _b178, MySqlBinary, init_binary, _a257, _b179, MySqlBooleanBuilder, _a258, _b180, MySqlBoolean, init_boolean22, _a259, _b181, MySqlCharBuilder, _a260, _b182, MySqlChar, init_char22, _a261, _b183, MySqlCustomColumnBuilder, _a262, _b184, MySqlCustomColumn, init_custom3, _a263, _b185, MySqlDateBuilder, _a264, _b186, MySqlDate, _a265, _b187, MySqlDateStringBuilder, _a266, _b188, MySqlDateString, init_date22, _a267, _b189, MySqlDateTimeBuilder, _a268, _b190, MySqlDateTime, _a269, _b191, MySqlDateTimeStringBuilder, _a270, _b192, MySqlDateTimeString, init_datetime, _a271, _b193, MySqlDecimalBuilder, _a272, _b194, MySqlDecimal, _a273, _b195, MySqlDecimalNumberBuilder, _a274, _b196, MySqlDecimalNumber, _a275, _b197, MySqlDecimalBigIntBuilder, _a276, _b198, MySqlDecimalBigInt, init_decimal, _a277, _b199, MySqlDoubleBuilder, _a278, _b200, MySqlDouble, init_double, _a279, _b201, MySqlEnumColumnBuilder, _a280, _b202, MySqlEnumColumn, _a281, _b203, MySqlEnumObjectColumnBuilder, _a282, _b204, MySqlEnumObjectColumn, init_enum22, _a283, _b205, MySqlFloatBuilder, _a284, _b206, MySqlFloat, init_float, _a285, _b207, MySqlIntBuilder, _a286, _b208, MySqlInt, init_int, _a287, _b209, MySqlJsonBuilder, _a288, _b210, MySqlJson, init_json22, _a289, _b211, MySqlMediumIntBuilder, _a290, _b212, MySqlMediumInt, init_mediumint, _a291, _b213, MySqlRealBuilder, _a292, _b214, MySqlReal, init_real3, _a293, _b215, MySqlSerialBuilder, _a294, _b216, MySqlSerial, init_serial22, _a295, _b217, MySqlSmallIntBuilder, _a296, _b218, MySqlSmallInt, init_smallint22, _a297, _b219, MySqlTextBuilder, _a298, _b220, MySqlText, init_text3, _a299, _b221, MySqlTimeBuilder, _a300, _b222, MySqlTime, init_time22, _a301, _b223, MySqlDateColumnBaseBuilder, _a302, _b224, MySqlDateBaseColumn, init_date_common22, _a303, _b225, MySqlTimestampBuilder, _a304, _b226, MySqlTimestamp, _a305, _b227, MySqlTimestampStringBuilder, _a306, _b228, MySqlTimestampString, init_timestamp22, _a307, _b229, MySqlTinyIntBuilder, _a308, _b230, MySqlTinyInt, init_tinyint, _a309, _b231, MySqlVarBinaryBuilder, _a310, _b232, MySqlVarBinary, init_varbinary, _a311, _b233, MySqlVarCharBuilder, _a312, _b234, MySqlVarChar, init_varchar22, _a313, _b235, MySqlYearBuilder, _a314, _b236, MySqlYear, init_year, init_columns3, _a315, _b237, _c9, _MySqlCountBuilder, MySqlCountBuilder, init_count3, _a316, IndexBuilderOn3, _a317, IndexBuilder3, _a318, Index5, init_indexes3, init_all3, InlineForeignKeys3, _a319, _b238, _c10, _d4, _e4, MySqlTable, mysqlTable, init_table42, _a320, PrimaryKeyBuilder3, _a321, PrimaryKey3, init_primary_keys3, MySqlViewConfig, init_view_common32, init_utils8, _a3222, _b239, MySqlDeleteBase, init_delete3, _a323, _b240, MySqlViewBase, init_view_base3, _a324, MySqlDialect, init_dialect3, _a325, MySqlSelectBuilder, _a326, _b241, MySqlSelectQueryBuilderBase, _a327, _b242, MySqlSelectBase, getMySqlSetOperators, union4, unionAll3, intersect3, intersectAll22, except3, exceptAll22, init_select4, _a328, QueryBuilder3, init_query_builder4, _a329, MySqlInsertBuilder, _a330, _b243, MySqlInsertBase, init_insert3, init_select_types3, _a331, MySqlUpdateBuilder, _a332, _b244, MySqlUpdateBase, init_update3, init_query_builders3, _a333, RelationalQueryBuilder3, _a334, _b245, MySqlRelationalQuery, init_query3, _a335, MySqlDatabase, init_db3, _a336, ViewBuilderCore2, _a337, _b246, ViewBuilder3, _a338, _b247, ManualViewBuilder3, _a339, _b248, _c11, MySqlView2, init_view3, _a340, MySqlSchema5, init_schema22, _a341, MySqlPreparedQuery, _a342, MySqlSession, _a343, _b249, MySqlTransaction, init_session32, init_subquery4, init_mysql_core, handleEnumType, generateMySqlSnapshot, fromDatabase3, init_mysqlSerializer, cliConfigGenerate, pushParams, pullParams, configCheck, cliConfigCheck, init_cli, gelCredentials, init_gel, libSQLCredentials, init_libsql, mysqlCredentials, init_mysql, postgresCredentials, init_postgres, singlestoreCredentials, init_singlestore, sqliteCredentials, init_sqlite, credentials, studioCliParams, studioConfig, init_studio, es5_exports, _3, es5_default, init_es5, import_hanji7, assertES5, safeRegister, migrateConfig, init_utils9, prepareFromExports, init_pgImports, init_alias5, _a344, UniqueConstraintBuilder4, _a345, UniqueOnConstraintBuilder4, _a346, UniqueConstraint4, init_unique_constraint4, _a347, _b250, SingleStoreColumnBuilder, _a348, _b251, SingleStoreColumn, _a349, _b252, SingleStoreColumnBuilderWithAutoIncrement, _a350, _b253, SingleStoreColumnWithAutoIncrement, init_common5, _a351, _b254, SingleStoreBigInt53Builder, _a352, _b255, SingleStoreBigInt53, _a353, _b256, SingleStoreBigInt64Builder, _a354, _b257, SingleStoreBigInt64, init_bigint3, _a355, _b258, SingleStoreBinaryBuilder, _a356, _b259, SingleStoreBinary, init_binary2, _a357, _b260, SingleStoreBooleanBuilder, _a358, _b261, SingleStoreBoolean, init_boolean3, _a359, _b262, SingleStoreCharBuilder, _a360, _b263, SingleStoreChar, init_char3, _a361, _b264, SingleStoreCustomColumnBuilder, _a362, _b265, SingleStoreCustomColumn, init_custom4, _a363, _b266, SingleStoreDateBuilder, _a364, _b267, SingleStoreDate, _a365, _b268, SingleStoreDateStringBuilder, _a366, _b269, SingleStoreDateString, init_date3, _a367, _b270, SingleStoreDateTimeBuilder, _a368, _b271, SingleStoreDateTime, _a369, _b272, SingleStoreDateTimeStringBuilder, _a370, _b273, SingleStoreDateTimeString, init_datetime2, _a371, _b274, SingleStoreDecimalBuilder, _a372, _b275, SingleStoreDecimal, _a373, _b276, SingleStoreDecimalNumberBuilder, _a374, _b277, SingleStoreDecimalNumber, _a375, _b278, SingleStoreDecimalBigIntBuilder, _a376, _b279, SingleStoreDecimalBigInt, init_decimal2, _a377, _b280, SingleStoreDoubleBuilder, _a378, _b281, SingleStoreDouble, init_double2, _a379, _b282, SingleStoreEnumColumnBuilder, _a380, _b283, SingleStoreEnumColumn, init_enum3, _a381, _b284, SingleStoreFloatBuilder, _a382, _b285, SingleStoreFloat, init_float2, _a383, _b286, SingleStoreIntBuilder, _a384, _b287, SingleStoreInt, init_int2, _a385, _b288, SingleStoreJsonBuilder, _a386, _b289, SingleStoreJson, init_json3, _a387, _b290, SingleStoreMediumIntBuilder, _a388, _b291, SingleStoreMediumInt, init_mediumint2, _a389, _b292, SingleStoreRealBuilder, _a390, _b293, SingleStoreReal, init_real4, _a391, _b294, SingleStoreSerialBuilder, _a392, _b295, SingleStoreSerial, init_serial3, _a393, _b296, SingleStoreSmallIntBuilder, _a394, _b297, SingleStoreSmallInt, init_smallint3, _a395, _b298, SingleStoreTextBuilder, _a396, _b299, SingleStoreText, init_text4, _a397, _b300, SingleStoreTimeBuilder, _a398, _b301, SingleStoreTime, init_time3, _a399, _b302, SingleStoreDateColumnBaseBuilder, _a400, _b303, SingleStoreDateBaseColumn, init_date_common3, _a401, _b304, SingleStoreTimestampBuilder, _a402, _b305, SingleStoreTimestamp, _a403, _b306, SingleStoreTimestampStringBuilder, _a404, _b307, SingleStoreTimestampString, init_timestamp3, _a405, _b308, SingleStoreTinyIntBuilder, _a406, _b309, SingleStoreTinyInt, init_tinyint2, _a407, _b310, SingleStoreVarBinaryBuilder, _a408, _b311, SingleStoreVarBinary, init_varbinary2, _a409, _b312, SingleStoreVarCharBuilder, _a410, _b313, SingleStoreVarChar, init_varchar3, _a411, _b314, SingleStoreVectorBuilder, _a412, _b315, SingleStoreVector, init_vector4, _a413, _b316, SingleStoreYearBuilder, _a414, _b317, SingleStoreYear, init_year2, init_columns4, _a415, _b318, _c12, _SingleStoreCountBuilder, SingleStoreCountBuilder, init_count4, _a416, IndexBuilderOn4, _a417, IndexBuilder4, _a418, Index6, init_indexes4, init_all4, _a419, _b319, _c13, _d5, SingleStoreTable, init_table52, _a420, PrimaryKeyBuilder4, _a421, PrimaryKey4, init_primary_keys4, init_utils10, _a422, _b320, SingleStoreDeleteBase, init_delete4, _a423, SingleStoreInsertBuilder, _a424, _b321, SingleStoreInsertBase, init_insert4, _a425, SingleStoreDialect, init_dialect4, _a426, SingleStoreSelectBuilder, _a427, _b322, SingleStoreSelectQueryBuilderBase, _a428, _b323, SingleStoreSelectBase, getSingleStoreSetOperators, union5, unionAll4, intersect4, except4, minus, init_select5, _a429, QueryBuilder4, init_query_builder5, init_select_types4, _a430, SingleStoreUpdateBuilder, _a431, _b324, SingleStoreUpdateBase, init_update4, init_query_builders4, _a432, SingleStoreDatabase, init_db4, _a433, SingleStoreSchema5, init_schema32, _a434, SingleStorePreparedQuery, _a435, SingleStoreSession, _a436, _b325, SingleStoreTransaction, init_session4, init_subquery5, init_singlestore_core, dialect5, generateSingleStoreSnapshot, fromDatabase4, init_singlestoreSerializer, sqliteImports_exports, prepareFromExports2, prepareFromSqliteImports, init_sqliteImports, mysqlImports_exports, prepareFromExports3, prepareFromMySqlImports, init_mysqlImports, mysqlPushUtils_exports, import_hanji8, filterStatements, logSuggestionsAndReturn2, init_mysqlPushUtils, mysqlIntrospect_exports, import_hanji9, mysqlPushIntrospect, init_mysqlIntrospect, singlestoreImports_exports, prepareFromExports4, prepareFromSingleStoreImports, init_singlestoreImports, singlestorePushUtils_exports, import_hanji10, filterStatements2, logSuggestionsAndReturn3, init_singlestorePushUtils, singlestoreIntrospect_exports, import_hanji11, singlestorePushIntrospect, init_singlestoreIntrospect, import_hanji3, pgPushIntrospect = async (db2, filters, schemaFilters, entities, tsSchema) => {
101000
103393
  const matchers = filters.map((it3) => {
101001
103394
  return new Minimatch(it3);
101002
103395
  });
@@ -121422,7 +123815,7 @@ globstar while`, file3, fr, pattern, pr2, swallowee);
121422
123815
  });
121423
123816
  }
121424
123817
  });
121425
- init_sql3 = __esm2({
123818
+ init_sql4 = __esm2({
121426
123819
  "../drizzle-orm/dist/sql/sql.js"() {
121427
123820
  init_entity2();
121428
123821
  init_enum2();
@@ -121775,7 +124168,7 @@ globstar while`, file3, fr, pattern, pr2, swallowee);
121775
124168
  "../drizzle-orm/dist/alias.js"() {
121776
124169
  init_column2();
121777
124170
  init_entity2();
121778
- init_sql3();
124171
+ init_sql4();
121779
124172
  init_table8();
121780
124173
  init_view_common3();
121781
124174
  _a28 = entityKind2;
@@ -121949,7 +124342,7 @@ params: ${params}`);
121949
124342
  "../drizzle-orm/dist/utils.js"() {
121950
124343
  init_column2();
121951
124344
  init_entity2();
121952
- init_sql3();
124345
+ init_sql4();
121953
124346
  init_subquery2();
121954
124347
  init_table8();
121955
124348
  init_view_common3();
@@ -122208,7 +124601,7 @@ params: ${params}`);
122208
124601
  init_date_common2 = __esm2({
122209
124602
  "../drizzle-orm/dist/pg-core/columns/date.common.js"() {
122210
124603
  init_entity2();
122211
- init_sql3();
124604
+ init_sql4();
122212
124605
  init_common22();
122213
124606
  PgDateColumnBaseBuilder2 = class extends (_b33 = PgColumnBuilder2, _a54 = entityKind2, _b33) {
122214
124607
  defaultNow() {
@@ -122993,7 +125386,7 @@ params: ${params}`);
122993
125386
  init_uuid3 = __esm2({
122994
125387
  "../drizzle-orm/dist/pg-core/columns/uuid.js"() {
122995
125388
  init_entity2();
122996
- init_sql3();
125389
+ init_sql4();
122997
125390
  init_common22();
122998
125391
  PgUUIDBuilder2 = class extends (_b88 = PgColumnBuilder2, _a109 = entityKind2, _b88) {
122999
125392
  constructor(name22) {
@@ -123264,7 +125657,7 @@ params: ${params}`);
123264
125657
  init_column2();
123265
125658
  init_entity2();
123266
125659
  init_table8();
123267
- init_sql3();
125660
+ init_sql4();
123268
125661
  eq2 = (left, right) => {
123269
125662
  return sql4`${left} = ${bindIfParam2(right, left)}`;
123270
125663
  };
@@ -123287,7 +125680,7 @@ params: ${params}`);
123287
125680
  });
123288
125681
  init_select3 = __esm2({
123289
125682
  "../drizzle-orm/dist/sql/expressions/select.js"() {
123290
- init_sql3();
125683
+ init_sql4();
123291
125684
  }
123292
125685
  });
123293
125686
  init_expressions2 = __esm2({
@@ -123303,7 +125696,7 @@ params: ${params}`);
123303
125696
  init_entity2();
123304
125697
  init_primary_keys2();
123305
125698
  init_expressions2();
123306
- init_sql3();
125699
+ init_sql4();
123307
125700
  _a124 = entityKind2;
123308
125701
  Relation2 = class {
123309
125702
  constructor(sourceTable, referencedTable, relationName) {
@@ -123357,12 +125750,12 @@ params: ${params}`);
123357
125750
  "../drizzle-orm/dist/sql/functions/aggregate.js"() {
123358
125751
  init_column2();
123359
125752
  init_entity2();
123360
- init_sql3();
125753
+ init_sql4();
123361
125754
  }
123362
125755
  });
123363
125756
  init_vector22 = __esm2({
123364
125757
  "../drizzle-orm/dist/sql/functions/vector.js"() {
123365
- init_sql3();
125758
+ init_sql4();
123366
125759
  }
123367
125760
  });
123368
125761
  init_functions2 = __esm2({
@@ -123375,7 +125768,7 @@ params: ${params}`);
123375
125768
  "../drizzle-orm/dist/sql/index.js"() {
123376
125769
  init_expressions2();
123377
125770
  init_functions2();
123378
- init_sql3();
125771
+ init_sql4();
123379
125772
  }
123380
125773
  });
123381
125774
  dist_exports = {};
@@ -123592,7 +125985,7 @@ params: ${params}`);
123592
125985
  init_alias3();
123593
125986
  init_column2();
123594
125987
  init_entity2();
123595
- init_sql3();
125988
+ init_sql4();
123596
125989
  init_subquery2();
123597
125990
  init_view_common3();
123598
125991
  _a130 = entityKind2;
@@ -123651,7 +126044,7 @@ params: ${params}`);
123651
126044
  });
123652
126045
  init_indexes2 = __esm2({
123653
126046
  "../drizzle-orm/dist/pg-core/indexes.js"() {
123654
- init_sql3();
126047
+ init_sql4();
123655
126048
  init_entity2();
123656
126049
  init_columns2();
123657
126050
  _a131 = entityKind2;
@@ -123814,7 +126207,7 @@ params: ${params}`);
123814
126207
  init_view_base2 = __esm2({
123815
126208
  "../drizzle-orm/dist/pg-core/view-base.js"() {
123816
126209
  init_entity2();
123817
- init_sql3();
126210
+ init_sql4();
123818
126211
  PgViewBase2 = class extends (_b103 = View3, _a136 = entityKind2, _b103) {
123819
126212
  };
123820
126213
  __publicField(PgViewBase2, _a136, "PgViewBase");
@@ -123831,7 +126224,7 @@ params: ${params}`);
123831
126224
  init_table22();
123832
126225
  init_relations2();
123833
126226
  init_sql22();
123834
- init_sql3();
126227
+ init_sql4();
123835
126228
  init_subquery2();
123836
126229
  init_table8();
123837
126230
  init_utils22();
@@ -124415,7 +126808,7 @@ params: ${params}`);
124415
126808
  init_query_builder3();
124416
126809
  init_query_promise2();
124417
126810
  init_selection_proxy2();
124418
- init_sql3();
126811
+ init_sql4();
124419
126812
  init_subquery2();
124420
126813
  init_table8();
124421
126814
  init_tracing2();
@@ -125036,7 +127429,7 @@ params: ${params}`);
125036
127429
  "../drizzle-orm/dist/pg-core/utils.js"() {
125037
127430
  init_entity2();
125038
127431
  init_table22();
125039
- init_sql3();
127432
+ init_sql4();
125040
127433
  init_subquery2();
125041
127434
  init_table8();
125042
127435
  init_view_common3();
@@ -125124,7 +127517,7 @@ params: ${params}`);
125124
127517
  init_entity2();
125125
127518
  init_query_promise2();
125126
127519
  init_selection_proxy2();
125127
- init_sql3();
127520
+ init_sql4();
125128
127521
  init_table8();
125129
127522
  init_tracing2();
125130
127523
  init_utils22();
@@ -125318,7 +127711,7 @@ params: ${params}`);
125318
127711
  init_table22();
125319
127712
  init_query_promise2();
125320
127713
  init_selection_proxy2();
125321
- init_sql3();
127714
+ init_sql4();
125322
127715
  init_subquery2();
125323
127716
  init_table8();
125324
127717
  init_utils22();
@@ -125492,7 +127885,7 @@ params: ${params}`);
125492
127885
  init_count2 = __esm2({
125493
127886
  "../drizzle-orm/dist/pg-core/query-builders/count.js"() {
125494
127887
  init_entity2();
125495
- init_sql3();
127888
+ init_sql4();
125496
127889
  _PgCountBuilder = class _PgCountBuilder2 extends (_c6 = SQL2, _b116 = entityKind2, _a157 = Symbol.toStringTag, _c6) {
125497
127890
  constructor(params) {
125498
127891
  super(_PgCountBuilder2.buildEmbeddedCount(params.source, params.filters).queryChunks);
@@ -125660,7 +128053,7 @@ params: ${params}`);
125660
128053
  init_entity2();
125661
128054
  init_query_builders2();
125662
128055
  init_selection_proxy2();
125663
- init_sql3();
128056
+ init_sql4();
125664
128057
  init_subquery2();
125665
128058
  init_count2();
125666
128059
  init_query2();
@@ -125832,10 +128225,10 @@ params: ${params}`);
125832
128225
  __publicField(PgSequence, _a163, "PgSequence");
125833
128226
  }
125834
128227
  });
125835
- init_schema3 = __esm2({
128228
+ init_schema4 = __esm2({
125836
128229
  "../drizzle-orm/dist/pg-core/schema.js"() {
125837
128230
  init_entity2();
125838
- init_sql3();
128231
+ init_sql4();
125839
128232
  init_enum2();
125840
128233
  init_sequence2();
125841
128234
  init_table22();
@@ -126051,7 +128444,7 @@ params: ${params}`);
126051
128444
  init_primary_keys2();
126052
128445
  init_query_builders2();
126053
128446
  init_roles2();
126054
- init_schema3();
128447
+ init_schema4();
126055
128448
  init_sequence2();
126056
128449
  init_session3();
126057
128450
  init_subquery22();
@@ -127859,7 +130252,7 @@ ORDER BY
127859
130252
  init_integer22 = __esm2({
127860
130253
  "../drizzle-orm/dist/sqlite-core/columns/integer.js"() {
127861
130254
  init_entity2();
127862
- init_sql3();
130255
+ init_sql4();
127863
130256
  init_utils22();
127864
130257
  init_common3();
127865
130258
  SQLiteBaseIntegerBuilder = class extends (_b131 = SQLiteColumnBuilder, _a187 = entityKind2, _b131) {
@@ -128222,7 +130615,7 @@ ORDER BY
128222
130615
  init_utils72 = __esm2({
128223
130616
  "../drizzle-orm/dist/sqlite-core/utils.js"() {
128224
130617
  init_entity2();
128225
- init_sql3();
130618
+ init_sql4();
128226
130619
  init_subquery2();
128227
130620
  init_table8();
128228
130621
  init_view_common3();
@@ -128316,7 +130709,7 @@ ORDER BY
128316
130709
  init_view_base22 = __esm2({
128317
130710
  "../drizzle-orm/dist/sqlite-core/view-base.js"() {
128318
130711
  init_entity2();
128319
- init_sql3();
130712
+ init_sql4();
128320
130713
  SQLiteViewBase = class extends (_b153 = View3, _a214 = entityKind2, _b153) {
128321
130714
  };
128322
130715
  __publicField(SQLiteViewBase, _a214, "SQLiteViewBase");
@@ -128331,7 +130724,7 @@ ORDER BY
128331
130724
  init_errors22();
128332
130725
  init_relations2();
128333
130726
  init_sql22();
128334
- init_sql3();
130727
+ init_sql4();
128335
130728
  init_columns22();
128336
130729
  init_table32();
128337
130730
  init_subquery2();
@@ -128911,7 +131304,7 @@ ORDER BY
128911
131304
  init_query_builder3();
128912
131305
  init_query_promise2();
128913
131306
  init_selection_proxy2();
128914
- init_sql3();
131307
+ init_sql4();
128915
131308
  init_subquery2();
128916
131309
  init_table8();
128917
131310
  init_utils22();
@@ -129274,7 +131667,7 @@ ORDER BY
129274
131667
  "../drizzle-orm/dist/sqlite-core/query-builders/insert.js"() {
129275
131668
  init_entity2();
129276
131669
  init_query_promise2();
129277
- init_sql3();
131670
+ init_sql4();
129278
131671
  init_table32();
129279
131672
  init_table8();
129280
131673
  init_utils22();
@@ -129521,7 +131914,7 @@ ORDER BY
129521
131914
  init_count22 = __esm2({
129522
131915
  "../drizzle-orm/dist/sqlite-core/query-builders/count.js"() {
129523
131916
  init_entity2();
129524
- init_sql3();
131917
+ init_sql4();
129525
131918
  _SQLiteCountBuilder = class _SQLiteCountBuilder2 extends (_c8 = SQL2, _b160 = entityKind2, _a226 = Symbol.toStringTag, _c8) {
129526
131919
  constructor(params) {
129527
131920
  super(_SQLiteCountBuilder2.buildEmbeddedCount(params.source, params.filters).queryChunks);
@@ -129690,7 +132083,7 @@ ORDER BY
129690
132083
  "../drizzle-orm/dist/sqlite-core/db.js"() {
129691
132084
  init_entity2();
129692
132085
  init_selection_proxy2();
129693
- init_sql3();
132086
+ init_sql4();
129694
132087
  init_query_builders22();
129695
132088
  init_subquery2();
129696
132089
  init_count22();
@@ -131661,7 +134054,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
131661
134054
  init_date_common22 = __esm2({
131662
134055
  "../drizzle-orm/dist/mysql-core/columns/date.common.js"() {
131663
134056
  init_entity2();
131664
- init_sql3();
134057
+ init_sql4();
131665
134058
  init_common4();
131666
134059
  MySqlDateColumnBaseBuilder = class extends (_b223 = MySqlColumnBuilder, _a301 = entityKind2, _b223) {
131667
134060
  defaultNow() {
@@ -131887,7 +134280,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
131887
134280
  init_count3 = __esm2({
131888
134281
  "../drizzle-orm/dist/mysql-core/query-builders/count.js"() {
131889
134282
  init_entity2();
131890
- init_sql3();
134283
+ init_sql4();
131891
134284
  _MySqlCountBuilder = class _MySqlCountBuilder2 extends (_c9 = SQL2, _b237 = entityKind2, _a315 = Symbol.toStringTag, _c9) {
131892
134285
  constructor(params) {
131893
134286
  super(_MySqlCountBuilder2.buildEmbeddedCount(params.source, params.filters).queryChunks);
@@ -132149,7 +134542,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
132149
134542
  init_view_base3 = __esm2({
132150
134543
  "../drizzle-orm/dist/mysql-core/view-base.js"() {
132151
134544
  init_entity2();
132152
- init_sql3();
134545
+ init_sql4();
132153
134546
  MySqlViewBase = class extends (_b240 = View3, _a323 = entityKind2, _b240) {
132154
134547
  };
132155
134548
  __publicField(MySqlViewBase, _a323, "MySqlViewBase");
@@ -132164,7 +134557,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
132164
134557
  init_errors22();
132165
134558
  init_relations2();
132166
134559
  init_expressions2();
132167
- init_sql3();
134560
+ init_sql4();
132168
134561
  init_subquery2();
132169
134562
  init_table8();
132170
134563
  init_utils22();
@@ -132930,7 +135323,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
132930
135323
  init_query_builder3();
132931
135324
  init_query_promise2();
132932
135325
  init_selection_proxy2();
132933
- init_sql3();
135326
+ init_sql4();
132934
135327
  init_subquery2();
132935
135328
  init_table8();
132936
135329
  init_utils22();
@@ -133331,7 +135724,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
133331
135724
  "../drizzle-orm/dist/mysql-core/query-builders/insert.js"() {
133332
135725
  init_entity2();
133333
135726
  init_query_promise2();
133334
- init_sql3();
135727
+ init_sql4();
133335
135728
  init_table8();
133336
135729
  init_utils22();
133337
135730
  init_utils8();
@@ -133611,7 +136004,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
133611
136004
  "../drizzle-orm/dist/mysql-core/db.js"() {
133612
136005
  init_entity2();
133613
136006
  init_selection_proxy2();
133614
- init_sql3();
136007
+ init_sql4();
133615
136008
  init_subquery2();
133616
136009
  init_count3();
133617
136010
  init_query_builders3();
@@ -133840,7 +136233,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
133840
136233
  init_cache();
133841
136234
  init_entity2();
133842
136235
  init_errors22();
133843
- init_sql3();
136236
+ init_sql4();
133844
136237
  init_db3();
133845
136238
  _a341 = entityKind2;
133846
136239
  MySqlPreparedQuery = class {
@@ -135863,7 +138256,7 @@ AND
135863
138256
  init_date_common3 = __esm2({
135864
138257
  "../drizzle-orm/dist/singlestore-core/columns/date.common.js"() {
135865
138258
  init_entity2();
135866
- init_sql3();
138259
+ init_sql4();
135867
138260
  init_common5();
135868
138261
  SingleStoreDateColumnBaseBuilder = class extends (_b302 = SingleStoreColumnBuilder, _a399 = entityKind2, _b302) {
135869
138262
  defaultNow() {
@@ -135888,7 +138281,7 @@ AND
135888
138281
  init_timestamp3 = __esm2({
135889
138282
  "../drizzle-orm/dist/singlestore-core/columns/timestamp.js"() {
135890
138283
  init_entity2();
135891
- init_sql3();
138284
+ init_sql4();
135892
138285
  init_utils22();
135893
138286
  init_date_common3();
135894
138287
  SingleStoreTimestampBuilder = class extends (_b304 = SingleStoreDateColumnBaseBuilder, _a401 = entityKind2, _b304) {
@@ -136123,7 +138516,7 @@ AND
136123
138516
  init_count4 = __esm2({
136124
138517
  "../drizzle-orm/dist/singlestore-core/query-builders/count.js"() {
136125
138518
  init_entity2();
136126
- init_sql3();
138519
+ init_sql4();
136127
138520
  _SingleStoreCountBuilder = class _SingleStoreCountBuilder2 extends (_c12 = SQL2, _b318 = entityKind2, _a415 = Symbol.toStringTag, _c12) {
136128
138521
  constructor(params) {
136129
138522
  super(_SingleStoreCountBuilder2.buildEmbeddedCount(params.source, params.filters).queryChunks);
@@ -136293,7 +138686,7 @@ AND
136293
138686
  init_utils10 = __esm2({
136294
138687
  "../drizzle-orm/dist/singlestore-core/utils.js"() {
136295
138688
  init_entity2();
136296
- init_sql3();
138689
+ init_sql4();
136297
138690
  init_subquery2();
136298
138691
  init_table8();
136299
138692
  init_indexes4();
@@ -136371,7 +138764,7 @@ AND
136371
138764
  "../drizzle-orm/dist/singlestore-core/query-builders/insert.js"() {
136372
138765
  init_entity2();
136373
138766
  init_query_promise2();
136374
- init_sql3();
138767
+ init_sql4();
136375
138768
  init_table8();
136376
138769
  init_utils22();
136377
138770
  init_utils10();
@@ -136468,7 +138861,7 @@ AND
136468
138861
  init_errors22();
136469
138862
  init_relations2();
136470
138863
  init_expressions2();
136471
- init_sql3();
138864
+ init_sql4();
136472
138865
  init_subquery2();
136473
138866
  init_table8();
136474
138867
  init_utils22();
@@ -136999,7 +139392,7 @@ AND
136999
139392
  init_query_builder3();
137000
139393
  init_query_promise2();
137001
139394
  init_selection_proxy2();
137002
- init_sql3();
139395
+ init_sql4();
137003
139396
  init_subquery2();
137004
139397
  init_table8();
137005
139398
  init_utils22();
@@ -137457,7 +139850,7 @@ AND
137457
139850
  "../drizzle-orm/dist/singlestore-core/db.js"() {
137458
139851
  init_entity2();
137459
139852
  init_selection_proxy2();
137460
- init_sql3();
139853
+ init_sql4();
137461
139854
  init_subquery2();
137462
139855
  init_count4();
137463
139856
  init_query_builders4();
@@ -137571,7 +139964,7 @@ AND
137571
139964
  init_cache();
137572
139965
  init_entity2();
137573
139966
  init_errors22();
137574
- init_sql3();
139967
+ init_sql4();
137575
139968
  init_db4();
137576
139969
  _a434 = entityKind2;
137577
139970
  SingleStorePreparedQuery = class {
@@ -139846,7 +142239,7 @@ function requireUserId(userId) {
139846
142239
  return userId;
139847
142240
  }
139848
142241
  var init_params_util = __esm(() => {
139849
- init_src4();
142242
+ init_src5();
139850
142243
  init_errors();
139851
142244
  });
139852
142245
 
@@ -139899,6 +142292,7 @@ var init_utils11 = __esm(() => {
139899
142292
  init_lti_util();
139900
142293
  init_lti_provisioning();
139901
142294
  init_params_util();
142295
+ init_secrets_util();
139902
142296
  init_timeback_util();
139903
142297
  init_validation_util();
139904
142298
  });
@@ -140086,7 +142480,7 @@ var init_database_controller = __esm(() => {
140086
142480
  throw ApiError.unprocessableEntity("Validation failed", details);
140087
142481
  }
140088
142482
  }
140089
- return ctx.services.database.reset(slug2, ctx.user, body2.schema);
142483
+ return ctx.services.database.reset(slug2, ctx.user, body2);
140090
142484
  });
140091
142485
  database = defineControllerNames("database", {
140092
142486
  reset
@@ -140139,6 +142533,85 @@ var init_deploy_controller = __esm(() => {
140139
142533
  });
140140
142534
  });
140141
142535
 
142536
+ // ../api-core/src/controllers/deployment-state.controller.ts
142537
+ var get, baseline, realignMigration, resolveMigration, history, restorePoints, restore, reportBlocked, deploymentState;
142538
+ var init_deployment_state_controller = __esm(() => {
142539
+ init_schemas_index();
142540
+ init_errors();
142541
+ init_utils11();
142542
+ get = requireDeveloper(async (ctx) => {
142543
+ const slug2 = requireSlug(ctx.params.slug);
142544
+ const include = ctx.url.searchParams.getAll("include").flatMap((value) => value.split(",")).filter(Boolean);
142545
+ const unsupported = include.filter((value) => value !== "schemaSnapshot");
142546
+ if (unsupported.length > 0) {
142547
+ throw ApiError.badRequest(`Unsupported include value(s): ${unsupported.join(", ")}`);
142548
+ }
142549
+ return ctx.services.deploymentState.get(slug2, ctx.user, {
142550
+ includeSchemaSnapshot: include.includes("schemaSnapshot")
142551
+ });
142552
+ });
142553
+ baseline = requireDeveloper(async (ctx) => {
142554
+ const slug2 = requireSlug(ctx.params.slug);
142555
+ const body2 = await parseRequestBody(ctx.request, DeploymentStateBaselineSchema);
142556
+ return ctx.services.deploymentState.baseline(slug2, body2, ctx.user);
142557
+ });
142558
+ realignMigration = requireDeveloper(async (ctx) => {
142559
+ const slug2 = requireSlug(ctx.params.slug);
142560
+ const tag = ctx.params.tag;
142561
+ if (!tag) {
142562
+ throw ApiError.badRequest("Missing migration tag");
142563
+ }
142564
+ const body2 = await parseRequestBody(ctx.request, MigrationRealignSchema);
142565
+ return ctx.services.deploymentState.realignMigration(slug2, tag, body2.checksum, ctx.user);
142566
+ });
142567
+ resolveMigration = requireDeveloper(async (ctx) => {
142568
+ const slug2 = requireSlug(ctx.params.slug);
142569
+ const tag = ctx.params.tag;
142570
+ if (!tag) {
142571
+ throw ApiError.badRequest("Missing migration tag");
142572
+ }
142573
+ const body2 = await parseRequestBody(ctx.request, MigrationResolveSchema);
142574
+ return ctx.services.deploymentState.resolveMigration(slug2, tag, body2, ctx.user);
142575
+ });
142576
+ history = requireDeveloper(async (ctx) => {
142577
+ const slug2 = requireSlug(ctx.params.slug);
142578
+ const limitParam = ctx.url.searchParams.get("limit");
142579
+ let limit;
142580
+ if (limitParam !== null) {
142581
+ limit = Number(limitParam);
142582
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
142583
+ throw ApiError.badRequest("limit must be an integer between 1 and 100");
142584
+ }
142585
+ }
142586
+ return ctx.services.deploymentState.history(slug2, ctx.user, { limit });
142587
+ });
142588
+ restorePoints = requireDeveloper(async (ctx) => {
142589
+ const slug2 = requireSlug(ctx.params.slug);
142590
+ return ctx.services.deploymentState.restorePoints(slug2, ctx.user);
142591
+ });
142592
+ restore = requireDeveloper(async (ctx) => {
142593
+ const slug2 = requireSlug(ctx.params.slug);
142594
+ const body2 = await parseRequestBody(ctx.request, DatabaseRestoreSchema);
142595
+ return ctx.services.deploymentState.restoreToBookmark(slug2, body2, ctx.user);
142596
+ });
142597
+ reportBlocked = requireDeveloper(async (ctx) => {
142598
+ const slug2 = requireSlug(ctx.params.slug);
142599
+ const body2 = await parseRequestBody(ctx.request, DeployBlockedReportSchema);
142600
+ await ctx.services.deploymentState.reportDeployBlocked(slug2, ctx.user, body2);
142601
+ return { recorded: true };
142602
+ });
142603
+ deploymentState = defineControllerNames("deploymentState", {
142604
+ get,
142605
+ baseline,
142606
+ realignMigration,
142607
+ resolveMigration,
142608
+ history,
142609
+ restorePoints,
142610
+ restore,
142611
+ reportBlocked
142612
+ });
142613
+ });
142614
+
140142
142615
  // ../api-core/src/controllers/developer.controller.ts
140143
142616
  var apply, getStatus, developer;
140144
142617
  var init_developer_controller = __esm(() => {
@@ -140605,7 +143078,7 @@ var init_lti_controller = __esm(() => {
140605
143078
  });
140606
143079
 
140607
143080
  // ../api-core/src/controllers/secrets.controller.ts
140608
- var listKeys2, setSecrets, deleteSecret, secrets;
143081
+ var listKeys2, setSecrets, deleteSecret, diff, secrets;
140609
143082
  var init_secrets_controller = __esm(() => {
140610
143083
  init_esm();
140611
143084
  init_schemas_index();
@@ -140651,10 +143124,19 @@ var init_secrets_controller = __esm(() => {
140651
143124
  await ctx.services.secrets.deleteSecret(slug2, key, ctx.user);
140652
143125
  return { success: true };
140653
143126
  });
143127
+ diff = requireDeveloper(async (ctx) => {
143128
+ const slug2 = ctx.params.slug;
143129
+ if (!slug2) {
143130
+ throw ApiError.badRequest("Missing game slug");
143131
+ }
143132
+ const body2 = await parseRequestBody(ctx.request, SecretsDiffRequestSchema);
143133
+ return ctx.services.secrets.diff(slug2, body2.secrets, ctx.user);
143134
+ });
140654
143135
  secrets = defineControllerNames("secrets", {
140655
143136
  listKeys: listKeys2,
140656
143137
  setSecrets,
140657
- deleteSecret
143138
+ deleteSecret,
143139
+ diff
140658
143140
  });
140659
143141
  });
140660
143142
 
@@ -140714,7 +143196,7 @@ var init_session_controller = __esm(() => {
140714
143196
  let baseUrl;
140715
143197
  if (ctx.config.isLocal) {
140716
143198
  try {
140717
- baseUrl = await getTunnelUrl();
143199
+ baseUrl = await getTunnelUrl(ctx.config.baseUrl);
140718
143200
  } catch {}
140719
143201
  }
140720
143202
  return { token, exp, baseUrl };
@@ -140729,7 +143211,7 @@ var populateStudent, getUser, getUserEnrollments, getUserById, setupIntegration,
140729
143211
  var init_timeback_controller = __esm(() => {
140730
143212
  init_esm();
140731
143213
  init_schemas_index();
140732
- init_src4();
143214
+ init_src5();
140733
143215
  init_timeback3();
140734
143216
  init_errors();
140735
143217
  init_utils11();
@@ -141496,6 +143978,7 @@ var init_controllers = __esm(() => {
141496
143978
  init_dashboard_controller();
141497
143979
  init_database_controller();
141498
143980
  init_deploy_controller();
143981
+ init_deployment_state_controller();
141499
143982
  init_developer_controller();
141500
143983
  init_domain_controller();
141501
143984
  init_game_member_controller();
@@ -142030,6 +144513,23 @@ var init_deploy = __esm(async () => {
142030
144513
  });
142031
144514
  });
142032
144515
 
144516
+ // src/routes/platform/games/deployment-state.ts
144517
+ var gameDeploymentStateRouter;
144518
+ var init_deployment_state = __esm(async () => {
144519
+ init_dist7();
144520
+ init_controllers();
144521
+ await init_api3();
144522
+ gameDeploymentStateRouter = new Hono2;
144523
+ gameDeploymentStateRouter.get("/:slug/deployment-state", handle2(deploymentState.get));
144524
+ gameDeploymentStateRouter.post("/:slug/deployment-state/baseline", handle2(deploymentState.baseline));
144525
+ gameDeploymentStateRouter.post("/:slug/deployment-state/migrations/:tag/realign", handle2(deploymentState.realignMigration));
144526
+ gameDeploymentStateRouter.post("/:slug/deployment-state/migrations/:tag/resolve", handle2(deploymentState.resolveMigration));
144527
+ gameDeploymentStateRouter.get("/:slug/deployments", handle2(deploymentState.history));
144528
+ gameDeploymentStateRouter.post("/:slug/deployments/blocked", handle2(deploymentState.reportBlocked));
144529
+ gameDeploymentStateRouter.get("/:slug/database/restore-points", handle2(deploymentState.restorePoints));
144530
+ gameDeploymentStateRouter.post("/:slug/database/restore", handle2(deploymentState.restore));
144531
+ });
144532
+
142033
144533
  // src/routes/platform/games/domains.ts
142034
144534
  var gameDomainsRouter;
142035
144535
  var init_domains2 = __esm(async () => {
@@ -142075,6 +144575,7 @@ var init_secrets = __esm(async () => {
142075
144575
  gameSecretsRouter = new Hono2;
142076
144576
  gameSecretsRouter.get("/:slug/secrets", handle2(secrets.listKeys));
142077
144577
  gameSecretsRouter.post("/:slug/secrets", handle2(secrets.setSecrets));
144578
+ gameSecretsRouter.post("/:slug/secrets/diff", handle2(secrets.diff));
142078
144579
  gameSecretsRouter.delete("/:slug/secrets/:key", handle2(secrets.deleteSecret));
142079
144580
  });
142080
144581
 
@@ -142277,6 +144778,7 @@ var init_games2 = __esm(async () => {
142277
144778
  await __promiseAll([
142278
144779
  init_crud(),
142279
144780
  init_deploy(),
144781
+ init_deployment_state(),
142280
144782
  init_domains2(),
142281
144783
  init_logs(),
142282
144784
  init_scores(),
@@ -142291,6 +144793,7 @@ var init_games2 = __esm(async () => {
142291
144793
  gamesRouter.route("/", gameVerifyRouter);
142292
144794
  gamesRouter.route("/", gameUploadsRouter);
142293
144795
  gamesRouter.route("/", gameDeployRouter);
144796
+ gamesRouter.route("/", gameDeploymentStateRouter);
142294
144797
  gamesRouter.route("/", gameDomainsRouter);
142295
144798
  gamesRouter.route("/", gameLogsRouter);
142296
144799
  gamesRouter.route("/", gameScoresRouter);
@@ -144637,7 +147140,7 @@ function printBanner(options) {
144637
147140
  }
144638
147141
 
144639
147142
  // src/cli/options.ts
144640
- init_src4();
147143
+ init_src5();
144641
147144
  import { resolve as resolve3 } from "node:path";
144642
147145
 
144643
147146
  // ../utils/src/file-loader.ts