@lighthouse/common 6.9.5 → 6.9.7-canary.0

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 (28) hide show
  1. package/dist/errors/FetchImageError.js +19 -0
  2. package/dist/helpers/build-fetch-url/index.js +26 -1
  3. package/dist/helpers/fetch-image/index.js +37 -8
  4. package/dist/helpers/fetch-image-for-pdf-generator-service/index.js +14 -10
  5. package/dist/helpers/fetch-image-for-web/index.js +36 -5
  6. package/dist/helpers/validate-url/index.js +15 -0
  7. package/dist/pdf/helpers/default-header/index.js +11 -1
  8. package/dist/pdf/helpers/fields/index.js +51 -8
  9. package/dist/pdf/helpers/generate-definition/index.js +10 -2
  10. package/lib/errors/FetchImageError.js +27 -0
  11. package/lib/errors/FetchImageError.js.map +1 -0
  12. package/lib/helpers/build-fetch-url/index.js +26 -1
  13. package/lib/helpers/build-fetch-url/index.js.map +1 -1
  14. package/lib/helpers/fetch-image/index.js +39 -7
  15. package/lib/helpers/fetch-image/index.js.map +1 -1
  16. package/lib/helpers/fetch-image-for-pdf-generator-service/index.js +44 -29
  17. package/lib/helpers/fetch-image-for-pdf-generator-service/index.js.map +1 -1
  18. package/lib/helpers/fetch-image-for-web/index.js +56 -22
  19. package/lib/helpers/fetch-image-for-web/index.js.map +1 -1
  20. package/lib/helpers/validate-url/index.js +10 -0
  21. package/lib/helpers/validate-url/index.js.map +1 -0
  22. package/lib/pdf/helpers/default-header/index.js +11 -1
  23. package/lib/pdf/helpers/default-header/index.js.map +1 -1
  24. package/lib/pdf/helpers/fields/index.js +52 -8
  25. package/lib/pdf/helpers/fields/index.js.map +1 -1
  26. package/lib/pdf/helpers/generate-definition/index.js +10 -2
  27. package/lib/pdf/helpers/generate-definition/index.js.map +1 -1
  28. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["fetchPonyfill","Promise","LIGHTHOUSE_LOGO_URL","imageNotFound","fetchImageForPdfGeneratorService","fetchImageForWeb","fetch","self","_typeof","contentTypes","defaultOptions","cache","fetchImage","url","options","arguments","length","undefined","shouldUseCloudfront","isWebContext","window","encodedUrl","encodeURI","fetchOptions","_objectSpread","_options$isHeader","isHeader","then","response","contentHeader","headers","get","contentType","reject","Error","concat","ok","imageType","arrayBuffer","buffer","_ref","base64Flag","imageStr","arrayBufferToBase64","base64","isValid","validateBase64Image","catch","error","console","binary","bytes","slice","call","Uint8Array","forEach","b","String","fromCharCode","btoa","base64String","isJpeg","startsWith","validateJpegImage","isPng","validatePngImage","base64string","src","imageData","from","atob","replace","c","charCodeAt","imageCorrupted","sequence","i"],"sources":["../../../src/helpers/fetch-image/index.js"],"sourcesContent":["import fetchPonyfill from 'fetch-ponyfill'\nimport Promise from 'bluebird'\nimport { LIGHTHOUSE_LOGO_URL } from '../../constants'\nimport { imageNotFound } from '../../images'\nimport { fetchImageForPdfGeneratorService } from '../fetch-image-for-pdf-generator-service'\nimport { fetchImageForWeb } from '../fetch-image-for-web'\n\n// NOTE use the native fetch if it's available in the browser, because the\n// ponyfill (which actually uses the github polyfill) does not support all the\n// same options as native fetch\nconst fetch =\n (typeof self === 'object' && self.fetch) || fetchPonyfill({ Promise }).fetch\n\nconst contentTypes = {\n 'image/png': 'png',\n 'image/jpeg': 'jpeg',\n}\n\nconst defaultOptions = {\n // NOTE The cache: no-cache option is important to avoid an issue with CORS\n // and caching on Chrome. Here's a good explanation of the issue:\n // https://stackoverflow.com/a/37455118\n // In our case, when loading the web version of a form, the signature image is\n // cached without the correct CORS headers. If the pdf is then generated,\n // there's a mismatch between the cached image headers and the CORS headers\n // sent from the fetch request, causing an error\n cache: 'no-cache',\n}\n\nexport function fetchImage(url, options = {}) {\n const { shouldUseCloudfront } = options\n\n if (shouldUseCloudfront) {\n const isWebContext = typeof window === 'object'\n\n return isWebContext\n ? // Values used from options: isHeader, Signature, Policy, KeyPairId\n fetchImageForWeb(url, options)\n : fetchImageForPdfGeneratorService(url)\n }\n\n const encodedUrl = encodeURI(url)\n\n const fetchOptions = {\n ...defaultOptions,\n ...options,\n }\n const { isHeader = false } = options\n\n return fetch(encodedUrl, fetchOptions)\n .then((response) => {\n const contentHeader = response.headers.get('content-length')\n const contentType = response.headers.get('content-type')\n\n // NOTE: the response will be ok but we won't be able to render any\n // image meaning pdfmake will error. Raise error here and return early.\n if (contentHeader === '0') {\n return Promise.reject(\n new Error(`Failed to fetch image as no content length: ${encodedUrl}`)\n )\n }\n\n if (!response.ok) {\n return Promise.reject(new Error(`Failed to fetch image: ${encodedUrl}`))\n }\n\n const imageType = contentTypes[contentType]\n\n return response.arrayBuffer().then((buffer) => ({\n buffer,\n imageType,\n }))\n })\n .then(({ buffer, imageType }) => {\n const base64Flag = `data:image/${imageType};base64,`\n const imageStr = arrayBufferToBase64(buffer)\n\n const base64 = `${base64Flag}${imageStr}`\n const isValid = validateBase64Image(base64)\n\n if (!isValid) {\n return Promise.reject(new Error('InvalidImageError'))\n }\n\n return base64\n })\n .catch((error) => {\n if (isHeader) {\n // NOTE: Replace failed headers with LH logo\n console.error('FetchImageHeaderError', error)\n return fetchImage(LIGHTHOUSE_LOGO_URL, defaultOptions)\n }\n\n console.error(error)\n return imageNotFound\n })\n}\n\nexport function arrayBufferToBase64(buffer) {\n let binary = ''\n const bytes = [].slice.call(new Uint8Array(buffer))\n\n bytes.forEach((b) => (binary += String.fromCharCode(b)))\n\n return btoa(binary)\n}\n\nexport function validateBase64Image(base64String) {\n const isJpeg = base64String.startsWith('data:image/jpeg;base64,')\n\n if (isJpeg) return validateJpegImage(base64String)\n\n const isPng = base64String.startsWith('data:image/png;base64,')\n\n if (isPng) return validatePngImage(base64String)\n\n return false\n}\n\n// See SO for more info: https://stackoverflow.com/a/41635312\n// Fiddle: https://jsfiddle.net/Lnyxuchw/\nexport function validateJpegImage(base64string) {\n const src = base64string\n const imageData = Uint8Array.from(\n atob(src.replace('data:image/jpeg;base64,', '')),\n (c) => c.charCodeAt(0)\n )\n const imageCorrupted =\n imageData[imageData.length - 1] === 217 &&\n imageData[imageData.length - 2] === 255\n\n return imageCorrupted\n}\n\n// See SO for more info: https://stackoverflow.com/a/41635312\n// Fiddle: https://jsfiddle.net/Lnyxuchw/\nexport function validatePngImage(base64string) {\n const src = base64string\n const imageData = Uint8Array.from(\n atob(src.replace('data:image/png;base64,', '')),\n (c) => c.charCodeAt(0)\n )\n const sequence = [0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130]\n\n //check last 12 elements of array so they contains needed values\n for (let i = 12; i > 0; i--) {\n if (imageData[imageData.length - i] !== sequence[12 - i]) {\n return false\n }\n }\n\n return true\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["fetchPonyfill","Promise","LIGHTHOUSE_LOGO_URL","imageNotFound","fetchImageForPdfGeneratorService","fetchImageForWeb","isAbsoluteUrl","fetch","self","_typeof","contentTypes","defaultOptions","cache","fetchImage","url","options","arguments","length","undefined","shouldUseCloudfront","_options$isHeader","isHeader","_options$context","context","error","Error","concat","JSON","stringify","console","message","resolve","isWebContext","window","encodedUrl","encodeURI","fetchOptions","_objectSpread","then","response","contentHeader","headers","get","contentType","reject","ok","imageType","arrayBuffer","buffer","_ref","base64Flag","imageStr","arrayBufferToBase64","base64","isValid","validateBase64Image","catch","stack","binary","bytes","slice","call","Uint8Array","forEach","b","String","fromCharCode","btoa","base64String","isJpeg","startsWith","validateJpegImage","isPng","validatePngImage","base64string","src","imageData","from","atob","replace","c","charCodeAt","imageCorrupted","sequence","i"],"sources":["../../../src/helpers/fetch-image/index.js"],"sourcesContent":["import fetchPonyfill from 'fetch-ponyfill'\nimport Promise from 'bluebird'\nimport { LIGHTHOUSE_LOGO_URL } from '../../constants'\nimport { imageNotFound } from '../../images'\nimport { fetchImageForPdfGeneratorService } from '../fetch-image-for-pdf-generator-service'\nimport { fetchImageForWeb } from '../fetch-image-for-web'\nimport { isAbsoluteUrl } from '../validate-url/index.js'\n\n// NOTE use the native fetch if it's available in the browser, because the\n// ponyfill (which actually uses the github polyfill) does not support all the\n// same options as native fetch\nconst fetch =\n (typeof self === 'object' && self.fetch) || fetchPonyfill({ Promise }).fetch\n\nconst contentTypes = {\n 'image/png': 'png',\n 'image/jpeg': 'jpeg',\n}\n\nconst defaultOptions = {\n // NOTE The cache: no-cache option is important to avoid an issue with CORS\n // and caching on Chrome. Here's a good explanation of the issue:\n // https://stackoverflow.com/a/37455118\n // In our case, when loading the web version of a form, the signature image is\n // cached without the correct CORS headers. If the pdf is then generated,\n // there's a mismatch between the cached image headers and the CORS headers\n // sent from the fetch request, causing an error\n cache: 'no-cache',\n}\n\nexport function fetchImage(url, options = {}) {\n const { shouldUseCloudfront, isHeader = false, context = {} } = options\n\n // Validate url parameter\n if (!url || typeof url !== 'string') {\n const error = new Error(\n `fetchImage: Invalid url parameter. url=${JSON.stringify(url)}`\n )\n if (isHeader) {\n console.error('FetchImageHeaderError', {\n message: error.message,\n url,\n context,\n })\n return fetchImage(LIGHTHOUSE_LOGO_URL, defaultOptions)\n }\n console.error('FetchImageError', {\n message: error.message,\n url,\n context,\n })\n return Promise.resolve(imageNotFound)\n }\n\n if (shouldUseCloudfront) {\n const isWebContext = typeof window === 'object'\n\n return isWebContext\n ? // Values used from options: isHeader, Signature, Policy, KeyPairId\n fetchImageForWeb(url, options)\n : fetchImageForPdfGeneratorService(url)\n }\n\n const encodedUrl = encodeURI(url)\n\n const fetchOptions = {\n ...defaultOptions,\n ...options,\n }\n\n return fetch(encodedUrl, fetchOptions)\n .then((response) => {\n const contentHeader = response.headers.get('content-length')\n const contentType = response.headers.get('content-type')\n\n // NOTE: the response will be ok but we won't be able to render any\n // image meaning pdfmake will error. Raise error here and return early.\n if (contentHeader === '0') {\n return Promise.reject(\n new Error(`Failed to fetch image as no content length: ${url}`)\n )\n }\n\n if (!response.ok) {\n return Promise.reject(new Error(`Failed to fetch image: ${url}`))\n }\n\n const imageType = contentTypes[contentType]\n\n return response.arrayBuffer().then((buffer) => ({\n buffer,\n imageType,\n }))\n })\n .then(({ buffer, imageType }) => {\n const base64Flag = `data:image/${imageType};base64,`\n const imageStr = arrayBufferToBase64(buffer)\n\n const base64 = `${base64Flag}${imageStr}`\n const isValid = validateBase64Image(base64)\n\n if (!isValid) {\n return Promise.reject(new Error('InvalidImageError'))\n }\n\n return base64\n })\n .catch((error) => {\n if (isHeader) {\n // NOTE: Replace failed headers with LH logo\n console.error('FetchImageHeaderError', {\n url,\n message: error.message,\n context,\n stack: error.stack,\n })\n return fetchImage(LIGHTHOUSE_LOGO_URL, defaultOptions)\n }\n\n console.error('FetchImageError', {\n url,\n message: error.message,\n context,\n stack: error.stack,\n })\n return imageNotFound\n })\n}\n\nexport function arrayBufferToBase64(buffer) {\n let binary = ''\n const bytes = [].slice.call(new Uint8Array(buffer))\n\n bytes.forEach((b) => (binary += String.fromCharCode(b)))\n\n return btoa(binary)\n}\n\nexport function validateBase64Image(base64String) {\n const isJpeg = base64String.startsWith('data:image/jpeg;base64,')\n\n if (isJpeg) return validateJpegImage(base64String)\n\n const isPng = base64String.startsWith('data:image/png;base64,')\n\n if (isPng) return validatePngImage(base64String)\n\n return false\n}\n\n// See SO for more info: https://stackoverflow.com/a/41635312\n// Fiddle: https://jsfiddle.net/Lnyxuchw/\nexport function validateJpegImage(base64string) {\n const src = base64string\n const imageData = Uint8Array.from(\n atob(src.replace('data:image/jpeg;base64,', '')),\n (c) => c.charCodeAt(0)\n )\n const imageCorrupted =\n imageData[imageData.length - 1] === 217 &&\n imageData[imageData.length - 2] === 255\n\n return imageCorrupted\n}\n\n// See SO for more info: https://stackoverflow.com/a/41635312\n// Fiddle: https://jsfiddle.net/Lnyxuchw/\nexport function validatePngImage(base64string) {\n const src = base64string\n const imageData = Uint8Array.from(\n atob(src.replace('data:image/png;base64,', '')),\n (c) => c.charCodeAt(0)\n )\n const sequence = [0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130]\n\n //check last 12 elements of array so they contains needed values\n for (let i = 12; i > 0; i--) {\n if (imageData[imageData.length - i] !== sequence[12 - i]) {\n return false\n }\n }\n\n return true\n}\n"],"mappings":"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","ignoreList":[]}
@@ -14,7 +14,8 @@ var s3 = new AWS.S3({
14
14
  });
15
15
  export var fetchImageForPdfGeneratorService = /*#__PURE__*/function () {
16
16
  var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(url) {
17
- var urlMatch, applicationId, _parseUrlString, path, queryString, searchParamsObject, transformedBucketImagePath, alreadyTransformedImage, fullDataUrl, transformerResponse, statusCode, _fullDataUrl, redirectLocation, newlyTransformedImage, _fullDataUrl2, _t;
17
+ var _transformerResponse$;
18
+ var urlMatch, applicationId, _parseUrlString, path, queryString, searchParamsObject, transformedBucketImagePath, alreadyTransformedImage, fullDataUrl, transformerResponse, statusCode, redirectLocation, _fullDataUrl, response, buffer, _t, _t2, _t3;
18
19
  return _regeneratorRuntime.wrap(function (_context) {
19
20
  while (1) switch (_context.prev = _context.next) {
20
21
  case 0:
@@ -57,8 +58,9 @@ export var fetchImageForPdfGeneratorService = /*#__PURE__*/function () {
57
58
  case 5:
58
59
  transformerResponse = _context.sent;
59
60
  statusCode = transformerResponse.statusCode;
61
+ redirectLocation = (_transformerResponse$ = transformerResponse.headers) === null || _transformerResponse$ === void 0 ? void 0 : _transformerResponse$.Location;
60
62
  _t = statusCode;
61
- _context.next = _t === 200 ? 6 : _t === 302 ? 7 : _t === 400 ? 10 : _t === 403 ? 11 : _t === 404 ? 12 : _t === 500 ? 13 : 14;
63
+ _context.next = _t === 200 ? 6 : _t === 302 ? 7 : _t === 400 ? 14 : _t === 403 ? 15 : _t === 404 ? 16 : _t === 500 ? 17 : 18;
62
64
  break;
63
65
  case 6:
64
66
  console.debug('Image transformation successful');
@@ -68,42 +70,55 @@ export var fetchImageForPdfGeneratorService = /*#__PURE__*/function () {
68
70
  });
69
71
  return _context.abrupt("return", _fullDataUrl);
70
72
  case 7:
71
- console.debug('Image transformation successful but image is too big for lambda delivery, fetching directly from S3');
72
- redirectLocation = transformerResponse.headers.Location;
73
+ console.debug('Image transformation successful but image is too big for lambda delivery, fetching directly via redirect URL');
73
74
  if (redirectLocation) {
74
75
  _context.next = 8;
75
76
  break;
76
77
  }
77
78
  throw new Error('Redirect response received but no location provided');
78
79
  case 8:
80
+ _context.prev = 8;
79
81
  _context.next = 9;
80
- return fetchResourceFromS3({
81
- bucketName: process.env.S3_BUCKET_IMAGE_TRANSFORMER_CACHE,
82
- key: transformedBucketImagePath
83
- });
82
+ return fetch(redirectLocation);
84
83
  case 9:
85
- newlyTransformedImage = _context.sent;
86
- console.debug('Image successfully fetched from S3 at:', redirectLocation);
87
- _fullDataUrl2 = formatBase64Image({
88
- base64String: newlyTransformedImage.body.toString('base64'),
89
- key: transformedBucketImagePath
90
- });
91
- return _context.abrupt("return", _fullDataUrl2);
84
+ response = _context.sent;
85
+ _context.next = 11;
86
+ break;
92
87
  case 10:
93
- throw new Error("Bad request to image transformer: ".concat(transformerResponse.body));
88
+ _context.prev = 10;
89
+ _t2 = _context["catch"](8);
90
+ throw new Error("Failed to fetch image from redirect URL: ".concat(_t2.message));
94
91
  case 11:
95
- throw new Error('Requested transformed image is too big');
92
+ if (response.ok) {
93
+ _context.next = 12;
94
+ break;
95
+ }
96
+ throw new Error("Failed to fetch image from redirect: ".concat(response.status));
96
97
  case 12:
97
- throw new Error('The requested image does not exist');
98
+ _t3 = Buffer;
99
+ _context.next = 13;
100
+ return response.arrayBuffer();
98
101
  case 13:
99
- throw new Error("Image transformation failed: ".concat(transformerResponse.body));
102
+ buffer = _t3.from.call(_t3, _context.sent);
103
+ return _context.abrupt("return", formatBase64Image({
104
+ base64String: buffer.toString('base64'),
105
+ key: transformedBucketImagePath
106
+ }));
100
107
  case 14:
101
- throw new Error("Unexpected response from image transformer: ".concat(statusCode, " - ").concat(transformerResponse.body));
108
+ throw new Error("Bad request to image transformer: ".concat(transformerResponse.body));
102
109
  case 15:
110
+ throw new Error('Requested transformed image is too big');
111
+ case 16:
112
+ throw new Error('The requested image does not exist');
113
+ case 17:
114
+ throw new Error("Image transformation failed: ".concat(transformerResponse.body));
115
+ case 18:
116
+ throw new Error("Unexpected response from image transformer: ".concat(statusCode, " - ").concat(transformerResponse.body));
117
+ case 19:
103
118
  case "end":
104
119
  return _context.stop();
105
120
  }
106
- }, _callee);
121
+ }, _callee, null, [[8, 10]]);
107
122
  }));
