@mountainpass/addressr 2.0.3 → 2.1.0

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/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
@@ -3,10 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.ELASTIC_PORT = void 0;
6
+ exports.ES_LOCALITY_INDEX_NAME = exports.ELASTIC_PORT = void 0;
7
7
  exports.dropIndex = dropIndex;
8
+ exports.dropLocalityIndex = dropLocalityIndex;
8
9
  exports.esConnect = esConnect;
9
10
  exports.initIndex = initIndex;
11
+ exports.initLocalityIndex = initLocalityIndex;
10
12
  var _debug = _interopRequireDefault(require("debug"));
11
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
14
  const waitPort = require('wait-port');
@@ -14,6 +16,7 @@ const elasticsearch = require('@opensearch-project/opensearch');
14
16
  const logger = (0, _debug.default)('api');
15
17
  const error = (0, _debug.default)('error');
16
18
  const ES_INDEX_NAME = process.env.ES_INDEX_NAME || 'addressr';
19
+ const ES_LOCALITY_INDEX_NAME = exports.ES_LOCALITY_INDEX_NAME = `${ES_INDEX_NAME}-localities`;
17
20
  const ELASTIC_PORT = exports.ELASTIC_PORT = Number.parseInt(process.env.ELASTIC_PORT || '9200');
18
21
  const ELASTIC_HOST = process.env.ELASTIC_HOST || '127.0.0.1';
19
22
  const ELASTIC_USERNAME = process.env.ELASTIC_USERNAME || undefined;
@@ -75,7 +78,7 @@ async function initIndex(esClient, clear, synonyms) {
75
78
  tokenizer: {
76
79
  whitecomma: {
77
80
  type: 'pattern',
78
- pattern: '[\\W,]+',
81
+ pattern: String.raw`[\W,]+`,
79
82
  lowercase: false
80
83
  }
81
84
  }
@@ -164,6 +167,138 @@ async function initIndex(esClient, clear, synonyms) {
164
167
  });
165
168
  logger(`indexGetResult:\n${JSON.stringify(indexGetResult, undefined, 2)}`);
166
169
  }
170
+ async function dropLocalityIndex(esClient) {
171
+ let exists = await esClient.indices.exists({
172
+ index: ES_LOCALITY_INDEX_NAME
173
+ });
174
+ if (exists.body) {
175
+ const deleteIndexResult = await esClient.indices.delete({
176
+ index: ES_LOCALITY_INDEX_NAME
177
+ });
178
+ logger({
179
+ deleteIndexResult
180
+ });
181
+ }
182
+ }
183
+ async function initLocalityIndex(esClient, clear, synonyms) {
184
+ if (clear) {
185
+ await dropLocalityIndex(esClient);
186
+ }
187
+ const exists = await esClient.indices.exists({
188
+ index: ES_LOCALITY_INDEX_NAME
189
+ });
190
+ const indexBody = {
191
+ settings: {
192
+ index: {
193
+ analysis: {
194
+ filter: {
195
+ my_synonym_filter: {
196
+ type: 'synonym',
197
+ lenient: true,
198
+ synonyms: synonyms || []
199
+ },
200
+ comma_stripper: {
201
+ type: 'pattern_replace',
202
+ pattern: ',',
203
+ replacement: ''
204
+ }
205
+ },
206
+ analyzer: {
207
+ my_analyzer: {
208
+ tokenizer: 'whitecomma',
209
+ filter: ['uppercase', 'asciifolding', 'my_synonym_filter', 'comma_stripper', 'trim']
210
+ }
211
+ },
212
+ tokenizer: {
213
+ whitecomma: {
214
+ type: 'pattern',
215
+ pattern: String.raw`[\W,]+`,
216
+ lowercase: false
217
+ }
218
+ }
219
+ }
220
+ }
221
+ },
222
+ aliases: {},
223
+ mappings: {
224
+ properties: {
225
+ locality_name: {
226
+ type: 'text',
227
+ analyzer: 'my_analyzer',
228
+ fields: {
229
+ raw: {
230
+ type: 'keyword'
231
+ }
232
+ }
233
+ },
234
+ locality_class_code: {
235
+ type: 'keyword'
236
+ },
237
+ locality_class_name: {
238
+ type: 'keyword'
239
+ },
240
+ primary_postcode: {
241
+ type: 'keyword'
242
+ },
243
+ state_abbreviation: {
244
+ type: 'keyword'
245
+ },
246
+ state_name: {
247
+ type: 'keyword'
248
+ },
249
+ postcodes: {
250
+ type: 'keyword'
251
+ },
252
+ locality_pid: {
253
+ type: 'keyword'
254
+ }
255
+ }
256
+ }
257
+ };
258
+ if (exists.body) {
259
+ const indexCloseResult = await esClient.indices.close({
260
+ index: ES_LOCALITY_INDEX_NAME
261
+ });
262
+ logger({
263
+ indexCloseResult
264
+ });
265
+ const indexPutSettingsResult = await esClient.indices.putSettings({
266
+ index: ES_LOCALITY_INDEX_NAME,
267
+ body: indexBody
268
+ });
269
+ logger({
270
+ indexPutSettingsResult
271
+ });
272
+ const indexPutMappingResult = await esClient.indices.putMapping({
273
+ index: ES_LOCALITY_INDEX_NAME,
274
+ body: indexBody.mappings
275
+ });
276
+ logger({
277
+ indexPutMappingResult
278
+ });
279
+ const indexOpenResult = await esClient.indices.open({
280
+ index: ES_LOCALITY_INDEX_NAME
281
+ });
282
+ logger({
283
+ indexOpenResult
284
+ });
285
+ const refreshResult = await esClient.indices.refresh({
286
+ index: ES_LOCALITY_INDEX_NAME
287
+ });
288
+ logger({
289
+ refreshResult
290
+ });
291
+ } else {
292
+ logger(`creating index: ${ES_LOCALITY_INDEX_NAME}`);
293
+ const indexCreateResult = await esClient.indices.create({
294
+ index: ES_LOCALITY_INDEX_NAME,
295
+ body: indexBody
296
+ });
297
+ logger({
298
+ indexCreateResult
299
+ });
300
+ }
301
+ }
167
302
  async function esConnect(esport = ELASTIC_PORT, eshost = ELASTIC_HOST, interval = 1000, timeout = 0) {
168
303
  // we keep trying to connect, no matter what
169
304
 
@@ -208,7 +343,7 @@ async function esConnect(esport = ELASTIC_PORT, eshost = ELASTIC_HOST, interval
208
343
  logger(`connecting elastic search client on ${eshost}:${esport}...`);
209
344
  await esClient.ping();
210
345
  logger(`...connected to ${eshost}:${esport}`);
211
- global.esClient = esClient;
346
+ globalThis.esClient = esClient;
212
347
  return esClient;
213
348
  } catch (error_) {
214
349
  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,10 +17,11 @@ 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
+ const op = globalThis.swaggerDocument.paths[p].get;
24
25
  if (op.parameters && op.parameters.some(parameter => parameter.required === true)) {
25
26
  // skip
26
27
  } else {
@@ -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: {},