UNPKG

iframely

Version:

oEmbed/2 gateway endpoint. Get embed data for various http links through one self-hosted API

443 lines (383 loc) 13.4 kB
import * as path from 'path'; import * as fs from 'fs'; import * as yaml_config from 'node-yaml-config'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); import { readFile } from 'fs/promises'; const json = JSON.parse(await readFile(new URL('./package.json', import.meta.url))); var version = json.version; const config = { baseAppUrl: "", port: 8061, relativeStaticUrl: "/s", use_http2: true, DEBUG: false, WHITELIST_URL: 'https://iframely.com/qa/domains.json', WHITELIST_URL_RELOAD_PERIOD: 60 * 60 * 1000, // will reload WL every hour, if no local files are found in /whitelist folder WHITELIST_WILDCARD: {}, // Default cache engine to prevent warning. CACHE_ENGINE: 'node-cache', CACHE_TTL: 24 * 60 * 60, CACHE_ERROR_TTL: 10 * 60, // 10 min - cache for error responses. API_REQUEST_CACHE_TTL: 30 * 24 * 60 * 60, IMAGE_META_CACHE_TTL: 7 * 24 * 60 * 60, CACHE_TTL_PAGE_TIMEOUT: 10 * 60, CACHE_TTL_PAGE_404: 10 * 60, CACHE_TTL_PAGE_OTHER_ERROR: 1 * 60, HTTP2_RETRY_CODES_LIST: [ 'ECONNRESET', 'ESOCKETTIMEDOUT' ], CLUSTER_WORKER_RESTART_ON_PERIOD: 8 * 3600 * 1000, // 8 hours. CLUSTER_WORKER_RESTART_ON_MEMORY_USED: 120 * 1024 * 1024, // 120 MB. MAX_REDIRECTS: 5, RESPONSE_TIMEOUT: 15 * 1000, SHUTDOWN_TIMEOUT: 6 * 1000, VERSION: version, FB_USER_AGENT: 'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)', SKIP_IFRAMELY_RENDERS: false, DEFAULT_ASPECT_RATIO: 16 / 9, DOC_ASPECT_RATIO: 8.5 / 11, MAX_VERTICAL_ASPECT_RATIO: 1, ASPECT_RATIO_PRECISION: 0.25, DEFAULT_OMIT_CSS_WRAPPER_CLASS: 'iframely-responsive', DEFAULT_MAXWIDTH_WRAPPER_CLASS: 'iframely-embed', FORCE_WIDTH_LIMIT_CONTAINER: false, T: { text_html: "text/html", maybe_text_html: "maybe_text_html", javascript: "application/javascript", safe_html: "text/x-safe-html", image_jpeg: "image/jpeg", flash: "application/x-shockwave-flash", // Adobe Flash Player is no longer supported image: "image", image_icon: "image/icon", image_png: "image/png", image_svg: "image/svg+xml", image_gif: "image/gif", image_webp: "image/webp", video_mp4: "video/mp4", video_ogg: "video/ogg", video_webm: "video/webm", video_iso: "video/iso.segment", stream_apple_mpegurl: "application/vnd.apple.mpegurl", stream_x_mpegurl: "application/x-mpegURL", audio_mp3: "audio/mp3", audio_mpeg: "audio/mpeg", audio_mp4: "audio/mp4" }, PROMO_RELS: [ "player", "image", "thumbnail" ], REL_GROUPS: [ "promo", "app", "player", "survey", "summary", "image", "reader", "thumbnail", "logo", "icon", "file" ], MEDIA_ATTRS: [ "width", "min-width", "max-width", "height", "min-height", "max-height", "aspect-ratio", "padding-bottom", "scrolling" ], R: { player: "player", thumbnail: "thumbnail", image: "image", reader: "reader", file: "file", survey: "survey", app: "app", summary: "summary", iframely: "iframely", og: "og", twitter: "twitter", oembed: "oembed", icon: "icon", logo: "logo", inline: "inline", ssl: "ssl", resizable: "resizable", autoplay: "autoplay", html5: "html5", gifv: "gifv", promo: "promo", playerjs: "playerjs", audio: 'audio', slideshow: 'slideshow', playlist: 'playlist', '3d': '3d', encrypted: 'encrypted-media', profile: 'profile', map: 'map', maxwidth: 'maxwidth' }, FEATURES: [ // feature policy: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy#Directives 'accelerometer', 'ambient-light-sensor', 'autoplay', 'battery', 'bluetooth', 'camera', 'clipboard-read', 'clipboard-write', 'display-capture', 'document-domain', 'encrypted-media', 'execution-while-not-rendered', 'execution-while-out-of-viewport', 'fullscreen', 'gamepad', 'geolocation', 'gyroscope', 'hid', 'identity-credentials-get', 'idle-detection', 'local-fonts', 'magnetometer', 'microphone', 'midi', 'otp-credentials', 'payment', 'picture-in-picture', 'publickey-credentials-get', 'screen-wake-lock', 'serial', 'speaker-selection', 'storage-access', 'usb', 'web-share', 'window-management', 'xr-spatial-tracking' ], // Option labels: L: { horizontal: 'Slimmer horizontal player', playlist: 'Include playlist', hide_artwork: 'Hide artwork', theme: 'Theme color', light: 'Light', dark: 'Dark', auto: 'Auto', default: 'Default', height: 'Adjust height', width: 'Adjust width', page: 'Active page' }, LC: { "af": "Afrikaans", "sq": "Albanian", "arq": "Algerian Arabic", "am": "Amharic", "ar": "Arabic", "hy": "Armenian", "ast": "Asturian", "az": "Azerbaijani", "eu": "Basque", "be": "Belarusian", "bn": "Bengali", "bi": "Bislama", "bs": "Bosnian", "bg": "Bulgarian", "my": "Burmese", "ca": "Catalan", "ceb": "Cebuano", "zh-cn": "Chinese, Simplified", "zh-tw": "Chinese, Traditional", "zh": "Chinese, Yue", "ht": "Creole, Haitian", "hr": "Croatian", "cs": "Czech", "da": "Danish", "nl": "Dutch", "dz": "Dzongkha", "en": "English", "eo": "Esperanto", "et": "Estonian", "fil": "Filipino", "fi": "Finnish", "fr": "French", "fr-ca": "French (Canada)", "gl": "Galician", "ka": "Georgian", "de": "German", "el": "Greek", "gu": "Gujarati", "cnh": "Hakha Chin", "ha": "Hausa", "he": "Hebrew", "hi": "Hindi", "hu": "Hungarian", "hup": "Hupa", "is": "Icelandic", "ig": "Igbo", "id": "Indonesian", "inh": "Ingush", "ga": "Irish", "it": "Italian", "ja": "Japanese", "kn": "Kannada", "kk": "Kazakh", "km": "Khmer", "tlh": "Klingon", "ko": "Korean", "ku": "Kurdish", "lo": "Lao", "ltg": "Latgalian", "la": "Latin", "lv": "Latvian", "lt": "Lithuanian", "lb": "Luxembourgish", "rup": "Macedo", "mk": "Macedonian", "mg": "Malagasy", "ms": "Malay", "ml": "Malayalam", "mr": "Marathi", "mfe": "Mauritian Creole", "mn": "Mongolian", "srp": "Montenegrin", "ne": "Nepali", "nb": "Norwegian Bokmal", "nn": "Norwegian Nynorsk", "oc": "Occitan", "ps": "Pashto", "fa": "Persian", "pl": "Polish", "pt": "Portuguese", "pt-br": "Portuguese, Brazilian", "pa": "Punjabi", "ro": "Romanian", "ru": "Russian", "ry": "Rusyn", "sc": "Sardinian", "sr": "Serbian", "sh": "Serbo-Croatian", "szl": "Silesian", "si": "Sinhala", "sk": "Slovak", "sl": "Slovenian", "so": "Somali", "sp": "Spanish", "es": "Spanish", "sw": "Swahili", "sv": "Swedish", "art-x-bork": "Swedish Chef", "tl": "Tagalog", "tg": "Tajik", "ta": "Tamil", "tt": "Tatar", "te": "Telugu", "th": "Thai", "bo": "Tibetan", "aeb": "Tunisian Arabic", "tr": "Turkish", "tk": "Turkmen", "uk": "Ukrainian", "ur": "Urdu", "ug": "Uyghur", "uz": "Uzbek", "vi": "Vietnamese", }, // Whitelist settings. REL: { "iframely": [ "reader", "app", "player", "survey", "image", "summary", "thumbnail", "logo" ], "twitter": [ "player", "photo" ], "og": [ "video" ], "oembed": [ "link", "rich", "video", "photo" ], "html-meta": [ "video", "embedURL" ] }, // whitelist rel to iframely rel. REL_MAP: { "article": "reader", "photo": "image", "video": "player" }, // To detect: "html-meta". KNOWN_SOURCES: [ "oembed", "og", "twitter", "iframely" ], KNOWN_VIDEO_SOURCES: /(youtube|youtu|youtube\-nocookie|vimeo|dailymotion|theplatform|jwplatform|jwplayer|cnevids|newsinc|podbean|simplecast|libsyn|wistia|podiant|art19|kaltura|mtvnservices|brightcove|bcove|soundcloud|giphy|flowplayer|vidible|bandzoogle|podigee|smugmug|facebook|vid|ultimedia|mixcloud|vidyard|youplay|streamable|captivate|mdstrm|mediadelivery|hearstapps|rudo|acast|screen9|spotlightr|loom)\.\w+\//i, OEMBED_RELS_PRIORITY: ["app", "player", "survey", "image", "reader"], OEMBED_RELS_MEDIA_PRIORITY: ["player", "survey", "image", "reader", "app"], providerOptions: { "readability": {}, "twitter.status": {} }, LOG_DATE_FORMAT: "\\[YY-MM-DD HH:mm:ss\\]:", ERRORS_TO_RETRY: [ 'ECONN', 'EAI_AGAIN', 'ENET', 'HPE_INVALID_', 'ERR_SSL_' ] }; // Providers config loader. var local_config_path = path.resolve(__dirname, "config.providers.js"); if (fs.existsSync(local_config_path)) { var local = await import(local_config_path); local = local && local.default; Object.assign(config, local); } var env_config_path = path.resolve( __dirname, "config." + (process.env.NODE_ENV || "local") + ".js" ); local_config_path = path.resolve(__dirname, "config.local.js"); var local; // Try config by NODE_ENV. if (fs.existsSync(env_config_path)) { local = await import(env_config_path); local = local && local.default; } else if (fs.existsSync(local_config_path)) { // Else - try local config. local = await import(local_config_path); local = local && local.default; } Object.assign(config, local); env_config_path = path.resolve( __dirname, "config." + (process.env.NODE_ENV || "local") + ".yml" ); local_config_path = path.resolve(__dirname, "config.local.yml"); // Try config by NODE_ENV. if (fs.existsSync(env_config_path)) { local = yaml_config.load(env_config_path); } else if (fs.existsSync(local_config_path)) { // Else - try local config. local = yaml_config.load(local_config_path); } else { local = null; } Object.assign(config, local); if (!config.baseStaticUrl) { config.baseStaticUrl = config.baseAppUrl + config.relativeStaticUrl; } if (!config.USER_AGENT) { var baseAppUrlForAgent; if (config.baseAppUrl && config.baseAppUrl.match(/^\/\//)) { baseAppUrlForAgent = 'https:' + config.baseAppUrl; } else { baseAppUrlForAgent = config.baseAppUrl; } config.USER_AGENT = "Iframely/" + version + " (+" + (baseAppUrlForAgent || 'https://github.com/itteco/iframely') + ")"; } config.TYPES = Object.values(config.T); config.HTTP2_RETRY_CODES = {}; config.HTTP2_RETRY_CODES_LIST.forEach(function(item) { config.HTTP2_RETRY_CODES[item] = 1; }); export default config;