@zlooks.cn/images-server 1.0.1

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 (141) hide show
  1. package/dist/assets/provider.d.ts +3 -0
  2. package/dist/assets/provider.d.ts.map +1 -0
  3. package/dist/assets/provider.js +6 -0
  4. package/dist/assets/provider.js.map +1 -0
  5. package/dist/assets/read-image-asset.d.ts +5 -0
  6. package/dist/assets/read-image-asset.d.ts.map +1 -0
  7. package/dist/assets/read-image-asset.js +88 -0
  8. package/dist/assets/read-image-asset.js.map +1 -0
  9. package/dist/assets/response-policy.d.ts +6 -0
  10. package/dist/assets/response-policy.d.ts.map +1 -0
  11. package/dist/assets/response-policy.js +49 -0
  12. package/dist/assets/response-policy.js.map +1 -0
  13. package/dist/caches/public-image-cache.d.ts +18 -0
  14. package/dist/caches/public-image-cache.d.ts.map +1 -0
  15. package/dist/caches/public-image-cache.js +58 -0
  16. package/dist/caches/public-image-cache.js.map +1 -0
  17. package/dist/command/index.d.ts +3 -0
  18. package/dist/command/index.d.ts.map +1 -0
  19. package/dist/command/index.js +23 -0
  20. package/dist/command/index.js.map +1 -0
  21. package/dist/domain/image-error.d.ts +5 -0
  22. package/dist/domain/image-error.d.ts.map +1 -0
  23. package/dist/domain/image-error.js +9 -0
  24. package/dist/domain/image-error.js.map +1 -0
  25. package/dist/domain/list-cursor.d.ts +10 -0
  26. package/dist/domain/list-cursor.d.ts.map +1 -0
  27. package/dist/domain/list-cursor.js +31 -0
  28. package/dist/domain/list-cursor.js.map +1 -0
  29. package/dist/domain/output-schema.d.ts +63 -0
  30. package/dist/domain/output-schema.d.ts.map +1 -0
  31. package/dist/domain/output-schema.js +25 -0
  32. package/dist/domain/output-schema.js.map +1 -0
  33. package/dist/domain/schema.d.ts +69 -0
  34. package/dist/domain/schema.d.ts.map +1 -0
  35. package/dist/domain/schema.js +44 -0
  36. package/dist/domain/schema.js.map +1 -0
  37. package/dist/identity.d.ts +3 -0
  38. package/dist/identity.d.ts.map +1 -0
  39. package/dist/identity.js +3 -0
  40. package/dist/identity.js.map +1 -0
  41. package/dist/mcp/provider.d.ts +2 -0
  42. package/dist/mcp/provider.d.ts.map +1 -0
  43. package/dist/mcp/provider.js +96 -0
  44. package/dist/mcp/provider.js.map +1 -0
  45. package/dist/messages/public-asset/read.msg.d.ts +3 -0
  46. package/dist/messages/public-asset/read.msg.d.ts.map +1 -0
  47. package/dist/messages/public-asset/read.msg.js +10 -0
  48. package/dist/messages/public-asset/read.msg.js.map +1 -0
  49. package/dist/migrations/index.d.ts +3 -0
  50. package/dist/migrations/index.d.ts.map +1 -0
  51. package/dist/migrations/index.js +3 -0
  52. package/dist/migrations/index.js.map +1 -0
  53. package/dist/models/delete-image.model.d.ts +21 -0
  54. package/dist/models/delete-image.model.d.ts.map +1 -0
  55. package/dist/models/delete-image.model.js +36 -0
  56. package/dist/models/delete-image.model.js.map +1 -0
  57. package/dist/models/list-image.model.d.ts +21 -0
  58. package/dist/models/list-image.model.d.ts.map +1 -0
  59. package/dist/models/list-image.model.js +15 -0
  60. package/dist/models/list-image.model.js.map +1 -0
  61. package/dist/models/read-image.model.d.ts +20 -0
  62. package/dist/models/read-image.model.d.ts.map +1 -0
  63. package/dist/models/read-image.model.js +15 -0
  64. package/dist/models/read-image.model.js.map +1 -0
  65. package/dist/models/upload-image.model.d.ts +22 -0
  66. package/dist/models/upload-image.model.d.ts.map +1 -0
  67. package/dist/models/upload-image.model.js +52 -0
  68. package/dist/models/upload-image.model.js.map +1 -0
  69. package/dist/persistence/entities.d.ts +22 -0
  70. package/dist/persistence/entities.d.ts.map +1 -0
  71. package/dist/persistence/entities.js +20 -0
  72. package/dist/persistence/entities.js.map +1 -0
  73. package/dist/persistence/image-query.d.ts +5 -0
  74. package/dist/persistence/image-query.d.ts.map +1 -0
  75. package/dist/persistence/image-query.js +44 -0
  76. package/dist/persistence/image-query.js.map +1 -0
  77. package/dist/persistence/image-store.d.ts +30 -0
  78. package/dist/persistence/image-store.d.ts.map +1 -0
  79. package/dist/persistence/image-store.js +63 -0
  80. package/dist/persistence/image-store.js.map +1 -0
  81. package/dist/presentation/image-projection.d.ts +24 -0
  82. package/dist/presentation/image-projection.d.ts.map +1 -0
  83. package/dist/presentation/image-projection.js +19 -0
  84. package/dist/presentation/image-projection.js.map +1 -0
  85. package/dist/runtime/recover-images.d.ts +5 -0
  86. package/dist/runtime/recover-images.d.ts.map +1 -0
  87. package/dist/runtime/recover-images.js +21 -0
  88. package/dist/runtime/recover-images.js.map +1 -0
  89. package/dist/services/application.service.d.ts +4 -0
  90. package/dist/services/application.service.d.ts.map +1 -0
  91. package/dist/services/application.service.js +22 -0
  92. package/dist/services/application.service.js.map +1 -0
  93. package/dist/services/config.service.d.ts +25 -0
  94. package/dist/services/config.service.d.ts.map +1 -0
  95. package/dist/services/config.service.js +19 -0
  96. package/dist/services/config.service.js.map +1 -0
  97. package/dist/services/database.service.d.ts +3 -0
  98. package/dist/services/database.service.d.ts.map +1 -0
  99. package/dist/services/database.service.js +23 -0
  100. package/dist/services/database.service.js.map +1 -0
  101. package/dist/services/images-runtime.service.d.ts +9 -0
  102. package/dist/services/images-runtime.service.d.ts.map +1 -0
  103. package/dist/services/images-runtime.service.js +16 -0
  104. package/dist/services/images-runtime.service.js.map +1 -0
  105. package/dist/services/images.boot.d.ts +3 -0
  106. package/dist/services/images.boot.d.ts.map +1 -0
  107. package/dist/services/images.boot.js +8 -0
  108. package/dist/services/images.boot.js.map +1 -0
  109. package/dist/services/logger.service.d.ts +4 -0
  110. package/dist/services/logger.service.d.ts.map +1 -0
  111. package/dist/services/logger.service.js +8 -0
  112. package/dist/services/logger.service.js.map +1 -0
  113. package/dist/services/mcp-provider.service.d.ts +3 -0
  114. package/dist/services/mcp-provider.service.d.ts.map +1 -0
  115. package/dist/services/mcp-provider.service.js +15 -0
  116. package/dist/services/mcp-provider.service.js.map +1 -0
  117. package/dist/services/public-assets.service.d.ts +4 -0
  118. package/dist/services/public-assets.service.d.ts.map +1 -0
  119. package/dist/services/public-assets.service.js +15 -0
  120. package/dist/services/public-assets.service.js.map +1 -0
  121. package/dist/services/redis.service.d.ts +3 -0
  122. package/dist/services/redis.service.d.ts.map +1 -0
  123. package/dist/services/redis.service.js +35 -0
  124. package/dist/services/redis.service.js.map +1 -0
  125. package/dist/storage/image-path.d.ts +3 -0
  126. package/dist/storage/image-path.d.ts.map +1 -0
  127. package/dist/storage/image-path.js +17 -0
  128. package/dist/storage/image-path.js.map +1 -0
  129. package/dist/storage/inspect-image.d.ts +9 -0
  130. package/dist/storage/inspect-image.d.ts.map +1 -0
  131. package/dist/storage/inspect-image.js +36 -0
  132. package/dist/storage/inspect-image.js.map +1 -0
  133. package/dist/storage/local-storage.d.ts +10 -0
  134. package/dist/storage/local-storage.d.ts.map +1 -0
  135. package/dist/storage/local-storage.js +65 -0
  136. package/dist/storage/local-storage.js.map +1 -0
  137. package/dist/storage/read-upload-bytes.d.ts +3 -0
  138. package/dist/storage/read-upload-bytes.d.ts.map +1 -0
  139. package/dist/storage/read-upload-bytes.js +11 -0
  140. package/dist/storage/read-upload-bytes.js.map +1 -0
  141. package/package.json +69 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-query.js","sourceRoot":"","sources":["../../src/persistence/image-query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { Redis } from 'ioredis';
