@syncular/server-hono 0.0.6-55 → 0.0.6-66

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.
@@ -14,7 +14,7 @@
14
14
  * - POST /compact - Trigger compaction
15
15
  * - DELETE /clients/:id - Evict client
16
16
  */
17
- import type { SyncCoreDb } from '@syncular/server';
17
+ import type { SyncCoreDb, SyncServerAuth } from '@syncular/server';
18
18
  import type { Context } from 'hono';
19
19
  import { Hono } from 'hono';
20
20
  import type { ConsoleAuthResult, ConsoleEventEmitter, CreateConsoleRoutesOptions } from './types';
@@ -24,7 +24,7 @@ import type { ConsoleAuthResult, ConsoleEventEmitter, CreateConsoleRoutesOptions
24
24
  export declare function createConsoleEventEmitter(options?: {
25
25
  maxHistory?: number;
26
26
  }): ConsoleEventEmitter;
27
- export declare function createConsoleRoutes<DB extends SyncCoreDb>(options: CreateConsoleRoutesOptions<DB>): Hono;
27
+ export declare function createConsoleRoutes<DB extends SyncCoreDb, Auth extends SyncServerAuth>(options: CreateConsoleRoutesOptions<DB, Auth>): Hono;
28
28
  /**
29
29
  * Creates a simple token-based authenticator for local development.
30
30
  * The token can be set via SYNC_CONSOLE_TOKEN env var or passed directly.
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/console/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAqE5B,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EAEnB,0BAA0B,EAC3B,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,mBAAmB,CA0DtB;AAmOD,wBAAgB,mBAAmB,CAAC,EAAE,SAAS,UAAU,EACvD,OAAO,EAAE,0BAA0B,CAAC,EAAE,CAAC,GACtC,IAAI,CA2gGN;AA6BD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,CAAC,EAAE,MAAM,GACb,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA0BnD"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/console/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAQnE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAqE5B,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EAEnB,0BAA0B,EAC3B,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,mBAAmB,CA0DtB;AAmOD,wBAAgB,mBAAmB,CACjC,EAAE,SAAS,UAAU,EACrB,IAAI,SAAS,cAAc,EAC3B,OAAO,EAAE,0BAA0B,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,IAAI,CAqhGrD;AA6BD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,CAAC,EAAE,MAAM,GACb,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA0BnD"}
@@ -2560,115 +2560,122 @@ export function createConsoleRoutes(options) {
2560
2560
  // -----------------------------------------------------------------------
2561
2561
  // Storage endpoints
2562
2562
  // -----------------------------------------------------------------------
2563
- if (options.blobBucket) {
2564
- const bucket = options.blobBucket;
2565
- routes.get('/storage', describeRoute({
2566
- tags: ['console'],
2567
- summary: 'List storage items',
2568
- responses: {
2569
- 200: {
2570
- description: 'Paginated list of storage items',
2571
- content: {
2572
- 'application/json': {
2573
- schema: resolver(ConsoleBlobListResponseSchema),
2574
- },
2563
+ const bucket = options.blobBucket;
2564
+ routes.get('/storage', describeRoute({
2565
+ tags: ['console'],
2566
+ summary: 'List storage items',
2567
+ responses: {
2568
+ 200: {
2569
+ description: 'Paginated list of storage items',
2570
+ content: {
2571
+ 'application/json': {
2572
+ schema: resolver(ConsoleBlobListResponseSchema),
2575
2573
  },
2576
2574
  },
2577
- 401: {
2578
- description: 'Unauthenticated',
2579
- content: {
2580
- 'application/json': { schema: resolver(ErrorResponseSchema) },
2581
- },
2575
+ },
2576
+ 401: {
2577
+ description: 'Unauthenticated',
2578
+ content: {
2579
+ 'application/json': { schema: resolver(ErrorResponseSchema) },
2582
2580
  },
2583
2581
  },
2584
- }), zValidator('query', ConsoleBlobListQuerySchema), async (c) => {
2585
- const auth = await requireAuth(c);
2586
- if (!auth)
2587
- return c.json({ error: 'UNAUTHENTICATED' }, 401);
2588
- const { prefix, cursor, limit } = c.req.valid('query');
2589
- const listed = await bucket.list({
2590
- prefix: prefix || undefined,
2591
- cursor: cursor || undefined,
2592
- limit,
2593
- });
2594
- return c.json({
2595
- items: listed.objects.map((obj) => ({
2596
- key: obj.key,
2597
- size: obj.size,
2598
- uploaded: obj.uploaded.toISOString(),
2599
- httpMetadata: obj.httpMetadata?.contentType
2600
- ? { contentType: obj.httpMetadata.contentType }
2601
- : undefined,
2602
- })),
2603
- truncated: listed.truncated,
2604
- cursor: listed.cursor ?? null,
2605
- }, 200);
2582
+ },
2583
+ }), zValidator('query', ConsoleBlobListQuerySchema), async (c) => {
2584
+ const auth = await requireAuth(c);
2585
+ if (!auth)
2586
+ return c.json({ error: 'UNAUTHENTICATED' }, 401);
2587
+ if (!bucket) {
2588
+ return c.json({ error: 'BLOB_STORAGE_NOT_CONFIGURED' }, 501);
2589
+ }
2590
+ const { prefix, cursor, limit } = c.req.valid('query');
2591
+ const listed = await bucket.list({
2592
+ prefix: prefix || undefined,
2593
+ cursor: cursor || undefined,
2594
+ limit,
2606
2595
  });
2607
- routes.get('/storage/:key{.+}/download', describeRoute({
2608
- tags: ['console'],
2609
- summary: 'Download a storage item',
2610
- responses: {
2611
- 200: { description: 'Storage item contents' },
2612
- 401: {
2613
- description: 'Unauthenticated',
2614
- content: {
2615
- 'application/json': { schema: resolver(ErrorResponseSchema) },
2616
- },
2596
+ return c.json({
2597
+ items: listed.objects.map((obj) => ({
2598
+ key: obj.key,
2599
+ size: obj.size,
2600
+ uploaded: obj.uploaded.toISOString(),
2601
+ httpMetadata: obj.httpMetadata?.contentType
2602
+ ? { contentType: obj.httpMetadata.contentType }
2603
+ : undefined,
2604
+ })),
2605
+ truncated: listed.truncated,
2606
+ cursor: listed.cursor ?? null,
2607
+ }, 200);
2608
+ });
2609
+ routes.get('/storage/:key{.+}/download', describeRoute({
2610
+ tags: ['console'],
2611
+ summary: 'Download a storage item',
2612
+ responses: {
2613
+ 200: { description: 'Storage item contents' },
2614
+ 401: {
2615
+ description: 'Unauthenticated',
2616
+ content: {
2617
+ 'application/json': { schema: resolver(ErrorResponseSchema) },
2617
2618
  },
2618
- 404: {
2619
- description: 'Blob not found',
2620
- content: {
2621
- 'application/json': { schema: resolver(ErrorResponseSchema) },
2622
- },
2619
+ },
2620
+ 404: {
2621
+ description: 'Blob not found',
2622
+ content: {
2623
+ 'application/json': { schema: resolver(ErrorResponseSchema) },
2623
2624
  },
2624
2625
  },
2625
- }), async (c) => {
2626
- const auth = await requireAuth(c);
2627
- if (!auth)
2628
- return c.json({ error: 'UNAUTHENTICATED' }, 401);
2629
- const key = decodeURIComponent(c.req.param('key'));
2630
- const object = await bucket.get(key);
2631
- if (!object) {
2632
- return c.json({ error: 'BLOB_NOT_FOUND' }, 404);
2633
- }
2634
- const headers = new Headers();
2635
- headers.set('Content-Length', String(object.size));
2636
- headers.set('Content-Type', object.httpMetadata?.contentType ?? 'application/octet-stream');
2637
- const filename = key.split('/').pop() || key;
2638
- headers.set('Content-Disposition', `attachment; filename="${filename.replace(/"/g, '\\"')}"`);
2639
- return new Response(object.body, {
2640
- status: 200,
2641
- headers,
2642
- });
2626
+ },
2627
+ }), async (c) => {
2628
+ const auth = await requireAuth(c);
2629
+ if (!auth)
2630
+ return c.json({ error: 'UNAUTHENTICATED' }, 401);
2631
+ if (!bucket) {
2632
+ return c.json({ error: 'BLOB_STORAGE_NOT_CONFIGURED' }, 501);
2633
+ }
2634
+ const key = decodeURIComponent(c.req.param('key'));
2635
+ const object = await bucket.get(key);
2636
+ if (!object) {
2637
+ return c.json({ error: 'BLOB_NOT_FOUND' }, 404);
2638
+ }
2639
+ const headers = new Headers();
2640
+ headers.set('Content-Length', String(object.size));
2641
+ headers.set('Content-Type', object.httpMetadata?.contentType ?? 'application/octet-stream');
2642
+ const filename = key.split('/').pop() || key;
2643
+ headers.set('Content-Disposition', `attachment; filename="${filename.replace(/"/g, '\\"')}"`);
2644
+ return new Response(object.body, {
2645
+ status: 200,
2646
+ headers,
2643
2647
  });
2644
- routes.delete('/storage/:key{.+}', describeRoute({
2645
- tags: ['console'],
2646
- summary: 'Delete a storage item',
2647
- responses: {
2648
- 200: {
2649
- description: 'Storage item deleted',
2650
- content: {
2651
- 'application/json': {
2652
- schema: resolver(ConsoleBlobDeleteResponseSchema),
2653
- },
2648
+ });
2649
+ routes.delete('/storage/:key{.+}', describeRoute({
2650
+ tags: ['console'],
2651
+ summary: 'Delete a storage item',
2652
+ responses: {
2653
+ 200: {
2654
+ description: 'Storage item deleted',
2655
+ content: {
2656
+ 'application/json': {
2657
+ schema: resolver(ConsoleBlobDeleteResponseSchema),
2654
2658
  },
2655
2659
  },
2656
- 401: {
2657
- description: 'Unauthenticated',
2658
- content: {
2659
- 'application/json': { schema: resolver(ErrorResponseSchema) },
2660
- },
2660
+ },
2661
+ 401: {
2662
+ description: 'Unauthenticated',
2663
+ content: {
2664
+ 'application/json': { schema: resolver(ErrorResponseSchema) },
2661
2665
  },
2662
2666
  },
2663
- }), async (c) => {
2664
- const auth = await requireAuth(c);
2665
- if (!auth)
2666
- return c.json({ error: 'UNAUTHENTICATED' }, 401);
2667
- const key = decodeURIComponent(c.req.param('key'));
2668
- await bucket.delete(key);
2669
- return c.json({ deleted: true }, 200);
2670
- });
2671
- }
2667
+ },
2668
+ }), async (c) => {
2669
+ const auth = await requireAuth(c);
2670
+ if (!auth)
2671
+ return c.json({ error: 'UNAUTHENTICATED' }, 401);
2672
+ if (!bucket) {
2673
+ return c.json({ error: 'BLOB_STORAGE_NOT_CONFIGURED' }, 501);
2674
+ }
2675
+ const key = decodeURIComponent(c.req.param('key'));
2676
+ await bucket.delete(key);
2677
+ return c.json({ deleted: true }, 200);
2678
+ });
2672
2679
  return routes;
2673
2680
  }
2674
2681
  // ===========================================================================