@nz-open-data-connectors/nz-sources 0.0.0-stage → 0.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/README.md +47 -2
- package/dist/adeSearch.d.ts +30 -0
- package/dist/adeSearch.d.ts.map +1 -0
- package/dist/adeSearch.js +62 -0
- package/dist/adeSearch.js.map +1 -0
- package/dist/arcgisHub.d.ts +109 -0
- package/dist/arcgisHub.d.ts.map +1 -0
- package/dist/arcgisHub.js +200 -0
- package/dist/arcgisHub.js.map +1 -0
- package/dist/dataGovtDatastore.d.ts +28 -0
- package/dist/dataGovtDatastore.d.ts.map +1 -0
- package/dist/dataGovtDatastore.js +55 -0
- package/dist/dataGovtDatastore.js.map +1 -0
- package/dist/dataGovtNz.d.ts +25 -0
- package/dist/dataGovtNz.d.ts.map +1 -0
- package/dist/dataGovtNz.js +62 -0
- package/dist/dataGovtNz.js.map +1 -0
- package/dist/digitalNz.d.ts +53 -0
- package/dist/digitalNz.d.ts.map +1 -0
- package/dist/digitalNz.js +156 -0
- package/dist/digitalNz.js.map +1 -0
- package/dist/errors.d.ts +15 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +26 -0
- package/dist/errors.js.map +1 -0
- package/dist/fixtures.d.ts +5 -0
- package/dist/fixtures.d.ts.map +1 -0
- package/dist/fixtures.js +11 -0
- package/dist/fixtures.js.map +1 -0
- package/dist/geonet.d.ts +32 -0
- package/dist/geonet.d.ts.map +1 -0
- package/dist/geonet.js +80 -0
- package/dist/geonet.js.map +1 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/lawa.d.ts +32 -0
- package/dist/lawa.d.ts.map +1 -0
- package/dist/lawa.js +67 -0
- package/dist/lawa.js.map +1 -0
- package/dist/linz.d.ts +21 -0
- package/dist/linz.d.ts.map +1 -0
- package/dist/linz.js +49 -0
- package/dist/linz.js.map +1 -0
- package/dist/lris.d.ts +27 -0
- package/dist/lris.d.ts.map +1 -0
- package/dist/lris.js +55 -0
- package/dist/lris.js.map +1 -0
- package/dist/mfe.d.ts +27 -0
- package/dist/mfe.d.ts.map +1 -0
- package/dist/mfe.js +55 -0
- package/dist/mfe.js.map +1 -0
- package/dist/nzor.d.ts +19 -0
- package/dist/nzor.d.ts.map +1 -0
- package/dist/nzor.js +53 -0
- package/dist/nzor.js.map +1 -0
- package/dist/nzta.d.ts +29 -0
- package/dist/nzta.d.ts.map +1 -0
- package/dist/nzta.js +74 -0
- package/dist/nzta.js.map +1 -0
- package/dist/registry.d.ts +15 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +66 -0
- package/dist/registry.js.map +1 -0
- package/dist/tradeMe.d.ts +16 -0
- package/dist/tradeMe.d.ts.map +1 -0
- package/dist/tradeMe.js +48 -0
- package/dist/tradeMe.js.map +1 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +44 -4
package/README.md
CHANGED
|
@@ -1,3 +1,48 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @nz-open-data-connectors/nz-sources
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Uniform TypeScript adapters for NZ public data sources. Every adapter has the same shape: a live fetch, a strict parse, and a committed fixture fallback so builds work offline.
|
|
4
|
+
|
|
5
|
+
## Adapters
|
|
6
|
+
|
|
7
|
+
| id | Source | Auth | What it does |
|
|
8
|
+
| ------------- | ------------------------------- | ------ | ------------------------------------- |
|
|
9
|
+
| `geonet` | GeoNet | none | Felt earthquake reports |
|
|
10
|
+
| `data-govt-nz`| data.govt.nz search | none | Dataset search |
|
|
11
|
+
| `datastore` | data.govt.nz datastore | none | Row pulls (e.g. MSD benefits) |
|
|
12
|
+
| `ade-search` | Aotearoa Data Explorer search | none | Dataflow search |
|
|
13
|
+
| `digitalnz` | DigitalNZ | key | Record search (key optional) |
|
|
14
|
+
| `trademe` | Trade Me | none | Category tree |
|
|
15
|
+
| `nzor` | NZ Organisms Register | none | Species name search |
|
|
16
|
+
| `linz` | LINZ Data Service | key | Layer search (key optional) |
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { NZ_DATA_SOURCES, probeAllNzDataSources } from '@nz-open-data-connectors/nz-sources';
|
|
22
|
+
|
|
23
|
+
// List every source.
|
|
24
|
+
for (const source of NZ_DATA_SOURCES) {
|
|
25
|
+
console.log(source.id, source.name, source.auth);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Live probe every source, with optional keys.
|
|
29
|
+
const probes = await probeAllNzDataSources({
|
|
30
|
+
apiKeys: {
|
|
31
|
+
linz: process.env.LINZ_API_KEY,
|
|
32
|
+
digitalnz: process.env.DIGITAL_NZ_API_KEY,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Keys
|
|
38
|
+
|
|
39
|
+
All adapters work keyless. `linz` and `digitalnz` accept an optional key for higher rate limits and richer results. Keys are read from env only; never commit them.
|
|
40
|
+
|
|
41
|
+
## Tests
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npm run test -w @nz-open-data-connectors/nz-sources # unit tests, fixtures only, no network
|
|
45
|
+
RUN_SMOKE=1 npm run test:smoke -w @nz-open-data-connectors/nz-sources # live probes against the real APIs
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Fixtures in `src/fixtures/` are real snapshots from the live APIs. Smoke tests are skipped by default and must be run explicitly.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { NzDataAdapter } from './types.js';
|
|
2
|
+
/** One ADE table found by the Aotearoa Data Explorer search index. */
|
|
3
|
+
export interface AdeDataflow {
|
|
4
|
+
dataflowId: string;
|
|
5
|
+
version: string;
|
|
6
|
+
agencyId: string;
|
|
7
|
+
name: string;
|
|
8
|
+
dimensions: string[];
|
|
9
|
+
}
|
|
10
|
+
/** Aotearoa Data Explorer search results. */
|
|
11
|
+
export interface AdeSearchResult {
|
|
12
|
+
numFound: number;
|
|
13
|
+
dataflows: AdeDataflow[];
|
|
14
|
+
}
|
|
15
|
+
/** Parses an ADE search index payload into dataflow records. */
|
|
16
|
+
export declare function parseAdeSearchResults(payload: unknown): AdeSearchResult;
|
|
17
|
+
/**
|
|
18
|
+
* Searches the Aotearoa Data Explorer table index by keyword. Keyless.
|
|
19
|
+
* Falls back to a committed fixture when the API is unreachable.
|
|
20
|
+
*/
|
|
21
|
+
export declare function searchAdeTables(query: string, options?: {
|
|
22
|
+
limit?: number;
|
|
23
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
24
|
+
}): Promise<AdeSearchResult>;
|
|
25
|
+
/**
|
|
26
|
+
* Aotearoa Data Explorer search adapter: finds ADE table IDs by keyword.
|
|
27
|
+
* Keyless. The live probe searches for median annual earnings (LEED).
|
|
28
|
+
*/
|
|
29
|
+
export declare const adeSearchAdapter: NzDataAdapter<AdeSearchResult>;
|
|
30
|
+
//# sourceMappingURL=adeSearch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adeSearch.d.ts","sourceRoot":"","sources":["../src/adeSearch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,sEAAsE;AACtE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,WAAW,EAAE,CAAC;CAC1B;AAeD,gEAAgE;AAChE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAevE;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAAO,GACpE,OAAO,CAAC,eAAe,CAAC,CAU1B;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,eAAe,CAY3D,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { NzSourceApiError, NzSourceParseError } from './errors.js';
|
|
3
|
+
import { readFixtureJson } from './fixtures.js';
|
|
4
|
+
const ADE_DATAFLOW_SCHEMA = z.object({
|
|
5
|
+
dataflowId: z.string(),
|
|
6
|
+
version: z.string().optional().default(''),
|
|
7
|
+
agencyId: z.string().optional().default(''),
|
|
8
|
+
name: z.string().optional().default(''),
|
|
9
|
+
dimensions: z.array(z.string()).optional().default([]),
|
|
10
|
+
});
|
|
11
|
+
const ADE_SEARCH_RESPONSE_SCHEMA = z.object({
|
|
12
|
+
numFound: z.number(),
|
|
13
|
+
dataflows: z.array(ADE_DATAFLOW_SCHEMA).optional().default([]),
|
|
14
|
+
});
|
|
15
|
+
/** Parses an ADE search index payload into dataflow records. */
|
|
16
|
+
export function parseAdeSearchResults(payload) {
|
|
17
|
+
const parsed = ADE_SEARCH_RESPONSE_SCHEMA.safeParse(payload);
|
|
18
|
+
if (!parsed.success) {
|
|
19
|
+
throw new NzSourceParseError('ADE search', parsed.error.message);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
numFound: parsed.data.numFound,
|
|
23
|
+
dataflows: parsed.data.dataflows.map((flow) => ({
|
|
24
|
+
dataflowId: flow.dataflowId,
|
|
25
|
+
version: flow.version,
|
|
26
|
+
agencyId: flow.agencyId,
|
|
27
|
+
name: flow.name,
|
|
28
|
+
dimensions: flow.dimensions,
|
|
29
|
+
})),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Searches the Aotearoa Data Explorer table index by keyword. Keyless.
|
|
34
|
+
* Falls back to a committed fixture when the API is unreachable.
|
|
35
|
+
*/
|
|
36
|
+
export async function searchAdeTables(query, options = {}) {
|
|
37
|
+
const limit = options.limit ?? 20;
|
|
38
|
+
const url = `https://explore.data.stats.govt.nz/sfs/api/search?tenant=public` +
|
|
39
|
+
`&q=${encodeURIComponent(query)}&limit=${limit}`;
|
|
40
|
+
const response = await (options.fetchImpl ?? globalThis.fetch)(url);
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new NzSourceApiError('ADE search', `HTTP ${response.status}`);
|
|
43
|
+
}
|
|
44
|
+
return parseAdeSearchResults(await response.json());
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Aotearoa Data Explorer search adapter: finds ADE table IDs by keyword.
|
|
48
|
+
* Keyless. The live probe searches for median annual earnings (LEED).
|
|
49
|
+
*/
|
|
50
|
+
export const adeSearchAdapter = {
|
|
51
|
+
id: 'ade-search',
|
|
52
|
+
name: 'Aotearoa Data Explorer search index',
|
|
53
|
+
auth: 'none',
|
|
54
|
+
description: 'Searches ADE table IDs and titles by keyword.',
|
|
55
|
+
fetchLive: (options) => searchAdeTables('median annual earnings', {
|
|
56
|
+
limit: 5,
|
|
57
|
+
...(options?.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }),
|
|
58
|
+
}),
|
|
59
|
+
parse: parseAdeSearchResults,
|
|
60
|
+
loadFixture: () => parseAdeSearchResults(readFixtureJson('ade-search-earnings.json')),
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=adeSearch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adeSearch.js","sourceRoot":"","sources":["../src/adeSearch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/** Default ArcGIS Hub host: Auckland Council open data. */
|
|
2
|
+
export declare const DEFAULT_ARCGIS_HUB_HOST = "https://data-aucklandcouncil.opendata.arcgis.com";
|
|
3
|
+
/** One collection advertised by an ArcGIS Hub search API. */
|
|
4
|
+
export interface ArcgisHubCollection {
|
|
5
|
+
id: string;
|
|
6
|
+
title: string;
|
|
7
|
+
itemType: string;
|
|
8
|
+
description: string;
|
|
9
|
+
}
|
|
10
|
+
/** One dataset found by an ArcGIS Hub dataset search. */
|
|
11
|
+
export interface ArcgisHubDataset {
|
|
12
|
+
id: string;
|
|
13
|
+
title: string;
|
|
14
|
+
snippet: string;
|
|
15
|
+
type: string;
|
|
16
|
+
url: string;
|
|
17
|
+
owner: string;
|
|
18
|
+
source: string;
|
|
19
|
+
tags: string[];
|
|
20
|
+
modified: number;
|
|
21
|
+
created: number;
|
|
22
|
+
numViews: number;
|
|
23
|
+
access: string;
|
|
24
|
+
}
|
|
25
|
+
/** Options for ArcGIS Hub live fetches: host and optional search query. */
|
|
26
|
+
export interface ArcgisHubFetchOptions {
|
|
27
|
+
host?: string;
|
|
28
|
+
q?: string;
|
|
29
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
30
|
+
}
|
|
31
|
+
/** Result of an ArcGIS Hub live fetch: collections or dataset search. */
|
|
32
|
+
export type ArcgisHubResult = {
|
|
33
|
+
kind: 'collections';
|
|
34
|
+
collections: ArcgisHubCollection[];
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'datasets';
|
|
37
|
+
datasets: ArcgisHubDataset[];
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Normalizes a host option to a base URL with scheme and no trailing slash.
|
|
41
|
+
*
|
|
42
|
+
* @param host - Host or base URL, with or without scheme.
|
|
43
|
+
* @returns The normalized base URL.
|
|
44
|
+
*/
|
|
45
|
+
export declare function normalizeArcgisHubHost(host: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Parses an ArcGIS Hub collections payload into collections.
|
|
48
|
+
*
|
|
49
|
+
* @param payload - Raw JSON from the collections endpoint.
|
|
50
|
+
* @returns The advertised collections.
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseArcgisHubCollections(payload: unknown): ArcgisHubCollection[];
|
|
53
|
+
/**
|
|
54
|
+
* Parses an ArcGIS Hub dataset search payload into datasets.
|
|
55
|
+
*
|
|
56
|
+
* @param payload - Raw GeoJSON from the dataset items endpoint.
|
|
57
|
+
* @returns The datasets found by the search.
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseArcgisHubDatasets(payload: unknown): ArcgisHubDataset[];
|
|
60
|
+
/**
|
|
61
|
+
* Parses an ArcGIS Hub payload into collections or datasets by shape.
|
|
62
|
+
*
|
|
63
|
+
* @param payload - Raw JSON from either ArcGIS Hub endpoint.
|
|
64
|
+
* @returns Collections when the payload has a collections list, else datasets.
|
|
65
|
+
*/
|
|
66
|
+
export declare function parseArcgisHubResult(payload: unknown): ArcgisHubResult;
|
|
67
|
+
/**
|
|
68
|
+
* Fetches the collection list from an ArcGIS Hub search API. Keyless.
|
|
69
|
+
* Falls back to a committed fixture when the API is unreachable.
|
|
70
|
+
*
|
|
71
|
+
* @param options - Host and fetch override.
|
|
72
|
+
* @returns The advertised collections.
|
|
73
|
+
*/
|
|
74
|
+
export declare function fetchArcgisHubCollections(options?: ArcgisHubFetchOptions): Promise<ArcgisHubCollection[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Searches datasets on an ArcGIS Hub search API by keyword. Keyless.
|
|
77
|
+
* Falls back to a committed fixture when the API is unreachable.
|
|
78
|
+
*
|
|
79
|
+
* @param query - Search keyword, e.g. "parks".
|
|
80
|
+
* @param options - Host and fetch override.
|
|
81
|
+
* @returns The datasets found by the search.
|
|
82
|
+
*/
|
|
83
|
+
export declare function searchArcgisHubDatasets(query: string, options?: ArcgisHubFetchOptions): Promise<ArcgisHubDataset[]>;
|
|
84
|
+
/**
|
|
85
|
+
* ArcGIS Hub adapter: keyless open data search, host-configurable. The live
|
|
86
|
+
* probe hits the collections endpoint; passing a query searches datasets.
|
|
87
|
+
*/
|
|
88
|
+
export declare const arcgisHubAdapter: {
|
|
89
|
+
id: string;
|
|
90
|
+
name: string;
|
|
91
|
+
auth: "none";
|
|
92
|
+
description: string;
|
|
93
|
+
fetchLive: (options?: ArcgisHubFetchOptions) => Promise<{
|
|
94
|
+
kind: "collections";
|
|
95
|
+
collections: ArcgisHubCollection[];
|
|
96
|
+
} | {
|
|
97
|
+
kind: "datasets";
|
|
98
|
+
datasets: ArcgisHubDataset[];
|
|
99
|
+
} | {
|
|
100
|
+
kind: "datasets";
|
|
101
|
+
datasets: ArcgisHubDataset[];
|
|
102
|
+
}>;
|
|
103
|
+
parse: typeof parseArcgisHubResult;
|
|
104
|
+
loadFixture: () => {
|
|
105
|
+
kind: "datasets";
|
|
106
|
+
datasets: ArcgisHubDataset[];
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=arcgisHub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arcgisHub.d.ts","sourceRoot":"","sources":["../src/arcgisHub.ts"],"names":[],"mappings":"AAMA,2DAA2D;AAC3D,eAAO,MAAM,uBAAuB,qDAAqD,CAAC;AAE1F,6DAA6D;AAC7D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,2EAA2E;AAC3E,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACrC;AAED,yEAAyE;AACzE,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE,mBAAmB,EAAE,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,gBAAgB,EAAE,CAAA;CAAE,CAAC;AAwDvD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG3D;AAgBD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,mBAAmB,EAAE,CAWjF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,EAAE,CAmB3E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAQtE;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAQhC;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAS7B;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;;0BAML,qBAAqB;cAnMjC,aAAa;qBAAe,mBAAmB,EAAE;;cACjD,UAAU;kBAAY,gBAAgB,EAAE;;;;;;;;;;CA0NV,CAAC"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { NzSourceApiError, NzSourceParseError } from './errors.js';
|
|
3
|
+
import { readFixtureJson } from './fixtures.js';
|
|
4
|
+
/** Default ArcGIS Hub host: Auckland Council open data. */
|
|
5
|
+
export const DEFAULT_ARCGIS_HUB_HOST = 'https://data-aucklandcouncil.opendata.arcgis.com';
|
|
6
|
+
const ARCGIS_HUB_COLLECTION_SCHEMA = z.object({
|
|
7
|
+
id: z.string(),
|
|
8
|
+
title: z.string(),
|
|
9
|
+
itemType: z.string().optional().default(''),
|
|
10
|
+
description: z.string().optional().default(''),
|
|
11
|
+
});
|
|
12
|
+
const ARCGIS_HUB_COLLECTIONS_RESPONSE_SCHEMA = z.object({
|
|
13
|
+
collections: z.array(ARCGIS_HUB_COLLECTION_SCHEMA),
|
|
14
|
+
});
|
|
15
|
+
const ARCGIS_HUB_DATASET_SCHEMA = z.object({
|
|
16
|
+
id: z.string(),
|
|
17
|
+
title: z.string(),
|
|
18
|
+
snippet: z
|
|
19
|
+
.string()
|
|
20
|
+
.nullable()
|
|
21
|
+
.optional()
|
|
22
|
+
.transform((value) => value ?? ''),
|
|
23
|
+
type: z.string(),
|
|
24
|
+
url: z
|
|
25
|
+
.string()
|
|
26
|
+
.nullable()
|
|
27
|
+
.optional()
|
|
28
|
+
.transform((value) => value ?? ''),
|
|
29
|
+
owner: z
|
|
30
|
+
.string()
|
|
31
|
+
.nullable()
|
|
32
|
+
.optional()
|
|
33
|
+
.transform((value) => value ?? ''),
|
|
34
|
+
source: z
|
|
35
|
+
.string()
|
|
36
|
+
.nullable()
|
|
37
|
+
.optional()
|
|
38
|
+
.transform((value) => value ?? ''),
|
|
39
|
+
tags: z.array(z.string()).optional().default([]),
|
|
40
|
+
modified: z.number().optional().default(0),
|
|
41
|
+
created: z.number().optional().default(0),
|
|
42
|
+
numViews: z.number().optional().default(0),
|
|
43
|
+
access: z.string().optional().default(''),
|
|
44
|
+
});
|
|
45
|
+
const ARCGIS_HUB_DATASETS_RESPONSE_SCHEMA = z.object({
|
|
46
|
+
type: z.string(),
|
|
47
|
+
features: z.array(z.object({
|
|
48
|
+
id: z.string(),
|
|
49
|
+
properties: ARCGIS_HUB_DATASET_SCHEMA,
|
|
50
|
+
})),
|
|
51
|
+
numberMatched: z.number().optional().default(0),
|
|
52
|
+
numberReturned: z.number().optional().default(0),
|
|
53
|
+
});
|
|
54
|
+
/**
|
|
55
|
+
* Normalizes a host option to a base URL with scheme and no trailing slash.
|
|
56
|
+
*
|
|
57
|
+
* @param host - Host or base URL, with or without scheme.
|
|
58
|
+
* @returns The normalized base URL.
|
|
59
|
+
*/
|
|
60
|
+
export function normalizeArcgisHubHost(host) {
|
|
61
|
+
const trimmed = stripTrailingSlashes(host.trim());
|
|
62
|
+
return /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Removes trailing slashes without a regex, so host input stays linear.
|
|
66
|
+
*
|
|
67
|
+
* @param value - A host string that may end in slashes.
|
|
68
|
+
* @returns The host without trailing slashes.
|
|
69
|
+
*/
|
|
70
|
+
function stripTrailingSlashes(value) {
|
|
71
|
+
let end = value.length;
|
|
72
|
+
while (end > 0 && value[end - 1] === '/') {
|
|
73
|
+
end -= 1;
|
|
74
|
+
}
|
|
75
|
+
return value.slice(0, end);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Parses an ArcGIS Hub collections payload into collections.
|
|
79
|
+
*
|
|
80
|
+
* @param payload - Raw JSON from the collections endpoint.
|
|
81
|
+
* @returns The advertised collections.
|
|
82
|
+
*/
|
|
83
|
+
export function parseArcgisHubCollections(payload) {
|
|
84
|
+
const parsed = ARCGIS_HUB_COLLECTIONS_RESPONSE_SCHEMA.safeParse(payload);
|
|
85
|
+
if (!parsed.success) {
|
|
86
|
+
throw new NzSourceParseError('ArcGIS Hub', parsed.error.message);
|
|
87
|
+
}
|
|
88
|
+
return parsed.data.collections.map((collection) => ({
|
|
89
|
+
id: collection.id,
|
|
90
|
+
title: collection.title,
|
|
91
|
+
itemType: collection.itemType,
|
|
92
|
+
description: collection.description,
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Parses an ArcGIS Hub dataset search payload into datasets.
|
|
97
|
+
*
|
|
98
|
+
* @param payload - Raw GeoJSON from the dataset items endpoint.
|
|
99
|
+
* @returns The datasets found by the search.
|
|
100
|
+
*/
|
|
101
|
+
export function parseArcgisHubDatasets(payload) {
|
|
102
|
+
const parsed = ARCGIS_HUB_DATASETS_RESPONSE_SCHEMA.safeParse(payload);
|
|
103
|
+
if (!parsed.success) {
|
|
104
|
+
throw new NzSourceParseError('ArcGIS Hub', parsed.error.message);
|
|
105
|
+
}
|
|
106
|
+
return parsed.data.features.map((feature) => ({
|
|
107
|
+
id: feature.id,
|
|
108
|
+
title: feature.properties.title,
|
|
109
|
+
snippet: feature.properties.snippet,
|
|
110
|
+
type: feature.properties.type,
|
|
111
|
+
url: feature.properties.url,
|
|
112
|
+
owner: feature.properties.owner,
|
|
113
|
+
source: feature.properties.source,
|
|
114
|
+
tags: feature.properties.tags,
|
|
115
|
+
modified: feature.properties.modified,
|
|
116
|
+
created: feature.properties.created,
|
|
117
|
+
numViews: feature.properties.numViews,
|
|
118
|
+
access: feature.properties.access,
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Parses an ArcGIS Hub payload into collections or datasets by shape.
|
|
123
|
+
*
|
|
124
|
+
* @param payload - Raw JSON from either ArcGIS Hub endpoint.
|
|
125
|
+
* @returns Collections when the payload has a collections list, else datasets.
|
|
126
|
+
*/
|
|
127
|
+
export function parseArcgisHubResult(payload) {
|
|
128
|
+
if (typeof payload === 'object' && payload !== null && 'collections' in payload) {
|
|
129
|
+
return {
|
|
130
|
+
kind: 'collections',
|
|
131
|
+
collections: parseArcgisHubCollections(payload),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return { kind: 'datasets', datasets: parseArcgisHubDatasets(payload) };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Fetches the collection list from an ArcGIS Hub search API. Keyless.
|
|
138
|
+
* Falls back to a committed fixture when the API is unreachable.
|
|
139
|
+
*
|
|
140
|
+
* @param options - Host and fetch override.
|
|
141
|
+
* @returns The advertised collections.
|
|
142
|
+
*/
|
|
143
|
+
export async function fetchArcgisHubCollections(options = {}) {
|
|
144
|
+
const host = normalizeArcgisHubHost(options.host ?? DEFAULT_ARCGIS_HUB_HOST);
|
|
145
|
+
const url = `${host}/api/search/v1/collections`;
|
|
146
|
+
const response = await (options.fetchImpl ?? globalThis.fetch)(url);
|
|
147
|
+
if (!response.ok) {
|
|
148
|
+
throw new NzSourceApiError('ArcGIS Hub', `HTTP ${response.status}`);
|
|
149
|
+
}
|
|
150
|
+
return parseArcgisHubCollections(await response.json());
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Searches datasets on an ArcGIS Hub search API by keyword. Keyless.
|
|
154
|
+
* Falls back to a committed fixture when the API is unreachable.
|
|
155
|
+
*
|
|
156
|
+
* @param query - Search keyword, e.g. "parks".
|
|
157
|
+
* @param options - Host and fetch override.
|
|
158
|
+
* @returns The datasets found by the search.
|
|
159
|
+
*/
|
|
160
|
+
export async function searchArcgisHubDatasets(query, options = {}) {
|
|
161
|
+
const host = normalizeArcgisHubHost(options.host ?? DEFAULT_ARCGIS_HUB_HOST);
|
|
162
|
+
const url = new URL(`${host}/api/search/v1/collections/dataset/items`);
|
|
163
|
+
url.searchParams.set('q', query);
|
|
164
|
+
const response = await (options.fetchImpl ?? globalThis.fetch)(url);
|
|
165
|
+
if (!response.ok) {
|
|
166
|
+
throw new NzSourceApiError('ArcGIS Hub', `HTTP ${response.status}`);
|
|
167
|
+
}
|
|
168
|
+
return parseArcgisHubDatasets(await response.json());
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* ArcGIS Hub adapter: keyless open data search, host-configurable. The live
|
|
172
|
+
* probe hits the collections endpoint; passing a query searches datasets.
|
|
173
|
+
*/
|
|
174
|
+
export const arcgisHubAdapter = {
|
|
175
|
+
id: 'arcgis',
|
|
176
|
+
name: 'ArcGIS Hub open data',
|
|
177
|
+
auth: 'none',
|
|
178
|
+
description: 'Searches NZ open data published on ArcGIS Hub (Auckland Council, WCC, Canterbury, NZTA).',
|
|
179
|
+
fetchLive: (options) => {
|
|
180
|
+
const host = options?.host;
|
|
181
|
+
const query = options?.q;
|
|
182
|
+
const fetchImpl = options?.fetchImpl;
|
|
183
|
+
if (query !== undefined) {
|
|
184
|
+
return searchArcgisHubDatasets(query, {
|
|
185
|
+
...(host === undefined ? {} : { host }),
|
|
186
|
+
...(fetchImpl === undefined ? {} : { fetchImpl }),
|
|
187
|
+
}).then((datasets) => ({ kind: 'datasets', datasets }));
|
|
188
|
+
}
|
|
189
|
+
return fetchArcgisHubCollections({
|
|
190
|
+
...(host === undefined ? {} : { host }),
|
|
191
|
+
...(fetchImpl === undefined ? {} : { fetchImpl }),
|
|
192
|
+
}).then((collections) => ({ kind: 'collections', collections }));
|
|
193
|
+
},
|
|
194
|
+
parse: parseArcgisHubResult,
|
|
195
|
+
loadFixture: () => ({
|
|
196
|
+
kind: 'datasets',
|
|
197
|
+
datasets: parseArcgisHubDatasets(readFixtureJson('arcgis-hub-data-aucklandcouncil.opendata.arcgis.com-datasets-parks-2026-08-25.json')),
|
|
198
|
+
}),
|
|
199
|
+
};
|
|
200
|
+
//# sourceMappingURL=arcgisHub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arcgisHub.js","sourceRoot":"","sources":["../src/arcgisHub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { NzDataAdapter } from './types.js';
|
|
2
|
+
/** One row from a data.govt.nz CKAN datastore resource. */
|
|
3
|
+
export type DataGovtDatastoreRow = Record<string, string | number | boolean | null>;
|
|
4
|
+
/** Rows from a data.govt.nz CKAN datastore resource. */
|
|
5
|
+
export interface DataGovtDatastoreResult {
|
|
6
|
+
resourceId: string;
|
|
7
|
+
total: number;
|
|
8
|
+
records: DataGovtDatastoreRow[];
|
|
9
|
+
}
|
|
10
|
+
/** The default resource the adapter probes: MSD national-level main benefit data. */
|
|
11
|
+
export declare const MSD_BENEFIT_RESOURCE_ID = "9144a616-9ab1-4475-972b-ac42c1f891b7";
|
|
12
|
+
/** Parses a data.govt.nz CKAN datastore_search payload into rows. */
|
|
13
|
+
export declare function parseDataGovtDatastoreRows(payload: unknown): DataGovtDatastoreResult;
|
|
14
|
+
/**
|
|
15
|
+
* Fetches rows from a data.govt.nz CKAN datastore resource. Keyless.
|
|
16
|
+
* Falls back to a committed fixture when the API is unreachable.
|
|
17
|
+
*/
|
|
18
|
+
export declare function fetchDataGovtDatastoreRows(resourceId: string, options?: {
|
|
19
|
+
limit?: number;
|
|
20
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
21
|
+
}): Promise<DataGovtDatastoreResult>;
|
|
22
|
+
/**
|
|
23
|
+
* data.govt.nz datastore adapter: CKAN datastore_search over the national
|
|
24
|
+
* open data catalogue. Keyless. The live probe reads the MSD national
|
|
25
|
+
* benefit table, a long monthly series.
|
|
26
|
+
*/
|
|
27
|
+
export declare const dataGovtDatastoreAdapter: NzDataAdapter<DataGovtDatastoreResult>;
|
|
28
|
+
//# sourceMappingURL=dataGovtDatastore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataGovtDatastore.d.ts","sourceRoot":"","sources":["../src/dataGovtDatastore.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,2DAA2D;AAC3D,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;AAEpF,wDAAwD;AACxD,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC;AAED,qFAAqF;AACrF,eAAO,MAAM,uBAAuB,yCAAyC,CAAC;AAa9E,qEAAqE;AACrE,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,uBAAuB,CAUpF;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAAO,GACpE,OAAO,CAAC,uBAAuB,CAAC,CAUlC;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,aAAa,CAAC,uBAAuB,CAa3E,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { NzSourceApiError, NzSourceParseError } from './errors.js';
|
|
3
|
+
import { readFixtureJson } from './fixtures.js';
|
|
4
|
+
/** The default resource the adapter probes: MSD national-level main benefit data. */
|
|
5
|
+
export const MSD_BENEFIT_RESOURCE_ID = '9144a616-9ab1-4475-972b-ac42c1f891b7';
|
|
6
|
+
const DATA_GOVT_NZ_ROW_SCHEMA = z.record(z.union([z.string(), z.number(), z.boolean(), z.null()]));
|
|
7
|
+
const DATA_GOVT_NZ_DATASTORE_SCHEMA = z.object({
|
|
8
|
+
success: z.literal(true),
|
|
9
|
+
result: z.object({
|
|
10
|
+
resource_id: z.string(),
|
|
11
|
+
total: z.number(),
|
|
12
|
+
records: z.array(DATA_GOVT_NZ_ROW_SCHEMA),
|
|
13
|
+
}),
|
|
14
|
+
});
|
|
15
|
+
/** Parses a data.govt.nz CKAN datastore_search payload into rows. */
|
|
16
|
+
export function parseDataGovtDatastoreRows(payload) {
|
|
17
|
+
const parsed = DATA_GOVT_NZ_DATASTORE_SCHEMA.safeParse(payload);
|
|
18
|
+
if (!parsed.success) {
|
|
19
|
+
throw new NzSourceParseError('data.govt.nz datastore', parsed.error.message);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
resourceId: parsed.data.result.resource_id,
|
|
23
|
+
total: parsed.data.result.total,
|
|
24
|
+
records: parsed.data.result.records,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Fetches rows from a data.govt.nz CKAN datastore resource. Keyless.
|
|
29
|
+
* Falls back to a committed fixture when the API is unreachable.
|
|
30
|
+
*/
|
|
31
|
+
export async function fetchDataGovtDatastoreRows(resourceId, options = {}) {
|
|
32
|
+
const limit = options.limit ?? 1000;
|
|
33
|
+
const url = `https://catalogue.data.govt.nz/api/3/action/datastore_search` +
|
|
34
|
+
`?resource_id=${encodeURIComponent(resourceId)}&limit=${limit}`;
|
|
35
|
+
const response = await (options.fetchImpl ?? globalThis.fetch)(url);
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw new NzSourceApiError('data.govt.nz datastore', `HTTP ${response.status}`);
|
|
38
|
+
}
|
|
39
|
+
return parseDataGovtDatastoreRows(await response.json());
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* data.govt.nz datastore adapter: CKAN datastore_search over the national
|
|
43
|
+
* open data catalogue. Keyless. The live probe reads the MSD national
|
|
44
|
+
* benefit table, a long monthly series.
|
|
45
|
+
*/
|
|
46
|
+
export const dataGovtDatastoreAdapter = {
|
|
47
|
+
id: 'data-govt-datastore',
|
|
48
|
+
name: 'data.govt.nz datastore (MSD benefits)',
|
|
49
|
+
auth: 'none',
|
|
50
|
+
description: 'CKAN datastore_search rows, defaulting to national MSD benefit data.',
|
|
51
|
+
fetchLive: (options) => fetchDataGovtDatastoreRows(MSD_BENEFIT_RESOURCE_ID, options?.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }),
|
|
52
|
+
parse: parseDataGovtDatastoreRows,
|
|
53
|
+
loadFixture: () => parseDataGovtDatastoreRows(readFixtureJson('data-govt-datastore-msd-benefits.json')),
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=dataGovtDatastore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataGovtDatastore.js","sourceRoot":"","sources":["../src/dataGovtDatastore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAahD,qFAAqF;AACrF,MAAM,CAAC,MAAM,uBAAuB,GAAG,sCAAsC,CAAC;AAE9E,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAEnG,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACxB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;QACvB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC;KAC1C,CAAC;CACH,CAAC,CAAC;AAEH,qEAAqE;AACrE,MAAM,UAAU,0BAA0B,CAAC,OAAgB;IACzD,MAAM,MAAM,GAAG,6BAA6B,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAChE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,kBAAkB,CAAC,wBAAwB,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO;QACL,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW;QAC1C,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK;QAC/B,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;KACpC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,UAAkB,EAClB,UAAmE,EAAE;IAErE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC;IACpC,MAAM,GAAG,GACP,8DAA8D;QAC9D,gBAAgB,kBAAkB,CAAC,UAAU,CAAC,UAAU,KAAK,EAAE,CAAC;IAClE,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;IACpE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,gBAAgB,CAAC,wBAAwB,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,0BAA0B,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAA2C;IAC9E,EAAE,EAAE,qBAAqB;IACzB,IAAI,EAAE,uCAAuC;IAC7C,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,sEAAsE;IACnF,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CACrB,0BAA0B,CACxB,uBAAuB,EACvB,OAAO,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CACzE;IACH,KAAK,EAAE,0BAA0B;IACjC,WAAW,EAAE,GAAG,EAAE,CAChB,0BAA0B,CAAC,eAAe,CAAC,uCAAuC,CAAC,CAAC;CACvF,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { NzDataAdapter } from './types.js';
|
|
2
|
+
/** One dataset in the data.govt.nz catalogue. */
|
|
3
|
+
export interface DataGovtNzDataset {
|
|
4
|
+
name: string;
|
|
5
|
+
title: string;
|
|
6
|
+
notes: string;
|
|
7
|
+
metadataModified: string;
|
|
8
|
+
url: string;
|
|
9
|
+
organization: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
/** A data.govt.nz CKAN package_search response: total count plus the rows. */
|
|
12
|
+
export interface DataGovtNzSearchResult {
|
|
13
|
+
count: number;
|
|
14
|
+
datasets: DataGovtNzDataset[];
|
|
15
|
+
}
|
|
16
|
+
/** Parses a data.govt.nz CKAN package_search payload into datasets. */
|
|
17
|
+
export declare function parseDataGovtNzDatasets(payload: unknown): DataGovtNzSearchResult;
|
|
18
|
+
/**
|
|
19
|
+
* Searches the public data.govt.nz catalogue (CKAN API). Keyless.
|
|
20
|
+
* Falls back to a committed fixture when the API is unreachable.
|
|
21
|
+
*/
|
|
22
|
+
export declare function searchDataGovtNzDatasets(query: string, fetchImpl?: typeof globalThis.fetch): Promise<DataGovtNzSearchResult>;
|
|
23
|
+
/** data.govt.nz adapter: catalogue search, keyless. */
|
|
24
|
+
export declare const dataGovtNzAdapter: NzDataAdapter<DataGovtNzSearchResult>;
|
|
25
|
+
//# sourceMappingURL=dataGovtNz.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataGovtNz.d.ts","sourceRoot":"","sources":["../src/dataGovtNz.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,iDAAiD;AACjD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAsBD,uEAAuE;AACvE,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,sBAAsB,CAgBhF;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,OAAO,UAAU,CAAC,KAAwB,GACpD,OAAO,CAAC,sBAAsB,CAAC,CAOjC;AAED,uDAAuD;AACvD,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC,sBAAsB,CAQnE,CAAC"}
|