@mountainpass/addressr 2.1.1 → 2.1.3

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.
@@ -113,6 +113,9 @@ async function initIndex(esClient, clear, synonyms) {
113
113
  },
114
114
  confidence: {
115
115
  type: 'integer'
116
+ },
117
+ locality_pid: {
118
+ type: 'keyword'
116
119
  }
117
120
  }
118
121
  }
@@ -737,7 +737,8 @@ async function loadAddressDetails(file, expectedCount, context, {
737
737
  sla,
738
738
  ssla,
739
739
  structured,
740
- confidence: structured.structured.confidence
740
+ confidence: structured.structured.confidence,
741
+ locality_pid: row.LOCALITY_PID
741
742
  });
742
743
  }
743
744
  if (indexingBody.length > 0) {
@@ -984,20 +985,13 @@ async function getPostcode(postcode) {
984
985
  const searchResp = await globalThis.esClient.search({
985
986
  index: _elasticsearch.ES_LOCALITY_INDEX_NAME,
986
987
  body: {
987
- size: 0,
988
+ size: 100,
988
989
  query: {
989
990
  term: {
990
991
  postcodes: postcode
991
992
  }
992
993
  },
993
- aggs: {
994
- localities: {
995
- terms: {
996
- field: 'locality_name.raw',
997
- size: 100
998
- }
999
- }
1000
- }
994
+ _source: ['locality_name', 'locality_pid']
1001
995
  }
1002
996
  });
1003
997
  return searchResp;
@@ -1018,18 +1012,6 @@ async function getState(abbreviation) {
1018
1012
  field: 'state_name',
1019
1013
  size: 1
1020
1014
  }
1021
- },
1022
- localities: {
1023
- terms: {
1024
- field: 'locality_name.raw',
1025
- size: 1000
1026
- }
1027
- },
1028
- postcodes: {
1029
- terms: {
1030
- field: 'postcodes',
1031
- size: 1000
1032
- }
1033
1015
  }
1034
1016
  }
1035
1017
  }
@@ -1599,10 +1581,12 @@ async function getAddress(addressId) {
1599
1581
  });
1600
1582
  // TODO: store hash in address
1601
1583
  const hash = _nodeCrypto.default.createHash('md5').update(JSON.stringify(json)).digest('hex');
1584
+ const localityPid = jsonX.body._source.locality_pid;
1602
1585
  return {
1603
1586
  link,
1604
1587
  json,
1605
- hash
1588
+ hash,
1589
+ localityPid
1606
1590
  };
