@dickpy/dsh-imagegen 1.0.6 → 1.0.9

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/src/routes.ts CHANGED
@@ -11,8 +11,9 @@ import type { WebRoute } from '@deepseek-ai/dsh-host-webserver'
11
11
  import { SettingsConflictError, settingsNamespace, type SettingsDescriptor } from '@deepseek-ai/dsh-settings'
12
12
  import { generateImage, type UpstreamConfig } from './engine.ts'
13
13
  import { appendHistory, clearHistory, listHistory, readHistoryImage, removeHistory } from './history-store.ts'
14
+ import { listTemplates, readTemplateImage, refreshTemplates } from './templates-store.ts'
14
15
  import { checkForUpdate, CURRENT_VERSION, installUpdate } from './updater.ts'
15
- import { GENERATE_API, HISTORY_API, IMAGEGEN_SETTINGS_NAMESPACE, SETTINGS_API, UPDATE_API, type GeneratedImage, type GenerateRequest, type HistoryEntry, type HistoryEntryInput } from './protocol.ts'
16
+ import { GENERATE_API, HISTORY_API, IMAGEGEN_SETTINGS_NAMESPACE, SETTINGS_API, TEMPLATES_API, UPDATE_API, type GeneratedImage, type GenerateRequest, type HistoryEntry, type HistoryEntryInput, type TemplateListResult, type TemplateRefreshResult } from './protocol.ts'
16
17
 
17
18
  /** Cap on JSON request bodies (settings ops and generate payloads are small). */
18
19
  const MAX_JSON_BODY_BYTES = 24 * 1024 * 1024
@@ -41,6 +42,12 @@ export interface ImageGenRoutesDeps {
41
42
  clear: () => Promise<HistoryEntry[]>
42
43
  readImage: (file: string) => Promise<{ data: Buffer; mime: string } | undefined>
43
44
  }
45
+ /** Overrideable template-library backend, primarily for host integration tests. */
46
+ templates?: {
47
+ list: () => Promise<TemplateListResult>
48
+ refresh: () => Promise<TemplateRefreshResult>
49
+ readImage: (file: string) => Promise<{ data: Buffer; mime: string } | undefined>
50
+ }
44
51
  }
45
52
 
46
53
  /** Loopback literal check plus browser same-origin markers (mirrors dsh-ssh). */
@@ -183,6 +190,11 @@ export function makeRoutes(deps: ImageGenRoutesDeps): WebRoute[] {
183
190
  clear: clearHistory,
184
191
  readImage: readHistoryImage,
185
192
  }
193
+ const templates = deps.templates ?? {
194
+ list: listTemplates,
195
+ refresh: refreshTemplates,
196
+ readImage: readTemplateImage,
197
+ }
186
198
  const guard = (req: IncomingMessage, res: ServerResponse, method: string): boolean => {
187
199
  if (!isLoopbackRequest(req)) {
188
200
  writeJson(res, 403, { error: 'forbidden: loopback-only' })
@@ -442,5 +454,65 @@ export function makeRoutes(deps: ImageGenRoutesDeps): WebRoute[] {
442
454
  res.end(found.data)
443
455
  },
444
456
  },
457
+ // --------------------------------------------------- templates list
458
+ {
459
+ kind: 'exact',
460
+ path: TEMPLATES_API.list,
461
+ handler: async (req, res) => {
462
+ if (!guard(req, res, 'POST')) return
463
+ try {
464
+ const result = await templates.list()
465
+ writeJson(res, 200, { ok: true, ...result })
466
+ } catch (error) {
467
+ writeJson(res, 200, { ok: false, code: 'templates-failed', message: messageOf(error) })
468
+ }
469
+ },
470
+ },
471
+ // ------------------------------------------------- templates refresh
472
+ {
473
+ kind: 'exact',
474
+ path: TEMPLATES_API.refresh,
475
+ handler: async (req, res) => {
476
+ if (!guard(req, res, 'POST')) return
477
+ try {
478
+ const result = await templates.refresh()
479
+ writeJson(res, 200, { ok: true, ...result })
480
+ } catch (error) {
481
+ writeJson(res, 200, { ok: false, code: 'templates-refresh-failed', message: messageOf(error) })
482
+ }
483
+ },
484
+ },
485
+ // -------------------------------------- templates image (prefix, proxied)
486
+ {
487
+ kind: 'prefix',
488
+ path: TEMPLATES_API.image,
489
+ handler: async (req, res) => {
490
+ if (!isLoopbackRequest(req)) {
491
+ writeJson(res, 403, { error: 'forbidden: loopback-only' })
492
+ return
493
+ }
494
+ if (req.method !== 'GET') {
495
+ writeJson(res, 405, { error: `method not allowed: ${req.method}` })
496
+ return
497
+ }
498
+ const file = imageFileFrom(req.url, TEMPLATES_API.image)
499
+ if (file === undefined) {
500
+ writeJson(res, 404, { error: 'not found' })
501
+ return
502
+ }
503
+ const found = await templates.readImage(file)
504
+ if (found === undefined) {
505
+ writeJson(res, 404, { error: 'not found' })
506
+ return
507
+ }
508
+ res.writeHead(200, {
509
+ 'content-type': found.mime,
510
+ 'content-length': found.data.length,
511
+ // Cached on disk by the host; reference images are immutable per name.
512
+ 'cache-control': 'private, max-age=86400',
513
+ })
514
+ res.end(found.data)
515
+ },
516
+ },
445
517
  ]
446
518
  }