@bradleyhodges/addresskit 2.4.3 → 2.4.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.
Files changed (2) hide show
  1. package/dist/cli.js +140 -2
  2. package/package.json +8 -8
package/dist/cli.js CHANGED
@@ -39,7 +39,7 @@ var version;
39
39
  var init_version = __esm({
40
40
  "packages/core/version.ts"() {
41
41
  "use strict";
42
- version = "2.4.3";
42
+ version = "2.4.4";
43
43
  }
44
44
  });
45
45
 
@@ -67114,6 +67114,116 @@ async function loadAddressCollection(params) {
67114
67114
  }
67115
67115
  };
67116
67116
  }
67117
+ function mapLocalitySearchHitToResource(hit, maxScore) {
67118
+ const localityId = hit._id.replace("/localities/", "");
67119
+ const normalizedRank = maxScore > 0 ? hit._score / maxScore : 0;
67120
+ return {
67121
+ type: "locality-suggestion",
67122
+ id: localityId,
67123
+ attributes: {
67124
+ display: hit._source.display,
67125
+ rank: Math.round(normalizedRank * 100) / 100
67126
+ },
67127
+ links: {
67128
+ self: `/localities/${localityId}`
67129
+ }
67130
+ };
67131
+ }
67132
+ async function loadLocalityItem({
67133
+ localityPid
67134
+ }) {
67135
+ if (typeof localityPid !== "string" || localityPid.length === 0) {
67136
+ throw new Error("Locality PID is required to load a record.");
67137
+ }
67138
+ const { json, hash, statusCode } = await getLocality(
67139
+ localityPid
67140
+ );
67141
+ return {
67142
+ body: json,
67143
+ headers: {
67144
+ etag: `"${version}-${hash}"`,
67145
+ "cache-control": `public, max-age=${ONE_WEEK}`
67146
+ },
67147
+ status: statusCode ?? 200
67148
+ };
67149
+ }
67150
+ async function loadLocalityCollection(params) {
67151
+ const { page, q } = params;
67152
+ const resolvedPage = Number(page ?? 0);
67153
+ if (!Number.isFinite(resolvedPage)) {
67154
+ throw new Error("Search page value must be numeric.");
67155
+ }
67156
+ const baseUrl = `/localities${q ? `?q=${encodeURIComponent(q)}` : ""}`;
67157
+ if (q && q.length > 1) {
67158
+ logger6("Searching for localities with query:", q);
67159
+ const searchResult = await searchForLocality(
67160
+ q,
67161
+ resolvedPage + 1,
67162
+ pageSize
67163
+ );
67164
+ const hits = searchResult.searchResponse.body.hits.hits;
67165
+ const totalHits = searchResult.totalHits;
67166
+ const totalPages = Math.ceil(totalHits / pageSize);
67167
+ const currentPage = resolvedPage + 1;
67168
+ const maxScore = hits.length > 0 ? hits[0]._score : 1;
67169
+ const data = hits.map(
67170
+ (hit) => mapLocalitySearchHitToResource(hit, maxScore)
67171
+ );
67172
+ const jsonApiDocument = {
67173
+ jsonapi: { version: "1.1" },
67174
+ data,
67175
+ links: {
67176
+ self: `${baseUrl}${currentPage > 1 ? `&page[number]=${currentPage}` : ""}`,
67177
+ first: baseUrl,
67178
+ ...currentPage > 1 && {
67179
+ prev: currentPage === 2 ? baseUrl : `${baseUrl}&page[number]=${currentPage - 1}`
67180
+ },
67181
+ ...currentPage < totalPages && {
67182
+ next: `${baseUrl}&page[number]=${currentPage + 1}`
67183
+ },
67184
+ ...totalPages > 0 && {
67185
+ last: totalPages === 1 ? baseUrl : `${baseUrl}&page[number]=${totalPages}`
67186
+ }
67187
+ },
67188
+ meta: {
67189
+ total: totalHits,
67190
+ page: currentPage,
67191
+ pageSize,
67192
+ totalPages
67193
+ }
67194
+ };
67195
+ const responseHash = (0, import_node_crypto.createHash)("md5").update(JSON.stringify(jsonApiDocument)).digest("hex");
67196
+ return {
67197
+ body: jsonApiDocument,
67198
+ hasMore: currentPage < totalPages,
67199
+ headers: {
67200
+ etag: `"${version}-${responseHash}"`,
67201
+ "cache-control": `public, max-age=${ONE_WEEK}`
67202
+ }
67203
+ };
67204
+ }
67205
+ const emptyDocument = {
67206
+ jsonapi: { version: "1.1" },
67207
+ data: [],
67208
+ links: {
67209
+ self: baseUrl
67210
+ },
67211
+ meta: {
67212
+ total: 0,
67213
+ page: 1,
67214
+ pageSize,
67215
+ totalPages: 0
67216
+ }
67217
+ };
67218
+ return {
67219
+ body: emptyDocument,
67220
+ hasMore: false,
67221
+ headers: {
67222
+ etag: `"${version}"`,
67223
+ "cache-control": `public, max-age=${ONE_WEEK}`
67224
+ }
67225
+ };
67226
+ }
67117
67227
  function transformPaginationParams(req, _res, next) {
67118
67228
  const pageParam = req.query.page;
67119
67229
  if (pageParam && typeof pageParam === "object" && pageParam.number) {
@@ -67158,10 +67268,24 @@ async function startRest2Server() {
67158
67268
  }
67159
67269
  ]
67160
67270
  });