1607
1591
  } catch (error_) {
1608
1592
  error('error getting record from elastic search', error_);
@@ -18,6 +18,638 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
18
18
  var app = (0, _express.default)();
19
19
  const ONE_DAY = 60 * 60 * 24;
20
20
  const ONE_WEEK = ONE_DAY * 7;
21
+ function buildOpenApiSpec(apiVersion) {
22
+ const schemas = {
23
+ AddressSearchResult: {
24
+ type: 'object',
25
+ properties: {
26
+ sla: {
27
+ type: 'string',
28
+ description: 'Single line address',
29
+ example: 'UNIT 1, 19 MURRAY RD, CHRISTMAS ISLAND OT 6798'
30
+ },
31
+ ssla: {
32
+ type: 'string',
33
+ description: 'Short single line address (for addresses with flats)',
34
+ example: '1/19 MURRAY RD, CHRISTMAS ISLAND OT 6798'
35
+ },
36
+ highlight: {
37
+ type: 'object',
38
+ description: 'Search term highlights in the address',
39
+ properties: {
40
+ sla: {
41
+ type: 'string'
42
+ },
43
+ ssla: {
44
+ type: 'string'
45
+ }
46
+ }
47
+ },
48
+ score: {
49
+ type: 'number',
50
+ description: 'Search relevance score',
51
+ example: 5.43
52
+ },
53
+ pid: {
54
+ type: 'string',
55
+ description: 'Persistent identifier for the address',
56
+ example: 'GAOT_717882967'
57
+ }
58
+ }
59
+ },
60
+ Address: {
61
+ type: 'object',
62
+ properties: {
63
+ sla: {
64
+ type: 'string',
65
+ example: 'UNIT 1, 19 MURRAY RD, CHRISTMAS ISLAND OT 6798'
66
+ },
67
+ structured: {
68
+ type: 'object',
69
+ properties: {
70
+ confidence: {
71
+ type: 'integer',
72
+ example: 2
73
+ },
74
+ flat: {
75
+ type: 'object',
76
+ properties: {
77
+ number: {
78
+ type: 'integer',
79
+ example: 1
80
+ },
81
+ type: {
82
+ type: 'object',
83
+ properties: {
84
+ code: {
85
+ type: 'string',
86
+ example: 'UNIT'
87
+ },
88
+ name: {
89
+ type: 'string',
90
+ example: 'UNIT'
91
+ }
92
+ }
93
+ }
94
+ }
95
+ },
96
+ number: {
97
+ type: 'object',
98
+ properties: {
99
+ number: {
100
+ type: 'integer',
101
+ example: 19
102
+ }
103
+ }
104
+ },
105
+ street: {
106
+ type: 'object',
107
+ properties: {
108
+ name: {
109
+ type: 'string',
110
+ example: 'MURRAY'
111
+ },
112
+ type: {
113
+ type: 'object',
114
+ properties: {
115
+ code: {
116
+ type: 'string',
117
+ example: 'ROAD'
118
+ },
119
+ name: {
120
+ type: 'string',
121
+ example: 'RD'
122
+ }
123
+ }
124
+ }
125
+ }
126
+ },
127
+ locality: {
128
+ type: 'object',
129
+ properties: {
130
+ name: {
131
+ type: 'string',
132
+ example: 'CHRISTMAS ISLAND'
133
+ },
134
+ class: {
135
+ type: 'object',
136
+ properties: {
137
+ code: {
138
+ type: 'string',
139
+ example: 'U'
140
+ },
141
+ name: {
142
+ type: 'string',
143
+ example: 'UNOFFICIAL SUBURB'
144
+ }
145
+ }
146
+ }
147
+ }
148
+ },
149
+ postcode: {
150
+ type: 'string',
151
+ example: '6798'
152
+ },
153
+ state: {
154
+ type: 'object',
155
+ properties: {
156
+ abbreviation: {
157
+ type: 'string',
158
+ example: 'OT'
159
+ },
160
+ name: {
161
+ type: 'string',
162
+ example: 'OTHER TERRITORIES'
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+ },
170
+ LocalitySearchResult: {
171
+ type: 'object',
172
+ properties: {
173
+ name: {
174
+ type: 'string',
175
+ example: 'LILYDALE'
176
+ },
177
+ state: {
178
+ type: 'object',
179
+ properties: {
180
+ name: {
181
+ type: 'string',
182
+ example: 'VICTORIA'
183
+ },
184
+ abbreviation: {
185
+ type: 'string',
186
+ example: 'VIC'
187
+ }
188
+ }
189
+ },
190
+ class: {
191
+ type: 'object',
192
+ properties: {
193
+ code: {
194
+ type: 'string',
195
+ description: 'Classification code (G=Gazetted, U=Unofficial, T=Topographic, I=Informal)',
196
+ example: 'G'
197
+ },
198
+ name: {
199
+ type: 'string',
200
+ example: 'GAZETTED LOCALITY'
201
+ }
202
+ }
203
+ },
204
+ postcode: {
205
+ type: 'string',
206
+ description: 'Primary postcode for this locality',
207
+ example: '3140'
208
+ },
209
+ score: {
210
+ type: 'number',
211
+ example: 5.23
212
+ },
213
+ pid: {
214
+ type: 'string',
215
+ example: 'loc1234567890ab'
216
+ }
217
+ }
218
+ },
219
+ Locality: {
220
+ type: 'object',
221
+ properties: {
222
+ locality_name: {
223
+ type: 'string',
224
+ example: 'CHRISTMAS ISLAND'
225
+ },
226
+ locality_class_code: {
227
+ type: 'string',
228
+ example: 'U'
229
+ },
230
+ locality_class_name: {
231
+ type: 'string',
232
+ example: 'UNOFFICIAL SUBURB'
233
+ },
234
+ primary_postcode: {
235
+ type: 'string',
236
+ example: '6798'
237
+ },
238
+ postcodes: {
239
+ type: 'array',
240
+ items: {
241
+ type: 'string'
242
+ },
243
+ example: ['6798']
244
+ },
245
+ state_abbreviation: {
246
+ type: 'string',
247
+ example: 'OT'
248
+ },
249
+ state_name: {
250
+ type: 'string',
251
+ example: 'OTHER TERRITORIES'
252
+ },
253
+ locality_pid: {
254
+ type: 'string',
255
+ example: 'loc9984d8beb142'
256
+ }
257
+ }
258
+ },
259
+ PostcodeSearchResult: {
260
+ type: 'object',
261
+ properties: {
262
+ postcode: {
263
+ type: 'string',
264
+ example: '3140'
265
+ },
266
+ localities: {
267
+ type: 'array',
268
+ items: {
269
+ type: 'object',
270
+ properties: {
271
+ name: {
272
+ type: 'string',
273
+ example: 'LILYDALE'
274
+ }
275
+ }
276
+ }
277
+ }
278
+ }
279
+ },
280
+ PostcodeDetail: {
281
+ type: 'object',
282
+ properties: {
283
+ postcode: {
284
+ type: 'string',
285
+ example: '6798'
286
+ },
287
+ localities: {
288
+ type: 'array',
289
+ description: 'Locality names. Individual locality resources are linked via related Link headers.',
290
+ items: {
291
+ type: 'object',
292
+ properties: {
293
+ name: {
294
+ type: 'string',
295
+ example: 'CHRISTMAS ISLAND'
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+ },
302
+ State: {
303
+ type: 'object',
304
+ properties: {
305
+ abbreviation: {
306
+ type: 'string',
307
+ example: 'NSW'
308
+ },
309
+ name: {
310
+ type: 'string',
311
+ example: 'NEW SOUTH WALES'
312
+ }
313
+ }
314
+ },
315
+ Health: {
316
+ type: 'object',
317
+ properties: {
318
+ status: {
319
+ type: 'string',
320
+ example: 'healthy'
321
+ },
322
+ version: {
323
+ type: 'string',
324
+ example: '2.1.2'
325
+ },
326
+ timestamp: {
327
+ type: 'string',
328
+ format: 'date-time',
329
+ example: '2026-04-14T11:17:54.637Z'
330
+ }
331
+ }
332
+ }
333
+ };
334
+ return {
335
+ openapi: '3.0.3',
336
+ info: {
337
+ title: 'Addressr by Mountain Pass',
338
+ description: 'Free Australian Address Validation, Search and Autocomplete. This OpenAPI spec is supplementary — the HATEOAS link-driven API is the authoritative contract. Follow `related` Link headers to navigate between addresses, localities, postcodes and states.',
339
+ version: apiVersion
340
+ },
341
+ servers: [{
342
+ url: 'https://addressr.p.rapidapi.com',
343
+ description: 'RapidAPI'
344
+ }],
345
+ paths: {
346
+ '/addresses': {
347
+ get: {
348
+ summary: 'Search Addresses',
349
+ description: 'Search Australian addresses by any component — street, suburb, postcode, state. Supports fuzzy and prefix matching.',
350
+ operationId: 'searchAddresses',
351
+ tags: ['Addresses'],
352
+ parameters: [{
353
+ name: 'q',
354
+ in: 'query',
355
+ required: true,
356
+ schema: {
357
+ type: 'string',
358
+ minLength: 3
359
+ },
360
+ example: 'UNIT 1, 19 MURRAY RD, CHRISTMAS ISLAND',
361
+ description: 'Address search query (min 3 characters)'
362
+ }, {
363
+ name: 'page',
364
+ in: 'query',
365
+ required: false,
366
+ schema: {
367
+ type: 'integer',
368
+ minimum: 0
369
+ },
370
+ example: 0,
371
+ description: 'Zero-based page number for pagination'
372
+ }],
373
+ responses: {
374
+ 200: {
375
+ description: 'List of matching addresses',
376
+ content: {
377
+ 'application/json': {
378
+ schema: {
379
+ type: 'array',
380
+ items: {
381
+ $ref: '#/components/schemas/AddressSearchResult'
382
+ }
383
+ }
384
+ }
385
+ }
386
+ }
387
+ }
388
+ }
389
+ },
390
+ '/addresses/{pid}': {
391
+ get: {
392
+ summary: 'Get Address',
393
+ description: 'Get full structured details for a specific address. Response includes Link headers with `related` rels to the locality, postcode, and state.',
394
+ operationId: 'getAddress',
395
+ tags: ['Addresses'],
396
+ parameters: [{
397
+ name: 'pid',
398
+ in: 'path',
399
+ required: true,
400
+ schema: {
401
+ type: 'string'
402
+ },
403
+ example: 'GAOT_717882967',
404
+ description: 'Address persistent identifier (G-NAF PID)'
405
+ }],
406
+ responses: {
407
+ 200: {
408
+ description: 'Address details with structured data',
409
+ content: {
410
+ 'application/json': {
411
+ schema: {
412
+ $ref: '#/components/schemas/Address'
413
+ }
414
+ }
415
+ }
416
+ }
417
+ }
418
+ }
419
+ },
420
+ '/localities': {
421
+ get: {
422
+ summary: 'Search Localities',
423
+ description: 'Search Australian suburbs and localities by name. Supports fuzzy and prefix matching. Returns localities with state, postcode, and classification.',
424
+ operationId: 'searchLocalities',
425
+ tags: ['Localities'],
426
+ parameters: [{
427
+ name: 'q',
428
+ in: 'query',
429
+ required: true,
430
+ schema: {
431
+ type: 'string',
432
+ minLength: 2
433
+ },
434
+ example: 'lilydale',
435
+ description: 'Locality/suburb name search query (min 2 characters)'
436
+ }],
437
+ responses: {
438
+ 200: {
439
+ description: 'List of matching localities',
440
+ content: {
441
+ 'application/json': {
442
+ schema: {
443
+ type: 'array',
444
+ items: {
445
+ $ref: '#/components/schemas/LocalitySearchResult'
446
+ }
447
+ }
448
+ }
449
+ }
450
+ }
451
+ }
452
+ }
453
+ },
454
+ '/localities/{pid}': {
455
+ get: {
456
+ summary: 'Get Locality',
457
+ description: 'Get details for a specific locality. Response includes Link headers with `related` rels to the postcode and state.',
458
+ operationId: 'getLocality',
459
+ tags: ['Localities'],
460
+ parameters: [{
461
+ name: 'pid',
462
+ in: 'path',
463
+ required: true,
464
+ schema: {
465
+ type: 'string'
466
+ },
467
+ example: 'loc9984d8beb142',
468
+ description: 'Locality persistent identifier'
469
+ }],
470
+ responses: {
471
+ 200: {
472
+ description: 'Locality details',
473
+ content: {
474
+ 'application/json': {
475
+ schema: {
476
+ $ref: '#/components/schemas/Locality'
477
+ }
478
+ }
479
+ }
480
+ }
481
+ }
482
+ }
483
+ },
484
+ '/postcodes': {
485
+ get: {
486
+ summary: 'Search Postcodes',
487
+ description: 'Search Australian postcodes by prefix. Returns matching postcodes with their associated localities. Omit `q` to list all postcodes in ascending order.',
488
+ operationId: 'searchPostcodes',
489
+ tags: ['Postcodes'],
490
+ parameters: [{
491
+ name: 'q',
492
+ in: 'query',
493
+ required: false,
494
+ schema: {
495
+ type: 'string'
496
+ },
497
+ example: '314',
498
+ description: 'Postcode prefix search query (0+ characters). Omit to list all postcodes.'
499
+ }],
500
+ responses: {
501
+ 200: {
502
+ description: 'List of matching postcodes with associated localities',
503
+ content: {
504
+ 'application/json': {
505
+ schema: {
506
+ type: 'array',
507
+ items: {
508
+ $ref: '#/components/schemas/PostcodeSearchResult'
509
+ }
510
+ }
511
+ }
512
+ }
513
+ }
514
+ }
515
+ }
516
+ },
517
+ '/postcodes/{postcode}': {
518
+ get: {
519
+ summary: 'Get Postcode',
520
+ description: 'Get details for a specific postcode including all associated localities. Each locality is linked via a `related` Link header.',
521
+ operationId: 'getPostcode',
522
+ tags: ['Postcodes'],
523
+ parameters: [{
524
+ name: 'postcode',
525
+ in: 'path',
526
+ required: true,
527
+ schema: {
528
+ type: 'string'
529
+ },
530
+ example: '6798',
531
+ description: 'Australian postcode'
532
+ }],
533
+ responses: {
534
+ 200: {
535
+ description: 'Postcode details with associated localities',
536
+ content: {
537
+ 'application/json': {
538
+ schema: {
539
+ $ref: '#/components/schemas/PostcodeDetail'
540
+ }
541
+ }
542
+ }
543
+ }
544
+ }
545
+ }
546
+ },
547
+ '/states': {
548
+ get: {
549
+ summary: 'Search States',
550
+ description: 'Search Australian states and territories by name or abbreviation. Omit `q` to list all states alphabetically.',
551
+ operationId: 'searchStates',
552
+ tags: ['States'],
553
+ parameters: [{
554
+ name: 'q',
555
+ in: 'query',
556
+ required: false,
557
+ schema: {
558
+ type: 'string'
559
+ },
560
+ example: 'New',
561
+ description: 'State name or abbreviation search (0+ characters). Omit to list all states.'
562
+ }],
563
+ responses: {
564
+ 200: {
565
+ description: 'List of matching states and territories',
566
+ content: {
567
+ 'application/json': {
568
+ schema: {
569
+ type: 'array',
570
+ items: {
571
+ $ref: '#/components/schemas/State'
572
+ }
573
+ }
574
+ }
575
+ }
576
+ }
577
+ }
578
+ }
579
+ },
580
+ '/states/{abbreviation}': {
581
+ get: {
582
+ summary: 'Get State',
583
+ description: 'Get details for a specific state or territory. Use `/localities?q=` or `/postcodes?q=` to search within a state.',
584
+ operationId: 'getState',
585
+ tags: ['States'],
586
+ parameters: [{
587
+ name: 'abbreviation',
588
+ in: 'path',
589
+ required: true,
590
+ schema: {
591
+ type: 'string',
592
+ enum: ['ACT', 'NSW', 'NT', 'QLD', 'SA', 'TAS', 'VIC', 'WA', 'OT']
593
+ },
594
+ example: 'NSW',
595
+ description: 'State/territory abbreviation'
596
+ }],
597
+ responses: {
598
+ 200: {
599
+ description: 'State/territory details',
600
+ content: {
601
+ 'application/json': {
602
+ schema: {
603
+ $ref: '#/components/schemas/State'
604
+ }
605
+ }
606
+ }
607
+ }
608
+ }
609
+ }
610
+ },
611
+ '/health': {
612
+ get: {
613
+ summary: 'Health Check',
614
+ description: 'Check API service status. Returns version, timestamp, and health status.',
615
+ operationId: 'healthCheck',
616
+ tags: ['System'],
617
+ responses: {
618
+ 200: {
619
+ description: 'API is healthy',
620
+ content: {
621
+ 'application/json': {
622
+ schema: {
623
+ $ref: '#/components/schemas/Health'
624
+ }
625
+ }
626
+ }
627
+ }
628
+ }
629
+ }
630
+ }
631
+ },
632
+ components: {
633
+ schemas
634
+ },
635
+ tags: [{
636
+ name: 'Addresses',
637
+ description: 'Search and retrieve addresses'
638
+ }, {
639
+ name: 'Localities',
640
+ description: 'Search and retrieve suburbs/localities'
641
+ }, {
642
+ name: 'Postcodes',
643
+ description: 'Search and retrieve postcodes'
644
+ }, {
645
+ name: 'States',
646
+ description: 'Search and retrieve states/territories'
647
+ }, {
648
+ name: 'System',
649
+ description: 'System endpoints'
650
+ }]
651
+ };
652
+ }
21
653
  var serverPort = process.env.PORT || 8080;
22
654
  var logger = (0, _debug.default)('api');
23
655
  var error = (0, _debug.default)('error');
@@ -47,10 +679,37 @@ function startRest2Server() {
47
679
  const {
48
680
  json,
49
681
  hash,
50
- statusCode
682
+ statusCode,
683
+ localityPid
51
684
  } = await (0, _addressService.getAddress)(pid);
685
+ const links = [];
686
+ if (localityPid) {
687
+ links.push({
688
+ rel: 'related',
689
+ uri: `/localities/${localityPid}`,
690
+ title: json.structured?.locality?.name || 'Locality'
691
+ });
692
+ }
693
+ if (json.structured) {
694
+ const s = json.structured;
695
+ if (s.postcode) {
696
+ links.push({
697
+ rel: 'related',
698
+ uri: `/postcodes/${s.postcode}`,
699
+ title: `Postcode ${s.postcode}`
700
+ });
701
+ }
702
+ if (s.state && s.state.abbreviation) {
703
+ links.push({
704
+ rel: 'related',
705
+ uri: `/states/${s.state.abbreviation}`,
706
+ title: s.state.name
707
+ });
708
+ }
709
+ }
52
710
  return {
53
711
  body: json,
712
+ links,
54
713
  headers: {
55
714
  etag: `"${_version.version}-${hash}"`,
56
715
  'cache-control': `public, max-age=${ONE_WEEK}`
@@ -114,9 +773,25 @@ function startRest2Server() {
114
773
  }) => {
115
774
  const resp = await (0, _addressService.getLocality)(pid);
116
775
  const source = resp.body._source;
776
+ const links = [];
777
+ if (source.primary_postcode) {
778
+ links.push({
779
+ rel: 'related',
780
+ uri: `/postcodes/${source.primary_postcode}`,
781
+ title: `Postcode ${source.primary_postcode}`
782
+ });
783
+ }
784
+ if (source.state_abbreviation) {
785
+ links.push({
786
+ rel: 'related',
787
+ uri: `/states/${source.state_abbreviation}`,
788
+ title: source.state_name
789
+ });
790
+ }
117
791
  const hash = _nodeCrypto.default.createHash('md5').update(JSON.stringify(source)).digest('hex');
118
792
  return {
119
793
  body: source,
794
+ links,
120
795
  headers: {
121
796
  etag: `"${_version.version}-${hash}"`,
122
797
  'cache-control': `public, max-age=${ONE_WEEK}`
@@ -182,8 +857,14 @@ function startRest2Server() {
182
857
  postcode
183
858
  }) => {
184
859
  const result = await (0, _addressService.getPostcode)(postcode);
185
- const localities = result.body.aggregations.localities.buckets.map(l => ({
186
- name: l.key
860
+ const hits = result.body.hits.hits;
861
+ const localities = hits.map(h => ({
862
+ name: h._source.locality_name
863
+ }));
864
+ const links = hits.map(h => ({
865
+ rel: 'related',
866
+ uri: `/localities/${h._source.locality_pid}`,
867
+ title: h._source.locality_name
187
868
  }));
188
869
  const body = {
189
870
  postcode,
@@ -192,6 +873,7 @@ function startRest2Server() {
192
873
  const hash = _nodeCrypto.default.createHash('md5').update(JSON.stringify(body)).digest('hex');
193
874
  return {
194
875
  body,
876
+ links,
195
877
  headers: {
196
878
  etag: `"${_version.version}-${hash}"`,
197
879
  'cache-control': `public, max-age=${ONE_WEEK}`
@@ -233,15 +915,9 @@ function startRest2Server() {
233
915
  }) => {
234
916
  const result = await (0, _addressService.getState)(abbreviation);
235
917
  const stateName = result.body.aggregations.state_name.buckets[0]?.key || abbreviation.toUpperCase();
236
- const localities = result.body.aggregations.localities.buckets.map(l => ({
237
- name: l.key
238
- }));
239
- const postcodes = result.body.aggregations.postcodes.buckets.map(p => p.key);
240
918
  const body = {
241
919
  abbreviation: abbreviation.toUpperCase(),
242
- name: stateName,
243
- localities,
244
- postcodes
920
+ name: stateName
245
921
  };
246
922
  const hash = _nodeCrypto.default.createHash('md5').update(JSON.stringify(body)).digest('hex');
247
923
  return {
@@ -293,12 +969,28 @@ function startRest2Server() {
293
969
  };
294
970
  }
295
971
  });
972
+ waycharter.registerResourceType({
973
+ path: '/api-docs',
974
+ loader: async () => {
975
+ const spec = buildOpenApiSpec(_version.version);
976
+ return {
977
+ body: spec,
978
+ headers: {
979
+ 'cache-control': `public, max-age=${ONE_WEEK}`,
980
+ 'content-type': 'application/json'
981
+ }
982
+ };
983
+ }
984
+ });
296
985
  waycharter.registerResourceType({
297
986
  path: '/',
298
987
  loader: async () => {
299
988
  return {
300
989
  body: {},
301
990
  links: [...addressesType.additionalPaths, ...localitiesType.additionalPaths, ...postcodesType.additionalPaths, ...statesType.additionalPaths, {
991
+ rel: 'https://addressr.io/rels/api-docs',
992
+ uri: '/api-docs'
993
+ }, {
302
994
  rel: 'https://addressr.io/rels/health',
303
995
  uri: '/health'
304
996
  }],
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.1.1';
8
+ const version = exports.version = '2.1.3';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mountainpass/addressr",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "Australian Address Validation, Search and Autocomplete",
5
5
  "author": {
6
6
  "name": "Mountain Pass",