@google-psat/report 0.9.0-3 → 0.10.1-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dashboard/components/cookiesWithIssues/index.js +43 -0
- package/dist/dashboard/components/header/index.js +26 -0
- package/dist/dashboard/components/siteMapReport/cookies.js +73 -0
- package/dist/dashboard/components/siteMapReport/index.js +31 -0
- package/dist/dashboard/components/siteMapReport/layout.js +140 -0
- package/dist/dashboard/components/siteMapReport/sidebarData.js +46 -0
- package/dist/dashboard/components/siteMapReport/sitemapCookiesWithIssues.js +9 -0
- package/dist/dashboard/components/siteReport/components/layout.js +145 -0
- package/dist/dashboard/components/siteReport/index.js +33 -0
- package/dist/dashboard/components/siteReport/stateProviders/contentStore/index.js +55 -0
- package/dist/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/blockedCookiesSection.js +82 -0
- package/dist/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/cookiesSection.js +38 -0
- package/dist/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/exemptedCookiesSection.js +63 -0
- package/dist/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/framesSection.js +38 -0
- package/dist/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/index.js +17 -0
- package/dist/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/knownBreakages.js +53 -0
- package/dist/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/landing.js +110 -0
- package/dist/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/index.js +58 -0
- package/dist/dashboard/components/siteReport/tabs/cookies/cookiesListing/index.js +47 -0
- package/dist/dashboard/components/siteReport/tabs/cookies/index.js +56 -0
- package/dist/dashboard/components/siteReport/tabs/index.js +54 -0
- package/dist/dashboard/components/siteReport/tabs/siteCookiesWithIssues/index.js +29 -0
- package/dist/dashboard/components/siteReport/tabs/technologies/index.js +91 -0
- package/dist/dashboard/components/utils/NamePrefixIconSelector.js +67 -0
- package/dist/dashboard/components/utils/extractCookies.js +36 -0
- package/dist/dashboard/components/utils/extractReportData.js +56 -0
- package/dist/dashboard/components/utils/reportDownloader/generateSiteMapReportandDownload.js +44 -0
- package/dist/dashboard/components/utils/reportDownloader/generateSiteReportandDownload.js +52 -0
- package/dist/dashboard/components/utils/reportDownloader/index.js +17 -0
- package/dist/dashboard/components/utils/reportDownloader/utils.js +148 -0
- package/dist/dashboard/components/utils/reshapeCookies.js +102 -0
- package/dist/dashboard/components/utils/tests/data.mock.js +176 -0
- package/dist/dashboard/components/utils/tests/extractCookies.js +84 -0
- package/dist/dashboard/components/utils/tests/extractReportData.js +64 -0
- package/dist/dashboard/components/utils/tests/reshapeCookies.js +89 -0
- package/dist/dashboard/hooks/useCookieListing/index.js +412 -0
- package/dist/dashboard/index.js +19 -0
- package/dist/index.js +16 -0
- package/dist-types/dashboard/components/cookiesWithIssues/index.d.ts +8 -0
- package/dist-types/dashboard/components/header/index.d.ts +6 -0
- package/dist-types/dashboard/components/siteMapReport/cookies.d.ts +15 -0
- package/dist-types/dashboard/components/siteMapReport/index.d.ts +11 -0
- package/dist-types/dashboard/components/siteMapReport/layout.d.ts +18 -0
- package/dist-types/dashboard/components/siteMapReport/sidebarData.d.ts +3 -0
- package/dist-types/dashboard/components/siteMapReport/sitemapCookiesWithIssues.d.ts +10 -0
- package/dist-types/dashboard/components/siteReport/components/layout.d.ts +13 -0
- package/dist-types/dashboard/components/siteReport/index.d.ts +17 -0
- package/dist-types/dashboard/components/siteReport/stateProviders/contentStore/index.d.ts +32 -0
- package/dist-types/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/blockedCookiesSection.d.ts +8 -0
- package/dist-types/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/cookiesSection.d.ts +7 -0
- package/dist-types/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/exemptedCookiesSection.d.ts +7 -0
- package/dist-types/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/framesSection.d.ts +9 -0
- package/dist-types/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/index.d.ts +2 -0
- package/dist-types/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/knownBreakages.d.ts +9 -0
- package/dist-types/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/cookieLanding/landing.d.ts +15 -0
- package/dist-types/dashboard/components/siteReport/tabs/cookies/cookiesLandingContainer/index.d.ts +23 -0
- package/dist-types/dashboard/components/siteReport/tabs/cookies/cookiesListing/index.d.ts +9 -0
- package/dist-types/dashboard/components/siteReport/tabs/cookies/index.d.ts +9 -0
- package/dist-types/dashboard/components/siteReport/tabs/index.d.ts +3 -0
- package/dist-types/dashboard/components/siteReport/tabs/siteCookiesWithIssues/index.d.ts +5 -0
- package/dist-types/dashboard/components/siteReport/tabs/technologies/index.d.ts +5 -0
- package/dist-types/dashboard/components/utils/NamePrefixIconSelector.d.ts +3 -0
- package/dist-types/dashboard/components/utils/extractCookies.d.ts +6 -0
- package/dist-types/dashboard/components/utils/extractReportData.d.ts +11 -0
- package/dist-types/dashboard/components/utils/reportDownloader/generateSiteMapReportandDownload.d.ts +4 -0
- package/dist-types/dashboard/components/utils/reportDownloader/generateSiteReportandDownload.d.ts +4 -0
- package/dist-types/dashboard/components/utils/reportDownloader/index.d.ts +2 -0
- package/dist-types/dashboard/components/utils/reportDownloader/utils.d.ts +9 -0
- package/dist-types/dashboard/components/utils/reshapeCookies.d.ts +8 -0
- package/dist-types/dashboard/components/utils/tests/data.mock.d.ts +6 -0
- package/dist-types/dashboard/components/utils/tests/extractCookies.d.ts +1 -0
- package/dist-types/dashboard/components/utils/tests/extractReportData.d.ts +1 -0
- package/dist-types/dashboard/components/utils/tests/reshapeCookies.d.ts +1 -0
- package/dist-types/dashboard/hooks/useCookieListing/index.d.ts +10 -0
- package/dist-types/dashboard/index.d.ts +4 -0
- package/dist-types/index.d.ts +1 -0
- package/package.json +11 -5
- package/public/index.html +1 -0
- package/tsconfig.json +19 -3
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2023 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* External dependencies
|
|
19
|
+
*/
|
|
20
|
+
import { useMemo, useState } from 'react';
|
|
21
|
+
import { Resizable } from 're-resizable';
|
|
22
|
+
import { noop } from '@google-psat/common';
|
|
23
|
+
import { I18n } from '@google-psat/i18n';
|
|
24
|
+
import { Table, TableProvider, } from '@google-psat/design-system';
|
|
25
|
+
/**
|
|
26
|
+
* Internal dependencies
|
|
27
|
+
*/
|
|
28
|
+
import { useContentStore } from '../../stateProviders/contentStore';
|
|
29
|
+
const Technologies = ({ selectedSite }) => {
|
|
30
|
+
const data = useContentStore(({ state }) => state.technologies || []);
|
|
31
|
+
const [selectedRow, setSelectedRow] = useState();
|
|
32
|
+
const tableColumns = useMemo(() => [
|
|
33
|
+
{
|
|
34
|
+
header: I18n.getMessage('name'),
|
|
35
|
+
accessorKey: 'name',
|
|
36
|
+
cell: (info) => info,
|
|
37
|
+
enableHiding: false,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
header: I18n.getMessage('description'),
|
|
41
|
+
accessorKey: 'description',
|
|
42
|
+
cell: (info) => info,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
header: I18n.getMessage('confidence'),
|
|
46
|
+
accessorKey: 'confidence',
|
|
47
|
+
cell: (info) => (_jsx("span", { className: "w-full flex justify-center", children: info + '%' })),
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
header: I18n.getMessage('website'),
|
|
51
|
+
accessorKey: 'website',
|
|
52
|
+
cell: (info) => info,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
header: I18n.getMessage('category'),
|
|
56
|
+
accessorKey: 'categories',
|
|
57
|
+
cell: (info) => info.map((i) => i.name).join(' | '),
|
|
58
|
+
sortingComparator: (a, b) => {
|
|
59
|
+
const aCategories = a
|
|
60
|
+
?.map((i) => i.name)
|
|
61
|
+
.join(' | ') || '';
|
|
62
|
+
const bCategories = b
|
|
63
|
+
?.map((i) => i.name)
|
|
64
|
+
.join(' | ') || '';
|
|
65
|
+
return aCategories.localeCompare(bCategories);
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
], []);
|
|
69
|
+
const filters = useMemo(() => ({}), []);
|
|
70
|
+
const searchKeys = useMemo(() => ['name', 'website'], []);
|
|
71
|
+
const tablePersistentSettingsKey = useMemo(() => {
|
|
72
|
+
if (selectedSite) {
|
|
73
|
+
return `technologyListing#${selectedSite}`;
|
|
74
|
+
}
|
|
75
|
+
return 'technologyListing';
|
|
76
|
+
}, [selectedSite]);
|
|
77
|
+
return (_jsxs("div", { className: "w-full h-full text-outer-space-crayola border-x border-american-silver dark:border-quartz flex flex-col", children: [_jsx(Resizable, { defaultSize: {
|
|
78
|
+
width: '100%',
|
|
79
|
+
height: '80%',
|
|
80
|
+
}, minHeight: "6%", maxHeight: "95%", enable: {
|
|
81
|
+
top: false,
|
|
82
|
+
right: false,
|
|
83
|
+
bottom: true,
|
|
84
|
+
left: false,
|
|
85
|
+
}, className: "h-full flex", children: _jsx(TableProvider, { data: data, tableColumns: tableColumns, tableFilterData: filters, tableSearchKeys: searchKeys, tablePersistentSettingsKey: tablePersistentSettingsKey, onRowClick: (row) => {
|
|
86
|
+
setSelectedRow(row);
|
|
87
|
+
}, onRowContextMenu: noop, getRowObjectKey: (row) => {
|
|
88
|
+
return row.originalData.slug;
|
|
89
|
+
}, children: _jsx(Table, { hideFiltering: true, selectedKey: selectedRow?.slug }) }) }), _jsx("div", { className: "flex-1 border border-gray-300 dark:border-quartz shadow h-full min-w-[10rem]", children: selectedRow ? (_jsxs("div", { className: "text-xs py-1 px-1.5", children: [selectedRow.name && (_jsxs(_Fragment, { children: [_jsx("p", { className: "font-bold text-granite-gray dark:text-manatee mb-1 text-semibold flex items-center", children: _jsx("span", { children: I18n.getMessage('technologyDetails') }) }), _jsx("p", { className: "mb-4 break-words text-outer-space-crayola dark:text-bright-gray", children: selectedRow.name })] })), _jsxs(_Fragment, { children: [_jsx("p", { className: "font-bold text-granite-gray dark:text-manatee mb-1", children: I18n.getMessage('description') }), _jsx("p", { className: "text-outer-space-crayola dark:text-bright-gray", children: selectedRow?.description || I18n.getMessage('noDescription') })] })] })) : (_jsx("div", { className: "h-full p-8 flex items-center", children: _jsx("p", { className: "text-lg w-full font-bold text-granite-gray dark:text-manatee text-center", children: I18n.getMessage('selectRowToPreview') }) })) })] }));
|
|
90
|
+
};
|
|
91
|
+
export default Technologies;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2023 Google LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* External dependencies.
|
|
19
|
+
*/
|
|
20
|
+
import { BLOCK_STATUS } from '@google-psat/common';
|
|
21
|
+
import { InboundIcon, OutboundIcon, OutboundInboundColoredIcon, OutboundInboundIcon, QuestionMark, GreenTick, } from '@google-psat/design-system';
|
|
22
|
+
const NamePrefixIconSelector = ({ originalData }) => {
|
|
23
|
+
const data = originalData;
|
|
24
|
+
const isDomainInAllowList = data?.isDomainInAllowList;
|
|
25
|
+
if (isDomainInAllowList) {
|
|
26
|
+
return _jsx(GreenTick, {});
|
|
27
|
+
}
|
|
28
|
+
const isInboundBlocked = data?.blockingStatus?.inboundBlock !== undefined &&
|
|
29
|
+
data.blockingStatus.inboundBlock !== BLOCK_STATUS.NOT_BLOCKED;
|
|
30
|
+
const isInboundBlockedInAll = data?.blockingStatus?.inboundBlock === BLOCK_STATUS.BLOCKED_IN_ALL_EVENTS;
|
|
31
|
+
const isOutboundBlocked = data?.blockingStatus?.outboundBlock !== undefined &&
|
|
32
|
+
data.blockingStatus.outboundBlock !== BLOCK_STATUS.NOT_BLOCKED;
|
|
33
|
+
const isOutboundBlockedInAll = data?.blockingStatus?.outboundBlock === BLOCK_STATUS.BLOCKED_IN_ALL_EVENTS;
|
|
34
|
+
const hasValidBlockedReason = data?.blockedReasons && data.blockedReasons.length !== 0;
|
|
35
|
+
if (!hasValidBlockedReason) {
|
|
36
|
+
if (isInboundBlocked || isOutboundBlocked) {
|
|
37
|
+
return _jsx(QuestionMark, {});
|
|
38
|
+
}
|
|
39
|
+
return _jsx(_Fragment, {});
|
|
40
|
+
}
|
|
41
|
+
if (isInboundBlocked && isOutboundBlocked) {
|
|
42
|
+
if (isInboundBlockedInAll && isOutboundBlockedInAll) {
|
|
43
|
+
return _jsx(OutboundInboundIcon, { className: "stroke-[#D8302F] scale-150" });
|
|
44
|
+
}
|
|
45
|
+
if (!isInboundBlockedInAll && !isOutboundBlockedInAll) {
|
|
46
|
+
return _jsx(OutboundInboundIcon, { className: "stroke-[#FE8455] scale-150" });
|
|
47
|
+
}
|
|
48
|
+
if (isInboundBlockedInAll) {
|
|
49
|
+
return _jsx(OutboundInboundColoredIcon, { className: "rotate-180 scale-150" });
|
|
50
|
+
}
|
|
51
|
+
return _jsx(OutboundInboundColoredIcon, { className: "scale-150" });
|
|
52
|
+
}
|
|
53
|
+
if (isInboundBlocked) {
|
|
54
|
+
if (isInboundBlockedInAll) {
|
|
55
|
+
return _jsx(InboundIcon, { className: "stroke-[#D8302F] scale-150" });
|
|
56
|
+
}
|
|
57
|
+
return _jsx(InboundIcon, { className: "stroke-[#FE8455] scale-150" });
|
|
58
|
+
}
|
|
59
|
+
if (isOutboundBlocked) {
|
|
60
|
+
if (isOutboundBlockedInAll) {
|
|
61
|
+
return _jsx(OutboundIcon, { className: "stroke-[#D8302F] scale-150" });
|
|
62
|
+
}
|
|
63
|
+
return _jsx(OutboundIcon, { className: "stroke-[#FE8455] scale-150" });
|
|
64
|
+
}
|
|
65
|
+
return _jsx(_Fragment, {});
|
|
66
|
+
};
|
|
67
|
+
export default NamePrefixIconSelector;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { calculateEffectiveExpiryDate, } from '@google-psat/common';
|
|
17
|
+
/**
|
|
18
|
+
* Internal dependencies
|
|
19
|
+
*/
|
|
20
|
+
const extractCookies = (cookieData, pageUrl, shouldAddUrlToKey = false) => {
|
|
21
|
+
return Object.entries(cookieData).reduce((acc, [frame, _data]) => {
|
|
22
|
+
acc[frame] = Object.fromEntries(Object.entries(_data.frameCookies).map(([key, cookie]) => [
|
|
23
|
+
key + (shouldAddUrlToKey ? '' : pageUrl),
|
|
24
|
+
{
|
|
25
|
+
...cookie,
|
|
26
|
+
pageUrl,
|
|
27
|
+
parsedCookie: {
|
|
28
|
+
...cookie.parsedCookie,
|
|
29
|
+
expires: calculateEffectiveExpiryDate(cookie.parsedCookie.expires),
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
]));
|
|
33
|
+
return acc;
|
|
34
|
+
}, {});
|
|
35
|
+
};
|
|
36
|
+
export default extractCookies;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Internal dependencies
|
|
18
|
+
*/
|
|
19
|
+
import extractCookies from './extractCookies';
|
|
20
|
+
const extractReportData = (data) => {
|
|
21
|
+
const landingPageCookies = {};
|
|
22
|
+
const technologies = [];
|
|
23
|
+
const consolidatedLibraryMatches = {};
|
|
24
|
+
data.forEach(({ cookieData, pageUrl, libraryMatches, technologyData }) => {
|
|
25
|
+
formatCookieData(extractCookies(cookieData, pageUrl, true), landingPageCookies);
|
|
26
|
+
technologies.push(...technologyData.map((technology) => ({
|
|
27
|
+
...technology,
|
|
28
|
+
pageUrl,
|
|
29
|
+
})));
|
|
30
|
+
consolidatedLibraryMatches[pageUrl] = libraryMatches;
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
landingPageCookies,
|
|
34
|
+
consolidatedLibraryMatches,
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
const formatCookieData = (cookieData, store) => {
|
|
38
|
+
Object.entries(cookieData).forEach(([frame, _cData]) => {
|
|
39
|
+
if (!store[frame]) {
|
|
40
|
+
store[frame] = {};
|
|
41
|
+
}
|
|
42
|
+
Object.entries(_cData).forEach(([key, cookie]) => {
|
|
43
|
+
store[frame][key] = {
|
|
44
|
+
...cookie,
|
|
45
|
+
isBlocked: store[frame][key]?.isBlocked || cookie.isBlocked,
|
|
46
|
+
blockedReasons: [
|
|
47
|
+
...new Set([
|
|
48
|
+
...(store[frame][key]?.blockedReasons || []),
|
|
49
|
+
...(cookie.blockedReasons || []),
|
|
50
|
+
]),
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
export default extractReportData;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* External dependencies
|
|
18
|
+
*/
|
|
19
|
+
import JSZip from 'jszip';
|
|
20
|
+
import { saveAs } from 'file-saver';
|
|
21
|
+
import { getCurrentDateAndTime } from '@google-psat/common';
|
|
22
|
+
import {} from '@google-psat/design-system';
|
|
23
|
+
/**
|
|
24
|
+
* Internal dependencies
|
|
25
|
+
*/
|
|
26
|
+
import { createZip, getFolderName, generateSitemapHTMLFile } from './utils';
|
|
27
|
+
const generateSiteMapReportandDownload = async (JSONReport, appliedFilters, path) => {
|
|
28
|
+
if (!JSONReport.length) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const zip = new JSZip();
|
|
32
|
+
JSONReport.forEach((data) => {
|
|
33
|
+
const zipFolder = zip.folder(`psat_cli_report_${getFolderName(data.pageUrl)}_${getCurrentDateAndTime('YYYY-MM-DD_HH-MM-SS')}`);
|
|
34
|
+
if (!zipFolder) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
createZip(data, appliedFilters, zipFolder);
|
|
38
|
+
});
|
|
39
|
+
const report = generateSitemapHTMLFile(JSONReport, appliedFilters);
|
|
40
|
+
zip.file('report.html', report);
|
|
41
|
+
const content = await zip.generateAsync({ type: 'blob' });
|
|
42
|
+
saveAs(content, `psat_cli_report_${getFolderName(path)}_${getCurrentDateAndTime('YYYY-MM-DD_HH-MM-SS')}.zip`);
|
|
43
|
+
};
|
|
44
|
+
export default generateSiteMapReportandDownload;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* External dependencies
|
|
18
|
+
*/
|
|
19
|
+
import JSZip from 'jszip';
|
|
20
|
+
import { saveAs } from 'file-saver';
|
|
21
|
+
import { getCurrentDateAndTime } from '@google-psat/common';
|
|
22
|
+
import {} from '@google-psat/design-system';
|
|
23
|
+
/**
|
|
24
|
+
* Internal dependencies
|
|
25
|
+
*/
|
|
26
|
+
import { createZip, getFolderName } from './utils';
|
|
27
|
+
const generateSiteReportandDownload = async (JSONReport, appliedFilters, selectedPageUrl) => {
|
|
28
|
+
if (!JSONReport.length) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const zip = new JSZip();
|
|
32
|
+
let siteAnalysisData;
|
|
33
|
+
if (selectedPageUrl) {
|
|
34
|
+
siteAnalysisData = JSONReport.find(({ pageUrl }) => pageUrl === selectedPageUrl);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
siteAnalysisData = JSONReport[0];
|
|
38
|
+
}
|
|
39
|
+
const hostName = new URL(siteAnalysisData.pageUrl).hostname;
|
|
40
|
+
// @ts-ignore -- because this data will already be injected from the extension.
|
|
41
|
+
const fileName = globalThis?.PSAT_EXTENSION
|
|
42
|
+
? `${hostName.replace('.', '-')}-report-${getCurrentDateAndTime('YYYY-MM-DD_HH-MM-SS')}`
|
|
43
|
+
: `psat_cli_report_${getFolderName(JSONReport[0].pageUrl)}_${getCurrentDateAndTime('YYYY-MM-DD_HH-MM-SS')}`;
|
|
44
|
+
const zipFolder = zip.folder(fileName);
|
|
45
|
+
if (!zipFolder) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
createZip(siteAnalysisData, appliedFilters, zipFolder);
|
|
49
|
+
const content = await zip.generateAsync({ type: 'blob' });
|
|
50
|
+
saveAs(content, fileName + '.zip');
|
|
51
|
+
};
|
|
52
|
+
export default generateSiteReportandDownload;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
export { default as generateSiteMapReportandDownload } from './generateSiteMapReportandDownload';
|
|
17
|
+
export { default as generateSiteReportandDownload } from './generateSiteReportandDownload';
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { generateCookiesWithIssuesCSV, generateAllCookiesCSV, generateSummaryDataCSV, generateTechnologyCSV, } from '@google-psat/common';
|
|
17
|
+
import {} from '@google-psat/design-system';
|
|
18
|
+
const generateCSVFiles = (data) => {
|
|
19
|
+
const allCookiesCSV = generateAllCookiesCSV(data);
|
|
20
|
+
let technologyDataCSV = null;
|
|
21
|
+
if (data.technologyData.length > 0) {
|
|
22
|
+
technologyDataCSV = generateTechnologyCSV(data);
|
|
23
|
+
}
|
|
24
|
+
const cookiesWithIssuesDataCSV = generateCookiesWithIssuesCSV(data);
|
|
25
|
+
const summaryDataCSV = generateSummaryDataCSV(data);
|
|
26
|
+
return {
|
|
27
|
+
allCookiesCSV,
|
|
28
|
+
technologyDataCSV,
|
|
29
|
+
cookiesWithIssuesDataCSV,
|
|
30
|
+
summaryDataCSV,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const generateHTMLFile = (analysisData, appliedFilters) => {
|
|
34
|
+
const parser = new DOMParser();
|
|
35
|
+
const reportDom = parser.parseFromString(`
|
|
36
|
+
<html>
|
|
37
|
+
${document.documentElement.innerHTML}
|
|
38
|
+
</html>
|
|
39
|
+
`, 'text/html');
|
|
40
|
+
const translations =
|
|
41
|
+
// @ts-ignore
|
|
42
|
+
globalThis?.PSAT_DATA?.translations;
|
|
43
|
+
const previousJSONDATA = reportDom.getElementById('JSONDATASCRIPT');
|
|
44
|
+
const styleNodes = reportDom.querySelectorAll('style');
|
|
45
|
+
if (styleNodes.length > 1) {
|
|
46
|
+
styleNodes.forEach((styleNode, index) => {
|
|
47
|
+
if (index !== 0) {
|
|
48
|
+
reportDom.head.removeChild(styleNode);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (previousJSONDATA) {
|
|
53
|
+
reportDom.head.removeChild(previousJSONDATA);
|
|
54
|
+
}
|
|
55
|
+
// Injections
|
|
56
|
+
const script = reportDom.createElement('script');
|
|
57
|
+
const reportData = {
|
|
58
|
+
json: [analysisData],
|
|
59
|
+
type: 'url',
|
|
60
|
+
// @ts-ignore -- because this data will already be injected from cli or the extension.
|
|
61
|
+
selectedSite: globalThis?.PSAT_DATA?.selectedSite ?? '',
|
|
62
|
+
translations,
|
|
63
|
+
appliedFilters,
|
|
64
|
+
// @ts-ignore -- because this data will already be injected from cli or the extension.
|
|
65
|
+
dateTime: globalThis?.PSAT_DATA.dateTime,
|
|
66
|
+
hideDownloadButton: true,
|
|
67
|
+
};
|
|
68
|
+
let code = `window.PSAT_DATA = ${JSON.stringify(reportData)};`;
|
|
69
|
+
// @ts-ignore -- because this data will already be injected from cli or the extension.
|
|
70
|
+
if (globalThis?.PSAT_EXTENSION) {
|
|
71
|
+
code += `window.PSAT_EXTENSION = true;`;
|
|
72
|
+
}
|
|
73
|
+
// @ts-ignore -- because this data will already be injected from the extension.
|
|
74
|
+
code += `window.PSAT_USING_CDP = ${globalThis?.PSAT_USING_CDP ?? undefined};`;
|
|
75
|
+
script.text = code;
|
|
76
|
+
script.id = 'JSONDATASCRIPT';
|
|
77
|
+
reportDom.head.appendChild(script);
|
|
78
|
+
const injectedHtmlText = `<head>${reportDom.head.innerHTML}<head><body>${reportDom.body.innerHTML}</body>`;
|
|
79
|
+
const html = new Blob([injectedHtmlText]);
|
|
80
|
+
return html;
|
|
81
|
+
};
|
|
82
|
+
export const generateSitemapHTMLFile = (analysisData, appliedFilters) => {
|
|
83
|
+
const parser = new DOMParser();
|
|
84
|
+
const reportDom = parser.parseFromString(`
|
|
85
|
+
<html>
|
|
86
|
+
${document.documentElement.innerHTML}
|
|
87
|
+
</html>
|
|
88
|
+
`, 'text/html');
|
|
89
|
+
const previousJSONDATA = reportDom.getElementById('JSONDATASCRIPT');
|
|
90
|
+
const styleNodes = reportDom.querySelectorAll('style');
|
|
91
|
+
if (styleNodes.length > 1) {
|
|
92
|
+
styleNodes.forEach((styleNode, index) => {
|
|
93
|
+
if (index !== 0) {
|
|
94
|
+
reportDom.head.removeChild(styleNode);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (previousJSONDATA) {
|
|
99
|
+
reportDom.head.removeChild(previousJSONDATA);
|
|
100
|
+
}
|
|
101
|
+
// Injections
|
|
102
|
+
const script = reportDom.createElement('script');
|
|
103
|
+
const translations =
|
|
104
|
+
// @ts-ignore
|
|
105
|
+
globalThis?.PSAT_DATA?.translations;
|
|
106
|
+
const reportData = {
|
|
107
|
+
json: analysisData,
|
|
108
|
+
type: 'sitemap',
|
|
109
|
+
// @ts-ignore -- because this data will already be injected from cli or the extension.
|
|
110
|
+
selectedSite: globalThis?.PSAT_DATA?.selectedSite ?? '',
|
|
111
|
+
translations,
|
|
112
|
+
// @ts-ignore -- because this data will already be injected from cli or the extension.
|
|
113
|
+
dateTime: globalThis?.PSAT_DATA.dateTime,
|
|
114
|
+
appliedFilters,
|
|
115
|
+
hideDownloadButton: true,
|
|
116
|
+
};
|
|
117
|
+
const code = `window.PSAT_DATA = ${JSON.stringify(reportData)}`;
|
|
118
|
+
script.text = code;
|
|
119
|
+
script.id = 'JSONDATASCRIPT';
|
|
120
|
+
reportDom.head.appendChild(script);
|
|
121
|
+
const injectedHtmlText = `<head>${reportDom.head.innerHTML}<head><body>${reportDom.body.innerHTML}</body>`;
|
|
122
|
+
const html = new Blob([injectedHtmlText]);
|
|
123
|
+
return html;
|
|
124
|
+
};
|
|
125
|
+
export const createZip = (analysisData, appliedFilters, zipObject) => {
|
|
126
|
+
const { allCookiesCSV, technologyDataCSV, cookiesWithIssuesDataCSV, summaryDataCSV, } = generateCSVFiles(analysisData);
|
|
127
|
+
const file = generateHTMLFile(analysisData, appliedFilters);
|
|
128
|
+
zipObject.file('cookies.csv', allCookiesCSV);
|
|
129
|
+
if (technologyDataCSV) {
|
|
130
|
+
zipObject.file('technologies.csv', technologyDataCSV);
|
|
131
|
+
}
|
|
132
|
+
zipObject.file('cookie-issues.csv', cookiesWithIssuesDataCSV);
|
|
133
|
+
zipObject.file('report.csv', summaryDataCSV);
|
|
134
|
+
zipObject.file('report.json', JSON.stringify(analysisData, null, 4));
|
|
135
|
+
zipObject.file('report.html', file);
|
|
136
|
+
};
|
|
137
|
+
export const getFolderName = (pageUrl) => {
|
|
138
|
+
let folderName = pageUrl
|
|
139
|
+
.trim()
|
|
140
|
+
.replace(/^https?:\/\//, '')
|
|
141
|
+
.replace(/\/+/g, '-')
|
|
142
|
+
.replace(/\./g, '-');
|
|
143
|
+
if (folderName.endsWith('-')) {
|
|
144
|
+
const lastDashIndex = folderName.lastIndexOf('-');
|
|
145
|
+
folderName = folderName.substring(0, lastDashIndex);
|
|
146
|
+
}
|
|
147
|
+
return folderName;
|
|
148
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2023 Google LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* https://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* External dependencies
|
|
18
|
+
*/
|
|
19
|
+
import { deriveBlockingStatus, } from '@google-psat/common';
|
|
20
|
+
import { I18n } from '@google-psat/i18n';
|
|
21
|
+
const reshapeCookies = (cookies) => {
|
|
22
|
+
return Object.entries(cookies)
|
|
23
|
+
.filter(([frame]) => frame.includes('http'))
|
|
24
|
+
.map(([frame, _cookies]) => createCookieObj(frame, _cookies))
|
|
25
|
+
.reduce((acc, cookieObj) => {
|
|
26
|
+
Object.keys(cookieObj).forEach((key) => {
|
|
27
|
+
if (acc[key]) {
|
|
28
|
+
const frameUrls = [
|
|
29
|
+
...(acc[key]?.frameUrls ?? []),
|
|
30
|
+
...(cookieObj[key]?.frameUrls ?? []),
|
|
31
|
+
];
|
|
32
|
+
const blockedReasons = [
|
|
33
|
+
...new Set([
|
|
34
|
+
...(acc[key]?.blockedReasons ?? []),
|
|
35
|
+
...(cookieObj[key]?.blockedReasons ?? []),
|
|
36
|
+
]),
|
|
37
|
+
];
|
|
38
|
+
const frameIdList = Array.from(new Set([
|
|
39
|
+
...(acc[key]?.frameIdList ?? []),
|
|
40
|
+
...(cookieObj[key]?.frameIdList ?? []),
|
|
41
|
+
]));
|
|
42
|
+
const networkEvents = {
|
|
43
|
+
requestEvents: [
|
|
44
|
+
...(cookieObj[key]?.networkEvents?.requestEvents || []),
|
|
45
|
+
...(acc[key].networkEvents?.requestEvents || []),
|
|
46
|
+
],
|
|
47
|
+
responseEvents: [
|
|
48
|
+
...(cookieObj[key]?.networkEvents?.responseEvents || []),
|
|
49
|
+
...(acc[key].networkEvents?.responseEvents || []),
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
let blockingStatus = deriveBlockingStatus(networkEvents);
|
|
53
|
+
//@ts-ignore -- Since this has to be run for data coming from extension only.
|
|
54
|
+
if (globalThis?.PSAT_EXTENSION) {
|
|
55
|
+
blockingStatus = cookieObj[key].blockingStatus;
|
|
56
|
+
}
|
|
57
|
+
acc[key] = {
|
|
58
|
+
...cookieObj[key],
|
|
59
|
+
...acc[key],
|
|
60
|
+
blockedReasons,
|
|
61
|
+
frameIdList,
|
|
62
|
+
exemptionReason: acc[key]?.exemptionReason || cookieObj[key]?.exemptionReason,
|
|
63
|
+
frameUrls,
|
|
64
|
+
networkEvents,
|
|
65
|
+
blockingStatus,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
acc[key] = cookieObj[key];
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
return acc;
|
|
73
|
+
}, {});
|
|
74
|
+
};
|
|
75
|
+
const createCookieObj = (frame, cookies) => Object.fromEntries(Object.values(cookies).map((cookie) => [
|
|
76
|
+
cookie.parsedCookie.name +
|
|
77
|
+
':' +
|
|
78
|
+
cookie.parsedCookie.domain +
|
|
79
|
+
':' +
|
|
80
|
+
cookie.parsedCookie.path,
|
|
81
|
+
{
|
|
82
|
+
parsedCookie: cookie.parsedCookie,
|
|
83
|
+
analytics: {
|
|
84
|
+
...cookie.analytics,
|
|
85
|
+
category: cookie.analytics?.category === 'Unknown Category'
|
|
86
|
+
? I18n.getMessage('sdUncategorized')
|
|
87
|
+
: cookie.analytics?.category,
|
|
88
|
+
},
|
|
89
|
+
url: cookie.url,
|
|
90
|
+
headerType: 'response',
|
|
91
|
+
blockedReasons: cookie.blockedReasons,
|
|
92
|
+
isFirstParty: cookie.isFirstParty,
|
|
93
|
+
frameIdList: [frame], // Hot fix: For Displaying cookies in CLI Dashboard.
|
|
94
|
+
isBlocked: cookie.isBlocked,
|
|
95
|
+
networkEvents: cookie.networkEvents,
|
|
96
|
+
blockingStatus: cookie.blockingStatus,
|
|
97
|
+
frameUrls: [frame],
|
|
98
|
+
exemptionReason: cookie.exemptionReason,
|
|
99
|
+
pageUrl: cookie.pageUrl,
|
|
100
|
+
},
|
|
101
|
+
]));
|
|
102
|
+
export default reshapeCookies;
|