From 6d1ba8607a81d1703e25c855c337de8d361e1ae1 Mon Sep 17 00:00:00 2001 From: Ayush Nirwal <53055971+ayushnirwal@users.noreply.github.com> Date: Tue, 26 Dec 2023 19:02:30 +0530 Subject: [PATCH] Enhancements: CLI interface updates and column reordering (#362) * chore:reorder table coloums in cli dashboard * feat: add flag to omit prompts * feat:add flag to skip technology assesment * feat: Dont show tech table if no data available * fix: Show frames horizontal count component * Revert "feat: Dont show tech table if no data available" This reverts commit 79b3ca7eb7c5653c7268800759a03a2fd85aa27d. * feat: Move tech table to bottom and don't show if no data available * feat: add argument to pass no of urls to be analyzed * fix: url limit * fix:ignore creating technologies csv file --------- Co-authored-by: Mayank Rana --- .../siteReport/components/layout.tsx | 21 +++-- .../cookies/cookiesLandingContainer/index.tsx | 1 + .../tabs/cookies/cookiesListing/index.tsx | 48 +++++----- .../src/components/siteReport/tabs/index.tsx | 8 -- .../src/components/utils/reportDownloader.ts | 9 +- packages/cli/src/index.ts | 90 +++++++++++++------ packages/cli/src/utils/utility/index.ts | 4 +- packages/common/tsconfig.json | 2 +- .../src/components/cookiesLanding/index.tsx | 3 +- 9 files changed, 114 insertions(+), 72 deletions(-) diff --git a/packages/cli-dashboard/src/components/siteReport/components/layout.tsx b/packages/cli-dashboard/src/components/siteReport/components/layout.tsx index 0b3884cad..ed5d019eb 100644 --- a/packages/cli-dashboard/src/components/siteReport/components/layout.tsx +++ b/packages/cli-dashboard/src/components/siteReport/components/layout.tsx @@ -24,6 +24,8 @@ import { Sidebar, useSidebar, type SidebarItems, + SiteBoundariesIcon, + SiteBoundariesIconWhite, } from '@ps-analysis-tool/design-system'; /** @@ -42,8 +44,9 @@ interface LayoutProps { const Layout = ({ selectedSite }: LayoutProps) => { const [data, setData] = useState(TABS); - const { tabCookies } = useContentStore(({ state }) => ({ + const { tabCookies, technologies } = useContentStore(({ state }) => ({ tabCookies: state.tabCookies, + technologies: state.technologies, })); const frameUrls = useMemo( @@ -113,13 +116,21 @@ const Layout = ({ selectedSite }: LayoutProps) => { ); - _data['technologies'].panel = ( - - ); + if (technologies && technologies.length > 0) { + _data['technologies'] = { + title: 'Technologies', + children: {}, + icon: , + selectedIcon: , + panel: , + }; + } else { + delete _data['technologies']; + } return _data; }); - }, [frameUrls, selectedItemKey, selectedSite]); + }, [frameUrls, selectedItemKey, selectedSite, technologies]); useEffect(() => { if (selectedItemKey === null) { diff --git a/packages/cli-dashboard/src/components/siteReport/tabs/cookies/cookiesLandingContainer/index.tsx b/packages/cli-dashboard/src/components/siteReport/tabs/cookies/cookiesLandingContainer/index.tsx index c3dfc26a6..dd56a33af 100644 --- a/packages/cli-dashboard/src/components/siteReport/tabs/cookies/cookiesLandingContainer/index.tsx +++ b/packages/cli-dashboard/src/components/siteReport/tabs/cookies/cookiesLandingContainer/index.tsx @@ -47,6 +47,7 @@ const CookiesLandingContainer = ({ showInfoIcon={false} associatedCookiesCount={Object.values(tabFrames).length} showMessageBoxBody={false} + showHorizontalMatrix >

diff --git a/packages/cli-dashboard/src/components/siteReport/tabs/cookies/cookiesListing/index.tsx b/packages/cli-dashboard/src/components/siteReport/tabs/cookies/cookiesListing/index.tsx index c8f86091c..1e454acfd 100644 --- a/packages/cli-dashboard/src/components/siteReport/tabs/cookies/cookiesListing/index.tsx +++ b/packages/cli-dashboard/src/components/siteReport/tabs/cookies/cookiesListing/index.tsx @@ -61,9 +61,13 @@ const CookiesListing = ({ enableHiding: false, }, { - header: 'Value', - accessorKey: 'parsedCookie.value', - cell: (info: InfoType) => info, + header: 'Scope', + accessorKey: 'isFirstParty', + cell: (info: InfoType) => ( +

+ {!info ? 'Third Party' : 'First Party'} +

+ ), }, { header: 'Domain', @@ -71,14 +75,19 @@ const CookiesListing = ({ cell: (info: InfoType) => info, }, { - header: 'Path', - accessorKey: 'parsedCookie.path', + header: 'SameSite', + accessorKey: 'parsedCookie.samesite', + cell: (info: InfoType) => {info}, + }, + { + header: 'Category', + accessorKey: 'analytics.category', cell: (info: InfoType) => info, }, { - header: 'Expires / Max-Age', - accessorKey: 'parsedCookie.expires', - cell: (info: InfoType) => (info ? info : 'Session'), + header: 'Platform', + accessorKey: 'analytics.platform', + cell: (info: InfoType) => info, }, { header: 'HttpOnly', @@ -89,11 +98,6 @@ const CookiesListing = ({

), }, - { - header: 'SameSite', - accessorKey: 'parsedCookie.samesite', - cell: (info: InfoType) => {info}, - }, { header: 'Secure', accessorKey: 'parsedCookie.secure', @@ -104,23 +108,19 @@ const CookiesListing = ({ ), }, { - header: 'Category', - accessorKey: 'analytics.category', + header: 'Value', + accessorKey: 'parsedCookie.value', cell: (info: InfoType) => info, }, { - header: 'Platform', - accessorKey: 'analytics.platform', + header: 'Path', + accessorKey: 'parsedCookie.path', cell: (info: InfoType) => info, }, { - header: 'Scope', - accessorKey: 'isFirstParty', - cell: (info: InfoType) => ( -

- {!info ? 'Third Party' : 'First Party'} -

- ), + header: 'Expires / Max-Age', + accessorKey: 'parsedCookie.expires', + cell: (info: InfoType) => (info ? info : 'Session'), }, ], [] diff --git a/packages/cli-dashboard/src/components/siteReport/tabs/index.tsx b/packages/cli-dashboard/src/components/siteReport/tabs/index.tsx index e3f6f5adc..d71a4c481 100644 --- a/packages/cli-dashboard/src/components/siteReport/tabs/index.tsx +++ b/packages/cli-dashboard/src/components/siteReport/tabs/index.tsx @@ -20,8 +20,6 @@ import React from 'react'; import { CookieIcon, CookieIconWhite, - SiteBoundariesIcon, - SiteBoundariesIconWhite, type SidebarItems, } from '@ps-analysis-tool/design-system'; @@ -32,12 +30,6 @@ const Tabs: SidebarItems = { icon: , selectedIcon: , }, - technologies: { - title: 'Technologies', - children: {}, - icon: , - selectedIcon: , - }, 'affected-cookies': { title: 'Affected Cookies', children: {}, diff --git a/packages/cli-dashboard/src/components/utils/reportDownloader.ts b/packages/cli-dashboard/src/components/utils/reportDownloader.ts index 738a4f1f5..765891009 100644 --- a/packages/cli-dashboard/src/components/utils/reportDownloader.ts +++ b/packages/cli-dashboard/src/components/utils/reportDownloader.ts @@ -49,13 +49,18 @@ export const genereateAndDownloadCSVReports = ( } const allCookiesCSV = generateAllCookiesCSV(siteAnalysisData); - const technologyDataCSV = generateTechnologyCSV(siteAnalysisData); + let technologyDataCSV = null; + if (siteAnalysisData.technologyData.length > 0) { + technologyDataCSV = generateTechnologyCSV(siteAnalysisData); + } const affectedCookiesDataCSV = generateAffectedCookiesCSV(siteAnalysisData); const summaryDataCSV = generateSummaryDataCSV(siteAnalysisData); const zip = new JSZip(); zip.file('cookies.csv', allCookiesCSV); - zip.file('technologies.csv', technologyDataCSV); + if (technologyDataCSV) { + zip.file('technologies.csv', technologyDataCSV); + } zip.file('affected-cookies.csv', affectedCookiesDataCSV); zip.file('report.csv', summaryDataCSV); zip.file('report.json', JSON.stringify(JSONReport, null, 4)); diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 0b07bd301..1de24bd5d 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -39,7 +39,6 @@ import { checkPortInUse } from './utils/checkPortInUse'; events.EventEmitter.defaultMaxListeners = 15; const DELAY_TIME = 20000; - const program = new Command(); program @@ -52,10 +51,16 @@ program '-p, --sitemap-path ', 'Path to a sitmap saved in the file system' ) + .option('-ul, --url-limit ', 'No of Urls to analyze') .option( '-nh, --no-headless ', 'Flag for running puppeteer in non headless mode' - ); + ) + .option( + '-np, --no-prompts', + 'Flags for skipping all prompts. Default options will be used' + ) + .option('-nt, --no-technology', 'Flags for skipping technology analysis.'); program.parse(); @@ -77,7 +82,8 @@ const validateArgs = async ( url: string, sitemapUrl: string, csvPath: string, - sitemapPath: string + sitemapPath: string, + numberOfUrls: string ) => { if (!url && !sitemapUrl && !csvPath && !sitemapPath) { console.log( @@ -132,6 +138,13 @@ const validateArgs = async ( process.exit(1); } } + + if (numberOfUrls) { + if (isNaN(parseInt(numberOfUrls))) { + console.log(`${numberOfUrls} is not valid numeric value`); + process.exit(1); + } + } }; const getUrlListFromArgs = async ( @@ -262,6 +275,7 @@ const getUrlListFromArgs = async ( return urls; }; +// eslint-disable-next-line complexity (async () => { await initialize(); @@ -269,9 +283,12 @@ const getUrlListFromArgs = async ( const sitemapUrl = program.opts().sitemapUrl; const csvPath = program.opts().csvPath; const sitemapPath = program.opts().sitemapPath; + const numberOfUrlsInput = program.opts().urlLimit; const isHeadless = Boolean(program.opts().headless); + const shouldSkipPrompts = !program.opts().prompts; + const shouldSkipTechnologyAnalysis = !program.opts().technology; - validateArgs(url, sitemapUrl, csvPath, sitemapPath); + validateArgs(url, sitemapUrl, csvPath, sitemapPath, numberOfUrlsInput); const prefix = url || sitemapUrl @@ -292,19 +309,29 @@ const getUrlListFromArgs = async ( let urlsToProcess: string[] = []; if (sitemapUrl || csvPath || sitemapPath) { - const userInput = await Utility.askUserInput( - `Provided ${sitemapUrl || sitemapPath ? 'Sitemap' : 'CSV file'} has ${ - urls.length - } pages. Please enter the number of pages you want to analyze (Default ${ - urls.length - }):`, - { default: urls.length.toString() } - ); - let numberOfUrls: number = isNaN(userInput) - ? urls.length - : parseInt(userInput); - - numberOfUrls = numberOfUrls < urls.length ? numberOfUrls : urls.length; + let numberOfUrls: number | null = null; + let userInput: string | null = null; + + if (!shouldSkipPrompts && !numberOfUrlsInput) { + userInput = await Utility.askUserInput( + `Provided ${sitemapUrl || sitemapPath ? 'Sitemap' : 'CSV file'} has ${ + urls.length + } pages. Please enter the number of pages you want to analyze (Default ${ + urls.length + }):`, + { default: urls.length.toString() } + ); + numberOfUrls = + userInput && isNaN(parseInt(userInput)) + ? urls.length + : parseInt(userInput); + } else if (numberOfUrlsInput) { + console.log(`Analysing ${numberOfUrlsInput} urls.`); + numberOfUrls = parseInt(numberOfUrlsInput); + } else { + console.log(`Analysing all ${urls.length} urls.`); + numberOfUrls = urls.length; + } urlsToProcess = urlsToProcess.concat(urls.splice(0, numberOfUrls)); } else if (url) { @@ -329,24 +356,29 @@ const getUrlListFromArgs = async ( spinnies.succeed('cookie-spinner', { text: 'Done analyzing cookies.', }); - spinnies.add('technology-spinner', { - text: 'Analysing technologies', - }); - const technologyAnalysisData = await analyzeTechnologiesUrlsInBatches( - urlsToProcess, - 3, - urlsToProcess.length !== 1 ? spinnies : undefined - ); + let technologyAnalysisData: any = null; - spinnies.succeed('technology-spinner', { - text: 'Done analyzing technologies.', - }); + if (!shouldSkipTechnologyAnalysis) { + spinnies.add('technology-spinner', { + text: 'Analysing technologies', + }); + + technologyAnalysisData = await analyzeTechnologiesUrlsInBatches( + urlsToProcess, + 3, + urlsToProcess.length !== 1 ? spinnies : undefined + ); + + spinnies.succeed('technology-spinner', { + text: 'Done analyzing technologies.', + }); + } const result = urlsToProcess.map((_url, ind) => { return { pageUrl: _url, - technologyData: technologyAnalysisData[ind], + technologyData: technologyAnalysisData ? technologyAnalysisData[ind] : [], cookieData: cookieAnalysisData[ind].cookieData, }; }); diff --git a/packages/cli/src/utils/utility/index.ts b/packages/cli/src/utils/utility/index.ts index 3a0d36447..64ebf6d54 100644 --- a/packages/cli/src/utils/utility/index.ts +++ b/packages/cli/src/utils/utility/index.ts @@ -156,8 +156,8 @@ export default class Utility { public static async askUserInput( message: string, options: object = {} - ): Promise { - const userInput: any = await promptly.prompt(message, options); + ): Promise { + const userInput: string = await promptly.prompt(message, options); return userInput; } diff --git a/packages/common/tsconfig.json b/packages/common/tsconfig.json index bec720433..6ca0c6b71 100644 --- a/packages/common/tsconfig.json +++ b/packages/common/tsconfig.json @@ -12,5 +12,5 @@ "esModuleInterop": true, "moduleResolution": "node" }, - "exclude": ["**/tests/**/*.ts"] + "exclude": ["**/tests/**/*.ts", "dist/**", "dist-types/**"] } diff --git a/packages/design-system/src/components/cookiesLanding/index.tsx b/packages/design-system/src/components/cookiesLanding/index.tsx index a9e005165..e1e92efa0 100644 --- a/packages/design-system/src/components/cookiesLanding/index.tsx +++ b/packages/design-system/src/components/cookiesLanding/index.tsx @@ -50,6 +50,7 @@ const CookiesLanding = ({ associatedCookiesCount = null, showMessageBoxBody = true, showBlockedCookiesSection = false, + showHorizontalMatrix = false, }: CookiesLandingProps) => { const cookieStats = prepareCookiesCount(tabCookies); const cookiesStatsComponents = prepareCookieStatsComponents(cookieStats); @@ -104,7 +105,7 @@ const CookiesLanding = ({ componentData={cookiesStatsComponents.legend} tabFrames={tabFrames} showInfoIcon={showInfoIcon} - showHorizontalMatrix={false} + showHorizontalMatrix={showHorizontalMatrix} associatedCookiesCount={associatedCookiesCount} /> {children &&
{children}
}