@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.
- package/dist/assets/provider.d.ts +3 -0
- package/dist/assets/provider.d.ts.map +1 -0
- package/dist/assets/provider.js +6 -0
- package/dist/assets/provider.js.map +1 -0
- package/dist/assets/read-image-asset.d.ts +5 -0
- package/dist/assets/read-image-asset.d.ts.map +1 -0
- package/dist/assets/read-image-asset.js +88 -0
- package/dist/assets/read-image-asset.js.map +1 -0
- package/dist/assets/response-policy.d.ts +6 -0
- package/dist/assets/response-policy.d.ts.map +1 -0
- package/dist/assets/response-policy.js +49 -0
- package/dist/assets/response-policy.js.map +1 -0
- package/dist/caches/public-image-cache.d.ts +18 -0
- package/dist/caches/public-image-cache.d.ts.map +1 -0
- package/dist/caches/public-image-cache.js +58 -0
- package/dist/caches/public-image-cache.js.map +1 -0
- package/dist/command/index.d.ts +3 -0
- package/dist/command/index.d.ts.map +1 -0
- package/dist/command/index.js +23 -0
- package/dist/command/index.js.map +1 -0
- package/dist/domain/image-error.d.ts +5 -0
- package/dist/domain/image-error.d.ts.map +1 -0
- package/dist/domain/image-error.js +9 -0
- package/dist/domain/image-error.js.map +1 -0
- package/dist/domain/list-cursor.d.ts +10 -0
- package/dist/domain/list-cursor.d.ts.map +1 -0
- package/dist/domain/list-cursor.js +31 -0
- package/dist/domain/list-cursor.js.map +1 -0
- package/dist/domain/output-schema.d.ts +63 -0
- package/dist/domain/output-schema.d.ts.map +1 -0
- package/dist/domain/output-schema.js +25 -0
- package/dist/domain/output-schema.js.map +1 -0
- package/dist/domain/schema.d.ts +69 -0
- package/dist/domain/schema.d.ts.map +1 -0
- package/dist/domain/schema.js +44 -0
- package/dist/domain/schema.js.map +1 -0
- package/dist/identity.d.ts +3 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +3 -0
- package/dist/identity.js.map +1 -0
- package/dist/mcp/provider.d.ts +2 -0
- package/dist/mcp/provider.d.ts.map +1 -0
- package/dist/mcp/provider.js +96 -0
- package/dist/mcp/provider.js.map +1 -0
- package/dist/messages/public-asset/read.msg.d.ts +3 -0
- package/dist/messages/public-asset/read.msg.d.ts.map +1 -0
- package/dist/messages/public-asset/read.msg.js +10 -0
- package/dist/messages/public-asset/read.msg.js.map +1 -0
- package/dist/migrations/index.d.ts +3 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +3 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/models/delete-image.model.d.ts +21 -0
- package/dist/models/delete-image.model.d.ts.map +1 -0
- package/dist/models/delete-image.model.js +36 -0
- package/dist/models/delete-image.model.js.map +1 -0
- package/dist/models/list-image.model.d.ts +21 -0
- package/dist/models/list-image.model.d.ts.map +1 -0
- package/dist/models/list-image.model.js +15 -0
- package/dist/models/list-image.model.js.map +1 -0
- package/dist/models/read-image.model.d.ts +20 -0
- package/dist/models/read-image.model.d.ts.map +1 -0
- package/dist/models/read-image.model.js +15 -0
- package/dist/models/read-image.model.js.map +1 -0
- package/dist/models/upload-image.model.d.ts +22 -0
- package/dist/models/upload-image.model.d.ts.map +1 -0
- package/dist/models/upload-image.model.js +52 -0
- package/dist/models/upload-image.model.js.map +1 -0
- package/dist/persistence/entities.d.ts +22 -0
- package/dist/persistence/entities.d.ts.map +1 -0
- package/dist/persistence/entities.js +20 -0
- package/dist/persistence/entities.js.map +1 -0
- package/dist/persistence/image-query.d.ts +5 -0
- package/dist/persistence/image-query.d.ts.map +1 -0
- package/dist/persistence/image-query.js +44 -0
- package/dist/persistence/image-query.js.map +1 -0
- package/dist/persistence/image-store.d.ts +30 -0
- package/dist/persistence/image-store.d.ts.map +1 -0
- package/dist/persistence/image-store.js +63 -0
- package/dist/persistence/image-store.js.map +1 -0
- package/dist/presentation/image-projection.d.ts +24 -0
- package/dist/presentation/image-projection.d.ts.map +1 -0
- package/dist/presentation/image-projection.js +19 -0
- package/dist/presentation/image-projection.js.map +1 -0
- package/dist/runtime/recover-images.d.ts +5 -0
- package/dist/runtime/recover-images.d.ts.map +1 -0
- package/dist/runtime/recover-images.js +21 -0
- package/dist/runtime/recover-images.js.map +1 -0
- package/dist/services/application.service.d.ts +4 -0
- package/dist/services/application.service.d.ts.map +1 -0
- package/dist/services/application.service.js +22 -0
- package/dist/services/application.service.js.map +1 -0
- package/dist/services/config.service.d.ts +25 -0
- package/dist/services/config.service.d.ts.map +1 -0
- package/dist/services/config.service.js +19 -0
- package/dist/services/config.service.js.map +1 -0
- package/dist/services/database.service.d.ts +3 -0
- package/dist/services/database.service.d.ts.map +1 -0
- package/dist/services/database.service.js +23 -0
- package/dist/services/database.service.js.map +1 -0
- package/dist/services/images-runtime.service.d.ts +9 -0
- package/dist/services/images-runtime.service.d.ts.map +1 -0
- package/dist/services/images-runtime.service.js +16 -0
- package/dist/services/images-runtime.service.js.map +1 -0
- package/dist/services/images.boot.d.ts +3 -0
- package/dist/services/images.boot.d.ts.map +1 -0
- package/dist/services/images.boot.js +8 -0
- package/dist/services/images.boot.js.map +1 -0
- package/dist/services/logger.service.d.ts +4 -0
- package/dist/services/logger.service.d.ts.map +1 -0
- package/dist/services/logger.service.js +8 -0
- package/dist/services/logger.service.js.map +1 -0
- package/dist/services/mcp-provider.service.d.ts +3 -0
- package/dist/services/mcp-provider.service.d.ts.map +1 -0
- package/dist/services/mcp-provider.service.js +15 -0
- package/dist/services/mcp-provider.service.js.map +1 -0
- package/dist/services/public-assets.service.d.ts +4 -0
- package/dist/services/public-assets.service.d.ts.map +1 -0
- package/dist/services/public-assets.service.js +15 -0
- package/dist/services/public-assets.service.js.map +1 -0
- package/dist/services/redis.service.d.ts +3 -0
- package/dist/services/redis.service.d.ts.map +1 -0
- package/dist/services/redis.service.js +35 -0
- package/dist/services/redis.service.js.map +1 -0
- package/dist/storage/image-path.d.ts +3 -0
- package/dist/storage/image-path.d.ts.map +1 -0
- package/dist/storage/image-path.js +17 -0
- package/dist/storage/image-path.js.map +1 -0
- package/dist/storage/inspect-image.d.ts +9 -0
- package/dist/storage/inspect-image.d.ts.map +1 -0
- package/dist/storage/inspect-image.js +36 -0
- package/dist/storage/inspect-image.js.map +1 -0
- package/dist/storage/local-storage.d.ts +10 -0
- package/dist/storage/local-storage.d.ts.map +1 -0
- package/dist/storage/local-storage.js +65 -0
- package/dist/storage/local-storage.js.map +1 -0
- package/dist/storage/read-upload-bytes.d.ts +3 -0
- package/dist/storage/read-upload-bytes.d.ts.map +1 -0
- package/dist/storage/read-upload-bytes.js +11 -0
- package/dist/storage/read-upload-bytes.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/assets/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAGjE,eAAO,MAAM,kBAAkB,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAGzG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/assets/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE7D,MAAM,CAAC,MAAM,kBAAkB,GAA+E;IAC5G,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,gBAAgB;IAClD,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC;CACnD,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type AssetMetadata } from '@zlooks.cn/public-asset';
|
|
2
|
+
import type { ImageStore } from '../persistence/image-store.js';
|
|
3
|
+
import type { LocalImageStorage } from '../storage/local-storage.js';
|
|
4
|
+
export declare function readImageAsset(store: ImageStore, storage: LocalImageStorage, input: unknown, signal: AbortSignal): AsyncGenerator<AssetMetadata | Buffer>;
|
|
5
|
+
//# sourceMappingURL=read-image-asset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-image-asset.d.ts","sourceRoot":"","sources":["../../src/assets/read-image-asset.ts"],"names":[],"mappings":"AACA,OAAO,EAAyC,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACpG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,wBAAuB,cAAc,CACnC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,WAAW,GAClB,cAAc,CAAC,aAAa,GAAG,MAAM,CAAC,CAsDxC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import rangeParser from 'range-parser';
|
|
2
|
+
import { ASSET_CHUNK_BYTES, assetRequestSchema } from '@zlooks.cn/public-asset';
|
|
3
|
+
import { imagePreconditionStatus, permitsImageRange, imageReadHeaders, emptyImageResponse } from './response-policy.js';
|
|
4
|
+
export async function* readImageAsset(store, storage, input, signal) {
|
|
5
|
+
signal.throwIfAborted();
|
|
6
|
+
const parsed = assetRequestSchema.safeParse(input);
|
|
7
|
+
if (!parsed.success) {
|
|
8
|
+
yield emptyImageResponse(400);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const request = parsed.data;
|
|
12
|
+
const path = /^\/media\/images\/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})\.(jpg|png|webp|gif|avif)$/.exec(request.path);
|
|
13
|
+
if (!path) {
|
|
14
|
+
yield emptyImageResponse(404);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
let row;
|
|
18
|
+
try {
|
|
19
|
+
row = await store.readAsset(path[1], signal);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
signal.throwIfAborted();
|
|
23
|
+
yield emptyImageResponse(503);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (!row || row.extension !== path[2]) {
|
|
27
|
+
yield emptyImageResponse(404);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const file = await storage.open(row.relativePath).catch(() => null);
|
|
31
|
+
if (!file) {
|
|
32
|
+
yield emptyImageResponse(503);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
signal.throwIfAborted();
|
|
37
|
+
const stat = await file.stat();
|
|
38
|
+
if (!stat.isFile() || stat.size !== row.byteSize) {
|
|
39
|
+
yield emptyImageResponse(503);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const etag = `"${row.sha256}"`;
|
|
43
|
+
const modified = new Date(row.modifiedAt);
|
|
44
|
+
const headers = imageReadHeaders(etag, modified);
|
|
45
|
+
const precondition = imagePreconditionStatus(request.headers, etag, modified);
|
|
46
|
+
if (precondition) {
|
|
47
|
+
yield precondition === 304 ? { status: 304, headers } : emptyImageResponse(precondition);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
let start = 0;
|
|
51
|
+
let end = row.byteSize - 1;
|
|
52
|
+
let partial = false;
|
|
53
|
+
if (request.method === 'GET' && request.headers.range && permitsImageRange(request.headers['if-range'], etag, modified)) {
|
|
54
|
+
const ranges = rangeParser(row.byteSize, request.headers.range);
|
|
55
|
+
if (typeof ranges === 'number' || ranges.type !== 'bytes' || ranges.length !== 1) {
|
|
56
|
+
const response = emptyImageResponse(416);
|
|
57
|
+
response.headers['content-range'] = `bytes */${row.byteSize}`;
|
|
58
|
+
yield response;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
({ start, end } = ranges[0]);
|
|
62
|
+
partial = true;
|
|
63
|
+
}
|
|
64
|
+
yield {
|
|
65
|
+
status: partial ? 206 : 200,
|
|
66
|
+
headers: {
|
|
67
|
+
...headers, 'content-length': String(end - start + 1), 'content-type': row.mediaType,
|
|
68
|
+
...(partial ? { 'content-range': `bytes ${start}-${end}/${row.byteSize}` } : {}),
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
if (request.method === 'HEAD')
|
|
72
|
+
return;
|
|
73
|
+
const stream = file.createReadStream({ start, end, autoClose: false, highWaterMark: ASSET_CHUNK_BYTES, signal });
|
|
74
|
+
try {
|
|
75
|
+
for await (const chunk of stream) {
|
|
76
|
+
signal.throwIfAborted();
|
|
77
|
+
yield chunk;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
stream.destroy();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
await file.close();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=read-image-asset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-image-asset.js","sourceRoot":"","sources":["../../src/assets/read-image-asset.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AssetMetadata, AssetRequest } from '@zlooks.cn/public-asset';
|
|
2
|
+
export declare function imageReadHeaders(etag: string, modified: Date): AssetMetadata['headers'];
|
|
3
|
+
export declare function emptyImageResponse(status: number): AssetMetadata;
|
|
4
|
+
export declare function imagePreconditionStatus(headers: AssetRequest['headers'], etag: string, modified: Date): 304 | 412 | undefined;
|
|
5
|
+
export declare function permitsImageRange(value: string | undefined, etag: string, modified: Date): boolean;
|
|
6
|
+
//# sourceMappingURL=response-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-policy.d.ts","sourceRoot":"","sources":["../../src/assets/response-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE3E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,CAOvF;AACD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAEhE;AACD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,SAAS,CAS7H;AACD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,GAAG,OAAO,CAIlG"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export function imageReadHeaders(etag, modified) {
|
|
2
|
+
return {
|
|
3
|
+
etag, 'last-modified': modified.toUTCString(), 'accept-ranges': 'bytes',
|
|
4
|
+
'cache-control': 'public, max-age=31536000, immutable',
|
|
5
|
+
'content-disposition': 'inline', 'x-content-type-options': 'nosniff',
|
|
6
|
+
'access-control-allow-origin': '*', 'cross-origin-resource-policy': 'cross-origin',
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function emptyImageResponse(status) {
|
|
10
|
+
return { status, headers: { 'content-length': '0', 'cache-control': 'no-store', 'access-control-allow-origin': '*' } };
|
|
11
|
+
}
|
|
12
|
+
export function imagePreconditionStatus(headers, etag, modified) {
|
|
13
|
+
const match = headers['if-match'];
|
|
14
|
+
if (match && !matchesTag(match, etag, false))
|
|
15
|
+
return 412;
|
|
16
|
+
if (!match && isOlder(headers['if-unmodified-since'], modified))
|
|
17
|
+
return 412;
|
|
18
|
+
const none = headers['if-none-match'];
|
|
19
|
+
if (none)
|
|
20
|
+
return matchesTag(none, etag, true) ? 304 : undefined;
|
|
21
|
+
const since = parseDate(headers['if-modified-since']);
|
|
22
|
+
if (since !== undefined && modifiedSeconds(modified) <= since)
|
|
23
|
+
return 304;
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
export function permitsImageRange(value, etag, modified) {
|
|
27
|
+
if (!value || value === etag)
|
|
28
|
+
return true;
|
|
29
|
+
const date = parseDate(value);
|
|
30
|
+
return date !== undefined && date >= modifiedSeconds(modified);
|
|
31
|
+
}
|
|
32
|
+
function matchesTag(value, etag, weak) {
|
|
33
|
+
return value.split(',').some((item) => {
|
|
34
|
+
const tag = item.trim();
|
|
35
|
+
return tag === '*' || (weak ? tag.replace(/^W\//, '') : tag) === etag;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function parseDate(value) {
|
|
39
|
+
if (!value)
|
|
40
|
+
return undefined;
|
|
41
|
+
const time = Date.parse(value);
|
|
42
|
+
return Number.isFinite(time) ? Math.floor(time / 1000) : undefined;
|
|
43
|
+
}
|
|
44
|
+
function modifiedSeconds(modified) { return Math.floor(modified.getTime() / 1000); }
|
|
45
|
+
function isOlder(value, modified) {
|
|
46
|
+
const date = parseDate(value);
|
|
47
|
+
return date !== undefined && date < modifiedSeconds(modified);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=response-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-policy.js","sourceRoot":"","sources":["../../src/assets/response-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Redis } from 'ioredis';
|
|
2
|
+
import type { ImageRow } from '../persistence/entities.js';
|
|
3
|
+
export declare class PublicImageCache {
|
|
4
|
+
private readonly prefix;
|
|
5
|
+
private readonly locks;
|
|
6
|
+
private readonly entry;
|
|
7
|
+
constructor(redis: Redis, prefix: string, load: (id: string) => Promise<ImageRow>);
|
|
8
|
+
read(id: string, signal: AbortSignal): Promise<{
|
|
9
|
+
extension: "avif" | "gif" | "jpg" | "png" | "webp";
|
|
10
|
+
relativePath: string;
|
|
11
|
+
byteSize: number;
|
|
12
|
+
mediaType: "image/avif" | "image/gif" | "image/jpeg" | "image/png" | "image/webp";
|
|
13
|
+
sha256: string;
|
|
14
|
+
modifiedAt: number;
|
|
15
|
+
} | undefined>;
|
|
16
|
+
change<T>(id: string, mutation: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=public-image-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-image-cache.d.ts","sourceRoot":"","sources":["../../src/caches/public-image-cache.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAe3D,qBAAa,gBAAgB;IAID,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAEvB,YAAY,KAAK,EAAE,KAAK,EAAmB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,EAiBjG;IAEK,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW;;;;;;;mBAKzC;IAEK,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAUxF;CACF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Cache, defineCache, RedisCache } from '@hile/cache';
|
|
2
|
+
import { RedisLock } from '@hile/redis-lock';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { ImageError } from '../domain/image-error.js';
|
|
5
|
+
import { validateImagePath } from '../storage/image-path.js';
|
|
6
|
+
import { IMAGE_MAX_BYTES, mediaTypeSchema } from '../domain/schema.js';
|
|
7
|
+
const imageAssetSchema = z.strictObject({
|
|
8
|
+
extension: z.enum(['jpg', 'png', 'webp', 'gif', 'avif']),
|
|
9
|
+
relativePath: z.string().transform(validateImagePath),
|
|
10
|
+
byteSize: z.number().int().positive().max(IMAGE_MAX_BYTES),
|
|
11
|
+
mediaType: mediaTypeSchema,
|
|
12
|
+
sha256: z.string().regex(/^[a-f0-9]{64}$/),
|
|
13
|
+
modifiedAt: z.number().int().min(0).max(8_640_000_000_000_000),
|
|
14
|
+
});
|
|
15
|
+
const lockOptions = { ttl: 30_000, wait: 5_000 };
|
|
16
|
+
export class PublicImageCache {
|
|
17
|
+
prefix;
|
|
18
|
+
locks;
|
|
19
|
+
entry;
|
|
20
|
+
constructor(redis, prefix, load) {
|
|
21
|
+
this.prefix = prefix;
|
|
22
|
+
this.locks = new RedisLock(redis, { renew: true });
|
|
23
|
+
const definition = defineCache('image:{id:string}', async ({ id }) => {
|
|
24
|
+
const row = await load(id).catch((error) => {
|
|
25
|
+
if (error instanceof ImageError && error.code === 'NOT_FOUND')
|
|
26
|
+
return undefined;
|
|
27
|
+
throw error;
|
|
28
|
+
});
|
|
29
|
+
if (!row || row.status !== 'ready' || !row.relativePath || !row.extension || !row.byteSize || !row.mediaType || !row.sha256) {
|
|
30
|
+
return new Cache(undefined);
|
|
31
|
+
}
|
|
32
|
+
const asset = imageAssetSchema.parse({
|
|
33
|
+
extension: row.extension, relativePath: row.relativePath, byteSize: row.byteSize,
|
|
34
|
+
mediaType: row.mediaType, sha256: row.sha256, modifiedAt: (row.readyAt ?? row.createdAt).getTime(),
|
|
35
|
+
});
|
|
36
|
+
return new Cache(asset).setExpire(300);
|
|
37
|
+
}, { singleflight: lockOptions, negative: { ttl: 5 } });
|
|
38
|
+
this.entry = new RedisCache(prefix, redis, { locks: this.locks }).loadCache(definition);
|
|
39
|
+
}
|
|
40
|
+
async read(id, signal) {
|
|
41
|
+
signal.throwIfAborted();
|
|
42
|
+
const asset = await (await this.entry).read({ id });
|
|
43
|
+
signal.throwIfAborted();
|
|
44
|
+
return asset === undefined ? undefined : imageAssetSchema.parse(asset);
|
|
45
|
+
}
|
|
46
|
+
async change(id, mutation, signal) {
|
|
47
|
+
signal?.throwIfAborted();
|
|
48
|
+
// Share @hile/cache 4.0.1's singleflight lock: an old fill must finish before invalidation.
|
|
49
|
+
return this.locks.withLock(`${this.prefix}image:${id}:lock`, lockOptions, async () => {
|
|
50
|
+
signal?.throwIfAborted();
|
|
51
|
+
// Invalidate before committing; a Redis failure must not leave changed DB state behind a live cache.
|
|
52
|
+
await (await this.entry).remove({ id });
|
|
53
|
+
signal?.throwIfAborted();
|
|
54
|
+
return mutation();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=public-image-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-image-cache.js","sourceRoot":"","sources":["../../src/caches/public-image-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/command/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { createRegistryDatabaseDataSource, registerDatabaseCommands } from '@zlooks.cn/database-command';
|
|
4
|
+
import { runServiceCommand } from '@zlooks.cn/service-command';
|
|
5
|
+
import { imagesMigrations } from '../migrations/index.js';
|
|
6
|
+
import { ImageEntity } from '../persistence/entities.js';
|
|
7
|
+
import { IMAGES_NAMESPACE } from '../identity.js';
|
|
8
|
+
await runServiceCommand({
|
|
9
|
+
packageRoot: fileURLToPath(new URL('../../', import.meta.url)),
|
|
10
|
+
requiresReactServer: false,
|
|
11
|
+
configure(program) {
|
|
12
|
+
registerDatabaseCommands(program, {
|
|
13
|
+
createDataSource: (envFile) => createRegistryDatabaseDataSource(envFile, {
|
|
14
|
+
commandNamespace: `${IMAGES_NAMESPACE}.db.command`, entities: [ImageEntity],
|
|
15
|
+
}),
|
|
16
|
+
migrations: imagesMigrations,
|
|
17
|
+
});
|
|
18
|
+
},
|
|
19
|
+
}).catch((error) => {
|
|
20
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
21
|
+
process.exitCode = 1;
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/command/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,gCAAgC,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACzG,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,iBAAiB,CAAC;IACtB,WAAW,EAAE,aAAa,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9D,mBAAmB,EAAE,KAAK;IAC1B,SAAS,CAAC,OAAO;QACf,wBAAwB,CAAC,OAAO,EAAE;YAChC,gBAAgB,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,gCAAgC,CAAC,OAAO,EAAE;gBACvE,gBAAgB,EAAE,GAAG,gBAAgB,aAAa,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC;aAC5E,CAAC;YACF,UAAU,EAAE,gBAAgB;SAC7B,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-error.d.ts","sourceRoot":"","sources":["../../src/domain/image-error.ts"],"names":[],"mappings":"AAAA,qBAAa,UAAW,SAAQ,KAAK;aACP,IAAI,EAAE,MAAM;IAAxC,YAA4B,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAGxD;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-error.js","sourceRoot":"","sources":["../../src/domain/image-error.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,UAAW,SAAQ,KAAK;IACP,IAAI;IAAhC,YAA4B,IAAY,EAAE,OAAe;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;oBADW,IAAI;QAE9B,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ListImageInput } from './schema.js';
|
|
2
|
+
export declare function encodeCursor(filter: ListImageInput, row: {
|
|
3
|
+
id: string;
|
|
4
|
+
createdAt: Date;
|
|
5
|
+
}): string;
|
|
6
|
+
export declare function decodeCursor(filter: ListImageInput): {
|
|
7
|
+
id: string;
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
} | undefined;
|
|
10
|
+
//# sourceMappingURL=list-cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-cursor.d.ts","sourceRoot":"","sources":["../../src/domain/list-cursor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAalD,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,GAAG,MAAM,CAGjG;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,GAAG,SAAS,CAUhG"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { ImageError } from './image-error.js';
|
|
4
|
+
const cursorSchema = z.strictObject({
|
|
5
|
+
filter: z.string().regex(/^[a-f0-9]{64}$/),
|
|
6
|
+
id: z.uuid(),
|
|
7
|
+
createdAt: z.iso.datetime(),
|
|
8
|
+
});
|
|
9
|
+
function filterFingerprint({ cursor: _cursor, limit: _limit, ...filter }) {
|
|
10
|
+
const entries = Object.entries(filter).sort(([left], [right]) => left.localeCompare(right));
|
|
11
|
+
return createHash('sha256').update(JSON.stringify(entries)).digest('hex');
|
|
12
|
+
}
|
|
13
|
+
export function encodeCursor(filter, row) {
|
|
14
|
+
const cursor = { filter: filterFingerprint(filter), id: row.id, createdAt: row.createdAt.toISOString() };
|
|
15
|
+
return Buffer.from(JSON.stringify(cursor)).toString('base64url');
|
|
16
|
+
}
|
|
17
|
+
export function decodeCursor(filter) {
|
|
18
|
+
if (!filter.cursor)
|
|
19
|
+
return;
|
|
20
|
+
try {
|
|
21
|
+
const decoded = JSON.parse(Buffer.from(filter.cursor, 'base64url').toString('utf8'));
|
|
22
|
+
const cursor = cursorSchema.parse(decoded);
|
|
23
|
+
if (cursor.filter !== filterFingerprint(filter))
|
|
24
|
+
throw new Error('Filter mismatch');
|
|
25
|
+
return { id: cursor.id, createdAt: new Date(cursor.createdAt) };
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new ImageError('INVALID_CURSOR', '分页游标无效或查询条件已改变');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=list-cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-cursor.js","sourceRoot":"","sources":["../../src/domain/list-cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC;IAClC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC;IAC1C,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE;IACZ,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC;AAEH,SAAS,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAkB;IACtF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5F,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAsB,EAAE,GAAoC;IACvF,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;IACzG,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAsB;IACjD,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO;IAC3B,IAAI,CAAC;QACH,MAAM,OAAO,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9F,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,MAAM,CAAC,MAAM,KAAK,iBAAiB,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACpF,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Public metadata only; persistence paths, request fingerprints and credentials stay private. */
|
|
3
|
+
export declare const imageMetadataSchema: z.ZodObject<{
|
|
4
|
+
id: z.ZodUUID;
|
|
5
|
+
originalFilename: z.ZodNullable<z.ZodString>;
|
|
6
|
+
status: z.ZodEnum<{
|
|
7
|
+
deleted: "deleted";
|
|
8
|
+
deleting: "deleting";
|
|
9
|
+
failed: "failed";
|
|
10
|
+
ready: "ready";
|
|
11
|
+
uploading: "uploading";
|
|
12
|
+
}>;
|
|
13
|
+
url: z.ZodNullable<z.ZodURL>;
|
|
14
|
+
mediaType: z.ZodNullable<z.ZodEnum<{
|
|
15
|
+
"image/avif": "image/avif";
|
|
16
|
+
"image/gif": "image/gif";
|
|
17
|
+
"image/jpeg": "image/jpeg";
|
|
18
|
+
"image/png": "image/png";
|
|
19
|
+
"image/webp": "image/webp";
|
|
20
|
+
}>>;
|
|
21
|
+
byteSize: z.ZodNullable<z.ZodNumber>;
|
|
22
|
+
width: z.ZodNullable<z.ZodNumber>;
|
|
23
|
+
height: z.ZodNullable<z.ZodNumber>;
|
|
24
|
+
sha256: z.ZodNullable<z.ZodString>;
|
|
25
|
+
createdBy: z.ZodString;
|
|
26
|
+
createdAt: z.ZodISODateTime;
|
|
27
|
+
readyAt: z.ZodNullable<z.ZodISODateTime>;
|
|
28
|
+
deletedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
29
|
+
failureCode: z.ZodNullable<z.ZodString>;
|
|
30
|
+
}, z.core.$strict>;
|
|
31
|
+
export declare const imagePageSchema: z.ZodObject<{
|
|
32
|
+
items: z.ZodArray<z.ZodObject<{
|
|
33
|
+
id: z.ZodUUID;
|
|
34
|
+
originalFilename: z.ZodNullable<z.ZodString>;
|
|
35
|
+
status: z.ZodEnum<{
|
|
36
|
+
deleted: "deleted";
|
|
37
|
+
deleting: "deleting";
|
|
38
|
+
failed: "failed";
|
|
39
|
+
ready: "ready";
|
|
40
|
+
uploading: "uploading";
|
|
41
|
+
}>;
|
|
42
|
+
url: z.ZodNullable<z.ZodURL>;
|
|
43
|
+
mediaType: z.ZodNullable<z.ZodEnum<{
|
|
44
|
+
"image/avif": "image/avif";
|
|
45
|
+
"image/gif": "image/gif";
|
|
46
|
+
"image/jpeg": "image/jpeg";
|
|
47
|
+
"image/png": "image/png";
|
|
48
|
+
"image/webp": "image/webp";
|
|
49
|
+
}>>;
|
|
50
|
+
byteSize: z.ZodNullable<z.ZodNumber>;
|
|
51
|
+
width: z.ZodNullable<z.ZodNumber>;
|
|
52
|
+
height: z.ZodNullable<z.ZodNumber>;
|
|
53
|
+
sha256: z.ZodNullable<z.ZodString>;
|
|
54
|
+
createdBy: z.ZodString;
|
|
55
|
+
createdAt: z.ZodISODateTime;
|
|
56
|
+
readyAt: z.ZodNullable<z.ZodISODateTime>;
|
|
57
|
+
deletedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
58
|
+
failureCode: z.ZodNullable<z.ZodString>;
|
|
59
|
+
}, z.core.$strict>>;
|
|
60
|
+
hasMore: z.ZodBoolean;
|
|
61
|
+
nextCursor: z.ZodNullable<z.ZodString>;
|
|
62
|
+
}, z.core.$strict>;
|
|
63
|
+
//# sourceMappingURL=output-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-schema.d.ts","sourceRoot":"","sources":["../../src/domain/output-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,kGAAkG;AAClG,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAe9B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAI1B,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { IMAGE_MAX_BYTES, mediaTypeSchema, statusSchema } from './schema.js';
|
|
3
|
+
/** Public metadata only; persistence paths, request fingerprints and credentials stay private. */
|
|
4
|
+
export const imageMetadataSchema = z.strictObject({
|
|
5
|
+
id: z.uuid().describe('不可变图片 ID;用于 read-image、delete-image 和 images://image/{id}。'),
|
|
6
|
+
originalFilename: z.string().max(200).nullable().describe('上传时提供的原始文件名;未提供时为 null,仅作搜索元数据。'),
|
|
7
|
+
status: statusSchema.describe('uploading 上传中;ready 原图可读;failed 上传失败;deleting 原图已禁用、清理中;deleted 已删除。'),
|
|
8
|
+
url: z.url().nullable().describe('仅 ready 状态返回公开原图 URL,其余为 null。公开 GET/HEAD 无需身份或防盗链参数,缓存副本不能随删除撤销。'),
|
|
9
|
+
mediaType: mediaTypeSchema.nullable().describe('服务检测出的真实图片 MIME type;尚未完成检测时为 null。'),
|
|
10
|
+
byteSize: z.number().int().min(1).max(IMAGE_MAX_BYTES).nullable().describe('原始文件字节数;尚未完成检测时为 null,不是 Base64 字符数。'),
|
|
11
|
+
width: z.number().int().positive().nullable().describe('图片宽度,单位像素;尚未完成检测时为 null。'),
|
|
12
|
+
height: z.number().int().positive().nullable().describe('图片高度,单位像素;动画为单帧高度,尚未完成检测时为 null。'),
|
|
13
|
+
sha256: z.string().regex(/^[a-f0-9]{64}$/).nullable().describe('原始字节 SHA-256;删除时用作 expectedSha256,尚未完成检测时为 null。不表示跨图片去重。'),
|
|
14
|
+
createdBy: z.string().min(1).max(128).describe('创建图片的 MCP clientId,缺失时为 subject。'),
|
|
15
|
+
createdAt: z.iso.datetime().describe('数据库记录创建时间,UTC ISO-8601;list-image 时间筛选基于此字段。'),
|
|
16
|
+
readyAt: z.iso.datetime().nullable().describe('原图持久化并提交 ready 的 UTC 时间;未就绪时为 null,删除后保留。'),
|
|
17
|
+
deletedAt: z.iso.datetime().nullable().describe('完成删除的 UTC 时间;未完成时为 null,重复删除保留首次时间。'),
|
|
18
|
+
failureCode: z.string().max(64).nullable().describe('上传失败或启动恢复记录的安全错误码;无失败时为 null,不含底层异常或本地路径。'),
|
|
19
|
+
});
|
|
20
|
+
export const imagePageSchema = z.strictObject({
|
|
21
|
+
items: z.array(imageMetadataSchema).max(100).describe('当前页图片元数据;空结果为 [],不返回图片字节、本地路径或上传幂等键。'),
|
|
22
|
+
hasMore: z.boolean().describe('是否存在下一页;false 时停止翻页。分页不是跨请求的数据库快照。'),
|
|
23
|
+
nextCursor: z.string().min(1).max(2048).nullable().describe('下一页续查值:保持筛选及排序,将此值作为 cursor;hasMore=false 时为 null。'),
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=output-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-schema.js","sourceRoot":"","sources":["../../src/domain/output-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7E,kGAAkG;AAClG,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,YAAY,CAAC;IAChD,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;IACnF,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;IAC5F,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,sEAAsE,CAAC;IACrG,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mEAAmE,CAAC;IACrG,SAAS,EAAE,eAAe,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IACrF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAClH,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;IAClF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAC3F,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2DAA2D,CAAC;IAC3H,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IAClF,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;IACpF,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;IAC1F,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IACtF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;CACjG,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,YAAY,CAAC;IAC5C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAC7F,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;IACnE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;CAClH,CAAC,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const IMAGE_MAX_BYTES: number;
|
|
3
|
+
export declare const BASE64_MAX_BYTES: number;
|
|
4
|
+
export declare const mediaTypeSchema: z.ZodEnum<{
|
|
5
|
+
"image/avif": "image/avif";
|
|
6
|
+
"image/gif": "image/gif";
|
|
7
|
+
"image/jpeg": "image/jpeg";
|
|
8
|
+
"image/png": "image/png";
|
|
9
|
+
"image/webp": "image/webp";
|
|
10
|
+
}>;
|
|
11
|
+
export declare const statusSchema: z.ZodEnum<{
|
|
12
|
+
deleted: "deleted";
|
|
13
|
+
deleting: "deleting";
|
|
14
|
+
failed: "failed";
|
|
15
|
+
ready: "ready";
|
|
16
|
+
uploading: "uploading";
|
|
17
|
+
}>;
|
|
18
|
+
export declare const uploadImageSchema: z.ZodObject<{
|
|
19
|
+
idempotencyKey: z.ZodString;
|
|
20
|
+
filename: z.ZodOptional<z.ZodString>;
|
|
21
|
+
source: z.ZodLiteral<"base64">;
|
|
22
|
+
base64: z.ZodString;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
export declare const readImageSchema: z.ZodObject<{
|
|
25
|
+
id: z.ZodUUID;
|
|
26
|
+
}, z.core.$strict>;
|
|
27
|
+
export declare const deleteImageSchema: z.ZodObject<{
|
|
28
|
+
id: z.ZodUUID;
|
|
29
|
+
expectedSha256: z.ZodString;
|
|
30
|
+
}, z.core.$strict>;
|
|
31
|
+
export declare const listImageSchema: z.ZodObject<{
|
|
32
|
+
createdFrom: z.ZodOptional<z.ZodPipe<z.ZodISODateTime, z.ZodTransform<string, string>>>;
|
|
33
|
+
createdTo: z.ZodOptional<z.ZodPipe<z.ZodISODateTime, z.ZodTransform<string, string>>>;
|
|
34
|
+
mediaTypes: z.ZodOptional<z.ZodPipe<z.ZodArray<z.ZodEnum<{
|
|
35
|
+
"image/avif": "image/avif";
|
|
36
|
+
"image/gif": "image/gif";
|
|
37
|
+
"image/jpeg": "image/jpeg";
|
|
38
|
+
"image/png": "image/png";
|
|
39
|
+
"image/webp": "image/webp";
|
|
40
|
+
}>>, z.ZodTransform<("image/avif" | "image/gif" | "image/jpeg" | "image/png" | "image/webp")[], ("image/avif" | "image/gif" | "image/jpeg" | "image/png" | "image/webp")[]>>>;
|
|
41
|
+
filenameContains: z.ZodOptional<z.ZodString>;
|
|
42
|
+
minBytes: z.ZodOptional<z.ZodNumber>;
|
|
43
|
+
maxBytes: z.ZodOptional<z.ZodNumber>;
|
|
44
|
+
minWidth: z.ZodOptional<z.ZodNumber>;
|
|
45
|
+
maxWidth: z.ZodOptional<z.ZodNumber>;
|
|
46
|
+
minHeight: z.ZodOptional<z.ZodNumber>;
|
|
47
|
+
maxHeight: z.ZodOptional<z.ZodNumber>;
|
|
48
|
+
statuses: z.ZodPipe<z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
49
|
+
deleted: "deleted";
|
|
50
|
+
deleting: "deleting";
|
|
51
|
+
failed: "failed";
|
|
52
|
+
ready: "ready";
|
|
53
|
+
uploading: "uploading";
|
|
54
|
+
}>>>, z.ZodTransform<("deleted" | "deleting" | "failed" | "ready" | "uploading")[], ("deleted" | "deleting" | "failed" | "ready" | "uploading")[]>>;
|
|
55
|
+
createdBy: z.ZodOptional<z.ZodString>;
|
|
56
|
+
sha256: z.ZodOptional<z.ZodString>;
|
|
57
|
+
order: z.ZodDefault<z.ZodEnum<{
|
|
58
|
+
asc: "asc";
|
|
59
|
+
desc: "desc";
|
|
60
|
+
}>>;
|
|
61
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
62
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
63
|
+
}, z.core.$strict>;
|
|
64
|
+
export type ListImageInput = z.infer<typeof listImageSchema>;
|
|
65
|
+
export type ListImageRequest = z.input<typeof listImageSchema>;
|
|
66
|
+
export type ReadImageInput = z.infer<typeof readImageSchema>;
|
|
67
|
+
export type UploadImageInput = z.infer<typeof uploadImageSchema>;
|
|
68
|
+
export type DeleteImageInput = z.infer<typeof deleteImageSchema>;
|
|
69
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/domain/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,eAAe,QAAmB,CAAC;AAChD,eAAO,MAAM,gBAAgB,QAAkB,CAAC;AAChD,eAAO,MAAM,eAAe;;;;;;EAA+E,CAAC;AAC5G,eAAO,MAAM,YAAY;;;;;;EAAkE,CAAC;AAK5F,eAAO,MAAM,iBAAiB;;;;;kBAG5B,CAAC;AACH,eAAO,MAAM,eAAe;;kBAA+F,CAAC;AAC5H,eAAO,MAAM,iBAAiB;;;kBAA0K,CAAC;AAIzM,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsB1B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC7D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC/D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC7D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACjE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
|