108
123
  return function fetchImageForPdfGeneratorService(_x) {
109
124
  return _ref.apply(this, arguments);
@@ -114,7 +129,7 @@ export function requestImageTransformation(_x2, _x3) {
114
129
  }
115
130
  function _requestImageTransformation() {
116
131
  _requestImageTransformation = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(path, searchParamsObject) {
117
- var lambdaEvent, params, result, response, errorMessage, _t2;
132
+ var lambdaEvent, params, result, response, errorMessage, _t4;
118
133
  return _regeneratorRuntime.wrap(function (_context2) {
119
134
  while (1) switch (_context2.prev = _context2.next) {
120
135
  case 0:
@@ -151,9 +166,9 @@ function _requestImageTransformation() {
151
166
  return _context2.abrupt("return", response);
152
167
  case 4:
153
168
  _context2.prev = 4;
154
- _t2 = _context2["catch"](2);
155
- errorMessage = "Failed to invoke image transformer lambda: ".concat(_t2.message);
156
- console.error(errorMessage, _t2);
169
+ _t4 = _context2["catch"](2);
170
+ errorMessage = "Failed to invoke image transformer lambda: ".concat(_t4.message);
171
+ console.error(errorMessage, _t4);
157
172
  throw new Error(errorMessage);
158
173
  case 5:
159
174
  case "end":
@@ -168,7 +183,7 @@ export function fetchResourceFromS3(_x4) {
168
183
  }
169
184
  function _fetchResourceFromS() {
170
185
  _fetchResourceFromS = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref2) {
171
- var bucketName, key, params, result, _t3;
186
+ var bucketName, key, params, result, _t5;
172
187
  return _regeneratorRuntime.wrap(function (_context3) {
173
188
  while (1) switch (_context3.prev = _context3.next) {
174
189
  case 0:
@@ -201,12 +216,12 @@ function _fetchResourceFromS() {
201
216
  });
202
217
  case 4:
203
218
  _context3.prev = 4;
204
- _t3 = _context3["catch"](2);
205
- if (!(_t3.code !== 'NoSuchKey')) {
219
+ _t5 = _context3["catch"](2);
220
+ if (!(_t5.code !== 'NoSuchKey')) {
206
221
  _context3.next = 5;
207
222
  break;
208
223
  }
209
- console.error('Failed to fetch image:', _t3);
224
+ console.error('Failed to fetch image:', _t5);
210
225
  throw new Error("Failed to fetch image: ".concat(bucketName, "/").concat(key));
211
226
  case 5:
212
227
  console.debug('Image not found in transformed bucket, invoking transformer');
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["validateBase64Image","AWS","IMAGE_CACHE_REGION","lambda","Lambda","region","s3","S3","fetchImageForPdfGeneratorService","_ref","_asyncToGenerator","_regeneratorRuntime","mark","_callee","url","urlMatch","applicationId","_parseUrlString","path","queryString","searchParamsObject","transformedBucketImagePath","alreadyTransformedImage","fullDataUrl","transformerResponse","statusCode","_fullDataUrl","redirectLocation","newlyTransformedImage","_fullDataUrl2","_t","wrap","_context","prev","next","console","debug","Error","match","parseUrlString","concat","fetchResourceFromS3","bucketName","process","env","S3_BUCKET_IMAGE_TRANSFORMER_CACHE","key","sent","body","formatBase64Image","base64String","toString","abrupt","requestImageTransformation","headers","Location","stop","_x","apply","arguments","_x2","_x3","_requestImageTransformation","_callee2","lambdaEvent","params","result","response","errorMessage","_t2","_context2","queryStringParameters","requestContext","http","method","FunctionName","IMAGE_TRANSFORMER_ARN","InvocationType","Payload","JSON","stringify","invoke","promise","parse","message","error","_x4","_fetchResourceFromS","_callee3","_ref2","_t3","_context3","Bucket","Key","getObject","Body","contentType","ContentType","contentLength","ContentLength","lastModified","LastModified","etag","ETag","code","_ref3","imageType","toLowerCase","includes","base64Flag","isValid","urlString","URL","searchParams","forEach","value","replace","pathname","substring"],"sources":["../../../src/helpers/fetch-image-for-pdf-generator-service/index.js"],"sourcesContent":["import { validateBase64Image } from '../image-validators'\nimport AWS from 'aws-sdk'\n\n// Image transformer and cache are always in us-east-1 (shared across all regions)\n// The image-optimisation-image-processing Lambda only exists in us-east-1\nconst IMAGE_CACHE_REGION = 'us-east-1'\n\nconst lambda = new AWS.Lambda({\n region: IMAGE_CACHE_REGION,\n})\n\nconst s3 = new AWS.S3({\n region: IMAGE_CACHE_REGION,\n})\n\nexport const fetchImageForPdfGeneratorService = async function (url) {\n console.debug(\n 'Fetching image via CloudFront For Serverless Pdf Generator Service'\n )\n\n if (!url) {\n throw new Error('URL is required to fetch image for PDF generator service')\n }\n\n const urlMatch = url && url.match(/([a-f0-9]{24})\\//)\n const applicationId = urlMatch && urlMatch[1]\n\n if (!applicationId) {\n throw new Error('Requestor has insufficient permissions')\n }\n\n const { path, queryString, searchParamsObject } = parseUrlString(url)\n\n const transformedBucketImagePath =\n path + (queryString ? `/${queryString}` : '')\n\n const alreadyTransformedImage = await fetchResourceFromS3({\n bucketName: process.env.S3_BUCKET_IMAGE_TRANSFORMER_CACHE,\n key: transformedBucketImagePath,\n })\n\n if (alreadyTransformedImage?.body) {\n const fullDataUrl = formatBase64Image({\n base64String: alreadyTransformedImage.body.toString('base64'),\n key: transformedBucketImagePath,\n })\n return fullDataUrl\n }\n\n const transformerResponse = await requestImageTransformation(\n `/${path}`,\n searchParamsObject\n )\n\n const statusCode = transformerResponse.statusCode\n\n switch (statusCode) {\n case 200: {\n console.debug('Image transformation successful')\n\n const fullDataUrl = formatBase64Image({\n base64String: transformerResponse.body.toString('base64'),\n key: url,\n })\n\n return fullDataUrl\n }\n case 302: {\n console.debug(\n 'Image transformation successful but image is too big for lambda delivery, fetching directly from S3'\n )\n const redirectLocation = transformerResponse.headers.Location\n\n if (!redirectLocation) {\n throw new Error('Redirect response received but no location provided')\n }\n const newlyTransformedImage = await fetchResourceFromS3({\n bucketName: process.env.S3_BUCKET_IMAGE_TRANSFORMER_CACHE,\n key: transformedBucketImagePath,\n })\n console.debug('Image successfully fetched from S3 at:', redirectLocation)\n\n const fullDataUrl = formatBase64Image({\n base64String: newlyTransformedImage.body.toString('base64'),\n key: transformedBucketImagePath,\n })\n\n return fullDataUrl\n }\n case 400:\n throw new Error(\n `Bad request to image transformer: ${transformerResponse.body}`\n )\n case 403:\n throw new Error('Requested transformed image is too big')\n case 404:\n throw new Error('The requested image does not exist')\n case 500:\n throw new Error(\n `Image transformation failed: ${transformerResponse.body}`\n )\n default:\n throw new Error(\n `Unexpected response from image transformer: ${statusCode} - ${transformerResponse.body}`\n )\n }\n}\n\nexport async function requestImageTransformation(path, searchParamsObject) {\n if (!path) {\n throw new Error('Image Path is required for image transformation')\n }\n\n console.debug(\n 'ImageTransformation: Invoking image transformer lambda for path:',\n { path, searchParamsObject }\n )\n\n const lambdaEvent = {\n queryStringParameters: searchParamsObject,\n requestContext: {\n http: {\n method: 'GET',\n path,\n },\n },\n }\n\n const params = {\n FunctionName: process.env.IMAGE_TRANSFORMER_ARN,\n InvocationType: 'RequestResponse',\n Payload: JSON.stringify(lambdaEvent),\n }\n\n try {\n const result = await lambda.invoke(params).promise()\n\n const response = JSON.parse(result.Payload)\n\n return response\n } catch (error) {\n const errorMessage = `Failed to invoke image transformer lambda: ${error.message}`\n console.error(errorMessage, error)\n throw new Error(errorMessage)\n }\n}\n\nexport async function fetchResourceFromS3({ bucketName, key }) {\n console.debug(\n `Fetching resource from S3 Bucket: '${bucketName}' at path: '${key}'`\n )\n if (!bucketName || !key) {\n throw new Error(\n 'bucketName and key are required for S3 resource fetch ' +\n JSON.stringify({ bucketName, key })\n )\n }\n\n const params = {\n Bucket: bucketName,\n Key: key,\n }\n\n try {\n const result = await s3.getObject(params).promise()\n\n return {\n body: result.Body,\n contentType: result.ContentType,\n contentLength: result.ContentLength,\n lastModified: result.LastModified,\n etag: result.ETag,\n }\n } catch (error) {\n if (error.code !== 'NoSuchKey') {\n console.error('Failed to fetch image:', error)\n throw new Error(`Failed to fetch image: ${bucketName}/${key}`)\n }\n\n console.debug('Image not found in transformed bucket, invoking transformer')\n }\n}\n\nexport function formatBase64Image({ base64String, key }) {\n if (!key) {\n throw new Error('Key is required for image formatting')\n }\n\n const imageType = key.toLowerCase().includes('.png') ? 'png' : 'jpeg'\n const base64Flag = `data:image/${imageType};base64,`\n const fullDataUrl = `${base64Flag}${base64String}`\n\n // Validate the formatted data URL\n const isValid = validateBase64Image(fullDataUrl)\n if (!isValid) {\n throw new Error('InvalidImageError')\n }\n\n return fullDataUrl\n}\n\n/**\n * Parses a URL-like string into path and query parameters\n * @param {string} urlString - String like \"https://example.cloudfront.net/<applicationId>/<path>/filename.jpeg?width=100&height=100\"\n * @returns {Object} - Object with { path: string, queryString: string, searchParamsObject: Object }\n * @example\n * parseUrlString(\"https://example.cloudfront.net/abc123/folder/image.jpeg?width=100&height=100\")\n * // Returns: { path: \"abc123/folder/image.jpeg\", queryString: \"width=100,t=456\", searchParamsObject: { width: \"100\", height: \"100\" } }\n */\nfunction parseUrlString(urlString) {\n if (!urlString || typeof urlString !== 'string') {\n throw new Error('URL string is required and must be a string')\n }\n\n // Extract the path after the domain\n const url = new URL(urlString)\n\n let searchParamsObject = {}\n url.searchParams.forEach((value, key) => {\n searchParamsObject[key] = value\n })\n\n let queryString = url.searchParams.toString()\n queryString = queryString ? queryString.replace(/&/g, ',') : ''\n\n return {\n path: url.pathname.substring(1), // Remove leading '/'\n queryString,\n searchParamsObject,\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["validateBase64Image","AWS","IMAGE_CACHE_REGION","lambda","Lambda","region","s3","S3","fetchImageForPdfGeneratorService","_ref","_asyncToGenerator","_regeneratorRuntime","mark","_callee","url","_transformerResponse$","urlMatch","applicationId","_parseUrlString","path","queryString","searchParamsObject","transformedBucketImagePath","alreadyTransformedImage","fullDataUrl","transformerResponse","statusCode","redirectLocation","_fullDataUrl","response","buffer","_t","_t2","_t3","wrap","_context","prev","next","console","debug","Error","match","parseUrlString","concat","fetchResourceFromS3","bucketName","process","env","S3_BUCKET_IMAGE_TRANSFORMER_CACHE","key","sent","body","formatBase64Image","base64String","toString","abrupt","requestImageTransformation","headers","Location","fetch","message","ok","status","Buffer","arrayBuffer","from","call","stop","_x","apply","arguments","_x2","_x3","_requestImageTransformation","_callee2","lambdaEvent","params","result","errorMessage","_t4","_context2","queryStringParameters","requestContext","http","method","FunctionName","IMAGE_TRANSFORMER_ARN","InvocationType","Payload","JSON","stringify","invoke","promise","parse","error","_x4","_fetchResourceFromS","_callee3","_ref2","_t5","_context3","Bucket","Key","getObject","Body","contentType","ContentType","contentLength","ContentLength","lastModified","LastModified","etag","ETag","code","_ref3","imageType","toLowerCase","includes","base64Flag","isValid","urlString","URL","searchParams","forEach","value","replace","pathname","substring"],"sources":["../../../src/helpers/fetch-image-for-pdf-generator-service/index.js"],"sourcesContent":["import { validateBase64Image } from '../image-validators'\nimport AWS from 'aws-sdk'\n\n// Image transformer and cache are always in us-east-1 (shared across all regions)\n// The image-optimisation-image-processing Lambda only exists in us-east-1\nconst IMAGE_CACHE_REGION = 'us-east-1'\n\nconst lambda = new AWS.Lambda({\n region: IMAGE_CACHE_REGION,\n})\n\nconst s3 = new AWS.S3({\n region: IMAGE_CACHE_REGION,\n})\n\nexport const fetchImageForPdfGeneratorService = async function (url) {\n console.debug(\n 'Fetching image via CloudFront For Serverless Pdf Generator Service'\n )\n\n if (!url) {\n throw new Error('URL is required to fetch image for PDF generator service')\n }\n\n const urlMatch = url && url.match(/([a-f0-9]{24})\\//)\n const applicationId = urlMatch && urlMatch[1]\n\n if (!applicationId) {\n throw new Error('Requestor has insufficient permissions')\n }\n\n const { path, queryString, searchParamsObject } = parseUrlString(url)\n\n const transformedBucketImagePath =\n path + (queryString ? `/${queryString}` : '')\n\n const alreadyTransformedImage = await fetchResourceFromS3({\n bucketName: process.env.S3_BUCKET_IMAGE_TRANSFORMER_CACHE,\n key: transformedBucketImagePath,\n })\n\n if (alreadyTransformedImage?.body) {\n const fullDataUrl = formatBase64Image({\n base64String: alreadyTransformedImage.body.toString('base64'),\n key: transformedBucketImagePath,\n })\n return fullDataUrl\n }\n\n const transformerResponse = await requestImageTransformation(\n `/${path}`,\n searchParamsObject\n )\n\n const statusCode = transformerResponse.statusCode\n const redirectLocation = transformerResponse.headers?.Location\n\n switch (statusCode) {\n case 200: {\n console.debug('Image transformation successful')\n\n const fullDataUrl = formatBase64Image({\n base64String: transformerResponse.body.toString('base64'),\n key: url,\n })\n\n return fullDataUrl\n }\n case 302: {\n console.debug(\n 'Image transformation successful but image is too big for lambda delivery, fetching directly via redirect URL'\n )\n\n if (!redirectLocation) {\n throw new Error('Redirect response received but no location provided')\n }\n\n let response\n try {\n response = await fetch(redirectLocation)\n } catch (error) {\n throw new Error(\n `Failed to fetch image from redirect URL: ${error.message}`\n )\n }\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch image from redirect: ${response.status}`\n )\n }\n\n const buffer = Buffer.from(await response.arrayBuffer())\n\n return formatBase64Image({\n base64String: buffer.toString('base64'),\n key: transformedBucketImagePath,\n })\n }\n case 400:\n throw new Error(\n `Bad request to image transformer: ${transformerResponse.body}`\n )\n case 403:\n throw new Error('Requested transformed image is too big')\n case 404:\n throw new Error('The requested image does not exist')\n case 500:\n throw new Error(\n `Image transformation failed: ${transformerResponse.body}`\n )\n default:\n throw new Error(\n `Unexpected response from image transformer: ${statusCode} - ${transformerResponse.body}`\n )\n }\n}\n\nexport async function requestImageTransformation(path, searchParamsObject) {\n if (!path) {\n throw new Error('Image Path is required for image transformation')\n }\n\n console.debug(\n 'ImageTransformation: Invoking image transformer lambda for path:',\n { path, searchParamsObject }\n )\n\n const lambdaEvent = {\n queryStringParameters: searchParamsObject,\n requestContext: {\n http: {\n method: 'GET',\n path,\n },\n },\n }\n\n const params = {\n FunctionName: process.env.IMAGE_TRANSFORMER_ARN,\n InvocationType: 'RequestResponse',\n Payload: JSON.stringify(lambdaEvent),\n }\n\n try {\n const result = await lambda.invoke(params).promise()\n\n const response = JSON.parse(result.Payload)\n\n return response\n } catch (error) {\n const errorMessage = `Failed to invoke image transformer lambda: ${error.message}`\n console.error(errorMessage, error)\n throw new Error(errorMessage)\n }\n}\n\nexport async function fetchResourceFromS3({ bucketName, key }) {\n console.debug(\n `Fetching resource from S3 Bucket: '${bucketName}' at path: '${key}'`\n )\n if (!bucketName || !key) {\n throw new Error(\n 'bucketName and key are required for S3 resource fetch ' +\n JSON.stringify({ bucketName, key })\n )\n }\n\n const params = {\n Bucket: bucketName,\n Key: key,\n }\n\n try {\n const result = await s3.getObject(params).promise()\n\n return {\n body: result.Body,\n contentType: result.ContentType,\n contentLength: result.ContentLength,\n lastModified: result.LastModified,\n etag: result.ETag,\n }\n } catch (error) {\n if (error.code !== 'NoSuchKey') {\n console.error('Failed to fetch image:', error)\n throw new Error(`Failed to fetch image: ${bucketName}/${key}`)\n }\n\n console.debug('Image not found in transformed bucket, invoking transformer')\n }\n}\n\nexport function formatBase64Image({ base64String, key }) {\n if (!key) {\n throw new Error('Key is required for image formatting')\n }\n\n const imageType = key.toLowerCase().includes('.png') ? 'png' : 'jpeg'\n const base64Flag = `data:image/${imageType};base64,`\n const fullDataUrl = `${base64Flag}${base64String}`\n\n // Validate the formatted data URL\n const isValid = validateBase64Image(fullDataUrl)\n if (!isValid) {\n throw new Error('InvalidImageError')\n }\n\n return fullDataUrl\n}\n\n/**\n * Parses a URL-like string into path and query parameters\n * @param {string} urlString - String like \"https://example.cloudfront.net/<applicationId>/<path>/filename.jpeg?width=100&height=100\"\n * @returns {Object} - Object with { path: string, queryString: string, searchParamsObject: Object }\n * @example\n * parseUrlString(\"https://example.cloudfront.net/abc123/folder/image.jpeg?width=100&height=100\")\n * // Returns: { path: \"abc123/folder/image.jpeg\", queryString: \"width=100,t=456\", searchParamsObject: { width: \"100\", height: \"100\" } }\n */\nfunction parseUrlString(urlString) {\n if (!urlString || typeof urlString !== 'string') {\n throw new Error('URL string is required and must be a string')\n }\n\n // Extract the path after the domain\n const url = new URL(urlString)\n\n let searchParamsObject = {}\n url.searchParams.forEach((value, key) => {\n searchParamsObject[key] = value\n })\n\n let queryString = url.searchParams.toString()\n queryString = queryString ? queryString.replace(/&/g, ',') : ''\n\n return {\n path: url.pathname.substring(1), // Remove leading '/'\n queryString,\n searchParamsObject,\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -2,57 +2,91 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _regeneratorRuntime from "@babel/runtime/regenerator";
3
3
  import { imageNotFound } from '../../images';
4
4
  import { fetchLighthouseLogo } from '../fetch-lighthouse-logo';
5
+ import { isAbsoluteUrl } from '../validate-url/index.js';
5
6
  export var fetchImageForWeb = /*#__PURE__*/function () {
6
7
  var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(url, options) {
7
- var _options$isHeader, isHeader, Signature, Policy, KeyPairId, firstParamConnector, hasSignatureParams, constructedUrl, imageResponse, contentLengthHeader, _t;
8
+ var _options$isHeader, isHeader, Signature, Policy, KeyPairId, _options$context, context, error, firstParamConnector, hasSignatureParams, constructedUrl, imageResponse, contentLengthHeader, _t;
8
9
  return _regeneratorRuntime.wrap(function (_context) {
9
10
  while (1) switch (_context.prev = _context.next) {
10
11
  case 0:
11
- _options$isHeader = options.isHeader, isHeader = _options$isHeader === void 0 ? false : _options$isHeader, Signature = options.Signature, Policy = options.Policy, KeyPairId = options.KeyPairId;
12
- _context.prev = 1;
12
+ _options$isHeader = options.isHeader, isHeader = _options$isHeader === void 0 ? false : _options$isHeader, Signature = options.Signature, Policy = options.Policy, KeyPairId = options.KeyPairId, _options$context = options.context, context = _options$context === void 0 ? {} : _options$context; // Validate url parameter
13
+ if (!(!url || typeof url !== 'string')) {
14
+ _context.next = 2;
15
+ break;
16
+ }
17
+ error = new Error("fetchImageForWeb: Invalid url parameter. url=".concat(JSON.stringify(url)));
18
+ if (!isHeader) {
19
+ _context.next = 1;
20
+ break;
21
+ }
22
+ console.error('FetchImageHeaderError', {
23
+ message: error.message,
24
+ url: url,
25
+ context: context
26
+ });
27
+ return _context.abrupt("return", fetchLighthouseLogo());
28
+ case 1:
29
+ console.error('FetchImageError', {
30
+ message: error.message,
31
+ url: url,
32
+ context: context
33
+ });
34
+ return _context.abrupt("return", imageNotFound);
35
+ case 2:
36
+ _context.prev = 2;
13
37
  firstParamConnector = url.indexOf('?') > -1 ? '&' : '?';
14
38
  hasSignatureParams = url.includes('Signature=') && url.includes('Policy=') && url.includes('Key-Pair-Id=');
15
39
  constructedUrl = !hasSignatureParams ? "".concat(url).concat(firstParamConnector, "Signature=").concat(Signature, "&Policy=").concat(Policy, "&Key-Pair-Id=").concat(KeyPairId) : url;
16
40
  console.debug('Fetching image via CloudFront For Web');
17
- _context.next = 2;
41
+ _context.next = 3;
18
42
  return fetch(constructedUrl);
19
- case 2:
43
+ case 3:
20
44
  imageResponse = _context.sent;
21
45
  contentLengthHeader = imageResponse.headers.get('content-length');
22
46
  if (!(contentLengthHeader === '0')) {
23
- _context.next = 3;
47
+ _context.next = 4;
24
48
  break;
25
49
  }
26
- return _context.abrupt("return", Promise.reject(new Error("Failed to fetch image as no content length: ".concat(encodedUrl))));
27
- case 3:
50
+ return _context.abrupt("return", Promise.reject(new Error("Failed to fetch image as no content length: ".concat(url))));
51
+ case 4:
28
52
  if (imageResponse.ok) {
29
- _context.next = 4;
53
+ _context.next = 5;
30
54
  break;
31
55
  }
32
- return _context.abrupt("return", Promise.reject(new Error("Failed to fetch image: ".concat(encodedUrl))));
33
- case 4:
34
- _context.next = 5;
35
- return imageResponse.arrayBuffer();
56
+ return _context.abrupt("return", Promise.reject(new Error("Failed to fetch image: ".concat(url))));
36
57
  case 5:
37
- return _context.abrupt("return", _context.sent);
58
+ _context.next = 6;
59
+ return imageResponse.arrayBuffer();
38
60
  case 6:
39
- _context.prev = 6;
40
- _t = _context["catch"](1);
61
+ return _context.abrupt("return", _context.sent);
62
+ case 7:
63
+ _context.prev = 7;
64
+ _t = _context["catch"](2);
41
65
  if (!isHeader) {
42
- _context.next = 7;
66
+ _context.next = 8;
43
67
  break;
44
68
  }
45
69
  // NOTE: Replace failed headers with LH logo
46
- console.error('FetchImageHeaderError', _t);
70
+ console.error('FetchImageHeaderError', {
71
+ url: url,
72
+ message: _t.message,
73
+ context: context,
74
+ stack: _t.stack
75
+ });
47
76
  return _context.abrupt("return", fetchLighthouseLogo());
48
- case 7:
49
- console.error(_t);
50
- return _context.abrupt("return", imageNotFound);
51
77
  case 8:
78
+ console.error('FetchImageError', {
79
+ url: url,
80
+ message: _t.message,
81
+ context: context,
82
+ stack: _t.stack
83
+ });
84
+ return _context.abrupt("return", imageNotFound);
85
+ case 9:
52
86
  case "end":
53
87
  return _context.stop();
54
88
  }
55
- }, _callee, null, [[1, 6]]);
89
+ }, _callee, null, [[2, 7]]);
56
90
  }));
57
91
  return function fetchImageForWeb(_x, _x2) {
58
92
  return _ref.apply(this, arguments);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["imageNotFound","fetchLighthouseLogo","fetchImageForWeb","_ref","_asyncToGenerator","_regeneratorRuntime","mark","_callee","url","options","_options$isHeader","isHeader","Signature","Policy","KeyPairId","firstParamConnector","hasSignatureParams","constructedUrl","imageResponse","contentLengthHeader","_t","wrap","_context","prev","next","indexOf","includes","concat","console","debug","fetch","sent","headers","get","abrupt","Promise","reject","Error","encodedUrl","ok","arrayBuffer","error","stop","_x","_x2","apply","arguments"],"sources":["../../../src/helpers/fetch-image-for-web/index.js"],"sourcesContent":["import { imageNotFound } from '../../images'\nimport { fetchLighthouseLogo } from '../fetch-lighthouse-logo'\nexport const fetchImageForWeb = async function (url, options) {\n const { isHeader = false, Signature, Policy, KeyPairId } = options\n\n try {\n const firstParamConnector = url.indexOf('?') > -1 ? '&' : '?'\n\n const hasSignatureParams =\n url.includes('Signature=') &&\n url.includes('Policy=') &&\n url.includes('Key-Pair-Id=')\n\n const constructedUrl = !hasSignatureParams\n ? `${url}${firstParamConnector}Signature=${Signature}&Policy=${Policy}&Key-Pair-Id=${KeyPairId}`\n : url\n\n console.debug('Fetching image via CloudFront For Web')\n\n const imageResponse = await fetch(constructedUrl)\n\n const contentLengthHeader = imageResponse.headers.get('content-length')\n\n if (contentLengthHeader === '0') {\n return Promise.reject(\n new Error(`Failed to fetch image as no content length: ${encodedUrl}`)\n )\n }\n\n if (!imageResponse.ok) {\n return Promise.reject(new Error(`Failed to fetch image: ${encodedUrl}`))\n }\n\n return await imageResponse.arrayBuffer()\n } catch (error) {\n if (isHeader) {\n // NOTE: Replace failed headers with LH logo\n console.error('FetchImageHeaderError', error)\n return fetchLighthouseLogo()\n }\n\n console.error(error)\n return imageNotFound\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["imageNotFound","fetchLighthouseLogo","isAbsoluteUrl","fetchImageForWeb","_ref","_asyncToGenerator","_regeneratorRuntime","mark","_callee","url","options","_options$isHeader","isHeader","Signature","Policy","KeyPairId","_options$context","context","error","firstParamConnector","hasSignatureParams","constructedUrl","imageResponse","contentLengthHeader","_t","wrap","_context","prev","next","Error","concat","JSON","stringify","console","message","abrupt","indexOf","includes","debug","fetch","sent","headers","get","Promise","reject","ok","arrayBuffer","stack","stop","_x","_x2","apply","arguments"],"sources":["../../../src/helpers/fetch-image-for-web/index.js"],"sourcesContent":["import { imageNotFound } from '../../images'\nimport { fetchLighthouseLogo } from '../fetch-lighthouse-logo'\nimport { isAbsoluteUrl } from '../validate-url/index.js'\n\nexport const fetchImageForWeb = async function (url, options) {\n const {\n isHeader = false,\n Signature,\n Policy,\n KeyPairId,\n context = {},\n } = options\n\n // Validate url parameter\n if (!url || typeof url !== 'string') {\n const error = new Error(\n `fetchImageForWeb: Invalid url parameter. url=${JSON.stringify(url)}`\n )\n if (isHeader) {\n console.error('FetchImageHeaderError', {\n message: error.message,\n url,\n context,\n })\n return fetchLighthouseLogo()\n }\n console.error('FetchImageError', {\n message: error.message,\n url,\n context,\n })\n return imageNotFound\n }\n\n try {\n const firstParamConnector = url.indexOf('?') > -1 ? '&' : '?'\n\n const hasSignatureParams =\n url.includes('Signature=') &&\n url.includes('Policy=') &&\n url.includes('Key-Pair-Id=')\n\n const constructedUrl = !hasSignatureParams\n ? `${url}${firstParamConnector}Signature=${Signature}&Policy=${Policy}&Key-Pair-Id=${KeyPairId}`\n : url\n\n console.debug('Fetching image via CloudFront For Web')\n\n const imageResponse = await fetch(constructedUrl)\n\n const contentLengthHeader = imageResponse.headers.get('content-length')\n\n if (contentLengthHeader === '0') {\n return Promise.reject(\n new Error(`Failed to fetch image as no content length: ${url}`)\n )\n }\n\n if (!imageResponse.ok) {\n return Promise.reject(new Error(`Failed to fetch image: ${url}`))\n }\n\n return await imageResponse.arrayBuffer()\n } catch (error) {\n if (isHeader) {\n // NOTE: Replace failed headers with LH logo\n console.error('FetchImageHeaderError', {\n url,\n message: error.message,\n context,\n stack: error.stack,\n })\n return fetchLighthouseLogo()\n }\n\n console.error('FetchImageError', {\n url,\n message: error.message,\n context,\n stack: error.stack,\n })\n return imageNotFound\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Checks if a URL is absolute (starts with http:// or https://)
3
+ * @param {string} url - The URL to validate
4
+ * @returns {boolean} - True if URL is absolute, false otherwise
5
+ */
6
+ export function isAbsoluteUrl(url) {
7
+ if (!url || typeof url !== 'string') return false;
8
+ return url.startsWith('http://') || url.startsWith('https://');
9
+ }
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["isAbsoluteUrl","url","startsWith"],"sources":["../../../src/helpers/validate-url/index.js"],"sourcesContent":["/**\n * Checks if a URL is absolute (starts with http:// or https://)\n * @param {string} url - The URL to validate\n * @returns {boolean} - True if URL is absolute, false otherwise\n */\nexport function isAbsoluteUrl(url) {\n if (!url || typeof url !== 'string') return false\n return url.startsWith('http://') || url.startsWith('https://')\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,aAAaA,CAACC,GAAG,EAAE;EACjC,IAAI,CAACA,GAAG,IAAI,OAAOA,GAAG,KAAK,QAAQ,EAAE,OAAO,KAAK;EACjD,OAAOA,GAAG,CAACC,UAAU,CAAC,SAAS,CAAC,IAAID,GAAG,CAACC,UAAU,CAAC,UAAU,CAAC;AAChE","ignoreList":[]}
@@ -1,4 +1,6 @@
1
1
  import { fetchImage, getTimezoneDatetime } from '../../../helpers';
2
+ import { LIGHTHOUSE_LOGO_URL } from '../../../constants';
3
+ import { isAbsoluteUrl } from '../../../helpers/validate-url/index.js';
2
4
  export function defaultHeader(_ref) {
3
5
  var Signature = _ref.Signature,
4
6
  Policy = _ref.Policy,
@@ -12,7 +14,15 @@ export function defaultHeader(_ref) {
12
14
  timestamp: timestamp,
13
15
  timezone: timezone
14
16
  });
15
- return fetchImage(logoUrl, {
17
+
18
+ // Validate logoUrl and use fallback if invalid
19
+ var effectiveLogoUrl = isAbsoluteUrl(logoUrl) ? logoUrl : LIGHTHOUSE_LOGO_URL;
20
+ if (!isAbsoluteUrl(logoUrl)) {
21
+ console.warn('defaultHeader: Invalid logoUrl, using Lighthouse logo', {
22
+ providedLogoUrl: logoUrl
23
+ });
24
+ }
25
+ return fetchImage(effectiveLogoUrl, {
16
26
  Signature: Signature,
17
27
  Policy: Policy,
18
28
  KeyPairId: KeyPairId,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["fetchImage","getTimezoneDatetime","defaultHeader","_ref","Signature","Policy","KeyPairId","logoUrl","timestamp","timezone","datetime","format","showTzAbbr","isHeader","then","image","columns","fit","margin","alignment","color","font","fontSize","text"],"sources":["../../../../src/pdf/helpers/default-header/index.js"],"sourcesContent":["import { fetchImage, getTimezoneDatetime } from '../../../helpers'\n\nexport function defaultHeader({\n Signature,\n Policy,\n KeyPairId,\n logoUrl,\n timestamp,\n timezone,\n}) {\n const datetime = getTimezoneDatetime({\n format: 'ddd, Do MMM YYYY',\n showTzAbbr: false,\n timestamp,\n timezone,\n })\n\n return fetchImage(logoUrl, {\n Signature,\n Policy,\n KeyPairId,\n isHeader: true,\n }).then(image => ({\n columns: [\n {\n fit: [130, 30],\n image,\n margin: [60, 60, 60, 0],\n },\n {\n alignment: 'right',\n color: '#999',\n font: 'Gotham',\n fontSize: 11,\n text: datetime,\n margin: [60, 70, 60, 0],\n },\n ],\n }))\n}\n"],"mappings":"AAAA,SAASA,UAAU,EAAEC,mBAAmB,QAAQ,kBAAkB;AAElE,OAAO,SAASC,aAAaA,CAAAC,IAAA,EAO1B;EAAA,IANDC,SAAS,GAAAD,IAAA,CAATC,SAAS;IACTC,MAAM,GAAAF,IAAA,CAANE,MAAM;IACNC,SAAS,GAAAH,IAAA,CAATG,SAAS;IACTC,OAAO,GAAAJ,IAAA,CAAPI,OAAO;IACPC,SAAS,GAAAL,IAAA,CAATK,SAAS;IACTC,QAAQ,GAAAN,IAAA,CAARM,QAAQ;EAER,IAAMC,QAAQ,GAAGT,mBAAmB,CAAC;IACnCU,MAAM,EAAE,kBAAkB;IAC1BC,UAAU,EAAE,KAAK;IACjBJ,SAAS,EAATA,SAAS;IACTC,QAAQ,EAARA;EACF,CAAC,CAAC;EAEF,OAAOT,UAAU,CAACO,OAAO,EAAE;IACzBH,SAAS,EAATA,SAAS;IACTC,MAAM,EAANA,MAAM;IACNC,SAAS,EAATA,SAAS;IACTO,QAAQ,EAAE;EACZ,CAAC,CAAC,CAACC,IAAI,CAAC,UAAAC,KAAK;IAAA,OAAK;MAChBC,OAAO,EAAE,CACP;QACEC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC;QACdF,KAAK,EAALA,KAAK;QACLG,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;MACxB,CAAC,EACD;QACEC,SAAS,EAAE,OAAO;QAClBC,KAAK,EAAE,MAAM;QACbC,IAAI,EAAE,QAAQ;QACdC,QAAQ,EAAE,EAAE;QACZC,IAAI,EAAEb,QAAQ;QACdQ,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;MACxB,CAAC;IAEL,CAAC;EAAA,CAAC,CAAC;AACL","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["fetchImage","getTimezoneDatetime","LIGHTHOUSE_LOGO_URL","isAbsoluteUrl","defaultHeader","_ref","Signature","Policy","KeyPairId","logoUrl","timestamp","timezone","datetime","format","showTzAbbr","effectiveLogoUrl","console","warn","providedLogoUrl","isHeader","then","image","columns","fit","margin","alignment","color","font","fontSize","text"],"sources":["../../../../src/pdf/helpers/default-header/index.js"],"sourcesContent":["import { fetchImage, getTimezoneDatetime } from '../../../helpers'\nimport { LIGHTHOUSE_LOGO_URL } from '../../../constants'\nimport { isAbsoluteUrl } from '../../../helpers/validate-url/index.js'\n\nexport function defaultHeader({\n Signature,\n Policy,\n KeyPairId,\n logoUrl,\n timestamp,\n timezone,\n}) {\n const datetime = getTimezoneDatetime({\n format: 'ddd, Do MMM YYYY',\n showTzAbbr: false,\n timestamp,\n timezone,\n })\n\n // Validate logoUrl and use fallback if invalid\n const effectiveLogoUrl = isAbsoluteUrl(logoUrl)\n ? logoUrl\n : LIGHTHOUSE_LOGO_URL\n\n if (!isAbsoluteUrl(logoUrl)) {\n console.warn('defaultHeader: Invalid logoUrl, using Lighthouse logo', {\n providedLogoUrl: logoUrl,\n })\n }\n\n return fetchImage(effectiveLogoUrl, {\n Signature,\n Policy,\n KeyPairId,\n isHeader: true,\n }).then((image) => ({\n columns: [\n {\n fit: [130, 30],\n image,\n margin: [60, 60, 60, 0],\n },\n {\n alignment: 'right',\n color: '#999',\n font: 'Gotham',\n fontSize: 11,\n text: datetime,\n margin: [60, 70, 60, 0],\n },\n ],\n }))\n}\n"],"mappings":"AAAA,SAASA,UAAU,EAAEC,mBAAmB,QAAQ,kBAAkB;AAClE,SAASC,mBAAmB,QAAQ,oBAAoB;AACxD,SAASC,aAAa,QAAQ,wCAAwC;AAEtE,OAAO,SAASC,aAAaA,CAAAC,IAAA,EAO1B;EAAA,IANDC,SAAS,GAAAD,IAAA,CAATC,SAAS;IACTC,MAAM,GAAAF,IAAA,CAANE,MAAM;IACNC,SAAS,GAAAH,IAAA,CAATG,SAAS;IACTC,OAAO,GAAAJ,IAAA,CAAPI,OAAO;IACPC,SAAS,GAAAL,IAAA,CAATK,SAAS;IACTC,QAAQ,GAAAN,IAAA,CAARM,QAAQ;EAER,IAAMC,QAAQ,GAAGX,mBAAmB,CAAC;IACnCY,MAAM,EAAE,kBAAkB;IAC1BC,UAAU,EAAE,KAAK;IACjBJ,SAAS,EAATA,SAAS;IACTC,QAAQ,EAARA;EACF,CAAC,CAAC;;EAEF;EACA,IAAMI,gBAAgB,GAAGZ,aAAa,CAACM,OAAO,CAAC,GAC3CA,OAAO,GACPP,mBAAmB;EAEvB,IAAI,CAACC,aAAa,CAACM,OAAO,CAAC,EAAE;IAC3BO,OAAO,CAACC,IAAI,CAAC,uDAAuD,EAAE;MACpEC,eAAe,EAAET;IACnB,CAAC,CAAC;EACJ;EAEA,OAAOT,UAAU,CAACe,gBAAgB,EAAE;IAClCT,SAAS,EAATA,SAAS;IACTC,MAAM,EAANA,MAAM;IACNC,SAAS,EAATA,SAAS;IACTW,QAAQ,EAAE;EACZ,CAAC,CAAC,CAACC,IAAI,CAAC,UAACC,KAAK;IAAA,OAAM;MAClBC,OAAO,EAAE,CACP;QACEC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC;QACdF,KAAK,EAALA,KAAK;QACLG,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;MACxB,CAAC,EACD;QACEC,SAAS,EAAE,OAAO;QAClBC,KAAK,EAAE,MAAM;QACbC,IAAI,EAAE,QAAQ;QACdC,QAAQ,EAAE,EAAE;QACZC,IAAI,EAAEjB,QAAQ;QACdY,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;MACxB,CAAC;IAEL,CAAC;EAAA,CAAC,CAAC;AACL","ignoreList":[]}
@@ -1,4 +1,7 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2
5
  import { isArray, isEmpty, join, first, map, startsWith } from 'lodash';
3
6
  import Promise from 'bluebird';
4
7
  import moment from 'moment-timezone';
@@ -31,7 +34,10 @@ function buildImage(options) {
31
34
  settings = _options$settings === void 0 ? {} : _options$settings,
32
35
  signedAsset = options.signedAsset,
33
36
  _options$width = options.width,
34
- width = _options$width === void 0 ? 210 : _options$width;
37
+ width = _options$width === void 0 ? 210 : _options$width,
38
+ fieldLabel = options.fieldLabel,
39
+ _options$fieldType = options.fieldType,
40
+ fieldType = _options$fieldType === void 0 ? 'image' : _options$fieldType;
35
41
  var awsS3BaseUrl = settings.awsS3BaseUrl,
36
42
  cloudinaryBaseUrl = settings.cloudinaryBaseUrl,
37
43
  cloudfrontBaseUrl = settings.cloudfrontBaseUrl,
@@ -58,7 +64,14 @@ function buildImage(options) {
58
64
  });
59
65
 
60
66
  // NOTE: shouldUseCloudfront, Signature, Policy and KeyPairId from settings are used in this context
61
- return fetchImage(url, settings).then(function (base64String) {
67
+ return fetchImage(url, _objectSpread(_objectSpread({}, settings), {}, {
68
+ context: {
69
+ stage: 'field',
70
+ fieldLabel: fieldLabel,
71
+ fieldType: fieldType,
72
+ filepath: filepath
73
+ }
74
+ })).then(function (base64String) {
62
75
  return {
63
76
  alignment: alignment,
64
77
  fit: [width, height],
@@ -108,7 +121,13 @@ export function buildSummaryField(_ref2) {
108
121
  };
109
122
  }
110
123
  // NOTE: shouldUseCloudfront, Signature, Policy and KeyPairId from settings are used in this context
111
- return fetchImage(value, settings).then(function (base64String) {
124
+ return fetchImage(value, _objectSpread(_objectSpread({}, settings), {}, {
125
+ context: {
126
+ stage: 'field',
127
+ fieldLabel: field.label,
128
+ fieldType: 'signature'
129
+ }
130
+ })).then(function (base64String) {
112
131
  return {
113
132
  alignment: 'left',
114
133
  image: base64String,
@@ -132,7 +151,9 @@ export function buildSummaryField(_ref2) {
132
151
  height: 140,
133
152
  width: 140,
134
153
  settings: settings,
135
- signedAsset: signedAssets && isArray(signedAssets) ? signedAssets[0] : null
154
+ signedAsset: signedAssets && isArray(signedAssets) ? signedAssets[0] : null,
155
+ fieldLabel: field.label,
156
+ fieldType: 'media'
136
157
  });
137
158
  return image;
138
159
  }
@@ -234,7 +255,13 @@ export function buildTemplateFieldRow(_ref3) {
234
255
  if (isSignatureField) {
235
256
  if (!value) return [labelText, ''];
236
257
  // NOTE: shouldUseCloudfront, Signature, Policy and KeyPairId from settings are used in this context
237
- return fetchImage(value, settings).then(function (base64String) {
258
+ return fetchImage(value, _objectSpread(_objectSpread({}, settings), {}, {
259
+ context: {
260
+ stage: 'field',
261
+ fieldLabel: label,
262
+ fieldType: 'signature'
263
+ }
264
+ })).then(function (base64String) {
238
265
  var values = {
239
266
  alignment: 'left',
240
267
  image: base64String,
@@ -244,24 +271,41 @@ export function buildTemplateFieldRow(_ref3) {
244
271
  });
245
272
  }
246
273
  if (isDisplayImageField) {
247
- return Promise.map([value], function (filepath, index) {
274
+ // Guard against nullish values
275
+ if (!value) {
276
+ return [[], {}];
277
+ }
278
+
279
+ // Ensure value is always treated as an array of filepaths
280
+ var filepaths = isArray(value) ? value : [value];
281
+ return Promise.map(filepaths, function (filepath, index) {
248
282
  var signedAssetValue = isArray(signedAssets) ? signedAssets[index] : signedAssets;
249
283
  return buildImage({
250
284
  filepath: filepath,
251
285
  settings: settings,
252
- signedAsset: signedAssetValue
286
+ signedAsset: signedAssetValue,
287
+ fieldLabel: label,
288
+ fieldType: 'image-display'
253
289
  });
254
290
  }).then(function (fieldImages) {
255
291
  return [fieldImages, {}];
256
292
  });
257
293
  }
258
294
  if (isPhotoField) {
295
+ // Guard against nullish values
296
+ if (!value || isArray(value) && value.length === 0) {
297
+ return [labelText, {
298
+ text: ''
299
+ }];
300
+ }
259
301
  return Promise.map(value, function (filepath, index) {
260
302
  var signedAssetValue = isArray(signedAssets) ? signedAssets[index] : signedAssets;
261
303
  return buildImage({
262
304
  filepath: filepath,
263
305
  settings: settings,
264
- signedAsset: signedAssetValue
306
+ signedAsset: signedAssetValue,
307
+ fieldLabel: label,
308
+ fieldType: 'media'
265
309
  });
266
310
  }).then(function (fieldImages) {
267
311
  var tables = !isEmpty(fieldImages) ? imageTables(fieldImages) : [];