@ministryofjustice/hmpps-connect-dps-shared-items 1.2.1 → 2.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.
Files changed (40) hide show
  1. package/README.md +34 -11
  2. package/dist/addressAutosuggest/osPlacesAddressService.d.ts +14 -0
  3. package/dist/addressAutosuggest/osPlacesAddressService.test.d.ts +1 -0
  4. package/dist/addressAutosuggest/osPlacesApiClient.d.ts +13 -0
  5. package/dist/addressAutosuggest/osPlacesApiClient.test.d.ts +1 -0
  6. package/dist/addressAutosuggest/testMocks/osPlacesAddressQueryResponse.d.ts +12 -0
  7. package/dist/addressAutosuggest/testMocks/osPlacesApiClientMock.d.ts +2 -0
  8. package/dist/alertFlags/getAlertFlagLabelsForAlerts.d.ts +3 -4
  9. package/dist/alertFlags/getAlertFlagLabelsForAlerts.test.d.ts +1 -0
  10. package/dist/assets/dps/components/address-autosuggest/_address-autosuggest.scss +98 -0
  11. package/dist/assets/dps/components/address-autosuggest/abortable-fetch.js +43 -0
  12. package/dist/assets/dps/components/address-autosuggest/autosuggest-address.js +90 -0
  13. package/dist/assets/dps/components/address-autosuggest/autosuggest-ui.js +369 -0
  14. package/dist/assets/dps/components/address-autosuggest/index.js +10 -0
  15. package/dist/assets/dps/components/address-autosuggest/macro.njk +61 -0
  16. package/dist/assets/js/all.js +5 -0
  17. package/dist/assets/scss/all.scss +2 -1
  18. package/dist/index.cjs +277 -0
  19. package/dist/index.cjs.map +1 -0
  20. package/dist/index.d.ts +237 -5
  21. package/dist/index.esm.js +273 -0
  22. package/dist/index.esm.js.map +1 -0
  23. package/dist/types/public/ConnectDpsComponentLogger.d.ts +2 -0
  24. package/dist/types/public/addressAutosuggest/index.d.ts +2 -0
  25. package/dist/types/public/addressAutosuggest/osAddress.d.ts +13 -0
  26. package/dist/types/public/addressAutosuggest/osPlaces.d.ts +124 -0
  27. package/dist/{alertFlags/types → types/public/alertFlags}/Alert.d.ts +1 -3
  28. package/dist/{alertFlags/types → types/public/alertFlags}/AlertFlagLabel.d.ts +1 -1
  29. package/dist/types/public/alertFlags/index.d.ts +1 -0
  30. package/dist/utils/utils.d.ts +8 -0
  31. package/package.json +51 -52
  32. package/readme/publishing.md +21 -0
  33. package/dist/alertFlags/getAlertFlagLabelsForAlerts.js +0 -146
  34. package/dist/alertFlags/getAlertFlagLabelsForAlerts.js.map +0 -1
  35. package/dist/alertFlags/types/Alert.js +0 -7
  36. package/dist/alertFlags/types/Alert.js.map +0 -1
  37. package/dist/alertFlags/types/AlertFlagLabel.js +0 -3
  38. package/dist/alertFlags/types/AlertFlagLabel.js.map +0 -1
  39. package/dist/index.js +0 -12
  40. package/dist/index.js.map +0 -1
