This shows how to use IpIntelligencePipelineBuilder instead of specific IpIntelligenceCloudPipelineBuilder.
This shows how to use IpIntelligencePipelineBuilder instead of specific IpIntelligenceCloudPipelineBuilder. This example is available in full on GitHub.
Expected output:
Which country is the IP address '8.8.8.8' in?
United States
/* *********************************************************************
* This Original Work is copyright of 51 Degrees Mobile Experts Limited.
* Copyright 2026 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 path = require('path');
const require51 = (requestedPackage) => {
try {
return require(path.join(__dirname, '/../../../node_modules/', requestedPackage));
} catch (e) {
return require(requestedPackage);
}
};
const fs = require('fs');
const http = require('http');
const pug = require('pug');
const compiledFunction =
pug.compileFile(path.join(__dirname, '/index.pug'));
const ipi = require51('fiftyone.ipintelligence.onpremise');
const translation = require51('fiftyone.ipintelligence.translation');
const optionsExtension =
require51('fiftyone.ipintelligence.shared').optionsExtension;
const dataExtension =
require51('fiftyone.ipintelligence.shared').dataExtension;
require(path.join(__dirname, '/../exampleUtils'));
// Pipeline variable to be used
let pipeline;
const setPipeline = (options) => {
let dataFilePath = optionsExtension.getDataFilePath(options);
if (!dataFilePath) {
throw 'A data file must be specified in the 51d.json file.';
}
if (!fs.existsSync(dataFilePath)) {
// Check the _51DEGREES_IPI_PATH environment variable for an explicit
// path, then search the folder hierarchy for the file name.
const newDataFilePath =
ExampleUtils.findDataFile(path.basename(dataFilePath));
if (newDataFilePath !== undefined) {
dataFilePath = newDataFilePath;
console.warn('Failed to find an IP intelligence data file ' +
`at the specified path '${dataFilePath}'. Use '${newDataFilePath}' ` +
'instead.');
} else {
throw 'Failed to find an IP intelligence data file at ' +
`'${dataFilePath}'. If using the lite file, then make sure the ` +
'cxx/data submodule has been fetched by running ' +
'\'git submodule update --init --recursive\'. Otherwise, ensure ' +
'that the filename is correct in 51d.json.';
}
}
// Build the on-premise IP intelligence pipeline and append the two country
// translation engines. The IP intelligence engine emits the weighted lists
// of country codes; the translation engines turn those into the localized,
// ordered country name lists that the page binds the dropdown to. The
// browser language is taken from the request's Accept-Language header (a
// 'translation' query parameter overrides it).
pipeline = new ipi.IpIntelligenceOnPremisePipelineBuilder({
performanceProfile: 'Balanced',
dataFile: dataFilePath,
shareUsage: false,
autoUpdate: false,
updateOnStart: false,
fileSystemWatcher: false,
suppressProcessExceptions: true
})
.add(new translation.CountryCodeTranslationEngineBuilder().build())
.add(new translation.CountriesTranslationEngineBuilder().build())
.build();
// Logging of errors and other messages.
// Valid logs types are info, debug, warn, error
pipeline.on('error', console.error);
};
// Directory holding the shared pattern-library assets (CSS and JS) that
// are served at '/css/...' and '/js/...'.
const publicDir = path.join(__dirname, '/public');
const server = http.createServer((req, res) => {
// Serve the shared example assets before running the pipeline. When the
// request is for one of those files the response is sent here and we
// return early.
return;
}
// FlowData is a data structure that is used to convey
// information required for detection and the results of the
// detection through the pipeline.
// Information required for detection is called "evidence".
// For IP intelligence the IP address of the requesting client
// is used. This is added automatically from the request.
const flowData = pipeline.createFlowData();
// Extract required evidence from the Http request.
flowData.evidence.addFromRequest(req);
flowData.process().then(function () {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
// Obtain all used evidence
const allEvidence = flowData.evidence.getAll();
const evidences =
pipeline.getElement('ip').evidenceKeyFilter.filterEvidence(
allEvidence);
// The IP address supplied through the lookup form, used to
// pre-populate the input on the rendered page.
const inputIpAddress =
(allEvidence['query.client-ip'] ||
allEvidence['header.x-forwarded-for'] || '');
// Read one of the ordered "All" lists produced by the country
// translation engine, returning an empty array when it is not present.
const allList = (key) => {
try {
const value = flowData.get('countrynamestranslated').get(key);
return value && value.hasValue ? value.value : [];
} catch (e) {
return [];
}
};
// Read a weighted list from the IP intelligence element data and format
// each entry as 'value (weight%)' for display, returning an empty array
// when the property is not present.
const ipList = (key) => {
try {
const value = flowData.ip[key];
if (value && value.hasValue && Array.isArray(value.value)) {
return value.value.map((item) => dataExtension.formatValue(item));
}
return [];
} catch (e) {
return [];
}
};
// A property that the data file does not have is shown as needing the
// Enterprise data file. The country lists are built from the country
// codes, which only the Enterprise data file has, so without them each
// list says so in place of every country in alphabetical order.
const ipEngine = pipeline.getElement('ip');
const countriesNeedEnterprise =
const countries = (list) =>
countriesNeedEnterprise ? [NEEDS_ENTERPRISE] : list;
const located = (value) => value === NEEDS_ENTERPRISE ? '' : value;
// Compile a response
res.end(compiledFunction(
{
countryCodesGeographical: countries(ipList('countrycodesgeographical')),
countryCodesPopulation: countries(ipList('countrycodespopulation')),
countryCodesGeographicalAll:
countries(allList('countrycodesgeographicalall')),
countryNamesGeographicalAllTranslated:
countries(allList('countrynamesgeographicalalltranslated')),
countryCodesPopulationAll:
countries(allList('countrycodespopulationall')),
countryNamesPopulationAllTranslated:
countries(allList('countrynamespopulationalltranslated')),
dataFilePublishedTime: new Date().getTime(),
dataFileAgeWarning: DATA_FILE_AGE_WARNING,
evidenceUsed: evidences,
allEvidence,
inputIpAddress,
areas,
mapAreas: located(areas),
freeDataFile: ExampleUtils.isFreeDataFile(ipEngine),
registeredName: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'registeredname'),
registeredOwner: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'registeredowner'),
registeredCountry: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'registeredcountry'),
ipRangeStart: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'iprangestart'),
ipRangeEnd: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'iprangeend'),
country: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'country'),
countryCode: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'countrycode'),
countryCode3: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'countrycode3'),
region: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'region'),
state: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'state'),
town: ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'town'),
latitude,
longitude,
mapLatitude: located(latitude),
mapLongitude: located(longitude),
accuracyRadius:
ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'accuracyradiusmin'),
timeZoneOffset:
ExampleUtils.getEnterpriseValue(ipEngine, flowData.ip, 'timezoneoffset')
})
);
});
});
// Don't run the server if under TEST
if (process.env.JEST_WORKER_ID === undefined) {
// Load the configuration options from config file.
const options = JSON.parse(fs.readFileSync(path.join(__dirname, '/51d.json')));
setPipeline(options);
const port = 3001;
const hostname = 'localhost';
server.listen(port, hostname);
console.log(`Server listening on: http://${hostname}:${port}`);
};
// Export server object and set pipeline.
module.exports = {
server,
setPipeline
};
Definition fiftyone.ipintelligence.onpremise/examples/onpremise/exampleUtils.js:203
