Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

geo-tz

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

geo-tz - npm Package Compare versions

Comparing version 7.0.7 to 8.0.0

data/timezones-1970.geojson.geo.dat

20

dist/find.d.ts

@@ -1,2 +0,2 @@

type CacheOptions = {
export type CacheOptions = {
/**

@@ -10,13 +10,18 @@ * If set to true, all features will be loaded into memory to shorten future lookup

*/
store?: any;
store?: Map<string, any>;
};
/**
* Set caching behavior.
* Set caching behavior and return feature cache.
*
* @param tzData The index data of the timezeone data product
* @param {string} featureFilePath The path to the binary geo.dat file for the timezeone data product
* @param {CacheOptions} options cachine options.
*/
declare function cacheLevel(options?: CacheOptions): void;
export declare function setCacheLevel(tzData: any, featureFilePath: string, options?: CacheOptions): Map<string, any>;
/**
* Find the timezone ID(s) at the given GPS coordinates.
*
* @param tzData The indexed lookup dataset to use
* @param featureCache The appropriate featureCache to use
* @param featureFilePath The appropriate featureFilePath to use
* @param lat latitude (must be >= -90 and <=90)

@@ -26,7 +31,2 @@ * @param lon longitue (must be >= -180 and <=180)

*/
export declare function find(lat: number, lon: number): string[];
export { cacheLevel as setCache };
/**
* Load all features into memory to speed up future lookups.
*/
export declare function preCache(): void;
export declare function findUsingDataset(tzData: any, featureCache: any, featureFilePath: string, lat: number, lon: number): string[];

@@ -0,0 +0,0 @@ type OceanZone = {

{
"name": "geo-tz",
"version": "7.0.7",
"version": "8.0.0",
"description": "A node.js module to find the timezone at specific gps coordinates",

@@ -21,9 +21,31 @@ "keywords": [

},
"source": "src/find.ts",
"main": "./dist/geo-tz.js",
"module": "./dist/geo-tz.module.js",
"unpkg": "./dist/geo-tz.umd.js",
"types": "dist/find.d.ts",
"funding": {
"url": "https://github.com/sponsors/evansiroky"
},
"main": "dist/find-1970.js",
"exports": {
".": {
"main": "./dist/find-1970.js",
"import": "./dist/find-1970.js",
"require": "./dist/find-1970.js",
"types": "./dist/find-1970.d.ts"
},
"./all": {
"main": "./dist/find-all.js",
"import": "./dist/find-all.js",
"require": "./dist/find-all.js",
"types": "./dist/find-all.d.ts"
},
"./now": {
"main": "./dist/find-now.js",
"import": "./dist/find-now.js",
"require": "./dist/find-now.js",
"types": "./dist/find-now.d.ts"
}
},
"scripts": {
"build": "microbundle",
"build": "npm-run-all build:*",
"build:all": "microbundle -i src/find-all.ts -o ./dist/find-all.js -f cjs",
"build:1970": "microbundle -i src/find-1970.ts -o ./dist/find-1970.js -f cjs",
"build:now": "microbundle -i src/find-now.ts -o ./dist/find-now.js -f cjs",
"cover": "nyc -r=lcov -r=text npm run test",

@@ -33,35 +55,36 @@ "lint": "eslint scripts src tests --ext .js,.ts",

"test": "mocha -r ts-node/register --max-old-space-size=8192 \"tests/**/*.ts\"",
"updateTzData": "ts-node scripts/update-data.ts"
"updateTzData": "node -r ts-node/register --max-old-space-size=8192 scripts/update-data.ts"
},
"devDependencies": {
"@types/async": "^3.2.16",
"@types/chai": "^4.3.4",
"@types/follow-redirects": "^1.14.1",
"@types/geobuf": "^3.0.1",
"@types/async": "^3.2.24",
"@types/chai": "^4.3.11",
"@types/follow-redirects": "^1.14.4",
"@types/geobuf": "^3.0.4",
"@types/jsts": "^0.17.14",
"@types/lodash": "^4.14.191",
"@types/mocha": "^10.0.1",
"@types/yauzl": "^2.10.0",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"async": "^3.2.4",
"chai": "^4.3.7",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.26.0",
"@types/lodash": "^4.14.202",
"@types/mocha": "^10.0.6",
"@types/yauzl": "^2.10.3",
"@typescript-eslint/eslint-plugin": "^6.16.0",
"@typescript-eslint/parser": "^6.16.0",
"async": "^3.2.5",
"chai": "^4.3.10",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-standard": "^17.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^5.2.0",
"follow-redirects": "^1.15.2",
"eslint-plugin-prettier": "^5.1.2",
"eslint-plugin-promise": "^6.1.1",
"follow-redirects": "^1.15.4",
"jsts": "2.6.1",
"lodash": "^4.17.21",
"microbundle": "^0.15.1",
"mocha": "^10.1.0",
"nock": "^13.2.9",
"mocha": "^10.2.0",
"nock": "^13.4.0",
"npm-run-all": "^4.1.5",
"nyc": "^15.1.0",
"prettier": "^2.8.0",
"semantic-release": "^19.0.5",
"ts-node": "^10.9.1",
"typescript": "^4.9.3",
"prettier": "^3.1.1",
"semantic-release": "^22.0.12",
"ts-node": "^10.9.2",
"typescript": "^5.3.3",
"yauzl": "^2.10.0"

@@ -68,0 +91,0 @@ },

# node-geo-tz
[![npm version](https://badge.fury.io/js/geo-tz.svg)](http://badge.fury.io/js/geo-tz) [![Build Status](https://travis-ci.org/evansiroky/node-geo-tz.svg?branch=master)](https://travis-ci.org/evansiroky/node-geo-tz) [![Dependency Status](https://david-dm.org/evansiroky/node-geo-tz.svg)](https://david-dm.org/evansiroky/node-geo-tz) [![Test Coverage](https://img.shields.io/codecov/c/github/evansiroky/node-geo-tz.svg)](https://codecov.io/github/evansiroky/node-geo-tz)
[![npm version](https://badge.fury.io/js/geo-tz.svg)](http://badge.fury.io/js/geo-tz) [![Test Coverage](https://img.shields.io/codecov/c/github/evansiroky/node-geo-tz.svg)](https://codecov.io/github/evansiroky/node-geo-tz)

@@ -13,21 +13,68 @@ The most up-to-date and accurate node.js geographical timezone lookup package. It's fast too!

```js
const { find } = require('geo-tz')
const { find } = require('geo-tz')
find(47.650499, -122.350070) // ['America/Los_Angeles']
find(43.839319, 87.526148) // ['Asia/Shanghai', 'Asia/Urumqi']
find(47.650499, -122.350070) // ['America/Los_Angeles']
find(43.839319, 87.526148) // ['Asia/Shanghai', 'Asia/Urumqi']
```
## API Docs:
## Data Source and Architecture
As of Version 7, there is no longer a default import. The `find` function should be used instead.
This library aims to do one thing and do it well: find the timezone(s) in use at a GPS coordinate. The output consists of timezone identifiers as defined in the [timezone database](https://www.iana.org/time-zones). The underlying geographic data is obtained from the [timezone-boudary-builder](https://github.com/evansiroky/timezone-boundary-builder) project. The data is indexed for fast analysis by caching subregions of geographic data when a precise lookup is needed.
As of Version 5, the API now returns a list of possible timezones. There are certain coordinates where the timekeeping method will depend on the person you ask. Also, another case where 2 or more timezones could be returned is when a request is made with a coordinate that happens to be exactly on the border between two or more timezones.
This library does an exact geographic lookup which has tradeoffs. The results are more accurate than other libraries that compromise by approximating the lookup of the data. However, it is perhaps a little bit slower that other libraries, has a larger installation size on disk and may encounter difficulties when bundling.
## Entry Points
As of version 8, node-geo-tz offers the ability to choose from the three different timezone boundary products that the [timezone-boudary-builder](https://github.com/evansiroky/timezone-boundary-builder) project produces.
### Alike Since 1970 (default)
The default data product used by this library are unioned timezones that are alike since 1970. This is a breaking change from versions below version 8 that used timezone identifiers that generally had a minimum of one timezone per country. In a number of places, the timezone identifier returned will be that which has the highest population among all timezone identifiers with similar timekeeping methods since 1970.
```js
const { find } = require('geo-tz')
find(12.826174, 45.036933) // ['Asia/Riyadh']
```
When using this product, it is possible that the timezone identifier returned will not be appropriate for calculating the observed time at the GPS coordinate prior to the year 1970.
### Comprehensive
A comprehensive dataset is available to query for all timezone identifiers available. This has the same behavior of this library prior to version 8. This version has the largest file size to accomodate all the needed boundaries. In this dataset, with a few rare exceptions, there is at least one unique timezone identifier per country.
```js
const { find } = require('geo-tz/all')
find(12.826174, 45.036933) // ['Asia/Aden']
```
When using this product, the timezone identifier returned will be appropriate for calculating the observed time at the GPS coordinate including years prior to 1970.
### Same since now
A dataset containing a unioned set of timezones that share the same timekeeping method into the future is the final data product available. This version has the smallest file size as it does not include as many timezones and boundaries. In a number of places, the timezone identifier returned will be that which has the highest population among all timezone identifiers with similar timekeeping methods since the current time.
```js
const { find } = require('geo-tz/now')
find(12.826174, 45.036933) // ['Europe/Moscow']
```
When using this product, the timezone identifier returned will only be appropriate for calculating the observed time at the GPS coordinate for the current and future time.
## API Docs
The API available is the same for each data product.
### find(lat, lon)
Returns the timezone names found at `lat`, `lon`. The timezone names will be the timezone identifiers as defined in the [timezone database](https://www.iana.org/time-zones). The underlying geographic data is obtained from the [timezone-boudary-builder](https://github.com/evansiroky/timezone-boundary-builder) project.
Returns the timezone identifiers found at `lat`, `lon`. There are certain coordinates where the timekeeping method will depend on the person you ask. Also, another case where 2 or more timezones could be returned is when a request is made with a coordinate that happens to be exactly on the border between two or more timezones. If the GPS coordinate does not fall inside any timezone boundary on land, then a timezone at sea will be returned.
This library does an exact geographic lookup which has tradeoffs. It is perhaps a little bit slower that other libraries, has a larger installation size on disk and cannot be used in the browser. However, the results are more accurate than other libraries that compromise by approximating the lookup of the data.
```js
const { find } = require('geo-tz')
The data is indexed for fast analysis by caching subregions of geographic data when a precise lookup is needed.
find(47.650499, -122.350070) // ['America/Los_Angeles']
find(43.839319, 87.526148) // ['Asia/Shanghai', 'Asia/Urumqi']
```

@@ -52,6 +99,18 @@ ### setCache(options)

This library is not intended to be used in the browser due to the large amount of files that are included to perform exact geographic lookups.
### Performance
This library relies on reading a large data file from disk to perform exact geographic lookups. Therefore, it is not intended to be used in the browser and may have issues with bundlers if they don't include the necessary file.
### Accuracy of Output
The underlying data is obtained from the [timezone-boudary-builder](https://github.com/evansiroky/timezone-boundary-builder) project. The data from that project is mostly sourced from OpenStreetMap which is editable by anyone. In most cases, the timezone boundaries follow officially observed boundaries, but often times some communities near timezone boundaries may follow whichever timekeeping method works best for them.
The boundaries in the ocean come from the [timezone-boudary-builder](https://github.com/evansiroky/timezone-boundary-builder) project which only includes territorial waters and not exclusive economic zones. Additionally, special cases where the GPS coordinate falls with an area of [Terra nullius](https://en.wikipedia.org/wiki/Terra_nullius) will also have an ocean zone(s) returned.
The resulting timezone identifiers will represent the timekeeping method as is cataloged to the best of the knowledge of the maintainers of the timezone database. This could be wrong in the past (especially prior to 1970) and could change in the future should an area change the way they keep track of time.
Any concerns about the correctness of results are encouraged to be submitted as issues using the [Incorrect Result Issue Template](https://github.com/evansiroky/node-geo-tz/issues/new?assignees=&labels=&projects=&template=incorrect-result.md&title=Incorrect%20Result%3A+).
## An Important Note About Maintenance
Due to the ever-changing nature of timezone data, it is critical that you always use the latest version of this package. If you use old versions, there will be a few edge cases where the calculated time is wrong. If you use greenkeeper, please be sure to specify an exact target version so you will always get PR's for even patch-level releases.
Due to the ever-changing nature of timezone data, it is critical that the latest version of this package is used. If older versions are used, there will be a few edge cases where the calculated time is wrong.
import * as fs from 'fs'
import * as path from 'path'

@@ -11,8 +10,3 @@ import { decode } from 'geobuf'

const tzData = require('../data/index.json')
const FEATURE_FILE_PATH = path.join(__dirname, '..', 'data', 'geo.dat')
let featureCache
type CacheOptions = {
export type CacheOptions = {
/**

@@ -26,11 +20,18 @@ * If set to true, all features will be loaded into memory to shorten future lookup

*/
store?: any
store?: Map<string, any>
}
/**
* Set caching behavior.
* Set caching behavior and return feature cache.
*
* @param tzData The index data of the timezeone data product
* @param {string} featureFilePath The path to the binary geo.dat file for the timezeone data product
* @param {CacheOptions} options cachine options.
*/
function cacheLevel(options?: CacheOptions) {
export function setCacheLevel(
tzData: any,
featureFilePath: string,
options?: CacheOptions,
): Map<string, any> {
let featureCache
if (

@@ -47,3 +48,3 @@ options &&

if (options && options.preload) {
const featureFileFd = fs.openSync(FEATURE_FILE_PATH, 'r')
const featureFileFd = fs.openSync(featureFilePath, 'r')

@@ -54,17 +55,24 @@ if (featureFileFd < 0) {

_preCache(featureFileFd)
_preCache(tzData, featureFilePath, featureFileFd, featureCache)
fs.closeSync(featureFileFd)
}
return featureCache
}
cacheLevel()
/**
* A function that will load all features into an unexpiring cache
*
* @param tzData
* @param {string} featureFilePath
* @param {number} featureFileFd
* @param featureCache
* @returns {void}
*/
function _preCache(featureFileFd: number) {
function _preCache(
tzData: any,
featureFilePath: string,
featureFileFd: number,
featureCache: Map<string, any>,
) {
// shoutout to github user @magwo for an initial version of this recursive function

@@ -74,10 +82,10 @@ function preloadFeaturesRecursive(curTzData, quadPos: string) {

const geoJson = loadFeatures(
quadPos,
featureFilePath,
curTzData.pos,
curTzData.len,
featureFileFd
featureFileFd,
)
featureCache.set(quadPos, geoJson)
} else if (typeof curTzData === 'object') {
Object.getOwnPropertyNames(curTzData).forEach(function (value) {
Object.getOwnPropertyNames(curTzData).forEach((value) => {
preloadFeaturesRecursive(curTzData[value], quadPos + value)

@@ -94,3 +102,3 @@ })

*
* @param quadPos
* @param featureFilePath
* @param pos

@@ -103,10 +111,10 @@ * @param len

function loadFeatures(
quadPos: string,
featureFilePath: string,
pos: number,
len: number,
fd: number = -1
fd: number = -1,
) {
let featureFileFd = fd
if (featureFileFd < 0) {
featureFileFd = fs.openSync(FEATURE_FILE_PATH, 'r')
featureFileFd = fs.openSync(featureFilePath, 'r')
if (featureFileFd < 0) {

@@ -129,3 +137,3 @@ throw new Error('Failed to open geo.dat file')

throw new Error(
`tried to read ${len} bytes from geo.dat but only got ${bytesRead} bytes`
`tried to read ${len} bytes from geo.dat but only got ${bytesRead} bytes`,
)

@@ -141,2 +149,5 @@ }

*
* @param tzData The indexed lookup dataset to use
* @param featureCache The appropriate featureCache to use
* @param featureFilePath The appropriate featureFilePath to use
* @param lat latitude (must be >= -90 and <=90)

@@ -146,3 +157,9 @@ * @param lon longitue (must be >= -180 and <=180)

*/
export function find(lat: number, lon: number): string[] {
export function findUsingDataset(
tzData: any,
featureCache: any,
featureFilePath: string,
lat: number,
lon: number,
): string[] {
const originalLon = lon

@@ -228,3 +245,3 @@

if (!geoJson) {
geoJson = loadFeatures(quadPos, curTzData.pos, curTzData.len)
geoJson = loadFeatures(featureFilePath, curTzData.pos, curTzData.len)
featureCache.set(quadPos, geoJson)

@@ -260,10 +277,1 @@ }

}
export { cacheLevel as setCache }
/**
* Load all features into memory to speed up future lookups.
*/
export function preCache() {
cacheLevel({ preload: true })
}
import * as fs from 'fs'
import * as path from 'path'

@@ -12,4 +13,10 @@ import { featureCollection, polygon } from '@turf/helpers'

export default function (tzGeojson, dataDir, targetIndexPercent, callback) {
console.log('indexing')
export default function (
tzGeojson,
dataDir,
product,
targetIndexPercent,
callback,
) {
console.log(`indexing data for ${product}`)

@@ -62,3 +69,3 @@ const data = {

'debug_' + debugWriteIdx + '_' + filename + '.json',
JSON.stringify(geoJsonWriter.write(geom))
JSON.stringify(geoJsonWriter.write(geom)),
)

@@ -148,3 +155,3 @@ }

tzIdx,
unindexableData.curBoundsGeometry
unindexableData.curBoundsGeometry,
)

@@ -217,3 +224,3 @@

' of ',
curZones.length
curZones.length,
)

@@ -234,4 +241,4 @@ }

],
]).geometry
)
]).geometry,
),
)

@@ -340,4 +347,4 @@

console.log('reached target index: ', curPctIndexed)
console.log('writing unindexable zone data')
const geoDatFd = fs.openSync(`${dataDir}/geo.dat`, 'w')
console.log(`writing unindexable zone data for ${product}`)
const geoDatFd = fs.openSync(path.join(dataDir, `${product}.geo.dat`), 'w')

@@ -353,3 +360,3 @@ printMod = Math.round(curZones.length / 5)

' of ',
curZones.length
curZones.length,
)

@@ -370,4 +377,4 @@ }

],
]).geometry
)
]).geometry,
),
)

@@ -397,3 +404,3 @@

},
geoDatFd
geoDatFd,
)

@@ -411,5 +418,9 @@ }

console.log('writing index file')
console.log(`writing index file for product ${product}`)
fs.writeFile(dataDir + '/index.json', JSON.stringify(data), callback)
fs.writeFile(
path.join(dataDir, `${product}.index.json`),
JSON.stringify(data),
callback,
)
}

@@ -10,166 +10,184 @@ import * as fs from 'fs'

const TARGET_INDEX_PERCENT = 0.75
const dlFile = path.join(__dirname, '..', 'downloads', 'timezones.zip')
const tzFile = path.join(__dirname, '..', 'downloads', 'timezones.json')
const TARGET_INDEX_PERCENT = 0.8
const dataProducts = [
'timezones.geojson',
'timezones-1970.geojson',
'timezones-now.geojson',
]
let resolvedBaseDir, downloadsDir, dataDir
const downloadLatest = function (callback) {
console.log('Downloading geojson')
async.auto(
{
getLatestUrl: function (cb) {
console.log('Downloading latest release metadata')
https
.get(
{
headers: { 'user-agent': 'node-geo-tz' },
host: 'api.github.com',
path: '/repos/evansiroky/timezone-boundary-builder/releases/latest',
},
function (res) {
let data = ''
res.on('data', function (chunk) {
data += chunk
})
res.on('end', function () {
const parsed = JSON.parse(data)
for (let i = 0; i < parsed.assets.length; i++) {
if (
parsed.assets[i].browser_download_url.indexOf(
'timezones.geojson'
) > -1
) {
return cb(null, parsed.assets[i].browser_download_url)
}
}
cb(new Error('geojson not found'))
})
}
)
.on('error', cb)
function makeFileDownloadPath(product: string) {
return path.join(downloadsDir, `${product}.zip`)
}
function makeUnzipFilePath(product: string) {
return path.join(downloadsDir, `${product}.json`)
}
function recreateDirectory(dir: string, callback) {
console.log(`recreating directory: ${dir}`)
// fs.rm requires node v14+, so this will cause CI failures on node v12
fs.rm(dir, { force: true, recursive: true }, (err) => {
if (err) return callback(err)
fs.mkdir(dir, { recursive: true }, callback)
})
}
function downloadReleaseMetadata(results, callback) {
console.log('Downloading latest release metadata')
https
.get(
{
headers: { 'user-agent': 'node-geo-tz' },
host: 'api.github.com',
path: '/repos/evansiroky/timezone-boundary-builder/releases/latest',
},
rm: function (cb) {
// fs.rm requires node v14+, so this will cause CI failures on node v12
fs.rm(dlFile, { force: true, recursive: true }, cb)
function (res) {
let data = ''
res.on('data', function (chunk) {
data += chunk
})
res.on('end', function () {
let parsed
try {
parsed = JSON.parse(data)
} catch (error) {
return callback(error)
}
if (!parsed.assets) {
return callback(new Error('Unexpected format'))
}
return callback(null, parsed)
})
},
mkdir: [
'rm',
function (results, cb) {
fs.mkdir(
path.join(__dirname, '..', 'downloads'),
{ recursive: true },
cb
)
},
],
dl: [
'mkdir',
'getLatestUrl',
function (results, cb) {
console.log('Downloading latest release data')
https
.get(
{
headers: { 'user-agent': 'node-geo-tz' },
host: 'github.com',
path: results.getLatestUrl.replace('https://github.com', ''),
},
function (response) {
const file = fs.createWriteStream(dlFile)
response.pipe(file)
file.on('finish', function () {
file.close(cb)
})
}
)
.on('error', cb)
},
],
)
.on('error', callback)
}
function downloadProduct(releaseMetadata, product, callback) {
const { assets } = releaseMetadata
let productFound = false
for (let i = 0; i < assets.length; i++) {
if (assets[i].browser_download_url.indexOf(product) > -1) {
productFound = true
const downloadUrl = assets[i].browser_download_url
console.log(`Downloading latest release data product ${product}`)
https
.get(
{
headers: { 'user-agent': 'node-geo-tz' },
host: 'github.com',
path: downloadUrl.replace('https://github.com', ''),
},
function (response) {
const file = fs.createWriteStream(makeFileDownloadPath(product))
response.pipe(file)
file.on('finish', function () {
file.close(callback)
})
},
)
.on('error', callback)
}
}
if (!productFound) {
callback(new Error('Data product not found in release metadata'))
}
}
function unzipDownloadProduct(product, callback) {
console.log(`unzipping data for ${product}`)
yauzl.open(
makeFileDownloadPath(product),
{ lazyEntries: true },
(err, zipfile) => {
if (err) {
return callback(err)
}
zipfile.readEntry()
zipfile.on('entry', (entry) => {
if (/\/$/.test(entry.fileName)) {
// directory, keep reading
zipfile.readEntry()
} else {
// assuming a json file
zipfile.openReadStream(entry, (err, readStream) => {
if (err) {
return callback(err)
}
readStream.pipe(fs.createWriteStream(makeUnzipFilePath(product)))
readStream.on('end', function () {
zipfile.readEntry()
})
})
}
})
zipfile.on('end', callback)
},
callback
)
}
export default function (cfg, callback) {
if (!callback) {
if (typeof cfg === 'function') {
callback = cfg
cfg = {}
} else {
callback = function () {}
}
function processDataProduct(product, callback) {
async.series(
[
// unzip data
(cb) => unzipDownloadProduct(product, cb),
// geoIndex data
(cb) =>
indexGeoJSON(
require(makeUnzipFilePath(product)),
dataDir,
product,
TARGET_INDEX_PERCENT,
cb,
),
],
callback,
)
}
export default function (cfg: { baseDir?: string } | Function, callback?) {
if (typeof cfg === 'function') {
callback = cfg
resolvedBaseDir = path.join(__dirname, '..')
} else {
resolvedBaseDir = cfg.baseDir
callback = callback || function () {}
}
const resolvedDataDir = cfg.dataDir
? path.join(__dirname, '..', cfg.dataDir)
: path.join(__dirname, '..', 'data')
downloadsDir = path.join(resolvedBaseDir, 'downloads')
dataDir = path.join(resolvedBaseDir, 'data')
async.auto(
{
// download latest geojson data
downloadData: function (cb) {
downloadLatest(cb)
},
deleteIndexFoldersAndFiles: [
'downloadData',
function (results, cb) {
async.each(
['geo.dat', 'index.json'],
function (fileOrFolder, eachCb) {
// fs.rm requires node v14+, so this will cause CI failures on node v12
fs.rm(
resolvedDataDir + '/' + fileOrFolder,
{ force: true, recursive: true },
eachCb
)
},
cb
)
},
recreateDownloadDir: (cb) => recreateDirectory(downloadsDir, cb),
recreateDataDir: (cb) => recreateDirectory(dataDir, cb),
downloadReleaseMetadata: ['recreateDownloadDir', downloadReleaseMetadata],
downloadData: [
'downloadReleaseMetadata',
(results, cb) =>
async.map(
dataProducts,
(dataProduct, mapCb) =>
downloadProduct(
results.downloadReleaseMetadata,
dataProduct,
mapCb,
),
cb,
),
],
unzipGeoJson: [
calculateLookupData: [
'recreateDataDir',
'downloadData',
function (results, cb) {
yauzl.open(dlFile, { lazyEntries: true }, function (err, zipfile) {
if (err) {
return cb(err)
}
zipfile.readEntry()
zipfile.on('entry', function (entry) {
if (/\/$/.test(entry.fileName)) {
// directory, keep reading
zipfile.readEntry()
} else {
// assuming a json file
zipfile.openReadStream(entry, function (err, readStream) {
if (err) {
return cb(err)
}
readStream.pipe(fs.createWriteStream(tzFile))
readStream.on('end', function () {
zipfile.readEntry()
})
})
}
})
zipfile.on('end', function (err) {
cb(err)
})
})
},
(results, cb) =>
async.map(
dataProducts,
(dataProduct, mapCb) => processDataProduct(dataProduct, mapCb),
cb,
),
],
createIndex: [
'deleteIndexFoldersAndFiles',
'unzipGeoJson',
function (results, cb) {
indexGeoJSON(
require(tzFile),
resolvedDataDir,
TARGET_INDEX_PERCENT,
cb
)
},
],
},
callback
callback,
)
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc