@mountainpass/addressr 2.0.2 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,79 +1,56 @@
1
1
  # Addressr
2
2
 
3
- ![Addressr](https://addressr.io/icons/icon-144x144.png 'Addressr')
3
+ ![Addressr](https://addressr.io/icons/icon-144x144.png Addressr)
4
4
 
5
5
  [Australian Address Validation, Search and Autocomplete](https://addressr.io) - [addressr.io](https://addressr.io)
6
6
 
7
- [![GitHub license](https://img.shields.io/github/license/mountain-pass/addressr)](https://github.com/mountain-pass/addressr/blob/master/LICENSE) [![npm](https://img.shields.io/npm/v/@mountainpass/addressr)](https://www.npmjs.com/package/@mountainpass/addressr) [![npm downloads](https://img.shields.io/npm/dm/@mountainpass/addressr)](https://www.npmjs.com/package/@mountainpass/addressr) [![Docker Image Version (latest by date)](https://img.shields.io/docker/v/mountainpass/addressr?label=image%20version)](https://hub.docker.com/r/mountainpass/addressr) [![Docker Pulls](https://img.shields.io/docker/pulls/mountainpass/addressr)](https://hub.docker.com/r/mountainpass/addressr)
7
+ [![GitHub license](https://img.shields.io/github/license/mountain-pass/addressr)](https://github.com/mountain-pass/addressr/blob/master/LICENSE) [![npm](https://img.shields.io/npm/v/@mountainpass/addressr)](https://www.npmjs.com/package/@mountainpass/addressr) [![npm downloads](https://img.shields.io/npm/dm/@mountainpass/addressr)](https://www.npmjs.com/package/@mountainpass/addressr)
8
8
 
9
- [![Addressr Build Status](https://circleci.com/gh/mountain-pass/addressr.svg?style=shield)](https://circleci.com/gh/mountain-pass/addressr) [![Maintainability](https://api.codeclimate.com/v1/badges/e5117809cacb7e32eb5c/maintainability)](https://codeclimate.com/github/mountain-pass/addressr/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/e5117809cacb7e32eb5c/test_coverage)](https://codeclimate.com/github/mountain-pass/addressr/test_coverage)
9
+ [![Maintainability](https://api.codeclimate.com/v1/badges/e5117809cacb7e32eb5c/maintainability)](https://codeclimate.com/github/mountain-pass/addressr/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/e5117809cacb7e32eb5c/test_coverage)](https://codeclimate.com/github/mountain-pass/addressr/test_coverage) ![Uptime Robot ratio (30 days)](https://img.shields.io/uptimerobot/ratio/m788652244-3e35661f9886333310f4dc2f)
10
10
 
11
- [![GitHub issues](https://img.shields.io/github/issues/mountain-pass/addressr)](https://github.com/mountain-pass/addressr/issues) [![GitHub pull requests](https://img.shields.io/github/issues-pr/mountain-pass/addressr)](https://github.com/mountain-pass/addressr/pulls) [![Libraries.io dependency status for latest release](https://img.shields.io/librariesio/release/npm/@mountainpass/addressr)](https://libraries.io/npm/@mountainpass%2Faddressr) [![Join the chat at https://gitter.im/mountainpass-addressr/community](https://badges.gitter.im/mountainpass-addressr/community.svg)](https://gitter.im/mountainpass-addressr/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
12
-
13
- [![Gitter](https://badges.gitter.im/mountainpass-addressr/community.svg)](https://gitter.im/mountainpass-addressr/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
14
-
15
- ![Uptime Robot ratio (30 days)](https://img.shields.io/uptimerobot/ratio/m788652244-3e35661f9886333310f4dc2f?logo=data:image/png;base64,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)
11
+ [![GitHub issues](https://img.shields.io/github/issues/mountain-pass/addressr)](https://github.com/mountain-pass/addressr/issues) [![GitHub pull requests](https://img.shields.io/github/issues-pr/mountain-pass/addressr)](https://github.com/mountain-pass/addressr/pulls)
16
12
 
17
13
  # About
18
14
 
19
- Australian Address Validation, Search and Autocomplete
20
-
21
- ## Australian Data Source
22
-
23
- Addresses validated against the Geocoded National Address File (referred to as G-NAF), Australia’s **authoritative** address file.
24
-
25
- ## Software As or **NOT** As A Service
26
-
27
- We love SaaS, but we know its not for everyone. SaaS or self hosted, we've got you covered.
28
-
29
- ## Always Up-To-Date
30
-
31
- Addressr automatically updates with the latest data, so you're never out-of-date.
15
+ Australian Address Validation, Search and Autocomplete powered by the Geocoded National Address File (G-NAF), Australia’s **authoritative** address database with 15+ million addresses.
32
16
 
33
- ## Real-time Address Validation
34
-
35
- Add address autocomplete, search and validation to your forms.
36
-
37
- ## Easy To Use API
17
+ # Quick Start
38
18
 
39
- Build your solution quickly, with our straightforward API.
19
+ ## Use the Hosted API
40
20
 
41
- ## Run On Your Own Infrastructure or Use Ours
21
+ The fastest way to get started. No infrastructure to manage.
42
22
 
43
- On-premise or in the cloud, run Addressr on your own infrastructure, or leave all the hard work to us.
23
+ 1. Get an API key at [RapidAPI](https://rapidapi.com/addressr-addressr-default/api/addressr)
24
+ 2. Search for an address:
44
25
 
45
- ## Completely Free or Pay for Support
26
+ ```sh
27
+ curl "https://addressr.p.rapidapi.com/addresses?q=1+george+st+sydney" \
28
+ -H "x-rapidapi-key: YOUR_KEY" \
29
+ -H "x-rapidapi-host: addressr.p.rapidapi.com"
30
+ ```
46
31
 
47
- That's right, Addressr is completely free **Forever**.
48
- Or for peace of mind for your mission critical solutions, get commercial support you can truly rely on.
32
+ ## Use with AI Assistants
49
33
 
50
- # ToC
34
+ Connect Addressr to Claude, Cursor, VS Code Copilot, or any MCP-compatible AI assistant.
51
35
 
52
- - [Addressr](#addressr)
53
- - [About](#about)
54
- - [Australian Data Source](#australian-data-source)
55
- - [Software As or **NOT** As A Service](#software-as-or-not-as-a-service)
56
- - [Always Up-To-Date](#always-up-to-date)
57
- - [Real-time Address Validation](#real-time-address-validation)
58
- - [Easy To Use API](#easy-to-use-api)
59
- - [Run On Your Own Infrastructure or Use Ours](#run-on-your-own-infrastructure-or-use-ours)
60
- - [Completely Free or Pay for Support](#completely-free-or-pay-for-support)
61
- - [ToC](#toc)
62
- - [Quick Start](#quick-start)
63
- - [Self Hosted](#self-hosted)
64
- - [How it Works](#how-it-works)
65
- - [Additional Settings](#additional-settings)
66
- - [System requirements](#system-requirements)
67
- - [Open Search](#open-search)
68
- - [Addressr Loader](#addressr-loader)
69
- - [Default](#default)
70
- - [With Geocoding enabled](#with-geocoding-enabled)
71
- - [Addressr Server](#addressr-server)
36
+ ```json
37
+ {
38
+ "mcpServers": {
39
+ "addressr": {
40
+ "command": "npx",
41
+ "args": ["-y", "@mountainpass/addressr-mcp"],
42
+ "env": { "RAPIDAPI_KEY": "your-key" }
43
+ }
44
+ }
45
+ }
46
+ ```
72
47
 
73
- # Quick Start
48
+ Three tools available: **search-addresses**, **get-address**, and **health**. See [@mountainpass/addressr-mcp](https://github.com/mountain-pass/addressr-mcp) for full setup instructions.
74
49
 
75
50
  ## Self Hosted
76
51
 
52
+ Run Addressr on your own infrastructure for full control over your data.
53
+
77
54
  1. Install addressr
78
55
 
79
56
  ```
@@ -186,12 +163,12 @@ opensearch >= 1.2.4 with 1.4GiB of memory
186
163
 
187
164
  #### Default
188
165
 
189
- Node.js >= 12.11.0 with 1GiB of memory
166
+ Node.js >= 22 with 1GiB of memory
190
167
 
191
168
  #### With Geocoding enabled
192
169
 
193
- Node.js >= 12.11.0 with 8GiB of memory
170
+ Node.js >= 22 with 8GiB of memory
194
171
 
195
172
  ### Addressr Server
196
173
 
197
- Node.js >= 12.11.0 with 64MiB of memory
174
+ Node.js >= 22 with 64MiB of memory
package/lib/ci/build.js CHANGED
@@ -35,7 +35,7 @@ console.log('starting...');
35
35
  const node = client.container().from('node:12.11.0');
36
36
 
37
37
  // mount cloned repository into Node image
38
- const runner = client.container({
38
+ await client.container({
39
39
  id: node
40
40
  }).withMountedDirectory('/src', source).withWorkdir('/src').withExec(['npm', 'run', 'hello']);
41
41
  });
@@ -28,10 +28,12 @@ actions:
28
28
 
29
29
  */
30
30
 
31
- const cacheDir = `${(0, _envPaths.default)('', {
31
+ const cacheDirectory = `${(0, _envPaths.default)('', {
32
32
  suffix: ''
33
33
  }).cache}/dagger`;
34
- const binLocation = `${cacheDir}/dagger-0.3.9`;
34
+ const binLocation = `${cacheDirectory}/dagger-0.3.9`;
35
+
36
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- internal cache path
35
37
  if (!process.env._EXPERIMENTAL_DAGGER_CLI_BIN && _nodeFs.default.existsSync(binLocation)) {
36
38
  process.env._EXPERIMENTAL_DAGGER_CLI_BIN = binLocation;
37
39
  console.log(`using already downloaded '${binLocation}'`);
@@ -59,8 +61,6 @@ console.log('connecting...');
59
61
  // console.log("Hello from Dagger and Node " + version)
60
62
 
61
63
  await installed.withExec(['npm', 'run', 'genversion']).file('version.js').export('dagger-version.js');
62
- console.log(stdout);
63
- console.error(stderr);
64
64
 
65
65
  /*
66
66
  npm run genversion
@@ -75,7 +75,7 @@ async function initIndex(esClient, clear, synonyms) {
75
75
  tokenizer: {
76
76
  whitecomma: {
77
77
  type: 'pattern',
78
- pattern: '[\\W,]+',
78
+ pattern: String.raw`[\W,]+`,
79
79
  lowercase: false
80
80
  }
81
81
  }
@@ -208,7 +208,7 @@ async function esConnect(esport = ELASTIC_PORT, eshost = ELASTIC_HOST, interval
208
208
  logger(`connecting elastic search client on ${eshost}:${esport}...`);
209
209
  await esClient.ping();
210
210
  logger(`...connected to ${eshost}:${esport}`);
211
- global.esClient = esClient;
211
+ globalThis.esClient = esClient;
212
212
  return esClient;
213
213
  } catch (error_) {
214
214
  error(`An error occurred while trying to connect the elastic search client on ${eshost}:${esport}`, error_);
@@ -17,12 +17,12 @@ function getAddress(request, response) {
17
17
  if (addressResponse.statusCode) {
18
18
  response.setHeader('Content-Type', 'application/json');
19
19
  response.status(addressResponse.statusCode);
20
- response.json(addressResponse.json);
21
- } else {
22
- response.setHeader('link', addressResponse.link.toString());
23
- (0, _writer.writeJson)(response, addressResponse.json);
20
+ return response.json(addressResponse.json);
24
21
  }
25
- return;
22
+ response.setHeader('link', addressResponse.link.toString());
23
+ return (0, _writer.writeJson)(response, addressResponse.json);
24
+ }).catch(function (error_) {
25
+ (0, _writer.writeJson)(response, error_.body || error_);
26
26
  });
27
27
  }
28
28
  function getAddresses(request, response) {
@@ -33,12 +33,12 @@ function getAddresses(request, response) {
33
33
  if (addressesResponse.statusCode) {
34
34
  response.setHeader('Content-Type', 'application/json');
35
35
  response.status(addressesResponse.statusCode);
36
- response.json(addressesResponse.json);
37
- } else {
38
- response.setHeader('link', addressesResponse.link.toString());
39
- response.setHeader('link-template', addressesResponse.linkTemplate.toString());
40
- (0, _writer.writeJson)(response, addressesResponse.json);
36
+ return response.json(addressesResponse.json);
41
37
  }
42
- return;
38
+ response.setHeader('link', addressesResponse.link.toString());
39
+ response.setHeader('link-template', addressesResponse.linkTemplate.toString());
40
+ return (0, _writer.writeJson)(response, addressesResponse.json);
41
+ }).catch(function (error_) {
42
+ (0, _writer.writeJson)(response, error_.body || error_);
43
43
  });
44
44
  }
@@ -10,12 +10,12 @@ var _writer = require("../utils/writer.js");
10
10
 
11
11
  // var logger = debug('api');
12
12
 
13
- function getApiRoot(request, res) {
13
+ function getApiRoot(request, response_) {
14
14
  (0, _DefaultService.getApiRoot)().then(function (response) {
15
- res.setHeader('link', response.link.toString());
16
- res.setHeader('link-template', response.linkTemplate.toString());
17
- (0, _writer.writeJson)(res, response.body);
15
+ response_.setHeader('link', response.link.toString());
16
+ response_.setHeader('link-template', response.linkTemplate.toString());
17
+ return (0, _writer.writeJson)(response_, response.body);
18
18
  }).catch(function (error) {
19
- (0, _writer.writeJson)(res, error.body);
19
+ (0, _writer.writeJson)(response_, error.body);
20
20
  });
21
21
  }
@@ -62,12 +62,12 @@ function createPackageJson(context, filepath) {
62
62
  [name]: version
63
63
  }
64
64
  };
65
- fs.writeFileSync(filepath, JSON.stringify(newPackageJson, null, 2));
65
+ fs.writeFileSync(filepath, JSON.stringify(newPackageJson, undefined, 2)); // eslint-disable-line security/detect-non-literal-fs-filename -- internal deployment path
66
66
  }
67
- async function createDeploymentArchive(deploymentDir) {
68
- shell.mkdir('-p', deploymentDir);
69
- createPackageJson(packageJson, `${deploymentDir}/package.json`);
67
+ async function createDeploymentArchive(deploymentDirectory) {
68
+ shell.mkdir('-p', deploymentDirectory);
69
+ createPackageJson(packageJson, `${deploymentDirectory}/package.json`);
70
70
  const archiveName = packageJson.name.replace('@', '').replace('/', '-');
71
- await zip(`${deploymentDir}/`, `${archiveName}-deployment-${packageJson.version}.zip`);
71
+ await zip(`${deploymentDirectory}/`, `${archiveName}-deployment-${packageJson.version}.zip`);
72
72
  }
73
73
  createDeploymentArchive('./deployment');
@@ -37,24 +37,28 @@ var _default = exports.default = [{
37
37
  strict: 2,
38
38
  'prettier/prettier': 'error',
39
39
  'import-x/default': 0,
40
- 'unicorn/filename-case': ['warn', {
40
+ 'unicorn/filename-case': ['error', {
41
41
  cases: {
42
42
  kebabCase: true,
43
43
  pascalCase: true
44
44
  }
45
45
  }],
46
- 'unicorn/prevent-abbreviations': 'warn',
47
- 'unicorn/no-null': 'warn',
48
- 'unicorn/no-process-exit': 'warn',
46
+ 'unicorn/prevent-abbreviations': ['error', {
47
+ replacements: {
48
+ res: {
49
+ response: true
50
+ },
51
+ dir: {
52
+ directory: true
53
+ }
54
+ }
55
+ }],
56
+ // Blocked by ADR 005 (Babel/CJS — requires native ESM)
49
57
  'unicorn/prefer-module': 'off',
58
+ // waycharter ops.find()/ops.filter() are not Array.prototype — false positives
50
59
  'unicorn/no-array-callback-reference': 'off',
51
- 'unicorn/no-array-for-each': 'off',
52
- 'unicorn/prefer-spread': 'off',
60
+ // Blocked by ADR 005 (Babel/CJS — requires native ESM)
53
61
  'unicorn/prefer-top-level-await': 'off',
54
- 'unicorn/prefer-global-this': 'off',
55
- 'unicorn/require-module-specifiers': 'off',
56
- 'unicorn/prefer-string-raw': 'off',
57
- 'unicorn/no-anonymous-default-export': 'off',
58
62
  'promise/always-return': 'warn',
59
63
  'promise/catch-or-return': 'warn',
60
64
  'n/no-unsupported-features/es-syntax': 'off',
@@ -65,9 +69,16 @@ var _default = exports.default = [{
65
69
  'no-process-exit': 'warn',
66
70
  'no-useless-assignment': 'off',
67
71
  complexity: 'warn',
72
+ 'max-lines-per-function': ['warn', {
73
+ max: 100,
74
+ skipBlankLines: true,
75
+ skipComments: true
76
+ }],
77
+ 'max-depth': ['warn', 4],
78
+ 'max-params': ['warn', 4],
68
79
  'n/hashbang': ['error', {
69
80
  convertPath: {
70
- 'bin/**/*.js': ['^bin/(.+?)\\.js$', 'lib/bin/$1.js']
81
+ 'bin/**/*.js': [String.raw`^bin/(.+?)\.js$`, 'lib/bin/$1.js']
71
82
  }
72
83
  }]
73
84
  }
@@ -89,4 +100,24 @@ var _default = exports.default = [{
89
100
  rules: {
90
101
  'n/hashbang': 'off'
91
102
  }
103
+ }, {
104
+ // Dagger CI runtime — modules resolved by Dagger SDK, not Node.js
105
+ files: ['ci/**'],
106
+ rules: {
107
+ 'import-x/no-unresolved': 'off',
108
+ 'n/no-missing-import': 'off'
109
+ }
110
+ }, {
111
+ // k6 load testing runtime — modules resolved by k6, not Node.js
112
+ files: ['test/k6/**'],
113
+ rules: {
114
+ 'import-x/no-unresolved': 'off',
115
+ 'n/no-missing-import': 'off'
116
+ }
117
+ }, {
118
+ // Deploy scripts — deps installed in deployment context, not dev
119
+ files: ['deploy/**'],
120
+ rules: {
121
+ 'n/no-missing-require': 'off'
122
+ }
92
123
  }];
package/lib/loader.js CHANGED
@@ -3,7 +3,7 @@
3
3
  var _debug = _interopRequireDefault(require("debug"));
4
4
  var _elasticsearch = require("./client/elasticsearch");
5
5
  var _addressService = require("./service/address-service");
6
- var _printVersion = require("./service/printVersion");
6
+ var _printVersion = require("./service/print-version");
7
7
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
8
  const logger = (0, _debug.default)('api');
9
9
  const error = (0, _debug.default)('error');
@@ -12,20 +12,20 @@ if (process.env.DEBUG == undefined) {
12
12
  }
13
13
  const start = process.hrtime();
14
14
  (0, _elasticsearch.esConnect)().then(() => {
15
- logger('es client connected');
15
+ return logger('es client connected');
16
16
  }).then(() => {
17
17
  console.log('======================');
18
18
  console.log('Addressr - Data Loader');
19
19
  console.log('======================');
20
- (0, _printVersion.printVersion)();
20
+ return (0, _printVersion.printVersion)();
21
21
  }).then(_addressService.loadGnaf).then(() => {
22
- logger('data loaded');
22
+ return logger('data loaded');
23
23
  }).then(() => {
24
24
  const end = process.hrtime(start);
25
- logger(`Execution time: ${end[0]}s ${end[1] / 1_000_000}ms`);
25
+ return logger(`Execution time: ${end[0]}s ${end[1] / 1_000_000}ms`);
26
26
  }).then(() => {
27
27
  logger(`Fin`);
28
- process.exit();
28
+ process.exit(); // eslint-disable-line unicorn/no-process-exit, n/no-process-exit, no-process-exit -- CLI loader entry point
29
29
  }).catch(error_ => {
30
30
  error('error loading data', error_);
31
31
  throw error_;
package/lib/server.js CHANGED
@@ -2,20 +2,20 @@
2
2
 
3
3
  var _debug = _interopRequireDefault(require("debug"));
4
4
  var _elasticsearch = require("./client/elasticsearch");
5
- var _printVersion = require("./service/printVersion");
5
+ var _printVersion = require("./service/print-version");
6
6
  var _swagger = require("./swagger");
7
7
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
8
  const logger = (0, _debug.default)('api');
9
- (0, _swagger.startServer)().then(() => {
9
+ (0, _swagger.startServer)().then(async () => {
10
10
  logger('connecting es client');
11
- const p1 = (0, _elasticsearch.esConnect)().then(esClient => {
12
- global.esClient = esClient;
13
- logger('es client connected');
14
- });
15
- p1.then(() => {
16
- console.log('=====================');
17
- console.log('Addressr - API Server');
18
- console.log('=====================');
19
- (0, _printVersion.printVersion)();
20
- });
11
+ const esClient = await (0, _elasticsearch.esConnect)();
12
+ globalThis.esClient = esClient;
13
+ logger('es client connected');
14
+ console.log('=====================');
15
+ console.log('Addressr - API Server');
16
+ console.log('=====================');
17
+ (0, _printVersion.printVersion)();
18
+ }).catch(error => {
19
+ console.error('Failed to start server:', error);
20
+ throw error;
21
21
  });
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getApiRoot = getApiRoot;
7
7
  var _debug = _interopRequireDefault(require("debug"));
8
8
  var _httpLinkHeader = _interopRequireDefault(require("http-link-header"));
9
- var _setLinkOptions = require("./setLinkOptions");
9
+ var _setLinkOptions = require("./set-link-options");
10
10
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
11
  var logger = (0, _debug.default)('api');
12
12
 
@@ -17,11 +17,12 @@ var logger = (0, _debug.default)('api');
17
17
  * returns Root
18
18
  **/
19
19
  async function getApiRoot() {
20
- const paths = Object.keys(global.swaggerDoc.paths).filter(p => global.swaggerDoc.paths[p].get !== undefined && global.swaggerDoc.paths[p].get['x-root-rel'] !== undefined);
20
+ /* eslint-disable security/detect-object-injection -- iterating Object.keys() of swagger spec, not user input */
21
+ const paths = Object.keys(globalThis.swaggerDocument.paths).filter(p => globalThis.swaggerDocument.paths[p].get !== undefined && globalThis.swaggerDocument.paths[p].get['x-root-rel'] !== undefined);
21
22
  const link = new _httpLinkHeader.default();
22
23
  for (const p of paths) {
23
- const op = global.swaggerDoc.paths[p].get;
24
- if (op.parameters && op.parameters.find(parameter => parameter.required === true)) {
24
+ const op = globalThis.swaggerDocument.paths[p].get;
25
+ if (op.parameters && op.parameters.some(parameter => parameter.required === true)) {
25
26
  // skip
26
27
  } else {
27
28
  link.set({
@@ -45,10 +46,13 @@ async function getApiRoot() {
45
46
  });
46
47
  const linkTemplate = new _httpLinkHeader.default();
47
48
  for (const url of paths) {
48
- const op = global.swaggerDoc.paths[url].get;
49
+ const op = globalThis.swaggerDocument.paths[url].get;
49
50
  logger(op);
50
51
  (0, _setLinkOptions.setLinkOptions)(op, url, linkTemplate);
51
52
  }
53
+
54
+ /* eslint-enable security/detect-object-injection */
55
+
52
56
  return {
53
57
  link: link,
54
58
  body: {},
@@ -23,8 +23,8 @@ var _nodeStream = _interopRequireDefault(require("node:stream"));
23
23
  var _unzipStream = _interopRequireDefault(require("unzip-stream"));
24
24
  var _elasticsearch = require("../client/elasticsearch");
25
25
  var _streamDown = _interopRequireDefault(require("../utils/stream-down"));
26
- var _setLinkOptions = require("./setLinkOptions");
27
- var _keyv = _interopRequireDefault(require("keyv"));
26
+ var _setLinkOptions = require("./set-link-options");
27
+ var _keyv = require("keyv");
28
28
  var _keyvFile = require("keyv-file");
29
29
  var _nodeCrypto = _interopRequireDefault(require("node:crypto"));
30
30
  var _glob = require("glob");
@@ -37,7 +37,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
37
37
  const fsp = _nodeFs.default.promises;
38
38
  var logger = (0, _debug.default)('api');
39
39
  var error = (0, _debug.default)('error');
40
- const cache = new _keyv.default({
40
+ const cache = new _keyv.Keyv({
41
41
  store: new _keyvFile.KeyvFile({
42
42
  filename: 'target/keyv-file.msgpack'
43
43
  })
@@ -54,10 +54,10 @@ const ONE_DAY_MS = 1000 * ONE_DAY_S;
54
54
  const THIRTY_DAYS_MS = ONE_DAY_MS * 30;
55
55
  const ES_INDEX_NAME = process.env.ES_INDEX_NAME || 'addressr';
56
56
  async function dropIndex() {
57
- await (0, _elasticsearch.dropIndex)(global.esClient);
57
+ await (0, _elasticsearch.dropIndex)(globalThis.esClient);
58
58
  }
59
59
  async function clearAddresses() {
60
- await (0, _elasticsearch.initIndex)(global.esClient, true);
60
+ await (0, _elasticsearch.initIndex)(globalThis.esClient, true);
61
61
  }
62
62
  async function setAddresses(addr) {
63
63
  await clearAddresses();
@@ -458,7 +458,7 @@ function mapGeo(geoSite, context, geoDefault) {
458
458
  })
459
459
  };
460
460
  }) : [];
461
- const def = geoDefault && !foundDefault ? geoDefault.map(geo => {
461
+ const defaults = geoDefault && !foundDefault ? geoDefault.map(geo => {
462
462
  return {
463
463
  default: true,
464
464
  ...(geo.GEOCODE_TYPE_CODE !== '' && {
@@ -475,7 +475,7 @@ function mapGeo(geoSite, context, geoDefault) {
475
475
  })
476
476
  };
477
477
  }) : [];
478
- return sites.concat(def);
478
+ return [...sites, ...defaults];
479
479
  }
480
480
  function mapToSla(fla) {
481
481
  return fla.join(', ');
@@ -819,7 +819,7 @@ async function loadAddressDetails(file, expectedCount, context, {
819
819
  }
820
820
  async function searchForAddress(searchString, p, pageSize = PAGE_SIZE) {
821
821
  // const searchString = '657 The Entrance Road'; //'2/25 TOTTERDE'; // 'UNT 2, BELCONNEN';
822
- const searchResp = await global.esClient.search({
822
+ const searchResp = await globalThis.esClient.search({
823
823
  index: ES_INDEX_NAME,
824
824
  body: {
825
825
  from: (p - 1 || 0) * pageSize,
@@ -882,7 +882,7 @@ async function sendIndexRequest(indexingBody, initialBackoff = Number.parseInt(p
882
882
  // eslint-disable-next-line no-constant-condition
883
883
  for (let count = 0; true; count++) {
884
884
  try {
885
- const resp = await global.esClient.bulk({
885
+ const resp = await globalThis.esClient.bulk({
886
886
  refresh,
887
887
  body: indexingBody,
888
888
  timeout: process.env.ADDRESSR_INDEX_TIMEOUT || '300s'
@@ -962,21 +962,21 @@ function buildSynonyms(context) {
962
962
  const {
963
963
  readdir
964
964
  } = require('node:fs').promises;
965
- async function getFiles(currentDir, baseDir) {
966
- const dir = _nodePath.default.resolve(baseDir, currentDir);
967
- logger(`reading ${dir} (${currentDir} in ${baseDir})`);
968
- const dirents = await readdir(dir, {
965
+ async function getFiles(currentDirectory, baseDirectory) {
966
+ const directory = _nodePath.default.resolve(baseDirectory, currentDirectory);
967
+ logger(`reading ${directory} (${currentDirectory} in ${baseDirectory})`);
968
+ const dirents = await readdir(directory, {
969
969
  withFileTypes: true
970
970
  });
971
971
  const files = await Promise.all(dirents.map(dirent => {
972
- const res = `${currentDir}/${dirent.name}`;
973
- return dirent.isDirectory() ? getFiles(res, baseDir) : res;
972
+ const result = `${currentDirectory}/${dirent.name}`;
973
+ return dirent.isDirectory() ? getFiles(result, baseDirectory) : result;
974
974
  }));
975
- return Array.prototype.concat(...files);
975
+ return files.flat();
976
976
  }
977
977
  function countFileLines(filePath) {
978
978
  return new Promise((resolve, reject) => {
979
- const readStream = _nodeFs.default.createReadStream(filePath, 'utf-8');
979
+ const readStream = _nodeFs.default.createReadStream(filePath, 'utf8');
980
980
  let lines = 0;
981
981
  let last;
982
982
  readStream.on('data', function (chunk) {
@@ -1028,7 +1028,7 @@ async function loadGnafData(directory, {
1028
1028
  await loadAuthFiles(files, directory, loadContext, filesCounts);
1029
1029
  // loadContext now contains all the auth files, so we can build the synonyms
1030
1030
  const synonyms = buildSynonyms(loadContext);
1031
- await (0, _elasticsearch.initIndex)(global.esClient, process.env.ES_CLEAR_INDEX || false, synonyms);
1031
+ await (0, _elasticsearch.initIndex)(globalThis.esClient, process.env.ES_CLEAR_INDEX || false, synonyms);
1032
1032
  const addressDetailFiles = files.filter(f => f.match(/ADDRESS_DETAIL/) && f.match(/\/Standard\//));
1033
1033
  logger('addressDetailFiles', addressDetailFiles);
1034
1034
  for (const detailFile of addressDetailFiles) {
@@ -1113,10 +1113,6 @@ async function loadFileCounts(countsFile) {
1113
1113
  logger('filesCounts', filesCounts);
1114
1114
  return filesCounts;
1115
1115
  }
1116
- async function loadFileContents(contentsFile) {
1117
- const contents = await fsp.readFile(contentsFile);
1118
- return contents.toString().split('\n').map(line => line.trim());
1119
- }
1120
1116
  async function loadState(files, directory, state) {
1121
1117
  const stateFile = files.find(f => f.match(new RegExp(`${state}_STATE_psv`)));
1122
1118
  if (stateFile === undefined) {
@@ -1310,14 +1306,14 @@ async function loadGnaf({
1310
1306
  if (contents.length === 0) {
1311
1307
  throw new Error(`Data dir '${unzipped}' is empty`);
1312
1308
  }
1313
- const gnafDir = await (0, _glob.glob)('**/G-NAF/', {
1309
+ const gnafDirectory = await (0, _glob.glob)('**/G-NAF/', {
1314
1310
  cwd: unzipped
1315
1311
  });
1316
- console.log(gnafDir);
1317
- if (gnafDir.length === 0) {
1312
+ console.log(gnafDirectory);
1313
+ if (gnafDirectory.length === 0) {
1318
1314
  throw new Error(`Cannot find 'G-NAF' directory in Data dir '${unzipped}'`);
1319
1315
  }
1320
- mainDirectory = _nodePath.default.dirname(`${unzipped}/${gnafDir[0].slice(0, -1)}`);
1316
+ mainDirectory = _nodePath.default.dirname(`${unzipped}/${gnafDirectory[0].slice(0, -1)}`);
1321
1317
  }
1322
1318
  logger('Main Data dir', mainDirectory);
1323
1319
  await loadGnafData(mainDirectory, {
@@ -1334,7 +1330,7 @@ async function loadGnaf({
1334
1330
  **/
1335
1331
  async function getAddress(addressId) {
1336
1332
  try {
1337
- const jsonX = await global.esClient.get({
1333
+ const jsonX = await globalThis.esClient.get({
1338
1334
  index: ES_INDEX_NAME,
1339
1335
  id: `/addresses/${addressId}`
1340
1336
  });
@@ -2,20 +2,20 @@
2
2
 
3
3
  var _debug = _interopRequireDefault(require("debug"));
4
4
  var _elasticsearch = require("../client/elasticsearch");
5
- var _printVersion = require("../service/printVersion");
6
- var _waycharterServer = require("./waycharterServer");
5
+ var _printVersion = require("../service/print-version");
6
+ var _waycharterServer = require("./waycharter-server");
7
7
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
8
  const logger = (0, _debug.default)('api');
9
- (0, _waycharterServer.startRest2Server)().then(() => {
9
+ (0, _waycharterServer.startRest2Server)().then(async () => {
10
10
  logger('connecting es client');
11
- const p1 = (0, _elasticsearch.esConnect)().then(esClient => {
12
- global.esClient = esClient;
13
- logger('es client connected');
14
- });
15
- p1.then(() => {
16
- console.log('=======================');
17
- console.log('Addressr - API Server 2');
18
- console.log('=======================');
19
- (0, _printVersion.printVersion)();
20
- });
11
+ const esClient = await (0, _elasticsearch.esConnect)();
12
+ globalThis.esClient = esClient;
13
+ logger('es client connected');
14
+ console.log('=======================');
15
+ console.log('Addressr - API Server 2');
16
+ console.log('=======================');
17
+ (0, _printVersion.printVersion)();
18
+ }).catch(error => {
19
+ console.error('Failed to start server:', error);
20
+ throw error;
21
21
  });
package/lib/swagger.js CHANGED
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.startServer = startServer;
7
7
  exports.stopServer = stopServer;
8
- exports.swaggerDoc = void 0;
8
+ exports.swaggerDocument = void 0;
9
9
  exports.swaggerInit = swaggerInit;
10
10
  var _debug = _interopRequireDefault(require("debug"));
11
11
  var _express = _interopRequireDefault(require("express"));
@@ -32,12 +32,12 @@ var options = {
32
32
 
33
33
  // The Swagger document (require it, build it programmatically, fetch it from a URL, ...)
34
34
  var spec = (0, _nodeFs.readFileSync)(_nodePath.default.join(__dirname, 'api/swagger.yaml'), 'utf8');
35
- var swaggerDoc = exports.swaggerDoc = (0, _jsYaml.load)(spec);
36
- global.swaggerDoc = swaggerDoc;
35
+ var swaggerDocument = exports.swaggerDocument = (0, _jsYaml.load)(spec);
36
+ globalThis.swaggerDocument = swaggerDocument;
37
37
  function swaggerInit() {
38
38
  // Initialize the Swagger middleware
39
39
  return new Promise(resolve => {
40
- (0, _swaggerTools.initializeMiddleware)(swaggerDoc, function (middleware) {
40
+ (0, _swaggerTools.initializeMiddleware)(swaggerDocument, function (middleware) {
41
41
  // Interpret Swagger resources and attach metadata to request - must be first in swagger-tools middleware chain
42
42
  const metaData = middleware.swaggerMetadata();
43
43
  app.use(metaData);
@@ -55,7 +55,7 @@ function swaggerInit() {
55
55
  // apiDocs: '/api-docs',
56
56
  // swaggerUi: '/docs',
57
57
  }));
58
- app.use(function (error_, request, res, next) {
58
+ app.use(function (error_, request, response, next) {
59
59
  if (error_.failedValidation) {
60
60
  // handle validation errror
61
61
  const rehydratedError = Object.assign({}, error_);
@@ -70,13 +70,13 @@ function swaggerInit() {
70
70
  delete rehydratedError.results;
71
71
  }
72
72
  error('error!!!', error_.message, JSON.stringify(rehydratedError, undefined, 2));
73
- res.status(error_.code === 'SCHEMA_VALIDATION_FAILED' ? '500' : '400').json(rehydratedError);
73
+ response.status(error_.code === 'SCHEMA_VALIDATION_FAILED' ? '500' : '400').json(rehydratedError);
74
74
  } else {
75
75
  next();
76
76
  }
77
77
  });
78
- global.swaggerApp = app;
79
- global.swaggerMiddleware = middleware;
78
+ globalThis.swaggerApp = app;
79
+ globalThis.swaggerMiddleware = middleware;
80
80
  resolve({
81
81
  app,
82
82
  middleware
@@ -2,21 +2,19 @@
2
2
 
3
3
  var _progress = _interopRequireDefault(require("progress"));
4
4
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
5
- const {
6
- parse
7
- } = require('node:url');
8
5
  const http = require('node:https');
9
6
  const fs = require('node:fs');
10
7
  const pathUtil = require('node:path');
11
- module.exports = function (url, path, size) {
12
- const uri = parse(url);
8
+ module.exports = function streamDown(url, path, size) {
9
+ const uri = new URL(url);
13
10
  if (!path) {
14
- path = pathUtil.basename(uri.path);
11
+ path = pathUtil.basename(uri.pathname);
15
12
  }
16
- const file = fs.createWriteStream(path);
13
+ const file = fs.createWriteStream(path); // eslint-disable-line security/detect-non-literal-fs-filename -- path is internal
14
+
17
15
  return new Promise(function (resolve, reject) {
18
- http.get(uri.href).on('response', function (res) {
19
- const length = res.headers['content-length'] ? Number.parseInt(res.headers['content-length'], 10) : size;
16
+ http.get(uri.toString()).on('response', function (response) {
17
+ const length = response.headers['content-length'] ? Number.parseInt(response.headers['content-length'], 10) : size;
20
18
  // let downloaded = 0;
21
19
  // let percent = 0;
22
20
  var bar = new _progress.default(' downloading [:bar] :rate/bps :percent :etas', {
@@ -25,7 +23,7 @@ module.exports = function (url, path, size) {
25
23
  width: 20,
26
24
  total: length
27
25
  });
28
- res.on('data', function (chunk) {
26
+ response.on('data', function (chunk) {
29
27
  file.write(chunk);
30
28
  // downloaded += chunk.length;
31
29
  //percent = ((100.0 * downloaded) / len).toFixed(2);
@@ -39,8 +37,8 @@ module.exports = function (url, path, size) {
39
37
  // );
40
38
  }).on('end', function () {
41
39
  file.end();
42
- console.log(`\n${uri.path} downloaded to: ${path}`);
43
- resolve(res);
40
+ console.log(`\n${uri.pathname} downloaded to: ${path}`);
41
+ resolve(response);
44
42
  }).on('error', function (error) {
45
43
  reject(error);
46
44
  });
package/lib/version.js CHANGED
@@ -5,4 +5,4 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.version = void 0;
7
7
  // Generated by genversion.
8
- const version = exports.version = '2.0.2';
8
+ const version = exports.version = '2.0.4';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mountainpass/addressr",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "Australian Address Validation, Search and Autocomplete",
5
5
  "author": {
6
6
  "name": "Mountain Pass",
@@ -106,6 +106,7 @@
106
106
  "test:cli2:geo": "ES_INDEX_NAME=test PORT=$npm_package_config_localport ADDRESSR_ENABLE_GEO=1 DEBUG=error,api,express:*,swagger-tools*,test,es run-p --race start:server2:preinstalled dotest:cli2:geo",
107
107
  "dotest:cli2:geo": "ADDRESSR_ENABLE_GEO=1 ES_INDEX_NAME=test COVERED_STATES=OT TEST_PROFILE=cli2 cucumber-js -p cli2 -- --harmony_async_iteration",
108
108
  "cover:cli:geo": "nyc --report-dir coverage/cli --temp-dir coverage/cli/.nyc_output npm run test:cli:nogeo",
109
+ "test:mcp:smoke": "node --test test/mcp/smoke.test.mjs",
109
110
  "test:nodejs:QLD:nogeo": "PORT=$npm_package_config_localport ES_INDEX_NAME=test COVERED_STATES=QLD DEBUG=error,api,express:*,swagger-tools*,test,es TEST_PROFILE=default cucumber-js -p default -- --harmony_async_iteration",
110
111
  "test:nodejs:QLD:geo": "PORT=$npm_package_config_localport ADDRESSR_ENABLE_GEO=1 ES_INDEX_NAME=test-geo COVERED_STATES=QLD DEBUG=error,api,express:*,swagger-tools*,test,es TEST_PROFILE=default NODE_OPTIONS=--max_old_space_size=8196 cucumber-js -p default -- --harmony_async_iteration",
111
112
  "prebuildX": "npm run genversion && cat ./templates/LICENSE.md | envsubst '${PRODUCT},${VERSION},${COMPANY},${YEAR}' > ./LICENSE.md",
@@ -170,9 +171,9 @@
170
171
  "glob": "^13.0.6",
171
172
  "http-link-header": "^1.1.3",
172
173
  "js-yaml": "^4.1.1",
173
- "json-ptr": "2.1.0",
174
- "keyv": "^4.0.1",
175
- "keyv-file": "^0.2.0",
174
+ "json-ptr": "^3.1.1",
175
+ "keyv": "^5.6.0",
176
+ "keyv-file": "^5.3.3",
176
177
  "node-machine-id": "^1.1.12",
177
178
  "papaparse": "^5.0.0",
178
179
  "progress": "^2.0.3",
@@ -180,7 +181,7 @@
180
181
  "swagger-tools": "^0.10.4",
181
182
  "unzip-stream": "^0.3.0",
182
183
  "uri-template-lite": "^23.4.0",
183
- "wait-port": "^0.2.2"
184
+ "wait-port": "^1.1.0"
184
185
  },
185
186
  "devDependencies": {
186
187
  "@babel/cli": "^7.6.2",
@@ -195,10 +196,11 @@
195
196
  "@babel/register": "^7.7.0",
196
197
  "@babel/runtime": "^7.5.0",
197
198
  "@cucumber/cucumber": "^12.7.0",
199
+ "@modelcontextprotocol/sdk": "^1.29.0",
198
200
  "@eslint-community/eslint-plugin-eslint-comments": "^4.7.1",
199
201
  "@eslint/js": "^9.39.4",
200
202
  "@istanbuljs/nyc-config-babel": "^3.0.0",
201
- "@mountainpass/waychaser": "^5.0.44",
203
+ "@mountainpass/waychaser": "^5.0.50",
202
204
  "babel-plugin-istanbul": "^7.0.1",
203
205
  "bats": "^1.13.0",
204
206
  "chai": "^4.2.0",
@@ -211,7 +213,7 @@
211
213
  "eslint-plugin-prettier": "^5.5.5",
212
214
  "eslint-plugin-promise": "^7.2.1",
213
215
  "eslint-plugin-security": "^4.0.0",
214
- "eslint-plugin-unicorn": "^63.0.0",
216
+ "eslint-plugin-unicorn": "^64.0.0",
215
217
  "genversion": "^3.0.0",
216
218
  "globals": "^17.4.0",
217
219
  "husky": "^9.1.7",
@@ -222,7 +224,7 @@
222
224
  "nodemon": "^3.1.14",
223
225
  "npm-check": "^6.0.1",
224
226
  "npm-run-all": "^4.1.5",
225
- "nyc": "^15.1.0",
227
+ "nyc": "^18.0.0",
226
228
  "prettier": "^3.8.1",
227
229
  "prettier-config-standard": "^7.0.0",
228
230
  "turbo": "^2.8.17"
@@ -7,5 +7,5 @@ if (!satisfies(process.version, version)) {
7
7
  console.log(
8
8
  `Required node version ${version} not satisfied with current version ${process.version}.`,
9
9
  );
10
- process.exit(1);
10
+ process.exit(1); // eslint-disable-line no-process-exit, n/no-process-exit -- postinstall version check
11
11
  }