package/dist/index.cjs ADDED
@@ -0,0 +1,277 @@
1
+ 'use strict';
2
+
3
+ var Fuse = require('fuse.js');
4
+ var superagent = require('superagent');
5
+
6
+ const isBlank = (str) => !str || /^\s*$/.test(str);
7
+ const properCase = (word) => word.length >= 1 ? word[0].toUpperCase() + word.toLowerCase().slice(1) : word;
8
+ /**
9
+ * Converts a name (first name, last name, middle name, etc.) to proper case equivalent, handling double-barreled names
10
+ * correctly (i.e. each part in a double-barreled is converted to proper case).
11
+ * @param name name to be converted.
12
+ * @returns name converted to proper case.
13
+ */
14
+ const properCaseName = (name) => (isBlank(name) ? '' : name.split('-').map(properCase).join('-'));
15
+ const convertToTitleCase = (sentence) => isBlank(sentence) ? '' : sentence.split(' ').map(properCaseName).join(' ');
16
+
17
+ const simplePostCodeRegex = /^[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}$/i;
18
+ const stringContainingPostCodeRegex = /^(.*?)([A-Z]{1,2}\d[A-Z\d]? ?)(\d[A-Z]{2})(.*)$/i;
19
+ class OsPlacesAddressService {
20
+ logger;
21
+ osPlacesApiClient;
22
+ constructor(logger, osPlacesApiClient) {
23
+ this.logger = logger;
24
+ this.osPlacesApiClient = osPlacesApiClient;
25
+ }
26
+ async getAddressesMatchingQuery(searchQuery, sanitisePostcode = true) {
27
+ const response = await this.osPlacesApiClient.getAddressesByFreeTextQuery(sanitisePostcode ? this.sanitiseUkPostcode(searchQuery) : searchQuery);
28
+ const rawResults = this.handleResponse(response);
29
+ const bestMatchResults = new Fuse(rawResults, {
30
+ shouldSort: true,
31
+ threshold: 0.2,
32
+ ignoreLocation: true,
33
+ keys: [{ name: 'addressString' }],
34
+ })
35
+ .search(searchQuery)
36
+ .map(result => result.item);
37
+ const queryIsAPostCode = simplePostCodeRegex.test(searchQuery.trim());
38
+ const buildingNumberSort = (a, b) => a?.addressString && b?.addressString && queryIsAPostCode
39
+ ? a.addressString.localeCompare(b.addressString, undefined, { numeric: true, sensitivity: 'base' })
40
+ : 1;
41
+ // maximum number of properties in a postcode is 100
42
+ return (bestMatchResults.length ? bestMatchResults : rawResults).sort(buildingNumberSort).slice(0, 100);
43
+ }
44
+ async getAddressByUprn(uprn) {
45
+ const response = await this.osPlacesApiClient.getAddressesByUprn(uprn);
46
+ const result = this.handleResponse(response);
47
+ if (result.length === 0)
48
+ return null;
49
+ if (result.length > 1)
50
+ this.logger.info(`Multiple results returned for UPRN`);
51
+ return result[result.length - 1];
52
+ }
53
+ sanitiseUkPostcode(stringContainingPostcode) {
54
+ const postCodeQuery = stringContainingPostCodeRegex.exec(stringContainingPostcode?.replace(/[^A-Z0-9 ]/gi, ''));
55
+ if (!postCodeQuery)
56
+ return stringContainingPostcode;
57
+ return `${postCodeQuery[1]}${postCodeQuery[2].toUpperCase().trim()} ${postCodeQuery[3].toUpperCase().trim()}${postCodeQuery[4]}`;
58
+ }
59
+ handleResponse(response) {
60
+ if (response.header && response.header.totalresults === 0)
61
+ return [];
62
+ return response.results.filter(result => result.DPA).map(result => this.toOsAddress(result.DPA));
63
+ }
64
+ toOsAddress(addressResult) {
65
+ const { UPRN, DEPENDENT_LOCALITY, SUB_BUILDING_NAME, BUILDING_NAME, BUILDING_NUMBER, THOROUGHFARE_NAME, POST_TOWN, POSTCODE, COUNTRY_CODE, LOCAL_CUSTODIAN_CODE_DESCRIPTION, } = addressResult;
66
+ return {
67
+ addressString: this.formatAddressString(addressResult),
68
+ buildingNumber: BUILDING_NUMBER,
69
+ buildingName: convertToTitleCase(BUILDING_NAME),
70
+ subBuildingName: convertToTitleCase(SUB_BUILDING_NAME),
71
+ thoroughfareName: convertToTitleCase(THOROUGHFARE_NAME),
72
+ dependentLocality: convertToTitleCase(DEPENDENT_LOCALITY),
73
+ postTown: convertToTitleCase(POST_TOWN),
74
+ county: convertToTitleCase(LOCAL_CUSTODIAN_CODE_DESCRIPTION),
75
+ postcode: POSTCODE,
76
+ country: COUNTRY_CODE,
77
+ uprn: UPRN,
78
+ };
79
+ }
80
+ formatAddressString(addressResult) {
81
+ const { ADDRESS, BUILDING_NUMBER, THOROUGHFARE_NAME, POSTCODE } = addressResult;
82
+ const withoutPostcode = ADDRESS.replace(`, ${POSTCODE}`, '').replace(`${BUILDING_NUMBER}, ${THOROUGHFARE_NAME}`, `${BUILDING_NUMBER} ${THOROUGHFARE_NAME}`);
83
+ return `${convertToTitleCase(withoutPostcode)}, ${POSTCODE}`;
84
+ }
85
+ }
86
+
87
+ class OsPlacesApiClient {
88
+ logger;
89
+ config;
90
+ constructor(logger, config) {
91
+ this.logger = logger;
92
+ this.config = config;
93
+ }
94
+ async getAddressesByFreeTextQuery(freeTextQuery) {
95
+ const queryParams = {
96
+ query: freeTextQuery,
97
+ lr: 'EN',
98
+ key: this.config.apiKey,
99
+ };
100
+ return this.get('/find', queryParams);
101
+ }
102
+ async getAddressesByUprn(uprn) {
103
+ const queryParams = {
104
+ uprn,
105
+ key: this.config.apiKey,
106
+ };
107
+ return this.get('/uprn', queryParams);
108
+ }
109
+ async get(path, query) {
110
+ const endpoint = `${this.config.url}${path}`;
111
+ try {
112
+ const result = await superagent
113
+ .get(endpoint)
114
+ .retry(2, (err, res) => {
115
+ if (err)
116
+ this.logger.info(`Retry handler found API error with ${err.code} ${err.message}`);
117
+ return undefined; // retry handler only for logging retries, not to influence retry logic
118
+ })
119
+ .query(query)
120
+ .timeout(this.config.timeout);
121
+ return result.body;
122
+ }
123
+ catch (error) {
124
+ throw Error(`Error calling OS Places API: ${error.message}`);
125
+ }
126
+ }
127
+ }
128
+
129
+ const alertFlagLabels = [
130
+ { alertCodes: ['HA'], classes: 'dps-alert-status dps-alert-status--self-harm', label: 'ACCT open' },
131
+ {
132
+ alertCodes: ['HA1'],
133
+ classes: 'dps-alert-status dps-alert-status--self-harm',
134
+ label: 'ACCT post closure',
135
+ },
136
+ {
137
+ alertCodes: ['XSA', 'SA'],
138
+ classes: 'dps-alert-status dps-alert-status--security',
139
+ label: 'Staff assaulter',
140
+ },
141
+ {
142
+ alertCodes: ['XA'],
143
+ classes: 'dps-alert-status dps-alert-status--security',
144
+ label: 'Arsonist',
145
+ },
146
+ {
147
+ alertCodes: ['PEEP'],
148
+ classes: 'dps-alert-status dps-alert-status--medical',
149
+ label: 'PEEP',
150
+ },
151
+ {
152
+ alertCodes: ['HID'],
153
+ classes: 'dps-alert-status dps-alert-status--medical',
154
+ label: 'Hidden disability',
155
+ },
156
+ { alertCodes: ['XEL'], classes: 'dps-alert-status dps-alert-status--security', label: 'E-list' },
157
+ { alertCodes: ['XELH'], classes: 'dps-alert-status dps-alert-status--security', label: 'E-list heightened' },
158
+ { alertCodes: ['XER'], classes: 'dps-alert-status dps-alert-status--security', label: 'Escape risk' },
159
+ {
160
+ alertCodes: ['XRF'],
161
+ classes: 'dps-alert-status dps-alert-status--security',
162
+ label: 'Risk to females',
163
+ },
164
+ { alertCodes: ['XTACT'], classes: 'dps-alert-status dps-alert-status--security', label: 'TACT' },
165
+ {
166
+ alertCodes: ['XCO'],
167
+ classes: 'dps-alert-status dps-alert-status--security',
168
+ label: 'Corruptor',
169
+ },
170
+ {
171
+ alertCodes: ['XCA'],
172
+ classes: 'dps-alert-status dps-alert-status--security',
173
+ label: 'Chemical attacker',
174
+ },
175
+ {
176
+ alertCodes: ['XCI'],
177
+ classes: 'dps-alert-status dps-alert-status--security',
178
+ label: 'Concerted indiscipline',
179
+ },
180
+ { alertCodes: ['XR'], classes: 'dps-alert-status dps-alert-status--security', label: 'Racist' },
181
+ {
182
+ alertCodes: ['RTP', 'RLG'],
183
+ classes: 'dps-alert-status dps-alert-status--risk',
184
+ label: 'Risk to LGBT',
185
+ },
186
+ {
187
+ alertCodes: ['XHT'],
188
+ classes: 'dps-alert-status dps-alert-status--security',
189
+ label: 'Hostage taker',
190
+ },
191
+ {
192
+ alertCodes: ['XCU'],
193
+ classes: 'dps-alert-status dps-alert-status--security',
194
+ label: 'Controlled unlock',
195
+ },
196
+ {
197
+ alertCodes: ['XGANG'],
198
+ classes: 'dps-alert-status dps-alert-status--security',
199
+ label: 'Gang member',
200
+ },
201
+ { alertCodes: ['CSIP'], classes: 'dps-alert-status dps-alert-status--other', label: 'CSIP' },
202
+ { alertCodes: ['F1'], classes: 'dps-alert-status dps-alert-status--ex-armed-forces', label: 'Veteran' },
203
+ {
204
+ alertCodes: ['LCE'],
205
+ classes: 'dps-alert-status dps-alert-status--care-leaver',
206
+ label: 'Care experienced',
207
+ },
208
+ {
209
+ alertCodes: ['RNO121'],
210
+ classes: 'dps-alert-status dps-alert-status--risk',
211
+ label: 'No one-to-one',
212
+ },
213
+ { alertCodes: ['RCON'], classes: 'dps-alert-status dps-alert-status--risk', label: 'Conflict' },
214
+ {
215
+ alertCodes: ['RCDR'],
216
+ classes: 'dps-alert-status dps-alert-status--quarantined',
217
+ label: 'Quarantined',
218
+ },
219
+ {
220
+ alertCodes: ['URCU'],
221
+ classes: 'dps-alert-status dps-alert-status--reverse-cohorting-unit',
222
+ label: 'Reverse Cohorting Unit',
223
+ },
224
+ {
225
+ alertCodes: ['UPIU'],
226
+ classes: 'dps-alert-status dps-alert-status--protective-isolation-unit',
227
+ label: 'Protective Isolation Unit',
228
+ },
229
+ { alertCodes: ['USU'], classes: 'dps-alert-status dps-alert-status--shielding-unit', label: 'Shielding Unit' },
230
+ {
231
+ alertCodes: ['URS'],
232
+ classes: 'dps-alert-status dps-alert-status--refusing-to-shield',
233
+ label: 'Refusing to shield',
234
+ },
235
+ {
236
+ alertCodes: ['RKS'],
237
+ classes: 'dps-alert-status dps-alert-status--risk-to-known-adults',
238
+ label: 'Risk to known adults',
239
+ },
240
+ { alertCodes: ['VIP'], classes: 'dps-alert-status dps-alert-status--isolated-prisoner', label: 'Isolated' },
241
+ {
242
+ alertCodes: ['PVN'],
243
+ classes: 'dps-alert-status dps-alert-status--multicase dps-alert-status--visor',
244
+ label: 'ViSOR',
245
+ },
246
+ {
247
+ alertCodes: ['XCDO'],
248
+ classes: 'dps-alert-status dps-alert-status--security',
249
+ label: 'Involved in 2024 civil disorder',
250
+ },
251
+ {
252
+ alertCodes: ['XVL'],
253
+ classes: 'dps-alert-status dps-alert-status--security',
254
+ label: 'Violent',
255
+ },
256
+ ].sort((a, b) => a.label.localeCompare(b.label));
257
+ function isAlertsServiceAlert(alert) {
258
+ return typeof alert.alertCode !== 'string';
259
+ }
260
+ function getAlertFlagLabelsForAlerts(prisonerAlerts) {
261
+ return alertFlagLabels.reduce((acc, flag) => {
262
+ const alertIds = prisonerAlerts
263
+ .filter(alert => {
264
+ const alertsServiceAlert = isAlertsServiceAlert(alert);
265
+ const alertIsActive = alertsServiceAlert ? alert.isActive : alert.active && !alert.expired;
266
+ const prisonerAlertCode = alertsServiceAlert ? alert.alertCode.code : alert.alertCode;
267
+ return alertIsActive && flag.alertCodes.includes(prisonerAlertCode);
268
+ })
269
+ .map(alert => (isAlertsServiceAlert(alert) ? alert.alertUuid : alert.alertCode));
270
+ return alertIds.length ? [...acc, { ...flag, alertIds }] : acc;
271
+ }, []);
272
+ }
273
+
274
+ exports.OsPlacesAddressService = OsPlacesAddressService;
275
+ exports.OsPlacesApiClient = OsPlacesApiClient;
276
+ exports.getAlertFlagLabelsForAlerts = getAlertFlagLabelsForAlerts;
277
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/utils/utils.ts","../src/addressAutosuggest/osPlacesAddressService.ts","../src/addressAutosuggest/osPlacesApiClient.ts","../src/alertFlags/getAlertFlagLabelsForAlerts.ts"],"sourcesContent":["const isBlank = (str: string): boolean => !str || /^\\s*$/.test(str)\n\nconst properCase = (word: string): string =>\n word.length >= 1 ? word[0].toUpperCase() + word.toLowerCase().slice(1) : word\n\n/**\n * Converts a name (first name, last name, middle name, etc.) to proper case equivalent, handling double-barreled names\n * correctly (i.e. each part in a double-barreled is converted to proper case).\n * @param name name to be converted.\n * @returns name converted to proper case.\n */\nexport const properCaseName = (name: string): string => (isBlank(name) ? '' : name.split('-').map(properCase).join('-'))\n\nexport const convertToTitleCase = (sentence: string): string =>\n isBlank(sentence) ? '' : sentence.split(' ').map(properCaseName).join(' ')\n","import Fuse from 'fuse.js'\nimport { OsAddress } from '../types/public/addressAutosuggest/osAddress'\nimport { convertToTitleCase } from '../utils/utils'\nimport OsPlacesApiClient from './osPlacesApiClient'\nimport { ConnectDpsComponentLogger } from '../types/public/ConnectDpsComponentLogger'\nimport { OsPlacesDeliveryPointAddress, OsPlacesQueryResponse } from '../types/public/addressAutosuggest/osPlaces'\n\nconst simplePostCodeRegex = /^[A-Z]{1,2}\\d[A-Z\\d]? ?\\d[A-Z]{2}$/i\nconst stringContainingPostCodeRegex = /^(.*?)([A-Z]{1,2}\\d[A-Z\\d]? ?)(\\d[A-Z]{2})(.*)$/i\n\nexport default class OsPlacesAddressService {\n constructor(\n private readonly logger: ConnectDpsComponentLogger,\n private readonly osPlacesApiClient: OsPlacesApiClient,\n ) {}\n\n public async getAddressesMatchingQuery(searchQuery: string, sanitisePostcode: boolean = true): Promise<OsAddress[]> {\n const response = await this.osPlacesApiClient.getAddressesByFreeTextQuery(\n sanitisePostcode ? this.sanitiseUkPostcode(searchQuery) : searchQuery,\n )\n\n const rawResults = this.handleResponse(response)\n\n const bestMatchResults = new Fuse(rawResults, {\n shouldSort: true,\n threshold: 0.2,\n ignoreLocation: true,\n keys: [{ name: 'addressString' }],\n })\n .search(searchQuery)\n .map(result => result.item)\n\n const queryIsAPostCode = simplePostCodeRegex.test(searchQuery.trim())\n const buildingNumberSort = (a: OsAddress, b: OsAddress) =>\n a?.addressString && b?.addressString && queryIsAPostCode\n ? a.addressString.localeCompare(b.addressString, undefined, { numeric: true, sensitivity: 'base' })\n : 1\n\n // maximum number of properties in a postcode is 100\n return (bestMatchResults.length ? bestMatchResults : rawResults).sort(buildingNumberSort).slice(0, 100)\n }\n\n public async getAddressByUprn(uprn: string): Promise<OsAddress | null> {\n const response = await this.osPlacesApiClient.getAddressesByUprn(uprn)\n const result = this.handleResponse(response)\n\n if (result.length === 0) return null\n if (result.length > 1) this.logger.info(`Multiple results returned for UPRN`)\n\n return result[result.length - 1]\n }\n\n public sanitiseUkPostcode(stringContainingPostcode: string) {\n const postCodeQuery = stringContainingPostCodeRegex.exec(stringContainingPostcode?.replace(/[^A-Z0-9 ]/gi, ''))\n if (!postCodeQuery) return stringContainingPostcode\n\n return `${postCodeQuery[1]}${postCodeQuery[2].toUpperCase().trim()} ${postCodeQuery[3].toUpperCase().trim()}${postCodeQuery[4]}`\n }\n\n private handleResponse(response: OsPlacesQueryResponse): OsAddress[] {\n if (response.header && response.header.totalresults === 0) return []\n\n return response.results.filter(result => result.DPA).map(result => this.toOsAddress(result.DPA!))\n }\n\n private toOsAddress(addressResult: OsPlacesDeliveryPointAddress): OsAddress {\n const {\n UPRN,\n DEPENDENT_LOCALITY,\n SUB_BUILDING_NAME,\n BUILDING_NAME,\n BUILDING_NUMBER,\n THOROUGHFARE_NAME,\n POST_TOWN,\n POSTCODE,\n COUNTRY_CODE,\n LOCAL_CUSTODIAN_CODE_DESCRIPTION,\n } = addressResult\n\n return {\n addressString: this.formatAddressString(addressResult),\n buildingNumber: BUILDING_NUMBER,\n buildingName: convertToTitleCase(BUILDING_NAME),\n subBuildingName: convertToTitleCase(SUB_BUILDING_NAME),\n thoroughfareName: convertToTitleCase(THOROUGHFARE_NAME),\n dependentLocality: convertToTitleCase(DEPENDENT_LOCALITY),\n postTown: convertToTitleCase(POST_TOWN),\n county: convertToTitleCase(LOCAL_CUSTODIAN_CODE_DESCRIPTION),\n postcode: POSTCODE,\n country: COUNTRY_CODE,\n uprn: UPRN,\n }\n }\n\n private formatAddressString(addressResult: OsPlacesDeliveryPointAddress) {\n const { ADDRESS, BUILDING_NUMBER, THOROUGHFARE_NAME, POSTCODE } = addressResult\n const withoutPostcode = ADDRESS.replace(`, ${POSTCODE}`, '').replace(\n `${BUILDING_NUMBER}, ${THOROUGHFARE_NAME}`,\n `${BUILDING_NUMBER} ${THOROUGHFARE_NAME}`,\n )\n return `${convertToTitleCase(withoutPostcode)}, ${POSTCODE}`\n }\n}\n","import superagent from 'superagent'\nimport { ApiConfig } from '@ministryofjustice/hmpps-rest-client'\nimport { OsPlacesQueryResponse } from '../types/public/addressAutosuggest/osPlaces'\nimport { ConnectDpsComponentLogger } from '../types/public/ConnectDpsComponentLogger'\n\nexport default class OsPlacesApiClient {\n constructor(\n private readonly logger: ConnectDpsComponentLogger,\n private readonly config: ApiConfig & { apiKey: string },\n ) {}\n\n async getAddressesByFreeTextQuery(freeTextQuery: string): Promise<OsPlacesQueryResponse> {\n const queryParams: Record<string, string> = {\n query: freeTextQuery,\n lr: 'EN',\n key: this.config.apiKey,\n }\n\n return this.get<Promise<OsPlacesQueryResponse>>('/find', queryParams)\n }\n\n async getAddressesByUprn(uprn: string): Promise<OsPlacesQueryResponse> {\n const queryParams: Record<string, string> = {\n uprn,\n key: this.config.apiKey,\n }\n\n return this.get<Promise<OsPlacesQueryResponse>>('/uprn', queryParams)\n }\n\n async get<T>(path: string, query: Record<string, string>): Promise<T> {\n const endpoint = `${this.config.url}${path}`\n try {\n const result = await superagent\n .get(endpoint)\n .retry(2, (err, res) => {\n if (err) this.logger.info(`Retry handler found API error with ${err.code} ${err.message}`)\n return undefined // retry handler only for logging retries, not to influence retry logic\n })\n .query(query)\n .timeout(this.config.timeout)\n\n return result.body\n } catch (error: any) {\n throw Error(`Error calling OS Places API: ${error.message}`)\n }\n }\n}\n","import { Alert, AlertsServiceAlert } from '../types/public/alertFlags/Alert'\nimport { AlertFlagLabel } from '../types/public/alertFlags/AlertFlagLabel'\n\nexport const alertFlagLabels = [\n { alertCodes: ['HA'], classes: 'dps-alert-status dps-alert-status--self-harm', label: 'ACCT open' },\n {\n alertCodes: ['HA1'],\n classes: 'dps-alert-status dps-alert-status--self-harm',\n label: 'ACCT post closure',\n },\n {\n alertCodes: ['XSA', 'SA'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Staff assaulter',\n },\n {\n alertCodes: ['XA'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Arsonist',\n },\n {\n alertCodes: ['PEEP'],\n classes: 'dps-alert-status dps-alert-status--medical',\n label: 'PEEP',\n },\n {\n alertCodes: ['HID'],\n classes: 'dps-alert-status dps-alert-status--medical',\n label: 'Hidden disability',\n },\n { alertCodes: ['XEL'], classes: 'dps-alert-status dps-alert-status--security', label: 'E-list' },\n { alertCodes: ['XELH'], classes: 'dps-alert-status dps-alert-status--security', label: 'E-list heightened' },\n { alertCodes: ['XER'], classes: 'dps-alert-status dps-alert-status--security', label: 'Escape risk' },\n {\n alertCodes: ['XRF'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Risk to females',\n },\n { alertCodes: ['XTACT'], classes: 'dps-alert-status dps-alert-status--security', label: 'TACT' },\n {\n alertCodes: ['XCO'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Corruptor',\n },\n {\n alertCodes: ['XCA'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Chemical attacker',\n },\n {\n alertCodes: ['XCI'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Concerted indiscipline',\n },\n { alertCodes: ['XR'], classes: 'dps-alert-status dps-alert-status--security', label: 'Racist' },\n {\n alertCodes: ['RTP', 'RLG'],\n classes: 'dps-alert-status dps-alert-status--risk',\n label: 'Risk to LGBT',\n },\n {\n alertCodes: ['XHT'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Hostage taker',\n },\n {\n alertCodes: ['XCU'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Controlled unlock',\n },\n {\n alertCodes: ['XGANG'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Gang member',\n },\n { alertCodes: ['CSIP'], classes: 'dps-alert-status dps-alert-status--other', label: 'CSIP' },\n { alertCodes: ['F1'], classes: 'dps-alert-status dps-alert-status--ex-armed-forces', label: 'Veteran' },\n {\n alertCodes: ['LCE'],\n classes: 'dps-alert-status dps-alert-status--care-leaver',\n label: 'Care experienced',\n },\n {\n alertCodes: ['RNO121'],\n classes: 'dps-alert-status dps-alert-status--risk',\n label: 'No one-to-one',\n },\n { alertCodes: ['RCON'], classes: 'dps-alert-status dps-alert-status--risk', label: 'Conflict' },\n {\n alertCodes: ['RCDR'],\n classes: 'dps-alert-status dps-alert-status--quarantined',\n label: 'Quarantined',\n },\n {\n alertCodes: ['URCU'],\n classes: 'dps-alert-status dps-alert-status--reverse-cohorting-unit',\n label: 'Reverse Cohorting Unit',\n },\n {\n alertCodes: ['UPIU'],\n classes: 'dps-alert-status dps-alert-status--protective-isolation-unit',\n label: 'Protective Isolation Unit',\n },\n { alertCodes: ['USU'], classes: 'dps-alert-status dps-alert-status--shielding-unit', label: 'Shielding Unit' },\n {\n alertCodes: ['URS'],\n classes: 'dps-alert-status dps-alert-status--refusing-to-shield',\n label: 'Refusing to shield',\n },\n {\n alertCodes: ['RKS'],\n classes: 'dps-alert-status dps-alert-status--risk-to-known-adults',\n label: 'Risk to known adults',\n },\n { alertCodes: ['VIP'], classes: 'dps-alert-status dps-alert-status--isolated-prisoner', label: 'Isolated' },\n {\n alertCodes: ['PVN'],\n classes: 'dps-alert-status dps-alert-status--multicase dps-alert-status--visor',\n label: 'ViSOR',\n },\n {\n alertCodes: ['XCDO'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Involved in 2024 civil disorder',\n },\n {\n alertCodes: ['XVL'],\n classes: 'dps-alert-status dps-alert-status--security',\n label: 'Violent',\n },\n].sort((a, b) => a.label.localeCompare(b.label))\n\nfunction isAlertsServiceAlert(alert: Alert): alert is AlertsServiceAlert {\n return typeof alert.alertCode !== 'string'\n}\n\nexport default function getAlertFlagLabelsForAlerts(prisonerAlerts: Alert[]): AlertFlagLabel[] {\n return alertFlagLabels.reduce(\n (acc: AlertFlagLabel[], flag: { alertCodes: string[]; classes: string; label: string }) => {\n const alertIds = prisonerAlerts\n .filter(alert => {\n const alertsServiceAlert = isAlertsServiceAlert(alert)\n const alertIsActive = alertsServiceAlert ? alert.isActive : alert.active && !alert.expired\n const prisonerAlertCode = alertsServiceAlert ? alert.alertCode.code : alert.alertCode\n\n return alertIsActive && flag.alertCodes.includes(prisonerAlertCode)\n })\n .map(alert => (isAlertsServiceAlert(alert) ? (alert.alertUuid as string) : alert.alertCode))\n\n return alertIds.length ? [...acc, { ...flag, alertIds }] : acc\n },\n [] as AlertFlagLabel[],\n )\n}\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,238 @@
1
- declare const _default: {
2
- alertFlags: {
3
- getAlertFlagLabelsForAlerts: (prisonerAlerts: import("./alertFlags/types/Alert").default[]) => import("./alertFlags/types/AlertFlagLabel").default[];
1
+ import Logger from 'bunyan';
2
+ import { ApiConfig } from '@ministryofjustice/hmpps-rest-client';
3
+
4
+ type ConnectDpsComponentLogger = Logger | typeof console;
5
+
6
+ interface OsAddress {
7
+ addressString?: string;
8
+ buildingNumber?: number;
9
+ buildingName?: string;
10
+ subBuildingName?: string;
11
+ thoroughfareName?: string;
12
+ dependentLocality?: string;
13
+ postTown?: string;
14
+ county?: string;
15
+ postcode?: string;
16
+ country?: string;
17
+ uprn?: number;
18
+ }
19
+
20
+ interface OsPlacesQueryResponse {
21
+ header: OsPlacesResponseHeader;
22
+ results: OsPlacesQueryResult[];
23
+ }
24
+ interface OsPlacesResponseHeader {
25
+ uri: string;
26
+ query: string;
27
+ offset: number;
28
+ totalresults: number;
29
+ format: string;
30
+ dataset: string;
31
+ lr: string;
32
+ maxresults: number;
33
+ matchprecision: number;
34
+ epoch: string;
35
+ lastupdate: string;
36
+ output_srs: string;
37
+ }
38
+ interface OsPlacesQueryResult {
39
+ DPA?: OsPlacesDeliveryPointAddress;
40
+ LPI?: OsPlacesLandPropertyIdentifier;
41
+ }
42
+ interface OsPlacesLandPropertyIdentifier {
43
+ UPRN: number;
44
+ ADDRESS: string;
45
+ USRN: number;
46
+ LPI_KEY: string;
47
+ ORGANISATION: string;
48
+ SAO_START_NUMBER: number;
49
+ SAO_START_SUFFIX: string;
50
+ SAO_END_NUMBER: number;
51
+ SAO_END_SUFFIX: string;
52
+ SAO_TEXT: string;
53
+ PAO_START_NUMBER: number;
54
+ PAO_START_SUFFIX: string;
55
+ PAO_END_NUMBER: number;
56
+ PAO_END_SUFFIX: string;
57
+ PAO_TEXT: string;
58
+ STREET_DESCRIPTION: string;
59
+ LOCALITY_NAME: string;
60
+ TOWN_NAME: string;
61
+ ADMINISTRATIVE_AREA: string;
62
+ AREA_NAME: string;
63
+ POSTCODE_LOCATOR: string;
64
+ RPC: string;
65
+ X_COORDINATE: number;
66
+ Y_COORDINATE: number;
67
+ LNG: number;
68
+ LAT: number;
69
+ STATUS: string;
70
+ LOGICAL_STATUS_CODE: number;
71
+ CLASSIFICATION_CODE: string;
72
+ CLASSIFICATION_CODE_DESCRIPTION: string;
73
+ LOCAL_CUSTODIAN_CODE: number;
74
+ LOCAL_CUSTODIAN_CODE_DESCRIPTION: string;
75
+ COUNTRY_CODE: string;
76
+ COUNTRY_CODE_DESCRIPTION: string;
77
+ POSTAL_ADDRESS_CODE: string;
78
+ POSTAL_ADDRESS_CODE_DESCRIPTION: string;
79
+ BLPU_STATE_CODE: number;
80
+ BLPU_STATE_CODE_DESCRIPTION: string;
81
+ TOPOGRAPHY_LAYER_TOID: string;
82
+ WARD_CODE: string;
83
+ PARISH_CODE: string;
84
+ PARENT_UPRN: number;
85
+ LAST_UPDATE_DATE: string;
86
+ ENTRY_DATE: string;
87
+ LEGAL_NAME: string;
88
+ BLPU_STATE_DATE: string;
89
+ STREET_STATE_CODE: number;
90
+ STREET_STATE_CODE_DESCRIPTION: string;
91
+ STREET_CLASSIFICATION_CODE: string;
92
+ STREET_CLASSIFICATION_CODE_DESCRIPTION: string;
93
+ LPI_LOGICAL_STATUS_CODE: number;
94
+ LPI_LOGICAL_STATUS_CODE_DESCRIPTION: string;
95
+ LANGUAGE: string;
96
+ MATCH: number;
97
+ MATCH_DESCRIPTION: string;
98
+ }
99
+ interface OsPlacesDeliveryPointAddress {
100
+ UPRN: number;
101
+ UDPRN: number;
102
+ ADDRESS: string;
103
+ ORGANISATION_NAME: string;
104
+ DEPARTMENT_NAME: string;
105
+ SUB_BUILDING_NAME: string;
106
+ BUILDING_NAME: string;
107
+ BUILDING_NUMBER: number;
108
+ DEPENDENT_THOROUGHFARE_NAME: string;
109
+ THOROUGHFARE_NAME: string;
110
+ DOUBLE_DEPENDENT_LOCALITY: string;
111
+ DEPENDENT_LOCALITY: string;
112
+ POST_TOWN: string;
113
+ POSTCODE: string;
114
+ RPC: string;
115
+ X_COORDINATE: number;
116
+ Y_COORDINATE: number;
117
+ LNG: number;
118
+ LAT: number;
119
+ STATUS: string;
120
+ LOGICAL_STATUS_CODE: number;
121
+ CLASSIFICATION_CODE: string;
122
+ CLASSIFICATION_CODE_DESCRIPTION: string;
123
+ LOCAL_CUSTODIAN_CODE: number;
124
+ LOCAL_CUSTODIAN_CODE_DESCRIPTION: string;
125
+ COUNTRY_CODE: string;
126
+ COUNTRY_CODE_DESCRIPTION: string;
127
+ POSTAL_ADDRESS_CODE: string;
128
+ POSTAL_ADDRESS_CODE_DESCRIPTION: string;
129
+ BLPU_STATE_CODE: number;
130
+ BLPU_STATE_CODE_DESCRIPTION: string;
131
+ TOPOGRAPHY_LAYER_TOID: string;
132
+ WARD_CODE: string;
133
+ PARISH_CODE: string;
134
+ PARENT_UPRN: number;
135
+ LAST_UPDATE_DATE: string;
136
+ ENTRY_DATE: string;
137
+ LEGAL_NAME: string;
138
+ BLPU_STATE_DATE: string;
139
+ LANGUAGE: string;
140
+ MATCH: number;
141
+ MATCH_DESCRIPTION: string;
142
+ DELIVERY_POINT_SUFFIX: string;
143
+ }
144
+
145
+ declare class OsPlacesApiClient {
146
+ private readonly logger;
147
+ private readonly config;
148
+ constructor(logger: ConnectDpsComponentLogger, config: ApiConfig & {
149
+ apiKey: string;
150
+ });
151
+ getAddressesByFreeTextQuery(freeTextQuery: string): Promise<OsPlacesQueryResponse>;
152
+ getAddressesByUprn(uprn: string): Promise<OsPlacesQueryResponse>;
153
+ get<T>(path: string, query: Record<string, string>): Promise<T>;
154
+ }
155
+
156
+ declare class OsPlacesAddressService {
157
+ private readonly logger;
158
+ private readonly osPlacesApiClient;
159
+ constructor(logger: ConnectDpsComponentLogger, osPlacesApiClient: OsPlacesApiClient);
160
+ getAddressesMatchingQuery(searchQuery: string, sanitisePostcode?: boolean): Promise<OsAddress[]>;
161
+ getAddressByUprn(uprn: string): Promise<OsAddress | null>;
162
+ sanitiseUkPostcode(stringContainingPostcode: string): string;
163
+ private handleResponse;
164
+ private toOsAddress;
165
+ private formatAddressString;
166
+ }
167
+
168
+ type Alert = BasicAlert | PrisonApiAlert | AlertsServiceAlert;
169
+ interface BasicAlert {
170
+ alertType: string;
171
+ alertCode: string;
172
+ active: boolean;
173
+ expired: boolean;
174
+ }
175
+ interface PrisonApiAlert {
176
+ alertId: string;
177
+ alertType: string;
178
+ alertTypeDescription: string;
179
+ alertCode: string;
180
+ alertCodeDescription: string;
181
+ comment?: string;
182
+ dateCreated: string;
183
+ modifiedDateTime?: string;
184
+ dateExpires?: string;
185
+ expired: boolean;
186
+ active: boolean;
187
+ addedByFirstName?: string;
188
+ addedByLastName?: string;
189
+ addedByFullName?: string;
190
+ expiredByFirstName?: string;
191
+ expiredByLastName?: string;
192
+ expiredByFullName?: string;
193
+ }
194
+ interface AlertsServiceAlert {
195
+ alertUuid?: string;
196
+ prisonNumber?: string;
197
+ alertCode: {
198
+ alertTypeCode: string;
199
+ alertTypeDescription: string;
200
+ code: string;
201
+ description: string;
4
202
  };
5
- };
6
- export default _default;
203
+ description: string;
204
+ authorisedBy?: string;
205
+ activeFrom: string;
206
+ activeTo?: string;
207
+ isActive: boolean;
208
+ comments?: [
209
+ {
210
+ commentUuid: string;
211
+ comment: string;
212
+ createdAt: string;
213
+ createdBy: string;
214
+ createdByDisplayName: string;
215
+ }
216
+ ];
217
+ createdAt?: string;
218
+ createdBy?: string;
219
+ createdByDisplayName: string;
220
+ lastModifiedAt?: string;
221
+ lastModifiedBy?: string;
222
+ lastModifiedByDisplayName?: string;
223
+ activeToLastSetAt?: string;
224
+ activeToLastSetBy?: string;
225
+ activeToLastSetByDisplayName?: string;
226
+ }
227
+
228
+ interface AlertFlagLabel {
229
+ alertCodes: string[];
230
+ classes: string;
231
+ label: string;
232
+ alertIds?: string[];
233
+ }
234
+
235
+ declare function getAlertFlagLabelsForAlerts(prisonerAlerts: Alert[]): AlertFlagLabel[];
236
+
237
+ export { OsPlacesAddressService, OsPlacesApiClient, getAlertFlagLabelsForAlerts };
238
+ export type { Alert, AlertFlagLabel, AlertsServiceAlert, BasicAlert, ConnectDpsComponentLogger, OsAddress, OsPlacesDeliveryPointAddress, OsPlacesLandPropertyIdentifier, OsPlacesQueryResponse, OsPlacesQueryResult, OsPlacesResponseHeader, PrisonApiAlert };