@uk-open-data-connectors/uk-sources 0.1.0 → 0.1.1
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 +21 -0
- package/dist/exploreEducationStatistics.d.ts +72 -0
- package/dist/exploreEducationStatistics.d.ts.map +1 -0
- package/dist/exploreEducationStatistics.js +110 -0
- package/dist/exploreEducationStatistics.js.map +1 -0
- package/dist/findATender.d.ts +76 -0
- package/dist/findATender.d.ts.map +1 -0
- package/dist/findATender.js +109 -0
- package/dist/findATender.js.map +1 -0
- package/dist/fingertipsIndicators.d.ts +67 -0
- package/dist/fingertipsIndicators.d.ts.map +1 -0
- package/dist/fingertipsIndicators.js +94 -0
- package/dist/fingertipsIndicators.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -1
- package/dist/londonDatastore.d.ts +46 -0
- package/dist/londonDatastore.d.ts.map +1 -0
- package/dist/londonDatastore.js +64 -0
- package/dist/londonDatastore.js.map +1 -0
- package/dist/nhsbsaCkan.d.ts +43 -0
- package/dist/nhsbsaCkan.d.ts.map +1 -0
- package/dist/nhsbsaCkan.js +61 -0
- package/dist/nhsbsaCkan.js.map +1 -0
- package/dist/nomis.d.ts +71 -0
- package/dist/nomis.d.ts.map +1 -0
- package/dist/nomis.js +126 -0
- package/dist/nomis.js.map +1 -0
- package/dist/postcodeLookup.d.ts +55 -0
- package/dist/postcodeLookup.d.ts.map +1 -0
- package/dist/postcodeLookup.js +89 -0
- package/dist/postcodeLookup.js.map +1 -0
- package/dist/publicHealthScotland.d.ts +43 -0
- package/dist/publicHealthScotland.d.ts.map +1 -0
- package/dist/publicHealthScotland.js +61 -0
- package/dist/publicHealthScotland.js.map +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +22 -0
- package/dist/registry.js.map +1 -1
- package/dist/tflLineStatus.d.ts +59 -0
- package/dist/tflLineStatus.d.ts.map +1 -0
- package/dist/tflLineStatus.js +93 -0
- package/dist/tflLineStatus.js.map +1 -0
- package/dist/tnaDiscovery.d.ts +76 -0
- package/dist/tnaDiscovery.d.ts.map +1 -0
- package/dist/tnaDiscovery.js +101 -0
- package/dist/tnaDiscovery.js.map +1 -0
- package/dist/ukhsaDashboard.d.ts +92 -0
- package/dist/ukhsaDashboard.d.ts.map +1 -0
- package/dist/ukhsaDashboard.js +136 -0
- package/dist/ukhsaDashboard.js.map +1 -0
- package/package.json +11 -3
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { UkDataAdapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* postcodes.io, a free keyless lookup over ONS and Ordnance Survey postcode
|
|
4
|
+
* data published under the Open Government Licence v3. The service itself is
|
|
5
|
+
* a third party, not a government API: the postcode data is OGL, the lookup
|
|
6
|
+
* and the geocoding around it are postcodes.io's own.
|
|
7
|
+
*/
|
|
8
|
+
export declare const POSTCODE_LOOKUP_SOURCE_ID = "postcode-lookup";
|
|
9
|
+
/** Base URL for the postcodes.io single postcode lookup. */
|
|
10
|
+
export declare const POSTCODES_IO_BASE_URL = "https://api.postcodes.io/postcodes/";
|
|
11
|
+
/** The postcode the adapter looks up when the caller does not name one. */
|
|
12
|
+
export declare const DEFAULT_POSTCODE_QUERY = "SW1A1AA";
|
|
13
|
+
/** One postcode and the administrative areas it falls inside. */
|
|
14
|
+
export interface PostcodeLookupRecord {
|
|
15
|
+
/** The postcode as the service formats it, letters and digits spaced. */
|
|
16
|
+
postcode: string;
|
|
17
|
+
country: string;
|
|
18
|
+
/** English region or devolved nation region, or null when unset. */
|
|
19
|
+
region: string | null;
|
|
20
|
+
adminDistrict: string | null;
|
|
21
|
+
adminWard: string | null;
|
|
22
|
+
parliamentaryConstituency: string | null;
|
|
23
|
+
latitude: number;
|
|
24
|
+
longitude: number;
|
|
25
|
+
/** The NHS area the postcode sits in, or null when unset. */
|
|
26
|
+
nhsHa: string | null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Builds the postcodes.io lookup URL for one postcode.
|
|
30
|
+
*
|
|
31
|
+
* @param postcode - the postcode to look up, spaced or unspaced
|
|
32
|
+
* @returns the single postcode lookup URL
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildPostcodeLookupUrl(postcode: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Parses a postcodes.io single postcode payload.
|
|
37
|
+
*
|
|
38
|
+
* @param payload - the raw JSON body from the lookup endpoint
|
|
39
|
+
* @returns the postcode record the service returns
|
|
40
|
+
*/
|
|
41
|
+
export declare function parsePostcodeLookup(payload: unknown): PostcodeLookupRecord;
|
|
42
|
+
/**
|
|
43
|
+
* Looks up one postcode. The service answers 404 for an unknown postcode,
|
|
44
|
+
* which becomes an API error like any other failed request.
|
|
45
|
+
*
|
|
46
|
+
* @param postcode - the postcode to look up, default SW1A 1AA
|
|
47
|
+
* @param options - an optional fetch implementation
|
|
48
|
+
* @returns the postcode record the service returns
|
|
49
|
+
*/
|
|
50
|
+
export declare function fetchPostcodeLookup(postcode?: string, options?: {
|
|
51
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
52
|
+
}): Promise<PostcodeLookupRecord>;
|
|
53
|
+
/** postcodes.io single postcode lookup, keyless. */
|
|
54
|
+
export declare const postcodeLookupAdapter: UkDataAdapter<PostcodeLookupRecord>;
|
|
55
|
+
//# sourceMappingURL=postcodeLookup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postcodeLookup.d.ts","sourceRoot":"","sources":["../src/postcodeLookup.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAE3D,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,wCAAwC,CAAC;AAE3E,2EAA2E;AAC3E,eAAO,MAAM,sBAAsB,YAAY,CAAC;AAEhD,iEAAiE;AACjE,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAmBD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAiB1E;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,GAAE,MAA+B,EACzC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAAO,GACpD,OAAO,CAAC,oBAAoB,CAAC,CAO/B;AAED,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,oBAAoB,CAYrE,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { UkSourceApiError, UkSourceParseError } from './errors.js';
|
|
3
|
+
import { readFixtureJson } from './fixtures.js';
|
|
4
|
+
/**
|
|
5
|
+
* postcodes.io, a free keyless lookup over ONS and Ordnance Survey postcode
|
|
6
|
+
* data published under the Open Government Licence v3. The service itself is
|
|
7
|
+
* a third party, not a government API: the postcode data is OGL, the lookup
|
|
8
|
+
* and the geocoding around it are postcodes.io's own.
|
|
9
|
+
*/
|
|
10
|
+
export const POSTCODE_LOOKUP_SOURCE_ID = 'postcode-lookup';
|
|
11
|
+
/** Base URL for the postcodes.io single postcode lookup. */
|
|
12
|
+
export const POSTCODES_IO_BASE_URL = 'https://api.postcodes.io/postcodes/';
|
|
13
|
+
/** The postcode the adapter looks up when the caller does not name one. */
|
|
14
|
+
export const DEFAULT_POSTCODE_QUERY = 'SW1A1AA';
|
|
15
|
+
const POSTCODE_RESULT_SCHEMA = z.object({
|
|
16
|
+
postcode: z.string(),
|
|
17
|
+
country: z.string(),
|
|
18
|
+
region: z.string().nullable().optional(),
|
|
19
|
+
admin_district: z.string().nullable().optional(),
|
|
20
|
+
admin_ward: z.string().nullable().optional(),
|
|
21
|
+
parliamentary_constituency: z.string().nullable().optional(),
|
|
22
|
+
latitude: z.number(),
|
|
23
|
+
longitude: z.number(),
|
|
24
|
+
nhs_ha: z.string().nullable().optional(),
|
|
25
|
+
});
|
|
26
|
+
const POSTCODE_LOOKUP_SCHEMA = z.object({
|
|
27
|
+
status: z.number(),
|
|
28
|
+
result: POSTCODE_RESULT_SCHEMA,
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Builds the postcodes.io lookup URL for one postcode.
|
|
32
|
+
*
|
|
33
|
+
* @param postcode - the postcode to look up, spaced or unspaced
|
|
34
|
+
* @returns the single postcode lookup URL
|
|
35
|
+
*/
|
|
36
|
+
export function buildPostcodeLookupUrl(postcode) {
|
|
37
|
+
return `${POSTCODES_IO_BASE_URL}${encodeURIComponent(postcode)}`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parses a postcodes.io single postcode payload.
|
|
41
|
+
*
|
|
42
|
+
* @param payload - the raw JSON body from the lookup endpoint
|
|
43
|
+
* @returns the postcode record the service returns
|
|
44
|
+
*/
|
|
45
|
+
export function parsePostcodeLookup(payload) {
|
|
46
|
+
const parsed = POSTCODE_LOOKUP_SCHEMA.safeParse(payload);
|
|
47
|
+
if (!parsed.success) {
|
|
48
|
+
throw new UkSourceParseError('postcode-lookup', parsed.error.message);
|
|
49
|
+
}
|
|
50
|
+
const result = parsed.data.result;
|
|
51
|
+
return {
|
|
52
|
+
postcode: result.postcode,
|
|
53
|
+
country: result.country,
|
|
54
|
+
region: result.region ?? null,
|
|
55
|
+
adminDistrict: result.admin_district ?? null,
|
|
56
|
+
adminWard: result.admin_ward ?? null,
|
|
57
|
+
parliamentaryConstituency: result.parliamentary_constituency ?? null,
|
|
58
|
+
latitude: result.latitude,
|
|
59
|
+
longitude: result.longitude,
|
|
60
|
+
nhsHa: result.nhs_ha ?? null,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Looks up one postcode. The service answers 404 for an unknown postcode,
|
|
65
|
+
* which becomes an API error like any other failed request.
|
|
66
|
+
*
|
|
67
|
+
* @param postcode - the postcode to look up, default SW1A 1AA
|
|
68
|
+
* @param options - an optional fetch implementation
|
|
69
|
+
* @returns the postcode record the service returns
|
|
70
|
+
*/
|
|
71
|
+
export async function fetchPostcodeLookup(postcode = DEFAULT_POSTCODE_QUERY, options = {}) {
|
|
72
|
+
const { fetchImpl = globalThis.fetch } = options;
|
|
73
|
+
const response = await fetchImpl(buildPostcodeLookupUrl(postcode));
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
throw new UkSourceApiError('postcode-lookup', `HTTP ${response.status} looking up ${postcode}`);
|
|
76
|
+
}
|
|
77
|
+
return parsePostcodeLookup(await response.json());
|
|
78
|
+
}
|
|
79
|
+
/** postcodes.io single postcode lookup, keyless. */
|
|
80
|
+
export const postcodeLookupAdapter = {
|
|
81
|
+
id: POSTCODE_LOOKUP_SOURCE_ID,
|
|
82
|
+
name: 'postcodes.io postcode lookup',
|
|
83
|
+
auth: 'none',
|
|
84
|
+
description: `One postcode's country, region, wards, and coordinates, default ${DEFAULT_POSTCODE_QUERY}.`,
|
|
85
|
+
fetchLive: (options) => fetchPostcodeLookup(DEFAULT_POSTCODE_QUERY, options?.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }),
|
|
86
|
+
parse: parsePostcodeLookup,
|
|
87
|
+
loadFixture: () => parsePostcodeLookup(readFixtureJson('postcode-lookup-2026-10-05.json')),
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=postcodeLookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postcodeLookup.js","sourceRoot":"","sources":["../src/postcodeLookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { UkDataAdapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Public Health Scotland's open data portal, served by CKAN. Keyless, and the
|
|
4
|
+
* datasets are published under the Open Government Licence v3.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PUBLIC_HEALTH_SCOTLAND_SOURCE_ID = "public-health-scotland";
|
|
7
|
+
/** The CKAN package_list call on the Public Health Scotland portal. */
|
|
8
|
+
export declare const PUBLIC_HEALTH_SCOTLAND_PACKAGE_LIST_URL = "https://www.opendata.nhs.scot/api/3/action/package_list";
|
|
9
|
+
/** One dataset in the Public Health Scotland catalogue. */
|
|
10
|
+
export interface PublicHealthScotlandDataset {
|
|
11
|
+
/** CKAN package name, the identifier used in every other CKAN call. */
|
|
12
|
+
name: string;
|
|
13
|
+
}
|
|
14
|
+
/** Rolled-up view of the Public Health Scotland catalogue. */
|
|
15
|
+
export interface PublicHealthScotlandSummary {
|
|
16
|
+
packageCount: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parses a Public Health Scotland package_list payload.
|
|
20
|
+
*
|
|
21
|
+
* @param payload - the raw JSON body from the CKAN package_list call
|
|
22
|
+
* @returns one entry per dataset in the catalogue
|
|
23
|
+
*/
|
|
24
|
+
export declare function parsePublicHealthScotlandDatasets(payload: unknown): PublicHealthScotlandDataset[];
|
|
25
|
+
/**
|
|
26
|
+
* Counts the Public Health Scotland catalogue.
|
|
27
|
+
*
|
|
28
|
+
* @param datasets - dataset names from {@link parsePublicHealthScotlandDatasets}
|
|
29
|
+
* @returns the number of datasets listed
|
|
30
|
+
*/
|
|
31
|
+
export declare function summarizePublicHealthScotlandDatasets(datasets: PublicHealthScotlandDataset[]): PublicHealthScotlandSummary;
|
|
32
|
+
/**
|
|
33
|
+
* Lists every dataset in the Public Health Scotland catalogue.
|
|
34
|
+
*
|
|
35
|
+
* @param options - an optional fetch implementation
|
|
36
|
+
* @returns the package names the catalogue returns
|
|
37
|
+
*/
|
|
38
|
+
export declare function fetchPublicHealthScotlandDatasets(options?: {
|
|
39
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
40
|
+
}): Promise<PublicHealthScotlandDataset[]>;
|
|
41
|
+
/** Public Health Scotland open data catalogue, keyless. */
|
|
42
|
+
export declare const publicHealthScotlandAdapter: UkDataAdapter<PublicHealthScotlandDataset[]>;
|
|
43
|
+
//# sourceMappingURL=publicHealthScotland.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publicHealthScotland.d.ts","sourceRoot":"","sources":["../src/publicHealthScotland.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,gCAAgC,2BAA2B,CAAC;AAEzE,uEAAuE;AACvE,eAAO,MAAM,uCAAuC,4DACO,CAAC;AAE5D,2DAA2D;AAC3D,MAAM,WAAW,2BAA2B;IAC1C,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;CACd;AAED,8DAA8D;AAC9D,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,MAAM,CAAC;CACtB;AAOD;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,OAAO,GAAG,2BAA2B,EAAE,CAMjG;AAED;;;;;GAKG;AACH,wBAAgB,qCAAqC,CACnD,QAAQ,EAAE,2BAA2B,EAAE,GACtC,2BAA2B,CAE7B;AAED;;;;;GAKG;AACH,wBAAsB,iCAAiC,CACrD,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAAO,GACpD,OAAO,CAAC,2BAA2B,EAAE,CAAC,CAUxC;AAED,2DAA2D;AAC3D,eAAO,MAAM,2BAA2B,EAAE,aAAa,CAAC,2BAA2B,EAAE,CAYpF,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { UkSourceApiError, UkSourceParseError } from './errors.js';
|
|
3
|
+
import { readFixtureJson } from './fixtures.js';
|
|
4
|
+
/**
|
|
5
|
+
* Public Health Scotland's open data portal, served by CKAN. Keyless, and the
|
|
6
|
+
* datasets are published under the Open Government Licence v3.
|
|
7
|
+
*/
|
|
8
|
+
export const PUBLIC_HEALTH_SCOTLAND_SOURCE_ID = 'public-health-scotland';
|
|
9
|
+
/** The CKAN package_list call on the Public Health Scotland portal. */
|
|
10
|
+
export const PUBLIC_HEALTH_SCOTLAND_PACKAGE_LIST_URL = 'https://www.opendata.nhs.scot/api/3/action/package_list';
|
|
11
|
+
const PUBLIC_HEALTH_SCOTLAND_PACKAGE_LIST_SCHEMA = z.object({
|
|
12
|
+
success: z.boolean(),
|
|
13
|
+
result: z.array(z.string()),
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Parses a Public Health Scotland package_list payload.
|
|
17
|
+
*
|
|
18
|
+
* @param payload - the raw JSON body from the CKAN package_list call
|
|
19
|
+
* @returns one entry per dataset in the catalogue
|
|
20
|
+
*/
|
|
21
|
+
export function parsePublicHealthScotlandDatasets(payload) {
|
|
22
|
+
const parsed = PUBLIC_HEALTH_SCOTLAND_PACKAGE_LIST_SCHEMA.safeParse(payload);
|
|
23
|
+
if (!parsed.success) {
|
|
24
|
+
throw new UkSourceParseError('public-health-scotland', parsed.error.message);
|
|
25
|
+
}
|
|
26
|
+
return parsed.data.result.map((name) => ({ name }));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Counts the Public Health Scotland catalogue.
|
|
30
|
+
*
|
|
31
|
+
* @param datasets - dataset names from {@link parsePublicHealthScotlandDatasets}
|
|
32
|
+
* @returns the number of datasets listed
|
|
33
|
+
*/
|
|
34
|
+
export function summarizePublicHealthScotlandDatasets(datasets) {
|
|
35
|
+
return { packageCount: datasets.length };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Lists every dataset in the Public Health Scotland catalogue.
|
|
39
|
+
*
|
|
40
|
+
* @param options - an optional fetch implementation
|
|
41
|
+
* @returns the package names the catalogue returns
|
|
42
|
+
*/
|
|
43
|
+
export async function fetchPublicHealthScotlandDatasets(options = {}) {
|
|
44
|
+
const { fetchImpl = globalThis.fetch } = options;
|
|
45
|
+
const response = await fetchImpl(PUBLIC_HEALTH_SCOTLAND_PACKAGE_LIST_URL);
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new UkSourceApiError('public-health-scotland', `HTTP ${response.status} listing packages`);
|
|
48
|
+
}
|
|
49
|
+
return parsePublicHealthScotlandDatasets(await response.json());
|
|
50
|
+
}
|
|
51
|
+
/** Public Health Scotland open data catalogue, keyless. */
|
|
52
|
+
export const publicHealthScotlandAdapter = {
|
|
53
|
+
id: PUBLIC_HEALTH_SCOTLAND_SOURCE_ID,
|
|
54
|
+
name: 'Public Health Scotland open data catalogue',
|
|
55
|
+
auth: 'none',
|
|
56
|
+
description: 'Every dataset Public Health Scotland publishes on its open data portal.',
|
|
57
|
+
fetchLive: (options) => fetchPublicHealthScotlandDatasets(options?.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }),
|
|
58
|
+
parse: parsePublicHealthScotlandDatasets,
|
|
59
|
+
loadFixture: () => parsePublicHealthScotlandDatasets(readFixtureJson('public-health-scotland-2026-10-05.json')),
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=publicHealthScotland.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publicHealthScotland.js","sourceRoot":"","sources":["../src/publicHealthScotland.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;AAGhD;;;GAGG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,wBAAwB,CAAC;AAEzE,uEAAuE;AACvE,MAAM,CAAC,MAAM,uCAAuC,GAClD,yDAAyD,CAAC;AAa5D,MAAM,0CAA0C,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;IACpB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CAC5B,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,iCAAiC,CAAC,OAAgB;IAChE,MAAM,MAAM,GAAG,0CAA0C,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC7E,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,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qCAAqC,CACnD,QAAuC;IAEvC,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iCAAiC,CACrD,UAAmD,EAAE;IAErD,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC,KAAK,EAAE,GAAG,OAAO,CAAC;IACjD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,uCAAuC,CAAC,CAAC;IAC1E,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,gBAAgB,CACxB,wBAAwB,EACxB,QAAQ,QAAQ,CAAC,MAAM,mBAAmB,CAC3C,CAAC;IACJ,CAAC;IACD,OAAO,iCAAiC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,MAAM,2BAA2B,GAAiD;IACvF,EAAE,EAAE,gCAAgC;IACpC,IAAI,EAAE,4CAA4C;IAClD,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,yEAAyE;IACtF,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CACrB,iCAAiC,CAC/B,OAAO,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CACzE;IACH,KAAK,EAAE,iCAAiC;IACxC,WAAW,EAAE,GAAG,EAAE,CAChB,iCAAiC,CAAC,eAAe,CAAC,wCAAwC,CAAC,CAAC;CAC/F,CAAC"}
|
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,aAAa,EAAkB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/E,iEAAiE;AACjE,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,OAAO,CAAC,EAuBnD,CAAC;AAEF,uCAAuC;AACvC,wBAAgB,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,SAAS,CAE3E;AAED,mEAAmE;AACnE,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EACzB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAAE,GACjE,OAAO,CAAC,aAAa,CAAC,CAwBxB;AAED,iFAAiF;AACjF,wBAAsB,qBAAqB,CAAC,OAAO,CAAC,EAAE;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACrC,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAW3B"}
|
package/dist/registry.js
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import { ancientWoodlandAdapter } from './ancientWoodland.js';
|
|
2
2
|
import { bankRateAdapter } from './bankRate.js';
|
|
3
3
|
import { carbonIntensityAdapter } from './carbonIntensity.js';
|
|
4
|
+
import { exploreEducationStatisticsAdapter } from './exploreEducationStatistics.js';
|
|
5
|
+
import { findATenderAdapter } from './findATender.js';
|
|
6
|
+
import { fingertipsIndicatorsAdapter } from './fingertipsIndicators.js';
|
|
4
7
|
import { floodReadingsAdapter, floodStationsAdapter } from './floodMonitoring.js';
|
|
5
8
|
import { foodHygieneAuthoritiesAdapter } from './foodHygiene.js';
|
|
9
|
+
import { londonDatastoreAdapter } from './londonDatastore.js';
|
|
10
|
+
import { nhsbsaCkanAdapter } from './nhsbsaCkan.js';
|
|
11
|
+
import { nomisAdapter } from './nomis.js';
|
|
6
12
|
import { onsDatasetsAdapter } from './onsDatasets.js';
|
|
7
13
|
import { parliamentSeatsAdapter } from './parliamentSeats.js';
|
|
8
14
|
import { planningDatasetsAdapter } from './planningDatasets.js';
|
|
9
15
|
import { policeCrimesAdapter } from './policeCrimes.js';
|
|
16
|
+
import { postcodeLookupAdapter } from './postcodeLookup.js';
|
|
17
|
+
import { publicHealthScotlandAdapter } from './publicHealthScotland.js';
|
|
10
18
|
import { tflBikePointsAdapter } from './tflBikePoints.js';
|
|
19
|
+
import { tflLineStatusAdapter } from './tflLineStatus.js';
|
|
20
|
+
import { tnaDiscoveryAdapter } from './tnaDiscovery.js';
|
|
21
|
+
import { ukhsaDashboardAdapter } from './ukhsaDashboard.js';
|
|
11
22
|
/** Every UK data source behind the uniform adapter interface. */
|
|
12
23
|
export const UK_DATA_SOURCES = [
|
|
13
24
|
floodStationsAdapter,
|
|
@@ -21,6 +32,17 @@ export const UK_DATA_SOURCES = [
|
|
|
21
32
|
policeCrimesAdapter,
|
|
22
33
|
carbonIntensityAdapter,
|
|
23
34
|
parliamentSeatsAdapter,
|
|
35
|
+
postcodeLookupAdapter,
|
|
36
|
+
exploreEducationStatisticsAdapter,
|
|
37
|
+
londonDatastoreAdapter,
|
|
38
|
+
tnaDiscoveryAdapter,
|
|
39
|
+
ukhsaDashboardAdapter,
|
|
40
|
+
nomisAdapter,
|
|
41
|
+
fingertipsIndicatorsAdapter,
|
|
42
|
+
findATenderAdapter,
|
|
43
|
+
tflLineStatusAdapter,
|
|
44
|
+
publicHealthScotlandAdapter,
|
|
45
|
+
nhsbsaCkanAdapter,
|
|
24
46
|
];
|
|
25
47
|
/** Looks up a source adapter by id. */
|
|
26
48
|
export function getUkDataSource(id) {
|
package/dist/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { UkDataAdapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Transport for London's live Tube line status. Keyless: the endpoint answers
|
|
4
|
+
* without an app key, and TfL asks for one only above the free rate limit.
|
|
5
|
+
* Published as TfL Open Data.
|
|
6
|
+
*/
|
|
7
|
+
export declare const TFL_LINE_STATUS_SOURCE_ID = "tfl-line-status";
|
|
8
|
+
/** The Tube line status endpoint, covering every Tube line at once. */
|
|
9
|
+
export declare const TFL_LINE_STATUS_URL = "https://api.tfl.gov.uk/Line/Mode/tube/Status";
|
|
10
|
+
/** TfL's severity code for a line running a good service. */
|
|
11
|
+
export declare const TFL_LINE_STATUS_GOOD_SERVICE_SEVERITY = 10;
|
|
12
|
+
/** One Tube line and the service status TfL reports for it. */
|
|
13
|
+
export interface TflLineStatus {
|
|
14
|
+
/** TfL's line id, such as "bakerloo". */
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
modeName: string;
|
|
18
|
+
/** TfL's numeric severity, 10 for a good service. */
|
|
19
|
+
statusSeverity: number;
|
|
20
|
+
/** TfL's own wording for the severity, such as "Minor Delays". */
|
|
21
|
+
statusSeverityDescription: string;
|
|
22
|
+
/** The operator's explanation, or "" when there is nothing to explain. */
|
|
23
|
+
reason: string;
|
|
24
|
+
}
|
|
25
|
+
/** Rolled-up view of the Tube line status list. */
|
|
26
|
+
export interface TflLineStatusSummary {
|
|
27
|
+
lineCount: number;
|
|
28
|
+
/** Lines TfL reports at good-service severity. */
|
|
29
|
+
goodServiceCount: number;
|
|
30
|
+
/** The lines running below a good service, in TfL's order. */
|
|
31
|
+
disruptedLines: TflLineStatus[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parses a TfL line status payload into one record per line.
|
|
35
|
+
*
|
|
36
|
+
* @param payload - the raw JSON body from the line status endpoint
|
|
37
|
+
* @returns one record per Tube line, in TfL's order
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseTflLineStatuses(payload: unknown): TflLineStatus[];
|
|
40
|
+
/**
|
|
41
|
+
* Counts the lines and keeps the ones running below a good service.
|
|
42
|
+
*
|
|
43
|
+
* @param lines - lines from {@link parseTflLineStatuses}
|
|
44
|
+
* @returns line and good-service counts plus the disrupted lines
|
|
45
|
+
*/
|
|
46
|
+
export declare function summarizeTflLineStatuses(lines: TflLineStatus[]): TflLineStatusSummary;
|
|
47
|
+
/**
|
|
48
|
+
* Reads the live status of every Tube line from TfL.
|
|
49
|
+
*
|
|
50
|
+
* @param options - an optional app key and fetch implementation
|
|
51
|
+
* @returns the line statuses the endpoint returns
|
|
52
|
+
*/
|
|
53
|
+
export declare function fetchTflLineStatuses(options?: {
|
|
54
|
+
apiKey?: string;
|
|
55
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
56
|
+
}): Promise<TflLineStatus[]>;
|
|
57
|
+
/** Transport for London Tube line status, keyless. */
|
|
58
|
+
export declare const tflLineStatusAdapter: UkDataAdapter<TflLineStatus[]>;
|
|
59
|
+
//# sourceMappingURL=tflLineStatus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tflLineStatus.d.ts","sourceRoot":"","sources":["../src/tflLineStatus.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAE3D,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,iDAAiD,CAAC;AAElF,6DAA6D;AAC7D,eAAO,MAAM,qCAAqC,KAAK,CAAC;AAExD,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,yBAAyB,EAAE,MAAM,CAAC;IAClC,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,mDAAmD;AACnD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,gBAAgB,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC;AAkBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,EAAE,CAgBtE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,oBAAoB,CAUrF;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAAO,GACrE,OAAO,CAAC,aAAa,EAAE,CAAC,CAW1B;AAED,sDAAsD;AACtD,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,aAAa,EAAE,CAY/D,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { UkSourceApiError, UkSourceParseError } from './errors.js';
|
|
3
|
+
import { readFixtureJson } from './fixtures.js';
|
|
4
|
+
/**
|
|
5
|
+
* Transport for London's live Tube line status. Keyless: the endpoint answers
|
|
6
|
+
* without an app key, and TfL asks for one only above the free rate limit.
|
|
7
|
+
* Published as TfL Open Data.
|
|
8
|
+
*/
|
|
9
|
+
export const TFL_LINE_STATUS_SOURCE_ID = 'tfl-line-status';
|
|
10
|
+
/** The Tube line status endpoint, covering every Tube line at once. */
|
|
11
|
+
export const TFL_LINE_STATUS_URL = 'https://api.tfl.gov.uk/Line/Mode/tube/Status';
|
|
12
|
+
/** TfL's severity code for a line running a good service. */
|
|
13
|
+
export const TFL_LINE_STATUS_GOOD_SERVICE_SEVERITY = 10;
|
|
14
|
+
const TFL_LINE_STATUS_ENTRY_SCHEMA = z.object({
|
|
15
|
+
id: z.number(),
|
|
16
|
+
statusSeverity: z.number(),
|
|
17
|
+
statusSeverityDescription: z.string(),
|
|
18
|
+
reason: z.string().optional(),
|
|
19
|
+
});
|
|
20
|
+
const TFL_LINE_SCHEMA = z.object({
|
|
21
|
+
id: z.string(),
|
|
22
|
+
name: z.string(),
|
|
23
|
+
modeName: z.string(),
|
|
24
|
+
lineStatuses: z.array(TFL_LINE_STATUS_ENTRY_SCHEMA).min(1),
|
|
25
|
+
});
|
|
26
|
+
const TFL_LINES_SCHEMA = z.array(TFL_LINE_SCHEMA);
|
|
27
|
+
/**
|
|
28
|
+
* Parses a TfL line status payload into one record per line.
|
|
29
|
+
*
|
|
30
|
+
* @param payload - the raw JSON body from the line status endpoint
|
|
31
|
+
* @returns one record per Tube line, in TfL's order
|
|
32
|
+
*/
|
|
33
|
+
export function parseTflLineStatuses(payload) {
|
|
34
|
+
const parsed = TFL_LINES_SCHEMA.safeParse(payload);
|
|
35
|
+
if (!parsed.success) {
|
|
36
|
+
throw new UkSourceParseError('tfl-line-status', parsed.error.message);
|
|
37
|
+
}
|
|
38
|
+
return parsed.data.map((line) => {
|
|
39
|
+
const status = line.lineStatuses[0];
|
|
40
|
+
return {
|
|
41
|
+
id: line.id,
|
|
42
|
+
name: line.name,
|
|
43
|
+
modeName: line.modeName,
|
|
44
|
+
statusSeverity: status?.statusSeverity ?? 0,
|
|
45
|
+
statusSeverityDescription: status?.statusSeverityDescription ?? '',
|
|
46
|
+
reason: status?.reason ?? '',
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Counts the lines and keeps the ones running below a good service.
|
|
52
|
+
*
|
|
53
|
+
* @param lines - lines from {@link parseTflLineStatuses}
|
|
54
|
+
* @returns line and good-service counts plus the disrupted lines
|
|
55
|
+
*/
|
|
56
|
+
export function summarizeTflLineStatuses(lines) {
|
|
57
|
+
return {
|
|
58
|
+
lineCount: lines.length,
|
|
59
|
+
goodServiceCount: lines.filter((line) => line.statusSeverity === TFL_LINE_STATUS_GOOD_SERVICE_SEVERITY).length,
|
|
60
|
+
disruptedLines: lines.filter((line) => line.statusSeverity !== TFL_LINE_STATUS_GOOD_SERVICE_SEVERITY),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Reads the live status of every Tube line from TfL.
|
|
65
|
+
*
|
|
66
|
+
* @param options - an optional app key and fetch implementation
|
|
67
|
+
* @returns the line statuses the endpoint returns
|
|
68
|
+
*/
|
|
69
|
+
export async function fetchTflLineStatuses(options = {}) {
|
|
70
|
+
const { apiKey, fetchImpl = globalThis.fetch } = options;
|
|
71
|
+
const url = apiKey === undefined
|
|
72
|
+
? TFL_LINE_STATUS_URL
|
|
73
|
+
: `${TFL_LINE_STATUS_URL}?app_key=${encodeURIComponent(apiKey)}`;
|
|
74
|
+
const response = await fetchImpl(url);
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
throw new UkSourceApiError('tfl-line-status', `HTTP ${response.status} reading line status`);
|
|
77
|
+
}
|
|
78
|
+
return parseTflLineStatuses(await response.json());
|
|
79
|
+
}
|
|
80
|
+
/** Transport for London Tube line status, keyless. */
|
|
81
|
+
export const tflLineStatusAdapter = {
|
|
82
|
+
id: TFL_LINE_STATUS_SOURCE_ID,
|
|
83
|
+
name: 'Transport for London Tube line status',
|
|
84
|
+
auth: 'none',
|
|
85
|
+
description: 'The live service status of every Tube line, with disruption reasons.',
|
|
86
|
+
fetchLive: (options) => fetchTflLineStatuses({
|
|
87
|
+
...(options?.apiKey === undefined ? {} : { apiKey: options.apiKey }),
|
|
88
|
+
...(options?.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }),
|
|
89
|
+
}),
|
|
90
|
+
parse: parseTflLineStatuses,
|
|
91
|
+
loadFixture: () => parseTflLineStatuses(readFixtureJson('tfl-line-status-2026-10-05.json')),
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=tflLineStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tflLineStatus.js","sourceRoot":"","sources":["../src/tflLineStatus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { UkDataAdapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Discovery, The National Archives' catalogue search API. Keyless, and the
|
|
4
|
+
* catalogue metadata is published under the Open Government Licence v3.
|
|
5
|
+
*/
|
|
6
|
+
export declare const TNA_DISCOVERY_SOURCE_ID = "tna-discovery";
|
|
7
|
+
/** Base URL for the Discovery record search. */
|
|
8
|
+
export declare const TNA_DISCOVERY_SEARCH_URL = "https://discovery.nationalarchives.gov.uk/API/search/records";
|
|
9
|
+
/**
|
|
10
|
+
* The header Discovery expects for a JSON answer. On 2026-10-05 the endpoint
|
|
11
|
+
* also answered JSON without it, but the adapter sends it either way.
|
|
12
|
+
*/
|
|
13
|
+
export declare const TNA_DISCOVERY_ACCEPT_HEADER = "application/json";
|
|
14
|
+
/** The search term the adapter asks for when the caller does not name one. */
|
|
15
|
+
export declare const DEFAULT_TNA_DISCOVERY_QUERY = "test";
|
|
16
|
+
/** One catalogue record Discovery returns for a search. */
|
|
17
|
+
export interface TnaDiscoveryRecord {
|
|
18
|
+
id: string;
|
|
19
|
+
/** The archive's own reference, such as a catalogue piece number. */
|
|
20
|
+
reference: string;
|
|
21
|
+
title: string;
|
|
22
|
+
description: string;
|
|
23
|
+
/** The date range the record covers, as the archive writes it. */
|
|
24
|
+
coveringDates: string;
|
|
25
|
+
/** Depth in the catalogue hierarchy, or null when the record leaves it out. */
|
|
26
|
+
catalogueLevel: number | null;
|
|
27
|
+
/** The department code the record belongs to, or "" when unset. */
|
|
28
|
+
department: string;
|
|
29
|
+
/** Repositories holding the record. */
|
|
30
|
+
heldBy: string[];
|
|
31
|
+
}
|
|
32
|
+
/** One page of Discovery search results plus the total hit count. */
|
|
33
|
+
export interface TnaDiscoverySearchResult {
|
|
34
|
+
/** Total records matching the query, not just this page. */
|
|
35
|
+
totalCount: number;
|
|
36
|
+
records: TnaDiscoveryRecord[];
|
|
37
|
+
}
|
|
38
|
+
/** Rolled-up view of one Discovery search page. */
|
|
39
|
+
export interface TnaDiscoverySearchSummary {
|
|
40
|
+
recordCount: number;
|
|
41
|
+
totalCount: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Builds a Discovery record search URL for one query.
|
|
45
|
+
*
|
|
46
|
+
* @param query - the free-text search term
|
|
47
|
+
* @returns the record search URL
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildTnaDiscoverySearchUrl(query: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Parses a Discovery record search payload.
|
|
52
|
+
*
|
|
53
|
+
* @param payload - the raw JSON body from the record search endpoint
|
|
54
|
+
* @returns the page of catalogue records plus the total hit count
|
|
55
|
+
*/
|
|
56
|
+
export declare function parseTnaDiscoveryRecords(payload: unknown): TnaDiscoverySearchResult;
|
|
57
|
+
/**
|
|
58
|
+
* Sums one Discovery search page.
|
|
59
|
+
*
|
|
60
|
+
* @param result - a page from {@link parseTnaDiscoveryRecords}
|
|
61
|
+
* @returns the page size and the total hit count
|
|
62
|
+
*/
|
|
63
|
+
export declare function summarizeTnaDiscoverySearch(result: TnaDiscoverySearchResult): TnaDiscoverySearchSummary;
|
|
64
|
+
/**
|
|
65
|
+
* Searches the Discovery catalogue for one query.
|
|
66
|
+
*
|
|
67
|
+
* @param options - the search term and an optional fetch implementation
|
|
68
|
+
* @returns the page of records the search endpoint returns
|
|
69
|
+
*/
|
|
70
|
+
export declare function fetchTnaDiscoveryRecords(options?: {
|
|
71
|
+
query?: string;
|
|
72
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
73
|
+
}): Promise<TnaDiscoverySearchResult>;
|
|
74
|
+
/** The National Archives Discovery catalogue search, keyless. */
|
|
75
|
+
export declare const tnaDiscoveryAdapter: UkDataAdapter<TnaDiscoverySearchResult>;
|
|
76
|
+
//# sourceMappingURL=tnaDiscovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tnaDiscovery.d.ts","sourceRoot":"","sources":["../src/tnaDiscovery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AAEvD,gDAAgD;AAChD,eAAO,MAAM,wBAAwB,iEAC2B,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,2BAA2B,qBAAqB,CAAC;AAE9D,8EAA8E;AAC9E,eAAO,MAAM,2BAA2B,SAAS,CAAC;AAElD,2DAA2D;AAC3D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qEAAqE;AACrE,MAAM,WAAW,wBAAwB;IACvC,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,mDAAmD;AACnD,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAkBD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,wBAAwB,CAkBnF;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,wBAAwB,GAC/B,yBAAyB,CAE3B;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAAO,GACpE,OAAO,CAAC,wBAAwB,CAAC,CASnC;AAED,iEAAiE;AACjE,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC,wBAAwB,CAWvE,CAAC"}
|