@playcademy/sandbox 0.6.1-beta.6 → 0.6.1-beta.8

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/server.js CHANGED
@@ -310,7 +310,7 @@ var init_timeback2 = __esm(() => {
310
310
  });
311
311
 
312
312
  // ../constants/src/cloudflare.ts
313
- var WORKER_NAMING, MAX_WORKER_NAME_LENGTH = 63, SECRETS_PREFIX = "secrets_", CLOUDFLARE_COMPATIBILITY_DATE = "2025-10-11";
313
+ var WORKER_NAMING, MAX_WORKER_NAME_LENGTH = 63, SECRETS_PREFIX = "secrets_", CLOUDFLARE_COMPATIBILITY_DATE = "2025-10-11", D1_TIME_TRAVEL_RETENTION_DAYS = 30;
314
314
  var init_cloudflare = __esm(() => {
315
315
  WORKER_NAMING = {
316
316
  STAGING_PREFIX: "staging-",
@@ -1083,7 +1083,7 @@ var package_default;
1083
1083
  var init_package = __esm(() => {
1084
1084
  package_default = {
1085
1085
  name: "@playcademy/sandbox",
1086
- version: "0.6.1-beta.6",
1086
+ version: "0.6.1-beta.8",
1087
1087
  description: "Local development server for Playcademy game development",
1088
1088
  type: "module",
1089
1089
  exports: {
@@ -1152,6 +1152,16 @@ var init_package = __esm(() => {
1152
1152
  });
1153
1153
 
1154
1154
  // ../api-core/src/errors/domain.error.ts
1155
+ function deployErrorCode(error) {
1156
+ if (!(error instanceof DomainError)) {
1157
+ return null;
1158
+ }
1159
+ const details = error.details;
1160
+ if (typeof details !== "object" || details === null || !("code" in details)) {
1161
+ return null;
1162
+ }
1163
+ return typeof details.code === "string" ? details.code : null;
1164
+ }
1155
1165
  var DomainError, BadRequestError, UnauthorizedError, AccessDeniedError, NotFoundError, ConflictError, AlreadyExistsError, ValidationError, RateLimitError, InternalError, ServiceUnavailableError, TimeoutError;
1156
1166
  var init_domain_error = __esm(() => {
1157
1167
  DomainError = class DomainError extends Error {
@@ -1234,6 +1244,158 @@ var init_domain_error = __esm(() => {
1234
1244
  };
1235
1245
  });
1236
1246
 
1247
+ // ../types/src/game.ts
1248
+ var DEPLOY_ERROR_CODES, REFUSAL_CODES, DEPLOY_REFUSAL_CODES, DELETED_ACCOUNT_LABEL = "(deleted account)";
1249
+ var init_game2 = __esm(() => {
1250
+ DEPLOY_ERROR_CODES = {
1251
+ deployIdPayloadMismatch: "deploy-id-payload-mismatch",
1252
+ stateConflict: "deployment-state-conflict",
1253
+ stateDrift: "deployment-state-drift",
1254
+ destructiveSchema: "destructive-schema-changes",
1255
+ upgradeRequired: "deploy-upgrade-required",
1256
+ checksumMismatch: "migration-checksum-mismatch",
1257
+ journalDivergence: "migration-journal-divergence",
1258
+ outOfOrder: "migration-out-of-order",
1259
+ migrationFailed: "migration-failed",
1260
+ strategyMismatch: "strategy-mismatch",
1261
+ pushFailed: "push-failed",
1262
+ pruneUnmanagedSecrets: "secrets-prune-unmanaged",
1263
+ baselineLedgerNotEmpty: "baseline-ledger-not-empty",
1264
+ baselineDatabaseEmpty: "baseline-database-empty",
1265
+ baselineAlreadyAdopted: "baseline-already-adopted",
1266
+ baselineClaimRejected: "baseline-claim-rejected",
1267
+ restoreUnsupported: "restore-unsupported",
1268
+ restoreIncomplete: "restore-incomplete",
1269
+ restoreBlockedByDeploy: "restore-blocked-by-deploy",
1270
+ restoreExpired: "restore-expired"
1271
+ };
1272
+ REFUSAL_CODES = [
1273
+ DEPLOY_ERROR_CODES.deployIdPayloadMismatch,
1274
+ DEPLOY_ERROR_CODES.stateConflict,
1275
+ DEPLOY_ERROR_CODES.stateDrift,
1276
+ DEPLOY_ERROR_CODES.destructiveSchema,
1277
+ DEPLOY_ERROR_CODES.upgradeRequired,
1278
+ DEPLOY_ERROR_CODES.checksumMismatch,
1279
+ DEPLOY_ERROR_CODES.journalDivergence,
1280
+ DEPLOY_ERROR_CODES.outOfOrder,
1281
+ DEPLOY_ERROR_CODES.strategyMismatch,
1282
+ DEPLOY_ERROR_CODES.pruneUnmanagedSecrets,
1283
+ DEPLOY_ERROR_CODES.baselineLedgerNotEmpty,
1284
+ DEPLOY_ERROR_CODES.baselineDatabaseEmpty,
1285
+ DEPLOY_ERROR_CODES.baselineAlreadyAdopted,
1286
+ DEPLOY_ERROR_CODES.baselineClaimRejected
1287
+ ];
1288
+ DEPLOY_REFUSAL_CODES = new Set(REFUSAL_CODES);
1289
+ });
1290
+
1291
+ // ../api-core/src/errors/deploy.error.ts
1292
+ var DeployIdConflictError, DeploymentStateConflictError, DeploymentStateDriftError, LegacySchemaUpgradeRequiredError, DestructiveSchemaError, MigrationChecksumMismatchError, MigrationJournalDivergenceError, MigrationOrderError, SecretsPruneUnmanagedError, BaselineLedgerNotEmptyError, BaselineDatabaseEmptyError, BaselineAlreadyAdoptedError, BaselineClaimRejectedError, MigrationExecutionError, PushExecutionError;
1293
+ var init_deploy_error = __esm(() => {
1294
+ init_game2();
1295
+ init_domain_error();
1296
+ DeployIdConflictError = class DeployIdConflictError extends ConflictError {
1297
+ constructor(deployId, existingJobId) {
1298
+ 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 });
1299
+ this.name = "DeployIdConflictError";
1300
+ }
1301
+ };
1302
+ DeploymentStateConflictError = class DeploymentStateConflictError extends ConflictError {
1303
+ constructor(payload) {
1304
+ 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 });
1305
+ this.name = "DeploymentStateConflictError";
1306
+ }
1307
+ };
1308
+ DeploymentStateDriftError = class DeploymentStateDriftError extends ConflictError {
1309
+ constructor(payload) {
1310
+ 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 });
1311
+ this.name = "DeploymentStateDriftError";
1312
+ }
1313
+ };
1314
+ LegacySchemaUpgradeRequiredError = class LegacySchemaUpgradeRequiredError extends ValidationError {
1315
+ constructor() {
1316
+ 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 });
1317
+ this.name = "LegacySchemaUpgradeRequiredError";
1318
+ }
1319
+ };
1320
+ DestructiveSchemaError = class DestructiveSchemaError extends ValidationError {
1321
+ constructor(statements) {
1322
+ 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 });
1323
+ this.name = "DestructiveSchemaError";
1324
+ }
1325
+ };
1326
+ MigrationChecksumMismatchError = class MigrationChecksumMismatchError extends ConflictError {
1327
+ constructor(mismatches) {
1328
+ const tags = mismatches.map((mismatch) => mismatch.tag).join(", ");
1329
+ super(`Applied migration(s) ${tags} no longer match their recorded checksums.`, {
1330
+ code: DEPLOY_ERROR_CODES.checksumMismatch,
1331
+ mismatches
1332
+ });
1333
+ this.name = "MigrationChecksumMismatchError";
1334
+ }
1335
+ };
1336
+ MigrationJournalDivergenceError = class MigrationJournalDivergenceError extends ConflictError {
1337
+ constructor(tags) {
1338
+ 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 });
1339
+ this.name = "MigrationJournalDivergenceError";
1340
+ }
1341
+ };
1342
+ MigrationOrderError = class MigrationOrderError extends ValidationError {
1343
+ constructor(tags) {
1344
+ 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 });
1345
+ this.name = "MigrationOrderError";
1346
+ }
1347
+ };
1348
+ SecretsPruneUnmanagedError = class SecretsPruneUnmanagedError extends ValidationError {
1349
+ constructor(keys) {
1350
+ 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 });
1351
+ this.name = "SecretsPruneUnmanagedError";
1352
+ }
1353
+ };
1354
+ BaselineLedgerNotEmptyError = class BaselineLedgerNotEmptyError extends ConflictError {
1355
+ constructor(tags) {
1356
+ 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 });
1357
+ this.name = "BaselineLedgerNotEmptyError";
1358
+ }
1359
+ };
1360
+ BaselineDatabaseEmptyError = class BaselineDatabaseEmptyError extends ValidationError {
1361
+ constructor() {
1362
+ 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 });
1363
+ this.name = "BaselineDatabaseEmptyError";
1364
+ }
1365
+ };
1366
+ BaselineAlreadyAdoptedError = class BaselineAlreadyAdoptedError extends ConflictError {
1367
+ constructor(baselineSource) {
1368
+ 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 });
1369
+ this.name = "BaselineAlreadyAdoptedError";
1370
+ }
1371
+ };
1372
+ BaselineClaimRejectedError = class BaselineClaimRejectedError extends ConflictError {
1373
+ constructor(details) {
1374
+ const [first] = details.contradictions;
1375
+ 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 });
1376
+ this.name = "BaselineClaimRejectedError";
1377
+ }
1378
+ };
1379
+ MigrationExecutionError = class MigrationExecutionError extends ValidationError {
1380
+ tag;
1381
+ offset;
1382
+ constructor(input) {
1383
+ 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 });
1384
+ this.name = "MigrationExecutionError";
1385
+ this.tag = input.tag;
1386
+ this.offset = input.offset;
1387
+ }
1388
+ };
1389
+ PushExecutionError = class PushExecutionError extends ValidationError {
1390
+ offset;
1391
+ constructor(input) {
1392
+ super(`Push schema changes failed and rolled back: ${input.d1Message}. ` + "Fix the schema and redeploy — nothing was applied", { code: DEPLOY_ERROR_CODES.pushFailed, ...input });
1393
+ this.name = "PushExecutionError";
1394
+ this.offset = input.offset;
1395
+ }
1396
+ };
1397
+ });
1398
+
1237
1399
  // ../api-core/src/errors/api.error.ts
1238
1400
  var STATUS_MAP, ApiError;
