@playcademy/sandbox 0.6.1-beta.3 → 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/cli.js
CHANGED
|
@@ -204,6 +204,20 @@ var init_auth = __esm(() => {
|
|
|
204
204
|
};
|
|
205
205
|
});
|
|
206
206
|
|
|
207
|
+
// ../constants/src/dashboard.ts
|
|
208
|
+
var DASHBOARD_USER_ROLES, DASHBOARD_WORKER_ROUTES, DASHBOARD_WORKER_SUFFIX = "-dash";
|
|
209
|
+
var init_dashboard = __esm(() => {
|
|
210
|
+
DASHBOARD_USER_ROLES = {
|
|
211
|
+
ADMIN: "admin",
|
|
212
|
+
VIEWER: "viewer"
|
|
213
|
+
};
|
|
214
|
+
DASHBOARD_WORKER_ROUTES = {
|
|
215
|
+
verifySession: "/sessions",
|
|
216
|
+
acceptInvite: "/invites/accept",
|
|
217
|
+
acceptReset: "/resets/accept"
|
|
218
|
+
};
|
|
219
|
+
});
|
|
220
|
+
|
|
207
221
|
// ../constants/src/typescript.ts
|
|
208
222
|
var init_typescript = () => {};
|
|
209
223
|
|
|
@@ -245,17 +259,8 @@ var init_platform = __esm(() => {
|
|
|
245
259
|
var PLATFORM_TIMEZONE = "America/New_York";
|
|
246
260
|
|
|
247
261
|
// ../constants/src/timeback.ts
|
|
248
|
-
var
|
|
262
|
+
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;
|
|
249
263
|
var init_timeback2 = __esm(() => {
|
|
250
|
-
TIMEBACK_ROUTES = {
|
|
251
|
-
END_ACTIVITY: "/integrations/timeback/end-activity",
|
|
252
|
-
GET_XP: "/integrations/timeback/xp",
|
|
253
|
-
GET_MASTERY: "/integrations/timeback/mastery",
|
|
254
|
-
GET_HIGHEST_GRADE_MASTERED: "/integrations/timeback/highest-grade-mastered",
|
|
255
|
-
HEARTBEAT: "/integrations/timeback/heartbeat",
|
|
256
|
-
ADVANCE_COURSE: "/integrations/timeback/advance-course",
|
|
257
|
-
UNENROLL_COURSE: "/integrations/timeback/unenroll-course"
|
|
258
|
-
};
|
|
259
264
|
TIMEBACK_COURSE_DEFAULTS = {
|
|
260
265
|
gradingScheme: "STANDARD",
|
|
261
266
|
level: {
|
|
@@ -306,7 +311,7 @@ var init_timeback2 = __esm(() => {
|
|
|
306
311
|
});
|
|
307
312
|
|
|
308
313
|
// ../constants/src/cloudflare.ts
|
|
309
|
-
var WORKER_NAMING, SECRETS_PREFIX = "secrets_", CLOUDFLARE_COMPATIBILITY_DATE = "2025-10-11";
|
|
314
|
+
var WORKER_NAMING, MAX_WORKER_NAME_LENGTH = 63, SECRETS_PREFIX = "secrets_", CLOUDFLARE_COMPATIBILITY_DATE = "2025-10-11";
|
|
310
315
|
var init_cloudflare = __esm(() => {
|
|
311
316
|
WORKER_NAMING = {
|
|
312
317
|
STAGING_PREFIX: "staging-",
|
|
@@ -318,6 +323,7 @@ var init_cloudflare = __esm(() => {
|
|
|
318
323
|
// ../constants/src/index.ts
|
|
319
324
|
var init_src = __esm(() => {
|
|
320
325
|
init_auth();
|
|
326
|
+
init_dashboard();
|
|
321
327
|
init_typescript();
|
|
322
328
|
init_domains();
|
|
323
329
|
init_env_vars();
|
|
@@ -1057,8 +1063,7 @@ async function waitForPort(port, timeoutMs = 5000) {
|
|
|
1057
1063
|
const start2 = Date.now();
|
|
1058
1064
|
while (await isPortInUse(port)) {
|
|
1059
1065
|
if (Date.now() - start2 > timeoutMs) {
|
|
1060
|
-
throw new Error(`Port ${port} is already in use
|
|
1061
|
-
` + `Stop the other server or specify a different port with --port <number>.`);
|
|
1066
|
+
throw new Error(`Port ${port} is already in use`);
|
|
1062
1067
|
}
|
|
1063
1068
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1064
1069
|
}
|
|
@@ -1067,8 +1072,7 @@ async function requirePortAvailable(port, timeoutMs = 100) {
|
|
|
1067
1072
|
const start2 = Date.now();
|
|
1068
1073
|
while (await isPortInUse(port)) {
|
|
1069
1074
|
if (Date.now() - start2 > timeoutMs) {
|
|
1070
|
-
throw new Error(`Port ${port} is already in use
|
|
1071
|
-
` + `Stop the other server or specify a different port with --port <number>.`);
|
|
1075
|
+
throw new Error(`Port ${port} is already in use`);
|
|
1072
1076
|
}
|
|
1073
1077
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
1074
1078
|
}
|
|
@@ -1080,7 +1084,7 @@ var package_default;
|
|
|
1080
1084
|
var init_package = __esm(() => {
|
|
1081
1085
|
package_default = {
|
|
1082
1086
|
name: "@playcademy/sandbox",
|
|
1083
|
-
version: "0.6.1-beta.
|
|
1087
|
+
version: "0.6.1-beta.5",
|
|
1084
1088
|
description: "Local development server for Playcademy game development",
|
|
1085
1089
|
type: "module",
|
|
1086
1090
|
exports: {
|
|
@@ -1149,7 +1153,7 @@ var init_package = __esm(() => {
|
|
|
1149
1153
|
});
|
|
1150
1154
|
|
|
1151
1155
|
// ../api-core/src/errors/domain.error.ts
|
|
1152
|
-
var DomainError, BadRequestError, AccessDeniedError, NotFoundError, ConflictError, AlreadyExistsError, ValidationError, InternalError, ServiceUnavailableError, TimeoutError;
|
|
1156
|
+
var DomainError, BadRequestError, UnauthorizedError, AccessDeniedError, NotFoundError, ConflictError, AlreadyExistsError, ValidationError, RateLimitError, InternalError, ServiceUnavailableError, TimeoutError;
|
|
1153
1157
|
var init_domain_error = __esm(() => {
|
|
1154
1158
|
DomainError = class DomainError extends Error {
|
|
1155
1159
|
code;
|
|
@@ -1167,6 +1171,12 @@ var init_domain_error = __esm(() => {
|
|
|
1167
1171
|
this.name = "BadRequestError";
|
|
1168
1172
|
}
|
|
1169
1173
|
};
|
|
1174
|
+
UnauthorizedError = class UnauthorizedError extends DomainError {
|
|
1175
|
+
constructor(message = "Unauthorized", details) {
|
|
1176
|
+
super("UNAUTHORIZED", message, details);
|
|
1177
|
+
this.name = "UnauthorizedError";
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1170
1180
|
AccessDeniedError = class AccessDeniedError extends DomainError {
|
|
1171
1181
|
constructor(message = "Access denied", details) {
|
|
1172
1182
|
super("ACCESS_DENIED", message, details);
|
|
@@ -1199,6 +1209,12 @@ var init_domain_error = __esm(() => {
|
|
|
1199
1209
|
this.name = "ValidationError";
|
|
1200
1210
|
}
|
|
1201
1211
|
};
|
|
1212
|
+
RateLimitError = class RateLimitError extends DomainError {
|
|
1213
|
+
constructor(message = "Rate limit exceeded", details) {
|
|
1214
|
+
super("RATE_LIMITED", message, details);
|
|
1215
|
+
this.name = "RateLimitError";
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1202
1218
|
InternalError = class InternalError extends DomainError {
|
|
1203
1219
|
constructor(message = "Internal error", details) {
|
|
1204
1220
|
super("INTERNAL", message, details);
|
|
@@ -1557,12 +1573,24 @@ data: ${JSON.stringify(data)}
|
|
|
1557
1573
|
return sseEncoder.encode(payload);
|
|
1558
1574
|
}
|
|
1559
1575
|
function createContextBuilder(options) {
|
|
1560
|
-
const {
|
|
1576
|
+
const {
|
|
1577
|
+
db,
|
|
1578
|
+
config: config2,
|
|
1579
|
+
providers,
|
|
1580
|
+
services,
|
|
1581
|
+
cloudflare: cloudflare2,
|
|
1582
|
+
timeback: timeback2,
|
|
1583
|
+
resolveUser,
|
|
1584
|
+
resolveGameId,
|
|
1585
|
+
resolveApiKey
|
|
1586
|
+
} = options;
|
|
1561
1587
|
return async (c) => {
|
|
1562
1588
|
const user = resolveUser ? await resolveUser(c) : null;
|
|
1563
1589
|
const gameId = resolveGameId ? await resolveGameId(c) : undefined;
|
|
1590
|
+
const apiKey = resolveApiKey ? await resolveApiKey(c) : undefined;
|
|
1564
1591
|
return {
|
|
1565
1592
|
user,
|
|
1593
|
+
apiKey,
|
|
1566
1594
|
gameId,
|
|
1567
1595
|
params: c.req.param(),
|
|
1568
1596
|
url: new URL(c.req.url),
|
|
@@ -11181,7 +11209,7 @@ var init_table4 = __esm(() => {
|
|
|
11181
11209
|
});
|
|
11182
11210
|
|
|
11183
11211
|
// ../data/src/domains/game/table.ts
|
|
11184
|
-
var gamePlatformEnum, gameTypeEnum, gameVisibilityEnum, games, gameMemberRoleEnum, gameMembers, gameMembersRelations, deploymentProviderEnum, deployJobStatusEnum, gameDeployments, gameDeployJobs, customHostnameStatusEnum, customHostnameSslStatusEnum, customHostnameEnvironmentEnum, gameCustomHostnames;
|
|
11212
|
+
var gamePlatformEnum, gameTypeEnum, gameVisibilityEnum, games, gameMemberRoleEnum, gameMembers, gameMembersRelations, gameDashboardUserRoleEnum, gameDashboardUsers, gameDashboardUsersRelations, deploymentProviderEnum, deploymentTargetEnum, deployJobStatusEnum, gameDeployments, gameDeployJobs, customHostnameStatusEnum, customHostnameSslStatusEnum, customHostnameEnvironmentEnum, gameCustomHostnames;
|
|
11185
11213
|
var init_table5 = __esm(() => {
|
|
11186
11214
|
init_drizzle_orm();
|
|
11187
11215
|
init_pg_core();
|
|
@@ -11225,7 +11253,37 @@ var init_table5 = __esm(() => {
|
|
|
11225
11253
|
references: [users.id]
|
|
11226
11254
|
})
|
|
11227
11255
|
}));
|
|
11256
|
+
gameDashboardUserRoleEnum = pgEnum("game_dashboard_user_role", [
|
|
11257
|
+
DASHBOARD_USER_ROLES.ADMIN,
|
|
11258
|
+
DASHBOARD_USER_ROLES.VIEWER
|
|
11259
|
+
]);
|
|
11260
|
+
gameDashboardUsers = pgTable("game_dashboard_users", {
|
|
11261
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
11262
|
+
gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
|
|
11263
|
+
email: text("email").notNull(),
|
|
11264
|
+
displayName: text("display_name"),
|
|
11265
|
+
role: gameDashboardUserRoleEnum("role").notNull().default(DASHBOARD_USER_ROLES.VIEWER),
|
|
11266
|
+
passwordHash: text("password_hash"),
|
|
11267
|
+
inviteTokenHash: text("invite_token_hash"),
|
|
11268
|
+
inviteExpiresAt: timestamp("invite_expires_at", { withTimezone: true }),
|
|
11269
|
+
resetTokenHash: text("reset_token_hash"),
|
|
11270
|
+
resetExpiresAt: timestamp("reset_expires_at", { withTimezone: true }),
|
|
11271
|
+
failedLoginAttempts: integer("failed_login_attempts").notNull().default(0),
|
|
11272
|
+
lastFailedLoginAt: timestamp("last_failed_login_at", { withTimezone: true }),
|
|
11273
|
+
platformUserId: text("platform_user_id").references(() => users.id, {
|
|
11274
|
+
onDelete: "set null"
|
|
11275
|
+
}),
|
|
11276
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
11277
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
11278
|
+
}, (table3) => [uniqueIndex("game_dashboard_users_game_email_idx").on(table3.gameId, table3.email)]);
|
|
11279
|
+
gameDashboardUsersRelations = relations(gameDashboardUsers, ({ one }) => ({
|
|
11280
|
+
game: one(games, {
|
|
11281
|
+
fields: [gameDashboardUsers.gameId],
|
|
11282
|
+
references: [games.id]
|
|
11283
|
+
})
|
|
11284
|
+
}));
|
|
11228
11285
|
deploymentProviderEnum = pgEnum("deployment_provider", ["cloudflare", "aws"]);
|
|
11286
|
+
deploymentTargetEnum = pgEnum("deployment_target", ["game", "dashboard"]);
|
|
11229
11287
|
deployJobStatusEnum = pgEnum("deploy_job_status", [
|
|
11230
11288
|
"pending",
|
|
11231
11289
|
"running",
|
|
@@ -11237,6 +11295,7 @@ var init_table5 = __esm(() => {
|
|
|
11237
11295
|
gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
|
|
11238
11296
|
deploymentId: text("deployment_id").notNull(),
|
|
11239
11297
|
provider: deploymentProviderEnum("provider").notNull(),
|
|
11298
|
+
target: deploymentTargetEnum("target").notNull().default("game"),
|
|
11240
11299
|
url: text("url").notNull(),
|
|
11241
11300
|
codeHash: text("code_hash"),
|
|
11242
11301
|
isActive: boolean("is_active").notNull().default(false),
|
|
@@ -11424,8 +11483,12 @@ __export(exports_tables_index, {
|
|
|
11424
11483
|
gameMemberRoleEnum: () => gameMemberRoleEnum,
|
|
11425
11484
|
gameDeployments: () => gameDeployments,
|
|
11426
11485
|
gameDeployJobs: () => gameDeployJobs,
|
|
11486
|
+
gameDashboardUsersRelations: () => gameDashboardUsersRelations,
|
|
11487
|
+
gameDashboardUsers: () => gameDashboardUsers,
|
|
11488
|
+
gameDashboardUserRoleEnum: () => gameDashboardUserRoleEnum,
|
|
11427
11489
|
gameCustomHostnames: () => gameCustomHostnames,
|
|
11428
11490
|
developerStatusEnum: () => developerStatusEnum,
|
|
11491
|
+
deploymentTargetEnum: () => deploymentTargetEnum,
|
|
11429
11492
|
deploymentProviderEnum: () => deploymentProviderEnum,
|
|
11430
11493
|
deployJobStatusEnum: () => deployJobStatusEnum,
|
|
11431
11494
|
customHostnameStatusEnum: () => customHostnameStatusEnum,
|
|
@@ -12929,6 +12992,10 @@ function errorMessage(err2) {
|
|
|
12929
12992
|
function errorType(err2) {
|
|
12930
12993
|
return err2 instanceof Error ? err2.constructor.name : typeof err2;
|
|
12931
12994
|
}
|
|
12995
|
+
function isUniqueViolation(err2) {
|
|
12996
|
+
return typeof err2 === "object" && err2 !== null && err2.code === PG_UNIQUE_VIOLATION;
|
|
12997
|
+
}
|
|
12998
|
+
var PG_UNIQUE_VIOLATION = "23505";
|
|
12932
12999
|
|
|
12933
13000
|
// ../otel/src/spans.ts
|
|
12934
13001
|
function truncate(value) {
|
|
@@ -13007,6 +13074,310 @@ var init_spans = __esm(() => {
|
|
|
13007
13074
|
ROOT_SPAN_KEY = import_api2.createContextKey("playcademy.root_span");
|
|
13008
13075
|
});
|
|
13009
13076
|
|
|
13077
|
+
// ../utils/src/random.ts
|
|
13078
|
+
async function generateSecureRandomString(length) {
|
|
13079
|
+
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
|
|
13080
|
+
const randomValues = new Uint8Array(length);
|
|
13081
|
+
crypto.getRandomValues(randomValues);
|
|
13082
|
+
return [...randomValues].map((byte) => charset[byte % charset.length]).join("");
|
|
13083
|
+
}
|
|
13084
|
+
|
|
13085
|
+
// ../api-core/src/utils/hash.util.ts
|
|
13086
|
+
async function sha256Hex(input) {
|
|
13087
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
|
|
13088
|
+
return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
13089
|
+
}
|
|
13090
|
+
|
|
13091
|
+
// ../api-core/src/utils/dashboard.util.ts
|
|
13092
|
+
function dashboardCredentialScope(slug) {
|
|
13093
|
+
return `${CREDENTIAL_SCOPE_PREFIX}${slug}`;
|
|
13094
|
+
}
|
|
13095
|
+
function dashboardCredentialSlugs(permissions) {
|
|
13096
|
+
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);
|
|
13097
|
+
}
|
|
13098
|
+
function isAllowedDashboardWorkerRequest(method, pathname, permissions) {
|
|
13099
|
+
const path = pathname.replace(/\/+$/, "");
|
|
13100
|
+
return dashboardCredentialSlugs(permissions).some((slug) => {
|
|
13101
|
+
if (method === "GET") {
|
|
13102
|
+
return path === `/api/games/${slug}`;
|
|
13103
|
+
}
|
|
13104
|
+
if (method === "POST") {
|
|
13105
|
+
return Object.values(DASHBOARD_WORKER_ROUTES).some((subpath) => path === `/api/games/${slug}/dashboard${subpath}`);
|
|
13106
|
+
}
|
|
13107
|
+
return false;
|
|
13108
|
+
});
|
|
13109
|
+
}
|
|
13110
|
+
function hashDashboardToken(token) {
|
|
13111
|
+
return sha256Hex(token);
|
|
13112
|
+
}
|
|
13113
|
+
function loginBackoffMs(failedAttempts) {
|
|
13114
|
+
if (failedAttempts < LOGIN_BACKOFF_THRESHOLD) {
|
|
13115
|
+
return 0;
|
|
13116
|
+
}
|
|
13117
|
+
return Math.min(LOGIN_BACKOFF_CAP_MS, LOGIN_BACKOFF_BASE_MS * 2 ** (failedAttempts - LOGIN_BACKOFF_THRESHOLD));
|
|
13118
|
+
}
|
|
13119
|
+
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;
|
|
13120
|
+
var init_dashboard_util = __esm(() => {
|
|
13121
|
+
init_src();
|
|
13122
|
+
LOGIN_BACKOFF_CAP_MS = 5 * 60 * 1000;
|
|
13123
|
+
});
|
|
13124
|
+
|
|
13125
|
+
// ../api-core/src/services/dashboard.service.ts
|
|
13126
|
+
function alreadyExists(gameId) {
|
|
13127
|
+
return new AlreadyExistsError("A dashboard user with this email already exists", { gameId });
|
|
13128
|
+
}
|
|
13129
|
+
var DashboardService;
|
|
13130
|
+
var init_dashboard_service = __esm(() => {
|
|
13131
|
+
init_drizzle_orm();
|
|
13132
|
+
init_tables_index();
|
|
13133
|
+
init_spans();
|
|
13134
|
+
init_errors();
|
|
13135
|
+
init_dashboard_util();
|
|
13136
|
+
DashboardService = class DashboardService {
|
|
13137
|
+
deps;
|
|
13138
|
+
static INVITE_TOKEN_LENGTH = 48;
|
|
13139
|
+
static INVITE_TTL_MS = 72 * 60 * 60 * 1000;
|
|
13140
|
+
static RESET_TTL_MS = 24 * 60 * 60 * 1000;
|
|
13141
|
+
constructor(deps) {
|
|
13142
|
+
this.deps = deps;
|
|
13143
|
+
}
|
|
13144
|
+
async listUsers(slug, user) {
|
|
13145
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13146
|
+
const rows = await this.deps.db.select({
|
|
13147
|
+
id: gameDashboardUsers.id,
|
|
13148
|
+
gameId: gameDashboardUsers.gameId,
|
|
13149
|
+
email: gameDashboardUsers.email,
|
|
13150
|
+
displayName: gameDashboardUsers.displayName,
|
|
13151
|
+
role: gameDashboardUsers.role,
|
|
13152
|
+
platformUserId: gameDashboardUsers.platformUserId,
|
|
13153
|
+
createdAt: gameDashboardUsers.createdAt,
|
|
13154
|
+
updatedAt: gameDashboardUsers.updatedAt,
|
|
13155
|
+
pending: sql`(${gameDashboardUsers.passwordHash} IS NULL)`
|
|
13156
|
+
}).from(gameDashboardUsers).where(eq(gameDashboardUsers.gameId, game2.id)).orderBy(asc(gameDashboardUsers.createdAt));
|
|
13157
|
+
setAttributes({
|
|
13158
|
+
"app.dashboard.operation": "list_users",
|
|
13159
|
+
"app.dashboard.result_count": rows.length
|
|
13160
|
+
});
|
|
13161
|
+
return rows;
|
|
13162
|
+
}
|
|
13163
|
+
async addUser(slug, user, input) {
|
|
13164
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13165
|
+
const email = input.email.toLowerCase();
|
|
13166
|
+
setAttributes({
|
|
13167
|
+
"app.dashboard.operation": "add_user",
|
|
13168
|
+
"app.dashboard.user_role": input.role
|
|
13169
|
+
});
|
|
13170
|
+
const existing = await this.findByEmail(game2.id, email);
|
|
13171
|
+
if (existing) {
|
|
13172
|
+
throw alreadyExists(game2.id);
|
|
13173
|
+
}
|
|
13174
|
+
const inviteToken = await generateSecureRandomString(DashboardService.INVITE_TOKEN_LENGTH);
|
|
13175
|
+
let created;
|
|
13176
|
+
try {
|
|
13177
|
+
[created] = await this.deps.db.insert(gameDashboardUsers).values({
|
|
13178
|
+
gameId: game2.id,
|
|
13179
|
+
email,
|
|
13180
|
+
displayName: input.displayName,
|
|
13181
|
+
role: input.role,
|
|
13182
|
+
inviteTokenHash: await hashDashboardToken(inviteToken),
|
|
13183
|
+
inviteExpiresAt: new Date(Date.now() + DashboardService.INVITE_TTL_MS),
|
|
13184
|
+
platformUserId: email === user.email.toLowerCase() ? user.id : undefined
|
|
13185
|
+
}).returning();
|
|
13186
|
+
} catch (error) {
|
|
13187
|
+
if (isUniqueViolation(error)) {
|
|
13188
|
+
throw alreadyExists(game2.id);
|
|
13189
|
+
}
|
|
13190
|
+
throw error;
|
|
13191
|
+
}
|
|
13192
|
+
if (!created) {
|
|
13193
|
+
throw new ValidationError("Failed to create dashboard user");
|
|
13194
|
+
}
|
|
13195
|
+
return { user: DashboardService.toSummary(created), token: inviteToken, kind: "invite" };
|
|
13196
|
+
}
|
|
13197
|
+
async removeUser(slug, user, dashboardUserId) {
|
|
13198
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13199
|
+
setAttributes({
|
|
13200
|
+
"app.dashboard.operation": "remove_user",
|
|
13201
|
+
"app.dashboard.user_id": dashboardUserId
|
|
13202
|
+
});
|
|
13203
|
+
const [deleted] = await this.deps.db.delete(gameDashboardUsers).where(and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.id, dashboardUserId))).returning({ id: gameDashboardUsers.id });
|
|
13204
|
+
if (!deleted) {
|
|
13205
|
+
throw new NotFoundError("Dashboard user", dashboardUserId);
|
|
13206
|
+
}
|
|
13207
|
+
}
|
|
13208
|
+
async verifyLogin(slug, input) {
|
|
13209
|
+
const game2 = await this.getGameForRuntime(slug);
|
|
13210
|
+
setAttributes({ "app.dashboard.operation": "verify_login" });
|
|
13211
|
+
const dashboardUser = await this.findByEmail(game2.id, input.email.toLowerCase());
|
|
13212
|
+
if (!dashboardUser?.passwordHash) {
|
|
13213
|
+
throw new UnauthorizedError("Invalid credentials");
|
|
13214
|
+
}
|
|
13215
|
+
if (dashboardUser.lastFailedLoginAt) {
|
|
13216
|
+
const retryAt = dashboardUser.lastFailedLoginAt.getTime() + loginBackoffMs(dashboardUser.failedLoginAttempts);
|
|
13217
|
+
if (retryAt > Date.now()) {
|
|
13218
|
+
addEvent("dashboard.login_throttled", {
|
|
13219
|
+
"app.dashboard.failed_attempts": dashboardUser.failedLoginAttempts
|
|
13220
|
+
});
|
|
13221
|
+
throw new RateLimitError("Too many failed attempts — try again shortly", {
|
|
13222
|
+
retryAfterSeconds: Math.ceil((retryAt - Date.now()) / 1000)
|
|
13223
|
+
});
|
|
13224
|
+
}
|
|
13225
|
+
}
|
|
13226
|
+
const valid = await this.deps.verifyPassword({
|
|
13227
|
+
hash: dashboardUser.passwordHash,
|
|
13228
|
+
password: input.password
|
|
13229
|
+
});
|
|
13230
|
+
if (!valid) {
|
|
13231
|
+
await this.deps.db.update(gameDashboardUsers).set({
|
|
13232
|
+
failedLoginAttempts: sql`${gameDashboardUsers.failedLoginAttempts} + 1`,
|
|
13233
|
+
lastFailedLoginAt: new Date
|
|
13234
|
+
}).where(eq(gameDashboardUsers.id, dashboardUser.id));
|
|
13235
|
+
throw new UnauthorizedError("Invalid credentials");
|
|
13236
|
+
}
|
|
13237
|
+
if (dashboardUser.failedLoginAttempts > 0) {
|
|
13238
|
+
await this.deps.db.update(gameDashboardUsers).set({ failedLoginAttempts: 0, lastFailedLoginAt: null }).where(eq(gameDashboardUsers.id, dashboardUser.id));
|
|
13239
|
+
}
|
|
13240
|
+
return DashboardService.toSummary(dashboardUser);
|
|
13241
|
+
}
|
|
13242
|
+
async acceptInvite(slug, input) {
|
|
13243
|
+
const game2 = await this.getGameForRuntime(slug);
|
|
13244
|
+
setAttributes({ "app.dashboard.operation": "accept_invite" });
|
|
13245
|
+
const tokenHash = await hashDashboardToken(input.token);
|
|
13246
|
+
const invited = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13247
|
+
where: and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.inviteTokenHash, tokenHash))
|
|
13248
|
+
});
|
|
13249
|
+
if (!invited) {
|
|
13250
|
+
throw new UnauthorizedError("Invalid or already-used invite token");
|
|
13251
|
+
}
|
|
13252
|
+
if (invited.inviteExpiresAt && invited.inviteExpiresAt.getTime() < Date.now()) {
|
|
13253
|
+
throw new UnauthorizedError("This invite has expired — ask for a new one");
|
|
13254
|
+
}
|
|
13255
|
+
const passwordHash = await this.deps.hashPassword(input.password);
|
|
13256
|
+
const [updated] = await this.deps.db.update(gameDashboardUsers).set({
|
|
13257
|
+
passwordHash,
|
|
13258
|
+
inviteTokenHash: null,
|
|
13259
|
+
inviteExpiresAt: null,
|
|
13260
|
+
updatedAt: new Date
|
|
13261
|
+
}).where(and(eq(gameDashboardUsers.id, invited.id), eq(gameDashboardUsers.inviteTokenHash, tokenHash), isNull(gameDashboardUsers.passwordHash))).returning();
|
|
13262
|
+
if (!updated) {
|
|
13263
|
+
throw new UnauthorizedError("Invalid or already-used invite token");
|
|
13264
|
+
}
|
|
13265
|
+
return DashboardService.toSummary(updated);
|
|
13266
|
+
}
|
|
13267
|
+
async acceptReset(slug, input) {
|
|
13268
|
+
const game2 = await this.getGameForRuntime(slug);
|
|
13269
|
+
setAttributes({ "app.dashboard.operation": "accept_reset" });
|
|
13270
|
+
const tokenHash = await hashDashboardToken(input.token);
|
|
13271
|
+
const found = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13272
|
+
where: and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.resetTokenHash, tokenHash))
|
|
13273
|
+
});
|
|
13274
|
+
if (!found) {
|
|
13275
|
+
throw new UnauthorizedError("Invalid or already-used reset token");
|
|
13276
|
+
}
|
|
13277
|
+
if (found.resetExpiresAt && found.resetExpiresAt.getTime() < Date.now()) {
|
|
13278
|
+
throw new UnauthorizedError("This reset link has expired — ask for a new one");
|
|
13279
|
+
}
|
|
13280
|
+
const passwordHash = await this.deps.hashPassword(input.password);
|
|
13281
|
+
const [updated] = await this.deps.db.update(gameDashboardUsers).set({
|
|
13282
|
+
passwordHash,
|
|
13283
|
+
resetTokenHash: null,
|
|
13284
|
+
resetExpiresAt: null,
|
|
13285
|
+
inviteTokenHash: null,
|
|
13286
|
+
inviteExpiresAt: null,
|
|
13287
|
+
failedLoginAttempts: 0,
|
|
13288
|
+
lastFailedLoginAt: null,
|
|
13289
|
+
updatedAt: new Date
|
|
13290
|
+
}).where(and(eq(gameDashboardUsers.id, found.id), eq(gameDashboardUsers.resetTokenHash, tokenHash))).returning();
|
|
13291
|
+
if (!updated) {
|
|
13292
|
+
throw new UnauthorizedError("Invalid or already-used reset token");
|
|
13293
|
+
}
|
|
13294
|
+
return DashboardService.toSummary(updated);
|
|
13295
|
+
}
|
|
13296
|
+
async issueRecoveryLink(slug, user, dashboardUserId) {
|
|
13297
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13298
|
+
const existing = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13299
|
+
where: and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.id, dashboardUserId))
|
|
13300
|
+
});
|
|
13301
|
+
if (!existing) {
|
|
13302
|
+
throw new NotFoundError("Dashboard user", dashboardUserId);
|
|
13303
|
+
}
|
|
13304
|
+
const kind = existing.passwordHash ? "reset" : "invite";
|
|
13305
|
+
setAttributes({
|
|
13306
|
+
"app.dashboard.operation": "issue_recovery_link",
|
|
13307
|
+
"app.dashboard.recovery_kind": kind
|
|
13308
|
+
});
|
|
13309
|
+
const token = await generateSecureRandomString(DashboardService.INVITE_TOKEN_LENGTH);
|
|
13310
|
+
const tokenHash = await hashDashboardToken(token);
|
|
13311
|
+
const fields = kind === "invite" ? {
|
|
13312
|
+
inviteTokenHash: tokenHash,
|
|
13313
|
+
inviteExpiresAt: new Date(Date.now() + DashboardService.INVITE_TTL_MS)
|
|
13314
|
+
} : {
|
|
13315
|
+
resetTokenHash: tokenHash,
|
|
13316
|
+
resetExpiresAt: new Date(Date.now() + DashboardService.RESET_TTL_MS)
|
|
13317
|
+
};
|
|
13318
|
+
const [updated] = await this.deps.db.update(gameDashboardUsers).set({ ...fields, updatedAt: new Date }).where(eq(gameDashboardUsers.id, existing.id)).returning();
|
|
13319
|
+
if (!updated) {
|
|
13320
|
+
throw new NotFoundError("Dashboard user", dashboardUserId);
|
|
13321
|
+
}
|
|
13322
|
+
return { user: DashboardService.toSummary(updated), token, kind };
|
|
13323
|
+
}
|
|
13324
|
+
async getGameForRuntime(slug) {
|
|
13325
|
+
const game2 = await this.deps.db.query.games.findFirst({
|
|
13326
|
+
where: eq(games.slug, slug),
|
|
13327
|
+
columns: { id: true }
|
|
13328
|
+
});
|
|
13329
|
+
if (!game2) {
|
|
13330
|
+
throw new NotFoundError("Game", slug);
|
|
13331
|
+
}
|
|
13332
|
+
return game2;
|
|
13333
|
+
}
|
|
13334
|
+
async findByEmail(gameId, email) {
|
|
13335
|
+
const row = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13336
|
+
where: and(eq(gameDashboardUsers.gameId, gameId), eq(gameDashboardUsers.email, email))
|
|
13337
|
+
});
|
|
13338
|
+
return row ?? null;
|
|
13339
|
+
}
|
|
13340
|
+
static toSummary(row) {
|
|
13341
|
+
return {
|
|
13342
|
+
id: row.id,
|
|
13343
|
+
gameId: row.gameId,
|
|
13344
|
+
email: row.email,
|
|
13345
|
+
displayName: row.displayName,
|
|
13346
|
+
role: row.role,
|
|
13347
|
+
platformUserId: row.platformUserId,
|
|
13348
|
+
createdAt: row.createdAt,
|
|
13349
|
+
updatedAt: row.updatedAt,
|
|
13350
|
+
pending: !row.passwordHash
|
|
13351
|
+
};
|
|
13352
|
+
}
|
|
13353
|
+
};
|
|
13354
|
+
});
|
|
13355
|
+
|
|
13356
|
+
// ../data/src/domains/game/helpers.ts
|
|
13357
|
+
function activeDeploymentWhere(gameId, target = "game") {
|
|
13358
|
+
return and(eq(gameDeployments.gameId, gameId), eq(gameDeployments.target, target), eq(gameDeployments.isActive, true));
|
|
13359
|
+
}
|
|
13360
|
+
var init_helpers = __esm(() => {
|
|
13361
|
+
init_drizzle_orm();
|
|
13362
|
+
init_table5();
|
|
13363
|
+
});
|
|
13364
|
+
|
|
13365
|
+
// ../data/src/domains/timeback/helpers.ts
|
|
13366
|
+
function isActiveGameTimebackIntegrationStatus(statusColumn = gameTimebackIntegrations.status) {
|
|
13367
|
+
return sql`${statusColumn} IS DISTINCT FROM ${DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS}`;
|
|
13368
|
+
}
|
|
13369
|
+
var ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS = "active", DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS = "deactivated";
|
|
13370
|
+
var init_helpers2 = __esm(() => {
|
|
13371
|
+
init_drizzle_orm();
|
|
13372
|
+
init_table7();
|
|
13373
|
+
});
|
|
13374
|
+
|
|
13375
|
+
// ../data/src/helpers.index.ts
|
|
13376
|
+
var init_helpers_index = __esm(() => {
|
|
13377
|
+
init_helpers();
|
|
13378
|
+
init_helpers2();
|
|
13379
|
+
});
|
|
13380
|
+
|
|
13010
13381
|
// ../../node_modules/.bun/process-nextick-args@2.0.1/node_modules/process-nextick-args/index.js
|
|
13011
13382
|
var require_process_nextick_args = __commonJS((exports, module2) => {
|
|
13012
13383
|
if (typeof process === "undefined" || !process.version || process.version.indexOf("v0.") === 0 || process.version.indexOf("v1.") === 0 && process.version.indexOf("v1.8.") !== 0) {
|
|
@@ -22087,8 +22458,8 @@ var require_lib3 = __commonJS((exports, module2) => {
|
|
|
22087
22458
|
});
|
|
22088
22459
|
|
|
22089
22460
|
// ../utils/src/zip.ts
|
|
22090
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
22091
|
-
import { join as join2 } from "path";
|
|
22461
|
+
import { mkdir, readdir, readFile, writeFile } from "fs/promises";
|
|
22462
|
+
import { join as join2, relative, sep } from "path";
|
|
22092
22463
|
async function extractZipToDirectory(zipBuffer, targetDir) {
|
|
22093
22464
|
try {
|
|
22094
22465
|
const zip = await import_jszip.default.loadAsync(zipBuffer);
|
|
@@ -22114,9 +22485,10 @@ async function extractZipToDirectory(zipBuffer, targetDir) {
|
|
|
22114
22485
|
fileCount: Object.keys(zip.files).length
|
|
22115
22486
|
});
|
|
22116
22487
|
} catch (error) {
|
|
22117
|
-
const errorMessage2 = error instanceof Error ? error.message : String(error);
|
|
22118
22488
|
log.error("[utils/zip] Failed to extract ZIP", { targetDir, error });
|
|
22119
|
-
throw new Error(`Failed to extract ZIP to ${targetDir}: ${
|
|
22489
|
+
throw new Error(`Failed to extract ZIP to ${targetDir}: ${errorMessage(error)}`, {
|
|
22490
|
+
cause: error
|
|
22491
|
+
});
|
|
22120
22492
|
}
|
|
22121
22493
|
}
|
|
22122
22494
|
var import_jszip;
|
|
@@ -22386,6 +22758,7 @@ class DeployJobService {
|
|
|
22386
22758
|
jobId,
|
|
22387
22759
|
leaseId,
|
|
22388
22760
|
leaseLost,
|
|
22761
|
+
target,
|
|
22389
22762
|
game: game2,
|
|
22390
22763
|
user,
|
|
22391
22764
|
error
|
|
@@ -22415,9 +22788,12 @@ class DeployJobService {
|
|
|
22415
22788
|
}
|
|
22416
22789
|
}
|
|
22417
22790
|
if (!effectiveLeaseLost) {
|
|
22418
|
-
await this.deps.notifyDeploymentFailure(
|
|
22419
|
-
|
|
22420
|
-
|
|
22791
|
+
await this.deps.notifyDeploymentFailure({
|
|
22792
|
+
slug: game2.slug,
|
|
22793
|
+
displayName: game2.displayName,
|
|
22794
|
+
error: message,
|
|
22795
|
+
target,
|
|
22796
|
+
developer: { id: user.id, email: user.email }
|
|
22421
22797
|
});
|
|
22422
22798
|
}
|
|
22423
22799
|
await this.deleteCodeBundle(jobId);
|
|
@@ -22519,7 +22895,7 @@ class DeployJobService {
|
|
|
22519
22895
|
}
|
|
22520
22896
|
assertLease();
|
|
22521
22897
|
const activeDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
22522
|
-
where:
|
|
22898
|
+
where: activeDeploymentWhere(job.gameId, request.target ?? "game"),
|
|
22523
22899
|
columns: {
|
|
22524
22900
|
deploymentId: true,
|
|
22525
22901
|
url: true
|
|
@@ -22542,7 +22918,15 @@ class DeployJobService {
|
|
|
22542
22918
|
} catch (error) {
|
|
22543
22919
|
clearInterval(heartbeat);
|
|
22544
22920
|
setAttribute("app.deploy_job.run_duration_ms", DeployJobService.elapsedMsSince(new Date(runStartedAt)));
|
|
22545
|
-
await this.handleRunError({
|
|
22921
|
+
await this.handleRunError({
|
|
22922
|
+
jobId,
|
|
22923
|
+
leaseId,
|
|
22924
|
+
leaseLost,
|
|
22925
|
+
target: request.target ?? "game",
|
|
22926
|
+
game: game2,
|
|
22927
|
+
user,
|
|
22928
|
+
error
|
|
22929
|
+
});
|
|
22546
22930
|
throw error;
|
|
22547
22931
|
}
|
|
22548
22932
|
}
|
|
@@ -22561,6 +22945,7 @@ async function forceMarkDeployJobFailed(db2, jobId, error) {
|
|
|
22561
22945
|
var STATUS_MAP2, DEPLOY_JOB_LEASE_MS, DEPLOY_JOB_HEARTBEAT_MS, DEPLOY_JOB_CODE_BUNDLE_PREFIX = "deploy-job-code";
|
|
22562
22946
|
var init_deploy_job_service = __esm(() => {
|
|
22563
22947
|
init_drizzle_orm();
|
|
22948
|
+
init_helpers_index();
|
|
22564
22949
|
init_tables_index();
|
|
22565
22950
|
init_spans();
|
|
22566
22951
|
init_zip();
|
|
@@ -24704,7 +25089,7 @@ var init_bindings = __esm(() => {
|
|
|
24704
25089
|
});
|
|
24705
25090
|
|
|
24706
25091
|
// ../cloudflare/src/playcademy/provider/helpers.ts
|
|
24707
|
-
var
|
|
25092
|
+
var init_helpers3 = __esm(() => {
|
|
24708
25093
|
init_mime();
|
|
24709
25094
|
});
|
|
24710
25095
|
|
|
@@ -24716,7 +25101,7 @@ var init_provider = __esm(() => {
|
|
|
24716
25101
|
init_constants2();
|
|
24717
25102
|
init_assets_config();
|
|
24718
25103
|
init_bindings();
|
|
24719
|
-
|
|
25104
|
+
init_helpers3();
|
|
24720
25105
|
});
|
|
24721
25106
|
// ../cloudflare/src/playcademy/provider/index.ts
|
|
24722
25107
|
var init_provider2 = __esm(() => {
|
|
@@ -27167,7 +27552,7 @@ var init_stages = __esm(() => {
|
|
|
27167
27552
|
});
|
|
27168
27553
|
|
|
27169
27554
|
// ../api-core/src/utils/deployment.util.ts
|
|
27170
|
-
function
|
|
27555
|
+
function getGameDeploymentId(gameSlug, sstStage) {
|
|
27171
27556
|
if (sstStage === "production") {
|
|
27172
27557
|
return gameSlug;
|
|
27173
27558
|
}
|
|
@@ -27176,45 +27561,57 @@ function getDeploymentId(gameSlug, sstStage) {
|
|
|
27176
27561
|
}
|
|
27177
27562
|
return `${WORKER_NAMING.LOCAL_PREFIX}${sstStage}-${gameSlug}`;
|
|
27178
27563
|
}
|
|
27564
|
+
function getDashboardDeploymentId(gameSlug, sstStage) {
|
|
27565
|
+
return `${getGameDeploymentId(gameSlug, sstStage)}${DASHBOARD_WORKER_SUFFIX}`;
|
|
27566
|
+
}
|
|
27179
27567
|
function getGameWorkerApiKeyName(slug) {
|
|
27180
|
-
return
|
|
27568
|
+
return `${GAME_WORKER_KEY_PREFIX}${slug}`.substring(0, 32);
|
|
27569
|
+
}
|
|
27570
|
+
function getDashboardWorkerApiKeyName(slug) {
|
|
27571
|
+
return `${DASHBOARD_WORKER_KEY_PREFIX}${slug}`;
|
|
27181
27572
|
}
|
|
27182
27573
|
function toBindingName(queueKey) {
|
|
27183
27574
|
return `${queueKey.replace(/-/g, "_").toUpperCase()}_QUEUE`;
|
|
27184
27575
|
}
|
|
27185
|
-
|
|
27186
|
-
|
|
27187
|
-
const data = encoder.encode(code);
|
|
27188
|
-
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
27189
|
-
const hashArray = [...new Uint8Array(hashBuffer)];
|
|
27190
|
-
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
27576
|
+
function generateDeploymentHash(code) {
|
|
27577
|
+
return sha256Hex(code);
|
|
27191
27578
|
}
|
|
27579
|
+
var GAME_WORKER_KEY_PREFIX = "game-worker-", DASHBOARD_WORKER_KEY_PREFIX = "dash-worker-";
|
|
27192
27580
|
var init_deployment_util = __esm(() => {
|
|
27193
27581
|
init_src();
|
|
27194
27582
|
init_stages();
|
|
27195
27583
|
});
|
|
27196
27584
|
|
|
27585
|
+
// ../api-core/src/utils/worker-keys.util.ts
|
|
27586
|
+
async function sweepDashboardWorkerKeys(deleteApiKeysByName, slug) {
|
|
27587
|
+
try {
|
|
27588
|
+
await deleteApiKeysByName(getDashboardWorkerApiKeyName(slug));
|
|
27589
|
+
} catch (error) {
|
|
27590
|
+
addEvent("dashboard.worker_key_sweep_failed", {
|
|
27591
|
+
"exception.type": errorType(error),
|
|
27592
|
+
"app.error.message": errorMessage(error)
|
|
27593
|
+
});
|
|
27594
|
+
}
|
|
27595
|
+
}
|
|
27596
|
+
var init_worker_keys_util = __esm(() => {
|
|
27597
|
+
init_spans();
|
|
27598
|
+
init_deployment_util();
|
|
27599
|
+
});
|
|
27600
|
+
|
|
27197
27601
|
// ../api-core/src/services/deploy.service.ts
|
|
27602
|
+
function readDashboardTheme(config2) {
|
|
27603
|
+
const theme = config2?.dashboard?.theme;
|
|
27604
|
+
return {
|
|
27605
|
+
...typeof theme?.primary === "string" && { primary: theme.primary },
|
|
27606
|
+
...typeof theme?.secondary === "string" && { secondary: theme.secondary }
|
|
27607
|
+
};
|
|
27608
|
+
}
|
|
27609
|
+
|
|
27198
27610
|
class DeployService {
|
|
27199
27611
|
deps;
|
|
27200
27612
|
constructor(deps) {
|
|
27201
27613
|
this.deps = deps;
|
|
27202
27614
|
}
|
|
27203
|
-
static classifyDeployType(flags2) {
|
|
27204
|
-
if (flags2.hasBackend && flags2.hasFrontend) {
|
|
27205
|
-
return "full_stack";
|
|
27206
|
-
}
|
|
27207
|
-
if (flags2.hasFrontend) {
|
|
27208
|
-
return "frontend_only";
|
|
27209
|
-
}
|
|
27210
|
-
if (flags2.hasBackend) {
|
|
27211
|
-
return "backend_only";
|
|
27212
|
-
}
|
|
27213
|
-
return "metadata_only";
|
|
27214
|
-
}
|
|
27215
|
-
static countDeadLetterQueues(bindings) {
|
|
27216
|
-
return bindings?.queues?.filter((queue) => Boolean(queue.deadLetterQueue)).length ?? 0;
|
|
27217
|
-
}
|
|
27218
27615
|
getCloudflare() {
|
|
27219
27616
|
const cf = this.deps.cloudflare;
|
|
27220
27617
|
if (!cf) {
|
|
@@ -27222,86 +27619,307 @@ class DeployService {
|
|
|
27222
27619
|
}
|
|
27223
27620
|
return cf;
|
|
27224
27621
|
}
|
|
27225
|
-
async
|
|
27226
|
-
const
|
|
27227
|
-
|
|
27228
|
-
|
|
27229
|
-
|
|
27230
|
-
|
|
27231
|
-
|
|
27232
|
-
}
|
|
27233
|
-
|
|
27234
|
-
|
|
27235
|
-
|
|
27236
|
-
|
|
27237
|
-
|
|
27238
|
-
|
|
27239
|
-
if (existingKeyId) {
|
|
27240
|
-
setAttribute("app.deploy.api_key_outcome", "regenerated");
|
|
27241
|
-
try {
|
|
27242
|
-
await this.deps.deleteAuthApiKey(existingKeyId);
|
|
27243
|
-
} catch (error) {
|
|
27244
|
-
addEvent("deploy.api_key_revoke_failed", {
|
|
27245
|
-
"exception.type": errorType(error),
|
|
27246
|
-
"app.error.message": errorMessage(error),
|
|
27247
|
-
"app.deploy.old_key_id": existingKeyId
|
|
27248
|
-
});
|
|
27622
|
+
async* deploy(slug, request, user, uploadDeps, extractZip) {
|
|
27623
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
27624
|
+
const context2 = { slug, request, user, game: game2, uploadDeps, extractZip };
|
|
27625
|
+
switch (request.target ?? "game") {
|
|
27626
|
+
case "dashboard": {
|
|
27627
|
+
yield* this.deployDashboard(context2);
|
|
27628
|
+
break;
|
|
27629
|
+
}
|
|
27630
|
+
case "game": {
|
|
27631
|
+
yield* this.deployGame(context2);
|
|
27632
|
+
break;
|
|
27633
|
+
}
|
|
27634
|
+
default: {
|
|
27635
|
+
throw new ValidationError("Invalid deployment target");
|
|
27249
27636
|
}
|
|
27250
27637
|
}
|
|
27251
|
-
return this.createApiKey(user, slug, keyName);
|
|
27252
27638
|
}
|
|
27253
|
-
async
|
|
27639
|
+
async* deployGame(context2) {
|
|
27640
|
+
const { slug, request, user, game: game2, uploadDeps, extractZip } = context2;
|
|
27254
27641
|
const cf = this.getCloudflare();
|
|
27255
|
-
const
|
|
27256
|
-
const
|
|
27257
|
-
|
|
27642
|
+
const db2 = this.deps.db;
|
|
27643
|
+
const flags2 = this.validateGameRequest(request);
|
|
27644
|
+
const { hasBackend, hasFrontend } = flags2;
|
|
27645
|
+
const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
27646
|
+
let frontendAssetsPath;
|
|
27647
|
+
let tempDir;
|
|
27648
|
+
if (hasFrontend) {
|
|
27649
|
+
if (!uploadDeps || !extractZip) {
|
|
27650
|
+
throw new ValidationError("Upload dependencies not configured for frontend deployment");
|
|
27651
|
+
}
|
|
27652
|
+
yield { type: "status", data: { message: "Fetching temporary files" } };
|
|
27653
|
+
const extracted = await this.fetchAndExtractFrontendAssets(slug, game2.id, request.uploadToken, uploadDeps, extractZip);
|
|
27654
|
+
tempDir = extracted.tempDir;
|
|
27655
|
+
frontendAssetsPath = extracted.assetsPath;
|
|
27656
|
+
yield { type: "status", data: { message: "Extracting assets" } };
|
|
27657
|
+
}
|
|
27658
|
+
const platformBaseUrl = await this.resolvePlatformBaseUrl();
|
|
27659
|
+
const env = {
|
|
27660
|
+
GAME_ID: game2.id,
|
|
27661
|
+
PLAYCADEMY_BASE_URL: platformBaseUrl,
|
|
27662
|
+
PLAYCADEMY_PLATFORM_SERVICE_JWKS: this.deps.config.platformServiceJwt?.publicJwks
|
|
27663
|
+
};
|
|
27664
|
+
yield {
|
|
27665
|
+
type: "status",
|
|
27666
|
+
data: { message: hasBackend ? "Deploying backend code" : "Deploying to platform" }
|
|
27667
|
+
};
|
|
27668
|
+
const keepAssets = hasBackend && !hasFrontend;
|
|
27669
|
+
const deploymentOptions = this.mapGameBindingsToOptions(deploymentId, request.bindings, request.schema);
|
|
27670
|
+
const bindings = deploymentOptions?.bindings;
|
|
27671
|
+
setAttributes({
|
|
27672
|
+
"app.deploy.has_d1": Boolean(bindings?.d1?.length),
|
|
27673
|
+
"app.deploy.has_kv": Boolean(bindings?.kv?.length),
|
|
27674
|
+
"app.deploy.has_r2": Boolean(bindings?.r2?.length),
|
|
27675
|
+
"app.deploy.queue_count": bindings?.queues?.length ?? 0,
|
|
27676
|
+
"app.deploy.dead_letter_queue_count": DeployService.countDeadLetterQueues(bindings)
|
|
27677
|
+
});
|
|
27678
|
+
const activeDeployment = await db2.query.gameDeployments.findFirst({
|
|
27679
|
+
where: activeDeploymentWhere(game2.id, "game"),
|
|
27680
|
+
columns: { resources: true }
|
|
27681
|
+
});
|
|
27682
|
+
if (deploymentOptions?.bindings?.d1?.length) {
|
|
27683
|
+
await this.cleanupOrphanD1Databases(cf, deploymentOptions.bindings.d1, slug, game2.id);
|
|
27684
|
+
}
|
|
27685
|
+
const result = await this.deployToCloudflare({
|
|
27686
|
+
deploymentId,
|
|
27687
|
+
code: request.code,
|
|
27688
|
+
env,
|
|
27689
|
+
tempDir,
|
|
27690
|
+
options: {
|
|
27691
|
+
...deploymentOptions,
|
|
27692
|
+
compatibilityDate: request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27693
|
+
compatibilityFlags: request.compatibilityFlags,
|
|
27694
|
+
existingResources: activeDeployment?.resources ?? undefined,
|
|
27695
|
+
assetsPath: frontendAssetsPath,
|
|
27696
|
+
keepAssets
|
|
27697
|
+
}
|
|
27698
|
+
});
|
|
27699
|
+
yield { type: "status", data: { message: "Finalizing deployment" } };
|
|
27700
|
+
const updatedGame = await this.finalizeGameDeployment({
|
|
27701
|
+
game: game2,
|
|
27702
|
+
slug,
|
|
27703
|
+
deploymentId,
|
|
27704
|
+
result,
|
|
27705
|
+
request,
|
|
27706
|
+
user,
|
|
27707
|
+
flags: flags2
|
|
27708
|
+
});
|
|
27709
|
+
yield { type: "complete", data: updatedGame };
|
|
27710
|
+
}
|
|
27711
|
+
async* deployDashboard(context2) {
|
|
27712
|
+
const { slug, request, user, game: game2 } = context2;
|
|
27713
|
+
const db2 = this.deps.db;
|
|
27714
|
+
const contract = this.validateDashboardRequest(request, context2.uploadDeps, context2.extractZip);
|
|
27715
|
+
const deploymentId = getDashboardDeploymentId(slug, this.deps.config.sstStage);
|
|
27716
|
+
if (deploymentId.length > MAX_WORKER_NAME_LENGTH) {
|
|
27717
|
+
throw new ValidationError(`Dashboard worker name '${deploymentId}' exceeds Cloudflare's ${MAX_WORKER_NAME_LENGTH}-character limit — shorten the game slug`);
|
|
27718
|
+
}
|
|
27719
|
+
const collidingGame = await db2.query.games.findFirst({
|
|
27720
|
+
where: eq(games.slug, `${slug}${DASHBOARD_WORKER_SUFFIX}`),
|
|
27258
27721
|
columns: { id: true }
|
|
27259
27722
|
});
|
|
27260
|
-
|
|
27261
|
-
|
|
27262
|
-
|
|
27263
|
-
|
|
27264
|
-
|
|
27265
|
-
|
|
27266
|
-
|
|
27267
|
-
|
|
27268
|
-
|
|
27269
|
-
|
|
27270
|
-
|
|
27271
|
-
|
|
27272
|
-
|
|
27273
|
-
|
|
27274
|
-
|
|
27723
|
+
if (collidingGame) {
|
|
27724
|
+
throw new ValidationError(`Cannot deploy this dashboard: an existing game's slug is '${slug}${DASHBOARD_WORKER_SUFFIX}', which owns the '${deploymentId}' worker name`);
|
|
27725
|
+
}
|
|
27726
|
+
const gameDeployment = await db2.query.gameDeployments.findFirst({
|
|
27727
|
+
where: activeDeploymentWhere(game2.id, "game"),
|
|
27728
|
+
columns: { resources: true }
|
|
27729
|
+
});
|
|
27730
|
+
if (!gameDeployment) {
|
|
27731
|
+
throw new ValidationError("Deploy the game before its dashboard — the dashboard attaches to the game deployment");
|
|
27732
|
+
}
|
|
27733
|
+
setAttributes({
|
|
27734
|
+
"app.deploy.type": "dashboard",
|
|
27735
|
+
"app.deploy.deployment_id": deploymentId,
|
|
27736
|
+
"app.deploy.code_size": contract.code.length,
|
|
27737
|
+
"app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27738
|
+
"app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0
|
|
27739
|
+
});
|
|
27740
|
+
yield { type: "status", data: { message: "Fetching temporary files" } };
|
|
27741
|
+
const [{ tempDir, assetsPath }, platformBaseUrl, dashboardActive] = await Promise.all([
|
|
27742
|
+
this.fetchAndExtractFrontendAssets(slug, game2.id, contract.uploadToken, contract.uploadDeps, contract.extractZip),
|
|
27743
|
+
this.resolvePlatformBaseUrl(),
|
|
27744
|
+
db2.query.gameDeployments.findFirst({
|
|
27745
|
+
where: activeDeploymentWhere(game2.id, "dashboard"),
|
|
27746
|
+
columns: { resources: true }
|
|
27747
|
+
})
|
|
27748
|
+
]);
|
|
27749
|
+
yield { type: "status", data: { message: "Extracting assets" } };
|
|
27750
|
+
const theme = readDashboardTheme(request.config);
|
|
27751
|
+
const env = {
|
|
27752
|
+
GAME_ID: game2.id,
|
|
27753
|
+
GAME_SLUG: slug,
|
|
27754
|
+
GAME_NAME: game2.displayName,
|
|
27755
|
+
...game2.metadata?.emoji && { GAME_EMOJI: game2.metadata.emoji },
|
|
27756
|
+
...theme.primary && { DASHBOARD_THEME_PRIMARY: theme.primary },
|
|
27757
|
+
...theme.secondary && { DASHBOARD_THEME_SECONDARY: theme.secondary },
|
|
27758
|
+
PLAYCADEMY_BASE_URL: platformBaseUrl,
|
|
27759
|
+
PLAYCADEMY_PLATFORM_SERVICE_JWKS: this.deps.config.platformServiceJwt?.publicJwks
|
|
27760
|
+
};
|
|
27761
|
+
const gameResources = gameDeployment.resources;
|
|
27762
|
+
const bindings = {
|
|
27763
|
+
d1: gameResources?.d1?.map((database) => database.name) ?? [],
|
|
27764
|
+
kv: gameResources?.kv?.map((namespace) => namespace.name) ?? [],
|
|
27765
|
+
r2: gameResources?.r2?.filter((bucket) => bucket.kind !== "assets").map((bucket) => bucket.name) ?? []
|
|
27766
|
+
};
|
|
27767
|
+
const existingResources = {
|
|
27768
|
+
...dashboardActive?.resources,
|
|
27769
|
+
d1: gameResources?.d1,
|
|
27770
|
+
kv: gameResources?.kv,
|
|
27771
|
+
r2: gameResources?.r2
|
|
27772
|
+
};
|
|
27773
|
+
yield { type: "status", data: { message: "Deploying dashboard" } };
|
|
27774
|
+
const result = await this.deployToCloudflare({
|
|
27775
|
+
deploymentId,
|
|
27776
|
+
code: contract.code,
|
|
27777
|
+
env,
|
|
27778
|
+
tempDir,
|
|
27779
|
+
options: {
|
|
27780
|
+
bindings,
|
|
27781
|
+
compatibilityDate: request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27782
|
+
compatibilityFlags: request.compatibilityFlags,
|
|
27783
|
+
existingResources,
|
|
27784
|
+
assetsPath,
|
|
27785
|
+
keepAssets: false,
|
|
27786
|
+
assetsConfig: { run_worker_first: true }
|
|
27275
27787
|
}
|
|
27276
|
-
|
|
27788
|
+
});
|
|
27789
|
+
yield { type: "status", data: { message: "Finalizing deployment" } };
|
|
27790
|
+
await withSpan("deploy.configure_worker_secrets", async () => {
|
|
27791
|
+
const existingSecrets = await this.listWorkerSecretNames(result.deploymentId);
|
|
27792
|
+
await this.ensureWorkerApiKeyOnWorker(user, DeployService.dashboardWorkerKeySpec(slug), result.deploymentId, existingSecrets);
|
|
27793
|
+
await this.ensureDashboardSessionSecret(result.deploymentId, existingSecrets, Boolean(dashboardActive));
|
|
27794
|
+
});
|
|
27795
|
+
const codeHash = await generateDeploymentHash(contract.code);
|
|
27796
|
+
await this.saveDeployment({
|
|
27797
|
+
gameId: game2.id,
|
|
27798
|
+
deploymentId: result.deploymentId,
|
|
27799
|
+
url: result.url,
|
|
27800
|
+
codeHash,
|
|
27801
|
+
resources: result.resources,
|
|
27802
|
+
target: "dashboard"
|
|
27803
|
+
});
|
|
27804
|
+
setAttribute("app.deploy.code_hash", codeHash);
|
|
27805
|
+
try {
|
|
27806
|
+
await withSpan("deploy.send_alert", () => this.deps.alerts.notifyDashboardDeployment({
|
|
27807
|
+
slug,
|
|
27808
|
+
displayName: game2.displayName,
|
|
27809
|
+
url: result.url,
|
|
27810
|
+
developer: { id: user.id, email: user.email }
|
|
27811
|
+
}));
|
|
27812
|
+
} catch (error) {
|
|
27813
|
+
setAttribute("app.alerts.delivery", "failed");
|
|
27814
|
+
setAttribute("app.alerts.delivery_error", errorMessage(error));
|
|
27815
|
+
setAttribute("app.alerts.type", "dashboard_deployment");
|
|
27277
27816
|
}
|
|
27278
|
-
|
|
27817
|
+
yield { type: "complete", data: game2 };
|
|
27279
27818
|
}
|
|
27280
|
-
|
|
27281
|
-
const
|
|
27282
|
-
|
|
27283
|
-
|
|
27819
|
+
validateGameRequest(request) {
|
|
27820
|
+
const hasBackend = Boolean(request.code);
|
|
27821
|
+
const hasFrontend = Boolean(request.uploadToken);
|
|
27822
|
+
const hasMetadata = Boolean(request.metadata);
|
|
27823
|
+
setAttributes({
|
|
27824
|
+
"app.deploy.has_backend": hasBackend,
|
|
27825
|
+
"app.deploy.has_frontend": hasFrontend,
|
|
27826
|
+
"app.deploy.has_metadata": hasMetadata,
|
|
27827
|
+
"app.deploy.type": DeployService.classifyGameDeployType({
|
|
27828
|
+
hasBackend,
|
|
27829
|
+
hasFrontend,
|
|
27830
|
+
hasMetadata
|
|
27831
|
+
}),
|
|
27832
|
+
"app.deploy.code_size": request.code?.length ?? 0,
|
|
27833
|
+
"app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27834
|
+
"app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0,
|
|
27835
|
+
"app.deploy.has_schema": Boolean(request.schema)
|
|
27836
|
+
});
|
|
27837
|
+
if (!hasBackend && !hasFrontend && !hasMetadata) {
|
|
27838
|
+
throw new ValidationError("Must provide at least one of: uploadToken (frontend), code (backend), or metadata");
|
|
27284
27839
|
}
|
|
27285
|
-
|
|
27286
|
-
|
|
27840
|
+
if (!this.deps.config.baseUrl) {
|
|
27841
|
+
throw new ValidationError("baseUrl is not configured");
|
|
27842
|
+
}
|
|
27843
|
+
return { hasBackend, hasFrontend, hasMetadata };
|
|
27287
27844
|
}
|
|
27288
|
-
|
|
27289
|
-
|
|
27290
|
-
|
|
27291
|
-
throw new ValidationError("Uploaded file is empty or not found");
|
|
27845
|
+
validateDashboardRequest(request, uploadDeps, extractZip) {
|
|
27846
|
+
if (!request.code || !request.uploadToken) {
|
|
27847
|
+
throw new ValidationError("Dashboard deployments require both worker code and an asset upload");
|
|
27292
27848
|
}
|
|
27293
|
-
|
|
27294
|
-
|
|
27295
|
-
|
|
27296
|
-
|
|
27297
|
-
|
|
27298
|
-
|
|
27299
|
-
|
|
27300
|
-
|
|
27849
|
+
if (request.metadata) {
|
|
27850
|
+
throw new ValidationError("Dashboard deployments cannot update game metadata");
|
|
27851
|
+
}
|
|
27852
|
+
if (!uploadDeps || !extractZip) {
|
|
27853
|
+
throw new ValidationError("Upload dependencies not configured for frontend deployment");
|
|
27854
|
+
}
|
|
27855
|
+
if (!this.deps.config.baseUrl) {
|
|
27856
|
+
throw new ValidationError("baseUrl is not configured");
|
|
27857
|
+
}
|
|
27858
|
+
return { code: request.code, uploadToken: request.uploadToken, uploadDeps, extractZip };
|
|
27859
|
+
}
|
|
27860
|
+
static classifyGameDeployType(flags2) {
|
|
27861
|
+
if (flags2.hasBackend && flags2.hasFrontend) {
|
|
27862
|
+
return "full_stack";
|
|
27863
|
+
}
|
|
27864
|
+
if (flags2.hasFrontend) {
|
|
27865
|
+
return "frontend_only";
|
|
27866
|
+
}
|
|
27867
|
+
if (flags2.hasBackend) {
|
|
27868
|
+
return "backend_only";
|
|
27869
|
+
}
|
|
27870
|
+
return "metadata_only";
|
|
27871
|
+
}
|
|
27872
|
+
mapGameBindingsToOptions(deploymentId, bindings, schema2) {
|
|
27873
|
+
if (!bindings && !schema2) {
|
|
27874
|
+
return;
|
|
27875
|
+
}
|
|
27876
|
+
const workerBindings = {};
|
|
27877
|
+
if (bindings?.database) {
|
|
27878
|
+
workerBindings.d1 = [deploymentId];
|
|
27879
|
+
}
|
|
27880
|
+
if (bindings?.keyValue) {
|
|
27881
|
+
workerBindings.kv = [deploymentId];
|
|
27882
|
+
}
|
|
27883
|
+
if (bindings?.bucket) {
|
|
27884
|
+
workerBindings.r2 = [deploymentId];
|
|
27885
|
+
}
|
|
27886
|
+
if (bindings?.queues) {
|
|
27887
|
+
let toQueueName = function(queueKey) {
|
|
27888
|
+
return `${QUEUE_NAME_PREFIX}-${deploymentId}--${queueKey}`;
|
|
27889
|
+
};
|
|
27890
|
+
const queueNameByKey = new Map;
|
|
27891
|
+
for (const queueKey of Object.keys(bindings.queues)) {
|
|
27892
|
+
queueNameByKey.set(queueKey, toQueueName(queueKey));
|
|
27893
|
+
}
|
|
27894
|
+
workerBindings.queues = Object.entries(bindings.queues).map(([queueKey, queueConfig]) => {
|
|
27895
|
+
const config2 = queueConfig === true ? undefined : queueConfig;
|
|
27896
|
+
const deadLetterQueue = config2?.deadLetterQueue && queueNameByKey.get(config2.deadLetterQueue) ? queueNameByKey.get(config2.deadLetterQueue) : undefined;
|
|
27897
|
+
return {
|
|
27898
|
+
bindingName: toBindingName(queueKey),
|
|
27899
|
+
queueName: toQueueName(queueKey),
|
|
27900
|
+
settings: config2 ? {
|
|
27901
|
+
maxBatchSize: config2.maxBatchSize,
|
|
27902
|
+
maxRetries: config2.maxRetries,
|
|
27903
|
+
maxBatchTimeout: config2.maxBatchTimeout,
|
|
27904
|
+
maxConcurrency: config2.maxConcurrency,
|
|
27905
|
+
retryDelay: config2.retryDelay
|
|
27906
|
+
} : undefined,
|
|
27907
|
+
deadLetterQueue
|
|
27908
|
+
};
|
|
27909
|
+
});
|
|
27910
|
+
}
|
|
27911
|
+
const hasBindings = workerBindings.d1?.length || workerBindings.kv?.length || workerBindings.r2?.length || workerBindings.queues?.length;
|
|
27912
|
+
return {
|
|
27913
|
+
...hasBindings && { bindings: workerBindings },
|
|
27914
|
+
...schema2 && { schema: schema2 }
|
|
27915
|
+
};
|
|
27916
|
+
}
|
|
27917
|
+
static countDeadLetterQueues(bindings) {
|
|
27918
|
+
return bindings?.queues?.filter((queue) => Boolean(queue.deadLetterQueue)).length ?? 0;
|
|
27301
27919
|
}
|
|
27302
27920
|
async cleanupOrphanD1Databases(cf, d1Names, slug, gameId) {
|
|
27303
27921
|
const hasAnyPriorDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
27304
|
-
where: eq(gameDeployments.gameId, gameId),
|
|
27922
|
+
where: and(eq(gameDeployments.gameId, gameId), eq(gameDeployments.target, "game")),
|
|
27305
27923
|
columns: { id: true }
|
|
27306
27924
|
});
|
|
27307
27925
|
if (hasAnyPriorDeployment) {
|
|
@@ -27336,33 +27954,7 @@ class DeployService {
|
|
|
27336
27954
|
}
|
|
27337
27955
|
await this.deps.db.update(games).set(updates).where(eq(games.id, gameId));
|
|
27338
27956
|
}
|
|
27339
|
-
|
|
27340
|
-
const hasBackend = Boolean(request.code);
|
|
27341
|
-
const hasFrontend = Boolean(request.uploadToken);
|
|
27342
|
-
const hasMetadata = Boolean(request.metadata);
|
|
27343
|
-
setAttributes({
|
|
27344
|
-
"app.deploy.has_backend": hasBackend,
|
|
27345
|
-
"app.deploy.has_frontend": hasFrontend,
|
|
27346
|
-
"app.deploy.has_metadata": hasMetadata,
|
|
27347
|
-
"app.deploy.type": DeployService.classifyDeployType({
|
|
27348
|
-
hasBackend,
|
|
27349
|
-
hasFrontend,
|
|
27350
|
-
hasMetadata
|
|
27351
|
-
}),
|
|
27352
|
-
"app.deploy.code_size": request.code?.length ?? 0,
|
|
27353
|
-
"app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27354
|
-
"app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0,
|
|
27355
|
-
"app.deploy.has_schema": Boolean(request.schema)
|
|
27356
|
-
});
|
|
27357
|
-
if (!hasBackend && !hasFrontend && !hasMetadata) {
|
|
27358
|
-
throw new ValidationError("Must provide at least one of: uploadToken (frontend), code (backend), or metadata");
|
|
27359
|
-
}
|
|
27360
|
-
if (!this.deps.config.baseUrl) {
|
|
27361
|
-
throw new ValidationError("baseUrl is not configured");
|
|
27362
|
-
}
|
|
27363
|
-
return { hasBackend, hasFrontend, hasMetadata };
|
|
27364
|
-
}
|
|
27365
|
-
async finalizeDeployment({
|
|
27957
|
+
async finalizeGameDeployment({
|
|
27366
27958
|
game: game2,
|
|
27367
27959
|
slug,
|
|
27368
27960
|
deploymentId,
|
|
@@ -27374,10 +27966,17 @@ class DeployService {
|
|
|
27374
27966
|
const { hasBackend, hasFrontend, hasMetadata } = flags2;
|
|
27375
27967
|
const db2 = this.deps.db;
|
|
27376
27968
|
const codeHash = hasBackend ? await generateDeploymentHash(request.code) : null;
|
|
27377
|
-
await this.saveDeployment(
|
|
27969
|
+
await this.saveDeployment({
|
|
27970
|
+
gameId: game2.id,
|
|
27971
|
+
deploymentId: result.deploymentId,
|
|
27972
|
+
url: result.url,
|
|
27973
|
+
codeHash,
|
|
27974
|
+
resources: result.resources,
|
|
27975
|
+
target: "game"
|
|
27976
|
+
});
|
|
27378
27977
|
if (hasBackend) {
|
|
27379
27978
|
await withSpan("deploy.configure_worker_secrets", async () => {
|
|
27380
|
-
await this.
|
|
27979
|
+
await this.ensureWorkerApiKeyOnWorker(user, DeployService.gameWorkerKeySpec(slug), result.deploymentId);
|
|
27381
27980
|
await this.ensureQueueIngressSecretOnWorker(slug, result.deploymentId);
|
|
27382
27981
|
});
|
|
27383
27982
|
}
|
|
@@ -27410,169 +28009,232 @@ class DeployService {
|
|
|
27410
28009
|
}
|
|
27411
28010
|
return updatedGame;
|
|
27412
28011
|
}
|
|
27413
|
-
|
|
27414
|
-
|
|
27415
|
-
|
|
27416
|
-
|
|
27417
|
-
|
|
27418
|
-
const { hasBackend, hasFrontend } = flags2;
|
|
27419
|
-
const deploymentId = getDeploymentId(slug, this.deps.config.sstStage);
|
|
27420
|
-
let frontendAssetsPath;
|
|
27421
|
-
let tempDir;
|
|
27422
|
-
if (hasFrontend) {
|
|
27423
|
-
if (!uploadDeps || !extractZip) {
|
|
27424
|
-
throw new ValidationError("Upload dependencies not configured for frontend deployment");
|
|
27425
|
-
}
|
|
27426
|
-
yield { type: "status", data: { message: "Fetching temporary files" } };
|
|
27427
|
-
const extracted = await this.fetchAndExtractFrontendAssets(slug, game2.id, request.uploadToken, uploadDeps, extractZip);
|
|
27428
|
-
tempDir = extracted.tempDir;
|
|
27429
|
-
frontendAssetsPath = extracted.assetsPath;
|
|
27430
|
-
yield { type: "status", data: { message: "Extracting assets" } };
|
|
27431
|
-
}
|
|
27432
|
-
let platformBaseUrl = this.deps.config.baseUrl;
|
|
27433
|
-
if (this.deps.config.isLocal) {
|
|
27434
|
-
try {
|
|
27435
|
-
platformBaseUrl = await getTunnelUrl();
|
|
27436
|
-
} catch {
|
|
27437
|
-
setAttributes({
|
|
27438
|
-
"app.deploy.tunnel_available": false,
|
|
27439
|
-
"app.deploy.failure_kind": "local_tunnel_unavailable"
|
|
27440
|
-
});
|
|
27441
|
-
throw new ValidationError("Local tunnel is not running. Ensure cloudflared is installed (`brew install cloudflared`) and the tunnel DevCommand started successfully.");
|
|
27442
|
-
}
|
|
27443
|
-
}
|
|
27444
|
-
const env = {
|
|
27445
|
-
GAME_ID: game2.id,
|
|
27446
|
-
PLAYCADEMY_BASE_URL: platformBaseUrl,
|
|
27447
|
-
PLAYCADEMY_PLATFORM_SERVICE_JWKS: this.deps.config.platformServiceJwt?.publicJwks
|
|
28012
|
+
static gameWorkerKeySpec(slug) {
|
|
28013
|
+
return {
|
|
28014
|
+
keyName: getGameWorkerApiKeyName(slug),
|
|
28015
|
+
permissions: { games: [`read:${slug}`, `write:${slug}`] },
|
|
28016
|
+
lookup: "owner-and-name"
|
|
27448
28017
|
};
|
|
27449
|
-
|
|
27450
|
-
|
|
27451
|
-
|
|
28018
|
+
}
|
|
28019
|
+
static dashboardWorkerKeySpec(slug) {
|
|
28020
|
+
return {
|
|
28021
|
+
keyName: getDashboardWorkerApiKeyName(slug),
|
|
28022
|
+
permissions: {
|
|
28023
|
+
games: [`read:${slug}`],
|
|
28024
|
+
[DASHBOARD_PERMISSION_NAMESPACE]: [dashboardCredentialScope(slug)]
|
|
28025
|
+
},
|
|
28026
|
+
rateLimit: { maxRequests: 300, timeWindowMs: 60000 },
|
|
28027
|
+
lookup: "name",
|
|
28028
|
+
isCurrent: (permissionsJson) => DeployService.hasDashboardCredentialScope(permissionsJson, slug)
|
|
27452
28029
|
};
|
|
27453
|
-
|
|
27454
|
-
|
|
27455
|
-
|
|
27456
|
-
|
|
27457
|
-
"app.deploy.has_d1": Boolean(bindings?.d1?.length),
|
|
27458
|
-
"app.deploy.has_kv": Boolean(bindings?.kv?.length),
|
|
27459
|
-
"app.deploy.has_r2": Boolean(bindings?.r2?.length),
|
|
27460
|
-
"app.deploy.queue_count": bindings?.queues?.length ?? 0,
|
|
27461
|
-
"app.deploy.dead_letter_queue_count": DeployService.countDeadLetterQueues(bindings)
|
|
27462
|
-
});
|
|
27463
|
-
const activeDeployment = await db2.query.gameDeployments.findFirst({
|
|
27464
|
-
where: and(eq(gameDeployments.gameId, game2.id), eq(gameDeployments.isActive, true)),
|
|
27465
|
-
columns: { resources: true }
|
|
27466
|
-
});
|
|
27467
|
-
if (deploymentOptions?.bindings?.d1?.length) {
|
|
27468
|
-
await this.cleanupOrphanD1Databases(cf, deploymentOptions.bindings.d1, slug, game2.id);
|
|
28030
|
+
}
|
|
28031
|
+
static hasDashboardCredentialScope(permissionsJson, slug) {
|
|
28032
|
+
if (!permissionsJson) {
|
|
28033
|
+
return false;
|
|
27469
28034
|
}
|
|
27470
|
-
let result;
|
|
27471
28035
|
try {
|
|
27472
|
-
|
|
27473
|
-
|
|
27474
|
-
|
|
27475
|
-
|
|
27476
|
-
|
|
27477
|
-
|
|
27478
|
-
|
|
27479
|
-
|
|
27480
|
-
|
|
27481
|
-
|
|
27482
|
-
|
|
27483
|
-
|
|
28036
|
+
const parsed = JSON.parse(permissionsJson);
|
|
28037
|
+
return dashboardCredentialSlugs(parsed).includes(slug);
|
|
28038
|
+
} catch {
|
|
28039
|
+
return false;
|
|
28040
|
+
}
|
|
28041
|
+
}
|
|
28042
|
+
async ensureWorkerApiKeyOnWorker(user, spec, deploymentId, existingSecrets) {
|
|
28043
|
+
const cf = this.getCloudflare();
|
|
28044
|
+
const existingKey = await this.deps.db.query.apikey.findFirst({
|
|
28045
|
+
where: spec.lookup === "owner-and-name" ? and(eq(apikey.userId, user.id), eq(apikey.name, spec.keyName)) : eq(apikey.name, spec.keyName),
|
|
28046
|
+
columns: { id: true, permissions: true }
|
|
28047
|
+
});
|
|
28048
|
+
let apiKey;
|
|
28049
|
+
if (!existingKey) {
|
|
28050
|
+
apiKey = await this.createApiKey(user, spec);
|
|
28051
|
+
} else {
|
|
28052
|
+
const current = spec.isCurrent?.(existingKey.permissions) ?? true;
|
|
28053
|
+
const workerHasKey = existingSecrets ? existingSecrets.includes("PLAYCADEMY_API_KEY") : await this.workerHasSecret(deploymentId, "PLAYCADEMY_API_KEY");
|
|
28054
|
+
if (current && workerHasKey) {
|
|
28055
|
+
setAttribute("app.deploy.api_key_outcome", "already_set");
|
|
28056
|
+
return;
|
|
27484
28057
|
}
|
|
28058
|
+
apiKey = await this.regenerateApiKey(user, existingKey.id, spec);
|
|
27485
28059
|
}
|
|
27486
|
-
|
|
27487
|
-
|
|
27488
|
-
|
|
27489
|
-
|
|
27490
|
-
|
|
27491
|
-
|
|
27492
|
-
|
|
27493
|
-
|
|
27494
|
-
|
|
28060
|
+
await cf.setSecrets(deploymentId, { PLAYCADEMY_API_KEY: apiKey });
|
|
28061
|
+
}
|
|
28062
|
+
async createApiKey(user, spec) {
|
|
28063
|
+
const { key: apiKey } = await this.deps.createAuthApiKey({
|
|
28064
|
+
userId: user.id,
|
|
28065
|
+
name: spec.keyName,
|
|
28066
|
+
expiresIn: null,
|
|
28067
|
+
permissions: spec.permissions,
|
|
28068
|
+
...spec.rateLimit ? {
|
|
28069
|
+
rateLimitEnabled: true,
|
|
28070
|
+
rateLimitMax: spec.rateLimit.maxRequests,
|
|
28071
|
+
rateLimitTimeWindow: spec.rateLimit.timeWindowMs
|
|
28072
|
+
} : { rateLimitEnabled: false }
|
|
27495
28073
|
});
|
|
27496
|
-
|
|
28074
|
+
setAttribute("app.deploy.api_key_outcome", "created");
|
|
28075
|
+
return apiKey;
|
|
27497
28076
|
}
|
|
27498
|
-
|
|
27499
|
-
|
|
28077
|
+
async regenerateApiKey(user, existingKeyId, spec) {
|
|
28078
|
+
setAttribute("app.deploy.api_key_outcome", "regenerated");
|
|
28079
|
+
try {
|
|
28080
|
+
await this.deps.deleteAuthApiKey(existingKeyId);
|
|
28081
|
+
} catch (error) {
|
|
28082
|
+
addEvent("deploy.api_key_revoke_failed", {
|
|
28083
|
+
"exception.type": errorType(error),
|
|
28084
|
+
"app.error.message": errorMessage(error),
|
|
28085
|
+
"app.deploy.old_key_id": existingKeyId
|
|
28086
|
+
});
|
|
28087
|
+
}
|
|
28088
|
+
return this.createApiKey(user, spec);
|
|
28089
|
+
}
|
|
28090
|
+
async listWorkerSecretNames(deploymentId) {
|
|
28091
|
+
try {
|
|
28092
|
+
return await this.getCloudflare().listSecrets(deploymentId);
|
|
28093
|
+
} catch (error) {
|
|
28094
|
+
addEvent("deploy.worker_secrets_check_failed", {
|
|
28095
|
+
"exception.type": errorType(error),
|
|
28096
|
+
"app.error.message": errorMessage(error)
|
|
28097
|
+
});
|
|
28098
|
+
return null;
|
|
28099
|
+
}
|
|
28100
|
+
}
|
|
28101
|
+
async workerHasSecret(deploymentId, secretName) {
|
|
28102
|
+
const workerSecrets = await this.listWorkerSecretNames(deploymentId);
|
|
28103
|
+
return Boolean(workerSecrets?.includes(secretName));
|
|
28104
|
+
}
|
|
28105
|
+
async ensureQueueIngressSecretOnWorker(slug, deploymentId) {
|
|
28106
|
+
const secret = this.deps.config.queueIngressSecret;
|
|
28107
|
+
if (!secret) {
|
|
27500
28108
|
return;
|
|
27501
28109
|
}
|
|
27502
|
-
const
|
|
27503
|
-
|
|
27504
|
-
|
|
28110
|
+
const cf = this.getCloudflare();
|
|
28111
|
+
await cf.setSecrets(deploymentId, { QUEUE_INGRESS_SECRET: secret });
|
|
28112
|
+
}
|
|
28113
|
+
async ensureDashboardSessionSecret(deploymentId, existingSecrets, hasPriorDeployment) {
|
|
28114
|
+
if (existingSecrets === null && hasPriorDeployment) {
|
|
28115
|
+
setAttribute("app.deploy.session_secret_outcome", "check_failed_kept");
|
|
28116
|
+
return;
|
|
27505
28117
|
}
|
|
27506
|
-
if (
|
|
27507
|
-
|
|
28118
|
+
if (existingSecrets?.includes("DASHBOARD_SESSION_SECRET")) {
|
|
28119
|
+
setAttribute("app.deploy.session_secret_outcome", "already_set");
|
|
28120
|
+
return;
|
|
27508
28121
|
}
|
|
27509
|
-
|
|
27510
|
-
|
|
28122
|
+
const secret = await generateSecureRandomString(64);
|
|
28123
|
+
await this.getCloudflare().setSecrets(deploymentId, { DASHBOARD_SESSION_SECRET: secret });
|
|
28124
|
+
setAttribute("app.deploy.session_secret_outcome", "created");
|
|
28125
|
+
}
|
|
28126
|
+
async rotateDashboardSessionSecret(slug, user) {
|
|
28127
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
28128
|
+
const deployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
28129
|
+
where: activeDeploymentWhere(game2.id, "dashboard"),
|
|
28130
|
+
columns: { deploymentId: true }
|
|
28131
|
+
});
|
|
28132
|
+
if (!deployment) {
|
|
28133
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, slug);
|
|
28134
|
+
throw new NotFoundError("Dashboard deployment", slug);
|
|
27511
28135
|
}
|
|
27512
|
-
|
|
27513
|
-
|
|
27514
|
-
|
|
27515
|
-
|
|
27516
|
-
|
|
27517
|
-
|
|
27518
|
-
|
|
27519
|
-
|
|
27520
|
-
|
|
27521
|
-
|
|
27522
|
-
|
|
27523
|
-
|
|
27524
|
-
|
|
27525
|
-
|
|
27526
|
-
|
|
27527
|
-
|
|
27528
|
-
|
|
27529
|
-
|
|
27530
|
-
|
|
27531
|
-
|
|
27532
|
-
|
|
27533
|
-
|
|
27534
|
-
|
|
28136
|
+
const secret = await generateSecureRandomString(64);
|
|
28137
|
+
await this.getCloudflare().setSecrets(deployment.deploymentId, {
|
|
28138
|
+
DASHBOARD_SESSION_SECRET: secret
|
|
28139
|
+
});
|
|
28140
|
+
setAttribute("app.deploy.session_secret_outcome", "rotated");
|
|
28141
|
+
}
|
|
28142
|
+
async removeDashboard(slug, user) {
|
|
28143
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
28144
|
+
const db2 = this.deps.db;
|
|
28145
|
+
const deployment = await db2.query.gameDeployments.findFirst({
|
|
28146
|
+
where: activeDeploymentWhere(game2.id, "dashboard"),
|
|
28147
|
+
columns: { deploymentId: true, provider: true, resources: true }
|
|
28148
|
+
});
|
|
28149
|
+
if (!deployment) {
|
|
28150
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, slug);
|
|
28151
|
+
throw new NotFoundError("Dashboard deployment", slug);
|
|
28152
|
+
}
|
|
28153
|
+
const assetBuckets = deployment.resources?.r2?.filter((bucket) => bucket.kind === "assets") ?? [];
|
|
28154
|
+
await this.getCloudflare().delete(deployment.deploymentId, {
|
|
28155
|
+
deleteBindings: assetBuckets.length > 0,
|
|
28156
|
+
resources: assetBuckets.length > 0 ? { r2: assetBuckets } : undefined
|
|
28157
|
+
});
|
|
28158
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, slug);
|
|
28159
|
+
await db2.delete(gameDeployments).where(and(eq(gameDeployments.gameId, game2.id), eq(gameDeployments.target, "dashboard")));
|
|
28160
|
+
setAttribute("app.deploy.dashboard_removed", true);
|
|
28161
|
+
await withSpan("deploy.send_alert", () => this.deps.alerts.notifyDashboardRemoval({
|
|
28162
|
+
slug,
|
|
28163
|
+
displayName: game2.displayName,
|
|
28164
|
+
developer: { id: user.id, email: user.email }
|
|
28165
|
+
})).catch(catchAttrs("alerts.delivery", { "app.alerts.type": "dashboard_removal" }));
|
|
28166
|
+
}
|
|
28167
|
+
async fetchAndExtractFrontendAssets(slug, gameId, uploadToken, uploadDeps, extractZip) {
|
|
28168
|
+
const frontendZip = await withSpan("deploy.fetch_temporary_files", () => uploadDeps.getObjectAsByteArray(uploadToken));
|
|
28169
|
+
if (!frontendZip || frontendZip.length === 0) {
|
|
28170
|
+
throw new ValidationError("Uploaded file is empty or not found");
|
|
28171
|
+
}
|
|
28172
|
+
setAttribute("app.deploy.asset_upload_size", frontendZip.length);
|
|
28173
|
+
const os2 = await import("os");
|
|
28174
|
+
const path = await import("path");
|
|
28175
|
+
const tempDir = path.join(os2.tmpdir(), `playcademy-deploy-${gameId}-${Date.now()}`);
|
|
28176
|
+
const assetsPath = path.join(tempDir, "dist");
|
|
28177
|
+
await withSpan("deploy.extract_assets", () => extractZip(frontendZip, assetsPath));
|
|
28178
|
+
uploadDeps.deleteObject(uploadToken).catch(catchAttrs("deploy.temp_cleanup"));
|
|
28179
|
+
return { frontendZip, tempDir, assetsPath };
|
|
28180
|
+
}
|
|
28181
|
+
async resolvePlatformBaseUrl() {
|
|
28182
|
+
if (!this.deps.config.isLocal) {
|
|
28183
|
+
return this.deps.config.baseUrl;
|
|
28184
|
+
}
|
|
28185
|
+
try {
|
|
28186
|
+
return await getTunnelUrl();
|
|
28187
|
+
} catch {
|
|
28188
|
+
setAttributes({
|
|
28189
|
+
"app.deploy.tunnel_available": false,
|
|
28190
|
+
"app.deploy.failure_kind": "local_tunnel_unavailable"
|
|
27535
28191
|
});
|
|
28192
|
+
throw new ValidationError("Local tunnel is not running. Ensure cloudflared is installed (`brew install cloudflared`) and the tunnel DevCommand started successfully.");
|
|
27536
28193
|
}
|
|
27537
|
-
const hasBindings = workerBindings.d1?.length || workerBindings.kv?.length || workerBindings.r2?.length || workerBindings.queues?.length;
|
|
27538
|
-
return {
|
|
27539
|
-
...hasBindings && { bindings: workerBindings },
|
|
27540
|
-
...schema2 && { schema: schema2 }
|
|
27541
|
-
};
|
|
27542
28194
|
}
|
|
27543
|
-
async
|
|
27544
|
-
|
|
27545
|
-
|
|
27546
|
-
|
|
27547
|
-
|
|
27548
|
-
|
|
27549
|
-
|
|
28195
|
+
async deployToCloudflare(args2) {
|
|
28196
|
+
const cf = this.getCloudflare();
|
|
28197
|
+
try {
|
|
28198
|
+
return await withSpan("deploy.cloudflare", () => cf.deploy(args2.deploymentId, args2.code, args2.env, args2.options));
|
|
28199
|
+
} finally {
|
|
28200
|
+
if (args2.tempDir) {
|
|
28201
|
+
const fs2 = await import("fs/promises");
|
|
28202
|
+
fs2.rm(args2.tempDir, { recursive: true, force: true }).catch(catchAttrs("deploy.temp_cleanup"));
|
|
28203
|
+
}
|
|
28204
|
+
}
|
|
27550
28205
|
}
|
|
27551
|
-
async saveDeployment(
|
|
28206
|
+
async saveDeployment(record) {
|
|
27552
28207
|
const db2 = this.deps.db;
|
|
27553
28208
|
await db2.transaction(async (tx) => {
|
|
27554
|
-
await tx.update(gameDeployments).set({ isActive: false }).where(eq(gameDeployments.gameId, gameId));
|
|
28209
|
+
await tx.update(gameDeployments).set({ isActive: false }).where(and(eq(gameDeployments.gameId, record.gameId), eq(gameDeployments.target, record.target)));
|
|
27555
28210
|
await tx.insert(gameDeployments).values({
|
|
27556
|
-
gameId,
|
|
27557
|
-
deploymentId,
|
|
28211
|
+
gameId: record.gameId,
|
|
28212
|
+
deploymentId: record.deploymentId,
|
|
27558
28213
|
provider: "cloudflare",
|
|
27559
|
-
|
|
27560
|
-
|
|
27561
|
-
|
|
28214
|
+
target: record.target,
|
|
28215
|
+
url: record.url,
|
|
28216
|
+
codeHash: record.codeHash,
|
|
28217
|
+
resources: record.resources,
|
|
27562
28218
|
isActive: true
|
|
27563
28219
|
});
|
|
27564
28220
|
});
|
|
27565
28221
|
}
|
|
28222
|
+
async notifyDeploymentFailure(failure) {
|
|
28223
|
+
await this.deps.alerts.notifyDeploymentFailure(failure).catch(catchAttrs("alerts.delivery", { "app.alerts.type": "deployment_failure" }));
|
|
28224
|
+
}
|
|
27566
28225
|
}
|
|
27567
28226
|
var init_deploy_service = __esm(() => {
|
|
27568
28227
|
init_drizzle_orm();
|
|
27569
28228
|
init_playcademy();
|
|
27570
28229
|
init_src();
|
|
28230
|
+
init_helpers_index();
|
|
27571
28231
|
init_tables_index();
|
|
27572
28232
|
init_spans();
|
|
27573
28233
|
init_tunnel();
|
|
27574
28234
|
init_errors();
|
|
28235
|
+
init_dashboard_util();
|
|
27575
28236
|
init_deployment_util();
|
|
28237
|
+
init_worker_keys_util();
|
|
27576
28238
|
});
|
|
27577
28239
|
|
|
27578
28240
|
// ../api-core/src/services/developer.service.ts
|
|
@@ -27817,20 +28479,6 @@ var init_game_member_service = __esm(() => {
|
|
|
27817
28479
|
init_spans();
|
|
27818
28480
|
init_errors();
|
|
27819
28481
|
});
|
|
27820
|
-
// ../data/src/domains/timeback/helpers.ts
|
|
27821
|
-
function isActiveGameTimebackIntegrationStatus(statusColumn = gameTimebackIntegrations.status) {
|
|
27822
|
-
return sql`${statusColumn} IS DISTINCT FROM ${DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS}`;
|
|
27823
|
-
}
|
|
27824
|
-
var ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS = "active", DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS = "deactivated";
|
|
27825
|
-
var init_helpers2 = __esm(() => {
|
|
27826
|
-
init_drizzle_orm();
|
|
27827
|
-
init_table7();
|
|
27828
|
-
});
|
|
27829
|
-
|
|
27830
|
-
// ../data/src/helpers.index.ts
|
|
27831
|
-
var init_helpers_index = __esm(() => {
|
|
27832
|
-
init_helpers2();
|
|
27833
|
-
});
|
|
27834
28482
|
|
|
27835
28483
|
// ../utils/src/fns.ts
|
|
27836
28484
|
function sleep(ms) {
|
|
@@ -28274,6 +28922,7 @@ var init_game_service = __esm(() => {
|
|
|
28274
28922
|
init_errors();
|
|
28275
28923
|
init_deployment_util();
|
|
28276
28924
|
init_timeback_util();
|
|
28925
|
+
init_worker_keys_util();
|
|
28277
28926
|
inFlightManifestFetches = new Map;
|
|
28278
28927
|
GameService = class GameService {
|
|
28279
28928
|
deps;
|
|
@@ -28460,7 +29109,7 @@ var init_game_service = __esm(() => {
|
|
|
28460
29109
|
GameService.recordGameShape(game2);
|
|
28461
29110
|
return game2;
|
|
28462
29111
|
}
|
|
28463
|
-
async getBySlug(slug, caller) {
|
|
29112
|
+
async getBySlug(slug, caller, options) {
|
|
28464
29113
|
const db2 = this.deps.db;
|
|
28465
29114
|
const game2 = await db2.query.games.findFirst({
|
|
28466
29115
|
where: eq(games.slug, slug)
|
|
@@ -28468,7 +29117,9 @@ var init_game_service = __esm(() => {
|
|
|
28468
29117
|
if (!game2) {
|
|
28469
29118
|
throw new NotFoundError("Game", slug);
|
|
28470
29119
|
}
|
|
28471
|
-
|
|
29120
|
+
if (!options?.scopeAuthorized) {
|
|
29121
|
+
await this.enforceVisibility(game2, caller, slug);
|
|
29122
|
+
}
|
|
28472
29123
|
GameService.recordGameShape(game2);
|
|
28473
29124
|
return game2;
|
|
28474
29125
|
}
|
|
@@ -28645,6 +29296,9 @@ var init_game_service = __esm(() => {
|
|
|
28645
29296
|
await this.validateDeveloperAccess(user, gameId);
|
|
28646
29297
|
} else {
|
|
28647
29298
|
this.validateDeveloperStatus(user);
|
|
29299
|
+
if (slug.endsWith(DASHBOARD_WORKER_SUFFIX)) {
|
|
29300
|
+
throw new ValidationError(`Game slugs may not end with '${DASHBOARD_WORKER_SUFFIX}' — it is reserved for dashboard workers`);
|
|
29301
|
+
}
|
|
28648
29302
|
}
|
|
28649
29303
|
const gameDataForDb = {
|
|
28650
29304
|
displayName: data.displayName,
|
|
@@ -28771,15 +29425,21 @@ var init_game_service = __esm(() => {
|
|
|
28771
29425
|
if (!gameToDelete?.slug) {
|
|
28772
29426
|
throw new NotFoundError("Game", gameId);
|
|
28773
29427
|
}
|
|
28774
|
-
const activeDeployment = await
|
|
28775
|
-
|
|
28776
|
-
|
|
28777
|
-
|
|
28778
|
-
|
|
28779
|
-
|
|
28780
|
-
|
|
28781
|
-
|
|
28782
|
-
|
|
29428
|
+
const [activeDeployment, dashboardDeployment, customHostnames] = await Promise.all([
|
|
29429
|
+
db2.query.gameDeployments.findFirst({
|
|
29430
|
+
where: activeDeploymentWhere(gameId, "game"),
|
|
29431
|
+
columns: { deploymentId: true, provider: true, resources: true }
|
|
29432
|
+
}),
|
|
29433
|
+
db2.query.gameDeployments.findFirst({
|
|
29434
|
+
where: activeDeploymentWhere(gameId, "dashboard"),
|
|
29435
|
+
columns: { deploymentId: true, provider: true, resources: true }
|
|
29436
|
+
}),
|
|
29437
|
+
db2.select({
|
|
29438
|
+
hostname: gameCustomHostnames.hostname,
|
|
29439
|
+
cloudflareId: gameCustomHostnames.cloudflareId,
|
|
29440
|
+
environment: gameCustomHostnames.environment
|
|
29441
|
+
}).from(gameCustomHostnames).where(eq(gameCustomHostnames.gameId, gameId))
|
|
29442
|
+
]);
|
|
28783
29443
|
const result = await db2.delete(games).where(eq(games.id, gameId)).returning({ id: games.id });
|
|
28784
29444
|
if (result.length === 0) {
|
|
28785
29445
|
throw new NotFoundError("Game", gameId);
|
|
@@ -28823,6 +29483,22 @@ var init_game_service = __esm(() => {
|
|
|
28823
29483
|
setAttribute("app.game.api_key_cleanup_error", errorMessage(error));
|
|
28824
29484
|
}
|
|
28825
29485
|
}
|
|
29486
|
+
if (dashboardDeployment?.provider === "cloudflare" && this.deps.cloudflare) {
|
|
29487
|
+
const dashboardAssetBuckets = dashboardDeployment.resources?.r2?.filter((bucket) => bucket.kind === "assets") ?? [];
|
|
29488
|
+
try {
|
|
29489
|
+
await this.deps.cloudflare.delete(dashboardDeployment.deploymentId, {
|
|
29490
|
+
deleteBindings: dashboardAssetBuckets.length > 0,
|
|
29491
|
+
resources: dashboardAssetBuckets.length > 0 ? { r2: dashboardAssetBuckets } : undefined
|
|
29492
|
+
});
|
|
29493
|
+
setAttribute("app.game.dashboard_cleanup", "succeeded");
|
|
29494
|
+
} catch (error) {
|
|
29495
|
+
setAttributes({
|
|
29496
|
+
"app.game.dashboard_cleanup": "failed",
|
|
29497
|
+
"app.game.dashboard_cleanup_error": errorMessage(error)
|
|
29498
|
+
});
|
|
29499
|
+
}
|
|
29500
|
+
}
|
|
29501
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, gameToDelete.slug);
|
|
28826
29502
|
const corsOrigin = GameService.safeOrigin(gameToDelete);
|
|
28827
29503
|
if (this.deps.corsKvs && corsOrigin) {
|
|
28828
29504
|
setAttribute("app.cors_kvs.origin", corsOrigin);
|
|
@@ -28946,7 +29622,7 @@ class LogsService {
|
|
|
28946
29622
|
}
|
|
28947
29623
|
async generateToken(user, slug, sstStage) {
|
|
28948
29624
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
28949
|
-
const workerId =
|
|
29625
|
+
const workerId = getGameDeploymentId(slug, sstStage);
|
|
28950
29626
|
const token = await this.deps.mintLogStreamToken(user.id, workerId);
|
|
28951
29627
|
setAttribute("app.logs.worker_id", workerId);
|
|
28952
29628
|
return { token, workerId };
|
|
@@ -28966,7 +29642,8 @@ function createGameServices(deps) {
|
|
|
28966
29642
|
cache,
|
|
28967
29643
|
cloudflare: cloudflare2,
|
|
28968
29644
|
corsKvs,
|
|
28969
|
-
deleteApiKeyByName: auth2.deleteApiKeyByName.bind(auth2)
|
|
29645
|
+
deleteApiKeyByName: auth2.deleteApiKeyByName.bind(auth2),
|
|
29646
|
+
deleteApiKeysByName: auth2.deleteApiKeysByName.bind(auth2)
|
|
28970
29647
|
});
|
|
28971
29648
|
const gameMember = new GameMemberService({
|
|
28972
29649
|
db: db2,
|
|
@@ -28979,6 +29656,7 @@ function createGameServices(deps) {
|
|
|
28979
29656
|
cloudflare: cloudflare2,
|
|
28980
29657
|
createAuthApiKey: auth2.createApiKey.bind(auth2),
|
|
28981
29658
|
deleteAuthApiKey: auth2.deleteApiKey.bind(auth2),
|
|
29659
|
+
deleteApiKeysByName: auth2.deleteApiKeysByName.bind(auth2),
|
|
28982
29660
|
alerts,
|
|
28983
29661
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug)
|
|
28984
29662
|
});
|
|
@@ -28988,14 +29666,20 @@ function createGameServices(deps) {
|
|
|
28988
29666
|
storage,
|
|
28989
29667
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug),
|
|
28990
29668
|
runDeploy: (slug, request, user, uploadDeps, extractZip) => deploy.deploy(slug, request, user, uploadDeps, extractZip),
|
|
28991
|
-
notifyDeploymentFailure: (
|
|
29669
|
+
notifyDeploymentFailure: (failure) => deploy.notifyDeploymentFailure(failure)
|
|
28992
29670
|
});
|
|
28993
29671
|
const logs = new LogsService({
|
|
28994
29672
|
mintLogStreamToken: auth2.mintLogStreamToken.bind(auth2),
|
|
28995
29673
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug)
|
|
28996
29674
|
});
|
|
29675
|
+
const dashboard2 = new DashboardService({
|
|
29676
|
+
db: db2,
|
|
29677
|
+
hashPassword: auth2.hashPassword.bind(auth2),
|
|
29678
|
+
verifyPassword: auth2.verifyPassword.bind(auth2),
|
|
29679
|
+
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug)
|
|
29680
|
+
});
|
|
28997
29681
|
return {
|
|
28998
|
-
services: { game: game2, gameMember, developer, deploy, deployJobs, logs },
|
|
29682
|
+
services: { game: game2, gameMember, developer, deploy, deployJobs, logs, dashboard: dashboard2 },
|
|
28999
29683
|
validators: {
|
|
29000
29684
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug),
|
|
29001
29685
|
validateDeveloperAccess: (user, gameId) => game2.validateDeveloperAccess(user, gameId),
|
|
@@ -29005,6 +29689,7 @@ function createGameServices(deps) {
|
|
|
29005
29689
|
};
|
|
29006
29690
|
}
|
|
29007
29691
|
var init_game2 = __esm(() => {
|
|
29692
|
+
init_dashboard_service();
|
|
29008
29693
|
init_deploy_job_service();
|
|
29009
29694
|
init_deploy_service();
|
|
29010
29695
|
init_developer_service();
|
|
@@ -29189,12 +29874,25 @@ class AlertsService {
|
|
|
29189
29874
|
embed.setFooter("Playcademy Developer Platform").setTimestamp();
|
|
29190
29875
|
await this.sendAlert(discord, embed.build());
|
|
29191
29876
|
}
|
|
29877
|
+
async notifyDashboardDeployment(dashboard2) {
|
|
29878
|
+
const discord = this.recordAlert("dashboard_deployment");
|
|
29879
|
+
if (!discord) {
|
|
29880
|
+
return;
|
|
29881
|
+
}
|
|
29882
|
+
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);
|
|
29883
|
+
if (dashboard2.developer) {
|
|
29884
|
+
embed.addField("Developer", dashboard2.developer.email || dashboard2.developer.id, true);
|
|
29885
|
+
}
|
|
29886
|
+
embed.setFooter("Playcademy Developer Platform").setTimestamp();
|
|
29887
|
+
await this.sendAlert(discord, embed.build());
|
|
29888
|
+
}
|
|
29192
29889
|
async notifyDeploymentFailure(failure) {
|
|
29193
29890
|
const discord = this.recordAlert("deployment_failure");
|
|
29194
29891
|
if (!discord) {
|
|
29195
29892
|
return;
|
|
29196
29893
|
}
|
|
29197
|
-
const
|
|
29894
|
+
const [title, subject] = failure.target === "dashboard" ? ["❌ Dashboard Deployment Failed", "Dashboard deployment"] : ["❌ Deployment Failed", "Deployment"];
|
|
29895
|
+
const embed = new DiscordEmbedBuilder().setTitle(title).setDescription(`${subject} failed for **${failure.displayName || failure.slug}** (**${this.getEnvironment()}**).`).setColor(DiscordColors.RED).addField("Slug", failure.slug, true);
|
|
29198
29896
|
if (failure.developer) {
|
|
29199
29897
|
embed.addField("Developer", failure.developer.email || failure.developer.id, true);
|
|
29200
29898
|
}
|
|
@@ -29209,6 +29907,14 @@ class AlertsService {
|
|
|
29209
29907
|
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();
|
|
29210
29908
|
await this.sendAlert(discord, embed);
|
|
29211
29909
|
}
|
|
29910
|
+
async notifyDashboardRemoval(dashboard2) {
|
|
29911
|
+
const discord = this.recordAlert("dashboard_removal");
|
|
29912
|
+
if (!discord) {
|
|
29913
|
+
return;
|
|
29914
|
+
}
|
|
29915
|
+
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();
|
|
29916
|
+
await this.sendAlert(discord, embed);
|
|
29917
|
+
}
|
|
29212
29918
|
async notifySeedFailure(failure) {
|
|
29213
29919
|
const discord = this.recordAlert("seed_failure");
|
|
29214
29920
|
if (!discord) {
|
|
@@ -29374,6 +30080,7 @@ class KVBackupService {
|
|
|
29374
30080
|
async getTargets(gameSlug) {
|
|
29375
30081
|
const conditions2 = [
|
|
29376
30082
|
eq(gameDeployments.isActive, true),
|
|
30083
|
+
eq(gameDeployments.target, "game"),
|
|
29377
30084
|
eq(gameDeployments.provider, "cloudflare")
|
|
29378
30085
|
];
|
|
29379
30086
|
if (gameSlug) {
|
|
@@ -29600,7 +30307,7 @@ class BucketService {
|
|
|
29600
30307
|
return extensionIndex > 0 ? fileName.slice(extensionIndex + 1).toLowerCase() : "(none)";
|
|
29601
30308
|
}
|
|
29602
30309
|
getBucketName(slug) {
|
|
29603
|
-
return
|
|
30310
|
+
return getGameDeploymentId(slug, this.deps.sstStage);
|
|
29604
30311
|
}
|
|
29605
30312
|
async listFiles(slug, user, prefix) {
|
|
29606
30313
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
@@ -29689,6 +30396,32 @@ class DatabaseService {
|
|
|
29689
30396
|
}
|
|
29690
30397
|
return d1;
|
|
29691
30398
|
}
|
|
30399
|
+
async syncDashboardD1Binding(gameId, d1ResourceName, databaseId) {
|
|
30400
|
+
const dashboardDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
30401
|
+
where: activeDeploymentWhere(gameId, "dashboard"),
|
|
30402
|
+
columns: { id: true, deploymentId: true, resources: true }
|
|
30403
|
+
});
|
|
30404
|
+
if (!dashboardDeployment || !this.deps.cloudflare) {
|
|
30405
|
+
return;
|
|
30406
|
+
}
|
|
30407
|
+
try {
|
|
30408
|
+
await this.deps.cloudflare.updateD1Binding(dashboardDeployment.deploymentId, databaseId);
|
|
30409
|
+
if (dashboardDeployment.resources?.d1?.length) {
|
|
30410
|
+
const updatedResources = {
|
|
30411
|
+
...dashboardDeployment.resources,
|
|
30412
|
+
d1: dashboardDeployment.resources.d1.map((dbResource) => dbResource.name === d1ResourceName ? { ...dbResource, id: databaseId } : dbResource)
|
|
30413
|
+
};
|
|
30414
|
+
await this.deps.db.update(gameDeployments).set({ resources: updatedResources }).where(eq(gameDeployments.id, dashboardDeployment.id));
|
|
30415
|
+
}
|
|
30416
|
+
setAttribute("app.database.dashboard_binding", "updated");
|
|
30417
|
+
} catch (error) {
|
|
30418
|
+
addEvent("database.dashboard_binding_sync_failed", {
|
|
30419
|
+
"exception.type": errorType(error),
|
|
30420
|
+
"app.error.message": errorMessage(error),
|
|
30421
|
+
"app.deploy.deployment_id": dashboardDeployment.deploymentId
|
|
30422
|
+
});
|
|
30423
|
+
}
|
|
30424
|
+
}
|
|
29692
30425
|
async reset(slug, user, schema2) {
|
|
29693
30426
|
setAttributes({
|
|
29694
30427
|
"app.database.operation": "reset",
|
|
@@ -29697,7 +30430,7 @@ class DatabaseService {
|
|
|
29697
30430
|
});
|
|
29698
30431
|
const d1 = this.getD1();
|
|
29699
30432
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
29700
|
-
const deploymentId =
|
|
30433
|
+
const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
29701
30434
|
try {
|
|
29702
30435
|
const databaseId = await d1.reset(deploymentId);
|
|
29703
30436
|
setAttribute("app.database.id", databaseId);
|
|
@@ -29713,7 +30446,7 @@ class DatabaseService {
|
|
|
29713
30446
|
setAttribute("app.database.binding", "skipped_no_provider");
|
|
29714
30447
|
}
|
|
29715
30448
|
const activeDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
29716
|
-
where:
|
|
30449
|
+
where: activeDeploymentWhere(game2.id),
|
|
29717
30450
|
columns: { id: true, resources: true }
|
|
29718
30451
|
});
|
|
29719
30452
|
setAttribute("app.database.active_deployment_found", Boolean(activeDeployment));
|
|
@@ -29724,6 +30457,7 @@ class DatabaseService {
|
|
|
29724
30457
|
};
|
|
29725
30458
|
await this.deps.db.update(gameDeployments).set({ resources: updatedResources }).where(eq(gameDeployments.id, activeDeployment.id));
|
|
29726
30459
|
}
|
|
30460
|
+
await this.syncDashboardD1Binding(game2.id, deploymentId, databaseId);
|
|
29727
30461
|
setAttributes({
|
|
29728
30462
|
"app.database.deployment_id": deploymentId,
|
|
29729
30463
|
"app.database.schema_pushed": schemaPushed
|
|
@@ -29747,6 +30481,7 @@ class DatabaseService {
|
|
|
29747
30481
|
}
|
|
29748
30482
|
var init_database_service = __esm(() => {
|
|
29749
30483
|
init_drizzle_orm();
|
|
30484
|
+
init_helpers_index();
|
|
29750
30485
|
init_tables_index();
|
|
29751
30486
|
init_spans();
|
|
29752
30487
|
init_errors();
|
|
@@ -29990,7 +30725,7 @@ class KVService {
|
|
|
29990
30725
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
29991
30726
|
const db2 = this.deps.db;
|
|
29992
30727
|
const deployment = await db2.query.gameDeployments.findFirst({
|
|
29993
|
-
where:
|
|
30728
|
+
where: activeDeploymentWhere(game2.id),
|
|
29994
30729
|
columns: { resources: true }
|
|
29995
30730
|
});
|
|
29996
30731
|
if (!deployment?.resources?.kv?.length) {
|
|
@@ -30111,8 +30846,7 @@ class KVService {
|
|
|
30111
30846
|
}
|
|
30112
30847
|
}
|
|
30113
30848
|
var init_kv_service = __esm(() => {
|
|
30114
|
-
|
|
30115
|
-
init_tables_index();
|
|
30849
|
+
init_helpers_index();
|
|
30116
30850
|
init_spans();
|
|
30117
30851
|
init_errors();
|
|
30118
30852
|
});
|
|
@@ -30129,13 +30863,13 @@ class SecretsService {
|
|
|
30129
30863
|
}
|
|
30130
30864
|
return this.deps.cloudflare;
|
|
30131
30865
|
}
|
|
30132
|
-
|
|
30133
|
-
return
|
|
30866
|
+
getGameDeploymentId(slug) {
|
|
30867
|
+
return getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
30134
30868
|
}
|
|
30135
30869
|
async listKeys(slug, user) {
|
|
30136
30870
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30137
30871
|
const cf = this.getCloudflare();
|
|
30138
|
-
const deploymentId = this.
|
|
30872
|
+
const deploymentId = this.getGameDeploymentId(slug);
|
|
30139
30873
|
try {
|
|
30140
30874
|
const allKeys = await cf.listSecrets(deploymentId);
|
|
30141
30875
|
const userKeys = allKeys.filter((k) => k.startsWith(SECRETS_PREFIX)).map((k) => k.slice(SECRETS_PREFIX.length));
|
|
@@ -30161,7 +30895,7 @@ class SecretsService {
|
|
|
30161
30895
|
async setSecrets(slug, newSecrets, user) {
|
|
30162
30896
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30163
30897
|
const cf = this.getCloudflare();
|
|
30164
|
-
const deploymentId = this.
|
|
30898
|
+
const deploymentId = this.getGameDeploymentId(slug);
|
|
30165
30899
|
const secretKeys = Object.keys(newSecrets);
|
|
30166
30900
|
if (secretKeys.length === 0) {
|
|
30167
30901
|
throw new ValidationError("At least one secret must be provided");
|
|
@@ -30214,7 +30948,7 @@ class SecretsService {
|
|
|
30214
30948
|
}
|
|
30215
30949
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30216
30950
|
const cf = this.getCloudflare();
|
|
30217
|
-
const deploymentId = this.
|
|
30951
|
+
const deploymentId = this.getGameDeploymentId(slug);
|
|
30218
30952
|
try {
|
|
30219
30953
|
const prefixedKey = `${SECRETS_PREFIX}${key}`;
|
|
30220
30954
|
const existingKeys = await cf.listSecrets(deploymentId);
|
|
@@ -30251,27 +30985,7 @@ var init_secrets_service = __esm(() => {
|
|
|
30251
30985
|
init_deployment_util();
|
|
30252
30986
|
INTERNAL_SECRET_KEYS = ["PLAYCADEMY_API_KEY", "GAME_ID", "PLAYCADEMY_BASE_URL"];
|
|
30253
30987
|
});
|
|
30254
|
-
|
|
30255
|
-
// ../edge-play/src/constants.ts
|
|
30256
|
-
var ASSET_ROUTE_PREFIX = "/api/assets/", ROUTES;
|
|
30257
|
-
var init_constants3 = __esm(() => {
|
|
30258
|
-
init_src();
|
|
30259
|
-
ROUTES = {
|
|
30260
|
-
INDEX: "/api",
|
|
30261
|
-
HEALTH: "/api/health",
|
|
30262
|
-
ASSETS: `${ASSET_ROUTE_PREFIX}*`,
|
|
30263
|
-
TIMEBACK: {
|
|
30264
|
-
END_ACTIVITY: `/api${TIMEBACK_ROUTES.END_ACTIVITY}`,
|
|
30265
|
-
GET_XP: `/api${TIMEBACK_ROUTES.GET_XP}`,
|
|
30266
|
-
GET_MASTERY: `/api${TIMEBACK_ROUTES.GET_MASTERY}`,
|
|
30267
|
-
GET_HIGHEST_GRADE_MASTERED: `/api${TIMEBACK_ROUTES.GET_HIGHEST_GRADE_MASTERED}`,
|
|
30268
|
-
HEARTBEAT: `/api${TIMEBACK_ROUTES.HEARTBEAT}`,
|
|
30269
|
-
ADVANCE_COURSE: `/api${TIMEBACK_ROUTES.ADVANCE_COURSE}`,
|
|
30270
|
-
UNENROLL_COURSE: `/api${TIMEBACK_ROUTES.UNENROLL_COURSE}`
|
|
30271
|
-
}
|
|
30272
|
-
};
|
|
30273
|
-
});
|
|
30274
|
-
// ../edge-play/src/entry/setup.ts
|
|
30988
|
+
// ../edge-play/src/game/setup.ts
|
|
30275
30989
|
function prefixSecrets(secrets) {
|
|
30276
30990
|
const prefixed = {};
|
|
30277
30991
|
for (const [key, value] of Object.entries(secrets)) {
|
|
@@ -30281,7 +30995,6 @@ function prefixSecrets(secrets) {
|
|
|
30281
30995
|
}
|
|
30282
30996
|
var init_setup2 = __esm(() => {
|
|
30283
30997
|
init_src();
|
|
30284
|
-
init_constants3();
|
|
30285
30998
|
});
|
|
30286
30999
|
|
|
30287
31000
|
// ../api-core/src/services/seed.service.ts
|
|
@@ -30316,7 +31029,7 @@ class SeedService {
|
|
|
30316
31029
|
async seed(slug, code, user, secrets) {
|
|
30317
31030
|
const cf = this.getCloudflare();
|
|
30318
31031
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30319
|
-
const deploymentId =
|
|
31032
|
+
const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
30320
31033
|
const uniqueSuffix = Date.now().toString(36);
|
|
30321
31034
|
const seedDeploymentId = `seed-${deploymentId}-${uniqueSuffix}`;
|
|
30322
31035
|
setAttributes({
|
|
@@ -30807,7 +31520,7 @@ var init_emoji = __esm(() => {
|
|
|
30807
31520
|
});
|
|
30808
31521
|
|
|
30809
31522
|
// ../data/src/domains/game/schemas.ts
|
|
30810
|
-
var HttpUrlSchema, GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SeedRequestSchema, SchemaInfoSchema, DatabaseResetRequestSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployRequestSchema;
|
|
31523
|
+
var HttpUrlSchema, GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, AddGameDashboardUserSchema, VerifyGameDashboardLoginSchema, AcceptGameDashboardInviteSchema, AcceptGameDashboardResetSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SeedRequestSchema, SchemaInfoSchema, DatabaseResetRequestSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployRequestSchema;
|
|
30811
31524
|
var init_schemas2 = __esm(() => {
|
|
30812
31525
|
init_drizzle_zod();
|
|
30813
31526
|
init_esm();
|
|
@@ -30918,6 +31631,20 @@ var init_schemas2 = __esm(() => {
|
|
|
30918
31631
|
UpdateGameMemberRoleSchema = exports_external.object({
|
|
30919
31632
|
role: exports_external.enum(gameMemberRoleEnum.enumValues)
|
|
30920
31633
|
}).strict();
|
|
31634
|
+
AddGameDashboardUserSchema = exports_external.object({
|
|
31635
|
+
email: exports_external.string().email().max(255),
|
|
31636
|
+
displayName: exports_external.string().min(1).max(255).optional(),
|
|
31637
|
+
role: exports_external.enum(gameDashboardUserRoleEnum.enumValues).optional().default(DASHBOARD_USER_ROLES.VIEWER)
|
|
31638
|
+
}).strict();
|
|
31639
|
+
VerifyGameDashboardLoginSchema = exports_external.object({
|
|
31640
|
+
email: exports_external.string().email().max(255),
|
|
31641
|
+
password: exports_external.string().min(1).max(1024)
|
|
31642
|
+
}).strict();
|
|
31643
|
+
AcceptGameDashboardInviteSchema = exports_external.object({
|
|
31644
|
+
token: exports_external.string().min(1).max(255),
|
|
31645
|
+
password: exports_external.string().min(8, "Password must be at least 8 characters").max(1024, "Password must be at most 1024 characters")
|
|
31646
|
+
}).strict();
|
|
31647
|
+
AcceptGameDashboardResetSchema = AcceptGameDashboardInviteSchema;
|
|
30921
31648
|
ALLOWED_UPLOAD_EXTENSIONS = [".zip", ".js"];
|
|
30922
31649
|
InitiateUploadSchema = exports_external.object({
|
|
30923
31650
|
fileName: exports_external.string().min(1).refine((name2) => ALLOWED_UPLOAD_EXTENSIONS.some((ext) => name2.endsWith(ext)), {
|
|
@@ -30952,6 +31679,7 @@ var init_schemas2 = __esm(() => {
|
|
|
30952
31679
|
}))
|
|
30953
31680
|
});
|
|
30954
31681
|
DeployRequestSchema = exports_external.object({
|
|
31682
|
+
target: exports_external.enum(deploymentTargetEnum.enumValues).optional().default("game"),
|
|
30955
31683
|
uploadToken: exports_external.string().optional(),
|
|
30956
31684
|
code: exports_external.string().optional(),
|
|
30957
31685
|
codeUploadToken: exports_external.string().optional(),
|
|
@@ -30987,6 +31715,9 @@ var init_schemas2 = __esm(() => {
|
|
|
30987
31715
|
}).refine((data) => !(data.code && data.codeUploadToken), {
|
|
30988
31716
|
message: "Specify either code or codeUploadToken, not both",
|
|
30989
31717
|
path: ["codeUploadToken"]
|
|
31718
|
+
}).refine((data) => !(data.target === "dashboard" && (data.schema || data.bindings)), {
|
|
31719
|
+
message: "Dashboard deployments cannot include schema or bindings — they attach to the game deployment’s existing resources",
|
|
31720
|
+
path: ["target"]
|
|
30990
31721
|
});
|
|
30991
31722
|
});
|
|
30992
31723
|
|
|
@@ -74418,6 +75149,17 @@ function isValidUUID(value) {
|
|
|
74418
75149
|
}
|
|
74419
75150
|
return UUID_REGEX.test(value);
|
|
74420
75151
|
}
|
|
75152
|
+
async function deterministicUUID(input) {
|
|
75153
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
|
|
75154
|
+
const bytes = new Uint8Array(digest).slice(0, 16);
|
|
75155
|
+
bytes[6] = bytes[6] & 15 | 80;
|
|
75156
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
75157
|
+
const hex3 = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
75158
|
+
return `${hex3.slice(0, 8)}-${hex3.slice(8, 12)}-${hex3.slice(12, 16)}-${hex3.slice(16, 20)}-${hex3.slice(20)}`;
|
|
75159
|
+
}
|
|
75160
|
+
async function localGameId(slug) {
|
|
75161
|
+
return deterministicUUID(`playcademy:local-game:${slug}`);
|
|
75162
|
+
}
|
|
74421
75163
|
var UUID_REGEX;
|
|
74422
75164
|
var init_uuid2 = __esm(() => {
|
|
74423
75165
|
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}$/;
|
|
@@ -76819,7 +77561,7 @@ function deriveTimebackCourseLevelFromGrade(grade) {
|
|
|
76819
77561
|
return TIMEBACK_COURSE_DEFAULTS.level.high;
|
|
76820
77562
|
}
|
|
76821
77563
|
var ONEROSTER_STATUS2, SCORE_STATUS2, CACHE_DEFAULTS3, RESOURCE_DEFAULTS3;
|
|
76822
|
-
var
|
|
77564
|
+
var init_constants3 = __esm(() => {
|
|
76823
77565
|
init_src();
|
|
76824
77566
|
ONEROSTER_STATUS2 = {
|
|
76825
77567
|
active: "active",
|
|
@@ -77793,7 +78535,7 @@ function qtiIdCandidates(parentLineItem, resource) {
|
|
|
77793
78535
|
}
|
|
77794
78536
|
var GRADE_LEVEL_TEST_TYPES, naturalTitleSort;
|
|
77795
78537
|
var init_timeback_grade_level_results_util = __esm(() => {
|
|
77796
|
-
|
|
78538
|
+
init_constants3();
|
|
77797
78539
|
GRADE_LEVEL_TEST_TYPES = [
|
|
77798
78540
|
"placement",
|
|
77799
78541
|
"test out",
|
|
@@ -77988,7 +78730,7 @@ async function upsertMasteryCompletionEntry(params) {
|
|
|
77988
78730
|
}
|
|
77989
78731
|
var init_timeback_mastery_completion_util = __esm(async () => {
|
|
77990
78732
|
init_spans();
|
|
77991
|
-
|
|
78733
|
+
init_constants3();
|
|
77992
78734
|
init_utils6();
|
|
77993
78735
|
await init_errors8();
|
|
77994
78736
|
});
|
|
@@ -78684,7 +79426,7 @@ class TimebackAdminService {
|
|
|
78684
79426
|
columns: { slug: true }
|
|
78685
79427
|
}),
|
|
78686
79428
|
this.deps.db.query.gameDeployments.findFirst({
|
|
78687
|
-
where:
|
|
79429
|
+
where: activeDeploymentWhere(gameId),
|
|
78688
79430
|
columns: { url: true }
|
|
78689
79431
|
})
|
|
78690
79432
|
]);
|
|
@@ -79765,7 +80507,7 @@ var init_timeback_admin_service = __esm(async () => {
|
|
|
79765
80507
|
init_schemas_index();
|
|
79766
80508
|
init_tables_index();
|
|
79767
80509
|
init_spans();
|
|
79768
|
-
|
|
80510
|
+
init_constants3();
|
|
79769
80511
|
init_types2();
|
|
79770
80512
|
init_utils6();
|
|
79771
80513
|
init_src4();
|
|
@@ -80240,7 +80982,7 @@ function timebackConfigMatchesCreateIntegrationRequest(config4, request) {
|
|
|
80240
80982
|
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;
|
|
80241
80983
|
}
|
|
80242
80984
|
var init_timeback_create_integration_util = __esm(() => {
|
|
80243
|
-
|
|
80985
|
+
init_constants3();
|
|
80244
80986
|
init_types2();
|
|
80245
80987
|
init_timeback_util();
|
|
80246
80988
|
});
|
|
@@ -83086,6 +83828,19 @@ function createSandboxAuthProvider() {
|
|
|
83086
83828
|
}
|
|
83087
83829
|
return null;
|
|
83088
83830
|
},
|
|
83831
|
+
async deleteApiKeysByName(name3) {
|
|
83832
|
+
const deleted = [];
|
|
83833
|
+
for (const [id, key] of sandboxApiKeys.entries()) {
|
|
83834
|
+
if (key.name === name3) {
|
|
83835
|
+
sandboxApiKeys.delete(id);
|
|
83836
|
+
deleted.push(id);
|
|
83837
|
+
}
|
|
83838
|
+
}
|
|
83839
|
+
if (deleted.length > 0) {
|
|
83840
|
+
log.debug("[SandboxAuthProvider] Deleted API keys by name", { name: name3, deleted });
|
|
83841
|
+
}
|
|
83842
|
+
return deleted;
|
|
83843
|
+
},
|
|
83089
83844
|
async mintGameToken(gameId, userId) {
|
|
83090
83845
|
const header = btoa(JSON.stringify({ alg: "none", typ: "sandbox" }));
|
|
83091
83846
|
const exp = Date.now() + 15 * 60 * 1000;
|
|
@@ -83164,6 +83919,12 @@ function createSandboxAuthProvider() {
|
|
|
83164
83919
|
} catch {
|
|
83165
83920
|
return null;
|
|
83166
83921
|
}
|
|
83922
|
+
},
|
|
83923
|
+
async hashPassword(password) {
|
|
83924
|
+
return `sandbox:${btoa(password)}`;
|
|
83925
|
+
},
|
|
83926
|
+
async verifyPassword(data) {
|
|
83927
|
+
return data.hash === `sandbox:${btoa(data.password)}`;
|
|
83167
83928
|
}
|
|
83168
83929
|
};
|
|
83169
83930
|
}
|
|
@@ -83448,7 +84209,7 @@ var init_http_exception = () => {};
|
|
|
83448
84209
|
|
|
83449
84210
|
// ../../node_modules/.bun/hono@4.10.7/node_modules/hono/dist/request/constants.js
|
|
83450
84211
|
var GET_MATCH_RESULT;
|
|
83451
|
-
var
|
|
84212
|
+
var init_constants4 = __esm(() => {
|
|
83452
84213
|
GET_MATCH_RESULT = Symbol();
|
|
83453
84214
|
});
|
|
83454
84215
|
|
|
@@ -83712,7 +84473,7 @@ var init_url = __esm(() => {
|
|
|
83712
84473
|
var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_), HonoRequest;
|
|
83713
84474
|
var init_request = __esm(() => {
|
|
83714
84475
|
init_http_exception();
|
|
83715
|
-
|
|
84476
|
+
init_constants4();
|
|
83716
84477
|
init_body();
|
|
83717
84478
|
init_url();
|
|
83718
84479
|
HonoRequest = class {
|
|
@@ -84042,7 +84803,7 @@ var init_router = __esm(() => {
|
|
|
84042
84803
|
|
|
84043
84804
|
// ../../node_modules/.bun/hono@4.10.7/node_modules/hono/dist/utils/constants.js
|
|
84044
84805
|
var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
|
|
84045
|
-
var
|
|
84806
|
+
var init_constants5 = () => {};
|
|
84046
84807
|
|
|
84047
84808
|
// ../../node_modules/.bun/hono@4.10.7/node_modules/hono/dist/hono-base.js
|
|
84048
84809
|
var notFoundHandler = (c) => {
|
|
@@ -84264,7 +85025,7 @@ var init_hono_base = __esm(() => {
|
|
|
84264
85025
|
init_compose();
|
|
84265
85026
|
init_context2();
|
|
84266
85027
|
init_router();
|
|
84267
|
-
|
|
85028
|
+
init_constants5();
|
|
84268
85029
|
init_url();
|
|
84269
85030
|
});
|
|
84270
85031
|
|
|
@@ -92934,7 +93695,7 @@ var require_node3 = __commonJS((exports) => {
|
|
|
92934
93695
|
exports2.isAbsolute = function(aPath) {
|
|
92935
93696
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
92936
93697
|
};
|
|
92937
|
-
function
|
|
93698
|
+
function relative2(aRoot, aPath) {
|
|
92938
93699
|
if (aRoot === "") {
|
|
92939
93700
|
aRoot = ".";
|
|
92940
93701
|
}
|
|
@@ -92953,7 +93714,7 @@ var require_node3 = __commonJS((exports) => {
|
|
|
92953
93714
|
}
|
|
92954
93715
|
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
|
92955
93716
|
}
|
|
92956
|
-
exports2.relative =
|
|
93717
|
+
exports2.relative = relative2;
|
|
92957
93718
|
var supportsNullProto = function() {
|
|
92958
93719
|
var obj = Object.create(null);
|
|
92959
93720
|
return !("__proto__" in obj);
|
|
@@ -94984,7 +95745,7 @@ If you have no idea what this means or what Pirates is, let me explain: Pirates
|
|
|
94984
95745
|
});
|
|
94985
95746
|
};
|
|
94986
95747
|
}
|
|
94987
|
-
var
|
|
95748
|
+
var readFile2 = (fp) => new Promise((resolve2, reject) => {
|
|
94988
95749
|
_fs.default.readFile(fp, "utf8", (err2, data) => {
|
|
94989
95750
|
if (err2)
|
|
94990
95751
|
return reject(err2);
|
|
@@ -95182,7 +95943,7 @@ If you have no idea what this means or what Pirates is, let me explain: Pirates
|
|
|
95182
95943
|
data: _this3.packageJsonCache.get(filepath)[options.packageKey]
|
|
95183
95944
|
};
|
|
95184
95945
|
}
|
|
95185
|
-
const data = _this3.options.parseJSON(yield
|
|
95946
|
+
const data = _this3.options.parseJSON(yield readFile2(filepath));
|
|
95186
95947
|
return {
|
|
95187
95948
|
path: filepath,
|
|
95188
95949
|
data
|
|
@@ -95190,7 +95951,7 @@ If you have no idea what this means or what Pirates is, let me explain: Pirates
|
|
|
95190
95951
|
}
|
|
95191
95952
|
return {
|
|
95192
95953
|
path: filepath,
|
|
95193
|
-
data: yield
|
|
95954
|
+
data: yield readFile2(filepath)
|
|
95194
95955
|
};
|
|
95195
95956
|
}
|
|
95196
95957
|
return {};
|
|
@@ -100235,7 +100996,7 @@ var __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf2,
|
|
|
100235
100996
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
|
|
100236
100997
|
}
|
|
100237
100998
|
return to;
|
|
100238
|
-
}, __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) => {
|
|
100999
|
+
}, __toESM5 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod)), __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value), ANSI_BACKGROUND_OFFSET, wrapAnsi16, wrapAnsi256, wrapAnsi16m, styles2, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default, init_ansi_styles, env, flagForceColor, supportsColor, supports_color_default, init_supports_color, init_utilities, stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles22, applyOptions, chalkFactory, getModelAnsi, usedModels, proto, createStyler, createBuilder, applyStyle, chalk, chalkStderr, source_default, init_source, require_old, require_fs, require_path, require_balanced_match, require_brace_expansion, require_minimatch, require_inherits_browser2, require_inherits2, require_common3, require_sync, require_wrappy, require_once, require_inflight, require_glob, require_readline, require_src3, require_utils4, require_lodash, require_hanji, originUUID, snapshotVersion, mapValues, mapKeys, mapEntries, customMapEntries, init_global2, util3, objectUtil2, ZodParsedType2, getParsedType4, init_util4, ZodIssueCode4, ZodError5, init_ZodError2, errorMap2, en_default4, init_en4, overrideErrorMap2, init_errors9, makeIssue2, ParseStatus2, INVALID3, DIRTY2, OK2, isAborted2, isDirty2, isValid2, isAsync2, init_parseUtil2, init_typeAliases2, errorUtil2, init_errorUtil2, ParseInputLazyPath2, handleResult2, ZodType4, cuidRegex2, cuid2Regex2, ulidRegex2, uuidRegex2, nanoidRegex2, jwtRegex2, durationRegex2, emailRegex2, _emojiRegex2, emojiRegex2, ipv4Regex2, ipv4CidrRegex2, ipv6Regex2, ipv6CidrRegex2, base64Regex2, base64urlRegex2, dateRegexSource2, dateRegex2, ZodString4, ZodNumber4, ZodBigInt4, ZodBoolean4, ZodDate4, ZodSymbol4, ZodUndefined4, ZodNull4, ZodAny4, ZodUnknown4, ZodNever4, ZodVoid4, ZodArray4, ZodObject4, ZodUnion4, getDiscriminator2, ZodDiscriminatedUnion4, ZodIntersection4, ZodTuple4, ZodRecord4, ZodMap4, ZodSet4, ZodFunction3, ZodLazy4, ZodLiteral4, ZodEnum4, ZodNativeEnum2, ZodPromise4, ZodEffects2, ZodOptional4, ZodNullable4, ZodDefault4, ZodCatch4, ZodNaN4, BRAND2, ZodBranded2, ZodPipeline2, ZodReadonly4, late2, ZodFirstPartyTypeKind3, stringType2, numberType2, nanType2, bigIntType2, booleanType2, dateType2, symbolType2, undefinedType2, nullType2, anyType2, unknownType2, neverType2, voidType2, arrayType2, objectType2, strictObjectType2, unionType2, discriminatedUnionType2, intersectionType2, tupleType2, recordType2, mapType2, setType2, functionType2, lazyType2, literalType2, enumType2, nativeEnumType2, promiseType2, effectsType2, optionalType2, nullableType2, preprocessType2, pipelineType2, coerce2, init_types5, init_external4, init_v32, init_esm2, enumSchema, enumSchemaV1, indexColumn, index2, fk, sequenceSchema, roleSchema, sequenceSquashed, column2, checkConstraint, columnSquashed, compositePK, uniqueConstraint, policy, policySquashed, viewWithOption, matViewWithOption, mergedViewWithOption, view2, table8, schemaHash, kitInternals, gelSchemaExternal, gelSchemaInternal, tableSquashed, gelSchemaSquashed, gelSchema, dryGel, init_gelSchema, index22, fk2, column22, tableV3, compositePK2, uniqueConstraint2, checkConstraint2, tableV4, table22, viewMeta, view22, kitInternals2, dialect2, schemaHash2, schemaInternalV3, schemaInternalV4, schemaInternalV5, schemaInternal, schemaV3, schemaV4, schemaV5, schema2, tableSquashedV4, tableSquashed2, viewSquashed, schemaSquashed, schemaSquashedV4, MySqlSquasher, squashMysqlScheme, mysqlSchema, mysqlSchemaV5, mysqlSchemaSquashed, backwardCompatibleMysqlSchema, dryMySql, init_mysqlSchema, indexV2, columnV2, tableV2, enumSchemaV12, enumSchema2, pgSchemaV2, references, columnV1, tableV1, pgSchemaV1, indexColumn2, index3, indexV4, indexV5, indexV6, fk3, sequenceSchema2, roleSchema2, sequenceSquashed2, columnV7, column3, checkConstraint3, columnSquashed2, tableV32, compositePK3, uniqueConstraint3, policy2, policySquashed2, viewWithOption2, matViewWithOption2, mergedViewWithOption2, view3, tableV42, tableV5, tableV6, tableV7, table32, schemaHash3, kitInternals3, pgSchemaInternalV3, pgSchemaInternalV4, pgSchemaInternalV5, pgSchemaInternalV6, pgSchemaExternal, pgSchemaInternalV7, pgSchemaInternal, tableSquashed3, tableSquashedV42, pgSchemaSquashedV4, pgSchemaSquashedV6, pgSchemaSquashed, pgSchemaV3, pgSchemaV4, pgSchemaV5, pgSchemaV6, pgSchemaV7, pgSchema, backwardCompatiblePgSchema, PgSquasher, squashPgScheme, dryPg, init_pgSchema, index4, column4, compositePK4, uniqueConstraint4, table42, viewMeta2, kitInternals4, dialect22, schemaHash4, schemaInternal2, schema22, tableSquashed4, schemaSquashed2, SingleStoreSquasher, squashSingleStoreScheme, singlestoreSchema, singlestoreSchemaSquashed, backwardCompatibleSingleStoreSchema, drySingleStore, init_singlestoreSchema, index5, fk4, compositePK5, column5, tableV33, uniqueConstraint5, checkConstraint4, table52, view4, dialect3, schemaHash5, schemaInternalV32, schemaInternalV42, schemaInternalV52, kitInternals5, latestVersion, schemaInternal3, schemaV32, schemaV42, schemaV52, schema3, tableSquashed5, schemaSquashed3, SQLiteSquasher, squashSqliteScheme, drySQLite, sqliteSchemaV5, sqliteSchema, SQLiteSchemaSquashed, backwardCompatibleSqliteSchema, init_sqliteSchema, copy, prepareMigrationMeta, schemaRenameKey, tableRenameKey, columnRenameKey, init_utils7, import_hanji, warning, error88, isRenamePromptItem, ResolveColumnSelect, tableKey, ResolveSelectNamed, ResolveSelect, ResolveSchemasSelect, Spinner2, ProgressView, init_views, glob, init_serializer, fillPgSnapshot, init_migrationPreparator, require_heap, require_heap2, require_difflib, require_difflib2, require_util2, require_styles, require_has_flag2, require_supports_colors, require_trap, require_zalgo, require_america, require_zebra, require_rainbow, require_random, require_colors, require_safe, require_colorize, require_lib4, import_json_diff, mapArraysDiff, findAlternationsInTable, alternationsInColumn, init_jsonDiffer, parseType, Convertor, PgCreateRoleConvertor, PgDropRoleConvertor, PgRenameRoleConvertor, PgAlterRoleConvertor, PgCreatePolicyConvertor, PgDropPolicyConvertor, PgRenamePolicyConvertor, PgAlterPolicyConvertor, PgCreateIndPolicyConvertor, PgDropIndPolicyConvertor, PgRenameIndPolicyConvertor, PgAlterIndPolicyConvertor, PgEnableRlsConvertor, PgDisableRlsConvertor, PgCreateTableConvertor, MySqlCreateTableConvertor, SingleStoreCreateTableConvertor, SQLiteCreateTableConvertor, PgCreateViewConvertor, MySqlCreateViewConvertor, SqliteCreateViewConvertor, PgDropViewConvertor, MySqlDropViewConvertor, SqliteDropViewConvertor, MySqlAlterViewConvertor, PgRenameViewConvertor, MySqlRenameViewConvertor, PgAlterViewSchemaConvertor, PgAlterViewAddWithOptionConvertor, PgAlterViewDropWithOptionConvertor, PgAlterViewAlterTablespaceConvertor, PgAlterViewAlterUsingConvertor, PgAlterTableAlterColumnSetGenerated, PgAlterTableAlterColumnDropGenerated, PgAlterTableAlterColumnAlterGenerated, PgAlterTableAddUniqueConstraintConvertor, PgAlterTableDropUniqueConstraintConvertor, PgAlterTableAddCheckConstraintConvertor, PgAlterTableDeleteCheckConstraintConvertor, MySQLAlterTableAddUniqueConstraintConvertor, MySQLAlterTableDropUniqueConstraintConvertor, MySqlAlterTableAddCheckConstraintConvertor, SingleStoreAlterTableAddUniqueConstraintConvertor, SingleStoreAlterTableDropUniqueConstraintConvertor, MySqlAlterTableDeleteCheckConstraintConvertor, CreatePgSequenceConvertor, DropPgSequenceConvertor, RenamePgSequenceConvertor, MovePgSequenceConvertor, AlterPgSequenceConvertor, CreateTypeEnumConvertor, DropTypeEnumConvertor, AlterTypeAddValueConvertor, AlterTypeSetSchemaConvertor, AlterRenameTypeConvertor, AlterTypeDropValueConvertor, PgDropTableConvertor, MySQLDropTableConvertor, SingleStoreDropTableConvertor, SQLiteDropTableConvertor, PgRenameTableConvertor, SqliteRenameTableConvertor, MySqlRenameTableConvertor, SingleStoreRenameTableConvertor, PgAlterTableRenameColumnConvertor, MySqlAlterTableRenameColumnConvertor, SingleStoreAlterTableRenameColumnConvertor, SQLiteAlterTableRenameColumnConvertor, PgAlterTableDropColumnConvertor, MySqlAlterTableDropColumnConvertor, SingleStoreAlterTableDropColumnConvertor, SQLiteAlterTableDropColumnConvertor, PgAlterTableAddColumnConvertor, MySqlAlterTableAddColumnConvertor, SingleStoreAlterTableAddColumnConvertor, SQLiteAlterTableAddColumnConvertor, PgAlterTableAlterColumnSetTypeConvertor, PgAlterTableAlterColumnSetDefaultConvertor, PgAlterTableAlterColumnDropDefaultConvertor, PgAlterTableAlterColumnDropGeneratedConvertor, PgAlterTableAlterColumnSetExpressionConvertor, PgAlterTableAlterColumnAlterrGeneratedConvertor, SqliteAlterTableAlterColumnDropGeneratedConvertor, SqliteAlterTableAlterColumnSetExpressionConvertor, SqliteAlterTableAlterColumnAlterGeneratedConvertor, MySqlAlterTableAlterColumnAlterrGeneratedConvertor, MySqlAlterTableAddPk, MySqlAlterTableDropPk, LibSQLModifyColumn, MySqlModifyColumn, SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor, SingleStoreAlterTableAddPk, SingleStoreAlterTableDropPk, SingleStoreModifyColumn, PgAlterTableCreateCompositePrimaryKeyConvertor, PgAlterTableDeleteCompositePrimaryKeyConvertor, PgAlterTableAlterCompositePrimaryKeyConvertor, MySqlAlterTableCreateCompositePrimaryKeyConvertor, MySqlAlterTableDeleteCompositePrimaryKeyConvertor, MySqlAlterTableAlterCompositePrimaryKeyConvertor, PgAlterTableAlterColumnSetPrimaryKeyConvertor, PgAlterTableAlterColumnDropPrimaryKeyConvertor, PgAlterTableAlterColumnSetNotNullConvertor, PgAlterTableAlterColumnDropNotNullConvertor, PgCreateForeignKeyConvertor, LibSQLCreateForeignKeyConvertor, MySqlCreateForeignKeyConvertor, PgAlterForeignKeyConvertor, PgDeleteForeignKeyConvertor, MySqlDeleteForeignKeyConvertor, CreatePgIndexConvertor, CreateMySqlIndexConvertor, CreateSingleStoreIndexConvertor, CreateSqliteIndexConvertor, PgDropIndexConvertor, PgCreateSchemaConvertor, PgRenameSchemaConvertor, PgDropSchemaConvertor, PgAlterTableSetSchemaConvertor, PgAlterTableSetNewSchemaConvertor, PgAlterTableRemoveFromSchemaConvertor, SqliteDropIndexConvertor, MySqlDropIndexConvertor, SingleStoreDropIndexConvertor, SQLiteRecreateTableConvertor, LibSQLRecreateTableConvertor, SingleStoreRecreateTableConvertor, convertors, init_sqlgenerator, _moveDataStatements, getOldTableName, getNewTableName, logSuggestionsAndReturn, init_sqlitePushUtils, preparePgCreateTableJson, prepareMySqlCreateTableJson, prepareSingleStoreCreateTableJson, prepareSQLiteCreateTable, prepareDropTableJson, prepareRenameTableJson, prepareCreateEnumJson, prepareAddValuesToEnumJson, prepareDropEnumValues, prepareDropEnumJson, prepareMoveEnumJson, prepareRenameEnumJson, prepareCreateSequenceJson, prepareAlterSequenceJson, prepareDropSequenceJson, prepareMoveSequenceJson, prepareRenameSequenceJson, prepareCreateRoleJson, prepareAlterRoleJson, prepareDropRoleJson, prepareRenameRoleJson, prepareCreateSchemasJson, prepareRenameSchemasJson, prepareDeleteSchemasJson, prepareRenameColumns, _prepareDropColumns, _prepareAddColumns, _prepareSqliteAddColumns, prepareAlterColumnsMysql, preparePgAlterColumns, prepareSqliteAlterColumns, prepareRenamePolicyJsons, prepareRenameIndPolicyJsons, prepareCreatePolicyJsons, prepareCreateIndPolicyJsons, prepareDropPolicyJsons, prepareDropIndPolicyJsons, prepareAlterPolicyJson, prepareAlterIndPolicyJson, preparePgCreateIndexesJson, prepareCreateIndexesJson, prepareCreateReferencesJson, prepareLibSQLCreateReferencesJson, prepareDropReferencesJson, prepareLibSQLDropReferencesJson, prepareAlterReferencesJson, prepareDropIndexesJson, prepareAddCompositePrimaryKeySqlite, prepareDeleteCompositePrimaryKeySqlite, prepareAlterCompositePrimaryKeySqlite, prepareAddCompositePrimaryKeyPg, prepareDeleteCompositePrimaryKeyPg, prepareAlterCompositePrimaryKeyPg, prepareAddUniqueConstraintPg, prepareDeleteUniqueConstraintPg, prepareAddCheckConstraint, prepareDeleteCheckConstraint, prepareAddCompositePrimaryKeyMySql, prepareDeleteCompositePrimaryKeyMySql, prepareAlterCompositePrimaryKeyMySql, preparePgCreateViewJson, prepareMySqlCreateViewJson, prepareSqliteCreateViewJson, prepareDropViewJson, prepareRenameViewJson, preparePgAlterViewAlterSchemaJson, preparePgAlterViewAddWithOptionJson, preparePgAlterViewDropWithOptionJson, preparePgAlterViewAlterTablespaceJson, preparePgAlterViewAlterUsingJson, prepareMySqlAlterView, init_jsonStatements, prepareLibSQLRecreateTable, prepareSQLiteRecreateTable, libSQLCombineStatements, sqliteCombineStatements, prepareSingleStoreRecreateTable, singleStoreCombineStatements, init_statementCombiner, snapshotsDiffer_exports, makeChanged, makeSelfOrChanged, makePatched, makeSelfOrPatched, columnSchema, alteredColumnSchema, enumSchema3, changedEnumSchema, tableScheme, alteredTableScheme, alteredViewCommon, alteredPgViewSchema, alteredMySqlViewSchema, diffResultScheme, diffResultSchemeMysql, diffResultSchemeSingleStore, diffResultSchemeSQLite, schemaChangeFor, nameChangeFor, nameSchemaChangeFor, columnChangeFor, applyPgSnapshotsDiff, applyMysqlSnapshotsDiff, applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff, applyLibSQLSnapshotsDiff, init_snapshotsDiffer, init_words, dialects, dialect4, commonSquashedSchema, commonSchema, init_schemaValidator, sqliteDriversLiterals, postgresqlDriversLiterals, prefixes, prefix, casingTypes, casingType, sqliteDriver, postgresDriver, driver2, configMigrations, configCommonSchema, casing, introspectParams, configIntrospectCliSchema, configGenerateSchema, configPushSchema, init_common2, withStyle, init_outputs, import_hanji2, schemasResolver, tablesResolver, viewsResolver, mySqlViewsResolver, sqliteViewsResolver, sequencesResolver, roleResolver, policyResolver, indPolicyResolver, enumsResolver, columnsResolver, promptColumnsConflicts, promptNamedConflict, promptNamedWithSchemasConflict, promptSchemasConflict, BREAKPOINT, init_migrate, posixClasses, braceEscape, regexpEscape, rangesToString, parseClass, init_brace_expressions, escape, init_escape, unescape, init_unescape, import_brace_expansion, minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path, sep2, GLOBSTAR, plTypes, qmark, star, twoStarDot, twoStarNoDot, charSet, reSpecials, addPatternStartSet, filter, ext, defaults, braceExpand, MAX_PATTERN_LENGTH, assertValidPattern, makeRe, match2, globUnescape, globMagic, regExpEscape, Minimatch, init_mjs, entityKind2, hasOwnEntityKind2, init_entity2, _a3, Column2, init_column2, _a22, ColumnBuilder2, init_column_builder2, TableName2, init_table_utils2, _a32, ForeignKeyBuilder2, _a4, ForeignKey2, init_foreign_keys2, init_tracing_utils2, _a5, UniqueConstraintBuilder, _a6, UniqueOnConstraintBuilder, _a7, UniqueConstraint, init_unique_constraint2, init_array2, _a8, _b, PgColumnBuilder2, _a9, _b2, PgColumn2, _a10, _b3, ExtraConfigColumn2, _a11, IndexedColumn2, _a12, _b4, PgArrayBuilder2, _a13, _b5, _PgArray, PgArray2, init_common22, _a14, _b6, PgEnumObjectColumnBuilder2, _a15, _b7, PgEnumObjectColumn2, isPgEnumSym2, _a16, _b8, PgEnumColumnBuilder2, _a17, _b9, PgEnumColumn2, init_enum2, _a18, Subquery2, _a19, _b10, WithSubquery2, init_subquery2, version4, init_version2, otel2, rawTracer2, tracer2, init_tracing2, ViewBaseConfig2, init_view_common3, Schema2, Columns2, ExtraConfigColumns2, OriginalName2, BaseName2, IsAlias2, ExtraConfigBuilder2, IsDrizzleTable2, _a20, _b11, _c, _d, _e3, _f, _g, _h, _i, _j, Table2, init_table8, _a21, FakePrimitiveParam, _a222, StringChunk2, _a23, _SQL, SQL2, _a24, Name2, noopDecoder2, noopEncoder2, noopMapper2, _a25, Param2, _a26, Placeholder2, IsDrizzleView2, _a27, _b12, _c2, View3, init_sql3, _a28, ColumnAliasProxyHandler2, _a29, TableAliasProxyHandler2, _a30, RelationTableAliasProxyHandler, init_alias3, _a31, _b13, DrizzleError2, DrizzleQueryError, _a322, _b14, TransactionRollbackError2, init_errors22, _a33, ConsoleLogWriter2, _a34, DefaultLogger2, _a35, NoopLogger2, init_logger3, init_operations, _a36, _b15, QueryPromise2, init_query_promise2, textDecoder, init_utils22, _a37, _b16, PgIntColumnBaseBuilder2, init_int_common2, _a38, _b17, PgBigInt53Builder2, _a39, _b18, PgBigInt532, _a40, _b19, PgBigInt64Builder2, _a41, _b20, PgBigInt642, init_bigint2, _a42, _b21, PgBigSerial53Builder2, _a43, _b22, PgBigSerial532, _a44, _b23, PgBigSerial64Builder2, _a45, _b24, PgBigSerial642, init_bigserial2, _a46, _b25, PgBooleanBuilder2, _a47, _b26, PgBoolean2, init_boolean2, _a48, _b27, PgCharBuilder2, _a49, _b28, PgChar2, init_char2, _a50, _b29, PgCidrBuilder2, _a51, _b30, PgCidr2, init_cidr2, _a52, _b31, PgCustomColumnBuilder2, _a53, _b32, PgCustomColumn2, init_custom2, _a54, _b33, PgDateColumnBaseBuilder2, init_date_common2, _a55, _b34, PgDateBuilder2, _a56, _b35, PgDate2, _a57, _b36, PgDateStringBuilder2, _a58, _b37, PgDateString2, init_date2, _a59, _b38, PgDoublePrecisionBuilder2, _a60, _b39, PgDoublePrecision2, init_double_precision2, _a61, _b40, PgInetBuilder2, _a62, _b41, PgInet2, init_inet2, _a63, _b42, PgIntegerBuilder2, _a64, _b43, PgInteger2, init_integer2, _a65, _b44, PgIntervalBuilder2, _a66, _b45, PgInterval2, init_interval2, _a67, _b46, PgJsonBuilder2, _a68, _b47, PgJson2, init_json2, _a69, _b48, PgJsonbBuilder2, _a70, _b49, PgJsonb2, init_jsonb2, _a71, _b50, PgLineBuilder2, _a72, _b51, PgLineTuple2, _a73, _b52, PgLineABCBuilder2, _a74, _b53, PgLineABC2, init_line2, _a75, _b54, PgMacaddrBuilder2, _a76, _b55, PgMacaddr2, init_macaddr2, _a77, _b56, PgMacaddr8Builder2, _a78, _b57, PgMacaddr82, init_macaddr82, _a79, _b58, PgNumericBuilder2, _a80, _b59, PgNumeric2, _a81, _b60, PgNumericNumberBuilder2, _a82, _b61, PgNumericNumber2, _a83, _b62, PgNumericBigIntBuilder2, _a84, _b63, PgNumericBigInt2, init_numeric2, _a85, _b64, PgPointTupleBuilder2, _a86, _b65, PgPointTuple2, _a87, _b66, PgPointObjectBuilder2, _a88, _b67, PgPointObject2, init_point2, init_utils32, _a89, _b68, PgGeometryBuilder2, _a90, _b69, PgGeometry2, _a91, _b70, PgGeometryObjectBuilder2, _a92, _b71, PgGeometryObject2, init_geometry2, _a93, _b72, PgRealBuilder2, _a94, _b73, PgReal2, init_real2, _a95, _b74, PgSerialBuilder2, _a96, _b75, PgSerial2, init_serial2, _a97, _b76, PgSmallIntBuilder2, _a98, _b77, PgSmallInt2, init_smallint2, _a99, _b78, PgSmallSerialBuilder2, _a100, _b79, PgSmallSerial2, init_smallserial2, _a101, _b80, PgTextBuilder2, _a102, _b81, PgText2, init_text2, _a103, _b82, PgTimeBuilder2, _a104, _b83, PgTime2, init_time2, _a105, _b84, PgTimestampBuilder2, _a106, _b85, PgTimestamp2, _a107, _b86, PgTimestampStringBuilder2, _a108, _b87, PgTimestampString2, init_timestamp2, _a109, _b88, PgUUIDBuilder2, _a110, _b89, PgUUID2, init_uuid3, _a111, _b90, PgVarcharBuilder2, _a112, _b91, PgVarchar2, init_varchar2, _a113, _b92, PgBinaryVectorBuilder2, _a114, _b93, PgBinaryVector2, init_bit2, _a115, _b94, PgHalfVectorBuilder2, _a116, _b95, PgHalfVector2, init_halfvec2, _a117, _b96, PgSparseVectorBuilder2, _a118, _b97, PgSparseVector2, init_sparsevec2, _a119, _b98, PgVectorBuilder2, _a120, _b99, PgVector2, init_vector3, init_all2, InlineForeignKeys2, EnableRLS2, _a121, _b100, _c3, _d2, _e22, _f2, PgTable2, pgTable2, init_table22, _a122, PrimaryKeyBuilder2, _a123, PrimaryKey2, init_primary_keys2, eq2, ne4, gt3, gte2, lt4, lte2, init_conditions2, init_select3, init_expressions2, _a124, Relation2, _a125, Relations2, _a126, _b101, _One, One2, _a127, _b102, _Many, Many2, init_relations2, init_aggregate2, init_vector22, init_functions2, init_sql22, dist_exports, init_dist9, init_alias22, _a128, CheckBuilder, _a129, Check, init_checks6, init_columns2, _a130, _SelectionProxyHandler, SelectionProxyHandler2, init_selection_proxy2, _a131, IndexBuilderOn2, _a132, IndexBuilder2, _a133, Index2, init_indexes2, _a134, PgPolicy, init_policies2, PgViewConfig2, init_view_common22, _a135, CasingCache2, init_casing2, _a136, _b103, PgViewBase2, init_view_base2, _a137, PgDialect2, init_dialect2, _a138, TypedQueryBuilder2, init_query_builder3, _a139, PgSelectBuilder2, _a140, _b104, PgSelectQueryBuilderBase2, _a141, _b105, PgSelectBase2, getPgSetOperators2, union22, unionAll2, intersect2, intersectAll2, except2, exceptAll2, init_select22, _a142, QueryBuilder2, init_query_builder22, _a143, DefaultViewBuilderCore, _a144, _b106, ViewBuilder, _a145, _b107, ManualViewBuilder, _a146, MaterializedViewBuilderCore, _a147, _b108, MaterializedViewBuilder, _a148, _b109, ManualMaterializedViewBuilder, _a149, _b110, _c4, PgView2, PgMaterializedViewConfig2, _a150, _b111, _c5, PgMaterializedView, init_view2, init_utils42, _a151, _b112, PgDeleteBase2, init_delete2, _a152, PgInsertBuilder2, _a153, _b113, PgInsertBase2, init_insert2, _a154, _b114, PgRefreshMaterializedView2, init_refresh_materialized_view2, init_select_types, _a155, PgUpdateBuilder2, _a156, _b115, PgUpdateBase2, init_update2, init_query_builders2, _a157, _b116, _c6, _PgCountBuilder, PgCountBuilder2, init_count2, _a158, RelationalQueryBuilder2, _a159, _b117, PgRelationalQuery2, init_query2, _a160, _b118, PgRaw2, init_raw2, _a161, PgDatabase2, init_db2, _a162, PgRole, init_roles2, _a163, PgSequence, init_sequence2, _a164, PgSchema5, init_schema3, _a165, Cache, _a166, _b119, NoopCache, init_cache, _a167, PgPreparedQuery2, _a168, PgSession2, _a169, _b120, PgTransaction2, init_session3, init_subquery22, init_utils52, init_pg_core2, vectorOps, init_vector32, sqlToStr, init_utils62, indexName, generatePgSnapshot, trimChar, fromDatabase, defaultForColumn, getColumnsInfoQuery, init_pgSerializer, import_hanji4, Select, init_selector_ui, init_alias32, _a170, CheckBuilder2, _a171, Check2, init_checks22, _a172, ForeignKeyBuilder22, _a173, ForeignKey22, init_foreign_keys22, _a174, UniqueConstraintBuilder2, _a175, UniqueOnConstraintBuilder2, _a176, UniqueConstraint2, init_unique_constraint22, _a177, _b121, SQLiteColumnBuilder, _a178, _b122, SQLiteColumn, init_common3, _a179, _b123, SQLiteBigIntBuilder, _a180, _b124, SQLiteBigInt, _a181, _b125, SQLiteBlobJsonBuilder, _a182, _b126, SQLiteBlobJson, _a183, _b127, SQLiteBlobBufferBuilder, _a184, _b128, SQLiteBlobBuffer, init_blob, _a185, _b129, SQLiteCustomColumnBuilder, _a186, _b130, SQLiteCustomColumn, init_custom22, _a187, _b131, SQLiteBaseIntegerBuilder, _a188, _b132, SQLiteBaseInteger, _a189, _b133, SQLiteIntegerBuilder, _a190, _b134, SQLiteInteger, _a191, _b135, SQLiteTimestampBuilder, _a192, _b136, SQLiteTimestamp, _a193, _b137, SQLiteBooleanBuilder, _a194, _b138, SQLiteBoolean, init_integer22, _a195, _b139, SQLiteNumericBuilder, _a196, _b140, SQLiteNumeric, _a197, _b141, SQLiteNumericNumberBuilder, _a198, _b142, SQLiteNumericNumber, _a199, _b143, SQLiteNumericBigIntBuilder, _a200, _b144, SQLiteNumericBigInt, init_numeric22, _a201, _b145, SQLiteRealBuilder, _a202, _b146, SQLiteReal, init_real22, _a203, _b147, SQLiteTextBuilder, _a204, _b148, SQLiteText, _a205, _b149, SQLiteTextJsonBuilder, _a206, _b150, SQLiteTextJson, init_text22, init_columns22, init_all22, InlineForeignKeys22, _a207, _b151, _c7, _d3, _e32, SQLiteTable, sqliteTable, init_table32, _a208, IndexBuilderOn22, _a209, IndexBuilder22, _a210, Index4, init_indexes22, _a211, PrimaryKeyBuilder22, _a212, PrimaryKey22, init_primary_keys22, init_utils72, _a213, _b152, SQLiteDeleteBase, init_delete22, _a214, _b153, SQLiteViewBase, init_view_base22, _a215, SQLiteDialect, _a216, _b154, SQLiteSyncDialect, _a217, _b155, SQLiteAsyncDialect, init_dialect22, _a218, SQLiteSelectBuilder, _a219, _b156, SQLiteSelectQueryBuilderBase, _a220, _b157, SQLiteSelectBase, getSQLiteSetOperators, union32, unionAll22, intersect22, except22, init_select32, _a221, QueryBuilder22, init_query_builder32, _a2222, SQLiteInsertBuilder, _a223, _b158, SQLiteInsertBase, init_insert22, init_select_types2, _a224, SQLiteUpdateBuilder, _a225, _b159, SQLiteUpdateBase, init_update22, init_query_builders22, _a226, _b160, _c8, _SQLiteCountBuilder, SQLiteCountBuilder, init_count22, _a227, RelationalQueryBuilder22, _a228, _b161, SQLiteRelationalQuery, _a229, _b162, SQLiteSyncRelationalQuery, init_query22, _a230, _b163, SQLiteRaw, init_raw22, _a231, BaseSQLiteDatabase, init_db22, _a232, _b164, ExecuteResultSync, _a233, SQLitePreparedQuery, _a234, SQLiteSession, _a235, _b165, SQLiteTransaction, init_session22, init_subquery3, _a236, ViewBuilderCore, _a237, _b166, ViewBuilder2, _a238, _b167, ManualViewBuilder2, _a239, _b168, SQLiteView2, init_view22, init_sqlite_core, generateSqliteSnapshot, fromDatabase2, init_sqliteSerializer, getTablesFilterByExtensions, init_getTablesFilterByExtensions, init_alias4, _a240, CheckBuilder3, _a241, Check3, init_checks32, _a242, ForeignKeyBuilder3, _a243, ForeignKey3, init_foreign_keys3, _a244, UniqueConstraintBuilder3, _a245, UniqueOnConstraintBuilder3, _a246, UniqueConstraint3, init_unique_constraint3, _a247, _b169, MySqlColumnBuilder, _a248, _b170, MySqlColumn, _a249, _b171, MySqlColumnBuilderWithAutoIncrement, _a250, _b172, MySqlColumnWithAutoIncrement, init_common4, _a251, _b173, MySqlBigInt53Builder, _a252, _b174, MySqlBigInt53, _a253, _b175, MySqlBigInt64Builder, _a254, _b176, MySqlBigInt64, init_bigint22, _a255, _b177, MySqlBinaryBuilder, _a256, _b178, MySqlBinary, init_binary, _a257, _b179, MySqlBooleanBuilder, _a258, _b180, MySqlBoolean, init_boolean22, _a259, _b181, MySqlCharBuilder, _a260, _b182, MySqlChar, init_char22, _a261, _b183, MySqlCustomColumnBuilder, _a262, _b184, MySqlCustomColumn, init_custom3, _a263, _b185, MySqlDateBuilder, _a264, _b186, MySqlDate, _a265, _b187, MySqlDateStringBuilder, _a266, _b188, MySqlDateString, init_date22, _a267, _b189, MySqlDateTimeBuilder, _a268, _b190, MySqlDateTime, _a269, _b191, MySqlDateTimeStringBuilder, _a270, _b192, MySqlDateTimeString, init_datetime, _a271, _b193, MySqlDecimalBuilder, _a272, _b194, MySqlDecimal, _a273, _b195, MySqlDecimalNumberBuilder, _a274, _b196, MySqlDecimalNumber, _a275, _b197, MySqlDecimalBigIntBuilder, _a276, _b198, MySqlDecimalBigInt, init_decimal, _a277, _b199, MySqlDoubleBuilder, _a278, _b200, MySqlDouble, init_double, _a279, _b201, MySqlEnumColumnBuilder, _a280, _b202, MySqlEnumColumn, _a281, _b203, MySqlEnumObjectColumnBuilder, _a282, _b204, MySqlEnumObjectColumn, init_enum22, _a283, _b205, MySqlFloatBuilder, _a284, _b206, MySqlFloat, init_float, _a285, _b207, MySqlIntBuilder, _a286, _b208, MySqlInt, init_int, _a287, _b209, MySqlJsonBuilder, _a288, _b210, MySqlJson, init_json22, _a289, _b211, MySqlMediumIntBuilder, _a290, _b212, MySqlMediumInt, init_mediumint, _a291, _b213, MySqlRealBuilder, _a292, _b214, MySqlReal, init_real3, _a293, _b215, MySqlSerialBuilder, _a294, _b216, MySqlSerial, init_serial22, _a295, _b217, MySqlSmallIntBuilder, _a296, _b218, MySqlSmallInt, init_smallint22, _a297, _b219, MySqlTextBuilder, _a298, _b220, MySqlText, init_text3, _a299, _b221, MySqlTimeBuilder, _a300, _b222, MySqlTime, init_time22, _a301, _b223, MySqlDateColumnBaseBuilder, _a302, _b224, MySqlDateBaseColumn, init_date_common22, _a303, _b225, MySqlTimestampBuilder, _a304, _b226, MySqlTimestamp, _a305, _b227, MySqlTimestampStringBuilder, _a306, _b228, MySqlTimestampString, init_timestamp22, _a307, _b229, MySqlTinyIntBuilder, _a308, _b230, MySqlTinyInt, init_tinyint, _a309, _b231, MySqlVarBinaryBuilder, _a310, _b232, MySqlVarBinary, init_varbinary, _a311, _b233, MySqlVarCharBuilder, _a312, _b234, MySqlVarChar, init_varchar22, _a313, _b235, MySqlYearBuilder, _a314, _b236, MySqlYear, init_year, init_columns3, _a315, _b237, _c9, _MySqlCountBuilder, MySqlCountBuilder, init_count3, _a316, IndexBuilderOn3, _a317, IndexBuilder3, _a318, Index5, init_indexes3, init_all3, InlineForeignKeys3, _a319, _b238, _c10, _d4, _e4, MySqlTable, mysqlTable, init_table42, _a320, PrimaryKeyBuilder3, _a321, PrimaryKey3, init_primary_keys3, MySqlViewConfig, init_view_common32, init_utils8, _a3222, _b239, MySqlDeleteBase, init_delete3, _a323, _b240, MySqlViewBase, init_view_base3, _a324, MySqlDialect, init_dialect3, _a325, MySqlSelectBuilder, _a326, _b241, MySqlSelectQueryBuilderBase, _a327, _b242, MySqlSelectBase, getMySqlSetOperators, union4, unionAll3, intersect3, intersectAll22, except3, exceptAll22, init_select4, _a328, QueryBuilder3, init_query_builder4, _a329, MySqlInsertBuilder, _a330, _b243, MySqlInsertBase, init_insert3, init_select_types3, _a331, MySqlUpdateBuilder, _a332, _b244, MySqlUpdateBase, init_update3, init_query_builders3, _a333, RelationalQueryBuilder3, _a334, _b245, MySqlRelationalQuery, init_query3, _a335, MySqlDatabase, init_db3, _a336, ViewBuilderCore2, _a337, _b246, ViewBuilder3, _a338, _b247, ManualViewBuilder3, _a339, _b248, _c11, MySqlView2, init_view3, _a340, MySqlSchema5, init_schema22, _a341, MySqlPreparedQuery, _a342, MySqlSession, _a343, _b249, MySqlTransaction, init_session32, init_subquery4, init_mysql_core, handleEnumType, generateMySqlSnapshot, fromDatabase3, init_mysqlSerializer, cliConfigGenerate, pushParams, pullParams, configCheck, cliConfigCheck, init_cli, gelCredentials, init_gel, libSQLCredentials, init_libsql, mysqlCredentials, init_mysql, postgresCredentials, init_postgres, singlestoreCredentials, init_singlestore, sqliteCredentials, init_sqlite, credentials, studioCliParams, studioConfig, init_studio, es5_exports, _3, es5_default, init_es5, import_hanji7, assertES5, safeRegister, migrateConfig, init_utils9, prepareFromExports, init_pgImports, init_alias5, _a344, UniqueConstraintBuilder4, _a345, UniqueOnConstraintBuilder4, _a346, UniqueConstraint4, init_unique_constraint4, _a347, _b250, SingleStoreColumnBuilder, _a348, _b251, SingleStoreColumn, _a349, _b252, SingleStoreColumnBuilderWithAutoIncrement, _a350, _b253, SingleStoreColumnWithAutoIncrement, init_common5, _a351, _b254, SingleStoreBigInt53Builder, _a352, _b255, SingleStoreBigInt53, _a353, _b256, SingleStoreBigInt64Builder, _a354, _b257, SingleStoreBigInt64, init_bigint3, _a355, _b258, SingleStoreBinaryBuilder, _a356, _b259, SingleStoreBinary, init_binary2, _a357, _b260, SingleStoreBooleanBuilder, _a358, _b261, SingleStoreBoolean, init_boolean3, _a359, _b262, SingleStoreCharBuilder, _a360, _b263, SingleStoreChar, init_char3, _a361, _b264, SingleStoreCustomColumnBuilder, _a362, _b265, SingleStoreCustomColumn, init_custom4, _a363, _b266, SingleStoreDateBuilder, _a364, _b267, SingleStoreDate, _a365, _b268, SingleStoreDateStringBuilder, _a366, _b269, SingleStoreDateString, init_date3, _a367, _b270, SingleStoreDateTimeBuilder, _a368, _b271, SingleStoreDateTime, _a369, _b272, SingleStoreDateTimeStringBuilder, _a370, _b273, SingleStoreDateTimeString, init_datetime2, _a371, _b274, SingleStoreDecimalBuilder, _a372, _b275, SingleStoreDecimal, _a373, _b276, SingleStoreDecimalNumberBuilder, _a374, _b277, SingleStoreDecimalNumber, _a375, _b278, SingleStoreDecimalBigIntBuilder, _a376, _b279, SingleStoreDecimalBigInt, init_decimal2, _a377, _b280, SingleStoreDoubleBuilder, _a378, _b281, SingleStoreDouble, init_double2, _a379, _b282, SingleStoreEnumColumnBuilder, _a380, _b283, SingleStoreEnumColumn, init_enum3, _a381, _b284, SingleStoreFloatBuilder, _a382, _b285, SingleStoreFloat, init_float2, _a383, _b286, SingleStoreIntBuilder, _a384, _b287, SingleStoreInt, init_int2, _a385, _b288, SingleStoreJsonBuilder, _a386, _b289, SingleStoreJson, init_json3, _a387, _b290, SingleStoreMediumIntBuilder, _a388, _b291, SingleStoreMediumInt, init_mediumint2, _a389, _b292, SingleStoreRealBuilder, _a390, _b293, SingleStoreReal, init_real4, _a391, _b294, SingleStoreSerialBuilder, _a392, _b295, SingleStoreSerial, init_serial3, _a393, _b296, SingleStoreSmallIntBuilder, _a394, _b297, SingleStoreSmallInt, init_smallint3, _a395, _b298, SingleStoreTextBuilder, _a396, _b299, SingleStoreText, init_text4, _a397, _b300, SingleStoreTimeBuilder, _a398, _b301, SingleStoreTime, init_time3, _a399, _b302, SingleStoreDateColumnBaseBuilder, _a400, _b303, SingleStoreDateBaseColumn, init_date_common3, _a401, _b304, SingleStoreTimestampBuilder, _a402, _b305, SingleStoreTimestamp, _a403, _b306, SingleStoreTimestampStringBuilder, _a404, _b307, SingleStoreTimestampString, init_timestamp3, _a405, _b308, SingleStoreTinyIntBuilder, _a406, _b309, SingleStoreTinyInt, init_tinyint2, _a407, _b310, SingleStoreVarBinaryBuilder, _a408, _b311, SingleStoreVarBinary, init_varbinary2, _a409, _b312, SingleStoreVarCharBuilder, _a410, _b313, SingleStoreVarChar, init_varchar3, _a411, _b314, SingleStoreVectorBuilder, _a412, _b315, SingleStoreVector, init_vector4, _a413, _b316, SingleStoreYearBuilder, _a414, _b317, SingleStoreYear, init_year2, init_columns4, _a415, _b318, _c12, _SingleStoreCountBuilder, SingleStoreCountBuilder, init_count4, _a416, IndexBuilderOn4, _a417, IndexBuilder4, _a418, Index6, init_indexes4, init_all4, _a419, _b319, _c13, _d5, SingleStoreTable, init_table52, _a420, PrimaryKeyBuilder4, _a421, PrimaryKey4, init_primary_keys4, init_utils10, _a422, _b320, SingleStoreDeleteBase, init_delete4, _a423, SingleStoreInsertBuilder, _a424, _b321, SingleStoreInsertBase, init_insert4, _a425, SingleStoreDialect, init_dialect4, _a426, SingleStoreSelectBuilder, _a427, _b322, SingleStoreSelectQueryBuilderBase, _a428, _b323, SingleStoreSelectBase, getSingleStoreSetOperators, union5, unionAll4, intersect4, except4, minus, init_select5, _a429, QueryBuilder4, init_query_builder5, init_select_types4, _a430, SingleStoreUpdateBuilder, _a431, _b324, SingleStoreUpdateBase, init_update4, init_query_builders4, _a432, SingleStoreDatabase, init_db4, _a433, SingleStoreSchema5, init_schema32, _a434, SingleStorePreparedQuery, _a435, SingleStoreSession, _a436, _b325, SingleStoreTransaction, init_session4, init_subquery5, init_singlestore_core, dialect5, generateSingleStoreSnapshot, fromDatabase4, init_singlestoreSerializer, sqliteImports_exports, prepareFromExports2, prepareFromSqliteImports, init_sqliteImports, mysqlImports_exports, prepareFromExports3, prepareFromMySqlImports, init_mysqlImports, mysqlPushUtils_exports, import_hanji8, filterStatements, logSuggestionsAndReturn2, init_mysqlPushUtils, mysqlIntrospect_exports, import_hanji9, mysqlPushIntrospect, init_mysqlIntrospect, singlestoreImports_exports, prepareFromExports4, prepareFromSingleStoreImports, init_singlestoreImports, singlestorePushUtils_exports, import_hanji10, filterStatements2, logSuggestionsAndReturn3, init_singlestorePushUtils, singlestoreIntrospect_exports, import_hanji11, singlestorePushIntrospect, init_singlestoreIntrospect, import_hanji3, pgPushIntrospect = async (db2, filters, schemaFilters, entities, tsSchema) => {
|
|
100239
101000
|
const matchers = filters.map((it3) => {
|
|
100240
101001
|
return new Minimatch(it3);
|
|
100241
101002
|
});
|
|
@@ -119281,8 +120042,8 @@ ${BREAKPOINT}ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT "${statement.newC
|
|
|
119281
120042
|
win32: { sep: "\\" },
|
|
119282
120043
|
posix: { sep: "/" }
|
|
119283
120044
|
};
|
|
119284
|
-
|
|
119285
|
-
minimatch.sep =
|
|
120045
|
+
sep2 = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
|
|
120046
|
+
minimatch.sep = sep2;
|
|
119286
120047
|
GLOBSTAR = Symbol("globstar **");
|
|
119287
120048
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
119288
120049
|
plTypes = {
|
|
@@ -138184,7 +138945,7 @@ async function seedCoreGames(db2) {
|
|
|
138184
138945
|
}
|
|
138185
138946
|
async function seedCurrentProjectGame(db2, project) {
|
|
138186
138947
|
const now2 = new Date;
|
|
138187
|
-
const desiredGameId = project.gameId?.trim() ||
|
|
138948
|
+
const desiredGameId = project.gameId?.trim() || await localGameId(project.slug);
|
|
138188
138949
|
try {
|
|
138189
138950
|
const existingGame = await db2.query.games.findFirst({
|
|
138190
138951
|
where: (row, operators) => operators.eq(row.slug, project.slug)
|
|
@@ -138200,7 +138961,7 @@ async function seedCurrentProjectGame(db2, project) {
|
|
|
138200
138961
|
}
|
|
138201
138962
|
}
|
|
138202
138963
|
const gameRecord = {
|
|
138203
|
-
id: desiredGameId
|
|
138964
|
+
id: desiredGameId,
|
|
138204
138965
|
slug: project.slug,
|
|
138205
138966
|
displayName: project.displayName,
|
|
138206
138967
|
version: project.version,
|
|
@@ -138235,6 +138996,7 @@ var init_games = __esm(() => {
|
|
|
138235
138996
|
init_drizzle_orm();
|
|
138236
138997
|
init_src();
|
|
138237
138998
|
init_tables_index();
|
|
138999
|
+
init_uuid2();
|
|
138238
139000
|
init_constants();
|
|
138239
139001
|
init_logging();
|
|
138240
139002
|
init_timeback5();
|
|
@@ -138820,19 +139582,50 @@ var init_types6 = () => {};
|
|
|
138820
139582
|
function hasGameManagementAccess(user) {
|
|
138821
139583
|
return user.role === "admin" || user.role === "teacher" || user.role === "developer" && user.developerStatus === "approved";
|
|
138822
139584
|
}
|
|
139585
|
+
function isDashboardWorkerKey(key) {
|
|
139586
|
+
return Boolean(key?.permissions?.[DASHBOARD_PERMISSION_NAMESPACE]);
|
|
139587
|
+
}
|
|
139588
|
+
function workerKeyGrantsGameRead(key, slug2) {
|
|
139589
|
+
if (!isDashboardWorkerKey(key) && !isGameWorkerKey(key)) {
|
|
139590
|
+
return false;
|
|
139591
|
+
}
|
|
139592
|
+
const games2 = key?.permissions?.games;
|
|
139593
|
+
return Boolean(games2?.includes(`read:${slug2}`) || games2?.includes(`write:${slug2}`));
|
|
139594
|
+
}
|
|
139595
|
+
function isGameWorkerKey(key) {
|
|
139596
|
+
return Boolean(key?.name?.startsWith(GAME_WORKER_KEY_PREFIX));
|
|
139597
|
+
}
|
|
139598
|
+
function deniedWorkerKeyRequest(key, method, pathname) {
|
|
139599
|
+
if (isDashboardWorkerKey(key) && !isAllowedDashboardWorkerRequest(method, pathname, key.permissions)) {
|
|
139600
|
+
return DASHBOARD_WORKER_KEY_RESTRICTED;
|
|
139601
|
+
}
|
|
139602
|
+
return null;
|
|
139603
|
+
}
|
|
139604
|
+
function rejectDashboardWorkerKey(ctx) {
|
|
139605
|
+
if (isDashboardWorkerKey(ctx.apiKey)) {
|
|
139606
|
+
throw ApiError.forbidden(DASHBOARD_WORKER_KEY_RESTRICTED);
|
|
139607
|
+
}
|
|
139608
|
+
}
|
|
139609
|
+
function assertAuthenticatedRequest(ctx) {
|
|
139610
|
+
if (!isAuthenticated(ctx)) {
|
|
139611
|
+
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
139612
|
+
}
|
|
139613
|
+
if (ctx.apiKey) {
|
|
139614
|
+
const denied = deniedWorkerKeyRequest(ctx.apiKey, ctx.request.method, ctx.url.pathname);
|
|
139615
|
+
if (denied) {
|
|
139616
|
+
throw ApiError.forbidden(denied);
|
|
139617
|
+
}
|
|
139618
|
+
}
|
|
139619
|
+
}
|
|
138823
139620
|
function requireAuth(handler) {
|
|
138824
139621
|
return async (ctx) => {
|
|
138825
|
-
|
|
138826
|
-
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
138827
|
-
}
|
|
139622
|
+
assertAuthenticatedRequest(ctx);
|
|
138828
139623
|
return handler(ctx);
|
|
138829
139624
|
};
|
|
138830
139625
|
}
|
|
138831
139626
|
function requireNonAnonymous(handler) {
|
|
138832
139627
|
return async (ctx) => {
|
|
138833
|
-
|
|
138834
|
-
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
138835
|
-
}
|
|
139628
|
+
assertAuthenticatedRequest(ctx);
|
|
138836
139629
|
if (ctx.user.isAnonymous) {
|
|
138837
139630
|
throw ApiError.forbidden("This operation is not available for demo/anonymous users");
|
|
138838
139631
|
}
|
|
@@ -138841,9 +139634,7 @@ function requireNonAnonymous(handler) {
|
|
|
138841
139634
|
}
|
|
138842
139635
|
function requireAnonymous(handler) {
|
|
138843
139636
|
return async (ctx) => {
|
|
138844
|
-
|
|
138845
|
-
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
138846
|
-
}
|
|
139637
|
+
assertAuthenticatedRequest(ctx);
|
|
138847
139638
|
if (!ctx.user.isAnonymous) {
|
|
138848
139639
|
throw ApiError.forbidden("This operation is only available for demo/anonymous users");
|
|
138849
139640
|
}
|
|
@@ -138852,9 +139643,8 @@ function requireAnonymous(handler) {
|
|
|
138852
139643
|
}
|
|
138853
139644
|
function requireAdmin(handler) {
|
|
138854
139645
|
return async (ctx) => {
|
|
138855
|
-
|
|
138856
|
-
|
|
138857
|
-
}
|
|
139646
|
+
assertAuthenticatedRequest(ctx);
|
|
139647
|
+
rejectDashboardWorkerKey(ctx);
|
|
138858
139648
|
if (ctx.user.role !== "admin") {
|
|
138859
139649
|
throw ApiError.forbidden("Admin access required");
|
|
138860
139650
|
}
|
|
@@ -138863,9 +139653,8 @@ function requireAdmin(handler) {
|
|
|
138863
139653
|
}
|
|
138864
139654
|
function requireDeveloper(handler) {
|
|
138865
139655
|
return async (ctx) => {
|
|
138866
|
-
|
|
138867
|
-
|
|
138868
|
-
}
|
|
139656
|
+
assertAuthenticatedRequest(ctx);
|
|
139657
|
+
rejectDashboardWorkerKey(ctx);
|
|
138869
139658
|
const isAdmin = ctx.user.role === "admin";
|
|
138870
139659
|
const isApprovedDev = ctx.user.role === "developer" && ctx.user.developerStatus === "approved";
|
|
138871
139660
|
if (!isAdmin && !isApprovedDev) {
|
|
@@ -138874,20 +139663,30 @@ function requireDeveloper(handler) {
|
|
|
138874
139663
|
return handler(ctx);
|
|
138875
139664
|
};
|
|
138876
139665
|
}
|
|
139666
|
+
function requireHumanDeveloper(handler) {
|
|
139667
|
+
return requireDeveloper(async (ctx) => {
|
|
139668
|
+
if (isDashboardWorkerKey(ctx.apiKey) || isGameWorkerKey(ctx.apiKey)) {
|
|
139669
|
+
throw ApiError.forbidden(WORKER_KEY_HUMAN_ONLY);
|
|
139670
|
+
}
|
|
139671
|
+
return handler(ctx);
|
|
139672
|
+
});
|
|
139673
|
+
}
|
|
138877
139674
|
function requireGameManagementAccess(handler) {
|
|
138878
139675
|
return async (ctx) => {
|
|
138879
|
-
|
|
138880
|
-
|
|
138881
|
-
}
|
|
139676
|
+
assertAuthenticatedRequest(ctx);
|
|
139677
|
+
rejectDashboardWorkerKey(ctx);
|
|
138882
139678
|
if (!hasGameManagementAccess(ctx.user)) {
|
|
138883
139679
|
throw ApiError.forbidden("Game management access required");
|
|
138884
139680
|
}
|
|
138885
139681
|
return handler(ctx);
|
|
138886
139682
|
};
|
|
138887
139683
|
}
|
|
139684
|
+
var WORKER_KEY_HUMAN_ONLY = "This operation requires your own credential — platform worker keys are refused";
|
|
138888
139685
|
var init_auth_util = __esm(() => {
|
|
138889
139686
|
init_errors();
|
|
138890
139687
|
init_types6();
|
|
139688
|
+
init_dashboard_util();
|
|
139689
|
+
init_deployment_util();
|
|
138891
139690
|
});
|
|
138892
139691
|
|
|
138893
139692
|
// ../api-core/src/utils/controller.util.ts
|
|
@@ -139031,6 +139830,21 @@ function requireGameId(gameId) {
|
|
|
139031
139830
|
}
|
|
139032
139831
|
return gameId;
|
|
139033
139832
|
}
|
|
139833
|
+
function requireSlug(slug2) {
|
|
139834
|
+
if (!slug2) {
|
|
139835
|
+
throw ApiError.badRequest("Missing game slug");
|
|
139836
|
+
}
|
|
139837
|
+
return slug2;
|
|
139838
|
+
}
|
|
139839
|
+
function requireUserId(userId) {
|
|
139840
|
+
if (!userId) {
|
|
139841
|
+
throw ApiError.badRequest("Missing user ID");
|
|
139842
|
+
}
|
|
139843
|
+
if (!isValidUUID(userId)) {
|
|
139844
|
+
throw ApiError.unprocessableEntity("userId must be a valid UUID format");
|
|
139845
|
+
}
|
|
139846
|
+
return userId;
|
|
139847
|
+
}
|
|
139034
139848
|
var init_params_util = __esm(() => {
|
|
139035
139849
|
init_src4();
|
|
139036
139850
|
init_errors();
|
|
@@ -139079,6 +139893,7 @@ var init_validation_util = __esm(() => {
|
|
|
139079
139893
|
// ../api-core/src/utils/index.ts
|
|
139080
139894
|
var init_utils11 = __esm(() => {
|
|
139081
139895
|
init_auth_util();
|
|
139896
|
+
init_dashboard_util();
|
|
139082
139897
|
init_deployment_util();
|
|
139083
139898
|
init_leaderboard_util();
|
|
139084
139899
|
init_lti_util();
|
|
@@ -139171,6 +139986,83 @@ var init_bucket_controller = __esm(() => {
|
|
|
139171
139986
|
});
|
|
139172
139987
|
});
|
|
139173
139988
|
|
|
139989
|
+
// ../api-core/src/controllers/dashboard.controller.ts
|
|
139990
|
+
function requireDashboardWorkerKey(ctx, slug2) {
|
|
139991
|
+
const scopes = ctx.apiKey?.permissions?.[DASHBOARD_PERMISSION_NAMESPACE];
|
|
139992
|
+
if (!scopes?.includes(dashboardCredentialScope(slug2))) {
|
|
139993
|
+
throw ApiError.forbidden("This endpoint requires the dashboard worker key for this game");
|
|
139994
|
+
}
|
|
139995
|
+
}
|
|
139996
|
+
var listUsers, addUser, issueRecoveryLink, removeUser, remove, verifyLogin, acceptInvite, revokeSessions, acceptReset, dashboard2;
|
|
139997
|
+
var init_dashboard_controller = __esm(() => {
|
|
139998
|
+
init_schemas_index();
|
|
139999
|
+
init_errors();
|
|
140000
|
+
init_utils11();
|
|
140001
|
+
listUsers = requireHumanDeveloper(async (ctx) => {
|
|
140002
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140003
|
+
const users2 = await ctx.services.dashboard.listUsers(slug2, ctx.user);
|
|
140004
|
+
return { users: users2 };
|
|
140005
|
+
});
|
|
140006
|
+
addUser = requireHumanDeveloper(async (ctx) => {
|
|
140007
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140008
|
+
const body2 = await parseRequestBody(ctx.request, AddGameDashboardUserSchema);
|
|
140009
|
+
return ctx.services.dashboard.addUser(slug2, ctx.user, body2);
|
|
140010
|
+
});
|
|
140011
|
+
issueRecoveryLink = requireHumanDeveloper(async (ctx) => {
|
|
140012
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140013
|
+
const userId = requireUserId(ctx.params.userId);
|
|
140014
|
+
return ctx.services.dashboard.issueRecoveryLink(slug2, ctx.user, userId);
|
|
140015
|
+
});
|
|
140016
|
+
removeUser = requireHumanDeveloper(async (ctx) => {
|
|
140017
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140018
|
+
const userId = requireUserId(ctx.params.userId);
|
|
140019
|
+
await ctx.services.dashboard.removeUser(slug2, ctx.user, userId);
|
|
140020
|
+
return { success: true };
|
|
140021
|
+
});
|
|
140022
|
+
remove = requireHumanDeveloper(async (ctx) => {
|
|
140023
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140024
|
+
await ctx.services.deploy.removeDashboard(slug2, ctx.user);
|
|
140025
|
+
return { success: true };
|
|
140026
|
+
});
|
|
140027
|
+
verifyLogin = requireAuth(async (ctx) => {
|
|
140028
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140029
|
+
requireDashboardWorkerKey(ctx, slug2);
|
|
140030
|
+
const body2 = await parseRequestBody(ctx.request, VerifyGameDashboardLoginSchema);
|
|
140031
|
+
const user = await ctx.services.dashboard.verifyLogin(slug2, body2);
|
|
140032
|
+
return { user };
|
|
140033
|
+
});
|
|
140034
|
+
acceptInvite = requireAuth(async (ctx) => {
|
|
140035
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140036
|
+
requireDashboardWorkerKey(ctx, slug2);
|
|
140037
|
+
const body2 = await parseRequestBody(ctx.request, AcceptGameDashboardInviteSchema);
|
|
140038
|
+
const user = await ctx.services.dashboard.acceptInvite(slug2, body2);
|
|
140039
|
+
return { user };
|
|
140040
|
+
});
|
|
140041
|
+
revokeSessions = requireHumanDeveloper(async (ctx) => {
|
|
140042
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140043
|
+
await ctx.services.deploy.rotateDashboardSessionSecret(slug2, ctx.user);
|
|
140044
|
+
return { success: true };
|
|
140045
|
+
});
|
|
140046
|
+
acceptReset = requireAuth(async (ctx) => {
|
|
140047
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140048
|
+
requireDashboardWorkerKey(ctx, slug2);
|
|
140049
|
+
const body2 = await parseRequestBody(ctx.request, AcceptGameDashboardResetSchema);
|
|
140050
|
+
const user = await ctx.services.dashboard.acceptReset(slug2, body2);
|
|
140051
|
+
return { user };
|
|
140052
|
+
});
|
|
140053
|
+
dashboard2 = defineControllerNames("dashboard", {
|
|
140054
|
+
listUsers,
|
|
140055
|
+
addUser,
|
|
140056
|
+
removeUser,
|
|
140057
|
+
remove,
|
|
140058
|
+
issueRecoveryLink,
|
|
140059
|
+
revokeSessions,
|
|
140060
|
+
verifyLogin,
|
|
140061
|
+
acceptInvite,
|
|
140062
|
+
acceptReset
|
|
140063
|
+
});
|
|
140064
|
+
});
|
|
140065
|
+
|
|
139174
140066
|
// ../api-core/src/controllers/database.controller.ts
|
|
139175
140067
|
var reset, database;
|
|
139176
140068
|
var init_database_controller = __esm(() => {
|
|
@@ -139265,7 +140157,7 @@ var init_developer_controller = __esm(() => {
|
|
|
139265
140157
|
});
|
|
139266
140158
|
|
|
139267
140159
|
// ../api-core/src/controllers/domain.controller.ts
|
|
139268
|
-
var add, list, getStatus2,
|
|
140160
|
+
var add, list, getStatus2, remove2, domains2;
|
|
139269
140161
|
var init_domain_controller = __esm(() => {
|
|
139270
140162
|
init_esm();
|
|
139271
140163
|
init_schemas_index();
|
|
@@ -139314,7 +140206,7 @@ var init_domain_controller = __esm(() => {
|
|
|
139314
140206
|
const environment = getPlatformEnvironment(ctx.config);
|
|
139315
140207
|
return ctx.services.domain.getStatus(slug2, hostname4, environment, ctx.user, refresh);
|
|
139316
140208
|
});
|
|
139317
|
-
|
|
140209
|
+
remove2 = requireDeveloper(async (ctx) => {
|
|
139318
140210
|
const slug2 = ctx.params.slug;
|
|
139319
140211
|
const hostname4 = ctx.params.hostname;
|
|
139320
140212
|
if (!slug2) {
|
|
@@ -139330,12 +140222,12 @@ var init_domain_controller = __esm(() => {
|
|
|
139330
140222
|
add,
|
|
139331
140223
|
list,
|
|
139332
140224
|
getStatus: getStatus2,
|
|
139333
|
-
remove
|
|
140225
|
+
remove: remove2
|
|
139334
140226
|
});
|
|
139335
140227
|
});
|
|
139336
140228
|
|
|
139337
140229
|
// ../api-core/src/controllers/game-member.controller.ts
|
|
139338
|
-
function
|
|
140230
|
+
function requireUserId2(userId) {
|
|
139339
140231
|
if (!userId) {
|
|
139340
140232
|
throw ApiError.badRequest("Missing user ID");
|
|
139341
140233
|
}
|
|
@@ -139357,13 +140249,13 @@ var init_game_member_controller = __esm(() => {
|
|
|
139357
140249
|
});
|
|
139358
140250
|
updateMemberRole = requireNonAnonymous(async (ctx) => {
|
|
139359
140251
|
const gameId = requireGameId(ctx.params.gameId);
|
|
139360
|
-
const userId =
|
|
140252
|
+
const userId = requireUserId2(ctx.params.userId);
|
|
139361
140253
|
const body2 = await parseRequestBody(ctx.request, UpdateGameMemberRoleSchema);
|
|
139362
140254
|
return ctx.services.gameMember.updateRole(gameId, userId, ctx.user, body2);
|
|
139363
140255
|
});
|
|
139364
140256
|
removeMember = requireNonAnonymous(async (ctx) => {
|
|
139365
140257
|
const gameId = requireGameId(ctx.params.gameId);
|
|
139366
|
-
const userId =
|
|
140258
|
+
const userId = requireUserId2(ctx.params.userId);
|
|
139367
140259
|
await ctx.services.gameMember.remove(gameId, userId, ctx.user);
|
|
139368
140260
|
});
|
|
139369
140261
|
searchUsersForMember = requireNonAnonymous(async (ctx) => {
|
|
@@ -139381,12 +140273,13 @@ var init_game_member_controller = __esm(() => {
|
|
|
139381
140273
|
});
|
|
139382
140274
|
|
|
139383
140275
|
// ../api-core/src/controllers/game.controller.ts
|
|
139384
|
-
var list2, listAccessible, getSubjects, getTimebackSummaries, getById, getBySlug, getManifest, upsertBySlug, patchGameMetadata,
|
|
140276
|
+
var list2, listAccessible, getSubjects, getTimebackSummaries, getById, getBySlug, getManifest, upsertBySlug, patchGameMetadata, remove3, games2;
|
|
139385
140277
|
var init_game_controller = __esm(() => {
|
|
139386
140278
|
init_esm();
|
|
139387
140279
|
init_schemas_index();
|
|
139388
140280
|
init_errors();
|
|
139389
140281
|
init_utils11();
|
|
140282
|
+
init_auth_util();
|
|
139390
140283
|
list2 = requireNonAnonymous(async (ctx) => ctx.services.game.list(ctx.user));
|
|
139391
140284
|
listAccessible = requireNonAnonymous(async (ctx) => ctx.services.game.listAccessible(ctx.user));
|
|
139392
140285
|
getSubjects = requireNonAnonymous(async (ctx) => ctx.services.game.getSubjects());
|
|
@@ -139400,7 +140293,9 @@ var init_game_controller = __esm(() => {
|
|
|
139400
140293
|
if (!slug2) {
|
|
139401
140294
|
throw ApiError.badRequest("Missing game slug");
|
|
139402
140295
|
}
|
|
139403
|
-
return ctx.services.game.getBySlug(slug2, ctx.user
|
|
140296
|
+
return ctx.services.game.getBySlug(slug2, ctx.user, {
|
|
140297
|
+
scopeAuthorized: workerKeyGrantsGameRead(ctx.apiKey, slug2)
|
|
140298
|
+
});
|
|
139404
140299
|
});
|
|
139405
140300
|
getManifest = requireNonAnonymous(async (ctx) => {
|
|
139406
140301
|
const gameId = requireGameId(ctx.params.gameId);
|
|
@@ -139430,7 +140325,7 @@ var init_game_controller = __esm(() => {
|
|
|
139430
140325
|
const body2 = await parseRequestBody(ctx.request, PatchGameMetadataSchema);
|
|
139431
140326
|
return ctx.services.game.updateMetadata(gameId, body2, ctx.user);
|
|
139432
140327
|
});
|
|
139433
|
-
|
|
140328
|
+
remove3 = requireNonAnonymous(async (ctx) => {
|
|
139434
140329
|
const gameId = requireGameId(ctx.params.gameId);
|
|
139435
140330
|
await ctx.services.game.delete(gameId, ctx.user);
|
|
139436
140331
|
});
|
|
@@ -139444,7 +140339,7 @@ var init_game_controller = __esm(() => {
|
|
|
139444
140339
|
getBySlug,
|
|
139445
140340
|
upsertBySlug,
|
|
139446
140341
|
patchGameMetadata,
|
|
139447
|
-
remove:
|
|
140342
|
+
remove: remove3
|
|
139448
140343
|
});
|
|
139449
140344
|
});
|
|
139450
140345
|
|
|
@@ -140598,6 +141493,7 @@ var init_verify_controller = __esm(() => {
|
|
|
140598
141493
|
// ../api-core/src/controllers/index.ts
|
|
140599
141494
|
var init_controllers = __esm(() => {
|
|
140600
141495
|
init_bucket_controller();
|
|
141496
|
+
init_dashboard_controller();
|
|
140601
141497
|
init_database_controller();
|
|
140602
141498
|
init_deploy_controller();
|
|
140603
141499
|
init_developer_controller();
|
|
@@ -143746,7 +144642,7 @@ import { resolve as resolve3 } from "node:path";
|
|
|
143746
144642
|
|
|
143747
144643
|
// ../utils/src/file-loader.ts
|
|
143748
144644
|
import { existsSync as existsSync3, readdirSync, statSync } from "fs";
|
|
143749
|
-
import { readFile } from "fs/promises";
|
|
144645
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
143750
144646
|
import { dirname as dirname2, parse as parse9, resolve as resolve2 } from "path";
|
|
143751
144647
|
function findFilePath(filename, startDir, maxLevels = 3) {
|
|
143752
144648
|
const filenames = Array.isArray(filename) ? filename : [filename];
|
|
@@ -143815,7 +144711,7 @@ async function loadFile(filename, options = {}) {
|
|
|
143815
144711
|
return null;
|
|
143816
144712
|
}
|
|
143817
144713
|
try {
|
|
143818
|
-
let content = await
|
|
144714
|
+
let content = await readFile2(fileResult.path, "utf8");
|
|
143819
144715
|
if (parseJson) {
|
|
143820
144716
|
if (stripComments) {
|
|
143821
144717
|
content = stripJsonComments(content);
|
|
@@ -144044,6 +144940,9 @@ program2.name("playcademy-sandbox").description("Local development server for Pl
|
|
|
144044
144940
|
process.on("SIGTERM", cleanup);
|
|
144045
144941
|
} catch (error89) {
|
|
144046
144942
|
console.error(`❌ Failed to start sandbox: ${error89}`);
|
|
144943
|
+
if (error89 instanceof Error && error89.message.includes("already in use")) {
|
|
144944
|
+
console.error("Stop the other server or specify a different port with --port <number>.");
|
|
144945
|
+
}
|
|
144047
144946
|
process.exit(1);
|
|
144048
144947
|
}
|
|
144049
144948
|
});
|