@playcademy/sandbox 0.6.1-beta.4 → 0.6.1-beta.6
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 +1355 -404
- package/dist/constants.js +17 -11
- package/dist/server.js +1350 -402
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -203,6 +203,20 @@ var init_auth = __esm(() => {
|
|
|
203
203
|
};
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
+
// ../constants/src/dashboard.ts
|
|
207
|
+
var DASHBOARD_USER_ROLES, DASHBOARD_WORKER_ROUTES, DASHBOARD_WORKER_SUFFIX = "-dash";
|
|
208
|
+
var init_dashboard = __esm(() => {
|
|
209
|
+
DASHBOARD_USER_ROLES = {
|
|
210
|
+
ADMIN: "admin",
|
|
211
|
+
VIEWER: "viewer"
|
|
212
|
+
};
|
|
213
|
+
DASHBOARD_WORKER_ROUTES = {
|
|
214
|
+
verifySession: "/sessions",
|
|
215
|
+
acceptInvite: "/invites/accept",
|
|
216
|
+
acceptReset: "/resets/accept"
|
|
217
|
+
};
|
|
218
|
+
});
|
|
219
|
+
|
|
206
220
|
// ../constants/src/typescript.ts
|
|
207
221
|
var init_typescript = () => {};
|
|
208
222
|
|
|
@@ -244,17 +258,8 @@ var init_platform = __esm(() => {
|
|
|
244
258
|
var PLATFORM_TIMEZONE = "America/New_York";
|
|
245
259
|
|
|
246
260
|
// ../constants/src/timeback.ts
|
|
247
|
-
var
|
|
261
|
+
var TIMEBACK_ORG_SOURCED_ID = "PLAYCADEMY", TIMEBACK_ORG_NAME = "Playcademy Studios", TIMEBACK_ORG_TYPE = "department", TIMEBACK_COURSE_DEFAULTS, TIMEBACK_RESOURCE_DEFAULTS, TIMEBACK_COMPONENT_DEFAULTS, TIMEBACK_COMPONENT_RESOURCE_DEFAULTS, TIMEBACK_GAME_METRIC_DECIMAL_PLACES, TIMEBACK_GAME_METRIC_COMPARISON_TOLERANCE;
|
|
248
262
|
var init_timeback2 = __esm(() => {
|
|
249
|
-
TIMEBACK_ROUTES = {
|
|
250
|
-
END_ACTIVITY: "/integrations/timeback/end-activity",
|
|
251
|
-
GET_XP: "/integrations/timeback/xp",
|
|
252
|
-
GET_MASTERY: "/integrations/timeback/mastery",
|
|
253
|
-
GET_HIGHEST_GRADE_MASTERED: "/integrations/timeback/highest-grade-mastered",
|
|
254
|
-
HEARTBEAT: "/integrations/timeback/heartbeat",
|
|
255
|
-
ADVANCE_COURSE: "/integrations/timeback/advance-course",
|
|
256
|
-
UNENROLL_COURSE: "/integrations/timeback/unenroll-course"
|
|
257
|
-
};
|
|
258
263
|
TIMEBACK_COURSE_DEFAULTS = {
|
|
259
264
|
gradingScheme: "STANDARD",
|
|
260
265
|
level: {
|
|
@@ -305,7 +310,7 @@ var init_timeback2 = __esm(() => {
|
|
|
305
310
|
});
|
|
306
311
|
|
|
307
312
|
// ../constants/src/cloudflare.ts
|
|
308
|
-
var WORKER_NAMING, SECRETS_PREFIX = "secrets_", CLOUDFLARE_COMPATIBILITY_DATE = "2025-10-11";
|
|
313
|
+
var WORKER_NAMING, MAX_WORKER_NAME_LENGTH = 63, SECRETS_PREFIX = "secrets_", CLOUDFLARE_COMPATIBILITY_DATE = "2025-10-11";
|
|
309
314
|
var init_cloudflare = __esm(() => {
|
|
310
315
|
WORKER_NAMING = {
|
|
311
316
|
STAGING_PREFIX: "staging-",
|
|
@@ -317,6 +322,7 @@ var init_cloudflare = __esm(() => {
|
|
|
317
322
|
// ../constants/src/index.ts
|
|
318
323
|
var init_src = __esm(() => {
|
|
319
324
|
init_auth();
|
|
325
|
+
init_dashboard();
|
|
320
326
|
init_typescript();
|
|
321
327
|
init_domains();
|
|
322
328
|
init_env_vars();
|
|
@@ -1056,8 +1062,7 @@ async function waitForPort(port, timeoutMs = 5000) {
|
|
|
1056
1062
|
const start2 = Date.now();
|
|
1057
1063
|
while (await isPortInUse(port)) {
|
|
1058
1064
|
if (Date.now() - start2 > timeoutMs) {
|
|
1059
|
-
throw new Error(`Port ${port} is already in use
|
|
1060
|
-
` + `Stop the other server or specify a different port with --port <number>.`);
|
|
1065
|
+
throw new Error(`Port ${port} is already in use`);
|
|
1061
1066
|
}
|
|
1062
1067
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1063
1068
|
}
|
|
@@ -1066,8 +1071,7 @@ async function requirePortAvailable(port, timeoutMs = 100) {
|
|
|
1066
1071
|
const start2 = Date.now();
|
|
1067
1072
|
while (await isPortInUse(port)) {
|
|
1068
1073
|
if (Date.now() - start2 > timeoutMs) {
|
|
1069
|
-
throw new Error(`Port ${port} is already in use
|
|
1070
|
-
` + `Stop the other server or specify a different port with --port <number>.`);
|
|
1074
|
+
throw new Error(`Port ${port} is already in use`);
|
|
1071
1075
|
}
|
|
1072
1076
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
1073
1077
|
}
|
|
@@ -1079,7 +1083,7 @@ var package_default;
|
|
|
1079
1083
|
var init_package = __esm(() => {
|
|
1080
1084
|
package_default = {
|
|
1081
1085
|
name: "@playcademy/sandbox",
|
|
1082
|
-
version: "0.6.1-beta.
|
|
1086
|
+
version: "0.6.1-beta.6",
|
|
1083
1087
|
description: "Local development server for Playcademy game development",
|
|
1084
1088
|
type: "module",
|
|
1085
1089
|
exports: {
|
|
@@ -1148,7 +1152,7 @@ var init_package = __esm(() => {
|
|
|
1148
1152
|
});
|
|
1149
1153
|
|
|
1150
1154
|
// ../api-core/src/errors/domain.error.ts
|
|
1151
|
-
var DomainError, BadRequestError, AccessDeniedError, NotFoundError, ConflictError, AlreadyExistsError, ValidationError, InternalError, ServiceUnavailableError, TimeoutError;
|
|
1155
|
+
var DomainError, BadRequestError, UnauthorizedError, AccessDeniedError, NotFoundError, ConflictError, AlreadyExistsError, ValidationError, RateLimitError, InternalError, ServiceUnavailableError, TimeoutError;
|
|
1152
1156
|
var init_domain_error = __esm(() => {
|
|
1153
1157
|
DomainError = class DomainError extends Error {
|
|
1154
1158
|
code;
|
|
@@ -1166,6 +1170,12 @@ var init_domain_error = __esm(() => {
|
|
|
1166
1170
|
this.name = "BadRequestError";
|
|
1167
1171
|
}
|
|
1168
1172
|
};
|
|
1173
|
+
UnauthorizedError = class UnauthorizedError extends DomainError {
|
|
1174
|
+
constructor(message = "Unauthorized", details) {
|
|
1175
|
+
super("UNAUTHORIZED", message, details);
|
|
1176
|
+
this.name = "UnauthorizedError";
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1169
1179
|
AccessDeniedError = class AccessDeniedError extends DomainError {
|
|
1170
1180
|
constructor(message = "Access denied", details) {
|
|
1171
1181
|
super("ACCESS_DENIED", message, details);
|
|
@@ -1198,6 +1208,12 @@ var init_domain_error = __esm(() => {
|
|
|
1198
1208
|
this.name = "ValidationError";
|
|
1199
1209
|
}
|
|
1200
1210
|
};
|
|
1211
|
+
RateLimitError = class RateLimitError extends DomainError {
|
|
1212
|
+
constructor(message = "Rate limit exceeded", details) {
|
|
1213
|
+
super("RATE_LIMITED", message, details);
|
|
1214
|
+
this.name = "RateLimitError";
|
|
1215
|
+
}
|
|
1216
|
+
};
|
|
1201
1217
|
InternalError = class InternalError extends DomainError {
|
|
1202
1218
|
constructor(message = "Internal error", details) {
|
|
1203
1219
|
super("INTERNAL", message, details);
|
|
@@ -1556,12 +1572,24 @@ data: ${JSON.stringify(data)}
|
|
|
1556
1572
|
return sseEncoder.encode(payload);
|
|
1557
1573
|
}
|
|
1558
1574
|
function createContextBuilder(options) {
|
|
1559
|
-
const {
|
|
1575
|
+
const {
|
|
1576
|
+
db,
|
|
1577
|
+
config: config2,
|
|
1578
|
+
providers,
|
|
1579
|
+
services,
|
|
1580
|
+
cloudflare: cloudflare2,
|
|
1581
|
+
timeback: timeback2,
|
|
1582
|
+
resolveUser,
|
|
1583
|
+
resolveGameId,
|
|
1584
|
+
resolveApiKey
|
|
1585
|
+
} = options;
|
|
1560
1586
|
return async (c) => {
|
|
1561
1587
|
const user = resolveUser ? await resolveUser(c) : null;
|
|
1562
1588
|
const gameId = resolveGameId ? await resolveGameId(c) : undefined;
|
|
1589
|
+
const apiKey = resolveApiKey ? await resolveApiKey(c) : undefined;
|
|
1563
1590
|
return {
|
|
1564
1591
|
user,
|
|
1592
|
+
apiKey,
|
|
1565
1593
|
gameId,
|
|
1566
1594
|
params: c.req.param(),
|
|
1567
1595
|
url: new URL(c.req.url),
|
|
@@ -5660,6 +5688,14 @@ var init_schema = __esm(() => {
|
|
|
5660
5688
|
platformServiceJwt: platformServiceJwtConfigSchema.optional(),
|
|
5661
5689
|
uploadBucket: exports_external.string().optional(),
|
|
5662
5690
|
queueIngressSecret: exports_external.string().optional()
|
|
5691
|
+
}).superRefine((config2, ctx) => {
|
|
5692
|
+
if (config2.isLocal && !config2.baseUrl) {
|
|
5693
|
+
ctx.addIssue({
|
|
5694
|
+
code: exports_external.ZodIssueCode.custom,
|
|
5695
|
+
path: ["baseUrl"],
|
|
5696
|
+
message: "baseUrl is required when isLocal is true"
|
|
5697
|
+
});
|
|
5698
|
+
}
|
|
5663
5699
|
});
|
|
5664
5700
|
});
|
|
5665
5701
|
|
|
@@ -11180,7 +11216,7 @@ var init_table4 = __esm(() => {
|
|
|
11180
11216
|
});
|
|
11181
11217
|
|
|
11182
11218
|
// ../data/src/domains/game/table.ts
|
|
11183
|
-
var gamePlatformEnum, gameTypeEnum, gameVisibilityEnum, games, gameMemberRoleEnum, gameMembers, gameMembersRelations, deploymentProviderEnum, deployJobStatusEnum, gameDeployments, gameDeployJobs, customHostnameStatusEnum, customHostnameSslStatusEnum, customHostnameEnvironmentEnum, gameCustomHostnames;
|
|
11219
|
+
var gamePlatformEnum, gameTypeEnum, gameVisibilityEnum, games, gameMemberRoleEnum, gameMembers, gameMembersRelations, gameDashboardUserRoleEnum, gameDashboardUsers, gameDashboardUsersRelations, deploymentProviderEnum, deploymentTargetEnum, deployJobStatusEnum, gameDeployments, gameDeployJobs, customHostnameStatusEnum, customHostnameSslStatusEnum, customHostnameEnvironmentEnum, gameCustomHostnames;
|
|
11184
11220
|
var init_table5 = __esm(() => {
|
|
11185
11221
|
init_drizzle_orm();
|
|
11186
11222
|
init_pg_core();
|
|
@@ -11224,7 +11260,37 @@ var init_table5 = __esm(() => {
|
|
|
11224
11260
|
references: [users.id]
|
|
11225
11261
|
})
|
|
11226
11262
|
}));
|
|
11263
|
+
gameDashboardUserRoleEnum = pgEnum("game_dashboard_user_role", [
|
|
11264
|
+
DASHBOARD_USER_ROLES.ADMIN,
|
|
11265
|
+
DASHBOARD_USER_ROLES.VIEWER
|
|
11266
|
+
]);
|
|
11267
|
+
gameDashboardUsers = pgTable("game_dashboard_users", {
|
|
11268
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
11269
|
+
gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
|
|
11270
|
+
email: text("email").notNull(),
|
|
11271
|
+
displayName: text("display_name"),
|
|
11272
|
+
role: gameDashboardUserRoleEnum("role").notNull().default(DASHBOARD_USER_ROLES.VIEWER),
|
|
11273
|
+
passwordHash: text("password_hash"),
|
|
11274
|
+
inviteTokenHash: text("invite_token_hash"),
|
|
11275
|
+
inviteExpiresAt: timestamp("invite_expires_at", { withTimezone: true }),
|
|
11276
|
+
resetTokenHash: text("reset_token_hash"),
|
|
11277
|
+
resetExpiresAt: timestamp("reset_expires_at", { withTimezone: true }),
|
|
11278
|
+
failedLoginAttempts: integer("failed_login_attempts").notNull().default(0),
|
|
11279
|
+
lastFailedLoginAt: timestamp("last_failed_login_at", { withTimezone: true }),
|
|
11280
|
+
platformUserId: text("platform_user_id").references(() => users.id, {
|
|
11281
|
+
onDelete: "set null"
|
|
11282
|
+
}),
|
|
11283
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
11284
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
11285
|
+
}, (table3) => [uniqueIndex("game_dashboard_users_game_email_idx").on(table3.gameId, table3.email)]);
|
|
11286
|
+
gameDashboardUsersRelations = relations(gameDashboardUsers, ({ one }) => ({
|
|
11287
|
+
game: one(games, {
|
|
11288
|
+
fields: [gameDashboardUsers.gameId],
|
|
11289
|
+
references: [games.id]
|
|
11290
|
+
})
|
|
11291
|
+
}));
|
|
11227
11292
|
deploymentProviderEnum = pgEnum("deployment_provider", ["cloudflare", "aws"]);
|
|
11293
|
+
deploymentTargetEnum = pgEnum("deployment_target", ["game", "dashboard"]);
|
|
11228
11294
|
deployJobStatusEnum = pgEnum("deploy_job_status", [
|
|
11229
11295
|
"pending",
|
|
11230
11296
|
"running",
|
|
@@ -11236,6 +11302,7 @@ var init_table5 = __esm(() => {
|
|
|
11236
11302
|
gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
|
|
11237
11303
|
deploymentId: text("deployment_id").notNull(),
|
|
11238
11304
|
provider: deploymentProviderEnum("provider").notNull(),
|
|
11305
|
+
target: deploymentTargetEnum("target").notNull().default("game"),
|
|
11239
11306
|
url: text("url").notNull(),
|
|
11240
11307
|
codeHash: text("code_hash"),
|
|
11241
11308
|
isActive: boolean("is_active").notNull().default(false),
|
|
@@ -11423,8 +11490,12 @@ __export(exports_tables_index, {
|
|
|
11423
11490
|
gameMemberRoleEnum: () => gameMemberRoleEnum,
|
|
11424
11491
|
gameDeployments: () => gameDeployments,
|
|
11425
11492
|
gameDeployJobs: () => gameDeployJobs,
|
|
11493
|
+
gameDashboardUsersRelations: () => gameDashboardUsersRelations,
|
|
11494
|
+
gameDashboardUsers: () => gameDashboardUsers,
|
|
11495
|
+
gameDashboardUserRoleEnum: () => gameDashboardUserRoleEnum,
|
|
11426
11496
|
gameCustomHostnames: () => gameCustomHostnames,
|
|
11427
11497
|
developerStatusEnum: () => developerStatusEnum,
|
|
11498
|
+
deploymentTargetEnum: () => deploymentTargetEnum,
|
|
11428
11499
|
deploymentProviderEnum: () => deploymentProviderEnum,
|
|
11429
11500
|
deployJobStatusEnum: () => deployJobStatusEnum,
|
|
11430
11501
|
customHostnameStatusEnum: () => customHostnameStatusEnum,
|
|
@@ -12928,6 +12999,10 @@ function errorMessage(err2) {
|
|
|
12928
12999
|
function errorType(err2) {
|
|
12929
13000
|
return err2 instanceof Error ? err2.constructor.name : typeof err2;
|
|
12930
13001
|
}
|
|
13002
|
+
function isUniqueViolation(err2) {
|
|
13003
|
+
return typeof err2 === "object" && err2 !== null && err2.code === PG_UNIQUE_VIOLATION;
|
|
13004
|
+
}
|
|
13005
|
+
var PG_UNIQUE_VIOLATION = "23505";
|
|
12931
13006
|
|
|
12932
13007
|
// ../otel/src/spans.ts
|
|
12933
13008
|
function truncate(value) {
|
|
@@ -13006,6 +13081,310 @@ var init_spans = __esm(() => {
|
|
|
13006
13081
|
ROOT_SPAN_KEY = import_api2.createContextKey("playcademy.root_span");
|
|
13007
13082
|
});
|
|
13008
13083
|
|
|
13084
|
+
// ../utils/src/random.ts
|
|
13085
|
+
async function generateSecureRandomString(length) {
|
|
13086
|
+
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
|
|
13087
|
+
const randomValues = new Uint8Array(length);
|
|
13088
|
+
crypto.getRandomValues(randomValues);
|
|
13089
|
+
return [...randomValues].map((byte) => charset[byte % charset.length]).join("");
|
|
13090
|
+
}
|
|
13091
|
+
|
|
13092
|
+
// ../api-core/src/utils/hash.util.ts
|
|
13093
|
+
async function sha256Hex(input) {
|
|
13094
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
|
|
13095
|
+
return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
13096
|
+
}
|
|
13097
|
+
|
|
13098
|
+
// ../api-core/src/utils/dashboard.util.ts
|
|
13099
|
+
function dashboardCredentialScope(slug) {
|
|
13100
|
+
return `${CREDENTIAL_SCOPE_PREFIX}${slug}`;
|
|
13101
|
+
}
|
|
13102
|
+
function dashboardCredentialSlugs(permissions) {
|
|
13103
|
+
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);
|
|
13104
|
+
}
|
|
13105
|
+
function isAllowedDashboardWorkerRequest(method, pathname, permissions) {
|
|
13106
|
+
const path = pathname.replace(/\/+$/, "");
|
|
13107
|
+
return dashboardCredentialSlugs(permissions).some((slug) => {
|
|
13108
|
+
if (method === "GET") {
|
|
13109
|
+
return path === `/api/games/${slug}`;
|
|
13110
|
+
}
|
|
13111
|
+
if (method === "POST") {
|
|
13112
|
+
return Object.values(DASHBOARD_WORKER_ROUTES).some((subpath) => path === `/api/games/${slug}/dashboard${subpath}`);
|
|
13113
|
+
}
|
|
13114
|
+
return false;
|
|
13115
|
+
});
|
|
13116
|
+
}
|
|
13117
|
+
function hashDashboardToken(token) {
|
|
13118
|
+
return sha256Hex(token);
|
|
13119
|
+
}
|
|
13120
|
+
function loginBackoffMs(failedAttempts) {
|
|
13121
|
+
if (failedAttempts < LOGIN_BACKOFF_THRESHOLD) {
|
|
13122
|
+
return 0;
|
|
13123
|
+
}
|
|
13124
|
+
return Math.min(LOGIN_BACKOFF_CAP_MS, LOGIN_BACKOFF_BASE_MS * 2 ** (failedAttempts - LOGIN_BACKOFF_THRESHOLD));
|
|
13125
|
+
}
|
|
13126
|
+
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;
|
|
13127
|
+
var init_dashboard_util = __esm(() => {
|
|
13128
|
+
init_src();
|
|
13129
|
+
LOGIN_BACKOFF_CAP_MS = 5 * 60 * 1000;
|
|
13130
|
+
});
|
|
13131
|
+
|
|
13132
|
+
// ../api-core/src/services/dashboard.service.ts
|
|
13133
|
+
function alreadyExists(gameId) {
|
|
13134
|
+
return new AlreadyExistsError("A dashboard user with this email already exists", { gameId });
|
|
13135
|
+
}
|
|
13136
|
+
var DashboardService;
|
|
13137
|
+
var init_dashboard_service = __esm(() => {
|
|
13138
|
+
init_drizzle_orm();
|
|
13139
|
+
init_tables_index();
|
|
13140
|
+
init_spans();
|
|
13141
|
+
init_errors();
|
|
13142
|
+
init_dashboard_util();
|
|
13143
|
+
DashboardService = class DashboardService {
|
|
13144
|
+
deps;
|
|
13145
|
+
static INVITE_TOKEN_LENGTH = 48;
|
|
13146
|
+
static INVITE_TTL_MS = 72 * 60 * 60 * 1000;
|
|
13147
|
+
static RESET_TTL_MS = 24 * 60 * 60 * 1000;
|
|
13148
|
+
constructor(deps) {
|
|
13149
|
+
this.deps = deps;
|
|
13150
|
+
}
|
|
13151
|
+
async listUsers(slug, user) {
|
|
13152
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13153
|
+
const rows = await this.deps.db.select({
|
|
13154
|
+
id: gameDashboardUsers.id,
|
|
13155
|
+
gameId: gameDashboardUsers.gameId,
|
|
13156
|
+
email: gameDashboardUsers.email,
|
|
13157
|
+
displayName: gameDashboardUsers.displayName,
|
|
13158
|
+
role: gameDashboardUsers.role,
|
|
13159
|
+
platformUserId: gameDashboardUsers.platformUserId,
|
|
13160
|
+
createdAt: gameDashboardUsers.createdAt,
|
|
13161
|
+
updatedAt: gameDashboardUsers.updatedAt,
|
|
13162
|
+
pending: sql`(${gameDashboardUsers.passwordHash} IS NULL)`
|
|
13163
|
+
}).from(gameDashboardUsers).where(eq(gameDashboardUsers.gameId, game2.id)).orderBy(asc(gameDashboardUsers.createdAt));
|
|
13164
|
+
setAttributes({
|
|
13165
|
+
"app.dashboard.operation": "list_users",
|
|
13166
|
+
"app.dashboard.result_count": rows.length
|
|
13167
|
+
});
|
|
13168
|
+
return rows;
|
|
13169
|
+
}
|
|
13170
|
+
async addUser(slug, user, input) {
|
|
13171
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13172
|
+
const email = input.email.toLowerCase();
|
|
13173
|
+
setAttributes({
|
|
13174
|
+
"app.dashboard.operation": "add_user",
|
|
13175
|
+
"app.dashboard.user_role": input.role
|
|
13176
|
+
});
|
|
13177
|
+
const existing = await this.findByEmail(game2.id, email);
|
|
13178
|
+
if (existing) {
|
|
13179
|
+
throw alreadyExists(game2.id);
|
|
13180
|
+
}
|
|
13181
|
+
const inviteToken = await generateSecureRandomString(DashboardService.INVITE_TOKEN_LENGTH);
|
|
13182
|
+
let created;
|
|
13183
|
+
try {
|
|
13184
|
+
[created] = await this.deps.db.insert(gameDashboardUsers).values({
|
|
13185
|
+
gameId: game2.id,
|
|
13186
|
+
email,
|
|
13187
|
+
displayName: input.displayName,
|
|
13188
|
+
role: input.role,
|
|
13189
|
+
inviteTokenHash: await hashDashboardToken(inviteToken),
|
|
13190
|
+
inviteExpiresAt: new Date(Date.now() + DashboardService.INVITE_TTL_MS),
|
|
13191
|
+
platformUserId: email === user.email.toLowerCase() ? user.id : undefined
|
|
13192
|
+
}).returning();
|
|
13193
|
+
} catch (error) {
|
|
13194
|
+
if (isUniqueViolation(error)) {
|
|
13195
|
+
throw alreadyExists(game2.id);
|
|
13196
|
+
}
|
|
13197
|
+
throw error;
|
|
13198
|
+
}
|
|
13199
|
+
if (!created) {
|
|
13200
|
+
throw new ValidationError("Failed to create dashboard user");
|
|
13201
|
+
}
|
|
13202
|
+
return { user: DashboardService.toSummary(created), token: inviteToken, kind: "invite" };
|
|
13203
|
+
}
|
|
13204
|
+
async removeUser(slug, user, dashboardUserId) {
|
|
13205
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13206
|
+
setAttributes({
|
|
13207
|
+
"app.dashboard.operation": "remove_user",
|
|
13208
|
+
"app.dashboard.user_id": dashboardUserId
|
|
13209
|
+
});
|
|
13210
|
+
const [deleted] = await this.deps.db.delete(gameDashboardUsers).where(and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.id, dashboardUserId))).returning({ id: gameDashboardUsers.id });
|
|
13211
|
+
if (!deleted) {
|
|
13212
|
+
throw new NotFoundError("Dashboard user", dashboardUserId);
|
|
13213
|
+
}
|
|
13214
|
+
}
|
|
13215
|
+
async verifyLogin(slug, input) {
|
|
13216
|
+
const game2 = await this.getGameForRuntime(slug);
|
|
13217
|
+
setAttributes({ "app.dashboard.operation": "verify_login" });
|
|
13218
|
+
const dashboardUser = await this.findByEmail(game2.id, input.email.toLowerCase());
|
|
13219
|
+
if (!dashboardUser?.passwordHash) {
|
|
13220
|
+
throw new UnauthorizedError("Invalid credentials");
|
|
13221
|
+
}
|
|
13222
|
+
if (dashboardUser.lastFailedLoginAt) {
|
|
13223
|
+
const retryAt = dashboardUser.lastFailedLoginAt.getTime() + loginBackoffMs(dashboardUser.failedLoginAttempts);
|
|
13224
|
+
if (retryAt > Date.now()) {
|
|
13225
|
+
addEvent("dashboard.login_throttled", {
|
|
13226
|
+
"app.dashboard.failed_attempts": dashboardUser.failedLoginAttempts
|
|
13227
|
+
});
|
|
13228
|
+
throw new RateLimitError("Too many failed attempts — try again shortly", {
|
|
13229
|
+
retryAfterSeconds: Math.ceil((retryAt - Date.now()) / 1000)
|
|
13230
|
+
});
|
|
13231
|
+
}
|
|
13232
|
+
}
|
|
13233
|
+
const valid = await this.deps.verifyPassword({
|
|
13234
|
+
hash: dashboardUser.passwordHash,
|
|
13235
|
+
password: input.password
|
|
13236
|
+
});
|
|
13237
|
+
if (!valid) {
|
|
13238
|
+
await this.deps.db.update(gameDashboardUsers).set({
|
|
13239
|
+
failedLoginAttempts: sql`${gameDashboardUsers.failedLoginAttempts} + 1`,
|
|
13240
|
+
lastFailedLoginAt: new Date
|
|
13241
|
+
}).where(eq(gameDashboardUsers.id, dashboardUser.id));
|
|
13242
|
+
throw new UnauthorizedError("Invalid credentials");
|
|
13243
|
+
}
|
|
13244
|
+
if (dashboardUser.failedLoginAttempts > 0) {
|
|
13245
|
+
await this.deps.db.update(gameDashboardUsers).set({ failedLoginAttempts: 0, lastFailedLoginAt: null }).where(eq(gameDashboardUsers.id, dashboardUser.id));
|
|
13246
|
+
}
|
|
13247
|
+
return DashboardService.toSummary(dashboardUser);
|
|
13248
|
+
}
|
|
13249
|
+
async acceptInvite(slug, input) {
|
|
13250
|
+
const game2 = await this.getGameForRuntime(slug);
|
|
13251
|
+
setAttributes({ "app.dashboard.operation": "accept_invite" });
|
|
13252
|
+
const tokenHash = await hashDashboardToken(input.token);
|
|
13253
|
+
const invited = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13254
|
+
where: and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.inviteTokenHash, tokenHash))
|
|
13255
|
+
});
|
|
13256
|
+
if (!invited) {
|
|
13257
|
+
throw new UnauthorizedError("Invalid or already-used invite token");
|
|
13258
|
+
}
|
|
13259
|
+
if (invited.inviteExpiresAt && invited.inviteExpiresAt.getTime() < Date.now()) {
|
|
13260
|
+
throw new UnauthorizedError("This invite has expired — ask for a new one");
|
|
13261
|
+
}
|
|
13262
|
+
const passwordHash = await this.deps.hashPassword(input.password);
|
|
13263
|
+
const [updated] = await this.deps.db.update(gameDashboardUsers).set({
|
|
13264
|
+
passwordHash,
|
|
13265
|
+
inviteTokenHash: null,
|
|
13266
|
+
inviteExpiresAt: null,
|
|
13267
|
+
updatedAt: new Date
|
|
13268
|
+
}).where(and(eq(gameDashboardUsers.id, invited.id), eq(gameDashboardUsers.inviteTokenHash, tokenHash), isNull(gameDashboardUsers.passwordHash))).returning();
|
|
13269
|
+
if (!updated) {
|
|
13270
|
+
throw new UnauthorizedError("Invalid or already-used invite token");
|
|
13271
|
+
}
|
|
13272
|
+
return DashboardService.toSummary(updated);
|
|
13273
|
+
}
|
|
13274
|
+
async acceptReset(slug, input) {
|
|
13275
|
+
const game2 = await this.getGameForRuntime(slug);
|
|
13276
|
+
setAttributes({ "app.dashboard.operation": "accept_reset" });
|
|
13277
|
+
const tokenHash = await hashDashboardToken(input.token);
|
|
13278
|
+
const found = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13279
|
+
where: and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.resetTokenHash, tokenHash))
|
|
13280
|
+
});
|
|
13281
|
+
if (!found) {
|
|
13282
|
+
throw new UnauthorizedError("Invalid or already-used reset token");
|
|
13283
|
+
}
|
|
13284
|
+
if (found.resetExpiresAt && found.resetExpiresAt.getTime() < Date.now()) {
|
|
13285
|
+
throw new UnauthorizedError("This reset link has expired — ask for a new one");
|
|
13286
|
+
}
|
|
13287
|
+
const passwordHash = await this.deps.hashPassword(input.password);
|
|
13288
|
+
const [updated] = await this.deps.db.update(gameDashboardUsers).set({
|
|
13289
|
+
passwordHash,
|
|
13290
|
+
resetTokenHash: null,
|
|
13291
|
+
resetExpiresAt: null,
|
|
13292
|
+
inviteTokenHash: null,
|
|
13293
|
+
inviteExpiresAt: null,
|
|
13294
|
+
failedLoginAttempts: 0,
|
|
13295
|
+
lastFailedLoginAt: null,
|
|
13296
|
+
updatedAt: new Date
|
|
13297
|
+
}).where(and(eq(gameDashboardUsers.id, found.id), eq(gameDashboardUsers.resetTokenHash, tokenHash))).returning();
|
|
13298
|
+
if (!updated) {
|
|
13299
|
+
throw new UnauthorizedError("Invalid or already-used reset token");
|
|
13300
|
+
}
|
|
13301
|
+
return DashboardService.toSummary(updated);
|
|
13302
|
+
}
|
|
13303
|
+
async issueRecoveryLink(slug, user, dashboardUserId) {
|
|
13304
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
13305
|
+
const existing = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13306
|
+
where: and(eq(gameDashboardUsers.gameId, game2.id), eq(gameDashboardUsers.id, dashboardUserId))
|
|
13307
|
+
});
|
|
13308
|
+
if (!existing) {
|
|
13309
|
+
throw new NotFoundError("Dashboard user", dashboardUserId);
|
|
13310
|
+
}
|
|
13311
|
+
const kind = existing.passwordHash ? "reset" : "invite";
|
|
13312
|
+
setAttributes({
|
|
13313
|
+
"app.dashboard.operation": "issue_recovery_link",
|
|
13314
|
+
"app.dashboard.recovery_kind": kind
|
|
13315
|
+
});
|
|
13316
|
+
const token = await generateSecureRandomString(DashboardService.INVITE_TOKEN_LENGTH);
|
|
13317
|
+
const tokenHash = await hashDashboardToken(token);
|
|
13318
|
+
const fields = kind === "invite" ? {
|
|
13319
|
+
inviteTokenHash: tokenHash,
|
|
13320
|
+
inviteExpiresAt: new Date(Date.now() + DashboardService.INVITE_TTL_MS)
|
|
13321
|
+
} : {
|
|
13322
|
+
resetTokenHash: tokenHash,
|
|
13323
|
+
resetExpiresAt: new Date(Date.now() + DashboardService.RESET_TTL_MS)
|
|
13324
|
+
};
|
|
13325
|
+
const [updated] = await this.deps.db.update(gameDashboardUsers).set({ ...fields, updatedAt: new Date }).where(eq(gameDashboardUsers.id, existing.id)).returning();
|
|
13326
|
+
if (!updated) {
|
|
13327
|
+
throw new NotFoundError("Dashboard user", dashboardUserId);
|
|
13328
|
+
}
|
|
13329
|
+
return { user: DashboardService.toSummary(updated), token, kind };
|
|
13330
|
+
}
|
|
13331
|
+
async getGameForRuntime(slug) {
|
|
13332
|
+
const game2 = await this.deps.db.query.games.findFirst({
|
|
13333
|
+
where: eq(games.slug, slug),
|
|
13334
|
+
columns: { id: true }
|
|
13335
|
+
});
|
|
13336
|
+
if (!game2) {
|
|
13337
|
+
throw new NotFoundError("Game", slug);
|
|
13338
|
+
}
|
|
13339
|
+
return game2;
|
|
13340
|
+
}
|
|
13341
|
+
async findByEmail(gameId, email) {
|
|
13342
|
+
const row = await this.deps.db.query.gameDashboardUsers.findFirst({
|
|
13343
|
+
where: and(eq(gameDashboardUsers.gameId, gameId), eq(gameDashboardUsers.email, email))
|
|
13344
|
+
});
|
|
13345
|
+
return row ?? null;
|
|
13346
|
+
}
|
|
13347
|
+
static toSummary(row) {
|
|
13348
|
+
return {
|
|
13349
|
+
id: row.id,
|
|
13350
|
+
gameId: row.gameId,
|
|
13351
|
+
email: row.email,
|
|
13352
|
+
displayName: row.displayName,
|
|
13353
|
+
role: row.role,
|
|
13354
|
+
platformUserId: row.platformUserId,
|
|
13355
|
+
createdAt: row.createdAt,
|
|
13356
|
+
updatedAt: row.updatedAt,
|
|
13357
|
+
pending: !row.passwordHash
|
|
13358
|
+
};
|
|
13359
|
+
}
|
|
13360
|
+
};
|
|
13361
|
+
});
|
|
13362
|
+
|
|
13363
|
+
// ../data/src/domains/game/helpers.ts
|
|
13364
|
+
function activeDeploymentWhere(gameId, target = "game") {
|
|
13365
|
+
return and(eq(gameDeployments.gameId, gameId), eq(gameDeployments.target, target), eq(gameDeployments.isActive, true));
|
|
13366
|
+
}
|
|
13367
|
+
var init_helpers = __esm(() => {
|
|
13368
|
+
init_drizzle_orm();
|
|
13369
|
+
init_table5();
|
|
13370
|
+
});
|
|
13371
|
+
|
|
13372
|
+
// ../data/src/domains/timeback/helpers.ts
|
|
13373
|
+
function isActiveGameTimebackIntegrationStatus(statusColumn = gameTimebackIntegrations.status) {
|
|
13374
|
+
return sql`${statusColumn} IS DISTINCT FROM ${DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS}`;
|
|
13375
|
+
}
|
|
13376
|
+
var ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS = "active", DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS = "deactivated";
|
|
13377
|
+
var init_helpers2 = __esm(() => {
|
|
13378
|
+
init_drizzle_orm();
|
|
13379
|
+
init_table7();
|
|
13380
|
+
});
|
|
13381
|
+
|
|
13382
|
+
// ../data/src/helpers.index.ts
|
|
13383
|
+
var init_helpers_index = __esm(() => {
|
|
13384
|
+
init_helpers();
|
|
13385
|
+
init_helpers2();
|
|
13386
|
+
});
|
|
13387
|
+
|
|
13009
13388
|
// ../../node_modules/.bun/process-nextick-args@2.0.1/node_modules/process-nextick-args/index.js
|
|
13010
13389
|
var require_process_nextick_args = __commonJS((exports, module2) => {
|
|
13011
13390
|
if (typeof process === "undefined" || !process.version || process.version.indexOf("v0.") === 0 || process.version.indexOf("v1.") === 0 && process.version.indexOf("v1.8.") !== 0) {
|
|
@@ -22086,8 +22465,8 @@ var require_lib3 = __commonJS((exports, module2) => {
|
|
|
22086
22465
|
});
|
|
22087
22466
|
|
|
22088
22467
|
// ../utils/src/zip.ts
|
|
22089
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
22090
|
-
import { join as join2 } from "path";
|
|
22468
|
+
import { mkdir, readdir, readFile, writeFile } from "fs/promises";
|
|
22469
|
+
import { join as join2, relative, sep } from "path";
|
|
22091
22470
|
async function extractZipToDirectory(zipBuffer, targetDir) {
|
|
22092
22471
|
try {
|
|
22093
22472
|
const zip = await import_jszip.default.loadAsync(zipBuffer);
|
|
@@ -22113,9 +22492,10 @@ async function extractZipToDirectory(zipBuffer, targetDir) {
|
|
|
22113
22492
|
fileCount: Object.keys(zip.files).length
|
|
22114
22493
|
});
|
|
22115
22494
|
} catch (error) {
|
|
22116
|
-
const errorMessage2 = error instanceof Error ? error.message : String(error);
|
|
22117
22495
|
log.error("[utils/zip] Failed to extract ZIP", { targetDir, error });
|
|
22118
|
-
throw new Error(`Failed to extract ZIP to ${targetDir}: ${
|
|
22496
|
+
throw new Error(`Failed to extract ZIP to ${targetDir}: ${errorMessage(error)}`, {
|
|
22497
|
+
cause: error
|
|
22498
|
+
});
|
|
22119
22499
|
}
|
|
22120
22500
|
}
|
|
22121
22501
|
var import_jszip;
|
|
@@ -22385,6 +22765,7 @@ class DeployJobService {
|
|
|
22385
22765
|
jobId,
|
|
22386
22766
|
leaseId,
|
|
22387
22767
|
leaseLost,
|
|
22768
|
+
target,
|
|
22388
22769
|
game: game2,
|
|
22389
22770
|
user,
|
|
22390
22771
|
error
|
|
@@ -22414,9 +22795,12 @@ class DeployJobService {
|
|
|
22414
22795
|
}
|
|
22415
22796
|
}
|
|
22416
22797
|
if (!effectiveLeaseLost) {
|
|
22417
|
-
await this.deps.notifyDeploymentFailure(
|
|
22418
|
-
|
|
22419
|
-
|
|
22798
|
+
await this.deps.notifyDeploymentFailure({
|
|
22799
|
+
slug: game2.slug,
|
|
22800
|
+
displayName: game2.displayName,
|
|
22801
|
+
error: message,
|
|
22802
|
+
target,
|
|
22803
|
+
developer: { id: user.id, email: user.email }
|
|
22420
22804
|
});
|
|
22421
22805
|
}
|
|
22422
22806
|
await this.deleteCodeBundle(jobId);
|
|
@@ -22518,7 +22902,7 @@ class DeployJobService {
|
|
|
22518
22902
|
}
|
|
22519
22903
|
assertLease();
|
|
22520
22904
|
const activeDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
22521
|
-
where:
|
|
22905
|
+
where: activeDeploymentWhere(job.gameId, request.target ?? "game"),
|
|
22522
22906
|
columns: {
|
|
22523
22907
|
deploymentId: true,
|
|
22524
22908
|
url: true
|
|
@@ -22541,7 +22925,15 @@ class DeployJobService {
|
|
|
22541
22925
|
} catch (error) {
|
|
22542
22926
|
clearInterval(heartbeat);
|
|
22543
22927
|
setAttribute("app.deploy_job.run_duration_ms", DeployJobService.elapsedMsSince(new Date(runStartedAt)));
|
|
22544
|
-
await this.handleRunError({
|
|
22928
|
+
await this.handleRunError({
|
|
22929
|
+
jobId,
|
|
22930
|
+
leaseId,
|
|
22931
|
+
leaseLost,
|
|
22932
|
+
target: request.target ?? "game",
|
|
22933
|
+
game: game2,
|
|
22934
|
+
user,
|
|
22935
|
+
error
|
|
22936
|
+
});
|
|
22545
22937
|
throw error;
|
|
22546
22938
|
}
|
|
22547
22939
|
}
|
|
@@ -22560,6 +22952,7 @@ async function forceMarkDeployJobFailed(db2, jobId, error) {
|
|
|
22560
22952
|
var STATUS_MAP2, DEPLOY_JOB_LEASE_MS, DEPLOY_JOB_HEARTBEAT_MS, DEPLOY_JOB_CODE_BUNDLE_PREFIX = "deploy-job-code";
|
|
22561
22953
|
var init_deploy_job_service = __esm(() => {
|
|
22562
22954
|
init_drizzle_orm();
|
|
22955
|
+
init_helpers_index();
|
|
22563
22956
|
init_tables_index();
|
|
22564
22957
|
init_spans();
|
|
22565
22958
|
init_zip();
|
|
@@ -24703,7 +25096,7 @@ var init_bindings = __esm(() => {
|
|
|
24703
25096
|
});
|
|
24704
25097
|
|
|
24705
25098
|
// ../cloudflare/src/playcademy/provider/helpers.ts
|
|
24706
|
-
var
|
|
25099
|
+
var init_helpers3 = __esm(() => {
|
|
24707
25100
|
init_mime();
|
|
24708
25101
|
});
|
|
24709
25102
|
|
|
@@ -24715,7 +25108,7 @@ var init_provider = __esm(() => {
|
|
|
24715
25108
|
init_constants2();
|
|
24716
25109
|
init_assets_config();
|
|
24717
25110
|
init_bindings();
|
|
24718
|
-
|
|
25111
|
+
init_helpers3();
|
|
24719
25112
|
});
|
|
24720
25113
|
// ../cloudflare/src/playcademy/provider/index.ts
|
|
24721
25114
|
var init_provider2 = __esm(() => {
|
|
@@ -27134,26 +27527,70 @@ var init_playcademy = __esm(() => {
|
|
|
27134
27527
|
});
|
|
27135
27528
|
|
|
27136
27529
|
// ../utils/src/tunnel.ts
|
|
27137
|
-
|
|
27138
|
-
|
|
27530
|
+
function servicePort(service) {
|
|
27531
|
+
if (!service) {
|
|
27532
|
+
return null;
|
|
27533
|
+
}
|
|
27139
27534
|
try {
|
|
27140
|
-
|
|
27535
|
+
const url = new URL(service);
|
|
27536
|
+
return url.port || (url.protocol === "https:" ? "443" : "80");
|
|
27141
27537
|
} catch {
|
|
27142
|
-
|
|
27538
|
+
return null;
|
|
27143
27539
|
}
|
|
27144
|
-
|
|
27145
|
-
|
|
27540
|
+
}
|
|
27541
|
+
async function readTunnelIngress(port) {
|
|
27542
|
+
try {
|
|
27543
|
+
const response = await fetch(`http://127.0.0.1:${port}/config`, {
|
|
27544
|
+
signal: AbortSignal.timeout(1000)
|
|
27545
|
+
});
|
|
27546
|
+
if (!response.ok) {
|
|
27547
|
+
return null;
|
|
27548
|
+
}
|
|
27549
|
+
const data = await response.json();
|
|
27550
|
+
return data.config?.ingress ?? [];
|
|
27551
|
+
} catch {
|
|
27552
|
+
return null;
|
|
27553
|
+
}
|
|
27554
|
+
}
|
|
27555
|
+
function matchingHostname(rules, expectedPort) {
|
|
27556
|
+
for (const rule of rules ?? []) {
|
|
27557
|
+
if (rule.hostname && servicePort(rule.service) === expectedPort) {
|
|
27558
|
+
return rule.hostname;
|
|
27559
|
+
}
|
|
27560
|
+
}
|
|
27561
|
+
return null;
|
|
27562
|
+
}
|
|
27563
|
+
async function getTunnelUrl(platformBaseUrl) {
|
|
27564
|
+
const expectedPort = servicePort(platformBaseUrl);
|
|
27565
|
+
if (!expectedPort) {
|
|
27566
|
+
throw new Error(`Cannot resolve a tunnel for unparseable platform URL '${platformBaseUrl}'`);
|
|
27567
|
+
}
|
|
27568
|
+
const cachedPort = matchedPorts.get(expectedPort);
|
|
27569
|
+
if (cachedPort !== undefined) {
|
|
27570
|
+
const hostname = matchingHostname(await readTunnelIngress(cachedPort), expectedPort);
|
|
27571
|
+
if (hostname) {
|
|
27572
|
+
return `https://${hostname}`;
|
|
27573
|
+
}
|
|
27574
|
+
matchedPorts.delete(expectedPort);
|
|
27575
|
+
}
|
|
27576
|
+
const ports = Array.from({ length: TUNNEL_METRICS_PORT_RANGE }, (_, offset) => TUNNEL_METRICS_PORT + offset);
|
|
27577
|
+
const results = await Promise.all(ports.map(async (port) => ({ port, rules: await readTunnelIngress(port) })));
|
|
27578
|
+
for (const { port, rules } of results) {
|
|
27579
|
+
const hostname = matchingHostname(rules, expectedPort);
|
|
27580
|
+
if (hostname) {
|
|
27581
|
+
matchedPorts.set(expectedPort, port);
|
|
27582
|
+
return `https://${hostname}`;
|
|
27583
|
+
}
|
|
27146
27584
|
}
|
|
27147
|
-
const
|
|
27148
|
-
|
|
27149
|
-
|
|
27150
|
-
throw new Error("Tunnel is running but no hostname found in ingress config");
|
|
27585
|
+
const foreign = results.flatMap(({ rules }) => (rules ?? []).filter((rule) => rule.hostname).map((rule) => `${rule.hostname} -> ${rule.service}`));
|
|
27586
|
+
if (foreign.length > 0) {
|
|
27587
|
+
throw new Error(`A local tunnel is running, but none route to the platform at ${platformBaseUrl} (found: ${foreign.join(", ")}). ${TUNNEL_START_HINT}`);
|
|
27151
27588
|
}
|
|
27152
|
-
|
|
27589
|
+
throw new Error(`Local tunnel is not running. ${TUNNEL_START_HINT}`);
|
|
27153
27590
|
}
|
|
27154
|
-
var TUNNEL_METRICS_PORT = 20241,
|
|
27591
|
+
var TUNNEL_METRICS_PORT = 20241, TUNNEL_METRICS_PORT_RANGE = 10, TUNNEL_START_HINT = "Start this platform's tunnel with `bun dev` or `bun run tunnel`.", matchedPorts;
|
|
27155
27592
|
var init_tunnel = __esm(() => {
|
|
27156
|
-
|
|
27593
|
+
matchedPorts = new Map;
|
|
27157
27594
|
});
|
|
27158
27595
|
|
|
27159
27596
|
// ../utils/src/stages.ts
|
|
@@ -27166,7 +27603,7 @@ var init_stages = __esm(() => {
|
|
|
27166
27603
|
});
|
|
27167
27604
|
|
|
27168
27605
|
// ../api-core/src/utils/deployment.util.ts
|
|
27169
|
-
function
|
|
27606
|
+
function getGameDeploymentId(gameSlug, sstStage) {
|
|
27170
27607
|
if (sstStage === "production") {
|
|
27171
27608
|
return gameSlug;
|
|
27172
27609
|
}
|
|
@@ -27175,45 +27612,57 @@ function getDeploymentId(gameSlug, sstStage) {
|
|
|
27175
27612
|
}
|
|
27176
27613
|
return `${WORKER_NAMING.LOCAL_PREFIX}${sstStage}-${gameSlug}`;
|
|
27177
27614
|
}
|
|
27615
|
+
function getDashboardDeploymentId(gameSlug, sstStage) {
|
|
27616
|
+
return `${getGameDeploymentId(gameSlug, sstStage)}${DASHBOARD_WORKER_SUFFIX}`;
|
|
27617
|
+
}
|
|
27178
27618
|
function getGameWorkerApiKeyName(slug) {
|
|
27179
|
-
return
|
|
27619
|
+
return `${GAME_WORKER_KEY_PREFIX}${slug}`.substring(0, 32);
|
|
27620
|
+
}
|
|
27621
|
+
function getDashboardWorkerApiKeyName(slug) {
|
|
27622
|
+
return `${DASHBOARD_WORKER_KEY_PREFIX}${slug}`;
|
|
27180
27623
|
}
|
|
27181
27624
|
function toBindingName(queueKey) {
|
|
27182
27625
|
return `${queueKey.replace(/-/g, "_").toUpperCase()}_QUEUE`;
|
|
27183
27626
|
}
|
|
27184
|
-
|
|
27185
|
-
|
|
27186
|
-
const data = encoder.encode(code);
|
|
27187
|
-
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
27188
|
-
const hashArray = [...new Uint8Array(hashBuffer)];
|
|
27189
|
-
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
27627
|
+
function generateDeploymentHash(code) {
|
|
27628
|
+
return sha256Hex(code);
|
|
27190
27629
|
}
|
|
27630
|
+
var GAME_WORKER_KEY_PREFIX = "game-worker-", DASHBOARD_WORKER_KEY_PREFIX = "dash-worker-";
|
|
27191
27631
|
var init_deployment_util = __esm(() => {
|
|
27192
27632
|
init_src();
|
|
27193
27633
|
init_stages();
|
|
27194
27634
|
});
|
|
27195
27635
|
|
|
27636
|
+
// ../api-core/src/utils/worker-keys.util.ts
|
|
27637
|
+
async function sweepDashboardWorkerKeys(deleteApiKeysByName, slug) {
|
|
27638
|
+
try {
|
|
27639
|
+
await deleteApiKeysByName(getDashboardWorkerApiKeyName(slug));
|
|
27640
|
+
} catch (error) {
|
|
27641
|
+
addEvent("dashboard.worker_key_sweep_failed", {
|
|
27642
|
+
"exception.type": errorType(error),
|
|
27643
|
+
"app.error.message": errorMessage(error)
|
|
27644
|
+
});
|
|
27645
|
+
}
|
|
27646
|
+
}
|
|
27647
|
+
var init_worker_keys_util = __esm(() => {
|
|
27648
|
+
init_spans();
|
|
27649
|
+
init_deployment_util();
|
|
27650
|
+
});
|
|
27651
|
+
|
|
27196
27652
|
// ../api-core/src/services/deploy.service.ts
|
|
27653
|
+
function readDashboardTheme(config2) {
|
|
27654
|
+
const theme = config2?.dashboard?.theme;
|
|
27655
|
+
return {
|
|
27656
|
+
...typeof theme?.primary === "string" && { primary: theme.primary },
|
|
27657
|
+
...typeof theme?.secondary === "string" && { secondary: theme.secondary }
|
|
27658
|
+
};
|
|
27659
|
+
}
|
|
27660
|
+
|
|
27197
27661
|
class DeployService {
|
|
27198
27662
|
deps;
|
|
27199
27663
|
constructor(deps) {
|
|
27200
27664
|
this.deps = deps;
|
|
27201
27665
|
}
|
|
27202
|
-
static classifyDeployType(flags2) {
|
|
27203
|
-
if (flags2.hasBackend && flags2.hasFrontend) {
|
|
27204
|
-
return "full_stack";
|
|
27205
|
-
}
|
|
27206
|
-
if (flags2.hasFrontend) {
|
|
27207
|
-
return "frontend_only";
|
|
27208
|
-
}
|
|
27209
|
-
if (flags2.hasBackend) {
|
|
27210
|
-
return "backend_only";
|
|
27211
|
-
}
|
|
27212
|
-
return "metadata_only";
|
|
27213
|
-
}
|
|
27214
|
-
static countDeadLetterQueues(bindings) {
|
|
27215
|
-
return bindings?.queues?.filter((queue) => Boolean(queue.deadLetterQueue)).length ?? 0;
|
|
27216
|
-
}
|
|
27217
27666
|
getCloudflare() {
|
|
27218
27667
|
const cf = this.deps.cloudflare;
|
|
27219
27668
|
if (!cf) {
|
|
@@ -27221,86 +27670,307 @@ class DeployService {
|
|
|
27221
27670
|
}
|
|
27222
27671
|
return cf;
|
|
27223
27672
|
}
|
|
27224
|
-
async
|
|
27225
|
-
const
|
|
27226
|
-
|
|
27227
|
-
|
|
27228
|
-
|
|
27229
|
-
|
|
27230
|
-
|
|
27231
|
-
}
|
|
27232
|
-
|
|
27233
|
-
|
|
27234
|
-
|
|
27235
|
-
|
|
27236
|
-
|
|
27237
|
-
|
|
27238
|
-
if (existingKeyId) {
|
|
27239
|
-
setAttribute("app.deploy.api_key_outcome", "regenerated");
|
|
27240
|
-
try {
|
|
27241
|
-
await this.deps.deleteAuthApiKey(existingKeyId);
|
|
27242
|
-
} catch (error) {
|
|
27243
|
-
addEvent("deploy.api_key_revoke_failed", {
|
|
27244
|
-
"exception.type": errorType(error),
|
|
27245
|
-
"app.error.message": errorMessage(error),
|
|
27246
|
-
"app.deploy.old_key_id": existingKeyId
|
|
27247
|
-
});
|
|
27673
|
+
async* deploy(slug, request, user, uploadDeps, extractZip) {
|
|
27674
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
27675
|
+
const context2 = { slug, request, user, game: game2, uploadDeps, extractZip };
|
|
27676
|
+
switch (request.target ?? "game") {
|
|
27677
|
+
case "dashboard": {
|
|
27678
|
+
yield* this.deployDashboard(context2);
|
|
27679
|
+
break;
|
|
27680
|
+
}
|
|
27681
|
+
case "game": {
|
|
27682
|
+
yield* this.deployGame(context2);
|
|
27683
|
+
break;
|
|
27684
|
+
}
|
|
27685
|
+
default: {
|
|
27686
|
+
throw new ValidationError("Invalid deployment target");
|
|
27248
27687
|
}
|
|
27249
27688
|
}
|
|
27250
|
-
return this.createApiKey(user, slug, keyName);
|
|
27251
27689
|
}
|
|
27252
|
-
async
|
|
27690
|
+
async* deployGame(context2) {
|
|
27691
|
+
const { slug, request, user, game: game2, uploadDeps, extractZip } = context2;
|
|
27253
27692
|
const cf = this.getCloudflare();
|
|
27254
|
-
const
|
|
27255
|
-
const
|
|
27256
|
-
|
|
27693
|
+
const db2 = this.deps.db;
|
|
27694
|
+
const flags2 = this.validateGameRequest(request);
|
|
27695
|
+
const { hasBackend, hasFrontend } = flags2;
|
|
27696
|
+
const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
27697
|
+
let frontendAssetsPath;
|
|
27698
|
+
let tempDir;
|
|
27699
|
+
if (hasFrontend) {
|
|
27700
|
+
if (!uploadDeps || !extractZip) {
|
|
27701
|
+
throw new ValidationError("Upload dependencies not configured for frontend deployment");
|
|
27702
|
+
}
|
|
27703
|
+
yield { type: "status", data: { message: "Fetching temporary files" } };
|
|
27704
|
+
const extracted = await this.fetchAndExtractFrontendAssets(slug, game2.id, request.uploadToken, uploadDeps, extractZip);
|
|
27705
|
+
tempDir = extracted.tempDir;
|
|
27706
|
+
frontendAssetsPath = extracted.assetsPath;
|
|
27707
|
+
yield { type: "status", data: { message: "Extracting assets" } };
|
|
27708
|
+
}
|
|
27709
|
+
const platformBaseUrl = await this.resolvePlatformBaseUrl();
|
|
27710
|
+
const env = {
|
|
27711
|
+
GAME_ID: game2.id,
|
|
27712
|
+
PLAYCADEMY_BASE_URL: platformBaseUrl,
|
|
27713
|
+
PLAYCADEMY_PLATFORM_SERVICE_JWKS: this.deps.config.platformServiceJwt?.publicJwks
|
|
27714
|
+
};
|
|
27715
|
+
yield {
|
|
27716
|
+
type: "status",
|
|
27717
|
+
data: { message: hasBackend ? "Deploying backend code" : "Deploying to platform" }
|
|
27718
|
+
};
|
|
27719
|
+
const keepAssets = hasBackend && !hasFrontend;
|
|
27720
|
+
const deploymentOptions = this.mapGameBindingsToOptions(deploymentId, request.bindings, request.schema);
|
|
27721
|
+
const bindings = deploymentOptions?.bindings;
|
|
27722
|
+
setAttributes({
|
|
27723
|
+
"app.deploy.has_d1": Boolean(bindings?.d1?.length),
|
|
27724
|
+
"app.deploy.has_kv": Boolean(bindings?.kv?.length),
|
|
27725
|
+
"app.deploy.has_r2": Boolean(bindings?.r2?.length),
|
|
27726
|
+
"app.deploy.queue_count": bindings?.queues?.length ?? 0,
|
|
27727
|
+
"app.deploy.dead_letter_queue_count": DeployService.countDeadLetterQueues(bindings)
|
|
27728
|
+
});
|
|
27729
|
+
const activeDeployment = await db2.query.gameDeployments.findFirst({
|
|
27730
|
+
where: activeDeploymentWhere(game2.id, "game"),
|
|
27731
|
+
columns: { resources: true }
|
|
27732
|
+
});
|
|
27733
|
+
if (deploymentOptions?.bindings?.d1?.length) {
|
|
27734
|
+
await this.cleanupOrphanD1Databases(cf, deploymentOptions.bindings.d1, slug, game2.id);
|
|
27735
|
+
}
|
|
27736
|
+
const result = await this.deployToCloudflare({
|
|
27737
|
+
deploymentId,
|
|
27738
|
+
code: request.code,
|
|
27739
|
+
env,
|
|
27740
|
+
tempDir,
|
|
27741
|
+
options: {
|
|
27742
|
+
...deploymentOptions,
|
|
27743
|
+
compatibilityDate: request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27744
|
+
compatibilityFlags: request.compatibilityFlags,
|
|
27745
|
+
existingResources: activeDeployment?.resources ?? undefined,
|
|
27746
|
+
assetsPath: frontendAssetsPath,
|
|
27747
|
+
keepAssets
|
|
27748
|
+
}
|
|
27749
|
+
});
|
|
27750
|
+
yield { type: "status", data: { message: "Finalizing deployment" } };
|
|
27751
|
+
const updatedGame = await this.finalizeGameDeployment({
|
|
27752
|
+
game: game2,
|
|
27753
|
+
slug,
|
|
27754
|
+
deploymentId,
|
|
27755
|
+
result,
|
|
27756
|
+
request,
|
|
27757
|
+
user,
|
|
27758
|
+
flags: flags2
|
|
27759
|
+
});
|
|
27760
|
+
yield { type: "complete", data: updatedGame };
|
|
27761
|
+
}
|
|
27762
|
+
async* deployDashboard(context2) {
|
|
27763
|
+
const { slug, request, user, game: game2 } = context2;
|
|
27764
|
+
const db2 = this.deps.db;
|
|
27765
|
+
const contract = this.validateDashboardRequest(request, context2.uploadDeps, context2.extractZip);
|
|
27766
|
+
const deploymentId = getDashboardDeploymentId(slug, this.deps.config.sstStage);
|
|
27767
|
+
if (deploymentId.length > MAX_WORKER_NAME_LENGTH) {
|
|
27768
|
+
throw new ValidationError(`Dashboard worker name '${deploymentId}' exceeds Cloudflare's ${MAX_WORKER_NAME_LENGTH}-character limit — shorten the game slug`);
|
|
27769
|
+
}
|
|
27770
|
+
const collidingGame = await db2.query.games.findFirst({
|
|
27771
|
+
where: eq(games.slug, `${slug}${DASHBOARD_WORKER_SUFFIX}`),
|
|
27257
27772
|
columns: { id: true }
|
|
27258
27773
|
});
|
|
27259
|
-
|
|
27260
|
-
|
|
27261
|
-
|
|
27262
|
-
|
|
27263
|
-
|
|
27264
|
-
|
|
27265
|
-
|
|
27266
|
-
|
|
27267
|
-
|
|
27268
|
-
|
|
27269
|
-
|
|
27270
|
-
|
|
27271
|
-
|
|
27272
|
-
|
|
27273
|
-
|
|
27774
|
+
if (collidingGame) {
|
|
27775
|
+
throw new ValidationError(`Cannot deploy this dashboard: an existing game's slug is '${slug}${DASHBOARD_WORKER_SUFFIX}', which owns the '${deploymentId}' worker name`);
|
|
27776
|
+
}
|
|
27777
|
+
const gameDeployment = await db2.query.gameDeployments.findFirst({
|
|
27778
|
+
where: activeDeploymentWhere(game2.id, "game"),
|
|
27779
|
+
columns: { resources: true }
|
|
27780
|
+
});
|
|
27781
|
+
if (!gameDeployment) {
|
|
27782
|
+
throw new ValidationError("Deploy the game before its dashboard — the dashboard attaches to the game deployment");
|
|
27783
|
+
}
|
|
27784
|
+
setAttributes({
|
|
27785
|
+
"app.deploy.type": "dashboard",
|
|
27786
|
+
"app.deploy.deployment_id": deploymentId,
|
|
27787
|
+
"app.deploy.code_size": contract.code.length,
|
|
27788
|
+
"app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27789
|
+
"app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0
|
|
27790
|
+
});
|
|
27791
|
+
yield { type: "status", data: { message: "Fetching temporary files" } };
|
|
27792
|
+
const [{ tempDir, assetsPath }, platformBaseUrl, dashboardActive] = await Promise.all([
|
|
27793
|
+
this.fetchAndExtractFrontendAssets(slug, game2.id, contract.uploadToken, contract.uploadDeps, contract.extractZip),
|
|
27794
|
+
this.resolvePlatformBaseUrl(),
|
|
27795
|
+
db2.query.gameDeployments.findFirst({
|
|
27796
|
+
where: activeDeploymentWhere(game2.id, "dashboard"),
|
|
27797
|
+
columns: { resources: true }
|
|
27798
|
+
})
|
|
27799
|
+
]);
|
|
27800
|
+
yield { type: "status", data: { message: "Extracting assets" } };
|
|
27801
|
+
const theme = readDashboardTheme(request.config);
|
|
27802
|
+
const env = {
|
|
27803
|
+
GAME_ID: game2.id,
|
|
27804
|
+
GAME_SLUG: slug,
|
|
27805
|
+
GAME_NAME: game2.displayName,
|
|
27806
|
+
...game2.metadata?.emoji && { GAME_EMOJI: game2.metadata.emoji },
|
|
27807
|
+
...theme.primary && { DASHBOARD_THEME_PRIMARY: theme.primary },
|
|
27808
|
+
...theme.secondary && { DASHBOARD_THEME_SECONDARY: theme.secondary },
|
|
27809
|
+
PLAYCADEMY_BASE_URL: platformBaseUrl,
|
|
27810
|
+
PLAYCADEMY_PLATFORM_SERVICE_JWKS: this.deps.config.platformServiceJwt?.publicJwks
|
|
27811
|
+
};
|
|
27812
|
+
const gameResources = gameDeployment.resources;
|
|
27813
|
+
const bindings = {
|
|
27814
|
+
d1: gameResources?.d1?.map((database) => database.name) ?? [],
|
|
27815
|
+
kv: gameResources?.kv?.map((namespace) => namespace.name) ?? [],
|
|
27816
|
+
r2: gameResources?.r2?.filter((bucket) => bucket.kind !== "assets").map((bucket) => bucket.name) ?? []
|
|
27817
|
+
};
|
|
27818
|
+
const existingResources = {
|
|
27819
|
+
...dashboardActive?.resources,
|
|
27820
|
+
d1: gameResources?.d1,
|
|
27821
|
+
kv: gameResources?.kv,
|
|
27822
|
+
r2: gameResources?.r2
|
|
27823
|
+
};
|
|
27824
|
+
yield { type: "status", data: { message: "Deploying dashboard" } };
|
|
27825
|
+
const result = await this.deployToCloudflare({
|
|
27826
|
+
deploymentId,
|
|
27827
|
+
code: contract.code,
|
|
27828
|
+
env,
|
|
27829
|
+
tempDir,
|
|
27830
|
+
options: {
|
|
27831
|
+
bindings,
|
|
27832
|
+
compatibilityDate: request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27833
|
+
compatibilityFlags: request.compatibilityFlags,
|
|
27834
|
+
existingResources,
|
|
27835
|
+
assetsPath,
|
|
27836
|
+
keepAssets: false,
|
|
27837
|
+
assetsConfig: { run_worker_first: true }
|
|
27274
27838
|
}
|
|
27275
|
-
|
|
27839
|
+
});
|
|
27840
|
+
yield { type: "status", data: { message: "Finalizing deployment" } };
|
|
27841
|
+
await withSpan("deploy.configure_worker_secrets", async () => {
|
|
27842
|
+
const existingSecrets = await this.listWorkerSecretNames(result.deploymentId);
|
|
27843
|
+
await this.ensureWorkerApiKeyOnWorker(user, DeployService.dashboardWorkerKeySpec(slug), result.deploymentId, existingSecrets);
|
|
27844
|
+
await this.ensureDashboardSessionSecret(result.deploymentId, existingSecrets, Boolean(dashboardActive));
|
|
27845
|
+
});
|
|
27846
|
+
const codeHash = await generateDeploymentHash(contract.code);
|
|
27847
|
+
await this.saveDeployment({
|
|
27848
|
+
gameId: game2.id,
|
|
27849
|
+
deploymentId: result.deploymentId,
|
|
27850
|
+
url: result.url,
|
|
27851
|
+
codeHash,
|
|
27852
|
+
resources: result.resources,
|
|
27853
|
+
target: "dashboard"
|
|
27854
|
+
});
|
|
27855
|
+
setAttribute("app.deploy.code_hash", codeHash);
|
|
27856
|
+
try {
|
|
27857
|
+
await withSpan("deploy.send_alert", () => this.deps.alerts.notifyDashboardDeployment({
|
|
27858
|
+
slug,
|
|
27859
|
+
displayName: game2.displayName,
|
|
27860
|
+
url: result.url,
|
|
27861
|
+
developer: { id: user.id, email: user.email }
|
|
27862
|
+
}));
|
|
27863
|
+
} catch (error) {
|
|
27864
|
+
setAttribute("app.alerts.delivery", "failed");
|
|
27865
|
+
setAttribute("app.alerts.delivery_error", errorMessage(error));
|
|
27866
|
+
setAttribute("app.alerts.type", "dashboard_deployment");
|
|
27276
27867
|
}
|
|
27277
|
-
|
|
27868
|
+
yield { type: "complete", data: game2 };
|
|
27278
27869
|
}
|
|
27279
|
-
|
|
27280
|
-
const
|
|
27281
|
-
|
|
27282
|
-
|
|
27870
|
+
validateGameRequest(request) {
|
|
27871
|
+
const hasBackend = Boolean(request.code);
|
|
27872
|
+
const hasFrontend = Boolean(request.uploadToken);
|
|
27873
|
+
const hasMetadata = Boolean(request.metadata);
|
|
27874
|
+
setAttributes({
|
|
27875
|
+
"app.deploy.has_backend": hasBackend,
|
|
27876
|
+
"app.deploy.has_frontend": hasFrontend,
|
|
27877
|
+
"app.deploy.has_metadata": hasMetadata,
|
|
27878
|
+
"app.deploy.type": DeployService.classifyGameDeployType({
|
|
27879
|
+
hasBackend,
|
|
27880
|
+
hasFrontend,
|
|
27881
|
+
hasMetadata
|
|
27882
|
+
}),
|
|
27883
|
+
"app.deploy.code_size": request.code?.length ?? 0,
|
|
27884
|
+
"app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27885
|
+
"app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0,
|
|
27886
|
+
"app.deploy.has_schema": Boolean(request.schema)
|
|
27887
|
+
});
|
|
27888
|
+
if (!hasBackend && !hasFrontend && !hasMetadata) {
|
|
27889
|
+
throw new ValidationError("Must provide at least one of: uploadToken (frontend), code (backend), or metadata");
|
|
27283
27890
|
}
|
|
27284
|
-
|
|
27285
|
-
|
|
27891
|
+
if (!this.deps.config.baseUrl) {
|
|
27892
|
+
throw new ValidationError("baseUrl is not configured");
|
|
27893
|
+
}
|
|
27894
|
+
return { hasBackend, hasFrontend, hasMetadata };
|
|
27286
27895
|
}
|
|
27287
|
-
|
|
27288
|
-
|
|
27289
|
-
|
|
27290
|
-
throw new ValidationError("Uploaded file is empty or not found");
|
|
27896
|
+
validateDashboardRequest(request, uploadDeps, extractZip) {
|
|
27897
|
+
if (!request.code || !request.uploadToken) {
|
|
27898
|
+
throw new ValidationError("Dashboard deployments require both worker code and an asset upload");
|
|
27291
27899
|
}
|
|
27292
|
-
|
|
27293
|
-
|
|
27294
|
-
|
|
27295
|
-
|
|
27296
|
-
|
|
27297
|
-
|
|
27298
|
-
|
|
27299
|
-
|
|
27900
|
+
if (request.metadata) {
|
|
27901
|
+
throw new ValidationError("Dashboard deployments cannot update game metadata");
|
|
27902
|
+
}
|
|
27903
|
+
if (!uploadDeps || !extractZip) {
|
|
27904
|
+
throw new ValidationError("Upload dependencies not configured for frontend deployment");
|
|
27905
|
+
}
|
|
27906
|
+
if (!this.deps.config.baseUrl) {
|
|
27907
|
+
throw new ValidationError("baseUrl is not configured");
|
|
27908
|
+
}
|
|
27909
|
+
return { code: request.code, uploadToken: request.uploadToken, uploadDeps, extractZip };
|
|
27910
|
+
}
|
|
27911
|
+
static classifyGameDeployType(flags2) {
|
|
27912
|
+
if (flags2.hasBackend && flags2.hasFrontend) {
|
|
27913
|
+
return "full_stack";
|
|
27914
|
+
}
|
|
27915
|
+
if (flags2.hasFrontend) {
|
|
27916
|
+
return "frontend_only";
|
|
27917
|
+
}
|
|
27918
|
+
if (flags2.hasBackend) {
|
|
27919
|
+
return "backend_only";
|
|
27920
|
+
}
|
|
27921
|
+
return "metadata_only";
|
|
27922
|
+
}
|
|
27923
|
+
mapGameBindingsToOptions(deploymentId, bindings, schema2) {
|
|
27924
|
+
if (!bindings && !schema2) {
|
|
27925
|
+
return;
|
|
27926
|
+
}
|
|
27927
|
+
const workerBindings = {};
|
|
27928
|
+
if (bindings?.database) {
|
|
27929
|
+
workerBindings.d1 = [deploymentId];
|
|
27930
|
+
}
|
|
27931
|
+
if (bindings?.keyValue) {
|
|
27932
|
+
workerBindings.kv = [deploymentId];
|
|
27933
|
+
}
|
|
27934
|
+
if (bindings?.bucket) {
|
|
27935
|
+
workerBindings.r2 = [deploymentId];
|
|
27936
|
+
}
|
|
27937
|
+
if (bindings?.queues) {
|
|
27938
|
+
let toQueueName = function(queueKey) {
|
|
27939
|
+
return `${QUEUE_NAME_PREFIX}-${deploymentId}--${queueKey}`;
|
|
27940
|
+
};
|
|
27941
|
+
const queueNameByKey = new Map;
|
|
27942
|
+
for (const queueKey of Object.keys(bindings.queues)) {
|
|
27943
|
+
queueNameByKey.set(queueKey, toQueueName(queueKey));
|
|
27944
|
+
}
|
|
27945
|
+
workerBindings.queues = Object.entries(bindings.queues).map(([queueKey, queueConfig]) => {
|
|
27946
|
+
const config2 = queueConfig === true ? undefined : queueConfig;
|
|
27947
|
+
const deadLetterQueue = config2?.deadLetterQueue && queueNameByKey.get(config2.deadLetterQueue) ? queueNameByKey.get(config2.deadLetterQueue) : undefined;
|
|
27948
|
+
return {
|
|
27949
|
+
bindingName: toBindingName(queueKey),
|
|
27950
|
+
queueName: toQueueName(queueKey),
|
|
27951
|
+
settings: config2 ? {
|
|
27952
|
+
maxBatchSize: config2.maxBatchSize,
|
|
27953
|
+
maxRetries: config2.maxRetries,
|
|
27954
|
+
maxBatchTimeout: config2.maxBatchTimeout,
|
|
27955
|
+
maxConcurrency: config2.maxConcurrency,
|
|
27956
|
+
retryDelay: config2.retryDelay
|
|
27957
|
+
} : undefined,
|
|
27958
|
+
deadLetterQueue
|
|
27959
|
+
};
|
|
27960
|
+
});
|
|
27961
|
+
}
|
|
27962
|
+
const hasBindings = workerBindings.d1?.length || workerBindings.kv?.length || workerBindings.r2?.length || workerBindings.queues?.length;
|
|
27963
|
+
return {
|
|
27964
|
+
...hasBindings && { bindings: workerBindings },
|
|
27965
|
+
...schema2 && { schema: schema2 }
|
|
27966
|
+
};
|
|
27967
|
+
}
|
|
27968
|
+
static countDeadLetterQueues(bindings) {
|
|
27969
|
+
return bindings?.queues?.filter((queue) => Boolean(queue.deadLetterQueue)).length ?? 0;
|
|
27300
27970
|
}
|
|
27301
27971
|
async cleanupOrphanD1Databases(cf, d1Names, slug, gameId) {
|
|
27302
27972
|
const hasAnyPriorDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
27303
|
-
where: eq(gameDeployments.gameId, gameId),
|
|
27973
|
+
where: and(eq(gameDeployments.gameId, gameId), eq(gameDeployments.target, "game")),
|
|
27304
27974
|
columns: { id: true }
|
|
27305
27975
|
});
|
|
27306
27976
|
if (hasAnyPriorDeployment) {
|
|
@@ -27335,33 +28005,7 @@ class DeployService {
|
|
|
27335
28005
|
}
|
|
27336
28006
|
await this.deps.db.update(games).set(updates).where(eq(games.id, gameId));
|
|
27337
28007
|
}
|
|
27338
|
-
|
|
27339
|
-
const hasBackend = Boolean(request.code);
|
|
27340
|
-
const hasFrontend = Boolean(request.uploadToken);
|
|
27341
|
-
const hasMetadata = Boolean(request.metadata);
|
|
27342
|
-
setAttributes({
|
|
27343
|
-
"app.deploy.has_backend": hasBackend,
|
|
27344
|
-
"app.deploy.has_frontend": hasFrontend,
|
|
27345
|
-
"app.deploy.has_metadata": hasMetadata,
|
|
27346
|
-
"app.deploy.type": DeployService.classifyDeployType({
|
|
27347
|
-
hasBackend,
|
|
27348
|
-
hasFrontend,
|
|
27349
|
-
hasMetadata
|
|
27350
|
-
}),
|
|
27351
|
-
"app.deploy.code_size": request.code?.length ?? 0,
|
|
27352
|
-
"app.deploy.compatibility_date": request.compatibilityDate ?? CLOUDFLARE_COMPATIBILITY_DATE,
|
|
27353
|
-
"app.deploy.compatibility_flag_count": request.compatibilityFlags?.length ?? 0,
|
|
27354
|
-
"app.deploy.has_schema": Boolean(request.schema)
|
|
27355
|
-
});
|
|
27356
|
-
if (!hasBackend && !hasFrontend && !hasMetadata) {
|
|
27357
|
-
throw new ValidationError("Must provide at least one of: uploadToken (frontend), code (backend), or metadata");
|
|
27358
|
-
}
|
|
27359
|
-
if (!this.deps.config.baseUrl) {
|
|
27360
|
-
throw new ValidationError("baseUrl is not configured");
|
|
27361
|
-
}
|
|
27362
|
-
return { hasBackend, hasFrontend, hasMetadata };
|
|
27363
|
-
}
|
|
27364
|
-
async finalizeDeployment({
|
|
28008
|
+
async finalizeGameDeployment({
|
|
27365
28009
|
game: game2,
|
|
27366
28010
|
slug,
|
|
27367
28011
|
deploymentId,
|
|
@@ -27373,10 +28017,17 @@ class DeployService {
|
|
|
27373
28017
|
const { hasBackend, hasFrontend, hasMetadata } = flags2;
|
|
27374
28018
|
const db2 = this.deps.db;
|
|
27375
28019
|
const codeHash = hasBackend ? await generateDeploymentHash(request.code) : null;
|
|
27376
|
-
await this.saveDeployment(
|
|
28020
|
+
await this.saveDeployment({
|
|
28021
|
+
gameId: game2.id,
|
|
28022
|
+
deploymentId: result.deploymentId,
|
|
28023
|
+
url: result.url,
|
|
28024
|
+
codeHash,
|
|
28025
|
+
resources: result.resources,
|
|
28026
|
+
target: "game"
|
|
28027
|
+
});
|
|
27377
28028
|
if (hasBackend) {
|
|
27378
28029
|
await withSpan("deploy.configure_worker_secrets", async () => {
|
|
27379
|
-
await this.
|
|
28030
|
+
await this.ensureWorkerApiKeyOnWorker(user, DeployService.gameWorkerKeySpec(slug), result.deploymentId);
|
|
27380
28031
|
await this.ensureQueueIngressSecretOnWorker(slug, result.deploymentId);
|
|
27381
28032
|
});
|
|
27382
28033
|
}
|
|
@@ -27409,169 +28060,232 @@ class DeployService {
|
|
|
27409
28060
|
}
|
|
27410
28061
|
return updatedGame;
|
|
27411
28062
|
}
|
|
27412
|
-
|
|
27413
|
-
|
|
27414
|
-
|
|
27415
|
-
|
|
27416
|
-
|
|
27417
|
-
const { hasBackend, hasFrontend } = flags2;
|
|
27418
|
-
const deploymentId = getDeploymentId(slug, this.deps.config.sstStage);
|
|
27419
|
-
let frontendAssetsPath;
|
|
27420
|
-
let tempDir;
|
|
27421
|
-
if (hasFrontend) {
|
|
27422
|
-
if (!uploadDeps || !extractZip) {
|
|
27423
|
-
throw new ValidationError("Upload dependencies not configured for frontend deployment");
|
|
27424
|
-
}
|
|
27425
|
-
yield { type: "status", data: { message: "Fetching temporary files" } };
|
|
27426
|
-
const extracted = await this.fetchAndExtractFrontendAssets(slug, game2.id, request.uploadToken, uploadDeps, extractZip);
|
|
27427
|
-
tempDir = extracted.tempDir;
|
|
27428
|
-
frontendAssetsPath = extracted.assetsPath;
|
|
27429
|
-
yield { type: "status", data: { message: "Extracting assets" } };
|
|
27430
|
-
}
|
|
27431
|
-
let platformBaseUrl = this.deps.config.baseUrl;
|
|
27432
|
-
if (this.deps.config.isLocal) {
|
|
27433
|
-
try {
|
|
27434
|
-
platformBaseUrl = await getTunnelUrl();
|
|
27435
|
-
} catch {
|
|
27436
|
-
setAttributes({
|
|
27437
|
-
"app.deploy.tunnel_available": false,
|
|
27438
|
-
"app.deploy.failure_kind": "local_tunnel_unavailable"
|
|
27439
|
-
});
|
|
27440
|
-
throw new ValidationError("Local tunnel is not running. Ensure cloudflared is installed (`brew install cloudflared`) and the tunnel DevCommand started successfully.");
|
|
27441
|
-
}
|
|
27442
|
-
}
|
|
27443
|
-
const env = {
|
|
27444
|
-
GAME_ID: game2.id,
|
|
27445
|
-
PLAYCADEMY_BASE_URL: platformBaseUrl,
|
|
27446
|
-
PLAYCADEMY_PLATFORM_SERVICE_JWKS: this.deps.config.platformServiceJwt?.publicJwks
|
|
28063
|
+
static gameWorkerKeySpec(slug) {
|
|
28064
|
+
return {
|
|
28065
|
+
keyName: getGameWorkerApiKeyName(slug),
|
|
28066
|
+
permissions: { games: [`read:${slug}`, `write:${slug}`] },
|
|
28067
|
+
lookup: "owner-and-name"
|
|
27447
28068
|
};
|
|
27448
|
-
|
|
27449
|
-
|
|
27450
|
-
|
|
28069
|
+
}
|
|
28070
|
+
static dashboardWorkerKeySpec(slug) {
|
|
28071
|
+
return {
|
|
28072
|
+
keyName: getDashboardWorkerApiKeyName(slug),
|
|
28073
|
+
permissions: {
|
|
28074
|
+
games: [`read:${slug}`],
|
|
28075
|
+
[DASHBOARD_PERMISSION_NAMESPACE]: [dashboardCredentialScope(slug)]
|
|
28076
|
+
},
|
|
28077
|
+
rateLimit: { maxRequests: 300, timeWindowMs: 60000 },
|
|
28078
|
+
lookup: "name",
|
|
28079
|
+
isCurrent: (permissionsJson) => DeployService.hasDashboardCredentialScope(permissionsJson, slug)
|
|
27451
28080
|
};
|
|
27452
|
-
|
|
27453
|
-
|
|
27454
|
-
|
|
27455
|
-
|
|
27456
|
-
"app.deploy.has_d1": Boolean(bindings?.d1?.length),
|
|
27457
|
-
"app.deploy.has_kv": Boolean(bindings?.kv?.length),
|
|
27458
|
-
"app.deploy.has_r2": Boolean(bindings?.r2?.length),
|
|
27459
|
-
"app.deploy.queue_count": bindings?.queues?.length ?? 0,
|
|
27460
|
-
"app.deploy.dead_letter_queue_count": DeployService.countDeadLetterQueues(bindings)
|
|
27461
|
-
});
|
|
27462
|
-
const activeDeployment = await db2.query.gameDeployments.findFirst({
|
|
27463
|
-
where: and(eq(gameDeployments.gameId, game2.id), eq(gameDeployments.isActive, true)),
|
|
27464
|
-
columns: { resources: true }
|
|
27465
|
-
});
|
|
27466
|
-
if (deploymentOptions?.bindings?.d1?.length) {
|
|
27467
|
-
await this.cleanupOrphanD1Databases(cf, deploymentOptions.bindings.d1, slug, game2.id);
|
|
28081
|
+
}
|
|
28082
|
+
static hasDashboardCredentialScope(permissionsJson, slug) {
|
|
28083
|
+
if (!permissionsJson) {
|
|
28084
|
+
return false;
|
|
27468
28085
|
}
|
|
27469
|
-
let result;
|
|
27470
28086
|
try {
|
|
27471
|
-
|
|
27472
|
-
|
|
27473
|
-
|
|
27474
|
-
|
|
27475
|
-
|
|
27476
|
-
|
|
27477
|
-
|
|
27478
|
-
|
|
27479
|
-
|
|
27480
|
-
|
|
27481
|
-
|
|
27482
|
-
|
|
28087
|
+
const parsed = JSON.parse(permissionsJson);
|
|
28088
|
+
return dashboardCredentialSlugs(parsed).includes(slug);
|
|
28089
|
+
} catch {
|
|
28090
|
+
return false;
|
|
28091
|
+
}
|
|
28092
|
+
}
|
|
28093
|
+
async ensureWorkerApiKeyOnWorker(user, spec, deploymentId, existingSecrets) {
|
|
28094
|
+
const cf = this.getCloudflare();
|
|
28095
|
+
const existingKey = await this.deps.db.query.apikey.findFirst({
|
|
28096
|
+
where: spec.lookup === "owner-and-name" ? and(eq(apikey.userId, user.id), eq(apikey.name, spec.keyName)) : eq(apikey.name, spec.keyName),
|
|
28097
|
+
columns: { id: true, permissions: true }
|
|
28098
|
+
});
|
|
28099
|
+
let apiKey;
|
|
28100
|
+
if (!existingKey) {
|
|
28101
|
+
apiKey = await this.createApiKey(user, spec);
|
|
28102
|
+
} else {
|
|
28103
|
+
const current = spec.isCurrent?.(existingKey.permissions) ?? true;
|
|
28104
|
+
const workerHasKey = existingSecrets ? existingSecrets.includes("PLAYCADEMY_API_KEY") : await this.workerHasSecret(deploymentId, "PLAYCADEMY_API_KEY");
|
|
28105
|
+
if (current && workerHasKey) {
|
|
28106
|
+
setAttribute("app.deploy.api_key_outcome", "already_set");
|
|
28107
|
+
return;
|
|
27483
28108
|
}
|
|
28109
|
+
apiKey = await this.regenerateApiKey(user, existingKey.id, spec);
|
|
27484
28110
|
}
|
|
27485
|
-
|
|
27486
|
-
|
|
27487
|
-
|
|
27488
|
-
|
|
27489
|
-
|
|
27490
|
-
|
|
27491
|
-
|
|
27492
|
-
|
|
27493
|
-
|
|
28111
|
+
await cf.setSecrets(deploymentId, { PLAYCADEMY_API_KEY: apiKey });
|
|
28112
|
+
}
|
|
28113
|
+
async createApiKey(user, spec) {
|
|
28114
|
+
const { key: apiKey } = await this.deps.createAuthApiKey({
|
|
28115
|
+
userId: user.id,
|
|
28116
|
+
name: spec.keyName,
|
|
28117
|
+
expiresIn: null,
|
|
28118
|
+
permissions: spec.permissions,
|
|
28119
|
+
...spec.rateLimit ? {
|
|
28120
|
+
rateLimitEnabled: true,
|
|
28121
|
+
rateLimitMax: spec.rateLimit.maxRequests,
|
|
28122
|
+
rateLimitTimeWindow: spec.rateLimit.timeWindowMs
|
|
28123
|
+
} : { rateLimitEnabled: false }
|
|
27494
28124
|
});
|
|
27495
|
-
|
|
28125
|
+
setAttribute("app.deploy.api_key_outcome", "created");
|
|
28126
|
+
return apiKey;
|
|
27496
28127
|
}
|
|
27497
|
-
|
|
27498
|
-
|
|
28128
|
+
async regenerateApiKey(user, existingKeyId, spec) {
|
|
28129
|
+
setAttribute("app.deploy.api_key_outcome", "regenerated");
|
|
28130
|
+
try {
|
|
28131
|
+
await this.deps.deleteAuthApiKey(existingKeyId);
|
|
28132
|
+
} catch (error) {
|
|
28133
|
+
addEvent("deploy.api_key_revoke_failed", {
|
|
28134
|
+
"exception.type": errorType(error),
|
|
28135
|
+
"app.error.message": errorMessage(error),
|
|
28136
|
+
"app.deploy.old_key_id": existingKeyId
|
|
28137
|
+
});
|
|
28138
|
+
}
|
|
28139
|
+
return this.createApiKey(user, spec);
|
|
28140
|
+
}
|
|
28141
|
+
async listWorkerSecretNames(deploymentId) {
|
|
28142
|
+
try {
|
|
28143
|
+
return await this.getCloudflare().listSecrets(deploymentId);
|
|
28144
|
+
} catch (error) {
|
|
28145
|
+
addEvent("deploy.worker_secrets_check_failed", {
|
|
28146
|
+
"exception.type": errorType(error),
|
|
28147
|
+
"app.error.message": errorMessage(error)
|
|
28148
|
+
});
|
|
28149
|
+
return null;
|
|
28150
|
+
}
|
|
28151
|
+
}
|
|
28152
|
+
async workerHasSecret(deploymentId, secretName) {
|
|
28153
|
+
const workerSecrets = await this.listWorkerSecretNames(deploymentId);
|
|
28154
|
+
return Boolean(workerSecrets?.includes(secretName));
|
|
28155
|
+
}
|
|
28156
|
+
async ensureQueueIngressSecretOnWorker(slug, deploymentId) {
|
|
28157
|
+
const secret = this.deps.config.queueIngressSecret;
|
|
28158
|
+
if (!secret) {
|
|
27499
28159
|
return;
|
|
27500
28160
|
}
|
|
27501
|
-
const
|
|
27502
|
-
|
|
27503
|
-
|
|
28161
|
+
const cf = this.getCloudflare();
|
|
28162
|
+
await cf.setSecrets(deploymentId, { QUEUE_INGRESS_SECRET: secret });
|
|
28163
|
+
}
|
|
28164
|
+
async ensureDashboardSessionSecret(deploymentId, existingSecrets, hasPriorDeployment) {
|
|
28165
|
+
if (existingSecrets === null && hasPriorDeployment) {
|
|
28166
|
+
setAttribute("app.deploy.session_secret_outcome", "check_failed_kept");
|
|
28167
|
+
return;
|
|
27504
28168
|
}
|
|
27505
|
-
if (
|
|
27506
|
-
|
|
28169
|
+
if (existingSecrets?.includes("DASHBOARD_SESSION_SECRET")) {
|
|
28170
|
+
setAttribute("app.deploy.session_secret_outcome", "already_set");
|
|
28171
|
+
return;
|
|
27507
28172
|
}
|
|
27508
|
-
|
|
27509
|
-
|
|
28173
|
+
const secret = await generateSecureRandomString(64);
|
|
28174
|
+
await this.getCloudflare().setSecrets(deploymentId, { DASHBOARD_SESSION_SECRET: secret });
|
|
28175
|
+
setAttribute("app.deploy.session_secret_outcome", "created");
|
|
28176
|
+
}
|
|
28177
|
+
async rotateDashboardSessionSecret(slug, user) {
|
|
28178
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
28179
|
+
const deployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
28180
|
+
where: activeDeploymentWhere(game2.id, "dashboard"),
|
|
28181
|
+
columns: { deploymentId: true }
|
|
28182
|
+
});
|
|
28183
|
+
if (!deployment) {
|
|
28184
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, slug);
|
|
28185
|
+
throw new NotFoundError("Dashboard deployment", slug);
|
|
27510
28186
|
}
|
|
27511
|
-
|
|
27512
|
-
|
|
27513
|
-
|
|
27514
|
-
|
|
27515
|
-
|
|
27516
|
-
|
|
27517
|
-
|
|
27518
|
-
|
|
27519
|
-
|
|
27520
|
-
|
|
27521
|
-
|
|
27522
|
-
|
|
27523
|
-
|
|
27524
|
-
|
|
27525
|
-
|
|
27526
|
-
|
|
27527
|
-
|
|
27528
|
-
|
|
27529
|
-
|
|
27530
|
-
|
|
27531
|
-
|
|
27532
|
-
|
|
27533
|
-
|
|
28187
|
+
const secret = await generateSecureRandomString(64);
|
|
28188
|
+
await this.getCloudflare().setSecrets(deployment.deploymentId, {
|
|
28189
|
+
DASHBOARD_SESSION_SECRET: secret
|
|
28190
|
+
});
|
|
28191
|
+
setAttribute("app.deploy.session_secret_outcome", "rotated");
|
|
28192
|
+
}
|
|
28193
|
+
async removeDashboard(slug, user) {
|
|
28194
|
+
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
28195
|
+
const db2 = this.deps.db;
|
|
28196
|
+
const deployment = await db2.query.gameDeployments.findFirst({
|
|
28197
|
+
where: activeDeploymentWhere(game2.id, "dashboard"),
|
|
28198
|
+
columns: { deploymentId: true, provider: true, resources: true }
|
|
28199
|
+
});
|
|
28200
|
+
if (!deployment) {
|
|
28201
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, slug);
|
|
28202
|
+
throw new NotFoundError("Dashboard deployment", slug);
|
|
28203
|
+
}
|
|
28204
|
+
const assetBuckets = deployment.resources?.r2?.filter((bucket) => bucket.kind === "assets") ?? [];
|
|
28205
|
+
await this.getCloudflare().delete(deployment.deploymentId, {
|
|
28206
|
+
deleteBindings: assetBuckets.length > 0,
|
|
28207
|
+
resources: assetBuckets.length > 0 ? { r2: assetBuckets } : undefined
|
|
28208
|
+
});
|
|
28209
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, slug);
|
|
28210
|
+
await db2.delete(gameDeployments).where(and(eq(gameDeployments.gameId, game2.id), eq(gameDeployments.target, "dashboard")));
|
|
28211
|
+
setAttribute("app.deploy.dashboard_removed", true);
|
|
28212
|
+
await withSpan("deploy.send_alert", () => this.deps.alerts.notifyDashboardRemoval({
|
|
28213
|
+
slug,
|
|
28214
|
+
displayName: game2.displayName,
|
|
28215
|
+
developer: { id: user.id, email: user.email }
|
|
28216
|
+
})).catch(catchAttrs("alerts.delivery", { "app.alerts.type": "dashboard_removal" }));
|
|
28217
|
+
}
|
|
28218
|
+
async fetchAndExtractFrontendAssets(slug, gameId, uploadToken, uploadDeps, extractZip) {
|
|
28219
|
+
const frontendZip = await withSpan("deploy.fetch_temporary_files", () => uploadDeps.getObjectAsByteArray(uploadToken));
|
|
28220
|
+
if (!frontendZip || frontendZip.length === 0) {
|
|
28221
|
+
throw new ValidationError("Uploaded file is empty or not found");
|
|
28222
|
+
}
|
|
28223
|
+
setAttribute("app.deploy.asset_upload_size", frontendZip.length);
|
|
28224
|
+
const os2 = await import("os");
|
|
28225
|
+
const path = await import("path");
|
|
28226
|
+
const tempDir = path.join(os2.tmpdir(), `playcademy-deploy-${gameId}-${Date.now()}`);
|
|
28227
|
+
const assetsPath = path.join(tempDir, "dist");
|
|
28228
|
+
await withSpan("deploy.extract_assets", () => extractZip(frontendZip, assetsPath));
|
|
28229
|
+
uploadDeps.deleteObject(uploadToken).catch(catchAttrs("deploy.temp_cleanup"));
|
|
28230
|
+
return { frontendZip, tempDir, assetsPath };
|
|
28231
|
+
}
|
|
28232
|
+
async resolvePlatformBaseUrl() {
|
|
28233
|
+
if (!this.deps.config.isLocal) {
|
|
28234
|
+
return this.deps.config.baseUrl;
|
|
28235
|
+
}
|
|
28236
|
+
try {
|
|
28237
|
+
return await getTunnelUrl(this.deps.config.baseUrl);
|
|
28238
|
+
} catch (error) {
|
|
28239
|
+
setAttributes({
|
|
28240
|
+
"app.deploy.tunnel_available": false,
|
|
28241
|
+
"app.deploy.failure_kind": "local_tunnel_unavailable"
|
|
27534
28242
|
});
|
|
28243
|
+
throw new ValidationError(errorMessage(error));
|
|
27535
28244
|
}
|
|
27536
|
-
const hasBindings = workerBindings.d1?.length || workerBindings.kv?.length || workerBindings.r2?.length || workerBindings.queues?.length;
|
|
27537
|
-
return {
|
|
27538
|
-
...hasBindings && { bindings: workerBindings },
|
|
27539
|
-
...schema2 && { schema: schema2 }
|
|
27540
|
-
};
|
|
27541
28245
|
}
|
|
27542
|
-
async
|
|
27543
|
-
|
|
27544
|
-
|
|
27545
|
-
|
|
27546
|
-
|
|
27547
|
-
|
|
27548
|
-
|
|
28246
|
+
async deployToCloudflare(args2) {
|
|
28247
|
+
const cf = this.getCloudflare();
|
|
28248
|
+
try {
|
|
28249
|
+
return await withSpan("deploy.cloudflare", () => cf.deploy(args2.deploymentId, args2.code, args2.env, args2.options));
|
|
28250
|
+
} finally {
|
|
28251
|
+
if (args2.tempDir) {
|
|
28252
|
+
const fs2 = await import("fs/promises");
|
|
28253
|
+
fs2.rm(args2.tempDir, { recursive: true, force: true }).catch(catchAttrs("deploy.temp_cleanup"));
|
|
28254
|
+
}
|
|
28255
|
+
}
|
|
27549
28256
|
}
|
|
27550
|
-
async saveDeployment(
|
|
28257
|
+
async saveDeployment(record) {
|
|
27551
28258
|
const db2 = this.deps.db;
|
|
27552
28259
|
await db2.transaction(async (tx) => {
|
|
27553
|
-
await tx.update(gameDeployments).set({ isActive: false }).where(eq(gameDeployments.gameId, gameId));
|
|
28260
|
+
await tx.update(gameDeployments).set({ isActive: false }).where(and(eq(gameDeployments.gameId, record.gameId), eq(gameDeployments.target, record.target)));
|
|
27554
28261
|
await tx.insert(gameDeployments).values({
|
|
27555
|
-
gameId,
|
|
27556
|
-
deploymentId,
|
|
28262
|
+
gameId: record.gameId,
|
|
28263
|
+
deploymentId: record.deploymentId,
|
|
27557
28264
|
provider: "cloudflare",
|
|
27558
|
-
|
|
27559
|
-
|
|
27560
|
-
|
|
28265
|
+
target: record.target,
|
|
28266
|
+
url: record.url,
|
|
28267
|
+
codeHash: record.codeHash,
|
|
28268
|
+
resources: record.resources,
|
|
27561
28269
|
isActive: true
|
|
27562
28270
|
});
|
|
27563
28271
|
});
|
|
27564
28272
|
}
|
|
28273
|
+
async notifyDeploymentFailure(failure) {
|
|
28274
|
+
await this.deps.alerts.notifyDeploymentFailure(failure).catch(catchAttrs("alerts.delivery", { "app.alerts.type": "deployment_failure" }));
|
|
28275
|
+
}
|
|
27565
28276
|
}
|
|
27566
28277
|
var init_deploy_service = __esm(() => {
|
|
27567
28278
|
init_drizzle_orm();
|
|
27568
28279
|
init_playcademy();
|
|
27569
28280
|
init_src();
|
|
28281
|
+
init_helpers_index();
|
|
27570
28282
|
init_tables_index();
|
|
27571
28283
|
init_spans();
|
|
27572
28284
|
init_tunnel();
|
|
27573
28285
|
init_errors();
|
|
28286
|
+
init_dashboard_util();
|
|
27574
28287
|
init_deployment_util();
|
|
28288
|
+
init_worker_keys_util();
|
|
27575
28289
|
});
|
|
27576
28290
|
|
|
27577
28291
|
// ../api-core/src/services/developer.service.ts
|
|
@@ -27816,20 +28530,6 @@ var init_game_member_service = __esm(() => {
|
|
|
27816
28530
|
init_spans();
|
|
27817
28531
|
init_errors();
|
|
27818
28532
|
});
|
|
27819
|
-
// ../data/src/domains/timeback/helpers.ts
|
|
27820
|
-
function isActiveGameTimebackIntegrationStatus(statusColumn = gameTimebackIntegrations.status) {
|
|
27821
|
-
return sql`${statusColumn} IS DISTINCT FROM ${DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS}`;
|
|
27822
|
-
}
|
|
27823
|
-
var ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS = "active", DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS = "deactivated";
|
|
27824
|
-
var init_helpers2 = __esm(() => {
|
|
27825
|
-
init_drizzle_orm();
|
|
27826
|
-
init_table7();
|
|
27827
|
-
});
|
|
27828
|
-
|
|
27829
|
-
// ../data/src/helpers.index.ts
|
|
27830
|
-
var init_helpers_index = __esm(() => {
|
|
27831
|
-
init_helpers2();
|
|
27832
|
-
});
|
|
27833
28533
|
|
|
27834
28534
|
// ../utils/src/fns.ts
|
|
27835
28535
|
function sleep(ms) {
|
|
@@ -28273,6 +28973,7 @@ var init_game_service = __esm(() => {
|
|
|
28273
28973
|
init_errors();
|
|
28274
28974
|
init_deployment_util();
|
|
28275
28975
|
init_timeback_util();
|
|
28976
|
+
init_worker_keys_util();
|
|
28276
28977
|
inFlightManifestFetches = new Map;
|
|
28277
28978
|
GameService = class GameService {
|
|
28278
28979
|
deps;
|
|
@@ -28459,7 +29160,7 @@ var init_game_service = __esm(() => {
|
|
|
28459
29160
|
GameService.recordGameShape(game2);
|
|
28460
29161
|
return game2;
|
|
28461
29162
|
}
|
|
28462
|
-
async getBySlug(slug, caller) {
|
|
29163
|
+
async getBySlug(slug, caller, options) {
|
|
28463
29164
|
const db2 = this.deps.db;
|
|
28464
29165
|
const game2 = await db2.query.games.findFirst({
|
|
28465
29166
|
where: eq(games.slug, slug)
|
|
@@ -28467,7 +29168,9 @@ var init_game_service = __esm(() => {
|
|
|
28467
29168
|
if (!game2) {
|
|
28468
29169
|
throw new NotFoundError("Game", slug);
|
|
28469
29170
|
}
|
|
28470
|
-
|
|
29171
|
+
if (!options?.scopeAuthorized) {
|
|
29172
|
+
await this.enforceVisibility(game2, caller, slug);
|
|
29173
|
+
}
|
|
28471
29174
|
GameService.recordGameShape(game2);
|
|
28472
29175
|
return game2;
|
|
28473
29176
|
}
|
|
@@ -28644,6 +29347,9 @@ var init_game_service = __esm(() => {
|
|
|
28644
29347
|
await this.validateDeveloperAccess(user, gameId);
|
|
28645
29348
|
} else {
|
|
28646
29349
|
this.validateDeveloperStatus(user);
|
|
29350
|
+
if (slug.endsWith(DASHBOARD_WORKER_SUFFIX)) {
|
|
29351
|
+
throw new ValidationError(`Game slugs may not end with '${DASHBOARD_WORKER_SUFFIX}' — it is reserved for dashboard workers`);
|
|
29352
|
+
}
|
|
28647
29353
|
}
|
|
28648
29354
|
const gameDataForDb = {
|
|
28649
29355
|
displayName: data.displayName,
|
|
@@ -28770,15 +29476,21 @@ var init_game_service = __esm(() => {
|
|
|
28770
29476
|
if (!gameToDelete?.slug) {
|
|
28771
29477
|
throw new NotFoundError("Game", gameId);
|
|
28772
29478
|
}
|
|
28773
|
-
const activeDeployment = await
|
|
28774
|
-
|
|
28775
|
-
|
|
28776
|
-
|
|
28777
|
-
|
|
28778
|
-
|
|
28779
|
-
|
|
28780
|
-
|
|
28781
|
-
|
|
29479
|
+
const [activeDeployment, dashboardDeployment, customHostnames] = await Promise.all([
|
|
29480
|
+
db2.query.gameDeployments.findFirst({
|
|
29481
|
+
where: activeDeploymentWhere(gameId, "game"),
|
|
29482
|
+
columns: { deploymentId: true, provider: true, resources: true }
|
|
29483
|
+
}),
|
|
29484
|
+
db2.query.gameDeployments.findFirst({
|
|
29485
|
+
where: activeDeploymentWhere(gameId, "dashboard"),
|
|
29486
|
+
columns: { deploymentId: true, provider: true, resources: true }
|
|
29487
|
+
}),
|
|
29488
|
+
db2.select({
|
|
29489
|
+
hostname: gameCustomHostnames.hostname,
|
|
29490
|
+
cloudflareId: gameCustomHostnames.cloudflareId,
|
|
29491
|
+
environment: gameCustomHostnames.environment
|
|
29492
|
+
}).from(gameCustomHostnames).where(eq(gameCustomHostnames.gameId, gameId))
|
|
29493
|
+
]);
|
|
28782
29494
|
const result = await db2.delete(games).where(eq(games.id, gameId)).returning({ id: games.id });
|
|
28783
29495
|
if (result.length === 0) {
|
|
28784
29496
|
throw new NotFoundError("Game", gameId);
|
|
@@ -28822,6 +29534,22 @@ var init_game_service = __esm(() => {
|
|
|
28822
29534
|
setAttribute("app.game.api_key_cleanup_error", errorMessage(error));
|
|
28823
29535
|
}
|
|
28824
29536
|
}
|
|
29537
|
+
if (dashboardDeployment?.provider === "cloudflare" && this.deps.cloudflare) {
|
|
29538
|
+
const dashboardAssetBuckets = dashboardDeployment.resources?.r2?.filter((bucket) => bucket.kind === "assets") ?? [];
|
|
29539
|
+
try {
|
|
29540
|
+
await this.deps.cloudflare.delete(dashboardDeployment.deploymentId, {
|
|
29541
|
+
deleteBindings: dashboardAssetBuckets.length > 0,
|
|
29542
|
+
resources: dashboardAssetBuckets.length > 0 ? { r2: dashboardAssetBuckets } : undefined
|
|
29543
|
+
});
|
|
29544
|
+
setAttribute("app.game.dashboard_cleanup", "succeeded");
|
|
29545
|
+
} catch (error) {
|
|
29546
|
+
setAttributes({
|
|
29547
|
+
"app.game.dashboard_cleanup": "failed",
|
|
29548
|
+
"app.game.dashboard_cleanup_error": errorMessage(error)
|
|
29549
|
+
});
|
|
29550
|
+
}
|
|
29551
|
+
}
|
|
29552
|
+
await sweepDashboardWorkerKeys(this.deps.deleteApiKeysByName, gameToDelete.slug);
|
|
28825
29553
|
const corsOrigin = GameService.safeOrigin(gameToDelete);
|
|
28826
29554
|
if (this.deps.corsKvs && corsOrigin) {
|
|
28827
29555
|
setAttribute("app.cors_kvs.origin", corsOrigin);
|
|
@@ -28945,7 +29673,7 @@ class LogsService {
|
|
|
28945
29673
|
}
|
|
28946
29674
|
async generateToken(user, slug, sstStage) {
|
|
28947
29675
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
28948
|
-
const workerId =
|
|
29676
|
+
const workerId = getGameDeploymentId(slug, sstStage);
|
|
28949
29677
|
const token = await this.deps.mintLogStreamToken(user.id, workerId);
|
|
28950
29678
|
setAttribute("app.logs.worker_id", workerId);
|
|
28951
29679
|
return { token, workerId };
|
|
@@ -28965,7 +29693,8 @@ function createGameServices(deps) {
|
|
|
28965
29693
|
cache,
|
|
28966
29694
|
cloudflare: cloudflare2,
|
|
28967
29695
|
corsKvs,
|
|
28968
|
-
deleteApiKeyByName: auth2.deleteApiKeyByName.bind(auth2)
|
|
29696
|
+
deleteApiKeyByName: auth2.deleteApiKeyByName.bind(auth2),
|
|
29697
|
+
deleteApiKeysByName: auth2.deleteApiKeysByName.bind(auth2)
|
|
28969
29698
|
});
|
|
28970
29699
|
const gameMember = new GameMemberService({
|
|
28971
29700
|
db: db2,
|
|
@@ -28978,6 +29707,7 @@ function createGameServices(deps) {
|
|
|
28978
29707
|
cloudflare: cloudflare2,
|
|
28979
29708
|
createAuthApiKey: auth2.createApiKey.bind(auth2),
|
|
28980
29709
|
deleteAuthApiKey: auth2.deleteApiKey.bind(auth2),
|
|
29710
|
+
deleteApiKeysByName: auth2.deleteApiKeysByName.bind(auth2),
|
|
28981
29711
|
alerts,
|
|
28982
29712
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug)
|
|
28983
29713
|
});
|
|
@@ -28987,14 +29717,20 @@ function createGameServices(deps) {
|
|
|
28987
29717
|
storage,
|
|
28988
29718
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug),
|
|
28989
29719
|
runDeploy: (slug, request, user, uploadDeps, extractZip) => deploy.deploy(slug, request, user, uploadDeps, extractZip),
|
|
28990
|
-
notifyDeploymentFailure: (
|
|
29720
|
+
notifyDeploymentFailure: (failure) => deploy.notifyDeploymentFailure(failure)
|
|
28991
29721
|
});
|
|
28992
29722
|
const logs = new LogsService({
|
|
28993
29723
|
mintLogStreamToken: auth2.mintLogStreamToken.bind(auth2),
|
|
28994
29724
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug)
|
|
28995
29725
|
});
|
|
29726
|
+
const dashboard2 = new DashboardService({
|
|
29727
|
+
db: db2,
|
|
29728
|
+
hashPassword: auth2.hashPassword.bind(auth2),
|
|
29729
|
+
verifyPassword: auth2.verifyPassword.bind(auth2),
|
|
29730
|
+
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug)
|
|
29731
|
+
});
|
|
28996
29732
|
return {
|
|
28997
|
-
services: { game: game2, gameMember, developer, deploy, deployJobs, logs },
|
|
29733
|
+
services: { game: game2, gameMember, developer, deploy, deployJobs, logs, dashboard: dashboard2 },
|
|
28998
29734
|
validators: {
|
|
28999
29735
|
validateDeveloperAccessBySlug: (user, slug) => game2.validateDeveloperAccessBySlug(user, slug),
|
|
29000
29736
|
validateDeveloperAccess: (user, gameId) => game2.validateDeveloperAccess(user, gameId),
|
|
@@ -29004,6 +29740,7 @@ function createGameServices(deps) {
|
|
|
29004
29740
|
};
|
|
29005
29741
|
}
|
|
29006
29742
|
var init_game2 = __esm(() => {
|
|
29743
|
+
init_dashboard_service();
|
|
29007
29744
|
init_deploy_job_service();
|
|
29008
29745
|
init_deploy_service();
|
|
29009
29746
|
init_developer_service();
|
|
@@ -29188,12 +29925,25 @@ class AlertsService {
|
|
|
29188
29925
|
embed.setFooter("Playcademy Developer Platform").setTimestamp();
|
|
29189
29926
|
await this.sendAlert(discord, embed.build());
|
|
29190
29927
|
}
|
|
29928
|
+
async notifyDashboardDeployment(dashboard2) {
|
|
29929
|
+
const discord = this.recordAlert("dashboard_deployment");
|
|
29930
|
+
if (!discord) {
|
|
29931
|
+
return;
|
|
29932
|
+
}
|
|
29933
|
+
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);
|
|
29934
|
+
if (dashboard2.developer) {
|
|
29935
|
+
embed.addField("Developer", dashboard2.developer.email || dashboard2.developer.id, true);
|
|
29936
|
+
}
|
|
29937
|
+
embed.setFooter("Playcademy Developer Platform").setTimestamp();
|
|
29938
|
+
await this.sendAlert(discord, embed.build());
|
|
29939
|
+
}
|
|
29191
29940
|
async notifyDeploymentFailure(failure) {
|
|
29192
29941
|
const discord = this.recordAlert("deployment_failure");
|
|
29193
29942
|
if (!discord) {
|
|
29194
29943
|
return;
|
|
29195
29944
|
}
|
|
29196
|
-
const
|
|
29945
|
+
const [title, subject] = failure.target === "dashboard" ? ["❌ Dashboard Deployment Failed", "Dashboard deployment"] : ["❌ Deployment Failed", "Deployment"];
|
|
29946
|
+
const embed = new DiscordEmbedBuilder().setTitle(title).setDescription(`${subject} failed for **${failure.displayName || failure.slug}** (**${this.getEnvironment()}**).`).setColor(DiscordColors.RED).addField("Slug", failure.slug, true);
|
|
29197
29947
|
if (failure.developer) {
|
|
29198
29948
|
embed.addField("Developer", failure.developer.email || failure.developer.id, true);
|
|
29199
29949
|
}
|
|
@@ -29208,6 +29958,14 @@ class AlertsService {
|
|
|
29208
29958
|
const embed = new DiscordEmbedBuilder().setTitle("\uD83D\uDDD1️ Game Deleted").setDescription(`**${game2.displayName || game2.slug}** has been deleted (**${this.getEnvironment()}**).`).setColor(DiscordColors.ORANGE).addField("Slug", game2.slug, true).addField("Developer", game2.developer.email || game2.developer.id, true).setFooter("Playcademy Developer Platform").setTimestamp().build();
|
|
29209
29959
|
await this.sendAlert(discord, embed);
|
|
29210
29960
|
}
|
|
29961
|
+
async notifyDashboardRemoval(dashboard2) {
|
|
29962
|
+
const discord = this.recordAlert("dashboard_removal");
|
|
29963
|
+
if (!discord) {
|
|
29964
|
+
return;
|
|
29965
|
+
}
|
|
29966
|
+
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();
|
|
29967
|
+
await this.sendAlert(discord, embed);
|
|
29968
|
+
}
|
|
29211
29969
|
async notifySeedFailure(failure) {
|
|
29212
29970
|
const discord = this.recordAlert("seed_failure");
|
|
29213
29971
|
if (!discord) {
|
|
@@ -29373,6 +30131,7 @@ class KVBackupService {
|
|
|
29373
30131
|
async getTargets(gameSlug) {
|
|
29374
30132
|
const conditions2 = [
|
|
29375
30133
|
eq(gameDeployments.isActive, true),
|
|
30134
|
+
eq(gameDeployments.target, "game"),
|
|
29376
30135
|
eq(gameDeployments.provider, "cloudflare")
|
|
29377
30136
|
];
|
|
29378
30137
|
if (gameSlug) {
|
|
@@ -29599,7 +30358,7 @@ class BucketService {
|
|
|
29599
30358
|
return extensionIndex > 0 ? fileName.slice(extensionIndex + 1).toLowerCase() : "(none)";
|
|
29600
30359
|
}
|
|
29601
30360
|
getBucketName(slug) {
|
|
29602
|
-
return
|
|
30361
|
+
return getGameDeploymentId(slug, this.deps.sstStage);
|
|
29603
30362
|
}
|
|
29604
30363
|
async listFiles(slug, user, prefix) {
|
|
29605
30364
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
@@ -29688,6 +30447,32 @@ class DatabaseService {
|
|
|
29688
30447
|
}
|
|
29689
30448
|
return d1;
|
|
29690
30449
|
}
|
|
30450
|
+
async syncDashboardD1Binding(gameId, d1ResourceName, databaseId) {
|
|
30451
|
+
const dashboardDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
30452
|
+
where: activeDeploymentWhere(gameId, "dashboard"),
|
|
30453
|
+
columns: { id: true, deploymentId: true, resources: true }
|
|
30454
|
+
});
|
|
30455
|
+
if (!dashboardDeployment || !this.deps.cloudflare) {
|
|
30456
|
+
return;
|
|
30457
|
+
}
|
|
30458
|
+
try {
|
|
30459
|
+
await this.deps.cloudflare.updateD1Binding(dashboardDeployment.deploymentId, databaseId);
|
|
30460
|
+
if (dashboardDeployment.resources?.d1?.length) {
|
|
30461
|
+
const updatedResources = {
|
|
30462
|
+
...dashboardDeployment.resources,
|
|
30463
|
+
d1: dashboardDeployment.resources.d1.map((dbResource) => dbResource.name === d1ResourceName ? { ...dbResource, id: databaseId } : dbResource)
|
|
30464
|
+
};
|
|
30465
|
+
await this.deps.db.update(gameDeployments).set({ resources: updatedResources }).where(eq(gameDeployments.id, dashboardDeployment.id));
|
|
30466
|
+
}
|
|
30467
|
+
setAttribute("app.database.dashboard_binding", "updated");
|
|
30468
|
+
} catch (error) {
|
|
30469
|
+
addEvent("database.dashboard_binding_sync_failed", {
|
|
30470
|
+
"exception.type": errorType(error),
|
|
30471
|
+
"app.error.message": errorMessage(error),
|
|
30472
|
+
"app.deploy.deployment_id": dashboardDeployment.deploymentId
|
|
30473
|
+
});
|
|
30474
|
+
}
|
|
30475
|
+
}
|
|
29691
30476
|
async reset(slug, user, schema2) {
|
|
29692
30477
|
setAttributes({
|
|
29693
30478
|
"app.database.operation": "reset",
|
|
@@ -29696,7 +30481,7 @@ class DatabaseService {
|
|
|
29696
30481
|
});
|
|
29697
30482
|
const d1 = this.getD1();
|
|
29698
30483
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
29699
|
-
const deploymentId =
|
|
30484
|
+
const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
29700
30485
|
try {
|
|
29701
30486
|
const databaseId = await d1.reset(deploymentId);
|
|
29702
30487
|
setAttribute("app.database.id", databaseId);
|
|
@@ -29712,7 +30497,7 @@ class DatabaseService {
|
|
|
29712
30497
|
setAttribute("app.database.binding", "skipped_no_provider");
|
|
29713
30498
|
}
|
|
29714
30499
|
const activeDeployment = await this.deps.db.query.gameDeployments.findFirst({
|
|
29715
|
-
where:
|
|
30500
|
+
where: activeDeploymentWhere(game2.id),
|
|
29716
30501
|
columns: { id: true, resources: true }
|
|
29717
30502
|
});
|
|
29718
30503
|
setAttribute("app.database.active_deployment_found", Boolean(activeDeployment));
|
|
@@ -29723,6 +30508,7 @@ class DatabaseService {
|
|
|
29723
30508
|
};
|
|
29724
30509
|
await this.deps.db.update(gameDeployments).set({ resources: updatedResources }).where(eq(gameDeployments.id, activeDeployment.id));
|
|
29725
30510
|
}
|
|
30511
|
+
await this.syncDashboardD1Binding(game2.id, deploymentId, databaseId);
|
|
29726
30512
|
setAttributes({
|
|
29727
30513
|
"app.database.deployment_id": deploymentId,
|
|
29728
30514
|
"app.database.schema_pushed": schemaPushed
|
|
@@ -29746,6 +30532,7 @@ class DatabaseService {
|
|
|
29746
30532
|
}
|
|
29747
30533
|
var init_database_service = __esm(() => {
|
|
29748
30534
|
init_drizzle_orm();
|
|
30535
|
+
init_helpers_index();
|
|
29749
30536
|
init_tables_index();
|
|
29750
30537
|
init_spans();
|
|
29751
30538
|
init_errors();
|
|
@@ -29989,7 +30776,7 @@ class KVService {
|
|
|
29989
30776
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
29990
30777
|
const db2 = this.deps.db;
|
|
29991
30778
|
const deployment = await db2.query.gameDeployments.findFirst({
|
|
29992
|
-
where:
|
|
30779
|
+
where: activeDeploymentWhere(game2.id),
|
|
29993
30780
|
columns: { resources: true }
|
|
29994
30781
|
});
|
|
29995
30782
|
if (!deployment?.resources?.kv?.length) {
|
|
@@ -30110,8 +30897,7 @@ class KVService {
|
|
|
30110
30897
|
}
|
|
30111
30898
|
}
|
|
30112
30899
|
var init_kv_service = __esm(() => {
|
|
30113
|
-
|
|
30114
|
-
init_tables_index();
|
|
30900
|
+
init_helpers_index();
|
|
30115
30901
|
init_spans();
|
|
30116
30902
|
init_errors();
|
|
30117
30903
|
});
|
|
@@ -30128,13 +30914,13 @@ class SecretsService {
|
|
|
30128
30914
|
}
|
|
30129
30915
|
return this.deps.cloudflare;
|
|
30130
30916
|
}
|
|
30131
|
-
|
|
30132
|
-
return
|
|
30917
|
+
getGameDeploymentId(slug) {
|
|
30918
|
+
return getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
30133
30919
|
}
|
|
30134
30920
|
async listKeys(slug, user) {
|
|
30135
30921
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30136
30922
|
const cf = this.getCloudflare();
|
|
30137
|
-
const deploymentId = this.
|
|
30923
|
+
const deploymentId = this.getGameDeploymentId(slug);
|
|
30138
30924
|
try {
|
|
30139
30925
|
const allKeys = await cf.listSecrets(deploymentId);
|
|
30140
30926
|
const userKeys = allKeys.filter((k) => k.startsWith(SECRETS_PREFIX)).map((k) => k.slice(SECRETS_PREFIX.length));
|
|
@@ -30160,7 +30946,7 @@ class SecretsService {
|
|
|
30160
30946
|
async setSecrets(slug, newSecrets, user) {
|
|
30161
30947
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30162
30948
|
const cf = this.getCloudflare();
|
|
30163
|
-
const deploymentId = this.
|
|
30949
|
+
const deploymentId = this.getGameDeploymentId(slug);
|
|
30164
30950
|
const secretKeys = Object.keys(newSecrets);
|
|
30165
30951
|
if (secretKeys.length === 0) {
|
|
30166
30952
|
throw new ValidationError("At least one secret must be provided");
|
|
@@ -30213,7 +30999,7 @@ class SecretsService {
|
|
|
30213
30999
|
}
|
|
30214
31000
|
await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30215
31001
|
const cf = this.getCloudflare();
|
|
30216
|
-
const deploymentId = this.
|
|
31002
|
+
const deploymentId = this.getGameDeploymentId(slug);
|
|
30217
31003
|
try {
|
|
30218
31004
|
const prefixedKey = `${SECRETS_PREFIX}${key}`;
|
|
30219
31005
|
const existingKeys = await cf.listSecrets(deploymentId);
|
|
@@ -30250,27 +31036,7 @@ var init_secrets_service = __esm(() => {
|
|
|
30250
31036
|
init_deployment_util();
|
|
30251
31037
|
INTERNAL_SECRET_KEYS = ["PLAYCADEMY_API_KEY", "GAME_ID", "PLAYCADEMY_BASE_URL"];
|
|
30252
31038
|
});
|
|
30253
|
-
|
|
30254
|
-
// ../edge-play/src/constants.ts
|
|
30255
|
-
var ASSET_ROUTE_PREFIX = "/api/assets/", ROUTES;
|
|
30256
|
-
var init_constants3 = __esm(() => {
|
|
30257
|
-
init_src();
|
|
30258
|
-
ROUTES = {
|
|
30259
|
-
INDEX: "/api",
|
|
30260
|
-
HEALTH: "/api/health",
|
|
30261
|
-
ASSETS: `${ASSET_ROUTE_PREFIX}*`,
|
|
30262
|
-
TIMEBACK: {
|
|
30263
|
-
END_ACTIVITY: `/api${TIMEBACK_ROUTES.END_ACTIVITY}`,
|
|
30264
|
-
GET_XP: `/api${TIMEBACK_ROUTES.GET_XP}`,
|
|
30265
|
-
GET_MASTERY: `/api${TIMEBACK_ROUTES.GET_MASTERY}`,
|
|
30266
|
-
GET_HIGHEST_GRADE_MASTERED: `/api${TIMEBACK_ROUTES.GET_HIGHEST_GRADE_MASTERED}`,
|
|
30267
|
-
HEARTBEAT: `/api${TIMEBACK_ROUTES.HEARTBEAT}`,
|
|
30268
|
-
ADVANCE_COURSE: `/api${TIMEBACK_ROUTES.ADVANCE_COURSE}`,
|
|
30269
|
-
UNENROLL_COURSE: `/api${TIMEBACK_ROUTES.UNENROLL_COURSE}`
|
|
30270
|
-
}
|
|
30271
|
-
};
|
|
30272
|
-
});
|
|
30273
|
-
// ../edge-play/src/entry/setup.ts
|
|
31039
|
+
// ../edge-play/src/game/setup.ts
|
|
30274
31040
|
function prefixSecrets(secrets) {
|
|
30275
31041
|
const prefixed = {};
|
|
30276
31042
|
for (const [key, value] of Object.entries(secrets)) {
|
|
@@ -30280,7 +31046,6 @@ function prefixSecrets(secrets) {
|
|
|
30280
31046
|
}
|
|
30281
31047
|
var init_setup2 = __esm(() => {
|
|
30282
31048
|
init_src();
|
|
30283
|
-
init_constants3();
|
|
30284
31049
|
});
|
|
30285
31050
|
|
|
30286
31051
|
// ../api-core/src/services/seed.service.ts
|
|
@@ -30315,7 +31080,7 @@ class SeedService {
|
|
|
30315
31080
|
async seed(slug, code, user, secrets) {
|
|
30316
31081
|
const cf = this.getCloudflare();
|
|
30317
31082
|
const game2 = await this.deps.validateDeveloperAccessBySlug(user, slug);
|
|
30318
|
-
const deploymentId =
|
|
31083
|
+
const deploymentId = getGameDeploymentId(slug, this.deps.config.sstStage);
|
|
30319
31084
|
const uniqueSuffix = Date.now().toString(36);
|
|
30320
31085
|
const seedDeploymentId = `seed-${deploymentId}-${uniqueSuffix}`;
|
|
30321
31086
|
setAttributes({
|
|
@@ -30806,7 +31571,7 @@ var init_emoji = __esm(() => {
|
|
|
30806
31571
|
});
|
|
30807
31572
|
|
|
30808
31573
|
// ../data/src/domains/game/schemas.ts
|
|
30809
|
-
var HttpUrlSchema, GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SeedRequestSchema, SchemaInfoSchema, DatabaseResetRequestSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployRequestSchema;
|
|
31574
|
+
var HttpUrlSchema, GameEmojiSchema, GameMetadataRecordSchema, InsertGameSchema, UpdateGameSchema, InsertGameDeploymentSchema, InsertGameDeployJobSchema, UpsertGameMetadataSchema, PatchGameMetadataSchema, AddGameMemberSchema, UpdateGameMemberRoleSchema, AddGameDashboardUserSchema, VerifyGameDashboardLoginSchema, AcceptGameDashboardInviteSchema, AcceptGameDashboardResetSchema, ALLOWED_UPLOAD_EXTENSIONS, InitiateUploadSchema, AddCustomHostnameSchema, SetSecretsRequestSchema, SeedRequestSchema, SchemaInfoSchema, DatabaseResetRequestSchema, VerifyTokenSchema, KVSeedRequestSchema, DeployRequestSchema;
|
|
30810
31575
|
var init_schemas2 = __esm(() => {
|
|
30811
31576
|
init_drizzle_zod();
|
|
30812
31577
|
init_esm();
|
|
@@ -30917,6 +31682,20 @@ var init_schemas2 = __esm(() => {
|
|
|
30917
31682
|
UpdateGameMemberRoleSchema = exports_external.object({
|
|
30918
31683
|
role: exports_external.enum(gameMemberRoleEnum.enumValues)
|
|
30919
31684
|
}).strict();
|
|
31685
|
+
AddGameDashboardUserSchema = exports_external.object({
|
|
31686
|
+
email: exports_external.string().email().max(255),
|
|
31687
|
+
displayName: exports_external.string().min(1).max(255).optional(),
|
|
31688
|
+
role: exports_external.enum(gameDashboardUserRoleEnum.enumValues).optional().default(DASHBOARD_USER_ROLES.VIEWER)
|
|
31689
|
+
}).strict();
|
|
31690
|
+
VerifyGameDashboardLoginSchema = exports_external.object({
|
|
31691
|
+
email: exports_external.string().email().max(255),
|
|
31692
|
+
password: exports_external.string().min(1).max(1024)
|
|
31693
|
+
}).strict();
|
|
31694
|
+
AcceptGameDashboardInviteSchema = exports_external.object({
|
|
31695
|
+
token: exports_external.string().min(1).max(255),
|
|
31696
|
+
password: exports_external.string().min(8, "Password must be at least 8 characters").max(1024, "Password must be at most 1024 characters")
|
|
31697
|
+
}).strict();
|
|
31698
|
+
AcceptGameDashboardResetSchema = AcceptGameDashboardInviteSchema;
|
|
30920
31699
|
ALLOWED_UPLOAD_EXTENSIONS = [".zip", ".js"];
|
|
30921
31700
|
InitiateUploadSchema = exports_external.object({
|
|
30922
31701
|
fileName: exports_external.string().min(1).refine((name2) => ALLOWED_UPLOAD_EXTENSIONS.some((ext) => name2.endsWith(ext)), {
|
|
@@ -30951,6 +31730,7 @@ var init_schemas2 = __esm(() => {
|
|
|
30951
31730
|
}))
|
|
30952
31731
|
});
|
|
30953
31732
|
DeployRequestSchema = exports_external.object({
|
|
31733
|
+
target: exports_external.enum(deploymentTargetEnum.enumValues).optional().default("game"),
|
|
30954
31734
|
uploadToken: exports_external.string().optional(),
|
|
30955
31735
|
code: exports_external.string().optional(),
|
|
30956
31736
|
codeUploadToken: exports_external.string().optional(),
|
|
@@ -30986,6 +31766,9 @@ var init_schemas2 = __esm(() => {
|
|
|
30986
31766
|
}).refine((data) => !(data.code && data.codeUploadToken), {
|
|
30987
31767
|
message: "Specify either code or codeUploadToken, not both",
|
|
30988
31768
|
path: ["codeUploadToken"]
|
|
31769
|
+
}).refine((data) => !(data.target === "dashboard" && (data.schema || data.bindings)), {
|
|
31770
|
+
message: "Dashboard deployments cannot include schema or bindings — they attach to the game deployment’s existing resources",
|
|
31771
|
+
path: ["target"]
|
|
30989
31772
|
});
|
|
30990
31773
|
});
|
|
30991
31774
|
|
|
@@ -74417,6 +75200,17 @@ function isValidUUID(value) {
|
|
|
74417
75200
|
}
|
|
74418
75201
|
return UUID_REGEX.test(value);
|
|
74419
75202
|
}
|
|
75203
|
+
async function deterministicUUID(input) {
|
|
75204
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
|
|
75205
|
+
const bytes = new Uint8Array(digest).slice(0, 16);
|
|
75206
|
+
bytes[6] = bytes[6] & 15 | 80;
|
|
75207
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
75208
|
+
const hex3 = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
75209
|
+
return `${hex3.slice(0, 8)}-${hex3.slice(8, 12)}-${hex3.slice(12, 16)}-${hex3.slice(16, 20)}-${hex3.slice(20)}`;
|
|
75210
|
+
}
|
|
75211
|
+
async function localGameId(slug) {
|
|
75212
|
+
return deterministicUUID(`playcademy:local-game:${slug}`);
|
|
75213
|
+
}
|
|
74420
75214
|
var UUID_REGEX;
|
|
74421
75215
|
var init_uuid2 = __esm(() => {
|
|
74422
75216
|
UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
@@ -76818,7 +77612,7 @@ function deriveTimebackCourseLevelFromGrade(grade) {
|
|
|
76818
77612
|
return TIMEBACK_COURSE_DEFAULTS.level.high;
|
|
76819
77613
|
}
|
|
76820
77614
|
var ONEROSTER_STATUS2, SCORE_STATUS2, CACHE_DEFAULTS3, RESOURCE_DEFAULTS3;
|
|
76821
|
-
var
|
|
77615
|
+
var init_constants3 = __esm(() => {
|
|
76822
77616
|
init_src();
|
|
76823
77617
|
ONEROSTER_STATUS2 = {
|
|
76824
77618
|
active: "active",
|
|
@@ -77792,7 +78586,7 @@ function qtiIdCandidates(parentLineItem, resource) {
|
|
|
77792
78586
|
}
|
|
77793
78587
|
var GRADE_LEVEL_TEST_TYPES, naturalTitleSort;
|
|
77794
78588
|
var init_timeback_grade_level_results_util = __esm(() => {
|
|
77795
|
-
|
|
78589
|
+
init_constants3();
|
|
77796
78590
|
GRADE_LEVEL_TEST_TYPES = [
|
|
77797
78591
|
"placement",
|
|
77798
78592
|
"test out",
|
|
@@ -77987,7 +78781,7 @@ async function upsertMasteryCompletionEntry(params) {
|
|
|
77987
78781
|
}
|
|
77988
78782
|
var init_timeback_mastery_completion_util = __esm(async () => {
|
|
77989
78783
|
init_spans();
|
|
77990
|
-
|
|
78784
|
+
init_constants3();
|
|
77991
78785
|
init_utils6();
|
|
77992
78786
|
await init_errors8();
|
|
77993
78787
|
});
|
|
@@ -78683,7 +79477,7 @@ class TimebackAdminService {
|
|
|
78683
79477
|
columns: { slug: true }
|
|
78684
79478
|
}),
|
|
78685
79479
|
this.deps.db.query.gameDeployments.findFirst({
|
|
78686
|
-
where:
|
|
79480
|
+
where: activeDeploymentWhere(gameId),
|
|
78687
79481
|
columns: { url: true }
|
|
78688
79482
|
})
|
|
78689
79483
|
]);
|
|
@@ -79764,7 +80558,7 @@ var init_timeback_admin_service = __esm(async () => {
|
|
|
79764
80558
|
init_schemas_index();
|
|
79765
80559
|
init_tables_index();
|
|
79766
80560
|
init_spans();
|
|
79767
|
-
|
|
80561
|
+
init_constants3();
|
|
79768
80562
|
init_types2();
|
|
79769
80563
|
init_utils6();
|
|
79770
80564
|
init_src4();
|
|
@@ -80239,7 +81033,7 @@ function timebackConfigMatchesCreateIntegrationRequest(config4, request) {
|
|
|
80239
81033
|
return subject === request.subject && grade === request.grade && config4.course.title === request.title && config4.course.courseCode === request.courseCode && config4.course.level === requestedLevel && (getTotalXpFromTimebackConfig(config4) ?? null) === request.totalXp && (getMasterableUnitsFromTimebackConfig(config4) ?? null) === request.masterableUnits;
|
|
80240
81034
|
}
|
|
80241
81035
|
var init_timeback_create_integration_util = __esm(() => {
|
|
80242
|
-
|
|
81036
|
+
init_constants3();
|
|
80243
81037
|
init_types2();
|
|
80244
81038
|
init_timeback_util();
|
|
80245
81039
|
});
|
|
@@ -83085,6 +83879,19 @@ function createSandboxAuthProvider() {
|
|
|
83085
83879
|
}
|
|
83086
83880
|
return null;
|
|
83087
83881
|
},
|
|
83882
|
+
async deleteApiKeysByName(name3) {
|
|
83883
|
+
const deleted = [];
|
|
83884
|
+
for (const [id, key] of sandboxApiKeys.entries()) {
|
|
83885
|
+
if (key.name === name3) {
|
|
83886
|
+
sandboxApiKeys.delete(id);
|
|
83887
|
+
deleted.push(id);
|
|
83888
|
+
}
|
|
83889
|
+
}
|
|
83890
|
+
if (deleted.length > 0) {
|
|
83891
|
+
log.debug("[SandboxAuthProvider] Deleted API keys by name", { name: name3, deleted });
|
|
83892
|
+
}
|
|
83893
|
+
return deleted;
|
|
83894
|
+
},
|
|
83088
83895
|
async mintGameToken(gameId, userId) {
|
|
83089
83896
|
const header = btoa(JSON.stringify({ alg: "none", typ: "sandbox" }));
|
|
83090
83897
|
const exp = Date.now() + 15 * 60 * 1000;
|
|
@@ -83163,6 +83970,12 @@ function createSandboxAuthProvider() {
|
|
|
83163
83970
|
} catch {
|
|
83164
83971
|
return null;
|
|
83165
83972
|
}
|
|
83973
|
+
},
|
|
83974
|
+
async hashPassword(password) {
|
|
83975
|
+
return `sandbox:${btoa(password)}`;
|
|
83976
|
+
},
|
|
83977
|
+
async verifyPassword(data) {
|
|
83978
|
+
return data.hash === `sandbox:${btoa(data.password)}`;
|
|
83166
83979
|
}
|
|
83167
83980
|
};
|
|
83168
83981
|
}
|
|
@@ -83447,7 +84260,7 @@ var init_http_exception = () => {};
|
|
|
83447
84260
|
|
|
83448
84261
|
// ../../node_modules/.bun/hono@4.10.7/node_modules/hono/dist/request/constants.js
|
|
83449
84262
|
var GET_MATCH_RESULT;
|
|
83450
|
-
var
|
|
84263
|
+
var init_constants4 = __esm(() => {
|
|
83451
84264
|
GET_MATCH_RESULT = Symbol();
|
|
83452
84265
|
});
|
|
83453
84266
|
|
|
@@ -83711,7 +84524,7 @@ var init_url = __esm(() => {
|
|
|
83711
84524
|
var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_), HonoRequest;
|
|
83712
84525
|
var init_request = __esm(() => {
|
|
83713
84526
|
init_http_exception();
|
|
83714
|
-
|
|
84527
|
+
init_constants4();
|
|
83715
84528
|
init_body();
|
|
83716
84529
|
init_url();
|
|
83717
84530
|
HonoRequest = class {
|
|
@@ -84041,7 +84854,7 @@ var init_router = __esm(() => {
|
|
|
84041
84854
|
|
|
84042
84855
|
// ../../node_modules/.bun/hono@4.10.7/node_modules/hono/dist/utils/constants.js
|
|
84043
84856
|
var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
|
|
84044
|
-
var
|
|
84857
|
+
var init_constants5 = () => {};
|
|
84045
84858
|
|
|
84046
84859
|
// ../../node_modules/.bun/hono@4.10.7/node_modules/hono/dist/hono-base.js
|
|
84047
84860
|
var notFoundHandler = (c) => {
|
|
@@ -84263,7 +85076,7 @@ var init_hono_base = __esm(() => {
|
|
|
84263
85076
|
init_compose();
|
|
84264
85077
|
init_context2();
|
|
84265
85078
|
init_router();
|
|
84266
|
-
|
|
85079
|
+
init_constants5();
|
|
84267
85080
|
init_url();
|
|
84268
85081
|
});
|
|
84269
85082
|
|
|
@@ -92933,7 +93746,7 @@ var require_node3 = __commonJS((exports) => {
|
|
|
92933
93746
|
exports2.isAbsolute = function(aPath) {
|
|
92934
93747
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
92935
93748
|
};
|
|
92936
|
-
function
|
|
93749
|
+
function relative2(aRoot, aPath) {
|
|
92937
93750
|
if (aRoot === "") {
|
|
92938
93751
|
aRoot = ".";
|
|
92939
93752
|
}
|
|
@@ -92952,7 +93765,7 @@ var require_node3 = __commonJS((exports) => {
|
|
|
92952
93765
|
}
|
|
92953
93766
|
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
|
92954
93767
|
}
|
|
92955
|
-
exports2.relative =
|
|
93768
|
+
exports2.relative = relative2;
|
|
92956
93769
|
var supportsNullProto = function() {
|
|
92957
93770
|
var obj = Object.create(null);
|
|
92958
93771
|
return !("__proto__" in obj);
|
|
@@ -94983,7 +95796,7 @@ If you have no idea what this means or what Pirates is, let me explain: Pirates
|
|
|
94983
95796
|
});
|
|
94984
95797
|
};
|
|
94985
95798
|
}
|
|
94986
|
-
var
|
|
95799
|
+
var readFile2 = (fp) => new Promise((resolve2, reject) => {
|
|
94987
95800
|
_fs.default.readFile(fp, "utf8", (err2, data) => {
|
|
94988
95801
|
if (err2)
|
|
94989
95802
|
return reject(err2);
|
|
@@ -95181,7 +95994,7 @@ If you have no idea what this means or what Pirates is, let me explain: Pirates
|
|
|
95181
95994
|
data: _this3.packageJsonCache.get(filepath)[options.packageKey]
|
|
95182
95995
|
};
|
|
95183
95996
|
}
|
|
95184
|
-
const data = _this3.options.parseJSON(yield
|
|
95997
|
+
const data = _this3.options.parseJSON(yield readFile2(filepath));
|
|
95185
95998
|
return {
|
|
95186
95999
|
path: filepath,
|
|
95187
96000
|
data
|
|
@@ -95189,7 +96002,7 @@ If you have no idea what this means or what Pirates is, let me explain: Pirates
|
|
|
95189
96002
|
}
|
|
95190
96003
|
return {
|
|
95191
96004
|
path: filepath,
|
|
95192
|
-
data: yield
|
|
96005
|
+
data: yield readFile2(filepath)
|
|
95193
96006
|
};
|
|
95194
96007
|
}
|
|
95195
96008
|
return {};
|
|
@@ -100234,7 +101047,7 @@ var __create2, __defProp2, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf2,
|
|
|
100234
101047
|
__defProp2(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
|
|
100235
101048
|
}
|
|
100236
101049
|
return to;
|
|
100237
|
-
}, __toESM5 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod)), __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value), ANSI_BACKGROUND_OFFSET, wrapAnsi16, wrapAnsi256, wrapAnsi16m, styles2, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default, init_ansi_styles, env, flagForceColor, supportsColor, supports_color_default, init_supports_color, init_utilities, stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles22, applyOptions, chalkFactory, getModelAnsi, usedModels, proto, createStyler, createBuilder, applyStyle, chalk, chalkStderr, source_default, init_source, require_old, require_fs, require_path, require_balanced_match, require_brace_expansion, require_minimatch, require_inherits_browser2, require_inherits2, require_common3, require_sync, require_wrappy, require_once, require_inflight, require_glob, require_readline, require_src3, require_utils4, require_lodash, require_hanji, originUUID, snapshotVersion, mapValues, mapKeys, mapEntries, customMapEntries, init_global2, util3, objectUtil2, ZodParsedType2, getParsedType4, init_util4, ZodIssueCode4, ZodError5, init_ZodError2, errorMap2, en_default4, init_en4, overrideErrorMap2, init_errors9, makeIssue2, ParseStatus2, INVALID3, DIRTY2, OK2, isAborted2, isDirty2, isValid2, isAsync2, init_parseUtil2, init_typeAliases2, errorUtil2, init_errorUtil2, ParseInputLazyPath2, handleResult2, ZodType4, cuidRegex2, cuid2Regex2, ulidRegex2, uuidRegex2, nanoidRegex2, jwtRegex2, durationRegex2, emailRegex2, _emojiRegex2, emojiRegex2, ipv4Regex2, ipv4CidrRegex2, ipv6Regex2, ipv6CidrRegex2, base64Regex2, base64urlRegex2, dateRegexSource2, dateRegex2, ZodString4, ZodNumber4, ZodBigInt4, ZodBoolean4, ZodDate4, ZodSymbol4, ZodUndefined4, ZodNull4, ZodAny4, ZodUnknown4, ZodNever4, ZodVoid4, ZodArray4, ZodObject4, ZodUnion4, getDiscriminator2, ZodDiscriminatedUnion4, ZodIntersection4, ZodTuple4, ZodRecord4, ZodMap4, ZodSet4, ZodFunction3, ZodLazy4, ZodLiteral4, ZodEnum4, ZodNativeEnum2, ZodPromise4, ZodEffects2, ZodOptional4, ZodNullable4, ZodDefault4, ZodCatch4, ZodNaN4, BRAND2, ZodBranded2, ZodPipeline2, ZodReadonly4, late2, ZodFirstPartyTypeKind3, stringType2, numberType2, nanType2, bigIntType2, booleanType2, dateType2, symbolType2, undefinedType2, nullType2, anyType2, unknownType2, neverType2, voidType2, arrayType2, objectType2, strictObjectType2, unionType2, discriminatedUnionType2, intersectionType2, tupleType2, recordType2, mapType2, setType2, functionType2, lazyType2, literalType2, enumType2, nativeEnumType2, promiseType2, effectsType2, optionalType2, nullableType2, preprocessType2, pipelineType2, coerce2, init_types5, init_external4, init_v32, init_esm2, enumSchema, enumSchemaV1, indexColumn, index2, fk, sequenceSchema, roleSchema, sequenceSquashed, column2, checkConstraint, columnSquashed, compositePK, uniqueConstraint, policy, policySquashed, viewWithOption, matViewWithOption, mergedViewWithOption, view2, table8, schemaHash, kitInternals, gelSchemaExternal, gelSchemaInternal, tableSquashed, gelSchemaSquashed, gelSchema, dryGel, init_gelSchema, index22, fk2, column22, tableV3, compositePK2, uniqueConstraint2, checkConstraint2, tableV4, table22, viewMeta, view22, kitInternals2, dialect2, schemaHash2, schemaInternalV3, schemaInternalV4, schemaInternalV5, schemaInternal, schemaV3, schemaV4, schemaV5, schema2, tableSquashedV4, tableSquashed2, viewSquashed, schemaSquashed, schemaSquashedV4, MySqlSquasher, squashMysqlScheme, mysqlSchema, mysqlSchemaV5, mysqlSchemaSquashed, backwardCompatibleMysqlSchema, dryMySql, init_mysqlSchema, indexV2, columnV2, tableV2, enumSchemaV12, enumSchema2, pgSchemaV2, references, columnV1, tableV1, pgSchemaV1, indexColumn2, index3, indexV4, indexV5, indexV6, fk3, sequenceSchema2, roleSchema2, sequenceSquashed2, columnV7, column3, checkConstraint3, columnSquashed2, tableV32, compositePK3, uniqueConstraint3, policy2, policySquashed2, viewWithOption2, matViewWithOption2, mergedViewWithOption2, view3, tableV42, tableV5, tableV6, tableV7, table32, schemaHash3, kitInternals3, pgSchemaInternalV3, pgSchemaInternalV4, pgSchemaInternalV5, pgSchemaInternalV6, pgSchemaExternal, pgSchemaInternalV7, pgSchemaInternal, tableSquashed3, tableSquashedV42, pgSchemaSquashedV4, pgSchemaSquashedV6, pgSchemaSquashed, pgSchemaV3, pgSchemaV4, pgSchemaV5, pgSchemaV6, pgSchemaV7, pgSchema, backwardCompatiblePgSchema, PgSquasher, squashPgScheme, dryPg, init_pgSchema, index4, column4, compositePK4, uniqueConstraint4, table42, viewMeta2, kitInternals4, dialect22, schemaHash4, schemaInternal2, schema22, tableSquashed4, schemaSquashed2, SingleStoreSquasher, squashSingleStoreScheme, singlestoreSchema, singlestoreSchemaSquashed, backwardCompatibleSingleStoreSchema, drySingleStore, init_singlestoreSchema, index5, fk4, compositePK5, column5, tableV33, uniqueConstraint5, checkConstraint4, table52, view4, dialect3, schemaHash5, schemaInternalV32, schemaInternalV42, schemaInternalV52, kitInternals5, latestVersion, schemaInternal3, schemaV32, schemaV42, schemaV52, schema3, tableSquashed5, schemaSquashed3, SQLiteSquasher, squashSqliteScheme, drySQLite, sqliteSchemaV5, sqliteSchema, SQLiteSchemaSquashed, backwardCompatibleSqliteSchema, init_sqliteSchema, copy, prepareMigrationMeta, schemaRenameKey, tableRenameKey, columnRenameKey, init_utils7, import_hanji, warning, error88, isRenamePromptItem, ResolveColumnSelect, tableKey, ResolveSelectNamed, ResolveSelect, ResolveSchemasSelect, Spinner2, ProgressView, init_views, glob, init_serializer, fillPgSnapshot, init_migrationPreparator, require_heap, require_heap2, require_difflib, require_difflib2, require_util2, require_styles, require_has_flag2, require_supports_colors, require_trap, require_zalgo, require_america, require_zebra, require_rainbow, require_random, require_colors, require_safe, require_colorize, require_lib4, import_json_diff, mapArraysDiff, findAlternationsInTable, alternationsInColumn, init_jsonDiffer, parseType, Convertor, PgCreateRoleConvertor, PgDropRoleConvertor, PgRenameRoleConvertor, PgAlterRoleConvertor, PgCreatePolicyConvertor, PgDropPolicyConvertor, PgRenamePolicyConvertor, PgAlterPolicyConvertor, PgCreateIndPolicyConvertor, PgDropIndPolicyConvertor, PgRenameIndPolicyConvertor, PgAlterIndPolicyConvertor, PgEnableRlsConvertor, PgDisableRlsConvertor, PgCreateTableConvertor, MySqlCreateTableConvertor, SingleStoreCreateTableConvertor, SQLiteCreateTableConvertor, PgCreateViewConvertor, MySqlCreateViewConvertor, SqliteCreateViewConvertor, PgDropViewConvertor, MySqlDropViewConvertor, SqliteDropViewConvertor, MySqlAlterViewConvertor, PgRenameViewConvertor, MySqlRenameViewConvertor, PgAlterViewSchemaConvertor, PgAlterViewAddWithOptionConvertor, PgAlterViewDropWithOptionConvertor, PgAlterViewAlterTablespaceConvertor, PgAlterViewAlterUsingConvertor, PgAlterTableAlterColumnSetGenerated, PgAlterTableAlterColumnDropGenerated, PgAlterTableAlterColumnAlterGenerated, PgAlterTableAddUniqueConstraintConvertor, PgAlterTableDropUniqueConstraintConvertor, PgAlterTableAddCheckConstraintConvertor, PgAlterTableDeleteCheckConstraintConvertor, MySQLAlterTableAddUniqueConstraintConvertor, MySQLAlterTableDropUniqueConstraintConvertor, MySqlAlterTableAddCheckConstraintConvertor, SingleStoreAlterTableAddUniqueConstraintConvertor, SingleStoreAlterTableDropUniqueConstraintConvertor, MySqlAlterTableDeleteCheckConstraintConvertor, CreatePgSequenceConvertor, DropPgSequenceConvertor, RenamePgSequenceConvertor, MovePgSequenceConvertor, AlterPgSequenceConvertor, CreateTypeEnumConvertor, DropTypeEnumConvertor, AlterTypeAddValueConvertor, AlterTypeSetSchemaConvertor, AlterRenameTypeConvertor, AlterTypeDropValueConvertor, PgDropTableConvertor, MySQLDropTableConvertor, SingleStoreDropTableConvertor, SQLiteDropTableConvertor, PgRenameTableConvertor, SqliteRenameTableConvertor, MySqlRenameTableConvertor, SingleStoreRenameTableConvertor, PgAlterTableRenameColumnConvertor, MySqlAlterTableRenameColumnConvertor, SingleStoreAlterTableRenameColumnConvertor, SQLiteAlterTableRenameColumnConvertor, PgAlterTableDropColumnConvertor, MySqlAlterTableDropColumnConvertor, SingleStoreAlterTableDropColumnConvertor, SQLiteAlterTableDropColumnConvertor, PgAlterTableAddColumnConvertor, MySqlAlterTableAddColumnConvertor, SingleStoreAlterTableAddColumnConvertor, SQLiteAlterTableAddColumnConvertor, PgAlterTableAlterColumnSetTypeConvertor, PgAlterTableAlterColumnSetDefaultConvertor, PgAlterTableAlterColumnDropDefaultConvertor, PgAlterTableAlterColumnDropGeneratedConvertor, PgAlterTableAlterColumnSetExpressionConvertor, PgAlterTableAlterColumnAlterrGeneratedConvertor, SqliteAlterTableAlterColumnDropGeneratedConvertor, SqliteAlterTableAlterColumnSetExpressionConvertor, SqliteAlterTableAlterColumnAlterGeneratedConvertor, MySqlAlterTableAlterColumnAlterrGeneratedConvertor, MySqlAlterTableAddPk, MySqlAlterTableDropPk, LibSQLModifyColumn, MySqlModifyColumn, SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor, SingleStoreAlterTableAddPk, SingleStoreAlterTableDropPk, SingleStoreModifyColumn, PgAlterTableCreateCompositePrimaryKeyConvertor, PgAlterTableDeleteCompositePrimaryKeyConvertor, PgAlterTableAlterCompositePrimaryKeyConvertor, MySqlAlterTableCreateCompositePrimaryKeyConvertor, MySqlAlterTableDeleteCompositePrimaryKeyConvertor, MySqlAlterTableAlterCompositePrimaryKeyConvertor, PgAlterTableAlterColumnSetPrimaryKeyConvertor, PgAlterTableAlterColumnDropPrimaryKeyConvertor, PgAlterTableAlterColumnSetNotNullConvertor, PgAlterTableAlterColumnDropNotNullConvertor, PgCreateForeignKeyConvertor, LibSQLCreateForeignKeyConvertor, MySqlCreateForeignKeyConvertor, PgAlterForeignKeyConvertor, PgDeleteForeignKeyConvertor, MySqlDeleteForeignKeyConvertor, CreatePgIndexConvertor, CreateMySqlIndexConvertor, CreateSingleStoreIndexConvertor, CreateSqliteIndexConvertor, PgDropIndexConvertor, PgCreateSchemaConvertor, PgRenameSchemaConvertor, PgDropSchemaConvertor, PgAlterTableSetSchemaConvertor, PgAlterTableSetNewSchemaConvertor, PgAlterTableRemoveFromSchemaConvertor, SqliteDropIndexConvertor, MySqlDropIndexConvertor, SingleStoreDropIndexConvertor, SQLiteRecreateTableConvertor, LibSQLRecreateTableConvertor, SingleStoreRecreateTableConvertor, convertors, init_sqlgenerator, _moveDataStatements, getOldTableName, getNewTableName, logSuggestionsAndReturn, init_sqlitePushUtils, preparePgCreateTableJson, prepareMySqlCreateTableJson, prepareSingleStoreCreateTableJson, prepareSQLiteCreateTable, prepareDropTableJson, prepareRenameTableJson, prepareCreateEnumJson, prepareAddValuesToEnumJson, prepareDropEnumValues, prepareDropEnumJson, prepareMoveEnumJson, prepareRenameEnumJson, prepareCreateSequenceJson, prepareAlterSequenceJson, prepareDropSequenceJson, prepareMoveSequenceJson, prepareRenameSequenceJson, prepareCreateRoleJson, prepareAlterRoleJson, prepareDropRoleJson, prepareRenameRoleJson, prepareCreateSchemasJson, prepareRenameSchemasJson, prepareDeleteSchemasJson, prepareRenameColumns, _prepareDropColumns, _prepareAddColumns, _prepareSqliteAddColumns, prepareAlterColumnsMysql, preparePgAlterColumns, prepareSqliteAlterColumns, prepareRenamePolicyJsons, prepareRenameIndPolicyJsons, prepareCreatePolicyJsons, prepareCreateIndPolicyJsons, prepareDropPolicyJsons, prepareDropIndPolicyJsons, prepareAlterPolicyJson, prepareAlterIndPolicyJson, preparePgCreateIndexesJson, prepareCreateIndexesJson, prepareCreateReferencesJson, prepareLibSQLCreateReferencesJson, prepareDropReferencesJson, prepareLibSQLDropReferencesJson, prepareAlterReferencesJson, prepareDropIndexesJson, prepareAddCompositePrimaryKeySqlite, prepareDeleteCompositePrimaryKeySqlite, prepareAlterCompositePrimaryKeySqlite, prepareAddCompositePrimaryKeyPg, prepareDeleteCompositePrimaryKeyPg, prepareAlterCompositePrimaryKeyPg, prepareAddUniqueConstraintPg, prepareDeleteUniqueConstraintPg, prepareAddCheckConstraint, prepareDeleteCheckConstraint, prepareAddCompositePrimaryKeyMySql, prepareDeleteCompositePrimaryKeyMySql, prepareAlterCompositePrimaryKeyMySql, preparePgCreateViewJson, prepareMySqlCreateViewJson, prepareSqliteCreateViewJson, prepareDropViewJson, prepareRenameViewJson, preparePgAlterViewAlterSchemaJson, preparePgAlterViewAddWithOptionJson, preparePgAlterViewDropWithOptionJson, preparePgAlterViewAlterTablespaceJson, preparePgAlterViewAlterUsingJson, prepareMySqlAlterView, init_jsonStatements, prepareLibSQLRecreateTable, prepareSQLiteRecreateTable, libSQLCombineStatements, sqliteCombineStatements, prepareSingleStoreRecreateTable, singleStoreCombineStatements, init_statementCombiner, snapshotsDiffer_exports, makeChanged, makeSelfOrChanged, makePatched, makeSelfOrPatched, columnSchema, alteredColumnSchema, enumSchema3, changedEnumSchema, tableScheme, alteredTableScheme, alteredViewCommon, alteredPgViewSchema, alteredMySqlViewSchema, diffResultScheme, diffResultSchemeMysql, diffResultSchemeSingleStore, diffResultSchemeSQLite, schemaChangeFor, nameChangeFor, nameSchemaChangeFor, columnChangeFor, applyPgSnapshotsDiff, applyMysqlSnapshotsDiff, applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff, applyLibSQLSnapshotsDiff, init_snapshotsDiffer, init_words, dialects, dialect4, commonSquashedSchema, commonSchema, init_schemaValidator, sqliteDriversLiterals, postgresqlDriversLiterals, prefixes, prefix, casingTypes, casingType, sqliteDriver, postgresDriver, driver2, configMigrations, configCommonSchema, casing, introspectParams, configIntrospectCliSchema, configGenerateSchema, configPushSchema, init_common2, withStyle, init_outputs, import_hanji2, schemasResolver, tablesResolver, viewsResolver, mySqlViewsResolver, sqliteViewsResolver, sequencesResolver, roleResolver, policyResolver, indPolicyResolver, enumsResolver, columnsResolver, promptColumnsConflicts, promptNamedConflict, promptNamedWithSchemasConflict, promptSchemasConflict, BREAKPOINT, init_migrate, posixClasses, braceEscape, regexpEscape, rangesToString, parseClass, init_brace_expressions, escape, init_escape, unescape, init_unescape, import_brace_expansion, minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path, sep, GLOBSTAR, plTypes, qmark, star, twoStarDot, twoStarNoDot, charSet, reSpecials, addPatternStartSet, filter, ext, defaults, braceExpand, MAX_PATTERN_LENGTH, assertValidPattern, makeRe, match2, globUnescape, globMagic, regExpEscape, Minimatch, init_mjs, entityKind2, hasOwnEntityKind2, init_entity2, _a3, Column2, init_column2, _a22, ColumnBuilder2, init_column_builder2, TableName2, init_table_utils2, _a32, ForeignKeyBuilder2, _a4, ForeignKey2, init_foreign_keys2, init_tracing_utils2, _a5, UniqueConstraintBuilder, _a6, UniqueOnConstraintBuilder, _a7, UniqueConstraint, init_unique_constraint2, init_array2, _a8, _b, PgColumnBuilder2, _a9, _b2, PgColumn2, _a10, _b3, ExtraConfigColumn2, _a11, IndexedColumn2, _a12, _b4, PgArrayBuilder2, _a13, _b5, _PgArray, PgArray2, init_common22, _a14, _b6, PgEnumObjectColumnBuilder2, _a15, _b7, PgEnumObjectColumn2, isPgEnumSym2, _a16, _b8, PgEnumColumnBuilder2, _a17, _b9, PgEnumColumn2, init_enum2, _a18, Subquery2, _a19, _b10, WithSubquery2, init_subquery2, version4, init_version2, otel2, rawTracer2, tracer2, init_tracing2, ViewBaseConfig2, init_view_common3, Schema2, Columns2, ExtraConfigColumns2, OriginalName2, BaseName2, IsAlias2, ExtraConfigBuilder2, IsDrizzleTable2, _a20, _b11, _c, _d, _e3, _f, _g, _h, _i, _j, Table2, init_table8, _a21, FakePrimitiveParam, _a222, StringChunk2, _a23, _SQL, SQL2, _a24, Name2, noopDecoder2, noopEncoder2, noopMapper2, _a25, Param2, _a26, Placeholder2, IsDrizzleView2, _a27, _b12, _c2, View3, init_sql3, _a28, ColumnAliasProxyHandler2, _a29, TableAliasProxyHandler2, _a30, RelationTableAliasProxyHandler, init_alias3, _a31, _b13, DrizzleError2, DrizzleQueryError, _a322, _b14, TransactionRollbackError2, init_errors22, _a33, ConsoleLogWriter2, _a34, DefaultLogger2, _a35, NoopLogger2, init_logger3, init_operations, _a36, _b15, QueryPromise2, init_query_promise2, textDecoder, init_utils22, _a37, _b16, PgIntColumnBaseBuilder2, init_int_common2, _a38, _b17, PgBigInt53Builder2, _a39, _b18, PgBigInt532, _a40, _b19, PgBigInt64Builder2, _a41, _b20, PgBigInt642, init_bigint2, _a42, _b21, PgBigSerial53Builder2, _a43, _b22, PgBigSerial532, _a44, _b23, PgBigSerial64Builder2, _a45, _b24, PgBigSerial642, init_bigserial2, _a46, _b25, PgBooleanBuilder2, _a47, _b26, PgBoolean2, init_boolean2, _a48, _b27, PgCharBuilder2, _a49, _b28, PgChar2, init_char2, _a50, _b29, PgCidrBuilder2, _a51, _b30, PgCidr2, init_cidr2, _a52, _b31, PgCustomColumnBuilder2, _a53, _b32, PgCustomColumn2, init_custom2, _a54, _b33, PgDateColumnBaseBuilder2, init_date_common2, _a55, _b34, PgDateBuilder2, _a56, _b35, PgDate2, _a57, _b36, PgDateStringBuilder2, _a58, _b37, PgDateString2, init_date2, _a59, _b38, PgDoublePrecisionBuilder2, _a60, _b39, PgDoublePrecision2, init_double_precision2, _a61, _b40, PgInetBuilder2, _a62, _b41, PgInet2, init_inet2, _a63, _b42, PgIntegerBuilder2, _a64, _b43, PgInteger2, init_integer2, _a65, _b44, PgIntervalBuilder2, _a66, _b45, PgInterval2, init_interval2, _a67, _b46, PgJsonBuilder2, _a68, _b47, PgJson2, init_json2, _a69, _b48, PgJsonbBuilder2, _a70, _b49, PgJsonb2, init_jsonb2, _a71, _b50, PgLineBuilder2, _a72, _b51, PgLineTuple2, _a73, _b52, PgLineABCBuilder2, _a74, _b53, PgLineABC2, init_line2, _a75, _b54, PgMacaddrBuilder2, _a76, _b55, PgMacaddr2, init_macaddr2, _a77, _b56, PgMacaddr8Builder2, _a78, _b57, PgMacaddr82, init_macaddr82, _a79, _b58, PgNumericBuilder2, _a80, _b59, PgNumeric2, _a81, _b60, PgNumericNumberBuilder2, _a82, _b61, PgNumericNumber2, _a83, _b62, PgNumericBigIntBuilder2, _a84, _b63, PgNumericBigInt2, init_numeric2, _a85, _b64, PgPointTupleBuilder2, _a86, _b65, PgPointTuple2, _a87, _b66, PgPointObjectBuilder2, _a88, _b67, PgPointObject2, init_point2, init_utils32, _a89, _b68, PgGeometryBuilder2, _a90, _b69, PgGeometry2, _a91, _b70, PgGeometryObjectBuilder2, _a92, _b71, PgGeometryObject2, init_geometry2, _a93, _b72, PgRealBuilder2, _a94, _b73, PgReal2, init_real2, _a95, _b74, PgSerialBuilder2, _a96, _b75, PgSerial2, init_serial2, _a97, _b76, PgSmallIntBuilder2, _a98, _b77, PgSmallInt2, init_smallint2, _a99, _b78, PgSmallSerialBuilder2, _a100, _b79, PgSmallSerial2, init_smallserial2, _a101, _b80, PgTextBuilder2, _a102, _b81, PgText2, init_text2, _a103, _b82, PgTimeBuilder2, _a104, _b83, PgTime2, init_time2, _a105, _b84, PgTimestampBuilder2, _a106, _b85, PgTimestamp2, _a107, _b86, PgTimestampStringBuilder2, _a108, _b87, PgTimestampString2, init_timestamp2, _a109, _b88, PgUUIDBuilder2, _a110, _b89, PgUUID2, init_uuid3, _a111, _b90, PgVarcharBuilder2, _a112, _b91, PgVarchar2, init_varchar2, _a113, _b92, PgBinaryVectorBuilder2, _a114, _b93, PgBinaryVector2, init_bit2, _a115, _b94, PgHalfVectorBuilder2, _a116, _b95, PgHalfVector2, init_halfvec2, _a117, _b96, PgSparseVectorBuilder2, _a118, _b97, PgSparseVector2, init_sparsevec2, _a119, _b98, PgVectorBuilder2, _a120, _b99, PgVector2, init_vector3, init_all2, InlineForeignKeys2, EnableRLS2, _a121, _b100, _c3, _d2, _e22, _f2, PgTable2, pgTable2, init_table22, _a122, PrimaryKeyBuilder2, _a123, PrimaryKey2, init_primary_keys2, eq2, ne4, gt3, gte2, lt4, lte2, init_conditions2, init_select3, init_expressions2, _a124, Relation2, _a125, Relations2, _a126, _b101, _One, One2, _a127, _b102, _Many, Many2, init_relations2, init_aggregate2, init_vector22, init_functions2, init_sql22, dist_exports, init_dist9, init_alias22, _a128, CheckBuilder, _a129, Check, init_checks6, init_columns2, _a130, _SelectionProxyHandler, SelectionProxyHandler2, init_selection_proxy2, _a131, IndexBuilderOn2, _a132, IndexBuilder2, _a133, Index2, init_indexes2, _a134, PgPolicy, init_policies2, PgViewConfig2, init_view_common22, _a135, CasingCache2, init_casing2, _a136, _b103, PgViewBase2, init_view_base2, _a137, PgDialect2, init_dialect2, _a138, TypedQueryBuilder2, init_query_builder3, _a139, PgSelectBuilder2, _a140, _b104, PgSelectQueryBuilderBase2, _a141, _b105, PgSelectBase2, getPgSetOperators2, union22, unionAll2, intersect2, intersectAll2, except2, exceptAll2, init_select22, _a142, QueryBuilder2, init_query_builder22, _a143, DefaultViewBuilderCore, _a144, _b106, ViewBuilder, _a145, _b107, ManualViewBuilder, _a146, MaterializedViewBuilderCore, _a147, _b108, MaterializedViewBuilder, _a148, _b109, ManualMaterializedViewBuilder, _a149, _b110, _c4, PgView2, PgMaterializedViewConfig2, _a150, _b111, _c5, PgMaterializedView, init_view2, init_utils42, _a151, _b112, PgDeleteBase2, init_delete2, _a152, PgInsertBuilder2, _a153, _b113, PgInsertBase2, init_insert2, _a154, _b114, PgRefreshMaterializedView2, init_refresh_materialized_view2, init_select_types, _a155, PgUpdateBuilder2, _a156, _b115, PgUpdateBase2, init_update2, init_query_builders2, _a157, _b116, _c6, _PgCountBuilder, PgCountBuilder2, init_count2, _a158, RelationalQueryBuilder2, _a159, _b117, PgRelationalQuery2, init_query2, _a160, _b118, PgRaw2, init_raw2, _a161, PgDatabase2, init_db2, _a162, PgRole, init_roles2, _a163, PgSequence, init_sequence2, _a164, PgSchema5, init_schema3, _a165, Cache, _a166, _b119, NoopCache, init_cache, _a167, PgPreparedQuery2, _a168, PgSession2, _a169, _b120, PgTransaction2, init_session3, init_subquery22, init_utils52, init_pg_core2, vectorOps, init_vector32, sqlToStr, init_utils62, indexName, generatePgSnapshot, trimChar, fromDatabase, defaultForColumn, getColumnsInfoQuery, init_pgSerializer, import_hanji4, Select, init_selector_ui, init_alias32, _a170, CheckBuilder2, _a171, Check2, init_checks22, _a172, ForeignKeyBuilder22, _a173, ForeignKey22, init_foreign_keys22, _a174, UniqueConstraintBuilder2, _a175, UniqueOnConstraintBuilder2, _a176, UniqueConstraint2, init_unique_constraint22, _a177, _b121, SQLiteColumnBuilder, _a178, _b122, SQLiteColumn, init_common3, _a179, _b123, SQLiteBigIntBuilder, _a180, _b124, SQLiteBigInt, _a181, _b125, SQLiteBlobJsonBuilder, _a182, _b126, SQLiteBlobJson, _a183, _b127, SQLiteBlobBufferBuilder, _a184, _b128, SQLiteBlobBuffer, init_blob, _a185, _b129, SQLiteCustomColumnBuilder, _a186, _b130, SQLiteCustomColumn, init_custom22, _a187, _b131, SQLiteBaseIntegerBuilder, _a188, _b132, SQLiteBaseInteger, _a189, _b133, SQLiteIntegerBuilder, _a190, _b134, SQLiteInteger, _a191, _b135, SQLiteTimestampBuilder, _a192, _b136, SQLiteTimestamp, _a193, _b137, SQLiteBooleanBuilder, _a194, _b138, SQLiteBoolean, init_integer22, _a195, _b139, SQLiteNumericBuilder, _a196, _b140, SQLiteNumeric, _a197, _b141, SQLiteNumericNumberBuilder, _a198, _b142, SQLiteNumericNumber, _a199, _b143, SQLiteNumericBigIntBuilder, _a200, _b144, SQLiteNumericBigInt, init_numeric22, _a201, _b145, SQLiteRealBuilder, _a202, _b146, SQLiteReal, init_real22, _a203, _b147, SQLiteTextBuilder, _a204, _b148, SQLiteText, _a205, _b149, SQLiteTextJsonBuilder, _a206, _b150, SQLiteTextJson, init_text22, init_columns22, init_all22, InlineForeignKeys22, _a207, _b151, _c7, _d3, _e32, SQLiteTable, sqliteTable, init_table32, _a208, IndexBuilderOn22, _a209, IndexBuilder22, _a210, Index4, init_indexes22, _a211, PrimaryKeyBuilder22, _a212, PrimaryKey22, init_primary_keys22, init_utils72, _a213, _b152, SQLiteDeleteBase, init_delete22, _a214, _b153, SQLiteViewBase, init_view_base22, _a215, SQLiteDialect, _a216, _b154, SQLiteSyncDialect, _a217, _b155, SQLiteAsyncDialect, init_dialect22, _a218, SQLiteSelectBuilder, _a219, _b156, SQLiteSelectQueryBuilderBase, _a220, _b157, SQLiteSelectBase, getSQLiteSetOperators, union32, unionAll22, intersect22, except22, init_select32, _a221, QueryBuilder22, init_query_builder32, _a2222, SQLiteInsertBuilder, _a223, _b158, SQLiteInsertBase, init_insert22, init_select_types2, _a224, SQLiteUpdateBuilder, _a225, _b159, SQLiteUpdateBase, init_update22, init_query_builders22, _a226, _b160, _c8, _SQLiteCountBuilder, SQLiteCountBuilder, init_count22, _a227, RelationalQueryBuilder22, _a228, _b161, SQLiteRelationalQuery, _a229, _b162, SQLiteSyncRelationalQuery, init_query22, _a230, _b163, SQLiteRaw, init_raw22, _a231, BaseSQLiteDatabase, init_db22, _a232, _b164, ExecuteResultSync, _a233, SQLitePreparedQuery, _a234, SQLiteSession, _a235, _b165, SQLiteTransaction, init_session22, init_subquery3, _a236, ViewBuilderCore, _a237, _b166, ViewBuilder2, _a238, _b167, ManualViewBuilder2, _a239, _b168, SQLiteView2, init_view22, init_sqlite_core, generateSqliteSnapshot, fromDatabase2, init_sqliteSerializer, getTablesFilterByExtensions, init_getTablesFilterByExtensions, init_alias4, _a240, CheckBuilder3, _a241, Check3, init_checks32, _a242, ForeignKeyBuilder3, _a243, ForeignKey3, init_foreign_keys3, _a244, UniqueConstraintBuilder3, _a245, UniqueOnConstraintBuilder3, _a246, UniqueConstraint3, init_unique_constraint3, _a247, _b169, MySqlColumnBuilder, _a248, _b170, MySqlColumn, _a249, _b171, MySqlColumnBuilderWithAutoIncrement, _a250, _b172, MySqlColumnWithAutoIncrement, init_common4, _a251, _b173, MySqlBigInt53Builder, _a252, _b174, MySqlBigInt53, _a253, _b175, MySqlBigInt64Builder, _a254, _b176, MySqlBigInt64, init_bigint22, _a255, _b177, MySqlBinaryBuilder, _a256, _b178, MySqlBinary, init_binary, _a257, _b179, MySqlBooleanBuilder, _a258, _b180, MySqlBoolean, init_boolean22, _a259, _b181, MySqlCharBuilder, _a260, _b182, MySqlChar, init_char22, _a261, _b183, MySqlCustomColumnBuilder, _a262, _b184, MySqlCustomColumn, init_custom3, _a263, _b185, MySqlDateBuilder, _a264, _b186, MySqlDate, _a265, _b187, MySqlDateStringBuilder, _a266, _b188, MySqlDateString, init_date22, _a267, _b189, MySqlDateTimeBuilder, _a268, _b190, MySqlDateTime, _a269, _b191, MySqlDateTimeStringBuilder, _a270, _b192, MySqlDateTimeString, init_datetime, _a271, _b193, MySqlDecimalBuilder, _a272, _b194, MySqlDecimal, _a273, _b195, MySqlDecimalNumberBuilder, _a274, _b196, MySqlDecimalNumber, _a275, _b197, MySqlDecimalBigIntBuilder, _a276, _b198, MySqlDecimalBigInt, init_decimal, _a277, _b199, MySqlDoubleBuilder, _a278, _b200, MySqlDouble, init_double, _a279, _b201, MySqlEnumColumnBuilder, _a280, _b202, MySqlEnumColumn, _a281, _b203, MySqlEnumObjectColumnBuilder, _a282, _b204, MySqlEnumObjectColumn, init_enum22, _a283, _b205, MySqlFloatBuilder, _a284, _b206, MySqlFloat, init_float, _a285, _b207, MySqlIntBuilder, _a286, _b208, MySqlInt, init_int, _a287, _b209, MySqlJsonBuilder, _a288, _b210, MySqlJson, init_json22, _a289, _b211, MySqlMediumIntBuilder, _a290, _b212, MySqlMediumInt, init_mediumint, _a291, _b213, MySqlRealBuilder, _a292, _b214, MySqlReal, init_real3, _a293, _b215, MySqlSerialBuilder, _a294, _b216, MySqlSerial, init_serial22, _a295, _b217, MySqlSmallIntBuilder, _a296, _b218, MySqlSmallInt, init_smallint22, _a297, _b219, MySqlTextBuilder, _a298, _b220, MySqlText, init_text3, _a299, _b221, MySqlTimeBuilder, _a300, _b222, MySqlTime, init_time22, _a301, _b223, MySqlDateColumnBaseBuilder, _a302, _b224, MySqlDateBaseColumn, init_date_common22, _a303, _b225, MySqlTimestampBuilder, _a304, _b226, MySqlTimestamp, _a305, _b227, MySqlTimestampStringBuilder, _a306, _b228, MySqlTimestampString, init_timestamp22, _a307, _b229, MySqlTinyIntBuilder, _a308, _b230, MySqlTinyInt, init_tinyint, _a309, _b231, MySqlVarBinaryBuilder, _a310, _b232, MySqlVarBinary, init_varbinary, _a311, _b233, MySqlVarCharBuilder, _a312, _b234, MySqlVarChar, init_varchar22, _a313, _b235, MySqlYearBuilder, _a314, _b236, MySqlYear, init_year, init_columns3, _a315, _b237, _c9, _MySqlCountBuilder, MySqlCountBuilder, init_count3, _a316, IndexBuilderOn3, _a317, IndexBuilder3, _a318, Index5, init_indexes3, init_all3, InlineForeignKeys3, _a319, _b238, _c10, _d4, _e4, MySqlTable, mysqlTable, init_table42, _a320, PrimaryKeyBuilder3, _a321, PrimaryKey3, init_primary_keys3, MySqlViewConfig, init_view_common32, init_utils8, _a3222, _b239, MySqlDeleteBase, init_delete3, _a323, _b240, MySqlViewBase, init_view_base3, _a324, MySqlDialect, init_dialect3, _a325, MySqlSelectBuilder, _a326, _b241, MySqlSelectQueryBuilderBase, _a327, _b242, MySqlSelectBase, getMySqlSetOperators, union4, unionAll3, intersect3, intersectAll22, except3, exceptAll22, init_select4, _a328, QueryBuilder3, init_query_builder4, _a329, MySqlInsertBuilder, _a330, _b243, MySqlInsertBase, init_insert3, init_select_types3, _a331, MySqlUpdateBuilder, _a332, _b244, MySqlUpdateBase, init_update3, init_query_builders3, _a333, RelationalQueryBuilder3, _a334, _b245, MySqlRelationalQuery, init_query3, _a335, MySqlDatabase, init_db3, _a336, ViewBuilderCore2, _a337, _b246, ViewBuilder3, _a338, _b247, ManualViewBuilder3, _a339, _b248, _c11, MySqlView2, init_view3, _a340, MySqlSchema5, init_schema22, _a341, MySqlPreparedQuery, _a342, MySqlSession, _a343, _b249, MySqlTransaction, init_session32, init_subquery4, init_mysql_core, handleEnumType, generateMySqlSnapshot, fromDatabase3, init_mysqlSerializer, cliConfigGenerate, pushParams, pullParams, configCheck, cliConfigCheck, init_cli, gelCredentials, init_gel, libSQLCredentials, init_libsql, mysqlCredentials, init_mysql, postgresCredentials, init_postgres, singlestoreCredentials, init_singlestore, sqliteCredentials, init_sqlite, credentials, studioCliParams, studioConfig, init_studio, es5_exports, _3, es5_default, init_es5, import_hanji7, assertES5, safeRegister, migrateConfig, init_utils9, prepareFromExports, init_pgImports, init_alias5, _a344, UniqueConstraintBuilder4, _a345, UniqueOnConstraintBuilder4, _a346, UniqueConstraint4, init_unique_constraint4, _a347, _b250, SingleStoreColumnBuilder, _a348, _b251, SingleStoreColumn, _a349, _b252, SingleStoreColumnBuilderWithAutoIncrement, _a350, _b253, SingleStoreColumnWithAutoIncrement, init_common5, _a351, _b254, SingleStoreBigInt53Builder, _a352, _b255, SingleStoreBigInt53, _a353, _b256, SingleStoreBigInt64Builder, _a354, _b257, SingleStoreBigInt64, init_bigint3, _a355, _b258, SingleStoreBinaryBuilder, _a356, _b259, SingleStoreBinary, init_binary2, _a357, _b260, SingleStoreBooleanBuilder, _a358, _b261, SingleStoreBoolean, init_boolean3, _a359, _b262, SingleStoreCharBuilder, _a360, _b263, SingleStoreChar, init_char3, _a361, _b264, SingleStoreCustomColumnBuilder, _a362, _b265, SingleStoreCustomColumn, init_custom4, _a363, _b266, SingleStoreDateBuilder, _a364, _b267, SingleStoreDate, _a365, _b268, SingleStoreDateStringBuilder, _a366, _b269, SingleStoreDateString, init_date3, _a367, _b270, SingleStoreDateTimeBuilder, _a368, _b271, SingleStoreDateTime, _a369, _b272, SingleStoreDateTimeStringBuilder, _a370, _b273, SingleStoreDateTimeString, init_datetime2, _a371, _b274, SingleStoreDecimalBuilder, _a372, _b275, SingleStoreDecimal, _a373, _b276, SingleStoreDecimalNumberBuilder, _a374, _b277, SingleStoreDecimalNumber, _a375, _b278, SingleStoreDecimalBigIntBuilder, _a376, _b279, SingleStoreDecimalBigInt, init_decimal2, _a377, _b280, SingleStoreDoubleBuilder, _a378, _b281, SingleStoreDouble, init_double2, _a379, _b282, SingleStoreEnumColumnBuilder, _a380, _b283, SingleStoreEnumColumn, init_enum3, _a381, _b284, SingleStoreFloatBuilder, _a382, _b285, SingleStoreFloat, init_float2, _a383, _b286, SingleStoreIntBuilder, _a384, _b287, SingleStoreInt, init_int2, _a385, _b288, SingleStoreJsonBuilder, _a386, _b289, SingleStoreJson, init_json3, _a387, _b290, SingleStoreMediumIntBuilder, _a388, _b291, SingleStoreMediumInt, init_mediumint2, _a389, _b292, SingleStoreRealBuilder, _a390, _b293, SingleStoreReal, init_real4, _a391, _b294, SingleStoreSerialBuilder, _a392, _b295, SingleStoreSerial, init_serial3, _a393, _b296, SingleStoreSmallIntBuilder, _a394, _b297, SingleStoreSmallInt, init_smallint3, _a395, _b298, SingleStoreTextBuilder, _a396, _b299, SingleStoreText, init_text4, _a397, _b300, SingleStoreTimeBuilder, _a398, _b301, SingleStoreTime, init_time3, _a399, _b302, SingleStoreDateColumnBaseBuilder, _a400, _b303, SingleStoreDateBaseColumn, init_date_common3, _a401, _b304, SingleStoreTimestampBuilder, _a402, _b305, SingleStoreTimestamp, _a403, _b306, SingleStoreTimestampStringBuilder, _a404, _b307, SingleStoreTimestampString, init_timestamp3, _a405, _b308, SingleStoreTinyIntBuilder, _a406, _b309, SingleStoreTinyInt, init_tinyint2, _a407, _b310, SingleStoreVarBinaryBuilder, _a408, _b311, SingleStoreVarBinary, init_varbinary2, _a409, _b312, SingleStoreVarCharBuilder, _a410, _b313, SingleStoreVarChar, init_varchar3, _a411, _b314, SingleStoreVectorBuilder, _a412, _b315, SingleStoreVector, init_vector4, _a413, _b316, SingleStoreYearBuilder, _a414, _b317, SingleStoreYear, init_year2, init_columns4, _a415, _b318, _c12, _SingleStoreCountBuilder, SingleStoreCountBuilder, init_count4, _a416, IndexBuilderOn4, _a417, IndexBuilder4, _a418, Index6, init_indexes4, init_all4, _a419, _b319, _c13, _d5, SingleStoreTable, init_table52, _a420, PrimaryKeyBuilder4, _a421, PrimaryKey4, init_primary_keys4, init_utils10, _a422, _b320, SingleStoreDeleteBase, init_delete4, _a423, SingleStoreInsertBuilder, _a424, _b321, SingleStoreInsertBase, init_insert4, _a425, SingleStoreDialect, init_dialect4, _a426, SingleStoreSelectBuilder, _a427, _b322, SingleStoreSelectQueryBuilderBase, _a428, _b323, SingleStoreSelectBase, getSingleStoreSetOperators, union5, unionAll4, intersect4, except4, minus, init_select5, _a429, QueryBuilder4, init_query_builder5, init_select_types4, _a430, SingleStoreUpdateBuilder, _a431, _b324, SingleStoreUpdateBase, init_update4, init_query_builders4, _a432, SingleStoreDatabase, init_db4, _a433, SingleStoreSchema5, init_schema32, _a434, SingleStorePreparedQuery, _a435, SingleStoreSession, _a436, _b325, SingleStoreTransaction, init_session4, init_subquery5, init_singlestore_core, dialect5, generateSingleStoreSnapshot, fromDatabase4, init_singlestoreSerializer, sqliteImports_exports, prepareFromExports2, prepareFromSqliteImports, init_sqliteImports, mysqlImports_exports, prepareFromExports3, prepareFromMySqlImports, init_mysqlImports, mysqlPushUtils_exports, import_hanji8, filterStatements, logSuggestionsAndReturn2, init_mysqlPushUtils, mysqlIntrospect_exports, import_hanji9, mysqlPushIntrospect, init_mysqlIntrospect, singlestoreImports_exports, prepareFromExports4, prepareFromSingleStoreImports, init_singlestoreImports, singlestorePushUtils_exports, import_hanji10, filterStatements2, logSuggestionsAndReturn3, init_singlestorePushUtils, singlestoreIntrospect_exports, import_hanji11, singlestorePushIntrospect, init_singlestoreIntrospect, import_hanji3, pgPushIntrospect = async (db2, filters, schemaFilters, entities, tsSchema) => {
|
|
101050
|
+
}, __toESM5 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod)), __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value), ANSI_BACKGROUND_OFFSET, wrapAnsi16, wrapAnsi256, wrapAnsi16m, styles2, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default, init_ansi_styles, env, flagForceColor, supportsColor, supports_color_default, init_supports_color, init_utilities, stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles22, applyOptions, chalkFactory, getModelAnsi, usedModels, proto, createStyler, createBuilder, applyStyle, chalk, chalkStderr, source_default, init_source, require_old, require_fs, require_path, require_balanced_match, require_brace_expansion, require_minimatch, require_inherits_browser2, require_inherits2, require_common3, require_sync, require_wrappy, require_once, require_inflight, require_glob, require_readline, require_src3, require_utils4, require_lodash, require_hanji, originUUID, snapshotVersion, mapValues, mapKeys, mapEntries, customMapEntries, init_global2, util3, objectUtil2, ZodParsedType2, getParsedType4, init_util4, ZodIssueCode4, ZodError5, init_ZodError2, errorMap2, en_default4, init_en4, overrideErrorMap2, init_errors9, makeIssue2, ParseStatus2, INVALID3, DIRTY2, OK2, isAborted2, isDirty2, isValid2, isAsync2, init_parseUtil2, init_typeAliases2, errorUtil2, init_errorUtil2, ParseInputLazyPath2, handleResult2, ZodType4, cuidRegex2, cuid2Regex2, ulidRegex2, uuidRegex2, nanoidRegex2, jwtRegex2, durationRegex2, emailRegex2, _emojiRegex2, emojiRegex2, ipv4Regex2, ipv4CidrRegex2, ipv6Regex2, ipv6CidrRegex2, base64Regex2, base64urlRegex2, dateRegexSource2, dateRegex2, ZodString4, ZodNumber4, ZodBigInt4, ZodBoolean4, ZodDate4, ZodSymbol4, ZodUndefined4, ZodNull4, ZodAny4, ZodUnknown4, ZodNever4, ZodVoid4, ZodArray4, ZodObject4, ZodUnion4, getDiscriminator2, ZodDiscriminatedUnion4, ZodIntersection4, ZodTuple4, ZodRecord4, ZodMap4, ZodSet4, ZodFunction3, ZodLazy4, ZodLiteral4, ZodEnum4, ZodNativeEnum2, ZodPromise4, ZodEffects2, ZodOptional4, ZodNullable4, ZodDefault4, ZodCatch4, ZodNaN4, BRAND2, ZodBranded2, ZodPipeline2, ZodReadonly4, late2, ZodFirstPartyTypeKind3, stringType2, numberType2, nanType2, bigIntType2, booleanType2, dateType2, symbolType2, undefinedType2, nullType2, anyType2, unknownType2, neverType2, voidType2, arrayType2, objectType2, strictObjectType2, unionType2, discriminatedUnionType2, intersectionType2, tupleType2, recordType2, mapType2, setType2, functionType2, lazyType2, literalType2, enumType2, nativeEnumType2, promiseType2, effectsType2, optionalType2, nullableType2, preprocessType2, pipelineType2, coerce2, init_types5, init_external4, init_v32, init_esm2, enumSchema, enumSchemaV1, indexColumn, index2, fk, sequenceSchema, roleSchema, sequenceSquashed, column2, checkConstraint, columnSquashed, compositePK, uniqueConstraint, policy, policySquashed, viewWithOption, matViewWithOption, mergedViewWithOption, view2, table8, schemaHash, kitInternals, gelSchemaExternal, gelSchemaInternal, tableSquashed, gelSchemaSquashed, gelSchema, dryGel, init_gelSchema, index22, fk2, column22, tableV3, compositePK2, uniqueConstraint2, checkConstraint2, tableV4, table22, viewMeta, view22, kitInternals2, dialect2, schemaHash2, schemaInternalV3, schemaInternalV4, schemaInternalV5, schemaInternal, schemaV3, schemaV4, schemaV5, schema2, tableSquashedV4, tableSquashed2, viewSquashed, schemaSquashed, schemaSquashedV4, MySqlSquasher, squashMysqlScheme, mysqlSchema, mysqlSchemaV5, mysqlSchemaSquashed, backwardCompatibleMysqlSchema, dryMySql, init_mysqlSchema, indexV2, columnV2, tableV2, enumSchemaV12, enumSchema2, pgSchemaV2, references, columnV1, tableV1, pgSchemaV1, indexColumn2, index3, indexV4, indexV5, indexV6, fk3, sequenceSchema2, roleSchema2, sequenceSquashed2, columnV7, column3, checkConstraint3, columnSquashed2, tableV32, compositePK3, uniqueConstraint3, policy2, policySquashed2, viewWithOption2, matViewWithOption2, mergedViewWithOption2, view3, tableV42, tableV5, tableV6, tableV7, table32, schemaHash3, kitInternals3, pgSchemaInternalV3, pgSchemaInternalV4, pgSchemaInternalV5, pgSchemaInternalV6, pgSchemaExternal, pgSchemaInternalV7, pgSchemaInternal, tableSquashed3, tableSquashedV42, pgSchemaSquashedV4, pgSchemaSquashedV6, pgSchemaSquashed, pgSchemaV3, pgSchemaV4, pgSchemaV5, pgSchemaV6, pgSchemaV7, pgSchema, backwardCompatiblePgSchema, PgSquasher, squashPgScheme, dryPg, init_pgSchema, index4, column4, compositePK4, uniqueConstraint4, table42, viewMeta2, kitInternals4, dialect22, schemaHash4, schemaInternal2, schema22, tableSquashed4, schemaSquashed2, SingleStoreSquasher, squashSingleStoreScheme, singlestoreSchema, singlestoreSchemaSquashed, backwardCompatibleSingleStoreSchema, drySingleStore, init_singlestoreSchema, index5, fk4, compositePK5, column5, tableV33, uniqueConstraint5, checkConstraint4, table52, view4, dialect3, schemaHash5, schemaInternalV32, schemaInternalV42, schemaInternalV52, kitInternals5, latestVersion, schemaInternal3, schemaV32, schemaV42, schemaV52, schema3, tableSquashed5, schemaSquashed3, SQLiteSquasher, squashSqliteScheme, drySQLite, sqliteSchemaV5, sqliteSchema, SQLiteSchemaSquashed, backwardCompatibleSqliteSchema, init_sqliteSchema, copy, prepareMigrationMeta, schemaRenameKey, tableRenameKey, columnRenameKey, init_utils7, import_hanji, warning, error88, isRenamePromptItem, ResolveColumnSelect, tableKey, ResolveSelectNamed, ResolveSelect, ResolveSchemasSelect, Spinner2, ProgressView, init_views, glob, init_serializer, fillPgSnapshot, init_migrationPreparator, require_heap, require_heap2, require_difflib, require_difflib2, require_util2, require_styles, require_has_flag2, require_supports_colors, require_trap, require_zalgo, require_america, require_zebra, require_rainbow, require_random, require_colors, require_safe, require_colorize, require_lib4, import_json_diff, mapArraysDiff, findAlternationsInTable, alternationsInColumn, init_jsonDiffer, parseType, Convertor, PgCreateRoleConvertor, PgDropRoleConvertor, PgRenameRoleConvertor, PgAlterRoleConvertor, PgCreatePolicyConvertor, PgDropPolicyConvertor, PgRenamePolicyConvertor, PgAlterPolicyConvertor, PgCreateIndPolicyConvertor, PgDropIndPolicyConvertor, PgRenameIndPolicyConvertor, PgAlterIndPolicyConvertor, PgEnableRlsConvertor, PgDisableRlsConvertor, PgCreateTableConvertor, MySqlCreateTableConvertor, SingleStoreCreateTableConvertor, SQLiteCreateTableConvertor, PgCreateViewConvertor, MySqlCreateViewConvertor, SqliteCreateViewConvertor, PgDropViewConvertor, MySqlDropViewConvertor, SqliteDropViewConvertor, MySqlAlterViewConvertor, PgRenameViewConvertor, MySqlRenameViewConvertor, PgAlterViewSchemaConvertor, PgAlterViewAddWithOptionConvertor, PgAlterViewDropWithOptionConvertor, PgAlterViewAlterTablespaceConvertor, PgAlterViewAlterUsingConvertor, PgAlterTableAlterColumnSetGenerated, PgAlterTableAlterColumnDropGenerated, PgAlterTableAlterColumnAlterGenerated, PgAlterTableAddUniqueConstraintConvertor, PgAlterTableDropUniqueConstraintConvertor, PgAlterTableAddCheckConstraintConvertor, PgAlterTableDeleteCheckConstraintConvertor, MySQLAlterTableAddUniqueConstraintConvertor, MySQLAlterTableDropUniqueConstraintConvertor, MySqlAlterTableAddCheckConstraintConvertor, SingleStoreAlterTableAddUniqueConstraintConvertor, SingleStoreAlterTableDropUniqueConstraintConvertor, MySqlAlterTableDeleteCheckConstraintConvertor, CreatePgSequenceConvertor, DropPgSequenceConvertor, RenamePgSequenceConvertor, MovePgSequenceConvertor, AlterPgSequenceConvertor, CreateTypeEnumConvertor, DropTypeEnumConvertor, AlterTypeAddValueConvertor, AlterTypeSetSchemaConvertor, AlterRenameTypeConvertor, AlterTypeDropValueConvertor, PgDropTableConvertor, MySQLDropTableConvertor, SingleStoreDropTableConvertor, SQLiteDropTableConvertor, PgRenameTableConvertor, SqliteRenameTableConvertor, MySqlRenameTableConvertor, SingleStoreRenameTableConvertor, PgAlterTableRenameColumnConvertor, MySqlAlterTableRenameColumnConvertor, SingleStoreAlterTableRenameColumnConvertor, SQLiteAlterTableRenameColumnConvertor, PgAlterTableDropColumnConvertor, MySqlAlterTableDropColumnConvertor, SingleStoreAlterTableDropColumnConvertor, SQLiteAlterTableDropColumnConvertor, PgAlterTableAddColumnConvertor, MySqlAlterTableAddColumnConvertor, SingleStoreAlterTableAddColumnConvertor, SQLiteAlterTableAddColumnConvertor, PgAlterTableAlterColumnSetTypeConvertor, PgAlterTableAlterColumnSetDefaultConvertor, PgAlterTableAlterColumnDropDefaultConvertor, PgAlterTableAlterColumnDropGeneratedConvertor, PgAlterTableAlterColumnSetExpressionConvertor, PgAlterTableAlterColumnAlterrGeneratedConvertor, SqliteAlterTableAlterColumnDropGeneratedConvertor, SqliteAlterTableAlterColumnSetExpressionConvertor, SqliteAlterTableAlterColumnAlterGeneratedConvertor, MySqlAlterTableAlterColumnAlterrGeneratedConvertor, MySqlAlterTableAddPk, MySqlAlterTableDropPk, LibSQLModifyColumn, MySqlModifyColumn, SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor, SingleStoreAlterTableAddPk, SingleStoreAlterTableDropPk, SingleStoreModifyColumn, PgAlterTableCreateCompositePrimaryKeyConvertor, PgAlterTableDeleteCompositePrimaryKeyConvertor, PgAlterTableAlterCompositePrimaryKeyConvertor, MySqlAlterTableCreateCompositePrimaryKeyConvertor, MySqlAlterTableDeleteCompositePrimaryKeyConvertor, MySqlAlterTableAlterCompositePrimaryKeyConvertor, PgAlterTableAlterColumnSetPrimaryKeyConvertor, PgAlterTableAlterColumnDropPrimaryKeyConvertor, PgAlterTableAlterColumnSetNotNullConvertor, PgAlterTableAlterColumnDropNotNullConvertor, PgCreateForeignKeyConvertor, LibSQLCreateForeignKeyConvertor, MySqlCreateForeignKeyConvertor, PgAlterForeignKeyConvertor, PgDeleteForeignKeyConvertor, MySqlDeleteForeignKeyConvertor, CreatePgIndexConvertor, CreateMySqlIndexConvertor, CreateSingleStoreIndexConvertor, CreateSqliteIndexConvertor, PgDropIndexConvertor, PgCreateSchemaConvertor, PgRenameSchemaConvertor, PgDropSchemaConvertor, PgAlterTableSetSchemaConvertor, PgAlterTableSetNewSchemaConvertor, PgAlterTableRemoveFromSchemaConvertor, SqliteDropIndexConvertor, MySqlDropIndexConvertor, SingleStoreDropIndexConvertor, SQLiteRecreateTableConvertor, LibSQLRecreateTableConvertor, SingleStoreRecreateTableConvertor, convertors, init_sqlgenerator, _moveDataStatements, getOldTableName, getNewTableName, logSuggestionsAndReturn, init_sqlitePushUtils, preparePgCreateTableJson, prepareMySqlCreateTableJson, prepareSingleStoreCreateTableJson, prepareSQLiteCreateTable, prepareDropTableJson, prepareRenameTableJson, prepareCreateEnumJson, prepareAddValuesToEnumJson, prepareDropEnumValues, prepareDropEnumJson, prepareMoveEnumJson, prepareRenameEnumJson, prepareCreateSequenceJson, prepareAlterSequenceJson, prepareDropSequenceJson, prepareMoveSequenceJson, prepareRenameSequenceJson, prepareCreateRoleJson, prepareAlterRoleJson, prepareDropRoleJson, prepareRenameRoleJson, prepareCreateSchemasJson, prepareRenameSchemasJson, prepareDeleteSchemasJson, prepareRenameColumns, _prepareDropColumns, _prepareAddColumns, _prepareSqliteAddColumns, prepareAlterColumnsMysql, preparePgAlterColumns, prepareSqliteAlterColumns, prepareRenamePolicyJsons, prepareRenameIndPolicyJsons, prepareCreatePolicyJsons, prepareCreateIndPolicyJsons, prepareDropPolicyJsons, prepareDropIndPolicyJsons, prepareAlterPolicyJson, prepareAlterIndPolicyJson, preparePgCreateIndexesJson, prepareCreateIndexesJson, prepareCreateReferencesJson, prepareLibSQLCreateReferencesJson, prepareDropReferencesJson, prepareLibSQLDropReferencesJson, prepareAlterReferencesJson, prepareDropIndexesJson, prepareAddCompositePrimaryKeySqlite, prepareDeleteCompositePrimaryKeySqlite, prepareAlterCompositePrimaryKeySqlite, prepareAddCompositePrimaryKeyPg, prepareDeleteCompositePrimaryKeyPg, prepareAlterCompositePrimaryKeyPg, prepareAddUniqueConstraintPg, prepareDeleteUniqueConstraintPg, prepareAddCheckConstraint, prepareDeleteCheckConstraint, prepareAddCompositePrimaryKeyMySql, prepareDeleteCompositePrimaryKeyMySql, prepareAlterCompositePrimaryKeyMySql, preparePgCreateViewJson, prepareMySqlCreateViewJson, prepareSqliteCreateViewJson, prepareDropViewJson, prepareRenameViewJson, preparePgAlterViewAlterSchemaJson, preparePgAlterViewAddWithOptionJson, preparePgAlterViewDropWithOptionJson, preparePgAlterViewAlterTablespaceJson, preparePgAlterViewAlterUsingJson, prepareMySqlAlterView, init_jsonStatements, prepareLibSQLRecreateTable, prepareSQLiteRecreateTable, libSQLCombineStatements, sqliteCombineStatements, prepareSingleStoreRecreateTable, singleStoreCombineStatements, init_statementCombiner, snapshotsDiffer_exports, makeChanged, makeSelfOrChanged, makePatched, makeSelfOrPatched, columnSchema, alteredColumnSchema, enumSchema3, changedEnumSchema, tableScheme, alteredTableScheme, alteredViewCommon, alteredPgViewSchema, alteredMySqlViewSchema, diffResultScheme, diffResultSchemeMysql, diffResultSchemeSingleStore, diffResultSchemeSQLite, schemaChangeFor, nameChangeFor, nameSchemaChangeFor, columnChangeFor, applyPgSnapshotsDiff, applyMysqlSnapshotsDiff, applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff, applyLibSQLSnapshotsDiff, init_snapshotsDiffer, init_words, dialects, dialect4, commonSquashedSchema, commonSchema, init_schemaValidator, sqliteDriversLiterals, postgresqlDriversLiterals, prefixes, prefix, casingTypes, casingType, sqliteDriver, postgresDriver, driver2, configMigrations, configCommonSchema, casing, introspectParams, configIntrospectCliSchema, configGenerateSchema, configPushSchema, init_common2, withStyle, init_outputs, import_hanji2, schemasResolver, tablesResolver, viewsResolver, mySqlViewsResolver, sqliteViewsResolver, sequencesResolver, roleResolver, policyResolver, indPolicyResolver, enumsResolver, columnsResolver, promptColumnsConflicts, promptNamedConflict, promptNamedWithSchemasConflict, promptSchemasConflict, BREAKPOINT, init_migrate, posixClasses, braceEscape, regexpEscape, rangesToString, parseClass, init_brace_expressions, escape, init_escape, unescape, init_unescape, import_brace_expansion, minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path, sep2, GLOBSTAR, plTypes, qmark, star, twoStarDot, twoStarNoDot, charSet, reSpecials, addPatternStartSet, filter, ext, defaults, braceExpand, MAX_PATTERN_LENGTH, assertValidPattern, makeRe, match2, globUnescape, globMagic, regExpEscape, Minimatch, init_mjs, entityKind2, hasOwnEntityKind2, init_entity2, _a3, Column2, init_column2, _a22, ColumnBuilder2, init_column_builder2, TableName2, init_table_utils2, _a32, ForeignKeyBuilder2, _a4, ForeignKey2, init_foreign_keys2, init_tracing_utils2, _a5, UniqueConstraintBuilder, _a6, UniqueOnConstraintBuilder, _a7, UniqueConstraint, init_unique_constraint2, init_array2, _a8, _b, PgColumnBuilder2, _a9, _b2, PgColumn2, _a10, _b3, ExtraConfigColumn2, _a11, IndexedColumn2, _a12, _b4, PgArrayBuilder2, _a13, _b5, _PgArray, PgArray2, init_common22, _a14, _b6, PgEnumObjectColumnBuilder2, _a15, _b7, PgEnumObjectColumn2, isPgEnumSym2, _a16, _b8, PgEnumColumnBuilder2, _a17, _b9, PgEnumColumn2, init_enum2, _a18, Subquery2, _a19, _b10, WithSubquery2, init_subquery2, version4, init_version2, otel2, rawTracer2, tracer2, init_tracing2, ViewBaseConfig2, init_view_common3, Schema2, Columns2, ExtraConfigColumns2, OriginalName2, BaseName2, IsAlias2, ExtraConfigBuilder2, IsDrizzleTable2, _a20, _b11, _c, _d, _e3, _f, _g, _h, _i, _j, Table2, init_table8, _a21, FakePrimitiveParam, _a222, StringChunk2, _a23, _SQL, SQL2, _a24, Name2, noopDecoder2, noopEncoder2, noopMapper2, _a25, Param2, _a26, Placeholder2, IsDrizzleView2, _a27, _b12, _c2, View3, init_sql3, _a28, ColumnAliasProxyHandler2, _a29, TableAliasProxyHandler2, _a30, RelationTableAliasProxyHandler, init_alias3, _a31, _b13, DrizzleError2, DrizzleQueryError, _a322, _b14, TransactionRollbackError2, init_errors22, _a33, ConsoleLogWriter2, _a34, DefaultLogger2, _a35, NoopLogger2, init_logger3, init_operations, _a36, _b15, QueryPromise2, init_query_promise2, textDecoder, init_utils22, _a37, _b16, PgIntColumnBaseBuilder2, init_int_common2, _a38, _b17, PgBigInt53Builder2, _a39, _b18, PgBigInt532, _a40, _b19, PgBigInt64Builder2, _a41, _b20, PgBigInt642, init_bigint2, _a42, _b21, PgBigSerial53Builder2, _a43, _b22, PgBigSerial532, _a44, _b23, PgBigSerial64Builder2, _a45, _b24, PgBigSerial642, init_bigserial2, _a46, _b25, PgBooleanBuilder2, _a47, _b26, PgBoolean2, init_boolean2, _a48, _b27, PgCharBuilder2, _a49, _b28, PgChar2, init_char2, _a50, _b29, PgCidrBuilder2, _a51, _b30, PgCidr2, init_cidr2, _a52, _b31, PgCustomColumnBuilder2, _a53, _b32, PgCustomColumn2, init_custom2, _a54, _b33, PgDateColumnBaseBuilder2, init_date_common2, _a55, _b34, PgDateBuilder2, _a56, _b35, PgDate2, _a57, _b36, PgDateStringBuilder2, _a58, _b37, PgDateString2, init_date2, _a59, _b38, PgDoublePrecisionBuilder2, _a60, _b39, PgDoublePrecision2, init_double_precision2, _a61, _b40, PgInetBuilder2, _a62, _b41, PgInet2, init_inet2, _a63, _b42, PgIntegerBuilder2, _a64, _b43, PgInteger2, init_integer2, _a65, _b44, PgIntervalBuilder2, _a66, _b45, PgInterval2, init_interval2, _a67, _b46, PgJsonBuilder2, _a68, _b47, PgJson2, init_json2, _a69, _b48, PgJsonbBuilder2, _a70, _b49, PgJsonb2, init_jsonb2, _a71, _b50, PgLineBuilder2, _a72, _b51, PgLineTuple2, _a73, _b52, PgLineABCBuilder2, _a74, _b53, PgLineABC2, init_line2, _a75, _b54, PgMacaddrBuilder2, _a76, _b55, PgMacaddr2, init_macaddr2, _a77, _b56, PgMacaddr8Builder2, _a78, _b57, PgMacaddr82, init_macaddr82, _a79, _b58, PgNumericBuilder2, _a80, _b59, PgNumeric2, _a81, _b60, PgNumericNumberBuilder2, _a82, _b61, PgNumericNumber2, _a83, _b62, PgNumericBigIntBuilder2, _a84, _b63, PgNumericBigInt2, init_numeric2, _a85, _b64, PgPointTupleBuilder2, _a86, _b65, PgPointTuple2, _a87, _b66, PgPointObjectBuilder2, _a88, _b67, PgPointObject2, init_point2, init_utils32, _a89, _b68, PgGeometryBuilder2, _a90, _b69, PgGeometry2, _a91, _b70, PgGeometryObjectBuilder2, _a92, _b71, PgGeometryObject2, init_geometry2, _a93, _b72, PgRealBuilder2, _a94, _b73, PgReal2, init_real2, _a95, _b74, PgSerialBuilder2, _a96, _b75, PgSerial2, init_serial2, _a97, _b76, PgSmallIntBuilder2, _a98, _b77, PgSmallInt2, init_smallint2, _a99, _b78, PgSmallSerialBuilder2, _a100, _b79, PgSmallSerial2, init_smallserial2, _a101, _b80, PgTextBuilder2, _a102, _b81, PgText2, init_text2, _a103, _b82, PgTimeBuilder2, _a104, _b83, PgTime2, init_time2, _a105, _b84, PgTimestampBuilder2, _a106, _b85, PgTimestamp2, _a107, _b86, PgTimestampStringBuilder2, _a108, _b87, PgTimestampString2, init_timestamp2, _a109, _b88, PgUUIDBuilder2, _a110, _b89, PgUUID2, init_uuid3, _a111, _b90, PgVarcharBuilder2, _a112, _b91, PgVarchar2, init_varchar2, _a113, _b92, PgBinaryVectorBuilder2, _a114, _b93, PgBinaryVector2, init_bit2, _a115, _b94, PgHalfVectorBuilder2, _a116, _b95, PgHalfVector2, init_halfvec2, _a117, _b96, PgSparseVectorBuilder2, _a118, _b97, PgSparseVector2, init_sparsevec2, _a119, _b98, PgVectorBuilder2, _a120, _b99, PgVector2, init_vector3, init_all2, InlineForeignKeys2, EnableRLS2, _a121, _b100, _c3, _d2, _e22, _f2, PgTable2, pgTable2, init_table22, _a122, PrimaryKeyBuilder2, _a123, PrimaryKey2, init_primary_keys2, eq2, ne4, gt3, gte2, lt4, lte2, init_conditions2, init_select3, init_expressions2, _a124, Relation2, _a125, Relations2, _a126, _b101, _One, One2, _a127, _b102, _Many, Many2, init_relations2, init_aggregate2, init_vector22, init_functions2, init_sql22, dist_exports, init_dist9, init_alias22, _a128, CheckBuilder, _a129, Check, init_checks6, init_columns2, _a130, _SelectionProxyHandler, SelectionProxyHandler2, init_selection_proxy2, _a131, IndexBuilderOn2, _a132, IndexBuilder2, _a133, Index2, init_indexes2, _a134, PgPolicy, init_policies2, PgViewConfig2, init_view_common22, _a135, CasingCache2, init_casing2, _a136, _b103, PgViewBase2, init_view_base2, _a137, PgDialect2, init_dialect2, _a138, TypedQueryBuilder2, init_query_builder3, _a139, PgSelectBuilder2, _a140, _b104, PgSelectQueryBuilderBase2, _a141, _b105, PgSelectBase2, getPgSetOperators2, union22, unionAll2, intersect2, intersectAll2, except2, exceptAll2, init_select22, _a142, QueryBuilder2, init_query_builder22, _a143, DefaultViewBuilderCore, _a144, _b106, ViewBuilder, _a145, _b107, ManualViewBuilder, _a146, MaterializedViewBuilderCore, _a147, _b108, MaterializedViewBuilder, _a148, _b109, ManualMaterializedViewBuilder, _a149, _b110, _c4, PgView2, PgMaterializedViewConfig2, _a150, _b111, _c5, PgMaterializedView, init_view2, init_utils42, _a151, _b112, PgDeleteBase2, init_delete2, _a152, PgInsertBuilder2, _a153, _b113, PgInsertBase2, init_insert2, _a154, _b114, PgRefreshMaterializedView2, init_refresh_materialized_view2, init_select_types, _a155, PgUpdateBuilder2, _a156, _b115, PgUpdateBase2, init_update2, init_query_builders2, _a157, _b116, _c6, _PgCountBuilder, PgCountBuilder2, init_count2, _a158, RelationalQueryBuilder2, _a159, _b117, PgRelationalQuery2, init_query2, _a160, _b118, PgRaw2, init_raw2, _a161, PgDatabase2, init_db2, _a162, PgRole, init_roles2, _a163, PgSequence, init_sequence2, _a164, PgSchema5, init_schema3, _a165, Cache, _a166, _b119, NoopCache, init_cache, _a167, PgPreparedQuery2, _a168, PgSession2, _a169, _b120, PgTransaction2, init_session3, init_subquery22, init_utils52, init_pg_core2, vectorOps, init_vector32, sqlToStr, init_utils62, indexName, generatePgSnapshot, trimChar, fromDatabase, defaultForColumn, getColumnsInfoQuery, init_pgSerializer, import_hanji4, Select, init_selector_ui, init_alias32, _a170, CheckBuilder2, _a171, Check2, init_checks22, _a172, ForeignKeyBuilder22, _a173, ForeignKey22, init_foreign_keys22, _a174, UniqueConstraintBuilder2, _a175, UniqueOnConstraintBuilder2, _a176, UniqueConstraint2, init_unique_constraint22, _a177, _b121, SQLiteColumnBuilder, _a178, _b122, SQLiteColumn, init_common3, _a179, _b123, SQLiteBigIntBuilder, _a180, _b124, SQLiteBigInt, _a181, _b125, SQLiteBlobJsonBuilder, _a182, _b126, SQLiteBlobJson, _a183, _b127, SQLiteBlobBufferBuilder, _a184, _b128, SQLiteBlobBuffer, init_blob, _a185, _b129, SQLiteCustomColumnBuilder, _a186, _b130, SQLiteCustomColumn, init_custom22, _a187, _b131, SQLiteBaseIntegerBuilder, _a188, _b132, SQLiteBaseInteger, _a189, _b133, SQLiteIntegerBuilder, _a190, _b134, SQLiteInteger, _a191, _b135, SQLiteTimestampBuilder, _a192, _b136, SQLiteTimestamp, _a193, _b137, SQLiteBooleanBuilder, _a194, _b138, SQLiteBoolean, init_integer22, _a195, _b139, SQLiteNumericBuilder, _a196, _b140, SQLiteNumeric, _a197, _b141, SQLiteNumericNumberBuilder, _a198, _b142, SQLiteNumericNumber, _a199, _b143, SQLiteNumericBigIntBuilder, _a200, _b144, SQLiteNumericBigInt, init_numeric22, _a201, _b145, SQLiteRealBuilder, _a202, _b146, SQLiteReal, init_real22, _a203, _b147, SQLiteTextBuilder, _a204, _b148, SQLiteText, _a205, _b149, SQLiteTextJsonBuilder, _a206, _b150, SQLiteTextJson, init_text22, init_columns22, init_all22, InlineForeignKeys22, _a207, _b151, _c7, _d3, _e32, SQLiteTable, sqliteTable, init_table32, _a208, IndexBuilderOn22, _a209, IndexBuilder22, _a210, Index4, init_indexes22, _a211, PrimaryKeyBuilder22, _a212, PrimaryKey22, init_primary_keys22, init_utils72, _a213, _b152, SQLiteDeleteBase, init_delete22, _a214, _b153, SQLiteViewBase, init_view_base22, _a215, SQLiteDialect, _a216, _b154, SQLiteSyncDialect, _a217, _b155, SQLiteAsyncDialect, init_dialect22, _a218, SQLiteSelectBuilder, _a219, _b156, SQLiteSelectQueryBuilderBase, _a220, _b157, SQLiteSelectBase, getSQLiteSetOperators, union32, unionAll22, intersect22, except22, init_select32, _a221, QueryBuilder22, init_query_builder32, _a2222, SQLiteInsertBuilder, _a223, _b158, SQLiteInsertBase, init_insert22, init_select_types2, _a224, SQLiteUpdateBuilder, _a225, _b159, SQLiteUpdateBase, init_update22, init_query_builders22, _a226, _b160, _c8, _SQLiteCountBuilder, SQLiteCountBuilder, init_count22, _a227, RelationalQueryBuilder22, _a228, _b161, SQLiteRelationalQuery, _a229, _b162, SQLiteSyncRelationalQuery, init_query22, _a230, _b163, SQLiteRaw, init_raw22, _a231, BaseSQLiteDatabase, init_db22, _a232, _b164, ExecuteResultSync, _a233, SQLitePreparedQuery, _a234, SQLiteSession, _a235, _b165, SQLiteTransaction, init_session22, init_subquery3, _a236, ViewBuilderCore, _a237, _b166, ViewBuilder2, _a238, _b167, ManualViewBuilder2, _a239, _b168, SQLiteView2, init_view22, init_sqlite_core, generateSqliteSnapshot, fromDatabase2, init_sqliteSerializer, getTablesFilterByExtensions, init_getTablesFilterByExtensions, init_alias4, _a240, CheckBuilder3, _a241, Check3, init_checks32, _a242, ForeignKeyBuilder3, _a243, ForeignKey3, init_foreign_keys3, _a244, UniqueConstraintBuilder3, _a245, UniqueOnConstraintBuilder3, _a246, UniqueConstraint3, init_unique_constraint3, _a247, _b169, MySqlColumnBuilder, _a248, _b170, MySqlColumn, _a249, _b171, MySqlColumnBuilderWithAutoIncrement, _a250, _b172, MySqlColumnWithAutoIncrement, init_common4, _a251, _b173, MySqlBigInt53Builder, _a252, _b174, MySqlBigInt53, _a253, _b175, MySqlBigInt64Builder, _a254, _b176, MySqlBigInt64, init_bigint22, _a255, _b177, MySqlBinaryBuilder, _a256, _b178, MySqlBinary, init_binary, _a257, _b179, MySqlBooleanBuilder, _a258, _b180, MySqlBoolean, init_boolean22, _a259, _b181, MySqlCharBuilder, _a260, _b182, MySqlChar, init_char22, _a261, _b183, MySqlCustomColumnBuilder, _a262, _b184, MySqlCustomColumn, init_custom3, _a263, _b185, MySqlDateBuilder, _a264, _b186, MySqlDate, _a265, _b187, MySqlDateStringBuilder, _a266, _b188, MySqlDateString, init_date22, _a267, _b189, MySqlDateTimeBuilder, _a268, _b190, MySqlDateTime, _a269, _b191, MySqlDateTimeStringBuilder, _a270, _b192, MySqlDateTimeString, init_datetime, _a271, _b193, MySqlDecimalBuilder, _a272, _b194, MySqlDecimal, _a273, _b195, MySqlDecimalNumberBuilder, _a274, _b196, MySqlDecimalNumber, _a275, _b197, MySqlDecimalBigIntBuilder, _a276, _b198, MySqlDecimalBigInt, init_decimal, _a277, _b199, MySqlDoubleBuilder, _a278, _b200, MySqlDouble, init_double, _a279, _b201, MySqlEnumColumnBuilder, _a280, _b202, MySqlEnumColumn, _a281, _b203, MySqlEnumObjectColumnBuilder, _a282, _b204, MySqlEnumObjectColumn, init_enum22, _a283, _b205, MySqlFloatBuilder, _a284, _b206, MySqlFloat, init_float, _a285, _b207, MySqlIntBuilder, _a286, _b208, MySqlInt, init_int, _a287, _b209, MySqlJsonBuilder, _a288, _b210, MySqlJson, init_json22, _a289, _b211, MySqlMediumIntBuilder, _a290, _b212, MySqlMediumInt, init_mediumint, _a291, _b213, MySqlRealBuilder, _a292, _b214, MySqlReal, init_real3, _a293, _b215, MySqlSerialBuilder, _a294, _b216, MySqlSerial, init_serial22, _a295, _b217, MySqlSmallIntBuilder, _a296, _b218, MySqlSmallInt, init_smallint22, _a297, _b219, MySqlTextBuilder, _a298, _b220, MySqlText, init_text3, _a299, _b221, MySqlTimeBuilder, _a300, _b222, MySqlTime, init_time22, _a301, _b223, MySqlDateColumnBaseBuilder, _a302, _b224, MySqlDateBaseColumn, init_date_common22, _a303, _b225, MySqlTimestampBuilder, _a304, _b226, MySqlTimestamp, _a305, _b227, MySqlTimestampStringBuilder, _a306, _b228, MySqlTimestampString, init_timestamp22, _a307, _b229, MySqlTinyIntBuilder, _a308, _b230, MySqlTinyInt, init_tinyint, _a309, _b231, MySqlVarBinaryBuilder, _a310, _b232, MySqlVarBinary, init_varbinary, _a311, _b233, MySqlVarCharBuilder, _a312, _b234, MySqlVarChar, init_varchar22, _a313, _b235, MySqlYearBuilder, _a314, _b236, MySqlYear, init_year, init_columns3, _a315, _b237, _c9, _MySqlCountBuilder, MySqlCountBuilder, init_count3, _a316, IndexBuilderOn3, _a317, IndexBuilder3, _a318, Index5, init_indexes3, init_all3, InlineForeignKeys3, _a319, _b238, _c10, _d4, _e4, MySqlTable, mysqlTable, init_table42, _a320, PrimaryKeyBuilder3, _a321, PrimaryKey3, init_primary_keys3, MySqlViewConfig, init_view_common32, init_utils8, _a3222, _b239, MySqlDeleteBase, init_delete3, _a323, _b240, MySqlViewBase, init_view_base3, _a324, MySqlDialect, init_dialect3, _a325, MySqlSelectBuilder, _a326, _b241, MySqlSelectQueryBuilderBase, _a327, _b242, MySqlSelectBase, getMySqlSetOperators, union4, unionAll3, intersect3, intersectAll22, except3, exceptAll22, init_select4, _a328, QueryBuilder3, init_query_builder4, _a329, MySqlInsertBuilder, _a330, _b243, MySqlInsertBase, init_insert3, init_select_types3, _a331, MySqlUpdateBuilder, _a332, _b244, MySqlUpdateBase, init_update3, init_query_builders3, _a333, RelationalQueryBuilder3, _a334, _b245, MySqlRelationalQuery, init_query3, _a335, MySqlDatabase, init_db3, _a336, ViewBuilderCore2, _a337, _b246, ViewBuilder3, _a338, _b247, ManualViewBuilder3, _a339, _b248, _c11, MySqlView2, init_view3, _a340, MySqlSchema5, init_schema22, _a341, MySqlPreparedQuery, _a342, MySqlSession, _a343, _b249, MySqlTransaction, init_session32, init_subquery4, init_mysql_core, handleEnumType, generateMySqlSnapshot, fromDatabase3, init_mysqlSerializer, cliConfigGenerate, pushParams, pullParams, configCheck, cliConfigCheck, init_cli, gelCredentials, init_gel, libSQLCredentials, init_libsql, mysqlCredentials, init_mysql, postgresCredentials, init_postgres, singlestoreCredentials, init_singlestore, sqliteCredentials, init_sqlite, credentials, studioCliParams, studioConfig, init_studio, es5_exports, _3, es5_default, init_es5, import_hanji7, assertES5, safeRegister, migrateConfig, init_utils9, prepareFromExports, init_pgImports, init_alias5, _a344, UniqueConstraintBuilder4, _a345, UniqueOnConstraintBuilder4, _a346, UniqueConstraint4, init_unique_constraint4, _a347, _b250, SingleStoreColumnBuilder, _a348, _b251, SingleStoreColumn, _a349, _b252, SingleStoreColumnBuilderWithAutoIncrement, _a350, _b253, SingleStoreColumnWithAutoIncrement, init_common5, _a351, _b254, SingleStoreBigInt53Builder, _a352, _b255, SingleStoreBigInt53, _a353, _b256, SingleStoreBigInt64Builder, _a354, _b257, SingleStoreBigInt64, init_bigint3, _a355, _b258, SingleStoreBinaryBuilder, _a356, _b259, SingleStoreBinary, init_binary2, _a357, _b260, SingleStoreBooleanBuilder, _a358, _b261, SingleStoreBoolean, init_boolean3, _a359, _b262, SingleStoreCharBuilder, _a360, _b263, SingleStoreChar, init_char3, _a361, _b264, SingleStoreCustomColumnBuilder, _a362, _b265, SingleStoreCustomColumn, init_custom4, _a363, _b266, SingleStoreDateBuilder, _a364, _b267, SingleStoreDate, _a365, _b268, SingleStoreDateStringBuilder, _a366, _b269, SingleStoreDateString, init_date3, _a367, _b270, SingleStoreDateTimeBuilder, _a368, _b271, SingleStoreDateTime, _a369, _b272, SingleStoreDateTimeStringBuilder, _a370, _b273, SingleStoreDateTimeString, init_datetime2, _a371, _b274, SingleStoreDecimalBuilder, _a372, _b275, SingleStoreDecimal, _a373, _b276, SingleStoreDecimalNumberBuilder, _a374, _b277, SingleStoreDecimalNumber, _a375, _b278, SingleStoreDecimalBigIntBuilder, _a376, _b279, SingleStoreDecimalBigInt, init_decimal2, _a377, _b280, SingleStoreDoubleBuilder, _a378, _b281, SingleStoreDouble, init_double2, _a379, _b282, SingleStoreEnumColumnBuilder, _a380, _b283, SingleStoreEnumColumn, init_enum3, _a381, _b284, SingleStoreFloatBuilder, _a382, _b285, SingleStoreFloat, init_float2, _a383, _b286, SingleStoreIntBuilder, _a384, _b287, SingleStoreInt, init_int2, _a385, _b288, SingleStoreJsonBuilder, _a386, _b289, SingleStoreJson, init_json3, _a387, _b290, SingleStoreMediumIntBuilder, _a388, _b291, SingleStoreMediumInt, init_mediumint2, _a389, _b292, SingleStoreRealBuilder, _a390, _b293, SingleStoreReal, init_real4, _a391, _b294, SingleStoreSerialBuilder, _a392, _b295, SingleStoreSerial, init_serial3, _a393, _b296, SingleStoreSmallIntBuilder, _a394, _b297, SingleStoreSmallInt, init_smallint3, _a395, _b298, SingleStoreTextBuilder, _a396, _b299, SingleStoreText, init_text4, _a397, _b300, SingleStoreTimeBuilder, _a398, _b301, SingleStoreTime, init_time3, _a399, _b302, SingleStoreDateColumnBaseBuilder, _a400, _b303, SingleStoreDateBaseColumn, init_date_common3, _a401, _b304, SingleStoreTimestampBuilder, _a402, _b305, SingleStoreTimestamp, _a403, _b306, SingleStoreTimestampStringBuilder, _a404, _b307, SingleStoreTimestampString, init_timestamp3, _a405, _b308, SingleStoreTinyIntBuilder, _a406, _b309, SingleStoreTinyInt, init_tinyint2, _a407, _b310, SingleStoreVarBinaryBuilder, _a408, _b311, SingleStoreVarBinary, init_varbinary2, _a409, _b312, SingleStoreVarCharBuilder, _a410, _b313, SingleStoreVarChar, init_varchar3, _a411, _b314, SingleStoreVectorBuilder, _a412, _b315, SingleStoreVector, init_vector4, _a413, _b316, SingleStoreYearBuilder, _a414, _b317, SingleStoreYear, init_year2, init_columns4, _a415, _b318, _c12, _SingleStoreCountBuilder, SingleStoreCountBuilder, init_count4, _a416, IndexBuilderOn4, _a417, IndexBuilder4, _a418, Index6, init_indexes4, init_all4, _a419, _b319, _c13, _d5, SingleStoreTable, init_table52, _a420, PrimaryKeyBuilder4, _a421, PrimaryKey4, init_primary_keys4, init_utils10, _a422, _b320, SingleStoreDeleteBase, init_delete4, _a423, SingleStoreInsertBuilder, _a424, _b321, SingleStoreInsertBase, init_insert4, _a425, SingleStoreDialect, init_dialect4, _a426, SingleStoreSelectBuilder, _a427, _b322, SingleStoreSelectQueryBuilderBase, _a428, _b323, SingleStoreSelectBase, getSingleStoreSetOperators, union5, unionAll4, intersect4, except4, minus, init_select5, _a429, QueryBuilder4, init_query_builder5, init_select_types4, _a430, SingleStoreUpdateBuilder, _a431, _b324, SingleStoreUpdateBase, init_update4, init_query_builders4, _a432, SingleStoreDatabase, init_db4, _a433, SingleStoreSchema5, init_schema32, _a434, SingleStorePreparedQuery, _a435, SingleStoreSession, _a436, _b325, SingleStoreTransaction, init_session4, init_subquery5, init_singlestore_core, dialect5, generateSingleStoreSnapshot, fromDatabase4, init_singlestoreSerializer, sqliteImports_exports, prepareFromExports2, prepareFromSqliteImports, init_sqliteImports, mysqlImports_exports, prepareFromExports3, prepareFromMySqlImports, init_mysqlImports, mysqlPushUtils_exports, import_hanji8, filterStatements, logSuggestionsAndReturn2, init_mysqlPushUtils, mysqlIntrospect_exports, import_hanji9, mysqlPushIntrospect, init_mysqlIntrospect, singlestoreImports_exports, prepareFromExports4, prepareFromSingleStoreImports, init_singlestoreImports, singlestorePushUtils_exports, import_hanji10, filterStatements2, logSuggestionsAndReturn3, init_singlestorePushUtils, singlestoreIntrospect_exports, import_hanji11, singlestorePushIntrospect, init_singlestoreIntrospect, import_hanji3, pgPushIntrospect = async (db2, filters, schemaFilters, entities, tsSchema) => {
|
|
100238
101051
|
const matchers = filters.map((it3) => {
|
|
100239
101052
|
return new Minimatch(it3);
|
|
100240
101053
|
});
|
|
@@ -119280,8 +120093,8 @@ ${BREAKPOINT}ALTER TABLE ${tableNameWithSchema} ADD CONSTRAINT "${statement.newC
|
|
|
119280
120093
|
win32: { sep: "\\" },
|
|
119281
120094
|
posix: { sep: "/" }
|
|
119282
120095
|
};
|
|
119283
|
-
|
|
119284
|
-
minimatch.sep =
|
|
120096
|
+
sep2 = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
|
|
120097
|
+
minimatch.sep = sep2;
|
|
119285
120098
|
GLOBSTAR = Symbol("globstar **");
|
|
119286
120099
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
119287
120100
|
plTypes = {
|
|
@@ -138183,7 +138996,7 @@ async function seedCoreGames(db2) {
|
|
|
138183
138996
|
}
|
|
138184
138997
|
async function seedCurrentProjectGame(db2, project) {
|
|
138185
138998
|
const now2 = new Date;
|
|
138186
|
-
const desiredGameId = project.gameId?.trim() ||
|
|
138999
|
+
const desiredGameId = project.gameId?.trim() || await localGameId(project.slug);
|
|
138187
139000
|
try {
|
|
138188
139001
|
const existingGame = await db2.query.games.findFirst({
|
|
138189
139002
|
where: (row, operators) => operators.eq(row.slug, project.slug)
|
|
@@ -138199,7 +139012,7 @@ async function seedCurrentProjectGame(db2, project) {
|
|
|
138199
139012
|
}
|
|
138200
139013
|
}
|
|
138201
139014
|
const gameRecord = {
|
|
138202
|
-
id: desiredGameId
|
|
139015
|
+
id: desiredGameId,
|
|
138203
139016
|
slug: project.slug,
|
|
138204
139017
|
displayName: project.displayName,
|
|
138205
139018
|
version: project.version,
|
|
@@ -138234,6 +139047,7 @@ var init_games = __esm(() => {
|
|
|
138234
139047
|
init_drizzle_orm();
|
|
138235
139048
|
init_src();
|
|
138236
139049
|
init_tables_index();
|
|
139050
|
+
init_uuid2();
|
|
138237
139051
|
init_constants();
|
|
138238
139052
|
init_logging();
|
|
138239
139053
|
init_timeback5();
|
|
@@ -138819,19 +139633,50 @@ var init_types6 = () => {};
|
|
|
138819
139633
|
function hasGameManagementAccess(user) {
|
|
138820
139634
|
return user.role === "admin" || user.role === "teacher" || user.role === "developer" && user.developerStatus === "approved";
|
|
138821
139635
|
}
|
|
139636
|
+
function isDashboardWorkerKey(key) {
|
|
139637
|
+
return Boolean(key?.permissions?.[DASHBOARD_PERMISSION_NAMESPACE]);
|
|
139638
|
+
}
|
|
139639
|
+
function workerKeyGrantsGameRead(key, slug2) {
|
|
139640
|
+
if (!isDashboardWorkerKey(key) && !isGameWorkerKey(key)) {
|
|
139641
|
+
return false;
|
|
139642
|
+
}
|
|
139643
|
+
const games2 = key?.permissions?.games;
|
|
139644
|
+
return Boolean(games2?.includes(`read:${slug2}`) || games2?.includes(`write:${slug2}`));
|
|
139645
|
+
}
|
|
139646
|
+
function isGameWorkerKey(key) {
|
|
139647
|
+
return Boolean(key?.name?.startsWith(GAME_WORKER_KEY_PREFIX));
|
|
139648
|
+
}
|
|
139649
|
+
function deniedWorkerKeyRequest(key, method, pathname) {
|
|
139650
|
+
if (isDashboardWorkerKey(key) && !isAllowedDashboardWorkerRequest(method, pathname, key.permissions)) {
|
|
139651
|
+
return DASHBOARD_WORKER_KEY_RESTRICTED;
|
|
139652
|
+
}
|
|
139653
|
+
return null;
|
|
139654
|
+
}
|
|
139655
|
+
function rejectDashboardWorkerKey(ctx) {
|
|
139656
|
+
if (isDashboardWorkerKey(ctx.apiKey)) {
|
|
139657
|
+
throw ApiError.forbidden(DASHBOARD_WORKER_KEY_RESTRICTED);
|
|
139658
|
+
}
|
|
139659
|
+
}
|
|
139660
|
+
function assertAuthenticatedRequest(ctx) {
|
|
139661
|
+
if (!isAuthenticated(ctx)) {
|
|
139662
|
+
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
139663
|
+
}
|
|
139664
|
+
if (ctx.apiKey) {
|
|
139665
|
+
const denied = deniedWorkerKeyRequest(ctx.apiKey, ctx.request.method, ctx.url.pathname);
|
|
139666
|
+
if (denied) {
|
|
139667
|
+
throw ApiError.forbidden(denied);
|
|
139668
|
+
}
|
|
139669
|
+
}
|
|
139670
|
+
}
|
|
138822
139671
|
function requireAuth(handler) {
|
|
138823
139672
|
return async (ctx) => {
|
|
138824
|
-
|
|
138825
|
-
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
138826
|
-
}
|
|
139673
|
+
assertAuthenticatedRequest(ctx);
|
|
138827
139674
|
return handler(ctx);
|
|
138828
139675
|
};
|
|
138829
139676
|
}
|
|
138830
139677
|
function requireNonAnonymous(handler) {
|
|
138831
139678
|
return async (ctx) => {
|
|
138832
|
-
|
|
138833
|
-
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
138834
|
-
}
|
|
139679
|
+
assertAuthenticatedRequest(ctx);
|
|
138835
139680
|
if (ctx.user.isAnonymous) {
|
|
138836
139681
|
throw ApiError.forbidden("This operation is not available for demo/anonymous users");
|
|
138837
139682
|
}
|
|
@@ -138840,9 +139685,7 @@ function requireNonAnonymous(handler) {
|
|
|
138840
139685
|
}
|
|
138841
139686
|
function requireAnonymous(handler) {
|
|
138842
139687
|
return async (ctx) => {
|
|
138843
|
-
|
|
138844
|
-
throw ApiError.unauthorized("Valid session or bearer token required");
|
|
138845
|
-
}
|
|
139688
|
+
assertAuthenticatedRequest(ctx);
|
|
138846
139689
|
if (!ctx.user.isAnonymous) {
|
|
138847
139690
|
throw ApiError.forbidden("This operation is only available for demo/anonymous users");
|
|
138848
139691
|
}
|
|
@@ -138851,9 +139694,8 @@ function requireAnonymous(handler) {
|
|
|
138851
139694
|
}
|
|
138852
139695
|
function requireAdmin(handler) {
|
|
138853
139696
|
return async (ctx) => {
|
|
138854
|
-
|
|
138855
|
-
|
|
138856
|
-
}
|
|
139697
|
+
assertAuthenticatedRequest(ctx);
|
|
139698
|
+
rejectDashboardWorkerKey(ctx);
|
|
138857
139699
|
if (ctx.user.role !== "admin") {
|
|
138858
139700
|
throw ApiError.forbidden("Admin access required");
|
|
138859
139701
|
}
|
|
@@ -138862,9 +139704,8 @@ function requireAdmin(handler) {
|
|
|
138862
139704
|
}
|
|
138863
139705
|
function requireDeveloper(handler) {
|
|
138864
139706
|
return async (ctx) => {
|
|
138865
|
-
|
|
138866
|
-
|
|
138867
|
-
}
|
|
139707
|
+
assertAuthenticatedRequest(ctx);
|
|
139708
|
+
rejectDashboardWorkerKey(ctx);
|
|
138868
139709
|
const isAdmin = ctx.user.role === "admin";
|
|
138869
139710
|
const isApprovedDev = ctx.user.role === "developer" && ctx.user.developerStatus === "approved";
|
|
138870
139711
|
if (!isAdmin && !isApprovedDev) {
|
|
@@ -138873,20 +139714,30 @@ function requireDeveloper(handler) {
|
|
|
138873
139714
|
return handler(ctx);
|
|
138874
139715
|
};
|
|
138875
139716
|
}
|
|
139717
|
+
function requireHumanDeveloper(handler) {
|
|
139718
|
+
return requireDeveloper(async (ctx) => {
|
|
139719
|
+
if (isDashboardWorkerKey(ctx.apiKey) || isGameWorkerKey(ctx.apiKey)) {
|
|
139720
|
+
throw ApiError.forbidden(WORKER_KEY_HUMAN_ONLY);
|
|
139721
|
+
}
|
|
139722
|
+
return handler(ctx);
|
|
139723
|
+
});
|
|
139724
|
+
}
|
|
138876
139725
|
function requireGameManagementAccess(handler) {
|
|
138877
139726
|
return async (ctx) => {
|
|
138878
|
-
|
|
138879
|
-
|
|
138880
|
-
}
|
|
139727
|
+
assertAuthenticatedRequest(ctx);
|
|
139728
|
+
rejectDashboardWorkerKey(ctx);
|
|
138881
139729
|
if (!hasGameManagementAccess(ctx.user)) {
|
|
138882
139730
|
throw ApiError.forbidden("Game management access required");
|
|
138883
139731
|
}
|
|
138884
139732
|
return handler(ctx);
|
|
138885
139733
|
};
|
|
138886
139734
|
}
|
|
139735
|
+
var WORKER_KEY_HUMAN_ONLY = "This operation requires your own credential — platform worker keys are refused";
|
|
138887
139736
|
var init_auth_util = __esm(() => {
|
|
138888
139737
|
init_errors();
|
|
138889
139738
|
init_types6();
|
|
139739
|
+
init_dashboard_util();
|
|
139740
|
+
init_deployment_util();
|
|
138890
139741
|
});
|
|
138891
139742
|
|
|
138892
139743
|
// ../api-core/src/utils/controller.util.ts
|
|
@@ -139030,6 +139881,21 @@ function requireGameId(gameId) {
|
|
|
139030
139881
|
}
|
|
139031
139882
|
return gameId;
|
|
139032
139883
|
}
|
|
139884
|
+
function requireSlug(slug2) {
|
|
139885
|
+
if (!slug2) {
|
|
139886
|
+
throw ApiError.badRequest("Missing game slug");
|
|
139887
|
+
}
|
|
139888
|
+
return slug2;
|
|
139889
|
+
}
|
|
139890
|
+
function requireUserId(userId) {
|
|
139891
|
+
if (!userId) {
|
|
139892
|
+
throw ApiError.badRequest("Missing user ID");
|
|
139893
|
+
}
|
|
139894
|
+
if (!isValidUUID(userId)) {
|
|
139895
|
+
throw ApiError.unprocessableEntity("userId must be a valid UUID format");
|
|
139896
|
+
}
|
|
139897
|
+
return userId;
|
|
139898
|
+
}
|
|
139033
139899
|
var init_params_util = __esm(() => {
|
|
139034
139900
|
init_src4();
|
|
139035
139901
|
init_errors();
|
|
@@ -139078,6 +139944,7 @@ var init_validation_util = __esm(() => {
|
|
|
139078
139944
|
// ../api-core/src/utils/index.ts
|
|
139079
139945
|
var init_utils11 = __esm(() => {
|
|
139080
139946
|
init_auth_util();
|
|
139947
|
+
init_dashboard_util();
|
|
139081
139948
|
init_deployment_util();
|
|
139082
139949
|
init_leaderboard_util();
|
|
139083
139950
|
init_lti_util();
|
|
@@ -139170,6 +140037,83 @@ var init_bucket_controller = __esm(() => {
|
|
|
139170
140037
|
});
|
|
139171
140038
|
});
|
|
139172
140039
|
|
|
140040
|
+
// ../api-core/src/controllers/dashboard.controller.ts
|
|
140041
|
+
function requireDashboardWorkerKey(ctx, slug2) {
|
|
140042
|
+
const scopes = ctx.apiKey?.permissions?.[DASHBOARD_PERMISSION_NAMESPACE];
|
|
140043
|
+
if (!scopes?.includes(dashboardCredentialScope(slug2))) {
|
|
140044
|
+
throw ApiError.forbidden("This endpoint requires the dashboard worker key for this game");
|
|
140045
|
+
}
|
|
140046
|
+
}
|
|
140047
|
+
var listUsers, addUser, issueRecoveryLink, removeUser, remove, verifyLogin, acceptInvite, revokeSessions, acceptReset, dashboard2;
|
|
140048
|
+
var init_dashboard_controller = __esm(() => {
|
|
140049
|
+
init_schemas_index();
|
|
140050
|
+
init_errors();
|
|
140051
|
+
init_utils11();
|
|
140052
|
+
listUsers = requireHumanDeveloper(async (ctx) => {
|
|
140053
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140054
|
+
const users2 = await ctx.services.dashboard.listUsers(slug2, ctx.user);
|
|
140055
|
+
return { users: users2 };
|
|
140056
|
+
});
|
|
140057
|
+
addUser = requireHumanDeveloper(async (ctx) => {
|
|
140058
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140059
|
+
const body2 = await parseRequestBody(ctx.request, AddGameDashboardUserSchema);
|
|
140060
|
+
return ctx.services.dashboard.addUser(slug2, ctx.user, body2);
|
|
140061
|
+
});
|
|
140062
|
+
issueRecoveryLink = requireHumanDeveloper(async (ctx) => {
|
|
140063
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140064
|
+
const userId = requireUserId(ctx.params.userId);
|
|
140065
|
+
return ctx.services.dashboard.issueRecoveryLink(slug2, ctx.user, userId);
|
|
140066
|
+
});
|
|
140067
|
+
removeUser = requireHumanDeveloper(async (ctx) => {
|
|
140068
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140069
|
+
const userId = requireUserId(ctx.params.userId);
|
|
140070
|
+
await ctx.services.dashboard.removeUser(slug2, ctx.user, userId);
|
|
140071
|
+
return { success: true };
|
|
140072
|
+
});
|
|
140073
|
+
remove = requireHumanDeveloper(async (ctx) => {
|
|
140074
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140075
|
+
await ctx.services.deploy.removeDashboard(slug2, ctx.user);
|
|
140076
|
+
return { success: true };
|
|
140077
|
+
});
|
|
140078
|
+
verifyLogin = requireAuth(async (ctx) => {
|
|
140079
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140080
|
+
requireDashboardWorkerKey(ctx, slug2);
|
|
140081
|
+
const body2 = await parseRequestBody(ctx.request, VerifyGameDashboardLoginSchema);
|
|
140082
|
+
const user = await ctx.services.dashboard.verifyLogin(slug2, body2);
|
|
140083
|
+
return { user };
|
|
140084
|
+
});
|
|
140085
|
+
acceptInvite = requireAuth(async (ctx) => {
|
|
140086
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140087
|
+
requireDashboardWorkerKey(ctx, slug2);
|
|
140088
|
+
const body2 = await parseRequestBody(ctx.request, AcceptGameDashboardInviteSchema);
|
|
140089
|
+
const user = await ctx.services.dashboard.acceptInvite(slug2, body2);
|
|
140090
|
+
return { user };
|
|
140091
|
+
});
|
|
140092
|
+
revokeSessions = requireHumanDeveloper(async (ctx) => {
|
|
140093
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140094
|
+
await ctx.services.deploy.rotateDashboardSessionSecret(slug2, ctx.user);
|
|
140095
|
+
return { success: true };
|
|
140096
|
+
});
|
|
140097
|
+
acceptReset = requireAuth(async (ctx) => {
|
|
140098
|
+
const slug2 = requireSlug(ctx.params.slug);
|
|
140099
|
+
requireDashboardWorkerKey(ctx, slug2);
|
|
140100
|
+
const body2 = await parseRequestBody(ctx.request, AcceptGameDashboardResetSchema);
|
|
140101
|
+
const user = await ctx.services.dashboard.acceptReset(slug2, body2);
|
|
140102
|
+
return { user };
|
|
140103
|
+
});
|
|
140104
|
+
dashboard2 = defineControllerNames("dashboard", {
|
|
140105
|
+
listUsers,
|
|
140106
|
+
addUser,
|
|
140107
|
+
removeUser,
|
|
140108
|
+
remove,
|
|
140109
|
+
issueRecoveryLink,
|
|
140110
|
+
revokeSessions,
|
|
140111
|
+
verifyLogin,
|
|
140112
|
+
acceptInvite,
|
|
140113
|
+
acceptReset
|
|
140114
|
+
});
|
|
140115
|
+
});
|
|
140116
|
+
|
|
139173
140117
|
// ../api-core/src/controllers/database.controller.ts
|
|
139174
140118
|
var reset, database;
|
|
139175
140119
|
var init_database_controller = __esm(() => {
|
|
@@ -139264,7 +140208,7 @@ var init_developer_controller = __esm(() => {
|
|
|
139264
140208
|
});
|
|
139265
140209
|
|
|
139266
140210
|
// ../api-core/src/controllers/domain.controller.ts
|
|
139267
|
-
var add, list, getStatus2,
|
|
140211
|
+
var add, list, getStatus2, remove2, domains2;
|
|
139268
140212
|
var init_domain_controller = __esm(() => {
|
|
139269
140213
|
init_esm();
|
|
139270
140214
|
init_schemas_index();
|
|
@@ -139313,7 +140257,7 @@ var init_domain_controller = __esm(() => {
|
|
|
139313
140257
|
const environment = getPlatformEnvironment(ctx.config);
|
|
139314
140258
|
return ctx.services.domain.getStatus(slug2, hostname4, environment, ctx.user, refresh);
|
|
139315
140259
|
});
|
|
139316
|
-
|
|
140260
|
+
remove2 = requireDeveloper(async (ctx) => {
|
|
139317
140261
|
const slug2 = ctx.params.slug;
|
|
139318
140262
|
const hostname4 = ctx.params.hostname;
|
|
139319
140263
|
if (!slug2) {
|
|
@@ -139329,12 +140273,12 @@ var init_domain_controller = __esm(() => {
|
|
|
139329
140273
|
add,
|
|
139330
140274
|
list,
|
|
139331
140275
|
getStatus: getStatus2,
|
|
139332
|
-
remove
|
|
140276
|
+
remove: remove2
|
|
139333
140277
|
});
|
|
139334
140278
|
});
|
|
139335
140279
|
|
|
139336
140280
|
// ../api-core/src/controllers/game-member.controller.ts
|
|
139337
|
-
function
|
|
140281
|
+
function requireUserId2(userId) {
|
|
139338
140282
|
if (!userId) {
|
|
139339
140283
|
throw ApiError.badRequest("Missing user ID");
|
|
139340
140284
|
}
|
|
@@ -139356,13 +140300,13 @@ var init_game_member_controller = __esm(() => {
|
|
|
139356
140300
|
});
|
|
139357
140301
|
updateMemberRole = requireNonAnonymous(async (ctx) => {
|
|
139358
140302
|
const gameId = requireGameId(ctx.params.gameId);
|
|
139359
|
-
const userId =
|
|
140303
|
+
const userId = requireUserId2(ctx.params.userId);
|
|
139360
140304
|
const body2 = await parseRequestBody(ctx.request, UpdateGameMemberRoleSchema);
|
|
139361
140305
|
return ctx.services.gameMember.updateRole(gameId, userId, ctx.user, body2);
|
|
139362
140306
|
});
|
|
139363
140307
|
removeMember = requireNonAnonymous(async (ctx) => {
|
|
139364
140308
|
const gameId = requireGameId(ctx.params.gameId);
|
|
139365
|
-
const userId =
|
|
140309
|
+
const userId = requireUserId2(ctx.params.userId);
|
|
139366
140310
|
await ctx.services.gameMember.remove(gameId, userId, ctx.user);
|
|
139367
140311
|
});
|
|
139368
140312
|
searchUsersForMember = requireNonAnonymous(async (ctx) => {
|
|
@@ -139380,12 +140324,13 @@ var init_game_member_controller = __esm(() => {
|
|
|
139380
140324
|
});
|
|
139381
140325
|
|
|
139382
140326
|
// ../api-core/src/controllers/game.controller.ts
|
|
139383
|
-
var list2, listAccessible, getSubjects, getTimebackSummaries, getById, getBySlug, getManifest, upsertBySlug, patchGameMetadata,
|
|
140327
|
+
var list2, listAccessible, getSubjects, getTimebackSummaries, getById, getBySlug, getManifest, upsertBySlug, patchGameMetadata, remove3, games2;
|
|
139384
140328
|
var init_game_controller = __esm(() => {
|
|
139385
140329
|
init_esm();
|
|
139386
140330
|
init_schemas_index();
|
|
139387
140331
|
init_errors();
|
|
139388
140332
|
init_utils11();
|
|
140333
|
+
init_auth_util();
|
|
139389
140334
|
list2 = requireNonAnonymous(async (ctx) => ctx.services.game.list(ctx.user));
|
|
139390
140335
|
listAccessible = requireNonAnonymous(async (ctx) => ctx.services.game.listAccessible(ctx.user));
|
|
139391
140336
|
getSubjects = requireNonAnonymous(async (ctx) => ctx.services.game.getSubjects());
|
|
@@ -139399,7 +140344,9 @@ var init_game_controller = __esm(() => {
|
|
|
139399
140344
|
if (!slug2) {
|
|
139400
140345
|
throw ApiError.badRequest("Missing game slug");
|
|
139401
140346
|
}
|
|
139402
|
-
return ctx.services.game.getBySlug(slug2, ctx.user
|
|
140347
|
+
return ctx.services.game.getBySlug(slug2, ctx.user, {
|
|
140348
|
+
scopeAuthorized: workerKeyGrantsGameRead(ctx.apiKey, slug2)
|
|
140349
|
+
});
|
|
139403
140350
|
});
|
|
139404
140351
|
getManifest = requireNonAnonymous(async (ctx) => {
|
|
139405
140352
|
const gameId = requireGameId(ctx.params.gameId);
|
|
@@ -139429,7 +140376,7 @@ var init_game_controller = __esm(() => {
|
|
|
139429
140376
|
const body2 = await parseRequestBody(ctx.request, PatchGameMetadataSchema);
|
|
139430
140377
|
return ctx.services.game.updateMetadata(gameId, body2, ctx.user);
|
|
139431
140378
|
});
|
|
139432
|
-
|
|
140379
|
+
remove3 = requireNonAnonymous(async (ctx) => {
|
|
139433
140380
|
const gameId = requireGameId(ctx.params.gameId);
|
|
139434
140381
|
await ctx.services.game.delete(gameId, ctx.user);
|
|
139435
140382
|
});
|
|
@@ -139443,7 +140390,7 @@ var init_game_controller = __esm(() => {
|
|
|
139443
140390
|
getBySlug,
|
|
139444
140391
|
upsertBySlug,
|
|
139445
140392
|
patchGameMetadata,
|
|
139446
|
-
remove:
|
|
140393
|
+
remove: remove3
|
|
139447
140394
|
});
|
|
139448
140395
|
});
|
|
139449
140396
|
|
|
@@ -139818,7 +140765,7 @@ var init_session_controller = __esm(() => {
|
|
|
139818
140765
|
let baseUrl;
|
|
139819
140766
|
if (ctx.config.isLocal) {
|
|
139820
140767
|
try {
|
|
139821
|
-
baseUrl = await getTunnelUrl();
|
|
140768
|
+
baseUrl = await getTunnelUrl(ctx.config.baseUrl);
|
|
139822
140769
|
} catch {}
|
|
139823
140770
|
}
|
|
139824
140771
|
return { token, exp, baseUrl };
|
|
@@ -140597,6 +141544,7 @@ var init_verify_controller = __esm(() => {
|
|
|
140597
141544
|
// ../api-core/src/controllers/index.ts
|
|
140598
141545
|
var init_controllers = __esm(() => {
|
|
140599
141546
|
init_bucket_controller();
|
|
141547
|
+
init_dashboard_controller();
|
|
140600
141548
|
init_database_controller();
|
|
140601
141549
|
init_deploy_controller();
|
|
140602
141550
|
init_developer_controller();
|