diff options
author | RaindropsSys <contact@minteck.org> | 2023-04-06 22:18:28 +0200 |
---|---|---|
committer | RaindropsSys <contact@minteck.org> | 2023-04-06 22:18:28 +0200 |
commit | 83354b2b88218090988dd6e526b0a2505b57e0f1 (patch) | |
tree | e3c73c38a122a78bb7e66fbb99056407edd9d4b9 /includes/external/addressbook/node_modules/open-graph-scraper | |
parent | 47b8f2299a483024c4a6a8876af825a010954caa (diff) | |
download | pluralconnect-83354b2b88218090988dd6e526b0a2505b57e0f1.tar.gz pluralconnect-83354b2b88218090988dd6e526b0a2505b57e0f1.tar.bz2 pluralconnect-83354b2b88218090988dd6e526b0a2505b57e0f1.zip |
Updated 5 files and added 1110 files (automated)
Diffstat (limited to 'includes/external/addressbook/node_modules/open-graph-scraper')
23 files changed, 2660 insertions, 0 deletions
diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/CHANGELOG.md b/includes/external/addressbook/node_modules/open-graph-scraper/CHANGELOG.md new file mode 100644 index 0000000..86c9e07 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/CHANGELOG.md @@ -0,0 +1,271 @@ +# Change Log + +## 5.2.3 + +- Add in declaration files for typescript users. + +## 5.2.2 + +- Specify true/false to distinguish `SuccessResult` and `ErrorResult` by `error` field. + +## 5.2.1 + +- Adding the importsNotUsedAsValues flag and fixing type import issues + +## 5.2.0 + +- Remove the `charset` lib and just use `chardet` for finding the html encoding +- Remove `peekSize` option since that was used by `charset` +- Updating the `charset` fallback to be more reliable +- Adding support for `article:published_date` and `article:modified_date` meta tags +- Updating Dependencies + +## 5.1.1 + +- Fix issue where using `import` would cause typescript errors +- Updating the `urlValidatorSettings` defaults to match `validatorjs` +- Updating Dependencies + +## 5.1.0 + +- Convert source code to typescript +- Changing `response.body` to be a `string` and `response.rawBody` to be a `buffer`. They now match the `node` type for `response`. +- Updating Dependencies + +## 5.0.5 + +- Adding `twitterImageObject` and `twitterPlayerObject` types +- Updating Dependencies + +## 5.0.4 + +- The `options.downloadLimit` type now allows for `false` +- Updating Dependencies + +## 5.0.3 + +- Adding successResult and errorResult types + +## 5.0.2 + +- TS export now has common GOT options. +- Updating Dependencies + +## 5.0.1 + +- TS export run as a Promise +- Updating Docs +- Updating Dependencies + +## 5.0.0 + +- Updating to `got` version 12! +- Adding typescript support. +- The `retry` option is now a object -> https://github.com/sindresorhus/got/blob/main/documentation/7-retry.md#retry +- The `timeout` option is now a object -> https://github.com/sindresorhus/got/blob/main/documentation/6-timeout.md#timeout-options +- Dropping callback support. If you still want to use callbacks, you can use `callbackify` -> https://nodejs.org/api/util.html#util_util_callbackify_original +- Auth errors will now be passed back to the clint and will no long just be `Page not found` errors. +- Dropping support for node12 since `got` no longer supports it. +- Removing `options.encoding`. +- Updating Dependencies + +## 4.11.1 + +- Updating Dependencies to fix a security vulnerability + +## 4.11.0 + +- Adding support for fetching the favicon +- Updating Dependencies + +## 4.10.0 + +- Adding a check for the `content-type` header, it has to contain `text/html` +- Adding `options.downloadLimit`, it sets the maximum size of the content downloaded from the server, in bytes +- Updating Dependencies + +## 4.9.2 + +- Updating Dependencies to fix a security vulnerability + +## 4.9.1 + +- Updating Dependencies to fix a security vulnerability + +## 4.9.0 + +- Dropping support for Node10 since it has reach it's end of life +- Setting response.rawBody to the parsed body since response.body is a buffer +- Updating Dependencies + +## 4.8.2 + +- Adding support for Node16 +- Updating Dependencies + +## 4.8.1 + +- Fixing bug where the title fallback would return multiple titles + +## 4.8.0 + +- Adding support for Proxies +- Updating Dependencies + +## 4.7.1 + +- Updating Dependencies to fix a security vulnerability + +## 4.7.0 + +- Adding `options.urlValidatorSettings`, it sets the options used by validator.js for testing the URL +- Updating Dependencies + +## 4.6.0 + +- Fixing issue where you would get a false positive errors with pages that have `.tar` in it like `www.target.com` +- Split extract and request into their own files +- Updating Dependencies + +## 4.5.1 + +- Fixing issue where you couldn't set the `ogImageFallback` option to false +- Fixing image type fallback so it works with arrays + +## 4.5.0 + +- Adding support for custom meta tags you want to scrape +- If ogs thinks the URL isn't a HTML page, it will return a 'Must scrape an HTML page' error. +- Updating Dependencies + +## 4.4.0 + +- Adding support for app links meta data +- Removed the `withCharset` option, you can use `onlyGetOpenGraphInfo` now if you do not want charset +- Removed the `runChar` option, this will always be turned on +- `options.encoding === null` is now deprecated +- Updating image fallback to only send back valid URLs +- Updating Dependencies + +## 4.3.1 + +- Small code clean up and adding tests +- Updating Dependencies + +## 4.3.0 + +- Adding support for request headers + +## 4.2.1 + +- Make sure item.fieldName exists before trying to use it +- Updating devDependencies +- Updating eslint rule set to be more simple +- Fixed the badge icon in the readme + +## 4.2.0 + +- Checking for new tags like article, book, profile, business and restaurant +- Adding support for Dublin Core tags! +- Updating image fallback to send back width/height/type +- Adding more title/description/locale/audio/other fallbacks +- Fixed bug where if there was a weird casing on a meta, ogs would skip it +- Will no longer return undefined values in some cases +- Updating dependencies and removed lodash + +## 4.1.1 + +- Updating to use github actions for CI! + +## 4.1.0 + +- Updating to use `validators.js`'s `isURL` to check user input URLs +- Moving snyk to be under devDependencies + +## 4.0.0 (has breaking changes!) + +- Dropping support for any node version under 10 +- Open Graph values are no longer nested in a data object. +- Stop using request.js(deprecated) and start using got.js +- Using promises will now send the error/result/response back in one object. +- Options.gzip is now options.decompress +- Options.followAllRedirects is now options.followRedirect +- Drop support for options.jar +- Options.timeout must be a number value +- Updating error messaging +- Updating dependencies + +## 3.6.2 + +- Updating lodash. + +## 3.6.1 + +- Updating dependencies to vulnerabilities. + +## 3.6.0 + +- Replaced jschardet with charde. + +## 3.5.1 + +- Updating dependencies. + +## 3.5.0 + +- Adding Open Graph music tags! + +## 3.4.0 + +- Adding a new option for the 'jar' setting for requests. It will now be turned off by default. + +## 3.3.0 + +- Code refactor to work in an es5 environment! + +## 3.2.0 + +- Website that don't have Open Graph images will now return an array of all of the images on the site + +## 3.1.5 + +- Updating lodash to fix vulnerable + +## 3.1.4 + +- Returns more info on the error occurred when using promises + +## 3.1.3 + +- Catch iconv exception to prevent unexpected charset + +## 3.1.2 + +- Checking for Open Graph price and availability info + +## 3.1.1 + +- Updating packages + +## 3.1.0 + +- Adding ability to extract meta from HTML string + +## 3.0.2 + +- Adding CHANGELOG.md + +## 3.0.1 + +- Fixing coverage reporter +- Fixing tests + +## 3.0.0 + +- Updated dependencies to their latest version(s) +- Officially now support Node.js v4 and up +- Adds unit tests to ensure code quality +- Adds options for encoding, blacklist, followAllRedirects, and maxRedirects +- Module can now be used a promise +- `err` is now `error` +- Adds check for Open Graph product info diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/LICENSE b/includes/external/addressbook/node_modules/open-graph-scraper/LICENSE new file mode 100644 index 0000000..3d02795 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2016 + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/README.md b/includes/external/addressbook/node_modules/open-graph-scraper/README.md new file mode 100644 index 0000000..c2f78df --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/README.md @@ -0,0 +1,141 @@ +# openGraphScraper + +[![Node.js CI](https://github.com/jshemas/openGraphScraper/workflows/Node.js%20CI/badge.svg?branch=master)](https://github.com/jshemas/openGraphScraper/actions?query=branch%3Amaster) +[![Known Vulnerabilities](https://snyk.io/test/github/jshemas/openGraphScraper/badge.svg)](https://snyk.io/test/github/jshemas/openGraphScraper) + +A simple node module for scraping Open Graph and Twitter Card info off a site. + +Note: `open-graph-scraper` doesn't support browser usage at this time. + +## Installation + +```bash +npm install open-graph-scraper --save +``` + +## Usage + +```javascript +const ogs = require('open-graph-scraper'); +const options = { url: 'http://ogp.me/' }; +ogs(options) + .then((data) => { + const { error, result, response } = data; + console.log('error:', error); // This returns true or false. True if there was an error. The error itself is inside the results object. + console.log('result:', result); // This contains all of the Open Graph results + console.log('response:', response); // This contains the HTML of page + }) +``` + +## Results JSON + +Check the return for a ```success``` flag. If success is set to true, then the url input was valid. Otherwise it will be set to false. The above example will return something like... + +```javascript +{ + ogTitle: 'Open Graph protocol', + ogType: 'website', + ogUrl: 'http://ogp.me/', + ogDescription: 'The Open Graph protocol enables any web page to become a rich object in a social graph.', + ogImage: { + url: 'http://ogp.me/logo.png', + width: '300', + height: '300', + type: 'image/png' + }, + requestUrl: 'http://ogp.me/', + success: true +} +``` + +## Options + +| Name | Info | Default Value | Required | +|----------------------|----------------------------------------------------------------------------|---------------|----------| +| url | URL of the site. | | x | +| html | You can pass in an HTML string to run ogs on it. (use without options.url) | | | +| blacklist | Pass in an array of sites you don't want ogs to run on. | [] | | +| onlyGetOpenGraphInfo | Only fetch open graph info and don't fall back on anything else. | false | | +| ogImageFallback | Fetch other images if no open graph ones are found. | true | | +| customMetaTags | Here you can define custom meta tags you want to scrape. | [] | | +| allMedia | By default, OGS will only send back the first image/video it finds | false | | +| downloadLimit | Maximum size of the content downloaded from the server, in bytes | 1000000 (1MB) | | +| urlValidatorSettings | Sets the options used by validator.js for testing the URL | [Here](https://github.com/jshemas/openGraphScraper/blob/master/lib/utils.js#L102-L114) | | + +Note: `open-graph-scraper` uses [got](https://github.com/sindresorhus/got) for requests and most of [got's options](https://github.com/sindresorhus/got/blob/main/documentation/2-options.md) should work as `open-graph-scraper` options. + +## Custom Meta Tag Example + +```javascript +const ogs = require('open-graph-scraper'); +const options = { + url: 'https://github.com/jshemas/openGraphScraper', + customMetaTags: [{ + multiple: false, // is there more than one of these tags on a page (normally this is false) + property: 'hostname', // meta tag name/property attribute + fieldName: 'hostnameMetaTag', // name of the result variable + }], +}; +ogs(options) + .then((data) => { + const { error, result, response } = data; + console.log('hostnameMetaTag:', result.hostnameMetaTag); // hostnameMetaTag: github.com + }) +``` + +## Proxy Example + +[Look here](https://github.com/sindresorhus/got/blob/main/documentation/tips.md#proxying) for more info on how to use proxies. + +```javascript +const ogs = require('open-graph-scraper'); +const tunnel = require('tunnel'); +const options = { + url: 'https://whatismyipaddress.com/', + timeout: { + request: 10000, + }, + agent: { + // setting proxy agent for https requests + https: tunnel.httpsOverHttp({ + // test proxies can be found here: https://hidemy.name/en/proxy-list/?country=US&type=h#list or http://free-proxy.cz/en/proxylist/country/US/https/ping/all + proxy: { + host: 'proxy_ip', + port: proxyPort, + rejectUnauthorized: false, + } + }) + } +}; +ogs(options) + .then((data) => { + const { error, result, response } = data; + console.log('response:', response); // you should see the proxy IP in here + }) +``` + +## User Agent Example + +```javascript +const ogs = require("open-graph-scraper"); +const options = { + url: "https://www.wikipedia.org/", + headers: { + "user-agent": "Googlebot/2.1 (+http://www.google.com/bot.html)", + }, +}; +ogs(options) + .then((data) => { + const { error, result, response } = data; + console.log("error:", error); // This returns true or false. True if there was an error. The error itself is inside the results object. + console.log("results:", results); // This contains all of the Open Graph results + }) +``` + +## Tests + +Then you can run the tests by running... + +```bash +npm run test +``` diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/index.d.ts b/includes/external/addressbook/node_modules/open-graph-scraper/dist/index.d.ts new file mode 100644 index 0000000..ed29970 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/index.d.ts @@ -0,0 +1,36 @@ +import type { OpenGraphScraperOptions, OgObject } from './lib/types'; +/** + * `open-graph-scraper` uses [got](https://github.com/sindresorhus/got) for requests and most of + * [got's options](https://github.com/sindresorhus/got/blob/main/documentation/2-options.md) + * should work as `open-graph-scraper` options. + * + * @param {object} options - The options used by Open Graph Scraper + * @param {string} options.url - URL of the site. (Required) + * @param {string} [options.html] - You can pass in an HTML string to run ogs on it. (use without options.url) + * @param {string[]} [options.blacklist] - Pass in an array of sites you don't want ogs to run on. + * @param {boolean} [options.onlyGetOpenGraphInfo] - Only fetch open graph info and don't fall back on anything else. + * @param {boolean} [options.ogImageFallback] - Fetch other images if no open graph ones are found. + * @param {object} [options.customMetaTags] - Here you can define custom meta tags you want to scrape. + * @param {boolean} [options.allMedia] - By default, OGS will only send back the first image/video it finds. + * @param {number | false} [options.downloadLimit] - Maximum size of the content downloaded from the server, in bytes. + * @param {object} [options.ValidatorSettings] - Sets the options used by validator.js for testing the URL + * @param {boolean} [options.decompress] - Set the accept-encoding to `gzip, deflate, br` (default: `true`). + * @param {boolean} [options.followRedirect] - Defines if redirect responses should be followed automatically. (default: `true`). + * @param {Object<string, string>} [options.headers] - An object containing request headers. Useful for setting the user-agent. + * @param {number} [options.maxRedirects] - If exceeded, the request will be aborted and a MaxRedirectsError will be thrown. (default: `10`). + * @param {object} [options.retry] - Number of times `og`s will retry the request (default: `2`). + * @param {object} [options.timeout] - Timeout of the request. + * @returns {Promise} Promise Object with the Open Graph results + */ +export default function run(options: OpenGraphScraperOptions): Promise<ErrorResult | SuccessResult>; +type SuccessResult = { + error: false; + result: OgObject; + response: object; +}; +type ErrorResult = { + error: true; + result: OgObject; + response: undefined; +}; +export {}; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/index.js b/includes/external/addressbook/node_modules/open-graph-scraper/dist/index.js new file mode 100644 index 0000000..fca5cab --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/index.js @@ -0,0 +1,56 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/* eslint-disable max-len, import/no-import-module-exports */ +const openGraphScraper_1 = require("./lib/openGraphScraper"); +/** + * `open-graph-scraper` uses [got](https://github.com/sindresorhus/got) for requests and most of + * [got's options](https://github.com/sindresorhus/got/blob/main/documentation/2-options.md) + * should work as `open-graph-scraper` options. + * + * @param {object} options - The options used by Open Graph Scraper + * @param {string} options.url - URL of the site. (Required) + * @param {string} [options.html] - You can pass in an HTML string to run ogs on it. (use without options.url) + * @param {string[]} [options.blacklist] - Pass in an array of sites you don't want ogs to run on. + * @param {boolean} [options.onlyGetOpenGraphInfo] - Only fetch open graph info and don't fall back on anything else. + * @param {boolean} [options.ogImageFallback] - Fetch other images if no open graph ones are found. + * @param {object} [options.customMetaTags] - Here you can define custom meta tags you want to scrape. + * @param {boolean} [options.allMedia] - By default, OGS will only send back the first image/video it finds. + * @param {number | false} [options.downloadLimit] - Maximum size of the content downloaded from the server, in bytes. + * @param {object} [options.ValidatorSettings] - Sets the options used by validator.js for testing the URL + * @param {boolean} [options.decompress] - Set the accept-encoding to `gzip, deflate, br` (default: `true`). + * @param {boolean} [options.followRedirect] - Defines if redirect responses should be followed automatically. (default: `true`). + * @param {Object<string, string>} [options.headers] - An object containing request headers. Useful for setting the user-agent. + * @param {number} [options.maxRedirects] - If exceeded, the request will be aborted and a MaxRedirectsError will be thrown. (default: `10`). + * @param {object} [options.retry] - Number of times `og`s will retry the request (default: `2`). + * @param {object} [options.timeout] - Timeout of the request. + * @returns {Promise} Promise Object with the Open Graph results + */ +async function run(options) { + let results; + try { + results = await (0, openGraphScraper_1.default)(options); + } + catch (error) { + const exception = error; + const returnError = { + error: true, + result: { + success: false, + requestUrl: options.url, + error: exception.message, + errorDetails: exception, + }, + response: undefined, + }; + // eslint-disable-next-line @typescript-eslint/no-throw-literal + throw returnError; + } + const returnSuccess = { + error: false, + result: results.ogObject, + response: results.response, + }; + return returnSuccess; +} +exports.default = run; +module.exports = run; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/extract.d.ts b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/extract.d.ts new file mode 100644 index 0000000..1b5cce7 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/extract.d.ts @@ -0,0 +1,10 @@ +import type { OgObject, OpenGraphScraperOptions } from './types'; +/** + * extract all of the meta tags needed for ogs + * + * @param {sting} body - the body of the got request + * @param {object} options - options for ogs + * @return {object} object with ogs results + * + */ +export default function extractMetaTags(body: string, options: OpenGraphScraperOptions, rawBody: any): OgObject; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/extract.js b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/extract.js new file mode 100644 index 0000000..cd4b802 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/extract.js @@ -0,0 +1,58 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const cheerio_1 = require("cheerio"); +const fallback_1 = require("./fallback"); +const fields_1 = require("./fields"); +const media = require("./media"); +const utils = require("./utils"); +/** + * extract all of the meta tags needed for ogs + * + * @param {sting} body - the body of the got request + * @param {object} options - options for ogs + * @return {object} object with ogs results + * + */ +function extractMetaTags(body, options, rawBody) { + let ogObject = {}; + const $ = (0, cheerio_1.load)(body); + const metaFields = fields_1.default.concat(options.customMetaTags); + // find all of the open graph info in the meta tags + $('meta').each((index, meta) => { + if (!meta.attribs || (!meta.attribs.property && !meta.attribs.name)) + return; + const property = meta.attribs.property || meta.attribs.name; + const content = meta.attribs.content || meta.attribs.value; + metaFields.forEach((item) => { + if (item && property.toLowerCase() === item.property.toLowerCase()) { + if (!item.multiple) { + ogObject[item.fieldName] = content; + } + else if (!ogObject[item.fieldName]) { + ogObject[item.fieldName] = [content]; + } + else if (Array.isArray(ogObject[item.fieldName])) { + ogObject[item.fieldName].push(content); + } + } + }); + }); + // set ogImage to ogImageSecureURL/ogImageURL if there is no ogImage + if (!ogObject.ogImage && ogObject.ogImageSecureURL) { + ogObject.ogImage = ogObject.ogImageSecureURL; + } + else if (!ogObject.ogImage && ogObject.ogImageURL) { + ogObject.ogImage = ogObject.ogImageURL; + } + // formats the multiple media values + ogObject = media.mediaSetup(ogObject, options); + // if onlyGetOpenGraphInfo isn't set, run the open graph fallbacks + if (!options.onlyGetOpenGraphInfo) { + ogObject = (0, fallback_1.default)(ogObject, options, $, rawBody); + } + // TODO: Is this still needed? + // removes any undefs + ogObject = utils.removeNestedUndefinedValues(ogObject); + return ogObject; +} +exports.default = extractMetaTags; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fallback.d.ts b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fallback.d.ts new file mode 100644 index 0000000..b349e24 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fallback.d.ts @@ -0,0 +1,12 @@ +import type { OpenGraphScraperOptions } from './types'; +/** + * ogs fallbacks + * + * @param {object} ogObject - the current ogObject + * @param {object} options - options for ogs + * @param {object} $ - cheerio.load() of the current html + * @return {object} object with ogs results with updated fallback values + * + */ +export declare function fallback(ogObject: any, options: OpenGraphScraperOptions, $: any, rawBody: any): any; +export default fallback; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fallback.js b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fallback.js new file mode 100644 index 0000000..92eaa61 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fallback.js @@ -0,0 +1,198 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.fallback = void 0; +const chardet_1 = require("chardet"); +const utils_1 = require("./utils"); +const doesElementExist = (selector, attribute, $) => ($(selector).attr(attribute) && $(selector).attr(attribute).length > 0); +/** + * ogs fallbacks + * + * @param {object} ogObject - the current ogObject + * @param {object} options - options for ogs + * @param {object} $ - cheerio.load() of the current html + * @return {object} object with ogs results with updated fallback values + * + */ +function fallback(ogObject, options, $, rawBody) { + // title fallback + if (!ogObject.ogTitle) { + if ($('title').text() && $('title').text().length > 0) { + ogObject.ogTitle = $('title').first().text(); + } + else if ($('head > meta[name="title"]').attr('content') && $('head > meta[name="title"]').attr('content').length > 0) { + ogObject.ogTitle = $('head > meta[name="title"]').attr('content'); + } + else if ($('.post-title').text() && $('.post-title').text().length > 0) { + ogObject.ogTitle = $('.post-title').text(); + } + else if ($('.entry-title').text() && $('.entry-title').text().length > 0) { + ogObject.ogTitle = $('.entry-title').text(); + } + else if ($('h1[class*="title" i] a').text() && $('h1[class*="title" i] a').text().length > 0) { + ogObject.ogTitle = $('h1[class*="title" i] a').text(); + } + else if ($('h1[class*="title" i]').text() && $('h1[class*="title" i]').text().length > 0) { + ogObject.ogTitle = $('h1[class*="title" i]').text(); + } + } + // Get meta description tag if og description was not provided + if (!ogObject.ogDescription) { + if (doesElementExist('head > meta[name="description"]', 'content', $)) { + ogObject.ogDescription = $('head > meta[name="description"]').attr('content'); + } + else if (doesElementExist('head > meta[itemprop="description"]', 'content', $)) { + ogObject.ogDescription = $('head > meta[itemprop="description"]').attr('content'); + } + else if ($('#description').text() && $('#description').text().length > 0) { + ogObject.ogDescription = $('#description').text(); + } + } + // Get all of images if there is no og:image info + if (!ogObject.ogImage && options.ogImageFallback) { + ogObject.ogImage = []; + $('img').map((index, imageElement) => { + if (doesElementExist(imageElement, 'src', $)) { + const source = $(imageElement).attr('src'); + const type = (0, utils_1.findImageTypeFromUrl)(source); + if (!(0, utils_1.isUrlValid)(source, options.urlValidatorSettings) || !(0, utils_1.isImageTypeValid)(type)) + return false; + ogObject.ogImage.push({ + url: source, + width: $(imageElement).attr('width') || null, + height: $(imageElement).attr('height') || null, + type, + }); + } + return false; + }); + if (ogObject.ogImage.length === 0) + delete ogObject.ogImage; + } + else if (ogObject.ogImage) { + // if there isn't a type, try to pull it from the URL + if (Array.isArray(ogObject.ogImage)) { + ogObject.ogImage.map((image) => { + if (image.url && !image.type) { + const type = (0, utils_1.findImageTypeFromUrl)(image.url); + if ((0, utils_1.isImageTypeValid)(type)) + image.type = type; + } + return false; + }); + } + else if (ogObject.ogImage.url && !ogObject.ogImage.type) { + const type = (0, utils_1.findImageTypeFromUrl)(ogObject.ogImage.url); + if ((0, utils_1.isImageTypeValid)(type)) + ogObject.ogImage.type = type; + } + } + // audio fallback + if (!ogObject.ogAudioURL && !ogObject.ogAudioSecureURL) { + const audioElementValue = $('audio').attr('src'); + const audioSourceElementValue = $('audio > source').attr('src'); + if (doesElementExist('audio', 'src', $)) { + if (audioElementValue.startsWith('https')) { + ogObject.ogAudioSecureURL = audioElementValue; + } + else { + ogObject.ogAudioURL = audioElementValue; + } + const audioElementTypeValue = $('audio').attr('type'); + if (!ogObject.ogAudioType && doesElementExist('audio', 'type', $)) + ogObject.ogAudioType = audioElementTypeValue; + } + else if (doesElementExist('audio > source', 'src', $)) { + if (audioSourceElementValue.startsWith('https')) { + ogObject.ogAudioSecureURL = audioSourceElementValue; + } + else { + ogObject.ogAudioURL = audioSourceElementValue; + } + const audioSourceElementTypeValue = $('audio > source').attr('type'); + if (!ogObject.ogAudioType && doesElementExist('audio > source', 'type', $)) + ogObject.ogAudioType = audioSourceElementTypeValue; + } + } + // locale fallback + if (!ogObject.ogLocale) { + if (doesElementExist('html', 'lang', $)) { + ogObject.ogLocale = $('html').attr('lang'); + } + else if (doesElementExist('head > meta[itemprop="inLanguage"]', 'content', $)) { + ogObject.ogLocale = $('head > meta[itemprop="inLanguage"]').attr('content'); + } + } + // logo fallback + if (!ogObject.ogLogo) { + if (doesElementExist('meta[itemprop="logo"]', 'content', $)) { + ogObject.ogLogo = $('meta[itemprop="logo"]').attr('content'); + } + else if (doesElementExist('img[itemprop="logo"]', 'src', $)) { + ogObject.ogLogo = $('img[itemprop="logo"]').attr('src'); + } + } + // url fallback + if (!ogObject.ogUrl) { + if (doesElementExist('link[rel="canonical"]', 'href', $)) { + ogObject.ogUrl = $('link[rel="canonical"]').attr('href'); + } + else if (doesElementExist('link[rel="alternate"][hreflang="x-default"]', 'href', $)) { + ogObject.ogUrl = $('link[rel="alternate"][hreflang="x-default"]').attr('href'); + } + } + // date fallback + if (!ogObject.ogDate) { + if (doesElementExist('head > meta[name="date"]', 'content', $)) { + ogObject.ogDate = $('head > meta[name="date"]').attr('content'); + } + else if (doesElementExist('[itemprop*="datemodified" i]', 'content', $)) { + ogObject.ogDate = $('[itemprop*="datemodified" i]').attr('content'); + } + else if (doesElementExist('[itemprop="datepublished" i]', 'content', $)) { + ogObject.ogDate = $('[itemprop="datepublished" i]').attr('content'); + } + else if (doesElementExist('[itemprop*="date" i]', 'content', $)) { + ogObject.ogDate = $('[itemprop*="date" i]').attr('content'); + } + else if (doesElementExist('time[itemprop*="date" i]', 'datetime', $)) { + ogObject.ogDate = $('time[itemprop*="date" i]').attr('datetime'); + } + else if (doesElementExist('time[datetime]', 'datetime', $)) { + ogObject.ogDate = $('time[datetime]').attr('datetime'); + } + } + // favicon fallback + if (!ogObject.favicon) { + if (doesElementExist('link[rel="shortcut icon"]', 'href', $)) { + ogObject.favicon = $('link[rel="shortcut icon"]').attr('href'); + } + else if (doesElementExist('link[rel="icon"]', 'href', $)) { + ogObject.favicon = $('link[rel="icon"]').attr('href'); + } + else if (doesElementExist('link[rel="mask-icon"]', 'href', $)) { + ogObject.favicon = $('link[rel="mask-icon"]').attr('href'); + } + else if (doesElementExist('link[rel="apple-touch-icon"]', 'href', $)) { + ogObject.favicon = $('link[rel="apple-touch-icon"]').attr('href'); + } + else if (doesElementExist('link[type="image/png"]', 'href', $)) { + ogObject.favicon = $('link[type="image/png"]').attr('href'); + } + else if (doesElementExist('link[type="image/ico"]', 'href', $)) { + ogObject.favicon = $('link[type="image/ico"]').attr('href'); + } + else if (doesElementExist('link[type="image/x-icon"]', 'href', $)) { + ogObject.favicon = $('link[type="image/x-icon"]').attr('href'); + } + } + // set the charset + if (doesElementExist('meta', 'charset', $)) { + ogObject.charset = $('meta').attr('charset'); + } + else if (rawBody) { + ogObject.charset = chardet_1.default.detect(rawBody); + } + return ogObject; +} +exports.fallback = fallback; +exports.default = fallback; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fields.d.ts b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fields.d.ts new file mode 100644 index 0000000..9084b8d --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fields.d.ts @@ -0,0 +1,12 @@ +/** + * array of meta tags ogs is looking for + * + * @return {array} array of meta tags + * + */ +declare const fields: { + multiple: boolean; + property: string; + fieldName: string; +}[]; +export default fields; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fields.js b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fields.js new file mode 100644 index 0000000..c17d467 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/fields.js @@ -0,0 +1,856 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * array of meta tags ogs is looking for + * + * @return {array} array of meta tags + * + */ +const fields = [ + { + multiple: false, + property: 'og:title', + fieldName: 'ogTitle', + }, + { + multiple: false, + property: 'og:type', + fieldName: 'ogType', + }, + { + multiple: false, + property: 'og:logo', + fieldName: 'ogLogo', + }, + { + multiple: true, + property: 'og:image', + fieldName: 'ogImage', + }, + { + multiple: true, + property: 'og:image:url', + fieldName: 'ogImageURL', + }, + { + multiple: true, + property: 'og:image:secure_url', + fieldName: 'ogImageSecureURL', + }, + { + multiple: true, + property: 'og:image:width', + fieldName: 'ogImageWidth', + }, + { + multiple: true, + property: 'og:image:height', + fieldName: 'ogImageHeight', + }, + { + multiple: true, + property: 'og:image:type', + fieldName: 'ogImageType', + }, + { + multiple: false, + property: 'og:url', + fieldName: 'ogUrl', + }, + { + multiple: false, + property: 'og:audio', + fieldName: 'ogAudio', + }, + { + multiple: false, + property: 'og:audio:url', + fieldName: 'ogAudioURL', + }, + { + multiple: false, + property: 'og:audio:secure_url', + fieldName: 'ogAudioSecureURL', + }, + { + multiple: false, + property: 'og:audio:type', + fieldName: 'ogAudioType', + }, + { + multiple: false, + property: 'og:description', + fieldName: 'ogDescription', + }, + { + multiple: false, + property: 'og:determiner', + fieldName: 'ogDeterminer', + }, + { + multiple: false, + property: 'og:locale', + fieldName: 'ogLocale', + }, + { + multiple: false, + property: 'og:locale:alternate', + fieldName: 'ogLocaleAlternate', + }, + { + multiple: false, + property: 'og:site_name', + fieldName: 'ogSiteName', + }, + { + multiple: false, + property: 'og:product:retailer_item_id', + fieldName: 'ogProductRetailerItemId', + }, + { + multiple: false, + property: 'og:product:price:amount', + fieldName: 'ogProductPriceAmount', + }, + { + multiple: false, + property: 'og:product:price:currency', + fieldName: 'ogProductPriceCurrency', + }, + { + multiple: false, + property: 'og:product:availability', + fieldName: 'ogProductAvailability', + }, + { + multiple: false, + property: 'og:product:condition', + fieldName: 'ogProductCondition', + }, + { + multiple: false, + property: 'og:price:amount', + fieldName: 'ogPriceAmount', + }, + { + multiple: false, + property: 'og:price:currency', + fieldName: 'ogPriceCurrency', + }, + { + multiple: false, + property: 'og:availability', + fieldName: 'ogAvailability', + }, + { + multiple: true, + property: 'og:video', + fieldName: 'ogVideo', + }, + { + multiple: true, + property: 'og:video:url', + fieldName: 'ogVideo', + }, + { + multiple: true, + property: 'og:video:secure_url', + fieldName: 'ogVideoSecureURL', + }, + { + multiple: true, + property: 'og:video:actor:id', + fieldName: 'ogVideoActorId', + }, + { + multiple: true, + property: 'og:video:width', + fieldName: 'ogVideoWidth', + }, + { + multiple: true, + property: 'og:video:height', + fieldName: 'ogVideoHeight', + }, + { + multiple: true, + property: 'og:video:type', + fieldName: 'ogVideoType', + }, + { + multiple: false, + property: 'twitter:card', + fieldName: 'twitterCard', + }, + { + multiple: false, + property: 'twitter:url', + fieldName: 'twitterUrl', + }, + { + multiple: false, + property: 'twitter:site', + fieldName: 'twitterSite', + }, + { + multiple: false, + property: 'twitter:site:id', + fieldName: 'twitterSiteId', + }, + { + multiple: false, + property: 'twitter:creator', + fieldName: 'twitterCreator', + }, + { + multiple: false, + property: 'twitter:creator:id', + fieldName: 'twitterCreatorId', + }, + { + multiple: false, + property: 'twitter:title', + fieldName: 'twitterTitle', + }, + { + multiple: false, + property: 'twitter:description', + fieldName: 'twitterDescription', + }, + { + multiple: true, + property: 'twitter:image', + fieldName: 'twitterImage', + }, + { + multiple: true, + property: 'twitter:image:height', + fieldName: 'twitterImageHeight', + }, + { + multiple: true, + property: 'twitter:image:width', + fieldName: 'twitterImageWidth', + }, + { + multiple: true, + property: 'twitter:image:src', + fieldName: 'twitterImageSrc', + }, + { + multiple: true, + property: 'twitter:image:alt', + fieldName: 'twitterImageAlt', + }, + { + multiple: true, + property: 'twitter:player', + fieldName: 'twitterPlayer', + }, + { + multiple: true, + property: 'twitter:player:width', + fieldName: 'twitterPlayerWidth', + }, + { + multiple: true, + property: 'twitter:player:height', + fieldName: 'twitterPlayerHeight', + }, + { + multiple: true, + property: 'twitter:player:stream', + fieldName: 'twitterPlayerStream', + }, + { + multiple: true, + property: 'twitter:player:stream:content_type', + fieldName: 'twitterPlayerStreamContentType', + }, + { + multiple: false, + property: 'twitter:app:name:iphone', + fieldName: 'twitterAppNameiPhone', + }, + { + multiple: false, + property: 'twitter:app:id:iphone', + fieldName: 'twitterAppIdiPhone', + }, + { + multiple: false, + property: 'twitter:app:url:iphone', + fieldName: 'twitterAppUrliPhone', + }, + { + multiple: false, + property: 'twitter:app:name:ipad', + fieldName: 'twitterAppNameiPad', + }, + { + multiple: false, + property: 'twitter:app:id:ipad', + fieldName: 'twitterAppIdiPad', + }, + { + multiple: false, + property: 'twitter:app:url:ipad', + fieldName: 'twitterAppUrliPad', + }, + { + multiple: false, + property: 'twitter:app:name:googleplay', + fieldName: 'twitterAppNameGooglePlay', + }, + { + multiple: false, + property: 'twitter:app:id:googleplay', + fieldName: 'twitterAppIdGooglePlay', + }, + { + multiple: false, + property: 'twitter:app:url:googleplay', + fieldName: 'twitterAppUrlGooglePlay', + }, + { + multiple: true, + property: 'music:song', + fieldName: 'musicSong', + }, + { + multiple: true, + property: 'music:song:disc', + fieldName: 'musicSongDisc', + }, + { + multiple: true, + property: 'music:song:track', + fieldName: 'musicSongTrack', + }, + { + multiple: true, + property: 'music:song:url', + fieldName: 'musicSongUrl', + }, + { + multiple: true, + property: 'music:musician', + fieldName: 'musicMusician', + }, + { + multiple: false, + property: 'music:release_date', + fieldName: 'musicReleaseDate', + }, + { + multiple: false, + property: 'music:duration', + fieldName: 'musicDuration', + }, + { + multiple: true, + property: 'music:creator', + fieldName: 'musicCreator', + }, + { + multiple: true, + property: 'music:album', + fieldName: 'musicAlbum', + }, + { + multiple: false, + property: 'music:album:disc', + fieldName: 'musicAlbumDisc', + }, + { + multiple: false, + property: 'music:album:track', + fieldName: 'musicAlbumTrack', + }, + { + multiple: false, + property: 'music:album:url', + fieldName: 'musicAlbumUrl', + }, + { + multiple: false, + property: 'article:published_date', + fieldName: 'articlePublishedDate', + }, + { + multiple: false, + property: 'article:published_time', + fieldName: 'articlePublishedTime', + }, + { + multiple: false, + property: 'article:modified_date', + fieldName: 'articleModifiedDate', + }, + { + multiple: false, + property: 'article:modified_time', + fieldName: 'articleModifiedTime', + }, + { + multiple: false, + property: 'article:expiration_time', + fieldName: 'articleExpirationTime', + }, + { + multiple: false, + property: 'article:author', + fieldName: 'articleAuthor', + }, + { + multiple: false, + property: 'article:section', + fieldName: 'articleSection', + }, + { + multiple: false, + property: 'article:tag', + fieldName: 'articleTag', + }, + { + multiple: false, + property: 'article:publisher', + fieldName: 'articlePublisher', + }, + { + multiple: false, + property: 'og:article:published_time', + fieldName: 'ogArticlePublishedTime', + }, + { + multiple: false, + property: 'og:article:modified_time', + fieldName: 'ogArticleModifiedTime', + }, + { + multiple: false, + property: 'og:article:expiration_time', + fieldName: 'ogArticleExpirationTime', + }, + { + multiple: false, + property: 'og:article:author', + fieldName: 'ogArticleAuthor', + }, + { + multiple: false, + property: 'og:article:section', + fieldName: 'ogArticleSection', + }, + { + multiple: false, + property: 'og:article:tag', + fieldName: 'ogArticleTag', + }, + { + multiple: false, + property: 'og:article:publisher', + fieldName: 'ogArticlePublisher', + }, + { + multiple: false, + property: 'books:book', + fieldName: 'booksBook', + }, + { + multiple: false, + property: 'book:author', + fieldName: 'bookAuthor', + }, + { + multiple: false, + property: 'book:isbn', + fieldName: 'bookIsbn', + }, + { + multiple: false, + property: 'book:release_date', + fieldName: 'bookReleaseDate', + }, + { + multiple: false, + property: 'book:canonical_name', + fieldName: 'bookCanonicalName', + }, + { + multiple: false, + property: 'book:tag', + fieldName: 'bookTag', + }, + { + multiple: false, + property: 'books:rating:value', + fieldName: 'booksRatingValue', + }, + { + multiple: false, + property: 'books:rating:scale', + fieldName: 'booksRatingScale', + }, + { + multiple: false, + property: 'profile:first_name', + fieldName: 'profileFirstName', + }, + { + multiple: false, + property: 'profile:last_name', + fieldName: 'profileLastName', + }, + { + multiple: false, + property: 'profile:username', + fieldName: 'profileUsername', + }, + { + multiple: false, + property: 'profile:gender', + fieldName: 'profileGender', + }, + { + multiple: false, + property: 'business:contact_data:street_address', + fieldName: 'businessContactDataStreetAddress', + }, + { + multiple: false, + property: 'business:contact_data:locality', + fieldName: 'businessContactDataLocality', + }, + { + multiple: false, + property: 'business:contact_data:region', + fieldName: 'businessContactDataRegion', + }, + { + multiple: false, + property: 'business:contact_data:postal_code', + fieldName: 'businessContactDataPostalCode', + }, + { + multiple: false, + property: 'business:contact_data:country_name', + fieldName: 'businessContactDataCountryName', + }, + { + multiple: false, + property: 'restaurant:menu', + fieldName: 'restaurantMenu', + }, + { + multiple: false, + property: 'restaurant:restaurant', + fieldName: 'restaurantRestaurant', + }, + { + multiple: false, + property: 'restaurant:section', + fieldName: 'restaurantSection', + }, + { + multiple: false, + property: 'restaurant:variation:price:amount', + fieldName: 'restaurantVariationPriceAmount', + }, + { + multiple: false, + property: 'restaurant:variation:price:currency', + fieldName: 'restaurantVariationPriceCurrency', + }, + { + multiple: false, + property: 'restaurant:contact_info:website', + fieldName: 'restaurantContactInfoWebsite', + }, + { + multiple: false, + property: 'restaurant:contact_info:street_address', + fieldName: 'restaurantContactInfoStreetAddress', + }, + { + multiple: false, + property: 'restaurant:contact_info:locality', + fieldName: 'restaurantContactInfoLocality', + }, + { + multiple: false, + property: 'restaurant:contact_info:region', + fieldName: 'restaurantContactInfoRegion', + }, + { + multiple: false, + property: 'restaurant:contact_info:postal_code', + fieldName: 'restaurantContactInfoPostalCode', + }, + { + multiple: false, + property: 'restaurant:contact_info:country_name', + fieldName: 'restaurantContactInfoCountryName', + }, + { + multiple: false, + property: 'restaurant:contact_info:email', + fieldName: 'restaurantContactInfoEmail', + }, + { + multiple: false, + property: 'restaurant:contact_info:phone_number', + fieldName: 'restaurantContactInfoPhoneNumber', + }, + { + multiple: false, + property: 'place:location:latitude', + fieldName: 'placeLocationLatitude', + }, + { + multiple: false, + property: 'place:location:longitude', + fieldName: 'placeLocationLongitude', + }, + { + multiple: false, + property: 'og:date', + fieldName: 'ogDate', + }, + { + multiple: false, + property: 'author', + fieldName: 'author', + }, + { + multiple: false, + property: 'updated_time', + fieldName: 'updatedTime', + }, + { + multiple: false, + property: 'modified_time', + fieldName: 'modifiedTime', + }, + { + multiple: false, + property: 'published_time', + fieldName: 'publishedTime', + }, + { + multiple: false, + property: 'release_date', + fieldName: 'releaseDate', + }, + { + multiple: false, + property: 'dc.source', + fieldName: 'dcSource', + }, + { + multiple: false, + property: 'dc.subject', + fieldName: 'dcSubject', + }, + { + multiple: false, + property: 'dc.title', + fieldName: 'dcTitle', + }, + { + multiple: false, + property: 'dc.type', + fieldName: 'dcType', + }, + { + multiple: false, + property: 'dc.creator', + fieldName: 'dcCreator', + }, + { + multiple: false, + property: 'dc.coverage', + fieldName: 'dcCoverage', + }, + { + multiple: false, + property: 'dc.language', + fieldName: 'dcLanguage', + }, + { + multiple: false, + property: 'dc.contributor', + fieldName: 'dcContributor', + }, + { + multiple: false, + property: 'dc.date', + fieldName: 'dcDate', + }, + { + multiple: false, + property: 'dc.date.issued', + fieldName: 'dcDateIssued', + }, + { + multiple: false, + property: 'dc.date.created', + fieldName: 'dcDateCreated', + }, + { + multiple: false, + property: 'dc.description', + fieldName: 'dcDescription', + }, + { + multiple: false, + property: 'dc.identifier', + fieldName: 'dcIdentifier', + }, + { + multiple: false, + property: 'dc.publisher', + fieldName: 'dcPublisher', + }, + { + multiple: false, + property: 'dc.rights', + fieldName: 'dcRights', + }, + { + multiple: false, + property: 'dc.relation', + fieldName: 'dcRelation', + }, + { + multiple: false, + property: 'dc.format.media', + fieldName: 'dcFormatMedia', + }, + { + multiple: false, + property: 'dc.format.size', + fieldName: 'dcFormatSize', + }, + { + multiple: false, + property: 'al:ios:url', + fieldName: 'alIosUrl', + }, + { + multiple: false, + property: 'al:ios:app_store_id', + fieldName: 'alIosAppStoreId', + }, + { + multiple: false, + property: 'al:ios:app_name', + fieldName: 'alIosAppName', + }, + { + multiple: false, + property: 'al:iphone:url', + fieldName: 'alIphoneUrl', + }, + { + multiple: false, + property: 'al:iphone:app_store_id', + fieldName: 'alIphoneAppStoreId', + }, + { + multiple: false, + property: 'al:iphone:app_name', + fieldName: 'alIphoneAppName', + }, + { + multiple: false, + property: 'al:ipad:url', + fieldName: 'alIpadUrl', + }, + { + multiple: false, + property: 'al:ipad:app_store_id', + fieldName: 'alIpadAppStoreId', + }, + { + multiple: false, + property: 'al:ipad:app_name', + fieldName: 'alIpadAppName', + }, + { + multiple: false, + property: 'al:android:url', + fieldName: 'alAndroidUrl', + }, + { + multiple: false, + property: 'al:android:package', + fieldName: 'alAndroidPackage', + }, + { + multiple: false, + property: 'al:android:class', + fieldName: 'alAndroidClass', + }, + { + multiple: false, + property: 'al:android:app_name', + fieldName: 'alAndroidAppName', + }, + { + multiple: false, + property: 'al:windows_phone:url', + fieldName: 'alWindowsPhoneUrl', + }, + { + multiple: false, + property: 'al:windows_phone:app_id', + fieldName: 'alWindowsPhoneAppId', + }, + { + multiple: false, + property: 'al:windows_phone:app_name', + fieldName: 'alWindowsPhoneAppName', + }, + { + multiple: false, + property: 'al:windows:url', + fieldName: 'alWindowsUrl', + }, + { + multiple: false, + property: 'al:windows:app_id', + fieldName: 'alWindowsAppId', + }, + { + multiple: false, + property: 'al:windows:app_name', + fieldName: 'alWindowsAppName', + }, + { + multiple: false, + property: 'al:windows_universal:url', + fieldName: 'alWindowsUniversalUrl', + }, + { + multiple: false, + property: 'al:windows_universal:app_id', + fieldName: 'alWindowsUniversalAppId', + }, + { + multiple: false, + property: 'al:windows_universal:app_name', + fieldName: 'alWindowsUniversalAppName', + }, + { + multiple: false, + property: 'al:web:url', + fieldName: 'alWebUrl', + }, + { + multiple: false, + property: 'al:web:should_fallback', + fieldName: 'alWebShouldFallback', + }, +]; +exports.default = fields; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/media.d.ts b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/media.d.ts new file mode 100644 index 0000000..4970468 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/media.d.ts @@ -0,0 +1,11 @@ +import type { OgObject, OpenGraphScraperOptions } from './types'; +/** + * formats the multiple media values + * + * @param {object} ogObject - the current ogObject + * @param {object} options - options for ogs + * @return {object} object with ogs results with updated media values + * + */ +export declare function mediaSetup(ogObject: OgObject, options: OpenGraphScraperOptions): OgObject; +export default mediaSetup; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/media.js b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/media.js new file mode 100644 index 0000000..c2dc885 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/media.js @@ -0,0 +1,163 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.mediaSetup = void 0; +const fields_1 = require("./fields"); +const mediaMapperTwitterImage = (item) => ({ + alt: item[3], + height: item[2], + url: item[0], + width: item[1], +}); +const mediaMapperTwitterPlayer = (item) => ({ + height: item[2], + stream: item[3], + url: item[0], + width: item[1], +}); +const mediaMapperMusicSong = (item) => ({ + disc: item[2], + track: item[1], + url: item[0], +}); +const mediaMapper = (item) => ({ + height: item[2], + type: item[3], + url: item[0], + width: item[1], +}); +const mediaSorter = (a, b) => { + if (!(a.url && b.url)) { + return 0; + } + const aRes = a.url.match(/\.(\w{2,5})$/); + const aExt = (aRes && aRes[1].toLowerCase()) || null; + const bRes = b.url.match(/\.(\w{2,5})$/); + const bExt = (bRes && bRes[1].toLowerCase()) || null; + if (aExt === 'gif' && bExt !== 'gif') { + return -1; + } + if (aExt !== 'gif' && bExt === 'gif') { + return 1; + } + return Math.max(b.width, b.height) - Math.max(a.width, a.height); +}; +const mediaSorterMusicSong = (a, b) => { + if (!(a.track && b.track)) { + return 0; + } + if (a.disc > b.disc) { + return 1; + } + if (a.disc < b.disc) { + return -1; + } + return a.track - b.track; +}; +// lodash zip replacement +const zip = (array, ...args) => { + if (array === undefined) + return []; + return array + .map((value, idx) => [value, ...args.map((arr) => arr[idx])]); +}; +/** + * formats the multiple media values + * + * @param {object} ogObject - the current ogObject + * @param {object} options - options for ogs + * @return {object} object with ogs results with updated media values + * + */ +function mediaSetup(ogObject, options) { + // sets ogImage image/width/height/type to null if one these exists + if (ogObject.ogImage || ogObject.ogImageWidth || ogObject.ogImageHeight || ogObject.ogImageType) { + ogObject.ogImage = ogObject.ogImage ? ogObject.ogImage : [null]; + ogObject.ogImageWidth = ogObject.ogImageWidth ? ogObject.ogImageWidth : [null]; + ogObject.ogImageHeight = ogObject.ogImageHeight ? ogObject.ogImageHeight : [null]; + ogObject.ogImageType = ogObject.ogImageType ? ogObject.ogImageType : [null]; + } + // format images + const ogImages = zip(ogObject.ogImage, ogObject.ogImageWidth, ogObject.ogImageHeight, ogObject.ogImageType) + .map(mediaMapper) + .sort(mediaSorter); + // sets ogVideo video/width/height/type to null if one these exists + if (ogObject.ogVideo || ogObject.ogVideoWidth || ogObject.ogVideoHeight || ogObject.ogVideoType) { + ogObject.ogVideo = ogObject.ogVideo ? ogObject.ogVideo : [null]; + ogObject.ogVideoWidth = ogObject.ogVideoWidth ? ogObject.ogVideoWidth : [null]; + ogObject.ogVideoHeight = ogObject.ogVideoHeight ? ogObject.ogVideoHeight : [null]; + ogObject.ogVideoType = ogObject.ogVideoType ? ogObject.ogVideoType : [null]; + } + // format videos + const ogVideos = zip(ogObject.ogVideo, ogObject.ogVideoWidth, ogObject.ogVideoHeight, ogObject.ogVideoType) + .map(mediaMapper) + .sort(mediaSorter); + // sets twitter image image/width/height/type to null if one these exists + if (ogObject.twitterImageSrc + || ogObject.twitterImage + || ogObject.twitterImageWidth + || ogObject.twitterImageHeight + || ogObject.twitterImageAlt) { + ogObject.twitterImageSrc = ogObject.twitterImageSrc ? ogObject.twitterImageSrc : [null]; + ogObject.twitterImage = ogObject.twitterImage ? ogObject.twitterImage : ogObject.twitterImageSrc; // deafult to twitterImageSrc + ogObject.twitterImageWidth = ogObject.twitterImageWidth ? ogObject.twitterImageWidth : [null]; + ogObject.twitterImageHeight = ogObject.twitterImageHeight ? ogObject.twitterImageHeight : [null]; + ogObject.twitterImageAlt = ogObject.twitterImageAlt ? ogObject.twitterImageAlt : [null]; + } + // format twitter images + const twitterImages = zip(ogObject.twitterImage, ogObject.twitterImageWidth, ogObject.twitterImageHeight, ogObject.twitterImageAlt).map(mediaMapperTwitterImage).sort(mediaSorter); + // sets twitter player/width/height/stream to null if one these exists + if (ogObject.twitterPlayer + || ogObject.twitterPlayerWidth + || ogObject.twitterPlayerHeight + || ogObject.twitterPlayerStream) { + ogObject.twitterPlayer = ogObject.twitterPlayer ? ogObject.twitterPlayer : [null]; + ogObject.twitterPlayerWidth = ogObject.twitterPlayerWidth ? ogObject.twitterPlayerWidth : [null]; + ogObject.twitterPlayerHeight = ogObject.twitterPlayerHeight ? ogObject.twitterPlayerHeight : [null]; + ogObject.twitterPlayerStream = ogObject.twitterPlayerStream ? ogObject.twitterPlayerStream : [null]; + } + // format twitter player + const twitterPlayers = zip(ogObject.twitterPlayer, ogObject.twitterPlayerWidth, ogObject.twitterPlayerHeight, ogObject.twitterPlayerStream).map(mediaMapperTwitterPlayer) + .sort(mediaSorter); + // sets music song/songTrack/songDisc to null if one these exists + if (ogObject.musicSong || ogObject.musicSongTrack || ogObject.musicSongDisc) { + ogObject.musicSong = ogObject.musicSong ? ogObject.musicSong : [null]; + ogObject.musicSongTrack = ogObject.musicSongTrack ? ogObject.musicSongTrack : [null]; + ogObject.musicSongDisc = ogObject.musicSongDisc ? ogObject.musicSongDisc : [null]; + } + // format music songs + const musicSongs = zip(ogObject.musicSong, ogObject.musicSongTrack, ogObject.musicSongDisc) + .map(mediaMapperMusicSong) + .sort(mediaSorterMusicSong); + // remove old values since everything will live under the main property + fields_1.default.filter((item) => (item.multiple && item.fieldName && item.fieldName.match('(ogImage|ogVideo|twitter|musicSong).*'))) + .forEach((item) => { + delete ogObject[item.fieldName]; + }); + if (options.allMedia) { + if (ogImages.length) + ogObject.ogImage = ogImages; + if (ogVideos.length) + ogObject.ogVideo = ogVideos; + if (twitterImages.length) + ogObject.twitterImage = twitterImages; + if (twitterPlayers.length) + ogObject.twitterPlayer = twitterPlayers; + if (musicSongs.length) + ogObject.musicSong = musicSongs; + } + else { + if (ogImages.length) + [ogObject.ogImage] = ogImages; + if (ogVideos.length) + [ogObject.ogVideo] = ogVideos; + if (twitterImages.length) + [ogObject.twitterImage] = twitterImages; + if (twitterPlayers.length) + [ogObject.twitterPlayer] = twitterPlayers; + if (musicSongs.length) + [ogObject.musicSong] = musicSongs; + } + return ogObject; +} +exports.mediaSetup = mediaSetup; +exports.default = mediaSetup; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/openGraphScraper.d.ts b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/openGraphScraper.d.ts new file mode 100644 index 0000000..2e2947c --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/openGraphScraper.d.ts @@ -0,0 +1,12 @@ +import type { OpenGraphScraperOptions } from './types'; +/** + * sets up options for the got request and calls extract on html + * + * @param {object} options - options for ogs + * @return {object} object with ogs results + * + */ +export default function setOptionsAndReturnOpenGraphResults(options: OpenGraphScraperOptions): Promise<{ + ogObject: import("./types").OgObject; + response: any; +}>; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/openGraphScraper.js b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/openGraphScraper.js new file mode 100644 index 0000000..b95a5eb --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/openGraphScraper.js @@ -0,0 +1,63 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const extract_1 = require("./extract"); +const request_1 = require("./request"); +const utils = require("./utils"); +/** + * sets up options for the got request and calls extract on html + * + * @param {object} options - options for ogs + * @return {object} object with ogs results + * + */ +async function setOptionsAndReturnOpenGraphResults(options) { + const { ogsOptions, gotOptions } = utils.optionSetupAndSplit(options); + if (ogsOptions.html) { + if (ogsOptions.url) + throw new Error('Must specify either `url` or `html`, not both'); + const ogObject = (0, extract_1.default)(ogsOptions.html, ogsOptions, null); + ogObject.requestUrl = null; + ogObject.success = true; + return { ogObject, response: { body: ogsOptions.html } }; + } + const formattedUrl = utils.validateAndFormatURL(ogsOptions.url, ogsOptions.urlValidatorSettings); + if (!formattedUrl.url) + throw new Error('Invalid URL'); + ogsOptions.url = formattedUrl.url; + gotOptions.url = formattedUrl.url; + // trying to limit non html pages + if (utils.isThisANonHTMLUrl(ogsOptions.url)) + throw new Error('Must scrape an HTML page'); + // eslint-disable-next-line max-len + if (ogsOptions.blacklist && ogsOptions.blacklist.some((blacklistedHostname) => ogsOptions.url.includes(blacklistedHostname))) { + throw new Error('Host name has been black listed'); + } + try { + const { decodedBody, response } = await (0, request_1.default)(gotOptions, ogsOptions); + const ogObject = (0, extract_1.default)(decodedBody, ogsOptions, response.rawBody); + ogObject.requestUrl = ogsOptions.url; + ogObject.success = true; + return { ogObject, response }; + } + catch (exception) { + if (exception && (exception.code === 'ENOTFOUND' || exception.code === 'EHOSTUNREACH' || exception.code === 'ENETUNREACH')) { + throw new Error('Page not found'); + } + else if (exception && (exception.code === 'ERR_INVALID_URL' || exception.code === 'EINVAL')) { + throw new Error('Page not found'); + } + else if (exception && exception.code === 'ETIMEDOUT') { + throw new Error('Time out'); + } + else if (exception && exception.message && exception.message.startsWith('Response code 5')) { + throw new Error('Web server is returning error'); + } + else if (exception && exception.message && exception.message === 'Promise was canceled') { + throw new Error(`Exceeded the download limit of ${ogsOptions.downloadLimit} bytes`); + } + if (exception instanceof Error) + throw exception; + throw new Error('Page not found'); + } +} +exports.default = setOptionsAndReturnOpenGraphResults; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/request.d.ts b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/request.d.ts new file mode 100644 index 0000000..a043f73 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/request.d.ts @@ -0,0 +1,9 @@ +/** + * performs the got request and formats the body for ogs + * + * @param {object} gotOptions - options for got + * @param {object} ogsOptions - options for ogs + * @return {object} formatted request body and response + * + */ +export default function requestAndResultsFormatter(gotOptions: any, ogsOptions: any): Promise<any>; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/request.js b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/request.js new file mode 100644 index 0000000..5d8ee9e --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/request.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const chardet_1 = require("chardet"); +const iconv_lite_1 = require("iconv-lite"); +const utils_1 = require("./utils"); +/** + * performs the got request and formats the body for ogs + * + * @param {object} gotOptions - options for got + * @param {object} ogsOptions - options for ogs + * @return {object} formatted request body and response + * + */ +async function requestAndResultsFormatter(gotOptions, ogsOptions) { + const got = await (0, utils_1.gotClient)(ogsOptions.downloadLimit); + return got(gotOptions) + .then((response) => { + if (response && response.headers && response.headers['content-type'] && !response.headers['content-type'].includes('text/')) { + throw new Error('Page must return a header content-type with text/'); + } + if (response && response.statusCode && (response.statusCode.toString().substring(0, 1) === '4' || response.statusCode.toString().substring(0, 1) === '5')) { + throw new Error('Server has returned a 400/500 error code'); + } + if (response.body === undefined || response.body === '') { + throw new Error('Page not found'); + } + const char = chardet_1.default.detect(response.rawBody); + let decodedBody = response.rawBody.toString(); + if (char && typeof response.rawBody === 'object') { + decodedBody = (0, iconv_lite_1.decode)(response.rawBody, char); + } + if (!decodedBody) { + throw new Error('Page not found'); + } + return { decodedBody, response }; + }) + .catch((error) => { + if (error instanceof Error) + throw error; + throw new Error(error); + }); +} +exports.default = requestAndResultsFormatter; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/types.d.ts b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/types.d.ts new file mode 100644 index 0000000..f4e003f --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/types.d.ts @@ -0,0 +1,280 @@ +/** + * The options used by Open Graph Scraper + * + * @typeParam {string} url - URL of the site. (Required) + * @typeParam {string} [html] - You can pass in an HTML string to run ogs on it. (use without options.url) + * @typeParam {string[]} [blacklist] - Pass in an array of sites you don't want ogs to run on. + * @typeParam {boolean} [onlyGetOpenGraphInfo] - Only fetch open graph info and don't fall back on anything else. + * @typeParam {boolean} [ogImageFallback] - Fetch other images if no open graph ones are found. + * @typeParam {object} [customMetaTags] - Here you can define custom meta tags you want to scrape. + * @typeParam {boolean} [allMedia] - By default, OGS will only send back the first image/video it finds. + * @typeParam {number | false} [downloadLimit] - Maximum size of the content downloaded from the server, in bytes. + * @typeParam {object} [ValidatorSettings] - Sets the options used by validator.js for testing the URL + * @typeParam {boolean} [decompress] - Set the accept-encoding to `gzip, deflate, br` (default: `true`). + * @typeParam {boolean} [followRedirect] - Defines if redirect responses should be followed automatically. (default: `true`). + * @typeParam {Object<string, string>} [headers] - An object containing request headers. Useful for setting the user-agent. + * @typeParam {number} [maxRedirects] - If exceeded, the request will be aborted and a MaxRedirectsError will be thrown. (default: `10`). + * @typeParam {object} [retry] - Number of times `og`s will retry the request (default: `2`). + * @typeParam {object} [timeout] - Timeout of the request. + */ +export type OpenGraphScraperOptions = { + allMedia?: boolean; + blacklist?: string[]; + customMetaTags?: CustomMetaTags[]; + decompress?: boolean; + downloadLimit?: number | false; + followRedirect?: boolean; + headers?: { + [x: string]: string; + }; + html?: string; + maxRedirects?: number; + ogImageFallback?: boolean; + onlyGetOpenGraphInfo?: boolean; + retry?: object; + timeout?: object; + url: string; + urlValidatorSettings?: ValidatorSettings; +}; +/** + * Options for isURL method in Validator.js + * + * @typeParam allow_protocol_relative_urls - if set as true protocol relative URLs will be allowed + * @typeParam protocols - valid protocols can be modified with this option + * @typeParam require_host - if set as false isURL will not check if host is present in the URL + * @typeParam require_port - if set as true isURL will check if port is present in the URL + * @typeParam require_protocol - if set as true isURL will return false if protocol is not present in the URL + * @typeParam require_valid_protocol - isURL will check if the URL's protocol is present in the protocols option + * @typeParam validate_length - if set as false isURL will skip string length validation (IE maximum is 2083) + * + */ +export type ValidatorSettings = { + allow_fragments: boolean; + allow_protocol_relative_urls: boolean; + allow_query_components: boolean; + allow_trailing_dot: boolean; + allow_underscores: boolean; + protocols: string[]; + require_host: boolean; + require_port: boolean; + require_protocol: boolean; + require_tld: boolean; + require_valid_protocol: boolean; + validate_length: boolean; +}; +/** + * The type for user defined custom meta tags you want to scrape. + * + * @typeParam {boolean} multiple - is there more than one of these tags on a page (normally this is false) + * @typeParam {string} property - meta tag name/property attribute + * @typeParam {string} fieldName - name of the result variable + */ +type CustomMetaTags = { + fieldName: string; + multiple: boolean; + property: string; +}; +export type TwitterImageObject = { + alt?: string; + height?: number; + url: string; + width?: number; +}; +export type TwitterPlayerObject = { + height?: number; + stream?: string; + url?: string; + width?: number; +}; +export type ImageObject = { + height?: number; + type: string; + url: string; + width?: number; +}; +export type VideoObject = { + height?: number; + type?: string; + url: string; + width?: number; +}; +export type MusicSongObject = { + disc?: string; + track?: number; + url: string; +}; +export type OgObject = { + alAndroidAppName?: string; + alAndroidClass?: string; + alAndroidPackage?: string; + alAndroidUrl?: string; + alIosAppName?: string; + alIosAppStoreId?: string; + alIosUrl?: string; + alIpadAppName?: string; + alIpadAppStoreId?: string; + alIpadUrl?: string; + alIphoneAppName?: string; + alIphoneAppStoreId?: string; + alIphoneUrl?: string; + alWebShouldFallback?: string; + alWebUrl?: string; + alWindowsAppId?: string; + alWindowsAppName?: string; + alWindowsPhoneAppId?: string; + alWindowsPhoneAppName?: string; + alWindowsPhoneUrl?: string; + alWindowsUniversalAppId?: string; + alWindowsUniversalAppName?: string; + alWindowsUniversalUrl?: string; + alWindowsUrl?: string; + articleAuthor?: string; + articleExpirationTime?: string; + articleModifiedTime?: string; + articlePublishedTime?: string; + articlePublisher?: string; + articleSection?: string; + articleTag?: string; + author?: string; + bookAuthor?: string; + bookCanonicalName?: string; + bookIsbn?: string; + bookReleaseDate?: string; + booksBook?: string; + booksRatingScale?: string; + booksRatingValue?: string; + bookTag?: string; + businessContactDataCountryName?: string; + businessContactDataLocality?: string; + businessContactDataPostalCode?: string; + businessContactDataRegion?: string; + businessContactDataStreetAddress?: string; + charset?: string; + dcContributor?: string; + dcCoverage?: string; + dcCreator?: string; + dcDate?: string; + dcDateCreated?: string; + dcDateIssued?: string; + dcDescription?: string; + dcFormatMedia?: string; + dcFormatSize?: string; + dcIdentifier?: string; + dcLanguage?: string; + dcPublisher?: string; + dcRelation?: string; + dcRights?: string; + dcSource?: string; + dcSubject?: string; + dcTitle?: string; + dcType?: string; + error?: string; + errorDetails?: Error; + favicon?: string; + modifiedTime?: string; + musicAlbum?: string; + musicAlbumDisc?: string; + musicAlbumTrack?: string; + musicAlbumUrl?: string; + musicCreator?: string; + musicDuration?: string; + musicMusician?: string; + musicReleaseDate?: string; + musicSong?: string | MusicSongObject | MusicSongObject[]; + musicSongDisc?: string | null[]; + musicSongTrack?: number | null[]; + musicSongUrl?: string; + ogArticleAuthor?: string; + ogArticleExpirationTime?: string; + ogArticleModifiedTime?: string; + ogArticlePublishedTime?: string; + ogArticlePublisher?: string; + ogArticleSection?: string; + ogArticleTag?: string; + ogAudio?: string; + ogAudioSecureURL?: string; + ogAudioType?: string; + ogAudioURL?: string; + ogAvailability?: string; + ogDate?: string; + ogDescription?: string; + ogDeterminer?: string; + ogImage?: string | ImageObject | ImageObject[]; + ogImageHeight?: string | null[]; + ogImageSecureURL?: string; + ogImageType?: string | null[]; + ogImageURL?: string; + ogImageWidth?: string | null[]; + ogLocale?: string; + ogLocaleAlternate?: string; + ogLogo?: string; + ogPriceAmount?: string; + ogPriceCurrency?: string; + ogProductAvailability?: string; + ogProductCondition?: string; + ogProductPriceAmount?: string; + ogProductPriceCurrency?: string; + ogProductRetailerItemId?: string; + ogSiteName?: string; + ogTitle?: string; + ogType?: string; + ogUrl?: string; + ogVideo?: string | VideoObject | VideoObject[]; + ogVideoActorId?: string; + ogVideoHeight?: string | null[]; + ogVideoSecureURL?: string; + ogVideoType?: string | null[]; + ogVideoWidth?: string | null[]; + placeLocationLatitude?: string; + placeLocationLongitude?: string; + profileFirstName?: string; + profileGender?: string; + profileLastName?: string; + profileUsername?: string; + publishedTime?: string; + releaseDate?: string; + requestUrl?: string; + restaurantContactInfoCountryName?: string; + restaurantContactInfoEmail?: string; + restaurantContactInfoLocality?: string; + restaurantContactInfoPhoneNumber?: string; + restaurantContactInfoPostalCode?: string; + restaurantContactInfoRegion?: string; + restaurantContactInfoStreetAddress?: string; + restaurantContactInfoWebsite?: string; + restaurantMenu?: string; + restaurantRestaurant?: string; + restaurantSection?: string; + restaurantVariationPriceAmount?: string; + restaurantVariationPriceCurrency?: string; + success?: boolean; + twitterAppIdGooglePlay?: string; + twitterAppIdiPad?: string; + twitterAppIdiPhone?: string; + twitterAppNameGooglePlay?: string; + twitterAppNameiPad?: string; + twitterAppNameiPhone?: string; + twitterAppUrlGooglePlay?: string; + twitterAppUrliPad?: string; + twitterAppUrliPhone?: string; + twitterCard?: string; + twitterCreator?: string; + twitterCreatorId?: string; + twitterDescription?: string; + twitterImage?: string | TwitterImageObject | TwitterImageObject[]; + twitterImageAlt?: string | null[]; + twitterImageHeight?: string | null[]; + twitterImageSrc?: string | null[]; + twitterImageWidth?: string | null[]; + twitterPlayer?: string | TwitterPlayerObject | TwitterPlayerObject[]; + twitterPlayerHeight?: string | null[]; + twitterPlayerStream?: string | null[]; + twitterPlayerStreamContentType?: string; + twitterPlayerWidth?: string | null[]; + twitterSite?: string; + twitterSiteId?: string; + twitterTitle?: string; + twitterUrl?: string; + updatedTime?: string; +}; +export {}; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/types.js b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/types.js new file mode 100644 index 0000000..7018809 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/types.js @@ -0,0 +1,3 @@ +"use strict"; +/* eslint-disable max-len */ +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/utils.d.ts b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/utils.d.ts new file mode 100644 index 0000000..ce2be38 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/utils.d.ts @@ -0,0 +1,81 @@ +import type { ValidatorSettings, OpenGraphScraperOptions } from './types'; +/** + * Checks if URL is valid + * + * @param {string} url - url to be checked + * @param {string} urlValidatorSettings - settings used by validator + * @return {boolean} boolean value if the url is valid + * + */ +export declare function isUrlValid(url: string, urlValidatorSettings: ValidatorSettings): boolean; +/** + * Validates and formats url + * + * @param {string} url - url to be checked and formatted + * @param {string} urlValidatorSettings - settings used by validator + * @return {string} proper url or null + * + */ +export declare function validateAndFormatURL(url: string, urlValidatorSettings: ValidatorSettings): { + url: string | null; +}; +/** + * Finds the image type from a given url + * + * @param {string} url - url to be checked + * @return {string} image type from url + * + */ +export declare function findImageTypeFromUrl(url: string): string; +/** + * Checks if image type is valid + * + * @param {string} type - type to be checked + * @return {boolean} boolean value if type is value + * + */ +export declare function isImageTypeValid(type: string): boolean; +/** + * Checks if URL is a non html page + * + * @param {string} url - url to be checked + * @return {boolean} boolean value if url is non html + * + */ +export declare function isThisANonHTMLUrl(url: string): boolean; +/** + * Find and delete nested undefs + * + * @param {object} object - object to be cleaned + * @return {object} object without nested undefs + * + */ +export declare function removeNestedUndefinedValues(object: { + [key: string]: any; +}): { + [key: string]: any; +}; +/** + * Split the options object into ogs and got option objects + * + * @param {object} options - options that need to be split + * @return {object} object with nested options for ogs and got + * + */ +export declare function optionSetupAndSplit(options: OpenGraphScraperOptions): { + ogsOptions: OpenGraphScraperOptions; + gotOptions: Options; +}; +interface Options { + [key: string]: any; +} +/** + * gotClient - limit the size of the content we fetch when performing the request + * from https://github.com/sindresorhus/got/blob/main/documentation/examples/advanced-creation.js + * + * @param {string} downloadLimit - the download limit, will close connection once it is reached + * @return {function} got client with download limit + * + */ +export declare function gotClient(downloadLimit: number | false): Promise<any>; +export {}; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/utils.js b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/utils.js new file mode 100644 index 0000000..39c3884 --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/dist/lib/utils.js @@ -0,0 +1,175 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.gotClient = exports.optionSetupAndSplit = exports.removeNestedUndefinedValues = exports.isThisANonHTMLUrl = exports.isImageTypeValid = exports.findImageTypeFromUrl = exports.validateAndFormatURL = exports.isUrlValid = void 0; +const validator_1 = require("validator"); +/** + * Checks if URL is valid + * + * @param {string} url - url to be checked + * @param {string} urlValidatorSettings - settings used by validator + * @return {boolean} boolean value if the url is valid + * + */ +function isUrlValid(url, urlValidatorSettings) { + return typeof url === 'string' && url.length > 0 && validator_1.default.isURL(url, urlValidatorSettings); +} +exports.isUrlValid = isUrlValid; +/** + * Forces url to start with http:// if it doesn't + * + * @param {string} url - url to be updated + * @return {string} url that starts with http + * + */ +const coerceUrl = (url) => (/^(f|ht)tps?:\/\//i.test(url) ? url : `http://${url}`); +/** + * Validates and formats url + * + * @param {string} url - url to be checked and formatted + * @param {string} urlValidatorSettings - settings used by validator + * @return {string} proper url or null + * + */ +function validateAndFormatURL(url, urlValidatorSettings) { + return { url: isUrlValid(url, urlValidatorSettings) ? coerceUrl(url) : null }; +} +exports.validateAndFormatURL = validateAndFormatURL; +/** + * Finds the image type from a given url + * + * @param {string} url - url to be checked + * @return {string} image type from url + * + */ +function findImageTypeFromUrl(url) { + let type = url.split('.').pop(); + [type] = type.split('?'); + return type; +} +exports.findImageTypeFromUrl = findImageTypeFromUrl; +/** + * Checks if image type is valid + * + * @param {string} type - type to be checked + * @return {boolean} boolean value if type is value + * + */ +function isImageTypeValid(type) { + const validImageTypes = ['apng', 'bmp', 'gif', 'ico', 'cur', 'jpg', 'jpeg', 'jfif', 'pjpeg', 'pjp', 'png', 'svg', 'tif', 'tiff', 'webp']; + return validImageTypes.includes(type); +} +exports.isImageTypeValid = isImageTypeValid; +/** + * Checks if URL is a non html page + * + * @param {string} url - url to be checked + * @return {boolean} boolean value if url is non html + * + */ +function isThisANonHTMLUrl(url) { + const invalidImageTypes = ['.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.3gp', '.avi', '.mov', '.mp4', '.m4v', '.m4a', '.mp3', '.mkv', '.ogv', '.ogm', '.ogg', '.oga', '.webm', '.wav', '.bmp', '.gif', '.jpg', '.jpeg', '.png', '.webp', '.zip', '.rar', '.tar', '.tar.gz', '.tgz', '.tar.bz2', '.tbz2', '.txt', '.pdf']; + const extension = findImageTypeFromUrl(url); + return invalidImageTypes.some((type) => `.${extension}`.includes(type)); +} +exports.isThisANonHTMLUrl = isThisANonHTMLUrl; +/** + * Find and delete nested undefs + * + * @param {object} object - object to be cleaned + * @return {object} object without nested undefs + * + */ +function removeNestedUndefinedValues(object) { + Object.entries(object).forEach(([key, value]) => { + if (value && typeof value === 'object') + removeNestedUndefinedValues(value); + else if (value === undefined) + delete object[key]; + }); + return object; +} +exports.removeNestedUndefinedValues = removeNestedUndefinedValues; +/** + * Split the options object into ogs and got option objects + * + * @param {object} options - options that need to be split + * @return {object} object with nested options for ogs and got + * + */ +function optionSetupAndSplit(options) { + const ogsOptions = { + allMedia: false, + customMetaTags: [], + downloadLimit: 1000000, + ogImageFallback: true, + onlyGetOpenGraphInfo: false, + urlValidatorSettings: { + allow_fragments: true, + allow_protocol_relative_urls: false, + allow_query_components: true, + allow_trailing_dot: false, + allow_underscores: false, + protocols: ['http', 'https'], + require_host: true, + require_port: false, + require_protocol: false, + require_tld: true, + require_valid_protocol: true, + validate_length: true, + }, + ...options, + }; + const gotOptions = { + decompress: true, + followRedirect: true, + headers: {}, + maxRedirects: 10, + ...options, + }; + // remove any OGS options from gotOptions since this will cause errors in got + delete gotOptions.allMedia; + delete gotOptions.blacklist; + delete gotOptions.customMetaTags; + delete gotOptions.downloadLimit; + delete gotOptions.ogImageFallback; + delete gotOptions.onlyGetOpenGraphInfo; + delete gotOptions.urlValidatorSettings; + return { ogsOptions, gotOptions }; +} +exports.optionSetupAndSplit = optionSetupAndSplit; +/** + * gotClient - limit the size of the content we fetch when performing the request + * from https://github.com/sindresorhus/got/blob/main/documentation/examples/advanced-creation.js + * + * @param {string} downloadLimit - the download limit, will close connection once it is reached + * @return {function} got client with download limit + * + */ +async function gotClient(downloadLimit) { + // https://github.com/sindresorhus/got/issues/1789 + // eslint-disable-next-line import/no-unresolved + const { got } = await import('got'); + return got.extend({ + handlers: [ + (options, next) => { + const promiseOrStream = next(options); + const destroy = (message) => { + if (options.isStream) { + promiseOrStream.destroy(new Error(message)); + return; + } + promiseOrStream.cancel(message); + }; + if (typeof downloadLimit === 'number') { + promiseOrStream.on('downloadProgress', (progress) => { + if (progress.transferred > downloadLimit && progress.percent !== 1) { + destroy(`Exceeded the download limit of ${downloadLimit} bytes`); + } + }); + } + return promiseOrStream; + }, + ], + }); +} +exports.gotClient = gotClient; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/index.ts b/includes/external/addressbook/node_modules/open-graph-scraper/index.ts new file mode 100644 index 0000000..9e36d7a --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/index.ts @@ -0,0 +1,70 @@ +/* eslint-disable max-len, import/no-import-module-exports */ +import setOptionsAndReturnOpenGraphResults from './lib/openGraphScraper'; +import type { + OpenGraphScraperOptions, + OgObject, +} from './lib/types'; + +/** + * `open-graph-scraper` uses [got](https://github.com/sindresorhus/got) for requests and most of + * [got's options](https://github.com/sindresorhus/got/blob/main/documentation/2-options.md) + * should work as `open-graph-scraper` options. + * + * @param {object} options - The options used by Open Graph Scraper + * @param {string} options.url - URL of the site. (Required) + * @param {string} [options.html] - You can pass in an HTML string to run ogs on it. (use without options.url) + * @param {string[]} [options.blacklist] - Pass in an array of sites you don't want ogs to run on. + * @param {boolean} [options.onlyGetOpenGraphInfo] - Only fetch open graph info and don't fall back on anything else. + * @param {boolean} [options.ogImageFallback] - Fetch other images if no open graph ones are found. + * @param {object} [options.customMetaTags] - Here you can define custom meta tags you want to scrape. + * @param {boolean} [options.allMedia] - By default, OGS will only send back the first image/video it finds. + * @param {number | false} [options.downloadLimit] - Maximum size of the content downloaded from the server, in bytes. + * @param {object} [options.ValidatorSettings] - Sets the options used by validator.js for testing the URL + * @param {boolean} [options.decompress] - Set the accept-encoding to `gzip, deflate, br` (default: `true`). + * @param {boolean} [options.followRedirect] - Defines if redirect responses should be followed automatically. (default: `true`). + * @param {Object<string, string>} [options.headers] - An object containing request headers. Useful for setting the user-agent. + * @param {number} [options.maxRedirects] - If exceeded, the request will be aborted and a MaxRedirectsError will be thrown. (default: `10`). + * @param {object} [options.retry] - Number of times `og`s will retry the request (default: `2`). + * @param {object} [options.timeout] - Timeout of the request. + * @returns {Promise} Promise Object with the Open Graph results + */ +export default async function run(options: OpenGraphScraperOptions): Promise<ErrorResult | SuccessResult> { + let results; + try { + results = await setOptionsAndReturnOpenGraphResults(options); + } catch (error) { + const exception = error as Error; + const returnError:ErrorResult = { + error: true, + result: { + success: false, + requestUrl: options.url, + error: exception.message, + errorDetails: exception, + }, + response: undefined, + }; + // eslint-disable-next-line @typescript-eslint/no-throw-literal + throw returnError; + } + const returnSuccess: SuccessResult = { + error: false, + result: results.ogObject, + response: results.response, + }; + return returnSuccess; +} + +module.exports = run; + +type SuccessResult = { + error: false; + result: OgObject; + response: object; +}; + +type ErrorResult = { + error: true; + result: OgObject; + response: undefined; +}; diff --git a/includes/external/addressbook/node_modules/open-graph-scraper/package.json b/includes/external/addressbook/node_modules/open-graph-scraper/package.json new file mode 100644 index 0000000..93eb30d --- /dev/null +++ b/includes/external/addressbook/node_modules/open-graph-scraper/package.json @@ -0,0 +1,80 @@ +{ + "name": "open-graph-scraper", + "description": "Node.js scraper module for Open Graph and Twitter Card info", + "version": "5.2.3", + "license": "MIT", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc", + "eslint:fix": "eslint . --ext .js,.ts --fix", + "eslint": "eslint . --ext .js,.ts", + "mocha:int": "ts-mocha --require ./tests/helpers/bootstrap.js --recursive \"./tests/integration/**/*.spec.js\" --timeout 10000", + "mocha:unit": "nyc --reporter=html --reporter=text --exclude=tests/ ts-mocha --require ./tests/helpers/bootstrap.js --recursive \"./tests/unit/**/*.spec.js\"", + "prepare": "npm run snyk-protect && npm run build", + "snyk-protect": "snyk-protect", + "test": "npm run mocha:unit && npm run mocha:int" + }, + "engines": { + "node": ">=14.16" + }, + "author": { + "name": "Josh Shemas", + "email": "jjs90jjs@gmail.com", + "url": "https://github.com/jshemas" + }, + "dependencies": { + "chardet": "^1.5.1", + "cheerio": "^1.0.0-rc.12", + "got": "^12.6.0", + "iconv-lite": "^0.6.3", + "validator": "^13.9.0" + }, + "files": [ + "/dist", + "CHANGELOG.md", + "index.ts" + ], + "devDependencies": { + "@snyk/protect": "^1.1118.0", + "@types/node": "^18.15.2", + "@typescript-eslint/eslint-plugin": "^5.55.0", + "@typescript-eslint/parser": "^5.55.0", + "chai": "^4.3.7", + "eslint": "^8.36.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-mocha": "^10.1.0", + "eslint-plugin-promise": "^6.1.1", + "mocha": "^10.2.0", + "nock": "^13.3.0", + "nyc": "^15.1.0", + "sinon": "^15.0.2", + "ts-mocha": "^10.0.0", + "tunnel": "^0.0.6", + "typescript": "^4.9.5" + }, + "repository": { + "type": "git", + "url": "http://github.com/jshemas/openGraphScraper.git", + "web": "http://github.com/jshemas/openGraphScraper" + }, + "keywords": [ + "app links", + "dublin core", + "meta tags", + "metadata", + "og", + "ogp", + "ogs", + "open graph scraper", + "open graph", + "opengraph", + "openGraphScraper", + "scraper", + "twitter card", + "twitter" + ], + "snyk": true +} |