@lighthouse/common 6.4.0-canary.5 → 6.5.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.
- package/dist/constants.js +13 -7
- package/dist/errors/DomainError.js +4 -2
- package/dist/errors/ValidationError.js +8 -0
- package/dist/errors/index.js +5 -1
- package/dist/helpers/build-fetch-url/index.js +5 -0
- package/dist/helpers/fetch-image/index.js +32 -16
- package/dist/helpers/fetch-image-for-pdf-generator-service/index.js +44 -22
- package/dist/helpers/fetch-image-for-web/index.js +9 -0
- package/dist/helpers/fetch-lighthouse-logo/index.js +13 -2
- package/dist/helpers/floatify/index.js +1 -0
- package/dist/helpers/get-assignees-full-names/index.js +4 -0
- package/dist/helpers/get-audit-entry-details/index.js +3 -0
- package/dist/helpers/get-audit-items-data/index.js +6 -2
- package/dist/helpers/get-geometry-geocoded-string/index.js +3 -0
- package/dist/helpers/get-issue-details/index.js +9 -0
- package/dist/helpers/get-job-details/index.js +7 -0
- package/dist/helpers/get-location-reference/index.js +21 -18
- package/dist/helpers/get-pretty-duration/index.js +5 -0
- package/dist/helpers/get-reference-details/index.js +4 -0
- package/dist/helpers/get-status-details/index.js +9 -2
- package/dist/helpers/get-task-entry-details/index.js +3 -0
- package/dist/helpers/get-timezone-abbr/index.js +4 -0
- package/dist/helpers/get-timezone-datetime/index.js +5 -0
- package/dist/helpers/get-user-full-name/index.js +1 -0
- package/dist/helpers/get-value-as-percentage/index.js +1 -0
- package/dist/helpers/image-validators/index.js +9 -8
- package/dist/helpers/index.js +33 -16
- package/dist/images/index.js +9 -5
- package/dist/index.js +20 -4
- package/dist/pdf/activity-report/index.js +62 -41
- package/dist/pdf/audit/index.js +14 -0
- package/dist/pdf/helpers/build-audit-content/index.js +15 -4
- package/dist/pdf/helpers/build-audit-follow-ups/index.js +14 -4
- package/dist/pdf/helpers/build-location-scans-content/index.js +17 -4
- package/dist/pdf/helpers/build-template-content/index.js +14 -5
- package/dist/pdf/helpers/default-footer/index.js +3 -2
- package/dist/pdf/helpers/default-header/index.js +2 -0
- package/dist/pdf/helpers/default-styles/index.js +3 -2
- package/dist/pdf/helpers/fields/index.js +51 -21
- package/dist/pdf/helpers/format-location-address/index.js +3 -0
- package/dist/pdf/helpers/generate-definition/index.js +12 -0
- package/dist/pdf/helpers/horizontal-line/index.js +1 -0
- package/dist/pdf/helpers/html-transformer/index.js +23 -11
- package/dist/pdf/helpers/index.js +55 -40
- package/dist/pdf/helpers/parse-value/index.js +6 -2
- package/dist/pdf/helpers/table/index.js +31 -13
- package/dist/pdf/helpers/text/index.js +1 -0
- package/dist/pdf/icons/index.js +5 -3
- package/dist/pdf/index.js +10 -4
- package/dist/pdf/issue/index.js +14 -0
- package/dist/pdf/job/index.js +13 -1
- package/dist/pdf/shift-report/emptyFixtures.js +6 -4
- package/dist/pdf/shift-report/index.js +25 -2
- package/dist/pdf/task/index.js +13 -0
- package/dist/scheduling/generators/index.js +6 -0
- package/dist/scheduling/generators/occurrenceIntervalsGenerator.js +6 -1
- package/dist/scheduling/generators/scheduleIntervalsGenerator.js +5 -0
- package/dist/scheduling/generators/serviceIntervalsGenerator.js +27 -13
- package/dist/scheduling/helpers/convertToTimezone.js +6 -1
- package/dist/scheduling/helpers/generateNonRepeatingSchedule.js +9 -3
- package/dist/scheduling/helpers/generateRepeatingSchedule.js +18 -11
- package/dist/scheduling/helpers/generateScheduleEnd.js +8 -2
- package/dist/scheduling/helpers/hasValidStartAndEnd.js +6 -0
- package/dist/scheduling/helpers/index.js +28 -0
- package/dist/scheduling/helpers/intervalCovers.js +1 -0
- package/dist/scheduling/helpers/intervalIntersectsEnd.js +1 -0
- package/dist/scheduling/helpers/intervalIntersectsStart.js +1 -0
- package/dist/scheduling/helpers/intervalOnlyIntersectsEnd.js +3 -1
- package/dist/scheduling/helpers/intervalOnlyIntersectsStart.js +3 -0
- package/dist/scheduling/helpers/intervalOutside.js +1 -0
- package/dist/scheduling/helpers/intervalWithin.js +1 -0
- package/dist/scheduling/helpers/mergeIntervals.js +4 -0
- package/dist/scheduling/helpers/splitIntervals.js +3 -0
- package/dist/scheduling/index.js +6 -0
- package/dist/scheduling/scheduling.types.js +18 -10
- package/dist/scheduling/strategies/getNext.js +13 -2
- package/dist/scheduling/strategies/getNextExactDateOfMonth.js +12 -0
- package/dist/scheduling/strategies/getNextLastDayOfMonth.js +10 -0
- package/dist/scheduling/strategies/getNextLastWeekdayOfMonth.js +11 -0
- package/dist/scheduling/strategies/getNextNoRepeat.js +7 -0
- package/dist/scheduling/strategies/getNextWeekday.js +10 -0
- package/dist/scheduling/strategies/getNextXDayOfXWeekOfMonth.js +12 -0
- package/dist/scheduling/strategies/index.js +14 -0
- package/dist/schema/index.js +2 -0
- package/dist/schema/schema.js +7 -2
- package/dist/service-hours/__helpers__/calculate-hours.js +13 -4
- package/dist/service-hours/__helpers__/isOpen.js +9 -0
- package/dist/service-hours/index.js +4 -0
- package/dist/service-hours/schema.js +43 -20
- package/lib/constants.js.map +1 -1
- package/lib/errors/DomainError.js +47 -11
- package/lib/errors/DomainError.js.map +1 -1
- package/lib/errors/ValidationError.js +52 -15
- package/lib/errors/ValidationError.js.map +1 -1
- package/lib/errors/index.js.map +1 -1
- package/lib/helpers/build-fetch-url/index.js +20 -14
- package/lib/helpers/build-fetch-url/index.js.map +1 -1
- package/lib/helpers/fetch-image/index.js +27 -20
- package/lib/helpers/fetch-image/index.js.map +1 -1
- package/lib/helpers/fetch-image-for-pdf-generator-service/index.js +242 -201
- package/lib/helpers/fetch-image-for-pdf-generator-service/index.js.map +1 -1
- package/lib/helpers/fetch-image-for-web/index.js +66 -50
- package/lib/helpers/fetch-image-for-web/index.js.map +1 -1
- package/lib/helpers/fetch-lighthouse-logo/index.js +59 -47
- package/lib/helpers/fetch-lighthouse-logo/index.js.map +1 -1
- package/lib/helpers/floatify/index.js.map +1 -1
- package/lib/helpers/get-assignees-full-names/index.js +1 -0
- package/lib/helpers/get-assignees-full-names/index.js.map +1 -1
- package/lib/helpers/get-audit-entry-details/index.js +8 -8
- package/lib/helpers/get-audit-entry-details/index.js.map +1 -1
- package/lib/helpers/get-audit-items-data/index.js +19 -16
- package/lib/helpers/get-audit-items-data/index.js.map +1 -1
- package/lib/helpers/get-geometry-geocoded-string/index.js.map +1 -1
- package/lib/helpers/get-issue-details/index.js +12 -9
- package/lib/helpers/get-issue-details/index.js.map +1 -1
- package/lib/helpers/get-job-details/index.js +12 -12
- package/lib/helpers/get-job-details/index.js.map +1 -1
- package/lib/helpers/get-location-reference/index.js +36 -32
- package/lib/helpers/get-location-reference/index.js.map +1 -1
- package/lib/helpers/get-pretty-duration/index.js +4 -0
- package/lib/helpers/get-pretty-duration/index.js.map +1 -1
- package/lib/helpers/get-reference-details/index.js +3 -1
- package/lib/helpers/get-reference-details/index.js.map +1 -1
- package/lib/helpers/get-status-details/index.js +4 -0
- package/lib/helpers/get-status-details/index.js.map +1 -1
- package/lib/helpers/get-task-entry-details/index.js +5 -5
- package/lib/helpers/get-task-entry-details/index.js.map +1 -1
- package/lib/helpers/get-timezone-abbr/index.js.map +1 -1
- package/lib/helpers/get-timezone-datetime/index.js +6 -6
- package/lib/helpers/get-timezone-datetime/index.js.map +1 -1
- package/lib/helpers/get-user-full-name/index.js.map +1 -1
- package/lib/helpers/get-value-as-percentage/index.js.map +1 -1
- package/lib/helpers/image-validators/index.js +7 -8
- package/lib/helpers/image-validators/index.js.map +1 -1
- package/lib/helpers/index.js.map +1 -1
- package/lib/images/index.js.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/pdf/activity-report/index.js +416 -360
- package/lib/pdf/activity-report/index.js.map +1 -1
- package/lib/pdf/audit/index.js +36 -25
- package/lib/pdf/audit/index.js.map +1 -1
- package/lib/pdf/fonts/index.js.map +1 -1
- package/lib/pdf/helpers/build-audit-content/index.js +5 -3
- package/lib/pdf/helpers/build-audit-content/index.js.map +1 -1
- package/lib/pdf/helpers/build-audit-follow-ups/index.js +12 -5
- package/lib/pdf/helpers/build-audit-follow-ups/index.js.map +1 -1
- package/lib/pdf/helpers/build-location-scans-content/index.js +9 -4
- package/lib/pdf/helpers/build-location-scans-content/index.js.map +1 -1
- package/lib/pdf/helpers/build-template-content/index.js +9 -7
- package/lib/pdf/helpers/build-template-content/index.js.map +1 -1
- package/lib/pdf/helpers/default-footer/index.js +8 -9
- package/lib/pdf/helpers/default-footer/index.js.map +1 -1
- package/lib/pdf/helpers/default-header/index.js +5 -5
- package/lib/pdf/helpers/default-header/index.js.map +1 -1
- package/lib/pdf/helpers/default-styles/index.js.map +1 -1
- package/lib/pdf/helpers/fields/index.js +81 -48
- package/lib/pdf/helpers/fields/index.js.map +1 -1
- package/lib/pdf/helpers/format-location-address/index.js.map +1 -1
- package/lib/pdf/helpers/generate-definition/index.js +29 -22
- package/lib/pdf/helpers/generate-definition/index.js.map +1 -1
- package/lib/pdf/helpers/horizontal-line/index.js +1 -1
- package/lib/pdf/helpers/horizontal-line/index.js.map +1 -1
- package/lib/pdf/helpers/html-transformer/index.js +30 -19
- package/lib/pdf/helpers/html-transformer/index.js.map +1 -1
- package/lib/pdf/helpers/index.js.map +1 -1
- package/lib/pdf/helpers/parse-value/index.js +4 -2
- package/lib/pdf/helpers/parse-value/index.js.map +1 -1
- package/lib/pdf/helpers/table/index.js +84 -78
- package/lib/pdf/helpers/table/index.js.map +1 -1
- package/lib/pdf/helpers/text/index.js +5 -2
- package/lib/pdf/helpers/text/index.js.map +1 -1
- package/lib/pdf/icons/index.js.map +1 -1
- package/lib/pdf/index.js.map +1 -1
- package/lib/pdf/issue/index.js +28 -19
- package/lib/pdf/issue/index.js.map +1 -1
- package/lib/pdf/job/index.js +19 -12
- package/lib/pdf/job/index.js.map +1 -1
- package/lib/pdf/shift-report/emptyFixtures.js.map +1 -1
- package/lib/pdf/shift-report/index.js +374 -308
- package/lib/pdf/shift-report/index.js.map +1 -1
- package/lib/pdf/task/index.js +19 -11
- package/lib/pdf/task/index.js.map +1 -1
- package/lib/scheduling/generators/index.js.map +1 -1
- package/lib/scheduling/generators/occurrenceIntervalsGenerator.js +38 -27
- package/lib/scheduling/generators/occurrenceIntervalsGenerator.js.map +1 -1
- package/lib/scheduling/generators/scheduleIntervalsGenerator.js +30 -19
- package/lib/scheduling/generators/scheduleIntervalsGenerator.js.map +1 -1
- package/lib/scheduling/generators/serviceIntervalsGenerator.js +181 -139
- package/lib/scheduling/generators/serviceIntervalsGenerator.js.map +1 -1
- package/lib/scheduling/helpers/convertToTimezone.js +1 -1
- package/lib/scheduling/helpers/convertToTimezone.js.map +1 -1
- package/lib/scheduling/helpers/generateNonRepeatingSchedule.js +124 -84
- package/lib/scheduling/helpers/generateNonRepeatingSchedule.js.map +1 -1
- package/lib/scheduling/helpers/generateRepeatingSchedule.js +175 -107
- package/lib/scheduling/helpers/generateRepeatingSchedule.js.map +1 -1
- package/lib/scheduling/helpers/generateScheduleEnd.js +6 -6
- package/lib/scheduling/helpers/generateScheduleEnd.js.map +1 -1
- package/lib/scheduling/helpers/hasValidStartAndEnd.js +2 -1
- package/lib/scheduling/helpers/hasValidStartAndEnd.js.map +1 -1
- package/lib/scheduling/helpers/index.js.map +1 -1
- package/lib/scheduling/helpers/intervalCovers.js.map +1 -1
- package/lib/scheduling/helpers/intervalIntersectsEnd.js.map +1 -1
- package/lib/scheduling/helpers/intervalIntersectsStart.js.map +1 -1
- package/lib/scheduling/helpers/intervalOnlyIntersectsEnd.js +0 -1
- package/lib/scheduling/helpers/intervalOnlyIntersectsEnd.js.map +1 -1
- package/lib/scheduling/helpers/intervalOnlyIntersectsStart.js +1 -1
- package/lib/scheduling/helpers/intervalOnlyIntersectsStart.js.map +1 -1
- package/lib/scheduling/helpers/intervalOutside.js.map +1 -1
- package/lib/scheduling/helpers/intervalWithin.js.map +1 -1
- package/lib/scheduling/helpers/mergeIntervals.js +3 -0
- package/lib/scheduling/helpers/mergeIntervals.js.map +1 -1
- package/lib/scheduling/helpers/splitIntervals.js +1 -1
- package/lib/scheduling/helpers/splitIntervals.js.map +1 -1
- package/lib/scheduling/index.js.map +1 -1
- package/lib/scheduling/scheduling.types.js +14 -9
- package/lib/scheduling/scheduling.types.js.map +1 -1
- package/lib/scheduling/strategies/getNext.js +30 -22
- package/lib/scheduling/strategies/getNext.js.map +1 -1
- package/lib/scheduling/strategies/getNextExactDateOfMonth.js +31 -22
- package/lib/scheduling/strategies/getNextExactDateOfMonth.js.map +1 -1
- package/lib/scheduling/strategies/getNextLastDayOfMonth.js +28 -21
- package/lib/scheduling/strategies/getNextLastDayOfMonth.js.map +1 -1
- package/lib/scheduling/strategies/getNextLastWeekdayOfMonth.js +28 -21
- package/lib/scheduling/strategies/getNextLastWeekdayOfMonth.js.map +1 -1
- package/lib/scheduling/strategies/getNextNoRepeat.js +23 -15
- package/lib/scheduling/strategies/getNextNoRepeat.js.map +1 -1
- package/lib/scheduling/strategies/getNextWeekday.js +78 -43
- package/lib/scheduling/strategies/getNextWeekday.js.map +1 -1
- package/lib/scheduling/strategies/getNextXDayOfXWeekOfMonth.js +28 -21
- package/lib/scheduling/strategies/getNextXDayOfXWeekOfMonth.js.map +1 -1
- package/lib/scheduling/strategies/index.js.map +1 -1
- package/lib/schema/index.js.map +1 -1
- package/lib/schema/schema.js +30 -22
- package/lib/schema/schema.js.map +1 -1
- package/lib/service-hours/__helpers__/calculate-hours.js +13 -4
- package/lib/service-hours/__helpers__/calculate-hours.js.map +1 -1
- package/lib/service-hours/__helpers__/isOpen.js +7 -3
- package/lib/service-hours/__helpers__/isOpen.js.map +1 -1
- package/lib/service-hours/index.js.map +1 -1
- package/lib/service-hours/schema.js +36 -21
- package/lib/service-hours/schema.js.map +1 -1
- package/package.json +4 -5
- package/mise.toml +0 -6
package/dist/constants.js
CHANGED
|
@@ -3,11 +3,17 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.LIGHTHOUSE_LOGO_URL = exports.
|
|
6
|
+
exports.LIGHTHOUSE_LOGO_URL = exports.DEFAULT_PAGE_SIZE = exports.DEFAULT_PAGE_ORIENTATION = exports.DEFAULT_PAGE_MARGINS = exports.DEFAULT_SUMMARY_FIELDS_COLUMN_LENGTH = exports.DEFAULT_IMAGE_COLUMN_LENGTH = void 0;
|
|
7
7
|
// pdf
|
|
8
|
-
const DEFAULT_IMAGE_COLUMN_LENGTH =
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
8
|
+
const DEFAULT_IMAGE_COLUMN_LENGTH = 2;
|
|
9
|
+
exports.DEFAULT_IMAGE_COLUMN_LENGTH = DEFAULT_IMAGE_COLUMN_LENGTH;
|
|
10
|
+
const DEFAULT_SUMMARY_FIELDS_COLUMN_LENGTH = 3;
|
|
11
|
+
exports.DEFAULT_SUMMARY_FIELDS_COLUMN_LENGTH = DEFAULT_SUMMARY_FIELDS_COLUMN_LENGTH;
|
|
12
|
+
const DEFAULT_PAGE_MARGINS = [60, 130, 60, 80];
|
|
13
|
+
exports.DEFAULT_PAGE_MARGINS = DEFAULT_PAGE_MARGINS;
|
|
14
|
+
const DEFAULT_PAGE_ORIENTATION = 'portrait';
|
|
15
|
+
exports.DEFAULT_PAGE_ORIENTATION = DEFAULT_PAGE_ORIENTATION;
|
|
16
|
+
const DEFAULT_PAGE_SIZE = 'A4';
|
|
17
|
+
exports.DEFAULT_PAGE_SIZE = DEFAULT_PAGE_SIZE;
|
|
18
|
+
const LIGHTHOUSE_LOGO_URL = 'https://assets-lighthouse-io.s3.amazonaws.com/img/lighthouse-color-logo-2023.png';
|
|
19
|
+
exports.LIGHTHOUSE_LOGO_URL = LIGHTHOUSE_LOGO_URL;
|
|
@@ -4,13 +4,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
+
|
|
7
8
|
// TODO is this universal?
|
|
8
9
|
class DomainError extends Error {
|
|
9
10
|
constructor(message) {
|
|
10
11
|
super(message);
|
|
11
|
-
this.name = this.constructor.name;
|
|
12
|
+
this.name = this.constructor.name; // @ts-ignore support both node and browser environments
|
|
12
13
|
|
|
13
|
-
// @ts-ignore support both node and browser environments
|
|
14
14
|
if (typeof Error.captureStackTrace === 'function') {
|
|
15
15
|
// @ts-ignore
|
|
16
16
|
Error.captureStackTrace(this, this.constructor);
|
|
@@ -18,5 +18,7 @@ class DomainError extends Error {
|
|
|
18
18
|
this.stack = new Error(message).stack;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
|
|
21
22
|
}
|
|
23
|
+
|
|
22
24
|
exports.default = DomainError;
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
4
5
|
Object.defineProperty(exports, "__esModule", {
|
|
5
6
|
value: true
|
|
6
7
|
});
|
|
7
8
|
exports.default = void 0;
|
|
9
|
+
|
|
8
10
|
var _yup = require("yup");
|
|
11
|
+
|
|
9
12
|
var _DomainError = _interopRequireDefault(require("./DomainError"));
|
|
13
|
+
|
|
10
14
|
const DEFAULT_MESSAGE = 'The data you submitted was invalid. Please try again with valid data.';
|
|
15
|
+
|
|
11
16
|
class ValidationError extends _DomainError.default {
|
|
12
17
|
constructor({
|
|
13
18
|
data,
|
|
@@ -26,9 +31,12 @@ class ValidationError extends _DomainError.default {
|
|
|
26
31
|
this.status = 400;
|
|
27
32
|
return;
|
|
28
33
|
}
|
|
34
|
+
|
|
29
35
|
super(message);
|
|
30
36
|
this.data = data;
|
|
31
37
|
this.status = 400;
|
|
32
38
|
}
|
|
39
|
+
|
|
33
40
|
}
|
|
41
|
+
|
|
34
42
|
exports.default = ValidationError;
|
package/dist/errors/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
4
5
|
Object.defineProperty(exports, "__esModule", {
|
|
5
6
|
value: true
|
|
6
7
|
});
|
|
8
|
+
exports.isKnownError = isKnownError;
|
|
7
9
|
Object.defineProperty(exports, "DomainError", {
|
|
8
10
|
enumerable: true,
|
|
9
11
|
get: function () {
|
|
@@ -16,9 +18,11 @@ Object.defineProperty(exports, "ValidationError", {
|
|
|
16
18
|
return _ValidationError.default;
|
|
17
19
|
}
|
|
18
20
|
});
|
|
19
|
-
|
|
21
|
+
|
|
20
22
|
var _DomainError = _interopRequireDefault(require("./DomainError"));
|
|
23
|
+
|
|
21
24
|
var _ValidationError = _interopRequireDefault(require("./ValidationError"));
|
|
25
|
+
|
|
22
26
|
function isKnownError(err) {
|
|
23
27
|
return err instanceof _DomainError.default;
|
|
24
28
|
}
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.buildFetchUrl = buildFetchUrl;
|
|
7
|
+
|
|
7
8
|
function buildFetchUrl(url, options) {
|
|
8
9
|
const {
|
|
9
10
|
awsS3BaseUrl,
|
|
@@ -18,6 +19,7 @@ function buildFetchUrl(url, options) {
|
|
|
18
19
|
KeyPairId,
|
|
19
20
|
Signature
|
|
20
21
|
} = options;
|
|
22
|
+
|
|
21
23
|
if (shouldUseCloudfront) {
|
|
22
24
|
const isWebContext = shouldUseCloudfront && typeof window === 'object';
|
|
23
25
|
const paramMap = {
|
|
@@ -26,15 +28,18 @@ function buildFetchUrl(url, options) {
|
|
|
26
28
|
quality,
|
|
27
29
|
fit: 'contain'
|
|
28
30
|
};
|
|
31
|
+
|
|
29
32
|
if (isWebContext) {
|
|
30
33
|
paramMap.Policy = Policy;
|
|
31
34
|
paramMap['Key-Pair-Id'] = KeyPairId;
|
|
32
35
|
paramMap.Signature = Signature;
|
|
33
36
|
}
|
|
37
|
+
|
|
34
38
|
const params = Object.entries(paramMap).filter(([, value]) => value != null).map(([key, value]) => `${key}=${String(value)}`);
|
|
35
39
|
const paramsString = params.join('&');
|
|
36
40
|
return `${cloudfrontBaseUrl}/${url}?${paramsString}`;
|
|
37
41
|
}
|
|
42
|
+
|
|
38
43
|
const transformations = [];
|
|
39
44
|
let transformationsString = '';
|
|
40
45
|
if (width) transformations.push(`w_${width.toString()}`);
|
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
4
5
|
Object.defineProperty(exports, "__esModule", {
|
|
5
6
|
value: true
|
|
6
7
|
});
|
|
7
|
-
exports.arrayBufferToBase64 = arrayBufferToBase64;
|
|
8
8
|
exports.fetchImage = fetchImage;
|
|
9
|
+
exports.arrayBufferToBase64 = arrayBufferToBase64;
|
|
9
10
|
exports.validateBase64Image = validateBase64Image;
|
|
10
11
|
exports.validateJpegImage = validateJpegImage;
|
|
11
12
|
exports.validatePngImage = validatePngImage;
|
|
13
|
+
|
|
12
14
|
var _abab = require("@lighthouse/abab");
|
|
15
|
+
|
|
13
16
|
var _fetchPonyfill = _interopRequireDefault(require("fetch-ponyfill"));
|
|
17
|
+
|
|
14
18
|
var _bluebird = _interopRequireDefault(require("bluebird"));
|
|
19
|
+
|
|
15
20
|
var _constants = require("../../constants");
|
|
21
|
+
|
|
16
22
|
var _images = require("../../images");
|
|
23
|
+
|
|
17
24
|
var _fetchImageForPdfGeneratorService = require("../fetch-image-for-pdf-generator-service");
|
|
25
|
+
|
|
18
26
|
var _fetchImageForWeb = require("../fetch-image-for-web");
|
|
27
|
+
|
|
19
28
|
// NOTE use the native fetch if it's available in the browser, because the
|
|
20
29
|
// ponyfill (which actually uses the github polyfill) does not support all the
|
|
21
30
|
// same options as native fetch
|
|
@@ -36,19 +45,20 @@ const defaultOptions = {
|
|
|
36
45
|
// sent from the fetch request, causing an error
|
|
37
46
|
cache: 'no-cache'
|
|
38
47
|
};
|
|
48
|
+
|
|
39
49
|
function fetchImage(url, options = {}) {
|
|
40
50
|
const {
|
|
41
51
|
shouldUseCloudfront
|
|
42
52
|
} = options;
|
|
53
|
+
|
|
43
54
|
if (shouldUseCloudfront) {
|
|
44
55
|
const isWebContext = typeof window === 'object';
|
|
45
|
-
return isWebContext ?
|
|
46
|
-
// Values used from options: isHeader, Signature, Policy, KeyPairId
|
|
56
|
+
return isWebContext ? // Values used from options: isHeader, Signature, Policy, KeyPairId
|
|
47
57
|
(0, _fetchImageForWeb.fetchImageForWeb)(url, options) : (0, _fetchImageForPdfGeneratorService.fetchImageForPdfGeneratorService)(url);
|
|
48
58
|
}
|
|
59
|
+
|
|
49
60
|
const encodedUrl = encodeURI(url);
|
|
50
|
-
const fetchOptions = {
|
|
51
|
-
...defaultOptions,
|
|
61
|
+
const fetchOptions = { ...defaultOptions,
|
|
52
62
|
...options
|
|
53
63
|
};
|
|
54
64
|
const {
|
|
@@ -56,16 +66,17 @@ function fetchImage(url, options = {}) {
|
|
|
56
66
|
} = options;
|
|
57
67
|
return fetch(encodedUrl, fetchOptions).then(response => {
|
|
58
68
|
const contentHeader = response.headers.get('content-length');
|
|
59
|
-
const contentType = response.headers.get('content-type');
|
|
60
|
-
|
|
61
|
-
// NOTE: the response will be ok but we won't be able to render any
|
|
69
|
+
const contentType = response.headers.get('content-type'); // NOTE: the response will be ok but we won't be able to render any
|
|
62
70
|
// image meaning pdfmake will error. Raise error here and return early.
|
|
71
|
+
|
|
63
72
|
if (contentHeader === '0') {
|
|
64
73
|
return _bluebird.default.reject(new Error(`Failed to fetch image as no content length: ${encodedUrl}`));
|
|
65
74
|
}
|
|
75
|
+
|
|
66
76
|
if (!response.ok) {
|
|
67
77
|
return _bluebird.default.reject(new Error(`Failed to fetch image: ${encodedUrl}`));
|
|
68
78
|
}
|
|
79
|
+
|
|
69
80
|
const imageType = contentTypes[contentType];
|
|
70
81
|
return response.arrayBuffer().then(buffer => ({
|
|
71
82
|
buffer,
|
|
@@ -79,9 +90,11 @@ function fetchImage(url, options = {}) {
|
|
|
79
90
|
const imageStr = arrayBufferToBase64(buffer);
|
|
80
91
|
const base64 = `${base64Flag}${imageStr}`;
|
|
81
92
|
const isValid = validateBase64Image(base64);
|
|
93
|
+
|
|
82
94
|
if (!isValid) {
|
|
83
95
|
return _bluebird.default.reject(new Error('InvalidImageError'));
|
|
84
96
|
}
|
|
97
|
+
|
|
85
98
|
return base64;
|
|
86
99
|
}).catch(error => {
|
|
87
100
|
if (isHeader) {
|
|
@@ -89,45 +102,48 @@ function fetchImage(url, options = {}) {
|
|
|
89
102
|
console.error('FetchImageHeaderError', error);
|
|
90
103
|
return fetchImage(_constants.LIGHTHOUSE_LOGO_URL, defaultOptions);
|
|
91
104
|
}
|
|
105
|
+
|
|
92
106
|
console.error(error);
|
|
93
107
|
return _images.imageNotFound;
|
|
94
108
|
});
|
|
95
109
|
}
|
|
110
|
+
|
|
96
111
|
function arrayBufferToBase64(buffer) {
|
|
97
112
|
let binary = '';
|
|
98
113
|
const bytes = [].slice.call(new Uint8Array(buffer));
|
|
99
114
|
bytes.forEach(b => binary += String.fromCharCode(b));
|
|
100
115
|
return (0, _abab.btoa)(binary);
|
|
101
116
|
}
|
|
117
|
+
|
|
102
118
|
function validateBase64Image(base64String) {
|
|
103
119
|
const isJpeg = base64String.startsWith('data:image/jpeg;base64,');
|
|
104
120
|
if (isJpeg) return validateJpegImage(base64String);
|
|
105
121
|
const isPng = base64String.startsWith('data:image/png;base64,');
|
|
106
122
|
if (isPng) return validatePngImage(base64String);
|
|
107
123
|
return false;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// See SO for more info: https://stackoverflow.com/a/41635312
|
|
124
|
+
} // See SO for more info: https://stackoverflow.com/a/41635312
|
|
111
125
|
// Fiddle: https://jsfiddle.net/Lnyxuchw/
|
|
126
|
+
|
|
127
|
+
|
|
112
128
|
function validateJpegImage(base64string) {
|
|
113
129
|
const src = base64string;
|
|
114
130
|
const imageData = Uint8Array.from((0, _abab.atob)(src.replace('data:image/jpeg;base64,', '')), c => c.charCodeAt(0));
|
|
115
131
|
const imageCorrupted = imageData[imageData.length - 1] === 217 && imageData[imageData.length - 2] === 255;
|
|
116
132
|
return imageCorrupted;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// See SO for more info: https://stackoverflow.com/a/41635312
|
|
133
|
+
} // See SO for more info: https://stackoverflow.com/a/41635312
|
|
120
134
|
// Fiddle: https://jsfiddle.net/Lnyxuchw/
|
|
135
|
+
|
|
136
|
+
|
|
121
137
|
function validatePngImage(base64string) {
|
|
122
138
|
const src = base64string;
|
|
123
139
|
const imageData = Uint8Array.from((0, _abab.atob)(src.replace('data:image/png;base64,', '')), c => c.charCodeAt(0));
|
|
124
|
-
const sequence = [0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130];
|
|
140
|
+
const sequence = [0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130]; //check last 12 elements of array so they contains needed values
|
|
125
141
|
|
|
126
|
-
//check last 12 elements of array so they contains needed values
|
|
127
142
|
for (let i = 12; i > 0; i--) {
|
|
128
143
|
if (imageData[imageData.length - i] !== sequence[12 - i]) {
|
|
129
144
|
return false;
|
|
130
145
|
}
|
|
131
146
|
}
|
|
147
|
+
|
|
132
148
|
return true;
|
|
133
149
|
}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
4
5
|
Object.defineProperty(exports, "__esModule", {
|
|
5
6
|
value: true
|
|
6
7
|
});
|
|
7
|
-
exports.
|
|
8
|
+
exports.requestImageTransformation = requestImageTransformation;
|
|
8
9
|
exports.fetchResourceFromS3 = fetchResourceFromS3;
|
|
9
10
|
exports.formatBase64Image = formatBase64Image;
|
|
10
|
-
exports.
|
|
11
|
+
exports.fetchImageForPdfGeneratorService = void 0;
|
|
12
|
+
|
|
11
13
|
var _imageValidators = require("../image-validators");
|
|
14
|
+
|
|
12
15
|
var _awsSdk = _interopRequireDefault(require("aws-sdk"));
|
|
16
|
+
|
|
13
17
|
const REGION = process.env.AWS_REGION;
|
|
14
18
|
const lambda = new _awsSdk.default.Lambda({
|
|
15
19
|
region: REGION
|
|
@@ -17,27 +21,32 @@ const lambda = new _awsSdk.default.Lambda({
|
|
|
17
21
|
const s3 = new _awsSdk.default.S3({
|
|
18
22
|
region: REGION
|
|
19
23
|
});
|
|
24
|
+
|
|
20
25
|
const fetchImageForPdfGeneratorService = async function (url) {
|
|
21
26
|
console.debug('Fetching image via CloudFront For Serverless Pdf Generator Service');
|
|
27
|
+
|
|
22
28
|
if (!url) {
|
|
23
29
|
throw new Error('URL is required to fetch image for PDF generator service');
|
|
24
30
|
}
|
|
31
|
+
|
|
25
32
|
const urlMatch = url && url.match(/([a-f0-9]{24})\//);
|
|
26
33
|
const applicationId = urlMatch && urlMatch[1];
|
|
34
|
+
|
|
27
35
|
if (!applicationId) {
|
|
28
36
|
throw new Error('Requestor has insufficient permissions');
|
|
29
37
|
}
|
|
38
|
+
|
|
30
39
|
const {
|
|
31
40
|
path,
|
|
32
41
|
queryString,
|
|
33
42
|
searchParamsObject
|
|
34
43
|
} = parseUrlString(url);
|
|
35
44
|
const transformedBucketImagePath = path + (queryString ? `/${queryString}` : '');
|
|
36
|
-
console.debug('Transformed S3 Image Path:', transformedBucketImagePath);
|
|
37
45
|
const alreadyTransformedImage = await fetchResourceFromS3({
|
|
38
46
|
bucketName: process.env.S3_BUCKET_IMAGE_TRANSFORMER_CACHE,
|
|
39
47
|
key: transformedBucketImagePath
|
|
40
48
|
});
|
|
49
|
+
|
|
41
50
|
if (alreadyTransformedImage?.body) {
|
|
42
51
|
const fullDataUrl = formatBase64Image({
|
|
43
52
|
base64String: alreadyTransformedImage.body.toString('base64'),
|
|
@@ -45,8 +54,10 @@ const fetchImageForPdfGeneratorService = async function (url) {
|
|
|
45
54
|
});
|
|
46
55
|
return fullDataUrl;
|
|
47
56
|
}
|
|
48
|
-
|
|
57
|
+
|
|
58
|
+
const transformerResponse = await requestImageTransformation(`/${path}`, searchParamsObject);
|
|
49
59
|
const statusCode = transformerResponse.statusCode;
|
|
60
|
+
|
|
50
61
|
switch (statusCode) {
|
|
51
62
|
case 200:
|
|
52
63
|
{
|
|
@@ -57,13 +68,16 @@ const fetchImageForPdfGeneratorService = async function (url) {
|
|
|
57
68
|
});
|
|
58
69
|
return fullDataUrl;
|
|
59
70
|
}
|
|
71
|
+
|
|
60
72
|
case 302:
|
|
61
73
|
{
|
|
62
74
|
console.debug('Image transformation successful but image is too big for lambda delivery, fetching directly from S3');
|
|
63
75
|
const redirectLocation = transformerResponse.headers.Location;
|
|
76
|
+
|
|
64
77
|
if (!redirectLocation) {
|
|
65
78
|
throw new Error('Redirect response received but no location provided');
|
|
66
79
|
}
|
|
80
|
+
|
|
67
81
|
const newlyTransformedImage = await fetchResourceFromS3({
|
|
68
82
|
bucketName: process.env.S3_BUCKET_IMAGE_TRANSFORMER_CACHE,
|
|
69
83
|
key: transformedBucketImagePath
|
|
@@ -75,23 +89,31 @@ const fetchImageForPdfGeneratorService = async function (url) {
|
|
|
75
89
|
});
|
|
76
90
|
return fullDataUrl;
|
|
77
91
|
}
|
|
92
|
+
|
|
78
93
|
case 400:
|
|
79
94
|
throw new Error(`Bad request to image transformer: ${transformerResponse.body}`);
|
|
95
|
+
|
|
80
96
|
case 403:
|
|
81
97
|
throw new Error('Requested transformed image is too big');
|
|
98
|
+
|
|
82
99
|
case 404:
|
|
83
100
|
throw new Error('The requested image does not exist');
|
|
101
|
+
|
|
84
102
|
case 500:
|
|
85
103
|
throw new Error(`Image transformation failed: ${transformerResponse.body}`);
|
|
104
|
+
|
|
86
105
|
default:
|
|
87
106
|
throw new Error(`Unexpected response from image transformer: ${statusCode} - ${transformerResponse.body}`);
|
|
88
107
|
}
|
|
89
108
|
};
|
|
109
|
+
|
|
90
110
|
exports.fetchImageForPdfGeneratorService = fetchImageForPdfGeneratorService;
|
|
111
|
+
|
|
91
112
|
async function requestImageTransformation(path, searchParamsObject) {
|
|
92
113
|
if (!path) {
|
|
93
114
|
throw new Error('Image Path is required for image transformation');
|
|
94
115
|
}
|
|
116
|
+
|
|
95
117
|
console.debug('ImageTransformation: Invoking image transformer lambda for path:', {
|
|
96
118
|
path,
|
|
97
119
|
searchParamsObject
|
|
@@ -110,6 +132,7 @@ async function requestImageTransformation(path, searchParamsObject) {
|
|
|
110
132
|
InvocationType: 'RequestResponse',
|
|
111
133
|
Payload: JSON.stringify(lambdaEvent)
|
|
112
134
|
};
|
|
135
|
+
|
|
113
136
|
try {
|
|
114
137
|
const result = await lambda.invoke(params).promise();
|
|
115
138
|
const response = JSON.parse(result.Payload);
|
|
@@ -120,21 +143,25 @@ async function requestImageTransformation(path, searchParamsObject) {
|
|
|
120
143
|
throw new Error(errorMessage);
|
|
121
144
|
}
|
|
122
145
|
}
|
|
146
|
+
|
|
123
147
|
async function fetchResourceFromS3({
|
|
124
148
|
bucketName,
|
|
125
149
|
key
|
|
126
150
|
}) {
|
|
127
151
|
console.debug(`Fetching resource from S3 Bucket: '${bucketName}' at path: '${key}'`);
|
|
152
|
+
|
|
128
153
|
if (!bucketName || !key) {
|
|
129
154
|
throw new Error('bucketName and key are required for S3 resource fetch ' + JSON.stringify({
|
|
130
155
|
bucketName,
|
|
131
156
|
key
|
|
132
157
|
}));
|
|
133
158
|
}
|
|
159
|
+
|
|
134
160
|
const params = {
|
|
135
161
|
Bucket: bucketName,
|
|
136
162
|
Key: key
|
|
137
163
|
};
|
|
164
|
+
|
|
138
165
|
try {
|
|
139
166
|
const result = await s3.getObject(params).promise();
|
|
140
167
|
return {
|
|
@@ -149,9 +176,11 @@ async function fetchResourceFromS3({
|
|
|
149
176
|
console.error('Failed to fetch image:', error);
|
|
150
177
|
throw new Error(`Failed to fetch image: ${bucketName}/${key}`);
|
|
151
178
|
}
|
|
179
|
+
|
|
152
180
|
console.debug('Image not found in transformed bucket, invoking transformer');
|
|
153
181
|
}
|
|
154
182
|
}
|
|
183
|
+
|
|
155
184
|
function formatBase64Image({
|
|
156
185
|
base64String,
|
|
157
186
|
key
|
|
@@ -159,18 +188,19 @@ function formatBase64Image({
|
|
|
159
188
|
if (!key) {
|
|
160
189
|
throw new Error('Key is required for image formatting');
|
|
161
190
|
}
|
|
191
|
+
|
|
162
192
|
const imageType = key.toLowerCase().includes('.png') ? 'png' : 'jpeg';
|
|
163
193
|
const base64Flag = `data:image/${imageType};base64,`;
|
|
164
|
-
const fullDataUrl = `${base64Flag}${base64String}`;
|
|
194
|
+
const fullDataUrl = `${base64Flag}${base64String}`; // Validate the formatted data URL
|
|
165
195
|
|
|
166
|
-
// Validate the formatted data URL
|
|
167
196
|
const isValid = (0, _imageValidators.validateBase64Image)(fullDataUrl);
|
|
197
|
+
|
|
168
198
|
if (!isValid) {
|
|
169
199
|
throw new Error('InvalidImageError');
|
|
170
200
|
}
|
|
201
|
+
|
|
171
202
|
return fullDataUrl;
|
|
172
203
|
}
|
|
173
|
-
|
|
174
204
|
/**
|
|
175
205
|
* Parses a URL-like string into path and query parameters
|
|
176
206
|
* @param {string} urlString - String like "https://example.cloudfront.net/<applicationId>/<path>/filename.jpeg?width=100&height=100"
|
|
@@ -179,29 +209,21 @@ function formatBase64Image({
|
|
|
179
209
|
* parseUrlString("https://example.cloudfront.net/abc123/folder/image.jpeg?width=100&height=100")
|
|
180
210
|
* // Returns: { path: "abc123/folder/image.jpeg", queryString: "width=100,t=456", searchParamsObject: { width: "100", height: "100" } }
|
|
181
211
|
*/
|
|
212
|
+
|
|
213
|
+
|
|
182
214
|
function parseUrlString(urlString) {
|
|
183
215
|
if (!urlString || typeof urlString !== 'string') {
|
|
184
216
|
throw new Error('URL string is required and must be a string');
|
|
185
|
-
}
|
|
186
|
-
const urlSearchParams = URLSearchParams(urlString);
|
|
187
|
-
|
|
188
|
-
// if (!urlString.includes('://')) {
|
|
189
|
-
// urlString = `https://domain.com/${urlString}`
|
|
190
|
-
// }
|
|
217
|
+
} // Extract the path after the domain
|
|
191
218
|
|
|
192
|
-
// Extract the path after the domain
|
|
193
|
-
// const url = new URL(urlString)
|
|
194
219
|
|
|
220
|
+
const url = new URL(urlString);
|
|
195
221
|
let searchParamsObject = {};
|
|
196
|
-
|
|
222
|
+
url.searchParams.forEach((value, key) => {
|
|
197
223
|
searchParamsObject[key] = value;
|
|
198
224
|
});
|
|
199
|
-
let queryString =
|
|
200
|
-
|
|
201
|
-
url: url.pathname.substring(1),
|
|
202
|
-
queryString,
|
|
203
|
-
searchParamsObject
|
|
204
|
-
});
|
|
225
|
+
let queryString = url.searchParams.toString();
|
|
226
|
+
queryString = queryString ? queryString.replace(/&/g, ',') : '';
|
|
205
227
|
return {
|
|
206
228
|
path: url.pathname.substring(1),
|
|
207
229
|
// Remove leading '/'
|
|
@@ -4,8 +4,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.fetchImageForWeb = void 0;
|
|
7
|
+
|
|
7
8
|
var _images = require("../../images");
|
|
9
|
+
|
|
8
10
|
var _fetchLighthouseLogo = require("../fetch-lighthouse-logo");
|
|
11
|
+
|
|
9
12
|
const fetchImageForWeb = async function (url, options) {
|
|
10
13
|
const {
|
|
11
14
|
isHeader = false,
|
|
@@ -13,6 +16,7 @@ const fetchImageForWeb = async function (url, options) {
|
|
|
13
16
|
Policy,
|
|
14
17
|
KeyPairId
|
|
15
18
|
} = options;
|
|
19
|
+
|
|
16
20
|
try {
|
|
17
21
|
const firstParamConnector = url.indexOf('?') > -1 ? '&' : '?';
|
|
18
22
|
const hasSignatureParams = url.includes('Signature=') && url.includes('Policy=') && url.includes('Key-Pair-Id=');
|
|
@@ -20,12 +24,15 @@ const fetchImageForWeb = async function (url, options) {
|
|
|
20
24
|
console.debug('Fetching image via CloudFront For Web');
|
|
21
25
|
const imageResponse = await fetch(constructedUrl);
|
|
22
26
|
const contentLengthHeader = imageResponse.headers.get('content-length');
|
|
27
|
+
|
|
23
28
|
if (contentLengthHeader === '0') {
|
|
24
29
|
return Promise.reject(new Error(`Failed to fetch image as no content length: ${encodedUrl}`));
|
|
25
30
|
}
|
|
31
|
+
|
|
26
32
|
if (!imageResponse.ok) {
|
|
27
33
|
return Promise.reject(new Error(`Failed to fetch image: ${encodedUrl}`));
|
|
28
34
|
}
|
|
35
|
+
|
|
29
36
|
return await imageResponse.arrayBuffer();
|
|
30
37
|
} catch (error) {
|
|
31
38
|
if (isHeader) {
|
|
@@ -33,8 +40,10 @@ const fetchImageForWeb = async function (url, options) {
|
|
|
33
40
|
console.error('FetchImageHeaderError', error);
|
|
34
41
|
return (0, _fetchLighthouseLogo.fetchLighthouseLogo)();
|
|
35
42
|
}
|
|
43
|
+
|
|
36
44
|
console.error(error);
|
|
37
45
|
return _images.imageNotFound;
|
|
38
46
|
}
|
|
39
47
|
};
|
|
48
|
+
|
|
40
49
|
exports.fetchImageForWeb = fetchImageForWeb;
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
4
5
|
Object.defineProperty(exports, "__esModule", {
|
|
5
6
|
value: true
|
|
6
7
|
});
|
|
7
8
|
exports.fetchLighthouseLogo = void 0;
|
|
9
|
+
|
|
8
10
|
var _constants = require("../../constants");
|
|
11
|
+
|
|
9
12
|
var _fetchImage = require("../fetch-image");
|
|
13
|
+
|
|
10
14
|
var _imageValidators = require("../image-validators");
|
|
15
|
+
|
|
11
16
|
var _fetchPonyfill = _interopRequireDefault(require("fetch-ponyfill"));
|
|
17
|
+
|
|
12
18
|
// NOTE use the native fetch if it's available in the browser, because the
|
|
13
19
|
// ponyfill (which actually uses the github polyfill) does not support all the
|
|
14
20
|
// same options as native fetch
|
|
@@ -18,29 +24,34 @@ const fetch = typeof self === 'object' && self.fetch || (0, _fetchPonyfill.defau
|
|
|
18
24
|
const contentTypes = {
|
|
19
25
|
'image/png': 'png',
|
|
20
26
|
'image/jpeg': 'jpeg'
|
|
21
|
-
};
|
|
27
|
+
}; // NOTE: This is not stored where other images are - so it cannot go through CloudFront
|
|
22
28
|
|
|
23
|
-
// NOTE: This is not stored where other images are - so it cannot go through CloudFront
|
|
24
29
|
const fetchLighthouseLogo = async function () {
|
|
25
30
|
const encodedLogoUrl = encodeURI(_constants.LIGHTHOUSE_LOGO_URL);
|
|
26
31
|
const logoResponse = await fetch(encodedLogoUrl);
|
|
27
32
|
const contentLengthHeader = logoResponse.headers.get('content-length');
|
|
28
33
|
const contentType = logoResponse.headers.get('content-type');
|
|
34
|
+
|
|
29
35
|
if (contentLengthHeader === '0') {
|
|
30
36
|
return Promise.reject(new Error(`Failed to fetch image as no content length: ${encodedLogoUrl}`));
|
|
31
37
|
}
|
|
38
|
+
|
|
32
39
|
if (!logoResponse.ok) {
|
|
33
40
|
return Promise.reject(new Error(`Failed to fetch image: ${encodedLogoUrl}`));
|
|
34
41
|
}
|
|
42
|
+
|
|
35
43
|
const imageType = contentTypes[contentType];
|
|
36
44
|
const logoArrayBuffer = await logoResponse.arrayBuffer();
|
|
37
45
|
const base64Flag = `data:image/${imageType};base64,`;
|
|
38
46
|
const imageStr = (0, _fetchImage.arrayBufferToBase64)(logoArrayBuffer);
|
|
39
47
|
const base64 = `${base64Flag}${imageStr}`;
|
|
40
48
|
const isValid = (0, _imageValidators.validateBase64Image)(base64);
|
|
49
|
+
|
|
41
50
|
if (isValid) {
|
|
42
51
|
return base64;
|
|
43
52
|
}
|
|
53
|
+
|
|
44
54
|
return Promise.reject(new Error('InvalidImageError'));
|
|
45
55
|
};
|
|
56
|
+
|
|
46
57
|
exports.fetchLighthouseLogo = fetchLighthouseLogo;
|
|
@@ -4,12 +4,16 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getAssigneesFullNames = getAssigneesFullNames;
|
|
7
|
+
|
|
7
8
|
var _lodash = require("lodash");
|
|
9
|
+
|
|
8
10
|
var _ = require("../");
|
|
11
|
+
|
|
9
12
|
function getAssigneesFullNames(users, assignees) {
|
|
10
13
|
if ((0, _lodash.isEmpty)(assignees)) {
|
|
11
14
|
return 'No users assigned';
|
|
12
15
|
}
|
|
16
|
+
|
|
13
17
|
const fullNames = (0, _lodash.chain)(assignees).map(userId => (0, _.getUserFullName)(users, userId)).compact().join(', ').value();
|
|
14
18
|
return fullNames;
|
|
15
19
|
}
|