@contember/engine-s3-plugin 2.1.0-alpha.3 → 2.1.0-alpha.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/package.json +19 -14
  2. package/src/Config.ts +0 -1
  3. package/src/S3ConfigProcessor.ts +0 -1
  4. package/src/S3ObjectAuthorizator.ts +0 -1
  5. package/src/S3SchemaContributor.ts +2 -7
  6. package/src/S3SchemaTypes.ts +3 -10
  7. package/src/S3Service.ts +1 -2
  8. package/src/S3Signer.ts +1 -1
  9. package/tests/cases/authorizator.test.ts +1 -2
  10. package/tests/cases/signRequest.test.ts +54 -26
  11. package/types/picomatch/index.d.ts +1 -1
  12. package/dist/development/index.cjs +0 -27
  13. package/dist/development/index.cjs.map +0 -1
  14. package/dist/development/index.js +0 -28
  15. package/dist/development/index.js.map +0 -1
  16. package/dist/development/src/Config.cjs +0 -73
  17. package/dist/development/src/Config.cjs.map +0 -1
  18. package/dist/development/src/Config.js +0 -56
  19. package/dist/development/src/Config.js.map +0 -1
  20. package/dist/development/src/S3ConfigProcessor.cjs +0 -60
  21. package/dist/development/src/S3ConfigProcessor.cjs.map +0 -1
  22. package/dist/development/src/S3ConfigProcessor.js +0 -43
  23. package/dist/development/src/S3ConfigProcessor.js.map +0 -1
  24. package/dist/development/src/S3ObjectAuthorizator.cjs +0 -46
  25. package/dist/development/src/S3ObjectAuthorizator.cjs.map +0 -1
  26. package/dist/development/src/S3ObjectAuthorizator.js +0 -46
  27. package/dist/development/src/S3ObjectAuthorizator.js.map +0 -1
  28. package/dist/development/src/S3SchemaContributor.cjs +0 -107
  29. package/dist/development/src/S3SchemaContributor.cjs.map +0 -1
  30. package/dist/development/src/S3SchemaContributor.js +0 -107
  31. package/dist/development/src/S3SchemaContributor.js.map +0 -1
  32. package/dist/development/src/S3SchemaTypes.cjs +0 -71
  33. package/dist/development/src/S3SchemaTypes.cjs.map +0 -1
  34. package/dist/development/src/S3SchemaTypes.js +0 -71
  35. package/dist/development/src/S3SchemaTypes.js.map +0 -1
  36. package/dist/development/src/S3Service.cjs +0 -105
  37. package/dist/development/src/S3Service.cjs.map +0 -1
  38. package/dist/development/src/S3Service.js +0 -105
  39. package/dist/development/src/S3Service.js.map +0 -1
  40. package/dist/development/src/S3Signer.cjs +0 -84
  41. package/dist/development/src/S3Signer.cjs.map +0 -1
  42. package/dist/development/src/S3Signer.js +0 -84
  43. package/dist/development/src/S3Signer.js.map +0 -1
  44. package/dist/production/index.cjs +0 -27
  45. package/dist/production/index.cjs.map +0 -1
  46. package/dist/production/index.js +0 -28
  47. package/dist/production/index.js.map +0 -1
  48. package/dist/production/src/Config.cjs +0 -73
  49. package/dist/production/src/Config.cjs.map +0 -1
  50. package/dist/production/src/Config.js +0 -56
  51. package/dist/production/src/Config.js.map +0 -1
  52. package/dist/production/src/S3ConfigProcessor.cjs +0 -60
  53. package/dist/production/src/S3ConfigProcessor.cjs.map +0 -1
  54. package/dist/production/src/S3ConfigProcessor.js +0 -43
  55. package/dist/production/src/S3ConfigProcessor.js.map +0 -1
  56. package/dist/production/src/S3ObjectAuthorizator.cjs +0 -46
  57. package/dist/production/src/S3ObjectAuthorizator.cjs.map +0 -1
  58. package/dist/production/src/S3ObjectAuthorizator.js +0 -46
  59. package/dist/production/src/S3ObjectAuthorizator.js.map +0 -1
  60. package/dist/production/src/S3SchemaContributor.cjs +0 -107
  61. package/dist/production/src/S3SchemaContributor.cjs.map +0 -1
  62. package/dist/production/src/S3SchemaContributor.js +0 -107
  63. package/dist/production/src/S3SchemaContributor.js.map +0 -1
  64. package/dist/production/src/S3SchemaTypes.cjs +0 -71
  65. package/dist/production/src/S3SchemaTypes.cjs.map +0 -1
  66. package/dist/production/src/S3SchemaTypes.js +0 -71
  67. package/dist/production/src/S3SchemaTypes.js.map +0 -1
  68. package/dist/production/src/S3Service.cjs +0 -105
  69. package/dist/production/src/S3Service.cjs.map +0 -1
  70. package/dist/production/src/S3Service.js +0 -105
  71. package/dist/production/src/S3Service.js.map +0 -1
  72. package/dist/production/src/S3Signer.cjs +0 -84
  73. package/dist/production/src/S3Signer.cjs.map +0 -1
  74. package/dist/production/src/S3Signer.js +0 -84
  75. package/dist/production/src/S3Signer.js.map +0 -1
  76. package/dist/tests/cases/authorizator.test.d.ts +0 -2
  77. package/dist/tests/cases/authorizator.test.d.ts.map +0 -1
  78. package/dist/tests/cases/signRequest.test.d.ts +0 -2
  79. package/dist/tests/cases/signRequest.test.d.ts.map +0 -1
  80. package/dist/tests/tsconfig.tsbuildinfo +0 -1
  81. package/dist/types/Config.d.ts +0 -33
  82. package/dist/types/Config.d.ts.map +0 -1
  83. package/dist/types/S3ConfigProcessor.d.ts +0 -9
  84. package/dist/types/S3ConfigProcessor.d.ts.map +0 -1
  85. package/dist/types/S3ObjectAuthorizator.d.ts +0 -22
  86. package/dist/types/S3ObjectAuthorizator.d.ts.map +0 -1
  87. package/dist/types/S3SchemaContributor.d.ts +0 -21
  88. package/dist/types/S3SchemaContributor.d.ts.map +0 -1
  89. package/dist/types/S3SchemaTypes.d.ts +0 -21
  90. package/dist/types/S3SchemaTypes.d.ts.map +0 -1
  91. package/dist/types/S3Service.d.ts +0 -44
  92. package/dist/types/S3Service.d.ts.map +0 -1
  93. package/dist/types/S3Signer.d.ts +0 -22
  94. package/dist/types/S3Signer.d.ts.map +0 -1
  95. package/dist/types/index.d.ts +0 -13
  96. package/dist/types/index.d.ts.map +0 -1
  97. package/dist/types/tsconfig.tsbuildinfo +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"S3Service.cjs","sources":["../../../../packages/engine-s3-plugin/src/S3Service.ts"],"sourcesContent":["import { extension as resolveExtension } from 'mime-types'\nimport { resolveS3PublicBaseUrl, S3Config } from './Config'\nimport { ForbiddenError, UserInputError } from '@contember/graphql-utils'\nimport { Providers } from '@contember/engine-plugins'\nimport { S3Signer } from './S3Signer'\nimport { S3GenerateSignedUploadInput } from './S3SchemaTypes'\nimport { S3ObjectAuthorizator } from './S3ObjectAuthorizator'\n\ntype SignedReadUrl = {\n\turl: string\n\tbucket: string\n\tobjectKey: string\n\theaders: { key: string; value: string }[]\n\tmethod: string\n}\n\ntype SignedUploadUrl = {\n\tobjectKey: string\n\turl: string\n\tbucket: string\n\tpublicUrl: string\n\theaders: { key: string; value: string }[]\n\tmethod: string\n}\n\n\nexport class S3Service {\n\tprivate readonly publicBaseUrl: string\n\n\tprivate readonly signer: S3Signer\n\n\tconstructor(\n\t\tpublic readonly config: S3Config,\n\t\tprivate readonly providers: Pick<Providers, 'uuid' | 'now'>,\n\t\tprivate readonly authorizator: S3ObjectAuthorizator,\n\t) {\n\t\tthis.publicBaseUrl = resolveS3PublicBaseUrl(config)\n\t\tthis.signer = new S3Signer(config, providers)\n\t}\n\n\tpublic getSignedUploadUrl(\n\t\t{ acl, contentDisposition, contentType, expiration, prefix, suffix, fileName, extension, size }: S3GenerateSignedUploadInput,\n\t): SignedUploadUrl {\n\t\tconst ext = extension ?? ((contentType ? resolveExtension(contentType) : null) || 'bin')\n\t\tconst id = this.providers.uuid()\n\t\tconst localObjectKey = (prefix ? prefix + '/' : '') + `${id}${suffix ?? ''}.${ext}`\n\t\tthis.authorizator.verifyUploadAccess({ key: localObjectKey, size })\n\n\t\tconst objectKey = (this.config.prefix ? this.config.prefix + '/' : '') + localObjectKey\n\n\t\tconst bucket = this.config.bucket\n\t\tif (acl && this.config.noAcl) {\n\t\t\tthrow new UserInputError('ACL is not supported')\n\t\t}\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Cache-Control': 'immutable',\n\t\t}\n\t\tif (contentType) {\n\t\t\theaders['Content-Type'] = contentType\n\t\t}\n\n\t\tif (!this.config.noAcl && acl !== 'NONE') {\n\t\t\tconst mapping = { PUBLIC_READ: 'public-read', PRIVATE: 'private' }\n\t\t\theaders['x-amz-acl'] = mapping[acl ?? 'PUBLIC_READ']\n\t\t}\n\t\tif (fileName || contentDisposition) {\n\t\t\tlet contentDispositionHeader = contentDisposition?.toLowerCase() ?? 'inline'\n\t\t\tif (fileName) {\n\t\t\t\tcontentDispositionHeader += `; filename*=UTF-8''${encodeURIComponent(fileName)}`\n\t\t\t}\n\t\t\theaders['Content-Disposition'] = contentDispositionHeader\n\t\t}\n\t\tconst headersToSend = Object.entries(headers).map(([key, value]) => ({ key, value }))\n\n\t\t// intentionally not sending following headers\n\t\tif (size) {\n\t\t\theaders['Content-Length'] = String(size)\n\t\t}\n\n\t\tconst url = this.signer.sign({\n\t\t\taction: 'upload',\n\t\t\texpiration: expiration ?? 3600,\n\t\t\tkey: objectKey,\n\t\t\theaders: { ...headers },\n\t\t})\n\n\t\tconst publicUrl = this.formatPublicUrl(objectKey)\n\t\treturn {\n\t\t\tbucket,\n\t\t\tobjectKey,\n\t\t\turl,\n\t\t\tpublicUrl,\n\t\t\theaders: headersToSend,\n\t\t\tmethod: 'PUT',\n\t\t}\n\t}\n\n\tpublic getSignedReadUrl({ objectKey, expiration }: { objectKey: string; expiration: number | null}): SignedReadUrl {\n\t\tconst bucket = this.config.bucket\n\n\t\tconst publicPrefix = this.formatPublicUrl('')\n\t\tif (objectKey.startsWith(publicPrefix)) {\n\t\t\tobjectKey = objectKey.substring(publicPrefix.length)\n\t\t}\n\t\tif (this.config.prefix && !objectKey.startsWith(this.config.prefix)) {\n\t\t\tthrow new ForbiddenError(\n\t\t\t\t`Given object key \"${objectKey}\" does not start with a project prefix \"${this.config.prefix}\"`,\n\t\t\t)\n\t\t}\n\t\tconst localObjectKey = this.config.prefix ? objectKey.substring(this.config.prefix.length + 1) : objectKey\n\t\tthis.authorizator.verifyReadAccess({ key: localObjectKey })\n\n\t\tconst url = this.signer.sign({\n\t\t\taction: 'read',\n\t\t\texpiration: expiration ?? 3600,\n\t\t\tkey: objectKey,\n\t\t\theaders: {},\n\t\t})\n\n\t\treturn {\n\t\t\tbucket,\n\t\t\tobjectKey,\n\t\t\turl,\n\t\t\theaders: [],\n\t\t\tmethod: 'GET',\n\t\t}\n\t}\n\n\tpublic formatPublicUrl(key: string): string {\n\t\treturn `${this.publicBaseUrl}/${key}`\n\t}\n}\n\nexport class S3ServiceFactory {\n\tpublic create(config: S3Config, providers: Providers, authorizator: S3ObjectAuthorizator) {\n\t\treturn new S3Service(config, providers, authorizator)\n\t}\n}\n"],"names":["resolveS3PublicBaseUrl","S3Signer","resolveExtension","UserInputError","ForbiddenError"],"mappings":"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"}
