@edge-base/server 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin-build/_app/immutable/chunks/{DILS_-VJ.js → B3CvhH3c.js} +1 -1
- package/admin-build/_app/immutable/chunks/BN_-k-Ck.js +1 -0
- package/admin-build/_app/immutable/chunks/{Dt4vL4Df.js → BYL_uBga.js} +1 -1
- package/admin-build/_app/immutable/chunks/{C72lTcG0.js → Bcs4KYNp.js} +1 -1
- package/admin-build/_app/immutable/chunks/{B8s_s9QY.js → BkZCgsc3.js} +1 -1
- package/admin-build/_app/immutable/chunks/{BgDzp0i0.js → BvoGcDFV.js} +1 -1
- package/admin-build/_app/immutable/chunks/{BME_U9TJ.js → CCUxCptE.js} +1 -1
- package/admin-build/_app/immutable/chunks/CLHN9MVr.js +1 -0
- package/admin-build/_app/immutable/chunks/{DYaCRWMA.js → CR37B8DX.js} +1 -1
- package/admin-build/_app/immutable/chunks/CbfX3ELZ.js +1 -0
- package/admin-build/_app/immutable/chunks/CjcrXziO.js +2 -0
- package/admin-build/_app/immutable/chunks/CrwlCAM0.js +1 -0
- package/admin-build/_app/immutable/chunks/{B0HRJ657.js → DOOPbWwG.js} +1 -1
- package/admin-build/_app/immutable/chunks/DQVP4KC-.js +1 -0
- package/admin-build/_app/immutable/chunks/{Dj0QUuOf.js → DdvsFblq.js} +1 -1
- package/admin-build/_app/immutable/chunks/DemDWbs-.js +128 -0
- package/admin-build/_app/immutable/chunks/{XQM1k9PM.js → DmDTovpg.js} +1 -1
- package/admin-build/_app/immutable/chunks/{fYEKMQ-Z.js → Ff90owjx.js} +1 -1
- package/admin-build/_app/immutable/chunks/{5RQRbp5q.js → LL3ulaxa.js} +1 -1
- package/admin-build/_app/immutable/chunks/{DBsVqhuh.js → Q3vAxeY-.js} +1 -1
- package/admin-build/_app/immutable/chunks/{D__dwMuW.js → SQVAC3Cv.js} +1 -1
- package/admin-build/_app/immutable/chunks/{Z41NK6i6.js → bguI1TeA.js} +1 -1
- package/admin-build/_app/immutable/chunks/{_teD5ji5.js → nlAMTi52.js} +1 -1
- package/admin-build/_app/immutable/chunks/{BjWZuf8W.js → qBm6xof8.js} +1 -1
- package/admin-build/_app/immutable/entry/{app.C8ylfBe6.js → app.CP83Ni80.js} +2 -2
- package/admin-build/_app/immutable/entry/start.DY6YakU0.js +1 -0
- package/admin-build/_app/immutable/nodes/{0.CJJ6HZbp.js → 0.DiRq7puO.js} +1 -1
- package/admin-build/_app/immutable/nodes/1.BFeyKLGT.js +1 -0
- package/admin-build/_app/immutable/nodes/10.zcee7hJx.js +1 -0
- package/admin-build/_app/immutable/nodes/11.BW7wLs2Y.js +1 -0
- package/admin-build/_app/immutable/nodes/12.CxJRlYSd.js +1 -0
- package/admin-build/_app/immutable/nodes/13.pp0F_5hn.js +110 -0
- package/admin-build/_app/immutable/nodes/14.t3AfGiGo.js +3 -0
- package/admin-build/_app/immutable/nodes/15.B3agc7NX.js +1 -0
- package/admin-build/_app/immutable/nodes/{16.D0xkPUBW.js → 16.C4uG2-i8.js} +1 -1
- package/admin-build/_app/immutable/nodes/{17.CebNqPeh.js → 17.CwGxi1Bn.js} +1 -1
- package/admin-build/_app/immutable/nodes/18.CrQyN_gU.js +1 -0
- package/admin-build/_app/immutable/nodes/19.NEPUOXl7.js +2 -0
- package/admin-build/_app/immutable/nodes/{20.DYb-q3W8.js → 20.DGHO8ipr.js} +1 -1
- package/admin-build/_app/immutable/nodes/21.UVKBDvp4.js +1 -0
- package/admin-build/_app/immutable/nodes/22.Dri5It7a.js +1 -0
- package/admin-build/_app/immutable/nodes/{23.BLgq21om.js → 23.BPQP_Zte.js} +2 -2
- package/admin-build/_app/immutable/nodes/24.D580FdSS.js +2 -0
- package/admin-build/_app/immutable/nodes/25.BMNPOZwF.js +2 -0
- package/admin-build/_app/immutable/nodes/26.XcpEcbiz.js +1 -0
- package/admin-build/_app/immutable/nodes/27.C1zHHcYv.js +1 -0
- package/admin-build/_app/immutable/nodes/28.CuKzzrY8.js +1 -0
- package/admin-build/_app/immutable/nodes/29.nLpBMXnM.js +1 -0
- package/admin-build/_app/immutable/nodes/{3.z8ut3jS-.js → 3.5G_aseoL.js} +1 -1
- package/admin-build/_app/immutable/nodes/30.CQC4nLoU.js +1 -0
- package/admin-build/_app/immutable/nodes/31.Bet8kxOK.js +1 -0
- package/admin-build/_app/immutable/nodes/4.nmJDYJpC.js +1 -0
- package/admin-build/_app/immutable/nodes/5.CnbYLG4E.js +1 -0
- package/admin-build/_app/immutable/nodes/6.KA01b-3y.js +1 -0
- package/admin-build/_app/immutable/nodes/7.CP9fkn1L.js +1 -0
- package/admin-build/_app/immutable/nodes/8.BTzDb---.js +1 -0
- package/admin-build/_app/immutable/nodes/9.DkNJg_J6.js +1 -0
- package/admin-build/_app/version.json +1 -1
- package/admin-build/index.html +7 -7
- package/package.json +3 -3
- package/src/__tests__/database-do-route-validation.test.ts +10 -7
- package/src/__tests__/meta-route-registration.test.ts +20 -15
- package/src/__tests__/push-handlers.test.ts +1 -1
- package/src/__tests__/room-auth-state-loss.test.ts +122 -0
- package/src/__tests__/room-handler-context.test.ts +4 -4
- package/src/__tests__/room-rate-limit-scopes.test.ts +38 -0
- package/src/__tests__/room-runtime-routing.test.ts +23 -0
- package/src/__tests__/route-parser.test.ts +6 -0
- package/src/__tests__/runtime-startup.test.ts +49 -0
- package/src/__tests__/schema.test.ts +15 -6
- package/src/durable-objects/database-do.ts +21 -1
- package/src/durable-objects/database-live-do.ts +15 -0
- package/src/durable-objects/room-runtime-base.ts +436 -169
- package/src/durable-objects/rooms-do.ts +63 -25
- package/src/index.ts +340 -280
- package/src/lib/d1-handler.ts +32 -17
- package/src/lib/postgres-handler.ts +24 -12
- package/src/lib/route-parser.ts +3 -0
- package/src/lib/runtime-startup.ts +53 -0
- package/src/lib/schemas.ts +12 -2
- package/src/middleware/captcha-verify.ts +16 -3
- package/src/middleware/error-handler.ts +1 -1
- package/src/middleware/rules.ts +28 -9
- package/src/routes/admin-auth.ts +3 -3
- package/src/routes/admin.ts +13 -8
- package/src/routes/analytics-api.ts +3 -3
- package/src/routes/auth.ts +1 -1
- package/src/routes/backup.ts +1 -1
- package/src/routes/d1.ts +14 -7
- package/src/routes/database-live.ts +13 -6
- package/src/routes/kv.ts +21 -10
- package/src/routes/oauth.ts +1 -1
- package/src/routes/push.ts +119 -77
- package/src/routes/room.ts +215 -7
- package/src/routes/schema-endpoint.ts +2 -2
- package/src/routes/sql.ts +10 -6
- package/src/routes/storage.ts +4 -2
- package/src/routes/vectorize.ts +16 -4
- package/admin-build/_app/immutable/chunks/BYI6CUvd.js +0 -1
- package/admin-build/_app/immutable/chunks/C6lpZLE2.js +0 -1
- package/admin-build/_app/immutable/chunks/CoI6jjbg.js +0 -2
- package/admin-build/_app/immutable/chunks/D5GswVnI.js +0 -128
- package/admin-build/_app/immutable/chunks/Dj-E9-FO.js +0 -1
- package/admin-build/_app/immutable/chunks/g_-Kpxu3.js +0 -1
- package/admin-build/_app/immutable/chunks/wCNueVYy.js +0 -1
- package/admin-build/_app/immutable/entry/start.CtsqDyfj.js +0 -1
- package/admin-build/_app/immutable/nodes/1.B4sI5cB4.js +0 -1
- package/admin-build/_app/immutable/nodes/10.D6hvCer6.js +0 -1
- package/admin-build/_app/immutable/nodes/11.Dx7b8aQ5.js +0 -1
- package/admin-build/_app/immutable/nodes/12.Bqmy5KIF.js +0 -1
- package/admin-build/_app/immutable/nodes/13.CC6KpXgS.js +0 -110
- package/admin-build/_app/immutable/nodes/14.yCo1Ix8E.js +0 -3
- package/admin-build/_app/immutable/nodes/15.co0UfPlh.js +0 -1
- package/admin-build/_app/immutable/nodes/18.JUoLOZxh.js +0 -1
- package/admin-build/_app/immutable/nodes/19.ND8kmQJe.js +0 -2
- package/admin-build/_app/immutable/nodes/21.cz3IN9Cc.js +0 -1
- package/admin-build/_app/immutable/nodes/22.UOzm8WYV.js +0 -1
- package/admin-build/_app/immutable/nodes/24.DN9usmUs.js +0 -2
- package/admin-build/_app/immutable/nodes/25.BddRfAyE.js +0 -2
- package/admin-build/_app/immutable/nodes/26.Dl6XHIeT.js +0 -1
- package/admin-build/_app/immutable/nodes/27.D0iNwALG.js +0 -1
- package/admin-build/_app/immutable/nodes/28.9dKQmdGi.js +0 -1
- package/admin-build/_app/immutable/nodes/29.wXzfJUXp.js +0 -1
- package/admin-build/_app/immutable/nodes/30.BtZETNsL.js +0 -1
- package/admin-build/_app/immutable/nodes/31.CYonj2Jh.js +0 -1
- package/admin-build/_app/immutable/nodes/4.COtDPQ9b.js +0 -1
- package/admin-build/_app/immutable/nodes/5.CTRCeIhp.js +0 -1
- package/admin-build/_app/immutable/nodes/6.ChHi3QkR.js +0 -1
- package/admin-build/_app/immutable/nodes/7.CCMtr6Ac.js +0 -1
- package/admin-build/_app/immutable/nodes/8.DpWJ-X_-.js +0 -1
- package/admin-build/_app/immutable/nodes/9.DOkvfmir.js +0 -1
package/src/routes/room.ts
CHANGED
|
@@ -45,6 +45,26 @@ const roomConnectDiagnosticSchema = z.object({
|
|
|
45
45
|
pendingCount: z.number().optional(),
|
|
46
46
|
maxPending: z.number().optional(),
|
|
47
47
|
});
|
|
48
|
+
const roomSummarySchema = z.object({
|
|
49
|
+
namespace: z.string(),
|
|
50
|
+
roomId: z.string(),
|
|
51
|
+
metadata: z.record(z.string(), z.unknown()),
|
|
52
|
+
occupancy: z.object({
|
|
53
|
+
activeMembers: z.number(),
|
|
54
|
+
activeConnections: z.number(),
|
|
55
|
+
}),
|
|
56
|
+
updatedAt: z.string(),
|
|
57
|
+
});
|
|
58
|
+
const roomSummaryBatchBodySchema = z.object({
|
|
59
|
+
namespace: z.string().openapi({ description: 'Room namespace shared by the requested room IDs' }),
|
|
60
|
+
ids: z.array(z.string()).min(1).max(100).openapi({ description: 'Room IDs to summarize' }),
|
|
61
|
+
});
|
|
62
|
+
const roomSummaryCollectionSchema = z.object({
|
|
63
|
+
namespace: z.string(),
|
|
64
|
+
items: z.array(roomSummarySchema),
|
|
65
|
+
deniedIds: z.array(z.string()),
|
|
66
|
+
updatedAt: z.string(),
|
|
67
|
+
});
|
|
48
68
|
const roomRealtimeSessionDescriptionSchema = z.object({
|
|
49
69
|
sdp: z.string().openapi({ description: 'WebRTC session description payload' }),
|
|
50
70
|
type: z.enum(['offer', 'answer']).openapi({ description: 'Session description type' }),
|
|
@@ -157,6 +177,22 @@ function isRoomOperationPublic(
|
|
|
157
177
|
return !!namespaceConfig.public[operation];
|
|
158
178
|
}
|
|
159
179
|
|
|
180
|
+
function warnRoomDevelopmentFallback(
|
|
181
|
+
namespace: string,
|
|
182
|
+
operation: 'metadata' | 'join' | 'action',
|
|
183
|
+
): void {
|
|
184
|
+
const warningKey = `${namespace}:${operation}`;
|
|
185
|
+
if (roomFallbackWarnings.has(warningKey)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
roomFallbackWarnings.add(warningKey);
|
|
189
|
+
console.warn(
|
|
190
|
+
`[Room] ${warningKey} is allowed because release=false and no explicit room rule was found. `
|
|
191
|
+
+ `This fallback is local-dev only. Add rooms.${namespace}.access.${operation} or set `
|
|
192
|
+
+ `rooms.${namespace}.public.${operation}=true to make the behavior explicit.`,
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
160
196
|
function getRoomAuthContext(
|
|
161
197
|
auth: {
|
|
162
198
|
id?: string;
|
|
@@ -188,11 +224,11 @@ export async function proxyRoomDoRequest(
|
|
|
188
224
|
const roomId = c.req.query('id');
|
|
189
225
|
|
|
190
226
|
if (!namespace || !roomId) {
|
|
191
|
-
return c.json({ code: 400, message: 'namespace and id
|
|
227
|
+
return c.json({ code: 400, message: "Missing required query parameters 'namespace' and 'id' for room requests." }, 400);
|
|
192
228
|
}
|
|
193
229
|
|
|
194
230
|
if (options?.requireAuth && !c.get('auth')) {
|
|
195
|
-
return c.json({ code: 401, message: 'Authentication required' }, 401);
|
|
231
|
+
return c.json({ code: 401, message: 'Authentication required. Sign in before trying to access this room.' }, 401);
|
|
196
232
|
}
|
|
197
233
|
|
|
198
234
|
const config = parseConfig(c.env);
|
|
@@ -433,6 +469,42 @@ const getRoomMetadata = createRoute({
|
|
|
433
469
|
},
|
|
434
470
|
});
|
|
435
471
|
|
|
472
|
+
const getRoomSummary = createRoute({
|
|
473
|
+
operationId: 'getRoomSummary',
|
|
474
|
+
method: 'get',
|
|
475
|
+
path: '/summary',
|
|
476
|
+
tags: ['client'],
|
|
477
|
+
summary: 'Get room summary',
|
|
478
|
+
description: 'Returns lobby-safe room metadata plus current occupancy without joining the room.',
|
|
479
|
+
request: {
|
|
480
|
+
query: roomQuerySchema,
|
|
481
|
+
},
|
|
482
|
+
responses: {
|
|
483
|
+
200: { description: 'Room summary', content: { 'application/json': { schema: roomSummarySchema } } },
|
|
484
|
+
400: { description: 'Bad request', content: { 'application/json': { schema: errorResponseSchema } } },
|
|
485
|
+
403: { description: 'Forbidden', content: { 'application/json': { schema: errorResponseSchema } } },
|
|
486
|
+
404: { description: 'Not found', content: { 'application/json': { schema: errorResponseSchema } } },
|
|
487
|
+
},
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
const getRoomSummaries = createRoute({
|
|
491
|
+
operationId: 'getRoomSummaries',
|
|
492
|
+
method: 'post',
|
|
493
|
+
path: '/summaries',
|
|
494
|
+
tags: ['client'],
|
|
495
|
+
summary: 'Get summaries for multiple rooms',
|
|
496
|
+
description: 'Returns lobby-safe room metadata plus current occupancy for multiple room IDs in the same namespace.',
|
|
497
|
+
request: {
|
|
498
|
+
body: { content: { 'application/json': { schema: roomSummaryBatchBodySchema } }, required: true },
|
|
499
|
+
},
|
|
500
|
+
responses: {
|
|
501
|
+
200: { description: 'Room summaries', content: { 'application/json': { schema: roomSummaryCollectionSchema } } },
|
|
502
|
+
400: { description: 'Bad request', content: { 'application/json': { schema: errorResponseSchema } } },
|
|
503
|
+
403: { description: 'Forbidden', content: { 'application/json': { schema: errorResponseSchema } } },
|
|
504
|
+
404: { description: 'Room feature not configured', content: { 'application/json': { schema: errorResponseSchema } } },
|
|
505
|
+
},
|
|
506
|
+
});
|
|
507
|
+
|
|
436
508
|
roomRoute.openapi(getRoomMetadata, async (c) => {
|
|
437
509
|
const namespace = c.req.query('namespace');
|
|
438
510
|
const roomId = c.req.query('id');
|
|
@@ -459,11 +531,7 @@ roomRoute.openapi(getRoomMetadata, async (c) => {
|
|
|
459
531
|
return c.json({ code: 403, message: 'Room metadata requires access.metadata or public.metadata in release mode' }, 403);
|
|
460
532
|
}
|
|
461
533
|
if (!config.release) {
|
|
462
|
-
|
|
463
|
-
if (!roomFallbackWarnings.has(warningKey)) {
|
|
464
|
-
roomFallbackWarnings.add(warningKey);
|
|
465
|
-
console.warn(`[Room] ${warningKey} is using development-mode allow-by-default. Add rooms.${namespace}.access.metadata or public.metadata to make this explicit.`);
|
|
466
|
-
}
|
|
534
|
+
warnRoomDevelopmentFallback(namespace, 'metadata');
|
|
467
535
|
}
|
|
468
536
|
}
|
|
469
537
|
if (metadataAccess) {
|
|
@@ -498,6 +566,146 @@ roomRoute.openapi(getRoomMetadata, async (c) => {
|
|
|
498
566
|
return doStub.fetch(doRequest);
|
|
499
567
|
});
|
|
500
568
|
|
|
569
|
+
roomRoute.openapi(getRoomSummary, async (c) => {
|
|
570
|
+
const namespace = c.req.query('namespace');
|
|
571
|
+
const roomId = c.req.query('id');
|
|
572
|
+
|
|
573
|
+
if (!namespace || !roomId) {
|
|
574
|
+
return c.json({ code: 400, message: 'namespace and id query parameters required' }, 400);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
const config = parseConfig(c.env);
|
|
578
|
+
const namespaceConfig = config.rooms?.[namespace];
|
|
579
|
+
if (config.release) {
|
|
580
|
+
if (!config.rooms?.[namespace]) {
|
|
581
|
+
return c.json({
|
|
582
|
+
code: 403,
|
|
583
|
+
message: `Room namespace '${namespace}' not configured`,
|
|
584
|
+
}, 403);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
const metadataAccess = namespaceConfig?.access?.metadata;
|
|
589
|
+
if (!metadataAccess) {
|
|
590
|
+
if (config.release && !isRoomOperationPublic(namespaceConfig, 'metadata')) {
|
|
591
|
+
return c.json({ code: 403, message: 'Room summary requires access.metadata or public.metadata in release mode' }, 403);
|
|
592
|
+
}
|
|
593
|
+
if (!config.release) {
|
|
594
|
+
warnRoomDevelopmentFallback(namespace, 'metadata');
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
if (metadataAccess) {
|
|
598
|
+
const auth = (c.get('auth') as { id?: string; role?: string; email?: string | null; custom?: Record<string, unknown> | null; isAnonymous?: boolean; meta?: Record<string, unknown> } | null | undefined) ?? null;
|
|
599
|
+
const allowed = await Promise.resolve(metadataAccess(
|
|
600
|
+
getRoomAuthContext(auth),
|
|
601
|
+
roomId,
|
|
602
|
+
)).catch(() => false);
|
|
603
|
+
if (!allowed) {
|
|
604
|
+
return c.json({ code: 403, message: 'Denied by room metadata access rule' }, 403);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
const runtime = resolveRoomRuntime(c.env);
|
|
609
|
+
if (!runtime.binding) {
|
|
610
|
+
return c.json({ code: 404, message: `Room runtime '${runtime.target}' not configured` }, 404);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
const doName = `${namespace}::${roomId}`;
|
|
614
|
+
const doId = runtime.binding.idFromName(doName);
|
|
615
|
+
const doStub = runtime.binding.get(doId);
|
|
616
|
+
|
|
617
|
+
const url = new URL(c.req.url);
|
|
618
|
+
url.pathname = '/summary';
|
|
619
|
+
url.searchParams.set('room', doName);
|
|
620
|
+
const doRequest = new Request(url.toString(), {
|
|
621
|
+
method: 'GET',
|
|
622
|
+
headers: c.req.raw.headers,
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
return doStub.fetch(doRequest);
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
roomRoute.openapi(getRoomSummaries, async (c) => {
|
|
629
|
+
const body = c.req.valid('json') as z.infer<typeof roomSummaryBatchBodySchema>;
|
|
630
|
+
const namespace = body.namespace;
|
|
631
|
+
const roomIds = [...new Set(body.ids)];
|
|
632
|
+
|
|
633
|
+
const config = parseConfig(c.env);
|
|
634
|
+
const namespaceConfig = config.rooms?.[namespace];
|
|
635
|
+
if (config.release && !namespaceConfig) {
|
|
636
|
+
return c.json({
|
|
637
|
+
code: 403,
|
|
638
|
+
message: `Room namespace '${namespace}' not configured`,
|
|
639
|
+
}, 403);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
const metadataAccess = namespaceConfig?.access?.metadata;
|
|
643
|
+
if (!metadataAccess) {
|
|
644
|
+
if (config.release && !isRoomOperationPublic(namespaceConfig, 'metadata')) {
|
|
645
|
+
return c.json({ code: 403, message: 'Room summaries require access.metadata or public.metadata in release mode' }, 403);
|
|
646
|
+
}
|
|
647
|
+
if (!config.release) {
|
|
648
|
+
warnRoomDevelopmentFallback(namespace, 'metadata');
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const runtime = resolveRoomRuntime(c.env);
|
|
653
|
+
if (!runtime.binding) {
|
|
654
|
+
return c.json({ code: 404, message: `Room runtime '${runtime.target}' not configured` }, 404);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const auth = (c.get('auth') as { id?: string; role?: string; email?: string | null; custom?: Record<string, unknown> | null; isAnonymous?: boolean; meta?: Record<string, unknown> } | null | undefined) ?? null;
|
|
658
|
+
const authContext = getRoomAuthContext(auth);
|
|
659
|
+
const allowedRoomIds: string[] = [];
|
|
660
|
+
const deniedIds: string[] = [];
|
|
661
|
+
|
|
662
|
+
if (metadataAccess) {
|
|
663
|
+
for (const roomId of roomIds) {
|
|
664
|
+
const allowed = await Promise.resolve(metadataAccess(authContext, roomId)).catch(() => false);
|
|
665
|
+
if (allowed) {
|
|
666
|
+
allowedRoomIds.push(roomId);
|
|
667
|
+
} else {
|
|
668
|
+
deniedIds.push(roomId);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
} else {
|
|
672
|
+
allowedRoomIds.push(...roomIds);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
const items = await Promise.all(
|
|
676
|
+
allowedRoomIds.map(async (roomId) => {
|
|
677
|
+
const doName = `${namespace}::${roomId}`;
|
|
678
|
+
const doId = runtime.binding!.idFromName(doName);
|
|
679
|
+
const doStub = runtime.binding!.get(doId);
|
|
680
|
+
|
|
681
|
+
const url = new URL(c.req.url);
|
|
682
|
+
url.pathname = '/summary';
|
|
683
|
+
url.searchParams.set('room', doName);
|
|
684
|
+
const doResponse = await doStub.fetch(new Request(url.toString(), {
|
|
685
|
+
method: 'GET',
|
|
686
|
+
headers: c.req.raw.headers,
|
|
687
|
+
}));
|
|
688
|
+
|
|
689
|
+
if (!doResponse.ok) {
|
|
690
|
+
const errorPayload = await doResponse.json().catch(() => null) as { message?: string } | null;
|
|
691
|
+
throw new Error(
|
|
692
|
+
errorPayload?.message
|
|
693
|
+
?? `Failed to load room summary for '${roomId}' in namespace '${namespace}'.`,
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
return doResponse.json() as Promise<z.infer<typeof roomSummarySchema>>;
|
|
698
|
+
}),
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
return c.json({
|
|
702
|
+
namespace,
|
|
703
|
+
items,
|
|
704
|
+
deniedIds,
|
|
705
|
+
updatedAt: new Date().toISOString(),
|
|
706
|
+
});
|
|
707
|
+
});
|
|
708
|
+
|
|
501
709
|
const getRoomRealtimeSession = createRoute({
|
|
502
710
|
operationId: 'getRoomRealtimeSession',
|
|
503
711
|
method: 'get',
|
|
@@ -45,14 +45,14 @@ schemaRoute.openapi(getSchema, async (c) => {
|
|
|
45
45
|
buildConstraintCtx(c.env, c.req),
|
|
46
46
|
);
|
|
47
47
|
if (skResult === 'invalid') {
|
|
48
|
-
throw new EdgeBaseError(401, '
|
|
48
|
+
throw new EdgeBaseError(401, 'Invalid X-EdgeBase-Service-Key for schema reads.');
|
|
49
49
|
}
|
|
50
50
|
const serviceKeyBypass = skResult === 'valid';
|
|
51
51
|
|
|
52
52
|
if (!serviceKeyBypass) {
|
|
53
53
|
const auth = c.get('auth');
|
|
54
54
|
if (!auth) {
|
|
55
|
-
throw new EdgeBaseError(401, 'Authentication required.');
|
|
55
|
+
throw new EdgeBaseError(401, 'Authentication required to read the schema endpoint.');
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
}
|
package/src/routes/sql.ts
CHANGED
|
@@ -39,6 +39,10 @@ import { executeProviderAwareSql } from '../lib/provider-aware-sql.js';
|
|
|
39
39
|
|
|
40
40
|
export const sqlRoute = new OpenAPIHono<HonoEnv>({ defaultHook: zodDefaultHook });
|
|
41
41
|
|
|
42
|
+
function invalidSqlJsonMessage(): string {
|
|
43
|
+
return 'Invalid JSON body for SQL execution. Send application/json with { namespace, sql, params? }.';
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
/**
|
|
43
47
|
* POST /api/sql
|
|
44
48
|
* Body: { namespace: string, id?: string, sql: string, params?: unknown[] }
|
|
@@ -81,19 +85,19 @@ sqlRoute.openapi(executeSql, async (c) => {
|
|
|
81
85
|
try {
|
|
82
86
|
body = await c.req.json();
|
|
83
87
|
} catch {
|
|
84
|
-
return c.json({ code: 400, message:
|
|
88
|
+
return c.json({ code: 400, message: invalidSqlJsonMessage() }, 400);
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
const { namespace, id, sql, params } = body;
|
|
88
92
|
|
|
89
93
|
if (!namespace || typeof namespace !== 'string') {
|
|
90
|
-
return c.json({ code: 400, message: 'namespace
|
|
94
|
+
return c.json({ code: 400, message: "Missing required field 'namespace' for SQL execution." }, 400);
|
|
91
95
|
}
|
|
92
96
|
if (id !== undefined && id !== null && typeof id !== 'string') {
|
|
93
|
-
return c.json({ code: 400, message: 'id must be a string
|
|
97
|
+
return c.json({ code: 400, message: "Field 'id' must be a string when provided for SQL execution." }, 400);
|
|
94
98
|
}
|
|
95
99
|
if (!sql || typeof sql !== 'string') {
|
|
96
|
-
return c.json({ code: 400, message: 'sql
|
|
100
|
+
return c.json({ code: 400, message: "Missing required field 'sql' for SQL execution." }, 400);
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
// Validate namespace is declared in databases config (§1)
|
|
@@ -124,10 +128,10 @@ sqlRoute.openapi(executeSql, async (c) => {
|
|
|
124
128
|
buildConstraintCtx(c.env, c.req),
|
|
125
129
|
);
|
|
126
130
|
if (skResult === 'missing') {
|
|
127
|
-
return c.json({ code: 403, message:
|
|
131
|
+
return c.json({ code: 403, message: `X-EdgeBase-Service-Key is required to execute SQL for database namespace '${namespace}'.` }, 403);
|
|
128
132
|
}
|
|
129
133
|
if (skResult === 'invalid') {
|
|
130
|
-
return c.json({ code: 401, message:
|
|
134
|
+
return c.json({ code: 401, message: `Invalid X-EdgeBase-Service-Key for SQL execution in database namespace '${namespace}'.` }, 401);
|
|
131
135
|
}
|
|
132
136
|
|
|
133
137
|
try {
|
package/src/routes/storage.ts
CHANGED
|
@@ -297,7 +297,7 @@ function checkServiceKey(env: Env, header: string | undefined, scope: string, re
|
|
|
297
297
|
const { result } = validateKey(header, scope, config, env, undefined, constraintCtx);
|
|
298
298
|
if (result === 'valid') return true;
|
|
299
299
|
if (result === 'invalid') {
|
|
300
|
-
throw new EdgeBaseError(401,
|
|
300
|
+
throw new EdgeBaseError(401, `Invalid X-EdgeBase-Service-Key for storage scope '${scope}'.`, undefined, 'unauthenticated');
|
|
301
301
|
}
|
|
302
302
|
return false; // 'missing' → continue to normal rules
|
|
303
303
|
}
|
|
@@ -1236,7 +1236,9 @@ storage.openapi(deleteBatch, async (c) => {
|
|
|
1236
1236
|
// afterDelete — plugin-registered storage hooks (per-file, non-blocking)
|
|
1237
1237
|
executeStorageHooks('afterDelete', { ...fileMeta, bucket: bucketName }, auth, c.executionCtx, c.env, getWorkerUrl(c.req.url, c.env));
|
|
1238
1238
|
} catch (e) {
|
|
1239
|
-
const msg = e instanceof EdgeBaseError
|
|
1239
|
+
const msg = e instanceof EdgeBaseError
|
|
1240
|
+
? e.message
|
|
1241
|
+
: 'Delete failed with an unexpected storage error. Check worker logs for details.';
|
|
1240
1242
|
failed.push({ key, error: msg });
|
|
1241
1243
|
}
|
|
1242
1244
|
}
|
package/src/routes/vectorize.ts
CHANGED
|
@@ -35,9 +35,14 @@ const READ_ACTIONS: Action[] = ['search', 'getByIds', 'queryById', 'describe'];
|
|
|
35
35
|
|
|
36
36
|
const STUB_WARNING = 'Vectorize not available in this environment';
|
|
37
37
|
const VECTOR_BATCH_LIMIT = 20;
|
|
38
|
+
const vectorizeStubWarnings = new Set<string>();
|
|
38
39
|
|
|
39
40
|
export const vectorizeRoute = new OpenAPIHono<HonoEnv>({ defaultHook: zodDefaultHook });
|
|
40
41
|
|
|
42
|
+
function invalidVectorizeJsonMessage(): string {
|
|
43
|
+
return 'Invalid JSON body for Vectorize. Send application/json with { action, ...payload }.';
|
|
44
|
+
}
|
|
45
|
+
|
|
41
46
|
/**
|
|
42
47
|
* POST /api/vectorize/:index
|
|
43
48
|
* Body: { action, vectors?, vector?, vectorId?, topK?, filter?, ids?, namespace?, returnValues?, returnMetadata? }
|
|
@@ -78,7 +83,7 @@ vectorizeRoute.openapi(vectorizeOperation, async (c) => {
|
|
|
78
83
|
try {
|
|
79
84
|
body = await c.req.json();
|
|
80
85
|
} catch {
|
|
81
|
-
return c.json({ code: 400, message:
|
|
86
|
+
return c.json({ code: 400, message: invalidVectorizeJsonMessage() }, 400);
|
|
82
87
|
}
|
|
83
88
|
|
|
84
89
|
const { action } = body;
|
|
@@ -108,10 +113,10 @@ vectorizeRoute.openapi(vectorizeOperation, async (c) => {
|
|
|
108
113
|
buildConstraintCtx(c.env, c.req),
|
|
109
114
|
);
|
|
110
115
|
if (skResult === 'missing') {
|
|
111
|
-
return c.json({ code: 403, message:
|
|
116
|
+
return c.json({ code: 403, message: `X-EdgeBase-Service-Key is required to access Vectorize index '${nameParam}'.` }, 403);
|
|
112
117
|
}
|
|
113
118
|
if (skResult === 'invalid') {
|
|
114
|
-
return c.json({ code: 401, message:
|
|
119
|
+
return c.json({ code: 401, message: `Invalid X-EdgeBase-Service-Key for Vectorize index '${nameParam}'.` }, 401);
|
|
115
120
|
}
|
|
116
121
|
|
|
117
122
|
// ─── Input validation ─────────────────────────────────────────────────
|
|
@@ -165,7 +170,14 @@ vectorizeRoute.openapi(vectorizeOperation, async (c) => {
|
|
|
165
170
|
const bindingName = vectorConfig.binding ?? `VECTORIZE_${nameParam.toUpperCase()}`;
|
|
166
171
|
const binding = (c.env as unknown as Record<string, unknown>)[bindingName] as VectorizeIndex | undefined;
|
|
167
172
|
if (!binding) {
|
|
168
|
-
|
|
173
|
+
const warningKey = `${nameParam}:${bindingName}`;
|
|
174
|
+
if (!vectorizeStubWarnings.has(warningKey)) {
|
|
175
|
+
vectorizeStubWarnings.add(warningKey);
|
|
176
|
+
console.warn(
|
|
177
|
+
`[Vectorize] '${nameParam}' is running with a local stub because binding '${bindingName}' is unavailable. `
|
|
178
|
+
+ 'Search and mutation calls will return no-op stub data until the binding is configured in Cloudflare.',
|
|
179
|
+
);
|
|
180
|
+
}
|
|
169
181
|
// Return stub responses for local development
|
|
170
182
|
// Include both v1 (count) and v2 (mutationId) fields so code for either version works.
|
|
171
183
|
switch (action) {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{w as h,g as m}from"./Bn2NtlTj.js";import{b as g}from"./DBsVqhuh.js";function c(e){return e.replace(/\/+$/,"")}function T(e){return!e||e==="/"?"":(e.startsWith("/")?e:`/${e}`).replace(/\/+$/,"")}function u(e,n){const t=c(e),a=n.startsWith("/")?n:`/${n}`;return`${t}${a}`}const l=c(""),d=c(""),j=T(g);function k(){return d||window.location.origin}function f(){return l||k()}function i(e=""){const n=e.replace(/^\/+/,"");return u(f(),n?`/admin/api/${n}`:"/admin/api")}function N(e=""){return u(f(),e||"/")}const p="edgebase_admin_auth",r=p;function y(){try{const e=localStorage.getItem(r);if(e){const n=JSON.parse(e);return{accessToken:n.accessToken??null,refreshToken:n.refreshToken??null,admin:n.admin??null}}}catch{try{localStorage.removeItem(r)}catch{}}return{accessToken:null,refreshToken:null,admin:null}}function S(e){try{localStorage.setItem(r,JSON.stringify(e))}catch{console.warn("[EdgeBase] Failed to save auth state to localStorage")}}function w(){try{localStorage.removeItem(r)}catch{console.warn("[EdgeBase] Failed to clear auth state from localStorage")}}const A=y(),o=h(A);o.subscribe(e=>{e.accessToken?S(e):w()});async function O(e,n){const t=await fetch(i("auth/login"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e,password:n})});if(!t.ok){const s=await t.json().catch(()=>({}));throw new Error(s.message??"Login failed. Please check your email and password.")}const a=await t.json();o.set({accessToken:a.accessToken,refreshToken:a.refreshToken,admin:a.admin})}async function b(e,n){const t=await fetch(i("setup"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e,password:n})});if(!t.ok){const s=await t.json().catch(()=>({}));throw new Error(s.message??"Failed to create admin account. Please check your details and try again.")}const a=await t.json();o.set({accessToken:a.accessToken,refreshToken:a.refreshToken,admin:a.admin})}async function P(){const e=m(o);if(!e.refreshToken)return!1;try{const n=await fetch(i("auth/refresh"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e.refreshToken})});if(!n.ok)return!1;const t=await n.json();return o.set({accessToken:t.accessToken,refreshToken:t.refreshToken,admin:t.admin}),!0}catch{return!1}}function E(){o.set({accessToken:null,refreshToken:null,admin:null})}const R={subscribe:o.subscribe,set:o.set,update:o.update,login:O,setup:b,refresh:P,logout:E};export{p as A,R as a,f as b,N as c,j as d,i as g};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var ge=Object.defineProperty;var _e=(e,n,r)=>n in e?ge(e,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[n]=r;var F=(e,n,r)=>_e(e,typeof n!="symbol"?n+"":n,r);import{a2 as q,x as me,au as he,h as k,n as L,v as Ee,e as we,g as oe,y as Te,A as Ae,B as ie,D as V,k as U,C as ye,av as Ie,aw as fe,_ as Ne,ax as w,a3 as G,ay as xe,a5 as Se,X as Ce,az as Re,aA as J,aB as ke,aC as De,a7 as Oe,aD as ue,aE as He,$ as ve,a1 as pe,aF as X,I as Me,aG as be,aH as Fe,aI as Ue,a0 as ze,l as $e,M as Z}from"./BdTBlfLy.js";import{g as K}from"./Bn2NtlTj.js";import{g as Be,a as Y}from"./BYI6CUvd.js";import{l as qe,d as ce}from"./XQM1k9PM.js";function an(e,n){return n}function Le(e,n,r){for(var f=[],u=n.length,i,c=n.length,v=0;v<u;v++){let m=n[v];pe(m,()=>{if(i){if(i.pending.delete(m),i.done.add(m),i.pending.size===0){var l=e.outrogroups;P(J(i.done)),l.delete(i),l.size===0&&(e.outrogroups=null)}}else c-=1},!1)}if(c===0){var o=f.length===0&&r!==null;if(o){var d=r,t=d.parentNode;Ue(t),t.append(d),e.items.clear()}P(n,!o)}else i={pending:new Set(n),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(i)}function P(e,n=!0){for(var r=0;r<e.length;r++)ze(e[r],n)}var le;function tn(e,n,r,f,u,i=null){var c=e,v=new Map,o=(n&he)!==0;if(o){var d=e;c=k?L(Ee(d)):d.appendChild(q())}k&&we();var t=null,m=Ce(()=>{var s=r();return Re(s)?s:s==null?[]:J(s)}),l,h=!0;function A(){a.fallback=t,Ve(a,l,c,n,f),t!==null&&(l.length===0?(t.f&w)===0?ve(t):(t.f^=w,H(t,null,c)):pe(t,()=>{t=null}))}var N=me(()=>{l=oe(m);var s=l.length;let x=!1;if(k){var S=Te(c)===Ae;S!==(s===0)&&(c=ie(),L(c),V(!1),x=!0)}for(var g=new Set,y=Ne,C=Se(),p=0;p<s;p+=1){k&&U.nodeType===ye&&U.data===Ie&&(c=U,x=!0,V(!1));var I=l[p],R=f(I,p),_=h?null:v.get(R);_?(_.v&&fe(_.v,I),_.i&&fe(_.i,p),C&&y.unskip_effect(_.e)):(_=Xe(v,h?c:le??(le=q()),I,R,p,u,n,r),h||(_.e.f|=w),v.set(R,_)),g.add(R)}if(s===0&&i&&!t&&(h?t=G(()=>i(c)):(t=G(()=>i(le??(le=q()))),t.f|=w)),s>g.size&&xe(),k&&s>0&&L(ie()),!h)if(C){for(const[M,b]of v)g.has(M)||y.skip_effect(b.e);y.oncommit(A),y.ondiscard(()=>{})}else A();x&&V(!0),oe(m)}),a={effect:N,items:v,outrogroups:null,fallback:t};h=!1,k&&(c=U)}function O(e){for(;e!==null&&(e.f&be)===0;)e=e.next;return e}function Ve(e,n,r,f,u){var _,M,b,j,ee,ne,re,ae,te;var i=(f&Fe)!==0,c=n.length,v=e.items,o=O(e.effect.first),d,t=null,m,l=[],h=[],A,N,a,s;if(i)for(s=0;s<c;s+=1)A=n[s],N=u(A,s),a=v.get(N).e,(a.f&w)===0&&((M=(_=a.nodes)==null?void 0:_.a)==null||M.measure(),(m??(m=new Set)).add(a));for(s=0;s<c;s+=1){if(A=n[s],N=u(A,s),a=v.get(N).e,e.outrogroups!==null)for(const E of e.outrogroups)E.pending.delete(a),E.done.delete(a);if((a.f&w)!==0)if(a.f^=w,a===o)H(a,null,r);else{var x=t?t.next:o;a===e.effect.last&&(e.effect.last=a.prev),a.prev&&(a.prev.next=a.next),a.next&&(a.next.prev=a.prev),T(e,t,a),T(e,a,x),H(a,x,r),t=a,l=[],h=[],o=O(t.next);continue}if((a.f&X)!==0&&(ve(a),i&&((j=(b=a.nodes)==null?void 0:b.a)==null||j.unfix(),(m??(m=new Set)).delete(a))),a!==o){if(d!==void 0&&d.has(a)){if(l.length<h.length){var S=h[0],g;t=S.prev;var y=l[0],C=l[l.length-1];for(g=0;g<l.length;g+=1)H(l[g],S,r);for(g=0;g<h.length;g+=1)d.delete(h[g]);T(e,y.prev,C.next),T(e,t,y),T(e,C,S),o=S,t=C,s-=1,l=[],h=[]}else d.delete(a),H(a,o,r),T(e,a.prev,a.next),T(e,a,t===null?e.effect.first:t.next),T(e,t,a),t=a;continue}for(l=[],h=[];o!==null&&o!==a;)(d??(d=new Set)).add(o),h.push(o),o=O(o.next);if(o===null)continue}(a.f&w)===0&&l.push(a),t=a,o=O(a.next)}if(e.outrogroups!==null){for(const E of e.outrogroups)E.pending.size===0&&(P(J(E.done)),(ee=e.outrogroups)==null||ee.delete(E));e.outrogroups.size===0&&(e.outrogroups=null)}if(o!==null||d!==void 0){var p=[];if(d!==void 0)for(a of d)(a.f&X)===0&&p.push(a);for(;o!==null;)(o.f&X)===0&&o!==e.fallback&&p.push(o),o=O(o.next);var I=p.length;if(I>0){var R=(f&he)!==0&&c===0?r:null;if(i){for(s=0;s<I;s+=1)(re=(ne=p[s].nodes)==null?void 0:ne.a)==null||re.measure();for(s=0;s<I;s+=1)(te=(ae=p[s].nodes)==null?void 0:ae.a)==null||te.fix()}Le(e,p,R)}}i&&Me(()=>{var E,se;if(m!==void 0)for(a of m)(se=(E=a.nodes)==null?void 0:E.a)==null||se.apply()})}function Xe(e,n,r,f,u,i,c,v){var o=(c&ke)!==0?(c&De)===0?Oe(r,!1,!1):ue(r):null,d=(c&He)!==0?ue(u):null;return{v:o,i:d,e:G(()=>(i(n,o??r,d??u,v),()=>{e.delete(f)}))}}function H(e,n,r){if(e.nodes)for(var f=e.nodes.start,u=e.nodes.end,i=n&&(n.f&w)===0?n.nodes.start:r;f!==null;){var c=$e(f);if(i.before(f),f===u)return;f=c}}function T(e,n,r){n===null?e.effect.first=r:n.next=r,r===null?e.effect.last=n:r.prev=n}const Ye={success:3e3,error:5e3,info:4e3,warning:4e3},de=50;let Ge=1,W=Z([]),z=Z([]);const $=Z({count:0});function sn(){return $.count}function B(e){const n=Ge++,r={id:n,...e};W.push(r),z.unshift({...r,timestamp:Date.now()}),z.length>de&&(z.length=de),$.count++;const f=Ye[e.type];return setTimeout(()=>{Ke(n)},f),n}function Ke(e){const n=W.findIndex(r=>r.id===e);n!==-1&&W.splice(n,1)}function on(){$.count=0}function fn(){z.length=0,$.count=0}function un(e){return B({type:"success",message:e})}function cn(e){return B({type:"error",message:e})}function ln(e){return B({type:"info",message:e})}class D extends Error{constructor(r,f,u,i){super(u);F(this,"code");F(this,"status");F(this,"data");this.name="ApiError",this.status=r,this.code=f,this.data=i}}async function Pe(e){try{const n=await e.json();return{code:n.code??"UNKNOWN",message:n.message??e.statusText,data:n.data}}catch{return{code:"UNKNOWN",message:e.statusText}}}async function Q(e,n={}){const r=K(Y),f={"Content-Type":"application/json",...n.headers};r.accessToken&&(f.Authorization=`Bearer ${r.accessToken}`);const u=await fetch(e,{method:n.method??"GET",headers:f,body:n.body!==void 0?JSON.stringify(n.body):void 0});if(u.status===401&&!n._skipRefresh){if(await Y.refresh())return Q(e,{...n,_skipRefresh:!0});throw Y.logout(),new D(401,"UNAUTHORIZED","Session expired")}if(!u.ok){const i=await Pe(u);throw new D(u.status,i.code,i.message,i.data)}if(u.status!==204)return u.json()}async function We(e,n={}){const r=Be(e);return Q(r,n)}async function Je(e,n={}){let r=K(ce);if(r.loaded||(await qe(),r=K(ce)),!r.devMode||r.sidecarPort===null)throw new D(0,"NOT_DEV_MODE","Schema mutations require dev mode with sidecar");const f=`http://localhost:${r.sidecarPort}/${e}`;try{return await Q(f,n)}catch(u){throw u instanceof D&&u.status===404?new D(404,u.code,"This dashboard action is not available on the current dev sidecar yet. Restart `pnpm dev` and try again."):u}}async function Ze(e,n){try{return await e()}catch(r){const f=r instanceof D||r instanceof Error?r.message:"Unknown error";return B({type:"error",message:n?`${n}: ${f}`:f}),null}}const dn={fetch:We,schemaMutation:Je,safeFetch:Ze};export{D as A,dn as a,un as b,B as c,ln as d,tn as e,z as f,sn as g,fn as h,an as i,W as j,on as m,Ke as r,cn as t};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{b5 as z,a0 as R,a3 as B,F as q,h as T,aa as x,_ as M,a8 as rr,az as ir,b6 as fr,ad as ar,ac as tr,b7 as er,b8 as ur,b9 as sr,ba as or,g as cr,bb as lr,bc as nr,bd as C,D as V,be as vr,bf as dr,I as br,bg as gr}from"./BdTBlfLy.js";import{i as hr,a as _r,d as Ar,c as Sr,n as Tr,b as Nr}from"./DtZk82gG.js";function pr(r,f){var i=void 0,a;z(()=>{i!==(i=f())&&(a&&(R(a),a=null),i&&(a=B(()=>{q(()=>i(r))})))})}function F(r){var f,i,a="";if(typeof r=="string"||typeof r=="number")a+=r;else if(typeof r=="object")if(Array.isArray(r)){var t=r.length;for(f=0;f<t;f++)r[f]&&(i=F(r[f]))&&(a&&(a+=" "),a+=i)}else for(i in r)r[i]&&(a&&(a+=" "),a+=i);return a}function Or(){for(var r,f,i=0,a="",t=arguments.length;i<t;i++)(r=arguments[i])&&(f=F(r))&&(a&&(a+=" "),a+=f);return a}function Er(r){return typeof r=="object"?Or(r):r??""}const D=[...`
|
|
2
|
-
\r\f \v\uFEFF`];function Ir(r,f,i){var a=r==null?"":""+r;if(f&&(a=a?a+" "+f:f),i){for(var t of Object.keys(i))if(i[t])a=a?a+" "+t:t;else if(a.length)for(var e=t.length,u=0;(u=a.indexOf(t,u))>=0;){var o=u+e;(u===0||D.includes(a[u-1]))&&(o===a.length||D.includes(a[o]))?a=(u===0?"":a.substring(0,u))+a.substring(o+1):u=o}}return a===""?null:a}function K(r,f=!1){var i=f?" !important;":";",a="";for(var t of Object.keys(r)){var e=r[t];e!=null&&e!==""&&(a+=" "+t+": "+e+i)}return a}function j(r){return r[0]!=="-"||r[1]!=="-"?r.toLowerCase():r}function Lr(r,f){if(f){var i="",a,t;if(Array.isArray(f)?(a=f[0],t=f[1]):a=f,r){r=String(r).replaceAll(/\s*\/\*.*?\*\/\s*/g,"").trim();var e=!1,u=0,o=!1,n=[];a&&n.push(...Object.keys(a).map(j)),t&&n.push(...Object.keys(t).map(j));var v=0,h=-1;const p=r.length;for(var d=0;d<p;d++){var s=r[d];if(o?s==="/"&&r[d-1]==="*"&&(o=!1):e?e===s&&(e=!1):s==="/"&&r[d+1]==="*"?o=!0:s==='"'||s==="'"?e=s:s==="("?u++:s===")"&&u--,!o&&e===!1&&u===0){if(s===":"&&h===-1)h=d;else if(s===";"||d===p-1){if(h!==-1){var N=j(r.substring(v,h).trim());if(!n.includes(N)){s!==";"&&d++;var S=r.substring(v,d).trim();i+=" "+S+";"}}v=d+1,h=-1}}}}return a&&(i+=K(a)),t&&(i+=K(t,!0)),i=i.trim(),i===""?null:i}return r==null?null:String(r)}function kr(r,f,i,a,t,e){var u=r.__className;if(T||u!==i||u===void 0){var o=Ir(i,a,e);(!T||o!==r.getAttribute("class"))&&(o==null?r.removeAttribute("class"):f?r.className=o:r.setAttribute("class",o)),r.__className=i}else if(e&&t!==e)for(var n in e){var v=!!e[n];(t==null||v!==!!t[n])&&r.classList.toggle(n,v)}return e}function G(r,f={},i,a){for(var t in i){var e=i[t];f[t]!==e&&(i[t]==null?r.style.removeProperty(t):r.style.setProperty(t,e,a))}}function Cr(r,f,i,a){var t=r.__style;if(T||t!==f){var e=Lr(f,a);(!T||e!==r.getAttribute("style"))&&(e==null?r.removeAttribute("style"):r.style.cssText=e),r.__style=f}else a&&(Array.isArray(a)?(G(r,i==null?void 0:i[0],a[0]),G(r,i==null?void 0:i[1],a[1],"important")):G(r,i,a));return a}function P(r,f,i=!1){if(r.multiple){if(f==null)return;if(!ir(f))return fr();for(var a of r.options)a.selected=f.includes(k(a));return}for(a of r.options){var t=k(a);if(ar(t,f)){a.selected=!0;return}}(!i||f!==void 0)&&(r.selectedIndex=-1)}function W(r){var f=new MutationObserver(()=>{P(r,r.__value)});f.observe(r,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),rr(()=>{f.disconnect()})}function Hr(r,f,i=f){var a=new WeakSet,t=!0;x(r,"change",e=>{var u=e?"[selected]":":checked",o;if(r.multiple)o=[].map.call(r.querySelectorAll(u),k);else{var n=r.querySelector(u)??r.querySelector("option:not([disabled])");o=n&&k(n)}i(o),M!==null&&a.add(M)}),q(()=>{var e=f();if(r===document.activeElement){var u=tr??M;if(a.has(u))return}if(P(r,e,t),t&&e===void 0){var o=r.querySelector(":checked");o!==null&&(e=k(o),i(e))}r.__value=e,t=!1}),W(r)}function k(r){return"__value"in r?r.__value:r.value}const I=Symbol("class"),L=Symbol("style"),X=Symbol("is custom element"),Z=Symbol("is html"),Pr=C?"link":"LINK",wr=C?"input":"INPUT",yr=C?"option":"OPTION",Mr=C?"select":"SELECT",jr=C?"progress":"PROGRESS";function Gr(r){if(T){var f=!1,i=()=>{if(!f){if(f=!0,r.hasAttribute("value")){var a=r.value;w(r,"value",null),r.value=a}if(r.hasAttribute("checked")){var t=r.checked;w(r,"checked",null),r.checked=t}}};r.__on_r=i,br(i),gr()}}function Vr(r,f){var i=y(r);i.value===(i.value=f??void 0)||r.value===f&&(f!==0||r.nodeName!==jr)||(r.value=f??"")}function Dr(r,f){var i=y(r);i.checked!==(i.checked=f??void 0)&&(r.checked=f)}function Rr(r,f){f?r.hasAttribute("selected")||r.setAttribute("selected",""):r.removeAttribute("selected")}function w(r,f,i,a){var t=y(r);T&&(t[f]=r.getAttribute(f),f==="src"||f==="srcset"||f==="href"&&r.nodeName===Pr)||t[f]!==(t[f]=i)&&(f==="loading"&&(r[ur]=i),i==null?r.removeAttribute(f):typeof i!="string"&&J(r).includes(f)?r[f]=i:r.setAttribute(f,i))}function qr(r,f,i,a,t=!1,e=!1){if(T&&t&&r.nodeName===wr){var u=r,o=u.type==="checkbox"?"defaultChecked":"defaultValue";o in i||Gr(u)}var n=y(r),v=n[X],h=!n[Z];let d=T&&v;d&&V(!1);var s=f||{},N=r.nodeName===yr;for(var S in f)S in i||(i[S]=null);i.class?i.class=Er(i.class):(a||i[I])&&(i.class=null),i[L]&&(i.style??(i.style=null));var p=J(r);for(const c in i){let l=i[c];if(N&&c==="value"&&l==null){r.value=r.__value="",s[c]=l;continue}if(c==="class"){var E=r.namespaceURI==="http://www.w3.org/1999/xhtml";kr(r,E,l,a,f==null?void 0:f[I],i[I]),s[c]=l,s[I]=i[I];continue}if(c==="style"){Cr(r,l,f==null?void 0:f[L],i[L]),s[c]=l,s[L]=i[L];continue}var _=s[c];if(!(l===_&&!(l===void 0&&r.hasAttribute(c)))){s[c]=l;var U=c[0]+c[1];if(U!=="$$")if(U==="on"){const A={},O="$$"+c;let g=c.slice(2);var $=Nr(g);if(hr(g)&&(g=g.slice(0,-7),A.capture=!0),!$&&_){if(l!=null)continue;r.removeEventListener(g,s[O],A),s[O]=null}if($)_r(g,r,l),Ar([g]);else if(l!=null){let Q=function(m){s[c].call(this,m)};s[O]=Sr(g,r,Q,A)}}else if(c==="style")w(r,c,l);else if(c==="autofocus")vr(r,!!l);else if(!v&&(c==="__value"||c==="value"&&l!=null))r.value=r.__value=l;else if(c==="selected"&&N)Rr(r,l);else{var b=c;h||(b=Tr(b));var H=b==="defaultValue"||b==="defaultChecked";if(l==null&&!v&&!H)if(n[c]=null,b==="value"||b==="checked"){let A=r;const O=f===void 0;if(b==="value"){let g=A.defaultValue;A.removeAttribute(b),A.defaultValue=g,A.value=A.__value=O?g:null}else{let g=A.defaultChecked;A.removeAttribute(b),A.defaultChecked=g,A.checked=O?g:!1}}else r.removeAttribute(c);else H||p.includes(b)&&(v||typeof l!="string")?(r[b]=l,b in n&&(n[b]=dr)):typeof l!="function"&&w(r,b,l)}}}return d&&V(!0),s}function Kr(r,f,i=[],a=[],t=[],e,u=!1,o=!1){er(t,i,a,n=>{var v=void 0,h={},d=r.nodeName===Mr,s=!1;if(z(()=>{var S=f(...n.map(cr)),p=qr(r,v,S,e,u,o);s&&d&&"value"in S&&P(r,S.value);for(let _ of Object.getOwnPropertySymbols(h))S[_]||R(h[_]);for(let _ of Object.getOwnPropertySymbols(S)){var E=S[_];_.description===lr&&(!v||E!==v[_])&&(h[_]&&R(h[_]),h[_]=B(()=>pr(r,()=>E))),p[_]=E}v=p}),d){var N=r;q(()=>{P(N,v.value,!0),W(N)})}s=!0})}function y(r){return r.__attributes??(r.__attributes={[X]:r.nodeName.includes("-"),[Z]:r.namespaceURI===sr})}var Y=new Map;function J(r){var f=r.getAttribute("is")||r.nodeName,i=Y.get(f);if(i)return i;Y.set(f,i=[]);for(var a,t=r,e=Element.prototype;e!==t;){a=nr(t);for(var u in a)a[u].set&&i.push(u);t=or(t)}return i}export{I as C,w as a,Hr as b,Cr as c,Kr as d,Dr as e,Er as f,Vr as g,P as h,W as i,Gr as r,kr as s};
|