@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.
Files changed (131) hide show
  1. package/admin-build/_app/immutable/chunks/{DILS_-VJ.js → B3CvhH3c.js} +1 -1
  2. package/admin-build/_app/immutable/chunks/BN_-k-Ck.js +1 -0
  3. package/admin-build/_app/immutable/chunks/{Dt4vL4Df.js → BYL_uBga.js} +1 -1
  4. package/admin-build/_app/immutable/chunks/{C72lTcG0.js → Bcs4KYNp.js} +1 -1
  5. package/admin-build/_app/immutable/chunks/{B8s_s9QY.js → BkZCgsc3.js} +1 -1
  6. package/admin-build/_app/immutable/chunks/{BgDzp0i0.js → BvoGcDFV.js} +1 -1
  7. package/admin-build/_app/immutable/chunks/{BME_U9TJ.js → CCUxCptE.js} +1 -1
  8. package/admin-build/_app/immutable/chunks/CLHN9MVr.js +1 -0
  9. package/admin-build/_app/immutable/chunks/{DYaCRWMA.js → CR37B8DX.js} +1 -1
  10. package/admin-build/_app/immutable/chunks/CbfX3ELZ.js +1 -0
  11. package/admin-build/_app/immutable/chunks/CjcrXziO.js +2 -0
  12. package/admin-build/_app/immutable/chunks/CrwlCAM0.js +1 -0
  13. package/admin-build/_app/immutable/chunks/{B0HRJ657.js → DOOPbWwG.js} +1 -1
  14. package/admin-build/_app/immutable/chunks/DQVP4KC-.js +1 -0
  15. package/admin-build/_app/immutable/chunks/{Dj0QUuOf.js → DdvsFblq.js} +1 -1
  16. package/admin-build/_app/immutable/chunks/DemDWbs-.js +128 -0
  17. package/admin-build/_app/immutable/chunks/{XQM1k9PM.js → DmDTovpg.js} +1 -1
  18. package/admin-build/_app/immutable/chunks/{fYEKMQ-Z.js → Ff90owjx.js} +1 -1
  19. package/admin-build/_app/immutable/chunks/{5RQRbp5q.js → LL3ulaxa.js} +1 -1
  20. package/admin-build/_app/immutable/chunks/{DBsVqhuh.js → Q3vAxeY-.js} +1 -1
  21. package/admin-build/_app/immutable/chunks/{D__dwMuW.js → SQVAC3Cv.js} +1 -1
  22. package/admin-build/_app/immutable/chunks/{Z41NK6i6.js → bguI1TeA.js} +1 -1
  23. package/admin-build/_app/immutable/chunks/{_teD5ji5.js → nlAMTi52.js} +1 -1
  24. package/admin-build/_app/immutable/chunks/{BjWZuf8W.js → qBm6xof8.js} +1 -1
  25. package/admin-build/_app/immutable/entry/{app.C8ylfBe6.js → app.CP83Ni80.js} +2 -2
  26. package/admin-build/_app/immutable/entry/start.DY6YakU0.js +1 -0
  27. package/admin-build/_app/immutable/nodes/{0.CJJ6HZbp.js → 0.DiRq7puO.js} +1 -1
  28. package/admin-build/_app/immutable/nodes/1.BFeyKLGT.js +1 -0
  29. package/admin-build/_app/immutable/nodes/10.zcee7hJx.js +1 -0
  30. package/admin-build/_app/immutable/nodes/11.BW7wLs2Y.js +1 -0
  31. package/admin-build/_app/immutable/nodes/12.CxJRlYSd.js +1 -0
  32. package/admin-build/_app/immutable/nodes/13.pp0F_5hn.js +110 -0
  33. package/admin-build/_app/immutable/nodes/14.t3AfGiGo.js +3 -0
  34. package/admin-build/_app/immutable/nodes/15.B3agc7NX.js +1 -0
  35. package/admin-build/_app/immutable/nodes/{16.D0xkPUBW.js → 16.C4uG2-i8.js} +1 -1
  36. package/admin-build/_app/immutable/nodes/{17.CebNqPeh.js → 17.CwGxi1Bn.js} +1 -1
  37. package/admin-build/_app/immutable/nodes/18.CrQyN_gU.js +1 -0
  38. package/admin-build/_app/immutable/nodes/19.NEPUOXl7.js +2 -0
  39. package/admin-build/_app/immutable/nodes/{20.DYb-q3W8.js → 20.DGHO8ipr.js} +1 -1
  40. package/admin-build/_app/immutable/nodes/21.UVKBDvp4.js +1 -0
  41. package/admin-build/_app/immutable/nodes/22.Dri5It7a.js +1 -0
  42. package/admin-build/_app/immutable/nodes/{23.BLgq21om.js → 23.BPQP_Zte.js} +2 -2
  43. package/admin-build/_app/immutable/nodes/24.D580FdSS.js +2 -0
  44. package/admin-build/_app/immutable/nodes/25.BMNPOZwF.js +2 -0
  45. package/admin-build/_app/immutable/nodes/26.XcpEcbiz.js +1 -0
  46. package/admin-build/_app/immutable/nodes/27.C1zHHcYv.js +1 -0
  47. package/admin-build/_app/immutable/nodes/28.CuKzzrY8.js +1 -0
  48. package/admin-build/_app/immutable/nodes/29.nLpBMXnM.js +1 -0
  49. package/admin-build/_app/immutable/nodes/{3.z8ut3jS-.js → 3.5G_aseoL.js} +1 -1
  50. package/admin-build/_app/immutable/nodes/30.CQC4nLoU.js +1 -0
  51. package/admin-build/_app/immutable/nodes/31.Bet8kxOK.js +1 -0
  52. package/admin-build/_app/immutable/nodes/4.nmJDYJpC.js +1 -0
  53. package/admin-build/_app/immutable/nodes/5.CnbYLG4E.js +1 -0
  54. package/admin-build/_app/immutable/nodes/6.KA01b-3y.js +1 -0
  55. package/admin-build/_app/immutable/nodes/7.CP9fkn1L.js +1 -0
  56. package/admin-build/_app/immutable/nodes/8.BTzDb---.js +1 -0
  57. package/admin-build/_app/immutable/nodes/9.DkNJg_J6.js +1 -0
  58. package/admin-build/_app/version.json +1 -1
  59. package/admin-build/index.html +7 -7
  60. package/package.json +3 -3
  61. package/src/__tests__/database-do-route-validation.test.ts +10 -7
  62. package/src/__tests__/meta-route-registration.test.ts +20 -15
  63. package/src/__tests__/push-handlers.test.ts +1 -1
  64. package/src/__tests__/room-auth-state-loss.test.ts +122 -0
  65. package/src/__tests__/room-handler-context.test.ts +4 -4
  66. package/src/__tests__/room-rate-limit-scopes.test.ts +38 -0
  67. package/src/__tests__/room-runtime-routing.test.ts +23 -0
  68. package/src/__tests__/route-parser.test.ts +6 -0
  69. package/src/__tests__/runtime-startup.test.ts +49 -0
  70. package/src/__tests__/schema.test.ts +15 -6
  71. package/src/durable-objects/database-do.ts +21 -1
  72. package/src/durable-objects/database-live-do.ts +15 -0
  73. package/src/durable-objects/room-runtime-base.ts +436 -169
  74. package/src/durable-objects/rooms-do.ts +63 -25
  75. package/src/index.ts +340 -280
  76. package/src/lib/d1-handler.ts +32 -17
  77. package/src/lib/postgres-handler.ts +24 -12
  78. package/src/lib/route-parser.ts +3 -0
  79. package/src/lib/runtime-startup.ts +53 -0
  80. package/src/lib/schemas.ts +12 -2
  81. package/src/middleware/captcha-verify.ts +16 -3
  82. package/src/middleware/error-handler.ts +1 -1
  83. package/src/middleware/rules.ts +28 -9
  84. package/src/routes/admin-auth.ts +3 -3
  85. package/src/routes/admin.ts +13 -8
  86. package/src/routes/analytics-api.ts +3 -3
  87. package/src/routes/auth.ts +1 -1
  88. package/src/routes/backup.ts +1 -1
  89. package/src/routes/d1.ts +14 -7
  90. package/src/routes/database-live.ts +13 -6
  91. package/src/routes/kv.ts +21 -10
  92. package/src/routes/oauth.ts +1 -1
  93. package/src/routes/push.ts +119 -77
  94. package/src/routes/room.ts +215 -7
  95. package/src/routes/schema-endpoint.ts +2 -2
  96. package/src/routes/sql.ts +10 -6
  97. package/src/routes/storage.ts +4 -2
  98. package/src/routes/vectorize.ts +16 -4
  99. package/admin-build/_app/immutable/chunks/BYI6CUvd.js +0 -1
  100. package/admin-build/_app/immutable/chunks/C6lpZLE2.js +0 -1
  101. package/admin-build/_app/immutable/chunks/CoI6jjbg.js +0 -2
  102. package/admin-build/_app/immutable/chunks/D5GswVnI.js +0 -128
  103. package/admin-build/_app/immutable/chunks/Dj-E9-FO.js +0 -1
  104. package/admin-build/_app/immutable/chunks/g_-Kpxu3.js +0 -1
  105. package/admin-build/_app/immutable/chunks/wCNueVYy.js +0 -1
  106. package/admin-build/_app/immutable/entry/start.CtsqDyfj.js +0 -1
  107. package/admin-build/_app/immutable/nodes/1.B4sI5cB4.js +0 -1
  108. package/admin-build/_app/immutable/nodes/10.D6hvCer6.js +0 -1
  109. package/admin-build/_app/immutable/nodes/11.Dx7b8aQ5.js +0 -1
  110. package/admin-build/_app/immutable/nodes/12.Bqmy5KIF.js +0 -1
  111. package/admin-build/_app/immutable/nodes/13.CC6KpXgS.js +0 -110
  112. package/admin-build/_app/immutable/nodes/14.yCo1Ix8E.js +0 -3
  113. package/admin-build/_app/immutable/nodes/15.co0UfPlh.js +0 -1
  114. package/admin-build/_app/immutable/nodes/18.JUoLOZxh.js +0 -1
  115. package/admin-build/_app/immutable/nodes/19.ND8kmQJe.js +0 -2
  116. package/admin-build/_app/immutable/nodes/21.cz3IN9Cc.js +0 -1
  117. package/admin-build/_app/immutable/nodes/22.UOzm8WYV.js +0 -1
  118. package/admin-build/_app/immutable/nodes/24.DN9usmUs.js +0 -2
  119. package/admin-build/_app/immutable/nodes/25.BddRfAyE.js +0 -2
  120. package/admin-build/_app/immutable/nodes/26.Dl6XHIeT.js +0 -1
  121. package/admin-build/_app/immutable/nodes/27.D0iNwALG.js +0 -1
  122. package/admin-build/_app/immutable/nodes/28.9dKQmdGi.js +0 -1
  123. package/admin-build/_app/immutable/nodes/29.wXzfJUXp.js +0 -1
  124. package/admin-build/_app/immutable/nodes/30.BtZETNsL.js +0 -1
  125. package/admin-build/_app/immutable/nodes/31.CYonj2Jh.js +0 -1
  126. package/admin-build/_app/immutable/nodes/4.COtDPQ9b.js +0 -1
  127. package/admin-build/_app/immutable/nodes/5.CTRCeIhp.js +0 -1
  128. package/admin-build/_app/immutable/nodes/6.ChHi3QkR.js +0 -1
  129. package/admin-build/_app/immutable/nodes/7.CCMtr6Ac.js +0 -1
  130. package/admin-build/_app/immutable/nodes/8.DpWJ-X_-.js +0 -1
  131. package/admin-build/_app/immutable/nodes/9.DOkvfmir.js +0 -1
@@ -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 query parameters required' }, 400);
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
- const warningKey = `${namespace}:metadata`;
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, 'Unauthorized. Invalid Service Key.');
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: 'Invalid JSON body' }, 400);
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 is required' }, 400);
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' }, 400);
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 is required' }, 400);
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: 'Service Key required to execute SQL' }, 403);
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: 'Unauthorized. Invalid Service Key.' }, 401);
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 {
@@ -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, 'Unauthorized. Invalid Service Key.', undefined, 'unauthenticated');
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 ? e.message : 'Unknown error.';
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
  }
@@ -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: 'Invalid JSON body' }, 400);
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: 'Service Key required to access Vectorize' }, 403);
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: 'Unauthorized. Invalid Service Key.' }, 401);
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
- console.warn(`⚠️ Vectorize binding '${bindingName}' for '${nameParam}' not available. Running locally or binding not configured.`);
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};