@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
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FetchImageError = void 0;
7
+ /**
8
+ * Custom error class for image fetching operations
9
+ * Includes context information for better debugging
10
+ */
11
+ class FetchImageError extends Error {
12
+ constructor(message, context = {}) {
13
+ super(message);
14
+ this.name = 'FetchImageError';
15
+ this.context = context;
16
+ this.url = context.url;
17
+ }
18
+ }
19
+ exports.FetchImageError = FetchImageError;
@@ -4,7 +4,12 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.buildFetchUrl = buildFetchUrl;
7
+ var _index = require("../validate-url/index.js");
7
8
  function buildFetchUrl(url, options) {
9
+ // Validate url parameter
10
+ if (!url || typeof url !== 'string') {
11
+ throw new Error(`buildFetchUrl: Invalid url parameter. url=${JSON.stringify(url)}`);
12
+ }
8
13
  const {
9
14
  awsS3BaseUrl,
10
15
  cloudfrontBaseUrl = '',
@@ -19,6 +24,10 @@ function buildFetchUrl(url, options) {
19
24
  Signature
20
25
  } = options;
21
26
  if (shouldUseCloudfront) {
27
+ // Validate cloudfrontBaseUrl when using CloudFront
28
+ if (!cloudfrontBaseUrl) {
29
+ throw new Error(`buildFetchUrl: cloudfrontBaseUrl is required when shouldUseCloudfront=true. cloudfrontBaseUrl=${JSON.stringify(cloudfrontBaseUrl)}`);
30
+ }
22
31
  const isWebContext = shouldUseCloudfront && typeof window === 'object';
23
32
  const paramMap = {
24
33
  width,
@@ -33,7 +42,18 @@ function buildFetchUrl(url, options) {
33
42
  }
34
43
  const params = Object.entries(paramMap).filter(([, value]) => value != null).map(([key, value]) => `${key}=${String(value)}`);
35
44
  const paramsString = params.join('&');
36
- return `${cloudfrontBaseUrl}/${url}?${paramsString}`;
45
+ const result = `${cloudfrontBaseUrl}/${url}?${paramsString}`;
46
+
47
+ // Validate output is absolute URL
48
+ if (!(0, _index.isAbsoluteUrl)(result)) {
49
+ throw new Error(`buildFetchUrl: Constructed URL is not absolute. cloudfrontBaseUrl=${JSON.stringify(cloudfrontBaseUrl)}, url=${JSON.stringify(url)}, result=${JSON.stringify(result)}`);
50
+ }
51
+ return result;
52
+ }
53
+
54
+ // Validate required base URLs for Cloudinary path
55
+ if (!cloudinaryBaseUrl || !awsS3BaseUrl) {
56
+ throw new Error(`buildFetchUrl: cloudinaryBaseUrl and awsS3BaseUrl are required. cloudinaryBaseUrl=${JSON.stringify(cloudinaryBaseUrl)}, awsS3BaseUrl=${JSON.stringify(awsS3BaseUrl)}`);
37
57
  }
38
58
  const transformations = [];
39
59
  let transformationsString = '';
@@ -43,5 +63,10 @@ function buildFetchUrl(url, options) {
43
63
  if (fit) transformations.push('c_fit');
44
64
  transformationsString = `${transformations.join(',')}/`;
45
65
  const fetchUrl = `${cloudinaryBaseUrl}/${transformationsString}${awsS3BaseUrl}/${url}`;
66
+
67
+ // Validate output is absolute URL
68
+ if (!(0, _index.isAbsoluteUrl)(fetchUrl)) {
69
+ throw new Error(`buildFetchUrl: Constructed URL is not absolute. cloudinaryBaseUrl=${JSON.stringify(cloudinaryBaseUrl)}, awsS3BaseUrl=${JSON.stringify(awsS3BaseUrl)}, url=${JSON.stringify(url)}, result=${JSON.stringify(fetchUrl)}`);
70
+ }
46
71
  return fetchUrl;
47
72
  }
@@ -15,6 +15,7 @@ var _constants = require("../../constants");
15
15
  var _images = require("../../images");
16
16
  var _fetchImageForPdfGeneratorService = require("../fetch-image-for-pdf-generator-service");
17
17
  var _fetchImageForWeb = require("../fetch-image-for-web");
18
+ var _index = require("../validate-url/index.js");
18
19
  // NOTE use the native fetch if it's available in the browser, because the
19
20
  // ponyfill (which actually uses the github polyfill) does not support all the
20
21
  // same options as native fetch
@@ -37,8 +38,29 @@ const defaultOptions = {
37
38
  };
38
39
  function fetchImage(url, options = {}) {
39
40
  const {
40
- shouldUseCloudfront
41
+ shouldUseCloudfront,
42
+ isHeader = false,
43
+ context = {}
41
44
  } = options;
45
+
46
+ // Validate url parameter
47
+ if (!url || typeof url !== 'string') {
48
+ const error = new Error(`fetchImage: Invalid url parameter. url=${JSON.stringify(url)}`);
49
+ if (isHeader) {
50
+ console.error('FetchImageHeaderError', {
51
+ message: error.message,
52
+ url,
53
+ context
54
+ });
55
+ return fetchImage(_constants.LIGHTHOUSE_LOGO_URL, defaultOptions);
56
+ }
57
+ console.error('FetchImageError', {
58
+ message: error.message,
59
+ url,
60
+ context
61
+ });
62
+ return _bluebird.default.resolve(_images.imageNotFound);
63
+ }
42
64
  if (shouldUseCloudfront) {
43
65
  const isWebContext = typeof window === 'object';
44
66
  return isWebContext ?
@@ -50,9 +72,6 @@ function fetchImage(url, options = {}) {
50
72
  ...defaultOptions,
51
73
  ...options
52
74
  };
53
- const {
54
- isHeader = false
55
- } = options;
56
75
  return fetch(encodedUrl, fetchOptions).then(response => {
57
76
  const contentHeader = response.headers.get('content-length');
58
77
  const contentType = response.headers.get('content-type');
@@ -60,10 +79,10 @@ function fetchImage(url, options = {}) {
60
79
  // NOTE: the response will be ok but we won't be able to render any
61
80
  // image meaning pdfmake will error. Raise error here and return early.
62
81
  if (contentHeader === '0') {
63
- return _bluebird.default.reject(new Error(`Failed to fetch image as no content length: ${encodedUrl}`));
82
+ return _bluebird.default.reject(new Error(`Failed to fetch image as no content length: ${url}`));
64
83
  }
65
84
  if (!response.ok) {
66
- return _bluebird.default.reject(new Error(`Failed to fetch image: ${encodedUrl}`));
85
+ return _bluebird.default.reject(new Error(`Failed to fetch image: ${url}`));
67
86
  }
68
87
  const imageType = contentTypes[contentType];
69
88
  return response.arrayBuffer().then(buffer => ({
@@ -85,10 +104,20 @@ function fetchImage(url, options = {}) {
85
104
  }).catch(error => {
86
105
  if (isHeader) {
87
106
  // NOTE: Replace failed headers with LH logo
88
- console.error('FetchImageHeaderError', error);
107
+ console.error('FetchImageHeaderError', {
108
+ url,
109
+ message: error.message,
110
+ context,
111
+ stack: error.stack
112
+ });
89
113
  return fetchImage(_constants.LIGHTHOUSE_LOGO_URL, defaultOptions);
90
114
  }
91
- console.error(error);
115
+ console.error('FetchImageError', {
116
+ url,
117
+ message: error.message,
118
+ context,
119
+ stack: error.stack
120
+ });
92
121
  return _images.imageNotFound;
93
122
  });
94
123
  }
@@ -48,6 +48,7 @@ const fetchImageForPdfGeneratorService = async function (url) {
48
48
  }
49
49
  const transformerResponse = await requestImageTransformation(`/${path}`, searchParamsObject);
50
50
  const statusCode = transformerResponse.statusCode;
51
+ const redirectLocation = transformerResponse.headers?.Location;
51
52
  switch (statusCode) {
52
53
  case 200:
53
54
  {
@@ -60,21 +61,24 @@ const fetchImageForPdfGeneratorService = async function (url) {
60
61
  }
61
62
  case 302:
62
63
  {
63
- console.debug('Image transformation successful but image is too big for lambda delivery, fetching directly from S3');
64
- const redirectLocation = transformerResponse.headers.Location;
64
+ console.debug('Image transformation successful but image is too big for lambda delivery, fetching directly via redirect URL');
65
65
  if (!redirectLocation) {
66
66
  throw new Error('Redirect response received but no location provided');
67
67
  }
68
- const newlyTransformedImage = await fetchResourceFromS3({
69
- bucketName: process.env.S3_BUCKET_IMAGE_TRANSFORMER_CACHE,
70
- key: transformedBucketImagePath
71
- });
72
- console.debug('Image successfully fetched from S3 at:', redirectLocation);
73
- const fullDataUrl = formatBase64Image({
74
- base64String: newlyTransformedImage.body.toString('base64'),
68
+ let response;
69
+ try {
70
+ response = await fetch(redirectLocation);
71
+ } catch (error) {
72
+ throw new Error(`Failed to fetch image from redirect URL: ${error.message}`);
73
+ }
74
+ if (!response.ok) {
75
+ throw new Error(`Failed to fetch image from redirect: ${response.status}`);
76
+ }
77
+ const buffer = Buffer.from(await response.arrayBuffer());
78
+ return formatBase64Image({
79
+ base64String: buffer.toString('base64'),
75
80
  key: transformedBucketImagePath
76
81
  });
77
- return fullDataUrl;
78
82
  }
79
83
  case 400:
80
84
  throw new Error(`Bad request to image transformer: ${transformerResponse.body}`);
@@ -6,13 +6,34 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.fetchImageForWeb = void 0;
7
7
  var _images = require("../../images");
8
8
  var _fetchLighthouseLogo = require("../fetch-lighthouse-logo");
9
+ var _index = require("../validate-url/index.js");
9
10
  const fetchImageForWeb = async function (url, options) {
10
11
  const {
11
12
  isHeader = false,
12
13
  Signature,
13
14
  Policy,
14
- KeyPairId
15
+ KeyPairId,
16
+ context = {}
15
17
  } = options;
18
+
19
+ // Validate url parameter
20
+ if (!url || typeof url !== 'string') {
21
+ const error = new Error(`fetchImageForWeb: Invalid url parameter. url=${JSON.stringify(url)}`);
22
+ if (isHeader) {
23
+ console.error('FetchImageHeaderError', {
24
+ message: error.message,
25
+ url,
26
+ context
27
+ });
28
+ return (0, _fetchLighthouseLogo.fetchLighthouseLogo)();
29
+ }
30
+ console.error('FetchImageError', {
31
+ message: error.message,
32
+ url,
33
+ context
34
+ });
35
+ return _images.imageNotFound;
36
+ }
16
37
  try {
17
38
  const firstParamConnector = url.indexOf('?') > -1 ? '&' : '?';
18
39
  const hasSignatureParams = url.includes('Signature=') && url.includes('Policy=') && url.includes('Key-Pair-Id=');
@@ -21,19 +42,29 @@ const fetchImageForWeb = async function (url, options) {
21
42
  const imageResponse = await fetch(constructedUrl);
22
43
  const contentLengthHeader = imageResponse.headers.get('content-length');
23
44
  if (contentLengthHeader === '0') {
24
- return Promise.reject(new Error(`Failed to fetch image as no content length: ${encodedUrl}`));
45
+ return Promise.reject(new Error(`Failed to fetch image as no content length: ${url}`));
25
46
  }
26
47
  if (!imageResponse.ok) {
27
- return Promise.reject(new Error(`Failed to fetch image: ${encodedUrl}`));
48
+ return Promise.reject(new Error(`Failed to fetch image: ${url}`));
28
49
  }
29
50
  return await imageResponse.arrayBuffer();
30
51
  } catch (error) {
31
52
  if (isHeader) {
32
53
  // NOTE: Replace failed headers with LH logo
33
- console.error('FetchImageHeaderError', error);
54
+ console.error('FetchImageHeaderError', {
55
+ url,
56
+ message: error.message,
57
+ context,
58
+ stack: error.stack
59
+ });
34
60
  return (0, _fetchLighthouseLogo.fetchLighthouseLogo)();
35
61
  }
36
- console.error(error);
62
+ console.error('FetchImageError', {
63
+ url,
64
+ message: error.message,
65
+ context,
66
+ stack: error.stack
67
+ });
37
68
  return _images.imageNotFound;
38
69
  }
39
70
  };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isAbsoluteUrl = isAbsoluteUrl;
7
+ /**
8
+ * Checks if a URL is absolute (starts with http:// or https://)
9
+ * @param {string} url - The URL to validate
10
+ * @returns {boolean} - True if URL is absolute, false otherwise
11
+ */
12
+ function isAbsoluteUrl(url) {
13
+ if (!url || typeof url !== 'string') return false;
14
+ return url.startsWith('http://') || url.startsWith('https://');
15
+ }
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.defaultHeader = defaultHeader;
7
7
  var _helpers = require("../../../helpers");
8
+ var _constants = require("../../../constants");
9
+ var _index = require("../../../helpers/validate-url/index.js");
8
10
  function defaultHeader({
9
11
  Signature,
10
12
  Policy,
@@ -19,7 +21,15 @@ function defaultHeader({
19
21
  timestamp,
20
22
  timezone
21
23
  });
22
- return (0, _helpers.fetchImage)(logoUrl, {
24
+
25
+ // Validate logoUrl and use fallback if invalid
26
+ const effectiveLogoUrl = (0, _index.isAbsoluteUrl)(logoUrl) ? logoUrl : _constants.LIGHTHOUSE_LOGO_URL;
27
+ if (!(0, _index.isAbsoluteUrl)(logoUrl)) {
28
+ console.warn('defaultHeader: Invalid logoUrl, using Lighthouse logo', {
29
+ providedLogoUrl: logoUrl
30
+ });
31
+ }
32
+ return (0, _helpers.fetchImage)(effectiveLogoUrl, {
23
33
  Signature,
24
34
  Policy,
25
35
  KeyPairId,
@@ -41,7 +41,9 @@ function buildImage(options) {
41
41
  height = 210,
42
42
  settings = {},
43
43
  signedAsset,
44
- width = 210
44
+ width = 210,
45
+ fieldLabel,
46
+ fieldType = 'image'
45
47
  } = options;
46
48
  const {
47
49
  awsS3BaseUrl,
@@ -71,7 +73,15 @@ function buildImage(options) {
71
73
  });
72
74
 
73
75
  // NOTE: shouldUseCloudfront, Signature, Policy and KeyPairId from settings are used in this context
74
- return (0, _helpers.fetchImage)(url, settings).then(base64String => ({
76
+ return (0, _helpers.fetchImage)(url, {
77
+ ...settings,
78
+ context: {
79
+ stage: 'field',
80
+ fieldLabel,
81
+ fieldType,
82
+ filepath
83
+ }
84
+ }).then(base64String => ({
75
85
  alignment,
76
86
  fit: [width, height],
77
87
  image: base64String,
@@ -121,7 +131,14 @@ function buildSummaryField({
121
131
  };
122
132
  }
123
133
  // NOTE: shouldUseCloudfront, Signature, Policy and KeyPairId from settings are used in this context
124
- return (0, _helpers.fetchImage)(value, settings).then(base64String => {
134
+ return (0, _helpers.fetchImage)(value, {
135
+ ...settings,
136
+ context: {
137
+ stage: 'field',
138
+ fieldLabel: field.label,
139
+ fieldType: 'signature'
140
+ }
141
+ }).then(base64String => {
125
142
  return {
126
143
  alignment: 'left',
127
144
  image: base64String,
@@ -145,7 +162,9 @@ function buildSummaryField({
145
162
  height: 140,
146
163
  width: 140,
147
164
  settings,
148
- signedAsset: signedAssets && (0, _lodash.isArray)(signedAssets) ? signedAssets[0] : null
165
+ signedAsset: signedAssets && (0, _lodash.isArray)(signedAssets) ? signedAssets[0] : null,
166
+ fieldLabel: field.label,
167
+ fieldType: 'media'
149
168
  });
150
169
  return image;
151
170
  }
@@ -244,7 +263,14 @@ function buildTemplateFieldRow({
244
263
  if (isSignatureField) {
245
264
  if (!value) return [labelText, ''];
246
265
  // NOTE: shouldUseCloudfront, Signature, Policy and KeyPairId from settings are used in this context
247
- return (0, _helpers.fetchImage)(value, settings).then(base64String => {
266
+ return (0, _helpers.fetchImage)(value, {
267
+ ...settings,
268
+ context: {
269
+ stage: 'field',
270
+ fieldLabel: label,
271
+ fieldType: 'signature'
272
+ }
273
+ }).then(base64String => {
248
274
  const values = {
249
275
  alignment: 'left',
250
276
  image: base64String,
@@ -254,22 +280,39 @@ function buildTemplateFieldRow({
254
280
  });
255
281
  }
256
282
  if (isDisplayImageField) {
257
- return _bluebird.default.map([value], (filepath, index) => {
283
+ // Guard against nullish values
284
+ if (!value) {
285
+ return [[], {}];
286
+ }
287
+
288
+ // Ensure value is always treated as an array of filepaths
289
+ const filepaths = (0, _lodash.isArray)(value) ? value : [value];
290
+ return _bluebird.default.map(filepaths, (filepath, index) => {
258
291
  const signedAssetValue = (0, _lodash.isArray)(signedAssets) ? signedAssets[index] : signedAssets;
259
292
  return buildImage({
260
293
  filepath,
261
294
  settings,
262
- signedAsset: signedAssetValue
295
+ signedAsset: signedAssetValue,
296
+ fieldLabel: label,
297
+ fieldType: 'image-display'
263
298
  });
264
299
  }).then(fieldImages => [fieldImages, {}]);
265
300
  }
266
301
  if (isPhotoField) {
302
+ // Guard against nullish values
303
+ if (!value || (0, _lodash.isArray)(value) && value.length === 0) {
304
+ return [labelText, {
305
+ text: ''
306
+ }];
307
+ }
267
308
  return _bluebird.default.map(value, (filepath, index) => {
268
309
  const signedAssetValue = (0, _lodash.isArray)(signedAssets) ? signedAssets[index] : signedAssets;
269
310
  return buildImage({
270
311
  filepath,
271
312
  settings,
272
- signedAsset: signedAssetValue
313
+ signedAsset: signedAssetValue,
314
+ fieldLabel: label,
315
+ fieldType: 'media'
273
316
  });
274
317
  }).then(fieldImages => {
275
318
  const tables = !(0, _lodash.isEmpty)(fieldImages) ? (0, _.imageTables)(fieldImages) : [];
@@ -52,8 +52,16 @@ function generateDefinition(options) {
52
52
  pageOrientation,
53
53
  pageSize,
54
54
  styles: pdfStyles
55
- })).catch(err => {
56
- throw new Error(`GenerateDefinitionError: ${err.message}`);
55
+ })).catch(error => {
56
+ // Preserve structured error information for better debugging
57
+ console.error('GenerateDefinitionError', {
58
+ message: error.message,
59
+ context: error.context,
60
+ url: error.url,
61
+ type: options.type,
62
+ stack: error.stack
63
+ });
64
+ throw error; // Preserve original error instead of wrapping
57
65
  });
58
66
  }
59
67
  function pdfHeader(header) {
@@ -0,0 +1,27 @@
1
+ import _createClass from "@babel/runtime/helpers/createClass";
2
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
+ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
4
+ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
5
+ import _inherits from "@babel/runtime/helpers/inherits";
6
+ import _wrapNativeSuper from "@babel/runtime/helpers/wrapNativeSuper";
7
+ function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
8
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
9
+ /**
10
+ * Custom error class for image fetching operations
11
+ * Includes context information for better debugging
12
+ */
13
+ export var FetchImageError = /*#__PURE__*/function (_Error) {
14
+ function FetchImageError(message) {
15
+ var _this;
16
+ var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
17
+ _classCallCheck(this, FetchImageError);
18
+ _this = _callSuper(this, FetchImageError, [message]);
19
+ _this.name = 'FetchImageError';
20
+ _this.context = context;
21
+ _this.url = context.url;
22
+ return _this;
23
+ }
24
+ _inherits(FetchImageError, _Error);
25
+ return _createClass(FetchImageError);
26
+ }(/*#__PURE__*/_wrapNativeSuper(Error));
27
+ //# sourceMappingURL=FetchImageError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FetchImageError.js","names":["FetchImageError","_Error","message","_this","context","arguments","length","undefined","_classCallCheck","_callSuper","name","url","_inherits","_createClass","_wrapNativeSuper","Error"],"sources":["../../src/errors/FetchImageError.js"],"sourcesContent":["/**\n * Custom error class for image fetching operations\n * Includes context information for better debugging\n */\nexport class FetchImageError extends Error {\n constructor(message, context = {}) {\n super(message)\n this.name = 'FetchImageError'\n this.context = context\n this.url = context.url\n }\n}\n"],"mappings":";;;;;;;;AAAA;AACA;AACA;AACA;AACA,WAAaA,eAAe,0BAAAC,MAAA;EAC1B,SAAAD,gBAAYE,OAAO,EAAgB;IAAA,IAAAC,KAAA;IAAA,IAAdC,OAAO,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;IAAAG,eAAA,OAAAR,eAAA;IAC/BG,KAAA,GAAAM,UAAA,OAAAT,eAAA,GAAME,OAAO;IACbC,KAAA,CAAKO,IAAI,GAAG,iBAAiB;IAC7BP,KAAA,CAAKC,OAAO,GAAGA,OAAO;IACtBD,KAAA,CAAKQ,GAAG,GAAGP,OAAO,CAACO,GAAG;IAAA,OAAAR,KAAA;EACxB;EAACS,SAAA,CAAAZ,eAAA,EAAAC,MAAA;EAAA,OAAAY,YAAA,CAAAb,eAAA;AAAA,eAAAc,gBAAA,CANkCC,KAAK","ignoreList":[]}
@@ -1,6 +1,11 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  import _typeof from "@babel/runtime/helpers/typeof";
3
+ import { isAbsoluteUrl } from '../validate-url/index.js';
3
4
  export function buildFetchUrl(url, options) {
5
+ // Validate url parameter
6
+ if (!url || typeof url !== 'string') {
7
+ throw new Error("buildFetchUrl: Invalid url parameter. url=".concat(JSON.stringify(url)));
8
+ }
4
9
  var awsS3BaseUrl = options.awsS3BaseUrl,
5
10
  _options$cloudfrontBa = options.cloudfrontBaseUrl,
6
11
  cloudfrontBaseUrl = _options$cloudfrontBa === void 0 ? '' : _options$cloudfrontBa,
@@ -14,6 +19,10 @@ export function buildFetchUrl(url, options) {
14
19
  KeyPairId = options.KeyPairId,
15
20
  Signature = options.Signature;
16
21
  if (shouldUseCloudfront) {
22
+ // Validate cloudfrontBaseUrl when using CloudFront
23
+ if (!cloudfrontBaseUrl) {
24
+ throw new Error("buildFetchUrl: cloudfrontBaseUrl is required when shouldUseCloudfront=true. cloudfrontBaseUrl=".concat(JSON.stringify(cloudfrontBaseUrl)));
25
+ }
17
26
  var isWebContext = shouldUseCloudfront && (typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object';
18
27
  var paramMap = {
19
28
  width: width,
@@ -37,7 +46,18 @@ export function buildFetchUrl(url, options) {
37
46
  return "".concat(key, "=").concat(String(value));
38
47
  });
39
48
  var paramsString = params.join('&');
40
- return "".concat(cloudfrontBaseUrl, "/").concat(url, "?").concat(paramsString);
49
+ var result = "".concat(cloudfrontBaseUrl, "/").concat(url, "?").concat(paramsString);
50
+
51
+ // Validate output is absolute URL
52
+ if (!isAbsoluteUrl(result)) {
53
+ throw new Error("buildFetchUrl: Constructed URL is not absolute. cloudfrontBaseUrl=".concat(JSON.stringify(cloudfrontBaseUrl), ", url=").concat(JSON.stringify(url), ", result=").concat(JSON.stringify(result)));
54
+ }
55
+ return result;
56
+ }
57
+
58
+ // Validate required base URLs for Cloudinary path
59
+ if (!cloudinaryBaseUrl || !awsS3BaseUrl) {
60
+ throw new Error("buildFetchUrl: cloudinaryBaseUrl and awsS3BaseUrl are required. cloudinaryBaseUrl=".concat(JSON.stringify(cloudinaryBaseUrl), ", awsS3BaseUrl=").concat(JSON.stringify(awsS3BaseUrl)));
41
61
  }
42
62
  var transformations = [];
43
63
  var transformationsString = '';
@@ -47,6 +67,11 @@ export function buildFetchUrl(url, options) {
47
67
  if (fit) transformations.push('c_fit');
48
68
  transformationsString = "".concat(transformations.join(','), "/");
49
69
  var fetchUrl = "".concat(cloudinaryBaseUrl, "/").concat(transformationsString).concat(awsS3BaseUrl, "/").concat(url);
70
+
71
+ // Validate output is absolute URL
72
+ if (!isAbsoluteUrl(fetchUrl)) {
73
+ throw new Error("buildFetchUrl: Constructed URL is not absolute. cloudinaryBaseUrl=".concat(JSON.stringify(cloudinaryBaseUrl), ", awsS3BaseUrl=").concat(JSON.stringify(awsS3BaseUrl), ", url=").concat(JSON.stringify(url), ", result=").concat(JSON.stringify(fetchUrl)));
74
+ }
50
75
  return fetchUrl;
51
76
  }
52
77
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["buildFetchUrl","url","options","awsS3BaseUrl","_options$cloudfrontBa","cloudfrontBaseUrl","cloudinaryBaseUrl","fit","height","width","quality","shouldUseCloudfront","Policy","KeyPairId","Signature","isWebContext","window","_typeof","paramMap","params","Object","entries","filter","_ref","_ref2","_slicedToArray","value","map","_ref3","_ref4","key","concat","String","paramsString","join","transformations","transformationsString","push","toString","fetchUrl"],"sources":["../../../src/helpers/build-fetch-url/index.js"],"sourcesContent":["export function buildFetchUrl(url, options) {\n const {\n awsS3BaseUrl,\n cloudfrontBaseUrl = '',\n cloudinaryBaseUrl,\n fit,\n height,\n width,\n quality,\n shouldUseCloudfront,\n Policy,\n KeyPairId,\n Signature,\n } = options\n\n if (shouldUseCloudfront) {\n const isWebContext = shouldUseCloudfront && typeof window === 'object'\n\n const paramMap = {\n width,\n height,\n quality,\n fit: 'contain',\n }\n\n if (isWebContext) {\n paramMap.Policy = Policy\n paramMap['Key-Pair-Id'] = KeyPairId\n paramMap.Signature = Signature\n }\n const params = Object.entries(paramMap)\n .filter(([, value]) => value != null)\n .map(([key, value]) => `${key}=${String(value)}`)\n\n const paramsString = params.join('&')\n return `${cloudfrontBaseUrl}/${url}?${paramsString}`\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"],"mappings":";;AAAA,OAAO,SAASA,aAAaA,CAACC,GAAG,EAAEC,OAAO,EAAE;EAC1C,IACEC,YAAY,GAWVD,OAAO,CAXTC,YAAY;IAAAC,qBAAA,GAWVF,OAAO,CAVTG,iBAAiB;IAAjBA,iBAAiB,GAAAD,qBAAA,cAAG,EAAE,GAAAA,qBAAA;IACtBE,iBAAiB,GASfJ,OAAO,CATTI,iBAAiB;IACjBC,GAAG,GAQDL,OAAO,CARTK,GAAG;IACHC,MAAM,GAOJN,OAAO,CAPTM,MAAM;IACNC,KAAK,GAMHP,OAAO,CANTO,KAAK;IACLC,OAAO,GAKLR,OAAO,CALTQ,OAAO;IACPC,mBAAmB,GAIjBT,OAAO,CAJTS,mBAAmB;IACnBC,MAAM,GAGJV,OAAO,CAHTU,MAAM;IACNC,SAAS,GAEPX,OAAO,CAFTW,SAAS;IACTC,SAAS,GACPZ,OAAO,CADTY,SAAS;EAGX,IAAIH,mBAAmB,EAAE;IACvB,IAAMI,YAAY,GAAGJ,mBAAmB,IAAI,QAAOK,MAAM,iCAAAC,OAAA,CAAND,MAAM,OAAK,QAAQ;IAEtE,IAAME,QAAQ,GAAG;MACfT,KAAK,EAALA,KAAK;MACLD,MAAM,EAANA,MAAM;MACNE,OAAO,EAAPA,OAAO;MACPH,GAAG,EAAE;IACP,CAAC;IAED,IAAIQ,YAAY,EAAE;MAChBG,QAAQ,CAACN,MAAM,GAAGA,MAAM;MACxBM,QAAQ,CAAC,aAAa,CAAC,GAAGL,SAAS;MACnCK,QAAQ,CAACJ,SAAS,GAAGA,SAAS;IAChC;IACA,IAAMK,MAAM,GAAGC,MAAM,CAACC,OAAO,CAACH,QAAQ,CAAC,CACpCI,MAAM,CAAC,UAAAC,IAAA;MAAA,IAAAC,KAAA,GAAAC,cAAA,CAAAF,IAAA;QAAIG,KAAK,GAAAF,KAAA;MAAA,OAAME,KAAK,IAAI,IAAI;IAAA,EAAC,CACpCC,GAAG,CAAC,UAAAC,KAAA;MAAA,IAAAC,KAAA,GAAAJ,cAAA,CAAAG,KAAA;QAAEE,GAAG,GAAAD,KAAA;QAAEH,KAAK,GAAAG,KAAA;MAAA,UAAAE,MAAA,CAASD,GAAG,OAAAC,MAAA,CAAIC,MAAM,CAACN,KAAK,CAAC;IAAA,CAAE,CAAC;IAEnD,IAAMO,YAAY,GAAGd,MAAM,CAACe,IAAI,CAAC,GAAG,CAAC;IACrC,UAAAH,MAAA,CAAU1B,iBAAiB,OAAA0B,MAAA,CAAI9B,GAAG,OAAA8B,MAAA,CAAIE,YAAY;EACpD;EAEA,IAAME,eAAe,GAAG,EAAE;EAC1B,IAAIC,qBAAqB,GAAG,EAAE;EAE9B,IAAI3B,KAAK,EAAE0B,eAAe,CAACE,IAAI,MAAAN,MAAA,CAAMtB,KAAK,CAAC6B,QAAQ,CAAC,CAAC,CAAE,CAAC;EACxD,IAAI9B,MAAM,EAAE2B,eAAe,CAACE,IAAI,MAAAN,MAAA,CAAMvB,MAAM,CAAC8B,QAAQ,CAAC,CAAC,CAAE,CAAC;EAC1D,IAAI5B,OAAO,EAAEyB,eAAe,CAACE,IAAI,MAAAN,MAAA,CAAMrB,OAAO,CAAC4B,QAAQ,CAAC,CAAC,CAAE,CAAC;EAC5D,IAAI/B,GAAG,EAAE4B,eAAe,CAACE,IAAI,CAAC,OAAO,CAAC;EAEtCD,qBAAqB,MAAAL,MAAA,CAAMI,eAAe,CAACD,IAAI,CAAC,GAAG,CAAC,MAAG;EAEvD,IAAMK,QAAQ,MAAAR,MAAA,CAAMzB,iBAAiB,OAAAyB,MAAA,CAAIK,qBAAqB,EAAAL,MAAA,CAAG5B,YAAY,OAAA4B,MAAA,CAAI9B,GAAG,CAAE;EAEtF,OAAOsC,QAAQ;AACjB","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["isAbsoluteUrl","buildFetchUrl","url","options","Error","concat","JSON","stringify","awsS3BaseUrl","_options$cloudfrontBa","cloudfrontBaseUrl","cloudinaryBaseUrl","fit","height","width","quality","shouldUseCloudfront","Policy","KeyPairId","Signature","isWebContext","window","_typeof","paramMap","params","Object","entries","filter","_ref","_ref2","_slicedToArray","value","map","_ref3","_ref4","key","String","paramsString","join","result","transformations","transformationsString","push","toString","fetchUrl"],"sources":["../../../src/helpers/build-fetch-url/index.js"],"sourcesContent":["import { isAbsoluteUrl } from '../validate-url/index.js'\n\nexport function buildFetchUrl(url, options) {\n // Validate url parameter\n if (!url || typeof url !== 'string') {\n throw new Error(\n `buildFetchUrl: Invalid url parameter. url=${JSON.stringify(url)}`\n )\n }\n\n const {\n awsS3BaseUrl,\n cloudfrontBaseUrl = '',\n cloudinaryBaseUrl,\n fit,\n height,\n width,\n quality,\n shouldUseCloudfront,\n Policy,\n KeyPairId,\n Signature,\n } = options\n\n if (shouldUseCloudfront) {\n // Validate cloudfrontBaseUrl when using CloudFront\n if (!cloudfrontBaseUrl) {\n throw new Error(\n `buildFetchUrl: cloudfrontBaseUrl is required when shouldUseCloudfront=true. cloudfrontBaseUrl=${JSON.stringify(cloudfrontBaseUrl)}`\n )\n }\n const isWebContext = shouldUseCloudfront && typeof window === 'object'\n\n const paramMap = {\n width,\n height,\n quality,\n fit: 'contain',\n }\n\n if (isWebContext) {\n paramMap.Policy = Policy\n paramMap['Key-Pair-Id'] = KeyPairId\n paramMap.Signature = Signature\n }\n const params = Object.entries(paramMap)\n .filter(([, value]) => value != null)\n .map(([key, value]) => `${key}=${String(value)}`)\n\n const paramsString = params.join('&')\n const result = `${cloudfrontBaseUrl}/${url}?${paramsString}`\n\n // Validate output is absolute URL\n if (!isAbsoluteUrl(result)) {\n throw new Error(\n `buildFetchUrl: Constructed URL is not absolute. cloudfrontBaseUrl=${JSON.stringify(cloudfrontBaseUrl)}, url=${JSON.stringify(url)}, result=${JSON.stringify(result)}`\n )\n }\n\n return result\n }\n\n // Validate required base URLs for Cloudinary path\n if (!cloudinaryBaseUrl || !awsS3BaseUrl) {\n throw new Error(\n `buildFetchUrl: cloudinaryBaseUrl and awsS3BaseUrl are required. cloudinaryBaseUrl=${JSON.stringify(cloudinaryBaseUrl)}, awsS3BaseUrl=${JSON.stringify(awsS3BaseUrl)}`\n )\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 // Validate output is absolute URL\n if (!isAbsoluteUrl(fetchUrl)) {\n throw new Error(\n `buildFetchUrl: Constructed URL is not absolute. cloudinaryBaseUrl=${JSON.stringify(cloudinaryBaseUrl)}, awsS3BaseUrl=${JSON.stringify(awsS3BaseUrl)}, url=${JSON.stringify(url)}, result=${JSON.stringify(fetchUrl)}`\n )\n }\n\n return fetchUrl\n}\n"],"mappings":"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","ignoreList":[]}
@@ -8,6 +8,7 @@ import { LIGHTHOUSE_LOGO_URL } from '../../constants';
8
8
  import { imageNotFound } from '../../images';
9
9
  import { fetchImageForPdfGeneratorService } from '../fetch-image-for-pdf-generator-service';
10
10
  import { fetchImageForWeb } from '../fetch-image-for-web';
11
+ import { isAbsoluteUrl } from '../validate-url/index.js';
11
12
 
12
13
  // NOTE use the native fetch if it's available in the browser, because the
13
14
  // ponyfill (which actually uses the github polyfill) does not support all the
@@ -31,7 +32,30 @@ var defaultOptions = {
31
32
  };
32
33
  export function fetchImage(url) {
33
34
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
34
- var shouldUseCloudfront = options.shouldUseCloudfront;
35
+ var shouldUseCloudfront = options.shouldUseCloudfront,
36
+ _options$isHeader = options.isHeader,
37
+ isHeader = _options$isHeader === void 0 ? false : _options$isHeader,
38
+ _options$context = options.context,
39
+ context = _options$context === void 0 ? {} : _options$context;
40
+
41
+ // Validate url parameter
42
+ if (!url || typeof url !== 'string') {
43
+ var error = new Error("fetchImage: Invalid url parameter. url=".concat(JSON.stringify(url)));
44
+ if (isHeader) {
45
+ console.error('FetchImageHeaderError', {
46
+ message: error.message,
47
+ url: url,
48
+ context: context
49
+ });
50
+ return fetchImage(LIGHTHOUSE_LOGO_URL, defaultOptions);
51
+ }
52
+ console.error('FetchImageError', {
53
+ message: error.message,
54
+ url: url,
55
+ context: context
56
+ });
57
+ return Promise.resolve(imageNotFound);
58
+ }
35
59
  if (shouldUseCloudfront) {
36
60
  var isWebContext = (typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object';
37
61
  return isWebContext ?
@@ -40,8 +64,6 @@ export function fetchImage(url) {
40
64
  }
41
65
  var encodedUrl = encodeURI(url);
42
66
  var fetchOptions = _objectSpread(_objectSpread({}, defaultOptions), options);
43
- var _options$isHeader = options.isHeader,
44
- isHeader = _options$isHeader === void 0 ? false : _options$isHeader;
45
67
  return fetch(encodedUrl, fetchOptions).then(function (response) {
46
68
  var contentHeader = response.headers.get('content-length');
47
69
  var contentType = response.headers.get('content-type');
@@ -49,10 +71,10 @@ export function fetchImage(url) {
49
71
  // NOTE: the response will be ok but we won't be able to render any
50
72
  // image meaning pdfmake will error. Raise error here and return early.
51
73
  if (contentHeader === '0') {
52
- return Promise.reject(new Error("Failed to fetch image as no content length: ".concat(encodedUrl)));
74
+ return Promise.reject(new Error("Failed to fetch image as no content length: ".concat(url)));
53
75
  }
54
76
  if (!response.ok) {
55
- return Promise.reject(new Error("Failed to fetch image: ".concat(encodedUrl)));
77
+ return Promise.reject(new Error("Failed to fetch image: ".concat(url)));
56
78
  }
57
79
  var imageType = contentTypes[contentType];
58
80
  return response.arrayBuffer().then(function (buffer) {
@@ -75,10 +97,20 @@ export function fetchImage(url) {
75
97
  }).catch(function (error) {
76
98
  if (isHeader) {
77
99
  // NOTE: Replace failed headers with LH logo
78
- console.error('FetchImageHeaderError', error);
100
+ console.error('FetchImageHeaderError', {
101
+ url: url,
102
+ message: error.message,
103
+ context: context,
104
+ stack: error.stack
105
+ });
79
106
  return fetchImage(LIGHTHOUSE_LOGO_URL, defaultOptions);
80
107
  }
81
- console.error(error);
108
+ console.error('FetchImageError', {
109
+ url: url,
110
+ message: error.message,
111
+ context: context,
112
+ stack: error.stack
113
+ });
82
114
  return imageNotFound;
83
115
  });
84
116
  }