1239
1401
  var init_api_error = __esm(() => {
@@ -1333,6 +1495,7 @@ var init_api_error = __esm(() => {
1333
1495
  // ../api-core/src/errors/index.ts
1334
1496
  var init_errors = __esm(() => {
1335
1497
  init_domain_error();
1498
+ init_deploy_error();
1336
1499
  init_api_error();
1337
1500
  });
1338
1501
 
@@ -5687,7 +5850,8 @@ var init_schema = __esm(() => {
5687
5850
  ltiTestMode: exports_external.boolean().default(false),
5688
5851
  platformServiceJwt: platformServiceJwtConfigSchema.optional(),
5689
5852
  uploadBucket: exports_external.string().optional(),
5690
- queueIngressSecret: exports_external.string().optional()
5853
+ queueIngressSecret: exports_external.string().optional(),
5854
+ secretsManifestPepper: exports_external.string().optional()
5691
5855
  }).superRefine((config2, ctx) => {
5692
5856
  if (config2.isLocal && !config2.baseUrl) {
5693
5857
  ctx.addIssue({
@@ -11216,7 +11380,7 @@ var init_table4 = __esm(() => {
11216
11380
  });
11217
11381
 
11218
11382
  // ../data/src/domains/game/table.ts
11219
- var gamePlatformEnum, gameTypeEnum, gameVisibilityEnum, games, gameMemberRoleEnum, gameMembers, gameMembersRelations, gameDashboardUserRoleEnum, gameDashboardUsers, gameDashboardUsersRelations, deploymentProviderEnum, deploymentTargetEnum, deployJobStatusEnum, gameDeployments, gameDeployJobs, customHostnameStatusEnum, customHostnameSslStatusEnum, customHostnameEnvironmentEnum, gameCustomHostnames;
11383
+ var gamePlatformEnum, gameTypeEnum, gameVisibilityEnum, games, gameMemberRoleEnum, gameMembers, gameMembersRelations, gameDashboardUserRoleEnum, gameDashboardUsers, gameDashboardUsersRelations, deploymentProviderEnum, deploymentTargetEnum, deployJobStatusEnum, gameDeployments, gameDeployJobs, gameDeployEvents, gameDeploymentState, customHostnameStatusEnum, customHostnameSslStatusEnum, customHostnameEnvironmentEnum, gameCustomHostnames;
11220
11384
  var init_table5 = __esm(() => {
11221
11385
  init_drizzle_orm();
11222
11386
  init_pg_core();
@@ -11305,15 +11469,20 @@ var init_table5 = __esm(() => {
11305
11469
  target: deploymentTargetEnum("target").notNull().default("game"),
11306
11470
  url: text("url").notNull(),
11307
11471
  codeHash: text("code_hash"),
11472
+ schemaHash: text("schema_hash"),
11473
+ schemaFingerprint: text("schema_fingerprint"),
11474
+ timeTravelBookmark: text("time_travel_bookmark"),
11475
+ bookmarkCapturedAt: timestamp("bookmark_captured_at", { withTimezone: true }),
11308
11476
  isActive: boolean("is_active").notNull().default(false),
11309
11477
  resources: jsonb("resources").$type(),
11310
11478
  deployedAt: timestamp("deployed_at", { withTimezone: true }).notNull().defaultNow()
11311
- });
11479
+ }, (table3) => [index("game_deployments_game_target_idx").on(table3.gameId, table3.target)]);
11312
11480
  gameDeployJobs = pgTable("game_deploy_jobs", {
11313
11481
  id: uuid("id").primaryKey().defaultRandom(),
11314
11482
  gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
11315
- userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
11483
+ userId: text("user_id").references(() => users.id, { onDelete: "set null" }),
11316
11484
  status: deployJobStatusEnum("status").notNull().default("pending"),
11485
+ deployId: text("deploy_id"),
11317
11486
  request: jsonb("request").$type().notNull(),
11318
11487
  events: jsonb("events").$type().notNull().default([]),
11319
11488
  error: text("error"),
@@ -11327,6 +11496,27 @@ var init_table5 = __esm(() => {
11327
11496
  createdAt: timestamp("created_at", { mode: "date", withTimezone: true }).notNull().defaultNow(),
11328
11497
  startedAt: timestamp("started_at", { mode: "date", withTimezone: true }),
11329
11498
  completedAt: timestamp("completed_at", { mode: "date", withTimezone: true })
11499
+ }, (table3) => [uniqueIndex("game_deploy_jobs_game_deploy_id_idx").on(table3.gameId, table3.deployId)]);
11500
+ gameDeployEvents = pgTable("game_deploy_events", {
11501
+ id: uuid("id").primaryKey().defaultRandom(),
11502
+ gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
11503
+ userId: text("user_id").references(() => users.id, { onDelete: "set null" }),
11504
+ kind: text("kind").$type().notNull(),
11505
+ payload: jsonb("payload").$type().notNull(),
11506
+ createdAt: timestamp("created_at", { mode: "date", withTimezone: true }).notNull().defaultNow()
11507
+ }, (table3) => [index("game_deploy_events_game_idx").on(table3.gameId, table3.createdAt)]);
11508
+ gameDeploymentState = pgTable("game_deployment_state", {
11509
+ id: uuid("id").primaryKey().defaultRandom(),
11510
+ gameId: uuid("game_id").notNull().unique().references(() => games.id, { onDelete: "cascade" }),
11511
+ schemaHash: text("schema_hash"),
11512
+ schemaSnapshot: jsonb("schema_snapshot"),
11513
+ schemaFingerprint: text("schema_fingerprint"),
11514
+ secretsManifest: jsonb("secrets_manifest").$type(),
11515
+ integrationsHash: text("integrations_hash"),
11516
+ buildHash: text("build_hash"),
11517
+ compatibilityDate: text("compatibility_date"),
11518
+ baselineSource: text("baseline_source").$type(),
11519
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
11330
11520
  });
11331
11521
  customHostnameStatusEnum = pgEnum("custom_hostname_status", [
11332
11522
  "pending",
@@ -11489,7 +11679,9 @@ __export(exports_tables_index, {
11489
11679
  gameMembers: () => gameMembers,
11490
11680
  gameMemberRoleEnum: () => gameMemberRoleEnum,
11491
11681
  gameDeployments: () => gameDeployments,
11682
+ gameDeploymentState: () => gameDeploymentState,
11492
11683
  gameDeployJobs: () => gameDeployJobs,
11684
+ gameDeployEvents: () => gameDeployEvents,
11493
11685
  gameDashboardUsersRelations: () => gameDashboardUsersRelations,
11494
11686
  gameDashboardUsers: () => gameDashboardUsers,
11495
11687
  gameDashboardUserRoleEnum: () => gameDashboardUserRoleEnum,
@@ -22504,7 +22696,112 @@ var init_zip = __esm(() => {
22504
22696
  import_jszip = __toESM(require_lib3(), 1);
22505
22697
  });
22506
22698
 
22699
+ // ../utils/src/stages.ts
22700
+ function isPreviewStage(stage) {
22701
+ return PREVIEW_STAGE_PATTERN.test(stage);
22702
+ }
22703
+ var PREVIEW_STAGE_PATTERN;
22704
+ var init_stages = __esm(() => {
22705
+ PREVIEW_STAGE_PATTERN = /^pr-\d+$/;
22706
+ });
22707
+
22708
+ // ../api-core/src/utils/deployment.util.ts
22709
+ function deployJobInstant() {
22710
+ return sql`COALESCE(${gameDeployJobs.completedAt}, ${gameDeployJobs.createdAt})`;
22711
+ }
22712
+ async function findLastSuccessfulDeploy(db2, gameId) {
22713
+ const job = await db2.query.gameDeployJobs.findFirst({
22714
+ where: and(eq(gameDeployJobs.gameId, gameId), eq(gameDeployJobs.status, "succeeded")),
22715
+ orderBy: desc(deployJobInstant()),
22716
+ columns: { userId: true, createdAt: true, completedAt: true }
22717
+ });
22718
+ if (!job) {
22719
+ return null;
22720
+ }
22721
+ return { userId: job.userId, at: job.completedAt ?? job.createdAt };
22722
+ }
22723
+ async function findLastSuccessfulDeployWithEmail(db2, gameId) {
22724
+ const lastDeploy = await findLastSuccessfulDeploy(db2, gameId);
22725
+ if (!lastDeploy) {
22726
+ return null;
22727
+ }
22728
+ const deployer = lastDeploy.userId ? await db2.query.users.findFirst({
22729
+ where: eq(users.id, lastDeploy.userId),
22730
+ columns: { email: true }
22731
+ }) : null;
22732
+ return { ...lastDeploy, email: deployer?.email ?? null };
22733
+ }
22734
+ function getGameDeploymentId(gameSlug, sstStage) {
22735
+ if (sstStage === "production") {
22736
+ return gameSlug;
22737
+ }
22738
+ if (sstStage === "dev" || isPreviewStage(sstStage)) {
22739
+ return `${WORKER_NAMING.STAGING_PREFIX}${gameSlug}`;
22740
+ }
22741
+ return `${WORKER_NAMING.LOCAL_PREFIX}${sstStage}-${gameSlug}`;
22742
+ }
22743
+ function getDashboardDeploymentId(gameSlug, sstStage) {
22744
+ return `${getGameDeploymentId(gameSlug, sstStage)}${DASHBOARD_WORKER_SUFFIX}`;
22745
+ }
22746
+ function getGameWorkerApiKeyName(slug) {
22747
+ return `${GAME_WORKER_KEY_PREFIX}${slug}`.substring(0, 32);
22748
+ }
22749
+ function getDashboardWorkerApiKeyName(slug) {
22750
+ return `${DASHBOARD_WORKER_KEY_PREFIX}${slug}`;
22751
+ }
22752
+ function toBindingName(queueKey) {
22753
+ return `${queueKey.replace(/-/g, "_").toUpperCase()}_QUEUE`;
22754
+ }
22755
+ function isSchemaAdopted(state) {
22756
+ if (!state) {
22757
+ return false;
22758
+ }
22759
+ return state.schemaHash !== null || state.schemaFingerprint !== null || state.schemaSnapshot !== null;
22760
+ }
22761
+ function isPushAdopted(state) {
22762
+ return Boolean(state?.schemaHash);
22763
+ }
22764
+ function isMigrateManaged(state) {
22765
+ return Boolean(state?.schemaFingerprint) && !state?.schemaHash;
22766
+ }
22767
+ function generateDeploymentHash(code) {
22768
+ return sha256Hex(code);
22769
+ }
22770
+ function computeDeployPayloadFingerprint(payload) {
22771
+ return sha256Hex(canonicalJson(payload));
22772
+ }
22773
+ function canonicalJson(value) {
22774
+ if (value === null || typeof value !== "object") {
22775
+ return JSON.stringify(value) ?? "null";
22776
+ }
22777
+ if (Array.isArray(value)) {
22778
+ return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
22779
+ }
22780
+ const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== undefined).toSorted(([a], [b]) => compareKeys(a, b)).map(([key, entryValue]) => `${JSON.stringify(key)}:${canonicalJson(entryValue)}`);
22781
+ return `{${entries.join(",")}}`;
22782
+ }
22783
+ function compareKeys(a, b) {
22784
+ if (a < b) {
22785
+ return -1;
22786
+ }
22787
+ if (a > b) {
22788
+ return 1;
22789
+ }
22790
+ return 0;
22791
+ }
22792
+ var GAME_WORKER_KEY_PREFIX = "game-worker-", DASHBOARD_WORKER_KEY_PREFIX = "dash-worker-";
22793
+ var init_deployment_util = __esm(() => {
22794
+ init_drizzle_orm();
22795
+ init_src();
22796
+ init_tables_index();
22797
+ init_stages();
22798
+ });
22799
+
22507
22800
  // ../api-core/src/services/deploy-job.service.ts
22801
+ function isEventDetails(value) {
22802
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22803
+ }
22804
+
22508
22805
  class DeployJobService {
22509
22806
  deps;
22510
22807
  constructor(deps) {
@@ -22517,6 +22814,9 @@ class DeployJobService {
22517
22814
  if (leaseLost) {
22518
22815
  return "lease_lost";
22519
22816
  }
22817
+ if (DEPLOY_REFUSAL_CODES.has(deployErrorCode(error) ?? "")) {
22818
+ return "refused";
22819
+ }
22520
22820
  if (error instanceof DomainError) {
22521
22821
  return "domain_error";
22522
22822
  }
@@ -22596,13 +22896,28 @@ class DeployJobService {
22596
22896
  const bucketName = this.getUploadBucket();
22597
22897
  this.deps.storage.deleteObject(bucketName, codeUploadToken).catch(catchAttrs("deploy_job.temp_cleanup"));
22598
22898
  }
22599
- sanitizeRequestForPersistence(request) {
22600
- const sanitized = { ...request };
22899
+ async sanitizeRequestForPersistence(request) {
22900
+ const sanitized = {
22901
+ ...request
22902
+ };
22601
22903
  delete sanitized._headers;
22602
22904
  delete sanitized.code;
22603
22905
  delete sanitized.codeUploadToken;
22906
+ const codeFingerprint = await this.computeCodeFingerprint(request);
22907
+ if (codeFingerprint) {
22908
+ sanitized.codeFingerprint = codeFingerprint;
22909
+ }
22604
22910
  return sanitized;
22605
22911
  }
22912
+ async computeCodeFingerprint(request) {
22913
+ if (request.codeUploadToken) {
22914
+ return `upload:${request.codeUploadToken}`;
22915
+ }
22916
+ if (request.code) {
22917
+ return `sha256:${await generateDeploymentHash(request.code)}`;
22918
+ }
22919
+ return;
22920
+ }
22606
22921
  getLeaseExpiry() {
22607
22922
  return new Date(Date.now() + DEPLOY_JOB_LEASE_MS);
22608
22923
  }
@@ -22635,8 +22950,36 @@ class DeployJobService {
22635
22950
  heartbeatAt: null
22636
22951
  }).where(and(eq(gameDeployJobs.id, jobId), eq(gameDeployJobs.leaseId, leaseId)));
22637
22952
  }
22953
+ async findByDeployId(gameId, deployId) {
22954
+ const job = await this.deps.db.query.gameDeployJobs.findFirst({
22955
+ where: and(eq(gameDeployJobs.gameId, gameId), eq(gameDeployJobs.deployId, deployId))
22956
+ });
22957
+ return job ?? null;
22958
+ }
22959
+ async resolveIdempotentReplay(existing, request) {
22960
+ const [incoming, stored] = await Promise.all([
22961
+ this.sanitizeRequestForPersistence(request).then(computeDeployPayloadFingerprint),
22962
+ computeDeployPayloadFingerprint(existing.request)
22963
+ ]);
22964
+ if (incoming !== stored) {
22965
+ setAttribute("app.deploy_job.idempotency", "payload_mismatch");
22966
+ throw new DeployIdConflictError(request.deployId, existing.id);
22967
+ }
22968
+ setAttributes({
22969
+ "app.deploy_job.idempotency": "replayed",
22970
+ "app.deploy_job.id": existing.id,
22971
+ "app.deploy_job.status": existing.status
22972
+ });
22973
+ return this.toResponse(existing);
22974
+ }
22638
22975
  async create(slug, request, user) {
22639
22976
  const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
22977
+ if (request.deployId) {
22978
+ const existing = await this.findByDeployId(game2.id, request.deployId);
22979
+ if (existing) {
22980
+ return this.resolveIdempotentReplay(existing, request);
22981
+ }
22982
+ }
22640
22983
  const jobId = crypto.randomUUID();
22641
22984
  let codeSource = "none";
22642
22985
  if (request.code) {
@@ -22652,7 +22995,7 @@ class DeployJobService {
22652
22995
  request.code = await this.loadUploadedCode(request.codeUploadToken, game2.id);
22653
22996
  }
22654
22997
  setAttribute("app.deploy_job.code_bundle_size", request.code?.length ?? 0);
22655
- const sanitizedRequest = this.sanitizeRequestForPersistence(request);
22998
+ const sanitizedRequest = await this.sanitizeRequestForPersistence(request);
22656
22999
  if (request.code) {
22657
23000
  await this.storeCodeBundle(jobId, request.code);
22658
23001
  }
@@ -22662,6 +23005,7 @@ class DeployJobService {
22662
23005
  id: jobId,
22663
23006
  gameId: game2.id,
22664
23007
  userId: user.id,
23008
+ deployId: request.deployId ?? null,
22665
23009
  request: sanitizedRequest,
22666
23010
  events: [
22667
23011
  {
@@ -22673,6 +23017,12 @@ class DeployJobService {
22673
23017
  }).returning();
22674
23018
  } catch (error) {
22675
23019
  await this.deleteCodeBundle(jobId);
23020
+ if (request.deployId) {
23021
+ const winner = await this.findByDeployId(game2.id, request.deployId);
23022
+ if (winner) {
23023
+ return this.resolveIdempotentReplay(winner, request);
23024
+ }
23025
+ }
22676
23026
  throw error;
22677
23027
  }
22678
23028
  if (!job) {
@@ -22787,7 +23137,11 @@ class DeployJobService {
22787
23137
  "app.deploy_job.error_status": errorClassification?.errorStatus
22788
23138
  });
22789
23139
  if (!effectiveLeaseLost) {
22790
- await this.addStatusEvent(jobId, "Deployment failed", { error: message });
23140
+ const structuredDetails = error instanceof DomainError && isEventDetails(error.details) ? error.details : undefined;
23141
+ await this.addStatusEvent(jobId, "Deployment failed", {
23142
+ error: message,
23143
+ ...structuredDetails
23144
+ });
22791
23145
  const failed = await this.markFailed(jobId, leaseId, message, errorClassification);
22792
23146
  if (!failed) {
22793
23147
  await this.clearLease(jobId, leaseId);
@@ -22800,18 +23154,21 @@ class DeployJobService {
22800
23154
  displayName: game2.displayName,
22801
23155
  error: message,
22802
23156
  target,
22803
- developer: { id: user.id, email: user.email }
23157
+ developer: { id: user.id, email: user.email },
23158
+ errorCode: deployErrorCode(error)
22804
23159
  });
22805
23160
  }
22806
23161
  await this.deleteCodeBundle(jobId);
22807
23162
  }
22808
23163
  async loadJobActors(job, jobId, leaseId, onMissing) {
22809
- const game2 = await this.deps.db.query.games.findFirst({
22810
- where: eq(games.id, job.gameId)
22811
- });
22812
- const user = await this.deps.db.query.users.findFirst({
22813
- where: eq(users.id, job.userId)
22814
- });
23164
+ const [game2, user] = await Promise.all([
23165
+ this.deps.db.query.games.findFirst({
23166
+ where: eq(games.id, job.gameId)
23167
+ }),
23168
+ job.userId ? this.deps.db.query.users.findFirst({
23169
+ where: eq(users.id, job.userId)
23170
+ }) : undefined
23171
+ ]);
22815
23172
  if (!game2 || !user) {
22816
23173
  const message = !game2 ? "Deploy job game no longer exists" : "Deploy job user no longer exists";
22817
23174
  onMissing();
@@ -22897,7 +23254,8 @@ class DeployJobService {
22897
23254
  for await (const step of this.deps.runDeploy(game2.slug, request, user, uploadDeps, extractZipToDirectory)) {
22898
23255
  assertLease();
22899
23256
  if (step.type === "status" && "message" in step.data && typeof step.data.message === "string") {
22900
- await this.addStatusEvent(jobId, step.data.message);
23257
+ const details = "details" in step.data && isEventDetails(step.data.details) ? step.data.details : undefined;
23258
+ await this.addStatusEvent(jobId, step.data.message, details);
22901
23259
  }
22902
23260
  }
22903
23261
  assertLease();
@@ -22955,8 +23313,10 @@ var init_deploy_job_service = __esm(() => {
22955
23313
  init_helpers_index();
22956
23314
  init_tables_index();
22957
23315
  init_spans();
23316
+ init_game2();
22958
23317
  init_zip();
22959
23318
  init_errors();
23319
+ init_deployment_util();
22960
23320
  STATUS_MAP2 = {
22961
23321
  BAD_REQUEST: 400,
22962
23322
  UNAUTHORIZED: 401,
@@ -22978,8 +23338,153 @@ var init_deploy_job_service = __esm(() => {
22978
23338
  DEPLOY_JOB_LEASE_MS = 2 * 60 * 1000;
22979
23339
  DEPLOY_JOB_HEARTBEAT_MS = 30 * 1000;
22980
23340
  });
23341
+ // ../cloudflare/src/utils/schema.ts
23342
+ function normalizeSqlForChecksum(sql4) {
23343
+ const unified = sql4.replace(/\r\n/g, `
23344
+ `).replace(/\r/g, `
23345
+ `);
23346
+ const stripped = stripSqlComments(unified);
23347
+ return stripped.split(`
23348
+ `).map((line3) => line3.replace(/\s+$/, "")).filter((line3) => line3 !== "").join(`
23349
+ `);
23350
+ }
23351
+ function stripSqlComments(sql4) {
23352
+ let output = "";
23353
+ let i2 = 0;
23354
+ while (i2 < sql4.length) {
23355
+ const char3 = sql4[i2];
23356
+ const next = sql4[i2 + 1];
23357
+ if (char3 === "-" && next === "-") {
23358
+ i2 = skipLineComment(sql4, i2);
23359
+ } else if (char3 === "/" && next === "*") {
23360
+ output += " ";
23361
+ i2 = skipBlockComment(sql4, i2);
23362
+ } else if (char3 === "'" || char3 === '"' || char3 === "`") {
23363
+ const quoted = copyQuoted(sql4, i2, char3);
23364
+ output += quoted.text;
23365
+ i2 = quoted.end;
23366
+ } else if (char3 === "[") {
23367
+ const bracketed = copyBracketed(sql4, i2);
23368
+ output += bracketed.text;
23369
+ i2 = bracketed.end;
23370
+ } else {
23371
+ output += char3;
23372
+ i2++;
23373
+ }
23374
+ }
23375
+ return output;
23376
+ }
23377
+ function skipLineComment(sql4, start2) {
23378
+ let i2 = start2 + 2;
23379
+ while (i2 < sql4.length && sql4[i2] !== `
23380
+ `) {
23381
+ i2++;
23382
+ }
23383
+ return i2;
23384
+ }
23385
+ function skipBlockComment(sql4, start2) {
23386
+ let i2 = start2 + 2;
23387
+ while (i2 < sql4.length && !(sql4[i2] === "*" && sql4[i2 + 1] === "/")) {
23388
+ i2++;
23389
+ }
23390
+ return i2 + 2;
23391
+ }
23392
+ function copyQuoted(sql4, start2, quote) {
23393
+ let text3 = quote;
23394
+ let i2 = start2 + 1;
23395
+ while (i2 < sql4.length) {
23396
+ text3 += sql4[i2];
23397
+ if (sql4[i2] !== quote) {
23398
+ i2++;
23399
+ } else if (sql4[i2 + 1] === quote) {
23400
+ text3 += quote;
23401
+ i2 += 2;
23402
+ } else {
23403
+ i2++;
23404
+ break;
23405
+ }
23406
+ }
23407
+ return { text: text3, end: i2 };
23408
+ }
23409
+ function copyBracketed(sql4, start2) {
23410
+ let text3 = "[";
23411
+ let i2 = start2 + 1;
23412
+ while (i2 < sql4.length) {
23413
+ text3 += sql4[i2];
23414
+ i2++;
23415
+ if (sql4[i2 - 1] === "]") {
23416
+ break;
23417
+ }
23418
+ }
23419
+ return { text: text3, end: i2 };
23420
+ }
23421
+ function findOversizedStatement(statements) {
23422
+ for (const [index2, statement] of statements.entries()) {
23423
+ const byteLength = Buffer.byteLength(statement, "utf8");
23424
+ if (byteLength > D1_MAX_STATEMENT_BYTES) {
23425
+ return { index: index2, byteLength };
23426
+ }
23427
+ }
23428
+ return null;
23429
+ }
23430
+ var MIGRATION_LEDGER_TABLE = "_playcademy_migrations", MIGRATION_CHECKSUM_ALGO = "sha256-v1", D1_MAX_STATEMENT_BYTES;
23431
+ var init_schema3 = __esm(() => {
23432
+ D1_MAX_STATEMENT_BYTES = 100 * 1024;
23433
+ });
23434
+
22981
23435
  // ../cloudflare/src/core/namespaces/d1.ts
22982
- var init_d1 = () => {};
23436
+ function parseD1ErrorOffset(message) {
23437
+ const match = message.match(/at offset (\d+)/);
23438
+ return match ? Number(match[1]) : null;
23439
+ }
23440
+ var MIGRATION_LEDGER_DDL, D1StatementTooLargeError, D1BatchError, D1MigrationError;
23441
+ var init_d1 = __esm(() => {
23442
+ init_schema3();
23443
+ MIGRATION_LEDGER_DDL = `CREATE TABLE IF NOT EXISTS ${MIGRATION_LEDGER_TABLE} (
23444
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
23445
+ tag TEXT NOT NULL UNIQUE,
23446
+ checksum TEXT NOT NULL,
23447
+ checksum_algo TEXT NOT NULL DEFAULT 'sha256-v1',
23448
+ deploy_id TEXT NOT NULL,
23449
+ applied_by TEXT,
23450
+ applied_at TEXT NOT NULL,
23451
+ source TEXT NOT NULL DEFAULT 'deploy',
23452
+ statements_total INTEGER
23453
+ )`;
23454
+ D1StatementTooLargeError = class D1StatementTooLargeError extends Error {
23455
+ name = "D1StatementTooLargeError";
23456
+ statementIndex;
23457
+ byteLength;
23458
+ constructor(tag, statementIndex, byteLength) {
23459
+ 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.");
23460
+ this.statementIndex = statementIndex;
23461
+ this.byteLength = byteLength;
23462
+ }
23463
+ };
23464
+ D1BatchError = class D1BatchError extends Error {
23465
+ name = "D1BatchError";
23466
+ d1Message;
23467
+ offset;
23468
+ constructor(d1Message, cause) {
23469
+ super(`Failed to execute batch: ${d1Message}`, { cause });
23470
+ this.d1Message = d1Message;
23471
+ this.offset = parseD1ErrorOffset(d1Message);
23472
+ }
23473
+ };
23474
+ D1MigrationError = class D1MigrationError extends Error {
23475
+ name = "D1MigrationError";
23476
+ tag;
23477
+ d1Message;
23478
+ offset;
23479
+ constructor(tag, d1Message, cause) {
23480
+ super(`Migration '${tag}' failed and rolled back: ${d1Message}`, { cause });
23481
+ this.tag = tag;
23482
+ this.d1Message = d1Message;
23483
+ this.offset = parseD1ErrorOffset(d1Message);
23484
+ }
23485
+ };
23486
+ });
23487
+
22983
23488
  // ../cloudflare/src/core/namespaces/kv.ts
22984
23489
  var init_kv = () => {};
22985
23490
 
@@ -22996,6 +23501,160 @@ var init_assets = __esm(() => {
22996
23501
  init_mime();
22997
23502
  });
22998
23503
 
23504
+ // ../cloudflare/src/utils/journal.ts
23505
+ function findOutOfOrderTags(orderedTags, applied) {
23506
+ let lastAppliedIndex = -1;
23507
+ orderedTags.forEach((tag, index2) => {
23508
+ if (applied.has(tag)) {
23509
+ lastAppliedIndex = index2;
23510
+ }
23511
+ });
23512
+ return orderedTags.filter((tag, index2) => index2 < lastAppliedIndex && !applied.has(tag));
23513
+ }
23514
+
23515
+ // ../cloudflare/src/utils/sql.ts
23516
+ function detectDestructiveStatements(statements) {
23517
+ return statements.filter((statement) => {
23518
+ const scannable = blankStringLiterals(normalizeSqlForChecksum(statement));
23519
+ return DESTRUCTIVE_SQL_PATTERNS.some((pattern) => pattern.test(scannable));
23520
+ });
23521
+ }
23522
+ function splitSqlStatements(sql4) {
23523
+ const statements = [];
23524
+ let current = "";
23525
+ let i2 = 0;
23526
+ while (i2 < sql4.length) {
23527
+ const char3 = sql4[i2];
23528
+ const next = sql4[i2 + 1];
23529
+ if (char3 === ";") {
23530
+ statements.push(current);
23531
+ current = "";
23532
+ i2++;
23533
+ } else if (char3 === "-" && next === "-") {
23534
+ const end = scanLineCommentEnd(sql4, i2);
23535
+ current += sql4.slice(i2, end);
23536
+ i2 = end;
23537
+ } else if (char3 === "/" && next === "*") {
23538
+ const end = scanBlockCommentEnd(sql4, i2);
23539
+ current += sql4.slice(i2, end);
23540
+ i2 = end;
23541
+ } else if (char3 === "'" || char3 === '"' || char3 === "`") {
23542
+ const end = scanQuoteEnd(sql4, i2, char3);
23543
+ current += sql4.slice(i2, end);
23544
+ i2 = end;
23545
+ } else if (char3 === "[") {
23546
+ const end = scanBracketEnd(sql4, i2);
23547
+ current += sql4.slice(i2, end);
23548
+ i2 = end;
23549
+ } else {
23550
+ current += char3;
23551
+ i2++;
23552
+ }
23553
+ }
23554
+ statements.push(current);
23555
+ return statements.map((statement) => statement.trim()).filter((statement) => normalizeSqlForChecksum(statement).trim() !== "");
23556
+ }
23557
+ function blankStringLiterals(sql4) {
23558
+ let output = "";
23559
+ let i2 = 0;
23560
+ while (i2 < sql4.length) {
23561
+ const char3 = sql4[i2];
23562
+ if (char3 === "'") {
23563
+ output += "''";
23564
+ i2 = scanQuoteEnd(sql4, i2, char3);
23565
+ } else if (char3 === '"' || char3 === "`") {
23566
+ const end = scanQuoteEnd(sql4, i2, char3);
23567
+ output += sql4.slice(i2, end);
23568
+ i2 = end;
23569
+ } else if (char3 === "[") {
23570
+ const end = scanBracketEnd(sql4, i2);
23571
+ output += sql4.slice(i2, end);
23572
+ i2 = end;
23573
+ } else {
23574
+ output += char3;
23575
+ i2++;
23576
+ }
23577
+ }
23578
+ return output;
23579
+ }
23580
+ function scanLineCommentEnd(sql4, start2) {
23581
+ let i2 = start2 + 2;
23582
+ while (i2 < sql4.length && sql4[i2] !== `
23583
+ `) {
23584
+ i2++;
23585
+ }
23586
+ return i2;
23587
+ }
23588
+ function scanBlockCommentEnd(sql4, start2) {
23589
+ let i2 = start2 + 2;
23590
+ while (i2 < sql4.length && !(sql4[i2] === "*" && sql4[i2 + 1] === "/")) {
23591
+ i2++;
23592
+ }
23593
+ return Math.min(i2 + 2, sql4.length);
23594
+ }
23595
+ function scanQuoteEnd(sql4, start2, quote) {
23596
+ let i2 = start2 + 1;
23597
+ while (i2 < sql4.length) {
23598
+ if (sql4[i2] !== quote) {
23599
+ i2++;
23600
+ } else if (sql4[i2 + 1] === quote) {
23601
+ i2 += 2;
23602
+ } else {
23603
+ return i2 + 1;
23604
+ }
23605
+ }
23606
+ return i2;
23607
+ }
23608
+ function scanBracketEnd(sql4, start2) {
23609
+ let i2 = start2 + 1;
23610
+ while (i2 < sql4.length) {
23611
+ if (sql4[i2] === "]") {
23612
+ return i2 + 1;
23613
+ }
23614
+ i2++;
23615
+ }
23616
+ return i2;
23617
+ }
23618
+ function isAlreadyExistsSqlError(message) {
23619
+ return /already exists|duplicate column/i.test(message);
23620
+ }
23621
+ function readIdentifier(groups) {
23622
+ return groups.find((group) => group !== undefined) ?? "";
23623
+ }
23624
+ function extractCreatedObjects(statements) {
23625
+ const tables = [];
23626
+ const columns2 = [];
23627
+ for (const statement of statements) {
23628
+ const scannable = blankStringLiterals(normalizeSqlForChecksum(statement));
23629
+ for (const match of scannable.matchAll(CREATE_TABLE_RE)) {
23630
+ const name2 = readIdentifier(match.slice(1, 5));
23631
+ if (name2 && !name2.startsWith("__new_")) {
23632
+ tables.push(name2);
23633
+ }
23634
+ }
23635
+ for (const match of scannable.matchAll(ADD_COLUMN_RE)) {
23636
+ const table8 = readIdentifier(match.slice(1, 5));
23637
+ const column2 = readIdentifier(match.slice(5, 9));
23638
+ if (table8 && column2 && !table8.startsWith("__new_")) {
23639
+ columns2.push({ table: table8, column: column2 });
23640
+ }
23641
+ }
23642
+ }
23643
+ return { tables, columns: columns2 };
23644
+ }
23645
+ var DESTRUCTIVE_SQL_PATTERNS, IDENTIFIER_SOURCE, CREATE_TABLE_RE, ADD_COLUMN_RE;
23646
+ var init_sql3 = __esm(() => {
23647
+ init_schema3();
23648
+ DESTRUCTIVE_SQL_PATTERNS = [
23649
+ /\bDROP\s+TABLE\b/i,
23650
+ /\bALTER\s+TABLE\b[\s\S]*\bDROP\b/i,
23651
+ /\bCREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["'`[]?__new_/i
23652
+ ];
23653
+ IDENTIFIER_SOURCE = String.raw`(?:"([^"]+)"|\`([^\`]+)\`|\[([^\]]+)\]|([A-Za-z_][\w$]*))`;
23654
+ CREATE_TABLE_RE = new RegExp(String.raw`\bCREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?${IDENTIFIER_SOURCE}`, "gi");
23655
+ ADD_COLUMN_RE = new RegExp(String.raw`\bALTER\s+TABLE\s+${IDENTIFIER_SOURCE}\s+ADD\s+(?:COLUMN\s+)?${IDENTIFIER_SOURCE}`, "gi");
23656
+ });
23657
+
22999
23658
  // ../../node_modules/.bun/@fastify+busboy@3.2.0/node_modules/@fastify/busboy/deps/streamsearch/sbmh.js
23000
23659
  var require_sbmh = __commonJS((exports, module2) => {
23001
23660
  var { EventEmitter } = __require("node:events");
@@ -24925,6 +25584,8 @@ var init_multipart = __esm(() => {
24925
25584
  var init_utils5 = __esm(() => {
24926
25585
  init_hostname();
24927
25586
  init_assets();
25587
+ init_schema3();
25588
+ init_sql3();
24928
25589
  init_multipart();
24929
25590
  });
24930
25591
 
@@ -25079,6 +25740,14 @@ var init_core = __esm(() => {
25079
25740
  init_client();
25080
25741
  });
25081
25742
 
25743
+ // ../cloudflare/src/index.ts
25744
+ var init_src4 = __esm(() => {
25745
+ init_core();
25746
+ init_namespaces();
25747
+ init_utils5();
25748
+ init_utils5();
25749
+ });
25750
+
25082
25751
  // ../cloudflare/src/playcademy/constants.ts
25083
25752
  var CUSTOM_DOMAINS_KV_NAME = "cademy-custom-domains", QUEUE_NAME_PREFIX = "playcademy", GAME_WORKER_DOMAIN_PRODUCTION, GAME_WORKER_DOMAIN_STAGING;
25084
25753
  var init_constants2 = __esm(() => {
@@ -27593,46 +28262,382 @@ var init_tunnel = __esm(() => {
27593
28262
  matchedPorts = new Map;
27594
28263
  });
27595
28264
 
27596
- // ../utils/src/stages.ts
27597
- function isPreviewStage(stage) {
27598
- return PREVIEW_STAGE_PATTERN.test(stage);
28265
+ // ../api-core/src/utils/baseline-validation.util.ts
28266
+ function assertBaselineClaimValid(args2) {
28267
+ const validation = validateBaselineClaim(args2);
28268
+ const blocked = validation.contradictions.length > 0 || validation.unverified.length > 0 && !args2.allowUnverified;
28269
+ if (blocked) {
28270
+ addEvent("deployment_state.baseline_claim_rejected", {
28271
+ "app.game.id": args2.gameId,
28272
+ "app.deployment_state.baseline_claim_source": args2.source,
28273
+ "app.deployment_state.baseline_contradictions": validation.contradictions.length,
28274
+ "app.deployment_state.baseline_unverified": validation.unverified.length,
28275
+ "app.deployment_state.baseline_suggested_tag": validation.suggestedTag ?? "none"
28276
+ });
28277
+ throw new BaselineClaimRejectedError({
28278
+ contradictions: validation.contradictions,
28279
+ unverified: validation.unverified,
28280
+ suggestedTag: validation.suggestedTag,
28281
+ claimedTag: args2.claimedTag
28282
+ });
28283
+ }
28284
+ if (validation.unverified.length > 0) {
28285
+ addEvent("deployment_state.baseline_unverified_overridden", {
28286
+ "app.game.id": args2.gameId,
28287
+ "app.user.id": args2.userId,
28288
+ "app.deployment_state.baseline_overridden_tags": validation.unverified.map((entry) => entry.tag).join(",")
28289
+ });
28290
+ }
28291
+ }
28292
+ function validateBaselineClaim(args2) {
28293
+ const { claimedTag, evidence, tables, indexes: indexes2, views, lastDeployAt } = args2;
28294
+ const claimedIndex = evidence.findIndex((entry) => entry.tag === claimedTag);
28295
+ const expected = replayEvidence(evidence, claimedIndex);
28296
+ const live = { tables, indexes: indexes2, views };
28297
+ const verdicts = [];
28298
+ const unverified = [];
28299
+ evidence.forEach((entry, index2) => {
28300
+ if (claimedIndex === -1 || index2 > claimedIndex) {
28301
+ verdicts.push(judgeBeyond(entry, expected, live));
28302
+ return;
28303
+ }
28304
+ const judged = judgeClaimed(entry, expected, live, lastDeployAt);
28305
+ verdicts.push(judged.verdict);
28306
+ if (judged.unverifiable) {
28307
+ unverified.push(judged.verdict);
28308
+ }
28309
+ });
28310
+ return {
28311
+ verdicts,
28312
+ contradictions: verdicts.filter((verdict) => verdict.verdict === "contradicted"),
28313
+ unverified,
28314
+ suggestedTag: suggestTag(evidence, tables)
28315
+ };
27599
28316
  }
27600
- var PREVIEW_STAGE_PATTERN;
27601
- var init_stages = __esm(() => {
27602
- PREVIEW_STAGE_PATTERN = /^pr-\d+$/;
28317
+ function replayEvidence(evidence, claimedIndex) {
28318
+ const state = { tables: new Map, indexes: new Map, views: new Map };
28319
+ for (let index2 = 0;index2 <= claimedIndex; index2++) {
28320
+ applyEvidenceEntry(state, evidence[index2]);
28321
+ }
28322
+ return state;
28323
+ }
28324
+ function applyEvidenceEntry(state, entry) {
28325
+ for (const table8 of entry.dropsTables) {
28326
+ state.tables.delete(table8);
28327
+ }
28328
+ for (const dropped of entry.dropsColumns) {
28329
+ state.tables.get(dropped.table)?.columns.delete(dropped.column);
28330
+ }
28331
+ for (const droppedIndex of entry.dropsIndexes) {
28332
+ state.indexes.delete(droppedIndex);
28333
+ }
28334
+ for (const view2 of entry.dropsViews) {
28335
+ state.views.delete(view2);
28336
+ }
28337
+ for (const table8 of entry.createsTables) {
28338
+ state.tables.set(table8.name, {
28339
+ creator: entry.tag,
28340
+ columns: new Map(table8.columns.map((column2) => [column2, entry.tag]))
28341
+ });
28342
+ }
28343
+ for (const added of entry.addsColumns) {
28344
+ state.tables.get(added.table)?.columns.set(added.column, entry.tag);
28345
+ }
28346
+ for (const createdIndex of entry.createsIndexes) {
28347
+ state.indexes.set(createdIndex, entry.tag);
28348
+ }
28349
+ for (const view2 of entry.createsViews) {
28350
+ state.views.set(view2, entry.tag);
28351
+ }
28352
+ }
28353
+ function judgeClaimed(entry, expected, live, lastDeployAt) {
28354
+ let surviving = 0;
28355
+ for (const table8 of entry.createsTables) {
28356
+ const expectation = expected.tables.get(table8.name);
28357
+ if (expectation?.creator === entry.tag) {
28358
+ surviving++;
28359
+ const columns2 = live.tables.get(table8.name);
28360
+ if (!columns2) {
28361
+ return {
28362
+ verdict: {
28363
+ tag: entry.tag,
28364
+ verdict: "contradicted",
28365
+ detail: `creates table \`${table8.name}\`, which is not in the live database`
28366
+ },
28367
+ unverifiable: false
28368
+ };
28369
+ }
28370
+ const missing = [...expectation.columns.entries()].filter(([, creator]) => creator === entry.tag).map(([column2]) => column2).filter((column2) => !columns2.includes(column2));
28371
+ if (missing.length > 0) {
28372
+ return {
28373
+ verdict: {
28374
+ tag: entry.tag,
28375
+ verdict: "contradicted",
28376
+ detail: `table \`${table8.name}\` exists but is missing column(s) ${missing.map((column2) => `\`${column2}\``).join(", ")} this migration defines`
28377
+ },
28378
+ unverifiable: false
28379
+ };
28380
+ }
28381
+ }
28382
+ }
28383
+ for (const added of entry.addsColumns) {
28384
+ if (expected.tables.get(added.table)?.columns.get(added.column) === entry.tag) {
28385
+ surviving++;
28386
+ const columns2 = live.tables.get(added.table);
28387
+ if (columns2 && !columns2.includes(added.column)) {
28388
+ return {
28389
+ verdict: {
28390
+ tag: entry.tag,
28391
+ verdict: "contradicted",
28392
+ detail: `adds column \`${added.column}\` to \`${added.table}\`, which the live table does not have`
28393
+ },
28394
+ unverifiable: false
28395
+ };
28396
+ }
28397
+ }
28398
+ }
28399
+ for (const name2 of entry.createsIndexes) {
28400
+ if (expected.indexes.get(name2) === entry.tag && live.indexes.has(name2)) {
28401
+ surviving++;
28402
+ }
28403
+ }
28404
+ for (const name2 of entry.createsViews) {
28405
+ if (expected.views.get(name2) === entry.tag && live.views.has(name2)) {
28406
+ surviving++;
28407
+ }
28408
+ }
28409
+ if (surviving === 0) {
28410
+ const generated = new Date(entry.generatedAt);
28411
+ if (lastDeployAt && generated > lastDeployAt) {
28412
+ return {
28413
+ verdict: {
28414
+ tag: entry.tag,
28415
+ verdict: "no-signal",
28416
+ detail: `no schema footprint to verify, and it was generated after the last deploy (${lastDeployAt.toISOString()})`
28417
+ },
28418
+ unverifiable: true
28419
+ };
28420
+ }
28421
+ return { verdict: { tag: entry.tag, verdict: "no-signal" }, unverifiable: false };
28422
+ }
28423
+ return { verdict: { tag: entry.tag, verdict: "verified" }, unverifiable: false };
28424
+ }
28425
+ function judgeBeyond(entry, expected, live) {
28426
+ for (const table8 of entry.createsTables) {
28427
+ if (live.tables.has(table8.name) && !expected.tables.has(table8.name)) {
28428
+ return {
28429
+ tag: entry.tag,
28430
+ verdict: "contradicted",
28431
+ detail: `is beyond the claim, but the table it creates (\`${table8.name}\`) already exists in the live database — the claim looks too old`
28432
+ };
28433
+ }
28434
+ }
28435
+ for (const added of entry.addsColumns) {
28436
+ const columns2 = live.tables.get(added.table);
28437
+ const explained = expected.tables.get(added.table)?.columns.has(added.column);
28438
+ if (columns2?.includes(added.column) && !explained) {
28439
+ return {
28440
+ tag: entry.tag,
28441
+ verdict: "contradicted",
28442
+ detail: `is beyond the claim, but the column it adds (\`${added.table}.${added.column}\`) already exists — the claim looks too old`
28443
+ };
28444
+ }
28445
+ }
28446
+ for (const index2 of entry.createsIndexes) {
28447
+ if (live.indexes.has(index2) && !expected.indexes.has(index2)) {
28448
+ return {
28449
+ tag: entry.tag,
28450
+ verdict: "contradicted",
28451
+ detail: `is beyond the claim, but the index it creates (\`${index2}\`) already exists — the claim looks too old`
28452
+ };
28453
+ }
28454
+ }
28455
+ for (const view2 of entry.createsViews) {
28456
+ if (live.views.has(view2) && !expected.views.has(view2)) {
28457
+ return {
28458
+ tag: entry.tag,
28459
+ verdict: "contradicted",
28460
+ detail: `is beyond the claim, but the view it creates (\`${view2}\`) already exists — the claim looks too old`
28461
+ };
28462
+ }
28463
+ }
28464
+ return { tag: entry.tag, verdict: "verified" };
28465
+ }
28466
+ function suggestTag(evidence, tables) {
28467
+ const liveCreated = [
28468
+ ...new Set(evidence.flatMap((entry) => entry.createsTables.map((table8) => table8.name)))
28469
+ ].filter((name2) => tables.has(name2));
28470
+ const state = { tables: new Map, indexes: new Map, views: new Map };
28471
+ let best = null;
28472
+ for (const entry of evidence) {
28473
+ applyEvidenceEntry(state, entry);
28474
+ const allPresent = [...state.tables.keys()].every((name2) => tables.has(name2));
28475
+ const noStray = liveCreated.every((name2) => state.tables.has(name2));
28476
+ if (allPresent && noStray) {
28477
+ best = entry.tag;
28478
+ }
28479
+ }
28480
+ return best;
28481
+ }
28482
+ var init_baseline_validation_util = __esm(() => {
28483
+ init_spans();
28484
+ init_errors();
27603
28485
  });
27604
28486
 
27605
- // ../api-core/src/utils/deployment.util.ts
27606
- function getGameDeploymentId(gameSlug, sstStage) {
27607
- if (sstStage === "production") {
27608
- return gameSlug;
28487
+ // ../api-core/src/utils/baseline.util.ts
28488
+ function sliceJournalToTag(journal, lastAppliedMigrationTag) {
28489
+ const index2 = journal.findIndex((entry) => entry.tag === lastAppliedMigrationTag);
28490
+ return index2 === -1 ? null : journal.slice(0, index2 + 1);
28491
+ }
28492
+ function evaluateBaselineGuardrails(input) {
28493
+ if (input.ledgerTags.length > 0) {
28494
+ return "ledger-not-empty";
27609
28495
  }
27610
- if (sstStage === "dev" || isPreviewStage(sstStage)) {
27611
- return `${WORKER_NAMING.STAGING_PREFIX}${gameSlug}`;
28496
+ if (input.liveTables.length === 0) {
28497
+ return "database-empty";
27612
28498
  }
27613
- return `${WORKER_NAMING.LOCAL_PREFIX}${sstStage}-${gameSlug}`;
28499
+ return "ok";
27614
28500
  }
27615
- function getDashboardDeploymentId(gameSlug, sstStage) {
27616
- return `${getGameDeploymentId(gameSlug, sstStage)}${DASHBOARD_WORKER_SUFFIX}`;
28501
+
28502
+ // ../api-core/src/utils/migration.util.ts
28503
+ function planMigrations(journal, ledger) {
28504
+ const ledgerByTag = new Map(ledger.map((row) => [row.tag, row]));
28505
+ const journalTags = new Set(journal.map((entry) => entry.tag));
28506
+ const pendingTags = [];
28507
+ const checksumMismatches = [];
28508
+ for (const entry of journal) {
28509
+ const applied = ledgerByTag.get(entry.tag);
28510
+ if (!applied) {
28511
+ pendingTags.push(entry.tag);
28512
+ } else {
28513
+ const comparable = applied.checksumAlgo === MIGRATION_CHECKSUM_ALGO;
28514
+ if (comparable && applied.checksum !== entry.checksum) {
28515
+ checksumMismatches.push({
28516
+ tag: entry.tag,
28517
+ ledgerChecksum: applied.checksum,
28518
+ journalChecksum: entry.checksum
28519
+ });
28520
+ }
28521
+ }
28522
+ }
28523
+ const outOfOrderTags = findOutOfOrderTags(journal.map((entry) => entry.tag), new Set(ledgerByTag.keys()));
28524
+ const missingFromJournalTags = ledger.filter((row) => !journalTags.has(row.tag)).map((row) => row.tag);
28525
+ return { pendingTags, checksumMismatches, outOfOrderTags, missingFromJournalTags };
27617
28526
  }
27618
- function getGameWorkerApiKeyName(slug) {
27619
- return `${GAME_WORKER_KEY_PREFIX}${slug}`.substring(0, 32);
28527
+ function assessMigrationAlreadyApplied(statements, liveTables) {
28528
+ const created = extractCreatedObjects(statements);
28529
+ const present = [];
28530
+ const missing = [];
28531
+ for (const table8 of created.tables) {
28532
+ (liveTables.has(table8) ? present : missing).push(`table ${table8}`);
28533
+ }
28534
+ for (const added of created.columns) {
28535
+ const live = Boolean(liveTables.get(added.table)?.includes(added.column));
28536
+ (live ? present : missing).push(`column ${added.table}.${added.column}`);
28537
+ }
28538
+ if (present.length === 0) {
28539
+ return { verdict: "no-signal", present, missing };
28540
+ }
28541
+ return {
28542
+ verdict: missing.length === 0 ? "all-present" : "partial",
28543
+ present,
28544
+ missing
28545
+ };
27620
28546
  }
27621
- function getDashboardWorkerApiKeyName(slug) {
27622
- return `${DASHBOARD_WORKER_KEY_PREFIX}${slug}`;
28547
+ function parseMigrationFailure(events) {
28548
+ if (!events) {
28549
+ return null;
28550
+ }
28551
+ for (let i2 = events.length - 1;i2 >= 0; i2--) {
28552
+ const event = events[i2];
28553
+ const failure = event ? parseFailureEvent(event) : null;
28554
+ if (failure) {
28555
+ return failure;
28556
+ }
28557
+ }
28558
+ return null;
27623
28559
  }
27624
- function toBindingName(queueKey) {
27625
- return `${queueKey.replace(/-/g, "_").toUpperCase()}_QUEUE`;
28560
+ function parseFailureEvent(event) {
28561
+ const details = event.details;
28562
+ if (!details) {
28563
+ return null;
28564
+ }
28565
+ const { code, tag, statementIndex, error, d1Message } = details;
28566
+ if (code !== DEPLOY_ERROR_CODES.migrationFailed || typeof tag !== "string") {
28567
+ return null;
28568
+ }
28569
+ return {
28570
+ tag,
28571
+ error: failureMessage(error, d1Message),
28572
+ statementIndex: typeof statementIndex === "number" ? statementIndex : null,
28573
+ at: event.createdAt
28574
+ };
27626
28575
  }
27627
- function generateDeploymentHash(code) {
27628
- return sha256Hex(code);
28576
+ function failureMessage(error, d1Message) {
28577
+ if (typeof error === "string") {
28578
+ return error;
28579
+ }
28580
+ if (typeof d1Message === "string") {
28581
+ return d1Message;
28582
+ }
28583
+ return "Migration failed";
27629
28584
  }
27630
- var GAME_WORKER_KEY_PREFIX = "game-worker-", DASHBOARD_WORKER_KEY_PREFIX = "dash-worker-";
27631
- var init_deployment_util = __esm(() => {
27632
- init_src();
27633
- init_stages();
28585
+ var init_migration_util = __esm(() => {
28586
+ init_src4();
28587
+ init_errors();
27634
28588
  });
27635
28589
 
28590
+ // ../api-core/src/utils/secrets-manifest.util.ts
28591
+ async function deriveSecretsManifestPepper(platformSecret) {
28592
+ const encoder = new TextEncoder;
28593
+ const keyMaterial = await crypto.subtle.importKey("raw", encoder.encode(platformSecret), "HKDF", false, ["deriveBits"]);
28594
+ const bits = await crypto.subtle.deriveBits({
28595
+ name: "HKDF",
28596
+ hash: "SHA-256",
28597
+ salt: new Uint8Array(32),
28598
+ info: encoder.encode(SECRETS_MANIFEST_HKDF_INFO)
28599
+ }, keyMaterial, 256);
28600
+ return new Uint8Array(bits);
28601
+ }
28602
+ async function computeSecretDigest(pepper, input) {
28603
+ const key = await crypto.subtle.importKey("raw", new Uint8Array(pepper), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
28604
+ const message = JSON.stringify([input.gameId, input.key, input.value]);
28605
+ const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(message));
28606
+ return [...new Uint8Array(signature)].map((b) => b.toString(16).padStart(2, "0")).join("");
28607
+ }
28608
+ function computeSecretsDiff(input) {
28609
+ const { localDigests, manifest, remoteKeys } = input;
28610
+ const added = [];
28611
+ const changed = [];
28612
+ const unchanged = [];
28613
+ for (const [key, digest] of Object.entries(localDigests)) {
28614
+ const recorded = manifest[key];
28615
+ if (recorded === undefined) {
28616
+ added.push(key);
28617
+ } else if (recorded === digest) {
28618
+ unchanged.push(key);
28619
+ } else {
28620
+ changed.push(key);
28621
+ }
28622
+ }
28623
+ const localKeys = new Set(Object.keys(localDigests));
28624
+ const managedKeys = new Set(Object.keys(manifest));
28625
+ const remoteOnlyManaged = [...managedKeys].filter((key) => !localKeys.has(key));
28626
+ const remoteOnlyUnmanaged = remoteKeys.filter((key) => !managedKeys.has(key) && !localKeys.has(key));
28627
+ return {
28628
+ added: added.toSorted(),
28629
+ changed: changed.toSorted(),
28630
+ unchanged: unchanged.toSorted(),
28631
+ remoteOnlyManaged: remoteOnlyManaged.toSorted(),
28632
+ remoteOnlyUnmanaged: remoteOnlyUnmanaged.toSorted()
28633
+ };
28634
+ }
28635
+ function findUnmanagedPruneKeys(pruneSecrets, manifest) {
28636
+ const managed = new Set(Object.keys(manifest ?? {}));
28637
+ return pruneSecrets.filter((key) => !managed.has(key));
28638
+ }
28639
+ var SECRETS_MANIFEST_HKDF_INFO = "playcademy:secrets-manifest:v1";
28640
+
27636
28641
  // ../api-core/src/utils/worker-keys.util.ts
27637
28642
  async function sweepDashboardWorkerKeys(deleteApiKeysByName, slug) {
27638
28643
  try {
@@ -27650,6 +28655,9 @@ var init_worker_keys_util = __esm(() => {
27650
28655
  });
27651
28656
 
27652
28657
  // ../api-core/src/services/deploy.service.ts
28658
+ function hasBinding(binding) {
28659
+ return binding === true || Array.isArray(binding) && binding.length > 0;
28660
+ }
27653
28661
  function readDashboardTheme(config2) {
27654
28662
  const theme = config2?.dashboard?.theme;
27655
28663
  return {
@@ -27717,7 +28725,7 @@ class DeployService {
27717
28725
  data: { message: hasBackend ? "Deploying backend code" : "Deploying to platform" }
27718
28726
  };
27719
28727
  const keepAssets = hasBackend && !hasFrontend;
27720
- const deploymentOptions = this.mapGameBindingsToOptions(deploymentId, request.bindings, request.schema);
28728
+ const deploymentOptions = this.mapGameBindingsToOptions(deploymentId, request.bindings);
27721
28729
  const bindings = deploymentOptions?.bindings;
27722
28730
  setAttributes({
27723
28731
  "app.deploy.has_d1": Boolean(bindings?.d1?.length),
@@ -27726,13 +28734,49 @@ class DeployService {
27726
28734
  "app.deploy.queue_count": bindings?.queues?.length ?? 0,
27727
28735
  "app.deploy.dead_letter_queue_count": DeployService.countDeadLetterQueues(bindings)
27728
28736
  });
27729
- const activeDeployment = await db2.query.gameDeployments.findFirst({
27730
- where: activeDeploymentWhere(game2.id, "game"),
27731
- columns: { resources: true }
27732
- });
27733
- if (deploymentOptions?.bindings?.d1?.length) {
28737
+ const [activeDeployment, deploymentState] = await Promise.all([
28738
+ db2.query.gameDeployments.findFirst({
28739
+ where: activeDeploymentWhere(game2.id, "game"),
28740
+ columns: { resources: true }
28741
+ }),
28742
+ db2.query.gameDeploymentState.findFirst({
28743
+ where: eq(gameDeploymentState.gameId, game2.id)
28744
+ })
28745
+ ]);
28746
+ if (request.pruneSecrets?.length) {
28747
+ const unmanaged = findUnmanagedPruneKeys(request.pruneSecrets, deploymentState?.secretsManifest);
28748
+ if (unmanaged.length > 0) {
28749
+ throw new SecretsPruneUnmanagedError(unmanaged);
28750
+ }
28751
+ }
28752
+ let state = deploymentState;
28753
+ if (request.baseline) {
28754
+ if (isSchemaAdopted(state)) {
28755
+ addEvent("deploy.baseline_skipped", {
28756
+ "app.deploy.baseline_source": state?.baselineSource ?? "unknown"
28757
+ });
28758
+ } else {
28759
+ state = yield* this.adoptClientBaseline({
28760
+ game: game2,
28761
+ request,
28762
+ user,
28763
+ deploymentId,
28764
+ baseline: request.baseline,
28765
+ existingResources: activeDeployment?.resources ?? undefined
28766
+ });
28767
+ }
28768
+ }
28769
+ if (deploymentOptions?.bindings?.d1?.length && !isSchemaAdopted(state)) {
27734
28770
  await this.cleanupOrphanD1Databases(cf, deploymentOptions.bindings.d1, slug, game2.id);
27735
28771
  }
28772
+ const databaseOutcome = yield* this.executeDatabaseStep({
28773
+ game: game2,
28774
+ request,
28775
+ user,
28776
+ deploymentId,
28777
+ state,
28778
+ existingResources: activeDeployment?.resources ?? undefined
28779
+ });
27736
28780
  const result = await this.deployToCloudflare({
27737
28781
  deploymentId,
27738
28782
  code: request.code,
@@ -27740,6 +28784,7 @@ class DeployService {
27740
28784
  tempDir,
27741
28785
  options: {
27742
28786
  ...deploymentOptions,
28787
+ ...databaseOutcome.legacySchema && { schema: databaseOutcome.legacySchema },
27743
28788
  compatibilityDate: request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
27744
28789
  compatibilityFlags: request.compatibilityFlags,
27745
28790
  existingResources: activeDeployment?.resources ?? undefined,
@@ -27755,8 +28800,12 @@ class DeployService {
27755
28800
  result,
27756
28801
  request,
27757
28802
  user,
27758
- flags: flags2
28803
+ flags: flags2,
28804
+ database: databaseOutcome
27759
28805
  });
28806
+ if (request.pruneSecrets?.length) {
28807
+ yield* this.pruneManagedSecretsStep(game2.id, result.deploymentId, request.pruneSecrets);
28808
+ }
27760
28809
  yield { type: "complete", data: updatedGame };
27761
28810
  }
27762
28811
  async* deployDashboard(context2) {
@@ -27883,7 +28932,10 @@ class DeployService {
27883
28932
  "app.deploy.code_size": request.code?.length ?? 0,
27884
28933
  "app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
27885
28934
  "app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0,
27886
- "app.deploy.has_schema": Boolean(request.schema)
28935
+ "app.deploy.has_schema": Boolean(request.schema),
28936
+ "app.deploy.has_database_payload": Boolean(request.database),
28937
+ "app.deploy.has_baseline": Boolean(request.baseline),
28938
+ "app.deploy.prune_secret_count": request.pruneSecrets?.length ?? 0
27887
28939
  });
27888
28940
  if (!hasBackend && !hasFrontend && !hasMetadata) {
27889
28941
  throw new ValidationError("Must provide at least one of: uploadToken (frontend), code (backend), or metadata");
@@ -27920,18 +28972,18 @@ class DeployService {
27920
28972
  }
27921
28973
  return "metadata_only";
27922
28974
  }
27923
- mapGameBindingsToOptions(deploymentId, bindings, schema2) {
27924
- if (!bindings && !schema2) {
28975
+ mapGameBindingsToOptions(deploymentId, bindings) {
28976
+ if (!bindings) {
27925
28977
  return;
27926
28978
  }
27927
28979
  const workerBindings = {};
27928
- if (bindings?.database) {
28980
+ if (hasBinding(bindings.database)) {
27929
28981
  workerBindings.d1 = [deploymentId];
27930
28982
  }
27931
- if (bindings?.keyValue) {
28983
+ if (hasBinding(bindings.keyValue)) {
27932
28984
  workerBindings.kv = [deploymentId];
27933
28985
  }
27934
- if (bindings?.bucket) {
28986
+ if (hasBinding(bindings.bucket)) {
27935
28987
  workerBindings.r2 = [deploymentId];
27936
28988
  }
27937
28989
  if (bindings?.queues) {
@@ -27960,10 +29012,7 @@ class DeployService {
27960
29012
  });
27961
29013
  }
27962
29014
  const hasBindings = workerBindings.d1?.length || workerBindings.kv?.length || workerBindings.r2?.length || workerBindings.queues?.length;
27963
- return {
27964
- ...hasBindings && { bindings: workerBindings },
27965
- ...schema2 && { schema: schema2 }
27966
- };
29015
+ return hasBindings ? { bindings: workerBindings } : undefined;
27967
29016
  }
27968
29017
  static countDeadLetterQueues(bindings) {
27969
29018
  return bindings?.queues?.filter((queue) => Boolean(queue.deadLetterQueue)).length ?? 0;
@@ -27987,6 +29036,473 @@ class DeployService {
27987
29036
  }
27988
29037
  }
27989
29038
  }
29039
+ async* executeDatabaseStep(context2) {
29040
+ const { game: game2, request, user, deploymentId, state } = context2;
29041
+ if (request.schema) {
29042
+ if (isSchemaAdopted(state)) {
29043
+ throw new LegacySchemaUpgradeRequiredError;
29044
+ }
29045
+ const legacyDbId = context2.existingResources?.d1?.find((db2) => db2.name === deploymentId)?.id;
29046
+ if (legacyDbId) {
29047
+ const ledger = await this.getCloudflare().d1.readMigrationLedger(legacyDbId);
29048
+ if (ledger.length > 0) {
29049
+ throw new LegacySchemaUpgradeRequiredError;
29050
+ }
29051
+ }
29052
+ setAttribute("app.deploy.db_mode", "legacy");
29053
+ return { ...NO_DATABASE_WORK, legacySchema: request.schema };
29054
+ }
29055
+ const database = request.database;
29056
+ if (!database) {
29057
+ return NO_DATABASE_WORK;
29058
+ }
29059
+ if (!hasBinding(request.bindings?.database)) {
29060
+ throw new ValidationError("The database payload requires a database binding");
29061
+ }
29062
+ if (!request.deployId) {
29063
+ throw new ValidationError("deployId is required when a database payload is present");
29064
+ }
29065
+ setAttribute("app.deploy.db_mode", database.mode);
29066
+ const cf = this.getCloudflare();
29067
+ const persistedId = context2.existingResources?.d1?.find((db2) => db2.name === deploymentId)?.id;
29068
+ const databaseId = persistedId ?? await cf.d1.create(deploymentId);
29069
+ if (database.mode === "migrate") {
29070
+ return yield* this.runMigrateMode({
29071
+ game: game2,
29072
+ user,
29073
+ deployId: request.deployId,
29074
+ databaseId,
29075
+ migrations: database.migrations,
29076
+ state
29077
+ });
29078
+ }
29079
+ return yield* this.runPushMode({ game: game2, databaseId, payload: database, state });
29080
+ }
29081
+ async* runMigrateMode(args2) {
29082
+ const { game: game2, user, deployId, databaseId, migrations, state } = args2;
29083
+ const cf = this.getCloudflare();
29084
+ yield { type: "status", data: { message: "Preparing database migrations" } };
29085
+ await this.assertNoSchemaDrift(databaseId, state);
29086
+ await cf.d1.ensureMigrationLedger(databaseId);
29087
+ const ledger = await cf.d1.readMigrationLedger(databaseId);
29088
+ const plan = planMigrations(migrations.map((migration) => ({ tag: migration.tag, checksum: migration.checksum })), ledger.map((row) => ({
29089
+ tag: row.tag,
29090
+ checksum: row.checksum,
29091
+ checksumAlgo: row.checksum_algo
29092
+ })));
29093
+ setAttributes({
29094
+ "app.deploy.migrations_total": migrations.length,
29095
+ "app.deploy.migrations_applied_before": ledger.length,
29096
+ "app.deploy.migrations_pending": plan.pendingTags.length
29097
+ });
29098
+ if (plan.checksumMismatches.length > 0) {
29099
+ throw new MigrationChecksumMismatchError(plan.checksumMismatches);
29100
+ }
29101
+ if (plan.missingFromJournalTags.length > 0) {
29102
+ throw new MigrationJournalDivergenceError(plan.missingFromJournalTags);
29103
+ }
29104
+ if (plan.outOfOrderTags.length > 0) {
29105
+ throw new MigrationOrderError(plan.outOfOrderTags);
29106
+ }
29107
+ if (plan.pendingTags.length === 0) {
29108
+ yield { type: "status", data: { message: "Database schema is up to date" } };
29109
+ if (ledger.length > 0 && !state?.schemaFingerprint) {
29110
+ const fingerprint2 = await cf.d1.fingerprintSchema(databaseId);
29111
+ await this.persistDeploymentState(game2.id, {
29112
+ schemaFingerprint: fingerprint2.fingerprint
29113
+ });
29114
+ return {
29115
+ ...NO_DATABASE_WORK,
29116
+ schemaFingerprint: fingerprint2.fingerprint
29117
+ };
29118
+ }
29119
+ return {
29120
+ ...NO_DATABASE_WORK,
29121
+ schemaFingerprint: state?.schemaFingerprint ?? null
29122
+ };
29123
+ }
29124
+ const capture = yield* this.captureBookmarkStep(databaseId);
29125
+ const migrationsByTag = new Map(migrations.map((migration) => [migration.tag, migration]));
29126
+ let appliedCount = 0;
29127
+ for (const tag of plan.pendingTags) {
29128
+ const migration = migrationsByTag.get(tag);
29129
+ const count = migration.statements.length;
29130
+ yield {
29131
+ type: "status",
29132
+ data: { message: `Applying ${tag} (${count} statement${count === 1 ? "" : "s"})` }
29133
+ };
29134
+ const startedAt = Date.now();
29135
+ try {
29136
+ await withSpan("deploy.apply_migration", () => cf.d1.applyMigration(databaseId, {
29137
+ tag,
29138
+ statements: migration.statements,
29139
+ checksum: migration.checksum,
29140
+ deployId,
29141
+ appliedBy: user.id
29142
+ }));
29143
+ } catch (error) {
29144
+ if (appliedCount > 0) {
29145
+ await this.recordAppliedPrefixFingerprint(game2.id, databaseId);
29146
+ }
29147
+ throw await this.toMigrationStepError(databaseId, error, migration);
29148
+ }
29149
+ appliedCount++;
29150
+ const seconds = ((Date.now() - startedAt) / 1000).toFixed(1);
29151
+ yield { type: "status", data: { message: `Applied ${tag} (${seconds}s)` } };
29152
+ }
29153
+ setAttribute("app.deploy.migrations_applied", plan.pendingTags.length);
29154
+ const fingerprint = await cf.d1.fingerprintSchema(databaseId);
29155
+ await this.persistDeploymentState(game2.id, {
29156
+ schemaFingerprint: fingerprint.fingerprint,
29157
+ schemaHash: null,
29158
+ schemaSnapshot: null
29159
+ });
29160
+ return {
29161
+ schemaHash: null,
29162
+ schemaFingerprint: fingerprint.fingerprint,
29163
+ timeTravelBookmark: capture?.bookmark ?? null,
29164
+ bookmarkCapturedAt: capture?.capturedAt ?? null
29165
+ };
29166
+ }
29167
+ async* runPushMode(args2) {
29168
+ const { game: game2, databaseId, payload, state } = args2;
29169
+ const cf = this.getCloudflare();
29170
+ yield { type: "status", data: { message: "Verifying database schema state" } };
29171
+ if (typeof payload.baselineHash !== "string" && payload.baselineHash !== null) {
29172
+ throw new ValidationError("Push deploys require baselineHash (null on first deploy)");
29173
+ }
29174
+ if (isMigrateManaged(state)) {
29175
+ const ledger = await cf.d1.readMigrationLedger(databaseId);
29176
+ 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 });
29177
+ }
29178
+ const storedHash = state?.schemaHash ?? null;
29179
+ if (payload.baselineHash !== storedHash) {
29180
+ throw await this.buildStateConflictError(game2.id, payload.baselineHash);
29181
+ }
29182
+ const statements = splitSqlStatements(payload.sql);
29183
+ const oversized = findOversizedStatement(statements);
29184
+ if (oversized) {
29185
+ 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.", {
29186
+ code: DEPLOY_ERROR_CODES.pushFailed,
29187
+ statementIndex: oversized.index,
29188
+ offset: null
29189
+ });
29190
+ }
29191
+ const destructive = detectDestructiveStatements(statements);
29192
+ setAttributes({
29193
+ "app.deploy.push_statement_count": statements.length,
29194
+ "app.deploy.push_destructive_count": destructive.length,
29195
+ "app.deploy.push_accept_data_loss": Boolean(payload.acceptDataLoss)
29196
+ });
29197
+ if (destructive.length > 0 && !payload.acceptDataLoss) {
29198
+ throw new DestructiveSchemaError(destructive);
29199
+ }
29200
+ await this.assertNoSchemaDrift(databaseId, state);
29201
+ const reserved = await this.persistPushDeploymentState(game2.id, payload.baselineHash, {
29202
+ schemaFingerprint: PUSH_RESERVATION_FINGERPRINT,
29203
+ schemaHash: payload.nextHash,
29204
+ schemaSnapshot: payload.nextSnapshot
29205
+ });
29206
+ if (!reserved) {
29207
+ throw await this.buildStateConflictError(game2.id, payload.baselineHash);
29208
+ }
29209
+ let capture = null;
29210
+ if (statements.length > 0) {
29211
+ capture = yield* this.captureBookmarkStep(databaseId);
29212
+ yield {
29213
+ type: "status",
29214
+ data: {
29215
+ message: `Applying database schema changes (${statements.length} statements)`
29216
+ }
29217
+ };
29218
+ try {
29219
+ await cf.d1.batch(databaseId, [
29220
+ { sql: "PRAGMA defer_foreign_keys = on" },
29221
+ ...statements.map((statement) => ({ sql: statement })),
29222
+ { sql: "PRAGMA defer_foreign_keys = off" }
29223
+ ]);
29224
+ } catch (error) {
29225
+ await this.persistPushDeploymentState(game2.id, payload.nextHash, {
29226
+ schemaFingerprint: state?.schemaFingerprint ?? null,
29227
+ schemaHash: state?.schemaHash ?? null,
29228
+ schemaSnapshot: state?.schemaSnapshot ?? null
29229
+ });
29230
+ throw this.toPushStepError(error);
29231
+ }
29232
+ }
29233
+ const fingerprint = await cf.d1.fingerprintSchema(databaseId);
29234
+ await this.persistDeploymentState(game2.id, {
29235
+ schemaFingerprint: fingerprint.fingerprint
29236
+ });
29237
+ return {
29238
+ schemaHash: payload.nextHash,
29239
+ schemaFingerprint: fingerprint.fingerprint,
29240
+ timeTravelBookmark: capture?.bookmark ?? null,
29241
+ bookmarkCapturedAt: capture?.capturedAt ?? null
29242
+ };
29243
+ }
29244
+ async* captureBookmarkStep(databaseId) {
29245
+ const cf = this.getCloudflare();
29246
+ const bookmark = await cf.d1.captureBookmark(databaseId);
29247
+ const capturedAt = new Date;
29248
+ setAttribute("app.deploy.db_bookmark_captured", bookmark.captured);
29249
+ if (!bookmark.captured) {
29250
+ yield {
29251
+ type: "status",
29252
+ data: { message: `Time Travel bookmark unavailable (${bookmark.error})` }
29253
+ };
29254
+ return null;
29255
+ }
29256
+ yield {
29257
+ type: "status",
29258
+ data: {
29259
+ message: "Captured Time Travel bookmark",
29260
+ details: { bookmark: bookmark.bookmark }
29261
+ }
29262
+ };
29263
+ return { bookmark: bookmark.bookmark, capturedAt };
29264
+ }
29265
+ async toMigrationStepError(databaseId, error, migration) {
29266
+ if (error instanceof D1StatementTooLargeError) {
29267
+ return new ValidationError(error.message, {
29268
+ code: DEPLOY_ERROR_CODES.migrationFailed,
29269
+ tag: migration.tag,
29270
+ statementIndex: error.statementIndex,
29271
+ offset: null,
29272
+ d1Message: error.message
29273
+ });
29274
+ }
29275
+ if (error instanceof D1MigrationError) {
29276
+ addEvent("deploy.migration_failed", {
29277
+ "app.d1.migration_tag": migration.tag,
29278
+ "app.error.message": error.d1Message,
29279
+ ...error.offset !== null && { "app.d1.error_offset": error.offset }
29280
+ });
29281
+ const alreadyApplied = isAlreadyExistsSqlError(error.d1Message) ? await this.assessAlreadyApplied(databaseId, migration.statements) : null;
29282
+ return new MigrationExecutionError({
29283
+ tag: migration.tag,
29284
+ d1Message: error.d1Message,
29285
+ offset: error.offset,
29286
+ ...alreadyApplied ? { alreadyApplied } : {}
29287
+ });
29288
+ }
29289
+ return error;
29290
+ }
29291
+ async assessAlreadyApplied(databaseId, statements) {
29292
+ try {
29293
+ const cf = this.getCloudflare();
29294
+ const live = await cf.d1.fingerprintSchema(databaseId);
29295
+ const tables = await cf.d1.readTableColumns(databaseId, live.tables);
29296
+ const assessment = assessMigrationAlreadyApplied(statements, tables);
29297
+ addEvent("deploy.already_applied_assessment", {
29298
+ "app.deploy.already_applied_verdict": assessment.verdict,
29299
+ "app.deploy.already_applied_present": assessment.present.length,
29300
+ "app.deploy.already_applied_missing": assessment.missing.length
29301
+ });
29302
+ return assessment.verdict === "no-signal" ? null : assessment;
29303
+ } catch (assessError) {
29304
+ addEvent("deploy.already_applied_check_failed", {
29305
+ "app.error.message": errorMessage(assessError)
29306
+ });
29307
+ return null;
29308
+ }
29309
+ }
29310
+ toPushStepError(error) {
29311
+ if (error instanceof D1BatchError) {
29312
+ addEvent("deploy.push_failed", {
29313
+ "app.error.message": error.d1Message,
29314
+ ...error.offset !== null && { "app.d1.error_offset": error.offset }
29315
+ });
29316
+ return new PushExecutionError({ d1Message: error.d1Message, offset: error.offset });
29317
+ }
29318
+ return error;
29319
+ }
29320
+ async assertNoSchemaDrift(databaseId, state) {
29321
+ if (!state?.schemaFingerprint) {
29322
+ return;
29323
+ }
29324
+ const live = await this.getCloudflare().d1.fingerprintSchema(databaseId);
29325
+ if (live.fingerprint !== state.schemaFingerprint) {
29326
+ addEvent("deploy.state_drift", {
29327
+ "app.deploy.expected_fingerprint": state.schemaFingerprint,
29328
+ "app.deploy.actual_fingerprint": live.fingerprint
29329
+ });
29330
+ throw new DeploymentStateDriftError({
29331
+ expectedFingerprint: state.schemaFingerprint,
29332
+ actualFingerprint: live.fingerprint
29333
+ });
29334
+ }
29335
+ }
29336
+ async buildStateConflictError(gameId, claimedHash) {
29337
+ const [row, lastDeploy] = await Promise.all([
29338
+ this.deps.db.query.gameDeploymentState.findFirst({
29339
+ where: eq(gameDeploymentState.gameId, gameId),
29340
+ columns: { schemaHash: true }
29341
+ }),
29342
+ findLastSuccessfulDeployWithEmail(this.deps.db, gameId)
29343
+ ]);
29344
+ const currentHash = row?.schemaHash ?? null;
29345
+ addEvent("deploy.state_conflict", {
29346
+ "app.deploy.baseline_hash": claimedHash ?? "null",
29347
+ "app.deploy.current_hash": currentHash ?? "null"
29348
+ });
29349
+ return new DeploymentStateConflictError({
29350
+ currentHash,
29351
+ lastDeployAt: lastDeploy?.at.toISOString() ?? null,
29352
+ lastDeployBy: lastDeploy?.email ?? lastDeploy?.userId ?? null
29353
+ });
29354
+ }
29355
+ async recordAppliedPrefixFingerprint(gameId, databaseId) {
29356
+ try {
29357
+ const fingerprint = await this.getCloudflare().d1.fingerprintSchema(databaseId);
29358
+ await this.persistDeploymentState(gameId, {
29359
+ schemaFingerprint: fingerprint.fingerprint
29360
+ });
29361
+ } catch (error) {
29362
+ addEvent("deploy.fingerprint_persist_failed", {
29363
+ "exception.type": errorType(error),
29364
+ "app.error.message": errorMessage(error)
29365
+ });
29366
+ }
29367
+ }
29368
+ async persistDeploymentState(gameId, patch) {
29369
+ const set = {
29370
+ ...patch,
29371
+ updatedAt: new Date
29372
+ };
29373
+ await this.deps.db.insert(gameDeploymentState).values({ gameId, baselineSource: "deploy", ...set }).onConflictDoUpdate({ target: gameDeploymentState.gameId, set });
29374
+ }
29375
+ async persistArtifactHashes(gameId, patch) {
29376
+ const set = {
29377
+ ...patch.buildHash !== undefined && { buildHash: patch.buildHash },
29378
+ ...patch.integrationsHash !== undefined && {
29379
+ integrationsHash: patch.integrationsHash
29380
+ }
29381
+ };
29382
+ if (Object.keys(set).length === 0) {
29383
+ return;
29384
+ }
29385
+ await this.deps.db.insert(gameDeploymentState).values({ gameId, ...set, updatedAt: new Date }).onConflictDoUpdate({
29386
+ target: gameDeploymentState.gameId,
29387
+ set: { ...set, updatedAt: new Date }
29388
+ });
29389
+ }
29390
+ async persistPushDeploymentState(gameId, baselineHash, patch) {
29391
+ const set = { ...patch, updatedAt: new Date };
29392
+ if (baselineHash === null) {
29393
+ const claimed2 = await this.deps.db.insert(gameDeploymentState).values({ gameId, baselineSource: "deploy", ...set }).onConflictDoUpdate({
29394
+ target: gameDeploymentState.gameId,
29395
+ set,
29396
+ setWhere: isNull(gameDeploymentState.schemaHash)
29397
+ }).returning({ gameId: gameDeploymentState.gameId });
29398
+ return claimed2.length > 0;
29399
+ }
29400
+ const claimed = await this.deps.db.update(gameDeploymentState).set(set).where(and(eq(gameDeploymentState.gameId, gameId), eq(gameDeploymentState.schemaHash, baselineHash))).returning({ gameId: gameDeploymentState.gameId });
29401
+ return claimed.length > 0;
29402
+ }
29403
+ async* adoptClientBaseline(context2) {
29404
+ const { game: game2, request, user, deploymentId, baseline } = context2;
29405
+ const cf = this.getCloudflare();
29406
+ const persistedId = context2.existingResources?.d1?.find((db2) => db2.name === deploymentId)?.id;
29407
+ const databaseId = persistedId ?? (hasBinding(request.bindings?.database) ? await cf.d1.create(deploymentId) : null);
29408
+ if (baseline.lastAppliedMigrationTag && !databaseId) {
29409
+ throw new ValidationError("Baseline claims applied migrations, but the deploy has no database binding");
29410
+ }
29411
+ const live = databaseId ? await cf.d1.fingerprintSchema(databaseId) : null;
29412
+ let recordedRows = 0;
29413
+ if (databaseId && baseline.lastAppliedMigrationTag) {
29414
+ if (live.tables.length === 0) {
29415
+ throw new BaselineDatabaseEmptyError;
29416
+ }
29417
+ const slice = sliceJournalToTag(baseline.journal ?? [], baseline.lastAppliedMigrationTag);
29418
+ if (!slice) {
29419
+ throw new ValidationError(`Baseline lastAppliedMigrationTag '${baseline.lastAppliedMigrationTag}' ` + "is not in the submitted journal");
29420
+ }
29421
+ if (baseline.evidence?.length) {
29422
+ const [tables, lastDeploy] = await Promise.all([
29423
+ cf.d1.readTableColumns(databaseId, live.tables),
29424
+ findLastSuccessfulDeploy(this.deps.db, game2.id)
29425
+ ]);
29426
+ assertBaselineClaimValid({
29427
+ claimedTag: baseline.lastAppliedMigrationTag,
29428
+ evidence: baseline.evidence,
29429
+ tables,
29430
+ indexes: new Set(live.indexes),
29431
+ views: new Set(live.views),
29432
+ lastDeployAt: lastDeploy?.at ?? null,
29433
+ allowUnverified: false,
29434
+ source: "seed",
29435
+ gameId: game2.id,
29436
+ userId: user.id
29437
+ });
29438
+ }
29439
+ await cf.d1.ensureMigrationLedger(databaseId);
29440
+ const ledger = await cf.d1.readMigrationLedger(databaseId);
29441
+ const plan = planMigrations(slice, ledger.map((row) => ({
29442
+ tag: row.tag,
29443
+ checksum: row.checksum,
29444
+ checksumAlgo: row.checksum_algo
29445
+ })));
29446
+ if (plan.checksumMismatches.length > 0) {
29447
+ throw new MigrationChecksumMismatchError(plan.checksumMismatches);
29448
+ }
29449
+ if (plan.missingFromJournalTags.length > 0) {
29450
+ throw new MigrationJournalDivergenceError(plan.missingFromJournalTags);
29451
+ }
29452
+ if (plan.outOfOrderTags.length > 0) {
29453
+ throw new MigrationOrderError(plan.outOfOrderTags);
29454
+ }
29455
+ const checksumByTag = new Map(slice.map((entry) => [entry.tag, entry.checksum]));
29456
+ const rows = plan.pendingTags.map((tag) => ({
29457
+ tag,
29458
+ checksum: checksumByTag.get(tag)
29459
+ }));
29460
+ if (rows.length > 0) {
29461
+ await cf.d1.recordLedgerRows(databaseId, {
29462
+ rows,
29463
+ deployId: `baseline:${request.deployId ?? crypto.randomUUID()}`,
29464
+ appliedBy: user.id,
29465
+ source: "baseline"
29466
+ });
29467
+ }
29468
+ recordedRows = rows.length;
29469
+ }
29470
+ const fingerprint = live?.fingerprint ?? null;
29471
+ const set = {
29472
+ ...baseline.schemaHash !== undefined && { schemaHash: baseline.schemaHash },
29473
+ ...baseline.schemaSnapshot !== undefined && {
29474
+ schemaSnapshot: baseline.schemaSnapshot
29475
+ },
29476
+ ...baseline.integrationsHash !== undefined && {
29477
+ integrationsHash: baseline.integrationsHash
29478
+ },
29479
+ ...baseline.buildHash !== undefined && { buildHash: baseline.buildHash },
29480
+ ...fingerprint !== null && { schemaFingerprint: fingerprint },
29481
+ baselineSource: "client-baseline",
29482
+ updatedAt: new Date
29483
+ };
29484
+ await this.deps.db.insert(gameDeploymentState).values({ gameId: game2.id, ...set }).onConflictDoUpdate({ target: gameDeploymentState.gameId, set });
29485
+ setAttributes({
29486
+ "app.deploy.baseline_adopted": true,
29487
+ "app.deploy.baseline_ledger_rows": recordedRows,
29488
+ "app.deploy.baseline_has_snapshot": baseline.schemaSnapshot !== undefined
29489
+ });
29490
+ yield {
29491
+ type: "status",
29492
+ data: {
29493
+ message: "Adopted deployment state from client baseline",
29494
+ details: {
29495
+ ledgerRows: recordedRows,
29496
+ ...baseline.lastAppliedMigrationTag && {
29497
+ lastAppliedMigrationTag: baseline.lastAppliedMigrationTag
29498
+ }
29499
+ }
29500
+ }
29501
+ };
29502
+ return this.deps.db.query.gameDeploymentState.findFirst({
29503
+ where: eq(gameDeploymentState.gameId, game2.id)
29504
+ });
29505
+ }
27990
29506
  async applyGameMetadata(gameId, request, hasFrontend, hasMetadata, deploymentUrl) {
27991
29507
  const updates = { updatedAt: new Date };
27992
29508
  if (hasFrontend) {
@@ -28012,7 +29528,8 @@ class DeployService {
28012
29528
  result,
28013
29529
  request,
28014
29530
  user,
28015
- flags: flags2
29531
+ flags: flags2,
29532
+ database
28016
29533
  }) {
28017
29534
  const { hasBackend, hasFrontend, hasMetadata } = flags2;
28018
29535
  const db2 = this.deps.db;
@@ -28022,9 +29539,17 @@ class DeployService {
28022
29539
  deploymentId: result.deploymentId,
28023
29540
  url: result.url,
28024
29541
  codeHash,
29542
+ schemaHash: database.schemaHash,
29543
+ schemaFingerprint: database.schemaFingerprint,
29544
+ timeTravelBookmark: database.timeTravelBookmark,
29545
+ bookmarkCapturedAt: database.bookmarkCapturedAt,
28025
29546
  resources: result.resources,
28026
29547
  target: "game"
28027
29548
  });
29549
+ await this.persistArtifactHashes(game2.id, {
29550
+ buildHash: hasFrontend ? request.buildHash : undefined,
29551
+ integrationsHash: request.integrationsHash
29552
+ });
28028
29553
  if (hasBackend) {
28029
29554
  await withSpan("deploy.configure_worker_secrets", async () => {
28030
29555
  await this.ensureWorkerApiKeyOnWorker(user, DeployService.gameWorkerKeySpec(slug), result.deploymentId);
@@ -28161,6 +29686,29 @@ class DeployService {
28161
29686
  const cf = this.getCloudflare();
28162
29687
  await cf.setSecrets(deploymentId, { QUEUE_INGRESS_SECRET: secret });
28163
29688
  }
29689
+ async* pruneManagedSecretsStep(gameId, deploymentId, pruneSecrets) {
29690
+ const cf = this.getCloudflare();
29691
+ const keys = [...new Set(pruneSecrets)];
29692
+ yield {
29693
+ type: "status",
29694
+ data: {
29695
+ message: `Pruning ${keys.length} managed secret(s)`,
29696
+ details: { keys }
29697
+ }
29698
+ };
29699
+ await withSpan("deploy.prune_secrets", async () => {
29700
+ const existing = await cf.listSecrets(deploymentId);
29701
+ for (const key of keys) {
29702
+ const prefixedKey = `${SECRETS_PREFIX}${key}`;
29703
+ if (existing.includes(prefixedKey)) {
29704
+ await cf.deleteSecret(deploymentId, prefixedKey);
29705
+ }
29706
+ }
29707
+ const pruned = keys.reduce((expr, key) => sql`${expr} - ${key}::text`, sql`coalesce(${gameDeploymentState.secretsManifest}, '{}'::jsonb)`);
29708
+ await this.deps.db.update(gameDeploymentState).set({ secretsManifest: pruned, updatedAt: new Date }).where(eq(gameDeploymentState.gameId, gameId));
29709
+ });
29710
+ setAttribute("app.deploy.pruned_secret_count", keys.length);
29711
+ }
28164
29712
  async ensureDashboardSessionSecret(deploymentId, existingSecrets, hasPriorDeployment) {
28165
29713
  if (existingSecrets === null && hasPriorDeployment) {
28166
29714
  setAttribute("app.deploy.session_secret_outcome", "check_failed_kept");
@@ -28265,6 +29813,10 @@ class DeployService {
28265
29813
  target: record.target,
28266
29814
  url: record.url,
28267
29815
  codeHash: record.codeHash,
29816
+ schemaHash: record.schemaHash ?? null,
29817
+ schemaFingerprint: record.schemaFingerprint ?? null,
29818
+ timeTravelBookmark: record.timeTravelBookmark ?? null,
29819
+ bookmarkCapturedAt: record.bookmarkCapturedAt ?? null,
28268
29820
  resources: record.resources,
28269
29821
  isActive: true
28270
29822
  });
@@ -28274,8 +29826,10 @@ class DeployService {
28274
29826
  await this.deps.alerts.notifyDeploymentFailure(failure).catch(catchAttrs("alerts.delivery", { "app.alerts.type": "deployment_failure" }));
28275
29827
  }
28276
29828
  }
29829
+ var PUSH_RESERVATION_FINGERPRINT = "reserved:push-in-flight", NO_DATABASE_WORK;
28277
29830
  var init_deploy_service = __esm(() => {
28278
29831
  init_drizzle_orm();
29832
+ init_src4();
28279
29833
  init_playcademy();
28280
29834
  init_src();
28281
29835
  init_helpers_index();
@@ -28283,9 +29837,17 @@ var init_deploy_service = __esm(() => {
28283
29837
  init_spans();
28284
29838
  init_tunnel();
28285
29839
  init_errors();
29840
+ init_baseline_validation_util();
28286
29841
  init_dashboard_util();
28287
29842
  init_deployment_util();
29843
+ init_migration_util();
28288
29844
  init_worker_keys_util();
29845
+ NO_DATABASE_WORK = {
29846
+ schemaHash: null,
29847
+ schemaFingerprint: null,
29848
+ timeTravelBookmark: null,
29849
+ bookmarkCapturedAt: null
29850
+ };
28289
29851
  });
28290
29852
 
28291
29853
  // ../api-core/src/services/developer.service.ts
@@ -29739,7 +31301,7 @@ function createGameServices(deps) {
29739
31301
  }
29740
31302
  };
29741
31303
  }
29742
- var init_game2 = __esm(() => {
31304
+ var init_game3 = __esm(() => {
29743
31305
  init_dashboard_service();
29744
31306
  init_deploy_job_service();
29745
31307
  init_deploy_service();
@@ -29938,16 +31500,37 @@ class AlertsService {
29938
31500
  await this.sendAlert(discord, embed.build());
29939
31501
  }
29940
31502
  async notifyDeploymentFailure(failure) {
29941
- const discord = this.recordAlert("deployment_failure");
31503
+ const refused = DEPLOY_REFUSAL_CODES.has(failure.errorCode ?? "");
31504
+ const discord = this.recordAlert(refused ? "deployment_blocked" : "deployment_failure");
29942
31505
  if (!discord) {
29943
31506
  return;
29944
31507
  }
29945
- const [title, subject] = failure.target === "dashboard" ? ["Dashboard Deployment Failed", "Dashboard deployment"] : ["Deployment Failed", "Deployment"];
29946
- const embed = new DiscordEmbedBuilder().setTitle(title).setDescription(`${subject} failed for **${failure.displayName || failure.slug}** (**${this.getEnvironment()}**).`).setColor(DiscordColors.RED).addField("Slug", failure.slug, true);
31508
+ const [noun, subject] = failure.target === "dashboard" ? ["Dashboard Deployment", "Dashboard deployment"] : ["Deployment", "Deployment"];
31509
+ const title = refused ? `\uD83D\uDEA7 ${noun} Blocked` : `❌ ${noun} Failed`;
31510
+ const verb = refused ? "was blocked" : "failed";
31511
+ 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);
29947
31512
  if (failure.developer) {
29948
31513
  embed.addField("Developer", failure.developer.email || failure.developer.id, true);
29949
31514
  }
29950
- embed.addField("Error", failure.error, false).setFooter("Playcademy Developer Platform").setTimestamp();
31515
+ embed.addField(refused ? "Reason" : "Error", failure.error, false);
31516
+ if (refused) {
31517
+ embed.addField("Next step", "The developer received repair guidance in their terminal", false);
31518
+ }
31519
+ embed.setFooter("Playcademy Developer Platform").setTimestamp();
31520
+ await this.sendAlert(discord, embed.build());
31521
+ }
31522
+ async notifyDeployBlocked(blocked) {
31523
+ const discord = this.recordAlert("deployment_blocked");
31524
+ if (!discord) {
31525
+ return;
31526
+ }
31527
+ 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);
31528
+ if (blocked.developer) {
31529
+ embed.addField("Developer", blocked.developer.email || blocked.developer.id, true);
31530
+ }
31531
+ embed.addField("Reason", blocked.reason, false);
31532
+ embed.addField("Next step", "The developer received repair guidance in their terminal", false);
31533
+ embed.setFooter("Playcademy Developer Platform").setTimestamp();
29951
31534
  await this.sendAlert(discord, embed.build());
29952
31535
  }
29953
31536
  async notifyGameDeletion(game2) {
@@ -30008,6 +31591,7 @@ var DISCORD_FIELD_LIMIT = 1024;
30008
31591
  var init_alerts_service = __esm(() => {
30009
31592
  init_discord();
30010
31593
  init_spans();
31594
+ init_game2();
30011
31595
  });
30012
31596
 
30013
31597
  // ../api-core/src/services/kv-backup.service.ts
@@ -30440,6 +32024,15 @@ class DatabaseService {
30440
32024
  constructor(deps) {
30441
32025
  this.deps = deps;
30442
32026
  }
32027
+ static remapD1Resource(resources, d1ResourceName, databaseId) {
32028
+ return {
32029
+ resources: {
32030
+ ...resources,
32031
+ d1: resources.d1?.map((dbResource) => dbResource.name === d1ResourceName ? { ...dbResource, id: databaseId } : dbResource)
32032
+ },
32033
+ timeTravelBookmark: null
32034
+ };
32035
+ }
30443
32036
  getD1() {
30444
32037
  const d1 = this.deps.cloudflare?.d1;
30445
32038
  if (!d1) {
@@ -30458,11 +32051,7 @@ class DatabaseService {
30458
32051
  try {
30459
32052
  await this.deps.cloudflare.updateD1Binding(dashboardDeployment.deploymentId, databaseId);
30460
32053
  if (dashboardDeployment.resources?.d1?.length) {
30461
- const updatedResources = {
30462
- ...dashboardDeployment.resources,
30463
- d1: dashboardDeployment.resources.d1.map((dbResource) => dbResource.name === d1ResourceName ? { ...dbResource, id: databaseId } : dbResource)
30464
- };
30465
- await this.deps.db.update(gameDeployments).set({ resources: updatedResources }).where(eq(gameDeployments.id, dashboardDeployment.id));
32054
+ await this.deps.db.update(gameDeployments).set(DatabaseService.remapD1Resource(dashboardDeployment.resources, d1ResourceName, databaseId)).where(eq(gameDeployments.id, dashboardDeployment.id));
30466
32055
  }
30467
32056
  setAttribute("app.database.dashboard_binding", "updated");
30468
32057
  } catch (error) {
@@ -30473,20 +32062,36 @@ class DatabaseService {
30473
32062
  });
30474
32063
  }
30475
32064
  }
30476
- async reset(slug, user, schema2) {
32065
+ async reset(slug, user, request = {}) {
32066
+ const { schema: schema2, database } = request;
30477
32067
  setAttributes({
30478
32068
  "app.database.operation": "reset",
32069
+ "app.database.mode": database?.mode ?? (schema2 ? "legacy" : "none"),
30479
32070
  "app.database.schema_size": schema2?.sql.length,
30480
32071
  "app.database.schema_version": schema2?.hash
30481
32072
  });
30482
32073
  const d1 = this.getD1();
30483
32074
  const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32075
+ const state = await this.deps.db.query.gameDeploymentState.findFirst({
32076
+ where: eq(gameDeploymentState.gameId, game2.id)
32077
+ });
32078
+ if (isSchemaAdopted(state) && !database) {
32079
+ if (schema2) {
32080
+ throw new LegacySchemaUpgradeRequiredError;
32081
+ }
32082
+ 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.");
32083
+ }
30484
32084
  const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
32085
+ let resetDatabaseId = null;
30485
32086
  try {
30486
32087
  const databaseId = await d1.reset(deploymentId);
32088
+ resetDatabaseId = databaseId;
30487
32089
  setAttribute("app.database.id", databaseId);
30488
32090
  let schemaPushed = false;
30489
- if (schema2?.sql) {
32091
+ if (database) {
32092
+ await this.rebuildDatabase(databaseId, database, game2.id, user);
32093
+ schemaPushed = true;
32094
+ } else if (schema2?.sql) {
30490
32095
  await d1.executeSchema(databaseId, schema2);
30491
32096
  schemaPushed = true;
30492
32097
  }
@@ -30502,11 +32107,7 @@ class DatabaseService {
30502
32107
  });
30503
32108
  setAttribute("app.database.active_deployment_found", Boolean(activeDeployment));
30504
32109
  if (activeDeployment?.resources?.d1?.length) {
30505
- const updatedResources = {
30506
- ...activeDeployment.resources,
30507
- d1: activeDeployment.resources.d1.map((dbResource) => dbResource.name === deploymentId ? { ...dbResource, id: databaseId } : dbResource)
30508
- };
30509
- await this.deps.db.update(gameDeployments).set({ resources: updatedResources }).where(eq(gameDeployments.id, activeDeployment.id));
32110
+ await this.deps.db.update(gameDeployments).set(DatabaseService.remapD1Resource(activeDeployment.resources, deploymentId, databaseId)).where(eq(gameDeployments.id, activeDeployment.id));
30510
32111
  }
30511
32112
  await this.syncDashboardD1Binding(game2.id, deploymentId, databaseId);
30512
32113
  setAttributes({
@@ -30520,18 +32121,81 @@ class DatabaseService {
30520
32121
  schemaPushed
30521
32122
  };
30522
32123
  } catch (error) {
32124
+ if (database && resetDatabaseId) {
32125
+ await this.recordLiveFingerprint(game2.id, resetDatabaseId);
32126
+ }
30523
32127
  this.deps.alerts.notifyDatabaseResetFailure({
30524
32128
  slug,
30525
32129
  displayName: game2.displayName,
30526
32130
  error: errorMessage(error),
30527
32131
  developer: { id: user.id, email: user.email }
30528
32132
  }).catch(catchAttrs("alerts.delivery", { "app.alerts.type": "database_reset" }));
32133
+ if (error instanceof DomainError) {
32134
+ throw error;
32135
+ }
30529
32136
  throw new ValidationError(`Database reset failed: ${errorMessage(error)}`);
30530
32137
  }
30531
32138
  }
32139
+ async rebuildDatabase(databaseId, payload, gameId, user) {
32140
+ const d1 = this.getD1();
32141
+ if (payload.mode === "migrate") {
32142
+ const deployId = `reset:${crypto.randomUUID()}`;
32143
+ await d1.ensureMigrationLedger(databaseId);
32144
+ for (const migration of payload.migrations) {
32145
+ await d1.applyMigration(databaseId, {
32146
+ tag: migration.tag,
32147
+ statements: migration.statements,
32148
+ checksum: migration.checksum,
32149
+ deployId,
32150
+ appliedBy: user.id
32151
+ });
32152
+ }
32153
+ setAttribute("app.database.migrations_replayed", payload.migrations.length);
32154
+ const fingerprint2 = await d1.fingerprintSchema(databaseId);
32155
+ await this.persistDeploymentState(gameId, {
32156
+ schemaFingerprint: fingerprint2.fingerprint,
32157
+ schemaHash: null,
32158
+ schemaSnapshot: null
32159
+ });
32160
+ return;
32161
+ }
32162
+ const statements = splitSqlStatements(payload.sql);
32163
+ if (statements.length > 0) {
32164
+ await d1.batch(databaseId, [
32165
+ { sql: "PRAGMA defer_foreign_keys = on" },
32166
+ ...statements.map((statement) => ({ sql: statement })),
32167
+ { sql: "PRAGMA defer_foreign_keys = off" }
32168
+ ]);
32169
+ }
32170
+ setAttribute("app.database.push_statement_count", statements.length);
32171
+ const fingerprint = await d1.fingerprintSchema(databaseId);
32172
+ await this.persistDeploymentState(gameId, {
32173
+ schemaFingerprint: fingerprint.fingerprint,
32174
+ schemaHash: payload.nextHash,
32175
+ schemaSnapshot: payload.nextSnapshot
32176
+ });
32177
+ }
32178
+ async persistDeploymentState(gameId, patch) {
32179
+ const set = { ...patch, updatedAt: new Date };
32180
+ await this.deps.db.insert(gameDeploymentState).values({ gameId, baselineSource: "deploy", ...set }).onConflictDoUpdate({ target: gameDeploymentState.gameId, set });
32181
+ }
32182
+ async recordLiveFingerprint(gameId, databaseId) {
32183
+ try {
32184
+ const fingerprint = await this.getD1().fingerprintSchema(databaseId);
32185
+ await this.persistDeploymentState(gameId, {
32186
+ schemaFingerprint: fingerprint.fingerprint
32187
+ });
32188
+ } catch (error) {
32189
+ addEvent("database.fingerprint_persist_failed", {
32190
+ "exception.type": errorType(error),
32191
+ "app.error.message": errorMessage(error)
32192
+ });
32193
+ }
32194
+ }
30532
32195
  }
30533
32196
  var init_database_service = __esm(() => {
30534
32197
  init_drizzle_orm();
32198
+ init_src4();
30535
32199
  init_helpers_index();
30536
32200
  init_tables_index();
30537
32201
  init_spans();
@@ -30539,6 +32203,527 @@ var init_database_service = __esm(() => {
30539
32203
  init_deployment_util();
30540
32204
  });
30541
32205
 
32206
+ // ../api-core/src/utils/secrets.util.ts
32207
+ async function listUserSecretKeys(cloudflare2, deploymentId) {
32208
+ try {
32209
+ const allKeys = await cloudflare2.listSecrets(deploymentId);
32210
+ return allKeys.filter((key) => key.startsWith(SECRETS_PREFIX)).map((key) => key.slice(SECRETS_PREFIX.length));
32211
+ } catch (error) {
32212
+ const message = errorMessage(error);
32213
+ if (message.includes("not found") || message.includes("10007")) {
32214
+ return null;
32215
+ }
32216
+ throw error;
32217
+ }
32218
+ }
32219
+ var init_secrets_util = __esm(() => {
32220
+ init_src();
32221
+ });
32222
+
32223
+ // ../api-core/src/services/deployment-state.service.ts
32224
+ function historyEventEntry(event) {
32225
+ const base = { at: event.createdAt.toISOString(), by: event.email ?? DELETED_ACCOUNT_LABEL };
32226
+ if (event.kind === "restore" && "restoredTo" in event.payload) {
32227
+ return [{ kind: "restore", ...base, restoredTo: event.payload.restoredTo }];
32228
+ }
32229
+ if (event.kind === "blocked" && "code" in event.payload) {
32230
+ return [
32231
+ { kind: "blocked", ...base, code: event.payload.code, reason: event.payload.reason }
32232
+ ];
32233
+ }
32234
+ return [];
32235
+ }
32236
+ function databaseIdFromResources(resources, deploymentId) {
32237
+ const database = resources?.d1?.find((db2) => db2.name === deploymentId) ?? resources?.d1?.[0];
32238
+ return database?.id ?? null;
32239
+ }
32240
+ function restorePointCapturedAt(row) {
32241
+ return row.bookmarkCapturedAt ?? row.deployedAt;
32242
+ }
32243
+
32244
+ class DeploymentStateService {
32245
+ deps;
32246
+ constructor(deps) {
32247
+ this.deps = deps;
32248
+ }
32249
+ async partitionSecretKeys(slug, manifest) {
32250
+ const managedKeys = Object.keys(manifest ?? {});
32251
+ if (!this.deps.cloudflare) {
32252
+ addEvent("deployment_state.secret_keys_unavailable", {
32253
+ "app.error.message": "Cloudflare provider not configured"
32254
+ });
32255
+ return { managedKeys, unmanagedKeys: null };
32256
+ }
32257
+ const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
32258
+ const remoteKeys = await listUserSecretKeys(this.deps.cloudflare, deploymentId);
32259
+ if (remoteKeys === null) {
32260
+ return { managedKeys, unmanagedKeys: [] };
32261
+ }
32262
+ const managed = new Set(managedKeys);
32263
+ return {
32264
+ managedKeys,
32265
+ unmanagedKeys: remoteKeys.filter((key) => !managed.has(key))
32266
+ };
32267
+ }
32268
+ async readAppliedMigrations(slug, resources) {
32269
+ if (!this.deps.cloudflare || !resources?.d1?.length) {
32270
+ return null;
32271
+ }
32272
+ const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
32273
+ const databaseId = databaseIdFromResources(resources, deploymentId);
32274
+ if (!databaseId) {
32275
+ return null;
32276
+ }
32277
+ const ledger = await this.deps.cloudflare.d1.readMigrationLedger(databaseId);
32278
+ setAttributes({ "app.deployment_state.applied_migrations": ledger.length });
32279
+ return ledger.map((row) => ({
32280
+ tag: row.tag,
32281
+ checksum: row.checksum,
32282
+ checksumAlgo: row.checksum_algo
32283
+ }));
32284
+ }
32285
+ async get(slug, user, options = {}) {
32286
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32287
+ const [state, gameDeployment, dashboardDeployment, lastSucceededJob, lastFailedJob] = await Promise.all([
32288
+ this.deps.db.query.gameDeploymentState.findFirst({
32289
+ where: eq(gameDeploymentState.gameId, game2.id)
32290
+ }),
32291
+ this.deps.db.query.gameDeployments.findFirst({
32292
+ where: activeDeploymentWhere(game2.id, "game"),
32293
+ columns: { codeHash: true, url: true, deployedAt: true, resources: true }
32294
+ }),
32295
+ this.deps.db.query.gameDeployments.findFirst({
32296
+ where: activeDeploymentWhere(game2.id, "dashboard"),
32297
+ columns: { url: true, deployedAt: true }
32298
+ }),
32299
+ findLastSuccessfulDeployWithEmail(this.deps.db, game2.id),
32300
+ this.deps.db.query.gameDeployJobs.findFirst({
32301
+ where: and(eq(gameDeployJobs.gameId, game2.id), eq(gameDeployJobs.status, "failed")),
32302
+ orderBy: desc(deployJobInstant()),
32303
+ columns: { events: true }
32304
+ })
32305
+ ]);
32306
+ const [secrets, appliedMigrations] = await Promise.all([
32307
+ this.partitionSecretKeys(slug, state?.secretsManifest ?? null),
32308
+ this.readAppliedMigrations(slug, gameDeployment?.resources ?? null)
32309
+ ]);
32310
+ setAttributes({
32311
+ "app.deployment_state.seeded": Boolean(state),
32312
+ "app.deployment_state.game_deployed": Boolean(gameDeployment),
32313
+ "app.deployment_state.dashboard_deployed": Boolean(dashboardDeployment)
32314
+ });
32315
+ return {
32316
+ gameId: game2.id,
32317
+ seeded: Boolean(state),
32318
+ game: gameDeployment ? {
32319
+ codeHash: gameDeployment.codeHash,
32320
+ buildHash: state?.buildHash ?? null,
32321
+ url: gameDeployment.url,
32322
+ deployedAt: gameDeployment.deployedAt.toISOString()
32323
+ } : null,
32324
+ dashboard: dashboardDeployment ? {
32325
+ url: dashboardDeployment.url,
32326
+ deployedAt: dashboardDeployment.deployedAt.toISOString()
32327
+ } : null,
32328
+ database: {
32329
+ appliedMigrations,
32330
+ lastFailure: parseMigrationFailure(lastFailedJob?.events ?? null),
32331
+ schemaHash: state?.schemaHash ?? null,
32332
+ schemaFingerprint: state?.schemaFingerprint ?? null,
32333
+ ...options.includeSchemaSnapshot && {
32334
+ schemaSnapshot: state?.schemaSnapshot ?? null
32335
+ }
32336
+ },
32337
+ secrets,
32338
+ integrationsHash: state?.integrationsHash ?? null,
32339
+ compatibilityDate: state?.compatibilityDate ?? null,
32340
+ lastDeploy: lastSucceededJob ? {
32341
+ at: lastSucceededJob.at.toISOString(),
32342
+ by: lastSucceededJob.email ?? DELETED_ACCOUNT_LABEL
32343
+ } : null
32344
+ };
32345
+ }
32346
+ requireCloudflare() {
32347
+ if (!this.deps.cloudflare) {
32348
+ throw new ValidationError("Deployment-state operations are not available in this environment");
32349
+ }
32350
+ return this.deps.cloudflare;
32351
+ }
32352
+ async resolveDatabaseId(slug, gameId) {
32353
+ const databaseId = await this.findDatabaseId(slug, gameId);
32354
+ if (!databaseId) {
32355
+ throw new ValidationError("Game has no deployed database — deploy with a database binding first");
32356
+ }
32357
+ return databaseId;
32358
+ }
32359
+ findSchemaHashState(gameId) {
32360
+ return this.deps.db.query.gameDeploymentState.findFirst({
32361
+ where: eq(gameDeploymentState.gameId, gameId),
32362
+ columns: { schemaHash: true }
32363
+ });
32364
+ }
32365
+ async findDatabaseId(slug, gameId) {
32366
+ const deployment = await this.deps.db.query.gameDeployments.findFirst({
32367
+ where: activeDeploymentWhere(gameId, "game"),
32368
+ columns: { resources: true }
32369
+ });
32370
+ return databaseIdFromResources(deployment?.resources, getGameDeploymentId(slug, this.deps.config.sstStage));
32371
+ }
32372
+ async baseline(slug, input, user) {
32373
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32374
+ const cf = this.requireCloudflare();
32375
+ const state = await this.deps.db.query.gameDeploymentState.findFirst({
32376
+ where: eq(gameDeploymentState.gameId, game2.id)
32377
+ });
32378
+ const schemaAdopted = isSchemaAdopted(state);
32379
+ const migrateOnlyClaim = Boolean(input.lastAppliedMigrationTag) && input.schemaHash === undefined && input.schemaSnapshot === undefined;
32380
+ if (schemaAdopted && !migrateOnlyClaim) {
32381
+ throw new BaselineAlreadyAdoptedError(state?.baselineSource ?? null);
32382
+ }
32383
+ const databaseId = await this.resolveDatabaseId(slug, game2.id);
32384
+ const [ledger, live] = await Promise.all([
32385
+ cf.d1.readMigrationLedger(databaseId),
32386
+ cf.d1.fingerprintSchema(databaseId)
32387
+ ]);
32388
+ const verdict = evaluateBaselineGuardrails({
32389
+ ledgerTags: ledger.map((row) => row.tag),
32390
+ liveTables: live.tables
32391
+ });
32392
+ if (verdict === "ledger-not-empty") {
32393
+ throw new BaselineLedgerNotEmptyError(ledger.map((row) => row.tag));
32394
+ }
32395
+ if (verdict === "database-empty") {
32396
+ throw new BaselineDatabaseEmptyError;
32397
+ }
32398
+ if (schemaAdopted && state?.schemaFingerprint && live.fingerprint !== state.schemaFingerprint) {
32399
+ throw new DeploymentStateDriftError({
32400
+ expectedFingerprint: state.schemaFingerprint,
32401
+ actualFingerprint: live.fingerprint
32402
+ });
32403
+ }
32404
+ if (input.lastAppliedMigrationTag && input.evidence?.length) {
32405
+ const [tables, lastDeploy] = await Promise.all([
32406
+ cf.d1.readTableColumns(databaseId, live.tables),
32407
+ findLastSuccessfulDeploy(this.deps.db, game2.id)
32408
+ ]);
32409
+ assertBaselineClaimValid({
32410
+ claimedTag: input.lastAppliedMigrationTag,
32411
+ evidence: input.evidence,
32412
+ tables,
32413
+ indexes: new Set(live.indexes),
32414
+ views: new Set(live.views),
32415
+ lastDeployAt: lastDeploy?.at ?? null,
32416
+ allowUnverified: Boolean(input.allowUnverified),
32417
+ source: "manual",
32418
+ gameId: game2.id,
32419
+ userId: user.id
32420
+ });
32421
+ }
32422
+ let recordedTags = [];
32423
+ if (input.lastAppliedMigrationTag) {
32424
+ const slice = sliceJournalToTag(input.journal ?? [], input.lastAppliedMigrationTag);
32425
+ if (!slice) {
32426
+ throw new ValidationError(`lastAppliedMigrationTag '${input.lastAppliedMigrationTag}' is not in the ` + "submitted journal");
32427
+ }
32428
+ await cf.d1.ensureMigrationLedger(databaseId);
32429
+ await cf.d1.recordLedgerRows(databaseId, {
32430
+ rows: slice,
32431
+ deployId: `baseline:${crypto.randomUUID()}`,
32432
+ appliedBy: user.id,
32433
+ source: "baseline"
32434
+ });
32435
+ recordedTags = slice.map((entry) => entry.tag);
32436
+ }
32437
+ const graduating = migrateOnlyClaim && isPushAdopted(state);
32438
+ const set = {
32439
+ ...graduating ? { schemaHash: null, schemaSnapshot: null } : {
32440
+ ...input.schemaHash !== undefined && { schemaHash: input.schemaHash },
32441
+ ...input.schemaSnapshot !== undefined && {
32442
+ schemaSnapshot: input.schemaSnapshot
32443
+ }
32444
+ },
32445
+ schemaFingerprint: live.fingerprint,
32446
+ baselineSource: "manual-baseline",
32447
+ updatedAt: new Date
32448
+ };
32449
+ await this.persistDeploymentState(game2.id, set);
32450
+ addEvent("deployment_state.baseline_recorded", {
32451
+ "app.game.id": game2.id,
32452
+ "app.deployment_state.baseline_source": "manual-baseline",
32453
+ "app.deployment_state.baseline_ledger_rows": recordedTags.length,
32454
+ "app.deployment_state.baseline_has_snapshot": input.schemaSnapshot !== undefined,
32455
+ "app.deployment_state.baseline_graduated_from_push": graduating
32456
+ });
32457
+ return this.get(slug, user);
32458
+ }
32459
+ async realignMigration(slug, tag, checksum, user) {
32460
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32461
+ const cf = this.requireCloudflare();
32462
+ const databaseId = await this.resolveDatabaseId(slug, game2.id);
32463
+ const ledger = await cf.d1.readMigrationLedger(databaseId);
32464
+ if (!ledger.some((row) => row.tag === tag)) {
32465
+ throw new NotFoundError("Applied migration", tag);
32466
+ }
32467
+ const updated = await cf.d1.updateLedgerChecksum(databaseId, { tag, checksum });
32468
+ if (!updated) {
32469
+ throw new NotFoundError("Applied migration", tag);
32470
+ }
32471
+ addEvent("deployment_state.migration_realigned", {
32472
+ "app.game.id": game2.id,
32473
+ "app.d1.migration_tag": tag,
32474
+ "app.user.id": user.id
32475
+ });
32476
+ return { tag, checksum, checksumAlgo: MIGRATION_CHECKSUM_ALGO };
32477
+ }
32478
+ async persistDeploymentState(gameId, set) {
32479
+ await this.deps.db.insert(gameDeploymentState).values({ gameId, ...set }).onConflictDoUpdate({ target: gameDeploymentState.gameId, set });
32480
+ }
32481
+ async updateDeploymentState(gameId, set) {
32482
+ const updated = await this.deps.db.update(gameDeploymentState).set(set).where(eq(gameDeploymentState.gameId, gameId)).returning({ gameId: gameDeploymentState.gameId });
32483
+ return updated.length > 0;
32484
+ }
32485
+ async resolveMigration(slug, tag, input, user) {
32486
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32487
+ const cf = this.requireCloudflare();
32488
+ const databaseId = await this.resolveDatabaseId(slug, game2.id);
32489
+ const [ledger, live] = await Promise.all([
32490
+ cf.d1.readMigrationLedger(databaseId),
32491
+ cf.d1.fingerprintSchema(databaseId)
32492
+ ]);
32493
+ const exists2 = ledger.some((row) => row.tag === tag);
32494
+ if (input.resolution === "applied") {
32495
+ if (!input.checksum) {
32496
+ throw new ValidationError("Resolving a migration as 'applied' requires its checksum");
32497
+ }
32498
+ if (exists2) {
32499
+ throw new AlreadyExistsError(`Migration '${tag}' is already recorded as applied`);
32500
+ }
32501
+ await cf.d1.ensureMigrationLedger(databaseId);
32502
+ await cf.d1.recordLedgerRows(databaseId, {
32503
+ rows: [{ tag, checksum: input.checksum }],
32504
+ deployId: `resolve:${crypto.randomUUID()}`,
32505
+ appliedBy: user.id,
32506
+ source: "resolve"
32507
+ });
32508
+ } else {
32509
+ if (!exists2) {
32510
+ throw new NotFoundError("Migration ledger row", tag);
32511
+ }
32512
+ await cf.d1.deleteLedgerRow(databaseId, tag);
32513
+ }
32514
+ const fingerprintRecorded = await this.updateDeploymentState(game2.id, {
32515
+ schemaFingerprint: live.fingerprint,
32516
+ updatedAt: new Date
32517
+ });
32518
+ addEvent("deployment_state.migration_resolved", {
32519
+ "app.game.id": game2.id,
32520
+ "app.d1.migration_tag": tag,
32521
+ "app.deployment_state.resolution": input.resolution,
32522
+ "app.deployment_state.fingerprint_rerecorded": fingerprintRecorded,
32523
+ "app.user.id": user.id
32524
+ });
32525
+ return {
32526
+ tag,
32527
+ resolution: input.resolution,
32528
+ schemaFingerprint: live.fingerprint,
32529
+ fingerprintRecorded
32530
+ };
32531
+ }
32532
+ async history(slug, user, options = {}) {
32533
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32534
+ const limit = options.limit ?? 20;
32535
+ const [jobs, events] = await Promise.all([
32536
+ this.deps.db.select({
32537
+ status: gameDeployJobs.status,
32538
+ createdAt: gameDeployJobs.createdAt,
32539
+ completedAt: gameDeployJobs.completedAt,
32540
+ deployId: gameDeployJobs.deployId,
32541
+ error: gameDeployJobs.error,
32542
+ email: users.email
32543
+ }).from(gameDeployJobs).leftJoin(users, eq(gameDeployJobs.userId, users.id)).where(eq(gameDeployJobs.gameId, game2.id)).orderBy(desc(deployJobInstant())).limit(limit),
32544
+ this.deps.db.select({
32545
+ kind: gameDeployEvents.kind,
32546
+ payload: gameDeployEvents.payload,
32547
+ createdAt: gameDeployEvents.createdAt,
32548
+ email: users.email
32549
+ }).from(gameDeployEvents).leftJoin(users, eq(gameDeployEvents.userId, users.id)).where(eq(gameDeployEvents.gameId, game2.id)).orderBy(desc(gameDeployEvents.createdAt)).limit(limit)
32550
+ ]);
32551
+ setAttributes({
32552
+ "app.deployment_state.history_jobs": jobs.length,
32553
+ "app.deployment_state.history_events": events.length
32554
+ });
32555
+ const deploys = jobs.map((job) => ({
32556
+ kind: "deploy",
32557
+ status: job.status,
32558
+ at: (job.completedAt ?? job.createdAt).toISOString(),
32559
+ completedAt: job.completedAt?.toISOString() ?? null,
32560
+ by: job.email ?? DELETED_ACCOUNT_LABEL,
32561
+ deployId: job.deployId,
32562
+ error: job.error
32563
+ }));
32564
+ const merged = [...deploys, ...events.flatMap(historyEventEntry)].toSorted((a, b) => a.at < b.at ? 1 : -1).slice(0, limit);
32565
+ return { deploys: merged };
32566
+ }
32567
+ async restorePoints(slug, user) {
32568
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32569
+ const retentionCutoff = new Date(Date.now() - D1_TIME_TRAVEL_RETENTION_DAYS * 24 * 60 * 60 * 1000);
32570
+ const [currentDatabaseId, rows, state] = await Promise.all([
32571
+ this.findDatabaseId(slug, game2.id),
32572
+ this.deps.db.query.gameDeployments.findMany({
32573
+ where: and(eq(gameDeployments.gameId, game2.id), eq(gameDeployments.target, "game"), isNotNull(gameDeployments.timeTravelBookmark), gte(gameDeployments.deployedAt, retentionCutoff)),
32574
+ orderBy: desc(gameDeployments.deployedAt),
32575
+ limit: 100,
32576
+ columns: {
32577
+ id: true,
32578
+ deployedAt: true,
32579
+ bookmarkCapturedAt: true,
32580
+ isActive: true,
32581
+ resources: true
32582
+ }
32583
+ }),
32584
+ this.findSchemaHashState(game2.id)
32585
+ ]);
32586
+ if (isPushAdopted(state)) {
32587
+ return { restorePoints: [], restoreUnsupported: true };
32588
+ }
32589
+ if (!currentDatabaseId) {
32590
+ return { restorePoints: [], restoreUnsupported: false };
32591
+ }
32592
+ const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
32593
+ const restorable = rows.filter((row) => databaseIdFromResources(row.resources, deploymentId) === currentDatabaseId && restorePointCapturedAt(row) >= retentionCutoff).slice(0, 20);
32594
+ setAttributes({ "app.deployment_state.restore_points": restorable.length });
32595
+ return {
32596
+ restorePoints: restorable.map((row) => ({
32597
+ id: row.id,
32598
+ capturedAt: restorePointCapturedAt(row).toISOString(),
32599
+ active: row.isActive
32600
+ })),
32601
+ restoreUnsupported: false
32602
+ };
32603
+ }
32604
+ async restoreToBookmark(slug, input, user) {
32605
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32606
+ const cf = this.requireCloudflare();
32607
+ const [row, state, currentDatabaseId, runningJob] = await Promise.all([
32608
+ this.deps.db.query.gameDeployments.findFirst({
32609
+ where: and(eq(gameDeployments.id, input.restorePointId), eq(gameDeployments.gameId, game2.id), eq(gameDeployments.target, "game")),
32610
+ columns: {
32611
+ id: true,
32612
+ timeTravelBookmark: true,
32613
+ deployedAt: true,
32614
+ bookmarkCapturedAt: true,
32615
+ resources: true
32616
+ }
32617
+ }),
32618
+ this.findSchemaHashState(game2.id),
32619
+ this.findDatabaseId(slug, game2.id),
32620
+ this.deps.db.query.gameDeployJobs.findFirst({
32621
+ where: and(eq(gameDeployJobs.gameId, game2.id), or(eq(gameDeployJobs.status, "pending"), and(eq(gameDeployJobs.status, "running"), gt(gameDeployJobs.leaseExpiresAt, new Date)))),
32622
+ columns: { id: true }
32623
+ })
32624
+ ]);
32625
+ if (!row?.timeTravelBookmark) {
32626
+ throw new NotFoundError("Bookmark", input.restorePointId);
32627
+ }
32628
+ if (isPushAdopted(state)) {
32629
+ 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 });
32630
+ }
32631
+ if (!currentDatabaseId) {
32632
+ throw new ValidationError("Game has no deployed database — deploy with a database binding first");
32633
+ }
32634
+ const databaseId = currentDatabaseId;
32635
+ const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
32636
+ if (databaseIdFromResources(row.resources, deploymentId) !== databaseId) {
32637
+ throw new ValidationError("This bookmark was captured on a previous database (a reset replaced " + "it since) and can no longer be restored");
32638
+ }
32639
+ const retentionCutoff = new Date(Date.now() - D1_TIME_TRAVEL_RETENTION_DAYS * 24 * 60 * 60 * 1000);
32640
+ if (restorePointCapturedAt(row) < retentionCutoff) {
32641
+ 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 });
32642
+ }
32643
+ if (runningJob) {
32644
+ throw new ValidationError("A deploy is currently running for this game. Wait for it to finish, " + "then restore.", { code: DEPLOY_ERROR_CODES.restoreBlockedByDeploy });
32645
+ }
32646
+ const restored = await cf.d1.restoreBookmark(databaseId, row.timeTravelBookmark);
32647
+ const restoredTo = restorePointCapturedAt(row).toISOString();
32648
+ let live;
32649
+ let fingerprintRecorded;
32650
+ try {
32651
+ live = await cf.d1.fingerprintSchema(databaseId);
32652
+ fingerprintRecorded = await this.updateDeploymentState(game2.id, {
32653
+ schemaFingerprint: live.fingerprint,
32654
+ updatedAt: new Date
32655
+ });
32656
+ await this.deps.db.insert(gameDeployEvents).values({
32657
+ gameId: game2.id,
32658
+ userId: user.id,
32659
+ kind: "restore",
32660
+ payload: { restoredTo, previousBookmark: restored.previousBookmark }
32661
+ });
32662
+ } catch (error) {
32663
+ 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 });
32664
+ }
32665
+ addEvent("deployment_state.bookmark_restored", {
32666
+ "app.game.id": game2.id,
32667
+ "app.deployment_state.restore_point": row.id,
32668
+ "app.deployment_state.fingerprint_rerecorded": fingerprintRecorded,
32669
+ "app.user.id": user.id
32670
+ });
32671
+ return {
32672
+ restorePointId: row.id,
32673
+ restoredTo,
32674
+ schemaFingerprint: live.fingerprint,
32675
+ fingerprintRecorded,
32676
+ previousBookmark: restored.previousBookmark
32677
+ };
32678
+ }
32679
+ async reportDeployBlocked(slug, user, report) {
32680
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
32681
+ const recent = await this.deps.db.query.gameDeployEvents.findMany({
32682
+ where: and(eq(gameDeployEvents.gameId, game2.id), eq(gameDeployEvents.kind, "blocked"), gt(gameDeployEvents.createdAt, new Date(Date.now() - BLOCKED_ALERT_DEDUP_MS))),
32683
+ orderBy: desc(gameDeployEvents.createdAt),
32684
+ limit: 10,
32685
+ columns: { payload: true }
32686
+ });
32687
+ const duplicate = recent.some((event) => ("code" in event.payload) && event.payload.code === report.code);
32688
+ await this.deps.db.insert(gameDeployEvents).values({
32689
+ gameId: game2.id,
32690
+ userId: user.id,
32691
+ kind: "blocked",
32692
+ payload: { code: report.code, reason: report.reason }
32693
+ });
32694
+ addEvent("deployment_state.deploy_blocked", {
32695
+ "app.game.id": game2.id,
32696
+ "app.deploy.blocked_code": report.code,
32697
+ "app.user.id": user.id,
32698
+ "app.alerts.deduped": duplicate
32699
+ });
32700
+ if (!duplicate) {
32701
+ await this.deps.alerts.notifyDeployBlocked({
32702
+ slug,
32703
+ displayName: game2.displayName,
32704
+ reason: report.reason,
32705
+ developer: { id: user.id, email: user.email ?? null }
32706
+ });
32707
+ }
32708
+ }
32709
+ }
32710
+ var BLOCKED_ALERT_DEDUP_MS;
32711
+ var init_deployment_state_service = __esm(() => {
32712
+ init_drizzle_orm();
32713
+ init_src4();
32714
+ init_src();
32715
+ init_helpers_index();
32716
+ init_tables_index();
32717
+ init_spans();
32718
+ init_game2();
32719
+ init_errors();
32720
+ init_baseline_validation_util();
32721
+ init_deployment_util();
32722
+ init_migration_util();
32723
+ init_secrets_util();
32724
+ BLOCKED_ALERT_DEDUP_MS = 10 * 60 * 1000;
32725
+ });
32726
+
30542
32727
  // ../api-core/src/services/domain.service.ts
30543
32728
  class DomainService {
30544
32729
  deps;
@@ -30905,6 +33090,7 @@ var init_kv_service = __esm(() => {
30905
33090
  // ../api-core/src/services/secrets.service.ts
30906
33091
  class SecretsService {
30907
33092
  deps;
33093
+ pepperPromise = null;
30908
33094
  constructor(deps) {
30909
33095
  this.deps = deps;
30910
33096
  }
@@ -30917,36 +33103,69 @@ class SecretsService {
30917
33103
  getGameDeploymentId(slug) {
30918
33104
  return getGameDeploymentId(slug, this.deps.config.sstStage);
30919
33105
  }
30920
- async listKeys(slug, user) {
30921
- await this.deps.validateDeveloperAccessBySlug(user, slug);
30922
- const cf = this.getCloudflare();
30923
- const deploymentId = this.getGameDeploymentId(slug);
30924
- try {
30925
- const allKeys = await cf.listSecrets(deploymentId);
30926
- const userKeys = allKeys.filter((k) => k.startsWith(SECRETS_PREFIX)).map((k) => k.slice(SECRETS_PREFIX.length));
30927
- setAttributes({
30928
- "app.secrets.operation": "list",
30929
- "app.secrets.count": userKeys.length,
30930
- "app.secrets.game_deployed": true
30931
- });
30932
- return userKeys;
30933
- } catch (error) {
30934
- const message = errorMessage(error);
30935
- if (message.includes("not found") || message.includes("10007")) {
33106
+ getPepper() {
33107
+ const pepperSecret = this.deps.config.secretsManifestPepper;
33108
+ if (!pepperSecret) {
33109
+ throw new ValidationError("Secrets manifest is not configured (missing manifest pepper secret)");
33110
+ }
33111
+ this.pepperPromise ??= deriveSecretsManifestPepper(pepperSecret);
33112
+ return this.pepperPromise;
33113
+ }
33114
+ async computeManifestEntries(gameId, secrets) {
33115
+ const pepper = await this.getPepper();
33116
+ const entries = {};
33117
+ for (const [key, value] of Object.entries(secrets)) {
33118
+ entries[key] = await computeSecretDigest(pepper, { gameId, key, value });
33119
+ }
33120
+ return entries;
33121
+ }
33122
+ async readManifest(gameId) {
33123
+ const state = await this.deps.db.query.gameDeploymentState.findFirst({
33124
+ where: eq(gameDeploymentState.gameId, gameId),
33125
+ columns: { secretsManifest: true }
33126
+ });
33127
+ return state?.secretsManifest ?? {};
33128
+ }
33129
+ async upsertManifestEntries(gameId, entries) {
33130
+ const merged = sql`coalesce(${gameDeploymentState.secretsManifest}, '{}'::jsonb) || ${JSON.stringify(entries)}::jsonb`;
33131
+ await this.deps.db.insert(gameDeploymentState).values({ gameId, secretsManifest: entries, updatedAt: new Date }).onConflictDoUpdate({
33132
+ target: gameDeploymentState.gameId,
33133
+ set: { secretsManifest: merged, updatedAt: new Date }
33134
+ });
33135
+ }
33136
+ async removeManifestKey(gameId, key) {
33137
+ await this.deps.db.update(gameDeploymentState).set({
33138
+ secretsManifest: sql`coalesce(${gameDeploymentState.secretsManifest}, '{}'::jsonb) - ${key}::text`,
33139
+ updatedAt: new Date
33140
+ }).where(eq(gameDeploymentState.gameId, gameId));
33141
+ }
33142
+ assertNoReservedKeys(keys, operation) {
33143
+ for (const key of keys) {
33144
+ if (INTERNAL_SECRET_KEYS.includes(key)) {
30936
33145
  setAttributes({
30937
- "app.secrets.operation": "list",
30938
- "app.secrets.count": 0,
30939
- "app.secrets.game_deployed": false
33146
+ "app.secrets.operation": operation,
33147
+ "app.secrets.reserved_key_rejected": true
30940
33148
  });
30941
- return [];
33149
+ throw new ValidationError(operation === "set" ? `Cannot set reserved secret "${key}"` : `Reserved secret "${key}" cannot be managed — remove it locally`);
30942
33150
  }
30943
- throw error;
30944
33151
  }
30945
33152
  }
30946
- async setSecrets(slug, newSecrets, user) {
33153
+ async listKeys(slug, user) {
30947
33154
  await this.deps.validateDeveloperAccessBySlug(user, slug);
30948
33155
  const cf = this.getCloudflare();
30949
33156
  const deploymentId = this.getGameDeploymentId(slug);
33157
+ const userKeys = await listUserSecretKeys(cf, deploymentId);
33158
+ setAttributes({
33159
+ "app.secrets.operation": "list",
33160
+ "app.secrets.count": userKeys?.length ?? 0,
33161
+ "app.secrets.game_deployed": userKeys !== null
33162
+ });
33163
+ return userKeys ?? [];
33164
+ }
33165
+ async setSecrets(slug, newSecrets, user) {
33166
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
33167
+ const cf = this.getCloudflare();
33168
+ const deploymentId = this.getGameDeploymentId(slug);
30950
33169
  const secretKeys = Object.keys(newSecrets);
30951
33170
  if (secretKeys.length === 0) {
30952
33171
  throw new ValidationError("At least one secret must be provided");
@@ -30955,14 +33174,9 @@ class SecretsService {
30955
33174
  if (typeof value !== "string") {
30956
33175
  throw new ValidationError(`Secret value for "${key}" must be a string`);
30957
33176
  }
30958
- if (INTERNAL_SECRET_KEYS.includes(key)) {
30959
- setAttributes({
30960
- "app.secrets.operation": "set",
30961
- "app.secrets.reserved_key_rejected": true
30962
- });
30963
- throw new ValidationError(`Cannot set reserved secret "${key}"`);
30964
- }
30965
33177
  }
33178
+ this.assertNoReservedKeys(secretKeys, "set");
33179
+ const manifestEntries = await this.computeManifestEntries(game2.id, newSecrets);
30966
33180
  try {
30967
33181
  const prefixedSecrets = {};
30968
33182
  for (const [key, value] of Object.entries(newSecrets)) {
@@ -30975,8 +33189,6 @@ class SecretsService {
30975
33189
  "app.secrets.game_deployed": true,
30976
33190
  "app.secrets.reserved_key_rejected": false
30977
33191
  });
30978
- const allKeys = await cf.listSecrets(deploymentId);
30979
- return allKeys.filter((k) => k.startsWith(SECRETS_PREFIX)).map((k) => k.slice(SECRETS_PREFIX.length));
30980
33192
  } catch (error) {
30981
33193
  const message = errorMessage(error);
30982
33194
  if (message.includes("not found") || message.includes("10007")) {
@@ -30988,6 +33200,9 @@ class SecretsService {
30988
33200
  }
30989
33201
  throw error;
30990
33202
  }
33203
+ await this.upsertManifestEntries(game2.id, manifestEntries);
33204
+ const allKeys = await cf.listSecrets(deploymentId);
33205
+ return allKeys.filter((k) => k.startsWith(SECRETS_PREFIX)).map((k) => k.slice(SECRETS_PREFIX.length));
30991
33206
  }
30992
33207
  async deleteSecret(slug, key, user) {
30993
33208
  if (INTERNAL_SECRET_KEYS.includes(key)) {
@@ -30997,19 +33212,25 @@ class SecretsService {
30997
33212
  });
30998
33213
  throw new ValidationError(`Cannot delete reserved secret "${key}"`);
30999
33214
  }
31000
- await this.deps.validateDeveloperAccessBySlug(user, slug);
33215
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
31001
33216
  const cf = this.getCloudflare();
31002
33217
  const deploymentId = this.getGameDeploymentId(slug);
33218
+ const manifest = await this.readManifest(game2.id);
33219
+ const managed = key in manifest;
31003
33220
  try {
31004
33221
  const prefixedKey = `${SECRETS_PREFIX}${key}`;
31005
33222
  const existingKeys = await cf.listSecrets(deploymentId);
31006
- if (!existingKeys.includes(prefixedKey)) {
33223
+ const onWorker = existingKeys.includes(prefixedKey);
33224
+ if (!onWorker && !managed) {
31007
33225
  throw new NotFoundError("Secret", key);
31008
33226
  }
31009
- await cf.deleteSecret(deploymentId, prefixedKey);
33227
+ if (onWorker) {
33228
+ await cf.deleteSecret(deploymentId, prefixedKey);
33229
+ }
31010
33230
  setAttributes({
31011
33231
  "app.secrets.operation": "delete",
31012
33232
  "app.secrets.game_deployed": true,
33233
+ "app.secrets.managed": managed,
31013
33234
  "app.secrets.reserved_key_rejected": false
31014
33235
  });
31015
33236
  } catch (error) {
@@ -31026,14 +33247,45 @@ class SecretsService {
31026
33247
  }
31027
33248
  throw error;
31028
33249
  }
33250
+ if (managed) {
33251
+ await this.removeManifestKey(game2.id, key);
33252
+ }
33253
+ }
33254
+ async diff(slug, localSecrets, user) {
33255
+ const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
33256
+ const deploymentId = this.getGameDeploymentId(slug);
33257
+ this.assertNoReservedKeys(Object.keys(localSecrets), "diff");
33258
+ const [manifest, remoteKeys, localDigests] = await Promise.all([
33259
+ this.readManifest(game2.id),
33260
+ this.deps.cloudflare ? listUserSecretKeys(this.deps.cloudflare, deploymentId) : null,
33261
+ this.computeManifestEntries(game2.id, localSecrets)
33262
+ ]);
33263
+ const verdicts = computeSecretsDiff({
33264
+ localDigests,
33265
+ manifest,
33266
+ remoteKeys: remoteKeys ?? []
33267
+ });
33268
+ setAttributes({
33269
+ "app.secrets.operation": "diff",
33270
+ "app.secrets.game_deployed": remoteKeys !== null,
33271
+ "app.secrets.diff_added": verdicts.added.length,
33272
+ "app.secrets.diff_changed": verdicts.changed.length,
33273
+ "app.secrets.diff_unchanged": verdicts.unchanged.length,
33274
+ "app.secrets.diff_remote_only_managed": verdicts.remoteOnlyManaged.length,
33275
+ "app.secrets.diff_remote_only_unmanaged": verdicts.remoteOnlyUnmanaged.length
33276
+ });
33277
+ return verdicts;
31029
33278
  }
31030
33279
  }
31031
33280
  var INTERNAL_SECRET_KEYS;
31032
33281
  var init_secrets_service = __esm(() => {
33282
+ init_drizzle_orm();
31033
33283
  init_src();
33284
+ init_tables_index();
31034
33285
  init_spans();
31035
33286
  init_errors();
31036
33287
  init_deployment_util();
33288
+ init_secrets_util();
31037
33289
  INTERNAL_SECRET_KEYS = ["PLAYCADEMY_API_KEY", "GAME_ID", "PLAYCADEMY_BASE_URL"];
31038
33290
  });
31039
33291
  // ../edge-play/src/game/setup.ts
@@ -31571,7 +33823,10 @@ var init_emoji = __esm(() => {
31571
33823
  });
31572
33824
 
31573
33825
  // ../data/src/domains/game/schemas.ts
31574
- 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;
33826
+ function requestsBinding(binding) {
33827
+ return binding === true || Array.isArray(binding) && binding.length > 0;
33828
+ }
33829
+ 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;
31575
33830
  var init_schemas2 = __esm(() => {
31576
33831
  init_drizzle_zod();
31577
33832
  init_esm();
@@ -31650,6 +33905,9 @@ var init_schemas2 = __esm(() => {
31650
33905
  InsertGameDeployJobSchema = createInsertSchema(gameDeployJobs, {
31651
33906
  status: exports_external.enum(deployJobStatusEnum.enumValues)
31652
33907
  });
33908
+ InsertGameDeploymentStateSchema = createInsertSchema(gameDeploymentState, {
33909
+ secretsManifest: exports_external.record(exports_external.string(), exports_external.string()).nullable().optional()
33910
+ });
31653
33911
  UpsertGameMetadataSchema = exports_external.object({
31654
33912
  displayName: exports_external.string().min(1),
31655
33913
  platform: exports_external.enum(gamePlatformEnum.enumValues),
@@ -31707,6 +33965,9 @@ var init_schemas2 = __esm(() => {
31707
33965
  hostname: exports_external.string().min(1).max(255)
31708
33966
  });
31709
33967
  SetSecretsRequestSchema = exports_external.record(exports_external.string().min(1), exports_external.string());
33968
+ SecretsDiffRequestSchema = exports_external.object({
33969
+ secrets: exports_external.record(exports_external.string().min(1), exports_external.string())
33970
+ });
31710
33971
  SeedRequestSchema = exports_external.object({
31711
33972
  code: exports_external.string().min(1, "Seed code is required"),
31712
33973
  secrets: exports_external.record(exports_external.string(), exports_external.string()).optional()
@@ -31715,9 +33976,6 @@ var init_schemas2 = __esm(() => {
31715
33976
  sql: exports_external.string(),
31716
33977
  hash: exports_external.string()
31717
33978
  });
31718
- DatabaseResetRequestSchema = exports_external.object({
31719
- schema: SchemaInfoSchema.optional()
31720
- });
31721
33979
  VerifyTokenSchema = exports_external.object({
31722
33980
  token: exports_external.string().min(1, "Token is required")
31723
33981
  });
@@ -31729,8 +33987,126 @@ var init_schemas2 = __esm(() => {
31729
33987
  metadata: exports_external.record(exports_external.unknown()).optional()
31730
33988
  }))
31731
33989
  });
33990
+ DeployMigrationSchema = exports_external.object({
33991
+ tag: exports_external.string().min(1),
33992
+ statements: exports_external.array(exports_external.string().min(1)).min(1),
33993
+ checksum: exports_external.string().min(1)
33994
+ });
33995
+ DeployDatabaseSchema = exports_external.discriminatedUnion("mode", [
33996
+ exports_external.object({
33997
+ mode: exports_external.literal("push"),
33998
+ sql: exports_external.string(),
33999
+ baselineHash: exports_external.string().nullable(),
34000
+ nextSnapshot: exports_external.record(exports_external.string(), exports_external.unknown()),
34001
+ nextHash: exports_external.string().min(1),
34002
+ acceptDataLoss: exports_external.boolean().optional()
34003
+ }),
34004
+ exports_external.object({
34005
+ mode: exports_external.literal("migrate"),
34006
+ migrations: exports_external.array(DeployMigrationSchema)
34007
+ })
34008
+ ]);
34009
+ DatabaseResetDatabaseSchema = exports_external.discriminatedUnion("mode", [
34010
+ exports_external.object({
34011
+ mode: exports_external.literal("push"),
34012
+ sql: exports_external.string(),
34013
+ nextSnapshot: exports_external.record(exports_external.string(), exports_external.unknown()),
34014
+ nextHash: exports_external.string().min(1)
34015
+ }),
34016
+ exports_external.object({
34017
+ mode: exports_external.literal("migrate"),
34018
+ migrations: exports_external.array(DeployMigrationSchema)
34019
+ })
34020
+ ]);
34021
+ DatabaseResetRequestSchema = exports_external.object({
34022
+ schema: SchemaInfoSchema.optional(),
34023
+ database: DatabaseResetDatabaseSchema.optional()
34024
+ }).refine((data) => !(data.schema && data.database), {
34025
+ message: "Send either the database payload or the legacy schema field, not both",
34026
+ path: ["database"]
34027
+ });
34028
+ BaselineEvidenceSchema = exports_external.array(exports_external.object({
34029
+ tag: exports_external.string().min(1),
34030
+ generatedAt: exports_external.string().min(1),
34031
+ createsTables: exports_external.array(exports_external.object({
34032
+ name: exports_external.string().min(1),
34033
+ columns: exports_external.array(exports_external.string())
34034
+ })),
34035
+ addsColumns: exports_external.array(exports_external.object({
34036
+ table: exports_external.string().min(1),
34037
+ column: exports_external.string().min(1)
34038
+ })),
34039
+ createsIndexes: exports_external.array(exports_external.string()),
34040
+ createsViews: exports_external.array(exports_external.string()),
34041
+ dropsTables: exports_external.array(exports_external.string()),
34042
+ dropsColumns: exports_external.array(exports_external.object({
34043
+ table: exports_external.string().min(1),
34044
+ column: exports_external.string().min(1)
34045
+ })),
34046
+ dropsIndexes: exports_external.array(exports_external.string()),
34047
+ dropsViews: exports_external.array(exports_external.string())
34048
+ })).optional();
34049
+ DeployBaselineSchema = exports_external.object({
34050
+ lastAppliedMigrationTag: exports_external.string().min(1).optional(),
34051
+ journal: exports_external.array(exports_external.object({
34052
+ tag: exports_external.string().min(1),
34053
+ checksum: exports_external.string().min(1)
34054
+ })).optional(),
34055
+ evidence: BaselineEvidenceSchema,
34056
+ schemaSnapshot: exports_external.unknown().optional(),
34057
+ schemaHash: exports_external.string().min(1).optional(),
34058
+ integrationsHash: exports_external.string().min(1).optional(),
34059
+ buildHash: exports_external.string().min(1).optional()
34060
+ }).refine((data) => !data.lastAppliedMigrationTag === !data.journal, {
34061
+ message: "lastAppliedMigrationTag and journal must be provided together",
34062
+ path: ["journal"]
34063
+ }).refine((data) => data.schemaSnapshot === undefined === !data.schemaHash, {
34064
+ message: "schemaSnapshot and schemaHash must be provided together",
34065
+ path: ["schemaHash"]
34066
+ }).refine((data) => Boolean(data.lastAppliedMigrationTag || data.schemaHash || data.integrationsHash || data.buildHash), {
34067
+ message: "A baseline must claim something — migration history, a schema snapshot, or artifact hashes",
34068
+ path: ["lastAppliedMigrationTag"]
34069
+ });
34070
+ DeploymentStateBaselineSchema = exports_external.object({
34071
+ lastAppliedMigrationTag: exports_external.string().min(1).optional(),
34072
+ journal: exports_external.array(exports_external.object({
34073
+ tag: exports_external.string().min(1),
34074
+ checksum: exports_external.string().min(1)
34075
+ })).optional(),
34076
+ schemaSnapshot: exports_external.unknown().optional(),
34077
+ schemaHash: exports_external.string().min(1).optional(),
34078
+ evidence: BaselineEvidenceSchema,
34079
+ allowUnverified: exports_external.boolean().optional()
34080
+ }).refine((data) => !data.lastAppliedMigrationTag === !data.journal, {
34081
+ message: "lastAppliedMigrationTag and journal must be provided together",
34082
+ path: ["journal"]
34083
+ }).refine((data) => data.schemaSnapshot === undefined === !data.schemaHash, {
34084
+ message: "schemaSnapshot and schemaHash must be provided together",
34085
+ path: ["schemaHash"]
34086
+ }).refine((data) => Boolean(data.lastAppliedMigrationTag) || Boolean(data.schemaHash), {
34087
+ message: "A baseline needs a migration claim, a schema snapshot, or both",
34088
+ path: ["lastAppliedMigrationTag"]
34089
+ });
34090
+ MigrationRealignSchema = exports_external.object({
34091
+ checksum: exports_external.string().min(1)
34092
+ });
34093
+ MigrationResolveSchema = exports_external.object({
34094
+ resolution: exports_external.enum(["applied", "rolled-back"]),
34095
+ checksum: exports_external.string().min(1).optional()
34096
+ }).refine((data) => data.resolution !== "applied" || Boolean(data.checksum), {
34097
+ message: "Resolving a migration as 'applied' requires its checksum",
34098
+ path: ["checksum"]
34099
+ });
34100
+ DatabaseRestoreSchema = exports_external.object({
34101
+ restorePointId: exports_external.string().uuid()
34102
+ });
34103
+ DeployBlockedReportSchema = exports_external.object({
34104
+ code: exports_external.string().regex(/^blocked:[a-z-]+$/).max(64),
34105
+ reason: exports_external.string().min(1).max(2000)
34106
+ });
31732
34107
  DeployRequestSchema = exports_external.object({
31733
34108
  target: exports_external.enum(deploymentTargetEnum.enumValues).optional().default("game"),
34109
+ deployId: exports_external.string().min(1).optional(),
31734
34110
  uploadToken: exports_external.string().optional(),
31735
34111
  code: exports_external.string().optional(),
31736
34112
  codeUploadToken: exports_external.string().optional(),
@@ -31757,6 +34133,11 @@ var init_schemas2 = __esm(() => {
31757
34133
  sql: exports_external.string(),
31758
34134
  hash: exports_external.string()
31759
34135
  }).optional(),
34136
+ database: DeployDatabaseSchema.optional(),
34137
+ baseline: DeployBaselineSchema.optional(),
34138
+ buildHash: exports_external.string().min(1).optional(),
34139
+ integrationsHash: exports_external.string().min(1).optional(),
34140
+ pruneSecrets: exports_external.array(exports_external.string().min(1)).optional(),
31760
34141
  metadata: exports_external.object({
31761
34142
  displayName: exports_external.string().optional(),
31762
34143
  description: exports_external.string().optional(),
@@ -31766,9 +34147,24 @@ var init_schemas2 = __esm(() => {
31766
34147
  }).refine((data) => !(data.code && data.codeUploadToken), {
31767
34148
  message: "Specify either code or codeUploadToken, not both",
31768
34149
  path: ["codeUploadToken"]
31769
- }).refine((data) => !(data.target === "dashboard" && (data.schema || data.bindings)), {
31770
- message: "Dashboard deployments cannot include schema or bindings — they attach to the game deployment’s existing resources",
34150
+ }).refine((data) => !(data.target === "dashboard" && (data.schema || data.bindings || data.database)), {
34151
+ message: "Dashboard deployments cannot include schema, database, or bindings — they attach to the game deployment’s existing resources",
31771
34152
  path: ["target"]
34153
+ }).refine((data) => !(data.target === "dashboard" && (data.baseline || data.pruneSecrets)), {
34154
+ message: "Dashboard deployments cannot adopt a baseline or prune secrets",
34155
+ path: ["target"]
34156
+ }).refine((data) => !(data.database && !data.deployId), {
34157
+ message: "deployId is required when a database payload is present",
34158
+ path: ["deployId"]
34159
+ }).refine((data) => !(data.database && data.schema), {
34160
+ message: "Send either the database payload or the legacy schema field, not both",
34161
+ path: ["database"]
34162
+ }).refine((data) => !(data.baseline && data.schema), {
34163
+ message: "The legacy schema field cannot ride a baseline-adopting deploy",
34164
+ path: ["baseline"]
34165
+ }).refine((data) => !(data.database && !requestsBinding(data.bindings?.database)), {
34166
+ message: "The database payload requires a database binding",
34167
+ path: ["database"]
31772
34168
  });
31773
34169
  });
31774
34170
 
@@ -75506,7 +77902,7 @@ var init_pure = __esm(() => {
75506
77902
  });
75507
77903
 
75508
77904
  // ../utils/src/index.ts
75509
- var init_src4 = __esm(() => {
77905
+ var init_src5 = __esm(() => {
75510
77906
  init_pure();
75511
77907
  });
75512
77908
 
@@ -77463,7 +79859,7 @@ var init_dist5 = __esm(async () => {
77463
79859
  init_spans();
77464
79860
  init_src();
77465
79861
  init_spans();
77466
- init_src4();
79862
+ init_src5();
77467
79863
  init_src();
77468
79864
  init_spans();
77469
79865
  init_spans();
@@ -78042,7 +80438,7 @@ function selectTimebackMetricDiscrepancyQueueItems(candidates, options) {
78042
80438
  }
78043
80439
  var DATE_INPUT_RE;
78044
80440
  var init_timeback_discrepancy_queue_util = __esm(() => {
78045
- init_src4();
80441
+ init_src5();
78046
80442
  init_timeback_util();
78047
80443
  DATE_INPUT_RE = /^\d{4}-\d{2}-\d{2}$/;
78048
80444
  });
@@ -80561,7 +82957,7 @@ var init_timeback_admin_service = __esm(async () => {
80561
82957
  init_constants3();
80562
82958
  init_types2();
80563
82959
  init_utils6();
80564
- init_src4();
82960
+ init_src5();
80565
82961
  init_timeback3();
80566
82962
  init_errors();
80567
82963
  init_timeback_admin_metrics_util();
@@ -83017,8 +85413,15 @@ function createPlatformServices(deps) {
83017
85413
  validateDeveloperAccess
83018
85414
  });
83019
85415
  const kv = new KVService({ db: db2, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
83020
- const secrets = new SecretsService({ config: config4, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
85416
+ const secrets = new SecretsService({ db: db2, config: config4, cloudflare: cloudflare2, validateDeveloperAccessBySlug });
83021
85417
  const domain3 = new DomainService({ db: db2, cloudflare: cloudflare2, corsKvs, validateDeveloperAccessBySlug });
85418
+ const deploymentState = new DeploymentStateService({
85419
+ db: db2,
85420
+ config: config4,
85421
+ cloudflare: cloudflare2,
85422
+ alerts,
85423
+ validateDeveloperAccessBySlug
85424
+ });
83022
85425
  const database = new DatabaseService({
83023
85426
  db: db2,
83024
85427
  config: config4,
@@ -83057,6 +85460,7 @@ function createPlatformServices(deps) {
83057
85460
  kv,
83058
85461
  secrets,
83059
85462
  domain: domain3,
85463
+ deploymentState,
83060
85464
  database,
83061
85465
  seed,
83062
85466
  timeback: timeback2,
@@ -83067,6 +85471,7 @@ function createPlatformServices(deps) {
83067
85471
  var init_platform2 = __esm(async () => {
83068
85472
  init_bucket_service();
83069
85473
  init_database_service();
85474
+ init_deployment_state_service();
83070
85475
  init_domain_service();
83071
85476
  init_kv_service();
83072
85477
  init_secrets_service();
@@ -83799,7 +86204,7 @@ function createServices(ctx) {
83799
86204
  };
83800
86205
  }
83801
86206
  var init_factory = __esm(async () => {
83802
- init_game2();
86207
+ init_game3();
83803
86208
  init_infra2();
83804
86209
  init_player();
83805
86210
  init_standalone();
@@ -84106,6 +86511,7 @@ function buildConfig(options) {
84106
86511
  gameDomain: "localhost",
84107
86512
  uploadBucket: "sandbox-uploads",
84108
86513
  ltiTestMode: true,
86514
+ secretsManifestPepper: "sandbox-secrets-manifest-pepper",
84109
86515
  ...options.config
84110
86516
  });
84111
86517
  }
@@ -101047,7 +103453,7 @@ var __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf2,
101047
103453
  __defProp2(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
101048
103454
  }
101049
103455
  return to;
101050
- }, __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) => {
103456
+ }, __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) => {
101051
103457
  const matchers = filters.map((it3) => {
101052
103458
  return new Minimatch(it3);
101053
103459
  });
@@ -121473,7 +123879,7 @@ globstar while`, file3, fr, pattern, pr2, swallowee);
121473
123879
  });
121474
123880
  }
121475
123881
  });
121476
- init_sql3 = __esm2({
123882
+ init_sql4 = __esm2({
121477
123883
  "../drizzle-orm/dist/sql/sql.js"() {
121478
123884
  init_entity2();
121479
123885
  init_enum2();
@@ -121826,7 +124232,7 @@ globstar while`, file3, fr, pattern, pr2, swallowee);
121826
124232
  "../drizzle-orm/dist/alias.js"() {
121827
124233
  init_column2();
121828
124234
  init_entity2();
121829
- init_sql3();
124235
+ init_sql4();
121830
124236
  init_table8();
121831
124237
  init_view_common3();
121832
124238
  _a28 = entityKind2;
@@ -122000,7 +124406,7 @@ params: ${params}`);
122000
124406
  "../drizzle-orm/dist/utils.js"() {
122001
124407
  init_column2();
122002
124408
  init_entity2();
122003
- init_sql3();
124409
+ init_sql4();
122004
124410
  init_subquery2();
122005
124411
  init_table8();
122006
124412
  init_view_common3();
@@ -122259,7 +124665,7 @@ params: ${params}`);
122259
124665
  init_date_common2 = __esm2({
122260
124666
  "../drizzle-orm/dist/pg-core/columns/date.common.js"() {
122261
124667
  init_entity2();
122262
- init_sql3();
124668
+ init_sql4();
122263
124669
  init_common22();
122264
124670
  PgDateColumnBaseBuilder2 = class extends (_b33 = PgColumnBuilder2, _a54 = entityKind2, _b33) {
122265
124671
  defaultNow() {
@@ -123044,7 +125450,7 @@ params: ${params}`);
123044
125450
  init_uuid3 = __esm2({
123045
125451
  "../drizzle-orm/dist/pg-core/columns/uuid.js"() {
123046
125452
  init_entity2();
123047
- init_sql3();
125453
+ init_sql4();
123048
125454
  init_common22();
123049
125455
  PgUUIDBuilder2 = class extends (_b88 = PgColumnBuilder2, _a109 = entityKind2, _b88) {
123050
125456
  constructor(name22) {
@@ -123315,7 +125721,7 @@ params: ${params}`);
123315
125721
  init_column2();
123316
125722
  init_entity2();
123317
125723
  init_table8();
123318
- init_sql3();
125724
+ init_sql4();
123319
125725
  eq2 = (left, right) => {
123320
125726
  return sql4`${left} = ${bindIfParam2(right, left)}`;
123321
125727
  };
@@ -123338,7 +125744,7 @@ params: ${params}`);
123338
125744
  });
123339
125745
  init_select3 = __esm2({
123340
125746
  "../drizzle-orm/dist/sql/expressions/select.js"() {
123341
- init_sql3();
125747
+ init_sql4();
123342
125748
  }
123343
125749
  });
123344
125750
  init_expressions2 = __esm2({
@@ -123354,7 +125760,7 @@ params: ${params}`);
123354
125760
  init_entity2();
123355
125761
  init_primary_keys2();
123356
125762
  init_expressions2();
123357
- init_sql3();
125763
+ init_sql4();
123358
125764
  _a124 = entityKind2;
123359
125765
  Relation2 = class {
123360
125766
  constructor(sourceTable, referencedTable, relationName) {
@@ -123408,12 +125814,12 @@ params: ${params}`);
123408
125814
  "../drizzle-orm/dist/sql/functions/aggregate.js"() {
123409
125815
  init_column2();
123410
125816
  init_entity2();
123411
- init_sql3();
125817
+ init_sql4();
123412
125818
  }
123413
125819
  });
123414
125820
  init_vector22 = __esm2({
123415
125821
  "../drizzle-orm/dist/sql/functions/vector.js"() {
123416
- init_sql3();
125822
+ init_sql4();
123417
125823
  }
123418
125824
  });
123419
125825
  init_functions2 = __esm2({
@@ -123426,7 +125832,7 @@ params: ${params}`);
123426
125832
  "../drizzle-orm/dist/sql/index.js"() {
123427
125833
  init_expressions2();
123428
125834
  init_functions2();
123429
- init_sql3();
125835
+ init_sql4();
123430
125836
  }
123431
125837
  });
123432
125838
  dist_exports = {};
@@ -123643,7 +126049,7 @@ params: ${params}`);
123643
126049
  init_alias3();
123644
126050
  init_column2();
123645
126051
  init_entity2();
123646
- init_sql3();
126052
+ init_sql4();
123647
126053
  init_subquery2();
123648
126054
  init_view_common3();
123649
126055
  _a130 = entityKind2;
@@ -123702,7 +126108,7 @@ params: ${params}`);
123702
126108
  });
123703
126109
  init_indexes2 = __esm2({
123704
126110
  "../drizzle-orm/dist/pg-core/indexes.js"() {
123705
- init_sql3();
126111
+ init_sql4();
123706
126112
  init_entity2();
123707
126113
  init_columns2();
123708
126114
  _a131 = entityKind2;
@@ -123865,7 +126271,7 @@ params: ${params}`);
123865
126271
  init_view_base2 = __esm2({
123866
126272
  "../drizzle-orm/dist/pg-core/view-base.js"() {
123867
126273
  init_entity2();
123868
- init_sql3();
126274
+ init_sql4();
123869
126275
  PgViewBase2 = class extends (_b103 = View3, _a136 = entityKind2, _b103) {
123870
126276
  };
123871
126277
  __publicField(PgViewBase2, _a136, "PgViewBase");
@@ -123882,7 +126288,7 @@ params: ${params}`);
123882
126288
  init_table22();
123883
126289
  init_relations2();
123884
126290
  init_sql22();
123885
- init_sql3();
126291
+ init_sql4();
123886
126292
  init_subquery2();
123887
126293
  init_table8();
123888
126294
  init_utils22();
@@ -124466,7 +126872,7 @@ params: ${params}`);
124466
126872
  init_query_builder3();
124467
126873
  init_query_promise2();
124468
126874
  init_selection_proxy2();
124469
- init_sql3();
126875
+ init_sql4();
124470
126876
  init_subquery2();
124471
126877
  init_table8();
124472
126878
  init_tracing2();
@@ -125087,7 +127493,7 @@ params: ${params}`);
125087
127493
  "../drizzle-orm/dist/pg-core/utils.js"() {
125088
127494
  init_entity2();
125089
127495
  init_table22();
125090
- init_sql3();
127496
+ init_sql4();
125091
127497
  init_subquery2();
125092
127498
  init_table8();
125093
127499
  init_view_common3();
@@ -125175,7 +127581,7 @@ params: ${params}`);
125175
127581
  init_entity2();
125176
127582
  init_query_promise2();
125177
127583
  init_selection_proxy2();
125178
- init_sql3();
127584
+ init_sql4();
125179
127585
  init_table8();
125180
127586
  init_tracing2();
125181
127587
  init_utils22();
@@ -125369,7 +127775,7 @@ params: ${params}`);
125369
127775
  init_table22();
125370
127776
  init_query_promise2();
125371
127777
  init_selection_proxy2();
125372
- init_sql3();
127778
+ init_sql4();
125373
127779
  init_subquery2();
125374
127780
  init_table8();
125375
127781
  init_utils22();
@@ -125543,7 +127949,7 @@ params: ${params}`);
125543
127949
  init_count2 = __esm2({
125544
127950
  "../drizzle-orm/dist/pg-core/query-builders/count.js"() {
125545
127951
  init_entity2();
125546
- init_sql3();
127952
+ init_sql4();
125547
127953
  _PgCountBuilder = class _PgCountBuilder2 extends (_c6 = SQL2, _b116 = entityKind2, _a157 = Symbol.toStringTag, _c6) {
125548
127954
  constructor(params) {
125549
127955
  super(_PgCountBuilder2.buildEmbeddedCount(params.source, params.filters).queryChunks);
@@ -125711,7 +128117,7 @@ params: ${params}`);
125711
128117
  init_entity2();
125712
128118
  init_query_builders2();
125713
128119
  init_selection_proxy2();
125714
- init_sql3();
128120
+ init_sql4();
125715
128121
  init_subquery2();
125716
128122
  init_count2();
125717
128123
  init_query2();
@@ -125883,10 +128289,10 @@ params: ${params}`);
125883
128289
  __publicField(PgSequence, _a163, "PgSequence");
125884
128290
  }
125885
128291
  });
125886
- init_schema3 = __esm2({
128292
+ init_schema4 = __esm2({
125887
128293
  "../drizzle-orm/dist/pg-core/schema.js"() {
125888
128294
  init_entity2();
125889
- init_sql3();
128295
+ init_sql4();
125890
128296
  init_enum2();
125891
128297
  init_sequence2();
125892
128298
  init_table22();
@@ -126102,7 +128508,7 @@ params: ${params}`);
126102
128508
  init_primary_keys2();
126103
128509
  init_query_builders2();
126104
128510
  init_roles2();
126105
- init_schema3();
128511
+ init_schema4();
126106
128512
  init_sequence2();
126107
128513
  init_session3();
126108
128514
  init_subquery22();
@@ -127910,7 +130316,7 @@ ORDER BY
127910
130316
  init_integer22 = __esm2({
127911
130317
  "../drizzle-orm/dist/sqlite-core/columns/integer.js"() {
127912
130318
  init_entity2();
127913
- init_sql3();
130319
+ init_sql4();
127914
130320
  init_utils22();
127915
130321
  init_common3();
127916
130322
  SQLiteBaseIntegerBuilder = class extends (_b131 = SQLiteColumnBuilder, _a187 = entityKind2, _b131) {
@@ -128273,7 +130679,7 @@ ORDER BY
128273
130679
  init_utils72 = __esm2({
128274
130680
  "../drizzle-orm/dist/sqlite-core/utils.js"() {
128275
130681
  init_entity2();
128276
- init_sql3();
130682
+ init_sql4();
128277
130683
  init_subquery2();
128278
130684
  init_table8();
128279
130685
  init_view_common3();
@@ -128367,7 +130773,7 @@ ORDER BY
128367
130773
  init_view_base22 = __esm2({
128368
130774
  "../drizzle-orm/dist/sqlite-core/view-base.js"() {
128369
130775
  init_entity2();
128370
- init_sql3();
130776
+ init_sql4();
128371
130777
  SQLiteViewBase = class extends (_b153 = View3, _a214 = entityKind2, _b153) {
128372
130778
  };
128373
130779
  __publicField(SQLiteViewBase, _a214, "SQLiteViewBase");
@@ -128382,7 +130788,7 @@ ORDER BY
128382
130788
  init_errors22();
128383
130789
  init_relations2();
128384
130790
  init_sql22();
128385
- init_sql3();
130791
+ init_sql4();
128386
130792
  init_columns22();
128387
130793
  init_table32();
128388
130794
  init_subquery2();
@@ -128962,7 +131368,7 @@ ORDER BY
128962
131368
  init_query_builder3();
128963
131369
  init_query_promise2();
128964
131370
  init_selection_proxy2();
128965
- init_sql3();
131371
+ init_sql4();
128966
131372
  init_subquery2();
128967
131373
  init_table8();
128968
131374
  init_utils22();
@@ -129325,7 +131731,7 @@ ORDER BY
129325
131731
  "../drizzle-orm/dist/sqlite-core/query-builders/insert.js"() {
129326
131732
  init_entity2();
129327
131733
  init_query_promise2();
129328
- init_sql3();
131734
+ init_sql4();
129329
131735
  init_table32();
129330
131736
  init_table8();
129331
131737
  init_utils22();
@@ -129572,7 +131978,7 @@ ORDER BY
129572
131978
  init_count22 = __esm2({
129573
131979
  "../drizzle-orm/dist/sqlite-core/query-builders/count.js"() {
129574
131980
  init_entity2();
129575
- init_sql3();
131981
+ init_sql4();
129576
131982
  _SQLiteCountBuilder = class _SQLiteCountBuilder2 extends (_c8 = SQL2, _b160 = entityKind2, _a226 = Symbol.toStringTag, _c8) {
129577
131983
  constructor(params) {
129578
131984
  super(_SQLiteCountBuilder2.buildEmbeddedCount(params.source, params.filters).queryChunks);
@@ -129741,7 +132147,7 @@ ORDER BY
129741
132147
  "../drizzle-orm/dist/sqlite-core/db.js"() {
129742
132148
  init_entity2();
129743
132149
  init_selection_proxy2();
129744
- init_sql3();
132150
+ init_sql4();
129745
132151
  init_query_builders22();
129746
132152
  init_subquery2();
129747
132153
  init_count22();
@@ -131712,7 +134118,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
131712
134118
  init_date_common22 = __esm2({
131713
134119
  "../drizzle-orm/dist/mysql-core/columns/date.common.js"() {
131714
134120
  init_entity2();
131715
- init_sql3();
134121
+ init_sql4();
131716
134122
  init_common4();
131717
134123
  MySqlDateColumnBaseBuilder = class extends (_b223 = MySqlColumnBuilder, _a301 = entityKind2, _b223) {
131718
134124
  defaultNow() {
@@ -131938,7 +134344,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
131938
134344
  init_count3 = __esm2({
131939
134345
  "../drizzle-orm/dist/mysql-core/query-builders/count.js"() {
131940
134346
  init_entity2();
131941
- init_sql3();
134347
+ init_sql4();
131942
134348
  _MySqlCountBuilder = class _MySqlCountBuilder2 extends (_c9 = SQL2, _b237 = entityKind2, _a315 = Symbol.toStringTag, _c9) {
131943
134349
  constructor(params) {
131944
134350
  super(_MySqlCountBuilder2.buildEmbeddedCount(params.source, params.filters).queryChunks);
@@ -132200,7 +134606,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
132200
134606
  init_view_base3 = __esm2({
132201
134607
  "../drizzle-orm/dist/mysql-core/view-base.js"() {
132202
134608
  init_entity2();
132203
- init_sql3();
134609
+ init_sql4();
132204
134610
  MySqlViewBase = class extends (_b240 = View3, _a323 = entityKind2, _b240) {
132205
134611
  };
132206
134612
  __publicField(MySqlViewBase, _a323, "MySqlViewBase");
@@ -132215,7 +134621,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
132215
134621
  init_errors22();
132216
134622
  init_relations2();
132217
134623
  init_expressions2();
132218
- init_sql3();
134624
+ init_sql4();
132219
134625
  init_subquery2();
132220
134626
  init_table8();
132221
134627
  init_utils22();
@@ -132981,7 +135387,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
132981
135387
  init_query_builder3();
132982
135388
  init_query_promise2();
132983
135389
  init_selection_proxy2();
132984
- init_sql3();
135390
+ init_sql4();
132985
135391
  init_subquery2();
132986
135392
  init_table8();
132987
135393
  init_utils22();
@@ -133382,7 +135788,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
133382
135788
  "../drizzle-orm/dist/mysql-core/query-builders/insert.js"() {
133383
135789
  init_entity2();
133384
135790
  init_query_promise2();
133385
- init_sql3();
135791
+ init_sql4();
133386
135792
  init_table8();
133387
135793
  init_utils22();
133388
135794
  init_utils8();
@@ -133662,7 +136068,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
133662
136068
  "../drizzle-orm/dist/mysql-core/db.js"() {
133663
136069
  init_entity2();
133664
136070
  init_selection_proxy2();
133665
- init_sql3();
136071
+ init_sql4();
133666
136072
  init_subquery2();
133667
136073
  init_count3();
133668
136074
  init_query_builders3();
@@ -133891,7 +136297,7 @@ ${withStyle.errorWarning(`We've found duplicated view name across ${source_defau
133891
136297
  init_cache();
133892
136298
  init_entity2();
133893
136299
  init_errors22();
133894
- init_sql3();
136300
+ init_sql4();
133895
136301
  init_db3();
133896
136302
  _a341 = entityKind2;
133897
136303
  MySqlPreparedQuery = class {
@@ -135914,7 +138320,7 @@ AND
135914
138320
  init_date_common3 = __esm2({
135915
138321
  "../drizzle-orm/dist/singlestore-core/columns/date.common.js"() {
135916
138322
  init_entity2();
135917
- init_sql3();
138323
+ init_sql4();
135918
138324
  init_common5();
135919
138325
  SingleStoreDateColumnBaseBuilder = class extends (_b302 = SingleStoreColumnBuilder, _a399 = entityKind2, _b302) {
135920
138326
  defaultNow() {
@@ -135939,7 +138345,7 @@ AND
135939
138345
  init_timestamp3 = __esm2({
135940
138346
  "../drizzle-orm/dist/singlestore-core/columns/timestamp.js"() {
135941
138347
  init_entity2();
135942
- init_sql3();
138348
+ init_sql4();
135943
138349
  init_utils22();
135944
138350
  init_date_common3();
135945
138351
  SingleStoreTimestampBuilder = class extends (_b304 = SingleStoreDateColumnBaseBuilder, _a401 = entityKind2, _b304) {
@@ -136174,7 +138580,7 @@ AND
136174
138580
  init_count4 = __esm2({
136175
138581
  "../drizzle-orm/dist/singlestore-core/query-builders/count.js"() {
136176
138582
  init_entity2();
136177
- init_sql3();
138583
+ init_sql4();
136178
138584
  _SingleStoreCountBuilder = class _SingleStoreCountBuilder2 extends (_c12 = SQL2, _b318 = entityKind2, _a415 = Symbol.toStringTag, _c12) {
136179
138585
  constructor(params) {
136180
138586
  super(_SingleStoreCountBuilder2.buildEmbeddedCount(params.source, params.filters).queryChunks);
@@ -136344,7 +138750,7 @@ AND
136344
138750
  init_utils10 = __esm2({
136345
138751
  "../drizzle-orm/dist/singlestore-core/utils.js"() {
136346
138752
  init_entity2();
136347
- init_sql3();
138753
+ init_sql4();
136348
138754
  init_subquery2();
136349
138755
  init_table8();
136350
138756
  init_indexes4();
@@ -136422,7 +138828,7 @@ AND
136422
138828
  "../drizzle-orm/dist/singlestore-core/query-builders/insert.js"() {
136423
138829
  init_entity2();
136424
138830
  init_query_promise2();
136425
- init_sql3();
138831
+ init_sql4();
136426
138832
  init_table8();
136427
138833
  init_utils22();
136428
138834
  init_utils10();
@@ -136519,7 +138925,7 @@ AND
136519
138925
  init_errors22();
136520
138926
  init_relations2();
136521
138927
  init_expressions2();
136522
- init_sql3();
138928
+ init_sql4();
136523
138929
  init_subquery2();
136524
138930
  init_table8();
136525
138931
  init_utils22();
@@ -137050,7 +139456,7 @@ AND
137050
139456
  init_query_builder3();
137051
139457
  init_query_promise2();
137052
139458
  init_selection_proxy2();
137053
- init_sql3();
139459
+ init_sql4();
137054
139460
  init_subquery2();
137055
139461
  init_table8();
137056
139462
  init_utils22();
@@ -137508,7 +139914,7 @@ AND
137508
139914
  "../drizzle-orm/dist/singlestore-core/db.js"() {
137509
139915
  init_entity2();
137510
139916
  init_selection_proxy2();
137511
- init_sql3();
139917
+ init_sql4();
137512
139918
  init_subquery2();
137513
139919
  init_count4();
137514
139920
  init_query_builders4();
@@ -137622,7 +140028,7 @@ AND
137622
140028
  init_cache();
137623
140029
  init_entity2();
137624
140030
  init_errors22();
137625
- init_sql3();
140031
+ init_sql4();
137626
140032
  init_db4();
137627
140033
  _a434 = entityKind2;
137628
140034
  SingleStorePreparedQuery = class {
@@ -139897,7 +142303,7 @@ function requireUserId(userId) {
139897
142303
  return userId;
139898
142304
  }
139899
142305
  var init_params_util = __esm(() => {
139900
- init_src4();
142306
+ init_src5();
139901
142307
  init_errors();
139902
142308
  });
139903
142309
 
@@ -139950,6 +142356,7 @@ var init_utils11 = __esm(() => {
139950
142356
  init_lti_util();
139951
142357
  init_lti_provisioning();
139952
142358
  init_params_util();
142359
+ init_secrets_util();
139953
142360
  init_timeback_util();
139954
142361
  init_validation_util();
139955
142362
  });
@@ -140137,7 +142544,7 @@ var init_database_controller = __esm(() => {
140137
142544
  throw ApiError.unprocessableEntity("Validation failed", details);
140138
142545
  }
140139
142546
  }
140140
- return ctx.services.database.reset(slug2, ctx.user, body2.schema);
142547
+ return ctx.services.database.reset(slug2, ctx.user, body2);
140141
142548
  });
140142
142549
  database = defineControllerNames("database", {
140143
142550
  reset
@@ -140190,6 +142597,85 @@ var init_deploy_controller = __esm(() => {
140190
142597
  });
140191
142598
  });
140192
142599
 
142600
+ // ../api-core/src/controllers/deployment-state.controller.ts
142601
+ var get, baseline, realignMigration, resolveMigration, history, restorePoints, restore, reportBlocked, deploymentState;
142602
+ var init_deployment_state_controller = __esm(() => {
142603
+ init_schemas_index();
142604
+ init_errors();
142605
+ init_utils11();
142606
+ get = requireDeveloper(async (ctx) => {
142607
+ const slug2 = requireSlug(ctx.params.slug);
142608
+ const include = ctx.url.searchParams.getAll("include").flatMap((value) => value.split(",")).filter(Boolean);
142609
+ const unsupported = include.filter((value) => value !== "schemaSnapshot");
142610
+ if (unsupported.length > 0) {
142611
+ throw ApiError.badRequest(`Unsupported include value(s): ${unsupported.join(", ")}`);
142612
+ }
142613
+ return ctx.services.deploymentState.get(slug2, ctx.user, {
142614
+ includeSchemaSnapshot: include.includes("schemaSnapshot")
142615
+ });
142616
+ });
142617
+ baseline = requireDeveloper(async (ctx) => {
142618
+ const slug2 = requireSlug(ctx.params.slug);
142619
+ const body2 = await parseRequestBody(ctx.request, DeploymentStateBaselineSchema);
142620
+ return ctx.services.deploymentState.baseline(slug2, body2, ctx.user);
142621
+ });
142622
+ realignMigration = requireDeveloper(async (ctx) => {
142623
+ const slug2 = requireSlug(ctx.params.slug);
142624
+ const tag = ctx.params.tag;
142625
+ if (!tag) {
142626
+ throw ApiError.badRequest("Missing migration tag");
142627
+ }
142628
+ const body2 = await parseRequestBody(ctx.request, MigrationRealignSchema);
142629
+ return ctx.services.deploymentState.realignMigration(slug2, tag, body2.checksum, ctx.user);
142630
+ });
142631
+ resolveMigration = requireDeveloper(async (ctx) => {
142632
+ const slug2 = requireSlug(ctx.params.slug);
142633
+ const tag = ctx.params.tag;
142634
+ if (!tag) {
142635
+ throw ApiError.badRequest("Missing migration tag");
142636
+ }
142637
+ const body2 = await parseRequestBody(ctx.request, MigrationResolveSchema);
142638
+ return ctx.services.deploymentState.resolveMigration(slug2, tag, body2, ctx.user);
142639
+ });
142640
+ history = requireDeveloper(async (ctx) => {
142641
+ const slug2 = requireSlug(ctx.params.slug);
142642
+ const limitParam = ctx.url.searchParams.get("limit");
142643
+ let limit;
142644
+ if (limitParam !== null) {
142645
+ limit = Number(limitParam);
142646
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
142647
+ throw ApiError.badRequest("limit must be an integer between 1 and 100");
142648
+ }
142649
+ }
142650
+ return ctx.services.deploymentState.history(slug2, ctx.user, { limit });
142651
+ });
142652
+ restorePoints = requireDeveloper(async (ctx) => {
142653
+ const slug2 = requireSlug(ctx.params.slug);
142654
+ return ctx.services.deploymentState.restorePoints(slug2, ctx.user);
142655
+ });
142656
+ restore = requireDeveloper(async (ctx) => {
142657
+ const slug2 = requireSlug(ctx.params.slug);
142658
+ const body2 = await parseRequestBody(ctx.request, DatabaseRestoreSchema);
142659
+ return ctx.services.deploymentState.restoreToBookmark(slug2, body2, ctx.user);
142660
+ });
142661
+ reportBlocked = requireDeveloper(async (ctx) => {
142662
+ const slug2 = requireSlug(ctx.params.slug);
142663
+ const body2 = await parseRequestBody(ctx.request, DeployBlockedReportSchema);
142664
+ await ctx.services.deploymentState.reportDeployBlocked(slug2, ctx.user, body2);
142665
+ return { recorded: true };
142666
+ });
142667
+ deploymentState = defineControllerNames("deploymentState", {
142668
+ get,
142669
+ baseline,
142670
+ realignMigration,
142671
+ resolveMigration,
142672
+ history,
142673
+ restorePoints,
142674
+ restore,
142675
+ reportBlocked
142676
+ });
142677
+ });
142678
+
140193
142679
  // ../api-core/src/controllers/developer.controller.ts
140194
142680
  var apply, getStatus, developer;
140195
142681
  var init_developer_controller = __esm(() => {
@@ -140656,7 +143142,7 @@ var init_lti_controller = __esm(() => {
140656
143142
  });
140657
143143
 
140658
143144
  // ../api-core/src/controllers/secrets.controller.ts
140659
- var listKeys2, setSecrets, deleteSecret, secrets;
143145
+ var listKeys2, setSecrets, deleteSecret, diff, secrets;
140660
143146
  var init_secrets_controller = __esm(() => {
140661
143147
  init_esm();
140662
143148
  init_schemas_index();
@@ -140702,10 +143188,19 @@ var init_secrets_controller = __esm(() => {
140702
143188
  await ctx.services.secrets.deleteSecret(slug2, key, ctx.user);
140703
143189
  return { success: true };
140704
143190
  });
143191
+ diff = requireDeveloper(async (ctx) => {
143192
+ const slug2 = ctx.params.slug;
143193
+ if (!slug2) {
143194
+ throw ApiError.badRequest("Missing game slug");
143195
+ }
143196
+ const body2 = await parseRequestBody(ctx.request, SecretsDiffRequestSchema);
143197
+ return ctx.services.secrets.diff(slug2, body2.secrets, ctx.user);
143198
+ });
140705
143199
  secrets = defineControllerNames("secrets", {
140706
143200
  listKeys: listKeys2,
140707
143201
  setSecrets,
140708
- deleteSecret
143202
+ deleteSecret,
143203
+ diff
140709
143204
  });
140710
143205
  });
140711
143206
 
@@ -140780,7 +143275,7 @@ var populateStudent, getUser, getUserEnrollments, getUserById, setupIntegration,
140780
143275
  var init_timeback_controller = __esm(() => {
140781
143276
  init_esm();
140782
143277
  init_schemas_index();
140783
- init_src4();
143278
+ init_src5();
140784
143279
  init_timeback3();
140785
143280
  init_errors();
140786
143281
  init_utils11();
@@ -141547,6 +144042,7 @@ var init_controllers = __esm(() => {
141547
144042
  init_dashboard_controller();
141548
144043
  init_database_controller();
141549
144044
  init_deploy_controller();
144045
+ init_deployment_state_controller();
141550
144046
  init_developer_controller();
141551
144047
  init_domain_controller();
141552
144048
  init_game_member_controller();
@@ -142081,6 +144577,23 @@ var init_deploy = __esm(async () => {
142081
144577
  });
142082
144578
  });
142083
144579
 
144580
+ // src/routes/platform/games/deployment-state.ts
144581
+ var gameDeploymentStateRouter;
144582
+ var init_deployment_state = __esm(async () => {
144583
+ init_dist7();
144584
+ init_controllers();
144585
+ await init_api3();
144586
+ gameDeploymentStateRouter = new Hono2;
144587
+ gameDeploymentStateRouter.get("/:slug/deployment-state", handle2(deploymentState.get));
144588
+ gameDeploymentStateRouter.post("/:slug/deployment-state/baseline", handle2(deploymentState.baseline));
144589
+ gameDeploymentStateRouter.post("/:slug/deployment-state/migrations/:tag/realign", handle2(deploymentState.realignMigration));
144590
+ gameDeploymentStateRouter.post("/:slug/deployment-state/migrations/:tag/resolve", handle2(deploymentState.resolveMigration));
144591
+ gameDeploymentStateRouter.get("/:slug/deployments", handle2(deploymentState.history));
144592
+ gameDeploymentStateRouter.post("/:slug/deployments/blocked", handle2(deploymentState.reportBlocked));
144593
+ gameDeploymentStateRouter.get("/:slug/database/restore-points", handle2(deploymentState.restorePoints));
144594
+ gameDeploymentStateRouter.post("/:slug/database/restore", handle2(deploymentState.restore));
144595
+ });
144596
+
142084
144597
  // src/routes/platform/games/domains.ts
142085
144598
  var gameDomainsRouter;
142086
144599
  var init_domains2 = __esm(async () => {
@@ -142126,6 +144639,7 @@ var init_secrets = __esm(async () => {
142126
144639
  gameSecretsRouter = new Hono2;
142127
144640
  gameSecretsRouter.get("/:slug/secrets", handle2(secrets.listKeys));
142128
144641
  gameSecretsRouter.post("/:slug/secrets", handle2(secrets.setSecrets));
144642
+ gameSecretsRouter.post("/:slug/secrets/diff", handle2(secrets.diff));
142129
144643
  gameSecretsRouter.delete("/:slug/secrets/:key", handle2(secrets.deleteSecret));
142130
144644
  });
142131
144645
 
@@ -142328,6 +144842,7 @@ var init_games2 = __esm(async () => {
142328
144842
  await __promiseAll([
142329
144843
  init_crud(),
142330
144844
  init_deploy(),
144845
+ init_deployment_state(),
142331
144846
  init_domains2(),
142332
144847
  init_logs(),
142333
144848
  init_scores(),
@@ -142342,6 +144857,7 @@ var init_games2 = __esm(async () => {
142342
144857
  gamesRouter.route("/", gameVerifyRouter);
142343
144858
  gamesRouter.route("/", gameUploadsRouter);
142344
144859
  gamesRouter.route("/", gameDeployRouter);
144860
+ gamesRouter.route("/", gameDeploymentStateRouter);
142345
144861
  gamesRouter.route("/", gameDomainsRouter);
142346
144862
  gamesRouter.route("/", gameLogsRouter);
142347
144863
  gamesRouter.route("/", gameScoresRouter);