diff --git a/bin/convert.js b/bin/convert.js index 735630988..6e2cb0b58 100644 --- a/bin/convert.js +++ b/bin/convert.js @@ -1,6 +1,6 @@ const fs = require('fs') const path = require('path') -const { convertFile } = require('convert-svg-to-png') +const { createConverter } = require('convert-svg-to-png') const appPaths = () => { const fileDir = path.dirname(require.main.filename).split('/') @@ -77,52 +77,85 @@ function dateDiff(file) { return Math.round(Math.abs((then - now) / 86400000)) } -// Main script -fs.readdirSync(appPaths().iconPath).forEach((fileName) => { - const image = { - id: fileName, - path: `${appPaths().iconPath}/${fileName}`, - convertPath: `${appPaths().convertPath}/${fileName}`, - async convertAndCopy() { - await convertFile(this.path, { - height: 32, - width: 32, - outputFilePath: this.convertPath, - }).then((outputFile) => { - console.log(`SVG Converted: ${outputFile}`) - }) - }, - processFile() { - // Setup variables. - const ext = getFileExtension(this.path) - - // If SVG, run checks. - if (ext === '.svg') { - // Check if converted file exists. - const convertFilePath = getConvertFileName(this.path) - if (checkFileExists(convertFilePath)) { - // If file has changed in past 7 days. - if (dateDiff(this.path) > 8) { - console.log(`File exists, skipping: ${this.id}`) - return null - } - } - // Convert and copy file. - this.convertAndCopy() - } else { - // If PNG or other, just copy the file as-is. - // eslint-disable-next-line no-lonely-if - if (checkIfFile(this.path)) { - copyFiles(this.path, this.convertPath) - } else { - console.info('Not a file, skipping...') +const converter = createConverter() + +;(async () => { + // Main script + const files = fs.readdirSync(appPaths().iconPath) + + const totalFiles = files.length + + do { + await Promise.all( + files.splice(0, 50).map(async (fileName) => { + const image = { + id: fileName, + path: `${appPaths().iconPath}/${fileName}`, + convertPath: `${appPaths().convertPath}/${fileName}`, + async convertAndCopy() { + for (let attempt = 1; attempt <= 3; attempt++) { + try { + await converter + .convertFile(this.path, { + height: 32, + width: 32, + outputFilePath: this.convertPath, + }) + .catch((error) => { + throw new Error(`${error} (${fileName})`) + }) + } catch (error) { + if (attempt >= 3) { + throw error + } else { + await new Promise((resolve) => + setTimeout(resolve, 500 * attempt) + ) + } + } + + break + } + }, + async processFile() { + // Setup variables. + const ext = getFileExtension(this.path) + + // If SVG, run checks. + if (ext === '.svg') { + // Check if converted file exists. + const convertFilePath = getConvertFileName(this.path) + if (checkFileExists(convertFilePath)) { + // If file has changed in past 7 days. + if (dateDiff(this.path) > 8) { + return null + } + } + // Convert and copy file. + await this.convertAndCopy() + } else { + // If PNG or other, just copy the file as-is. + // eslint-disable-next-line no-lonely-if + if (checkIfFile(this.path)) { + copyFiles(this.path, this.convertPath) + } + } + }, } - } - }, - } - image.processFile() -}) + await image.processFile() + }) + ) + + console.log(`${100 - Math.round((100 / totalFiles) * files.length)}%`) + } while (files.length) + + await converter.destroy() + + console.log(`Converted ${totalFiles.toLocaleString()} files.`) + + process.exit() +})() /** diff --git a/src/drivers/npm/package.json b/src/drivers/npm/package.json index 7fe2d6b52..14e890817 100644 --- a/src/drivers/npm/package.json +++ b/src/drivers/npm/package.json @@ -13,7 +13,7 @@ "software" ], "homepage": "https://www.wappalyzer.com/", - "version": "6.6.0", + "version": "6.7.0", "author": "Wappalyzer", "license": "MIT", "repository": { diff --git a/src/drivers/webextension/css/styles.css b/src/drivers/webextension/css/styles.css index 0d095f8fd..6d8b06fc4 100644 --- a/src/drivers/webextension/css/styles.css +++ b/src/drivers/webextension/css/styles.css @@ -23,7 +23,6 @@ body { line-height: 1.5rem; margin: 0; min-width: 24rem; - overflow-x: hidden; } a, a:focus, a:hover { @@ -305,6 +304,7 @@ body.dynamic-icon .category__heading:hover .category__pin { padding: .1rem .3rem; margin-left: .3rem; vertical-align: middle; + white-space: nowrap; } .technology__version { diff --git a/src/drivers/webextension/images/icons/Elasticsearch.svg b/src/drivers/webextension/images/icons/Elasticsearch.svg index e69de29bb..38262913e 100644 --- a/src/drivers/webextension/images/icons/Elasticsearch.svg +++ b/src/drivers/webextension/images/icons/Elasticsearch.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/drivers/webextension/images/icons/pico.svg b/src/drivers/webextension/images/icons/pico.svg index b9e533d6f..21e8fa12a 100644 --- a/src/drivers/webextension/images/icons/pico.svg +++ b/src/drivers/webextension/images/icons/pico.svg @@ -1,3 +1,3 @@ - - + + diff --git a/src/drivers/webextension/js/content.js b/src/drivers/webextension/js/content.js index 7b7a723f7..6694e7a82 100644 --- a/src/drivers/webextension/js/content.js +++ b/src/drivers/webextension/js/content.js @@ -122,11 +122,14 @@ const Content = { }, (response) => { chrome.runtime.lastError - ? reject( - new Error( - `${chrome.runtime.lastError}: Driver.${func}(${args})` + ? func === 'error' + ? resolve() + : Content.driver( + 'error', + new Error( + `${chrome.runtime.lastError}: Driver.${func}(${args})` + ) ) - ) : resolve(response) } ) diff --git a/src/drivers/webextension/manifest-safari.json b/src/drivers/webextension/manifest-safari.json index b21a490d9..4f16f0a9b 100644 --- a/src/drivers/webextension/manifest-safari.json +++ b/src/drivers/webextension/manifest-safari.json @@ -4,7 +4,7 @@ "author": "Wappalyzer", "homepage_url": "https://www.wappalyzer.com/", "description": "Identify web technologies", - "version": "6.5.20", + "version": "6.7.0", "default_locale": "en", "manifest_version": 2, "icons": { @@ -76,4 +76,4 @@ "https://*/*" ], "content_security_policy": "script-src 'self'; object-src 'self'" -} +} \ No newline at end of file diff --git a/src/drivers/webextension/manifest.json b/src/drivers/webextension/manifest.json index f6a1b76d9..46728eee4 100644 --- a/src/drivers/webextension/manifest.json +++ b/src/drivers/webextension/manifest.json @@ -4,7 +4,7 @@ "author": "Wappalyzer", "homepage_url": "https://www.wappalyzer.com/", "description": "Identify web technologies", - "version": "6.6.0", + "version": "6.7.0", "default_locale": "en", "manifest_version": 2, "icons": { diff --git a/src/package.json b/src/package.json index c2a185d36..ef8eac9f1 100644 --- a/src/package.json +++ b/src/package.json @@ -13,7 +13,7 @@ "software" ], "homepage": "https://www.wappalyzer.com/", - "version": "6.6.0", + "version": "6.7.0", "author": "Wappalyzer", "license": "MIT", "repository": { diff --git a/src/technologies.json b/src/technologies.json index 465cbbf5e..74f25f467 100644 --- a/src/technologies.json +++ b/src/technologies.json @@ -619,20 +619,6 @@ "scripts": "acsbapp?\\.com/.*/acsb\\.js", "website": "https://accessibe.com" }, - "Bookero": { - "cats": [ - 72 - ], - "description": "Bookero is online booking system for you website or Facebook page.", - "icon": "Bookero.svg", - "scripts": "cdn\\.bookero\\.pl", - "js": { - "bookero_config": "" - }, - "url": "\\.bookero\\.(?:org|pl)", - "pricing": ["low", "recurring"], - "website": "https://www.bookero.org" - }, "Accesso": { "cats": [ 6, @@ -677,34 +663,6 @@ "saas": true, "website": "https://www.acquia.com/" }, - "Elasticsearch": { - "cats": [ - 29 - ], - "description": "Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.", - "icon": "Elasticsearch.svg", - "website": "https://www.elastic.co" - }, - "Adabra": { - "cats": [ - 32 - ], - "description": "Adabra is a SaaS omnichannel marketing automation platform to help boost sales. Adabra allows you to manage user segmentation, create workflow and campaigns through email, social, SMS and more.", - "icon": "Adabra.svg", - "pricing": [ - "poa", - "recurring" - ], - "xhr": "my\\.adabra\\.com", - "js": { - "adabra_version_track": "(^.+$)\\;version:\\1", - "adabra_version_panel": "(^.+$)\\;version:\\1", - "adabraPreview": "" - }, - "scripts": "track\\.adabra\\.com", - "saas": true, - "website": "https://www.adabra.com" - }, "Act-On": { "cats": [ 32 @@ -865,6 +823,26 @@ "scripts": "\\.ada\\.support", "website": "https://www.ada.cx" }, + "Adabra": { + "cats": [ + 32 + ], + "description": "Adabra is a SaaS omnichannel marketing automation platform to help boost sales. Adabra allows you to manage user segmentation, create workflow and campaigns through email, social, SMS and more.", + "icon": "Adabra.svg", + "js": { + "adabraPreview": "", + "adabra_version_panel": "(^.+$)\\;version:\\1", + "adabra_version_track": "(^.+$)\\;version:\\1" + }, + "pricing": [ + "poa", + "recurring" + ], + "saas": true, + "scripts": "track\\.adabra\\.com", + "website": "https://www.adabra.com", + "xhr": "my\\.adabra\\.com" + }, "Adally": { "cats": [ 68 @@ -2016,27 +1994,6 @@ }, "website": "http://wicket.apache.org" }, - "STUDIO": { - "description": "STUDIO is a Japan-based company and SaaS application for designing and hosting websites. The service includes a visual editor with built-in CMS and analytics.", - "cats": [ - 51 - ], - "icon": "STUDIO.svg", - "dom": ".StudioCanvas, .publish-studio-style", - "meta": { - "generator": "^STUDIO$" - }, - "saas": true, - "pricing": ["low", "recurring", "freemium"], - "implies": [ - "Vue.js", - "Nuxt.js", - "Firebase", - "Google Cloud", - "Google Tag Manager" - ], - "website": "https://studio.design" - }, "ApexPages": { "cats": [ 51 @@ -3259,6 +3216,23 @@ "scripts": "bda\\.bookatable\\.com/deploy/lbui\\.direct\\.min\\.js", "website": "https://www.bookatable.co.uk" }, + "Bookero": { + "cats": [ + 72 + ], + "description": "Bookero is online booking system for you website or Facebook page.", + "icon": "Bookero.svg", + "js": { + "bookero_config": "" + }, + "pricing": [ + "low", + "recurring" + ], + "scripts": "cdn\\.bookero\\.pl", + "url": "\\.bookero\\.(?:org|pl)", + "website": "https://www.bookero.org" + }, "Bookingkit": { "cats": [ 5, @@ -4737,6 +4711,22 @@ "url": "\\.spaces.chec\\.io", "website": "https://www.commercejs.com" }, + "Commerce7": { + "cats": [ + 6 + ], + "description": "Commerce7 is an ecommerce platform for wineries.", + "icon": "Commerce7.svg", + "pricing": [ + "mid", + "recurring", + "payg" + ], + "saas": true, + "scripts": "cdn\\.commerce7\\.com", + "website": "https://commerce7.com", + "xhr": "api\\.commerce7\\.com" + }, "Concrete5": { "cats": [ 1 @@ -6136,6 +6126,14 @@ "url": "https?://(?:[^/]+\\.)?edgecastcdn\\.net/", "website": "http://www.edgecast.com" }, + "Elasticsearch": { + "cats": [ + 29 + ], + "description": "Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.", + "icon": "Elasticsearch.svg", + "website": "https://www.elastic.co" + }, "Elcodi": { "cats": [ 6 @@ -10063,7 +10061,10 @@ }, "html": "Kibana", "icon": "kibana.svg", - "implies": ["Node.js", "Elasticsearch"], + "implies": [ + "Node.js", + "Elasticsearch" + ], "url": "kibana#/dashboard/", "website": "http://www.elastic.co/products/kibana" }, @@ -12958,18 +12959,22 @@ 72 ], "description": "Occasion is an online booking system.", - "icon": "Occasion.png", "dom": [ "iframe[src*='app.getoccasion.com']", "a[href*='app.getoccasion.com']" ], + "icon": "Occasion.png", "js": { - "occsnMerchantToken": "", - "OCCSN.stack": "" + "OCCSN.stack": "", + "occsnMerchantToken": "" }, - "scripts": "app\\.getoccasion\\.com", + "pricing": [ + "low", + "payg", + "recurring" + ], "saas": true, - "pricing": ["low", "payg", "recurring"], + "scripts": "app\\.getoccasion\\.com", "website": "https://www.getoccasion.com" }, "Ochanoko": { @@ -15690,15 +15695,19 @@ 72 ], "description": "Reservio is a cloud-based appointment scheduling and online booking solution.", - "icon": "Reservio.svg", "dom": [ ".reservio-booking-button", "a[href*='.reservio.com'][target='_blank']", "a[href*='bookings.reservio.com']" ], - "scripts": "static\\.reservio\\.com", + "icon": "Reservio.svg", + "pricing": [ + "freemium", + "recurring", + "low" + ], "saas": true, - "pricing": ["freemium", "recurring","low"], + "scripts": "static\\.reservio\\.com", "website": "https://www.reservio.com" }, "Resin": { @@ -16279,6 +16288,31 @@ "icon": "SQLite.png", "website": "http://www.sqlite.org" }, + "STUDIO": { + "cats": [ + 51 + ], + "description": "STUDIO is a Japan-based company and SaaS application for designing and hosting websites. The service includes a visual editor with built-in CMS and analytics.", + "dom": ".StudioCanvas, .publish-studio-style", + "icon": "STUDIO.svg", + "implies": [ + "Vue.js", + "Nuxt.js", + "Firebase", + "Google Cloud", + "Google Tag Manager" + ], + "meta": { + "generator": "^STUDIO$" + }, + "pricing": [ + "low", + "recurring", + "freemium" + ], + "saas": true, + "website": "https://studio.design" + }, "SUSE": { "cats": [ 28 @@ -21855,18 +21889,6 @@ "scripts": "zkau/", "website": "http://zkoss.org" }, - "Zocdoc": { - "cats": [ - 72 - ], - "description": "Zocdoc is a New York City-based company offering an online service that allows people to find and book in-person or telemedicine appointments for medical or dental care.", - "icon": "Zocdoc.svg", - "dom": "a[href*='www.zocdoc.com'][target='_blank']", - "scripts": "offsiteschedule\\.zocdoc\\.com", - "saas": true, - "pricing": ["payg"], - "website": "https://www.zocdoc.com" - }, "ZURB Foundation": { "cats": [ 66 @@ -22048,6 +22070,20 @@ "icon": "Zipkin.png", "website": "https://zipkin.io/" }, + "Zocdoc": { + "cats": [ + 72 + ], + "description": "Zocdoc is a New York City-based company offering an online service that allows people to find and book in-person or telemedicine appointments for medical or dental care.", + "dom": "a[href*='www.zocdoc.com'][target='_blank']", + "icon": "Zocdoc.svg", + "pricing": [ + "payg" + ], + "saas": true, + "scripts": "offsiteschedule\\.zocdoc\\.com", + "website": "https://www.zocdoc.com" + }, "Zoey": { "cats": [ 6 @@ -22631,11 +22667,7 @@ "js": { "jQuery.fn.jquery": "([\\d.]+)\\;version:\\1" }, - "scripts": [ - "jquery[.-]([\\d.]*\\d)[^/]*\\.js\\;version:\\1", - "/([\\d.]+)/jquery(?:\\.min)?\\.js\\;version:\\1", - "jquery.*\\.js(?:\\?ver(?:sion)?=([\\d.]+))?\\;version:\\1" - ], + "scripts": "jquery", "website": "https://jquery.com" }, "jQuery DevBridge Autocomplete": { @@ -23561,18 +23593,6 @@ "scripts": "xcharts\\.js", "website": "https://tenxer.github.io/xcharts/" }, - "Commerce7": { - "cats": [ - 6 - ], - "description": "Commerce7 is an ecommerce platform for wineries.", - "icon": "Commerce7.svg", - "xhr": "api\\.commerce7\\.com", - "pricing": ["mid", "recurring", "payg"], - "scripts": "cdn\\.commerce7\\.com", - "saas": true, - "website": "https://commerce7.com" - }, "xtCommerce": { "cats": [ 6 diff --git a/src/wappalyzer.js b/src/wappalyzer.js index 171259af4..58f241a85 100644 --- a/src/wappalyzer.js +++ b/src/wappalyzer.js @@ -1,11 +1,7 @@ 'use strict' function next() { - return new Promise((resolve) => - (typeof setImmediate !== 'undefined' - ? setImmediate - : requestAnimationFrame)(resolve) - ) + return new Promise((resolve) => setTimeout(resolve, 0)) } function toArray(value) {