@lighthouse/common 4.37.0-canary-19 → 4.38.0-canary-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/helpers/build-fetch-url/index.js +1 -1
- package/dist/helpers/fetch-image/index.js +61 -67
- package/dist/helpers/fetch-image-for-pdf-generator-service/index.js +155 -0
- package/dist/pdf/helpers/build-audit-content/index.js +3 -1
- package/dist/pdf/helpers/default-footer/index.js +6 -2
- package/dist/pdf/helpers/default-header/index.js +6 -2
- package/dist/pdf/helpers/fields/index.js +10 -4
- package/lib/helpers/build-fetch-url/index.js +1 -1
- package/lib/helpers/build-fetch-url/index.js.map +1 -1
- package/lib/helpers/fetch-image/index.js +66 -104
- package/lib/helpers/fetch-image/index.js.map +1 -1
- package/lib/helpers/fetch-image-for-pdf-generator-service/index.js +247 -0
- package/lib/helpers/fetch-image-for-pdf-generator-service/index.js.map +1 -0
- package/lib/pdf/helpers/build-audit-content/index.js +3 -1
- package/lib/pdf/helpers/build-audit-content/index.js.map +1 -1
- package/lib/pdf/helpers/default-footer/index.js +6 -2
- package/lib/pdf/helpers/default-footer/index.js.map +1 -1
- package/lib/pdf/helpers/default-header/index.js +6 -2
- package/lib/pdf/helpers/default-header/index.js.map +1 -1
- package/lib/pdf/helpers/fields/index.js +24 -15
- package/lib/pdf/helpers/fields/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/helpers/fetch-jwt/index.js +0 -43
- package/lib/helpers/fetch-jwt/index.js +0 -64
- package/lib/helpers/fetch-jwt/index.js.map +0 -1
|
@@ -23,7 +23,7 @@ function buildFetchUrl(url, options) {
|
|
|
23
23
|
if (height) transformations.push(`height=${height.toString()}`);
|
|
24
24
|
if (quality) transformations.push(`quality=${quality.toString()}`);
|
|
25
25
|
transformations.push(`fit=contain`);
|
|
26
|
-
const transformationsString = transformations.join('
|
|
26
|
+
const transformationsString = transformations.join('&');
|
|
27
27
|
const fetchUrl = `${cloudfrontBaseUrl}/${url}?${transformationsString}`;
|
|
28
28
|
return fetchUrl;
|
|
29
29
|
}
|
|
@@ -20,7 +20,7 @@ var _constants = require("../../constants");
|
|
|
20
20
|
|
|
21
21
|
var _images = require("../../images");
|
|
22
22
|
|
|
23
|
-
var
|
|
23
|
+
var _fetchImageForPdfGeneratorService = require("../fetch-image-for-pdf-generator-service");
|
|
24
24
|
|
|
25
25
|
// NOTE use the native fetch if it's available in the browser, because the
|
|
26
26
|
// ponyfill (which actually uses the github polyfill) does not support all the
|
|
@@ -44,80 +44,74 @@ const defaultOptions = {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
function fetchImage(url, options = {}) {
|
|
47
|
-
const
|
|
48
|
-
const fetchOptions = { ...defaultOptions,
|
|
49
|
-
...options,
|
|
50
|
-
headers: { ...(options.headers || {})
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
const urlMatch = url && url.match(/([a-f0-9]{24})\//);
|
|
54
|
-
const applicationId = urlMatch && urlMatch[1];
|
|
55
|
-
const shouldUseCloudfront = url && url.includes('.cloudfront.net');
|
|
47
|
+
const isWebContext = typeof window === 'object';
|
|
56
48
|
const {
|
|
57
49
|
isHeader = false
|
|
58
50
|
} = options;
|
|
51
|
+
const shouldUseCloudfront = url && url.includes('.cloudfront.net');
|
|
59
52
|
|
|
60
|
-
if (shouldUseCloudfront) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (!response.ok) {
|
|
86
|
-
return _bluebird.default.reject(new Error(`Failed to fetch image: ${encodedUrl}`));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const imageType = contentTypes[contentType];
|
|
90
|
-
return response.arrayBuffer().then(buffer => ({
|
|
91
|
-
buffer,
|
|
92
|
-
imageType
|
|
93
|
-
}));
|
|
94
|
-
}).then(({
|
|
53
|
+
if (shouldUseCloudfront && isWebContext) {
|
|
54
|
+
const {
|
|
55
|
+
signature,
|
|
56
|
+
expiresAt,
|
|
57
|
+
'Key-Pair-Id': keyPairId
|
|
58
|
+
} = options;
|
|
59
|
+
const firstParamConnector = new URL(url).searchParams.size > 0 ? '&' : '?';
|
|
60
|
+
const urlToEncode = `${url}${firstParamConnector}Signature=${signature}&ExpiresAt=${expiresAt}&Key-Pair-Id=${keyPairId}`;
|
|
61
|
+
const encodedUrl = encodeURI(urlToEncode);
|
|
62
|
+
console.info('Fetching image via CloudFront For Web');
|
|
63
|
+
return fetch(encodedUrl).then(response => {
|
|
64
|
+
const contentHeader = response.headers.get('content-length');
|
|
65
|
+
const contentType = response.headers.get('content-type'); // NOTE: the response will be ok but we won't be able to render any
|
|
66
|
+
// image meaning pdfmake will error. Raise error here and return early.
|
|
67
|
+
|
|
68
|
+
if (contentHeader === '0') {
|
|
69
|
+
return _bluebird.default.reject(new Error(`Failed to fetch image as no content length: ${encodedUrl}`));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
return _bluebird.default.reject(new Error(`Failed to fetch image: ${encodedUrl}`));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const imageType = contentTypes[contentType];
|
|
77
|
+
return response.arrayBuffer().then(buffer => ({
|
|
95
78
|
buffer,
|
|
96
79
|
imageType
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
console.error(error);
|
|
116
|
-
return
|
|
117
|
-
}
|
|
118
|
-
|
|
80
|
+
}));
|
|
81
|
+
}).then(({
|
|
82
|
+
buffer,
|
|
83
|
+
imageType
|
|
84
|
+
}) => {
|
|
85
|
+
const base64Flag = `data:image/${imageType};base64,`;
|
|
86
|
+
const imageStr = arrayBufferToBase64(buffer);
|
|
87
|
+
const base64 = `${base64Flag}${imageStr}`;
|
|
88
|
+
const isValid = validateBase64Image(base64);
|
|
89
|
+
|
|
90
|
+
if (!isValid) {
|
|
91
|
+
return _bluebird.default.reject(new Error('InvalidImageError'));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return base64;
|
|
95
|
+
}).catch(error => {
|
|
96
|
+
if (isHeader) {
|
|
97
|
+
// NOTE: Replace failed headers with LH logo
|
|
98
|
+
console.error('FetchImageHeaderError', error);
|
|
99
|
+
return fetchImage(_constants.LIGHTHOUSE_LOGO_URL, defaultOptions);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.error(error);
|
|
103
|
+
return _images.imageNotFound;
|
|
104
|
+
});
|
|
105
|
+
} else if (shouldUseCloudfront && !isWebContext) {
|
|
106
|
+
return (0, _fetchImageForPdfGeneratorService.fetchImageForPdfGeneratorService)(url);
|
|
119
107
|
}
|
|
120
108
|
|
|
109
|
+
const encodedUrl = encodeURI(url);
|
|
110
|
+
const fetchOptions = { ...defaultOptions,
|
|
111
|
+
...options,
|
|
112
|
+
headers: { ...(options.headers || {})
|
|
113
|
+
}
|
|
114
|
+
};
|
|
121
115
|
return fetch(encodedUrl, fetchOptions).then(response => {
|
|
122
116
|
const contentHeader = response.headers.get('content-length');
|
|
123
117
|
const contentType = response.headers.get('content-type'); // NOTE: the response will be ok but we won't be able to render any
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.requestImageTransformation = requestImageTransformation;
|
|
9
|
+
exports.fetchResourceFromS3 = fetchResourceFromS3;
|
|
10
|
+
exports.fetchImageForPdfGeneratorService = void 0;
|
|
11
|
+
|
|
12
|
+
var _awsSdk = _interopRequireDefault(require("aws-sdk"));
|
|
13
|
+
|
|
14
|
+
const REGION = process.env.AWS_REGION;
|
|
15
|
+
const lambda = new _awsSdk.default.Lambda({
|
|
16
|
+
region: REGION
|
|
17
|
+
});
|
|
18
|
+
const s3 = new _awsSdk.default.S3({
|
|
19
|
+
region: REGION
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const fetchImageForPdfGeneratorService = async function (url) {
|
|
23
|
+
console.info('Fetching image via CloudFront For Serverless Pdf Generator Service');
|
|
24
|
+
|
|
25
|
+
if (!url) {
|
|
26
|
+
throw new Error('URL is required to fetch image for PDF generator service');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const urlMatch = url && url.match(/([a-f0-9]{24})\//);
|
|
30
|
+
const applicationId = urlMatch && urlMatch[1];
|
|
31
|
+
|
|
32
|
+
if (!applicationId) {
|
|
33
|
+
throw new Error('Requestor has insufficient permissions');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const key = url.split(applicationId)[1];
|
|
37
|
+
const alreadyTransformedImage = await fetchResourceFromS3({
|
|
38
|
+
bucketName: process.env.TRANSFORMED_IMAGES_S3_BUCKET,
|
|
39
|
+
key
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (alreadyTransformedImage && alreadyTransformedImage.body) {
|
|
43
|
+
return alreadyTransformedImage.body.toString('base64');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const transformerResponse = await requestImageTransformation(key);
|
|
47
|
+
const statusCode = transformerResponse.statusCode;
|
|
48
|
+
|
|
49
|
+
switch (statusCode) {
|
|
50
|
+
case 200:
|
|
51
|
+
console.log('Image transformation successful');
|
|
52
|
+
return transformerResponse.body;
|
|
53
|
+
|
|
54
|
+
case 302:
|
|
55
|
+
{
|
|
56
|
+
console.log('Image transformation successful but image is too big for lambda delivery, fetching directly from S3');
|
|
57
|
+
const redirectLocation = transformerResponse.headers?.Location;
|
|
58
|
+
|
|
59
|
+
if (redirectLocation) {
|
|
60
|
+
const newlyTransformedImage = await fetchResourceFromS3({
|
|
61
|
+
bucketName: process.env.TRANSFORMED_IMAGES_S3_BUCKET,
|
|
62
|
+
key
|
|
63
|
+
});
|
|
64
|
+
console.log('Image successfully fetched from S3 at:', redirectLocation);
|
|
65
|
+
return newlyTransformedImage.body.toString('base64');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
throw new Error('Redirect response received but no location provided');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
case 400:
|
|
72
|
+
throw new Error(`Bad request to image transformer: ${transformerResponse.body}`);
|
|
73
|
+
|
|
74
|
+
case 403:
|
|
75
|
+
throw new Error('Requested transformed image is too big');
|
|
76
|
+
|
|
77
|
+
case 404:
|
|
78
|
+
throw new Error('The requested image does not exist');
|
|
79
|
+
|
|
80
|
+
case 500:
|
|
81
|
+
throw new Error(`Image transformation failed: ${transformerResponse.body}`);
|
|
82
|
+
|
|
83
|
+
default:
|
|
84
|
+
throw new Error(`Unexpected response from image transformer: ${statusCode} - ${transformerResponse.body}`);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
exports.fetchImageForPdfGeneratorService = fetchImageForPdfGeneratorService;
|
|
89
|
+
|
|
90
|
+
async function requestImageTransformation(key) {
|
|
91
|
+
if (!key) {
|
|
92
|
+
throw new Error('Image Path is required for image transformation');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log('ImageTransformation: Invoking image transformer lambda for path:', key);
|
|
96
|
+
const lambdaEvent = {
|
|
97
|
+
requestContext: {
|
|
98
|
+
http: {
|
|
99
|
+
method: 'GET',
|
|
100
|
+
path: key
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const params = {
|
|
105
|
+
FunctionName: process.env.IMAGE_TRANSFORMER_ARN,
|
|
106
|
+
InvocationType: 'RequestResponse',
|
|
107
|
+
Payload: JSON.stringify(lambdaEvent)
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
const result = await lambda.invoke(params).promise();
|
|
112
|
+
const response = JSON.parse(result.Payload);
|
|
113
|
+
return response;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
const errorMessage = `Failed to invoke image transformer lambda: ${error.message}`;
|
|
116
|
+
console.error(errorMessage, error);
|
|
117
|
+
throw new Error(errorMessage);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function fetchResourceFromS3({
|
|
122
|
+
bucketName,
|
|
123
|
+
key
|
|
124
|
+
}) {
|
|
125
|
+
console.log(`Fetching resource from S3 Bucket: '${bucketName}' at path: '${key}'`);
|
|
126
|
+
|
|
127
|
+
if (!bucketName || !key) {
|
|
128
|
+
throw new Error('bucketName and key are required for S3 resource fetch ' + JSON.stringify({
|
|
129
|
+
bucketName,
|
|
130
|
+
key
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const params = {
|
|
135
|
+
Bucket: bucketName,
|
|
136
|
+
Key: key
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
const result = await s3.getObject(params).promise();
|
|
141
|
+
return {
|
|
142
|
+
body: result.Body,
|
|
143
|
+
contentType: result.ContentType,
|
|
144
|
+
contentLength: result.ContentLength,
|
|
145
|
+
lastModified: result.LastModified,
|
|
146
|
+
etag: result.ETag
|
|
147
|
+
};
|
|
148
|
+
} catch (error) {
|
|
149
|
+
if (error.code !== 'NoSuchKey') {
|
|
150
|
+
throw new Error(`Failed to fetch image: ${bucketName}/${key}`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log('Image not found in transformed bucket, invoking transformer');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -25,7 +25,9 @@ const buildAuditContent = _bluebird.default.method((items, settings = {}) => {
|
|
|
25
25
|
link
|
|
26
26
|
}) => {
|
|
27
27
|
return (0, _helpers.fetchImage)(assetUrl, {
|
|
28
|
-
|
|
28
|
+
signature: settings.signature,
|
|
29
|
+
expiresAt: settings.expiresAt,
|
|
30
|
+
keyPairId: settings.keyPairId
|
|
29
31
|
}).then(base64String => ({
|
|
30
32
|
alignment: 'center',
|
|
31
33
|
fit: [210, 210],
|
|
@@ -8,7 +8,9 @@ exports.defaultFooter = defaultFooter;
|
|
|
8
8
|
var _helpers = require("../../../helpers");
|
|
9
9
|
|
|
10
10
|
function defaultFooter({
|
|
11
|
-
|
|
11
|
+
signature,
|
|
12
|
+
expiresAt,
|
|
13
|
+
keyPairId,
|
|
12
14
|
logoUrl,
|
|
13
15
|
timestamp,
|
|
14
16
|
timezone,
|
|
@@ -24,7 +26,9 @@ function defaultFooter({
|
|
|
24
26
|
const footerText = sequenceId ? `${type} ${sequenceId}` : `${type}`; // eslint-disable-next-line no-unused-vars
|
|
25
27
|
|
|
26
28
|
return (0, _helpers.fetchImage)(logoUrl, {
|
|
27
|
-
|
|
29
|
+
signature,
|
|
30
|
+
expiresAt,
|
|
31
|
+
keyPairId,
|
|
28
32
|
isHeader: true
|
|
29
33
|
}).then(image => _page => ({
|
|
30
34
|
columns: [{
|
|
@@ -8,7 +8,9 @@ exports.defaultHeader = defaultHeader;
|
|
|
8
8
|
var _helpers = require("../../../helpers");
|
|
9
9
|
|
|
10
10
|
function defaultHeader({
|
|
11
|
-
|
|
11
|
+
signature,
|
|
12
|
+
expiresAt,
|
|
13
|
+
keyPairId,
|
|
12
14
|
logoUrl,
|
|
13
15
|
timestamp,
|
|
14
16
|
timezone
|
|
@@ -20,7 +22,9 @@ function defaultHeader({
|
|
|
20
22
|
timezone
|
|
21
23
|
});
|
|
22
24
|
return (0, _helpers.fetchImage)(logoUrl, {
|
|
23
|
-
|
|
25
|
+
signature,
|
|
26
|
+
expiresAt,
|
|
27
|
+
keyPairId,
|
|
24
28
|
isHeader: true
|
|
25
29
|
}).then(image => ({
|
|
26
30
|
columns: [{
|
|
@@ -52,8 +52,10 @@ function buildImage(options) {
|
|
|
52
52
|
awsS3BaseUrl,
|
|
53
53
|
cloudinaryBaseUrl,
|
|
54
54
|
cloudfrontBaseUrl,
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
signature,
|
|
56
|
+
expiresAt,
|
|
57
|
+
keyPairId
|
|
58
|
+
} = settings || {};
|
|
57
59
|
const isVideoType = new RegExp('.mp4$').test(filepath);
|
|
58
60
|
const link = `${awsS3BaseUrl}/${filepath}`;
|
|
59
61
|
|
|
@@ -76,7 +78,9 @@ function buildImage(options) {
|
|
|
76
78
|
quality: 50
|
|
77
79
|
});
|
|
78
80
|
return (0, _helpers.fetchImage)(url, {
|
|
79
|
-
|
|
81
|
+
signature,
|
|
82
|
+
expiresAt,
|
|
83
|
+
keyPairId
|
|
80
84
|
}).then(base64String => ({
|
|
81
85
|
alignment,
|
|
82
86
|
fit: [width, height],
|
|
@@ -259,7 +263,9 @@ function buildTemplateFieldRow({
|
|
|
259
263
|
if (isSignatureField) {
|
|
260
264
|
if (!value) return [labelText, ''];
|
|
261
265
|
return (0, _helpers.fetchImage)(value, {
|
|
262
|
-
|
|
266
|
+
signature: settings.signature,
|
|
267
|
+
expiresAt: settings.expiresAt,
|
|
268
|
+
keyPairId: settings.keyPairId
|
|
263
269
|
}).then(base64String => {
|
|
264
270
|
const values = {
|
|
265
271
|
alignment: 'left',
|
|
@@ -17,7 +17,7 @@ export function buildFetchUrl(url, options) {
|
|
|
17
17
|
|
|
18
18
|
_transformations.push("fit=contain");
|
|
19
19
|
|
|
20
|
-
var _transformationsString = _transformations.join('
|
|
20
|
+
var _transformationsString = _transformations.join('&');
|
|
21
21
|
|
|
22
22
|
var _fetchUrl = "".concat(cloudfrontBaseUrl, "/").concat(url, "?").concat(_transformationsString);
|
|
23
23
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/helpers/build-fetch-url/index.js"],"names":["buildFetchUrl","url","options","awsS3BaseUrl","cloudfrontBaseUrl","cloudinaryBaseUrl","fit","height","width","quality","shouldUseCloudfront","includes","transformations","push","toString","transformationsString","join","fetchUrl"],"mappings":"AAAA,OAAO,SAASA,aAAT,CAAuBC,GAAvB,EAA4BC,OAA5B,EAAqC;AAAA,MAExCC,YAFwC,GAStCD,OATsC,CAExCC,YAFwC;AAAA,8BAStCD,OATsC,CAGxCE,iBAHwC;AAAA,MAGxCA,iBAHwC,sCAGpB,EAHoB;AAAA,MAIxCC,iBAJwC,GAStCH,OATsC,CAIxCG,iBAJwC;AAAA,MAKxCC,GALwC,GAStCJ,OATsC,CAKxCI,GALwC;AAAA,MAMxCC,MANwC,GAStCL,OATsC,CAMxCK,MANwC;AAAA,MAOxCC,KAPwC,GAStCN,OATsC,CAOxCM,KAPwC;AAAA,MAQxCC,OARwC,GAStCP,OATsC,CAQxCO,OARwC;AAW1C,MAAMC,mBAAmB,GACvBN,iBAAiB,IAAIA,iBAAiB,CAACO,QAAlB,CAA2B,iBAA3B,CADvB;;AAGA,MAAID,mBAAJ,EAAyB;AACvB,QAAME,gBAAe,GAAG,EAAxB;AAEA,QAAIJ,KAAJ,EAAWI,gBAAe,CAACC,IAAhB,iBAA8BL,KAAK,CAACM,QAAN,EAA9B;AACX,QAAIP,MAAJ,EAAYK,gBAAe,CAACC,IAAhB,kBAA+BN,MAAM,CAACO,QAAP,EAA/B;AACZ,QAAIL,OAAJ,EAAaG,gBAAe,CAACC,IAAhB,mBAAgCJ,OAAO,CAACK,QAAR,EAAhC;;AACbF,IAAAA,gBAAe,CAACC,IAAhB;;AAEA,QAAME,sBAAqB,GAAGH,gBAAe,CAACI,IAAhB,CAAqB,GAArB,CAA9B;;AAEA,QAAMC,SAAQ,aAAMb,iBAAN,cAA2BH,GAA3B,cAAkCc,sBAAlC,CAAd;;AACA,WAAOE,SAAP;AACD;;AAED,MAAML,eAAe,GAAG,EAAxB;AACA,MAAIG,qBAAqB,GAAG,EAA5B;AAEA,MAAIP,KAAJ,EAAWI,eAAe,CAACC,IAAhB,aAA0BL,KAAK,CAACM,QAAN,EAA1B;AACX,MAAIP,MAAJ,EAAYK,eAAe,CAACC,IAAhB,aAA0BN,MAAM,CAACO,QAAP,EAA1B;AACZ,MAAIL,OAAJ,EAAaG,eAAe,CAACC,IAAhB,aAA0BJ,OAAO,CAACK,QAAR,EAA1B;AACb,MAAIR,GAAJ,EAASM,eAAe,CAACC,IAAhB,CAAqB,OAArB;AAETE,EAAAA,qBAAqB,aAAMH,eAAe,CAACI,IAAhB,CAAqB,GAArB,CAAN,MAArB;AAEA,MAAMC,QAAQ,aAAMZ,iBAAN,cAA2BU,qBAA3B,SAAmDZ,YAAnD,cAAmEF,GAAnE,CAAd;AAEA,SAAOgB,QAAP;AACD","sourcesContent":["export function buildFetchUrl(url, options) {\n const {\n awsS3BaseUrl,\n cloudfrontBaseUrl = '',\n cloudinaryBaseUrl,\n fit,\n height,\n width,\n quality,\n } = options\n\n const shouldUseCloudfront =\n cloudfrontBaseUrl && cloudfrontBaseUrl.includes('.cloudfront.net')\n\n if (shouldUseCloudfront) {\n const transformations = []\n\n if (width) transformations.push(`width=${width.toString()}`)\n if (height) transformations.push(`height=${height.toString()}`)\n if (quality) transformations.push(`quality=${quality.toString()}`)\n transformations.push(`fit=contain`)\n\n const transformationsString = transformations.join('
|
|
1
|
+
{"version":3,"sources":["../../../src/helpers/build-fetch-url/index.js"],"names":["buildFetchUrl","url","options","awsS3BaseUrl","cloudfrontBaseUrl","cloudinaryBaseUrl","fit","height","width","quality","shouldUseCloudfront","includes","transformations","push","toString","transformationsString","join","fetchUrl"],"mappings":"AAAA,OAAO,SAASA,aAAT,CAAuBC,GAAvB,EAA4BC,OAA5B,EAAqC;AAAA,MAExCC,YAFwC,GAStCD,OATsC,CAExCC,YAFwC;AAAA,8BAStCD,OATsC,CAGxCE,iBAHwC;AAAA,MAGxCA,iBAHwC,sCAGpB,EAHoB;AAAA,MAIxCC,iBAJwC,GAStCH,OATsC,CAIxCG,iBAJwC;AAAA,MAKxCC,GALwC,GAStCJ,OATsC,CAKxCI,GALwC;AAAA,MAMxCC,MANwC,GAStCL,OATsC,CAMxCK,MANwC;AAAA,MAOxCC,KAPwC,GAStCN,OATsC,CAOxCM,KAPwC;AAAA,MAQxCC,OARwC,GAStCP,OATsC,CAQxCO,OARwC;AAW1C,MAAMC,mBAAmB,GACvBN,iBAAiB,IAAIA,iBAAiB,CAACO,QAAlB,CAA2B,iBAA3B,CADvB;;AAGA,MAAID,mBAAJ,EAAyB;AACvB,QAAME,gBAAe,GAAG,EAAxB;AAEA,QAAIJ,KAAJ,EAAWI,gBAAe,CAACC,IAAhB,iBAA8BL,KAAK,CAACM,QAAN,EAA9B;AACX,QAAIP,MAAJ,EAAYK,gBAAe,CAACC,IAAhB,kBAA+BN,MAAM,CAACO,QAAP,EAA/B;AACZ,QAAIL,OAAJ,EAAaG,gBAAe,CAACC,IAAhB,mBAAgCJ,OAAO,CAACK,QAAR,EAAhC;;AACbF,IAAAA,gBAAe,CAACC,IAAhB;;AAEA,QAAME,sBAAqB,GAAGH,gBAAe,CAACI,IAAhB,CAAqB,GAArB,CAA9B;;AAEA,QAAMC,SAAQ,aAAMb,iBAAN,cAA2BH,GAA3B,cAAkCc,sBAAlC,CAAd;;AACA,WAAOE,SAAP;AACD;;AAED,MAAML,eAAe,GAAG,EAAxB;AACA,MAAIG,qBAAqB,GAAG,EAA5B;AAEA,MAAIP,KAAJ,EAAWI,eAAe,CAACC,IAAhB,aAA0BL,KAAK,CAACM,QAAN,EAA1B;AACX,MAAIP,MAAJ,EAAYK,eAAe,CAACC,IAAhB,aAA0BN,MAAM,CAACO,QAAP,EAA1B;AACZ,MAAIL,OAAJ,EAAaG,eAAe,CAACC,IAAhB,aAA0BJ,OAAO,CAACK,QAAR,EAA1B;AACb,MAAIR,GAAJ,EAASM,eAAe,CAACC,IAAhB,CAAqB,OAArB;AAETE,EAAAA,qBAAqB,aAAMH,eAAe,CAACI,IAAhB,CAAqB,GAArB,CAAN,MAArB;AAEA,MAAMC,QAAQ,aAAMZ,iBAAN,cAA2BU,qBAA3B,SAAmDZ,YAAnD,cAAmEF,GAAnE,CAAd;AAEA,SAAOgB,QAAP;AACD","sourcesContent":["export function buildFetchUrl(url, options) {\n const {\n awsS3BaseUrl,\n cloudfrontBaseUrl = '',\n cloudinaryBaseUrl,\n fit,\n height,\n width,\n quality,\n } = options\n\n const shouldUseCloudfront =\n cloudfrontBaseUrl && cloudfrontBaseUrl.includes('.cloudfront.net')\n\n if (shouldUseCloudfront) {\n const transformations = []\n\n if (width) transformations.push(`width=${width.toString()}`)\n if (height) transformations.push(`height=${height.toString()}`)\n if (quality) transformations.push(`quality=${quality.toString()}`)\n transformations.push(`fit=contain`)\n\n const transformationsString = transformations.join('&')\n\n const fetchUrl = `${cloudfrontBaseUrl}/${url}?${transformationsString}`\n return fetchUrl\n }\n\n const transformations = []\n let transformationsString = ''\n\n if (width) transformations.push(`w_${width.toString()}`)\n if (height) transformations.push(`h_${height.toString()}`)\n if (quality) transformations.push(`q_${quality.toString()}`)\n if (fit) transformations.push('c_fit')\n\n transformationsString = `${transformations.join(',')}/`\n\n const fetchUrl = `${cloudinaryBaseUrl}/${transformationsString}${awsS3BaseUrl}/${url}`\n\n return fetchUrl\n}\n"],"file":"index.js"}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
2
|
-
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
3
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
4
2
|
import _typeof from "@babel/runtime/helpers/typeof";
|
|
5
3
|
|
|
@@ -12,7 +10,7 @@ import fetchPonyfill from 'fetch-ponyfill';
|
|
|
12
10
|
import Promise from 'bluebird';
|
|
13
11
|
import { LIGHTHOUSE_LOGO_URL } from '../../constants';
|
|
14
12
|
import { imageNotFound } from '../../images';
|
|
15
|
-
import {
|
|
13
|
+
import { fetchImageForPdfGeneratorService } from '../fetch-image-for-pdf-generator-service'; // NOTE use the native fetch if it's available in the browser, because the
|
|
16
14
|
// ponyfill (which actually uses the github polyfill) does not support all the
|
|
17
15
|
// same options as native fetch
|
|
18
16
|
|
|
@@ -35,110 +33,74 @@ var defaultOptions = {
|
|
|
35
33
|
};
|
|
36
34
|
export function fetchImage(url) {
|
|
37
35
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
36
|
+
var isWebContext = (typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object';
|
|
37
|
+
var _options$isHeader = options.isHeader,
|
|
38
|
+
isHeader = _options$isHeader === void 0 ? false : _options$isHeader;
|
|
39
|
+
var shouldUseCloudfront = url && url.includes('.cloudfront.net');
|
|
40
|
+
|
|
41
|
+
if (shouldUseCloudfront && isWebContext) {
|
|
42
|
+
var signature = options.signature,
|
|
43
|
+
expiresAt = options.expiresAt,
|
|
44
|
+
keyPairId = options['Key-Pair-Id'];
|
|
45
|
+
var firstParamConnector = new URL(url).searchParams.size > 0 ? '&' : '?';
|
|
46
|
+
var urlToEncode = "".concat(url).concat(firstParamConnector, "Signature=").concat(signature, "&ExpiresAt=").concat(expiresAt, "&Key-Pair-Id=").concat(keyPairId);
|
|
47
|
+
|
|
48
|
+
var _encodedUrl = encodeURI(urlToEncode);
|
|
49
|
+
|
|
50
|
+
console.info('Fetching image via CloudFront For Web');
|
|
51
|
+
return fetch(_encodedUrl).then(function (response) {
|
|
52
|
+
var contentHeader = response.headers.get('content-length');
|
|
53
|
+
var contentType = response.headers.get('content-type'); // NOTE: the response will be ok but we won't be able to render any
|
|
54
|
+
// image meaning pdfmake will error. Raise error here and return early.
|
|
55
|
+
|
|
56
|
+
if (contentHeader === '0') {
|
|
57
|
+
return Promise.reject(new Error("Failed to fetch image as no content length: ".concat(_encodedUrl)));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
return Promise.reject(new Error("Failed to fetch image: ".concat(_encodedUrl)));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
var imageType = contentTypes[contentType];
|
|
65
|
+
return response.arrayBuffer().then(function (buffer) {
|
|
66
|
+
return {
|
|
67
|
+
buffer: buffer,
|
|
68
|
+
imageType: imageType
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
}).then(function (_ref) {
|
|
72
|
+
var buffer = _ref.buffer,
|
|
73
|
+
imageType = _ref.imageType;
|
|
74
|
+
var base64Flag = "data:image/".concat(imageType, ";base64,");
|
|
75
|
+
var imageStr = arrayBufferToBase64(buffer);
|
|
76
|
+
var base64 = "".concat(base64Flag).concat(imageStr);
|
|
77
|
+
var isValid = validateBase64Image(base64);
|
|
78
|
+
|
|
79
|
+
if (!isValid) {
|
|
80
|
+
return Promise.reject(new Error('InvalidImageError'));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return base64;
|
|
84
|
+
}).catch(function (error) {
|
|
85
|
+
if (isHeader) {
|
|
86
|
+
// NOTE: Replace failed headers with LH logo
|
|
87
|
+
console.error('FetchImageHeaderError', error);
|
|
88
|
+
return fetchImage(LIGHTHOUSE_LOGO_URL, defaultOptions);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
console.error(error);
|
|
92
|
+
return imageNotFound;
|
|
93
|
+
});
|
|
94
|
+
} else if (shouldUseCloudfront && !isWebContext) {
|
|
95
|
+
return fetchImageForPdfGeneratorService(url);
|
|
96
|
+
}
|
|
97
|
+
|
|
38
98
|
var encodedUrl = encodeURI(url);
|
|
39
99
|
|
|
40
100
|
var fetchOptions = _objectSpread(_objectSpread(_objectSpread({}, defaultOptions), options), {}, {
|
|
41
101
|
headers: _objectSpread({}, options.headers || {})
|
|
42
102
|
});
|
|
43
103
|
|
|
44
|
-
var urlMatch = url && url.match(/([a-f0-9]{24})\//);
|
|
45
|
-
var applicationId = urlMatch && urlMatch[1];
|
|
46
|
-
var shouldUseCloudfront = url && url.includes('.cloudfront.net');
|
|
47
|
-
var _options$isHeader = options.isHeader,
|
|
48
|
-
isHeader = _options$isHeader === void 0 ? false : _options$isHeader;
|
|
49
|
-
|
|
50
|
-
if (shouldUseCloudfront) {
|
|
51
|
-
console.info('Fetching image via CloudFront');
|
|
52
|
-
return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
53
|
-
var _fetchJWTFromGenerato;
|
|
54
|
-
|
|
55
|
-
var isWebContext, token, webFetchOptions, serverlessFetchOptions, fetchOptions;
|
|
56
|
-
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
57
|
-
while (1) {
|
|
58
|
-
switch (_context.prev = _context.next) {
|
|
59
|
-
case 0:
|
|
60
|
-
isWebContext = (typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object';
|
|
61
|
-
|
|
62
|
-
if (!isWebContext) {
|
|
63
|
-
_context.next = 5;
|
|
64
|
-
break;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
_context.t0 = options.imageAuthToken;
|
|
68
|
-
_context.next = 8;
|
|
69
|
-
break;
|
|
70
|
-
|
|
71
|
-
case 5:
|
|
72
|
-
_context.next = 7;
|
|
73
|
-
return (_fetchJWTFromGenerato = fetchJWTFromGenerator(applicationId)) === null || _fetchJWTFromGenerato === void 0 ? void 0 : _fetchJWTFromGenerato.token;
|
|
74
|
-
|
|
75
|
-
case 7:
|
|
76
|
-
_context.t0 = _context.sent;
|
|
77
|
-
|
|
78
|
-
case 8:
|
|
79
|
-
token = _context.t0;
|
|
80
|
-
webFetchOptions = {
|
|
81
|
-
headers: {
|
|
82
|
-
Authorization: "Bearer ".concat(token)
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
serverlessFetchOptions = _objectSpread(_objectSpread(_objectSpread({}, defaultOptions), options), {}, {
|
|
86
|
-
headers: _objectSpread({}, options.headers || {})
|
|
87
|
-
});
|
|
88
|
-
fetchOptions = isWebContext ? webFetchOptions : serverlessFetchOptions;
|
|
89
|
-
return _context.abrupt("return", fetch(encodedUrl, fetchOptions).then(function (response) {
|
|
90
|
-
var contentHeader = response.headers.get('content-length');
|
|
91
|
-
var contentType = response.headers.get('content-type'); // NOTE: the response will be ok but we won't be able to render any
|
|
92
|
-
// image meaning pdfmake will error. Raise error here and return early.
|
|
93
|
-
|
|
94
|
-
if (contentHeader === '0') {
|
|
95
|
-
return Promise.reject(new Error("Failed to fetch image as no content length: ".concat(encodedUrl)));
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (!response.ok) {
|
|
99
|
-
return Promise.reject(new Error("Failed to fetch image: ".concat(encodedUrl)));
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
var imageType = contentTypes[contentType];
|
|
103
|
-
return response.arrayBuffer().then(function (buffer) {
|
|
104
|
-
return {
|
|
105
|
-
buffer: buffer,
|
|
106
|
-
imageType: imageType
|
|
107
|
-
};
|
|
108
|
-
});
|
|
109
|
-
}).then(function (_ref2) {
|
|
110
|
-
var buffer = _ref2.buffer,
|
|
111
|
-
imageType = _ref2.imageType;
|
|
112
|
-
var base64Flag = "data:image/".concat(imageType, ";base64,");
|
|
113
|
-
var imageStr = arrayBufferToBase64(buffer);
|
|
114
|
-
var base64 = "".concat(base64Flag).concat(imageStr);
|
|
115
|
-
var isValid = validateBase64Image(base64);
|
|
116
|
-
|
|
117
|
-
if (!isValid) {
|
|
118
|
-
return Promise.reject(new Error('InvalidImageError'));
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return base64;
|
|
122
|
-
}).catch(function (error) {
|
|
123
|
-
if (isHeader) {
|
|
124
|
-
// NOTE: Replace failed headers with LH logo
|
|
125
|
-
console.error('FetchImageHeaderError', error);
|
|
126
|
-
return fetchImage(LIGHTHOUSE_LOGO_URL, defaultOptions);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
console.error(error);
|
|
130
|
-
return imageNotFound;
|
|
131
|
-
}));
|
|
132
|
-
|
|
133
|
-
case 13:
|
|
134
|
-
case "end":
|
|
135
|
-
return _context.stop();
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}, _callee);
|
|
139
|
-
}))();
|
|
140
|
-
}
|
|
141
|
-
|
|
142
104
|
return fetch(encodedUrl, fetchOptions).then(function (response) {
|
|
143
105
|
var contentHeader = response.headers.get('content-length');
|
|
144
106
|
var contentType = response.headers.get('content-type'); // NOTE: the response will be ok but we won't be able to render any
|
|
@@ -159,9 +121,9 @@ export function fetchImage(url) {
|
|
|
159
121
|
imageType: imageType
|
|
160
122
|
};
|
|
161
123
|
});
|
|
162
|
-
}).then(function (
|
|
163
|
-
var buffer =
|
|
164
|
-
imageType =
|
|
124
|
+
}).then(function (_ref2) {
|
|
125
|
+
var buffer = _ref2.buffer,
|
|
126
|
+
imageType = _ref2.imageType;
|
|
165
127
|
var base64Flag = "data:image/".concat(imageType, ";base64,");
|
|
166
128
|
var imageStr = arrayBufferToBase64(buffer);
|
|
167
129
|
var base64 = "".concat(base64Flag).concat(imageStr);
|