2
+ import { type DataSource } from 'typeorm';
3
+ import type { ListImageInput } from '../domain/schema.js';
4
+ import { type ImageRow } from './entities.js';
5
+ export declare class ImageStore {
6
+ #private;
7
+ constructor(database: DataSource, redis: Redis, cachePrefix: string);
8
+ reserve(createdBy: string, key: string, hash: string, filename: string | null): Promise<{
9
+ row: ImageRow;
10
+ created: boolean;
11
+ }>;
12
+ read(id: string): Promise<ImageRow>;
13
+ readAsset(id: string, signal: AbortSignal): Promise<{
14
+ extension: "avif" | "gif" | "jpg" | "png" | "webp";
15
+ relativePath: string;
16
+ byteSize: number;
17
+ mediaType: "image/avif" | "image/gif" | "image/jpeg" | "image/png" | "image/webp";
18
+ sha256: string;
19
+ modifiedAt: number;
20
+ } | undefined>;
21
+ list(query: ListImageInput): Promise<{
22
+ items: ImageRow[];
23
+ hasMore: boolean;
24
+ nextCursor: string | null;
25
+ }>;
26
+ transition(id: string, expected: ImageRow['status'], changes: Partial<ImageRow>, signal?: AbortSignal): Promise<void>;
27
+ compareAndSet(id: string, expected: ImageRow['status'], changes: Partial<ImageRow>, signal?: AbortSignal): Promise<boolean>;
28
+ interrupted(afterId?: string): Promise<ImageRow[]>;
29
+ }
30
+ //# sourceMappingURL=image-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-store.d.ts","sourceRoot":"","sources":["../../src/persistence/image-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAgB,KAAK,UAAU,EAAmB,MAAM,SAAS,CAAC;AAGzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG3D,qBAAa,UAAU;;IAIrB,YAAY,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAGlE;IACK,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;;;OAWlF;IACK,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAIxC;IACD,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW;;;;;;;mBAExC;IACK,IAAI,CAAC,KAAK,EAAE,cAAc;;;;OAK/B;IAEK,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1H;IAEK,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAKhI;IAEK,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CASvD;CACF"}
@@ -0,0 +1,63 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { PublicImageCache } from '../caches/public-image-cache.js';
3
+ import { In, MoreThan } from 'typeorm';
4
+ import { encodeCursor } from '../domain/list-cursor.js';
5
+ import { ImageError } from '../domain/image-error.js';
6
+ import { ImageEntity } from './entities.js';
7
+ import { imageQueryOptions } from './image-query.js';
8
+ export class ImageStore {
9
+ #rows;
10
+ #publicImages;
11
+ constructor(database, redis, cachePrefix) {
12
+ this.#rows = database.getRepository(ImageEntity);
13
+ this.#publicImages = new PublicImageCache(redis, cachePrefix, (id) => this.read(id));
14
+ }
15
+ async reserve(createdBy, key, hash, filename) {
16
+ const id = randomUUID();
17
+ await this.#rows.createQueryBuilder().insert().values({
18
+ id, createdBy, uploadIdempotencyKey: key, uploadRequestFingerprint: hash,
19
+ status: 'uploading', originalFilename: filename,
20
+ }).orIgnore().execute();
21
+ const row = await this.#rows.findOneByOrFail({ createdBy, uploadIdempotencyKey: key });
22
+ if (row.uploadRequestFingerprint !== hash) {
23
+ throw new ImageError('IDEMPOTENCY_CONFLICT', '同一幂等键不能用于不同上传请求');
24
+ }
25
+ return { row, created: row.id === id };
26
+ }
27
+ async read(id) {
28
+ const row = await this.#rows.findOneBy({ id });
29
+ if (!row)
30
+ throw new ImageError('NOT_FOUND', '图片不存在');
31
+ return row;
32
+ }
33
+ readAsset(id, signal) {
34
+ return this.#publicImages.read(id, signal);
35
+ }
36
+ async list(query) {
37
+ const rows = await this.#rows.find(imageQueryOptions(query));
38
+ const items = rows.slice(0, query.limit);
39
+ const hasMore = rows.length > query.limit;
40
+ return { items, hasMore, nextCursor: hasMore ? encodeCursor(query, items[items.length - 1]) : null };
41
+ }
42
+ async transition(id, expected, changes, signal) {
43
+ if (!await this.compareAndSet(id, expected, changes, signal))
44
+ throw new ImageError('STATE_CONFLICT', '图片状态已改变,请重新读取');
45
+ }
46
+ async compareAndSet(id, expected, changes, signal) {
47
+ return this.#publicImages.change(id, async () => {
48
+ const result = await this.#rows.update({ id, status: expected }, changes);
49
+ return result.affected === 1;
50
+ }, signal);
51
+ }
52
+ async interrupted(afterId) {
53
+ return this.#rows.find({
54
+ where: {
55
+ status: In(['uploading', 'deleting', 'failed']),
56
+ ...(afterId ? { id: MoreThan(afterId) } : {}),
57
+ },
58
+ order: { id: 'asc' },
59
+ take: 100,
60
+ });
61
+ }
62
+ }
63
+ //# sourceMappingURL=image-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-store.js","sourceRoot":"","sources":["../../src/persistence/image-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAoC,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAiB,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,OAAO,UAAU;IACZ,KAAK,CAAuB;IAC5B,aAAa,CAAmB;IAEzC,YAAY,QAAoB,EAAE,KAAY,EAAE,WAAmB;QACjE,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACjD,IAAI,CAAC,aAAa,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACvF,CAAC;IACD,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,GAAW,EAAE,IAAY,EAAE,QAAuB;QACjF,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC;YACpD,EAAE,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,EAAE,wBAAwB,EAAE,IAAI;YACxE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,QAAQ;SAChD,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC;QACvF,IAAI,GAAG,CAAC,wBAAwB,KAAK,IAAI,EAAE,CAAC;YAC1C,MAAM,IAAI,UAAU,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;IACzC,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAU;QACnB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,SAAS,CAAC,EAAU,EAAE,MAAmB;QACvC,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAqB;QAC9B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC;QAC1C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACxG,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,QAA4B,EAAE,OAA0B,EAAE,MAAoB;QACzG,IAAI,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;IACxH,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,EAAU,EAAE,QAA4B,EAAE,OAA0B,EAAE,MAAoB;QAC5G,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;YAC1E,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;QAC/B,CAAC,EAAE,MAAM,CAAC,CAAC;IACb,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAgB;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YACrB,KAAK,EAAE;gBACL,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;gBAC/C,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9C;YACD,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE;YACpB,IAAI,EAAE,GAAG;SACV,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,24 @@
1
+ import type { ImageRow } from '../persistence/entities.js';
2
+ export type ImageMetadata = ReturnType<typeof imageProjection>;
3
+ export interface ImagePage {
4
+ items: ImageMetadata[];
5
+ hasMore: boolean;
6
+ nextCursor: string | null;
7
+ }
8
+ export declare function imageProjection(row: ImageRow, origin: string): {
9
+ id: string;
10
+ originalFilename: string | null;
11
+ status: "deleted" | "deleting" | "failed" | "ready" | "uploading";
12
+ url: string | null;
13
+ mediaType: string | null;
14
+ byteSize: number | null;
15
+ width: number | null;
16
+ height: number | null;
17
+ sha256: string | null;
18
+ createdBy: string;
19
+ createdAt: string;
20
+ readyAt: string | null;
21
+ deletedAt: string | null;
22
+ failureCode: string | null;
23
+ };
24
+ //# sourceMappingURL=image-projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-projection.d.ts","sourceRoot":"","sources":["../../src/presentation/image-projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC/D,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM;IAEzD,EAAE;IACF,gBAAgB;IAChB,MAAM;IACN,GAAG;IACH,SAAS;IACT,QAAQ;IACR,KAAK;IACL,MAAM;IACN,MAAM;IACN,SAAS;IACT,SAAS;IACT,OAAO;IACP,SAAS;IACT,WAAW;EAEd"}
@@ -0,0 +1,19 @@
1
+ export function imageProjection(row, origin) {
2
+ return {
3
+ id: row.id,
4
+ originalFilename: row.originalFilename,
5
+ status: row.status,
6
+ url: row.status === 'ready' ? new URL(`/media/images/${row.id}.${row.extension}`, origin).href : null,
7
+ mediaType: row.mediaType,
8
+ byteSize: row.byteSize,
9
+ width: row.width,
10
+ height: row.height,
11
+ sha256: row.sha256,
12
+ createdBy: row.createdBy,
13
+ createdAt: row.createdAt.toISOString(),
14
+ readyAt: row.readyAt?.toISOString() ?? null,
15
+ deletedAt: row.deletedAt?.toISOString() ?? null,
16
+ failureCode: row.failureCode,
17
+ };
18
+ }
19
+ //# sourceMappingURL=image-projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-projection.js","sourceRoot":"","sources":["../../src/presentation/image-projection.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,eAAe,CAAC,GAAa,EAAE,MAAc;IAC3D,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,GAAG,EAAE,GAAG,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,iBAAiB,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;QACrG,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE;QACtC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,IAAI;QAC3C,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,IAAI;QAC/C,WAAW,EAAE,GAAG,CAAC,WAAW;KAC7B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ImageStore } from '../persistence/image-store.js';
2
+ import type { LocalImageStorage } from '../storage/local-storage.js';
3
+ /** Runs only during single-instance startup, before either catalog is published. */
4
+ export declare function recoverImages(store: ImageStore, storage: LocalImageStorage): Promise<void>;
5
+ //# sourceMappingURL=recover-images.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recover-images.d.ts","sourceRoot":"","sources":["../../src/runtime/recover-images.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,oFAAoF;AACpF,wBAAsB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhG"}
@@ -0,0 +1,21 @@
1
+ /** Runs only during single-instance startup, before either catalog is published. */
2
+ export async function recoverImages(store, storage) {
3
+ let afterId;
4
+ for (;;) {
5
+ const rows = await store.interrupted(afterId);
6
+ if (!rows.length)
7
+ return;
8
+ for (const row of rows) {
9
+ if (row.relativePath)
10
+ await storage.remove(row.relativePath);
11
+ if (row.status === 'deleting') {
12
+ await store.transition(row.id, 'deleting', { status: 'deleted', deletedAt: new Date() });
13
+ }
14
+ if (row.status === 'uploading') {
15
+ await store.transition(row.id, 'uploading', { status: 'failed', failureCode: 'UPLOAD_INTERRUPTED' });
16
+ }
17
+ }
18
+ afterId = rows[rows.length - 1].id;
19
+ }
20
+ }
21
+ //# sourceMappingURL=recover-images.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recover-images.js","sourceRoot":"","sources":["../../src/runtime/recover-images.ts"],"names":[],"mappings":"AAGA,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAiB,EAAE,OAA0B;IAC/E,IAAI,OAA2B,CAAC;IAChC,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,YAAY;gBAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC7D,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC9B,MAAM,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;YAC3F,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAC/B,MAAM,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACvG,CAAC;QACH,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,EAAE,CAAC;IACtC,CAAC;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Application } from '@hile/micro';
2
+ declare const _default: import("@hile/core").ServiceRegisterProps<Application>;
3
+ export default _default;
4
+ //# sourceMappingURL=application.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application.service.d.ts","sourceRoot":"","sources":["../../src/services/application.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import { defineService } from '@hile/core';
3
+ import { Application } from '@hile/micro';
4
+ import { parseAdvertiseHost, parseRegistryBootstrap } from '@zlooks.cn/registry-config';
5
+ import { detect } from 'detect-port';
6
+ import { IMAGES_NAMESPACE } from '../identity.js';
7
+ export default defineService('zlooks.images.application', async (shutdown) => {
8
+ const registry = parseRegistryBootstrap({
9
+ REGISTRY_HOST: process.env.REGISTRY_HOST,
10
+ REGISTRY_PORT: process.env.REGISTRY_PORT,
11
+ });
12
+ const advertiseHost = parseAdvertiseHost(process.env.HILE_ADVERTISE_HOST);
13
+ const application = new Application({
14
+ namespace: IMAGES_NAMESPACE,
15
+ registry,
16
+ ...(advertiseHost ? { advertiseHost } : {}),
17
+ });
18
+ await application.load(fileURLToPath(new URL('../messages', import.meta.url)));
19
+ shutdown(await application.listen(await detect()));
20
+ return application;
21
+ });
22
+ //# sourceMappingURL=application.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application.service.js","sourceRoot":"","sources":["../../src/services/application.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACxF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,eAAe,aAAa,CAAC,2BAA2B,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAC3E,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACtC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;QACxC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;KACzC,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC1E,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;QAClC,SAAS,EAAE,gBAAgB;QAC3B,QAAQ;QACR,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5C,CAAC,CAAC;IACH,MAAM,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,aAAa,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/E,QAAQ,CAAC,MAAM,WAAW,CAAC,MAAM,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC;IACnD,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ declare const _default: import("@hile/core").ServiceRegisterProps<import("@zlooks.cn/registry-config").RegistryConfigSubscription<Readonly<{
2
+ postgres: Readonly<{
3
+ host: string;
4
+ port: number;
5
+ username: string;
6
+ password: string;
7
+ database: string;
8
+ ssl: boolean;
9
+ poolSize: number;
10
+ }>;
11
+ redis: Readonly<{
12
+ host: string;
13
+ port: number;
14
+ username?: string | undefined;
15
+ password?: string | undefined;
16
+ database: number;
17
+ keyPrefix: string;
18
+ tls: boolean;
19
+ }>;
20
+ publicHost: Readonly<{
21
+ origin: string;
22
+ }>;
23
+ }>>>;
24
+ export default _default;
25
+ //# sourceMappingURL=config.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.service.d.ts","sourceRoot":"","sources":["../../src/services/config.service.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import { defineService, loadService } from '@hile/core';
2
+ import { parsePostgresConfig, parseRedisConfig } from '@zlooks.cn/infrastructure';
3
+ import { parsePublicHostConfig, PUBLIC_HOST_CONFIG_TOPIC_KEY } from '@zlooks.cn/public-host-contract';
4
+ import { registryConfigTopic, subscribeRegistryConfig } from '@zlooks.cn/registry-config';
5
+ import applicationService from './application.service.js';
6
+ export default defineService('zlooks.images.config', async (shutdown) => {
7
+ const application = await loadService(applicationService);
8
+ const subscriber = await subscribeRegistryConfig(application, {
9
+ sources: {
10
+ redis: { topic: registryConfigTopic('redis'), parse: parseRedisConfig },
11
+ postgres: { topic: registryConfigTopic('postgres'), parse: parsePostgresConfig },
12
+ publicHost: { topic: registryConfigTopic(PUBLIC_HOST_CONFIG_TOPIC_KEY), parse: parsePublicHostConfig },
13
+ },
14
+ compose: (sources) => Object.freeze({ postgres: sources.postgres, redis: sources.redis, publicHost: sources.publicHost }),
15
+ });
16
+ shutdown(() => subscriber.close());
17
+ return subscriber;
18
+ });
19
+ //# sourceMappingURL=config.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.service.js","sourceRoot":"","sources":["../../src/services/config.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AACtG,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,kBAAkB,MAAM,0BAA0B,CAAC;AAE1D,eAAe,aAAa,CAAC,sBAAsB,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IACtE,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,MAAM,uBAAuB,CAAC,WAAW,EAAE;QAC5D,OAAO,EAAE;YACP,KAAK,EAAE,EAAE,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE;YACvE,QAAQ,EAAE,EAAE,KAAK,EAAE,mBAAmB,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE;YAChF,UAAU,EAAE,EAAE,KAAK,EAAE,mBAAmB,CAAC,4BAA4B,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE;SACvG;QACD,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;KAC1H,CAAC,CAAC;IACH,QAAQ,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;IACnC,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@hile/core").ServiceRegisterProps<import("typeorm").DataSource>;
2
+ export default _default;
3
+ //# sourceMappingURL=database.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.service.d.ts","sourceRoot":"","sources":["../../src/services/database.service.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import { defineService, loadService } from '@hile/core';
2
+ import { createDataSource } from '@hile/typeorm';
3
+ import { ImageEntity } from '../persistence/entities.js';
4
+ import configService from './config.service.js';
5
+ export default defineService('zlooks.images.database', async (shutdown) => {
6
+ const config = (await loadService(configService)).snapshot().postgres;
7
+ const database = await createDataSource({
8
+ type: 'postgres',
9
+ host: config.host,
10
+ port: config.port,
11
+ username: config.username,
12
+ password: config.password,
13
+ database: config.database,
14
+ ssl: config.ssl,
15
+ poolSize: config.poolSize,
16
+ synchronize: true,
17
+ migrationsRun: false,
18
+ entities: [ImageEntity],
19
+ });
20
+ shutdown(() => database.destroy());
21
+ return database;
22
+ });
23
+ //# sourceMappingURL=database.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.service.js","sourceRoot":"","sources":["../../src/services/database.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAEhD,eAAe,aAAa,CAAC,wBAAwB,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IACxE,MAAM,MAAM,GAAG,CAAC,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC;IACtE,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC;QACtC,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,WAAW,EAAE,IAAI;QACjB,aAAa,EAAE,KAAK;QACpB,QAAQ,EAAE,CAAC,WAAW,CAAC;KACxB,CAAC,CAAC;IACH,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { ImageStore } from '../persistence/image-store.js';
2
+ import { LocalImageStorage } from '../storage/local-storage.js';
3
+ declare const _default: import("@hile/core").ServiceRegisterProps<{
4
+ store: ImageStore;
5
+ storage: LocalImageStorage;
6
+ origin: () => any;
7
+ }>;
8
+ export default _default;
9
+ //# sourceMappingURL=images-runtime.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images-runtime.service.d.ts","sourceRoot":"","sources":["../../src/services/images-runtime.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { defineService, loadService } from '@hile/core';
2
+ import { ImageStore } from '../persistence/image-store.js';
3
+ import { recoverImages } from '../runtime/recover-images.js';
4
+ import { LocalImageStorage } from '../storage/local-storage.js';
5
+ import configService from './config.service.js';
6
+ import redisService from './redis.service.js';
7
+ import databaseService from './database.service.js';
8
+ export default defineService('zlooks.images.runtime', async () => {
9
+ const [database, configs, redis] = await Promise.all([loadService(databaseService), loadService(configService), loadService(redisService)]);
10
+ const store = new ImageStore(database, redis, `${configs.snapshot().redis.keyPrefix}images:public:v1:`);
11
+ const storage = new LocalImageStorage();
12
+ await storage.initialize();
13
+ await recoverImages(store, storage);
14
+ return { store, storage, origin: () => configs.snapshot().publicHost.origin };
15
+ });
16
+ //# sourceMappingURL=images-runtime.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images-runtime.service.js","sourceRoot":"","sources":["../../src/services/images-runtime.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,eAAe,MAAM,uBAAuB,CAAC;AAEpD,eAAe,aAAa,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;IAC/D,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,eAAe,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC5I,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,SAAS,mBAAmB,CAAC,CAAC;IACxG,MAAM,OAAO,GAAG,IAAI,iBAAiB,EAAE,CAAC;IACxC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC3B,MAAM,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;AAChF,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@hile/core").ServiceRegisterProps<void>;
2
+ export default _default;
3
+ //# sourceMappingURL=images.boot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.boot.d.ts","sourceRoot":"","sources":["../../src/services/images.boot.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import { defineService, loadService } from '@hile/core';
2
+ import publicAssetsService from './public-assets.service.js';
3
+ import mcpProviderService from './mcp-provider.service.js';
4
+ export default defineService('zlooks.images.boot', async () => {
5
+ await loadService(publicAssetsService);
6
+ await loadService(mcpProviderService);
7
+ });
8
+ //# sourceMappingURL=images.boot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"images.boot.js","sourceRoot":"","sources":["../../src/services/images.boot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,mBAAmB,MAAM,4BAA4B,CAAC;AAC7D,OAAO,kBAAkB,MAAM,2BAA2B,CAAC;AAE3D,eAAe,aAAa,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;IAC5D,MAAM,WAAW,CAAC,mBAAmB,CAAC,CAAC;IACvC,MAAM,WAAW,CAAC,kBAAkB,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type Logger } from '@hile/logger';
2
+ declare const _default: import("@hile/core").ServiceRegisterProps<Logger>;
3
+ export default _default;
4
+ //# sourceMappingURL=logger.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.service.d.ts","sourceRoot":"","sources":["../../src/services/logger.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { defineService } from '@hile/core';
2
+ import { createLogger } from '@hile/logger';
3
+ export default defineService('zlooks.images.logger', async (shutdown) => {
4
+ const { logger, teardown } = createLogger({ level: 'info', pretty: false });
5
+ shutdown(teardown);
6
+ return logger;
7
+ });
8
+ //# sourceMappingURL=logger.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.service.js","sourceRoot":"","sources":["../../src/services/logger.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAe,MAAM,cAAc,CAAC;AAEzD,eAAe,aAAa,CAAC,sBAAsB,EAAE,KAAK,EAAE,QAAQ,EAAmB,EAAE;IACvF,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnB,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@hile/core").ServiceRegisterProps<import("@hile/mcp/micro").McpProviderAttachment>;
2
+ export default _default;
3
+ //# sourceMappingURL=mcp-provider.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-provider.service.d.ts","sourceRoot":"","sources":["../../src/services/mcp-provider.service.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import { defineService, loadService } from '@hile/core';
2
+ import { attachMcpProvider } from '@hile/mcp/micro';
3
+ import { createImagesProvider } from '../mcp/provider.js';
4
+ import applicationService from './application.service.js';
5
+ import imagesRuntimeService from './images-runtime.service.js';
6
+ export default defineService('zlooks.images.mcp-provider', async (shutdown) => {
7
+ await loadService(imagesRuntimeService);
8
+ const application = await loadService(applicationService);
9
+ const attachment = await attachMcpProvider(application, createImagesProvider(), {
10
+ invocationSecurity: { mode: 'trusted-internal' },
11
+ });
12
+ shutdown(() => attachment.close());
13
+ return attachment;
14
+ });
15
+ //# sourceMappingURL=mcp-provider.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-provider.service.js","sourceRoot":"","sources":["../../src/services/mcp-provider.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,kBAAkB,MAAM,0BAA0B,CAAC;AAC1D,OAAO,oBAAoB,MAAM,6BAA6B,CAAC;AAE/D,eAAe,aAAa,CAAC,4BAA4B,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAC5E,MAAM,WAAW,CAAC,oBAAoB,CAAC,CAAC;IACxC,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,WAAW,EAAE,oBAAoB,EAAE,EAAE;QAC9E,kBAAkB,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE;KACjD,CAAC,CAAC;IACH,QAAQ,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;IACnC,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { PublicAssetPublisher } from '@zlooks.cn/public-asset/publisher';
2
+ declare const _default: import("@hile/core").ServiceRegisterProps<PublicAssetPublisher>;
3
+ export default _default;
4
+ //# sourceMappingURL=public-assets.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-assets.service.d.ts","sourceRoot":"","sources":["../../src/services/public-assets.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { defineService, loadService } from '@hile/core';
2
+ import { PublicAssetPublisher } from '@zlooks.cn/public-asset/publisher';
3
+ import { imageAssetProvider } from '../assets/provider.js';
4
+ import applicationService from './application.service.js';
5
+ import imagesRuntimeService from './images-runtime.service.js';
6
+ import loggerService from './logger.service.js';
7
+ export default defineService('zlooks.images.public-assets', async (shutdown) => {
8
+ await loadService(imagesRuntimeService);
9
+ const [application, logger] = await Promise.all([loadService(applicationService), loadService(loggerService)]);
10
+ const publisher = new PublicAssetPublisher(application, imageAssetProvider, (error) => logger.error({ err: error, event: 'images.publication.failed' }, 'Image read publication failed'));
11
+ shutdown(() => publisher.close());
12
+ await publisher.start();
13
+ return publisher;
14
+ });
15
+ //# sourceMappingURL=public-assets.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-assets.service.js","sourceRoot":"","sources":["../../src/services/public-assets.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,kBAAkB,MAAM,0BAA0B,CAAC;AAC1D,OAAO,oBAAoB,MAAM,6BAA6B,CAAC;AAC/D,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAEhD,eAAe,aAAa,CAAC,6BAA6B,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAC7E,MAAM,WAAW,CAAC,oBAAoB,CAAC,CAAC;IACxC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAC/G,MAAM,SAAS,GAAG,IAAI,oBAAoB,CAAC,WAAW,EAAE,kBAAkB,EACxE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,EAAE,+BAA+B,CAAC,CAAC,CAAC;IAChH,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;IAClC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("@hile/core").ServiceRegisterProps<Redis>;
2
+ export default _default;
3
+ //# sourceMappingURL=redis.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.service.d.ts","sourceRoot":"","sources":["../../src/services/redis.service.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import { once } from 'node:events';
2
+ import { defineService, loadService } from '@hile/core';
3
+ import { createRedis } from '@hile/ioredis';
4
+ import configService from './config.service.js';
5
+ import loggerService from './logger.service.js';
6
+ export default defineService('zlooks.images.redis', async (shutdown) => {
7
+ const [configs, logger] = await Promise.all([loadService(configService), loadService(loggerService)]);
8
+ const config = configs.snapshot().redis;
9
+ let ready = false;
10
+ const redis = await createRedis({
11
+ host: config.host, port: config.port, db: config.database,
12
+ ...(config.username ? { username: config.username } : {}),
13
+ ...(config.password ? { password: config.password } : {}),
14
+ ...(config.tls ? { tls: {} } : {}),
15
+ connectTimeout: 3_000, commandTimeout: 3_000, maxRetriesPerRequest: 1, enableOfflineQueue: false,
16
+ // createRedis cannot expose a failed initial client for cleanup; stop initial retries.
17
+ retryStrategy: (attempt) => ready ? Math.min(attempt * 100, 1_000) : null,
18
+ });
19
+ const onError = () => logger.warn('图片元数据缓存 Redis 连接异常');
20
+ redis.on('error', onError);
21
+ shutdown(() => { redis.disconnect(); redis.off('error', onError); });
22
+ try {
23
+ // createRedis resolves at TCP connect; connect alone does not verify authentication/readiness.
24
+ if (redis.status !== 'ready')
25
+ await once(redis, 'ready', { signal: AbortSignal.timeout(3_000) });
26
+ ready = true;
27
+ return redis;
28
+ }
29
+ catch (error) {
30
+ redis.disconnect();
31
+ redis.off('error', onError);
32
+ throw error;
33
+ }
34
+ });
35
+ //# sourceMappingURL=redis.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.service.js","sourceRoot":"","sources":["../../src/services/redis.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAEhD,eAAe,aAAa,CAAC,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IACrE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IACtG,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC;IACxC,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC;QAC9B,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ;QACzD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClC,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,EAAE,kBAAkB,EAAE,KAAK;QAChG,uFAAuF;QACvF,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;KAC1E,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACxD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,IAAI,CAAC;QACH,+FAA+F;QAC/F,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO;YAAE,MAAM,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjG,KAAK,GAAG,IAAI,CAAC;QACb,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;AACnF,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function validateImagePath(relative: string): string;
2
+ export declare function imageRelativePath(id: string, extension: string, now: Date): string;
3
+ //# sourceMappingURL=image-path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-path.d.ts","sourceRoot":"","sources":["../../src/storage/image-path.ts"],"names":[],"mappings":"AAQA,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG1D;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,CAIlF"}
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+ import { ImageError } from '../domain/image-error.js';
3
+ const relativePattern = /^\d{4}\/\d{2}\/\d{2}\/[a-f0-9-]{36}\.(?:jpg|png|webp|gif|avif)$/;
4
+ const calendar = new Intl.DateTimeFormat('en-CA', {
5
+ timeZone: 'Asia/Shanghai', year: 'numeric', month: '2-digit', day: '2-digit',
6
+ });
7
+ export function validateImagePath(relative) {
8
+ if (!relativePattern.test(relative))
9
+ throw new ImageError('INVALID_PATH', '图片路径无效');
10
+ return relative;
11
+ }
12
+ export function imageRelativePath(id, extension, now) {
13
+ z.uuid().parse(id);
14
+ const parts = Object.fromEntries(calendar.formatToParts(now).map((part) => [part.type, part.value]));
15
+ return validateImagePath(`${parts.year}/${parts.month}/${parts.day}/${id}.${extension}`);
16
+ }
17
+ //# sourceMappingURL=image-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-path.js","sourceRoot":"","sources":["../../src/storage/image-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,MAAM,eAAe,GAAG,iEAAiE,CAAC;AAC1F,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;IAChD,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS;CAC7E,CAAC,CAAC;AAEH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACpF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAAU,EAAE,SAAiB,EAAE,GAAS;IACxE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnB,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrG,OAAO,iBAAiB,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,IAAI,EAAE,IAAI,SAAS,EAAE,CAAC,CAAC;AAC3F,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare function inspectImage(bytes: Buffer): Promise<{
2
+ mediaType: "image/avif" | "image/gif" | "image/jpeg" | "image/png" | "image/webp";
3
+ extension: "avif" | "gif" | "jpg" | "png" | "webp";
4
+ width: number;
5
+ height: number;
6
+ byteSize: number;
7
+ sha256: string;
8
+ }>;
9
+ //# sourceMappingURL=inspect-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect-image.d.ts","sourceRoot":"","sources":["../../src/storage/inspect-image.ts"],"names":[],"mappings":"AAUA,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM;;;;;;;GAuB/C"}