@playcademy/sandbox 0.6.1-beta.4 → 0.6.1-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1289 -390
- package/dist/constants.js +17 -11
- package/dist/server.js +1284 -388
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -203,6 +203,20 @@ var init_auth = __esm(() => {
|
|
|
203
203
|
};
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
+
// ../constants/src/dashboard.ts
|
|
207
|
+
var DASHBOARD_USER_ROLES, DASHBOARD_WORKER_ROUTES, DASHBOARD_WORKER_SUFFIX = "-dash";
|
|
208
|
+
var init_dashboard = __esm(() => {
|
|
209
|
+
DASHBOARD_USER_ROLES = {
|
|
210
|
+
ADMIN: "admin",
|
|
211
|
+
VIEWER: "viewer"
|
|
212
|
+
};
|
|
213
|
+
DASHBOARD_WORKER_ROUTES = {
|
|
214
|
+
verifySession: "/sessions",
|
|
215
|
+
acceptInvite: "/invites/accept",
|
|
216
|
+
acceptReset: "/resets/accept"
|
|
217
|
+
};
|
|
218
|
+
});
|
|
219
|
+
|
|
206
220
|
// ../constants/src/typescript.ts
|
|
207
221
|
var init_typescript = () => {};
|
|
208
222
|
|
|
@@ -244,17 +258,8 @@ var init_platform = __esm(() => {
|
|
|
244
258
|
var PLATFORM_TIMEZONE = "America/New_York";
|
|
245
259
|
|
|
246
260
|
// ../constants/src/timeback.ts
|
|
247
|
-
var
|
|
261
|
+
var TIMEBACK_ORG_SOURCED_ID = "PLAYCADEMY", TIMEBACK_ORG_NAME = "Playcademy Studios", TIMEBACK_ORG_TYPE = "department", TIMEBACK_COURSE_DEFAULTS, TIMEBACK_RESOURCE_DEFAULTS, TIMEBACK_COMPONENT_DEFAULTS, TIMEBACK_COMPONENT_RESOURCE_DEFAULTS, TIMEBACK_GAME_METRIC_DECIMAL_PLACES, TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE;
|
|
248
262
|
var init_timeback2 = __esm(() => {
|
|
249
|
-
TIMEBACK_ROUTES = {
|
|
250
|
-
END_ACTIVITY: "/integrations/timeback/end-activity",
|
|
251
|
-
GET_XP: "/integrations/timeback/xp",
|
|
252
|
-
GET_MASTERY: "/integrations/timeback/mastery",
|
|
253
|
-
GET_HIGHEST_GRADE_MASTERED: "/integrations/timeback/highest-grade-mastered",
|
|
254
|
-
HEARTBEAT: "/integrations/timeback/heartbeat",
|
|
255
|
-
ADVANCE_COURSE: "/integrations/timeback/advance-course",
|
|
256
|
-
UNENROLL_COURSE: "/integrations/timeback/unenroll-course"
|
|
257
|
-
};
|
|
258
263
|
TIMEBACK_COURSE_DEFAULTS = {
|
|
259
264
|
gradingScheme: "STANDARD",
|
|
260
265
|
level: {
|
|
@@ -305,7 +310,7 @@ var init_timeback2 = __esm(() => {
|
|
|
305
310
|
});
|
|
306
311
|
|
|
307
312
|
// ../constants/src/cloudflare.ts
|
|
308
|
-
var WORKER_NAMING, 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";
|
|
309
314
|
var init_cloudflare = __esm(() => {
|
|
310
315
|
WORKER_NAMING = {
|
|
311
316
|
STAGING_PREFIX: "staging-",
|
|
@@ -317,6 +322,7 @@ var init_cloudflare = __esm(() => {
|
|
|
317
322
|
// ../constants/src/index.ts
|
|
318
323
|
var init_src = __esm(() => {
|
|
319
324
|
init_auth();
|
|
325
|
+
init_dashboard();
|
|
320
326
|
init_typescript();
|
|
321
327
|
init_domains();
|
|
322
328
|
init_env_vars();
|
|
@@ -1056,8 +1062,7 @@ async function waitForPort(port, timeoutMs = 5000) {
|
|
|
1056
1062
|
const start2 = Date.now();
|
|
1057
1063
|
while (await isPortInUse(port)) {
|
|
1058
1064
|
if (Date.now() - start2 > timeoutMs) {
|
|
1059
|
-
throw new Error(`Port ${port} is already in use
|
|
1060
|
-
` + `Stop the other server or specify a different port with --port <number>.`);
|
|
1065
|
+
throw new Error(`Port ${port} is already in use`);
|
|
1061
1066
|
}
|
|
1062
1067
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1063
1068
|
}
|
|
@@ -1066,8 +1071,7 @@ async function requirePortAvailable(port, timeoutMs = 100) {
|
|
|
1066
1071
|
const start2 = Date.now();
|
|
1067
1072
|
while (await isPortInUse(port)) {
|
|
1068
1073
|
if (Date.now() - start2 > timeoutMs) {
|
|
1069
|
-
throw new Error(`Port ${port} is already in use
|
|
1070
|
-
` + `Stop the other server or specify a different port with --port <number>.`);
|
|
1074
|
+
throw new Error(`Port ${port} is already in use`);
|
|
1071
1075
|
}
|
|
1072
1076
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
1073
1077
|
}
|
|
@@ -1079,7 +1083,7 @@ var package_default;
|
|
|
1079
1083
|
var init_package = __esm(() => {
|
|
1080
1084
|
package_default = {
|
|
1081
1085
|
name: "@playcademy/sandbox",
|
|
1082
|
-
version: "0.6.1-beta.
|
|
1086
|
+
version: "0.6.1-beta.5",
|
|
1083
1087
|
description: "Local development server for Playcademy game development",
|
|
1084
1088
|
type: "module",
|
|
1085
1089
|
exports: {
|
|
@@ -1148,7 +1152,7 @@ var init_package = __esm(() => {
|
|
|
1148
1152
|
});
|
|
1149
1153
|
|
|
1150
1154
|
// ../api-core/src/errors/domain.error.ts
|
|
1151
|
-
var DomainError, BadRequestError, AccessDeniedError, NotFoundError, ConflictError, AlreadyExistsError, ValidationError, InternalError, ServiceUnavailableError, TimeoutError;
|
|
1155
|
+
var DomainError, BadRequestError, UnauthorizedError, AccessDeniedError, NotFoundError, ConflictError, AlreadyExistsError, ValidationError, RateLimitError, InternalError, ServiceUnavailableError, TimeoutError;
|
|
1152
1156
|
var init_domain_error = __esm(() => {
|
|
1153
1157
|
DomainError = class DomainError extends Error {
|
|
1154
1158
|
code;
|
|
@@ -1166,6 +1170,12 @@ var init_domain_error = __esm(() => {
|
|
|
1166
1170
|
this.name = "BadRequestError";
|
|
1167
1171
|
}
|
|
1168
1172
|
};
|
|
1173
|
+
UnauthorizedError = class UnauthorizedError extends DomainError {
|
|
1174
|
+
constructor(message = "Unauthorized", details) {
|
|
1175
|
+
super("UNAUTHORIZED", message, details);
|
|
1176
|
+
this.name = "UnauthorizedError";
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1169
1179
|
AccessDeniedError = class AccessDeniedError extends DomainError {
|
|
1170
1180
|
constructor(message = "Access denied", details) {
|
|
1171
1181
|
super("ACCESS_DENIED", message, details);
|
|
@@ -1198,6 +1208,12 @@ var init_domain_error = __esm(() => {
|
|
|
1198
1208
|
this.name = "ValidationError";
|
|
1199
1209
|
}
|
|
1200
1210
|
};
|
|
1211
|
+
RateLimitError = class RateLimitError extends DomainError {
|
|
1212
|
+
constructor(message = "Rate limit exceeded", details) {
|
|
1213
|
+
super("RATE_LIMITED", message, details);
|
|
1214
|
+
this.name = "RateLimitError";
|
|
1215
|
+
}
|
|
1216
|
+
};
|
|
1201
1217
|
InternalError = class InternalError extends DomainError {
|
|
1202
1218
|
constructor(message = "Internal error", details) {
|
|
1203
1219
|
super("INTERNAL", message, details);
|
|
@@ -1556,12 +1572,24 @@ data: ${JSON.stringify(data)}
|
|
|
1556
1572
|
return sseEncoder.encode(payload);
|
|
1557
1573
|
}
|
|
1558
1574
|
function createContextBuilder(options) {
|
|
1559
|
-
const {
|
|
1575
|
+
const {
|
|
1576
|
+
db,
|
|
1577
|
+
config: config2,
|
|
1578
|
+
providers,
|
|
1579
|
+
services,
|
|
1580
|
+
cloudflare: cloudflare2,
|
|
1581
|
+
timeback: timeback2,
|
|
1582
|
+
resolveUser,
|
|
1583
|
+
resolveGameId,
|
|
1584
|
+
resolveApiKey
|
|
1585
|
+
} = options;
|
|
1560
1586
|
return async (c) => {
|
|
1561
1587
|
const user = resolveUser ? await resolveUser(c) : null;
|
|
1562
1588
|
const gameId = resolveGameId ? await resolveGameId(c) : undefined;
|
|
1589
|
+
const apiKey = resolveApiKey ? await resolveApiKey(c) : undefined;
|
|
1563
1590
|
return {
|
|
1564
1591
|
user,
|
|
1592
|
+
apiKey,
|
|
1565
1593
|
gameId,
|
|
1566
1594
|
params: c.req.param(),
|
|
1567
1595
|
url: new URL(c.req.url),
|
|
@@ -11180,7 +11208,7 @@ var init_table4 = __esm(() => {
|
|
|
11180
11208
|
});
|
|
11181
11209
|
|
|
11182
11210
|
// ../data/src/domains/game/table.ts
|
|
11183
|
-
var gamePlatformEnum, gameTypeEnum, gameVisibilityEnum, games, gameMemberRoleEnum, gameMembers, gameMembersRelations, deploymentProviderEnum, deployJobStatusEnum, gameDeployments, gameDeployJobs, customHostnameStatusEnum, customHostnameSslStatusEnum, customHostnameEnvironmentEnum, gameCustomHostnames;
|
|
11211
|
+
var gamePlatformEnum, gameTypeEnum, gameVisibilityEnum, games, gameMemberRoleEnum, gameMembers, gameMembersRelations, gameDashboardUserRoleEnum, gameDashboardUsers, gameDashboardUsersRelations, deploymentProviderEnum, deploymentTargetEnum, deployJobStatusEnum, gameDeployments, gameDeployJobs, customHostnameStatusEnum, customHostnameSslStatusEnum, customHostnameEnvironmentEnum, gameCustomHostnames;
|
|
11184
11212
|
var init_table5 = __esm(() => {
|
|
11185
11213
|
init_drizzle_orm();
|
|
11186
11214
|
init_pg_core();
|
|
@@ -11224,7 +11252,37 @@ var init_table5 = __esm(() => {
|
|
|
11224
11252
|
references: [users.id]
|
|
11225
11253
|
})
|
|
11226
11254
|
}));
|
|
11255
|
+
gameDashboardUserRoleEnum = pgEnum("game_dashboard_user_role", [
|
|
11256
|
+
DASHBOARD_USER_ROLES.ADMIN,
|
|
11257
|
+
DASHBOARD_USER_ROLES.VIEWER
|
|
11258
|
+
]);
|
|
11259
|
+
gameDashboardUsers = pgTable("game_dashboard_users", {
|
|
11260
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
11261
|
+
gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
|
|
11262
|
+
email: text("email").notNull(),
|
|
11263
|
+
displayName: text("display_name"),
|
|
11264
|
+
role: gameDashboardUserRoleEnum("role").notNull().default(DASHBOARD_USER_ROLES.VIEWER),
|
|
11265
|
+
passwordHash: text("password_hash"),
|
|
11266
|
+
inviteTokenHash: text("invite_token_hash"),
|
|
11267
|
+
inviteExpiresAt: timestamp("invite_expires_at", { withTimezone: true }),
|
|
11268
|
+
resetTokenHash: text("reset_token_hash"),
|
|
11269
|
+
resetExpiresAt: timestamp("reset_expires_at", { withTimezone: true }),
|
|
11270
|
+
failedLoginAttempts: integer("failed_login_attempts").notNull().default(0),
|
|
11271
|
+
lastFailedLoginAt: timestamp("last_failed_login_at", { withTimezone: true }),
|
|
11272
|
+
platformUserId: text("platform_user_id").references(() => users.id, {
|
|
11273
|
+
onDelete: "set null"
|
|
11274
|
+
}),
|
|
11275
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
11276
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
11277
|
+
}, (table3) => [uniqueIndex("game_dashboard_users_game_email_idx").on(table3.gameId, table3.email)]);
|
|
11278
|
+
gameDashboardUsersRelations = relations(gameDashboardUsers, ({ one }) => ({
|
|
11279
|
+
game: one(games, {
|
|
11280
|
+
fields: [gameDashboardUsers.gameId],
|
|
11281
|
+
references: [games.id]
|
|
11282
|
+
})
|
|
11283
|
+
}));
|
|
11227
11284
|
deploymentProviderEnum = pgEnum("deployment_provider", ["cloudflare", "aws"]);
|
|
11285
|
+
deploymentTargetEnum = pgEnum("deployment_target", ["game", "dashboard"]);
|
|
11228
11286
|
deployJobStatusEnum = pgEnum("deploy_job_status", [
|
|
11229
11287
|
"pending",
|
|
11230
11288
|
"running",
|
|
@@ -11236,6 +11294,7 @@ var init_table5 = __esm(() => {
|
|
|
11236
11294
|
gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
|
|
11237
11295
|
deploymentId: text("deployment_id").notNull(),
|
|
11238
11296
|
provider: deploymentProviderEnum("provider").notNull(),
|
|
11297
|
+
target: deploymentTargetEnum("target").notNull().default("game"),
|
|
11239
11298
|
url: text("url").notNull(),
|
|
11240
11299
|
codeHash: text("code_hash"),
|
|
11241
11300
|
isActive: boolean("is_active").notNull().default(false),
|
|
@@ -11423,8 +11482,12 @@ __export(exports_tables_index, {
|
|
|
11423
11482
|
gameMemberRoleEnum: () => gameMemberRoleEnum,
|
|
11424
11483
|
gameDeployments: () => gameDeployments,
|
|
11425
11484
|
gameDeployJobs: () => gameDeployJobs,
|
|
11485
|
+
gameDashboardUsersRelations: () => gameDashboardUsersRelations,
|
|
11486
|
+
gameDashboardUsers: () => gameDashboardUsers,
|
|
11487
|
+
gameDashboardUserRoleEnum: () => gameDashboardUserRoleEnum,
|
|
11426
11488
|
gameCustomHostnames: () => gameCustomHostnames,
|
|
11427
11489
|
developerStatusEnum: () => developerStatusEnum,
|
|
11490
|
+
deploymentTargetEnum: () => deploymentTargetEnum,
|
|
11428
11491
|
deploymentProviderEnum: () => deploymentProviderEnum,
|
|
11429
11492
|
deployJobStatusEnum: () => deployJobStatusEnum,
|
|
11430
11493
|
customHostnameStatusEnum: () => customHostnameStatusEnum,
|
|
@@ -12928,6 +12991,10 @@ function errorMessage(err2) {
|
|
|
12928
12991
|
function errorType(err2) {
|
|
12929
12992
|
return err2 instanceof Error ? err2.constructor.name : typeof err2;
|
|
12930
12993
|
}
|
|
12994
|
+
function isUniqueViolation(err2) {
|
|
12995
|
+
return typeof err2 === "object" && err2 !== null && err2.code === PG_UNIQUE_VIOLATION;
|
|
12996
|
+
}
|
|
12997
|
+
var PG_UNIQUE_VIOLATION = "23505";
|
|
12931
12998
|
|
|
12932
12999
|
// ../otel/src/spans.ts
|
|
12933
13000
|
function truncate(value) {
|
|
@@ -13006,6 +13073,310 @@ var init_spans = __esm(() => {
|
|
|
13006
13073
|
ROOT_SPAN_KEY = import_api2.createContextKey("playcademy.root_span");
|
|
13007
13074
|
});
|
|
13008
13075
|
|
|
13076
|
+
// ../utils/src/random.ts
|
|
13077
|
+
async function generateSecureRandomString(length) {
|
|
13078
|
+
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
|
|
13079
|
+
const randomValues = new Uint8Array(length);
|
|
13080
|
+
crypto.getRandomValues(randomValues);
|
|
13081
|
+
return [...randomValues].map((byte) => charset[byte % charset.length]).join("");
|
|
13082
|
+
}
|
|
13083
|
+
|
|
13084
|
+
// ../api-core/src/utils/hash.util.ts
|
|
13085
|
+
async function sha256Hex(input) {
|
|
13086
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
|
|
13087
|
+
return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
13088
|
+
}
|
|
13089
|
+
|
|
13090
|
+
// ../api-core/src/utils/dashboard.util.ts
|
|
13091
|
+
function dashboardCredentialScope(slug) {
|
|
13092
|
+
return `${CREDENTIAL_SCOPE_PREFIX}${slug}`;
|
|
13093
|
+
}
|
|
13094
|
+
function dashboardCredentialSlugs(permissions) {
|
|
13095
|
+
return (permissions?.[DASHBOARD_PERMISSION_NAMESPACE] ?? []).filter((scope) => scope.startsWith(CREDENTIAL_SCOPE_PREFIX)).map((scope) => scope.slice(CREDENTIAL_SCOPE_PREFIX.length)).filter((slug) => slug.length > 0);
|
|
13096
|
+
}
|
|
13097
|
+
function isAllowedDashboardWorkerRequest(method, pathname, permissions) {
|
|
13098
|
+
const path = pathname.replace(/\/+$/, "");
|
|
13099
|
+
return dashboardCredentialSlugs(permissions).some((slug) => {
|
|
13100
|
+
if (method === "GET") {
|
|
13101
|
+
return path === `/api/games/${slug}`;
|
|
13102
|
+
}
|
|
13103
|
+
if (method === "POST") {
|
|
13104
|
+
return Object.values(DASHBOARD_WORKER_ROUTES).some((subpath) => path === `/api/games/${slug}/dashboard${subpath}`);
|
|
13105
|
+
}
|
|
13106
|
+
return false;
|
|
13107
|
+
});
|
|
13108
|
+
}
|
|
13109
|
+
function hashDashboardToken(token) {
|
|
13110
|
+
return sha256Hex(token);
|
|
13111
|
+
}
|
|
13112
|
+
function loginBackoffMs(failedAttempts) {
|
|
13113
|
+
if (failedAttempts < LOGIN_BACKOFF_THRESHOLD) {
|
|
13114
|
+
return 0;
|
|
13115
|
+
}
|
|
13116
|
+
return Math.min(LOGIN_BACKOFF_CAP_MS, LOGIN_BACKOFF_BASE_MS * 2 ** (failedAttempts - LOGIN_BACKOFF_THRESHOLD));
|
|
13117
|
+
}
|
|
13118
|
+
var DASHBOARD_PERMISSION_NAMESPACE = "dashboard", DASHBOARD_WORKER_KEY_RESTRICTED = "The dashboard worker key is restricted to dashboard runtime endpoints", CREDENTIAL_SCOPE_PREFIX = "credentials:", LOGIN_BACKOFF_THRESHOLD = 5, LOGIN_BACKOFF_BASE_MS = 1000, LOGIN_BACKOFF_CAP_MS;
|
|
13119
|
+
var init_dashboard_util = __esm(() => {
|
|
13120
|
+
init_src();
|
|
13121
|
+
LOGIN_BACKOFF_CAP_MS = 5 * 60 * 1000;
|
|
13122
|
+
});
|
|
13123
|
+
|
|
13124
|
+
// ../api-core/src/services/dashboard.service.ts
|
|
13125
|
+
function alreadyExists(gameId) {
|
|
13126
|
+
return new AlreadyExistsError("A dashboard user with this email already exists", { gameId });
|
|
13127
|
+
}
|
|
13128
|
+
var DashboardService;
|
|
13129
|
+
var init_dashboard_service = __esm(() => {
|
|
13130
|
+
init_drizzle_orm();
|
|
13131
|
+
init_tables_index();
|
|
13132
|
+
init_spans();
|
|
13133
|
+
init_errors();
|
|
13134
|
+
init_dashboard_util();
|
|
13135
|
+
DashboardService = class DashboardService {
|
|
13136
|
+
deps;
|
|
13137
|
+
static INVITE_TOKEN_LENGTH = 48;
|
|
13138
|
+
static INVITE_TTL_MS = 72 * 60 * 60 * 1000;
|
|
13139
|
+
static RESET_TTL_MS = 24 * 60 * 60 * 1000;
|
|
13140
|
+
constructor(deps) {
|
|
13141
|
+
this.deps = deps;
|
|
13142
|
+
}
|
|
13143
|
+
async listUsers(slug, user) {
|
|
13144
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13145
|
+
const rows = await this.deps.db.select({
|
|
13146
|
+
id: gameDashboardUsers.id,
|
|
13147
|
+
gameId: gameDashboardUsers.gameId,
|
|
13148
|
+
email: gameDashboardUsers.email,
|
|
13149
|
+
displayName: gameDashboardUsers.displayName,
|
|
13150
|
+
role: gameDashboardUsers.role,
|
|
13151
|
+
platformUserId: gameDashboardUsers.platformUserId,
|
|
13152
|
+
createdAt: gameDashboardUsers.createdAt,
|
|
13153
|
+
updatedAt: gameDashboardUsers.updatedAt,
|
|
13154
|
+
pending: sql`(${gameDashboardUsers.passwordHash} IS NULL)`
|
|
13155
|
+
}).from(gameDashboardUsers).where(eq(gameDashboardUsers.gameId, game2.id)).orderBy(asc(gameDashboardUsers.createdAt));
|
|
13156
|
+
setAttributes({
|
|
13157
|
+
"app.dashboard.operation": "list_users",
|
|
13158
|
+
"app.dashboard.result_count": rows.length
|
|
13159
|
+
});
|
|
13160
|
+
return rows;
|
|
13161
|
+
}
|
|
13162
|
+
async addUser(slug, user, input) {
|
|
13163
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13164
|
+
const email = input.email.toLowerCase();
|
|
13165
|
+
setAttributes({
|
|
13166
|
+
"app.dashboard.operation": "add_user",
|
|
13167
|
+
"app.dashboard.user_role": input.role
|
|
13168
|
+
});
|
|
13169
|
+
const existing = await this.findByEmail(game2.id, email);
|
|
13170
|
+
if (existing) {
|
|
13171
|
+
throw alreadyExists(game2.id);
|
|
13172
|
+
}
|
|
13173
|
+
const inviteToken = await generateSecureRandomString(DashboardService.INVITE_TOKEN_LENGTH);
|
|
13174
|
+
let created;
|
|
13175
|
+
try {
|
|
13176
|
+
[created] = await this.deps.db.insert(gameDashboardUsers).values({
|
|
13177
|
+
gameId: game2.id,
|
|
13178
|
+
email,
|
|
13179
|
+
displayName: input.displayName,
|
|
13180
|
+
role: input.role,
|
|
13181
|
+
inviteTokenHash: await hashDashboardToken(inviteToken),
|
|
13182
|
+
inviteExpiresAt: new Date(Date.now() + DashboardService.INVITE_TTL_MS),
|
|
13183
|
+
platformUserId: email === user.email.toLowerCase() ? user.id : undefined
|
|
13184
|
+
}).returning();
|
|
13185
|
+
} catch (error) {
|
|
13186
|
+
if (isUniqueViolation(error)) {
|
|
13187
|
+
throw alreadyExists(game2.id);
|
|
13188
|
+
}
|
|
13189
|
+
throw error;
|
|
13190
|
+
}
|
|
13191
|
+
if (!created) {
|
|
13192
|
+
throw new ValidationError("Failed to create dashboard user");
|
|
13193
|
+
}
|
|
13194
|
+
return { user: DashboardService.toSummary(created), token: inviteToken, kind: "invite" };
|
|
13195
|
+
}
|
|
13196
|
+
async removeUser(slug, user, dashboardUserId) {
|
|
13197
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13198
|
+
setAttributes({
|
|
13199
|
+
"app.dashboard.operation": "remove_user",
|
|
13200
|
+
"app.dashboard.user_id": dashboardUserId
|
|
13201
|
+
});
|
|
13202
|
+
const [deleted] = await this.deps.db.delete(gameDashboardUsers).where(and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.id, dashboardUserId))).returning({ id: gameDashboardUsers.id });
|
|
13203
|
+
if (!deleted) {
|
|
13204
|
+
throw new NotFoundError("Dashboard user", dashboardUserId);
|
|
13205
|
+
}
|
|
13206
|
+
}
|
|
13207
|
+
async verifyLogin(slug, input) {
|
|
13208
|
+
const game2 = await this.getGameForRuntime(slug);
|
|
13209
|
+
setAttributes({ "app.dashboard.operation": "verify_login" });
|
|
13210
|
+
const dashboardUser = await this.findByEmail(game2.id, input.email.toLowerCase());
|
|
13211
|
+
if (!dashboardUser?.passwordHash) {
|
|
13212
|
+
throw new UnauthorizedError("Invalid credentials");
|
|
13213
|
+
}
|
|
13214
|
+
if (dashboardUser.lastFailedLoginAt) {
|
|
13215
|
+
const retryAt = dashboardUser.lastFailedLoginAt.getTime() + loginBackoffMs(dashboardUser.failedLoginAttempts);
|
|
13216
|
+
if (retryAt > Date.now()) {
|
|
13217
|
+
addEvent("dashboard.login_throttled", {
|
|
13218
|
+
"app.dashboard.failed_attempts": dashboardUser.failedLoginAttempts
|
|
13219
|
+
});
|
|
13220
|
+
throw new RateLimitError("Too many failed attempts — try again shortly", {
|
|
13221
|
+
retryAfterSeconds: Math.ceil((retryAt - Date.now()) / 1000)
|
|
13222
|
+
});
|
|
13223
|
+
}
|
|
13224
|
+
}
|
|
13225
|
+
const valid = await this.deps.verifyPassword({
|
|
13226
|
+
hash: dashboardUser.passwordHash,
|
|
13227
|
+
password: input.password
|
|
13228
|
+
});
|
|
13229
|
+
if (!valid) {
|
|
13230
|
+
await this.deps.db.update(gameDashboardUsers).set({
|
|
13231
|
+
failedLoginAttempts: sql`${gameDashboardUsers.failedLoginAttempts} + 1`,
|
|
13232
|
+
lastFailedLoginAt: new Date
|
|
13233
|
+
}).where(eq(gameDashboardUsers.id, dashboardUser.id));
|
|
13234
|
+
throw new UnauthorizedError("Invalid credentials");
|
|
13235
|
+
}
|
|
13236
|
+
if (dashboardUser.failedLoginAttempts > 0) {
|
|
13237
|
+
await this.deps.db.update(gameDashboardUsers).set({ failedLoginAttempts: 0, lastFailedLoginAt: null }).where(eq(gameDashboardUsers.id, dashboardUser.id));
|
|
13238
|
+
}
|
|
13239
|
+
return DashboardService.toSummary(dashboardUser);
|
|
13240
|
+
}
|
|
13241
|
+
async acceptInvite(slug, input) {
|
|
13242
|
+
const game2 = await this.getGameForRuntime(slug);
|
|
13243
|
+
setAttributes({ "app.dashboard.operation": "accept_invite" });
|
|
13244
|
+
const tokenHash = await hashDashboardToken(input.token);
|
|
13245
|
+
const invited = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13246
|
+
where: and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.inviteTokenHash, tokenHash))
|
|
13247
|
+
});
|
|
13248
|
+
if (!invited) {
|
|
13249
|
+
throw new UnauthorizedError("Invalid or already-used invite token");
|
|
13250
|
+
}
|
|
13251
|
+
if (invited.inviteExpiresAt && invited.inviteExpiresAt.getTime() < Date.now()) {
|
|
13252
|
+
throw new UnauthorizedError("This invite has expired — ask for a new one");
|
|
13253
|
+
}
|
|
13254
|
+
const passwordHash = await this.deps.hashPassword(input.password);
|
|
13255
|
+
const [updated] = await this.deps.db.update(gameDashboardUsers).set({
|
|
13256
|
+
passwordHash,
|
|
13257
|
+
inviteTokenHash: null,
|
|
13258
|
+
inviteExpiresAt: null,
|
|
13259
|
+
updatedAt: new Date
|
|
13260
|
+
}).where(and(eq(gameDashboardUsers.id, invited.id), eq(gameDashboardUsers.inviteTokenHash, tokenHash), isNull(gameDashboardUsers.passwordHash))).returning();
|
|
13261
|
+
if (!updated) {
|
|
13262
|
+
throw new UnauthorizedError("Invalid or already-used invite token");
|
|
13263
|
+
}
|
|
13264
|
+
return DashboardService.toSummary(updated);
|
|
13265
|
+
}
|
|
13266
|
+
async acceptReset(slug, input) {
|
|
13267
|
+
const game2 = await this.getGameForRuntime(slug);
|
|
13268
|
+
setAttributes({ "app.dashboard.operation": "accept_reset" });
|
|
13269
|
+
const tokenHash = await hashDashboardToken(input.token);
|
|
13270
|
+
const found = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13271
|
+
where: and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.resetTokenHash, tokenHash))
|
|
13272
|
+
});
|
|
13273
|
+
if (!found) {
|
|
13274
|
+
throw new UnauthorizedError("Invalid or already-used reset token");
|
|
13275
|
+
}
|
|
13276
|
+
if (found.resetExpiresAt && found.resetExpiresAt.getTime() < Date.now()) {
|
|
13277
|
+
throw new UnauthorizedError("This reset link has expired — ask for a new one");
|
|
13278
|
+
}
|
|
13279
|
+
const passwordHash = await this.deps.hashPassword(input.password);
|
|
13280
|
+
const [updated] = await this.deps.db.update(gameDashboardUsers).set({
|
|
13281
|
+
passwordHash,
|
|
13282
|
+
resetTokenHash: null,
|
|
13283
|
+
resetExpiresAt: null,
|
|
13284
|
+
inviteTokenHash: null,
|
|
13285
|
+
inviteExpiresAt: null,
|
|
13286
|
+
failedLoginAttempts: 0,
|
|
13287
|
+
lastFailedLoginAt: null,
|
|
13288
|
+
updatedAt: new Date
|
|
13289
|
+
}).where(and(eq(gameDashboardUsers.id, found.id), eq(gameDashboardUsers.resetTokenHash, tokenHash))).returning();
|
|
13290
|
+
if (!updated) {
|
|
13291
|
+
throw new UnauthorizedError("Invalid or already-used reset token");
|
|
13292
|
+
}
|
|
13293
|
+
return DashboardService.toSummary(updated);
|
|
13294
|
+
}
|
|
13295
|
+
async issueRecoveryLink(slug, user, dashboardUserId) {
|
|
13296
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13297
|
+
const existing = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13298
|
+
where: and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.id, dashboardUserId))
|
|
13299
|
+
});
|
|
13300
|
+
if (!existing) {
|
|
13301
|
+
throw new NotFoundError("Dashboard user", dashboardUserId);
|
|
13302
|
+
}
|
|
13303
|
+
const kind = existing.passwordHash ? "reset" : "invite";
|
|
13304
|
+
setAttributes({
|
|
13305
|
+
"app.dashboard.operation": "issue_recovery_link",
|
|
13306
|
+
"app.dashboard.recovery_kind": kind
|
|
13307
|
+
});
|
|
13308
|
+
const token = await generateSecureRandomString(DashboardService.INVITE_TOKEN_LENGTH);
|
|
13309
|
+
const tokenHash = await hashDashboardToken(token);
|
|
13310
|
+
const fields = kind === "invite" ? {
|
|
13311
|
+
inviteTokenHash: tokenHash,
|
|
13312
|
+
inviteExpiresAt: new Date(Date.now() + DashboardService.INVITE_TTL_MS)
|
|
13313
|
+
} : {
|
|
13314
|
+
resetTokenHash: tokenHash,
|
|
13315
|
+
resetExpiresAt: new Date(Date.now() + DashboardService.RESET_TTL_MS)
|
|
13316
|
+
};
|
|
13317
|
+
const [updated] = await this.deps.db.update(gameDashboardUsers).set({ ...fields, updatedAt: new Date }).where(eq(gameDashboardUsers.id, existing.id)).returning();
|
|
13318
|
+
if (!updated) {
|
|
13319
|
+
throw new NotFoundError("Dashboard user", dashboardUserId);
|
|
13320
|
+
}
|
|
13321
|
+
return { user: DashboardService.toSummary(updated), token, kind };
|
|
13322
|
+
}
|
|
13323
|
+
async getGameForRuntime(slug) {
|
|
13324
|
+
const game2 = await this.deps.db.query.games.findFirst({
|
|
13325
|
+
where: eq(games.slug, slug),
|
|
13326
|
+
columns: { id: true }
|
|
13327
|
+
});
|
|
13328
|
+
if (!game2) {
|
|
13329
|
+
throw new NotFoundError("Game", slug);
|
|
13330
|
+
}
|
|
13331
|
+
return game2;
|
|
13332
|
+
}
|
|
13333
|
+
async findByEmail(gameId, email) {
|
|
13334
|
+
const row = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13335
|
+
where: and(eq(gameDashboardUsers.gameId, gameId), eq(gameDashboardUsers.email, email))
|
|
13336
|
+
});
|
|
13337
|
+
return row ?? null;
|
|
13338
|
+
}
|
|
13339
|
+
static toSummary(row) {
|
|
13340
|
+
return {
|
|
13341
|
+
id: row.id,
|
|
13342
|
+
gameId: row.gameId,
|
|
13343
|
+
email: row.email,
|
|
13344
|
+
displayName: row.displayName,
|
|
13345
|
+
role: row.role,
|
|
13346
|
+
platformUserId: row.platformUserId,
|
|
13347
|
+
createdAt: row.createdAt,
|
|
13348
|
+
updatedAt: row.updatedAt,
|
|
13349
|
+
pending: !row.passwordHash
|
|
13350
|
+
};
|
|
13351
|
+
}
|
|
13352
|
+
};
|
|
13353
|
+
});
|
|
13354
|
+
|
|
13355
|
+
// ../data/src/domains/game/helpers.ts
|
|
13356
|
+
function activeDeploymentWhere(gameId, target = "game") {
|
|
13357
|
+
return and(eq(gameDeployments.gameId, gameId), eq(gameDeployments.target, target), eq(gameDeployments.isActive, true));
|
|
13358
|
+
}
|
|
13359
|
+
var init_helpers = __esm(() => {
|
|
13360
|
+
init_drizzle_orm();
|
|
13361
|
+
init_table5();
|
|
13362
|
+
});
|
|
13363
|
+
|
|
13364
|
+
// ../data/src/domains/timeback/helpers.ts
|
|
13365
|
+
function isActiveGameTimebackIntegrationStatus(statusColumn = gameTimebackIntegrations.status) {
|
|
13366
|
+
return sql`${statusColumn} IS DISTINCT FROM ${DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS}`;
|
|
13367
|
+
}
|
|
13368
|
+
var ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS = "active", DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS = "deactivated";
|
|
13369
|
+
var init_helpers2 = __esm(() => {
|
|
13370
|
+
init_drizzle_orm();
|
|
13371
|
+
init_table7();
|
|
13372
|
+
});
|
|
13373
|
+
|
|
13374
|
+
// ../data/src/helpers.index.ts
|
|
13375
|
+
var init_helpers_index = __esm(() => {
|
|
13376
|
+
init_helpers();
|
|
13377
|
+
init_helpers2();
|
|
13378
|
+
});
|
|
13379
|
+
|
|
13009
13380
|
// ../../node_modules/.bun/process-nextick-args@2.0.1/node_modules/process-nextick-args/index.js
|
|
13010
13381
|
var require_process_nextick_args = __commonJS((exports, module2) => {
|
|
13011
13382
|
if (typeof process === "undefined" || !process.version || process.version.indexOf("v0.") === 0 || process.version.indexOf("v1.") === 0 && process.version.indexOf("v1.8.") !== 0) {
|
|
@@ -22086,8 +22457,8 @@ var require_lib3 = __commonJS((exports, module2) => {
|
|
|
22086
22457
|
});
|
|
22087
22458
|
|
|
22088
22459
|
// ../utils/src/zip.ts
|
|
22089
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
22090
|
-
import { join as join2 } from "path";
|
|
22460
|
+
import { mkdir, readdir, readFile, writeFile } from "fs/promises";
|
|
22461
|
+
import { join as join2, relative, sep } from "path";
|
|
22091
22462
|
async function extractZipToDirectory(zipBuffer, targetDir) {
|
|
22092
22463
|
try {
|
|
22093
22464
|
const zip = await import_jszip.default.loadAsync(zipBuffer);
|
|
@@ -22113,9 +22484,10 @@ async function extractZipToDirectory(zipBuffer, targetDir) {
|
|
|
22113
22484
|
fileCount: Object.keys(zip.files).length
|
|
22114
22485
|
});
|
|
22115
22486
|
} catch (error) {
|
|
22116
|
-
const errorMessage2 = error instanceof Error ? error.message : String(error);
|
|
22117
22487
|
log.error("[utils/zip] Failed to extract ZIP", { targetDir, error });
|
|
22118
|
-
throw new Error(`Failed to extract ZIP to ${targetDir}: ${
|
|
22488
|
+
throw new Error(`Failed to extract ZIP to ${targetDir}: ${errorMessage(error)}`, {
|
|
22489
|
+
cause: error
|
|
22490
|
+
});
|
|
22119
22491
|
}
|
|
22120
22492
|
}
|
|
22121
22493
|
var import_jszip;
|
|
@@ -22385,6 +22757,7 @@ class DeployJobService {
|
|
|
22385
22757
|
jobId,
|
|
22386
22758
|
leaseId,
|
|
22387
22759
|
leaseLost,
|
|
22760
|
+
target,
|
|
22388
22761
|
game: game2,
|
|
22389
22762
|
user,
|
|
22390
22763
|
error
|
|
@@ -22414,9 +22787,12 @@ class DeployJobService {
|
|
|
22414
22787
|
}
|
|
22415
22788
|
}
|
|
22416
22789
|
if (!effectiveLeaseLost) {
|
|
22417
|
-
await this.deps.notifyDeploymentFailure(
|
|
22418
|
-
|
|
22419
|
-
|
|
22790
|
+
await this.deps.notifyDeploymentFailure({
|
|
22791
|
+
slug: game2.slug,
|
|
22792
|
+
displayName: game2.displayName,
|
|
22793
|
+
error: message,
|
|
22794
|
+
target,
|
|
22795
|
+
developer: { id: user.id, email: user.email }
|
|
22420
22796
|
});
|
|
22421
22797
|
}
|
|
22422
22798
|
await this.deleteCodeBundle(jobId);
|
|
@@ -22518,7 +22894,7 @@ class DeployJobService {
|
|
|
22518
22894
|
}
|
|
22519
22895
|
assertLease();
|
|
22520
22896
|
const activeDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
22521
|
-
where:
|
|
22897
|
+
where: activeDeploymentWhere(job.gameId, request.target ?? "game"),
|
|
22522
22898
|
columns: {
|
|
22523
22899
|
deploymentId: true,
|
|
22524
22900
|
url: true
|
|
@@ -22541,7 +22917,15 @@ class DeployJobService {
|
|
|
22541
22917
|
} catch (error) {
|
|
22542
22918
|
clearInterval(heartbeat);
|
|
22543
22919
|
setAttribute("app.deploy_job.run_duration_ms", DeployJobService.elapsedMsSince(new Date(runStartedAt)));
|
|
22544
|
-
await this.handleRunError({
|
|
22920
|
+
await this.handleRunError({
|
|
22921
|
+
jobId,
|
|
22922
|
+
leaseId,
|
|
22923
|
+
leaseLost,
|
|
22924
|
+
target: request.target ?? "game",
|
|
22925
|
+
game: game2,
|
|
22926
|
+
user,
|
|
22927
|
+
error
|
|
22928
|
+
});
|
|
22545
22929
|
throw error;
|
|
22546
22930
|
}
|
|
22547
22931
|
}
|
|
@@ -22560,6 +22944,7 @@ async function forceMarkDeployJobFailed(db2, jobId, error) {
|
|
|
22560
22944
|
var STATUS_MAP2, DEPLOY_JOB_LEASE_MS, DEPLOY_JOB_HEARTBEAT_MS, DEPLOY_JOB_CODE_BUNDLE_PREFIX = "deploy-job-code";
|
|
22561
22945
|
var init_deploy_job_service = __esm(() => {
|
|
22562
22946
|
init_drizzle_orm();
|
|
22947
|
+
init_helpers_index();
|
|
22563
22948
|
init_tables_index();
|
|
22564
22949
|
init_spans();
|
|
22565
22950
|
init_zip();
|
|
@@ -24703,7 +25088,7 @@ var init_bindings = __esm(() => {
|
|
|
24703
25088
|
});
|
|
24704
25089
|
|
|
24705
25090
|
// ../cloudflare/src/playcademy/provider/helpers.ts
|
|
24706
|
-
var
|
|
25091
|
+
var init_helpers3 = __esm(() => {
|
|
24707
25092
|
init_mime();
|
|
24708
25093
|
});
|
|
24709
25094
|
|
|
@@ -24715,7 +25100,7 @@ var init_provider = __esm(() => {
|
|
|
24715
25100
|
init_constants2();
|
|
24716
25101
|
init_assets_config();
|
|
24717
25102
|
init_bindings();
|
|
24718
|
-
|
|
25103
|
+
init_helpers3();
|
|
24719
25104
|
});
|
|
24720
25105
|
// ../cloudflare/src/playcademy/provider/index.ts
|
|
24721
25106
|
var init_provider2 = __esm(() => {
|
|
@@ -27166,7 +27551,7 @@ var init_stages = __esm(() => {
|
|
|
27166
27551
|
});
|
|
27167
27552
|
|
|
27168
27553
|
// ../api-core/src/utils/deployment.util.ts
|
|
27169
|
-
function
|
|
27554
|
+
function getGameDeploymentId(gameSlug, sstStage) {
|
|
27170
27555
|
if (sstStage === "production") {
|
|
27171
27556
|
return gameSlug;
|
|
27172
27557
|
}
|
|
@@ -27175,45 +27560,57 @@ function getDeploymentId(gameSlug, sstStage) {
|
|
|
27175
27560
|
}
|
|
27176
27561
|
return `${WORKER_NAMING.LOCAL_PREFIX}${sstStage}-${gameSlug}`;
|
|
27177
27562
|
}
|
|
27563
|
+
function getDashboardDeploymentId(gameSlug, sstStage) {
|
|
27564
|
+
return `${getGameDeploymentId(gameSlug, sstStage)}${DASHBOARD_WORKER_SUFFIX}`;
|
|
27565
|
+
}
|
|
27178
27566
|
function getGameWorkerApiKeyName(slug) {
|
|
27179
|
-
return
|
|
27567
|
+
return `${GAME_WORKER_KEY_PREFIX}${slug}`.substring(0, 32);
|
|
27568
|
+
}
|
|
27569
|
+
function getDashboardWorkerApiKeyName(slug) {
|
|
27570
|
+
return `${DASHBOARD_WORKER_KEY_PREFIX}${slug}`;
|
|
27180
27571
|
}
|
|
27181
27572
|
function toBindingName(queueKey) {
|
|
27182
27573
|
return `${queueKey.replace(/-/g, "_").toUpperCase()}_QUEUE`;
|
|
27183
27574
|
}
|
|
27184
|
-
|
|
27185
|
-
|
|
27186
|
-
const data = encoder.encode(code);
|
|
27187
|
-
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
27188
|
-
const hashArray = [...new Uint8Array(hashBuffer)];
|
|
27189
|
-
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
27575
|
+
function generateDeploymentHash(code) {
|
|
27576
|
+
return sha256Hex(code);
|
|
27190
27577
|
}
|
|
27578
|
+
var GAME_WORKER_KEY_PREFIX = "game-worker-", DASHBOARD_WORKER_KEY_PREFIX = "dash-worker-";
|
|
27191
27579
|
var init_deployment_util = __esm(() => {
|
|
27192
27580
|
init_src();
|
|
27193
27581
|
init_stages();
|
|
27194
27582
|
});
|
|
27195
27583
|
|
|
27584
|
+
// ../api-core/src/utils/worker-keys.util.ts
|
|
27585
|
+
async function sweepDashboardWorkerKeys(deleteApiKeysByName, slug) {
|
|
27586
|
+
try {
|
|
27587
|
+
await deleteApiKeysByName(getDashboardWorkerApiKeyName(slug));
|
|
27588
|
+
} catch (error) {
|
|
27589
|
+
addEvent("dashboard.worker_key_sweep_failed", {
|
|
27590
|
+
"exception.type": errorType(error),
|
|
27591
|
+
"app.error.message": errorMessage(error)
|
|
27592
|
+
});
|
|
27593
|
+
}
|
|
27594
|
+
}
|
|
27595
|
+
var init_worker_keys_util = __esm(() => {
|
|
27596
|
+
init_spans();
|
|
27597
|
+
init_deployment_util();
|
|
27598
|
+
});
|
|
27599
|
+
|
|
27196
27600
|
// ../api-core/src/services/deploy.service.ts
|
|
27601
|
+
function readDashboardTheme(config2) {
|
|
27602
|
+
const theme = config2?.dashboard?.theme;
|
|
27603
|
+
return {
|
|
27604
|
+
...typeof theme?.primary === "string" && { primary: theme.primary },
|
|
27605
|
+
...typeof theme?.secondary === "string" && { secondary: theme.secondary }
|
|
27606
|
+
};
|
|
27607
|
+
}
|
|
27608
|
+
|
|
27197
27609
|
class DeployService {
|
|
27198
27610
|
deps;
|
|
27199
27611
|
constructor(deps) {
|
|
27200
27612
|
this.deps = deps;
|
|
27201
27613
|
}
|
|
27202
|
-
static classifyDeployType(flags2) {
|
|
27203
|
-
if (flags2.hasBackend && flags2.hasFrontend) {
|
|
27204
|
-
return "full_stack";
|
|
27205
|
-
}
|
|
27206
|
-
if (flags2.hasFrontend) {
|
|
27207
|
-
return "frontend_only";
|
|
27208
|
-
}
|
|
27209
|
-
if (flags2.hasBackend) {
|
|
27210
|
-
return "backend_only";
|
|
27211
|
-
}
|
|
27212
|
-
return "metadata_only";
|
|
27213
|
-
}
|
|
27214
|
-
static countDeadLetterQueues(bindings) {
|
|
27215
|
-
return bindings?.queues?.filter((queue) => Boolean(queue.deadLetterQueue)).length ?? 0;
|
|
27216
|
-
}
|
|
27217
27614
|
getCloudflare() {
|
|
27218
27615
|
const cf = this.deps.cloudflare;
|
|
27219
27616
|
if (!cf) {
|
|
@@ -27221,86 +27618,307 @@ class DeployService {
|
|
|
27221
27618
|
}
|
|
27222
27619
|
return cf;
|
|
27223
27620
|
}
|
|
27224
|
-
async
|
|
27225
|
-
const
|
|
27226
|
-
|
|
27227
|
-
|
|
27228
|
-
|
|
27229
|
-
|
|
27230
|
-
|
|
27231
|
-
}
|
|
27232
|
-
|
|
27233
|
-
|
|
27234
|
-
|
|
27235
|
-
|
|
27236
|
-
|
|
27237
|
-
|
|
27238
|
-
if (existingKeyId) {
|
|
27239
|
-
setAttribute("app.deploy.api_key_outcome", "regenerated");
|
|
27240
|
-
try {
|
|
27241
|
-
await this.deps.deleteAuthApiKey(existingKeyId);
|
|
27242
|
-
} catch (error) {
|
|
27243
|
-
addEvent("deploy.api_key_revoke_failed", {
|
|
27244
|
-
"exception.type": errorType(error),
|
|
27245
|
-
"app.error.message": errorMessage(error),
|
|
27246
|
-
"app.deploy.old_key_id": existingKeyId
|
|
27247
|
-
});
|
|
27621
|
+
async* deploy(slug, request, user, uploadDeps, extractZip) {
|
|
27622
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
27623
|
+
const context2 = { slug, request, user, game: game2, uploadDeps, extractZip };
|
|
27624
|
+
switch (request.target ?? "game") {
|
|
27625
|
+
case "dashboard": {
|
|
27626
|
+
yield* this.deployDashboard(context2);
|
|
27627
|
+
break;
|
|
27628
|
+
}
|
|
27629
|
+
case "game": {
|
|
27630
|
+
yield* this.deployGame(context2);
|
|
27631
|
+
break;
|
|
27632
|
+
}
|
|
27633
|
+
default: {
|
|
27634
|
+
throw new ValidationError("Invalid deployment target");
|
|
27248
27635
|
}
|
|
27249
27636
|
}
|
|
27250
|
-
return this.createApiKey(user, slug, keyName);
|
|
27251
27637
|
}
|
|
27252
|
-
async
|
|
27638
|
+
async* deployGame(context2) {
|
|
27639
|
+
const { slug, request, user, game: game2, uploadDeps, extractZip } = context2;
|
|
27253
27640
|
const cf = this.getCloudflare();
|
|
27254
|
-
const
|
|
27255
|
-
const
|
|
27256
|
-
|
|
27641
|
+
const db2 = this.deps.db;
|
|
27642
|
+
const flags2 = this.validateGameRequest(request);
|
|
27643
|
+
const { hasBackend, hasFrontend } = flags2;
|
|
27644
|
+
const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
27645
|
+
let frontendAssetsPath;
|
|
27646
|
+
let tempDir;
|
|
27647
|
+
if (hasFrontend) {
|
|
27648
|
+
if (!uploadDeps || !extractZip) {
|
|
27649
|
+
throw new ValidationError("Upload dependencies not configured for frontend deployment");
|
|
27650
|
+
}
|
|
27651
|
+
yield { type: "status", data: { message: "Fetching temporary files" } };
|
|
27652
|
+
const extracted = await this.fetchAndExtractFrontendAssets(slug, game2.id, request.uploadToken, uploadDeps, extractZip);
|
|
27653
|
+
tempDir = extracted.tempDir;
|
|
27654
|
+
frontendAssetsPath = extracted.assetsPath;
|
|
27655
|
+
yield { type: "status", data: { message: "Extracting assets" } };
|
|
27656
|
+
}
|
|
27657
|
+
const platformBaseUrl = await this.resolvePlatformBaseUrl();
|
|
27658
|
+
const env = {
|
|
27659
|
+
GAME_ID: game2.id,
|
|
27660
|
+
PLAYCADEMY_BASE_URL: platformBaseUrl,
|
|
27661
|
+
PLAYCADEMY_PLATFORM_SERVICE_JWKS: this.deps.config.platformServiceJwt?.publicJwks
|
|
27662
|
+
};
|
|
27663
|
+
yield {
|
|
27664
|
+
type: "status",
|
|
27665
|
+
data: { message: hasBackend ? "Deploying backend code" : "Deploying to platform" }
|
|
27666
|
+
};
|
|
27667
|
+
const keepAssets = hasBackend && !hasFrontend;
|
|
27668
|
+
const deploymentOptions = this.mapGameBindingsToOptions(deploymentId, request.bindings, request.schema);
|
|
27669
|
+
const bindings = deploymentOptions?.bindings;
|
|
27670
|
+
setAttributes({
|
|
27671
|
+
"app.deploy.has_d1": Boolean(bindings?.d1?.length),
|
|
27672
|
+
"app.deploy.has_kv": Boolean(bindings?.kv?.length),
|
|
27673
|
+
"app.deploy.has_r2": Boolean(bindings?.r2?.length),
|
|
27674
|
+
"app.deploy.queue_count": bindings?.queues?.length ?? 0,
|
|
27675
|
+
"app.deploy.dead_letter_queue_count": DeployService.countDeadLetterQueues(bindings)
|
|
27676
|
+
});
|
|
27677
|
+
const activeDeployment = await db2.query.gameDeployments.findFirst({
|
|
27678
|
+
where: activeDeploymentWhere(game2.id, "game"),
|
|
27679
|
+
columns: { resources: true }
|
|
27680
|
+
});
|
|
27681
|
+
if (deploymentOptions?.bindings?.d1?.length) {
|
|
27682
|
+
await this.cleanupOrphanD1Databases(cf, deploymentOptions.bindings.d1, slug, game2.id);
|
|
27683
|
+
}
|
|
27684
|
+
const result = await this.deployToCloudflare({
|
|
27685
|
+
deploymentId,
|
|
27686
|
+
code: request.code,
|
|
27687
|
+
env,
|
|
27688
|
+
tempDir,
|
|
27689
|
+
options: {
|
|
27690
|
+
...deploymentOptions,
|
|
27691
|
+
compatibilityDate: request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27692
|
+
compatibilityFlags: request.compatibilityFlags,
|
|
27693
|
+
existingResources: activeDeployment?.resources ?? undefined,
|
|
27694
|
+
assetsPath: frontendAssetsPath,
|
|
27695
|
+
keepAssets
|
|
27696
|
+
}
|
|
27697
|
+
});
|
|
27698
|
+
yield { type: "status", data: { message: "Finalizing deployment" } };
|
|
27699
|
+
const updatedGame = await this.finalizeGameDeployment({
|
|
27700
|
+
game: game2,
|
|
27701
|
+
slug,
|
|
27702
|
+
deploymentId,
|
|
27703
|
+
result,
|
|
27704
|
+
request,
|
|
27705
|
+
user,
|
|
27706
|
+
flags: flags2
|
|
27707
|
+
});
|
|
27708
|
+
yield { type: "complete", data: updatedGame };
|
|
27709
|
+
}
|
|
27710
|
+
async* deployDashboard(context2) {
|
|
27711
|
+
const { slug, request, user, game: game2 } = context2;
|
|
27712
|
+
const db2 = this.deps.db;
|
|
27713
|
+
const contract = this.validateDashboardRequest(request, context2.uploadDeps, context2.extractZip);
|
|
27714
|
+
const deploymentId = getDashboardDeploymentId(slug, this.deps.config.sstStage);
|
|
27715
|
+
if (deploymentId.length > MAX_WORKER_NAME_LENGTH) {
|
|
27716
|
+
throw new ValidationError(`Dashboard worker name '${deploymentId}' exceeds Cloudflare's ${MAX_WORKER_NAME_LENGTH}-character limit — shorten the game slug`);
|
|
27717
|
+
}
|
|
27718
|
+
const collidingGame = await db2.query.games.findFirst({
|
|
27719
|
+
where: eq(games.slug, `${slug}${DASHBOARD_WORKER_SUFFIX}`),
|
|
27257
27720
|
columns: { id: true }
|
|
27258
27721
|
});
|
|
27259
|
-
|
|
27260
|
-
|
|
27261
|
-
|
|
27262
|
-
|
|
27263
|
-
|
|
27264
|
-
|
|
27265
|
-
|
|
27266
|
-
|
|
27267
|
-
|
|
27268
|
-
|
|
27269
|
-
|
|
27270
|
-
|
|
27271
|
-
|
|
27272
|
-
|
|
27273
|
-
|
|
27722
|
+
if (collidingGame) {
|
|
27723
|
+
throw new ValidationError(`Cannot deploy this dashboard: an existing game's slug is '${slug}${DASHBOARD_WORKER_SUFFIX}', which owns the '${deploymentId}' worker name`);
|
|
27724
|
+
}
|
|
27725
|
+
const gameDeployment = await db2.query.gameDeployments.findFirst({
|
|
27726
|
+
where: activeDeploymentWhere(game2.id, "game"),
|
|
27727
|
+
columns: { resources: true }
|
|
27728
|
+
});
|
|
27729
|
+
if (!gameDeployment) {
|
|
27730
|
+
throw new ValidationError("Deploy the game before its dashboard — the dashboard attaches to the game deployment");
|
|
27731
|
+
}
|
|
27732
|
+
setAttributes({
|
|
27733
|
+
"app.deploy.type": "dashboard",
|
|
27734
|
+
"app.deploy.deployment_id": deploymentId,
|
|
27735
|
+
"app.deploy.code_size": contract.code.length,
|
|
27736
|
+
"app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27737
|
+
"app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0
|
|
27738
|
+
});
|
|
27739
|
+
yield { type: "status", data: { message: "Fetching temporary files" } };
|
|
27740
|
+
const [{ tempDir, assetsPath }, platformBaseUrl, dashboardActive] = await Promise.all([
|
|
27741
|
+
this.fetchAndExtractFrontendAssets(slug, game2.id, contract.uploadToken, contract.uploadDeps, contract.extractZip),
|
|
27742
|
+
this.resolvePlatformBaseUrl(),
|
|
27743
|
+
db2.query.gameDeployments.findFirst({
|
|
27744
|
+
where: activeDeploymentWhere(game2.id, "dashboard"),
|
|
27745
|
+
columns: { resources: true }
|
|
27746
|
+
})
|
|
27747
|
+
]);
|
|
27748
|
+
yield { type: "status", data: { message: "Extracting assets" } };
|
|
27749
|
+
const theme = readDashboardTheme(request.config);
|
|
27750
|
+
const env = {
|
|
27751
|
+
GAME_ID: game2.id,
|
|
27752
|
+
GAME_SLUG: slug,
|
|
27753
|
+
GAME_NAME: game2.displayName,
|
|
27754
|
+
...game2.metadata?.emoji && { GAME_EMOJI: game2.metadata.emoji },
|
|
27755
|
+
...theme.primary && { DASHBOARD_THEME_PRIMARY: theme.primary },
|
|
27756
|
+
...theme.secondary && { DASHBOARD_THEME_SECONDARY: theme.secondary },
|
|
27757
|
+
PLAYCADEMY_BASE_URL: platformBaseUrl,
|
|
27758
|
+
PLAYCADEMY_PLATFORM_SERVICE_JWKS: this.deps.config.platformServiceJwt?.publicJwks
|
|
27759
|
+
};
|
|
27760
|
+
const gameResources = gameDeployment.resources;
|
|
27761
|
+
const bindings = {
|
|
27762
|
+
d1: gameResources?.d1?.map((database) => database.name) ?? [],
|
|
27763
|
+
kv: gameResources?.kv?.map((namespace) => namespace.name) ?? [],
|
|
27764
|
+
r2: gameResources?.r2?.filter((bucket) => bucket.kind !== "assets").map((bucket) => bucket.name) ?? []
|
|
27765
|
+
};
|
|
27766
|
+
const existingResources = {
|
|
27767
|
+
...dashboardActive?.resources,
|
|
27768
|
+
d1: gameResources?.d1,
|
|
27769
|
+
kv: gameResources?.kv,
|
|
27770
|
+
r2: gameResources?.r2
|
|
27771
|
+
};
|
|
27772
|
+
yield { type: "status", data: { message: "Deploying dashboard" } };
|
|
27773
|
+
const result = await this.deployToCloudflare({
|
|
27774
|
+
deploymentId,
|
|
27775
|
+
code: contract.code,
|
|
27776
|
+
env,
|
|
27777
|
+
tempDir,
|
|
27778
|
+
options: {
|
|
27779
|
+
bindings,
|
|
27780
|
+
compatibilityDate: request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27781
|
+
compatibilityFlags: request.compatibilityFlags,
|
|
27782
|
+
existingResources,
|
|
27783
|
+
assetsPath,
|
|
27784
|
+
keepAssets: false,
|
|
27785
|
+
assetsConfig: { run_worker_first: true }
|
|
27274
27786
|
}
|
|
27275
|
-
|
|
27787
|
+
});
|
|
27788
|
+
yield { type: "status", data: { message: "Finalizing deployment" } };
|
|
27789
|
+
await withSpan("deploy.configure_worker_secrets", async () => {
|
|
27790
|
+
const existingSecrets = await this.listWorkerSecretNames(result.deploymentId);
|
|
27791
|
+
await this.ensureWorkerApiKeyOnWorker(user, DeployService.dashboardWorkerKeySpec(slug), result.deploymentId, existingSecrets);
|
|
27792
|
+
await this.ensureDashboardSessionSecret(result.deploymentId, existingSecrets, Boolean(dashboardActive));
|
|
27793
|
+
});
|
|
27794
|
+
const codeHash = await generateDeploymentHash(contract.code);
|
|
27795
|
+
await this.saveDeployment({
|
|
27796
|
+
gameId: game2.id,
|
|
27797
|
+
deploymentId: result.deploymentId,
|
|
27798
|
+
url: result.url,
|
|
27799
|
+
codeHash,
|
|
27800
|
+
resources: result.resources,
|
|
27801
|
+
target: "dashboard"
|
|
27802
|
+
});
|
|
27803
|
+
setAttribute("app.deploy.code_hash", codeHash);
|
|
27804
|
+
try {
|
|
27805
|
+
await withSpan("deploy.send_alert", () => this.deps.alerts.notifyDashboardDeployment({
|
|
27806
|
+
slug,
|
|
27807
|
+
displayName: game2.displayName,
|
|
27808
|
+
url: result.url,
|
|
27809
|
+
developer: { id: user.id, email: user.email }
|
|
27810
|
+
}));
|
|
27811
|
+
} catch (error) {
|
|
27812
|
+
setAttribute("app.alerts.delivery", "failed");
|
|
27813
|
+
setAttribute("app.alerts.delivery_error", errorMessage(error));
|
|
27814
|
+
setAttribute("app.alerts.type", "dashboard_deployment");
|
|
27276
27815
|
}
|
|
27277
|
-
|
|
27816
|
+
yield { type: "complete", data: game2 };
|
|
27278
27817
|
}
|
|
27279
|
-
|
|
27280
|
-
const
|
|
27281
|
-
|
|
27282
|
-
|
|
27818
|
+
validateGameRequest(request) {
|
|
27819
|
+
const hasBackend = Boolean(request.code);
|
|
27820
|
+
const hasFrontend = Boolean(request.uploadToken);
|
|
27821
|
+
const hasMetadata = Boolean(request.metadata);
|
|
27822
|
+
setAttributes({
|
|
27823
|
+
"app.deploy.has_backend": hasBackend,
|
|
27824
|
+
"app.deploy.has_frontend": hasFrontend,
|
|
27825
|
+
"app.deploy.has_metadata": hasMetadata,
|
|
27826
|
+
"app.deploy.type": DeployService.classifyGameDeployType({
|
|
27827
|
+
hasBackend,
|
|
27828
|
+
hasFrontend,
|
|
27829
|
+
hasMetadata
|
|
27830
|
+
}),
|
|
27831
|
+
"app.deploy.code_size": request.code?.length ?? 0,
|
|
27832
|
+
"app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27833
|
+
"app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0,
|
|
27834
|
+
"app.deploy.has_schema": Boolean(request.schema)
|
|
27835
|
+
});
|
|
27836
|
+
if (!hasBackend && !hasFrontend && !hasMetadata) {
|
|
27837
|
+
throw new ValidationError("Must provide at least one of: uploadToken (frontend), code (backend), or metadata");
|
|
27283
27838
|
}
|
|
27284
|
-
|
|
27285
|
-
|
|
27839
|
+
if (!this.deps.config.baseUrl) {
|
|
27840
|
+
throw new ValidationError("baseUrl is not configured");
|
|
27841
|
+
}
|
|
27842
|
+
return { hasBackend, hasFrontend, hasMetadata };
|
|
27286
27843
|
}
|
|
27287
|
-
|
|
27288
|
-
|
|
27289
|
-
|
|
27290
|
-
throw new ValidationError("Uploaded file is empty or not found");
|
|
27844
|
+
validateDashboardRequest(request, uploadDeps, extractZip) {
|
|
27845
|
+
if (!request.code || !request.uploadToken) {
|
|
27846
|
+
throw new ValidationError("Dashboard deployments require both worker code and an asset upload");
|
|
27291
27847
|
}
|
|
27292
|
-
|
|
27293
|
-
|
|
27294
|
-
|
|
27295
|
-
|
|
27296
|
-
|
|
27297
|
-
|
|
27298
|
-
|
|
27299
|
-
|
|
27848
|
+
if (request.metadata) {
|
|
27849
|
+
throw new ValidationError("Dashboard deployments cannot update game metadata");
|
|
27850
|
+
}
|
|
27851
|
+
if (!uploadDeps || !extractZip) {
|
|
27852
|
+
throw new ValidationError("Upload dependencies not configured for frontend deployment");
|
|
27853
|
+
}
|
|
27854
|
+
if (!this.deps.config.baseUrl) {
|
|
27855
|
+
throw new ValidationError("baseUrl is not configured");
|
|
27856
|
+
}
|
|
27857
|
+
return { code: request.code, uploadToken: request.uploadToken, uploadDeps, extractZip };
|
|
27858
|
+
}
|
|
27859
|
+
static classifyGameDeployType(flags2) {
|
|
27860
|
+
if (flags2.hasBackend && flags2.hasFrontend) {
|
|
27861
|
+
return "full_stack";
|
|
27862
|
+
}
|
|
27863
|
+
if (flags2.hasFrontend) {
|
|
27864
|
+
return "frontend_only";
|
|
27865
|
+
}
|
|
27866
|
+
if (flags2.hasBackend) {
|
|
27867
|
+
return "backend_only";
|
|
27868
|
+
}
|
|
27869
|
+
return "metadata_only";
|
|
27870
|
+
}
|
|
27871
|
+
mapGameBindingsToOptions(deploymentId, bindings, schema2) {
|
|
27872
|
+
if (!bindings && !schema2) {
|
|
27873
|
+
return;
|
|
27874
|
+
}
|
|
27875
|
+
const workerBindings = {};
|
|
27876
|
+
if (bindings?.database) {
|
|
27877
|
+
workerBindings.d1 = [deploymentId];
|
|
27878
|
+
}
|
|
27879
|
+
if (bindings?.keyValue) {
|
|
27880
|
+
workerBindings.kv = [deploymentId];
|
|
27881
|
+
}
|
|
27882
|
+
if (bindings?.bucket) {
|
|
27883
|
+
workerBindings.r2 = [deploymentId];
|
|
27884
|
+
}
|
|
27885
|
+
if (bindings?.queues) {
|
|
27886
|
+
let toQueueName = function(queueKey) {
|
|
27887
|
+
return `${QUEUE_NAME_PREFIX}-${deploymentId}--${queueKey}`;
|
|
27888
|
+
};
|
|
27889
|
+
const queueNameByKey = new Map;
|
|
27890
|
+
for (const queueKey of Object.keys(bindings.queues)) {
|
|
27891
|
+
queueNameByKey.set(queueKey, toQueueName(queueKey));
|
|
27892
|
+
}
|
|
27893
|
+
workerBindings.queues = Object.entries(bindings.queues).map(([queueKey, queueConfig]) => {
|
|
27894
|
+
const config2 = queueConfig === true ? undefined : queueConfig;
|
|
27895
|
+
const deadLetterQueue = config2?.deadLetterQueue && queueNameByKey.get(config2.deadLetterQueue) ? queueNameByKey.get(config2.deadLetterQueue) : undefined;
|
|
27896
|
+
return {
|
|
27897
|
+
bindingName: toBindingName(queueKey),
|
|
27898
|
+
queueName: toQueueName(queueKey),
|
|
27899
|
+
settings: config2 ? {
|
|
27900
|
+
maxBatchSize: config2.maxBatchSize,
|
|
27901
|
+
maxRetries: config2.maxRetries,
|
|
27902
|
+
maxBatchTimeout: config2.maxBatchTimeout,
|
|
27903
|
+
maxConcurrency: config2.maxConcurrency,
|
|
27904
|
+
retryDelay: config2.retryDelay
|
|
27905
|
+
} : undefined,
|
|
27906
|
+
deadLetterQueue
|
|
27907
|
+
};
|
|
27908
|
+
});
|
|
27909
|
+
}
|
|
27910
|
+
const hasBindings = workerBindings.d1?.length || workerBindings.kv?.length || workerBindings.r2?.length || workerBindings.queues?.length;
|
|
27911
|
+
return {
|
|
27912
|
+
...hasBindings && { bindings: workerBindings },
|
|
27913
|
+
...schema2 && { schema: schema2 }
|
|
27914
|
+
};
|
|
27915
|
+
}
|
|
27916
|
+
static countDeadLetterQueues(bindings) {
|
|
27917
|
+
return bindings?.queues?.filter((queue) => Boolean(queue.deadLetterQueue)).length ?? 0;
|
|
27300
27918
|
}
|
|
27301
27919
|
async cleanupOrphanD1Databases(cf, d1Names, slug, gameId) {
|
|
27302
27920
|
const hasAnyPriorDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
27303
|
-
where: eq(gameDeployments.gameId, gameId),
|
|
27921
|
+
where: and(eq(gameDeployments.gameId, gameId), eq(gameDeployments.target, "game")),
|
|
27304
27922
|
columns: { id: true }
|
|
27305
27923
|
});
|
|
27306
27924
|
if (hasAnyPriorDeployment) {
|
|
@@ -27335,33 +27953,7 @@ class DeployService {
|
|
|
27335
27953
|
}
|
|
27336
27954
|
await this.deps.db.update(games).set(updates).where(eq(games.id, gameId));
|
|
27337
27955
|
}
|
|
27338
|
-
|
|
27339
|
-
const hasBackend = Boolean(request.code);
|
|
27340
|
-
const hasFrontend = Boolean(request.uploadToken);
|
|
27341
|
-
const hasMetadata = Boolean(request.metadata);
|
|
27342
|
-
setAttributes({
|
|
27343
|
-
"app.deploy.has_backend": hasBackend,
|
|
27344
|
-
"app.deploy.has_frontend": hasFrontend,
|
|
27345
|
-
"app.deploy.has_metadata": hasMetadata,
|
|
27346
|
-
"app.deploy.type": DeployService.classifyDeployType({
|
|
27347
|
-
hasBackend,
|
|
27348
|
-
hasFrontend,
|
|
27349
|
-
hasMetadata
|
|
27350
|
-
}),
|
|
27351
|
-
"app.deploy.code_size": request.code?.length ?? 0,
|
|
27352
|
-
"app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27353
|
-
"app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0,
|
|
27354
|
-
"app.deploy.has_schema": Boolean(request.schema)
|
|
27355
|
-
});
|
|
27356
|
-
if (!hasBackend && !hasFrontend && !hasMetadata) {
|
|
27357
|
-
throw new ValidationError("Must provide at least one of: uploadToken (frontend), code (backend), or metadata");
|
|
27358
|
-
}
|
|
27359
|
-
if (!this.deps.config.baseUrl) {
|
|
27360
|
-
throw new ValidationError("baseUrl is not configured");
|
|
27361
|
-
}
|
|
27362
|
-
return { hasBackend, hasFrontend, hasMetadata };
|
|
27363
|
-
}
|
|
27364
|
-
async finalizeDeployment({
|
|
27956
|
+
async finalizeGameDeployment({
|
|
27365
27957
|
game: game2,
|
|
27366
27958
|
slug,
|
|
27367
27959
|
deploymentId,
|
|
@@ -27373,10 +27965,17 @@ class DeployService {
|
|
|
27373
27965
|
const { hasBackend, hasFrontend, hasMetadata } = flags2;
|
|
27374
27966
|
const db2 = this.deps.db;
|
|
27375
27967
|
const codeHash = hasBackend ? await generateDeploymentHash(request.code) : null;
|
|
27376
|
-
await this.saveDeployment(
|
|
27968
|
+
await this.saveDeployment({
|
|
27969
|
+
gameId: game2.id,
|
|
27970
|
+
deploymentId: result.deploymentId,
|
|
27971
|
+
url: result.url,
|
|
27972
|
+
codeHash,
|
|
27973
|
+
resources: result.resources,
|
|
27974
|
+
target: "game"
|
|
27975
|
+
});
|
|
27377
27976
|
if (hasBackend) {
|
|
27378
27977
|
await withSpan("deploy.configure_worker_secrets", async () => {
|
|
27379
|
-
await this.
|
|
27978
|
+
await this.ensureWorkerApiKeyOnWorker(user, DeployService.gameWorkerKeySpec(slug), result.deploymentId);
|
|
27380
27979
|
await this.ensureQueueIngressSecretOnWorker(slug, result.deploymentId);
|
|
27381
27980
|
});
|
|
27382
27981
|
}
|
|
@@ -27409,169 +28008,232 @@ class DeployService {
|
|
|
27409
28008
|
}
|
|
27410
28009
|
return updatedGame;
|
|
27411
28010
|
}
|
|
27412
|
-
|
|
27413
|
-
|
|
27414
|
-
|
|
27415
|
-
|
|
27416
|
-
|
|
27417
|
-
const { hasBackend, hasFrontend } = flags2;
|
|
27418
|
-
const deploymentId = getDeploymentId(slug, this.deps.config.sstStage);
|
|
27419
|
-
let frontendAssetsPath;
|
|
27420
|
-
let tempDir;
|
|
27421
|
-
if (hasFrontend) {
|
|
27422
|
-
if (!uploadDeps || !extractZip) {
|
|
27423
|
-
throw new ValidationError("Upload dependencies not configured for frontend deployment");
|
|
27424
|
-
}
|
|
27425
|
-
yield { type: "status", data: { message: "Fetching temporary files" } };
|
|
27426
|
-
const extracted = await this.fetchAndExtractFrontendAssets(slug, game2.id, request.uploadToken, uploadDeps, extractZip);
|
|
27427
|
-
tempDir = extracted.tempDir;
|
|
27428
|
-
frontendAssetsPath = extracted.assetsPath;
|
|
27429
|
-
yield { type: "status", data: { message: "Extracting assets" } };
|
|
27430
|
-
}
|
|
27431
|
-
let platformBaseUrl = this.deps.config.baseUrl;
|
|
27432
|
-
if (this.deps.config.isLocal) {
|
|
27433
|
-
try {
|
|
27434
|
-
platformBaseUrl = await getTunnelUrl();
|
|
27435
|
-
} catch {
|
|
27436
|
-
setAttributes({
|
|
27437
|
-
"app.deploy.tunnel_available": false,
|
|
27438
|
-
"app.deploy.failure_kind": "local_tunnel_unavailable"
|
|
27439
|
-
});
|
|
27440
|
-
throw new ValidationError("Local tunnel is not running. Ensure cloudflared is installed (`brew install cloudflared`) and the tunnel DevCommand started successfully.");
|
|
27441
|
-
}
|
|
27442
|
-
}
|
|
27443
|
-
const env = {
|
|
27444
|
-
GAME_ID: game2.id,
|
|
27445
|
-
PLAYCADEMY_BASE_URL: platformBaseUrl,
|
|
27446
|
-
PLAYCADEMY_PLATFORM_SERVICE_JWKS: this.deps.config.platformServiceJwt?.publicJwks
|
|
28011
|
+
static gameWorkerKeySpec(slug) {
|
|
28012
|
+
return {
|
|
28013
|
+
keyName: getGameWorkerApiKeyName(slug),
|
|
28014
|
+
permissions: { games: [`read:${slug}`, `write:${slug}`] },
|
|
28015
|
+
lookup: "owner-and-name"
|
|
27447
28016
|
};
|
|
27448
|
-
|
|
27449
|
-
|
|
27450
|
-
|
|
28017
|
+
}
|
|
28018
|
+
static dashboardWorkerKeySpec(slug) {
|
|
28019
|
+
return {
|
|
28020
|
+
keyName: getDashboardWorkerApiKeyName(slug),
|
|
28021
|
+
permissions: {
|
|
28022
|
+
games: [`read:${slug}`],
|
|
28023
|
+
[DASHBOARD_PERMISSION_NAMESPACE]: [dashboardCredentialScope(slug)]
|
|
28024
|
+
},
|
|
28025
|
+
rateLimit: { maxRequests: 300, timeWindowMs: 60000 },
|
|
28026
|
+
lookup: "name",
|
|
28027
|
+
isCurrent: (permissionsJson) => DeployService.hasDashboardCredentialScope(permissionsJson, slug)
|
|
27451
28028
|
};
|
|
27452
|
-
|
|
27453
|
-
|
|
27454
|
-
|
|
27455
|
-
|
|
27456
|
-
"app.deploy.has_d1": Boolean(bindings?.d1?.length),
|
|
27457
|
-
"app.deploy.has_kv": Boolean(bindings?.kv?.length),
|
|
27458
|
-
"app.deploy.has_r2": Boolean(bindings?.r2?.length),
|
|
27459
|
-
"app.deploy.queue_count": bindings?.queues?.length ?? 0,
|
|
27460
|
-
"app.deploy.dead_letter_queue_count": DeployService.countDeadLetterQueues(bindings)
|
|
27461
|
-
});
|
|
27462
|
-
const activeDeployment = await db2.query.gameDeployments.findFirst({
|
|
27463
|
-
where: and(eq(gameDeployments.gameId, game2.id), eq(gameDeployments.isActive, true)),
|
|
27464
|
-
columns: { resources: true }
|
|
27465
|
-
});
|
|
27466
|
-
if (deploymentOptions?.bindings?.d1?.length) {
|
|
27467
|
-
await this.cleanupOrphanD1Databases(cf, deploymentOptions.bindings.d1, slug, game2.id);
|
|
28029
|
+
}
|
|
28030
|
+
static hasDashboardCredentialScope(permissionsJson, slug) {
|
|
28031
|
+
if (!permissionsJson) {
|
|
28032
|
+
return false;
|
|
27468
28033
|
}
|
|
27469
|
-
let result;
|
|
27470
28034
|
try {
|
|
27471
|
-
|
|
27472
|
-
|
|
27473
|
-
|
|
27474
|
-
|
|
27475
|
-
|
|
27476
|
-
|
|
27477
|
-
|
|
27478
|
-
|
|
27479
|
-
|
|
27480
|
-
|
|
27481
|
-
|
|
27482
|
-
|
|
28035
|
+
const parsed = JSON.parse(permissionsJson);
|
|
28036
|
+
return dashboardCredentialSlugs(parsed).includes(slug);
|
|
28037
|
+
} catch {
|
|
28038
|
+
return false;
|
|
28039
|
+
}
|
|
28040
|
+
}
|
|
28041
|
+
async ensureWorkerApiKeyOnWorker(user, spec, deploymentId, existingSecrets) {
|
|
28042
|
+
const cf = this.getCloudflare();
|
|
28043
|
+
const existingKey = await this.deps.db.query.apikey.findFirst({
|
|
28044
|
+
where: spec.lookup === "owner-and-name" ? and(eq(apikey.userId, user.id), eq(apikey.name, spec.keyName)) : eq(apikey.name, spec.keyName),
|
|
28045
|
+
columns: { id: true, permissions: true }
|
|
28046
|
+
});
|
|
28047
|
+
let apiKey;
|
|
28048
|
+
if (!existingKey) {
|
|
28049
|
+
apiKey = await this.createApiKey(user, spec);
|
|
28050
|
+
} else {
|
|
28051
|
+
const current = spec.isCurrent?.(existingKey.permissions) ?? true;
|
|
28052
|
+
const workerHasKey = existingSecrets ? existingSecrets.includes("PLAYCADEMY_API_KEY") : await this.workerHasSecret(deploymentId, "PLAYCADEMY_API_KEY");
|
|
28053
|
+
if (current && workerHasKey) {
|
|
28054
|
+
setAttribute("app.deploy.api_key_outcome", "already_set");
|
|
28055
|
+
return;
|
|
27483
28056
|
}
|
|
28057
|
+
apiKey = await this.regenerateApiKey(user, existingKey.id, spec);
|
|
27484
28058
|
}
|
|
27485
|
-
|
|
27486
|
-
|
|
27487
|
-
|
|
27488
|
-
|
|
27489
|
-
|
|
27490
|
-
|
|
27491
|
-
|
|
27492
|
-
|
|
27493
|
-
|
|
28059
|
+
await cf.setSecrets(deploymentId, { PLAYCADEMY_API_KEY: apiKey });
|
|
28060
|
+
}
|
|
28061
|
+
async createApiKey(user, spec) {
|
|
28062
|
+
const { key: apiKey } = await this.deps.createAuthApiKey({
|
|
28063
|
+
userId: user.id,
|
|
28064
|
+
name: spec.keyName,
|
|
28065
|
+
expiresIn: null,
|
|
28066
|
+
permissions: spec.permissions,
|
|
28067
|
+
...spec.rateLimit ? {
|
|
28068
|
+
rateLimitEnabled: true,
|
|
28069
|
+
rateLimitMax: spec.rateLimit.maxRequests,
|
|
28070
|
+
rateLimitTimeWindow: spec.rateLimit.timeWindowMs
|
|
28071
|
+
} : { rateLimitEnabled: false }
|
|
27494
28072
|
});
|
|
27495
|
-
|
|
28073
|
+
setAttribute("app.deploy.api_key_outcome", "created");
|
|
28074
|
+
return apiKey;
|
|
27496
28075
|
}
|
|
27497
|
-
|
|
27498
|
-
|
|
28076
|
+
async regenerateApiKey(user, existingKeyId, spec) {
|
|
28077
|
+
setAttribute("app.deploy.api_key_outcome", "regenerated");
|
|
28078
|
+
try {
|
|
28079
|
+
await this.deps.deleteAuthApiKey(existingKeyId);
|
|
28080
|
+
} catch (error) {
|
|
28081
|
+
addEvent("deploy.api_key_revoke_failed", {
|
|
28082
|
+
"exception.type": errorType(error),
|
|
28083
|
+
"app.error.message": errorMessage(error),
|
|
28084
|
+
"app.deploy.old_key_id": existingKeyId
|
|
28085
|
+
});
|
|
28086
|
+
}
|
|
28087
|
+
return this.createApiKey(user, spec);
|
|
28088
|
+
}
|
|
28089
|
+
async listWorkerSecretNames(deploymentId) {
|
|
28090
|
+
try {
|
|
28091
|
+
return await this.getCloudflare().listSecrets(deploymentId);
|
|
28092
|
+
} catch (error) {
|
|
28093
|
+
addEvent("deploy.worker_secrets_check_failed", {
|
|
28094
|
+
"exception.type": errorType(error),
|
|
28095
|
+
"app.error.message": errorMessage(error)
|
|
28096
|
+
});
|
|
28097
|
+
return null;
|
|
28098
|
+
}
|
|
28099
|
+
}
|
|
28100
|
+
async workerHasSecret(deploymentId, secretName) {
|
|
28101
|
+
const workerSecrets = await this.listWorkerSecretNames(deploymentId);
|
|
28102
|
+
return Boolean(workerSecrets?.includes(secretName));
|
|
28103
|
+
}
|
|
28104
|
+
async ensureQueueIngressSecretOnWorker(slug, deploymentId) {
|
|
28105
|
+
const secret = this.deps.config.queueIngressSecret;
|
|
28106
|
+
if (!secret) {
|
|
27499
28107
|
return;
|
|
27500
28108
|
}
|
|
27501
|
-
const
|
|
27502
|
-
|
|
27503
|
-
|
|
28109
|
+
const cf = this.getCloudflare();
|
|
28110
|
+
await cf.setSecrets(deploymentId, { QUEUE_INGRESS_SECRET: secret });
|
|
28111
|
+
}
|
|
28112
|
+
async ensureDashboardSessionSecret(deploymentId, existingSecrets, hasPriorDeployment) {
|
|
28113
|
+
if (existingSecrets === null && hasPriorDeployment) {
|
|
28114
|
+
setAttribute("app.deploy.session_secret_outcome", "check_failed_kept");
|
|
28115
|
+
return;
|
|
27504
28116
|
}
|
|
27505
|
-
if (
|
|
27506
|
-
|
|
28117
|
+
if (existingSecrets?.includes("DASHBOARD_SESSION_SECRET")) {
|
|
28118
|
+
setAttribute("app.deploy.session_secret_outcome", "already_set");
|
|
28119
|
+
return;
|
|
27507
28120
|
}
|
|
27508
|
-
|
|
27509
|
-
|
|
28121
|
+
const secret = await generateSecureRandomString(64);
|
|
28122
|
+
await this.getCloudflare().setSecrets(deploymentId, { DASHBOARD_SESSION_SECRET: secret });
|
|
28123
|
+
setAttribute("app.deploy.session_secret_outcome", "created");
|
|
28124
|
+
}
|
|
28125
|
+
async rotateDashboardSessionSecret(slug, user) {
|
|
28126
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
28127
|
+
const deployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
28128
|
+
where: activeDeploymentWhere(game2.id, "dashboard"),
|
|
28129
|
+
columns: { deploymentId: true }
|
|
28130
|
+
});
|
|
28131
|
+
if (!deployment) {
|
|
28132
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, slug);
|
|
28133
|
+
throw new NotFoundError("Dashboard deployment", slug);
|
|
27510
28134
|
}
|
|
27511
|
-
|
|
27512
|
-
|
|
27513
|
-
|
|
27514
|
-
|
|
27515
|
-
|
|
27516
|
-
|
|
27517
|
-
|
|
27518
|
-
|
|
27519
|
-
|
|
27520
|
-
|
|
27521
|
-
|
|
27522
|
-
|
|
27523
|
-
|
|
27524
|
-
|
|
27525
|
-
|
|
27526
|
-
|
|
27527
|
-
|
|
27528
|
-
|
|
27529
|
-
|
|
27530
|
-
|
|
27531
|
-
|
|
27532
|
-
|
|
27533
|
-
|
|
28135
|
+
const secret = await generateSecureRandomString(64);
|
|
28136
|
+
await this.getCloudflare().setSecrets(deployment.deploymentId, {
|
|
28137
|
+
DASHBOARD_SESSION_SECRET: secret
|
|
28138
|
+
});
|
|
28139
|
+
setAttribute("app.deploy.session_secret_outcome", "rotated");
|
|
28140
|
+
}
|
|
28141
|
+
async removeDashboard(slug, user) {
|
|
28142
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
28143
|
+
const db2 = this.deps.db;
|
|
28144
|
+
const deployment = await db2.query.gameDeployments.findFirst({
|
|
28145
|
+
where: activeDeploymentWhere(game2.id, "dashboard"),
|
|
28146
|
+
columns: { deploymentId: true, provider: true, resources: true }
|
|
28147
|
+
});
|
|
28148
|
+
if (!deployment) {
|
|
28149
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, slug);
|
|
28150
|
+
throw new NotFoundError("Dashboard deployment", slug);
|
|
28151
|
+
}
|
|
28152
|
+
const assetBuckets = deployment.resources?.r2?.filter((bucket) => bucket.kind === "assets") ?? [];
|
|
28153
|
+
await this.getCloudflare().delete(deployment.deploymentId, {
|
|
28154
|
+
deleteBindings: assetBuckets.length > 0,
|
|
28155
|
+
resources: assetBuckets.length > 0 ? { r2: assetBuckets } : undefined
|
|
28156
|
+
});
|
|
28157
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, slug);
|
|
28158
|
+
await db2.delete(gameDeployments).where(and(eq(gameDeployments.gameId, game2.id), eq(gameDeployments.target, "dashboard")));
|
|
28159
|
+
setAttribute("app.deploy.dashboard_removed", true);
|
|
28160
|
+
await withSpan("deploy.send_alert", () => this.deps.alerts.notifyDashboardRemoval({
|
|
28161
|
+
slug,
|
|
28162
|
+
displayName: game2.displayName,
|
|
28163
|
+
developer: { id: user.id, email: user.email }
|
|
28164
|
+
})).catch(catchAttrs("alerts.delivery", { "app.alerts.type": "dashboard_removal" }));
|
|
28165
|
+
}
|
|
28166
|
+
async fetchAndExtractFrontendAssets(slug, gameId, uploadToken, uploadDeps, extractZip) {
|
|
28167
|
+
const frontendZip = await withSpan("deploy.fetch_temporary_files", () => uploadDeps.getObjectAsByteArray(uploadToken));
|
|
28168
|
+
if (!frontendZip || frontendZip.length === 0) {
|
|
28169
|
+
throw new ValidationError("Uploaded file is empty or not found");
|
|
28170
|
+
}
|
|
28171
|
+
setAttribute("app.deploy.asset_upload_size", frontendZip.length);
|
|
28172
|
+
const os2 = await import("os");
|
|
28173
|
+
const path = await import("path");
|
|
28174
|
+
const tempDir = path.join(os2.tmpdir(), `playcademy-deploy-${gameId}-${Date.now()}`);
|
|
28175
|
+
const assetsPath = path.join(tempDir, "dist");
|
|
28176
|
+
await withSpan("deploy.extract_assets", () => extractZip(frontendZip, assetsPath));
|
|
28177
|
+
uploadDeps.deleteObject(uploadToken).catch(catchAttrs("deploy.temp_cleanup"));
|
|
28178
|
+
return { frontendZip, tempDir, assetsPath };
|
|
28179
|
+
}
|
|
28180
|
+
async resolvePlatformBaseUrl() {
|
|
28181
|
+
if (!this.deps.config.isLocal) {
|
|
28182
|
+
return this.deps.config.baseUrl;
|
|
28183
|
+
}
|
|
28184
|
+
try {
|
|
28185
|
+
return await getTunnelUrl();
|
|
28186
|
+
} catch {
|
|
28187
|
+
setAttributes({
|
|
28188
|
+
"app.deploy.tunnel_available": false,
|
|
28189
|
+
"app.deploy.failure_kind": "local_tunnel_unavailable"
|
|
27534
28190
|
});
|
|
28191
|
+
throw new ValidationError("Local tunnel is not running. Ensure cloudflared is installed (`brew install cloudflared`) and the tunnel DevCommand started successfully.");
|
|
27535
28192
|
}
|
|
27536
|
-
const hasBindings = workerBindings.d1?.length || workerBindings.kv?.length || workerBindings.r2?.length || workerBindings.queues?.length;
|
|
27537
|
-
return {
|
|
27538
|
-
...hasBindings && { bindings: workerBindings },
|
|
27539
|
-
...schema2 && { schema: schema2 }
|
|
27540
|
-
};
|
|
27541
28193
|
}
|
|
27542
|
-
async
|
|
27543
|
-
|
|
27544
|
-
|
|
27545
|
-
|
|
27546
|
-
|
|
27547
|
-
|
|
27548
|
-
|
|
28194
|
+
async deployToCloudflare(args2) {
|
|
28195
|
+
const cf = this.getCloudflare();
|
|
28196
|
+
try {
|
|
28197
|
+
return await withSpan("deploy.cloudflare", () => cf.deploy(args2.deploymentId, args2.code, args2.env, args2.options));
|
|
28198
|
+
} finally {
|
|
28199
|
+
if (args2.tempDir) {
|
|
28200
|
+
const fs2 = await import("fs/promises");
|
|
28201
|
+
fs2.rm(args2.tempDir, { recursive: true, force: true }).catch(catchAttrs("deploy.temp_cleanup"));
|
|
28202
|
+
}
|
|
28203
|
+
}
|
|
27549
28204
|
}
|
|
27550
|
-
async saveDeployment(
|
|
28205
|
+
async saveDeployment(record) {
|
|
27551
28206
|
const db2 = this.deps.db;
|
|
27552
28207
|
await db2.transaction(async (tx) => {
|
|
27553
|
-
await tx.update(gameDeployments).set({ isActive: false }).where(eq(gameDeployments.gameId, gameId));
|
|
28208
|
+
await tx.update(gameDeployments).set({ isActive: false }).where(and(eq(gameDeployments.gameId, record.gameId), eq(gameDeployments.target, record.target)));
|
|
27554
28209
|
await tx.insert(gameDeployments).values({
|
|
27555
|
-
gameId,
|
|
27556
|
-
deploymentId,
|
|
28210
|
+
gameId: record.gameId,
|
|
28211
|
+
deploymentId: record.deploymentId,
|
|
27557
28212
|
provider: "cloudflare",
|
|
27558
|
-
|
|
27559
|
-
|
|
27560
|
-
|
|
28213
|
+
target: record.target,
|
|
28214
|
+
url: record.url,
|
|
28215
|
+
codeHash: record.codeHash,
|
|
28216
|
+
resources: record.resources,
|
|
27561
28217
|
isActive: true
|
|
27562
28218
|
});
|
|
27563
28219
|
});
|
|
27564
28220
|
}
|
|
28221
|
+
async notifyDeploymentFailure(failure) {
|
|
28222
|
+
await this.deps.alerts.notifyDeploymentFailure(failure).catch(catchAttrs("alerts.delivery", { "app.alerts.type": "deployment_failure" }));
|
|
28223
|
+
}
|
|
27565
28224
|
}
|
|
27566
28225
|
var init_deploy_service = __esm(() => {
|
|
27567
28226
|
init_drizzle_orm();
|
|
27568
28227
|
init_playcademy();
|
|
27569
28228
|
init_src();
|
|
28229
|
+
init_helpers_index();
|
|
27570
28230
|
init_tables_index();
|
|
27571
28231
|
init_spans();
|
|
27572
28232
|
init_tunnel();
|
|
27573
28233
|
init_errors();
|
|
28234
|
+
init_dashboard_util();
|
|
27574
28235
|
init_deployment_util();
|
|
28236
|
+
init_worker_keys_util();
|
|
27575
28237
|
});
|
|
27576
28238
|
|
|
27577
28239
|
// ../api-core/src/services/developer.service.ts
|
|
@@ -27816,20 +28478,6 @@ var init_game_member_service = __esm(() => {
|
|
|
27816
28478
|
init_spans();
|
|
27817
28479
|
init_errors();
|
|
27818
28480
|
});
|
|
27819
|
-
// ../data/src/domains/timeback/helpers.ts
|
|
27820
|
-
function isActiveGameTimebackIntegrationStatus(statusColumn = gameTimebackIntegrations.status) {
|
|
27821
|
-
return sql`${statusColumn} IS DISTINCT FROM ${DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS}`;
|
|
27822
|
-
}
|
|
27823
|
-
var ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS = "active", DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS = "deactivated";
|
|
27824
|
-
var init_helpers2 = __esm(() => {
|
|
27825
|
-
init_drizzle_orm();
|
|
27826
|
-
init_table7();
|
|
27827
|
-
});
|
|
27828
|
-
|
|
27829
|
-
// ../data/src/helpers.index.ts
|
|
27830
|
-
var init_helpers_index = __esm(() => {
|
|
27831
|
-
init_helpers2();
|
|
27832
|
-
});
|
|
27833
28481
|
|
|
27834
28482
|
// ../utils/src/fns.ts
|
|
27835
28483
|
function sleep(ms) {
|
|
@@ -28273,6 +28921,7 @@ var init_game_service = __esm(() => {
|
|
|
28273
28921
|
init_errors();
|
|
28274
28922
|
init_deployment_util();
|
|
28275
28923
|
init_timeback_util();
|
|
28924
|
+
init_worker_keys_util();
|
|
28276
28925
|
inFlightManifestFetches = new Map;
|
|
28277
28926
|
GameService = class GameService {
|
|
28278
28927
|
deps;
|
|
@@ -28459,7 +29108,7 @@ var init_game_service = __esm(() => {
|
|
|
28459
29108
|
GameService.recordGameShape(game2);
|
|
28460
29109
|
return game2;
|
|
28461
29110
|
}
|
|
28462
|
-
async getBySlug(slug, caller) {
|
|
29111
|
+
async getBySlug(slug, caller, options) {
|
|
28463
29112
|
const db2 = this.deps.db;
|
|
28464
29113
|
const game2 = await db2.query.games.findFirst({
|
|
28465
29114
|
where: eq(games.slug, slug)
|
|
@@ -28467,7 +29116,9 @@ var init_game_service = __esm(() => {
|
|
|
28467
29116
|
if (!game2) {
|
|
28468
29117
|
throw new NotFoundError("Game", slug);
|
|
28469
29118
|
}
|
|
28470
|
-
|
|
29119
|
+
if (!options?.scopeAuthorized) {
|
|
29120
|
+
await this.enforceVisibility(game2, caller, slug);
|
|
29121
|
+
}
|
|
28471
29122
|
GameService.recordGameShape(game2);
|
|
28472
29123
|
return game2;
|
|
28473
29124
|
}
|
|
@@ -28644,6 +29295,9 @@ var init_game_service = __esm(() => {
|
|
|
28644
29295
|
await this.validateDeveloperAccess(user, gameId);
|
|
28645
29296
|
} else {
|
|
28646
29297
|
this.validateDeveloperStatus(user);
|
|
29298
|
+
if (slug.endsWith(DASHBOARD_WORKER_SUFFIX)) {
|
|
29299
|
+
throw new ValidationError(`Game slugs may not end with '${DASHBOARD_WORKER_SUFFIX}' — it is reserved for dashboard workers`);
|
|
29300
|
+
}
|
|
28647
29301
|
}
|
|
28648
29302
|
const gameDataForDb = {
|
|
28649
29303
|
displayName: data.displayName,
|
|
@@ -28770,15 +29424,21 @@ var init_game_service = __esm(() => {
|
|
|
28770
29424
|
if (!gameToDelete?.slug) {
|
|
28771
29425
|
throw new NotFoundError("Game", gameId);
|
|
28772
29426
|
}
|
|
28773
|
-
const activeDeployment = await
|
|
28774
|
-
|
|
28775
|
-
|
|
28776
|
-
|
|
28777
|
-
|
|
28778
|
-
|
|
28779
|
-
|
|
28780
|
-
|
|
28781
|
-
|
|
29427
|
+
const [activeDeployment, dashboardDeployment, customHostnames] = await Promise.all([
|
|
29428
|
+
db2.query.gameDeployments.findFirst({
|
|
29429
|
+
where: activeDeploymentWhere(gameId, "game"),
|
|
29430
|
+
columns: { deploymentId: true, provider: true, resources: true }
|
|
29431
|
+
}),
|
|
29432
|
+
db2.query.gameDeployments.findFirst({
|
|
29433
|
+
where: activeDeploymentWhere(gameId, "dashboard"),
|
|
29434
|
+
columns: { deploymentId: true, provider: true, resources: true }
|
|
29435
|
+
}),
|
|
29436
|
+
db2.select({
|
|
29437
|
+
hostname: gameCustomHostnames.hostname,
|
|
29438
|
+
cloudflareId: gameCustomHostnames.cloudflareId,
|
|
29439
|
+
environment: gameCustomHostnames.environment
|
|
29440
|
+
}).from(gameCustomHostnames).where(eq(gameCustomHostnames.gameId, gameId))
|
|
29441
|
+
]);
|
|
28782
29442
|
const result = await db2.delete(games).where(eq(games.id, gameId)).returning({ id: games.id });
|
|
28783
29443
|
if (result.length === 0) {
|
|
28784
29444
|
throw new NotFoundError("Game", gameId);
|
|
@@ -28822,6 +29482,22 @@ var init_game_service = __esm(() => {
|
|
|
28822
29482
|
setAttribute("app.game.api_key_cleanup_error", errorMessage(error));
|
|
28823
29483
|
}
|
|
28824
29484
|
}
|
|
29485
|
+
if (dashboardDeployment?.provider === "cloudflare" && this.deps.cloudflare) {
|
|
29486
|
+
const dashboardAssetBuckets = dashboardDeployment.resources?.r2?.filter((bucket) => bucket.kind === "assets") ?? [];
|
|
29487
|
+
try {
|
|
29488
|
+
await this.deps.cloudflare.delete(dashboardDeployment.deploymentId, {
|
|
29489
|
+
deleteBindings: dashboardAssetBuckets.length > 0,
|
|
29490
|
+
resources: dashboardAssetBuckets.length > 0 ? { r2: dashboardAssetBuckets } : undefined
|
|
29491
|
+
});
|
|
29492
|
+
setAttribute("app.game.dashboard_cleanup", "succeeded");
|
|
29493
|
+
} catch (error) {
|
|
29494
|
+
setAttributes({
|
|
29495
|
+
"app.game.dashboard_cleanup": "failed",
|
|
29496
|
+
"app.game.dashboard_cleanup_error": errorMessage(error)
|
|
29497
|
+
});
|
|
29498
|
+
}
|
|
29499
|
+
}
|
|
29500
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, gameToDelete.slug);
|
|
28825
29501
|
const corsOrigin = GameService.safeOrigin(gameToDelete);
|
|
28826
29502
|
if (this.deps.corsKvs && corsOrigin) {
|
|
28827
29503
|
setAttribute("app.cors_kvs.origin", corsOrigin);
|
|
@@ -28945,7 +29621,7 @@ class LogsService {
|
|
|
28945
29621
|
}
|
|
28946
29622
|
async generateToken(user, slug, sstStage) {
|
|
28947
29623
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
28948
|
-
const workerId =
|
|
29624
|
+
const workerId = getGameDeploymentId(slug, sstStage);
|
|
28949
29625
|
const token = await this.deps.mintLogStreamToken(user.id, workerId);
|
|
28950
29626
|
setAttribute("app.logs.worker_id", workerId);
|
|
28951
29627
|
return { token, workerId };
|
|
@@ -28965,7 +29641,8 @@ function createGameServices(deps) {
|
|
|
28965
29641
|
cache,
|
|
28966
29642
|
cloudflare: cloudflare2,
|
|
28967
29643
|
corsKvs,
|
|
28968
|
-
deleteApiKeyByName: auth2.deleteApiKeyByName.bind(auth2)
|
|
29644
|
+
deleteApiKeyByName: auth2.deleteApiKeyByName.bind(auth2),
|
|
29645
|
+
deleteApiKeysByName: auth2.deleteApiKeysByName.bind(auth2)
|
|
28969
29646
|
});
|
|
28970
29647
|
const gameMember = new GameMemberService({
|
|
28971
29648
|
db: db2,
|
|
@@ -28978,6 +29655,7 @@ function createGameServices(deps) {
|
|
|
28978
29655
|
cloudflare: cloudflare2,
|
|
28979
29656
|
createAuthApiKey: auth2.createApiKey.bind(auth2),
|
|
28980
29657
|
deleteAuthApiKey: auth2.deleteApiKey.bind(auth2),
|
|
29658
|
+
deleteApiKeysByName: auth2.deleteApiKeysByName.bind(auth2),
|
|
28981
29659
|
alerts,
|
|
28982
29660
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug)
|
|
28983
29661
|
});
|
|
@@ -28987,14 +29665,20 @@ function createGameServices(deps) {
|
|
|
28987
29665
|
storage,
|
|
28988
29666
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug),
|
|
28989
29667
|
runDeploy: (slug, request, user, uploadDeps, extractZip) => deploy.deploy(slug, request, user, uploadDeps, extractZip),
|
|
28990
|
-
notifyDeploymentFailure: (
|
|
29668
|
+
notifyDeploymentFailure: (failure) => deploy.notifyDeploymentFailure(failure)
|
|
28991
29669
|
});
|
|
28992
29670
|
const logs = new LogsService({
|
|
28993
29671
|
mintLogStreamToken: auth2.mintLogStreamToken.bind(auth2),
|
|
28994
29672
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug)
|
|
28995
29673
|
});
|
|
29674
|
+
const dashboard2 = new DashboardService({
|
|
29675
|
+
db: db2,
|
|
29676
|
+
hashPassword: auth2.hashPassword.bind(auth2),
|
|
29677
|
+
verifyPassword: auth2.verifyPassword.bind(auth2),
|
|
29678
|
+
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug)
|
|
29679
|
+
});
|
|
28996
29680
|
return {
|
|
28997
|
-
services: { game: game2, gameMember, developer, deploy, deployJobs, logs },
|
|
29681
|
+
services: { game: game2, gameMember, developer, deploy, deployJobs, logs, dashboard: dashboard2 },
|
|
28998
29682
|
validators: {
|
|
28999
29683
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug),
|
|
29000
29684
|
validateDeveloperAccess: (user, gameId) => game2.validateDeveloperAccess(user, gameId),
|
|
@@ -29004,6 +29688,7 @@ function createGameServices(deps) {
|
|
|
29004
29688
|
};
|
|
29005
29689
|
}
|
|
29006
29690
|
var init_game2 = __esm(() => {
|
|
29691
|
+
init_dashboard_service();
|
|
29007
29692
|
init_deploy_job_service();
|
|
29008
29693
|
init_deploy_service();
|
|
29009
29694
|
init_developer_service();
|
|
@@ -29188,12 +29873,25 @@ class AlertsService {
|
|
|
29188
29873
|
embed.setFooter("Playcademy Developer Platform").setTimestamp();
|
|
29189
29874
|
await this.sendAlert(discord, embed.build());
|
|
29190
29875
|
}
|
|
29876
|
+
async notifyDashboardDeployment(dashboard2) {
|
|
29877
|
+
const discord = this.recordAlert("dashboard_deployment");
|
|
29878
|
+
if (!discord) {
|
|
29879
|
+
return;
|
|
29880
|
+
}
|
|
29881
|
+
const embed = new DiscordEmbedBuilder().setTitle("\uD83D\uDCCA Dashboard Deployed").setDescription(`The dashboard for **${dashboard2.displayName || dashboard2.slug}** has been deployed (**${this.getEnvironment()}**).`).setColor(DiscordColors.GREEN).addField("Slug", dashboard2.slug, true).addField("URL", dashboard2.url, false);
|
|
29882
|
+
if (dashboard2.developer) {
|
|
29883
|
+
embed.addField("Developer", dashboard2.developer.email || dashboard2.developer.id, true);
|
|
29884
|
+
}
|
|
29885
|
+
embed.setFooter("Playcademy Developer Platform").setTimestamp();
|
|
29886
|
+
await this.sendAlert(discord, embed.build());
|
|
29887
|
+
}
|
|
29191
29888
|
async notifyDeploymentFailure(failure) {
|
|
29192
29889
|
const discord = this.recordAlert("deployment_failure");
|
|
29193
29890
|
if (!discord) {
|
|
29194
29891
|
return;
|
|
29195
29892
|
}
|
|
29196
|
-
const
|
|
29893
|
+
const [title, subject] = failure.target === "dashboard" ? ["❌ Dashboard Deployment Failed", "Dashboard deployment"] : ["❌ Deployment Failed", "Deployment"];
|
|
29894
|
+
const embed = new DiscordEmbedBuilder().setTitle(title).setDescription(`${subject} failed for **${failure.displayName || failure.slug}** (**${this.getEnvironment()}**).`).setColor(DiscordColors.RED).addField("Slug", failure.slug, true);
|
|
29197
29895
|
if (failure.developer) {
|
|
29198
29896
|
embed.addField("Developer", failure.developer.email || failure.developer.id, true);
|
|
29199
29897
|
}
|
|
@@ -29208,6 +29906,14 @@ class AlertsService {
|
|
|
29208
29906
|
const embed = new DiscordEmbedBuilder().setTitle("\uD83D\uDDD1️ Game Deleted").setDescription(`**${game2.displayName || game2.slug}** has been deleted (**${this.getEnvironment()}**).`).setColor(DiscordColors.ORANGE).addField("Slug", game2.slug, true).addField("Developer", game2.developer.email || game2.developer.id, true).setFooter("Playcademy Developer Platform").setTimestamp().build();
|
|
29209
29907
|
await this.sendAlert(discord, embed);
|
|
29210
29908
|
}
|
|
29909
|
+
async notifyDashboardRemoval(dashboard2) {
|
|
29910
|
+
const discord = this.recordAlert("dashboard_removal");
|
|
29911
|
+
if (!discord) {
|
|
29912
|
+
return;
|
|
29913
|
+
}
|
|
29914
|
+
const embed = new DiscordEmbedBuilder().setTitle("\uD83D\uDDD1️ Dashboard Removed").setDescription(`The dashboard for **${dashboard2.displayName || dashboard2.slug}** has been removed (**${this.getEnvironment()}**).`).setColor(DiscordColors.ORANGE).addField("Slug", dashboard2.slug, true).addField("Developer", dashboard2.developer.email || dashboard2.developer.id, true).setFooter("Playcademy Developer Platform").setTimestamp().build();
|
|
29915
|
+
await this.sendAlert(discord, embed);
|
|
29916
|
+
}
|
|
29211
29917
|
async notifySeedFailure(failure) {
|
|
29212
29918
|
const discord = this.recordAlert("seed_failure");
|
|
29213
29919
|
if (!discord) {
|
|
@@ -29373,6 +30079,7 @@ class KVBackupService {
|
|
|
29373
30079
|
async getTargets(gameSlug) {
|
|
29374
30080
|
const conditions2 = [
|
|
29375
30081
|
eq(gameDeployments.isActive, true),
|
|
30082
|
+
eq(gameDeployments.target, "game"),
|
|
29376
30083
|
eq(gameDeployments.provider, "cloudflare")
|
|
29377
30084
|
];
|
|
29378
30085
|
if (gameSlug) {
|
|
@@ -29599,7 +30306,7 @@ class BucketService {
|
|
|
29599
30306
|
return extensionIndex > 0 ? fileName.slice(extensionIndex + 1).toLowerCase() : "(none)";
|
|
29600
30307
|
}
|
|
29601
30308
|
getBucketName(slug) {
|
|
29602
|
-
return
|
|
30309
|
+
return getGameDeploymentId(slug, this.deps.sstStage);
|
|
29603
30310
|
}
|
|
29604
30311
|
async listFiles(slug, user, prefix) {
|
|
29605
30312
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
@@ -29688,6 +30395,32 @@ class DatabaseService {
|
|
|
29688
30395
|
}
|
|
29689
30396
|
return d1;
|
|
29690
30397
|
}
|
|
30398
|
+
async syncDashboardD1Binding(gameId, d1ResourceName, databaseId) {
|
|
30399
|
+
const dashboardDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
30400
|
+
where: activeDeploymentWhere(gameId, "dashboard"),
|
|
30401
|
+
columns: { id: true, deploymentId: true, resources: true }
|
|
30402
|
+
});
|
|
30403
|
+
if (!dashboardDeployment || !this.deps.cloudflare) {
|
|
30404
|
+
return;
|
|
30405
|
+
}
|
|
30406
|
+
try {
|
|
30407
|
+
await this.deps.cloudflare.updateD1Binding(dashboardDeployment.deploymentId, databaseId);
|
|
30408
|
+
if (dashboardDeployment.resources?.d1?.length) {
|
|
30409
|
+
const updatedResources = {
|
|
30410
|
+
...dashboardDeployment.resources,
|
|
30411
|
+
d1: dashboardDeployment.resources.d1.map((dbResource) => dbResource.name === d1ResourceName ? { ...dbResource, id: databaseId } : dbResource)
|
|
30412
|
+
};
|
|
30413
|
+
await this.deps.db.update(gameDeployments).set({ resources: updatedResources }).where(eq(gameDeployments.id, dashboardDeployment.id));
|
|
30414
|
+
}
|
|
30415
|
+
setAttribute("app.database.dashboard_binding", "updated");
|
|
30416
|
+
} catch (error) {
|
|
30417
|
+
addEvent("database.dashboard_binding_sync_failed", {
|
|
30418
|
+
"exception.type": errorType(error),
|
|
30419
|
+
"app.error.message": errorMessage(error),
|
|
30420
|
+
"app.deploy.deployment_id": dashboardDeployment.deploymentId
|
|
30421
|
+
});
|
|
30422
|
+
}
|
|
30423
|
+
}
|
|
29691
30424
|
async reset(slug, user, schema2) {
|
|
29692
30425
|
setAttributes({
|
|
29693
30426
|
"app.database.operation": "reset",
|
|
@@ -29696,7 +30429,7 @@ class DatabaseService {
|
|
|
29696
30429
|
});
|
|
29697
30430
|
const d1 = this.getD1();
|
|
29698
30431
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
29699
|
-
const deploymentId =
|
|
30432
|
+
const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
29700
30433
|
try {
|
|
29701
30434
|
const databaseId = await d1.reset(deploymentId);
|
|
29702
30435
|
setAttribute("app.database.id", databaseId);
|
|
@@ -29712,7 +30445,7 @@ class DatabaseService {
|
|
|
29712
30445
|
setAttribute("app.database.binding", "skipped_no_provider");
|
|
29713
30446
|
}
|
|
29714
30447
|
const activeDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
29715
|
-
where:
|
|
30448
|
+
where: activeDeploymentWhere(game2.id),
|
|
29716
30449
|
columns: { id: true, resources: true }
|
|
29717
30450
|
});
|
|
29718
30451
|
setAttribute("app.database.active_deployment_found", Boolean(activeDeployment));
|
|
@@ -29723,6 +30456,7 @@ class DatabaseService {
|
|
|
29723
30456
|
};
|
|
29724
30457
|
await this.deps.db.update(gameDeployments).set({ resources: updatedResources }).where(eq(gameDeployments.id, activeDeployment.id));
|
|
29725
30458
|
}
|
|
30459
|
+
await this.syncDashboardD1Binding(game2.id, deploymentId, databaseId);
|
|
29726
30460
|
setAttributes({
|
|
29727
30461
|
"app.database.deployment_id": deploymentId,
|
|
29728
30462
|
"app.database.schema_pushed": schemaPushed
|
|
@@ -29746,6 +30480,7 @@ class DatabaseService {
|
|
|
29746
30480
|
}
|
|
29747
30481
|
var init_database_service = __esm(() => {
|
|
29748
30482
|
init_drizzle_orm();
|
|
30483
|
+
init_helpers_index();
|
|
29749
30484
|
init_tables_index();
|
|
29750
30485
|
init_spans();
|
|
29751
30486
|
init_errors();
|
|
@@ -29989,7 +30724,7 @@ class KVService {
|
|
|
29989
30724
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
29990
30725
|
const db2 = this.deps.db;
|
|
29991
30726
|
const deployment = await db2.query.gameDeployments.findFirst({
|
|
29992
|
-
where:
|
|
30727
|
+
where: activeDeploymentWhere(game2.id),
|
|
29993
30728
|
columns: { resources: true }
|
|
29994
30729
|
});
|
|
29995
30730
|
if (!deployment?.resources?.kv?.length) {
|
|
@@ -30110,8 +30845,7 @@ class KVService {
|
|
|
30110
30845
|
}
|
|
30111
30846
|
}
|
|
30112
30847
|
var init_kv_service = __esm(() => {
|
|
30113
|
-
|
|
30114
|
-
init_tables_index();
|
|
30848
|
+
init_helpers_index();
|
|
30115
30849
|
init_spans();
|
|
30116
30850
|
init_errors();
|
|
30117
30851
|
});
|
|
@@ -30128,13 +30862,13 @@ class SecretsService {
|
|
|
30128
30862
|
}
|
|
30129
30863
|
return this.deps.cloudflare;
|
|
30130
30864
|
}
|
|
30131
|
-
|
|
30132
|
-
return
|
|
30865
|
+
getGameDeploymentId(slug) {
|
|
30866
|
+
return getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
30133
30867
|
}
|
|
30134
30868
|
async listKeys(slug, user) {
|
|
30135
30869
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30136
30870
|
const cf = this.getCloudflare();
|
|
30137
|
-
const deploymentId = this.
|
|
30871
|
+
const deploymentId = this.getGameDeploymentId(slug);
|
|
30138
30872
|
try {
|
|
30139
30873
|
const allKeys = await cf.listSecrets(deploymentId);
|
|
30140
30874
|
const userKeys = allKeys.filter((k) => k.startsWith(SECRETS_PREFIX)).map((k) => k.slice(SECRETS_PREFIX.length));
|
|
@@ -30160,7 +30894,7 @@ class SecretsService {
|
|
|
30160
30894
|
async setSecrets(slug, newSecrets, user) {
|
|
30161
30895
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30162
30896
|
const cf = this.getCloudflare();
|
|
30163
|
-
const deploymentId = this.
|
|
30897
|
+
const deploymentId = this.getGameDeploymentId(slug);
|
|
30164
30898
|
const secretKeys = Object.keys(newSecrets);
|
|
30165
30899
|
if (secretKeys.length === 0) {
|
|
30166
30900
|
throw new ValidationError("At least one secret must be provided");
|
|
@@ -30213,7 +30947,7 @@ class SecretsService {
|
|
|
30213
30947
|
}
|
|
30214
30948
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30215
30949
|
const cf = this.getCloudflare();
|
|
30216
|
-
const deploymentId = this.
|
|
30950
|
+
const deploymentId = this.getGameDeploymentId(slug);
|
|
30217
30951
|
try {
|
|
30218
30952
|
const prefixedKey = `${SECRETS_PREFIX}${key}`;
|
|
30219
30953
|
const existingKeys = await cf.listSecrets(deploymentId);
|
|
@@ -30250,27 +30984,7 @@ var init_secrets_service = __esm(() => {
|
|
|
30250
30984
|
init_deployment_util();
|
|
30251
30985
|
INTERNAL_SECRET_KEYS = ["PLAYCADEMY_API_KEY", "GAME_ID", "PLAYCADEMY_BASE_URL"];
|
|
30252
30986
|
});
|
|
30253
|
-
|
|
30254
|
-
// ../edge-play/src/constants.ts
|
|
30255
|
-
var ASSET_ROUTE_PREFIX = "/api/assets/", ROUTES;
|
|
30256
|
-
var init_constants3 = __esm(() => {
|
|
30257
|
-
init_src();
|
|
30258
|
-
ROUTES = {
|
|
30259
|
-
INDEX: "/api",
|
|
30260
|
-
HEALTH: "/api/health",
|
|
30261
|
-
ASSETS: `${ASSET_ROUTE_PREFIX}*`,
|
|
30262
|
-
TIMEBACK: {
|
|
30263
|
-
END_ACTIVITY: `/api${TIMEBACK_ROUTES.END_ACTIVITY}`,
|
|
30264
|
-
GET_XP: `/api${TIMEBACK_ROUTES.GET_XP}`,
|
|
30265
|
-
GET_MASTERY: `/api${TIMEBACK_ROUTES.GET_MASTERY}`,
|
|
30266
|
-
GET_HIGHEST_GRADE_MASTERED: `/api${TIMEBACK_ROUTES.GET_HIGHEST_GRADE_MASTERED}`,
|
|
30267
|
-
HEARTBEAT: `/api${TIMEBACK_ROUTES.HEARTBEAT}`,
|
|
30268
|
-
ADVANCE_COURSE: `/api${TIMEBACK_ROUTES.ADVANCE_COURSE}`,
|
|
30269
|
-
UNENROLL_COURSE: `/api${TIMEBACK_ROUTES.UNENROLL_COURSE}`
|
|
30270
|
-
}
|
|
30271
|
-
};
|
|
30272
|
-
});
|
|
30273
|
-
// ../edge-play/src/entry/setup.ts
|
|
30987
|
+
// ../edge-play/src/game/setup.ts
|
|
30274
30988
|
function prefixSecrets(secrets) {
|
|
30275
30989
|
const prefixed = {};
|
|
30276
30990
|
for (const [key, value] of Object.entries(secrets)) {
|
|
@@ -30280,7 +30994,6 @@ function prefixSecrets(secrets) {
|
|
|
30280
30994
|
}
|
|
30281
30995
|
var init_setup2 = __esm(() => {
|
|
30282
30996
|
init_src();
|
|
30283
|
-
init_constants3();
|
|
30284
30997
|
});
|
|
30285
30998
|
|
|
30286
30999
|
// ../api-core/src/services/seed.service.ts
|
|
@@ -30315,7 +31028,7 @@ class SeedService {
|
|
|
30315
31028
|
async seed(slug, code, user, secrets) {
|
|
30316
31029
|
const cf = this.getCloudflare();
|
|
30317
31030
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30318
|
-
const deploymentId =
|
|
31031
|
+
const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
30319
31032
|
const uniqueSuffix = Date.now().toString(36);
|
|
30320
31033
|
const seedDeploymentId = `seed-${deploymentId}-${uniqueSuffix}`;
|
|
30321
31034
|
setAttributes({
|
|
@@ -30806,7 +31519,7 @@ var init_emoji = __esm(() => {
|
|
|
30806
31519
|
});
|
|
30807
31520
|
|
|
30808
31521
|
// ../data/src/domains/game/schemas.ts
|
|
30809
|
-
var HttpUrlSchema, GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SeedRequestSchema, SchemaInfoSchema, DatabaseResetRequestSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployRequestSchema;
|
|
31522
|
+
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;
|
|
30810
31523
|
var init_schemas2 = __esm(() => {
|
|
30811
31524
|
init_drizzle_zod();
|
|
30812
31525
|
init_esm();
|
|
@@ -30917,6 +31630,20 @@ var init_schemas2 = __esm(() => {
|
|
|
30917
31630
|
UpdateGameMemberRoleSchema = exports_external.object({
|
|
30918
31631
|
role: exports_external.enum(gameMemberRoleEnum.enumValues)
|
|
30919
31632
|
}).strict();
|
|
31633
|
+
AddGameDashboardUserSchema = exports_external.object({
|
|
31634
|
+
email: exports_external.string().email().max(255),
|
|
31635
|
+
displayName: exports_external.string().min(1).max(255).optional(),
|
|
31636
|
+
role: exports_external.enum(gameDashboardUserRoleEnum.enumValues).optional().default(DASHBOARD_USER_ROLES.VIEWER)
|
|
31637
|
+
}).strict();
|
|
31638
|
+
VerifyGameDashboardLoginSchema = exports_external.object({
|
|
31639
|
+
email: exports_external.string().email().max(255),
|
|
31640
|
+
password: exports_external.string().min(1).max(1024)
|
|
31641
|
+
}).strict();
|
|
31642
|
+
AcceptGameDashboardInviteSchema = exports_external.object({
|
|
31643
|
+
token: exports_external.string().min(1).max(255),
|
|
31644
|
+
password: exports_external.string().min(8, "Password must be at least 8 characters").max(1024, "Password must be at most 1024 characters")
|
|
31645
|
+
}).strict();
|
|
31646
|
+
AcceptGameDashboardResetSchema = AcceptGameDashboardInviteSchema;
|
|
30920
31647
|
ALLOWED_UPLOAD_EXTENSIONS = [".zip", ".js"];
|
|
30921
31648
|
InitiateUploadSchema = exports_external.object({
|
|
30922
31649
|
fileName: exports_external.string().min(1).refine((name2) => ALLOWED_UPLOAD_EXTENSIONS.some((ext) => name2.endsWith(ext)), {
|
|
@@ -30951,6 +31678,7 @@ var init_schemas2 = __esm(() => {
|
|
|
30951
31678
|
}))
|
|
30952
31679
|
});
|
|
30953
31680
|
DeployRequestSchema = exports_external.object({
|
|
31681
|
+
target: exports_external.enum(deploymentTargetEnum.enumValues).optional().default("game"),
|
|
30954
31682
|
uploadToken: exports_external.string().optional(),
|
|
30955
31683
|
code: exports_external.string().optional(),
|
|
30956
31684
|
codeUploadToken: exports_external.string().optional(),
|
|
@@ -30986,6 +31714,9 @@ var init_schemas2 = __esm(() => {
|
|
|
30986
31714
|
}).refine((data) => !(data.code && data.codeUploadToken), {
|
|
30987
31715
|
message: "Specify either code or codeUploadToken, not both",
|
|
30988
31716
|
path: ["codeUploadToken"]
|
|
31717
|
+
}).refine((data) => !(data.target === "dashboard" && (data.schema || data.bindings)), {
|
|
31718
|
+
message: "Dashboard deployments cannot include schema or bindings — they attach to the game deployment’s existing resources",
|
|
31719
|
+
path: ["target"]
|
|
30989
31720
|
});
|
|
30990
31721
|
});
|
|
30991
31722
|
|
|
@@ -74417,6 +75148,17 @@ function isValidUUID(value) {
|
|
|
74417
75148
|
}
|
|
74418
75149
|
return UUID_REGEX.test(value);
|
|
74419
75150
|
}
|
|
75151
|
+
async function deterministicUUID(input) {
|
|
75152
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
|
|
75153
|
+
const bytes = new Uint8Array(digest).slice(0, 16);
|
|
75154
|
+
bytes[6] = bytes[6] & 15 | 80;
|
|
75155
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
75156
|
+
const hex3 = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
75157
|
+
return `${hex3.slice(0, 8)}-${hex3.slice(8, 12)}-${hex3.slice(12, 16)}-${hex3.slice(16, 20)}-${hex3.slice(20)}`;
|
|
75158
|
+
}
|
|
75159
|
+
async function localGameId(slug) {
|
|
75160
|
+
return deterministicUUID(`playcademy:local-game:${slug}`);
|
|
75161
|
+
}
|
|
74420
75162
|
var UUID_REGEX;
|
|
74421
75163
|
var init_uuid2 = __esm(() => {
|
|
74422
75164
|
UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
@@ -76818,7 +77560,7 @@ function deriveTimebackCourseLevelFromGrade(grade) {
|
|
|
76818
77560
|
return TIMEBACK_COURSE_DEFAULTS.level.high;
|
|
76819
77561
|
}
|
|
76820
77562
|
var ONEROSTER_STATUS2, SCORE_STATUS2, CACHE_DEFAULTS3, RESOURCE_DEFAULTS3;
|
|
76821
|
-
var
|
|
77563
|
+
var init_constants3 = __esm(() => {
|
|
76822
77564
|
init_src();
|
|
76823
77565
|
ONEROSTER_STATUS2 = {
|
|
76824
77566
|
active: "active",
|
|
@@ -77792,7 +78534,7 @@ function qtiIdCandidates(parentLineItem, resource) {
|
|
|
77792
78534
|
}
|
|
77793
78535
|
var GRADE_LEVEL_TEST_TYPES, naturalTitleSort;
|
|
77794
78536
|
var init_timeback_grade_level_results_util = __esm(() => {
|
|
77795
|
-
|
|
78537
|
+
init_constants3();
|
|
77796
78538
|
GRADE_LEVEL_TEST_TYPES = [
|
|
77797
78539
|
"placement",
|
|
77798
78540
|
"test out",
|
|
@@ -77987,7 +78729,7 @@ async function upsertMasteryCompletionEntry(params) {
|
|
|
77987
78729
|
}
|
|
77988
78730
|
var init_timeback_mastery_completion_util = __esm(async () => {
|
|
77989
78731
|
init_spans();
|
|
77990
|
-
|
|
78732
|
+
init_constants3();
|
|
77991
78733
|
init_utils6();
|
|
77992
78734
|
await init_errors8();
|
|
77993
78735
|
});
|
|
@@ -78683,7 +79425,7 @@ class TimebackAdminService {
|
|
|
78683
79425
|
columns: { slug: true }
|
|
78684
79426
|
}),
|
|
78685
79427
|
this.deps.db.query.gameDeployments.findFirst({
|
|
78686
|
-
where:
|
|
79428
|
+
where: activeDeploymentWhere(gameId),
|
|
78687
79429
|
columns: { url: true }
|
|
78688
79430
|
})
|
|
78689
79431
|
]);
|
|
@@ -79764,7 +80506,7 @@ var init_timeback_admin_service = __esm(async () => {
|
|
|
79764
80506
|
init_schemas_index();
|
|
79765
80507
|
init_tables_index();
|
|
79766
80508
|
init_spans();
|
|
79767
|
-
|
|
80509
|
+
init_constants3();
|
|
79768
80510
|
init_types2();
|
|
79769
80511
|
init_utils6();
|
|
79770
80512
|
init_src4();
|
|
@@ -80239,7 +80981,7 @@ function timebackConfigMatchesCreateIntegrationRequest(config4, request) {
|
|
|
80239
80981
|
return subject === request.subject && grade === request.grade && config4.course.title === request.title && config4.course.courseCode === request.courseCode && config4.course.level === requestedLevel && (getTotalXpFromTimebackConfig(config4) ?? null) === request.totalXp && (getMasterableUnitsFromTimebackConfig(config4) ?? null) === request.masterableUnits;
|
|
80240
80982
|
}
|
|
80241
80983
|
var init_timeback_create_integration_util = __esm(() => {
|
|
80242
|
-
|
|
80984
|
+
init_constants3();
|
|
80243
80985
|
init_types2();
|
|
80244
80986
|
init_timeback_util();
|
|
80245
80987
|
});
|
|
@@ -83085,6 +83827,19 @@ function createSandboxAuthProvider() {
|
|
|
83085
83827
|
}
|
|
83086
83828
|
return null;
|
|
83087
83829
|
},
|
|
83830
|
+
async deleteApiKeysByName(name3) {
|
|
83831
|
+
const deleted = [];
|
|
83832
|
+
for (const [id, key] of sandboxApiKeys.entries()) {
|
|
83833
|
+
if (key.name === name3) {
|
|
83834
|
+
sandboxApiKeys.delete(id);
|
|
83835
|
+
deleted.push(id);
|
|
83836
|
+
}
|
|
83837
|
+
}
|
|
83838
|
+
if (deleted.length > 0) {
|
|
83839
|
+
log.debug("[SandboxAuthProvider] Deleted API keys by name", { name: name3, deleted });
|
|
83840
|
+
}
|
|
83841
|
+
return deleted;
|
|
83842
|
+
},
|
|
83088
83843
|
async mintGameToken(gameId, userId) {
|
|
83089
83844
|
const header = btoa(JSON.stringify({ alg: "none", typ: "sandbox" }));
|
|
83090
83845
|
const exp = Date.now() + 15 * 60 * 1000;
|
|
@@ -83163,6 +83918,12 @@ function createSandboxAuthProvider() {
|
|
|
83163
83918
|
} catch {
|
|
83164
83919
|
return null;
|
|
83165
83920
|
}
|
|
83921
|
+
},
|
|
83922
|
+
async hashPassword(password) {
|
|
83923
|
+
return `sandbox:${btoa(password)}`;
|
|
83924
|
+
},
|
|
83925
|
+
async verifyPassword(data) {
|
|
83926
|
+
return data.hash === `sandbox:${btoa(data.password)}`;
|
|
83166
83927
|
}
|
|
83167
83928
|
};
|
|
83168
83929
|
}
|
|
@@ -83447,7 +84208,7 @@ var init_http_exception = () => {};
|
|
|
83447
84208
|
|
|
83448
84209
|
// ../../node_modules/.bun/hono@4.10.7/node_modules/hono/dist/request/constants.js
|
|
83449
84210
|
var GET_MATCH_RESULT;
|
|
83450
|
-
var
|
|
84211
|
+
var init_constants4 = __esm(() => {
|
|
83451
84212
|
GET_MATCH_RESULT = Symbol();
|
|
83452
84213
|
});
|
|
83453
84214
|
|
|
@@ -83711,7 +84472,7 @@ var init_url = __esm(() => {
|
|
|
83711
84472
|
var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_), HonoRequest;
|
|
83712
84473
|
var init_request = __esm(() => {
|
|
83713
84474
|
init_http_exception();
|
|
83714
|
-
|
|
84475
|
+
init_constants4();
|
|
83715
84476
|
init_body();
|
|
83716
84477
|
init_url();
|
|
83717
84478
|
HonoRequest = class {
|
|
@@ -84041,7 +84802,7 @@ var init_router = __esm(() => {
|
|
|
84041
84802
|
|
|
84042
84803
|
// ../../node_modules/.bun/hono@4.10.7/node_modules/hono/dist/utils/constants.js
|
|
84043
84804
|
var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
|
|
84044
|
-
var
|
|
84805
|
+
var init_constants5 = () => {};
|
|
84045
84806
|
|
|
84046
84807
|
// ../../node_modules/.bun/hono@4.10.7/node_modules/hono/dist/hono-base.js
|
|
84047
84808
|
var notFoundHandler = (c) => {
|
|
@@ -84263,7 +85024,7 @@ var init_hono_base = __esm(() => {
|
|
|
84263
85024
|
init_compose();
|
|
84264
85025
|
init_context2();
|
|
84265
85026
|
init_router();
|
|
84266
|
-
|
|
85027
|
+
init_constants5();
|
|
84267
85028
|
init_url();
|
|
84268
85029
|
});
|
|
84269
85030
|
|
|
@@ -92933,7 +93694,7 @@ var require_node3 = __commonJS((exports) => {
|
|
|
92933
93694
|
exports2.isAbsolute = function(aPath) {
|
|
92934
93695
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
92935
93696
|
};
|
|
92936
|
-
function
|
|
93697
|
+
function relative2(aRoot, aPath) {
|
|
92937
93698
|
if (aRoot === "") {
|
|
92938
93699
|
aRoot = ".";
|
|
92939
93700
|
}
|
|
@@ -92952,7 +93713,7 @@ var require_node3 = __commonJS((exports) => {
|
|
|
92952
93713
|
}
|
|
92953
93714
|
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
|
92954
93715
|
}
|
|
92955
|
-
exports2.relative =
|
|
93716
|
+
exports2.relative = relative2;
|
|
92956
93717
|
var supportsNullProto = function() {
|
|
92957
93718
|
var obj = Object.create(null);
|
|
92958
93719
|
return !("__proto__" in obj);
|
|
@@ -94983,7 +95744,7 @@ If you have no idea what this means or what Pirates is, let me explain: Pirates
|
|
|
94983
95744
|
});
|
|
94984
95745
|
};
|
|
94985
95746
|
}
|
|
94986
|
-
var
|
|
95747
|
+
var readFile2 = (fp) => new Promise((resolve2, reject) => {
|
|
94987
95748
|
_fs.default.readFile(fp, "utf8", (err2, data) => {
|
|
94988
95749
|
if (err2)
|
|
94989
95750
|
return reject(err2);
|
|
@@ -95181,7 +95942,7 @@ If you have no idea what this means or what Pirates is, let me explain: Pirates
|
|
|
95181
95942
|
data: _this3.packageJsonCache.get(filepath)[options.packageKey]
|
|
95182
95943
|
};
|
|
95183
95944
|
}
|
|
95184
|
-
const data = _this3.options.parseJSON(yield
|
|
95945
|
+
const data = _this3.options.parseJSON(yield readFile2(filepath));
|
|
95185
95946
|
return {
|
|
95186
95947
|
path: filepath,
|
|
95187
95948
|
data
|
|
@@ -95189,7 +95950,7 @@ If you have no idea what this means or what Pirates is, let me explain: Pirates
|
|
|
95189
95950
|
}
|
|
95190
95951
|
return {
|
|
95191
95952
|
path: filepath,
|
|
95192
|
-
data: yield
|
|
95953
|
+
data: yield readFile2(filepath)
|
|
95193
95954
|
};
|
|
95194
95955
|
}
|
|
95195
95956
|
return {};
|
|
@@ -100234,7 +100995,7 @@ var __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf2,
|
|
|
100234
100995
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
|
|
100235
100996
|
}
|
|
100236
100997
|
return to;
|
|
100237
|
-
}, __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, sep, 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) => {
|
|
100998
|
+
}, __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) => {
|
|
100238
100999
|
const matchers = filters.map((it3) => {
|
|
100239
101000
|
return new Minimatch(it3);
|
|
100240
101001
|
});
|
|
@@ -119280,8 +120041,8 @@ ${BREAKPOINT}ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT "${statement.newC
|
|
|
119280
120041
|
win32: { sep: "\\" },
|
|
119281
120042
|
posix: { sep: "/" }
|
|
119282
120043
|
};
|
|
119283
|
-
|
|
119284
|
-
minimatch.sep =
|
|
120044
|
+
sep2 = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
|
|
120045
|
+
minimatch.sep = sep2;
|
|
119285
120046
|
GLOBSTAR = Symbol("globstar **");
|
|
119286
120047
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
119287
120048
|
plTypes = {
|
|
@@ -138183,7 +138944,7 @@ async function seedCoreGames(db2) {
|
|
|
138183
138944
|
}
|
|
138184
138945
|
async function seedCurrentProjectGame(db2, project) {
|
|
138185
138946
|
const now2 = new Date;
|
|
138186
|
-
const desiredGameId = project.gameId?.trim() ||
|
|
138947
|
+
const desiredGameId = project.gameId?.trim() || await localGameId(project.slug);
|
|
138187
138948
|
try {
|
|
138188
138949
|
const existingGame = await db2.query.games.findFirst({
|
|
138189
138950
|
where: (row, operators) => operators.eq(row.slug, project.slug)
|
|
@@ -138199,7 +138960,7 @@ async function seedCurrentProjectGame(db2, project) {
|
|
|
138199
138960
|
}
|
|
138200
138961
|
}
|
|
138201
138962
|
const gameRecord = {
|
|
138202
|
-
id: desiredGameId
|
|
138963
|
+
id: desiredGameId,
|
|
138203
138964
|
slug: project.slug,
|
|
138204
138965
|
displayName: project.displayName,
|
|
138205
138966
|
version: project.version,
|
|
@@ -138234,6 +138995,7 @@ var init_games = __esm(() => {
|
|
|
138234
138995
|
init_drizzle_orm();
|
|
138235
138996
|
init_src();
|
|
138236
138997
|
init_tables_index();
|
|
138998
|
+
init_uuid2();
|
|
138237
138999
|
init_constants();
|
|
138238
139000
|
init_logging();
|
|
138239
139001
|
init_timeback5();
|
|
@@ -138819,19 +139581,50 @@ var init_types6 = () => {};
|
|
|
138819
139581
|
function hasGameManagementAccess(user) {
|
|
138820
139582
|
return user.role === "admin" || user.role === "teacher" || user.role === "developer" && user.developerStatus === "approved";
|
|
138821
139583
|
}
|
|
139584
|
+
function isDashboardWorkerKey(key) {
|
|
139585
|
+
return Boolean(key?.permissions?.[DASHBOARD_PERMISSION_NAMESPACE]);
|
|
139586
|
+
}
|
|
139587
|
+
function workerKeyGrantsGameRead(key, slug2) {
|
|
139588
|
+
if (!isDashboardWorkerKey(key) && !isGameWorkerKey(key)) {
|
|
139589
|
+
return false;
|
|
139590
|
+
}
|
|
139591
|
+
const games2 = key?.permissions?.games;
|
|
139592
|
+
return Boolean(games2?.includes(`read:${slug2}`) || games2?.includes(`write:${slug2}`));
|
|
139593
|
+
}
|
|
139594
|
+
function isGameWorkerKey(key) {
|
|
139595
|
+
return Boolean(key?.name?.startsWith(GAME_WORKER_KEY_PREFIX));
|
|
139596
|
+
}
|
|
139597
|
+
function deniedWorkerKeyRequest(key, method, pathname) {
|
|
139598
|
+
if (isDashboardWorkerKey(key) && !isAllowedDashboardWorkerRequest(method, pathname, key.permissions)) {
|
|
139599
|
+
return DASHBOARD_WORKER_KEY_RESTRICTED;
|
|
139600
|
+
}
|
|
139601
|
+
return null;
|
|
139602
|
+
}
|
|
139603
|
+
function rejectDashboardWorkerKey(ctx) {
|
|
139604
|
+
if (isDashboardWorkerKey(ctx.apiKey)) {
|
|
139605
|
+
throw ApiError.forbidden(DASHBOARD_WORKER_KEY_RESTRICTED);
|
|
139606
|
+
}
|
|
139607
|
+
}
|
|
139608
|
+
function assertAuthenticatedRequest(ctx) {
|
|
139609
|
+
if (!isAuthenticated(ctx)) {
|
|
139610
|
+
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
139611
|
+
}
|
|
139612
|
+
if (ctx.apiKey) {
|
|
139613
|
+
const denied = deniedWorkerKeyRequest(ctx.apiKey, ctx.request.method, ctx.url.pathname);
|
|
139614
|
+
if (denied) {
|
|
139615
|
+
throw ApiError.forbidden(denied);
|
|
139616
|
+
}
|
|
139617
|
+
}
|
|
139618
|
+
}
|
|
138822
139619
|
function requireAuth(handler) {
|
|
138823
139620
|
return async (ctx) => {
|
|
138824
|
-
|
|
138825
|
-
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
138826
|
-
}
|
|
139621
|
+
assertAuthenticatedRequest(ctx);
|
|
138827
139622
|
return handler(ctx);
|
|
138828
139623
|
};
|
|
138829
139624
|
}
|
|
138830
139625
|
function requireNonAnonymous(handler) {
|
|
138831
139626
|
return async (ctx) => {
|
|
138832
|
-
|
|
138833
|
-
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
138834
|
-
}
|
|
139627
|
+
assertAuthenticatedRequest(ctx);
|
|
138835
139628
|
if (ctx.user.isAnonymous) {
|
|
138836
139629
|
throw ApiError.forbidden("This operation is not available for demo/anonymous users");
|
|
138837
139630
|
}
|
|
@@ -138840,9 +139633,7 @@ function requireNonAnonymous(handler) {
|
|
|
138840
139633
|
}
|
|
138841
139634
|
function requireAnonymous(handler) {
|
|
138842
139635
|
return async (ctx) => {
|
|
138843
|
-
|
|
138844
|
-
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
138845
|
-
}
|
|
139636
|
+
assertAuthenticatedRequest(ctx);
|
|
138846
139637
|
if (!ctx.user.isAnonymous) {
|
|
138847
139638
|
throw ApiError.forbidden("This operation is only available for demo/anonymous users");
|
|
138848
139639
|
}
|
|
@@ -138851,9 +139642,8 @@ function requireAnonymous(handler) {
|
|
|
138851
139642
|
}
|
|
138852
139643
|
function requireAdmin(handler) {
|
|
138853
139644
|
return async (ctx) => {
|
|
138854
|
-
|
|
138855
|
-
|
|
138856
|
-
}
|
|
139645
|
+
assertAuthenticatedRequest(ctx);
|
|
139646
|
+
rejectDashboardWorkerKey(ctx);
|
|
138857
139647
|
if (ctx.user.role !== "admin") {
|
|
138858
139648
|
throw ApiError.forbidden("Admin access required");
|
|
138859
139649
|
}
|
|
@@ -138862,9 +139652,8 @@ function requireAdmin(handler) {
|
|
|
138862
139652
|
}
|
|
138863
139653
|
function requireDeveloper(handler) {
|
|
138864
139654
|
return async (ctx) => {
|
|
138865
|
-
|
|
138866
|
-
|
|
138867
|
-
}
|
|
139655
|
+
assertAuthenticatedRequest(ctx);
|
|
139656
|
+
rejectDashboardWorkerKey(ctx);
|
|
138868
139657
|
const isAdmin = ctx.user.role === "admin";
|
|
138869
139658
|
const isApprovedDev = ctx.user.role === "developer" && ctx.user.developerStatus === "approved";
|
|
138870
139659
|
if (!isAdmin && !isApprovedDev) {
|
|
@@ -138873,20 +139662,30 @@ function requireDeveloper(handler) {
|
|
|
138873
139662
|
return handler(ctx);
|
|
138874
139663
|
};
|
|
138875
139664
|
}
|
|
139665
|
+
function requireHumanDeveloper(handler) {
|
|
139666
|
+
return requireDeveloper(async (ctx) => {
|
|
139667
|
+
if (isDashboardWorkerKey(ctx.apiKey) || isGameWorkerKey(ctx.apiKey)) {
|
|
139668
|
+
throw ApiError.forbidden(WORKER_KEY_HUMAN_ONLY);
|
|
139669
|
+
}
|
|
139670
|
+
return handler(ctx);
|
|
139671
|
+
});
|
|
139672
|
+
}
|
|
138876
139673
|
function requireGameManagementAccess(handler) {
|
|
138877
139674
|
return async (ctx) => {
|
|
138878
|
-
|
|
138879
|
-
|
|
138880
|
-
}
|
|
139675
|
+
assertAuthenticatedRequest(ctx);
|
|
139676
|
+
rejectDashboardWorkerKey(ctx);
|
|
138881
139677
|
if (!hasGameManagementAccess(ctx.user)) {
|
|
138882
139678
|
throw ApiError.forbidden("Game management access required");
|
|
138883
139679
|
}
|
|
138884
139680
|
return handler(ctx);
|
|
138885
139681
|
};
|
|
138886
139682
|
}
|
|
139683
|
+
var WORKER_KEY_HUMAN_ONLY = "This operation requires your own credential — platform worker keys are refused";
|
|
138887
139684
|
var init_auth_util = __esm(() => {
|
|
138888
139685
|
init_errors();
|
|
138889
139686
|
init_types6();
|
|
139687
|
+
init_dashboard_util();
|
|
139688
|
+
init_deployment_util();
|
|
138890
139689
|
});
|
|
138891
139690
|
|
|
138892
139691
|
// ../api-core/src/utils/controller.util.ts
|
|
@@ -139030,6 +139829,21 @@ function requireGameId(gameId) {
|
|
|
139030
139829
|
}
|
|
139031
139830
|
return gameId;
|
|
139032
139831
|
}
|
|
139832
|
+
function requireSlug(slug2) {
|
|
139833
|
+
if (!slug2) {
|
|
139834
|
+
throw ApiError.badRequest("Missing game slug");
|
|
139835
|
+
}
|
|
139836
|
+
return slug2;
|
|
139837
|
+
}
|
|
139838
|
+
function requireUserId(userId) {
|
|
139839
|
+
if (!userId) {
|
|
139840
|
+
throw ApiError.badRequest("Missing user ID");
|
|
139841
|
+
}
|
|
139842
|
+
if (!isValidUUID(userId)) {
|
|
139843
|
+
throw ApiError.unprocessableEntity("userId must be a valid UUID format");
|
|
139844
|
+
}
|
|
139845
|
+
return userId;
|
|
139846
|
+
}
|
|
139033
139847
|
var init_params_util = __esm(() => {
|
|
139034
139848
|
init_src4();
|
|
139035
139849
|
init_errors();
|
|
@@ -139078,6 +139892,7 @@ var init_validation_util = __esm(() => {
|
|
|
139078
139892
|
// ../api-core/src/utils/index.ts
|
|
139079
139893
|
var init_utils11 = __esm(() => {
|
|
139080
139894
|
init_auth_util();
|
|
139895
|
+
init_dashboard_util();
|
|
139081
139896
|
init_deployment_util();
|
|
139082
139897
|
init_leaderboard_util();
|
|
139083
139898
|
init_lti_util();
|
|
@@ -139170,6 +139985,83 @@ var init_bucket_controller = __esm(() => {
|
|
|
139170
139985
|
});
|
|
139171
139986
|
});
|
|
139172
139987
|
|
|
139988
|
+
// ../api-core/src/controllers/dashboard.controller.ts
|
|
139989
|
+
function requireDashboardWorkerKey(ctx, slug2) {
|
|
139990
|
+
const scopes = ctx.apiKey?.permissions?.[DASHBOARD_PERMISSION_NAMESPACE];
|
|
139991
|
+
if (!scopes?.includes(dashboardCredentialScope(slug2))) {
|
|
139992
|
+
throw ApiError.forbidden("This endpoint requires the dashboard worker key for this game");
|
|
139993
|
+
}
|
|
139994
|
+
}
|
|
139995
|
+
var listUsers, addUser, issueRecoveryLink, removeUser, remove, verifyLogin, acceptInvite, revokeSessions, acceptReset, dashboard2;
|
|
139996
|
+
var init_dashboard_controller = __esm(() => {
|
|
139997
|
+
init_schemas_index();
|
|
139998
|
+
init_errors();
|
|
139999
|
+
init_utils11();
|
|
140000
|
+
listUsers = requireHumanDeveloper(async (ctx) => {
|
|
140001
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140002
|
+
const users2 = await ctx.services.dashboard.listUsers(slug2, ctx.user);
|
|
140003
|
+
return { users: users2 };
|
|
140004
|
+
});
|
|
140005
|
+
addUser = requireHumanDeveloper(async (ctx) => {
|
|
140006
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140007
|
+
const body2 = await parseRequestBody(ctx.request, AddGameDashboardUserSchema);
|
|
140008
|
+
return ctx.services.dashboard.addUser(slug2, ctx.user, body2);
|
|
140009
|
+
});
|
|
140010
|
+
issueRecoveryLink = requireHumanDeveloper(async (ctx) => {
|
|
140011
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140012
|
+
const userId = requireUserId(ctx.params.userId);
|
|
140013
|
+
return ctx.services.dashboard.issueRecoveryLink(slug2, ctx.user, userId);
|
|
140014
|
+
});
|
|
140015
|
+
removeUser = requireHumanDeveloper(async (ctx) => {
|
|
140016
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140017
|
+
const userId = requireUserId(ctx.params.userId);
|
|
140018
|
+
await ctx.services.dashboard.removeUser(slug2, ctx.user, userId);
|
|
140019
|
+
return { success: true };
|
|
140020
|
+
});
|
|
140021
|
+
remove = requireHumanDeveloper(async (ctx) => {
|
|
140022
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140023
|
+
await ctx.services.deploy.removeDashboard(slug2, ctx.user);
|
|
140024
|
+
return { success: true };
|
|
140025
|
+
});
|
|
140026
|
+
verifyLogin = requireAuth(async (ctx) => {
|
|
140027
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140028
|
+
requireDashboardWorkerKey(ctx, slug2);
|
|
140029
|
+
const body2 = await parseRequestBody(ctx.request, VerifyGameDashboardLoginSchema);
|
|
140030
|
+
const user = await ctx.services.dashboard.verifyLogin(slug2, body2);
|
|
140031
|
+
return { user };
|
|
140032
|
+
});
|
|
140033
|
+
acceptInvite = requireAuth(async (ctx) => {
|
|
140034
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140035
|
+
requireDashboardWorkerKey(ctx, slug2);
|
|
140036
|
+
const body2 = await parseRequestBody(ctx.request, AcceptGameDashboardInviteSchema);
|
|
140037
|
+
const user = await ctx.services.dashboard.acceptInvite(slug2, body2);
|
|
140038
|
+
return { user };
|
|
140039
|
+
});
|
|
140040
|
+
revokeSessions = requireHumanDeveloper(async (ctx) => {
|
|
140041
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140042
|
+
await ctx.services.deploy.rotateDashboardSessionSecret(slug2, ctx.user);
|
|
140043
|
+
return { success: true };
|
|
140044
|
+
});
|
|
140045
|
+
acceptReset = requireAuth(async (ctx) => {
|
|
140046
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140047
|
+
requireDashboardWorkerKey(ctx, slug2);
|
|
140048
|
+
const body2 = await parseRequestBody(ctx.request, AcceptGameDashboardResetSchema);
|
|
140049
|
+
const user = await ctx.services.dashboard.acceptReset(slug2, body2);
|
|
140050
|
+
return { user };
|
|
140051
|
+
});
|
|
140052
|
+
dashboard2 = defineControllerNames("dashboard", {
|
|
140053
|
+
listUsers,
|
|
140054
|
+
addUser,
|
|
140055
|
+
removeUser,
|
|
140056
|
+
remove,
|
|
140057
|
+
issueRecoveryLink,
|
|
140058
|
+
revokeSessions,
|
|
140059
|
+
verifyLogin,
|
|
140060
|
+
acceptInvite,
|
|
140061
|
+
acceptReset
|
|
140062
|
+
});
|
|
140063
|
+
});
|
|
140064
|
+
|
|
139173
140065
|
// ../api-core/src/controllers/database.controller.ts
|
|
139174
140066
|
var reset, database;
|
|
139175
140067
|
var init_database_controller = __esm(() => {
|
|
@@ -139264,7 +140156,7 @@ var init_developer_controller = __esm(() => {
|
|
|
139264
140156
|
});
|
|
139265
140157
|
|
|
139266
140158
|
// ../api-core/src/controllers/domain.controller.ts
|
|
139267
|
-
var add, list, getStatus2,
|
|
140159
|
+
var add, list, getStatus2, remove2, domains2;
|
|
139268
140160
|
var init_domain_controller = __esm(() => {
|
|
139269
140161
|
init_esm();
|
|
139270
140162
|
init_schemas_index();
|
|
@@ -139313,7 +140205,7 @@ var init_domain_controller = __esm(() => {
|
|
|
139313
140205
|
const environment = getPlatformEnvironment(ctx.config);
|
|
139314
140206
|
return ctx.services.domain.getStatus(slug2, hostname4, environment, ctx.user, refresh);
|
|
139315
140207
|
});
|
|
139316
|
-
|
|
140208
|
+
remove2 = requireDeveloper(async (ctx) => {
|
|
139317
140209
|
const slug2 = ctx.params.slug;
|
|
139318
140210
|
const hostname4 = ctx.params.hostname;
|
|
139319
140211
|
if (!slug2) {
|
|
@@ -139329,12 +140221,12 @@ var init_domain_controller = __esm(() => {
|
|
|
139329
140221
|
add,
|
|
139330
140222
|
list,
|
|
139331
140223
|
getStatus: getStatus2,
|
|
139332
|
-
remove
|
|
140224
|
+
remove: remove2
|
|
139333
140225
|
});
|
|
139334
140226
|
});
|
|
139335
140227
|
|
|
139336
140228
|
// ../api-core/src/controllers/game-member.controller.ts
|
|
139337
|
-
function
|
|
140229
|
+
function requireUserId2(userId) {
|
|
139338
140230
|
if (!userId) {
|
|
139339
140231
|
throw ApiError.badRequest("Missing user ID");
|
|
139340
140232
|
}
|
|
@@ -139356,13 +140248,13 @@ var init_game_member_controller = __esm(() => {
|
|
|
139356
140248
|
});
|
|
139357
140249
|
updateMemberRole = requireNonAnonymous(async (ctx) => {
|
|
139358
140250
|
const gameId = requireGameId(ctx.params.gameId);
|
|
139359
|
-
const userId =
|
|
140251
|
+
const userId = requireUserId2(ctx.params.userId);
|
|
139360
140252
|
const body2 = await parseRequestBody(ctx.request, UpdateGameMemberRoleSchema);
|
|
139361
140253
|
return ctx.services.gameMember.updateRole(gameId, userId, ctx.user, body2);
|
|
139362
140254
|
});
|
|
139363
140255
|
removeMember = requireNonAnonymous(async (ctx) => {
|
|
139364
140256
|
const gameId = requireGameId(ctx.params.gameId);
|
|
139365
|
-
const userId =
|
|
140257
|
+
const userId = requireUserId2(ctx.params.userId);
|
|
139366
140258
|
await ctx.services.gameMember.remove(gameId, userId, ctx.user);
|
|
139367
140259
|
});
|
|
139368
140260
|
searchUsersForMember = requireNonAnonymous(async (ctx) => {
|
|
@@ -139380,12 +140272,13 @@ var init_game_member_controller = __esm(() => {
|
|
|
139380
140272
|
});
|
|
139381
140273
|
|
|
139382
140274
|
// ../api-core/src/controllers/game.controller.ts
|
|
139383
|
-
var list2, listAccessible, getSubjects, getTimebackSummaries, getById, getBySlug, getManifest, upsertBySlug, patchGameMetadata,
|
|
140275
|
+
var list2, listAccessible, getSubjects, getTimebackSummaries, getById, getBySlug, getManifest, upsertBySlug, patchGameMetadata, remove3, games2;
|
|
139384
140276
|
var init_game_controller = __esm(() => {
|
|
139385
140277
|
init_esm();
|
|
139386
140278
|
init_schemas_index();
|
|
139387
140279
|
init_errors();
|
|
139388
140280
|
init_utils11();
|
|
140281
|
+
init_auth_util();
|
|
139389
140282
|
list2 = requireNonAnonymous(async (ctx) => ctx.services.game.list(ctx.user));
|
|
139390
140283
|
listAccessible = requireNonAnonymous(async (ctx) => ctx.services.game.listAccessible(ctx.user));
|
|
139391
140284
|
getSubjects = requireNonAnonymous(async (ctx) => ctx.services.game.getSubjects());
|
|
@@ -139399,7 +140292,9 @@ var init_game_controller = __esm(() => {
|
|
|
139399
140292
|
if (!slug2) {
|
|
139400
140293
|
throw ApiError.badRequest("Missing game slug");
|
|
139401
140294
|
}
|
|
139402
|
-
return ctx.services.game.getBySlug(slug2, ctx.user
|
|
140295
|
+
return ctx.services.game.getBySlug(slug2, ctx.user, {
|
|
140296
|
+
scopeAuthorized: workerKeyGrantsGameRead(ctx.apiKey, slug2)
|
|
140297
|
+
});
|
|
139403
140298
|
});
|
|
139404
140299
|
getManifest = requireNonAnonymous(async (ctx) => {
|
|
139405
140300
|
const gameId = requireGameId(ctx.params.gameId);
|
|
@@ -139429,7 +140324,7 @@ var init_game_controller = __esm(() => {
|
|
|
139429
140324
|
const body2 = await parseRequestBody(ctx.request, PatchGameMetadataSchema);
|
|
139430
140325
|
return ctx.services.game.updateMetadata(gameId, body2, ctx.user);
|
|
139431
140326
|
});
|
|
139432
|
-
|
|
140327
|
+
remove3 = requireNonAnonymous(async (ctx) => {
|
|
139433
140328
|
const gameId = requireGameId(ctx.params.gameId);
|
|
139434
140329
|
await ctx.services.game.delete(gameId, ctx.user);
|
|
139435
140330
|
});
|
|
@@ -139443,7 +140338,7 @@ var init_game_controller = __esm(() => {
|
|
|
139443
140338
|
getBySlug,
|
|
139444
140339
|
upsertBySlug,
|
|
139445
140340
|
patchGameMetadata,
|
|
139446
|
-
remove:
|
|
140341
|
+
remove: remove3
|
|
139447
140342
|
});
|
|
139448
140343
|
});
|
|
139449
140344
|
|
|
@@ -140597,6 +141492,7 @@ var init_verify_controller = __esm(() => {
|
|
|
140597
141492
|
// ../api-core/src/controllers/index.ts
|
|
140598
141493
|
var init_controllers = __esm(() => {
|
|
140599
141494
|
init_bucket_controller();
|
|
141495
|
+
init_dashboard_controller();
|
|
140600
141496
|
init_database_controller();
|
|
140601
141497
|
init_deploy_controller();
|
|
140602
141498
|
init_developer_controller();
|