@webiny/api-file-manager 6.6.0-alpha.0 → 6.6.0-alpha.2
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/FileManagerAppFeature.js +4 -4
- package/FileManagerAppFeature.js.map +1 -1
- package/delivery/AssetDelivery/AssetRequest.d.ts +1 -1
- package/delivery/AssetDelivery/AssetRequest.js.map +1 -1
- package/delivery/AssetDeliveryRoute.d.ts +15 -6
- package/delivery/AssetDeliveryRoute.js +25 -32
- package/delivery/AssetDeliveryRoute.js.map +1 -1
- package/domain/file/abstractions.d.ts +13 -5
- package/domain/file/abstractions.js +2 -2
- package/domain/file/abstractions.js.map +1 -1
- package/domain/file/file.model.d.ts +3 -3
- package/domain/file/file.model.js +10 -6
- package/domain/file/file.model.js.map +1 -1
- package/features/assetDelivery/abstractions/AssetType.d.ts +17 -0
- package/features/assetDelivery/abstractions/AssetType.js +5 -0
- package/features/assetDelivery/abstractions/AssetType.js.map +1 -0
- package/features/assetDelivery/{transformation → assetTypes/image}/AssetKeyGenerator.d.ts +5 -2
- package/features/assetDelivery/assetTypes/image/AssetKeyGenerator.js +30 -0
- package/features/assetDelivery/assetTypes/image/AssetKeyGenerator.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetType.d.ts +9 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetType.js +18 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetType.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetTypeHandler.d.ts +5 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetTypeHandler.js +5 -0
- package/features/assetDelivery/assetTypes/image/ImageAssetTypeHandler.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/SharpTransformer.d.ts +18 -0
- package/features/assetDelivery/assetTypes/image/SharpTransformer.js +47 -0
- package/features/assetDelivery/assetTypes/image/SharpTransformer.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/WidthCollection.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/imageFormat.d.ts +26 -0
- package/features/assetDelivery/assetTypes/image/imageFormat.js +51 -0
- package/features/assetDelivery/assetTypes/image/imageFormat.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/imageTypes.d.ts +39 -0
- package/features/assetDelivery/assetTypes/image/imageTypes.js +0 -0
- package/features/assetDelivery/assetTypes/image/index.d.ts +5 -0
- package/features/assetDelivery/assetTypes/image/index.js +4 -0
- package/features/assetDelivery/assetTypes/image/normalizeImageOptions.d.ts +6 -0
- package/features/assetDelivery/assetTypes/image/normalizeImageOptions.js +56 -0
- package/features/assetDelivery/assetTypes/image/normalizeImageOptions.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/transformImage.d.ts +59 -0
- package/features/assetDelivery/assetTypes/image/transformImage.js +146 -0
- package/features/assetDelivery/assetTypes/image/transformImage.js.map +1 -0
- package/features/assetDelivery/assetTypes/image/utils.d.ts +26 -0
- package/features/assetDelivery/assetTypes/image/utils.js +47 -0
- package/features/assetDelivery/assetTypes/image/utils.js.map +1 -0
- package/features/assetDelivery/feature.js +7 -7
- package/features/assetDelivery/feature.js.map +1 -1
- package/features/assetDelivery/privateFiles/PrivateFilesAssetProcessor.js.map +1 -1
- package/features/assetDelivery/transformation/TransformationAssetProcessor.d.ts +4 -6
- package/features/assetDelivery/transformation/TransformationAssetProcessor.js +13 -11
- package/features/assetDelivery/transformation/TransformationAssetProcessor.js.map +1 -1
- package/features/assetDelivery/transformation/index.d.ts +4 -3
- package/features/assetDelivery/transformation/index.js +3 -3
- package/features/file/CreateFile/CreateFileRepository.d.ts +3 -3
- package/features/file/CreateFile/CreateFileRepository.js +6 -5
- package/features/file/CreateFile/CreateFileRepository.js.map +1 -1
- package/features/file/DeleteFile/DeleteFileRepository.d.ts +3 -3
- package/features/file/DeleteFile/DeleteFileRepository.js +6 -5
- package/features/file/DeleteFile/DeleteFileRepository.js.map +1 -1
- package/features/file/FileModelProvider.d.ts +31 -0
- package/features/file/FileModelProvider.js +22 -0
- package/features/file/FileModelProvider.js.map +1 -0
- package/features/file/GetFile/GetFileRepository.d.ts +3 -3
- package/features/file/GetFile/GetFileRepository.js +6 -5
- package/features/file/GetFile/GetFileRepository.js.map +1 -1
- package/features/file/ListFiles/ListFilesRepository.d.ts +3 -3
- package/features/file/ListFiles/ListFilesRepository.js +8 -7
- package/features/file/ListFiles/ListFilesRepository.js.map +1 -1
- package/features/file/ListImagesByTagTool/ListImagesByTagTool.d.ts +5 -0
- package/features/file/ListImagesByTagTool/ListImagesByTagTool.js +5 -0
- package/features/file/ListImagesByTagTool/ListImagesByTagTool.js.map +1 -1
- package/features/file/ListTags/ListTagsRepository.d.ts +3 -3
- package/features/file/ListTags/ListTagsRepository.js +7 -6
- package/features/file/ListTags/ListTagsRepository.js.map +1 -1
- package/features/file/UpdateFile/UpdateFileRepository.d.ts +3 -3
- package/features/file/UpdateFile/UpdateFileRepository.js +6 -5
- package/features/file/UpdateFile/UpdateFileRepository.js.map +1 -1
- package/features/upload/WriteFileMetadata/WriteMetadataAfterUpdateHandler.d.ts +11 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterUpdateHandler.js +22 -0
- package/features/upload/WriteFileMetadata/WriteMetadataAfterUpdateHandler.js.map +1 -0
- package/features/upload/WriteFileMetadata/feature.js +2 -0
- package/features/upload/WriteFileMetadata/feature.js.map +1 -1
- package/graphql/FmGraphQLSchema.d.ts +3 -3
- package/graphql/FmGraphQLSchema.js +13 -12
- package/graphql/FmGraphQLSchema.js.map +1 -1
- package/package.json +17 -18
- package/features/FileModelContextualSchema.d.ts +0 -13
- package/features/FileModelContextualSchema.js +0 -31
- package/features/FileModelContextualSchema.js.map +0 -1
- package/features/assetDelivery/transformation/AssetKeyGenerator.js +0 -24
- package/features/assetDelivery/transformation/AssetKeyGenerator.js.map +0 -1
- package/features/assetDelivery/transformation/PassthroughAssetTransformationStrategy.d.ts +0 -9
- package/features/assetDelivery/transformation/PassthroughAssetTransformationStrategy.js +0 -13
- package/features/assetDelivery/transformation/PassthroughAssetTransformationStrategy.js.map +0 -1
- package/features/assetDelivery/transformation/WidthCollection.js.map +0 -1
- package/features/assetDelivery/transformation/utils.d.ts +0 -9
- package/features/assetDelivery/transformation/utils.js +0 -31
- package/features/assetDelivery/transformation/utils.js.map +0 -1
- /package/features/assetDelivery/{transformation → assetTypes/image}/WidthCollection.d.ts +0 -0
- /package/features/assetDelivery/{transformation → assetTypes/image}/WidthCollection.js +0 -0
package/FileManagerAppFeature.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { createFeature } from "@webiny/feature/api";
|
|
2
2
|
import { AssetDeliveryFeature } from "./features/assetDelivery/feature.js";
|
|
3
|
-
import {
|
|
3
|
+
import { AssetDeliveryRouteDefinition } from "./delivery/AssetDeliveryRoute.js";
|
|
4
4
|
import { FileModel } from "./domain/file/file.model.js";
|
|
5
5
|
import { FmPermissionsFeature } from "./features/permissions/feature.js";
|
|
6
6
|
import { FileManagerFeature } from "./features/FileManagerFeature.js";
|
|
7
|
-
import {
|
|
7
|
+
import { FileModelProvider } from "./features/file/FileModelProvider.js";
|
|
8
8
|
const FileManagerAppFeature = createFeature({
|
|
9
9
|
name: "FileManagerApp",
|
|
10
10
|
register (container) {
|
|
11
11
|
AssetDeliveryFeature.register(container);
|
|
12
|
-
container.register(
|
|
12
|
+
container.register(AssetDeliveryRouteDefinition);
|
|
13
13
|
container.register(FileModel);
|
|
14
14
|
FmPermissionsFeature.register(container);
|
|
15
15
|
FileManagerFeature.register(container);
|
|
16
|
-
container.register(
|
|
16
|
+
container.register(FileModelProvider);
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
export { FileManagerAppFeature };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileManagerAppFeature.js","sources":["../src/FileManagerAppFeature.ts"],"sourcesContent":["import { type Container, createFeature } from \"@webiny/feature/api\";\nimport { AssetDeliveryFeature } from \"~/features/assetDelivery/feature.js\";\nimport {
|
|
1
|
+
{"version":3,"file":"FileManagerAppFeature.js","sources":["../src/FileManagerAppFeature.ts"],"sourcesContent":["import { type Container, createFeature } from \"@webiny/feature/api\";\nimport { AssetDeliveryFeature } from \"~/features/assetDelivery/feature.js\";\nimport { AssetDeliveryRouteDefinition } from \"./delivery/AssetDeliveryRoute.js\";\nimport { FileModel } from \"~/domain/file/file.model.js\";\nimport { FmPermissionsFeature } from \"~/features/permissions/feature.js\";\nimport { FileManagerFeature } from \"~/features/FileManagerFeature.js\";\nimport { FileModelProvider } from \"~/features/file/FileModelProvider.js\";\n\nexport const FileManagerAppFeature = createFeature({\n name: \"FileManagerApp\",\n register(container: Container) {\n AssetDeliveryFeature.register(container);\n container.register(AssetDeliveryRouteDefinition);\n container.register(FileModel);\n FmPermissionsFeature.register(container);\n FileManagerFeature.register(container);\n\n // Stateless — the model list is already cached per request by the CMS (`ModelCache`), so the\n // provider holds nothing and needs no lifetime of its own.\n container.register(FileModelProvider);\n }\n});\n"],"names":["FileManagerAppFeature","createFeature","container","AssetDeliveryFeature","AssetDeliveryRouteDefinition","FileModel","FmPermissionsFeature","FileManagerFeature","FileModelProvider"],"mappings":";;;;;;;AAQO,MAAMA,wBAAwBC,cAAc;IAC/C,MAAM;IACN,UAASC,SAAoB;QACzBC,qBAAqB,QAAQ,CAACD;QAC9BA,UAAU,QAAQ,CAACE;QACnBF,UAAU,QAAQ,CAACG;QACnBC,qBAAqB,QAAQ,CAACJ;QAC9BK,mBAAmB,QAAQ,CAACL;QAI5BA,UAAU,QAAQ,CAACM;IACvB;AACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery/AssetDelivery/AssetRequest.js","sources":["../../../src/delivery/AssetDelivery/AssetRequest.ts"],"sourcesContent":["import type { GenericRecord } from \"@webiny/api/types.js\";\n\nexport interface AssetRequestOptions {\n original?: boolean;\n
|
|
1
|
+
{"version":3,"file":"delivery/AssetDelivery/AssetRequest.js","sources":["../../../src/delivery/AssetDelivery/AssetRequest.ts"],"sourcesContent":["import type { GenericRecord } from \"@webiny/api/types.js\";\n\nexport interface AssetRequestOptions {\n original?: boolean;\n [key: string]: unknown;\n}\n\nexport type AssetRequestContext<T extends GenericRecord = GenericRecord> = T & {\n /**\n * Asset request URL.\n */\n url: string;\n};\n\nexport interface AssetRequestData<TOptions> {\n key: string;\n context: AssetRequestContext;\n options: TOptions;\n}\n\nexport class AssetRequest<TOptions extends AssetRequestOptions = AssetRequestOptions> {\n private data: AssetRequestData<TOptions>;\n\n constructor(data: AssetRequestData<TOptions>) {\n this.data = data;\n }\n\n getKey() {\n return this.data.key;\n }\n\n getOptions(): TOptions {\n return this.data.options;\n }\n\n setOptions(options: TOptions) {\n this.data.options = options;\n }\n\n getContext<T extends GenericRecord = GenericRecord>() {\n return this.data.context as AssetRequestContext<T>;\n }\n\n getExtension() {\n return this.data.key.split(\".\").pop();\n }\n}\n"],"names":["AssetRequest","data","options"],"mappings":"AAoBO,MAAMA;IAGT,YAAYC,IAAgC,CAAE;QAC1C,IAAI,CAAC,IAAI,GAAGA;IAChB;IAEA,SAAS;QACL,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG;IACxB;IAEA,aAAuB;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO;IAC5B;IAEA,WAAWC,OAAiB,EAAE;QAC1B,IAAI,CAAC,IAAI,CAAC,OAAO,GAAGA;IACxB;IAEA,aAAsD;QAClD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO;IAC5B;IAEA,eAAe;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG;IACvC;AACJ"}
|
|
@@ -1,14 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { IHttpRequest, IHttpResponse } from "@webiny/event-handler-core";
|
|
1
|
+
import { HttpRouteDefinition, HttpRouteHandler } from "@webiny/event-handler-core";
|
|
3
2
|
import type { Container } from "@webiny/di";
|
|
4
|
-
declare class AssetDeliveryRouteImpl implements
|
|
3
|
+
declare class AssetDeliveryRouteImpl implements HttpRouteHandler.Interface {
|
|
5
4
|
private container;
|
|
6
|
-
readonly method = "GET";
|
|
7
|
-
readonly path = "/files/*";
|
|
8
5
|
constructor(container: Container);
|
|
9
|
-
handle(request:
|
|
6
|
+
handle(request: HttpRouteHandler.Request, response: HttpRouteHandler.Response): Promise<import("@webiny/event-handler-core").IHttpResponseBuilder>;
|
|
10
7
|
}
|
|
11
8
|
export declare const AssetDeliveryRoute: typeof AssetDeliveryRouteImpl & {
|
|
12
9
|
__abstraction: import("@webiny/di").Abstraction<import("@webiny/event-handler-core").IHttpRoute>;
|
|
13
10
|
};
|
|
11
|
+
declare class AssetDeliveryRouteDefinitionImpl implements HttpRouteDefinition.Interface {
|
|
12
|
+
readonly name = "asset-delivery";
|
|
13
|
+
readonly method = "GET";
|
|
14
|
+
readonly path = "/files/*";
|
|
15
|
+
readonly handler: typeof AssetDeliveryRouteImpl & {
|
|
16
|
+
__abstraction: import("@webiny/di").Abstraction<import("@webiny/event-handler-core").IHttpRoute>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** What the router matches on. Zero dependencies, so building it costs nothing. */
|
|
20
|
+
export declare const AssetDeliveryRouteDefinition: typeof AssetDeliveryRouteDefinitionImpl & {
|
|
21
|
+
__abstraction: import("@webiny/di").Abstraction<import("@webiny/event-handler-core").IHttpRouteDefinition>;
|
|
22
|
+
};
|
|
14
23
|
export {};
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HttpRouteDefinition, HttpRouteHandler, RequestContainer } from "@webiny/event-handler-core";
|
|
2
2
|
import { AssetOutputStrategy, AssetProcessor, AssetRequestResolver, AssetResolver } from "../features/assetDelivery/abstractions.js";
|
|
3
|
-
const
|
|
4
|
-
"content-type": "application/json",
|
|
5
|
-
"cache-control": "no-cache, no-store, must-revalidate"
|
|
6
|
-
};
|
|
3
|
+
const NO_CACHE = "no-cache, no-store, must-revalidate";
|
|
7
4
|
class AssetDeliveryRouteImpl {
|
|
8
5
|
constructor(container){
|
|
9
6
|
this.container = container;
|
|
10
|
-
this.method = "GET";
|
|
11
|
-
this.path = "/files/*";
|
|
12
7
|
}
|
|
13
|
-
async handle(request) {
|
|
8
|
+
async handle(request, response) {
|
|
14
9
|
const requestResolver = this.container.resolve(AssetRequestResolver);
|
|
15
10
|
const assetResolver = this.container.resolve(AssetResolver);
|
|
16
11
|
const assetProcessor = this.container.resolve(AssetProcessor);
|
|
@@ -24,42 +19,40 @@ class AssetDeliveryRouteImpl {
|
|
|
24
19
|
headers: request.headers ?? {}
|
|
25
20
|
};
|
|
26
21
|
const resolvedRequest = await requestResolver.resolve(fakeRequest);
|
|
27
|
-
if (!resolvedRequest) return {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
body: JSON.stringify({
|
|
31
|
-
error: "Unable to resolve the request!"
|
|
32
|
-
})
|
|
33
|
-
};
|
|
22
|
+
if (!resolvedRequest) return response.status(404).header("cache-control", NO_CACHE).json({
|
|
23
|
+
error: "Unable to resolve the request!"
|
|
24
|
+
});
|
|
34
25
|
const resolvedAsset = await assetResolver.resolve(resolvedRequest);
|
|
35
|
-
if (!resolvedAsset) return {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
body: JSON.stringify({
|
|
39
|
-
error: "Asset not found!"
|
|
40
|
-
})
|
|
41
|
-
};
|
|
26
|
+
if (!resolvedAsset) return response.status(404).header("cache-control", NO_CACHE).json({
|
|
27
|
+
error: "Asset not found!"
|
|
28
|
+
});
|
|
42
29
|
resolvedAsset.setOutputStrategy(outputStrategy);
|
|
43
30
|
const processedAsset = await assetProcessor.process(resolvedRequest, resolvedAsset);
|
|
44
31
|
const assetReply = await processedAsset.output();
|
|
45
32
|
const rawHeaders = assetReply.getHeaders().getHeaders();
|
|
46
|
-
const
|
|
47
|
-
for (const [k, v] of Object.entries(rawHeaders))if (void 0 !== v) headers[k] = String(v);
|
|
33
|
+
for (const [k, v] of Object.entries(rawHeaders))if (void 0 !== v) response.header(k, String(v));
|
|
48
34
|
const body = await assetReply.getBody();
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
statusCode,
|
|
52
|
-
headers,
|
|
53
|
-
body: body ?? ""
|
|
54
|
-
};
|
|
35
|
+
return response.status(assetReply.getCode()).end(body ?? "");
|
|
55
36
|
}
|
|
56
37
|
}
|
|
57
|
-
const AssetDeliveryRoute =
|
|
38
|
+
const AssetDeliveryRoute = HttpRouteHandler.createImplementation({
|
|
58
39
|
implementation: AssetDeliveryRouteImpl,
|
|
59
40
|
dependencies: [
|
|
60
41
|
RequestContainer
|
|
61
42
|
]
|
|
62
43
|
});
|
|
63
|
-
|
|
44
|
+
class AssetDeliveryRouteDefinitionImpl {
|
|
45
|
+
constructor(){
|
|
46
|
+
this.name = "asset-delivery";
|
|
47
|
+
this.method = "GET";
|
|
48
|
+
this.path = "/files/*";
|
|
49
|
+
this.handler = AssetDeliveryRoute;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const AssetDeliveryRouteDefinition = HttpRouteDefinition.createImplementation({
|
|
53
|
+
implementation: AssetDeliveryRouteDefinitionImpl,
|
|
54
|
+
dependencies: []
|
|
55
|
+
});
|
|
56
|
+
export { AssetDeliveryRoute, AssetDeliveryRouteDefinition };
|
|
64
57
|
|
|
65
58
|
//# sourceMappingURL=AssetDeliveryRoute.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery/AssetDeliveryRoute.js","sources":["../../src/delivery/AssetDeliveryRoute.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"delivery/AssetDeliveryRoute.js","sources":["../../src/delivery/AssetDeliveryRoute.ts"],"sourcesContent":["import {\n HttpRouteDefinition,\n HttpRouteHandler,\n RequestContainer\n} from \"@webiny/event-handler-core\";\nimport type { Container } from \"@webiny/di\";\nimport {\n AssetRequestResolver,\n AssetResolver,\n AssetProcessor,\n AssetOutputStrategy\n} from \"~/features/assetDelivery/abstractions.js\";\n\nconst NO_CACHE = \"no-cache, no-store, must-revalidate\";\n\nclass AssetDeliveryRouteImpl implements HttpRouteHandler.Interface {\n constructor(private container: Container) {}\n\n async handle(request: HttpRouteHandler.Request, response: HttpRouteHandler.Response) {\n // Resolve asset-delivery collaborators lazily (request time), not as constructor deps.\n // HttpRouter eagerly constructs every route to match paths, and AssetProcessor's\n // PrivateFilesAssetProcessor decorator pulls in GetFileUseCase -> CMS entry repositories\n // that depend on EntryFromStorageTransform, which is only registered while a CMS GraphQL\n // request is in flight. Resolving here keeps route construction cheap so non-asset\n // requests (e.g. /graphql) don't trigger that chain before it is registered.\n const requestResolver = this.container.resolve(AssetRequestResolver);\n const assetResolver = this.container.resolve(AssetResolver);\n const assetProcessor = this.container.resolve(AssetProcessor);\n const outputStrategy = this.container.resolve(AssetOutputStrategy);\n\n // Reconstruct a minimal request object compatible with IAssetRequestResolver\n const fakeRequest = {\n url: request.path,\n params: { \"*\": request.path.replace(\"/files/\", \"\") },\n query: request.query ?? {},\n headers: request.headers ?? {}\n };\n\n const resolvedRequest = await requestResolver.resolve(fakeRequest as any);\n if (!resolvedRequest) {\n return response\n .status(404)\n .header(\"cache-control\", NO_CACHE)\n .json({ error: \"Unable to resolve the request!\" });\n }\n\n const resolvedAsset = await assetResolver.resolve(resolvedRequest);\n if (!resolvedAsset) {\n return response\n .status(404)\n .header(\"cache-control\", NO_CACHE)\n .json({ error: \"Asset not found!\" });\n }\n\n resolvedAsset.setOutputStrategy(outputStrategy);\n\n const processedAsset = await assetProcessor.process(resolvedRequest, resolvedAsset);\n const assetReply = await processedAsset.output();\n\n const rawHeaders = assetReply.getHeaders().getHeaders();\n for (const [k, v] of Object.entries(rawHeaders)) {\n if (v !== undefined) {\n response.header(k, String(v));\n }\n }\n\n const body = await assetReply.getBody();\n\n // `end()` (not `send()`) so the raw body passes through untouched and the asset's OWN\n // Content-Type — set from `rawHeaders` above — is preserved. The transport translator\n // (e.g. httpResponseToApiGatewayResult) base64-encodes Buffers and sets isBase64Encoded so\n // API Gateway returns proper binary. Pre-encoding to a base64 STRING here defeated that —\n // the string passed through undecoded and browsers received base64 text, not an image.\n return response.status(assetReply.getCode()).end(body ?? \"\");\n }\n}\n\nexport const AssetDeliveryRoute = HttpRouteHandler.createImplementation({\n implementation: AssetDeliveryRouteImpl,\n dependencies: [RequestContainer]\n});\n\nclass AssetDeliveryRouteDefinitionImpl implements HttpRouteDefinition.Interface {\n readonly name = \"asset-delivery\";\n readonly method = \"GET\";\n readonly path = \"/files/*\";\n readonly handler = AssetDeliveryRoute;\n}\n\n/** What the router matches on. Zero dependencies, so building it costs nothing. */\nexport const AssetDeliveryRouteDefinition = HttpRouteDefinition.createImplementation({\n implementation: AssetDeliveryRouteDefinitionImpl,\n dependencies: []\n});\n"],"names":["NO_CACHE","AssetDeliveryRouteImpl","container","request","response","requestResolver","AssetRequestResolver","assetResolver","AssetResolver","assetProcessor","AssetProcessor","outputStrategy","AssetOutputStrategy","fakeRequest","resolvedRequest","resolvedAsset","processedAsset","assetReply","rawHeaders","k","v","Object","undefined","String","body","AssetDeliveryRoute","HttpRouteHandler","RequestContainer","AssetDeliveryRouteDefinitionImpl","AssetDeliveryRouteDefinition","HttpRouteDefinition"],"mappings":";;AAaA,MAAMA,WAAW;AAEjB,MAAMC;IACF,YAAoBC,SAAoB,CAAE;aAAtBA,SAAS,GAATA;IAAuB;IAE3C,MAAM,OAAOC,OAAiC,EAAEC,QAAmC,EAAE;QAOjF,MAAMC,kBAAkB,IAAI,CAAC,SAAS,CAAC,OAAO,CAACC;QAC/C,MAAMC,gBAAgB,IAAI,CAAC,SAAS,CAAC,OAAO,CAACC;QAC7C,MAAMC,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAACC;QAC9C,MAAMC,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAACC;QAG9C,MAAMC,cAAc;YAChB,KAAKV,QAAQ,IAAI;YACjB,QAAQ;gBAAE,KAAKA,QAAQ,IAAI,CAAC,OAAO,CAAC,WAAW;YAAI;YACnD,OAAOA,QAAQ,KAAK,IAAI,CAAC;YACzB,SAASA,QAAQ,OAAO,IAAI,CAAC;QACjC;QAEA,MAAMW,kBAAkB,MAAMT,gBAAgB,OAAO,CAACQ;QACtD,IAAI,CAACC,iBACD,OAAOV,SACF,MAAM,CAAC,KACP,MAAM,CAAC,iBAAiBJ,UACxB,IAAI,CAAC;YAAE,OAAO;QAAiC;QAGxD,MAAMe,gBAAgB,MAAMR,cAAc,OAAO,CAACO;QAClD,IAAI,CAACC,eACD,OAAOX,SACF,MAAM,CAAC,KACP,MAAM,CAAC,iBAAiBJ,UACxB,IAAI,CAAC;YAAE,OAAO;QAAmB;QAG1Ce,cAAc,iBAAiB,CAACJ;QAEhC,MAAMK,iBAAiB,MAAMP,eAAe,OAAO,CAACK,iBAAiBC;QACrE,MAAME,aAAa,MAAMD,eAAe,MAAM;QAE9C,MAAME,aAAaD,WAAW,UAAU,GAAG,UAAU;QACrD,KAAK,MAAM,CAACE,GAAGC,EAAE,IAAIC,OAAO,OAAO,CAACH,YAChC,IAAIE,AAAME,WAANF,GACAhB,SAAS,MAAM,CAACe,GAAGI,OAAOH;QAIlC,MAAMI,OAAO,MAAMP,WAAW,OAAO;QAOrC,OAAOb,SAAS,MAAM,CAACa,WAAW,OAAO,IAAI,GAAG,CAACO,QAAQ;IAC7D;AACJ;AAEO,MAAMC,qBAAqBC,iBAAiB,oBAAoB,CAAC;IACpE,gBAAgBzB;IAChB,cAAc;QAAC0B;KAAiB;AACpC;AAEA,MAAMC;;aACO,IAAI,GAAG;aACP,MAAM,GAAG;aACT,IAAI,GAAG;aACP,OAAO,GAAGH;;AACvB;AAGO,MAAMI,+BAA+BC,oBAAoB,oBAAoB,CAAC;IACjF,gBAAgBF;IAChB,cAAc,EAAE;AACpB"}
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import type { CmsModel } from "@webiny/api-headless-cms/types";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Provides the `fmFile` CMS model for the current request's tenant.
|
|
4
|
+
*
|
|
5
|
+
* Fetching a model is asynchronous and tenant-dependent, which is why this is a provider rather
|
|
6
|
+
* than the model itself: DI resolution is synchronous, so an already-resolved `CmsModel` could only
|
|
7
|
+
* be supplied by a per-request hook running before any consumer (what `FileModelContextualSchema`
|
|
8
|
+
* used to do). Consumers instead `await get()` at the point of use — by which time the tenant is
|
|
9
|
+
* established — and the provider memoizes for the rest of the request.
|
|
5
10
|
*/
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
export interface IFileModelProvider {
|
|
12
|
+
get(): Promise<CmsModel>;
|
|
13
|
+
}
|
|
14
|
+
export declare const FileModelProvider: import("@webiny/di").Abstraction<IFileModelProvider>;
|
|
15
|
+
export declare namespace FileModelProvider {
|
|
16
|
+
type Interface = IFileModelProvider;
|
|
9
17
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createAbstraction } from "@webiny/feature/api";
|
|
2
|
-
const
|
|
3
|
-
export {
|
|
2
|
+
const FileModelProvider = createAbstraction("FileModelProvider");
|
|
3
|
+
export { FileModelProvider };
|
|
4
4
|
|
|
5
5
|
//# sourceMappingURL=abstractions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain/file/abstractions.js","sources":["../../../src/domain/file/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types\";\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"domain/file/abstractions.js","sources":["../../../src/domain/file/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { CmsModel } from \"@webiny/api-headless-cms/types\";\n\n/**\n * Provides the `fmFile` CMS model for the current request's tenant.\n *\n * Fetching a model is asynchronous and tenant-dependent, which is why this is a provider rather\n * than the model itself: DI resolution is synchronous, so an already-resolved `CmsModel` could only\n * be supplied by a per-request hook running before any consumer (what `FileModelContextualSchema`\n * used to do). Consumers instead `await get()` at the point of use — by which time the tenant is\n * established — and the provider memoizes for the rest of the request.\n */\nexport interface IFileModelProvider {\n get(): Promise<CmsModel>;\n}\n\nexport const FileModelProvider = createAbstraction<IFileModelProvider>(\"FileModelProvider\");\n\nexport namespace FileModelProvider {\n export type Interface = IFileModelProvider;\n}\n"],"names":["FileModelProvider","createAbstraction"],"mappings":";AAgBO,MAAMA,oBAAoBC,kBAAsC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ModelFactory } from "@webiny/api-headless-cms/features/modelBuilder/index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { FeatureFlags } from "@webiny/api-core/features/featureFlags/abstractions.js";
|
|
3
3
|
export declare const FILE_MODEL_ID: string;
|
|
4
4
|
declare class FilePrivateModelImpl implements ModelFactory.Interface {
|
|
5
|
-
private
|
|
6
|
-
constructor(
|
|
5
|
+
private featureFlags;
|
|
6
|
+
constructor(featureFlags: FeatureFlags.Interface);
|
|
7
7
|
execute(builder: ModelFactory.Builder): Promise<import("@webiny/api-headless-cms/features/modelBuilder/index.js").PrivateModelBuilder[]>;
|
|
8
8
|
}
|
|
9
9
|
export declare const FileModel: typeof FilePrivateModelImpl & {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { ModelFactory } from "@webiny/api-headless-cms/features/modelBuilder/index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { FeatureFlags } from "@webiny/api-core/features/featureFlags/abstractions.js";
|
|
3
3
|
const FILE_MODEL_ID = process.env.WEBINY_API_LEGACY_MODELS ? "fmFile" : "wbyFmFile";
|
|
4
4
|
class FilePrivateModelImpl {
|
|
5
|
-
constructor(
|
|
6
|
-
this.
|
|
5
|
+
constructor(featureFlags){
|
|
6
|
+
this.featureFlags = featureFlags;
|
|
7
7
|
}
|
|
8
8
|
async execute(builder) {
|
|
9
9
|
const model = builder.private({
|
|
10
10
|
modelId: FILE_MODEL_ID,
|
|
11
11
|
name: "FmFile"
|
|
12
12
|
});
|
|
13
|
-
const privateFiles = this.
|
|
13
|
+
const privateFiles = this.featureFlags.get().isEnabled("advancedAccessControlLayer.privateFiles");
|
|
14
14
|
model.fields((fields)=>({
|
|
15
15
|
name: fields.text().label("Name").required("Value is required."),
|
|
16
16
|
key: fields.text().label("Key").required("Value is required."),
|
|
@@ -21,7 +21,11 @@ class FilePrivateModelImpl {
|
|
|
21
21
|
width: fields.number().label("Width"),
|
|
22
22
|
height: fields.number().label("Height"),
|
|
23
23
|
format: fields.text().label("Format"),
|
|
24
|
-
orientation: fields.number().label("Orientation")
|
|
24
|
+
orientation: fields.number().label("Orientation"),
|
|
25
|
+
crop: fields.json().label("Crop"),
|
|
26
|
+
focalPoint: fields.json().label("Focal point"),
|
|
27
|
+
alt: fields.text().label("Alt text"),
|
|
28
|
+
caption: fields.text().label("Caption")
|
|
25
29
|
})),
|
|
26
30
|
exif: fields.searchableJson().label("EXIF Data"),
|
|
27
31
|
iptc: fields.searchableJson().label("IPTC Data")
|
|
@@ -57,7 +61,7 @@ class FilePrivateModelImpl {
|
|
|
57
61
|
const FileModel = ModelFactory.createImplementation({
|
|
58
62
|
implementation: FilePrivateModelImpl,
|
|
59
63
|
dependencies: [
|
|
60
|
-
|
|
64
|
+
FeatureFlags
|
|
61
65
|
]
|
|
62
66
|
});
|
|
63
67
|
export { FILE_MODEL_ID, FileModel };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain/file/file.model.js","sources":["../../../src/domain/file/file.model.ts"],"sourcesContent":["import { ModelFactory } from \"@webiny/api-headless-cms/features/modelBuilder/index.js\";\nimport {
|
|
1
|
+
{"version":3,"file":"domain/file/file.model.js","sources":["../../../src/domain/file/file.model.ts"],"sourcesContent":["import { ModelFactory } from \"@webiny/api-headless-cms/features/modelBuilder/index.js\";\nimport { FeatureFlags } from \"@webiny/api-core/features/featureFlags/abstractions.js\";\n\nexport const FILE_MODEL_ID = process.env.WEBINY_API_LEGACY_MODELS ? \"fmFile\" : \"wbyFmFile\";\n\nclass FilePrivateModelImpl implements ModelFactory.Interface {\n public constructor(private featureFlags: FeatureFlags.Interface) {}\n\n public async execute(builder: ModelFactory.Builder) {\n const model = builder.private({\n modelId: FILE_MODEL_ID,\n name: \"FmFile\"\n });\n const privateFiles = this.featureFlags\n .get()\n .isEnabled(\"advancedAccessControlLayer.privateFiles\");\n\n model.fields(fields => ({\n name: fields.text().label(\"Name\").required(\"Value is required.\"),\n key: fields.text().label(\"Key\").required(\"Value is required.\"),\n type: fields.text().label(\"Type\").required(\"Value is required.\"),\n size: fields.number().label(\"Size\").required(\"Value is required.\"),\n metadata: fields\n .object()\n .label(\"Metadata\")\n .renderer(\"hidden\")\n .fields(fields => ({\n image: fields\n .object()\n .label(\"Image\")\n .fields(fields => ({\n width: fields.number().label(\"Width\"),\n height: fields.number().label(\"Height\"),\n format: fields.text().label(\"Format\"),\n orientation: fields.number().label(\"Orientation\"),\n crop: fields.json().label(\"Crop\"),\n focalPoint: fields.json().label(\"Focal point\"),\n alt: fields.text().label(\"Alt text\"),\n caption: fields.text().label(\"Caption\")\n })),\n // Store complete raw EXIF as JSON\n exif: fields.searchableJson().label(\"EXIF Data\"),\n // Store complete raw IPTC as JSON\n iptc: fields.searchableJson().label(\"IPTC Data\")\n })),\n tags: fields\n .text()\n .label(\"Tags\")\n .tags([\"$bulk-edit\"])\n .list()\n .required(\"Value is required.\"),\n description: fields.text().label(\"Description\").defaultValue(\"\")\n }));\n\n if (privateFiles) {\n model.fields(fields => ({\n accessControl: fields\n .object()\n .label(\"Access Control\")\n .tags([\"$bulk-edit\"])\n .fields(fields => ({\n type: fields\n .text()\n .label(\"Type\")\n .predefinedValues([\n {\n label: \"Public\",\n value: \"public\",\n selected: true\n },\n {\n label: \"Private\",\n value: \"private-authenticated\",\n selected: false\n }\n ])\n }))\n }));\n }\n\n return [model];\n }\n}\n\nexport const FileModel = ModelFactory.createImplementation({\n implementation: FilePrivateModelImpl,\n dependencies: [FeatureFlags]\n});\n"],"names":["FILE_MODEL_ID","process","FilePrivateModelImpl","featureFlags","builder","model","privateFiles","fields","FileModel","ModelFactory","FeatureFlags"],"mappings":";;AAGO,MAAMA,gBAAgBC,QAAQ,GAAG,CAAC,wBAAwB,GAAG,WAAW;AAE/E,MAAMC;IACF,YAA2BC,YAAoC,CAAE;aAAtCA,YAAY,GAAZA;IAAuC;IAElE,MAAa,QAAQC,OAA6B,EAAE;QAChD,MAAMC,QAAQD,QAAQ,OAAO,CAAC;YAC1B,SAASJ;YACT,MAAM;QACV;QACA,MAAMM,eAAe,IAAI,CAAC,YAAY,CACjC,GAAG,GACH,SAAS,CAAC;QAEfD,MAAM,MAAM,CAACE,CAAAA,SAAW;gBACpB,MAAMA,OAAO,IAAI,GAAG,KAAK,CAAC,QAAQ,QAAQ,CAAC;gBAC3C,KAAKA,OAAO,IAAI,GAAG,KAAK,CAAC,OAAO,QAAQ,CAAC;gBACzC,MAAMA,OAAO,IAAI,GAAG,KAAK,CAAC,QAAQ,QAAQ,CAAC;gBAC3C,MAAMA,OAAO,MAAM,GAAG,KAAK,CAAC,QAAQ,QAAQ,CAAC;gBAC7C,UAAUA,OACL,MAAM,GACN,KAAK,CAAC,YACN,QAAQ,CAAC,UACT,MAAM,CAACA,CAAAA,SAAW;wBACf,OAAOA,OACF,MAAM,GACN,KAAK,CAAC,SACN,MAAM,CAACA,CAAAA,SAAW;gCACf,OAAOA,OAAO,MAAM,GAAG,KAAK,CAAC;gCAC7B,QAAQA,OAAO,MAAM,GAAG,KAAK,CAAC;gCAC9B,QAAQA,OAAO,IAAI,GAAG,KAAK,CAAC;gCAC5B,aAAaA,OAAO,MAAM,GAAG,KAAK,CAAC;gCACnC,MAAMA,OAAO,IAAI,GAAG,KAAK,CAAC;gCAC1B,YAAYA,OAAO,IAAI,GAAG,KAAK,CAAC;gCAChC,KAAKA,OAAO,IAAI,GAAG,KAAK,CAAC;gCACzB,SAASA,OAAO,IAAI,GAAG,KAAK,CAAC;4BACjC;wBAEJ,MAAMA,OAAO,cAAc,GAAG,KAAK,CAAC;wBAEpC,MAAMA,OAAO,cAAc,GAAG,KAAK,CAAC;oBACxC;gBACJ,MAAMA,OACD,IAAI,GACJ,KAAK,CAAC,QACN,IAAI,CAAC;oBAAC;iBAAa,EACnB,IAAI,GACJ,QAAQ,CAAC;gBACd,aAAaA,OAAO,IAAI,GAAG,KAAK,CAAC,eAAe,YAAY,CAAC;YACjE;QAEA,IAAID,cACAD,MAAM,MAAM,CAACE,CAAAA,SAAW;gBACpB,eAAeA,OACV,MAAM,GACN,KAAK,CAAC,kBACN,IAAI,CAAC;oBAAC;iBAAa,EACnB,MAAM,CAACA,CAAAA,SAAW;wBACf,MAAMA,OACD,IAAI,GACJ,KAAK,CAAC,QACN,gBAAgB,CAAC;4BACd;gCACI,OAAO;gCACP,OAAO;gCACP,UAAU;4BACd;4BACA;gCACI,OAAO;gCACP,OAAO;gCACP,UAAU;4BACd;yBACH;oBACT;YACR;QAGJ,OAAO;YAACF;SAAM;IAClB;AACJ;AAEO,MAAMG,YAAYC,aAAa,oBAAoB,CAAC;IACvD,gBAAgBP;IAChB,cAAc;QAACQ;KAAa;AAChC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Abstraction } from "@webiny/di";
|
|
2
|
+
import type { AssetRequest as IAssetRequest } from "../../../delivery/AssetDelivery/AssetRequest.js";
|
|
3
|
+
import type { Asset as IAsset } from "../../../delivery/AssetDelivery/Asset.js";
|
|
4
|
+
export interface IAssetTypeHandler {
|
|
5
|
+
handle(assetRequest: IAssetRequest, asset: IAsset): Promise<IAsset>;
|
|
6
|
+
}
|
|
7
|
+
export interface IAssetType {
|
|
8
|
+
canHandle(asset: IAsset): boolean;
|
|
9
|
+
getHandlerAbstraction(): Abstraction<IAssetTypeHandler>;
|
|
10
|
+
}
|
|
11
|
+
export declare const AssetType: Abstraction<IAssetType>;
|
|
12
|
+
export declare namespace AssetType {
|
|
13
|
+
type Interface = IAssetType;
|
|
14
|
+
type AssetRequest = IAssetRequest;
|
|
15
|
+
type Asset = IAsset;
|
|
16
|
+
type Handler = IAssetTypeHandler;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/abstractions/AssetType.js","sources":["../../../../src/features/assetDelivery/abstractions/AssetType.ts"],"sourcesContent":["import { Abstraction } from \"@webiny/di\";\nimport { createAbstraction } from \"@webiny/feature/api\";\nimport type { AssetRequest as IAssetRequest } from \"~/delivery/AssetDelivery/AssetRequest.js\";\nimport type { Asset as IAsset } from \"~/delivery/AssetDelivery/Asset.js\";\n\nexport interface IAssetTypeHandler {\n handle(assetRequest: IAssetRequest, asset: IAsset): Promise<IAsset>;\n}\n\nexport interface IAssetType {\n canHandle(asset: IAsset): boolean;\n getHandlerAbstraction(): Abstraction<IAssetTypeHandler>;\n}\n\nexport const AssetType = createAbstraction<IAssetType>(\"AssetDelivery/AssetType\");\n\nexport namespace AssetType {\n export type Interface = IAssetType;\n export type AssetRequest = IAssetRequest;\n export type Asset = IAsset;\n export type Handler = IAssetTypeHandler;\n}\n"],"names":["AssetType","createAbstraction"],"mappings":";AAcO,MAAMA,YAAYC,kBAA8B"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import type { Asset } from "
|
|
1
|
+
import type { Asset } from "../../../../delivery/index.js";
|
|
2
|
+
import type { Framing } from "./imageTypes.js";
|
|
2
3
|
export declare class AssetKeyGenerator {
|
|
3
4
|
private readonly utils;
|
|
4
5
|
private readonly asset;
|
|
5
|
-
|
|
6
|
+
private readonly framing?;
|
|
7
|
+
static create(asset: Asset, framing?: Framing): AssetKeyGenerator;
|
|
6
8
|
private constructor();
|
|
9
|
+
private signature;
|
|
7
10
|
getOptimizedImageKey(): string;
|
|
8
11
|
getTransformedImageKey(transformations: Record<string, any>): string;
|
|
9
12
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as __rspack_external__utils_js_a9c81ddd from "./utils.js";
|
|
2
|
+
class AssetKeyGenerator {
|
|
3
|
+
static create(asset, framing) {
|
|
4
|
+
return new AssetKeyGenerator(asset, framing);
|
|
5
|
+
}
|
|
6
|
+
constructor(asset, framing){
|
|
7
|
+
this.asset = asset;
|
|
8
|
+
this.utils = __rspack_external__utils_js_a9c81ddd;
|
|
9
|
+
this.framing = framing;
|
|
10
|
+
}
|
|
11
|
+
signature() {
|
|
12
|
+
if (this.framing) return this.utils.getFramingSignature(this.framing);
|
|
13
|
+
}
|
|
14
|
+
getOptimizedImageKey() {
|
|
15
|
+
return this.utils.getImageKey({
|
|
16
|
+
key: this.asset.getKey(),
|
|
17
|
+
cropSignature: this.signature()
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
getTransformedImageKey(transformations) {
|
|
21
|
+
return this.utils.getImageKey({
|
|
22
|
+
key: this.asset.getKey(),
|
|
23
|
+
transformations,
|
|
24
|
+
cropSignature: this.signature()
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export { AssetKeyGenerator };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=AssetKeyGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/assetTypes/image/AssetKeyGenerator.js","sources":["../../../../../src/features/assetDelivery/assetTypes/image/AssetKeyGenerator.ts"],"sourcesContent":["import type { Asset } from \"../../../../delivery/index.js\";\nimport type { Framing } from \"./imageTypes.js\";\nimport * as newUtils from \"./utils.js\";\n\nexport class AssetKeyGenerator {\n private readonly utils: typeof newUtils;\n private readonly asset: Asset;\n private readonly framing?: Framing;\n\n public static create(asset: Asset, framing?: Framing) {\n return new AssetKeyGenerator(asset, framing);\n }\n\n private constructor(asset: Asset, framing?: Framing) {\n this.asset = asset;\n this.utils = newUtils;\n this.framing = framing;\n }\n\n private signature() {\n if (this.framing) {\n return this.utils.getFramingSignature(this.framing);\n }\n return undefined;\n }\n\n public getOptimizedImageKey() {\n return this.utils.getImageKey({\n key: this.asset.getKey(),\n cropSignature: this.signature()\n });\n }\n\n public getTransformedImageKey(transformations: Record<string, any>) {\n return this.utils.getImageKey({\n key: this.asset.getKey(),\n transformations,\n cropSignature: this.signature()\n });\n }\n}\n"],"names":["AssetKeyGenerator","asset","framing","newUtils","transformations"],"mappings":";AAIO,MAAMA;IAKT,OAAc,OAAOC,KAAY,EAAEC,OAAiB,EAAE;QAClD,OAAO,IAAIF,kBAAkBC,OAAOC;IACxC;IAEA,YAAoBD,KAAY,EAAEC,OAAiB,CAAE;QACjD,IAAI,CAAC,KAAK,GAAGD;QACb,IAAI,CAAC,KAAK,GAAGE;QACb,IAAI,CAAC,OAAO,GAAGD;IACnB;IAEQ,YAAY;QAChB,IAAI,IAAI,CAAC,OAAO,EACZ,OAAO,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO;IAG1D;IAEO,uBAAuB;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YAC1B,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM;YACtB,eAAe,IAAI,CAAC,SAAS;QACjC;IACJ;IAEO,uBAAuBE,eAAoC,EAAE;QAChE,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YAC1B,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM;YACtBA;YACA,eAAe,IAAI,CAAC,SAAS;QACjC;IACJ;AACJ"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AssetType } from "../../abstractions/AssetType.js";
|
|
2
|
+
declare class ImageAssetTypeImpl implements AssetType.Interface {
|
|
3
|
+
canHandle(asset: AssetType.Asset): boolean;
|
|
4
|
+
getHandlerAbstraction(): import("@webiny/di").Abstraction<import("../../abstractions/AssetType.js").IAssetTypeHandler>;
|
|
5
|
+
}
|
|
6
|
+
export declare const ImageAssetType: typeof ImageAssetTypeImpl & {
|
|
7
|
+
__abstraction: import("@webiny/di").Abstraction<import("../../abstractions/AssetType.js").IAssetType>;
|
|
8
|
+
};
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AssetType } from "../../abstractions/AssetType.js";
|
|
2
|
+
import { SUPPORTED_TRANSFORMABLE_IMAGES } from "./utils.js";
|
|
3
|
+
import { ImageAssetTypeHandler } from "./ImageAssetTypeHandler.js";
|
|
4
|
+
class ImageAssetTypeImpl {
|
|
5
|
+
canHandle(asset) {
|
|
6
|
+
return SUPPORTED_TRANSFORMABLE_IMAGES.includes(asset.getExtension());
|
|
7
|
+
}
|
|
8
|
+
getHandlerAbstraction() {
|
|
9
|
+
return ImageAssetTypeHandler;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const ImageAssetType = AssetType.createImplementation({
|
|
13
|
+
implementation: ImageAssetTypeImpl,
|
|
14
|
+
dependencies: []
|
|
15
|
+
});
|
|
16
|
+
export { ImageAssetType };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=ImageAssetType.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/assetTypes/image/ImageAssetType.js","sources":["../../../../../src/features/assetDelivery/assetTypes/image/ImageAssetType.ts"],"sourcesContent":["import { AssetType } from \"../../abstractions/AssetType.js\";\nimport { SUPPORTED_TRANSFORMABLE_IMAGES } from \"./utils.js\";\nimport { ImageAssetTypeHandler } from \"./ImageAssetTypeHandler.js\";\n\nclass ImageAssetTypeImpl implements AssetType.Interface {\n canHandle(asset: AssetType.Asset): boolean {\n return SUPPORTED_TRANSFORMABLE_IMAGES.includes(asset.getExtension());\n }\n\n getHandlerAbstraction() {\n return ImageAssetTypeHandler;\n }\n}\n\nexport const ImageAssetType = AssetType.createImplementation({\n implementation: ImageAssetTypeImpl,\n dependencies: []\n});\n"],"names":["ImageAssetTypeImpl","asset","SUPPORTED_TRANSFORMABLE_IMAGES","ImageAssetTypeHandler","ImageAssetType","AssetType"],"mappings":";;;AAIA,MAAMA;IACF,UAAUC,KAAsB,EAAW;QACvC,OAAOC,+BAA+B,QAAQ,CAACD,MAAM,YAAY;IACrE;IAEA,wBAAwB;QACpB,OAAOE;IACX;AACJ;AAEO,MAAMC,iBAAiBC,UAAU,oBAAoB,CAAC;IACzD,gBAAgBL;IAChB,cAAc,EAAE;AACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/assetTypes/image/ImageAssetTypeHandler.js","sources":["../../../../../src/features/assetDelivery/assetTypes/image/ImageAssetTypeHandler.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/api\";\nimport type { IAssetTypeHandler } from \"../../abstractions/AssetType.js\";\n\nexport const ImageAssetTypeHandler = createAbstraction<IAssetTypeHandler>(\n \"AssetDelivery/ImageAssetTypeHandler\"\n);\n\nexport namespace ImageAssetTypeHandler {\n export type Interface = IAssetTypeHandler;\n}\n"],"names":["ImageAssetTypeHandler","createAbstraction"],"mappings":";AAGO,MAAMA,wBAAwBC,kBACjC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TransformImageParams, TransformImageResult } from "./transformImage.js";
|
|
2
|
+
import type { Framing } from "./imageTypes.js";
|
|
3
|
+
export declare class SharpTransformer {
|
|
4
|
+
private module?;
|
|
5
|
+
private sharp?;
|
|
6
|
+
private load;
|
|
7
|
+
private getSharp;
|
|
8
|
+
transformBuffer(params: TransformImageParams): Promise<TransformImageResult>;
|
|
9
|
+
extractFramedRegion(buffer: Buffer, framing: Framing): Promise<Buffer>;
|
|
10
|
+
cropBuffer(buffer: Buffer, crop: {
|
|
11
|
+
top: number;
|
|
12
|
+
left: number;
|
|
13
|
+
bottom: number;
|
|
14
|
+
right: number;
|
|
15
|
+
}): Promise<Buffer>;
|
|
16
|
+
optimizePng(buffer: Buffer): Promise<import("sharp").Sharp>;
|
|
17
|
+
optimizeJpeg(buffer: Buffer): Promise<import("sharp").Sharp>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
class SharpTransformer {
|
|
2
|
+
async load() {
|
|
3
|
+
if (!this.module) this.module = await import("./transformImage.js");
|
|
4
|
+
return this.module;
|
|
5
|
+
}
|
|
6
|
+
async getSharp() {
|
|
7
|
+
if (!this.sharp) this.sharp = (await import("sharp")).default;
|
|
8
|
+
return this.sharp;
|
|
9
|
+
}
|
|
10
|
+
async transformBuffer(params) {
|
|
11
|
+
const m = await this.load();
|
|
12
|
+
return m.transformImageBuffer(params);
|
|
13
|
+
}
|
|
14
|
+
async extractFramedRegion(buffer, framing) {
|
|
15
|
+
const m = await this.load();
|
|
16
|
+
return m.extractFramedRegion(buffer, framing);
|
|
17
|
+
}
|
|
18
|
+
async cropBuffer(buffer, crop) {
|
|
19
|
+
const m = await this.load();
|
|
20
|
+
return m.cropImageBuffer(buffer, crop);
|
|
21
|
+
}
|
|
22
|
+
async optimizePng(buffer) {
|
|
23
|
+
const s = await this.getSharp();
|
|
24
|
+
return s(buffer).resize({
|
|
25
|
+
width: 2560,
|
|
26
|
+
withoutEnlargement: true,
|
|
27
|
+
fit: "inside"
|
|
28
|
+
}).png({
|
|
29
|
+
compressionLevel: 9,
|
|
30
|
+
adaptiveFiltering: true,
|
|
31
|
+
force: true
|
|
32
|
+
}).withMetadata();
|
|
33
|
+
}
|
|
34
|
+
async optimizeJpeg(buffer) {
|
|
35
|
+
const s = await this.getSharp();
|
|
36
|
+
return s(buffer).resize({
|
|
37
|
+
width: 2560,
|
|
38
|
+
withoutEnlargement: true,
|
|
39
|
+
fit: "inside"
|
|
40
|
+
}).withMetadata().toFormat("jpeg", {
|
|
41
|
+
quality: 90
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export { SharpTransformer };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=SharpTransformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/assetTypes/image/SharpTransformer.js","sources":["../../../../../src/features/assetDelivery/assetTypes/image/SharpTransformer.ts"],"sourcesContent":["import type { TransformImageParams, TransformImageResult } from \"./transformImage.js\";\nimport type { Framing } from \"./imageTypes.js\";\n\nexport class SharpTransformer {\n private module?: typeof import(\"./transformImage.js\");\n private sharp?: typeof import(\"sharp\").default;\n\n private async load() {\n if (!this.module) {\n this.module = await import(\"./transformImage.js\");\n }\n return this.module;\n }\n\n private async getSharp() {\n if (!this.sharp) {\n this.sharp = (await import(\"sharp\")).default;\n }\n return this.sharp;\n }\n\n async transformBuffer(params: TransformImageParams): Promise<TransformImageResult> {\n const m = await this.load();\n return m.transformImageBuffer(params);\n }\n\n async extractFramedRegion(buffer: Buffer, framing: Framing): Promise<Buffer> {\n const m = await this.load();\n return m.extractFramedRegion(buffer, framing);\n }\n\n async cropBuffer(\n buffer: Buffer,\n crop: { top: number; left: number; bottom: number; right: number }\n ): Promise<Buffer> {\n const m = await this.load();\n return m.cropImageBuffer(buffer, crop);\n }\n\n async optimizePng(buffer: Buffer) {\n const s = await this.getSharp();\n return s(buffer)\n .resize({ width: 2560, withoutEnlargement: true, fit: \"inside\" })\n .png({ compressionLevel: 9, adaptiveFiltering: true, force: true })\n .withMetadata();\n }\n\n async optimizeJpeg(buffer: Buffer) {\n const s = await this.getSharp();\n return s(buffer)\n .resize({ width: 2560, withoutEnlargement: true, fit: \"inside\" })\n .withMetadata()\n .toFormat(\"jpeg\", { quality: 90 });\n }\n}\n"],"names":["SharpTransformer","params","m","buffer","framing","crop","s"],"mappings":"AAGO,MAAMA;IAIT,MAAc,OAAO;QACjB,IAAI,CAAC,IAAI,CAAC,MAAM,EACZ,IAAI,CAAC,MAAM,GAAG,MAAM,MAAM,CAAC;QAE/B,OAAO,IAAI,CAAC,MAAM;IACtB;IAEA,MAAc,WAAW;QACrB,IAAI,CAAC,IAAI,CAAC,KAAK,EACX,IAAI,CAAC,KAAK,GAAI,OAAM,MAAM,CAAC,QAAO,EAAG,OAAO;QAEhD,OAAO,IAAI,CAAC,KAAK;IACrB;IAEA,MAAM,gBAAgBC,MAA4B,EAAiC;QAC/E,MAAMC,IAAI,MAAM,IAAI,CAAC,IAAI;QACzB,OAAOA,EAAE,oBAAoB,CAACD;IAClC;IAEA,MAAM,oBAAoBE,MAAc,EAAEC,OAAgB,EAAmB;QACzE,MAAMF,IAAI,MAAM,IAAI,CAAC,IAAI;QACzB,OAAOA,EAAE,mBAAmB,CAACC,QAAQC;IACzC;IAEA,MAAM,WACFD,MAAc,EACdE,IAAkE,EACnD;QACf,MAAMH,IAAI,MAAM,IAAI,CAAC,IAAI;QACzB,OAAOA,EAAE,eAAe,CAACC,QAAQE;IACrC;IAEA,MAAM,YAAYF,MAAc,EAAE;QAC9B,MAAMG,IAAI,MAAM,IAAI,CAAC,QAAQ;QAC7B,OAAOA,EAAEH,QACJ,MAAM,CAAC;YAAE,OAAO;YAAM,oBAAoB;YAAM,KAAK;QAAS,GAC9D,GAAG,CAAC;YAAE,kBAAkB;YAAG,mBAAmB;YAAM,OAAO;QAAK,GAChE,YAAY;IACrB;IAEA,MAAM,aAAaA,MAAc,EAAE;QAC/B,MAAMG,IAAI,MAAM,IAAI,CAAC,QAAQ;QAC7B,OAAOA,EAAEH,QACJ,MAAM,CAAC;YAAE,OAAO;YAAM,oBAAoB;YAAM,KAAK;QAAS,GAC9D,YAAY,GACZ,QAAQ,CAAC,QAAQ;YAAE,SAAS;QAAG;IACxC;AACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features/assetDelivery/assetTypes/image/WidthCollection.js","sources":["../../../../../src/features/assetDelivery/assetTypes/image/WidthCollection.ts"],"sourcesContent":["export class WidthCollection {\n private readonly values: number[];\n\n public static create(values: number[]) {\n return new WidthCollection(values);\n }\n\n private constructor(values: number[]) {\n this.values = values.sort((a, b) => a - b);\n }\n\n public max() {\n return Math.max(...this.values);\n }\n\n public min() {\n return Math.min(...this.values);\n }\n\n public getClosestOrMax(value: number | undefined): number {\n if (!value) {\n return this.max();\n }\n const gteGivenValue = this.values.filter(w => w >= value);\n return gteGivenValue.length > 0 ? gteGivenValue[0] : this.max();\n }\n}\n"],"names":["WidthCollection","values","a","b","Math","value","gteGivenValue","w"],"mappings":"AAAO,MAAMA;IAGT,OAAc,OAAOC,MAAgB,EAAE;QACnC,OAAO,IAAID,gBAAgBC;IAC/B;IAEA,YAAoBA,MAAgB,CAAE;QAClC,IAAI,CAAC,MAAM,GAAGA,OAAO,IAAI,CAAC,CAACC,GAAGC,IAAMD,IAAIC;IAC5C;IAEO,MAAM;QACT,OAAOC,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM;IAClC;IAEO,MAAM;QACT,OAAOA,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM;IAClC;IAEO,gBAAgBC,KAAyB,EAAU;QACtD,IAAI,CAACA,OACD,OAAO,IAAI,CAAC,GAAG;QAEnB,MAAMC,gBAAgB,IAAI,CAAC,MAAM,CAAC,MAAM,CAACC,CAAAA,IAAKA,KAAKF;QACnD,OAAOC,cAAc,MAAM,GAAG,IAAIA,aAAa,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG;IACjE;AACJ"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure image-format helpers. IMPORTANT: this module must NOT import `sharp` (a
|
|
3
|
+
* native module). It is reachable from the GraphQL API handler via the asset
|
|
4
|
+
* request resolvers, and loading `sharp` there would crash that Lambda. The
|
|
5
|
+
* actual sharp pipeline lives in `transformImage.ts`, which only the transform
|
|
6
|
+
* strategies (the image Lambda) import.
|
|
7
|
+
*/
|
|
8
|
+
export type ImageFormat = "jpeg" | "png" | "webp" | "avif";
|
|
9
|
+
export declare const SUPPORTED_OUTPUT_FORMATS: ImageFormat[];
|
|
10
|
+
/**
|
|
11
|
+
* Default encoder quality per output format. AVIF reaches a comparable visual
|
|
12
|
+
* quality at a lower number than JPEG/WebP, hence the lower default.
|
|
13
|
+
*/
|
|
14
|
+
export declare const DEFAULT_IMAGE_QUALITY: Record<ImageFormat, number>;
|
|
15
|
+
export declare const contentTypeForFormat: (format: ImageFormat) => string;
|
|
16
|
+
export declare const formatFromContentType: (contentType: string) => ImageFormat | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a requested format string into a concrete output format.
|
|
19
|
+
*
|
|
20
|
+
* `"auto"` negotiates from the `Accept` header (AVIF ▸ WebP ▸ keep original), which
|
|
21
|
+
* is how we approach `next/image`'s automatic modern-format delivery. Returns
|
|
22
|
+
* `undefined` when the original format should be kept.
|
|
23
|
+
*/
|
|
24
|
+
export declare const resolveRequestedFormat: (requested: string | undefined, acceptHeader: string | undefined) => ImageFormat | undefined;
|
|
25
|
+
/** Clamp a requested quality into the valid 1–100 range; `undefined` when absent/invalid. */
|
|
26
|
+
export declare const clampQuality: (value: number | undefined) => number | undefined;
|