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