67271
+ const localitiesType = waycharter.registerCollection({
67272
+ itemPath: "/:localityPid",
67273
+ itemLoader: loadLocalityItem,
67274
+ collectionPath: "/localities",
67275
+ collectionLoader: loadLocalityCollection,
67276
+ filters: [
67277
+ {
67278
+ rel: "https://addressr.io/rels/locality-search",
67279
+ parameters: ["q"]
67280
+ }
67281
+ ]
67282
+ });
67161
67283
  const loadIndexResource = async () => {
67284
+ const addressLinks = addressesType.additionalPaths;
67285
+ const localityLinks = localitiesType.additionalPaths;
67162
67286
  return {
67163
67287
  body: {},
67164
- links: addressesType.additionalPaths,
67288
+ links: [...addressLinks, ...localityLinks],
67165
67289
  headers: {
67166
67290
  etag: `"${version}"`,
67167
67291
  "cache-control": `public, max-age=${ONE_WEEK}`
@@ -67285,6 +67409,20 @@ async function runStartCommand(options) {
67285
67409
  ` ${theme.dim("Get detailed information for a specific address")}`
67286
67410
  );
67287
67411
  console.log();
67412
+ console.log(
67413
+ ` ${theme.secondary("GET")} ${theme.muted("/localities?q=<query>")}`
67414
+ );
67415
+ console.log(
67416
+ ` ${theme.dim("Search for suburbs/postcodes matching the query")}`
67417
+ );
67418
+ console.log();
67419
+ console.log(
67420
+ ` ${theme.secondary("GET")} ${theme.muted("/localities/:id")}`
67421
+ );
67422
+ console.log(
67423
+ ` ${theme.dim("Get detailed information for a specific locality")}`
67424
+ );
67425
+ console.log();
67288
67426
  console.log(` ${theme.secondary("GET")} ${theme.muted("/docs")}`);
67289
67427
  console.log(` ${theme.dim("OpenAPI/Swagger documentation")}`);
67290
67428
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bradleyhodges/addresskit",
3
- "version": "2.4.3",
3
+ "version": "2.4.4",
4
4
  "description": "Scalable address ingestion, validation, search, and autocomplete engine for Australian addresses",
5
5
  "config": {
6
6
  "SEARCH_IMAGE": "opensearchproject/opensearch:1.3.20"
@@ -12,17 +12,15 @@
12
12
  "scripts": {
13
13
  "typecheck": "turbo run typecheck",
14
14
  "build": "pnpm format && pnpm run genversion && turbo run build && pnpm run bundle && pnpm run bundle:copy-assets",
15
- "bundle": "esbuild apps/server/cli/index.ts --bundle --platform=node --target=node24 --outfile=dist/cli.js --packages=bundle",
16
- "bundle:copy-assets": "node -e \"const fs=require('fs');fs.mkdirSync('api',{recursive:true});fs.copyFileSync('apps/server/api/swagger.yaml','api/swagger.yaml');fs.copyFileSync('apps/server/api/swagger-2.yaml','api/swagger-2.yaml');\"",
17
- "publish:npm": "npm publish --access public --registry=https://registry.npmjs.org",
18
- "publish:github": "npm publish --access public --registry=https://npm.pkg.github.com",
19
- "publish:all": "pnpm run publish:npm && pnpm run publish:github",
20
- "release": "git tag v%npm_package_version% && git push origin master --tags",
15
+ "build:docker": "docker build -f infra/docker/Dockerfile --build-arg PACKAGE_TGZ=bradleyhodges-addresskit-%npm_package_version%.tgz --build-arg PACKAGE=%npm_package_name% --build-arg VERSION=%npm_package_version% -t bradleyhodges/addresskit:%npm_package_version% -t bradleyhodges/addresskit:latest .",
21
16
  "release:all": "node tooling/scripts/release.js",
22
17
  "dev": "turbo run dev --parallel",
23
18
  "dev:docker": "docker compose -f infra/docker/compose.dev.yml up -d",
24
19
  "dev:docker:down": "docker compose -f infra/docker/compose.dev.yml down --volumes --remove-orphans --rmi all",
25
20
  "dev:docker:load": "docker compose -f infra/docker/compose.dev.yml run --rm loader",
21
+ "bundle": "esbuild apps/server/cli/index.ts --bundle --platform=node --target=node24 --outfile=dist/cli.js --packages=bundle",
22
+ "bundle:copy-assets": "node -e \"const fs=require('fs');fs.mkdirSync('api',{recursive:true});fs.copyFileSync('apps/server/api/swagger.yaml','api/swagger.yaml');fs.copyFileSync('apps/server/api/swagger-2.yaml','api/swagger-2.yaml');\"",
23
+ "release": "git tag v%npm_package_version% && git push origin master --tags",
26
24
  "smoke": "node tooling/smoke/smoke.mjs",
27
25
  "format": "biome check . --write --skip-errors",
28
26
  "clean": "git clean -xdf node_modules",
@@ -33,8 +31,10 @@
33
31
  "npm-check:interactive": "npm-check --skip-unused -u ",
34
32
  "npm-check-unused": "npm-check",
35
33
  "genversion": "genversion -p ./ --es6 --double ./packages/core/version.ts",
34
+ "publish:npm": "npm publish --access public --registry=https://registry.npmjs.org",
35
+ "publish:github": "npm publish --access public --registry=https://npm.pkg.github.com",
36
+ "publish:all": "pnpm run publish:npm && pnpm run publish:github",
36
37
  "prebuild:docker": "npm pack",
37
- "build:docker": "docker build -f infra/docker/Dockerfile --build-arg PACKAGE_TGZ=bradleyhodges-addresskit-%npm_package_version%.tgz --build-arg PACKAGE=%npm_package_name% --build-arg VERSION=%npm_package_version% -t bradleyhodges/addresskit:%npm_package_version% -t bradleyhodges/addresskit:latest .",
38
38
  "build:docker:ghcr": "docker build -f infra/docker/Dockerfile --build-arg PACKAGE_TGZ=bradleyhodges-addresskit-%npm_package_version%.tgz --build-arg PACKAGE=%npm_package_name% --build-arg VERSION=%npm_package_version% -t ghcr.io/bradleyhodges/addresskit:%npm_package_version% -t ghcr.io/bradleyhodges/addresskit:latest .",
39
39
  "postbuild": "echo \"postbuild skipped\"",
40
40
  "prepack": "npm run build",