@rakun-kit/core 1.7.0 → 1.7.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/README.md +9 -1
- package/dist/cjs/media/index.js +1 -0
- package/dist/cjs/media/index.js.map +1 -1
- package/dist/cjs/media/publicMedia.js +114 -0
- package/dist/cjs/media/publicMedia.js.map +1 -0
- package/dist/docs/index.md +6 -2
- package/dist/esm/media/adapters/index.d.ts +20 -0
- package/dist/esm/media/adapters/index.d.ts.map +1 -1
- package/dist/esm/media/index.d.ts +1 -0
- package/dist/esm/media/index.d.ts.map +1 -1
- package/dist/esm/media/index.js +1 -0
- package/dist/esm/media/index.js.map +1 -1
- package/dist/esm/media/publicMedia.d.ts +7 -0
- package/dist/esm/media/publicMedia.d.ts.map +1 -0
- package/dist/esm/media/publicMedia.js +109 -0
- package/dist/esm/media/publicMedia.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1153,7 +1153,15 @@ APIs:
|
|
|
1153
1153
|
- `getMediaService()`: returns the singleton or creates it from config.
|
|
1154
1154
|
- `handleMediaBinaryUpload`: processes manager binary uploads.
|
|
1155
1155
|
|
|
1156
|
-
The service supports prepare/finalize upload, URL generation, folders, and media optimization depending on adapter/configuration. Manager uploads encode original file names for transport, so Unicode names (including accents, non-Latin scripts, and emoji) are preserved without placing invalid characters in HTTP headers.
|
|
1156
|
+
The service supports prepare/finalize upload, URL generation, folders, and media optimization depending on adapter/configuration. Manager uploads encode original file names for transport, so Unicode names (including accents, non-Latin scripts, and emoji) are preserved without placing invalid characters in HTTP headers.
|
|
1157
|
+
|
|
1158
|
+
Adapters can implement `getPublicObject` to let every Rakun server adapter proxy
|
|
1159
|
+
public media at its normal `/media/public/<key>` API route. This keeps browser
|
|
1160
|
+
URLs stable even when the object store is private or only supports expiring
|
|
1161
|
+
presigned URLs. The core handler validates the key under `public/`, forwards
|
|
1162
|
+
byte ranges, preserves object metadata, and applies long-lived caching by
|
|
1163
|
+
default. The storage adapter receives server-side credentials; never expose its
|
|
1164
|
+
presigned storage URL as the public media URL.
|
|
1157
1165
|
|
|
1158
1166
|
Optimized video uploads use the `ffmpeg-static` peer dependency and produce an MP4 primary object plus MP4 and WebM entries in `sources`. Existing image-only optimize options remain compatible; use `video: { quality: 80 }` to configure video quality explicitly.
|
|
1159
1167
|
|
package/dist/cjs/media/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/media/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAoBA,gDAWC;AAED,0CAYC;AA5CD,iDAGwB;AASxB,IAAI,aAA2B,CAAC;AAChC,IAAI,OAA2B,CAAC;AAEzB,MAAM,qBAAqB,GAAG,CAAC,MAA0B,EAAE,EAAE;IAClE,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC,CAAC;AAFW,QAAA,qBAAqB,yBAEhC;AAEF,SAAgB,kBAAkB,CAAC,MAA0B;IAC3D,OAAO,GAAG,MAAM,CAAC;IAEjB,aAAa,GAAG,IAAA,4CAA6B,EAAC;QAC5C,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,0BAA0B,EAAE,MAAM,CAAC,0BAA0B;QAC7D,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;IAEH,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAgB,eAAe;IAC7B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;QACJ,CAAC;QAED,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,iDAA+B;AAC/B,6CAA2B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/media/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAoBA,gDAWC;AAED,0CAYC;AA5CD,iDAGwB;AASxB,IAAI,aAA2B,CAAC;AAChC,IAAI,OAA2B,CAAC;AAEzB,MAAM,qBAAqB,GAAG,CAAC,MAA0B,EAAE,EAAE;IAClE,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC,CAAC;AAFW,QAAA,qBAAqB,yBAEhC;AAEF,SAAgB,kBAAkB,CAAC,MAA0B;IAC3D,OAAO,GAAG,MAAM,CAAC;IAEjB,aAAa,GAAG,IAAA,4CAA6B,EAAC;QAC5C,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,0BAA0B,EAAE,MAAM,CAAC,0BAA0B;QAC7D,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;IAEH,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,SAAgB,eAAe;IAC7B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;QACJ,CAAC;QAED,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,iDAA+B;AAC/B,6CAA2B;AAC3B,gDAA6B"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handlePublicMediaRequest = exports.getPublicMediaKey = void 0;
|
|
4
|
+
const index_1 = require("./index");
|
|
5
|
+
const DEFAULT_CACHE_CONTROL = 'public, max-age=31536000, immutable';
|
|
6
|
+
const decodePathSegment = (segment) => {
|
|
7
|
+
try {
|
|
8
|
+
const value = decodeURIComponent(segment);
|
|
9
|
+
if (!value || value === '.' || value === '..' || value.includes('/'))
|
|
10
|
+
return null;
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const getPublicMediaKey = (pathSegments) => {
|
|
18
|
+
if (pathSegments.length === 0)
|
|
19
|
+
return null;
|
|
20
|
+
const segments = pathSegments.map(decodePathSegment);
|
|
21
|
+
if (segments.some((segment) => segment === null))
|
|
22
|
+
return null;
|
|
23
|
+
return `public/${segments.join('/')}`;
|
|
24
|
+
};
|
|
25
|
+
exports.getPublicMediaKey = getPublicMediaKey;
|
|
26
|
+
const errorResponse = (status) => new Response(null, { status });
|
|
27
|
+
const isNotFoundError = (error) => {
|
|
28
|
+
if (!error || typeof error !== 'object')
|
|
29
|
+
return false;
|
|
30
|
+
const value = error;
|
|
31
|
+
return (value.name === 'NotFound' ||
|
|
32
|
+
value.name === 'NoSuchKey' ||
|
|
33
|
+
value.code === 'NotFound' ||
|
|
34
|
+
value.code === 'NoSuchKey' ||
|
|
35
|
+
value.$metadata?.httpStatusCode === 404);
|
|
36
|
+
};
|
|
37
|
+
const getErrorStatus = (error) => {
|
|
38
|
+
if (isNotFoundError(error))
|
|
39
|
+
return 404;
|
|
40
|
+
const status = error && typeof error === 'object'
|
|
41
|
+
? error.$metadata?.httpStatusCode
|
|
42
|
+
: undefined;
|
|
43
|
+
if (status === 416) {
|
|
44
|
+
return 416;
|
|
45
|
+
}
|
|
46
|
+
return 502;
|
|
47
|
+
};
|
|
48
|
+
const setDateHeader = (headers, name, value) => {
|
|
49
|
+
if (!value)
|
|
50
|
+
return;
|
|
51
|
+
headers.set(name, value instanceof Date ? value.toUTCString() : value);
|
|
52
|
+
};
|
|
53
|
+
const buildHeaders = (object) => {
|
|
54
|
+
const headers = new Headers({
|
|
55
|
+
'Cache-Control': object.cacheControl ?? DEFAULT_CACHE_CONTROL,
|
|
56
|
+
'X-Content-Type-Options': 'nosniff',
|
|
57
|
+
});
|
|
58
|
+
if (object.acceptRanges)
|
|
59
|
+
headers.set('Accept-Ranges', object.acceptRanges);
|
|
60
|
+
if (object.contentDisposition)
|
|
61
|
+
headers.set('Content-Disposition', object.contentDisposition);
|
|
62
|
+
if (object.contentEncoding)
|
|
63
|
+
headers.set('Content-Encoding', object.contentEncoding);
|
|
64
|
+
if (object.contentLanguage)
|
|
65
|
+
headers.set('Content-Language', object.contentLanguage);
|
|
66
|
+
if (object.contentLength !== undefined)
|
|
67
|
+
headers.set('Content-Length', String(object.contentLength));
|
|
68
|
+
if (object.contentRange)
|
|
69
|
+
headers.set('Content-Range', object.contentRange);
|
|
70
|
+
if (object.contentType)
|
|
71
|
+
headers.set('Content-Type', object.contentType);
|
|
72
|
+
if (object.etag)
|
|
73
|
+
headers.set('ETag', object.etag);
|
|
74
|
+
setDateHeader(headers, 'Expires', object.expires);
|
|
75
|
+
setDateHeader(headers, 'Last-Modified', object.lastModified);
|
|
76
|
+
return headers;
|
|
77
|
+
};
|
|
78
|
+
const handlePublicMediaRequest = async ({ request, pathSegments, }) => {
|
|
79
|
+
if (request.method !== 'GET' && request.method !== 'HEAD')
|
|
80
|
+
return null;
|
|
81
|
+
let adapter;
|
|
82
|
+
try {
|
|
83
|
+
adapter = (0, index_1.getMediaService)().rawAdapter;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
if (!adapter.getPublicObject)
|
|
89
|
+
return null;
|
|
90
|
+
const key = (0, exports.getPublicMediaKey)(pathSegments);
|
|
91
|
+
if (!key)
|
|
92
|
+
return errorResponse(404);
|
|
93
|
+
try {
|
|
94
|
+
const object = await adapter.getPublicObject({
|
|
95
|
+
key,
|
|
96
|
+
method: request.method,
|
|
97
|
+
range: request.headers.get('Range') ?? undefined,
|
|
98
|
+
});
|
|
99
|
+
const headers = buildHeaders(object);
|
|
100
|
+
const status = object.status ?? (object.contentRange ? 206 : 200);
|
|
101
|
+
if (request.headers.get('If-None-Match') === object.etag) {
|
|
102
|
+
return new Response(null, { status: 304, headers });
|
|
103
|
+
}
|
|
104
|
+
return new Response(request.method === 'HEAD' ? null : object.body ?? null, {
|
|
105
|
+
status,
|
|
106
|
+
headers,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
return errorResponse(getErrorStatus(error));
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
exports.handlePublicMediaRequest = handlePublicMediaRequest;
|
|
114
|
+
//# sourceMappingURL=publicMedia.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publicMedia.js","sourceRoot":"","sources":["../../../src/media/publicMedia.ts"],"names":[],"mappings":"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"}
|
package/dist/docs/index.md
CHANGED
|
@@ -475,8 +475,12 @@ blocking. Account recovery requires both a mail service and
|
|
|
475
475
|
|
|
476
476
|
Core defines service contracts; concrete integrations are separate:
|
|
477
477
|
|
|
478
|
-
- Media: use `@rakun-kit/s3`, or local media from the selected framework
|
|
479
|
-
adapter. Configure the result as `media` in bootstrap.
|
|
478
|
+
- Media: use `@rakun-kit/s3`, or local media from the selected framework
|
|
479
|
+
adapter. Configure the result as `media` in bootstrap.
|
|
480
|
+
- Storage adapters may expose `getPublicObject`; Next.js, Express and Bun then
|
|
481
|
+
serve public media through their normal `/media/public/<key>` API route. This
|
|
482
|
+
gives public Rakun media a stable application URL while the backing object
|
|
483
|
+
store remains private or uses expiring storage URLs.
|
|
480
484
|
- Mail: use `@rakun-kit/smtp` or `@rakun-kit/resend`; optionally render typed
|
|
481
485
|
templates with `@rakun-kit/jsx-email`. Configure delivery as `mail`.
|
|
482
486
|
- Translation: use `@rakun-kit/openai` or implement the core translation
|
|
@@ -4,6 +4,21 @@ export type PresignedPut = {
|
|
|
4
4
|
headers?: Record<string, string>;
|
|
5
5
|
key: string;
|
|
6
6
|
};
|
|
7
|
+
export type PublicMediaObject = {
|
|
8
|
+
body?: ReadableStream<Uint8Array>;
|
|
9
|
+
status?: number;
|
|
10
|
+
acceptRanges?: string;
|
|
11
|
+
cacheControl?: string;
|
|
12
|
+
contentDisposition?: string;
|
|
13
|
+
contentEncoding?: string;
|
|
14
|
+
contentLanguage?: string;
|
|
15
|
+
contentLength?: number;
|
|
16
|
+
contentRange?: string;
|
|
17
|
+
contentType?: string;
|
|
18
|
+
etag?: string;
|
|
19
|
+
expires?: Date | string;
|
|
20
|
+
lastModified?: Date | string;
|
|
21
|
+
};
|
|
7
22
|
export interface StorageAdapter {
|
|
8
23
|
createPresignedPut(input: {
|
|
9
24
|
key: string;
|
|
@@ -41,5 +56,10 @@ export interface StorageAdapter {
|
|
|
41
56
|
key: string;
|
|
42
57
|
access: MediaAccess;
|
|
43
58
|
}): string | null;
|
|
59
|
+
getPublicObject?(input: {
|
|
60
|
+
key: string;
|
|
61
|
+
method: 'GET' | 'HEAD';
|
|
62
|
+
range?: string;
|
|
63
|
+
}): Promise<PublicMediaObject>;
|
|
44
64
|
}
|
|
45
65
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/media/adapters/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAA;AAE9C,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,WAAW,cAAc;IAC7B,kBAAkB,CAAC,KAAK,EAAE;QACxB,GAAG,EAAE,MAAM,CAAA;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,WAAW,CAAA;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAEzB,SAAS,CAAC,KAAK,EAAE;QACf,GAAG,EAAE,MAAM,CAAA;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,UAAU,CAAA;QACnB,MAAM,EAAE,WAAW,CAAA;KACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjB,UAAU,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC;QAC/D,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAC,CAAA;IAEF,kBAAkB,CAAC,KAAK,EAAE;QACxB,GAAG,EAAE,MAAM,CAAA;QACX,MAAM,EAAE,WAAW,CAAA;QACnB,gBAAgB,EAAE,MAAM,CAAA;KACzB,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,CAAC,CAAA;IAE7C,YAAY,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAExE,SAAS,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,MAAM,GAAG,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/media/adapters/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAA;AAE9C,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;CAC7B,CAAA;AAED,MAAM,WAAW,cAAc;IAC7B,kBAAkB,CAAC,KAAK,EAAE;QACxB,GAAG,EAAE,MAAM,CAAA;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,WAAW,CAAA;KACpB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAEzB,SAAS,CAAC,KAAK,EAAE;QACf,GAAG,EAAE,MAAM,CAAA;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,UAAU,CAAA;QACnB,MAAM,EAAE,WAAW,CAAA;KACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjB,UAAU,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC;QAC/D,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,IAAI,CAAC,EAAE,MAAM,CAAA;KACd,CAAC,CAAA;IAEF,kBAAkB,CAAC,KAAK,EAAE;QACxB,GAAG,EAAE,MAAM,CAAA;QACX,MAAM,EAAE,WAAW,CAAA;QACnB,gBAAgB,EAAE,MAAM,CAAA;KACzB,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,CAAC,CAAA;IAE7C,YAAY,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAExE,SAAS,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,GAAG,MAAM,GAAG,IAAI,CAAA;IAErE,eAAe,CAAC,CAAC,KAAK,EAAE;QACtB,GAAG,EAAE,MAAM,CAAA;QACX,MAAM,EAAE,KAAK,GAAG,MAAM,CAAA;QACtB,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;CAC/B"}
|
|
@@ -11,4 +11,5 @@ export declare function createMediaService(config: MediaServiceConfig): MediaSer
|
|
|
11
11
|
export declare function getMediaService(): MediaService;
|
|
12
12
|
export * from "./mediaService.js";
|
|
13
13
|
export * from "./adapters/index.js";
|
|
14
|
+
export * from './publicMedia.js';
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/media/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,cAAc,CAAC;IACxB,aAAa,CAAC,EAAE,WAAW,CAAC;IAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,kBAAkB,SAE/D,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAW3E;AAED,wBAAgB,eAAe,IAAI,YAAY,CAY9C;AAED,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/media/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,cAAc,CAAC;IACxB,aAAa,CAAC,EAAE,WAAW,CAAC;IAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,kBAAkB,SAE/D,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAW3E;AAED,wBAAgB,eAAe,IAAI,YAAY,CAY9C;AAED,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAA"}
|
package/dist/esm/media/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/media/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,6BAA6B,GAE9B,MAAM,gBAAgB,CAAC;AASxB,IAAI,aAA2B,CAAC;AAChC,IAAI,OAA2B,CAAC;AAEhC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAA0B,EAAE,EAAE;IAClE,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,MAA0B;IAC3D,OAAO,GAAG,MAAM,CAAC;IAEjB,aAAa,GAAG,6BAA6B,CAAC;QAC5C,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,0BAA0B,EAAE,MAAM,CAAC,0BAA0B;QAC7D,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;IAEH,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;QACJ,CAAC;QAED,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/media/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,6BAA6B,GAE9B,MAAM,gBAAgB,CAAC;AASxB,IAAI,aAA2B,CAAC;AAChC,IAAI,OAA2B,CAAC;AAEhC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAA0B,EAAE,EAAE;IAClE,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,MAA0B;IAC3D,OAAO,GAAG,MAAM,CAAC;IAEjB,aAAa,GAAG,6BAA6B,CAAC;QAC5C,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,0BAA0B,EAAE,MAAM,CAAC,0BAA0B;QAC7D,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;IAEH,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;QACJ,CAAC;QAED,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type HandlePublicMediaRequestInput = {
|
|
2
|
+
request: Request;
|
|
3
|
+
pathSegments: string[];
|
|
4
|
+
};
|
|
5
|
+
export declare const getPublicMediaKey: (pathSegments: string[]) => string | null;
|
|
6
|
+
export declare const handlePublicMediaRequest: ({ request, pathSegments, }: HandlePublicMediaRequestInput) => Promise<Response | null>;
|
|
7
|
+
//# sourceMappingURL=publicMedia.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publicMedia.d.ts","sourceRoot":"","sources":["../../../src/media/publicMedia.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB,CAAA;AAYD,eAAO,MAAM,iBAAiB,GAAI,cAAc,MAAM,EAAE,KAAG,MAAM,GAAG,IAOnE,CAAA;AAoED,eAAO,MAAM,wBAAwB,GAAU,4BAG5C,6BAA6B,KAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAkCzD,CAAA"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { getMediaService } from './index.js';
|
|
2
|
+
const DEFAULT_CACHE_CONTROL = 'public, max-age=31536000, immutable';
|
|
3
|
+
const decodePathSegment = (segment) => {
|
|
4
|
+
try {
|
|
5
|
+
const value = decodeURIComponent(segment);
|
|
6
|
+
if (!value || value === '.' || value === '..' || value.includes('/'))
|
|
7
|
+
return null;
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
export const getPublicMediaKey = (pathSegments) => {
|
|
15
|
+
if (pathSegments.length === 0)
|
|
16
|
+
return null;
|
|
17
|
+
const segments = pathSegments.map(decodePathSegment);
|
|
18
|
+
if (segments.some((segment) => segment === null))
|
|
19
|
+
return null;
|
|
20
|
+
return `public/${segments.join('/')}`;
|
|
21
|
+
};
|
|
22
|
+
const errorResponse = (status) => new Response(null, { status });
|
|
23
|
+
const isNotFoundError = (error) => {
|
|
24
|
+
if (!error || typeof error !== 'object')
|
|
25
|
+
return false;
|
|
26
|
+
const value = error;
|
|
27
|
+
return (value.name === 'NotFound' ||
|
|
28
|
+
value.name === 'NoSuchKey' ||
|
|
29
|
+
value.code === 'NotFound' ||
|
|
30
|
+
value.code === 'NoSuchKey' ||
|
|
31
|
+
value.$metadata?.httpStatusCode === 404);
|
|
32
|
+
};
|
|
33
|
+
const getErrorStatus = (error) => {
|
|
34
|
+
if (isNotFoundError(error))
|
|
35
|
+
return 404;
|
|
36
|
+
const status = error && typeof error === 'object'
|
|
37
|
+
? error.$metadata?.httpStatusCode
|
|
38
|
+
: undefined;
|
|
39
|
+
if (status === 416) {
|
|
40
|
+
return 416;
|
|
41
|
+
}
|
|
42
|
+
return 502;
|
|
43
|
+
};
|
|
44
|
+
const setDateHeader = (headers, name, value) => {
|
|
45
|
+
if (!value)
|
|
46
|
+
return;
|
|
47
|
+
headers.set(name, value instanceof Date ? value.toUTCString() : value);
|
|
48
|
+
};
|
|
49
|
+
const buildHeaders = (object) => {
|
|
50
|
+
const headers = new Headers({
|
|
51
|
+
'Cache-Control': object.cacheControl ?? DEFAULT_CACHE_CONTROL,
|
|
52
|
+
'X-Content-Type-Options': 'nosniff',
|
|
53
|
+
});
|
|
54
|
+
if (object.acceptRanges)
|
|
55
|
+
headers.set('Accept-Ranges', object.acceptRanges);
|
|
56
|
+
if (object.contentDisposition)
|
|
57
|
+
headers.set('Content-Disposition', object.contentDisposition);
|
|
58
|
+
if (object.contentEncoding)
|
|
59
|
+
headers.set('Content-Encoding', object.contentEncoding);
|
|
60
|
+
if (object.contentLanguage)
|
|
61
|
+
headers.set('Content-Language', object.contentLanguage);
|
|
62
|
+
if (object.contentLength !== undefined)
|
|
63
|
+
headers.set('Content-Length', String(object.contentLength));
|
|
64
|
+
if (object.contentRange)
|
|
65
|
+
headers.set('Content-Range', object.contentRange);
|
|
66
|
+
if (object.contentType)
|
|
67
|
+
headers.set('Content-Type', object.contentType);
|
|
68
|
+
if (object.etag)
|
|
69
|
+
headers.set('ETag', object.etag);
|
|
70
|
+
setDateHeader(headers, 'Expires', object.expires);
|
|
71
|
+
setDateHeader(headers, 'Last-Modified', object.lastModified);
|
|
72
|
+
return headers;
|
|
73
|
+
};
|
|
74
|
+
export const handlePublicMediaRequest = async ({ request, pathSegments, }) => {
|
|
75
|
+
if (request.method !== 'GET' && request.method !== 'HEAD')
|
|
76
|
+
return null;
|
|
77
|
+
let adapter;
|
|
78
|
+
try {
|
|
79
|
+
adapter = getMediaService().rawAdapter;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
if (!adapter.getPublicObject)
|
|
85
|
+
return null;
|
|
86
|
+
const key = getPublicMediaKey(pathSegments);
|
|
87
|
+
if (!key)
|
|
88
|
+
return errorResponse(404);
|
|
89
|
+
try {
|
|
90
|
+
const object = await adapter.getPublicObject({
|
|
91
|
+
key,
|
|
92
|
+
method: request.method,
|
|
93
|
+
range: request.headers.get('Range') ?? undefined,
|
|
94
|
+
});
|
|
95
|
+
const headers = buildHeaders(object);
|
|
96
|
+
const status = object.status ?? (object.contentRange ? 206 : 200);
|
|
97
|
+
if (request.headers.get('If-None-Match') === object.etag) {
|
|
98
|
+
return new Response(null, { status: 304, headers });
|
|
99
|
+
}
|
|
100
|
+
return new Response(request.method === 'HEAD' ? null : object.body ?? null, {
|
|
101
|
+
status,
|
|
102
|
+
headers,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
return errorResponse(getErrorStatus(error));
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=publicMedia.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publicMedia.js","sourceRoot":"","sources":["../../../src/media/publicMedia.ts"],"names":[],"mappings":"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"}
|