fiftyone.devicedetection
Version:
Parse HTTP headers to detect the device type, model, operating system, browser, and crawler information
192 lines (178 loc) • 7.94 kB
JavaScript
/* *********************************************************************
* This Original Work is copyright of 51 Degrees Mobile Experts Limited.
* Copyright 2025 51 Degrees Mobile Experts Limited, Davidson House,
* Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
*
* This Original Work is licensed under the European Union Public Licence
* (EUPL) v.1.2 and is subject to its terms as set out below.
*
* If a copy of the EUPL was not distributed with this file, You can obtain
* one at https://opensource.org/licenses/EUPL-1.2.
*
* The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
* amended by the European Commission) shall be deemed incompatible for
* the purposes of the Work and the provisions of the compatibility
* clause in Article 5 of the EUPL shall not apply.
*
* If using the Work as, or as part of, a network application, by
* including the attribution notice(s) required under Article 5 of the EUPL
* in the end user terms of the application under an appropriate heading,
* such notice(s) shall fulfill the requirements of that article.
* ********************************************************************* */
const core = require('fiftyone.pipeline.core');
const DeviceDetectionOnPremise = require('fiftyone.devicedetection.onpremise').DeviceDetectionOnPremise;
const DeviceDetectionCloud = require('fiftyone.devicedetection.cloud').DeviceDetectionCloud;
const CloudRequestEngine = require('fiftyone.pipeline.cloudrequestengine').CloudRequestEngine;
const PipelineBuilder = core.PipelineBuilder;
const engines = require('fiftyone.pipeline.engines');
const LruCache = engines.LruCache;
const ShareUsageElement = require('fiftyone.pipeline.engines.fiftyone').ShareUsage;
const errorMessages = require('fiftyone.devicedetection.shared').errorMessages;
class DeviceDetectionPipelineBuilder extends PipelineBuilder {
/**
* Extension of pipelineBuilder class that allows for the quick
* generation of a device detection pipeline. Adds share usage,
* caching and toggles between on premise and cloud with
* simple paramater changes
*
* @param {object} options the options for the pipeline builder
* @param {string} options.licenceKeys license key(s) used by the
* data file update service. A key can be obtained from the
* 51Degrees website: https://51degrees.com/pricing.
* This parameter MUST be set when using a data file.
* If you do not wish to use a key then you can specify
* an empty string, but this will cause automatic updates
* to be disabled.
* @param {string} options.resourceKey resourceKey, if using the
* cloud engine
* @param {string} options.dataFile dataFile path for the on premise engine
* @param {boolean} options.autoUpdate whether to autoUpdate the dataFile
* @param {number} options.pollingInterval How often to poll for
* updates to the datafile (minutes)
* @param {number} options.updateTimeMaximumRandomisation
* Maximum randomisation offset in seconds to polling time interval
* @param {boolean} options.fileSystemWatcher whether to monitor the datafile
* path for changes
* @param {boolean} options.updateOnStart whether to download / update a
* dataFile to the path specified in options.dataFile on start
* @param {boolean} options.shareUsage whether to include the share
* usage element
* @param {number} options.cacheSize size of the default cache
* (includes cache if set). NOTE: This is not supported for on-premise
* engine.
* @param {Array} options.restrictedProperties This setting only affects
* on-premise engines, not cloud.
* list of properties the engine will be restricted to
* @param {string} options.performanceProfile used to control the tradeoff
* between performance and system memory usage (Only applies to on-premise,
* not cloud) options are: LowMemory, MaxPerformance, Balanced,
* BalancedTemp, HighPerformance
* @param {boolean} options.updateMatchedUserAgent This setting only affects
* on-premise engines, not cloud.
* True if the detection should record the matched characters from the
* target User-Agent
* @param {number} options.maxMatchedUserAgentLength This setting only affects
* on-premise engines, not cloud.
* Number of characters to consider in the matched User-Agent. Ignored
* if updateMatchedUserAgent is false
* @param {number} options.drift This setting only affects on-premise engines,
* not cloud.
* Set maximum drift in hash position to allow when processing HTTP headers.
* @param {number} options.difference This setting only affects on-premise
* engines, not cloud.
* Set the maximum difference to allow when processing HTTP headers.
* The difference is the difference in hash value between the hash that
* was found, and the hash that is being searched for. By default this is 0.
* @param {string} options.allowUnmatched This setting only affects
* on-premise engines, not cloud.
* If set to false, a non-matching User-Agent will result in properties
* without set values.
* If set to true, a non-matching User-Agent will cause the 'default profiles'
* to be returned.
* This means that properties will always have values
* (i.e. no need to check .HasValue) but some may be inaccurate.
* By default, this is false.
* @param {string} options.cloudEndPoint This setting only affects
* cloud engine, not on-premise.
* Choose a non default endpoint for the cloud request engine
* @param {string} options.cloudRequestOrigin This setting only affects
* cloud engine, not on-premise.
* Set the value to use for the Origin header when making requests to the
* cloud service.
*
*/
constructor (
{
licenceKeys = null,
dataFile = null,
autoUpdate = true,
fileSystemWatcher = true,
pollingInterval = 30,
updateTimeMaximumRandomisation = 10,
shareUsage = true,
resourceKey = null,
cacheSize = null,
restrictedProperties,
performanceProfile = 'LowMemory',
updateMatchedUserAgent = false,
maxMatchedUserAgentLength,
drift,
difference,
allowUnmatched = false,
updateOnStart = false,
cloudEndPoint = null,
cloudRequestOrigin = null
}) {
super(...arguments);
const deprecatedOptions = ['usePredictiveGraph', 'usePerformanceGraph'];
for (const option of deprecatedOptions) {
if (arguments[0].hasOwnProperty(option)) {
console.warn(`{${option}} option is deprecated and has no effect on the configuration`);
}
}
// Check if share usage enabled and add it to the pipeline if so
if (shareUsage) {
this.flowElements.push(new ShareUsageElement());
}
let cache;
if (cacheSize) {
cache = new LruCache({ size: cacheSize });
}
if (dataFile) {
// Cache is not supported for on-premise engine.
if (cacheSize) {
throw errorMessages.cacheNotSupport;
}
this.flowElements.push(new DeviceDetectionOnPremise(
{
dataFilePath: dataFile,
autoUpdate,
fileSystemWatcher,
pollingInterval,
updateTimeMaximumRandomisation,
licenceKeys,
restrictedProperties,
performanceProfile,
updateMatchedUserAgent,
maxMatchedUserAgentLength,
drift,
difference,
allowUnmatched,
updateOnStart
}));
} else {
// First we need the cloudRequestEngine
this.flowElements.push(new CloudRequestEngine(
{
resourceKey,
licenseKey: licenceKeys,
baseURL: cloudEndPoint,
cloudRequestOrigin,
cache
}));
// Then add the cloud device detection engine
this.flowElements.push(new DeviceDetectionCloud());
}
}
}
module.exports = DeviceDetectionPipelineBuilder;