@void/platform 0.21.1 → 0.21.3
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/runtime/api/README.md +1 -1
- package/dist/runtime/api/assets/admin/client.js +4 -4
- package/dist/runtime/api/assets/admin/style.css +1 -1
- package/dist/runtime/api/index.js +890 -443
- package/dist/runtime/api/index.js.map +4 -4
- package/dist/runtime/dispatch/README.md +1 -1
- package/dist/runtime/drizzle/0051_icy_psylocke.sql +12 -0
- package/dist/runtime/drizzle/compatibility.json +4 -0
- package/dist/runtime/drizzle/meta/_journal.json +7 -0
- package/dist/runtime/emailGateway/README.md +1 -1
- package/dist/runtime/manifest.json +22 -12
- package/dist/runtime/proxy/README.md +1 -1
- package/dist/runtime/proxy/index.js +110 -71
- package/dist/runtime/proxy/index.js.map +4 -4
- package/dist/runtime/tail/README.md +1 -1
- package/package.json +1 -1
|
@@ -30346,6 +30346,7 @@ __export(cloudflare_api_exports, {
|
|
|
30346
30346
|
deleteKVNamespace: () => deleteKVNamespace,
|
|
30347
30347
|
deleteQueue: () => deleteQueue,
|
|
30348
30348
|
deleteR2Bucket: () => deleteR2Bucket,
|
|
30349
|
+
enableD1ReadReplication: () => enableD1ReadReplication,
|
|
30349
30350
|
getCustomHostname: () => getCustomHostname,
|
|
30350
30351
|
getCustomHostnameByHostname: () => getCustomHostnameByHostname,
|
|
30351
30352
|
getD1DatabaseByName: () => getD1DatabaseByName,
|
|
@@ -30384,7 +30385,13 @@ async function cfFetch(url2, apiToken, init) {
|
|
|
30384
30385
|
async function createD1Database(accountId, apiToken, name) {
|
|
30385
30386
|
return cfFetch(`${CF_API_BASE}/${accountId}/d1/database`, apiToken, {
|
|
30386
30387
|
method: "POST",
|
|
30387
|
-
body: JSON.stringify({ name })
|
|
30388
|
+
body: JSON.stringify({ name, read_replication: { mode: "auto" } })
|
|
30389
|
+
});
|
|
30390
|
+
}
|
|
30391
|
+
async function enableD1ReadReplication(accountId, apiToken, databaseId) {
|
|
30392
|
+
await cfFetch(`${CF_API_BASE}/${accountId}/d1/database/${databaseId}`, apiToken, {
|
|
30393
|
+
method: "PUT",
|
|
30394
|
+
body: JSON.stringify({ read_replication: { mode: "auto" } })
|
|
30388
30395
|
});
|
|
30389
30396
|
}
|
|
30390
30397
|
async function createKVNamespace(accountId, apiToken, title) {
|
|
@@ -30730,6 +30737,7 @@ var init_cloudflare_api = __esm({
|
|
|
30730
30737
|
};
|
|
30731
30738
|
__name(cfFetch, "cfFetch");
|
|
30732
30739
|
__name(createD1Database, "createD1Database");
|
|
30740
|
+
__name(enableD1ReadReplication, "enableD1ReadReplication");
|
|
30733
30741
|
__name(createKVNamespace, "createKVNamespace");
|
|
30734
30742
|
__name(createR2Bucket, "createR2Bucket");
|
|
30735
30743
|
__name(getD1DatabaseByName, "getD1DatabaseByName");
|
|
@@ -42022,6 +42030,7 @@ __export(schema_exports, {
|
|
|
42022
42030
|
platformLoginTests: () => platformLoginTests,
|
|
42023
42031
|
platformSettings: () => platformSettings,
|
|
42024
42032
|
projectAccessEvents: () => projectAccessEvents,
|
|
42033
|
+
projectCleanupJobs: () => projectCleanupJobs,
|
|
42025
42034
|
projectDatabaseCredentials: () => projectDatabaseCredentials,
|
|
42026
42035
|
projectDeployCredentials: () => projectDeployCredentials,
|
|
42027
42036
|
projectInvitations: () => projectInvitations,
|
|
@@ -42034,7 +42043,7 @@ __export(schema_exports, {
|
|
|
42034
42043
|
sandboxDrainCheckpoints: () => sandboxDrainCheckpoints,
|
|
42035
42044
|
users: () => users
|
|
42036
42045
|
});
|
|
42037
|
-
var users, oauthAccounts, platformAuthSettings, platformLoginConnections, platformLoginRevisions, platformLoginIdentities, platformHumanSessions, platformCompanyIdentities, platformLoginTests, platformAuthAttempts, platformAuthBootstrap, projects, projectDeployCredentials, projectMembers, projectInvitations, projectOwnershipPeriods, projectAccessEvents, deployments, projectSecrets, resources, domains, emailDestinations, emailDestinationCleanups, emailDomains, platformSettings, operatorSessions, operatorEvents, sandboxDrainCheckpoints, platformEvents, oauthNonces, authCodes, migrationRenames, projectMigrations, projectDatabaseCredentials, githubInstallations, githubConnections, githubInstallationMembers, githubInstallationRevocations, githubWebhookRedeliveries, builds, invitations;
|
|
42046
|
+
var users, oauthAccounts, platformAuthSettings, platformLoginConnections, platformLoginRevisions, platformLoginIdentities, platformHumanSessions, platformCompanyIdentities, platformLoginTests, platformAuthAttempts, platformAuthBootstrap, projects, projectDeployCredentials, projectMembers, projectInvitations, projectOwnershipPeriods, projectAccessEvents, deployments, projectCleanupJobs, projectSecrets, resources, domains, emailDestinations, emailDestinationCleanups, emailDomains, platformSettings, operatorSessions, operatorEvents, sandboxDrainCheckpoints, platformEvents, oauthNonces, authCodes, migrationRenames, projectMigrations, projectDatabaseCredentials, githubInstallations, githubConnections, githubInstallationMembers, githubInstallationRevocations, githubWebhookRedeliveries, builds, invitations;
|
|
42038
42047
|
var init_schema2 = __esm({
|
|
42039
42048
|
"../../home/runner/work/void/void/platform/packages/api/src/schema.ts"() {
|
|
42040
42049
|
"use strict";
|
|
@@ -42415,6 +42424,20 @@ var init_schema2 = __esm({
|
|
|
42415
42424
|
index("idx_deployments_created_id").on(table2.created_at, table2.id)
|
|
42416
42425
|
]
|
|
42417
42426
|
);
|
|
42427
|
+
projectCleanupJobs = pgTable(
|
|
42428
|
+
"project_cleanup_jobs",
|
|
42429
|
+
{
|
|
42430
|
+
target: text("target").primaryKey(),
|
|
42431
|
+
project_id: text("project_id").notNull(),
|
|
42432
|
+
kind: text("kind").notNull().$type(),
|
|
42433
|
+
payload: jsonb("payload").notNull().$type(),
|
|
42434
|
+
attempts: integer("attempts").notNull().default(0),
|
|
42435
|
+
last_error: text("last_error"),
|
|
42436
|
+
next_attempt_at: timestamp("next_attempt_at", { mode: "string" }).notNull().defaultNow(),
|
|
42437
|
+
created_at: timestamp("created_at", { mode: "string" }).notNull().defaultNow()
|
|
42438
|
+
},
|
|
42439
|
+
(table2) => [index("project_cleanup_jobs_due").on(table2.next_attempt_at, table2.created_at)]
|
|
42440
|
+
);
|
|
42418
42441
|
projectSecrets = pgTable(
|
|
42419
42442
|
"project_secrets",
|
|
42420
42443
|
{
|
|
@@ -47461,6 +47484,26 @@ var init_admission = __esm({
|
|
|
47461
47484
|
}
|
|
47462
47485
|
});
|
|
47463
47486
|
|
|
47487
|
+
// ../../home/runner/work/void/void/platform/packages/api/src/naming.ts
|
|
47488
|
+
function getLegacyProjectWorkerName(slug) {
|
|
47489
|
+
return `user-${slug}`;
|
|
47490
|
+
}
|
|
47491
|
+
function getProjectDeploymentWorkerName(slug, deploymentId) {
|
|
47492
|
+
return `user-${slug}-${deploymentId}`;
|
|
47493
|
+
}
|
|
47494
|
+
function getProjectQueueName(projectId, queueName) {
|
|
47495
|
+
return `${projectId}-${queueName}`.toLowerCase().replaceAll("_", "-");
|
|
47496
|
+
}
|
|
47497
|
+
var init_naming = __esm({
|
|
47498
|
+
"../../home/runner/work/void/void/platform/packages/api/src/naming.ts"() {
|
|
47499
|
+
"use strict";
|
|
47500
|
+
init_performance2();
|
|
47501
|
+
__name(getLegacyProjectWorkerName, "getLegacyProjectWorkerName");
|
|
47502
|
+
__name(getProjectDeploymentWorkerName, "getProjectDeploymentWorkerName");
|
|
47503
|
+
__name(getProjectQueueName, "getProjectQueueName");
|
|
47504
|
+
}
|
|
47505
|
+
});
|
|
47506
|
+
|
|
47464
47507
|
// ../../home/runner/work/void/void/platform/packages/api/src/tiers.ts
|
|
47465
47508
|
function getPlanLimits(plan) {
|
|
47466
47509
|
return PLAN_LIMITS[plan] ?? PLAN_LIMITS.free;
|
|
@@ -47626,6 +47669,7 @@ __export(db_exports, {
|
|
|
47626
47669
|
cancelDeployment: () => cancelDeployment,
|
|
47627
47670
|
cancelQueuedContainerBuildsForUsers: () => cancelQueuedContainerBuildsForUsers,
|
|
47628
47671
|
claimBuildForStartWithinLimit: () => claimBuildForStartWithinLimit,
|
|
47672
|
+
cleanupJobsForResource: () => cleanupJobsForResource,
|
|
47629
47673
|
clearGitHubInstallationOwnerForUser: () => clearGitHubInstallationOwnerForUser,
|
|
47630
47674
|
consumeAuthCode: () => consumeAuthCode,
|
|
47631
47675
|
consumeCliAuthCode: () => consumeCliAuthCode,
|
|
@@ -47661,9 +47705,11 @@ __export(db_exports, {
|
|
|
47661
47705
|
deleteProjectSecret: () => deleteProjectSecret,
|
|
47662
47706
|
deleteRollbackLease: () => deleteRollbackLease,
|
|
47663
47707
|
deleteUser: () => deleteUser,
|
|
47708
|
+
enqueueProjectCleanupJobs: () => enqueueProjectCleanupJobs,
|
|
47664
47709
|
failStaleActiveContainerBuilds: () => failStaleActiveContainerBuilds,
|
|
47665
47710
|
failStaleActiveGithubActionsBuilds: () => failStaleActiveGithubActionsBuilds,
|
|
47666
47711
|
failStaleDeployments: () => failStaleDeployments,
|
|
47712
|
+
getAccessibleProjectBySlug: () => getAccessibleProjectBySlug,
|
|
47667
47713
|
getAccessibleProjectsByUserId: () => getAccessibleProjectsByUserId,
|
|
47668
47714
|
getActivatedDeployments: () => getActivatedDeployments,
|
|
47669
47715
|
getActiveDeployment: () => getActiveDeployment,
|
|
@@ -47971,6 +48017,25 @@ async function getAccessibleProjectsByUserId(db, userId) {
|
|
|
47971
48017
|
owner: row.owner
|
|
47972
48018
|
}));
|
|
47973
48019
|
}
|
|
48020
|
+
async function getAccessibleProjectBySlug(db, userId, slug) {
|
|
48021
|
+
const [row] = await db.select({ project: projects, memberRole: projectMembers.role, owner: accessibleProjectOwner }).from(projects).innerJoin(accessibleProjectOwner, eq(projects.user_id, accessibleProjectOwner.id)).leftJoin(
|
|
48022
|
+
projectMembers,
|
|
48023
|
+
and(eq(projectMembers.project_id, projects.id), eq(projectMembers.user_id, userId))
|
|
48024
|
+
).where(
|
|
48025
|
+
and(
|
|
48026
|
+
eq(projects.slug, slug),
|
|
48027
|
+
or(eq(projects.user_id, userId), eq(projectMembers.user_id, userId))
|
|
48028
|
+
)
|
|
48029
|
+
).limit(1);
|
|
48030
|
+
if (!row || isAdminSuspended(row.owner.suspended_reason)) {
|
|
48031
|
+
return null;
|
|
48032
|
+
}
|
|
48033
|
+
return {
|
|
48034
|
+
project: row.project,
|
|
48035
|
+
role: row.project.user_id === userId ? "owner" : row.memberRole,
|
|
48036
|
+
owner: row.owner
|
|
48037
|
+
};
|
|
48038
|
+
}
|
|
47974
48039
|
async function getProjectMember(db, projectId, userId) {
|
|
47975
48040
|
const [row] = await db.select().from(projectMembers).where(and(eq(projectMembers.project_id, projectId), eq(projectMembers.user_id, userId))).limit(1);
|
|
47976
48041
|
return row ?? null;
|
|
@@ -48434,7 +48499,7 @@ async function getLatestDeploymentsByProjectIds(db, projectIds) {
|
|
|
48434
48499
|
if (projectIds.length === 0) {
|
|
48435
48500
|
return /* @__PURE__ */ new Map();
|
|
48436
48501
|
}
|
|
48437
|
-
const rows = await db.
|
|
48502
|
+
const rows = await db.selectDistinctOn([deployments.project_id], {
|
|
48438
48503
|
id: deployments.id,
|
|
48439
48504
|
project_id: deployments.project_id,
|
|
48440
48505
|
status: deployments.status,
|
|
@@ -48442,14 +48507,8 @@ async function getLatestDeploymentsByProjectIds(db, projectIds) {
|
|
|
48442
48507
|
commit: deployments.commit,
|
|
48443
48508
|
created_at: deployments.created_at,
|
|
48444
48509
|
deployed_at: deployments.deployed_at
|
|
48445
|
-
}).from(deployments).where(inArray(deployments.project_id, projectIds)).orderBy(desc(deployments.created_at));
|
|
48446
|
-
|
|
48447
|
-
for (const row of rows) {
|
|
48448
|
-
if (!latest.has(row.project_id)) {
|
|
48449
|
-
latest.set(row.project_id, row);
|
|
48450
|
-
}
|
|
48451
|
-
}
|
|
48452
|
-
return latest;
|
|
48510
|
+
}).from(deployments).where(inArray(deployments.project_id, projectIds)).orderBy(deployments.project_id, desc(deployments.created_at), desc(deployments.id));
|
|
48511
|
+
return new Map(rows.map((row) => [row.project_id, row]));
|
|
48453
48512
|
}
|
|
48454
48513
|
async function getProjectsByIds(db, ids) {
|
|
48455
48514
|
if (ids.length === 0) {
|
|
@@ -49154,7 +49213,36 @@ async function promoteEmailDestinationWithOwnerAudit(db, projectId, id2, cfDesti
|
|
|
49154
49213
|
async function deleteProject(db, id2) {
|
|
49155
49214
|
await db.delete(projects).where(eq(projects.id, id2));
|
|
49156
49215
|
}
|
|
49157
|
-
|
|
49216
|
+
function cleanupJobsForResource(projectId, resource) {
|
|
49217
|
+
if (resource.type === "container") {
|
|
49218
|
+
return [];
|
|
49219
|
+
}
|
|
49220
|
+
const jobs = [
|
|
49221
|
+
{
|
|
49222
|
+
target: `cf-resource:${projectId}:${resource.type}:${resource.cf_id}`,
|
|
49223
|
+
project_id: projectId,
|
|
49224
|
+
kind: "cf-resource",
|
|
49225
|
+
payload: { type: resource.type, cfId: resource.cf_id }
|
|
49226
|
+
}
|
|
49227
|
+
];
|
|
49228
|
+
if (resource.type === "queue") {
|
|
49229
|
+
const key = `queue:${getProjectQueueName(projectId, resource.binding_name)}`;
|
|
49230
|
+
jobs.push({
|
|
49231
|
+
target: `routing-key:${projectId}:${key}`,
|
|
49232
|
+
project_id: projectId,
|
|
49233
|
+
kind: "routing-key",
|
|
49234
|
+
payload: { key }
|
|
49235
|
+
});
|
|
49236
|
+
}
|
|
49237
|
+
return jobs;
|
|
49238
|
+
}
|
|
49239
|
+
async function enqueueProjectCleanupJobs(db, jobs) {
|
|
49240
|
+
if (jobs.length === 0) {
|
|
49241
|
+
return;
|
|
49242
|
+
}
|
|
49243
|
+
await db.insert(projectCleanupJobs).values([...jobs]).onConflictDoNothing();
|
|
49244
|
+
}
|
|
49245
|
+
async function deleteProjectCascade(db, projectId, processedResourceCfIds = /* @__PURE__ */ new Set()) {
|
|
49158
49246
|
return await db.transaction(async (tx) => {
|
|
49159
49247
|
const txDb = tx;
|
|
49160
49248
|
await tx.execute(sql`SELECT id FROM ${projects} WHERE id = ${projectId} FOR UPDATE`);
|
|
@@ -49163,6 +49251,10 @@ async function deleteProjectCascade(db, projectId) {
|
|
|
49163
49251
|
});
|
|
49164
49252
|
await tx.delete(domains).where(eq(domains.project_id, projectId));
|
|
49165
49253
|
const deletedResources = await tx.delete(resources).where(eq(resources.project_id, projectId)).returning();
|
|
49254
|
+
await enqueueProjectCleanupJobs(
|
|
49255
|
+
txDb,
|
|
49256
|
+
deletedResources.filter((resource) => !processedResourceCfIds.has(resource.cf_id)).flatMap((resource) => cleanupJobsForResource(projectId, resource))
|
|
49257
|
+
);
|
|
49166
49258
|
await tx.delete(projectSecrets).where(eq(projectSecrets.project_id, projectId));
|
|
49167
49259
|
await tx.delete(builds).where(eq(builds.project_id, projectId));
|
|
49168
49260
|
await tx.delete(deployments).where(eq(deployments.project_id, projectId));
|
|
@@ -49337,7 +49429,13 @@ async function searchProjects(db, query) {
|
|
|
49337
49429
|
last_deploy_id: lastDeploy.last_deploy_id,
|
|
49338
49430
|
last_deploy_status: lastDeploy.last_deploy_status
|
|
49339
49431
|
}).from(projects).leftJoin(users, eq(projects.user_id, users.id)).leftJoin(lastDeploy, eq(projects.id, lastDeploy.project_id)).where(
|
|
49340
|
-
or(
|
|
49432
|
+
or(
|
|
49433
|
+
ilike(projects.slug, pattern),
|
|
49434
|
+
ilike(users.login, pattern),
|
|
49435
|
+
ilike(projects.id, pattern),
|
|
49436
|
+
ilike(projects.type, pattern),
|
|
49437
|
+
ilike(lastDeploy.last_deploy_status, pattern)
|
|
49438
|
+
)
|
|
49341
49439
|
).orderBy(desc(projects.created_at)).limit(50);
|
|
49342
49440
|
}
|
|
49343
49441
|
async function searchDeployments(db, query) {
|
|
@@ -49353,7 +49451,8 @@ async function searchDeployments(db, query) {
|
|
|
49353
49451
|
ilike(deployments.status, pattern),
|
|
49354
49452
|
ilike(deployments.commit, pattern),
|
|
49355
49453
|
ilike(deployments.source, pattern),
|
|
49356
|
-
ilike(deployments.cli_version, pattern)
|
|
49454
|
+
ilike(deployments.cli_version, pattern),
|
|
49455
|
+
ilike(deployments.error_message, pattern)
|
|
49357
49456
|
)
|
|
49358
49457
|
).orderBy(desc(deployments.created_at)).limit(50);
|
|
49359
49458
|
}
|
|
@@ -49709,15 +49808,18 @@ async function getQueuedBuilds(db, limit = 50, excludeUserIds = []) {
|
|
|
49709
49808
|
return db.select().from(oldestPerProject).orderBy(asc(oldestPerProject.created_at)).limit(limit);
|
|
49710
49809
|
}
|
|
49711
49810
|
async function getUsersWithQueuedContainerBuilds(db) {
|
|
49811
|
+
const activeBuilds = alias(builds, "active_builds");
|
|
49712
49812
|
const rows = await db.select({
|
|
49713
49813
|
userId: users.id,
|
|
49714
49814
|
plan: users.plan,
|
|
49715
49815
|
suspendedReason: users.suspended_reason,
|
|
49716
|
-
//
|
|
49717
|
-
//
|
|
49718
|
-
//
|
|
49719
|
-
activeBuilds: sql`
|
|
49720
|
-
|
|
49816
|
+
// Count only active rows through idx_builds_user_status. Joining the
|
|
49817
|
+
// entire builds table here would touch every historical build belonging
|
|
49818
|
+
// to each queued owner on every scheduler tick.
|
|
49819
|
+
activeBuilds: sql`(
|
|
49820
|
+
select count(*) from ${builds} as active_builds
|
|
49821
|
+
where ${activeBuilds.user_id} = ${users.id}
|
|
49822
|
+
and ${inArray(activeBuilds.status, ACTIVE_BUILD_STATUSES)}
|
|
49721
49823
|
)`
|
|
49722
49824
|
}).from(users).innerJoin(
|
|
49723
49825
|
// Restrict to users who own at least one queued container build — the
|
|
@@ -49727,7 +49829,7 @@ async function getUsersWithQueuedContainerBuilds(db) {
|
|
|
49727
49829
|
where ${builds.status} = 'queued' and ${builds.executor} = 'container'
|
|
49728
49830
|
) as queued_owners`,
|
|
49729
49831
|
sql`queued_owners.user_id = ${users.id}`
|
|
49730
|
-
)
|
|
49832
|
+
);
|
|
49731
49833
|
return rows.map((r) => ({
|
|
49732
49834
|
userId: r.userId,
|
|
49733
49835
|
plan: r.plan,
|
|
@@ -50548,6 +50650,7 @@ var init_db2 = __esm({
|
|
|
50548
50650
|
init_configuration();
|
|
50549
50651
|
init_admission();
|
|
50550
50652
|
init_id2();
|
|
50653
|
+
init_naming();
|
|
50551
50654
|
init_project_access();
|
|
50552
50655
|
init_schema2();
|
|
50553
50656
|
init_schema2();
|
|
@@ -50606,6 +50709,7 @@ var init_db2 = __esm({
|
|
|
50606
50709
|
__name(getOwnedProjectsByUserId, "getOwnedProjectsByUserId");
|
|
50607
50710
|
accessibleProjectOwner = alias(users, "accessible_project_owner");
|
|
50608
50711
|
__name(getAccessibleProjectsByUserId, "getAccessibleProjectsByUserId");
|
|
50712
|
+
__name(getAccessibleProjectBySlug, "getAccessibleProjectBySlug");
|
|
50609
50713
|
__name(getProjectMember, "getProjectMember");
|
|
50610
50714
|
__name(getProjectMembers, "getProjectMembers");
|
|
50611
50715
|
ProjectTeamMutationError = class extends Error {
|
|
@@ -50715,6 +50819,8 @@ var init_db2 = __esm({
|
|
|
50715
50819
|
__name(queueUnreferencedEmailDestinationCleanup, "queueUnreferencedEmailDestinationCleanup");
|
|
50716
50820
|
__name(promoteEmailDestinationWithOwnerAudit, "promoteEmailDestinationWithOwnerAudit");
|
|
50717
50821
|
__name(deleteProject, "deleteProject");
|
|
50822
|
+
__name(cleanupJobsForResource, "cleanupJobsForResource");
|
|
50823
|
+
__name(enqueueProjectCleanupJobs, "enqueueProjectCleanupJobs");
|
|
50718
50824
|
__name(deleteProjectCascade, "deleteProjectCascade");
|
|
50719
50825
|
__name(countUsers, "countUsers");
|
|
50720
50826
|
__name(countProjects, "countProjects");
|
|
@@ -50841,6 +50947,28 @@ var init_env = __esm({
|
|
|
50841
50947
|
}
|
|
50842
50948
|
});
|
|
50843
50949
|
|
|
50950
|
+
// ../../home/runner/work/void/void/platform/packages/api/src/concurrency.ts
|
|
50951
|
+
async function uploadPool(items, concurrency, fn) {
|
|
50952
|
+
let nextIndex = 0;
|
|
50953
|
+
async function worker() {
|
|
50954
|
+
while (nextIndex < items.length) {
|
|
50955
|
+
const item = items[nextIndex++];
|
|
50956
|
+
await fn(item);
|
|
50957
|
+
}
|
|
50958
|
+
}
|
|
50959
|
+
__name(worker, "worker");
|
|
50960
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
50961
|
+
}
|
|
50962
|
+
var R2_CONCURRENCY;
|
|
50963
|
+
var init_concurrency = __esm({
|
|
50964
|
+
"../../home/runner/work/void/void/platform/packages/api/src/concurrency.ts"() {
|
|
50965
|
+
"use strict";
|
|
50966
|
+
init_performance2();
|
|
50967
|
+
R2_CONCURRENCY = 6;
|
|
50968
|
+
__name(uploadPool, "uploadPool");
|
|
50969
|
+
}
|
|
50970
|
+
});
|
|
50971
|
+
|
|
50844
50972
|
// ../../home/runner/work/void/void/platform/packages/api/src/routes/project-access.ts
|
|
50845
50973
|
async function requireProjectRouteCapability(context, projectId, capability, db = context.get("db")) {
|
|
50846
50974
|
try {
|
|
@@ -50890,7 +51018,7 @@ async function queryProjectUsage(accountId, apiToken, requestsDataset, projectId
|
|
|
50890
51018
|
}
|
|
50891
51019
|
);
|
|
50892
51020
|
if (!response.ok) {
|
|
50893
|
-
|
|
51021
|
+
throw new Error(`Usage query failed with HTTP ${response.status}`);
|
|
50894
51022
|
}
|
|
50895
51023
|
const result = await response.json();
|
|
50896
51024
|
const row = result.data?.[0];
|
|
@@ -50936,7 +51064,7 @@ async function getAccountUsageProjectWindows(db, userId, since, until) {
|
|
|
50936
51064
|
function analyticsStringLiteral(value) {
|
|
50937
51065
|
return `'${value.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'`;
|
|
50938
51066
|
}
|
|
50939
|
-
async function queryBatchProjectUsageWindows(accountId, apiToken, requestsDataset, windows) {
|
|
51067
|
+
async function queryBatchProjectUsageWindows(accountId, apiToken, requestsDataset, windows, failOnError = false) {
|
|
50940
51068
|
if (windows.length === 0) {
|
|
50941
51069
|
return /* @__PURE__ */ new Map();
|
|
50942
51070
|
}
|
|
@@ -50945,39 +51073,63 @@ async function queryBatchProjectUsageWindows(accountId, apiToken, requestsDatase
|
|
|
50945
51073
|
({ start, end }) => `(blob1 = ${analyticsStringLiteral(project.id)} AND timestamp >= toDateTime64(${analyticsStringLiteral(formatAnalyticsDateMilliseconds(start))}, 3) AND timestamp < toDateTime64(${analyticsStringLiteral(formatAnalyticsDateMilliseconds(end))}, 3))`
|
|
50946
51074
|
)
|
|
50947
51075
|
);
|
|
50948
|
-
const
|
|
51076
|
+
const usage = /* @__PURE__ */ new Map();
|
|
51077
|
+
for (let offset = 0; offset < predicates.length; offset += 50) {
|
|
51078
|
+
const query = `
|
|
50949
51079
|
SELECT
|
|
50950
51080
|
blob1,
|
|
50951
51081
|
SUM(_sample_interval * double1) as requests,
|
|
50952
51082
|
SUM(_sample_interval * double2) as bandwidth_bytes
|
|
50953
51083
|
FROM ${requestsDataset}
|
|
50954
|
-
WHERE ${predicates.join("\n OR ")}
|
|
51084
|
+
WHERE ${predicates.slice(offset, offset + 50).join("\n OR ")}
|
|
50955
51085
|
GROUP BY blob1
|
|
50956
51086
|
`;
|
|
50957
|
-
|
|
50958
|
-
|
|
50959
|
-
{
|
|
50960
|
-
method: "POST",
|
|
50961
|
-
headers: {
|
|
50962
|
-
Authorization: `Bearer ${apiToken}`,
|
|
50963
|
-
"Content-Type": "text/plain"
|
|
50964
|
-
},
|
|
50965
|
-
body: query
|
|
50966
|
-
}
|
|
50967
|
-
);
|
|
50968
|
-
if (!response.ok) {
|
|
50969
|
-
return /* @__PURE__ */ new Map();
|
|
50970
|
-
}
|
|
50971
|
-
const json3 = await response.json();
|
|
50972
|
-
return new Map(
|
|
50973
|
-
(json3.data ?? []).map((row) => [
|
|
50974
|
-
row.blob1,
|
|
51087
|
+
const response = await fetch(
|
|
51088
|
+
`https://api.cloudflare.com/client/v4/accounts/${accountId}/analytics_engine/sql`,
|
|
50975
51089
|
{
|
|
50976
|
-
|
|
50977
|
-
|
|
51090
|
+
method: "POST",
|
|
51091
|
+
headers: {
|
|
51092
|
+
Authorization: `Bearer ${apiToken}`,
|
|
51093
|
+
"Content-Type": "text/plain"
|
|
51094
|
+
},
|
|
51095
|
+
body: query
|
|
50978
51096
|
}
|
|
50979
|
-
|
|
51097
|
+
);
|
|
51098
|
+
if (!response.ok) {
|
|
51099
|
+
if (failOnError) {
|
|
51100
|
+
throw new Error(`Usage query failed with HTTP ${response.status}`);
|
|
51101
|
+
}
|
|
51102
|
+
return /* @__PURE__ */ new Map();
|
|
51103
|
+
}
|
|
51104
|
+
const json3 = await response.json();
|
|
51105
|
+
for (const row of json3.data ?? []) {
|
|
51106
|
+
const previous = usage.get(row.blob1) ?? ZERO_USAGE;
|
|
51107
|
+
usage.set(row.blob1, {
|
|
51108
|
+
requests: previous.requests + Math.round(row.requests ?? 0),
|
|
51109
|
+
bandwidthBytes: previous.bandwidthBytes + Math.round(row.bandwidth_bytes ?? 0)
|
|
51110
|
+
});
|
|
51111
|
+
}
|
|
51112
|
+
}
|
|
51113
|
+
return usage;
|
|
51114
|
+
}
|
|
51115
|
+
async function sumAiUsageForWindows(accountId, apiToken, gatewayId, windows) {
|
|
51116
|
+
const totals = windows.map(() => 0);
|
|
51117
|
+
const tasks = windows.flatMap(
|
|
51118
|
+
({ projectId, intervals }, index2) => intervals.map((interval2) => ({ projectId, interval: interval2, index: index2 }))
|
|
50980
51119
|
);
|
|
51120
|
+
await uploadPool(tasks, 4, async ({ projectId, interval: interval2, index: index2 }) => {
|
|
51121
|
+
const usage = await queryProjectAiUsage(
|
|
51122
|
+
accountId,
|
|
51123
|
+
apiToken,
|
|
51124
|
+
gatewayId,
|
|
51125
|
+
projectId,
|
|
51126
|
+
interval2.start,
|
|
51127
|
+
interval2.end,
|
|
51128
|
+
true
|
|
51129
|
+
);
|
|
51130
|
+
totals[index2] += usage.neurons;
|
|
51131
|
+
});
|
|
51132
|
+
return totals;
|
|
50981
51133
|
}
|
|
50982
51134
|
async function queryTopProjectTraffic(accountId, apiToken, requestsDataset, since, limit) {
|
|
50983
51135
|
if (limit <= 0) {
|
|
@@ -51217,6 +51369,7 @@ var init_usage = __esm({
|
|
|
51217
51369
|
init_performance2();
|
|
51218
51370
|
init_drizzle_orm();
|
|
51219
51371
|
init_dist2();
|
|
51372
|
+
init_concurrency();
|
|
51220
51373
|
init_env();
|
|
51221
51374
|
init_schema2();
|
|
51222
51375
|
init_tiers();
|
|
@@ -51238,22 +51391,30 @@ var init_usage = __esm({
|
|
|
51238
51391
|
}
|
|
51239
51392
|
const since = getCurrentBillingPeriodStart(access.owner.billing_cycle_start);
|
|
51240
51393
|
const requestsDataset = getRequestsDataset(context.env);
|
|
51241
|
-
|
|
51242
|
-
|
|
51243
|
-
|
|
51244
|
-
|
|
51245
|
-
|
|
51246
|
-
|
|
51247
|
-
|
|
51248
|
-
|
|
51249
|
-
|
|
51250
|
-
|
|
51251
|
-
|
|
51252
|
-
|
|
51253
|
-
|
|
51254
|
-
|
|
51255
|
-
|
|
51256
|
-
|
|
51394
|
+
let usage;
|
|
51395
|
+
let aiUsage;
|
|
51396
|
+
try {
|
|
51397
|
+
[usage, aiUsage] = await Promise.all([
|
|
51398
|
+
queryProjectUsage(
|
|
51399
|
+
context.env.CF_ACCOUNT_ID,
|
|
51400
|
+
context.env.CF_API_TOKEN,
|
|
51401
|
+
requestsDataset,
|
|
51402
|
+
projectId,
|
|
51403
|
+
since
|
|
51404
|
+
),
|
|
51405
|
+
queryProjectAiUsage(
|
|
51406
|
+
context.env.CF_ACCOUNT_ID,
|
|
51407
|
+
context.env.CF_API_TOKEN,
|
|
51408
|
+
context.env.AI_GATEWAY_ID ?? "void",
|
|
51409
|
+
projectId,
|
|
51410
|
+
since,
|
|
51411
|
+
void 0,
|
|
51412
|
+
true
|
|
51413
|
+
)
|
|
51414
|
+
]);
|
|
51415
|
+
} catch {
|
|
51416
|
+
return context.json({ error: "usage unavailable" }, 503);
|
|
51417
|
+
}
|
|
51257
51418
|
return context.json({
|
|
51258
51419
|
projectId,
|
|
51259
51420
|
billingPeriodStart: since.toISOString(),
|
|
@@ -51289,38 +51450,32 @@ var init_usage = __esm({
|
|
|
51289
51450
|
});
|
|
51290
51451
|
}
|
|
51291
51452
|
const requestsDataset = getRequestsDataset(context.env);
|
|
51292
|
-
|
|
51293
|
-
|
|
51294
|
-
|
|
51295
|
-
|
|
51296
|
-
|
|
51297
|
-
|
|
51298
|
-
|
|
51299
|
-
|
|
51300
|
-
|
|
51301
|
-
|
|
51302
|
-
|
|
51303
|
-
|
|
51304
|
-
|
|
51305
|
-
|
|
51306
|
-
|
|
51307
|
-
|
|
51308
|
-
project.id,
|
|
51309
|
-
interval2.start,
|
|
51310
|
-
interval2.end
|
|
51311
|
-
)
|
|
51312
|
-
]);
|
|
51313
|
-
return { neurons: total.neurons + usage.neurons };
|
|
51314
|
-
},
|
|
51315
|
-
Promise.resolve({ neurons: 0 })
|
|
51453
|
+
let usageMap;
|
|
51454
|
+
let aiUsages;
|
|
51455
|
+
try {
|
|
51456
|
+
[usageMap, aiUsages] = await Promise.all([
|
|
51457
|
+
queryBatchProjectUsageWindows(
|
|
51458
|
+
context.env.CF_ACCOUNT_ID,
|
|
51459
|
+
context.env.CF_API_TOKEN,
|
|
51460
|
+
requestsDataset,
|
|
51461
|
+
projectWindows,
|
|
51462
|
+
true
|
|
51463
|
+
),
|
|
51464
|
+
sumAiUsageForWindows(
|
|
51465
|
+
context.env.CF_ACCOUNT_ID,
|
|
51466
|
+
context.env.CF_API_TOKEN,
|
|
51467
|
+
context.env.AI_GATEWAY_ID ?? "void",
|
|
51468
|
+
projectWindows.map(({ project, intervals }) => ({ projectId: project.id, intervals }))
|
|
51316
51469
|
)
|
|
51317
|
-
)
|
|
51318
|
-
|
|
51470
|
+
]);
|
|
51471
|
+
} catch {
|
|
51472
|
+
return context.json({ error: "usage unavailable" }, 503);
|
|
51473
|
+
}
|
|
51319
51474
|
const projectUsages = projectWindows.map(({ project }, i) => ({
|
|
51320
51475
|
projectId: project.id,
|
|
51321
51476
|
slug: project.slug,
|
|
51322
51477
|
...usageMap.get(project.id) ?? ZERO_USAGE,
|
|
51323
|
-
aiNeurons: aiUsages[i]
|
|
51478
|
+
aiNeurons: aiUsages[i]
|
|
51324
51479
|
}));
|
|
51325
51480
|
const totals = projectUsages.reduce(
|
|
51326
51481
|
(acc, u) => ({
|
|
@@ -51343,6 +51498,7 @@ var init_usage = __esm({
|
|
|
51343
51498
|
__name(getAccountUsageProjectWindows, "getAccountUsageProjectWindows");
|
|
51344
51499
|
__name(analyticsStringLiteral, "analyticsStringLiteral");
|
|
51345
51500
|
__name(queryBatchProjectUsageWindows, "queryBatchProjectUsageWindows");
|
|
51501
|
+
__name(sumAiUsageForWindows, "sumAiUsageForWindows");
|
|
51346
51502
|
__name(queryTopProjectTraffic, "queryTopProjectTraffic");
|
|
51347
51503
|
__name(formatAnalyticsDate, "formatAnalyticsDate");
|
|
51348
51504
|
__name(formatAnalyticsDateMilliseconds, "formatAnalyticsDateMilliseconds");
|
|
@@ -56273,26 +56429,6 @@ var init_cron_scheduler_client = __esm({
|
|
|
56273
56429
|
}
|
|
56274
56430
|
});
|
|
56275
56431
|
|
|
56276
|
-
// ../../home/runner/work/void/void/platform/packages/api/src/naming.ts
|
|
56277
|
-
function getLegacyProjectWorkerName(slug) {
|
|
56278
|
-
return `user-${slug}`;
|
|
56279
|
-
}
|
|
56280
|
-
function getProjectDeploymentWorkerName(slug, deploymentId) {
|
|
56281
|
-
return `user-${slug}-${deploymentId}`;
|
|
56282
|
-
}
|
|
56283
|
-
function getProjectQueueName(projectId, queueName) {
|
|
56284
|
-
return `${projectId}-${queueName}`.toLowerCase().replaceAll("_", "-");
|
|
56285
|
-
}
|
|
56286
|
-
var init_naming = __esm({
|
|
56287
|
-
"../../home/runner/work/void/void/platform/packages/api/src/naming.ts"() {
|
|
56288
|
-
"use strict";
|
|
56289
|
-
init_performance2();
|
|
56290
|
-
__name(getLegacyProjectWorkerName, "getLegacyProjectWorkerName");
|
|
56291
|
-
__name(getProjectDeploymentWorkerName, "getProjectDeploymentWorkerName");
|
|
56292
|
-
__name(getProjectQueueName, "getProjectQueueName");
|
|
56293
|
-
}
|
|
56294
|
-
});
|
|
56295
|
-
|
|
56296
56432
|
// ../../home/runner/work/void/void/platform/packages/api/src/sandbox-drain.ts
|
|
56297
56433
|
async function writeSandboxDrainMirror(routing, checkpoint) {
|
|
56298
56434
|
const state = {
|
|
@@ -57048,6 +57184,97 @@ function deleteCloudflareResource(accountId, apiToken, resource) {
|
|
|
57048
57184
|
throw new Error(`Unsupported resource type: ${resourceType}`);
|
|
57049
57185
|
}
|
|
57050
57186
|
}
|
|
57187
|
+
function cleanupJob(projectId, kind, target, payload) {
|
|
57188
|
+
return { project_id: projectId, kind, target: `${kind}:${projectId}:${target}`, payload };
|
|
57189
|
+
}
|
|
57190
|
+
function jobValue(job, key) {
|
|
57191
|
+
const value = job.payload[key];
|
|
57192
|
+
if (!value) {
|
|
57193
|
+
throw new Error(`Project cleanup job ${job.target} is missing ${key}`);
|
|
57194
|
+
}
|
|
57195
|
+
return value;
|
|
57196
|
+
}
|
|
57197
|
+
async function ignoreMissingProviderObject(operation) {
|
|
57198
|
+
try {
|
|
57199
|
+
await operation();
|
|
57200
|
+
} catch (error63) {
|
|
57201
|
+
if (error63 instanceof CloudflareApiError && error63.status === 404) {
|
|
57202
|
+
return;
|
|
57203
|
+
}
|
|
57204
|
+
throw error63;
|
|
57205
|
+
}
|
|
57206
|
+
}
|
|
57207
|
+
async function executeCleanupJob(env2, job) {
|
|
57208
|
+
switch (job.kind) {
|
|
57209
|
+
case "cf-resource":
|
|
57210
|
+
await ignoreMissingProviderObject(
|
|
57211
|
+
() => deleteCloudflareResource(env2.CF_ACCOUNT_ID, env2.CF_API_TOKEN, {
|
|
57212
|
+
type: jobValue(job, "type"),
|
|
57213
|
+
cf_id: jobValue(job, "cfId")
|
|
57214
|
+
})
|
|
57215
|
+
);
|
|
57216
|
+
return;
|
|
57217
|
+
case "worker": {
|
|
57218
|
+
const namespace = jobValue(job, "namespace");
|
|
57219
|
+
const name = jobValue(job, "name");
|
|
57220
|
+
const response = await fetch(
|
|
57221
|
+
`https://api.cloudflare.com/client/v4/accounts/${env2.CF_ACCOUNT_ID}/workers/dispatch/namespaces/${namespace}/scripts/${name}`,
|
|
57222
|
+
{ method: "DELETE", headers: { Authorization: `Bearer ${env2.CF_API_TOKEN}` } }
|
|
57223
|
+
);
|
|
57224
|
+
if (!response.ok && response.status !== 404) {
|
|
57225
|
+
throw new Error(`Worker delete returned HTTP ${response.status}: ${await response.text()}`);
|
|
57226
|
+
}
|
|
57227
|
+
void response.body?.cancel().catch(() => {
|
|
57228
|
+
});
|
|
57229
|
+
return;
|
|
57230
|
+
}
|
|
57231
|
+
case "worker-bundle":
|
|
57232
|
+
await deleteWorkerBundle(
|
|
57233
|
+
env2.STATIC_ASSETS_R2,
|
|
57234
|
+
jobValue(job, "projectId"),
|
|
57235
|
+
jobValue(job, "deploymentId")
|
|
57236
|
+
);
|
|
57237
|
+
return;
|
|
57238
|
+
case "project-assets":
|
|
57239
|
+
await deleteProjectAssets(env2.STATIC_ASSETS_R2, jobValue(job, "projectId"));
|
|
57240
|
+
return;
|
|
57241
|
+
case "routing-key":
|
|
57242
|
+
await env2.ROUTING.delete(jobValue(job, "key"));
|
|
57243
|
+
return;
|
|
57244
|
+
case "cron":
|
|
57245
|
+
await clearCronScheduler(env2, jobValue(job, "projectId"));
|
|
57246
|
+
return;
|
|
57247
|
+
case "custom-hostname":
|
|
57248
|
+
await ignoreMissingProviderObject(
|
|
57249
|
+
() => deleteCustomHostname(
|
|
57250
|
+
jobValue(job, "zoneId"),
|
|
57251
|
+
env2.CF_API_TOKEN,
|
|
57252
|
+
jobValue(job, "hostnameId")
|
|
57253
|
+
)
|
|
57254
|
+
);
|
|
57255
|
+
return;
|
|
57256
|
+
}
|
|
57257
|
+
}
|
|
57258
|
+
async function runCleanupBatch(env2, jobs) {
|
|
57259
|
+
const warnings = [];
|
|
57260
|
+
const failed = [];
|
|
57261
|
+
let next = 0;
|
|
57262
|
+
await Promise.all(
|
|
57263
|
+
Array.from({ length: Math.min(5, jobs.length) }, async () => {
|
|
57264
|
+
while (next < jobs.length) {
|
|
57265
|
+
const job = jobs[next++];
|
|
57266
|
+
try {
|
|
57267
|
+
await executeCleanupJob(env2, job);
|
|
57268
|
+
} catch (error63) {
|
|
57269
|
+
const message2 = error63 instanceof Error ? error63.message : String(error63);
|
|
57270
|
+
warnings.push(`Failed to delete ${job.target}: ${message2}`);
|
|
57271
|
+
failed.push(job);
|
|
57272
|
+
}
|
|
57273
|
+
}
|
|
57274
|
+
})
|
|
57275
|
+
);
|
|
57276
|
+
return { warnings, failed };
|
|
57277
|
+
}
|
|
57051
57278
|
async function cleanupCriticalResources(context, projectId, _project) {
|
|
57052
57279
|
const resources2 = await getProjectResources(context.get("db"), projectId);
|
|
57053
57280
|
for (const resource of resources2) {
|
|
@@ -57118,8 +57345,10 @@ function parseDeploymentManifest(raw2) {
|
|
|
57118
57345
|
}
|
|
57119
57346
|
async function cleanupBestEffortResources(context, projectId, project) {
|
|
57120
57347
|
const warnings = [];
|
|
57121
|
-
const
|
|
57348
|
+
const failedJobs = [];
|
|
57349
|
+
const warn = /* @__PURE__ */ __name((msg, job) => (err) => {
|
|
57122
57350
|
warnings.push(`${msg}: ${err instanceof Error ? err.message : String(err)}`);
|
|
57351
|
+
failedJobs.push(job);
|
|
57123
57352
|
}, "warn");
|
|
57124
57353
|
const cleanedCfIds = /* @__PURE__ */ new Set();
|
|
57125
57354
|
const [projectDeployments, resources2, projectDomains] = await Promise.all([
|
|
@@ -57134,28 +57363,37 @@ async function cleanupBestEffortResources(context, projectId, project) {
|
|
|
57134
57363
|
(deployment) => getProjectDeploymentWorkerName(project.slug, deployment.id)
|
|
57135
57364
|
)
|
|
57136
57365
|
]);
|
|
57137
|
-
await
|
|
57366
|
+
const workerResult = await runCleanupBatch(
|
|
57367
|
+
context.env,
|
|
57138
57368
|
Array.from(
|
|
57139
57369
|
workerNames,
|
|
57140
|
-
(workerName) =>
|
|
57141
|
-
|
|
57142
|
-
|
|
57143
|
-
)
|
|
57144
|
-
if (!cfRes.ok && cfRes.status !== 404) {
|
|
57145
|
-
warnings.push(`Failed to delete worker ${workerName}: ${await cfRes.text()}`);
|
|
57146
|
-
}
|
|
57147
|
-
}).catch(warn(`Failed to delete worker ${workerName}`))
|
|
57370
|
+
(workerName) => cleanupJob(projectId, "worker", `${dispatchNamespace}:${workerName}`, {
|
|
57371
|
+
namespace: dispatchNamespace,
|
|
57372
|
+
name: workerName
|
|
57373
|
+
})
|
|
57148
57374
|
)
|
|
57149
57375
|
);
|
|
57150
|
-
|
|
57376
|
+
warnings.push(...workerResult.warnings);
|
|
57377
|
+
failedJobs.push(...workerResult.failed);
|
|
57378
|
+
if (workerResult.failed.some((job) => job.payload.name === getLegacyProjectWorkerName(project.slug))) {
|
|
57379
|
+
throw new Error("Could not remove the legacy project Worker; retry project deletion.");
|
|
57380
|
+
}
|
|
57381
|
+
const bundleResult = await runCleanupBatch(
|
|
57382
|
+
context.env,
|
|
57151
57383
|
projectDeployments.map(
|
|
57152
|
-
(deployment) =>
|
|
57153
|
-
|
|
57154
|
-
|
|
57384
|
+
(deployment) => cleanupJob(projectId, "worker-bundle", `${projectId}:${deployment.id}`, {
|
|
57385
|
+
projectId,
|
|
57386
|
+
deploymentId: deployment.id
|
|
57387
|
+
})
|
|
57155
57388
|
)
|
|
57156
57389
|
);
|
|
57390
|
+
warnings.push(...bundleResult.warnings);
|
|
57391
|
+
failedJobs.push(...bundleResult.failed);
|
|
57157
57392
|
await deleteProjectAssets(context.env.STATIC_ASSETS_R2, projectId).catch(
|
|
57158
|
-
warn(
|
|
57393
|
+
warn(
|
|
57394
|
+
`Failed to delete static assets for project ${projectId}`,
|
|
57395
|
+
cleanupJob(projectId, "project-assets", projectId, { projectId })
|
|
57396
|
+
)
|
|
57159
57397
|
);
|
|
57160
57398
|
const cleanup = [];
|
|
57161
57399
|
for (const resource of resources2) {
|
|
@@ -57163,48 +57401,45 @@ async function cleanupBestEffortResources(context, projectId, project) {
|
|
|
57163
57401
|
continue;
|
|
57164
57402
|
}
|
|
57165
57403
|
cleanedCfIds.add(resource.cf_id);
|
|
57166
|
-
|
|
57167
|
-
|
|
57168
|
-
context.env.CF_API_TOKEN,
|
|
57169
|
-
resource
|
|
57404
|
+
cleanup.push(
|
|
57405
|
+
...cleanupJobsForResource(projectId, resource).filter((job) => job.kind === "cf-resource")
|
|
57170
57406
|
);
|
|
57171
|
-
cleanup.push(del.catch(warn(`Failed to delete ${resource.type} resource ${resource.cf_id}`)));
|
|
57172
57407
|
}
|
|
57408
|
+
cleanup.push(cleanupJob(projectId, "cron", projectId, { projectId }));
|
|
57409
|
+
cleanup.push(cleanupJob(projectId, "routing-key", project.slug, { key: project.slug }));
|
|
57173
57410
|
cleanup.push(
|
|
57174
|
-
|
|
57175
|
-
warn(`Failed to clear cron scheduler for project ${projectId}`)
|
|
57176
|
-
)
|
|
57177
|
-
);
|
|
57178
|
-
cleanup.push(
|
|
57179
|
-
context.env.ROUTING.delete(project.slug).catch(warn("Failed to delete routing entry"))
|
|
57180
|
-
);
|
|
57181
|
-
cleanup.push(
|
|
57182
|
-
context.env.ROUTING.delete(`ai-block:${projectId}`).catch(
|
|
57183
|
-
warn("Failed to delete AI block entry")
|
|
57184
|
-
)
|
|
57411
|
+
cleanupJob(projectId, "routing-key", `ai-block:${projectId}`, { key: `ai-block:${projectId}` })
|
|
57185
57412
|
);
|
|
57186
57413
|
for (const q of resources2.filter((r) => r.type === "queue")) {
|
|
57187
57414
|
cleanup.push(
|
|
57188
|
-
|
|
57189
|
-
warn("Failed to delete queue routing entry")
|
|
57190
|
-
)
|
|
57415
|
+
...cleanupJobsForResource(projectId, q).filter((job) => job.kind === "routing-key")
|
|
57191
57416
|
);
|
|
57192
57417
|
}
|
|
57193
57418
|
for (const domain2 of projectDomains) {
|
|
57194
57419
|
cleanup.push(
|
|
57195
|
-
|
|
57196
|
-
|
|
57197
|
-
|
|
57198
|
-
domain2.cf_hostname_id
|
|
57199
|
-
|
|
57200
|
-
|
|
57201
|
-
|
|
57202
|
-
|
|
57203
|
-
|
|
57204
|
-
|
|
57420
|
+
cleanupJob(
|
|
57421
|
+
projectId,
|
|
57422
|
+
"custom-hostname",
|
|
57423
|
+
`${context.env.CF_ZONE_ID}:${domain2.cf_hostname_id}`,
|
|
57424
|
+
{
|
|
57425
|
+
zoneId: context.env.CF_ZONE_ID,
|
|
57426
|
+
hostnameId: domain2.cf_hostname_id
|
|
57427
|
+
}
|
|
57428
|
+
),
|
|
57429
|
+
cleanupJob(projectId, "routing-key", `domain:${domain2.hostname}`, {
|
|
57430
|
+
key: `domain:${domain2.hostname}`
|
|
57431
|
+
})
|
|
57205
57432
|
);
|
|
57206
57433
|
}
|
|
57207
|
-
await
|
|
57434
|
+
const remaining = await runCleanupBatch(context.env, cleanup);
|
|
57435
|
+
warnings.push(...remaining.warnings);
|
|
57436
|
+
failedJobs.push(...remaining.failed);
|
|
57437
|
+
if (remaining.failed.some(
|
|
57438
|
+
(job) => job.kind === "routing-key" && (job.payload.key === project.slug || job.payload.key?.startsWith("domain:"))
|
|
57439
|
+
)) {
|
|
57440
|
+
throw new Error("Could not remove project routing; retry project deletion.");
|
|
57441
|
+
}
|
|
57442
|
+
await enqueueProjectCleanupJobs(context.get("db"), failedJobs);
|
|
57208
57443
|
return { warnings, cleanedCfIds };
|
|
57209
57444
|
}
|
|
57210
57445
|
async function lockAndMarkDeleting(db, projectId, actorUserId, expectedOwnerUserId) {
|
|
@@ -57310,31 +57545,48 @@ async function detachProjectUsage(context, projectId, options) {
|
|
|
57310
57545
|
}
|
|
57311
57546
|
}
|
|
57312
57547
|
async function cleanupRaceWindowResourceOrphans(context, projectId, deletedResources, cleanedCfIds) {
|
|
57313
|
-
const warnings = [];
|
|
57314
|
-
const warn = /* @__PURE__ */ __name((msg) => (err) => {
|
|
57315
|
-
warnings.push(`${msg}: ${err instanceof Error ? err.message : String(err)}`);
|
|
57316
|
-
}, "warn");
|
|
57317
57548
|
const orphans = deletedResources.filter(
|
|
57318
57549
|
(r) => r.type !== "container" && !cleanedCfIds.has(r.cf_id)
|
|
57319
57550
|
);
|
|
57551
|
+
const jobs = orphans.flatMap((resource) => cleanupJobsForResource(projectId, resource));
|
|
57552
|
+
const result = await runCleanupBatch(context.env, jobs);
|
|
57553
|
+
const failedTargets = new Set(result.failed.map((job) => job.target));
|
|
57554
|
+
const completedTargets = jobs.filter((job) => !failedTargets.has(job.target)).map((job) => job.target);
|
|
57555
|
+
if (completedTargets.length > 0) {
|
|
57556
|
+
await context.get("db").delete(projectCleanupJobs).where(inArray(projectCleanupJobs.target, completedTargets)).catch((error63) => console.error("[project-cleanup] completed job delete failed:", error63));
|
|
57557
|
+
}
|
|
57558
|
+
return result.warnings;
|
|
57559
|
+
}
|
|
57560
|
+
async function reconcileProjectCleanupJobs(db, env2) {
|
|
57561
|
+
const due = await db.select().from(projectCleanupJobs).where(lte(projectCleanupJobs.next_attempt_at, sql`now()`)).orderBy(asc(projectCleanupJobs.created_at), asc(projectCleanupJobs.target)).limit(50);
|
|
57562
|
+
let next = 0;
|
|
57320
57563
|
await Promise.all(
|
|
57321
|
-
|
|
57322
|
-
|
|
57323
|
-
|
|
57324
|
-
|
|
57325
|
-
|
|
57326
|
-
|
|
57327
|
-
|
|
57328
|
-
|
|
57329
|
-
|
|
57330
|
-
|
|
57331
|
-
)
|
|
57332
|
-
);
|
|
57564
|
+
Array.from({ length: Math.min(5, due.length) }, async () => {
|
|
57565
|
+
while (next < due.length) {
|
|
57566
|
+
const job = due[next++];
|
|
57567
|
+
const claimed = await db.update(projectCleanupJobs).set({
|
|
57568
|
+
attempts: sql`${projectCleanupJobs.attempts} + 1`,
|
|
57569
|
+
next_attempt_at: new Date(Date.now() + 15 * 6e4).toISOString()
|
|
57570
|
+
}).where(
|
|
57571
|
+
and(
|
|
57572
|
+
eq(projectCleanupJobs.target, job.target),
|
|
57573
|
+
lte(projectCleanupJobs.next_attempt_at, sql`now()`)
|
|
57574
|
+
)
|
|
57575
|
+
).returning({ target: projectCleanupJobs.target });
|
|
57576
|
+
if (claimed.length === 0) {
|
|
57577
|
+
continue;
|
|
57578
|
+
}
|
|
57579
|
+
try {
|
|
57580
|
+
await executeCleanupJob(env2, job);
|
|
57581
|
+
await db.delete(projectCleanupJobs).where(eq(projectCleanupJobs.target, job.target));
|
|
57582
|
+
} catch (error63) {
|
|
57583
|
+
const message2 = (error63 instanceof Error ? error63.message : String(error63)).replaceAll(env2.CF_API_TOKEN, "[redacted]").slice(0, 500);
|
|
57584
|
+
await db.update(projectCleanupJobs).set({ last_error: message2 }).where(eq(projectCleanupJobs.target, job.target));
|
|
57585
|
+
console.warn(`[project-cleanup] retry failed for ${job.target}: ${message2}`);
|
|
57586
|
+
}
|
|
57333
57587
|
}
|
|
57334
|
-
return tasks;
|
|
57335
57588
|
})
|
|
57336
57589
|
);
|
|
57337
|
-
return warnings;
|
|
57338
57590
|
}
|
|
57339
57591
|
async function teardownProject(context, projectId, project, options = {}) {
|
|
57340
57592
|
const deletion = await lockAndMarkDeleting(
|
|
@@ -57364,7 +57616,8 @@ async function teardownProject(context, projectId, project, options = {}) {
|
|
|
57364
57616
|
await cleanupProjectEmailDestinations(context, projectId);
|
|
57365
57617
|
const { cancelledBuilds, deletedResources } = await deleteProjectCascade(
|
|
57366
57618
|
context.get("db"),
|
|
57367
|
-
projectId
|
|
57619
|
+
projectId,
|
|
57620
|
+
cleanedCfIds
|
|
57368
57621
|
);
|
|
57369
57622
|
await cancelContainerBuildDos(context.env, cancelledBuilds, "project deleted");
|
|
57370
57623
|
const orphanWarnings = await cleanupRaceWindowResourceOrphans(
|
|
@@ -57452,6 +57705,11 @@ var init_cleanup = __esm({
|
|
|
57452
57705
|
init_email_destination_cleanup();
|
|
57453
57706
|
init_sandbox_controller();
|
|
57454
57707
|
__name(deleteCloudflareResource, "deleteCloudflareResource");
|
|
57708
|
+
__name(cleanupJob, "cleanupJob");
|
|
57709
|
+
__name(jobValue, "jobValue");
|
|
57710
|
+
__name(ignoreMissingProviderObject, "ignoreMissingProviderObject");
|
|
57711
|
+
__name(executeCleanupJob, "executeCleanupJob");
|
|
57712
|
+
__name(runCleanupBatch, "runCleanupBatch");
|
|
57455
57713
|
__name(cleanupCriticalResources, "cleanupCriticalResources");
|
|
57456
57714
|
__name(sweepPerDeployContainerOrphans, "sweepPerDeployContainerOrphans");
|
|
57457
57715
|
__name(parseDeploymentManifest, "parseDeploymentManifest");
|
|
@@ -57468,6 +57726,7 @@ var init_cleanup = __esm({
|
|
|
57468
57726
|
}
|
|
57469
57727
|
};
|
|
57470
57728
|
__name(cleanupRaceWindowResourceOrphans, "cleanupRaceWindowResourceOrphans");
|
|
57729
|
+
__name(reconcileProjectCleanupJobs, "reconcileProjectCleanupJobs");
|
|
57471
57730
|
__name(teardownProject, "teardownProject");
|
|
57472
57731
|
__name(cleanupProjectEmailDestinations, "cleanupProjectEmailDestinations");
|
|
57473
57732
|
__name(cleanupProjectEmailAssignments, "cleanupProjectEmailAssignments");
|
|
@@ -69742,7 +70001,7 @@ A.finished.finally(function(){document.__reactViewTransition===A&&(document.__re
|
|
|
69742
70001
|
return [workInProgressHook.memoizedState, reducer];
|
|
69743
70002
|
}
|
|
69744
70003
|
__name(useReducer, "useReducer");
|
|
69745
|
-
function
|
|
70004
|
+
function useMemo36(nextCreate, deps) {
|
|
69746
70005
|
currentlyRenderingComponent = resolveCurrentlyRenderingComponent();
|
|
69747
70006
|
workInProgressHook = createWorkInProgressHook();
|
|
69748
70007
|
deps = void 0 === deps ? null : deps;
|
|
@@ -69766,7 +70025,7 @@ A.finished.finally(function(){document.__reactViewTransition===A&&(document.__re
|
|
|
69766
70025
|
workInProgressHook.memoizedState = [nextCreate, deps];
|
|
69767
70026
|
return nextCreate;
|
|
69768
70027
|
}
|
|
69769
|
-
__name(
|
|
70028
|
+
__name(useMemo36, "useMemo");
|
|
69770
70029
|
function dispatchAction(componentIdentity, queue, action2) {
|
|
69771
70030
|
if (25 <= numberOfReRenders)
|
|
69772
70031
|
throw Error(
|
|
@@ -69867,7 +70126,7 @@ A.finished.finally(function(){document.__reactViewTransition===A&&(document.__re
|
|
|
69867
70126
|
resolveCurrentlyRenderingComponent();
|
|
69868
70127
|
return context._currentValue;
|
|
69869
70128
|
}, "useContext"),
|
|
69870
|
-
useMemo:
|
|
70129
|
+
useMemo: useMemo36,
|
|
69871
70130
|
useReducer,
|
|
69872
70131
|
useRef: /* @__PURE__ */ __name(function(initialValue) {
|
|
69873
70132
|
currentlyRenderingComponent = resolveCurrentlyRenderingComponent();
|
|
@@ -69881,7 +70140,7 @@ A.finished.finally(function(){document.__reactViewTransition===A&&(document.__re
|
|
|
69881
70140
|
useInsertionEffect: noop,
|
|
69882
70141
|
useLayoutEffect: noop,
|
|
69883
70142
|
useCallback: /* @__PURE__ */ __name(function(callback, deps) {
|
|
69884
|
-
return
|
|
70143
|
+
return useMemo36(function() {
|
|
69885
70144
|
return callback;
|
|
69886
70145
|
}, deps);
|
|
69887
70146
|
}, "useCallback"),
|
|
@@ -75507,7 +75766,7 @@ var require_react_dom_server_legacy_browser_production = __commonJS({
|
|
|
75507
75766
|
return [workInProgressHook.memoizedState, reducer];
|
|
75508
75767
|
}
|
|
75509
75768
|
__name(useReducer, "useReducer");
|
|
75510
|
-
function
|
|
75769
|
+
function useMemo36(nextCreate, deps) {
|
|
75511
75770
|
currentlyRenderingComponent = resolveCurrentlyRenderingComponent();
|
|
75512
75771
|
workInProgressHook = createWorkInProgressHook();
|
|
75513
75772
|
deps = void 0 === deps ? null : deps;
|
|
@@ -75531,7 +75790,7 @@ var require_react_dom_server_legacy_browser_production = __commonJS({
|
|
|
75531
75790
|
workInProgressHook.memoizedState = [nextCreate, deps];
|
|
75532
75791
|
return nextCreate;
|
|
75533
75792
|
}
|
|
75534
|
-
__name(
|
|
75793
|
+
__name(useMemo36, "useMemo");
|
|
75535
75794
|
function dispatchAction(componentIdentity, queue, action2) {
|
|
75536
75795
|
if (25 <= numberOfReRenders) throw Error(formatProdErrorMessage(301));
|
|
75537
75796
|
if (componentIdentity === currentlyRenderingComponent)
|
|
@@ -75628,7 +75887,7 @@ var require_react_dom_server_legacy_browser_production = __commonJS({
|
|
|
75628
75887
|
resolveCurrentlyRenderingComponent();
|
|
75629
75888
|
return context._currentValue2;
|
|
75630
75889
|
}, "useContext"),
|
|
75631
|
-
useMemo:
|
|
75890
|
+
useMemo: useMemo36,
|
|
75632
75891
|
useReducer,
|
|
75633
75892
|
useRef: /* @__PURE__ */ __name(function(initialValue) {
|
|
75634
75893
|
currentlyRenderingComponent = resolveCurrentlyRenderingComponent();
|
|
@@ -75642,7 +75901,7 @@ var require_react_dom_server_legacy_browser_production = __commonJS({
|
|
|
75642
75901
|
useInsertionEffect: noop,
|
|
75643
75902
|
useLayoutEffect: noop,
|
|
75644
75903
|
useCallback: /* @__PURE__ */ __name(function(callback, deps) {
|
|
75645
|
-
return
|
|
75904
|
+
return useMemo36(function() {
|
|
75646
75905
|
return callback;
|
|
75647
75906
|
}, deps);
|
|
75648
75907
|
}, "useCallback"),
|
|
@@ -78469,13 +78728,130 @@ var init_context2 = __esm({
|
|
|
78469
78728
|
});
|
|
78470
78729
|
|
|
78471
78730
|
// ../../home/runner/work/void/void/packages/react/src/runtime/deferred-shell.ts
|
|
78472
|
-
var DEFERRED_SHELL_END_ID, DEFERRED_SHELL_END_MARKER;
|
|
78731
|
+
var DEFERRED_SHELL_END_ID, DEFERRED_SHELL_END_MARKER, DEFERRED_SHELL_CANCEL_REASON;
|
|
78473
78732
|
var init_deferred_shell = __esm({
|
|
78474
78733
|
"../../home/runner/work/void/void/packages/react/src/runtime/deferred-shell.ts"() {
|
|
78475
78734
|
"use strict";
|
|
78476
78735
|
init_performance2();
|
|
78477
78736
|
DEFERRED_SHELL_END_ID = "__VOID_DEFERRED_SHELL_END__";
|
|
78478
78737
|
DEFERRED_SHELL_END_MARKER = `<template id="${DEFERRED_SHELL_END_ID}"></template>`;
|
|
78738
|
+
DEFERRED_SHELL_CANCEL_REASON = "Void deferred shell complete";
|
|
78739
|
+
}
|
|
78740
|
+
});
|
|
78741
|
+
|
|
78742
|
+
// ../../home/runner/work/void/void/packages/react/src/runtime/page-streams.ts
|
|
78743
|
+
function concatStreams(streams) {
|
|
78744
|
+
let index2 = 0;
|
|
78745
|
+
let reader;
|
|
78746
|
+
let cancelled = false;
|
|
78747
|
+
const cancelRemaining = /* @__PURE__ */ __name(async (reason) => {
|
|
78748
|
+
const cancellations = [];
|
|
78749
|
+
if (reader) {
|
|
78750
|
+
cancellations.push(reader.cancel(reason));
|
|
78751
|
+
}
|
|
78752
|
+
for (let remaining = index2 + (reader ? 1 : 0); remaining < streams.length; remaining++) {
|
|
78753
|
+
cancellations.push(streams[remaining].cancel(reason));
|
|
78754
|
+
}
|
|
78755
|
+
await Promise.allSettled(cancellations);
|
|
78756
|
+
}, "cancelRemaining");
|
|
78757
|
+
return new ReadableStream(
|
|
78758
|
+
{
|
|
78759
|
+
async pull(controller) {
|
|
78760
|
+
try {
|
|
78761
|
+
while (index2 < streams.length) {
|
|
78762
|
+
reader ??= streams[index2].getReader();
|
|
78763
|
+
const { done, value } = await reader.read();
|
|
78764
|
+
if (cancelled) {
|
|
78765
|
+
return;
|
|
78766
|
+
}
|
|
78767
|
+
if (done) {
|
|
78768
|
+
reader.releaseLock();
|
|
78769
|
+
reader = void 0;
|
|
78770
|
+
index2++;
|
|
78771
|
+
continue;
|
|
78772
|
+
}
|
|
78773
|
+
controller.enqueue(value);
|
|
78774
|
+
return;
|
|
78775
|
+
}
|
|
78776
|
+
controller.close();
|
|
78777
|
+
} catch (error63) {
|
|
78778
|
+
if (!cancelled) {
|
|
78779
|
+
controller.error(error63);
|
|
78780
|
+
await cancelRemaining(error63);
|
|
78781
|
+
}
|
|
78782
|
+
}
|
|
78783
|
+
},
|
|
78784
|
+
async cancel(reason) {
|
|
78785
|
+
cancelled = true;
|
|
78786
|
+
await cancelRemaining(reason);
|
|
78787
|
+
}
|
|
78788
|
+
},
|
|
78789
|
+
{ highWaterMark: 0 }
|
|
78790
|
+
);
|
|
78791
|
+
}
|
|
78792
|
+
function readDeferredShell(stream) {
|
|
78793
|
+
const reader = stream.getReader();
|
|
78794
|
+
const decoder5 = new TextDecoder();
|
|
78795
|
+
const encoder12 = new TextEncoder();
|
|
78796
|
+
const keepLength = DEFERRED_SHELL_END_MARKER.length - 1;
|
|
78797
|
+
let buffer = "";
|
|
78798
|
+
let cancelled = false;
|
|
78799
|
+
return new ReadableStream(
|
|
78800
|
+
{
|
|
78801
|
+
async pull(controller) {
|
|
78802
|
+
try {
|
|
78803
|
+
while (true) {
|
|
78804
|
+
const { done, value } = await reader.read();
|
|
78805
|
+
if (cancelled) {
|
|
78806
|
+
return;
|
|
78807
|
+
}
|
|
78808
|
+
buffer += done ? decoder5.decode() : decoder5.decode(value, { stream: true });
|
|
78809
|
+
const markerIndex = buffer.indexOf(DEFERRED_SHELL_END_MARKER);
|
|
78810
|
+
if (markerIndex !== -1) {
|
|
78811
|
+
const shell = buffer.slice(0, markerIndex + DEFERRED_SHELL_END_MARKER.length);
|
|
78812
|
+
await reader.cancel(DEFERRED_SHELL_CANCEL_REASON);
|
|
78813
|
+
if (!cancelled) {
|
|
78814
|
+
controller.enqueue(encoder12.encode(shell));
|
|
78815
|
+
controller.close();
|
|
78816
|
+
}
|
|
78817
|
+
return;
|
|
78818
|
+
}
|
|
78819
|
+
if (done) {
|
|
78820
|
+
if (buffer) {
|
|
78821
|
+
controller.enqueue(encoder12.encode(buffer));
|
|
78822
|
+
}
|
|
78823
|
+
controller.close();
|
|
78824
|
+
return;
|
|
78825
|
+
}
|
|
78826
|
+
if (buffer.length > keepLength) {
|
|
78827
|
+
controller.enqueue(encoder12.encode(buffer.slice(0, -keepLength)));
|
|
78828
|
+
buffer = buffer.slice(-keepLength);
|
|
78829
|
+
return;
|
|
78830
|
+
}
|
|
78831
|
+
}
|
|
78832
|
+
} catch (error63) {
|
|
78833
|
+
if (!cancelled) {
|
|
78834
|
+
controller.error(error63);
|
|
78835
|
+
await reader.cancel(error63).catch(() => {
|
|
78836
|
+
});
|
|
78837
|
+
}
|
|
78838
|
+
}
|
|
78839
|
+
},
|
|
78840
|
+
async cancel(reason) {
|
|
78841
|
+
cancelled = true;
|
|
78842
|
+
await reader.cancel(reason);
|
|
78843
|
+
}
|
|
78844
|
+
},
|
|
78845
|
+
{ highWaterMark: 0 }
|
|
78846
|
+
);
|
|
78847
|
+
}
|
|
78848
|
+
var init_page_streams = __esm({
|
|
78849
|
+
"../../home/runner/work/void/void/packages/react/src/runtime/page-streams.ts"() {
|
|
78850
|
+
"use strict";
|
|
78851
|
+
init_performance2();
|
|
78852
|
+
init_deferred_shell();
|
|
78853
|
+
__name(concatStreams, "concatStreams");
|
|
78854
|
+
__name(readDeferredShell, "readDeferredShell");
|
|
78479
78855
|
}
|
|
78480
78856
|
});
|
|
78481
78857
|
|
|
@@ -78503,67 +78879,6 @@ function textStream(text2) {
|
|
|
78503
78879
|
}
|
|
78504
78880
|
});
|
|
78505
78881
|
}
|
|
78506
|
-
function concatStreams(streams) {
|
|
78507
|
-
return new ReadableStream({
|
|
78508
|
-
async start(controller) {
|
|
78509
|
-
try {
|
|
78510
|
-
for (const stream of streams) {
|
|
78511
|
-
const reader = stream.getReader();
|
|
78512
|
-
while (true) {
|
|
78513
|
-
const { done, value } = await reader.read();
|
|
78514
|
-
if (done) {
|
|
78515
|
-
break;
|
|
78516
|
-
}
|
|
78517
|
-
controller.enqueue(value);
|
|
78518
|
-
}
|
|
78519
|
-
}
|
|
78520
|
-
controller.close();
|
|
78521
|
-
} catch (error63) {
|
|
78522
|
-
controller.error(error63);
|
|
78523
|
-
}
|
|
78524
|
-
}
|
|
78525
|
-
});
|
|
78526
|
-
}
|
|
78527
|
-
function readDeferredShell(stream) {
|
|
78528
|
-
const encoder12 = new TextEncoder();
|
|
78529
|
-
return new ReadableStream({
|
|
78530
|
-
async start(controller) {
|
|
78531
|
-
const reader = stream.getReader();
|
|
78532
|
-
const decoder5 = new TextDecoder();
|
|
78533
|
-
let buffer = "";
|
|
78534
|
-
const keepLength = DEFERRED_SHELL_END_MARKER.length - 1;
|
|
78535
|
-
const flush = /* @__PURE__ */ __name((text2) => {
|
|
78536
|
-
if (text2) {
|
|
78537
|
-
controller.enqueue(encoder12.encode(text2));
|
|
78538
|
-
}
|
|
78539
|
-
}, "flush");
|
|
78540
|
-
try {
|
|
78541
|
-
while (true) {
|
|
78542
|
-
const { done, value } = await reader.read();
|
|
78543
|
-
if (done) {
|
|
78544
|
-
buffer += decoder5.decode();
|
|
78545
|
-
flush(buffer);
|
|
78546
|
-
break;
|
|
78547
|
-
}
|
|
78548
|
-
buffer += decoder5.decode(value, { stream: true });
|
|
78549
|
-
const markerIndex = buffer.indexOf(DEFERRED_SHELL_END_MARKER);
|
|
78550
|
-
if (markerIndex !== -1) {
|
|
78551
|
-
flush(buffer.slice(0, markerIndex + DEFERRED_SHELL_END_MARKER.length));
|
|
78552
|
-
await reader.cancel(DEFERRED_SHELL_CANCEL_REASON);
|
|
78553
|
-
break;
|
|
78554
|
-
}
|
|
78555
|
-
if (buffer.length > keepLength) {
|
|
78556
|
-
flush(buffer.slice(0, -keepLength));
|
|
78557
|
-
buffer = buffer.slice(-keepLength);
|
|
78558
|
-
}
|
|
78559
|
-
}
|
|
78560
|
-
controller.close();
|
|
78561
|
-
} catch (error63) {
|
|
78562
|
-
controller.error(error63);
|
|
78563
|
-
}
|
|
78564
|
-
}
|
|
78565
|
-
});
|
|
78566
|
-
}
|
|
78567
78882
|
async function renderReactPage({
|
|
78568
78883
|
pageObj,
|
|
78569
78884
|
assetTags,
|
|
@@ -78635,7 +78950,7 @@ async function renderReactPage({
|
|
|
78635
78950
|
</html>`)
|
|
78636
78951
|
]);
|
|
78637
78952
|
}
|
|
78638
|
-
var import_react2, import_server
|
|
78953
|
+
var import_react2, import_server;
|
|
78639
78954
|
var init_pages_server = __esm({
|
|
78640
78955
|
"../../home/runner/work/void/void/packages/react/src/runtime/pages-server.ts"() {
|
|
78641
78956
|
init_performance2();
|
|
@@ -78646,12 +78961,10 @@ var init_pages_server = __esm({
|
|
|
78646
78961
|
init_serialize();
|
|
78647
78962
|
init_context2();
|
|
78648
78963
|
init_deferred_shell();
|
|
78649
|
-
|
|
78964
|
+
init_page_streams();
|
|
78650
78965
|
__name(createPendingDeferred, "createPendingDeferred");
|
|
78651
78966
|
__name(propsForReactRender, "propsForReactRender");
|
|
78652
78967
|
__name(textStream, "textStream");
|
|
78653
|
-
__name(concatStreams, "concatStreams");
|
|
78654
|
-
__name(readDeferredShell, "readDeferredShell");
|
|
78655
78968
|
__name(renderReactPage, "renderReactPage");
|
|
78656
78969
|
}
|
|
78657
78970
|
});
|
|
@@ -121169,38 +121482,28 @@ var init_Typeahead2 = __esm({
|
|
|
121169
121482
|
function SearchTypeahead({
|
|
121170
121483
|
label,
|
|
121171
121484
|
onChange,
|
|
121172
|
-
|
|
121485
|
+
onSelect,
|
|
121486
|
+
onClear,
|
|
121487
|
+
suggestions = noSuggestions,
|
|
121488
|
+
remoteSearch,
|
|
121173
121489
|
initialValue = "",
|
|
121490
|
+
initialSelection,
|
|
121174
121491
|
width = 320
|
|
121175
121492
|
}) {
|
|
121176
121493
|
const items = (0, import_react148.useMemo)(() => {
|
|
121177
|
-
|
|
121178
|
-
for (const suggestion of suggestions) {
|
|
121179
|
-
if (!suggestion) {
|
|
121180
|
-
continue;
|
|
121181
|
-
}
|
|
121182
|
-
const item = typeof suggestion === "string" ? { id: suggestion, label: suggestion, auxiliaryData: { keywords: [] } } : {
|
|
121183
|
-
id: suggestion.id,
|
|
121184
|
-
label: suggestion.label,
|
|
121185
|
-
auxiliaryData: {
|
|
121186
|
-
keywords: suggestion.keywords?.filter((value) => Boolean(value)) ?? [],
|
|
121187
|
-
description: suggestion.description
|
|
121188
|
-
}
|
|
121189
|
-
};
|
|
121190
|
-
if (item.id && item.label) {
|
|
121191
|
-
byId.set(item.id, item);
|
|
121192
|
-
}
|
|
121193
|
-
}
|
|
121194
|
-
return [...byId.values()];
|
|
121494
|
+
return searchItems(suggestions);
|
|
121195
121495
|
}, [suggestions]);
|
|
121196
121496
|
const source = (0, import_react148.useMemo)(
|
|
121197
|
-
() =>
|
|
121497
|
+
() => remoteSearch ? {
|
|
121498
|
+
bootstrap: /* @__PURE__ */ __name(() => [], "bootstrap"),
|
|
121499
|
+
search: /* @__PURE__ */ __name(async (query) => searchItems(await remoteSearch(query)), "search")
|
|
121500
|
+
} : createStaticSource(items, {
|
|
121198
121501
|
keywords: /* @__PURE__ */ __name((item) => item.auxiliaryData?.keywords ?? [], "keywords")
|
|
121199
121502
|
}),
|
|
121200
|
-
[items]
|
|
121503
|
+
[items, remoteSearch]
|
|
121201
121504
|
);
|
|
121202
121505
|
const [selected, setSelected] = (0, import_react148.useState)(
|
|
121203
|
-
() => initialValue ? items.find((item) => item.id === initialValue) ?? {
|
|
121506
|
+
() => initialValue ? items.find((item) => item.id === initialValue) ?? (initialSelection?.id === initialValue ? searchItems([initialSelection])[0] : void 0) ?? {
|
|
121204
121507
|
id: initialValue,
|
|
121205
121508
|
label: initialValue
|
|
121206
121509
|
} : null
|
|
@@ -121217,19 +121520,46 @@ function SearchTypeahead({
|
|
|
121217
121520
|
onChange: (item) => {
|
|
121218
121521
|
setSelected(item);
|
|
121219
121522
|
onChange(item?.id ?? "");
|
|
121523
|
+
if (item) {
|
|
121524
|
+
onSelect?.(item.id);
|
|
121525
|
+
} else {
|
|
121526
|
+
onClear?.();
|
|
121527
|
+
}
|
|
121220
121528
|
},
|
|
121221
121529
|
onChangeQuery: (query) => {
|
|
121222
121530
|
setSelected(null);
|
|
121223
121531
|
onChange(query);
|
|
121224
121532
|
},
|
|
121225
|
-
hasEntriesOnFocus:
|
|
121226
|
-
|
|
121533
|
+
hasEntriesOnFocus: !remoteSearch,
|
|
121534
|
+
hasClear: true,
|
|
121535
|
+
minQueryLength: remoteSearch ? 2 : 1,
|
|
121536
|
+
debounceMs: remoteSearch ? 200 : 0,
|
|
121227
121537
|
width,
|
|
121228
|
-
emptySearchResultsText: "No suggestions. Search for any text."
|
|
121538
|
+
emptySearchResultsText: remoteSearch ? "No matching results." : "No suggestions. Search for any text."
|
|
121229
121539
|
}
|
|
121230
121540
|
);
|
|
121231
121541
|
}
|
|
121232
|
-
|
|
121542
|
+
function searchItems(suggestions) {
|
|
121543
|
+
const byId = /* @__PURE__ */ new Map();
|
|
121544
|
+
for (const suggestion of suggestions) {
|
|
121545
|
+
if (!suggestion) {
|
|
121546
|
+
continue;
|
|
121547
|
+
}
|
|
121548
|
+
const item = typeof suggestion === "string" ? { id: suggestion, label: suggestion, auxiliaryData: { keywords: [] } } : {
|
|
121549
|
+
id: suggestion.id,
|
|
121550
|
+
label: suggestion.label,
|
|
121551
|
+
auxiliaryData: {
|
|
121552
|
+
keywords: suggestion.keywords?.filter((value) => Boolean(value)) ?? [],
|
|
121553
|
+
description: suggestion.description
|
|
121554
|
+
}
|
|
121555
|
+
};
|
|
121556
|
+
if (item.id && item.label) {
|
|
121557
|
+
byId.set(item.id, item);
|
|
121558
|
+
}
|
|
121559
|
+
}
|
|
121560
|
+
return [...byId.values()];
|
|
121561
|
+
}
|
|
121562
|
+
var import_react148, import_jsx_runtime103, noSuggestions;
|
|
121233
121563
|
var init_SearchTypeahead = __esm({
|
|
121234
121564
|
"../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/SearchTypeahead.tsx"() {
|
|
121235
121565
|
"use strict";
|
|
@@ -121237,7 +121567,9 @@ var init_SearchTypeahead = __esm({
|
|
|
121237
121567
|
init_Typeahead2();
|
|
121238
121568
|
import_react148 = __toESM(require_react(), 1);
|
|
121239
121569
|
import_jsx_runtime103 = __toESM(require_jsx_runtime(), 1);
|
|
121570
|
+
noSuggestions = [];
|
|
121240
121571
|
__name(SearchTypeahead, "SearchTypeahead");
|
|
121572
|
+
__name(searchItems, "searchItems");
|
|
121241
121573
|
}
|
|
121242
121574
|
});
|
|
121243
121575
|
|
|
@@ -121631,13 +121963,61 @@ var init_Pagination = __esm({
|
|
|
121631
121963
|
// ../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/SearchForm.tsx
|
|
121632
121964
|
function SearchForm({
|
|
121633
121965
|
action: action2,
|
|
121966
|
+
kind,
|
|
121634
121967
|
label,
|
|
121635
121968
|
value,
|
|
121636
121969
|
onChange,
|
|
121637
|
-
suggestions,
|
|
121638
121970
|
initialValue,
|
|
121639
|
-
|
|
121971
|
+
initialSelection
|
|
121640
121972
|
}) {
|
|
121973
|
+
const fate = useFateClient();
|
|
121974
|
+
const router = useRouter();
|
|
121975
|
+
const remoteSearch = (0, import_react151.useCallback)(
|
|
121976
|
+
async (query) => {
|
|
121977
|
+
const path = `${action2}?search=${encodeURIComponent(query)}`;
|
|
121978
|
+
if (kind === "users") {
|
|
121979
|
+
const { usersPage: ref2 } = await fate.request(usersPageRequest(path), {
|
|
121980
|
+
mode: "network-only"
|
|
121981
|
+
});
|
|
121982
|
+
if (!ref2) {
|
|
121983
|
+
return [];
|
|
121984
|
+
}
|
|
121985
|
+
const { data: data2 } = await fate.readView(UsersPageView, ref2);
|
|
121986
|
+
return data2.users.map((user) => ({
|
|
121987
|
+
id: user.id,
|
|
121988
|
+
label: user.login,
|
|
121989
|
+
description: [user.email, user.id].filter(Boolean).join(" \xB7 ")
|
|
121990
|
+
}));
|
|
121991
|
+
}
|
|
121992
|
+
if (kind === "projects") {
|
|
121993
|
+
const { projectsPage: ref2 } = await fate.request(projectsPageRequest(path), {
|
|
121994
|
+
mode: "network-only"
|
|
121995
|
+
});
|
|
121996
|
+
if (!ref2) {
|
|
121997
|
+
return [];
|
|
121998
|
+
}
|
|
121999
|
+
const { data: data2 } = await fate.readView(ProjectsPageView, ref2);
|
|
122000
|
+
return data2.projects.map((project) => ({
|
|
122001
|
+
id: project.id,
|
|
122002
|
+
label: project.slug,
|
|
122003
|
+
description: project.owner_login ?? void 0
|
|
122004
|
+
}));
|
|
122005
|
+
}
|
|
122006
|
+
const { deploymentsPage: ref } = await fate.request(deploymentsPageRequest(path), {
|
|
122007
|
+
mode: "network-only"
|
|
122008
|
+
});
|
|
122009
|
+
if (!ref) {
|
|
122010
|
+
return [];
|
|
122011
|
+
}
|
|
122012
|
+
const { data } = await fate.readView(DeploymentsPageView, ref);
|
|
122013
|
+
return data.deployments.map((deployment) => ({
|
|
122014
|
+
id: deployment.id,
|
|
122015
|
+
label: deployment.id,
|
|
122016
|
+
description: [deployment.project_slug, deployment.status].filter(Boolean).join(" \xB7 ")
|
|
122017
|
+
}));
|
|
122018
|
+
},
|
|
122019
|
+
[action2, fate, kind]
|
|
122020
|
+
);
|
|
121641
122021
|
return /* @__PURE__ */ (0, import_jsx_runtime107.jsxs)("form", { method: "get", action: action2, className: "void-admin-search", children: [
|
|
121642
122022
|
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)("input", { type: "hidden", name: "search", value }),
|
|
121643
122023
|
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(
|
|
@@ -121645,22 +122025,31 @@ function SearchForm({
|
|
|
121645
122025
|
{
|
|
121646
122026
|
label,
|
|
121647
122027
|
onChange,
|
|
121648
|
-
|
|
121649
|
-
|
|
122028
|
+
onSelect: (id2) => void router.visit(`${action2}/${encodeURIComponent(id2)}`),
|
|
122029
|
+
onClear: () => {
|
|
122030
|
+
if (initialValue) {
|
|
122031
|
+
void router.visit(action2);
|
|
122032
|
+
}
|
|
122033
|
+
},
|
|
122034
|
+
remoteSearch,
|
|
122035
|
+
initialValue,
|
|
122036
|
+
initialSelection
|
|
121650
122037
|
},
|
|
121651
122038
|
initialValue ?? ""
|
|
121652
122039
|
),
|
|
121653
|
-
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(Button, { type: "submit", label: "Search" })
|
|
121654
|
-
showClear && /* @__PURE__ */ (0, import_jsx_runtime107.jsx)(Link, { href: action2, children: "Clear" })
|
|
122040
|
+
/* @__PURE__ */ (0, import_jsx_runtime107.jsx)(Button, { type: "submit", label: "Search" })
|
|
121655
122041
|
] });
|
|
121656
122042
|
}
|
|
121657
|
-
var import_jsx_runtime107;
|
|
122043
|
+
var import_react151, import_jsx_runtime107;
|
|
121658
122044
|
var init_SearchForm = __esm({
|
|
121659
122045
|
"../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/SearchForm.tsx"() {
|
|
121660
122046
|
"use strict";
|
|
121661
122047
|
init_performance2();
|
|
121662
122048
|
init_Button2();
|
|
121663
|
-
|
|
122049
|
+
init_runtime();
|
|
122050
|
+
import_react151 = __toESM(require_react(), 1);
|
|
122051
|
+
init_lib2();
|
|
122052
|
+
init_views();
|
|
121664
122053
|
init_SearchTypeahead();
|
|
121665
122054
|
import_jsx_runtime107 = __toESM(require_jsx_runtime(), 1);
|
|
121666
122055
|
__name(SearchForm, "SearchForm");
|
|
@@ -121677,59 +122066,37 @@ function DeploymentsListPage({ path, platformName, username }) {
|
|
|
121677
122066
|
throw new Error("Deployments page data is unavailable.");
|
|
121678
122067
|
}
|
|
121679
122068
|
const { deployments: deployments2, search, page, totalPages, tz } = pageData;
|
|
121680
|
-
const [filter, setFilter] = (0,
|
|
121681
|
-
(0,
|
|
121682
|
-
const
|
|
121683
|
-
(deployment) => [
|
|
121684
|
-
deployment.id,
|
|
121685
|
-
deployment.project_slug,
|
|
121686
|
-
deployment.status,
|
|
121687
|
-
deployment.source,
|
|
121688
|
-
deployment.cli_version,
|
|
121689
|
-
deployment.commit,
|
|
121690
|
-
deployment.error_message
|
|
121691
|
-
].some((value) => value?.toLowerCase().includes(filter.toLowerCase()))
|
|
121692
|
-
);
|
|
121693
|
-
const suggestions = (0, import_react150.useMemo)(
|
|
121694
|
-
() => deployments2.map((deployment) => ({
|
|
121695
|
-
id: deployment.id,
|
|
121696
|
-
label: deployment.id,
|
|
121697
|
-
keywords: [
|
|
121698
|
-
deployment.project_slug,
|
|
121699
|
-
deployment.status,
|
|
121700
|
-
deployment.source,
|
|
121701
|
-
deployment.cli_version,
|
|
121702
|
-
deployment.commit,
|
|
121703
|
-
deployment.error_message
|
|
121704
|
-
],
|
|
121705
|
-
description: [deployment.project_slug, deployment.status].filter(Boolean).join(" \xB7 ")
|
|
121706
|
-
})),
|
|
121707
|
-
[deployments2]
|
|
121708
|
-
);
|
|
122069
|
+
const [filter, setFilter] = (0, import_react152.useState)(search ?? "");
|
|
122070
|
+
(0, import_react152.useEffect)(() => setFilter(search ?? ""), [search]);
|
|
122071
|
+
const selectedDeployment = deployments2.find((deployment) => deployment.id === search);
|
|
121709
122072
|
return /* @__PURE__ */ jsxs(Layout2, { platformName, title: "Deployments", username, children: [
|
|
121710
122073
|
/* @__PURE__ */ jsx4("h1", { children: "Deployments" }),
|
|
121711
122074
|
/* @__PURE__ */ jsx4(
|
|
121712
122075
|
SearchForm,
|
|
121713
122076
|
{
|
|
121714
122077
|
action: "/admin/deployments",
|
|
122078
|
+
kind: "deployments",
|
|
121715
122079
|
label: "Search deployments",
|
|
121716
122080
|
value: filter,
|
|
121717
122081
|
onChange: setFilter,
|
|
121718
|
-
suggestions,
|
|
121719
122082
|
initialValue: search,
|
|
121720
|
-
|
|
122083
|
+
initialSelection: selectedDeployment ? {
|
|
122084
|
+
id: selectedDeployment.id,
|
|
122085
|
+
label: selectedDeployment.id,
|
|
122086
|
+
description: [selectedDeployment.project_slug, selectedDeployment.status].filter(Boolean).join(" \xB7 ")
|
|
122087
|
+
} : void 0
|
|
121721
122088
|
}
|
|
121722
122089
|
),
|
|
121723
|
-
/* @__PURE__ */ jsx4(DeploymentTable, { deployments:
|
|
122090
|
+
/* @__PURE__ */ jsx4(DeploymentTable, { deployments: deployments2, showProject: true, tz }),
|
|
121724
122091
|
page != null && totalPages != null && /* @__PURE__ */ jsx4(Pagination, { page, totalPages, baseUrl: "/admin/deployments" })
|
|
121725
122092
|
] });
|
|
121726
122093
|
}
|
|
121727
|
-
var
|
|
122094
|
+
var import_react152;
|
|
121728
122095
|
var init_DeploymentsListPage = __esm({
|
|
121729
122096
|
"../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/DeploymentsListPage.tsx"() {
|
|
121730
122097
|
"use strict";
|
|
121731
122098
|
init_performance2();
|
|
121732
|
-
|
|
122099
|
+
import_react152 = __toESM(require_react(), 1);
|
|
121733
122100
|
init_lib2();
|
|
121734
122101
|
init_views();
|
|
121735
122102
|
init_DeploymentTable();
|
|
@@ -122099,13 +122466,13 @@ function RadioList({
|
|
|
122099
122466
|
htmlName,
|
|
122100
122467
|
children
|
|
122101
122468
|
}) {
|
|
122102
|
-
const autoName = (0,
|
|
122469
|
+
const autoName = (0, import_react153.useId)();
|
|
122103
122470
|
const name = htmlName ?? autoName;
|
|
122104
|
-
const inputID = (0,
|
|
122105
|
-
const labelID = (0,
|
|
122106
|
-
const descriptionID = (0,
|
|
122107
|
-
const statusMessageID = (0,
|
|
122108
|
-
const groupRef = (0,
|
|
122471
|
+
const inputID = (0, import_react153.useId)();
|
|
122472
|
+
const labelID = (0, import_react153.useId)();
|
|
122473
|
+
const descriptionID = (0, import_react153.useId)();
|
|
122474
|
+
const statusMessageID = (0, import_react153.useId)();
|
|
122475
|
+
const groupRef = (0, import_react153.useRef)(null);
|
|
122109
122476
|
const isEffectivelyRequired = useResolvedRequired({
|
|
122110
122477
|
isRequired,
|
|
122111
122478
|
isOptional
|
|
@@ -122118,7 +122485,7 @@ function RadioList({
|
|
|
122118
122485
|
focusTrigger: "always",
|
|
122119
122486
|
isEnabled: showsDisabledMessage
|
|
122120
122487
|
});
|
|
122121
|
-
const contextValue = (0,
|
|
122488
|
+
const contextValue = (0, import_react153.useMemo)(() => ({
|
|
122122
122489
|
name,
|
|
122123
122490
|
value,
|
|
122124
122491
|
onChange,
|
|
@@ -122128,7 +122495,7 @@ function RadioList({
|
|
|
122128
122495
|
size,
|
|
122129
122496
|
status: status2
|
|
122130
122497
|
}), [name, value, onChange, isDisabled, showsDisabledMessage, isRequired, size, status2]);
|
|
122131
|
-
const handleFocus = (0,
|
|
122498
|
+
const handleFocus = (0, import_react153.useCallback)((e) => {
|
|
122132
122499
|
if (value !== "") {
|
|
122133
122500
|
return;
|
|
122134
122501
|
}
|
|
@@ -122212,12 +122579,12 @@ function RadioList({
|
|
|
122212
122579
|
}), showsDisabledMessage && disabledMessageTooltip.renderTooltip(disabledMessage)]
|
|
122213
122580
|
});
|
|
122214
122581
|
}
|
|
122215
|
-
var
|
|
122582
|
+
var import_react153, import_jsx_runtime111, RadioListContext;
|
|
122216
122583
|
var init_RadioList = __esm({
|
|
122217
122584
|
"../../home/runner/work/void/void/node_modules/.pnpm/@astryxdesign+core@0.6.3_@stylexjs+stylex@0.19.1_react-dom@19.3.0_react@19.3.0__react@19.3.0/node_modules/@astryxdesign/core/dist/RadioList/RadioList.js"() {
|
|
122218
122585
|
"use client";
|
|
122219
122586
|
init_performance2();
|
|
122220
|
-
|
|
122587
|
+
import_react153 = __toESM(require_react(), 1);
|
|
122221
122588
|
init_tokens_stylex();
|
|
122222
122589
|
init_tokens_stylex();
|
|
122223
122590
|
init_Field();
|
|
@@ -122226,7 +122593,7 @@ var init_RadioList = __esm({
|
|
|
122226
122593
|
init_utils7();
|
|
122227
122594
|
init_themeProps();
|
|
122228
122595
|
import_jsx_runtime111 = __toESM(require_jsx_runtime(), 1);
|
|
122229
|
-
RadioListContext = /* @__PURE__ */ (0,
|
|
122596
|
+
RadioListContext = /* @__PURE__ */ (0, import_react153.createContext)(null);
|
|
122230
122597
|
RadioListContext.displayName = "RadioListContext";
|
|
122231
122598
|
__name(RadioList, "RadioList");
|
|
122232
122599
|
RadioList.displayName = "RadioList";
|
|
@@ -122249,24 +122616,24 @@ function RadioListItem({
|
|
|
122249
122616
|
onClick,
|
|
122250
122617
|
...rest
|
|
122251
122618
|
}) {
|
|
122252
|
-
const context = (0,
|
|
122619
|
+
const context = (0, import_react154.use)(RadioListContext);
|
|
122253
122620
|
if (!context) {
|
|
122254
122621
|
throw new Error("RadioListItem must be used within an RadioList");
|
|
122255
122622
|
}
|
|
122256
|
-
const id2 = (0,
|
|
122257
|
-
const labelID = (0,
|
|
122258
|
-
const descriptionID = (0,
|
|
122623
|
+
const id2 = (0, import_react154.useId)();
|
|
122624
|
+
const labelID = (0, import_react154.useId)();
|
|
122625
|
+
const descriptionID = (0, import_react154.useId)();
|
|
122259
122626
|
const isDisabled = context.isDisabled || isItemDisabled;
|
|
122260
122627
|
const keepsFocusableForMessage = context.hasDisabledMessage && !isItemDisabled;
|
|
122261
122628
|
const isChecked = context.value === value;
|
|
122262
122629
|
const hasDescription = isRenderable(description);
|
|
122263
122630
|
const size = context.size;
|
|
122264
122631
|
const RadioControl = useIndicator("radio");
|
|
122265
|
-
const indicatorRef = (0,
|
|
122632
|
+
const indicatorRef = (0, import_react154.useRef)(null);
|
|
122266
122633
|
const {
|
|
122267
122634
|
focusProps
|
|
122268
122635
|
} = useIndicatorFocusRing(indicatorRef, isDisabled);
|
|
122269
|
-
const radioRef = (0,
|
|
122636
|
+
const radioRef = (0, import_react154.useRef)(null);
|
|
122270
122637
|
const radioCircle = /* @__PURE__ */ (0, import_jsx_runtime112.jsxs)("div", {
|
|
122271
122638
|
...props(styles56.radioWrapper, wrapperSizeStyles3[size], !isDisabled && styles56.indicatorPressOverlay),
|
|
122272
122639
|
...focusProps,
|
|
@@ -122356,12 +122723,12 @@ function RadioListItem({
|
|
|
122356
122723
|
...rest
|
|
122357
122724
|
});
|
|
122358
122725
|
}
|
|
122359
|
-
var
|
|
122726
|
+
var import_react154, import_jsx_runtime112, styles56, wrapperSizeStyles3, rowStyles;
|
|
122360
122727
|
var init_RadioListItem = __esm({
|
|
122361
122728
|
"../../home/runner/work/void/void/node_modules/.pnpm/@astryxdesign+core@0.6.3_@stylexjs+stylex@0.19.1_react-dom@19.3.0_react@19.3.0__react@19.3.0/node_modules/@astryxdesign/core/dist/RadioList/RadioListItem.js"() {
|
|
122362
122729
|
"use client";
|
|
122363
122730
|
init_performance2();
|
|
122364
|
-
|
|
122731
|
+
import_react154 = __toESM(require_react(), 1);
|
|
122365
122732
|
init_stylex();
|
|
122366
122733
|
init_RadioList();
|
|
122367
122734
|
init_tokens_stylex();
|
|
@@ -122478,29 +122845,29 @@ function EnabledEmailSettingsPage({ path, platformName, username }) {
|
|
|
122478
122845
|
throw new Error("Email settings are unavailable.");
|
|
122479
122846
|
}
|
|
122480
122847
|
const { policy, management, senderDomain } = pageData;
|
|
122481
|
-
const [mode, setMode] = (0,
|
|
122482
|
-
const [domainManagement, setDomainManagement] = (0,
|
|
122848
|
+
const [mode, setMode] = (0, import_react155.useState)(policy.mode);
|
|
122849
|
+
const [domainManagement, setDomainManagement] = (0, import_react155.useState)(management);
|
|
122483
122850
|
return /* @__PURE__ */ jsxs(Layout2, { platformName, title: "Email", username, children: [
|
|
122484
122851
|
/* @__PURE__ */ jsx4("h1", { children: "Email" }),
|
|
122485
122852
|
/* @__PURE__ */ jsx4("p", { style: META2, children: "Installation-wide settings. Per-project usage, caps and domains live on each project's email page (Projects \u2192 project \u2192 Email)." }),
|
|
122486
122853
|
/* @__PURE__ */ jsx4("h2", { children: "Recipient policy" }),
|
|
122487
122854
|
/* @__PURE__ */ jsxs("p", { children: [
|
|
122488
|
-
"
|
|
122855
|
+
"Choose which recipients can receive email sent from the shared sender",
|
|
122489
122856
|
senderDomain ? /* @__PURE__ */ jsxs(import_jsx_runtime18.Fragment, { children: [
|
|
122490
122857
|
" ",
|
|
122491
122858
|
"(",
|
|
122492
122859
|
/* @__PURE__ */ jsx4("code", { children: `<slug>+tag@${senderDomain}` }),
|
|
122493
122860
|
")"
|
|
122494
122861
|
] }) : null,
|
|
122495
|
-
" "
|
|
122496
|
-
"may reach. Custom-domain sends are not affected."
|
|
122862
|
+
". This does not affect email sent from custom domains."
|
|
122497
122863
|
] }),
|
|
122498
|
-
/* @__PURE__ */ jsxs("form", { method: "post", action: "/admin/email/policy",
|
|
122864
|
+
/* @__PURE__ */ jsxs("form", { method: "post", action: "/admin/email/policy", className: "void-admin-email-choice-form", children: [
|
|
122499
122865
|
/* @__PURE__ */ jsxs(
|
|
122500
122866
|
RadioList,
|
|
122501
122867
|
{
|
|
122502
122868
|
label: "Recipient policy",
|
|
122503
122869
|
isLabelHidden: true,
|
|
122870
|
+
size: "sm",
|
|
122504
122871
|
htmlName: "mode",
|
|
122505
122872
|
value: mode,
|
|
122506
122873
|
onChange: (value) => setMode(value),
|
|
@@ -122556,12 +122923,13 @@ function EnabledEmailSettingsPage({ path, platformName, username }) {
|
|
|
122556
122923
|
] }),
|
|
122557
122924
|
/* @__PURE__ */ jsx4("h2", { children: "Domain management" }),
|
|
122558
122925
|
/* @__PURE__ */ jsx4("p", { children: "Who registers custom email domains for projects." }),
|
|
122559
|
-
/* @__PURE__ */ jsxs("form", { method: "post", action: "/admin/email/settings", children: [
|
|
122926
|
+
/* @__PURE__ */ jsxs("form", { method: "post", action: "/admin/email/settings", className: "void-admin-email-choice-form", children: [
|
|
122560
122927
|
/* @__PURE__ */ jsxs(
|
|
122561
122928
|
RadioList,
|
|
122562
122929
|
{
|
|
122563
122930
|
label: "Domain management",
|
|
122564
122931
|
isLabelHidden: true,
|
|
122932
|
+
size: "sm",
|
|
122565
122933
|
htmlName: "domains",
|
|
122566
122934
|
value: domainManagement,
|
|
122567
122935
|
onChange: (value) => setDomainManagement(value),
|
|
@@ -122589,14 +122957,14 @@ function EnabledEmailSettingsPage({ path, platformName, username }) {
|
|
|
122589
122957
|
] })
|
|
122590
122958
|
] });
|
|
122591
122959
|
}
|
|
122592
|
-
var
|
|
122960
|
+
var import_react155, META2, EMAIL_SETUP_GUIDE;
|
|
122593
122961
|
var init_EmailSettingsPage = __esm({
|
|
122594
122962
|
"../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/EmailSettingsPage.tsx"() {
|
|
122595
122963
|
"use strict";
|
|
122596
122964
|
init_performance2();
|
|
122597
122965
|
init_Button2();
|
|
122598
122966
|
init_RadioList2();
|
|
122599
|
-
|
|
122967
|
+
import_react155 = __toESM(require_react(), 1);
|
|
122600
122968
|
init_lib2();
|
|
122601
122969
|
init_views();
|
|
122602
122970
|
init_FormControls();
|
|
@@ -122819,7 +123187,7 @@ function AdminUserTypeahead({
|
|
|
122819
123187
|
excludedUserIds = noExcludedUsers
|
|
122820
123188
|
}) {
|
|
122821
123189
|
const fate = useFateClient();
|
|
122822
|
-
const source = (0,
|
|
123190
|
+
const source = (0, import_react156.useMemo)(
|
|
122823
123191
|
() => ({
|
|
122824
123192
|
bootstrap: /* @__PURE__ */ __name(() => [], "bootstrap"),
|
|
122825
123193
|
search: /* @__PURE__ */ __name(async (query) => {
|
|
@@ -122862,13 +123230,13 @@ function AdminUserTypeahead({
|
|
|
122862
123230
|
}
|
|
122863
123231
|
);
|
|
122864
123232
|
}
|
|
122865
|
-
var
|
|
123233
|
+
var import_react156, import_jsx_runtime117, noExcludedUsers;
|
|
122866
123234
|
var init_AdminUserTypeahead = __esm({
|
|
122867
123235
|
"../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/AdminUserTypeahead.tsx"() {
|
|
122868
123236
|
"use strict";
|
|
122869
123237
|
init_performance2();
|
|
122870
123238
|
init_Typeahead2();
|
|
122871
|
-
|
|
123239
|
+
import_react156 = __toESM(require_react(), 1);
|
|
122872
123240
|
init_lib2();
|
|
122873
123241
|
init_views();
|
|
122874
123242
|
import_jsx_runtime117 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -122879,7 +123247,7 @@ var init_AdminUserTypeahead = __esm({
|
|
|
122879
123247
|
|
|
122880
123248
|
// ../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/ProjectOwnerTransferSection.tsx
|
|
122881
123249
|
function ProjectOwnerTransferSection({ projectId }) {
|
|
122882
|
-
const [selected, setSelected] = (0,
|
|
123250
|
+
const [selected, setSelected] = (0, import_react157.useState)(null);
|
|
122883
123251
|
return /* @__PURE__ */ (0, import_jsx_runtime118.jsxs)("section", { id: "owner-transfer", className: "void-admin-owner-transfer", children: [
|
|
122884
123252
|
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)("h2", { children: "Transfer Ownership" }),
|
|
122885
123253
|
/* @__PURE__ */ (0, import_jsx_runtime118.jsx)("p", { children: "Transfer this project to an existing Void Platform user. You will review the ownership, plan, suspension, active-work, routing, and usage-counter changes before applying them." }),
|
|
@@ -122898,13 +123266,13 @@ function ProjectOwnerTransferSection({ projectId }) {
|
|
|
122898
123266
|
)
|
|
122899
123267
|
] });
|
|
122900
123268
|
}
|
|
122901
|
-
var
|
|
123269
|
+
var import_react157, import_jsx_runtime118;
|
|
122902
123270
|
var init_ProjectOwnerTransferSection = __esm({
|
|
122903
123271
|
"../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/ProjectOwnerTransferSection.tsx"() {
|
|
122904
123272
|
"use strict";
|
|
122905
123273
|
init_performance2();
|
|
122906
123274
|
init_Button2();
|
|
122907
|
-
|
|
123275
|
+
import_react157 = __toESM(require_react(), 1);
|
|
122908
123276
|
init_AdminUserTypeahead();
|
|
122909
123277
|
import_jsx_runtime118 = __toESM(require_jsx_runtime(), 1);
|
|
122910
123278
|
__name(ProjectOwnerTransferSection, "ProjectOwnerTransferSection");
|
|
@@ -122919,8 +123287,8 @@ function ProjectTeamSection({
|
|
|
122919
123287
|
invitations: invitations2,
|
|
122920
123288
|
tz
|
|
122921
123289
|
}) {
|
|
122922
|
-
const [selected, setSelected] = (0,
|
|
122923
|
-
const excluded = (0,
|
|
123290
|
+
const [selected, setSelected] = (0, import_react158.useState)(null);
|
|
123291
|
+
const excluded = (0, import_react158.useMemo)(
|
|
122924
123292
|
() => /* @__PURE__ */ new Set([...owner ? [owner.id] : [], ...members2.map(({ user }) => user.id)]),
|
|
122925
123293
|
[owner, members2]
|
|
122926
123294
|
);
|
|
@@ -123057,14 +123425,14 @@ function ProjectTeamSection({
|
|
|
123057
123425
|
] })
|
|
123058
123426
|
] });
|
|
123059
123427
|
}
|
|
123060
|
-
var
|
|
123428
|
+
var import_react158, import_jsx_runtime119, roleOptions;
|
|
123061
123429
|
var init_ProjectTeamSection = __esm({
|
|
123062
123430
|
"../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/ProjectTeamSection.tsx"() {
|
|
123063
123431
|
"use strict";
|
|
123064
123432
|
init_performance2();
|
|
123065
123433
|
init_Button2();
|
|
123066
123434
|
init_Table2();
|
|
123067
|
-
|
|
123435
|
+
import_react158 = __toESM(require_react(), 1);
|
|
123068
123436
|
init_AdminUserTypeahead();
|
|
123069
123437
|
init_format();
|
|
123070
123438
|
init_FormControls();
|
|
@@ -123387,46 +123755,37 @@ function ProjectsListPage({ path, platformName, username }) {
|
|
|
123387
123755
|
throw new Error("Projects page data is unavailable.");
|
|
123388
123756
|
}
|
|
123389
123757
|
const { projects: projects2, search, page, totalPages, siteDomain, tz } = pageData;
|
|
123390
|
-
const [filter, setFilter] = (0,
|
|
123391
|
-
(0,
|
|
123392
|
-
const
|
|
123393
|
-
(project) => [project.slug, project.owner_login, project.type, project.last_deploy_status].some(
|
|
123394
|
-
(value) => value?.toLowerCase().includes(filter.toLowerCase())
|
|
123395
|
-
)
|
|
123396
|
-
);
|
|
123397
|
-
const suggestions = (0, import_react157.useMemo)(
|
|
123398
|
-
() => projects2.map((project) => ({
|
|
123399
|
-
id: project.id,
|
|
123400
|
-
label: project.slug,
|
|
123401
|
-
keywords: [project.owner_login, project.id, project.type, project.last_deploy_status],
|
|
123402
|
-
description: project.owner_login ?? void 0
|
|
123403
|
-
})),
|
|
123404
|
-
[projects2]
|
|
123405
|
-
);
|
|
123758
|
+
const [filter, setFilter] = (0, import_react159.useState)(search ?? "");
|
|
123759
|
+
(0, import_react159.useEffect)(() => setFilter(search ?? ""), [search]);
|
|
123760
|
+
const selectedProject = projects2.find((project) => project.id === search);
|
|
123406
123761
|
return /* @__PURE__ */ jsxs(Layout2, { platformName, title: "Projects", username, children: [
|
|
123407
123762
|
/* @__PURE__ */ jsx4("h1", { children: "Projects" }),
|
|
123408
123763
|
/* @__PURE__ */ jsx4(
|
|
123409
123764
|
SearchForm,
|
|
123410
123765
|
{
|
|
123411
123766
|
action: "/admin/projects",
|
|
123767
|
+
kind: "projects",
|
|
123412
123768
|
label: "Search projects",
|
|
123413
123769
|
value: filter,
|
|
123414
123770
|
onChange: setFilter,
|
|
123415
|
-
suggestions,
|
|
123416
123771
|
initialValue: search,
|
|
123417
|
-
|
|
123772
|
+
initialSelection: selectedProject ? {
|
|
123773
|
+
id: selectedProject.id,
|
|
123774
|
+
label: selectedProject.slug,
|
|
123775
|
+
description: selectedProject.owner_login ?? void 0
|
|
123776
|
+
} : void 0
|
|
123418
123777
|
}
|
|
123419
123778
|
),
|
|
123420
|
-
/* @__PURE__ */ jsx4(ProjectsTable, { projects:
|
|
123779
|
+
/* @__PURE__ */ jsx4(ProjectsTable, { projects: projects2, siteDomain, tz }),
|
|
123421
123780
|
page != null && totalPages != null && /* @__PURE__ */ jsx4(Pagination, { page, totalPages, baseUrl: "/admin/projects" })
|
|
123422
123781
|
] });
|
|
123423
123782
|
}
|
|
123424
|
-
var
|
|
123783
|
+
var import_react159;
|
|
123425
123784
|
var init_ProjectsListPage = __esm({
|
|
123426
123785
|
"../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/ProjectsListPage.tsx"() {
|
|
123427
123786
|
"use strict";
|
|
123428
123787
|
init_performance2();
|
|
123429
|
-
|
|
123788
|
+
import_react159 = __toESM(require_react(), 1);
|
|
123430
123789
|
init_lib2();
|
|
123431
123790
|
init_views();
|
|
123432
123791
|
init_Layout2();
|
|
@@ -123443,8 +123802,8 @@ function BooleanBadge({ value }) {
|
|
|
123443
123802
|
return /* @__PURE__ */ jsx4(Badge, { label: value ? "Yes" : "No", variant: value ? "success" : "neutral" });
|
|
123444
123803
|
}
|
|
123445
123804
|
function CopyValue({ label, value }) {
|
|
123446
|
-
const [copied, setCopied] = (0,
|
|
123447
|
-
const [failed, setFailed] = (0,
|
|
123805
|
+
const [copied, setCopied] = (0, import_react160.useState)(false);
|
|
123806
|
+
const [failed, setFailed] = (0, import_react160.useState)(false);
|
|
123448
123807
|
return /* @__PURE__ */ jsxs("div", { className: "void-admin-access-copy-value", children: [
|
|
123449
123808
|
/* @__PURE__ */ jsxs("label", { children: [
|
|
123450
123809
|
/* @__PURE__ */ jsx4("span", { children: label }),
|
|
@@ -123851,7 +124210,7 @@ function SignupControlPage({ path, platformName, username }) {
|
|
|
123851
124210
|
] }) })
|
|
123852
124211
|
] }) });
|
|
123853
124212
|
}
|
|
123854
|
-
var
|
|
124213
|
+
var import_react160;
|
|
123855
124214
|
var init_SignupControlPage = __esm({
|
|
123856
124215
|
"../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/SignupControlPage.tsx"() {
|
|
123857
124216
|
"use strict";
|
|
@@ -123861,7 +124220,7 @@ var init_SignupControlPage = __esm({
|
|
|
123861
124220
|
init_Card2();
|
|
123862
124221
|
init_Table2();
|
|
123863
124222
|
init_Text2();
|
|
123864
|
-
|
|
124223
|
+
import_react160 = __toESM(require_react(), 1);
|
|
123865
124224
|
init_lib2();
|
|
123866
124225
|
init_views();
|
|
123867
124226
|
init_format();
|
|
@@ -124082,34 +124441,25 @@ function UsersListPage({ path, platformName, username }) {
|
|
|
124082
124441
|
throw new Error("Users page data is unavailable.");
|
|
124083
124442
|
}
|
|
124084
124443
|
const { users: users2, search, page, totalPages, tz } = pageData;
|
|
124085
|
-
const [filter, setFilter] = (0,
|
|
124086
|
-
(0,
|
|
124087
|
-
const
|
|
124088
|
-
(user) => [user.login, user.email, user.id].some(
|
|
124089
|
-
(value) => value?.toLowerCase().includes(filter.toLowerCase())
|
|
124090
|
-
)
|
|
124091
|
-
);
|
|
124092
|
-
const suggestions = (0, import_react159.useMemo)(
|
|
124093
|
-
() => users2.map((user) => ({
|
|
124094
|
-
id: user.id,
|
|
124095
|
-
label: user.login,
|
|
124096
|
-
keywords: [user.email, user.id],
|
|
124097
|
-
description: [user.email, user.id].filter(Boolean).join(" \xB7 ")
|
|
124098
|
-
})),
|
|
124099
|
-
[users2]
|
|
124100
|
-
);
|
|
124444
|
+
const [filter, setFilter] = (0, import_react161.useState)(search ?? "");
|
|
124445
|
+
(0, import_react161.useEffect)(() => setFilter(search ?? ""), [search]);
|
|
124446
|
+
const selectedUser = users2.find((user) => user.id === search);
|
|
124101
124447
|
return /* @__PURE__ */ jsxs(Layout2, { platformName, title: "Users", username, children: [
|
|
124102
124448
|
/* @__PURE__ */ jsx4("h1", { children: "Users" }),
|
|
124103
124449
|
/* @__PURE__ */ jsx4(
|
|
124104
124450
|
SearchForm,
|
|
124105
124451
|
{
|
|
124106
124452
|
action: "/admin/users",
|
|
124453
|
+
kind: "users",
|
|
124107
124454
|
label: "Search users",
|
|
124108
124455
|
value: filter,
|
|
124109
124456
|
onChange: setFilter,
|
|
124110
|
-
suggestions,
|
|
124111
124457
|
initialValue: search,
|
|
124112
|
-
|
|
124458
|
+
initialSelection: selectedUser ? {
|
|
124459
|
+
id: selectedUser.id,
|
|
124460
|
+
label: selectedUser.login,
|
|
124461
|
+
description: [selectedUser.email, selectedUser.id].filter(Boolean).join(" \xB7 ")
|
|
124462
|
+
} : void 0
|
|
124113
124463
|
}
|
|
124114
124464
|
),
|
|
124115
124465
|
/* @__PURE__ */ jsxs(Table2, { hasHover: true, children: [
|
|
@@ -124123,7 +124473,7 @@ function UsersListPage({ path, platformName, username }) {
|
|
|
124123
124473
|
/* @__PURE__ */ jsx4(TableHeaderCell, { children: "Created" }),
|
|
124124
124474
|
/* @__PURE__ */ jsx4(TableHeaderCell, { children: "Actions" })
|
|
124125
124475
|
] }) }),
|
|
124126
|
-
/* @__PURE__ */ jsx4(TableBody, { children:
|
|
124476
|
+
/* @__PURE__ */ jsx4(TableBody, { children: users2.map((user) => /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
124127
124477
|
/* @__PURE__ */ jsx4(TableCell, { children: /* @__PURE__ */ jsx4("a", { href: `/admin/users/${user.id}`, children: user.login }) }),
|
|
124128
124478
|
/* @__PURE__ */ jsx4(TableCell, { children: user.provider }),
|
|
124129
124479
|
/* @__PURE__ */ jsx4(TableCell, { children: user.email ?? "-" }),
|
|
@@ -124143,18 +124493,18 @@ function UsersListPage({ path, platformName, username }) {
|
|
|
124143
124493
|
) })
|
|
124144
124494
|
] }, user.id)) })
|
|
124145
124495
|
] }),
|
|
124146
|
-
|
|
124496
|
+
users2.length === 0 && /* @__PURE__ */ jsx4("p", { children: /* @__PURE__ */ jsx4("em", { children: "No users found." }) }),
|
|
124147
124497
|
page != null && totalPages != null && /* @__PURE__ */ jsx4(Pagination, { page, totalPages, baseUrl: "/admin/users" })
|
|
124148
124498
|
] });
|
|
124149
124499
|
}
|
|
124150
|
-
var
|
|
124500
|
+
var import_react161;
|
|
124151
124501
|
var init_UsersListPage = __esm({
|
|
124152
124502
|
"../../home/runner/work/void/void/platform/packages/api/src/admin/react/views/UsersListPage.tsx"() {
|
|
124153
124503
|
"use strict";
|
|
124154
124504
|
init_performance2();
|
|
124155
124505
|
init_Button2();
|
|
124156
124506
|
init_Table2();
|
|
124157
|
-
|
|
124507
|
+
import_react161 = __toESM(require_react(), 1);
|
|
124158
124508
|
init_lib2();
|
|
124159
124509
|
init_views();
|
|
124160
124510
|
init_format();
|
|
@@ -144178,7 +144528,7 @@ var import_headless = __toESM(require_xterm_headless(), 1);
|
|
|
144178
144528
|
// ../../home/runner/work/void/void/packages/void/package.json
|
|
144179
144529
|
var package_default = {
|
|
144180
144530
|
name: "void",
|
|
144181
|
-
version: "0.21.
|
|
144531
|
+
version: "0.21.3",
|
|
144182
144532
|
repository: {
|
|
144183
144533
|
type: "git",
|
|
144184
144534
|
url: "git+https://github.com/voidzero-dev/void.git",
|
|
@@ -145762,7 +146112,9 @@ async function formatLogTailMarkdown(lines, totalCaptured) {
|
|
|
145762
146112
|
if (groups.slice(0, selectedStart).some((group) => group.requiresTerminal)) {
|
|
145763
146113
|
return null;
|
|
145764
146114
|
}
|
|
145765
|
-
const visibleLines = await renderTerminalGroups(selectedNewestFirst.reverse())
|
|
146115
|
+
const visibleLines = (await renderTerminalGroups(selectedNewestFirst.reverse())).map(
|
|
146116
|
+
(line2) => line2.replace(/^ {257,}/, " ".repeat(32))
|
|
146117
|
+
);
|
|
145766
146118
|
const keptNewestFirst = [];
|
|
145767
146119
|
let joinedBytes = 0;
|
|
145768
146120
|
for (let lineIndex = visibleLines.length - 1; lineIndex >= 0; lineIndex--) {
|
|
@@ -147383,9 +147735,15 @@ var BuildScheduler = class extends DurableObject2 {
|
|
|
147383
147735
|
}
|
|
147384
147736
|
return;
|
|
147385
147737
|
}
|
|
147738
|
+
const usersById = new Map(
|
|
147739
|
+
(await getUsersByIds(db, [...new Set(queued.map((build) => build.user_id))])).map((user) => [
|
|
147740
|
+
user.id,
|
|
147741
|
+
user
|
|
147742
|
+
])
|
|
147743
|
+
);
|
|
147386
147744
|
const saturatedNamespaces = /* @__PURE__ */ new Set();
|
|
147387
147745
|
for (const build of queued) {
|
|
147388
|
-
const user =
|
|
147746
|
+
const user = usersById.get(build.user_id);
|
|
147389
147747
|
if (!user) {
|
|
147390
147748
|
await updateBuildStatus(db, build.id, "failed", {
|
|
147391
147749
|
error: "owning user not found",
|
|
@@ -148155,6 +148513,8 @@ init_schema2();
|
|
|
148155
148513
|
init_suspension();
|
|
148156
148514
|
var DEPLOY_TOKEN_ALLOWLIST = [
|
|
148157
148515
|
{ method: "GET", segments: ["projects"] },
|
|
148516
|
+
{ method: "GET", segments: ["projects", "resolve"] },
|
|
148517
|
+
{ method: "GET", segments: ["projects", null] },
|
|
148158
148518
|
{ method: "GET", segments: ["projects", null, "resources"] },
|
|
148159
148519
|
{ method: "POST", segments: ["projects", null, "database"] },
|
|
148160
148520
|
{ method: "POST", segments: ["projects", null, "prerender-token"] },
|
|
@@ -149424,24 +149784,7 @@ init_dist2();
|
|
|
149424
149784
|
|
|
149425
149785
|
// ../../home/runner/work/void/void/platform/packages/api/src/asset-inventory.ts
|
|
149426
149786
|
init_performance2();
|
|
149427
|
-
|
|
149428
|
-
// ../../home/runner/work/void/void/platform/packages/api/src/concurrency.ts
|
|
149429
|
-
init_performance2();
|
|
149430
|
-
var R2_CONCURRENCY = 6;
|
|
149431
|
-
async function uploadPool(items, concurrency, fn) {
|
|
149432
|
-
let nextIndex = 0;
|
|
149433
|
-
async function worker() {
|
|
149434
|
-
while (nextIndex < items.length) {
|
|
149435
|
-
const item = items[nextIndex++];
|
|
149436
|
-
await fn(item);
|
|
149437
|
-
}
|
|
149438
|
-
}
|
|
149439
|
-
__name(worker, "worker");
|
|
149440
|
-
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
|
|
149441
|
-
}
|
|
149442
|
-
__name(uploadPool, "uploadPool");
|
|
149443
|
-
|
|
149444
|
-
// ../../home/runner/work/void/void/platform/packages/api/src/asset-inventory.ts
|
|
149787
|
+
init_concurrency();
|
|
149445
149788
|
async function findR2Assets(r2, projectId, requiredHashes) {
|
|
149446
149789
|
const found = /* @__PURE__ */ new Map();
|
|
149447
149790
|
if (requiredHashes.size === 0) {
|
|
@@ -149474,6 +149817,38 @@ async function findR2Assets(r2, projectId, requiredHashes) {
|
|
|
149474
149817
|
return found;
|
|
149475
149818
|
}
|
|
149476
149819
|
__name(findR2Assets, "findR2Assets");
|
|
149820
|
+
function persistedR2AssetSizes(raw2) {
|
|
149821
|
+
const sizes = /* @__PURE__ */ new Map();
|
|
149822
|
+
const conflicting = /* @__PURE__ */ new Set();
|
|
149823
|
+
if (!raw2) {
|
|
149824
|
+
return sizes;
|
|
149825
|
+
}
|
|
149826
|
+
let manifest;
|
|
149827
|
+
try {
|
|
149828
|
+
manifest = JSON.parse(raw2);
|
|
149829
|
+
} catch {
|
|
149830
|
+
return sizes;
|
|
149831
|
+
}
|
|
149832
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
149833
|
+
return sizes;
|
|
149834
|
+
}
|
|
149835
|
+
for (const value of Object.values(manifest)) {
|
|
149836
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
149837
|
+
continue;
|
|
149838
|
+
}
|
|
149839
|
+
const entry = value;
|
|
149840
|
+
if (entry.store === "r2" && typeof entry.hash === "string" && /^[0-9a-f]{32}$/.test(entry.hash) && typeof entry.size === "number" && Number.isSafeInteger(entry.size) && entry.size >= 0) {
|
|
149841
|
+
if (sizes.has(entry.hash) && sizes.get(entry.hash) !== entry.size) {
|
|
149842
|
+
conflicting.add(entry.hash);
|
|
149843
|
+
sizes.delete(entry.hash);
|
|
149844
|
+
} else if (!conflicting.has(entry.hash)) {
|
|
149845
|
+
sizes.set(entry.hash, entry.size);
|
|
149846
|
+
}
|
|
149847
|
+
}
|
|
149848
|
+
}
|
|
149849
|
+
return sizes;
|
|
149850
|
+
}
|
|
149851
|
+
__name(persistedR2AssetSizes, "persistedR2AssetSizes");
|
|
149477
149852
|
async function findMissingR2Assets(r2, projectId, manifest) {
|
|
149478
149853
|
const entries2 = Object.entries(manifest);
|
|
149479
149854
|
const found = await findR2Assets(r2, projectId, new Set(entries2.map(([, entry]) => entry.hash)));
|
|
@@ -149486,6 +149861,7 @@ init_assets();
|
|
|
149486
149861
|
init_hmac();
|
|
149487
149862
|
init_capabilities();
|
|
149488
149863
|
init_cf_api();
|
|
149864
|
+
init_concurrency();
|
|
149489
149865
|
init_cron_scheduler_client();
|
|
149490
149866
|
init_db2();
|
|
149491
149867
|
init_email();
|
|
@@ -149867,6 +150243,9 @@ async function ensureResource(db, accountId, apiToken, projectId, type, bindingN
|
|
|
149867
150243
|
const resourceName = `${projectId}-${bindingName}`.toLowerCase().replaceAll("_", "-");
|
|
149868
150244
|
const found = existing.find((r) => r.type === type && r.binding_name === bindingName);
|
|
149869
150245
|
if (found) {
|
|
150246
|
+
if (type === "d1") {
|
|
150247
|
+
await enableD1ReadReplication(accountId, apiToken, found.cf_id);
|
|
150248
|
+
}
|
|
149870
150249
|
if (type === "queue" && !UUID_RE.test(found.cf_id)) {
|
|
149871
150250
|
const queueInfo = await getQueueByName(accountId, apiToken, resourceName);
|
|
149872
150251
|
await db.update(resources).set({ cf_id: queueInfo.queue_id }).where(eq(resources.id, found.id));
|
|
@@ -149882,6 +150261,9 @@ async function ensureResource(db, accountId, apiToken, projectId, type, bindingN
|
|
|
149882
150261
|
} catch (err) {
|
|
149883
150262
|
if (isAlreadyExistsError3(err)) {
|
|
149884
150263
|
cfId = await lookupCfResource(type, accountId, apiToken, resourceName);
|
|
150264
|
+
if (type === "d1") {
|
|
150265
|
+
await enableD1ReadReplication(accountId, apiToken, cfId);
|
|
150266
|
+
}
|
|
149885
150267
|
} else {
|
|
149886
150268
|
throw err;
|
|
149887
150269
|
}
|
|
@@ -152376,6 +152758,19 @@ async function handleManifestOnlyDeploy(context) {
|
|
|
152376
152758
|
});
|
|
152377
152759
|
}, "withProjectAssetGcFence");
|
|
152378
152760
|
let remainingAssetGcHashBudget = ASSET_GC_MAX_HASHES_PER_DEPLOY;
|
|
152761
|
+
let orphanSweepAfterResponse = null;
|
|
152762
|
+
const finishOrphanSweep = /* @__PURE__ */ __name(async () => {
|
|
152763
|
+
const sweep = orphanSweepAfterResponse;
|
|
152764
|
+
if (!sweep) {
|
|
152765
|
+
return;
|
|
152766
|
+
}
|
|
152767
|
+
const work = Promise.resolve().then(sweep);
|
|
152768
|
+
try {
|
|
152769
|
+
context.executionCtx.waitUntil(work);
|
|
152770
|
+
} catch {
|
|
152771
|
+
await work;
|
|
152772
|
+
}
|
|
152773
|
+
}, "finishOrphanSweep");
|
|
152379
152774
|
const deleteAssetHashesWithProjectFence = /* @__PURE__ */ __name(async (knownRetainedHashes, hashes) => {
|
|
152380
152775
|
let deleted = 0;
|
|
152381
152776
|
const budgetedHashes = hashes.slice(0, remainingAssetGcHashBudget);
|
|
@@ -152519,6 +152914,15 @@ async function handleManifestOnlyDeploy(context) {
|
|
|
152519
152914
|
const declaredHashes = Array.from(
|
|
152520
152915
|
new Set(Object.values(incomingAssetManifest).map((e) => e.hash))
|
|
152521
152916
|
);
|
|
152917
|
+
const activeR2Sizes = currentLiveDeployment?.status === "live" && currentLiveDeployment.project_id === projectId ? persistedR2AssetSizes(currentLiveDeployment.asset_hashes) : /* @__PURE__ */ new Map();
|
|
152918
|
+
const declaredSizeByHash = /* @__PURE__ */ new Map();
|
|
152919
|
+
for (const entry of Object.values(incomingAssetManifest)) {
|
|
152920
|
+
if (!declaredSizeByHash.has(entry.hash)) {
|
|
152921
|
+
declaredSizeByHash.set(entry.hash, entry.size);
|
|
152922
|
+
} else if (declaredSizeByHash.get(entry.hash) !== entry.size) {
|
|
152923
|
+
declaredSizeByHash.set(entry.hash, null);
|
|
152924
|
+
}
|
|
152925
|
+
}
|
|
152522
152926
|
let previousBackendIsStatic = false;
|
|
152523
152927
|
if (currentLiveDeployment) {
|
|
152524
152928
|
const routingRaw = await context.env.ROUTING.get(project.slug);
|
|
@@ -152530,7 +152934,7 @@ async function handleManifestOnlyDeploy(context) {
|
|
|
152530
152934
|
}
|
|
152531
152935
|
}
|
|
152532
152936
|
}
|
|
152533
|
-
const newHashes = hasWorkerFiles
|
|
152937
|
+
const newHashes = hasWorkerFiles ? declaredHashes.filter((hash4) => activeR2Sizes.get(hash4) !== declaredSizeByHash.get(hash4)) : !previousBackendIsStatic ? declaredHashes : declaredHashes.filter((hash4) => !carryForwardHashes.has(hash4));
|
|
152534
152938
|
const missingHashes = [];
|
|
152535
152939
|
const r2HeadCache = /* @__PURE__ */ new Map();
|
|
152536
152940
|
const foundNewAssets = await findR2Assets(
|
|
@@ -152995,16 +153399,18 @@ ${Date.now()}
|
|
|
152995
153399
|
await context.env.ROUTING.delete(`manifest:${old.id}`);
|
|
152996
153400
|
}
|
|
152997
153401
|
if (assetCleanupSafe) {
|
|
152998
|
-
|
|
152999
|
-
|
|
153000
|
-
|
|
153001
|
-
|
|
153402
|
+
orphanSweepAfterResponse = /* @__PURE__ */ __name(async () => {
|
|
153403
|
+
try {
|
|
153404
|
+
const orphans = await sweepAssetOrphansWithProjectFence(retainedHashes);
|
|
153405
|
+
if (orphans > 0) {
|
|
153406
|
+
logger.info("retention_cleanup", "r2_orphans_swept", { count: orphans });
|
|
153407
|
+
}
|
|
153408
|
+
} catch (e) {
|
|
153409
|
+
logger.warn("retention_cleanup", "r2_orphan_sweep_failed", {
|
|
153410
|
+
err: e instanceof Error ? e.message : String(e)
|
|
153411
|
+
});
|
|
153002
153412
|
}
|
|
153003
|
-
}
|
|
153004
|
-
logger.warn("retention_cleanup", "r2_orphan_sweep_failed", {
|
|
153005
|
-
err: e instanceof Error ? e.message : String(e)
|
|
153006
|
-
});
|
|
153007
|
-
}
|
|
153413
|
+
}, "orphanSweepAfterResponse");
|
|
153008
153414
|
}
|
|
153009
153415
|
}
|
|
153010
153416
|
const application2 = readPlatformApplication(context.env);
|
|
@@ -153021,6 +153427,7 @@ ${Date.now()}
|
|
|
153021
153427
|
assets: assetCount,
|
|
153022
153428
|
workers: 0
|
|
153023
153429
|
});
|
|
153430
|
+
await finishOrphanSweep();
|
|
153024
153431
|
return;
|
|
153025
153432
|
}
|
|
153026
153433
|
currentStep = "provisioning";
|
|
@@ -154065,16 +154472,18 @@ ${Date.now()}
|
|
|
154065
154472
|
}
|
|
154066
154473
|
}
|
|
154067
154474
|
if (assetCleanupSafe) {
|
|
154068
|
-
|
|
154069
|
-
|
|
154070
|
-
|
|
154071
|
-
|
|
154475
|
+
orphanSweepAfterResponse = /* @__PURE__ */ __name(async () => {
|
|
154476
|
+
try {
|
|
154477
|
+
const orphans = await sweepAssetOrphansWithProjectFence(retainedHashes);
|
|
154478
|
+
if (orphans > 0) {
|
|
154479
|
+
logger.info("retention_cleanup", "r2_orphans_swept", { count: orphans });
|
|
154480
|
+
}
|
|
154481
|
+
} catch (e) {
|
|
154482
|
+
logger.warn("retention_cleanup", "r2_orphan_sweep_failed", {
|
|
154483
|
+
err: e instanceof Error ? e.message : String(e)
|
|
154484
|
+
});
|
|
154072
154485
|
}
|
|
154073
|
-
}
|
|
154074
|
-
logger.warn("retention_cleanup", "r2_orphan_sweep_failed", {
|
|
154075
|
-
err: e instanceof Error ? e.message : String(e)
|
|
154076
|
-
});
|
|
154077
|
-
}
|
|
154486
|
+
}, "orphanSweepAfterResponse");
|
|
154078
154487
|
}
|
|
154079
154488
|
}
|
|
154080
154489
|
const application = readPlatformApplication(context.env);
|
|
@@ -154092,6 +154501,7 @@ ${Date.now()}
|
|
|
154092
154501
|
workers: workerFiles.length,
|
|
154093
154502
|
...migrationsApplied > 0 && { migrations: migrationsApplied }
|
|
154094
154503
|
});
|
|
154504
|
+
await finishOrphanSweep();
|
|
154095
154505
|
} catch (err) {
|
|
154096
154506
|
const raw2 = err instanceof ProjectAccessDeniedError ? err.userMessage : err instanceof Error ? err.message : String(err);
|
|
154097
154507
|
const msg = sanitizeDeployErrorMessage(raw2);
|
|
@@ -154559,11 +154969,14 @@ app11.post("/:id/deploy/preflight", async (context) => {
|
|
|
154559
154969
|
if (!valid) {
|
|
154560
154970
|
return context.json({ needed: Object.keys(assetManifest), total, skipped: 0 });
|
|
154561
154971
|
}
|
|
154562
|
-
const
|
|
154563
|
-
|
|
154564
|
-
|
|
154565
|
-
assetManifest
|
|
154972
|
+
const active = project.active_deployment_id ? await getDeployment(context.get("db"), project.active_deployment_id) : null;
|
|
154973
|
+
const activeR2Sizes = active?.status === "live" && active.project_id === projectId ? persistedR2AssetSizes(active.asset_hashes) : /* @__PURE__ */ new Map();
|
|
154974
|
+
const unverified = Object.fromEntries(
|
|
154975
|
+
Object.entries(assetManifest).filter(
|
|
154976
|
+
([, entry]) => activeR2Sizes.get(entry.hash) !== entry.size
|
|
154977
|
+
)
|
|
154566
154978
|
);
|
|
154979
|
+
const needed2 = await findMissingR2Assets(context.env.STATIC_ASSETS_R2, projectId, unverified);
|
|
154567
154980
|
return context.json({ needed: needed2, total, skipped: total - needed2.length });
|
|
154568
154981
|
}
|
|
154569
154982
|
let activeDeploymentId = project.active_deployment_id;
|
|
@@ -156323,6 +156736,7 @@ async function tryActivateDomain(env2, db, domain2, project, options) {
|
|
|
156323
156736
|
__name(tryActivateDomain, "tryActivateDomain");
|
|
156324
156737
|
|
|
156325
156738
|
// ../../home/runner/work/void/void/platform/packages/api/src/index.ts
|
|
156739
|
+
init_cleanup();
|
|
156326
156740
|
init_cloudflare_api();
|
|
156327
156741
|
init_email_destination_cleanup();
|
|
156328
156742
|
init_sandbox_controller();
|
|
@@ -160739,6 +161153,7 @@ init_db2();
|
|
|
160739
161153
|
// ../../home/runner/work/void/void/platform/packages/api/src/revalidate-core.ts
|
|
160740
161154
|
init_performance2();
|
|
160741
161155
|
init_dist();
|
|
161156
|
+
init_concurrency();
|
|
160742
161157
|
init_db2();
|
|
160743
161158
|
|
|
160744
161159
|
// ../../home/runner/work/void/void/platform/packages/api/src/isr-cache.ts
|
|
@@ -162403,6 +162818,35 @@ var app30 = new Hono2().get("/", async (context) => {
|
|
|
162403
162818
|
};
|
|
162404
162819
|
});
|
|
162405
162820
|
return context.json(projectsWithSummaries.sort(sortProjectList));
|
|
162821
|
+
}).get("/choices", async (context) => {
|
|
162822
|
+
const projects2 = await getAccessibleProjectsByUserId(context.get("db"), context.get("user").id);
|
|
162823
|
+
return context.json(
|
|
162824
|
+
projects2.map(({ project, role, owner }) => ({
|
|
162825
|
+
...projectWithUrl(project, context.env),
|
|
162826
|
+
role,
|
|
162827
|
+
owner: { id: owner.id, login: owner.login }
|
|
162828
|
+
}))
|
|
162829
|
+
);
|
|
162830
|
+
}).get("/resolve", async (context) => {
|
|
162831
|
+
const slug = context.req.query("slug");
|
|
162832
|
+
if (!slug || slug.length > MAX_SLUG_LENGTH || !/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(slug)) {
|
|
162833
|
+
return context.json({ error: "valid slug is required" }, 400);
|
|
162834
|
+
}
|
|
162835
|
+
const access = await getAccessibleProjectBySlug(
|
|
162836
|
+
context.get("db"),
|
|
162837
|
+
context.get("user").id,
|
|
162838
|
+
slug
|
|
162839
|
+
);
|
|
162840
|
+
if (!access || context.get("deployScope") && context.get("deployScope") !== access.project.id) {
|
|
162841
|
+
return context.json({ project: null });
|
|
162842
|
+
}
|
|
162843
|
+
return context.json({
|
|
162844
|
+
project: {
|
|
162845
|
+
...projectWithUrl(access.project, context.env),
|
|
162846
|
+
role: access.role,
|
|
162847
|
+
owner: { id: access.owner.id, login: access.owner.login }
|
|
162848
|
+
}
|
|
162849
|
+
});
|
|
162406
162850
|
}).post("/", async (context) => {
|
|
162407
162851
|
const body = await context.req.json();
|
|
162408
162852
|
if (!body.slug) {
|
|
@@ -166147,6 +166591,9 @@ async function scheduled(controller, env2, _ctx) {
|
|
|
166147
166591
|
}
|
|
166148
166592
|
const db = createDb(env2.HYPERDRIVE.connectionString);
|
|
166149
166593
|
const capabilities = getPlatformCapabilities(env2);
|
|
166594
|
+
await reconcileProjectCleanupJobs(db, env2).catch(
|
|
166595
|
+
(error63) => console.error("[scheduled] project cleanup retry failed:", error63)
|
|
166596
|
+
);
|
|
166150
166597
|
if (capabilities.email) {
|
|
166151
166598
|
await reconcileEmailDestinationCleanups(db, {
|
|
166152
166599
|
accountId: env2.CF_ACCOUNT_ID,
|