@uk-open-data-connectors/uk-sources 0.1.0 → 0.1.2
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/LICENSE +21 -0
- package/README.md +110 -192
- package/dist/ancientWoodland.d.ts.map +1 -1
- package/dist/ancientWoodland.js +2 -4
- package/dist/ancientWoodland.js.map +1 -1
- package/dist/apiKey.d.ts +11 -0
- package/dist/apiKey.d.ts.map +1 -0
- package/dist/apiKey.js +17 -0
- package/dist/apiKey.js.map +1 -0
- package/dist/bankRate.d.ts.map +1 -1
- package/dist/bankRate.js +3 -5
- package/dist/bankRate.js.map +1 -1
- package/dist/carbonIntensity.d.ts +4 -1
- package/dist/carbonIntensity.d.ts.map +1 -1
- package/dist/carbonIntensity.js +6 -2
- package/dist/carbonIntensity.js.map +1 -1
- package/dist/errors.d.ts +12 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +8 -4
- package/dist/errors.js.map +1 -1
- package/dist/exploreEducationStatistics.d.ts +72 -0
- package/dist/exploreEducationStatistics.d.ts.map +1 -0
- package/dist/exploreEducationStatistics.js +108 -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 +107 -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 +92 -0
- package/dist/fingertipsIndicators.js.map +1 -0
- package/dist/floodMonitoring.d.ts.map +1 -1
- package/dist/floodMonitoring.js +4 -9
- package/dist/floodMonitoring.js.map +1 -1
- package/dist/foodHygiene.d.ts.map +1 -1
- package/dist/foodHygiene.js +4 -5
- package/dist/foodHygiene.js.map +1 -1
- package/dist/http.d.ts +34 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +83 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -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/nesoGenerationMix.d.ts +128 -0
- package/dist/nesoGenerationMix.d.ts.map +1 -0
- package/dist/nesoGenerationMix.js +241 -0
- package/dist/nesoGenerationMix.js.map +1 -0
- package/dist/nhsbsaCkan.d.ts +43 -0
- package/dist/nhsbsaCkan.d.ts.map +1 -0
- package/dist/nhsbsaCkan.js +59 -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 +124 -0
- package/dist/nomis.js.map +1 -0
- package/dist/onsDatasets.d.ts.map +1 -1
- package/dist/onsDatasets.js +3 -5
- package/dist/onsDatasets.js.map +1 -1
- package/dist/parliamentSeats.d.ts.map +1 -1
- package/dist/parliamentSeats.js +6 -5
- package/dist/parliamentSeats.js.map +1 -1
- package/dist/planningDatasets.d.ts.map +1 -1
- package/dist/planningDatasets.js +3 -5
- package/dist/planningDatasets.js.map +1 -1
- package/dist/policeCrimes.d.ts.map +1 -1
- package/dist/policeCrimes.js +5 -8
- package/dist/policeCrimes.js.map +1 -1
- 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 +59 -0
- package/dist/publicHealthScotland.js.map +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +24 -0
- package/dist/registry.js.map +1 -1
- package/dist/tflBikePoints.d.ts.map +1 -1
- package/dist/tflBikePoints.js +6 -6
- package/dist/tflBikePoints.js.map +1 -1
- package/dist/tflLineStatus.d.ts +59 -0
- package/dist/tflLineStatus.d.ts.map +1 -0
- package/dist/tflLineStatus.js +91 -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 +100 -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 +134 -0
- package/dist/ukhsaDashboard.js.map +1 -0
- package/package.json +13 -4
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { UkSourceParseError } from './errors.js';
|
|
3
|
+
import { httpGet } from './http.js';
|
|
4
|
+
import { readFixtureJson } from './fixtures.js';
|
|
5
|
+
/**
|
|
6
|
+
* Public Health Scotland's open data portal, served by CKAN. Keyless, and the
|
|
7
|
+
* datasets are published under the Open Government Licence v3.
|
|
8
|
+
*/
|
|
9
|
+
export const PUBLIC_HEALTH_SCOTLAND_SOURCE_ID = 'public-health-scotland';
|
|
10
|
+
/** The CKAN package_list call on the Public Health Scotland portal. */
|
|
11
|
+
export const PUBLIC_HEALTH_SCOTLAND_PACKAGE_LIST_URL = 'https://www.opendata.nhs.scot/api/3/action/package_list';
|
|
12
|
+
const PUBLIC_HEALTH_SCOTLAND_PACKAGE_LIST_SCHEMA = z.object({
|
|
13
|
+
success: z.boolean(),
|
|
14
|
+
result: z.array(z.string()),
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Parses a Public Health Scotland package_list payload.
|
|
18
|
+
*
|
|
19
|
+
* @param payload - the raw JSON body from the CKAN package_list call
|
|
20
|
+
* @returns one entry per dataset in the catalogue
|
|
21
|
+
*/
|
|
22
|
+
export function parsePublicHealthScotlandDatasets(payload) {
|
|
23
|
+
const parsed = PUBLIC_HEALTH_SCOTLAND_PACKAGE_LIST_SCHEMA.safeParse(payload);
|
|
24
|
+
if (!parsed.success) {
|
|
25
|
+
throw new UkSourceParseError('public-health-scotland', parsed.error.message);
|
|
26
|
+
}
|
|
27
|
+
return parsed.data.result.map((name) => ({ name }));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Counts the Public Health Scotland catalogue.
|
|
31
|
+
*
|
|
32
|
+
* @param datasets - dataset names from {@link parsePublicHealthScotlandDatasets}
|
|
33
|
+
* @returns the number of datasets listed
|
|
34
|
+
*/
|
|
35
|
+
export function summarizePublicHealthScotlandDatasets(datasets) {
|
|
36
|
+
return { packageCount: datasets.length };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Lists every dataset in the Public Health Scotland catalogue.
|
|
40
|
+
*
|
|
41
|
+
* @param options - an optional fetch implementation
|
|
42
|
+
* @returns the package names the catalogue returns
|
|
43
|
+
*/
|
|
44
|
+
export async function fetchPublicHealthScotlandDatasets(options = {}) {
|
|
45
|
+
const { fetchImpl = globalThis.fetch } = options;
|
|
46
|
+
const response = await httpGet('public-health-scotland', PUBLIC_HEALTH_SCOTLAND_PACKAGE_LIST_URL, { fetchImpl });
|
|
47
|
+
return parsePublicHealthScotlandDatasets(await response.json());
|
|
48
|
+
}
|
|
49
|
+
/** Public Health Scotland open data catalogue, keyless. */
|
|
50
|
+
export const publicHealthScotlandAdapter = {
|
|
51
|
+
id: PUBLIC_HEALTH_SCOTLAND_SOURCE_ID,
|
|
52
|
+
name: 'Public Health Scotland open data catalogue',
|
|
53
|
+
auth: 'none',
|
|
54
|
+
description: 'Every dataset Public Health Scotland publishes on its open data portal.',
|
|
55
|
+
fetchLive: (options) => fetchPublicHealthScotlandDatasets(options?.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }),
|
|
56
|
+
parse: parsePublicHealthScotlandDatasets,
|
|
57
|
+
loadFixture: () => parsePublicHealthScotlandDatasets(readFixtureJson('public-health-scotland-2026-10-05.json')),
|
|
58
|
+
};
|
|
59
|
+
//# 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,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,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,OAAO,CAC5B,wBAAwB,EACxB,uCAAuC,EACvC,EAAE,SAAS,EAAE,CACd,CAAC;IACF,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":"AAsBA,OAAO,KAAK,EAAE,aAAa,EAAkB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/E,iEAAiE;AACjE,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,OAAO,CAAC,EAwBnD,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,25 @@
|
|
|
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 { nesoGenerationMixAdapter } from './nesoGenerationMix.js';
|
|
11
|
+
import { nhsbsaCkanAdapter } from './nhsbsaCkan.js';
|
|
12
|
+
import { nomisAdapter } from './nomis.js';
|
|
6
13
|
import { onsDatasetsAdapter } from './onsDatasets.js';
|
|
7
14
|
import { parliamentSeatsAdapter } from './parliamentSeats.js';
|
|
8
15
|
import { planningDatasetsAdapter } from './planningDatasets.js';
|
|
9
16
|
import { policeCrimesAdapter } from './policeCrimes.js';
|
|
17
|
+
import { postcodeLookupAdapter } from './postcodeLookup.js';
|
|
18
|
+
import { publicHealthScotlandAdapter } from './publicHealthScotland.js';
|
|
10
19
|
import { tflBikePointsAdapter } from './tflBikePoints.js';
|
|
20
|
+
import { tflLineStatusAdapter } from './tflLineStatus.js';
|
|
21
|
+
import { tnaDiscoveryAdapter } from './tnaDiscovery.js';
|
|
22
|
+
import { ukhsaDashboardAdapter } from './ukhsaDashboard.js';
|
|
11
23
|
/** Every UK data source behind the uniform adapter interface. */
|
|
12
24
|
export const UK_DATA_SOURCES = [
|
|
13
25
|
floodStationsAdapter,
|
|
@@ -21,6 +33,18 @@ export const UK_DATA_SOURCES = [
|
|
|
21
33
|
policeCrimesAdapter,
|
|
22
34
|
carbonIntensityAdapter,
|
|
23
35
|
parliamentSeatsAdapter,
|
|
36
|
+
postcodeLookupAdapter,
|
|
37
|
+
exploreEducationStatisticsAdapter,
|
|
38
|
+
londonDatastoreAdapter,
|
|
39
|
+
tnaDiscoveryAdapter,
|
|
40
|
+
ukhsaDashboardAdapter,
|
|
41
|
+
nomisAdapter,
|
|
42
|
+
fingertipsIndicatorsAdapter,
|
|
43
|
+
findATenderAdapter,
|
|
44
|
+
tflLineStatusAdapter,
|
|
45
|
+
publicHealthScotlandAdapter,
|
|
46
|
+
nhsbsaCkanAdapter,
|
|
47
|
+
nesoGenerationMixAdapter,
|
|
24
48
|
];
|
|
25
49
|
/** Looks up a source adapter by id. */
|
|
26
50
|
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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tflBikePoints.d.ts","sourceRoot":"","sources":["../src/tflBikePoints.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tflBikePoints.d.ts","sourceRoot":"","sources":["../src/tflBikePoints.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,qCAAqC,CAAC;AAEtE,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD,6DAA6D;AAC7D,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,+DAA+D;AAC/D,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,eAAe,EAAE,cAAc,EAAE,CAAC;CACnC;AAwED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,EAAE,CAwBrE;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,EAAE,EAC1B,mBAAmB,GAAE,MAAsC,GAC1D,qBAAqB,CAYvB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAAO,GACrE,OAAO,CAAC,cAAc,EAAE,CAAC,CAS3B;AAED,uEAAuE;AACvE,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,cAAc,EAAE,CAYhE,CAAC"}
|
package/dist/tflBikePoints.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import { normalizeSourceApiKey } from './apiKey.js';
|
|
3
|
+
import { UkSourceParseError } from './errors.js';
|
|
4
|
+
import { httpGet } from './http.js';
|
|
3
5
|
import { readFixtureJson } from './fixtures.js';
|
|
4
6
|
/**
|
|
5
7
|
* Transport for London's Santander Cycles docking station list. Keyless: the
|
|
@@ -123,14 +125,12 @@ export function summarizeTflBikePoints(stations, largestStationLimit = DEFAULT_L
|
|
|
123
125
|
* @returns the docking stations the endpoint returns
|
|
124
126
|
*/
|
|
125
127
|
export async function fetchTflBikePoints(options = {}) {
|
|
126
|
-
const { apiKey, fetchImpl = globalThis.fetch } = options;
|
|
128
|
+
const { apiKey: rawApiKey, fetchImpl = globalThis.fetch } = options;
|
|
129
|
+
const apiKey = normalizeSourceApiKey(rawApiKey);
|
|
127
130
|
const url = apiKey === undefined
|
|
128
131
|
? TFL_BIKE_POINTS_URL
|
|
129
132
|
: `${TFL_BIKE_POINTS_URL}?app_key=${encodeURIComponent(apiKey)}`;
|
|
130
|
-
const response = await
|
|
131
|
-
if (!response.ok) {
|
|
132
|
-
throw new UkSourceApiError('tfl-bike-points', `HTTP ${response.status} listing docking stations`);
|
|
133
|
-
}
|
|
133
|
+
const response = await httpGet('tfl-bike-points', url, { fetchImpl });
|
|
134
134
|
return parseTflBikePoints(await response.json());
|
|
135
135
|
}
|
|
136
136
|
/** Transport for London Santander Cycles docking stations, keyless. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tflBikePoints.js","sourceRoot":"","sources":["../src/tflBikePoints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"tflBikePoints.js","sourceRoot":"","sources":["../src/tflBikePoints.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":"AAKA,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,CAQ1B;AAED,sDAAsD;AACtD,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,aAAa,EAAE,CAY/D,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { UkSourceParseError } from './errors.js';
|
|
3
|
+
import { httpGet } from './http.js';
|
|
4
|
+
import { readFixtureJson } from './fixtures.js';
|
|
5
|
+
/**
|
|
6
|
+
* Transport for London's live Tube line status. Keyless: the endpoint answers
|
|
7
|
+
* without an app key, and TfL asks for one only above the free rate limit.
|
|
8
|
+
* Published as TfL Open Data.
|
|
9
|
+
*/
|
|
10
|
+
export const TFL_LINE_STATUS_SOURCE_ID = 'tfl-line-status';
|
|
11
|
+
/** The Tube line status endpoint, covering every Tube line at once. */
|
|
12
|
+
export const TFL_LINE_STATUS_URL = 'https://api.tfl.gov.uk/Line/Mode/tube/Status';
|
|
13
|
+
/** TfL's severity code for a line running a good service. */
|
|
14
|
+
export const TFL_LINE_STATUS_GOOD_SERVICE_SEVERITY = 10;
|
|
15
|
+
const TFL_LINE_STATUS_ENTRY_SCHEMA = z.object({
|
|
16
|
+
id: z.number(),
|
|
17
|
+
statusSeverity: z.number(),
|
|
18
|
+
statusSeverityDescription: z.string(),
|
|
19
|
+
reason: z.string().optional(),
|
|
20
|
+
});
|
|
21
|
+
const TFL_LINE_SCHEMA = z.object({
|
|
22
|
+
id: z.string(),
|
|
23
|
+
name: z.string(),
|
|
24
|
+
modeName: z.string(),
|
|
25
|
+
lineStatuses: z.array(TFL_LINE_STATUS_ENTRY_SCHEMA).min(1),
|
|
26
|
+
});
|
|
27
|
+
const TFL_LINES_SCHEMA = z.array(TFL_LINE_SCHEMA);
|
|
28
|
+
/**
|
|
29
|
+
* Parses a TfL line status payload into one record per line.
|
|
30
|
+
*
|
|
31
|
+
* @param payload - the raw JSON body from the line status endpoint
|
|
32
|
+
* @returns one record per Tube line, in TfL's order
|
|
33
|
+
*/
|
|
34
|
+
export function parseTflLineStatuses(payload) {
|
|
35
|
+
const parsed = TFL_LINES_SCHEMA.safeParse(payload);
|
|
36
|
+
if (!parsed.success) {
|
|
37
|
+
throw new UkSourceParseError('tfl-line-status', parsed.error.message);
|
|
38
|
+
}
|
|
39
|
+
return parsed.data.map((line) => {
|
|
40
|
+
const status = line.lineStatuses[0];
|
|
41
|
+
return {
|
|
42
|
+
id: line.id,
|
|
43
|
+
name: line.name,
|
|
44
|
+
modeName: line.modeName,
|
|
45
|
+
statusSeverity: status?.statusSeverity ?? 0,
|
|
46
|
+
statusSeverityDescription: status?.statusSeverityDescription ?? '',
|
|
47
|
+
reason: status?.reason ?? '',
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Counts the lines and keeps the ones running below a good service.
|
|
53
|
+
*
|
|
54
|
+
* @param lines - lines from {@link parseTflLineStatuses}
|
|
55
|
+
* @returns line and good-service counts plus the disrupted lines
|
|
56
|
+
*/
|
|
57
|
+
export function summarizeTflLineStatuses(lines) {
|
|
58
|
+
return {
|
|
59
|
+
lineCount: lines.length,
|
|
60
|
+
goodServiceCount: lines.filter((line) => line.statusSeverity === TFL_LINE_STATUS_GOOD_SERVICE_SEVERITY).length,
|
|
61
|
+
disruptedLines: lines.filter((line) => line.statusSeverity !== TFL_LINE_STATUS_GOOD_SERVICE_SEVERITY),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Reads the live status of every Tube line from TfL.
|
|
66
|
+
*
|
|
67
|
+
* @param options - an optional app key and fetch implementation
|
|
68
|
+
* @returns the line statuses the endpoint returns
|
|
69
|
+
*/
|
|
70
|
+
export async function fetchTflLineStatuses(options = {}) {
|
|
71
|
+
const { apiKey, fetchImpl = globalThis.fetch } = options;
|
|
72
|
+
const url = apiKey === undefined
|
|
73
|
+
? TFL_LINE_STATUS_URL
|
|
74
|
+
: `${TFL_LINE_STATUS_URL}?app_key=${encodeURIComponent(apiKey)}`;
|
|
75
|
+
const response = await httpGet('tfl-line-status', url, { fetchImpl });
|
|
76
|
+
return parseTflLineStatuses(await response.json());
|
|
77
|
+
}
|
|
78
|
+
/** Transport for London Tube line status, keyless. */
|
|
79
|
+
export const tflLineStatusAdapter = {
|
|
80
|
+
id: TFL_LINE_STATUS_SOURCE_ID,
|
|
81
|
+
name: 'Transport for London Tube line status',
|
|
82
|
+
auth: 'none',
|
|
83
|
+
description: 'The live service status of every Tube line, with disruption reasons.',
|
|
84
|
+
fetchLive: (options) => fetchTflLineStatuses({
|
|
85
|
+
...(options?.apiKey === undefined ? {} : { apiKey: options.apiKey }),
|
|
86
|
+
...(options?.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }),
|
|
87
|
+
}),
|
|
88
|
+
parse: parseTflLineStatuses,
|
|
89
|
+
loadFixture: () => parseTflLineStatuses(readFixtureJson('tfl-line-status-2026-10-05.json')),
|
|
90
|
+
};
|
|
91
|
+
//# 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":"AAKA,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,CAOnC;AAED,iEAAiE;AACjE,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC,wBAAwB,CAWvE,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { UkSourceParseError } from './errors.js';
|
|
3
|
+
import { httpGet } from './http.js';
|
|
4
|
+
import { readFixtureJson } from './fixtures.js';
|
|
5
|
+
/**
|
|
6
|
+
* Discovery, The National Archives' catalogue search API. Keyless, and the
|
|
7
|
+
* catalogue metadata is published under the Open Government Licence v3.
|
|
8
|
+
*/
|
|
9
|
+
export const TNA_DISCOVERY_SOURCE_ID = 'tna-discovery';
|
|
10
|
+
/** Base URL for the Discovery record search. */
|
|
11
|
+
export const TNA_DISCOVERY_SEARCH_URL = 'https://discovery.nationalarchives.gov.uk/API/search/records';
|
|
12
|
+
/**
|
|
13
|
+
* The header Discovery expects for a JSON answer. On 2026-10-05 the endpoint
|
|
14
|
+
* also answered JSON without it, but the adapter sends it either way.
|
|
15
|
+
*/
|
|
16
|
+
export const TNA_DISCOVERY_ACCEPT_HEADER = 'application/json';
|
|
17
|
+
/** The search term the adapter asks for when the caller does not name one. */
|
|
18
|
+
export const DEFAULT_TNA_DISCOVERY_QUERY = 'test';
|
|
19
|
+
const TNA_DISCOVERY_RECORD_SCHEMA = z.object({
|
|
20
|
+
id: z.string(),
|
|
21
|
+
reference: z.string().nullable().optional(),
|
|
22
|
+
title: z.string().nullable().optional(),
|
|
23
|
+
description: z.string().nullable().optional(),
|
|
24
|
+
coveringDates: z.string().nullable().optional(),
|
|
25
|
+
catalogueLevel: z.number().nullable().optional(),
|
|
26
|
+
department: z.string().nullable().optional(),
|
|
27
|
+
heldBy: z.array(z.string()).nullable().optional(),
|
|
28
|
+
});
|
|
29
|
+
const TNA_DISCOVERY_SEARCH_SCHEMA = z.object({
|
|
30
|
+
records: z.array(TNA_DISCOVERY_RECORD_SCHEMA),
|
|
31
|
+
count: z.number(),
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* Builds a Discovery record search URL for one query.
|
|
35
|
+
*
|
|
36
|
+
* @param query - the free-text search term
|
|
37
|
+
* @returns the record search URL
|
|
38
|
+
*/
|
|
39
|
+
export function buildTnaDiscoverySearchUrl(query) {
|
|
40
|
+
return `${TNA_DISCOVERY_SEARCH_URL}?sps.searchQuery=${encodeURIComponent(query)}`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parses a Discovery record search payload.
|
|
44
|
+
*
|
|
45
|
+
* @param payload - the raw JSON body from the record search endpoint
|
|
46
|
+
* @returns the page of catalogue records plus the total hit count
|
|
47
|
+
*/
|
|
48
|
+
export function parseTnaDiscoveryRecords(payload) {
|
|
49
|
+
const parsed = TNA_DISCOVERY_SEARCH_SCHEMA.safeParse(payload);
|
|
50
|
+
if (!parsed.success) {
|
|
51
|
+
throw new UkSourceParseError('tna-discovery', parsed.error.message);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
totalCount: parsed.data.count,
|
|
55
|
+
records: parsed.data.records.map((record) => ({
|
|
56
|
+
id: record.id,
|
|
57
|
+
reference: record.reference ?? '',
|
|
58
|
+
title: record.title ?? '',
|
|
59
|
+
description: record.description ?? '',
|
|
60
|
+
coveringDates: record.coveringDates ?? '',
|
|
61
|
+
catalogueLevel: record.catalogueLevel ?? null,
|
|
62
|
+
department: record.department ?? '',
|
|
63
|
+
heldBy: record.heldBy ?? [],
|
|
64
|
+
})),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sums one Discovery search page.
|
|
69
|
+
*
|
|
70
|
+
* @param result - a page from {@link parseTnaDiscoveryRecords}
|
|
71
|
+
* @returns the page size and the total hit count
|
|
72
|
+
*/
|
|
73
|
+
export function summarizeTnaDiscoverySearch(result) {
|
|
74
|
+
return { recordCount: result.records.length, totalCount: result.totalCount };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Searches the Discovery catalogue for one query.
|
|
78
|
+
*
|
|
79
|
+
* @param options - the search term and an optional fetch implementation
|
|
80
|
+
* @returns the page of records the search endpoint returns
|
|
81
|
+
*/
|
|
82
|
+
export async function fetchTnaDiscoveryRecords(options = {}) {
|
|
83
|
+
const { query = DEFAULT_TNA_DISCOVERY_QUERY, fetchImpl = globalThis.fetch } = options;
|
|
84
|
+
const response = await httpGet('tna-discovery', buildTnaDiscoverySearchUrl(query), {
|
|
85
|
+
fetchImpl,
|
|
86
|
+
headers: { Accept: TNA_DISCOVERY_ACCEPT_HEADER },
|
|
87
|
+
});
|
|
88
|
+
return parseTnaDiscoveryRecords(await response.json());
|
|
89
|
+
}
|
|
90
|
+
/** The National Archives Discovery catalogue search, keyless. */
|
|
91
|
+
export const tnaDiscoveryAdapter = {
|
|
92
|
+
id: TNA_DISCOVERY_SOURCE_ID,
|
|
93
|
+
name: 'The National Archives Discovery catalogue search',
|
|
94
|
+
auth: 'none',
|
|
95
|
+
description: `Catalogue records matching "${DEFAULT_TNA_DISCOVERY_QUERY}", with the total hit count.`,
|
|
96
|
+
fetchLive: (options) => fetchTnaDiscoveryRecords(options?.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }),
|
|
97
|
+
parse: parseTnaDiscoveryRecords,
|
|
98
|
+
loadFixture: () => parseTnaDiscoveryRecords(readFixtureJson('tna-discovery-2026-10-05.json')),
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=tnaDiscovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tnaDiscovery.js","sourceRoot":"","sources":["../src/tnaDiscovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { UkDataAdapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The UK Health Security Agency data dashboard API. Keyless, published under
|
|
4
|
+
* the Open Government Licence v3.
|
|
5
|
+
*/
|
|
6
|
+
export declare const UKHSA_DASHBOARD_SOURCE_ID = "ukhsa-dashboard";
|
|
7
|
+
/** Root of the UKHSA data dashboard API. */
|
|
8
|
+
export declare const UKHSA_DASHBOARD_API_BASE_URL = "https://api.ukhsa-dashboard.data.gov.uk";
|
|
9
|
+
/**
|
|
10
|
+
* The metric the adapter reads: new HIV diagnoses in England, a country-level
|
|
11
|
+
* annual series the dashboard publishes with real counts.
|
|
12
|
+
*/
|
|
13
|
+
export declare const UKHSA_DASHBOARD_METRIC_PATH: string;
|
|
14
|
+
/** How many metric points the adapter asks for per page by default. */
|
|
15
|
+
export declare const UKHSA_DASHBOARD_PAGE_SIZE = 10;
|
|
16
|
+
/** One metric point from the UKHSA dashboard. */
|
|
17
|
+
export interface UkhsaMetricPoint {
|
|
18
|
+
theme: string;
|
|
19
|
+
subTheme: string;
|
|
20
|
+
topic: string;
|
|
21
|
+
geographyType: string;
|
|
22
|
+
geography: string;
|
|
23
|
+
/** ONS geography code for the area, or "" when the API leaves it out. */
|
|
24
|
+
geographyCode: string;
|
|
25
|
+
metric: string;
|
|
26
|
+
metricGroup: string;
|
|
27
|
+
stratum: string;
|
|
28
|
+
/** "all" for the whole population, otherwise a named subgroup. */
|
|
29
|
+
sex: string;
|
|
30
|
+
age: string;
|
|
31
|
+
year: number;
|
|
32
|
+
/** Calendar month, 1 to 12, or null for a point that is not monthly. */
|
|
33
|
+
month: number | null;
|
|
34
|
+
/** Epidemiological week, or null for a point that is not weekly. */
|
|
35
|
+
epiweek: number | null;
|
|
36
|
+
/** The point's date, ISO 8601. */
|
|
37
|
+
date: string;
|
|
38
|
+
/** The measured value, or null where the API publishes none. */
|
|
39
|
+
metricValue: number | null;
|
|
40
|
+
/** True while the dashboard flags the point as still settling. */
|
|
41
|
+
inReportingDelayPeriod: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** One page of UKHSA metric points plus the API's total count. */
|
|
44
|
+
export interface UkhsaMetricPage {
|
|
45
|
+
/** Total points the API holds for the metric, not just this page. */
|
|
46
|
+
totalCount: number;
|
|
47
|
+
points: UkhsaMetricPoint[];
|
|
48
|
+
}
|
|
49
|
+
/** Rolled-up view of one page of UKHSA metric points. */
|
|
50
|
+
export interface UkhsaMetricSummary {
|
|
51
|
+
pointCount: number;
|
|
52
|
+
totalCount: number;
|
|
53
|
+
/** Earliest and latest dates on the page, "" when the page is empty. */
|
|
54
|
+
firstDate: string;
|
|
55
|
+
lastDate: string;
|
|
56
|
+
/** The value on the latest point, or null when the page is empty. */
|
|
57
|
+
latestValue: number | null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Builds the metric URL for one page size.
|
|
61
|
+
*
|
|
62
|
+
* @param pageSize - how many metric points to ask for
|
|
63
|
+
* @returns the metric endpoint URL
|
|
64
|
+
*/
|
|
65
|
+
export declare function buildUkhsaMetricUrl(pageSize: number): string;
|
|
66
|
+
/**
|
|
67
|
+
* Parses a UKHSA dashboard metric payload.
|
|
68
|
+
*
|
|
69
|
+
* @param payload - the raw JSON body from the metric endpoint
|
|
70
|
+
* @returns the page of metric points plus the API's total count
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseUkhsaMetricPoints(payload: unknown): UkhsaMetricPage;
|
|
73
|
+
/**
|
|
74
|
+
* Sums one page of UKHSA metric points.
|
|
75
|
+
*
|
|
76
|
+
* @param page - a page from {@link parseUkhsaMetricPoints}
|
|
77
|
+
* @returns point counts, the date range on the page, and the latest value
|
|
78
|
+
*/
|
|
79
|
+
export declare function summarizeUkhsaMetricPoints(page: UkhsaMetricPage): UkhsaMetricSummary;
|
|
80
|
+
/**
|
|
81
|
+
* Reads one page of UKHSA dashboard metric points.
|
|
82
|
+
*
|
|
83
|
+
* @param options - page size and an optional fetch implementation
|
|
84
|
+
* @returns the page of metric points the endpoint returns
|
|
85
|
+
*/
|
|
86
|
+
export declare function fetchUkhsaMetricPoints(options?: {
|
|
87
|
+
pageSize?: number;
|
|
88
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
89
|
+
}): Promise<UkhsaMetricPage>;
|
|
90
|
+
/** UK Health Security Agency data dashboard metric points, keyless. */
|
|
91
|
+
export declare const ukhsaDashboardAdapter: UkDataAdapter<UkhsaMetricPage>;
|
|
92
|
+
//# sourceMappingURL=ukhsaDashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ukhsaDashboard.d.ts","sourceRoot":"","sources":["../src/ukhsaDashboard.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAE3D,4CAA4C;AAC5C,eAAO,MAAM,4BAA4B,4CAA4C,CAAC;AAEtF;;;GAGG;AACH,eAAO,MAAM,2BAA2B,QAEsC,CAAC;AAE/E,uEAAuE;AACvE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,iDAAiD;AACjD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oEAAoE;IACpE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kEAAkE;IAClE,sBAAsB,EAAE,OAAO,CAAC;CACjC;AAED,kEAAkE;AAClE,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AAED,yDAAyD;AACzD,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AA2BD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CA2BxE;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,eAAe,GAAG,kBAAkB,CAoBpF;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAAO,GACvE,OAAO,CAAC,eAAe,CAAC,CAI1B;AAED,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,eAAe,CAWhE,CAAC"}
|