@@ -1,105 +0,0 @@
1
- import { extension } from "mime-types";
2
- import { resolveS3PublicBaseUrl } from "./Config.js";
3
- import { UserInputError, ForbiddenError } from "@contember/graphql-utils";
4
- import { S3Signer } from "./S3Signer.js";
5
- var __defProp = Object.defineProperty;
6
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
- class S3Service {
9
- constructor(config, providers, authorizator) {
10
- this.config = config;
11
- this.providers = providers;
12
- this.authorizator = authorizator;
13
- __publicField(this, "publicBaseUrl");
14
- __publicField(this, "signer");
15
- this.publicBaseUrl = resolveS3PublicBaseUrl(config);
16
- this.signer = new S3Signer(config, providers);
17
- }
18
- getSignedUploadUrl({ acl, contentDisposition, contentType, expiration, prefix, suffix, fileName, extension: extension$1, size }) {
19
- const ext = extension$1 ?? ((contentType ? extension(contentType) : null) || "bin");
20
- const id = this.providers.uuid();
21
- const localObjectKey = (prefix ? prefix + "/" : "") + `${id}${suffix ?? ""}.${ext}`;
22
- this.authorizator.verifyUploadAccess({ key: localObjectKey, size });
23
- const objectKey = (this.config.prefix ? this.config.prefix + "/" : "") + localObjectKey;
24
- const bucket = this.config.bucket;
25
- if (acl && this.config.noAcl) {
26
- throw new UserInputError("ACL is not supported");
27
- }
28
- const headers = {
29
- "Cache-Control": "immutable"
30
- };
31
- if (contentType) {
32
- headers["Content-Type"] = contentType;
33
- }
34
- if (!this.config.noAcl && acl !== "NONE") {
35
- const mapping = { PUBLIC_READ: "public-read", PRIVATE: "private" };
36
- headers["x-amz-acl"] = mapping[acl ?? "PUBLIC_READ"];
37
- }
38
- if (fileName || contentDisposition) {
39
- let contentDispositionHeader = contentDisposition?.toLowerCase() ?? "inline";
40
- if (fileName) {
41
- contentDispositionHeader += `; filename*=UTF-8''${encodeURIComponent(fileName)}`;
42
- }
43
- headers["Content-Disposition"] = contentDispositionHeader;
44
- }
45
- const headersToSend = Object.entries(headers).map(([key, value]) => ({ key, value }));
46
- if (size) {
47
- headers["Content-Length"] = String(size);
48
- }
49
- const url = this.signer.sign({
50
- action: "upload",
51
- expiration: expiration ?? 3600,
52
- key: objectKey,
53
- headers: { ...headers }
54
- });
55
- const publicUrl = this.formatPublicUrl(objectKey);
56
- return {
57
- bucket,
58
- objectKey,
59
- url,
60
- publicUrl,
61
- headers: headersToSend,
62
- method: "PUT"
63
- };
64
- }
65
- getSignedReadUrl({ objectKey, expiration }) {
66
- const bucket = this.config.bucket;
67
- const publicPrefix = this.formatPublicUrl("");
68
- if (objectKey.startsWith(publicPrefix)) {
69
- objectKey = objectKey.substring(publicPrefix.length);
70
- }
71
- if (this.config.prefix && !objectKey.startsWith(this.config.prefix)) {
72
- throw new ForbiddenError(
73
- `Given object key "${objectKey}" does not start with a project prefix "${this.config.prefix}"`
74
- );
75
- }
76
- const localObjectKey = this.config.prefix ? objectKey.substring(this.config.prefix.length + 1) : objectKey;
77
- this.authorizator.verifyReadAccess({ key: localObjectKey });
78
- const url = this.signer.sign({
79
- action: "read",
80
- expiration: expiration ?? 3600,
81
- key: objectKey,
82
- headers: {}
83
- });
84
- return {
85
- bucket,
86
- objectKey,
87
- url,
88
- headers: [],
89
- method: "GET"
90
- };
91
- }
92
- formatPublicUrl(key) {
93
- return `${this.publicBaseUrl}/${key}`;
94
- }
95
- }
96
- class S3ServiceFactory {
97
- create(config, providers, authorizator) {
98
- return new S3Service(config, providers, authorizator);
99
- }
100
- }
101
- export {
102
- S3Service,
103
- S3ServiceFactory
104
- };
105
- //# sourceMappingURL=S3Service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"S3Service.js","sources":["../../../../packages/engine-s3-plugin/src/S3Service.ts"],"sourcesContent":["import { extension as resolveExtension } from 'mime-types'\nimport { resolveS3PublicBaseUrl, S3Config } from './Config'\nimport { ForbiddenError, UserInputError } from '@contember/graphql-utils'\nimport { Providers } from '@contember/engine-plugins'\nimport { S3Signer } from './S3Signer'\nimport { S3GenerateSignedUploadInput } from './S3SchemaTypes'\nimport { S3ObjectAuthorizator } from './S3ObjectAuthorizator'\n\ntype SignedReadUrl = {\n\turl: string\n\tbucket: string\n\tobjectKey: string\n\theaders: { key: string; value: string }[]\n\tmethod: string\n}\n\ntype SignedUploadUrl = {\n\tobjectKey: string\n\turl: string\n\tbucket: string\n\tpublicUrl: string\n\theaders: { key: string; value: string }[]\n\tmethod: string\n}\n\n\nexport class S3Service {\n\tprivate readonly publicBaseUrl: string\n\n\tprivate readonly signer: S3Signer\n\n\tconstructor(\n\t\tpublic readonly config: S3Config,\n\t\tprivate readonly providers: Pick<Providers, 'uuid' | 'now'>,\n\t\tprivate readonly authorizator: S3ObjectAuthorizator,\n\t) {\n\t\tthis.publicBaseUrl = resolveS3PublicBaseUrl(config)\n\t\tthis.signer = new S3Signer(config, providers)\n\t}\n\n\tpublic getSignedUploadUrl(\n\t\t{ acl, contentDisposition, contentType, expiration, prefix, suffix, fileName, extension, size }: S3GenerateSignedUploadInput,\n\t): SignedUploadUrl {\n\t\tconst ext = extension ?? ((contentType ? resolveExtension(contentType) : null) || 'bin')\n\t\tconst id = this.providers.uuid()\n\t\tconst localObjectKey = (prefix ? prefix + '/' : '') + `${id}${suffix ?? ''}.${ext}`\n\t\tthis.authorizator.verifyUploadAccess({ key: localObjectKey, size })\n\n\t\tconst objectKey = (this.config.prefix ? this.config.prefix + '/' : '') + localObjectKey\n\n\t\tconst bucket = this.config.bucket\n\t\tif (acl && this.config.noAcl) {\n\t\t\tthrow new UserInputError('ACL is not supported')\n\t\t}\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Cache-Control': 'immutable',\n\t\t}\n\t\tif (contentType) {\n\t\t\theaders['Content-Type'] = contentType\n\t\t}\n\n\t\tif (!this.config.noAcl && acl !== 'NONE') {\n\t\t\tconst mapping = { PUBLIC_READ: 'public-read', PRIVATE: 'private' }\n\t\t\theaders['x-amz-acl'] = mapping[acl ?? 'PUBLIC_READ']\n\t\t}\n\t\tif (fileName || contentDisposition) {\n\t\t\tlet contentDispositionHeader = contentDisposition?.toLowerCase() ?? 'inline'\n\t\t\tif (fileName) {\n\t\t\t\tcontentDispositionHeader += `; filename*=UTF-8''${encodeURIComponent(fileName)}`\n\t\t\t}\n\t\t\theaders['Content-Disposition'] = contentDispositionHeader\n\t\t}\n\t\tconst headersToSend = Object.entries(headers).map(([key, value]) => ({ key, value }))\n\n\t\t// intentionally not sending following headers\n\t\tif (size) {\n\t\t\theaders['Content-Length'] = String(size)\n\t\t}\n\n\t\tconst url = this.signer.sign({\n\t\t\taction: 'upload',\n\t\t\texpiration: expiration ?? 3600,\n\t\t\tkey: objectKey,\n\t\t\theaders: { ...headers },\n\t\t})\n\n\t\tconst publicUrl = this.formatPublicUrl(objectKey)\n\t\treturn {\n\t\t\tbucket,\n\t\t\tobjectKey,\n\t\t\turl,\n\t\t\tpublicUrl,\n\t\t\theaders: headersToSend,\n\t\t\tmethod: 'PUT',\n\t\t}\n\t}\n\n\tpublic getSignedReadUrl({ objectKey, expiration }: { objectKey: string; expiration: number | null}): SignedReadUrl {\n\t\tconst bucket = this.config.bucket\n\n\t\tconst publicPrefix = this.formatPublicUrl('')\n\t\tif (objectKey.startsWith(publicPrefix)) {\n\t\t\tobjectKey = objectKey.substring(publicPrefix.length)\n\t\t}\n\t\tif (this.config.prefix && !objectKey.startsWith(this.config.prefix)) {\n\t\t\tthrow new ForbiddenError(\n\t\t\t\t`Given object key \"${objectKey}\" does not start with a project prefix \"${this.config.prefix}\"`,\n\t\t\t)\n\t\t}\n\t\tconst localObjectKey = this.config.prefix ? objectKey.substring(this.config.prefix.length + 1) : objectKey\n\t\tthis.authorizator.verifyReadAccess({ key: localObjectKey })\n\n\t\tconst url = this.signer.sign({\n\t\t\taction: 'read',\n\t\t\texpiration: expiration ?? 3600,\n\t\t\tkey: objectKey,\n\t\t\theaders: {},\n\t\t})\n\n\t\treturn {\n\t\t\tbucket,\n\t\t\tobjectKey,\n\t\t\turl,\n\t\t\theaders: [],\n\t\t\tmethod: 'GET',\n\t\t}\n\t}\n\n\tpublic formatPublicUrl(key: string): string {\n\t\treturn `${this.publicBaseUrl}/${key}`\n\t}\n}\n\nexport class S3ServiceFactory {\n\tpublic create(config: S3Config, providers: Providers, authorizator: S3ObjectAuthorizator) {\n\t\treturn new S3Service(config, providers, authorizator)\n\t}\n}\n"],"names":["extension","resolveExtension"],"mappings":"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"}
@@ -1,84 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const Config = require("./Config.cjs");
4
- const qs = require("qs");
5
- const crypto = require("node:crypto");
6
- var __defProp = Object.defineProperty;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
9
- const hmac = (secret, data) => crypto.createHmac("sha256", secret).update(data).digest();
10
- const hash = (data) => crypto.createHash("sha256").update(data).digest("hex");
11
- const unsignableHeaders = ["authorization", "user-agent", "content-type", "expect", "x-amzn-trace-id"];
12
- const sortMap = (input) => {
13
- return Object.fromEntries(Object.entries(input).sort((a, b) => a[0] < b[0] ? -1 : 1));
14
- };
15
- class S3Signer {
16
- constructor(config, providers) {
17
- this.config = config;
18
- this.providers = providers;
19
- __publicField(this, "region");
20
- this.region = config.region || "eu-west-1";
21
- }
22
- sign(request) {
23
- const uris = Config.resolveS3Endpoint(this.config);
24
- request.headers.host = uris.endpoint.substring(uris.endpoint.indexOf("://") + 3);
25
- const nowFormatted = this.providers.now().toISOString().replace(/[:\-]|\.\d{3}/g, "");
26
- const queryString = this.getQueryParams(request, nowFormatted);
27
- const path = uris.basePath + "/" + request.key;
28
- const lines = [
29
- request.action === "read" ? "GET" : "PUT",
30
- path,
31
- queryString,
32
- this.getSignedHeaders(request),
33
- this.getSignedHeaderNames(Object.keys(request.headers)),
34
- "UNSIGNED-PAYLOAD"
35
- ];
36
- const canonicalRequest = lines.join("\n");
37
- const parts = ["AWS4-HMAC-SHA256", nowFormatted, this.getScope(nowFormatted), hash(canonicalRequest)];
38
- const signature = [nowFormatted.substring(0, 8), this.region, "s3", "aws4_request", parts.join("\n")].reduce((acc, x) => hmac(acc, x), Buffer.from("AWS4" + this.config.credentials.secret)).toString("hex");
39
- return uris.endpoint + path + "?" + (queryString + "&X-Amz-Signature=" + signature).split("&").sort().join("&");
40
- }
41
- getQueryParams(request, dateFormatted) {
42
- const scope = this.getScope(dateFormatted);
43
- const queryString = {
44
- "X-Amz-Date": dateFormatted,
45
- "X-Amz-Algorithm": "AWS4-HMAC-SHA256",
46
- "X-Amz-Credential": this.config.credentials.key + "/" + scope,
47
- "X-Amz-Expires": String(request.expiration),
48
- "X-Amz-SignedHeaders": this.getSignedHeaderNames(Object.keys(request.headers))
49
- };
50
- const headersToQs = ["content-type", "content-md5", "cache-control"];
51
- for (const header in request.headers) {
52
- const headerLc = header.toLowerCase();
53
- if (headersToQs.includes(headerLc) || headerLc.startsWith("x-amz-")) {
54
- queryString[headerLc.startsWith("x-amz-meta-") ? headerLc : header] = request.headers[header];
55
- }
56
- }
57
- const qsSorted = sortMap(queryString);
58
- return qs.stringify(qsSorted);
59
- }
60
- getScope(dateFormatted) {
61
- return dateFormatted.substring(0, 8) + "/" + this.region + "/s3/aws4_request";
62
- }
63
- getSignedHeaders(request) {
64
- const lines = [];
65
- for (const header in request.headers) {
66
- const headerNameLc = header.toLowerCase();
67
- if (!this.isHeaderSignable(headerNameLc)) {
68
- continue;
69
- }
70
- const value = request.headers[header].replace(/\s+/g, " ").replace(/^\s+|\s+$/g, "");
71
- lines.push(`${headerNameLc}:${value}
72
- `);
73
- }
74
- return lines.sort().join("");
75
- }
76
- isHeaderSignable(headerName) {
77
- return headerName.toLowerCase().startsWith("x-amz") || !unsignableHeaders.includes(headerName.toLowerCase());
78
- }
79
- getSignedHeaderNames(headers) {
80
- return headers.map((it) => it.toLowerCase()).filter(this.isHeaderSignable).sort().join(";");
81
- }
82
- }
83
- exports.S3Signer = S3Signer;
84
- //# sourceMappingURL=S3Signer.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"S3Signer.cjs","sources":["../../../../packages/engine-s3-plugin/src/S3Signer.ts"],"sourcesContent":["import { resolveS3Endpoint, S3Config } from './Config'\nimport { Providers } from '@contember/engine-plugins'\nimport qs from 'qs'\nimport { BinaryLike, createHash, createHmac } from 'node:crypto'\n\ninterface S3Request {\n\taction: 'read' | 'upload'\n\tkey: string\n\texpiration: number\n\theaders: Record<string, string>\n}\n\nconst hmac = (secret: BinaryLike, data: BinaryLike) => createHmac('sha256', secret).update(data).digest()\n\nconst hash = (data: BinaryLike) => createHash('sha256').update(data).digest('hex')\n\nconst unsignableHeaders = ['authorization', 'user-agent', 'content-type', 'expect', 'x-amzn-trace-id']\n\nconst sortMap = <T extends Record<string, any>>(input: T): T => {\n\treturn Object.fromEntries(Object.entries(input).sort((a, b) => (a[0] < b[0] ? -1 : 1))) as T\n}\nexport class S3Signer {\n\tprivate region: string\n\n\tconstructor(private readonly config: S3Config, private readonly providers: Pick<Providers, 'now'>) {\n\t\tthis.region = config.region || 'eu-west-1'\n\t}\n\n\tpublic sign(request: S3Request) {\n\t\tconst uris = resolveS3Endpoint(this.config)\n\t\trequest.headers.host = uris.endpoint.substring(uris.endpoint.indexOf('://') + 3)\n\t\tconst nowFormatted = this.providers\n\t\t\t.now()\n\t\t\t.toISOString()\n\t\t\t.replace(/[:\\-]|\\.\\d{3}/g, '')\n\t\tconst queryString = this.getQueryParams(request, nowFormatted)\n\t\tconst path = uris.basePath + '/' + request.key\n\t\tconst lines = [\n\t\t\trequest.action === 'read' ? 'GET' : 'PUT',\n\t\t\tpath,\n\t\t\tqueryString,\n\t\t\tthis.getSignedHeaders(request),\n\t\t\tthis.getSignedHeaderNames(Object.keys(request.headers)),\n\t\t\t'UNSIGNED-PAYLOAD',\n\t\t]\n\t\tconst canonicalRequest = lines.join('\\n')\n\n\t\tconst parts = ['AWS4-HMAC-SHA256', nowFormatted, this.getScope(nowFormatted), hash(canonicalRequest)]\n\n\t\tconst signature = [nowFormatted.substring(0, 8), this.region, 's3', 'aws4_request', parts.join('\\n')]\n\t\t\t.reduce<Buffer>((acc, x) => hmac(acc, x), Buffer.from('AWS4' + this.config.credentials.secret))\n\t\t\t.toString('hex')\n\t\treturn uris.endpoint + path + '?' + (queryString + '&X-Amz-Signature=' + signature).split('&').sort().join('&')\n\t}\n\n\tprivate getQueryParams(request: S3Request, dateFormatted: string) {\n\t\tconst scope = this.getScope(dateFormatted)\n\t\tconst queryString: Record<string, string> = {\n\t\t\t'X-Amz-Date': dateFormatted,\n\t\t\t'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',\n\t\t\t'X-Amz-Credential': this.config.credentials.key + '/' + scope,\n\t\t\t'X-Amz-Expires': String(request.expiration),\n\t\t\t'X-Amz-SignedHeaders': this.getSignedHeaderNames(Object.keys(request.headers)),\n\t\t}\n\n\t\tconst headersToQs = ['content-type', 'content-md5', 'cache-control']\n\t\tfor (const header in request.headers) {\n\t\t\tconst headerLc = header.toLowerCase()\n\t\t\tif (headersToQs.includes(headerLc) || headerLc.startsWith('x-amz-')) {\n\t\t\t\tqueryString[headerLc.startsWith('x-amz-meta-') ? headerLc : header] = request.headers[header]\n\t\t\t}\n\t\t}\n\t\tconst qsSorted = sortMap(queryString)\n\t\treturn qs.stringify(qsSorted)\n\t}\n\n\tprivate getScope(dateFormatted: string) {\n\t\treturn dateFormatted.substring(0, 8) + '/' + this.region + '/s3/aws4_request'\n\t}\n\n\tprivate getSignedHeaders(request: S3Request): string {\n\t\tconst lines = []\n\t\tfor (const header in request.headers) {\n\t\t\tconst headerNameLc = header.toLowerCase()\n\t\t\tif (!this.isHeaderSignable(headerNameLc)) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst value = request.headers[header].replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n\t\t\tlines.push(`${headerNameLc}:${value}\\n`)\n\t\t}\n\t\treturn lines.sort().join('')\n\t}\n\n\tprivate isHeaderSignable(headerName: string) {\n\t\treturn headerName.toLowerCase().startsWith('x-amz') || !unsignableHeaders.includes(headerName.toLowerCase())\n\t}\n\n\tprivate getSignedHeaderNames(headers: string[]) {\n\t\treturn headers\n\t\t\t.map(it => it.toLowerCase())\n\t\t\t.filter(this.isHeaderSignable)\n\t\t\t.sort()\n\t\t\t.join(';')\n\t}\n}\n"],"names":["createHmac","createHash","resolveS3Endpoint"],"mappings":"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"}
@@ -1,84 +0,0 @@
1
- import { resolveS3Endpoint } from "./Config.js";
2
- import qs from "qs";
3
- import { createHmac, createHash } from "node:crypto";
4
- var __defProp = Object.defineProperty;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
7
- const hmac = (secret, data) => createHmac("sha256", secret).update(data).digest();
8
- const hash = (data) => createHash("sha256").update(data).digest("hex");
9
- const unsignableHeaders = ["authorization", "user-agent", "content-type", "expect", "x-amzn-trace-id"];
10
- const sortMap = (input) => {
11
- return Object.fromEntries(Object.entries(input).sort((a, b) => a[0] < b[0] ? -1 : 1));
12
- };
13
- class S3Signer {
14
- constructor(config, providers) {
15
- this.config = config;
16
- this.providers = providers;
17
- __publicField(this, "region");
18
- this.region = config.region || "eu-west-1";
19
- }
20
- sign(request) {
21
- const uris = resolveS3Endpoint(this.config);
22
- request.headers.host = uris.endpoint.substring(uris.endpoint.indexOf("://") + 3);
23
- const nowFormatted = this.providers.now().toISOString().replace(/[:\-]|\.\d{3}/g, "");
24
- const queryString = this.getQueryParams(request, nowFormatted);
25
- const path = uris.basePath + "/" + request.key;
26
- const lines = [
27
- request.action === "read" ? "GET" : "PUT",
28
- path,
29
- queryString,
30
- this.getSignedHeaders(request),
31
- this.getSignedHeaderNames(Object.keys(request.headers)),
32
- "UNSIGNED-PAYLOAD"
33
- ];
34
- const canonicalRequest = lines.join("\n");
35
- const parts = ["AWS4-HMAC-SHA256", nowFormatted, this.getScope(nowFormatted), hash(canonicalRequest)];
36
- const signature = [nowFormatted.substring(0, 8), this.region, "s3", "aws4_request", parts.join("\n")].reduce((acc, x) => hmac(acc, x), Buffer.from("AWS4" + this.config.credentials.secret)).toString("hex");
37
- return uris.endpoint + path + "?" + (queryString + "&X-Amz-Signature=" + signature).split("&").sort().join("&");
38
- }
39
- getQueryParams(request, dateFormatted) {
40
- const scope = this.getScope(dateFormatted);
41
- const queryString = {
42
- "X-Amz-Date": dateFormatted,
43
- "X-Amz-Algorithm": "AWS4-HMAC-SHA256",
44
- "X-Amz-Credential": this.config.credentials.key + "/" + scope,
45
- "X-Amz-Expires": String(request.expiration),
46
- "X-Amz-SignedHeaders": this.getSignedHeaderNames(Object.keys(request.headers))
47
- };
48
- const headersToQs = ["content-type", "content-md5", "cache-control"];
49
- for (const header in request.headers) {
50
- const headerLc = header.toLowerCase();
51
- if (headersToQs.includes(headerLc) || headerLc.startsWith("x-amz-")) {
52
- queryString[headerLc.startsWith("x-amz-meta-") ? headerLc : header] = request.headers[header];
53
- }
54
- }
55
- const qsSorted = sortMap(queryString);
56
- return qs.stringify(qsSorted);
57
- }
58
- getScope(dateFormatted) {
59
- return dateFormatted.substring(0, 8) + "/" + this.region + "/s3/aws4_request";
60
- }
61
- getSignedHeaders(request) {
62
- const lines = [];
63
- for (const header in request.headers) {
64
- const headerNameLc = header.toLowerCase();
65
- if (!this.isHeaderSignable(headerNameLc)) {
66
- continue;
67
- }
68
- const value = request.headers[header].replace(/\s+/g, " ").replace(/^\s+|\s+$/g, "");
69
- lines.push(`${headerNameLc}:${value}
70
- `);
71
- }
72
- return lines.sort().join("");
73
- }
74
- isHeaderSignable(headerName) {
75
- return headerName.toLowerCase().startsWith("x-amz") || !unsignableHeaders.includes(headerName.toLowerCase());
76
- }
77
- getSignedHeaderNames(headers) {
78
- return headers.map((it) => it.toLowerCase()).filter(this.isHeaderSignable).sort().join(";");
79
- }
80
- }
81
- export {
82
- S3Signer
83
- };
84
- //# sourceMappingURL=S3Signer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"S3Signer.js","sources":["../../../../packages/engine-s3-plugin/src/S3Signer.ts"],"sourcesContent":["import { resolveS3Endpoint, S3Config } from './Config'\nimport { Providers } from '@contember/engine-plugins'\nimport qs from 'qs'\nimport { BinaryLike, createHash, createHmac } from 'node:crypto'\n\ninterface S3Request {\n\taction: 'read' | 'upload'\n\tkey: string\n\texpiration: number\n\theaders: Record<string, string>\n}\n\nconst hmac = (secret: BinaryLike, data: BinaryLike) => createHmac('sha256', secret).update(data).digest()\n\nconst hash = (data: BinaryLike) => createHash('sha256').update(data).digest('hex')\n\nconst unsignableHeaders = ['authorization', 'user-agent', 'content-type', 'expect', 'x-amzn-trace-id']\n\nconst sortMap = <T extends Record<string, any>>(input: T): T => {\n\treturn Object.fromEntries(Object.entries(input).sort((a, b) => (a[0] < b[0] ? -1 : 1))) as T\n}\nexport class S3Signer {\n\tprivate region: string\n\n\tconstructor(private readonly config: S3Config, private readonly providers: Pick<Providers, 'now'>) {\n\t\tthis.region = config.region || 'eu-west-1'\n\t}\n\n\tpublic sign(request: S3Request) {\n\t\tconst uris = resolveS3Endpoint(this.config)\n\t\trequest.headers.host = uris.endpoint.substring(uris.endpoint.indexOf('://') + 3)\n\t\tconst nowFormatted = this.providers\n\t\t\t.now()\n\t\t\t.toISOString()\n\t\t\t.replace(/[:\\-]|\\.\\d{3}/g, '')\n\t\tconst queryString = this.getQueryParams(request, nowFormatted)\n\t\tconst path = uris.basePath + '/' + request.key\n\t\tconst lines = [\n\t\t\trequest.action === 'read' ? 'GET' : 'PUT',\n\t\t\tpath,\n\t\t\tqueryString,\n\t\t\tthis.getSignedHeaders(request),\n\t\t\tthis.getSignedHeaderNames(Object.keys(request.headers)),\n\t\t\t'UNSIGNED-PAYLOAD',\n\t\t]\n\t\tconst canonicalRequest = lines.join('\\n')\n\n\t\tconst parts = ['AWS4-HMAC-SHA256', nowFormatted, this.getScope(nowFormatted), hash(canonicalRequest)]\n\n\t\tconst signature = [nowFormatted.substring(0, 8), this.region, 's3', 'aws4_request', parts.join('\\n')]\n\t\t\t.reduce<Buffer>((acc, x) => hmac(acc, x), Buffer.from('AWS4' + this.config.credentials.secret))\n\t\t\t.toString('hex')\n\t\treturn uris.endpoint + path + '?' + (queryString + '&X-Amz-Signature=' + signature).split('&').sort().join('&')\n\t}\n\n\tprivate getQueryParams(request: S3Request, dateFormatted: string) {\n\t\tconst scope = this.getScope(dateFormatted)\n\t\tconst queryString: Record<string, string> = {\n\t\t\t'X-Amz-Date': dateFormatted,\n\t\t\t'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',\n\t\t\t'X-Amz-Credential': this.config.credentials.key + '/' + scope,\n\t\t\t'X-Amz-Expires': String(request.expiration),\n\t\t\t'X-Amz-SignedHeaders': this.getSignedHeaderNames(Object.keys(request.headers)),\n\t\t}\n\n\t\tconst headersToQs = ['content-type', 'content-md5', 'cache-control']\n\t\tfor (const header in request.headers) {\n\t\t\tconst headerLc = header.toLowerCase()\n\t\t\tif (headersToQs.includes(headerLc) || headerLc.startsWith('x-amz-')) {\n\t\t\t\tqueryString[headerLc.startsWith('x-amz-meta-') ? headerLc : header] = request.headers[header]\n\t\t\t}\n\t\t}\n\t\tconst qsSorted = sortMap(queryString)\n\t\treturn qs.stringify(qsSorted)\n\t}\n\n\tprivate getScope(dateFormatted: string) {\n\t\treturn dateFormatted.substring(0, 8) + '/' + this.region + '/s3/aws4_request'\n\t}\n\n\tprivate getSignedHeaders(request: S3Request): string {\n\t\tconst lines = []\n\t\tfor (const header in request.headers) {\n\t\t\tconst headerNameLc = header.toLowerCase()\n\t\t\tif (!this.isHeaderSignable(headerNameLc)) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst value = request.headers[header].replace(/\\s+/g, ' ').replace(/^\\s+|\\s+$/g, '')\n\t\t\tlines.push(`${headerNameLc}:${value}\\n`)\n\t\t}\n\t\treturn lines.sort().join('')\n\t}\n\n\tprivate isHeaderSignable(headerName: string) {\n\t\treturn headerName.toLowerCase().startsWith('x-amz') || !unsignableHeaders.includes(headerName.toLowerCase())\n\t}\n\n\tprivate getSignedHeaderNames(headers: string[]) {\n\t\treturn headers\n\t\t\t.map(it => it.toLowerCase())\n\t\t\t.filter(this.isHeaderSignable)\n\t\t\t.sort()\n\t\t\t.join(';')\n\t}\n}\n"],"names":[],"mappings":"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"}
@@ -1,27 +0,0 @@
1
- "use strict";
2
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
3
- const S3ConfigProcessor = require("./src/S3ConfigProcessor.cjs");
4
- const S3SchemaContributor = require("./src/S3SchemaContributor.cjs");
5
- const S3Service = require("./src/S3Service.cjs");
6
- const S3ObjectAuthorizator = require("./src/S3ObjectAuthorizator.cjs");
7
- var __defProp = Object.defineProperty;
8
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
- var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
10
- class S3 {
11
- constructor() {
12
- __publicField(this, "name", "contember/s3");
13
- }
14
- getConfigProcessor() {
15
- return new S3ConfigProcessor.S3ConfigProcessor();
16
- }
17
- getSchemaContributor({ providers }) {
18
- const s3ServiceFactory = new S3Service.S3ServiceFactory();
19
- return new S3SchemaContributor.S3SchemaContributor(s3ServiceFactory, providers);
20
- }
21
- }
22
- exports.S3SchemaContributor = S3SchemaContributor.S3SchemaContributor;
23
- exports.S3Service = S3Service.S3Service;
24
- exports.S3ServiceFactory = S3Service.S3ServiceFactory;
25
- exports.S3ObjectAuthorizator = S3ObjectAuthorizator.S3ObjectAuthorizator;
26
- exports.default = S3;
27
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../packages/engine-s3-plugin/src/index.ts"],"sourcesContent":["import { Plugin, SchemaContributorArgs } from '@contember/engine-plugins'\nimport { S3ConfigProcessor } from './S3ConfigProcessor'\nimport { S3SchemaContributor } from './S3SchemaContributor'\nimport { S3ServiceFactory } from './S3Service'\nimport { Project3Config } from './Config'\n\nexport * from './S3ObjectAuthorizator'\nexport * from './S3SchemaContributor'\nexport * from './S3Service'\n\nexport default class S3 implements Plugin<Project3Config> {\n\tname = 'contember/s3'\n\n\tgetConfigProcessor() {\n\t\treturn new S3ConfigProcessor()\n\t}\n\n\tgetSchemaContributor({ providers }: SchemaContributorArgs) {\n\t\tconst s3ServiceFactory = new S3ServiceFactory()\n\t\treturn new S3SchemaContributor(s3ServiceFactory, providers)\n\t}\n}\n"],"names":["S3ConfigProcessor","S3ServiceFactory","S3SchemaContributor"],"mappings":";;;;;;;;;AAUA,MAAqB,GAAqC;AAAA,EAA1D,cAAA;AACQ,kBAAA,MAAA,QAAA,cAAA;AAAA,EAAA;AAAA,EAEP,qBAAqB;AACpB,WAAO,IAAIA,kBAAAA,kBAAkB;AAAA,EAAA;AAAA,EAG9B,qBAAqB,EAAE,aAAoC;AACpD,UAAA,mBAAmB,IAAIC,2BAAiB;AACvC,WAAA,IAAIC,oBAAAA,oBAAoB,kBAAkB,SAAS;AAAA,EAAA;AAE5D;;;;;;"}
@@ -1,28 +0,0 @@
1
- import { S3ConfigProcessor } from "./src/S3ConfigProcessor.js";
2
- import { S3SchemaContributor } from "./src/S3SchemaContributor.js";
3
- import { S3ServiceFactory } from "./src/S3Service.js";
4
- import { S3Service } from "./src/S3Service.js";
5
- import { S3ObjectAuthorizator } from "./src/S3ObjectAuthorizator.js";
6
- var __defProp = Object.defineProperty;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
9
- class S3 {
10
- constructor() {
11
- __publicField(this, "name", "contember/s3");
12
- }
13
- getConfigProcessor() {
14
- return new S3ConfigProcessor();
15
- }
16
- getSchemaContributor({ providers }) {
17
- const s3ServiceFactory = new S3ServiceFactory();
18
- return new S3SchemaContributor(s3ServiceFactory, providers);
19
- }
20
- }
21
- export {
22
- S3ObjectAuthorizator,
23
- S3SchemaContributor,
24
- S3Service,
25
- S3ServiceFactory,
26
- S3 as default
27
- };
28
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../../packages/engine-s3-plugin/src/index.ts"],"sourcesContent":["import { Plugin, SchemaContributorArgs } from '@contember/engine-plugins'\nimport { S3ConfigProcessor } from './S3ConfigProcessor'\nimport { S3SchemaContributor } from './S3SchemaContributor'\nimport { S3ServiceFactory } from './S3Service'\nimport { Project3Config } from './Config'\n\nexport * from './S3ObjectAuthorizator'\nexport * from './S3SchemaContributor'\nexport * from './S3Service'\n\nexport default class S3 implements Plugin<Project3Config> {\n\tname = 'contember/s3'\n\n\tgetConfigProcessor() {\n\t\treturn new S3ConfigProcessor()\n\t}\n\n\tgetSchemaContributor({ providers }: SchemaContributorArgs) {\n\t\tconst s3ServiceFactory = new S3ServiceFactory()\n\t\treturn new S3SchemaContributor(s3ServiceFactory, providers)\n\t}\n}\n"],"names":[],"mappings":";;;;;;;;AAUA,MAAqB,GAAqC;AAAA,EAA1D,cAAA;AACQ,kBAAA,MAAA,QAAA,cAAA;AAAA,EAAA;AAAA,EAEP,qBAAqB;AACpB,WAAO,IAAI,kBAAkB;AAAA,EAAA;AAAA,EAG9B,qBAAqB,EAAE,aAAoC;AACpD,UAAA,mBAAmB,IAAI,iBAAiB;AACvC,WAAA,IAAI,oBAAoB,kBAAkB,SAAS;AAAA,EAAA;AAE5D;"}
@@ -1,73 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const Typesafe = require("@contember/typesafe");
4
- function _interopNamespaceDefault(e) {
5
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
6
- if (e) {
7
- for (const k in e) {
8
- if (k !== "default") {
9
- const d = Object.getOwnPropertyDescriptor(e, k);
10
- Object.defineProperty(n, k, d.get ? d : {
11
- enumerable: true,
12
- get: () => e[k]
13
- });
14
- }
15
- }
16
- }
17
- n.default = e;
18
- return Object.freeze(n);
19
- }
20
- const Typesafe__namespace = /* @__PURE__ */ _interopNamespaceDefault(Typesafe);
21
- const s3ConfigSchema = Typesafe__namespace.intersection(
22
- Typesafe__namespace.object({
23
- bucket: Typesafe__namespace.string,
24
- region: Typesafe__namespace.string,
25
- prefix: Typesafe__namespace.string,
26
- credentials: Typesafe__namespace.object({
27
- key: Typesafe__namespace.string,
28
- secret: Typesafe__namespace.string
29
- })
30
- }),
31
- Typesafe__namespace.partial({
32
- endpoint: Typesafe__namespace.string,
33
- cdnEndpoint: Typesafe__namespace.string,
34
- provider: Typesafe__namespace.enumeration(
35
- "aws",
36
- "minio",
37
- "ceph",
38
- "localstack",
39
- "cloudserver"
40
- /* cloudserver */
41
- ),
42
- noAcl: Typesafe__namespace.boolean
43
- })
44
- );
45
- const serversWithoutAclSupport = [
46
- "minio"
47
- /* minio */
48
- ];
49
- const resolveS3Config = (config) => {
50
- return {
51
- noAcl: !!config.provider && serversWithoutAclSupport.includes(config.provider),
52
- ...config
53
- };
54
- };
55
- const defaultRegion = "eu-west-1";
56
- const resolveS3Endpoint = (config) => {
57
- const hasLegacyPath = !!config.endpoint || config.bucket.includes(".");
58
- const endpoint = config.endpoint || `https://${hasLegacyPath ? "" : `${config.bucket}.`}s3.${config.region || defaultRegion}.amazonaws.com`;
59
- const basePath = hasLegacyPath ? `/${config.bucket}` : "";
60
- return { endpoint, basePath };
61
- };
62
- const resolveS3PublicBaseUrl = (config) => {
63
- if (config.cdnEndpoint) {
64
- return config.cdnEndpoint;
65
- }
66
- const { endpoint, basePath } = resolveS3Endpoint(config);
67
- return endpoint + basePath;
68
- };
69
- exports.resolveS3Config = resolveS3Config;
70
- exports.resolveS3Endpoint = resolveS3Endpoint;
71
- exports.resolveS3PublicBaseUrl = resolveS3PublicBaseUrl;
72
- exports.s3ConfigSchema = s3ConfigSchema;
73
- //# sourceMappingURL=Config.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Config.cjs","sources":["../../../../packages/engine-s3-plugin/src/Config.ts"],"sourcesContent":["import * as Typesafe from '@contember/typesafe'\n\nexport enum S3Providers {\n\taws = 'aws',\n\tminio = 'minio',\n\tceph = 'ceph',\n\tlocalstack = 'localstack',\n\tcloudserver = 'cloudserver',\n}\n\n\nexport const s3ConfigSchema = Typesafe.intersection(\n\tTypesafe.object({\n\t\tbucket: Typesafe.string,\n\t\tregion: Typesafe.string,\n\t\tprefix: Typesafe.string,\n\t\tcredentials: Typesafe.object({\n\t\t\tkey: Typesafe.string,\n\t\t\tsecret: Typesafe.string,\n\t\t}),\n\t}),\n\tTypesafe.partial({\n\t\tendpoint: Typesafe.string,\n\t\tcdnEndpoint: Typesafe.string,\n\t\tprovider: Typesafe.enumeration(S3Providers.aws, S3Providers.minio, S3Providers.ceph, S3Providers.localstack, S3Providers.cloudserver),\n\t\tnoAcl: Typesafe.boolean,\n\t}),\n)\n\nexport type S3Config = ReturnType<typeof s3ConfigSchema>\n\nexport type Project3Config = { s3?: S3Config }\n\n// todo\nconst serversWithoutAclSupport = [S3Providers.minio]\n\nexport const resolveS3Config = (config: S3Config): S3Config => {\n\treturn {\n\t\tnoAcl: !!config.provider && serversWithoutAclSupport.includes(config.provider),\n\t\t...config,\n\t}\n}\n\nconst defaultRegion = 'eu-west-1'\n\nexport const resolveS3Endpoint = (\n\tconfig: S3Config,\n): {\n\tendpoint: string\n\tbasePath: string\n} => {\n\tconst hasLegacyPath = !!config.endpoint || config.bucket.includes('.')\n\tconst endpoint = config.endpoint || `https://${hasLegacyPath ? '' : `${config.bucket}.`}s3.${config.region || defaultRegion}.amazonaws.com`\n\tconst basePath = hasLegacyPath ? `/${config.bucket}` : ''\n\n\treturn { endpoint, basePath }\n}\n\nexport const resolveS3PublicBaseUrl = (config: S3Config): string => {\n\tif (config.cdnEndpoint) {\n\t\treturn config.cdnEndpoint\n\t}\n\tconst { endpoint, basePath } = resolveS3Endpoint(config)\n\treturn endpoint + basePath\n}\n"],"names":["Typesafe"],"mappings":";;;;;;;;;;;;;;;;;;;;AAWO,MAAM,iBAAiBA,oBAAS;AAAA,EACtCA,oBAAS,OAAO;AAAA,IACf,QAAQA,oBAAS;AAAA,IACjB,QAAQA,oBAAS;AAAA,IACjB,QAAQA,oBAAS;AAAA,IACjB,aAAaA,oBAAS,OAAO;AAAA,MAC5B,KAAKA,oBAAS;AAAA,MACd,QAAQA,oBAAS;AAAA,IACjB,CAAA;AAAA,EAAA,CACD;AAAA,EACDA,oBAAS,QAAQ;AAAA,IAChB,UAAUA,oBAAS;AAAA,IACnB,aAAaA,oBAAS;AAAA,IACtB,UAAUA,oBAAS;AAAA,MAAY;AAAA,MAAiB;AAAA,MAAmB;AAAA,MAAkB;AAAA,MAAwB;AAAA;AAAA,IAAuB;AAAA,IACpI,OAAOA,oBAAS;AAAA,EAChB,CAAA;AACF;AAOA,MAAM,2BAA2B;AAAA,EAAC;AAAA;AAAiB;AAEtC,MAAA,kBAAkB,CAAC,WAA+B;AACvD,SAAA;AAAA,IACN,OAAO,CAAC,CAAC,OAAO,YAAY,yBAAyB,SAAS,OAAO,QAAQ;AAAA,IAC7E,GAAG;AAAA,EACJ;AACD;AAEA,MAAM,gBAAgB;AAET,MAAA,oBAAoB,CAChC,WAII;AACE,QAAA,gBAAgB,CAAC,CAAC,OAAO,YAAY,OAAO,OAAO,SAAS,GAAG;AACrE,QAAM,WAAW,OAAO,YAAY,WAAW,gBAAgB,KAAK,GAAG,OAAO,MAAM,GAAG,MAAM,OAAO,UAAU,aAAa;AAC3H,QAAM,WAAW,gBAAgB,IAAI,OAAO,MAAM,KAAK;AAEhD,SAAA,EAAE,UAAU,SAAS;AAC7B;AAEa,MAAA,yBAAyB,CAAC,WAA6B;AACnE,MAAI,OAAO,aAAa;AACvB,WAAO,OAAO;AAAA,EAAA;AAEf,QAAM,EAAE,UAAU,aAAa,kBAAkB,MAAM;AACvD,SAAO,WAAW;AACnB;;;;;"}
@@ -1,56 +0,0 @@
1
- import * as Typesafe from "@contember/typesafe";
2
- const s3ConfigSchema = Typesafe.intersection(
3
- Typesafe.object({
4
- bucket: Typesafe.string,
5
- region: Typesafe.string,
6
- prefix: Typesafe.string,
7
- credentials: Typesafe.object({
8
- key: Typesafe.string,
9
- secret: Typesafe.string
10
- })
11
- }),
12
- Typesafe.partial({
13
- endpoint: Typesafe.string,
14
- cdnEndpoint: Typesafe.string,
15
- provider: Typesafe.enumeration(
16
- "aws",
17
- "minio",
18
- "ceph",
19
- "localstack",
20
- "cloudserver"
21
- /* cloudserver */
22
- ),
23
- noAcl: Typesafe.boolean
24
- })
25
- );
26
- const serversWithoutAclSupport = [
27
- "minio"
28
- /* minio */
29
- ];
30
- const resolveS3Config = (config) => {
31
- return {
32
- noAcl: !!config.provider && serversWithoutAclSupport.includes(config.provider),
33
- ...config
34
- };
35
- };
36
- const defaultRegion = "eu-west-1";
37
- const resolveS3Endpoint = (config) => {
38
- const hasLegacyPath = !!config.endpoint || config.bucket.includes(".");
39
- const endpoint = config.endpoint || `https://${hasLegacyPath ? "" : `${config.bucket}.`}s3.${config.region || defaultRegion}.amazonaws.com`;
40
- const basePath = hasLegacyPath ? `/${config.bucket}` : "";
41
- return { endpoint, basePath };
42
- };
43
- const resolveS3PublicBaseUrl = (config) => {
44
- if (config.cdnEndpoint) {
45
- return config.cdnEndpoint;
46
- }
47
- const { endpoint, basePath } = resolveS3Endpoint(config);
48
- return endpoint + basePath;
49
- };
50
- export {
51
- resolveS3Config,
52
- resolveS3Endpoint,
53
- resolveS3PublicBaseUrl,
54
- s3ConfigSchema
55
- };
56
- //# sourceMappingURL=Config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Config.js","sources":["../../../../packages/engine-s3-plugin/src/Config.ts"],"sourcesContent":["import * as Typesafe from '@contember/typesafe'\n\nexport enum S3Providers {\n\taws = 'aws',\n\tminio = 'minio',\n\tceph = 'ceph',\n\tlocalstack = 'localstack',\n\tcloudserver = 'cloudserver',\n}\n\n\nexport const s3ConfigSchema = Typesafe.intersection(\n\tTypesafe.object({\n\t\tbucket: Typesafe.string,\n\t\tregion: Typesafe.string,\n\t\tprefix: Typesafe.string,\n\t\tcredentials: Typesafe.object({\n\t\t\tkey: Typesafe.string,\n\t\t\tsecret: Typesafe.string,\n\t\t}),\n\t}),\n\tTypesafe.partial({\n\t\tendpoint: Typesafe.string,\n\t\tcdnEndpoint: Typesafe.string,\n\t\tprovider: Typesafe.enumeration(S3Providers.aws, S3Providers.minio, S3Providers.ceph, S3Providers.localstack, S3Providers.cloudserver),\n\t\tnoAcl: Typesafe.boolean,\n\t}),\n)\n\nexport type S3Config = ReturnType<typeof s3ConfigSchema>\n\nexport type Project3Config = { s3?: S3Config }\n\n// todo\nconst serversWithoutAclSupport = [S3Providers.minio]\n\nexport const resolveS3Config = (config: S3Config): S3Config => {\n\treturn {\n\t\tnoAcl: !!config.provider && serversWithoutAclSupport.includes(config.provider),\n\t\t...config,\n\t}\n}\n\nconst defaultRegion = 'eu-west-1'\n\nexport const resolveS3Endpoint = (\n\tconfig: S3Config,\n): {\n\tendpoint: string\n\tbasePath: string\n} => {\n\tconst hasLegacyPath = !!config.endpoint || config.bucket.includes('.')\n\tconst endpoint = config.endpoint || `https://${hasLegacyPath ? '' : `${config.bucket}.`}s3.${config.region || defaultRegion}.amazonaws.com`\n\tconst basePath = hasLegacyPath ? `/${config.bucket}` : ''\n\n\treturn { endpoint, basePath }\n}\n\nexport const resolveS3PublicBaseUrl = (config: S3Config): string => {\n\tif (config.cdnEndpoint) {\n\t\treturn config.cdnEndpoint\n\t}\n\tconst { endpoint, basePath } = resolveS3Endpoint(config)\n\treturn endpoint + basePath\n}\n"],"names":[],"mappings":";AAWO,MAAM,iBAAiB,SAAS;AAAA,EACtC,SAAS,OAAO;AAAA,IACf,QAAQ,SAAS;AAAA,IACjB,QAAQ,SAAS;AAAA,IACjB,QAAQ,SAAS;AAAA,IACjB,aAAa,SAAS,OAAO;AAAA,MAC5B,KAAK,SAAS;AAAA,MACd,QAAQ,SAAS;AAAA,IACjB,CAAA;AAAA,EAAA,CACD;AAAA,EACD,SAAS,QAAQ;AAAA,IAChB,UAAU,SAAS;AAAA,IACnB,aAAa,SAAS;AAAA,IACtB,UAAU,SAAS;AAAA,MAAY;AAAA,MAAiB;AAAA,MAAmB;AAAA,MAAkB;AAAA,MAAwB;AAAA;AAAA,IAAuB;AAAA,IACpI,OAAO,SAAS;AAAA,EAChB,CAAA;AACF;AAOA,MAAM,2BAA2B;AAAA,EAAC;AAAA;AAAiB;AAEtC,MAAA,kBAAkB,CAAC,WAA+B;AACvD,SAAA;AAAA,IACN,OAAO,CAAC,CAAC,OAAO,YAAY,yBAAyB,SAAS,OAAO,QAAQ;AAAA,IAC7E,GAAG;AAAA,EACJ;AACD;AAEA,MAAM,gBAAgB;AAET,MAAA,oBAAoB,CAChC,WAII;AACE,QAAA,gBAAgB,CAAC,CAAC,OAAO,YAAY,OAAO,OAAO,SAAS,GAAG;AACrE,QAAM,WAAW,OAAO,YAAY,WAAW,gBAAgB,KAAK,GAAG,OAAO,MAAM,GAAG,MAAM,OAAO,UAAU,aAAa;AAC3H,QAAM,WAAW,gBAAgB,IAAI,OAAO,MAAM,KAAK;AAEhD,SAAA,EAAE,UAAU,SAAS;AAC7B;AAEa,MAAA,yBAAyB,CAAC,WAA6B;AACnE,MAAI,OAAO,aAAa;AACvB,WAAO,OAAO;AAAA,EAAA;AAEf,QAAM,EAAE,UAAU,aAAa,kBAAkB,MAAM;AACvD,SAAO,WAAW;AACnB;"}
@@ -1,60 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const Config = require("./Config.cjs");
4
- const Typesafe = require("@contember/typesafe");
5
- function _interopNamespaceDefault(e) {
6
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
7
- if (e) {
8
- for (const k in e) {
9
- if (k !== "default") {
10
- const d = Object.getOwnPropertyDescriptor(e, k);
11
- Object.defineProperty(n, k, d.get ? d : {
12
- enumerable: true,
13
- get: () => e[k]
14
- });
15
- }
16
- }
17
- }
18
- n.default = e;
19
- return Object.freeze(n);
20
- }
21
- const Typesafe__namespace = /* @__PURE__ */ _interopNamespaceDefault(Typesafe);
22
- class S3ConfigProcessor {
23
- getDefaultEnv() {
24
- return {
25
- DEFAULT_S3_ENDPOINT: "",
26
- DEFAULT_S3_REGION: "us-east-1",
27
- DEFAULT_S3_PROVIDER: "aws"
28
- };
29
- }
30
- prepareConfigTemplate(template, { env }) {
31
- return {
32
- ...template,
33
- projectDefaults: {
34
- ...template.projectDefaults,
35
- s3: {
36
- bucket: `%?project.env.S3_BUCKET%`,
37
- prefix: `%?project.env.S3_PREFIX||project.slug%`,
38
- region: `%project.env.S3_REGION%`,
39
- endpoint: `%project.env.S3_ENDPOINT%`,
40
- cdnEndpoint: `%?project.env.S3_CDN%`,
41
- provider: "%project.env.S3_PROVIDER%",
42
- credentials: {
43
- key: `%?project.secret.s3.key||project.env.S3_KEY%`,
44
- secret: `%?project.secret.s3.secret||project.env.S3_SECRET%`
45
- }
46
- }
47
- }
48
- };
49
- }
50
- getProjectConfigSchema(slug) {
51
- return Typesafe__namespace.union(
52
- (input, path = []) => Typesafe__namespace.valueAt(input, ["s3", "credentials", "key"]) === void 0 ? {} : Typesafe__namespace.fail(path),
53
- Typesafe__namespace.object({
54
- s3: Config.s3ConfigSchema
55
- })
56
- );
57
- }
58
- }
59
- exports.S3ConfigProcessor = S3ConfigProcessor;
60
- //# sourceMappingURL=S3ConfigProcessor.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"S3ConfigProcessor.cjs","sources":["../../../../packages/engine-s3-plugin/src/S3ConfigProcessor.ts"],"sourcesContent":["import { ConfigProcessor, ConfigTemplate, ConfigTemplateContext } from '@contember/engine-plugins'\nimport { Project3Config, s3ConfigSchema } from './Config'\nimport * as Typesafe from '@contember/typesafe'\n\nexport class S3ConfigProcessor implements ConfigProcessor<Project3Config> {\n\tgetDefaultEnv(): Record<string, string> {\n\t\treturn {\n\t\t\tDEFAULT_S3_ENDPOINT: '',\n\t\t\tDEFAULT_S3_REGION: 'us-east-1',\n\t\t\tDEFAULT_S3_PROVIDER: 'aws',\n\t\t}\n\t}\n\n\tprepareConfigTemplate(template: ConfigTemplate, { env }: ConfigTemplateContext) {\n\t\treturn {\n\t\t\t...template,\n\t\t\tprojectDefaults: {\n\t\t\t\t...template.projectDefaults,\n\t\t\t\ts3: {\n\t\t\t\t\tbucket: `%?project.env.S3_BUCKET%`,\n\t\t\t\t\tprefix: `%?project.env.S3_PREFIX||project.slug%`,\n\t\t\t\t\tregion: `%project.env.S3_REGION%`,\n\t\t\t\t\tendpoint: `%project.env.S3_ENDPOINT%`,\n\t\t\t\t\tcdnEndpoint: `%?project.env.S3_CDN%`,\n\t\t\t\t\tprovider: '%project.env.S3_PROVIDER%',\n\t\t\t\t\tcredentials: {\n\t\t\t\t\t\tkey: `%?project.secret.s3.key||project.env.S3_KEY%`,\n\t\t\t\t\t\tsecret: `%?project.secret.s3.secret||project.env.S3_SECRET%`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t}\n\n\tgetProjectConfigSchema(slug: string): Typesafe.Type<Record<string, any>> {\n\t\treturn Typesafe.union(\n\t\t\t(input: unknown, path: PropertyKey[] = []) => Typesafe.valueAt(input, ['s3', 'credentials', 'key']) === undefined ? {} : Typesafe.fail(path),\n\t\t\tTypesafe.object({\n\t\t\t\ts3: s3ConfigSchema,\n\t\t\t}),\n\t\t)\n\t}\n\n}\n"],"names":["Typesafe","s3ConfigSchema"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAIO,MAAM,kBAA6D;AAAA,EACzE,gBAAwC;AAChC,WAAA;AAAA,MACN,qBAAqB;AAAA,MACrB,mBAAmB;AAAA,MACnB,qBAAqB;AAAA,IACtB;AAAA,EAAA;AAAA,EAGD,sBAAsB,UAA0B,EAAE,OAA8B;AACxE,WAAA;AAAA,MACN,GAAG;AAAA,MACH,iBAAiB;AAAA,QAChB,GAAG,SAAS;AAAA,QACZ,IAAI;AAAA,UACH,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,aAAa;AAAA,UACb,UAAU;AAAA,UACV,aAAa;AAAA,YACZ,KAAK;AAAA,YACL,QAAQ;AAAA,UAAA;AAAA,QACT;AAAA,MACD;AAAA,IAEF;AAAA,EAAA;AAAA,EAGD,uBAAuB,MAAkD;AACxE,WAAOA,oBAAS;AAAA,MACf,CAAC,OAAgB,OAAsB,CAAO,MAAAA,oBAAS,QAAQ,OAAO,CAAC,MAAM,eAAe,KAAK,CAAC,MAAM,SAAY,CAAK,IAAAA,oBAAS,KAAK,IAAI;AAAA,MAC3IA,oBAAS,OAAO;AAAA,QACf,IAAIC,OAAAA;AAAAA,MACJ,CAAA;AAAA,IACF;AAAA,EAAA;AAGF;;"}