@justair/justair-library 4.15.0-alpha.d287cce → 5.0.0-alpha.56f07df

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/dist/index.d.ts CHANGED
@@ -43,6 +43,7 @@ import { eventsAuditSchema } from "./models/events.js";
43
43
  import { MonitorAudit } from "./models/monitors.js";
44
44
  import { monitorAuditSchema } from "./models/monitors.js";
45
45
  import { parametersEnum } from "./models/monitors.js";
46
+ import { legacyParametersEnum } from "./models/monitors.js";
46
47
  import { deploymentTypesEnum } from "./models/monitors.js";
47
48
  import { AlertsAudit } from "./models/alerts.js";
48
49
  import { Alerts } from "./models/alerts.js";
@@ -66,5 +67,7 @@ import { Samples } from "./models/samples.js";
66
67
  import { samplesAuditSchema } from "./models/samples.js";
67
68
  import { SamplesAudit } from "./models/samples.js";
68
69
  import { sampleParameterReferenceConcentrations } from "./models/samples.js";
69
- export { Database, adminSchema, Admin, configurationsSchema, Configurations, measurementsSchema, Measurements, monitorRequestsSchema, MonitorRequests, monitorsSchema, Monitors, organizationsSchema, Organizations, usersSchema, Users, eventsSchema, Events, lightMonitorSchema, LightMonitors, monitorSuppliersSchema, MonitorSuppliers, contextsSchema, Contexts, parametersSchema, Parameters, announcementSchema, Announcements, jobsSchema, Jobs, apiKeySchema, ApiKey, UsageMetrics, usageMetricsSchema, Audit, auditSchema, EventsAudit, eventsAuditSchema, MonitorAudit, monitorAuditSchema, parametersEnum, deploymentTypesEnum, AlertsAudit, Alerts, alertsSchema, alertsAuditSchema, Features, featuresSchema, dataCompletenessSchema, DataCompleteness, networkMetricsSchema, NetworkMetrics, rateOfChangeSchema, RateOfChange, sampleSitesSchema, SampleSites, sampleSiteAuditSchema, SampleSiteAudit, sampleParametersEnum, samplesSchema, Samples, samplesAuditSchema, SamplesAudit, sampleParameterReferenceConcentrations };
70
+ import { PARAMETERS } from "./constants/pollutants.js";
71
+ import { HEAVY_METALS } from "./constants/pollutants.js";
72
+ export { Database, adminSchema, Admin, configurationsSchema, Configurations, measurementsSchema, Measurements, monitorRequestsSchema, MonitorRequests, monitorsSchema, Monitors, organizationsSchema, Organizations, usersSchema, Users, eventsSchema, Events, lightMonitorSchema, LightMonitors, monitorSuppliersSchema, MonitorSuppliers, contextsSchema, Contexts, parametersSchema, Parameters, announcementSchema, Announcements, jobsSchema, Jobs, apiKeySchema, ApiKey, UsageMetrics, usageMetricsSchema, Audit, auditSchema, EventsAudit, eventsAuditSchema, MonitorAudit, monitorAuditSchema, parametersEnum, legacyParametersEnum, deploymentTypesEnum, AlertsAudit, Alerts, alertsSchema, alertsAuditSchema, Features, featuresSchema, dataCompletenessSchema, DataCompleteness, networkMetricsSchema, NetworkMetrics, rateOfChangeSchema, RateOfChange, sampleSitesSchema, SampleSites, sampleSiteAuditSchema, SampleSiteAudit, sampleParametersEnum, samplesSchema, Samples, samplesAuditSchema, SamplesAudit, sampleParameterReferenceConcentrations, PARAMETERS, HEAVY_METALS };
70
73
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AA4EA;;;iBAEC;yBAtBwB,oBAAoB;qBADxB,gBAAgB;4BAvDF,mBAAmB;sBAAnB,mBAAmB;qCAI/C,4BAA4B;+BAA5B,4BAA4B;mCAM5B,0BAA0B;6BAA1B,0BAA0B;sCAI1B,6BAA6B;gCAA7B,6BAA6B;+BAQ7B,sBAAsB;yBAAtB,sBAAsB;oCACsB,2BAA2B;8BAA3B,2BAA2B;4BAQ3C,mBAAmB;sBAAnB,mBAAmB;6BAM/C,oBAAoB;uBAApB,oBAAoB;mCAbuB,2BAA2B;8BAA3B,2BAA2B;uCAItE,8BAA8B;iCAA9B,8BAA8B;+BACI,sBAAsB;yBAAtB,sBAAsB;iCAClB,wBAAwB;2BAAxB,wBAAwB;mCAQnB,2BAA2B;8BAA3B,2BAA2B;2BAC5C,kBAAkB;qBAAlB,kBAAkB;6BACd,oBAAoB;uBAApB,oBAAoB;6BACR,0BAA0B;mCAA1B,0BAA0B;sBA/BpE,0BAA0B;4BAA1B,0BAA0B;4BA2B1B,oBAAoB;kCAApB,oBAAoB;6BAfpB,sBAAsB;mCAAtB,sBAAsB;+BAAtB,sBAAsB;oCAAtB,sBAAsB;4BAyBtB,oBAAoB;uBAApB,oBAAoB;6BAApB,oBAAoB;kCAApB,oBAAoB;yBACc,sBAAsB;+BAAtB,sBAAsB;uCAIxD,8BAA8B;iCAA9B,8BAA8B;qCACgB,4BAA4B;+BAA5B,4BAA4B;mCAChC,0BAA0B;6BAA1B,0BAA0B;kCAWpE,yBAAyB;4BAAzB,yBAAyB;sCAAzB,yBAAyB;gCAAzB,yBAAyB;qCAAzB,yBAAyB;8BASzB,qBAAqB;wBAArB,qBAAqB;mCAArB,qBAAqB;6BAArB,qBAAqB;uDAArB,qBAAqB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AA8EA;;;iBAEC;yBAvBwB,oBAAoB;qBADxB,gBAAgB;4BAxDF,mBAAmB;sBAAnB,mBAAmB;qCAI/C,4BAA4B;+BAA5B,4BAA4B;mCAM5B,0BAA0B;6BAA1B,0BAA0B;sCAI1B,6BAA6B;gCAA7B,6BAA6B;+BAS7B,sBAAsB;yBAAtB,sBAAsB;oCACsB,2BAA2B;8BAA3B,2BAA2B;4BAQ3C,mBAAmB;sBAAnB,mBAAmB;6BAM/C,oBAAoB;uBAApB,oBAAoB;mCAbuB,2BAA2B;8BAA3B,2BAA2B;uCAItE,8BAA8B;iCAA9B,8BAA8B;+BACI,sBAAsB;yBAAtB,sBAAsB;iCAClB,wBAAwB;2BAAxB,wBAAwB;mCAQnB,2BAA2B;8BAA3B,2BAA2B;2BAC5C,kBAAkB;qBAAlB,kBAAkB;6BACd,oBAAoB;uBAApB,oBAAoB;6BACR,0BAA0B;mCAA1B,0BAA0B;sBAhCpE,0BAA0B;4BAA1B,0BAA0B;4BA4B1B,oBAAoB;kCAApB,oBAAoB;6BAfpB,sBAAsB;mCAAtB,sBAAsB;+BAAtB,sBAAsB;qCAAtB,sBAAsB;oCAAtB,sBAAsB;4BAyBtB,oBAAoB;uBAApB,oBAAoB;6BAApB,oBAAoB;kCAApB,oBAAoB;yBACc,sBAAsB;+BAAtB,sBAAsB;uCAIxD,8BAA8B;iCAA9B,8BAA8B;qCACgB,4BAA4B;+BAA5B,4BAA4B;mCAChC,0BAA0B;6BAA1B,0BAA0B;kCAYpE,yBAAyB;4BAAzB,yBAAyB;sCAAzB,yBAAyB;gCAAzB,yBAAyB;qCAAzB,yBAAyB;8BASzB,qBAAqB;wBAArB,qBAAqB;mCAArB,qBAAqB;6BAArB,qBAAqB;uDAArB,qBAAqB;2BAlBa,2BAA2B;6BAA3B,2BAA2B"}
@@ -3,6 +3,7 @@ export const Monitors: any;
3
3
  export const monitorAuditSchema: any;
4
4
  export const MonitorAudit: any;
5
5
  export const parametersEnum: string[];
6
+ export const legacyParametersEnum: string[];
6
7
  export namespace deploymentTypesEnum {
7
8
  let STATIONARY: string;
8
9
  let MOBILE: string;
@@ -1 +1 @@
1
- {"version":3,"file":"monitors.d.ts","sourceRoot":"","sources":["../../src/models/monitors.js"],"names":[],"mappings":"AAiLA,iCA0HE;AA6IF,2BAA4D;AAzS5D,qCA4BE;AAGF,+BAAwE;AA7KxE,sCAsBE"}
1
+ {"version":3,"file":"monitors.d.ts","sourceRoot":"","sources":["../../src/models/monitors.js"],"names":[],"mappings":"AAgKA,iCA0HE;AA6IF,2BAA4D;AAzS5D,qCA4BE;AAGF,+BAAwE;AAvJxE,sCAA6E;AAF7E,4CAA+F"}
@@ -1 +1 @@
1
- {"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../src/models/organizations.js"],"names":[],"mappings":"AAyFA,sCAsBE;AAyDF,gCAA2E"}
1
+ {"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../src/models/organizations.js"],"names":[],"mappings":"AAoGA,sCAsBE;AAyDF,gCAA2E"}
@@ -3,16 +3,7 @@ export const SampleSites: any;
3
3
  export const sampleSiteAuditSchema: any;
4
4
  export const SampleSiteAudit: any;
5
5
  export const sampleParametersEnum: string[];
6
- export namespace sampleParameterReferenceConcentrations {
7
- let C6H6: number;
8
- let PB: number;
9
- let AS: number;
10
- let CD: number;
11
- let CR: number;
12
- let NI: any;
13
- let BA: any;
14
- let FE: any;
15
- let CU: any;
16
- let ZN: any;
17
- }
6
+ export const sampleParameterReferenceConcentrations: {
7
+ [k: string]: any;
8
+ };
18
9
  //# sourceMappingURL=sampleSites.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sampleSites.d.ts","sourceRoot":"","sources":["../../src/models/sampleSites.js"],"names":[],"mappings":"AA8EA,oCAmDE;AA2JF,8BAAqE;AApOrE,wCAgBE;AAGF,kCAAiF;AAvEjF,4CAWE"}
1
+ {"version":3,"file":"sampleSites.d.ts","sourceRoot":"","sources":["../../src/models/sampleSites.js"],"names":[],"mappings":"AA4DA,oCAmDE;AA2JF,8BAAqE;AApOrE,wCAgBE;AAGF,kCAAiF;AAnDjF,4CAAuD;AAIvD;;EAEE"}
@@ -2,16 +2,7 @@ export const samplesSchema: any;
2
2
  export const Samples: any;
3
3
  export const SamplesAudit: any;
4
4
  export const samplesAuditSchema: any;
5
- export namespace sampleParameterReferenceConcentrations {
6
- let C6H6: number;
7
- let PB: number;
8
- let AS: number;
9
- let CD: number;
10
- let CR: number;
11
- let NI: any;
12
- let BA: any;
13
- let FE: any;
14
- let CU: any;
15
- let ZN: any;
16
- }
5
+ export const sampleParameterReferenceConcentrations: {
6
+ [k: string]: any;
7
+ };
17
8
  //# sourceMappingURL=samples.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"samples.d.ts","sourceRoot":"","sources":["../../src/models/samples.js"],"names":[],"mappings":"AA6CA,gCAkBE;AAoIF,0BAAyD;AAzJzD,+BAAwE;AAvBxE,qCAoBE"}
1
+ {"version":3,"file":"samples.d.ts","sourceRoot":"","sources":["../../src/models/samples.js"],"names":[],"mappings":"AAoCA,gCAkBE;AAoIF,0BAAyD;AAzJzD,+BAAwE;AAvBxE,qCAoBE;AAzBF;;EAEE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=enums.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enums.test.d.ts","sourceRoot":"","sources":["../../../src/models/tests/enums.test.js"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,12 +1,22 @@
1
1
  {
2
2
  "name": "@justair/justair-library",
3
- "version": "4.15.0-alpha.d287cce",
3
+ "version": "5.0.0-alpha.56f07df",
4
4
  "description": "JustAir Internal Library",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
7
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./src/index.js"
12
+ },
13
+ "./constants": {
14
+ "types": "./dist/constants/pollutants.d.ts",
15
+ "default": "./src/constants/pollutants.js"
16
+ }
17
+ },
8
18
  "scripts": {
9
- "test": "echo \"Error: no test specified\" && exit 1",
19
+ "test": "node --experimental-vm-modules node_modules/.bin/jest",
10
20
  "build": "tsc",
11
21
  "prepublish": "npm run build"
12
22
  },
@@ -20,8 +30,15 @@
20
30
  "nanoid": "^5.1.6",
21
31
  "winston": "^3.10.0"
22
32
  },
33
+ "jest": {
34
+ "testEnvironment": "node",
35
+ "transform": {}
36
+ },
23
37
  "devDependencies": {
38
+ "@jest/globals": "^29",
24
39
  "@types/node": "^16.0.0",
40
+ "jest": "^29",
41
+ "jest-environment-node": "^29",
25
42
  "ts-node": "^10.0.0",
26
43
  "typescript": "^5.3.2"
27
44
  }
@@ -0,0 +1,350 @@
1
+ // Parameters measured by air quality sensors in real time.
2
+ // These correspond to the values stored in Monitors.parameters and used across the platform.
3
+ export const PARAMETERS = {
4
+ PM1: {
5
+ id: "PM1",
6
+ label: "PM₁",
7
+ name: "Particulate Matter 1 (PM₁)",
8
+ unit: "µg/m³",
9
+ type: "Particulate Matter",
10
+ rfc: null,
11
+ origin: null,
12
+ impacts: null,
13
+ },
14
+ PM2_5: {
15
+ id: "PM2_5",
16
+ label: "PM₂.₅",
17
+ name: "Particulate Matter 2.5 (PM₂.₅)",
18
+ unit: "µg/m³",
19
+ type: "Particulate Matter",
20
+ rfc: null,
21
+ origin: "Tiny particles that can penetrate deep into lungs and bloodstream, originating from vehicle emissions, industrial processes, and wildfires.",
22
+ impacts: "Can cause respiratory and cardiovascular illnesses, exacerbate asthma, and increase mortality risk with prolonged exposure.",
23
+ },
24
+ PM10: {
25
+ id: "PM10",
26
+ label: "PM₁₀",
27
+ name: "Particulate Matter 10 (PM₁₀)",
28
+ unit: "µg/m³",
29
+ type: "Particulate Matter",
30
+ rfc: null,
31
+ origin: "Larger particles including dust, dirt, soot, and smoke from various sources like construction and natural activities.",
32
+ impacts: "Can worsen respiratory diseases including asthma and COPD, particularly with short-term exposure.",
33
+ },
34
+ BC: {
35
+ id: "BC",
36
+ label: "Black Carbon",
37
+ name: "Total Black Carbon (BC)",
38
+ unit: "ng/m³",
39
+ type: "Particulate Matter",
40
+ rfc: null,
41
+ origin: null,
42
+ impacts: null,
43
+ },
44
+ BRC: {
45
+ id: "BRC",
46
+ label: "Brown Carbon",
47
+ name: "Total Brown Carbon (BrC)",
48
+ unit: "ng/m³",
49
+ type: "Particulate Matter",
50
+ rfc: null,
51
+ origin: null,
52
+ impacts: null,
53
+ },
54
+ UFP: {
55
+ id: "UFP",
56
+ label: "Ultra Fine Particles",
57
+ name: "Ultra Fine Particles (UFP)",
58
+ unit: "pt/cm³",
59
+ type: "Particulate Matter",
60
+ rfc: null,
61
+ origin: null,
62
+ impacts: null,
63
+ },
64
+ O3: {
65
+ id: "O3",
66
+ label: "O₃",
67
+ name: "Ozone (O₃)",
68
+ unit: "ppm",
69
+ type: "Gas",
70
+ rfc: null,
71
+ origin: "Harmful smog component formed when pollution reacts with sunlight, especially problematic on hot, sunny days.",
72
+ impacts: "Can irritate lungs, intensify asthma and chronic bronchitis, and increase heart problems and mortality rates.",
73
+ },
74
+ NO: {
75
+ id: "NO",
76
+ label: "NO",
77
+ name: "Nitric Oxide (NO)",
78
+ unit: "ppb",
79
+ type: "Gas",
80
+ rfc: null,
81
+ origin: null,
82
+ impacts: null,
83
+ },
84
+ NO2: {
85
+ id: "NO2",
86
+ label: "NO₂",
87
+ name: "Nitrogen Dioxide (NO₂)",
88
+ unit: "ppb",
89
+ type: "Gas",
90
+ rfc: null,
91
+ origin: "Harmful gas from cars, power plants, and industrial equipment that contributes to smog and acid rain.",
92
+ impacts: "Can cause respiratory problems, worsen asthma and bronchitis, and increase heart-related health risks.",
93
+ },
94
+ SO2: {
95
+ id: "SO2",
96
+ label: "SO₂",
97
+ name: "Sulfur Dioxide (SO₂)",
98
+ unit: "ppb",
99
+ type: "Gas",
100
+ rfc: null,
101
+ origin: null,
102
+ impacts: null,
103
+ },
104
+ CO: {
105
+ id: "CO",
106
+ label: "CO",
107
+ name: "Carbon Monoxide (CO)",
108
+ unit: "ppm",
109
+ type: "Gas",
110
+ rfc: null,
111
+ origin: null,
112
+ impacts: null,
113
+ },
114
+ CO2: {
115
+ id: "CO2",
116
+ label: "CO₂",
117
+ name: "Carbon Dioxide (CO₂)",
118
+ unit: "ppm",
119
+ type: "Gas",
120
+ rfc: null,
121
+ origin: null,
122
+ impacts: null,
123
+ },
124
+ CH4: {
125
+ id: "CH4",
126
+ label: "CH₄",
127
+ name: "Methane (CH₄)",
128
+ unit: "ppm",
129
+ type: "Volatile Organic Compound",
130
+ rfc: null,
131
+ origin: null,
132
+ impacts: null,
133
+ },
134
+ H2S: {
135
+ id: "H2S",
136
+ label: "H₂S",
137
+ name: "Hydrogen Sulfide (H₂S)",
138
+ unit: "ppm",
139
+ type: "Volatile Organic Compound",
140
+ rfc: null,
141
+ origin: null,
142
+ impacts: null,
143
+ },
144
+ VOC: {
145
+ id: "VOC",
146
+ label: "VOC",
147
+ name: "Volatile Organic Compounds (VOC)",
148
+ unit: "ppm",
149
+ type: "Volatile Organic Compound",
150
+ rfc: null,
151
+ origin: null,
152
+ impacts: null,
153
+ },
154
+ T: {
155
+ id: "T",
156
+ label: "Temperature",
157
+ name: "Temperature (T)",
158
+ unit: "°F",
159
+ type: "Weather",
160
+ rfc: null,
161
+ origin: null,
162
+ impacts: null,
163
+ },
164
+ RH: {
165
+ id: "RH",
166
+ label: "Humidity",
167
+ name: "Relative Humidity (RH)",
168
+ unit: "%",
169
+ type: "Weather",
170
+ rfc: null,
171
+ origin: null,
172
+ impacts: null,
173
+ },
174
+ DP: {
175
+ id: "DP",
176
+ label: "Dew Point",
177
+ name: "Dew Point (DP)",
178
+ unit: "°F",
179
+ type: "Weather",
180
+ rfc: null,
181
+ origin: null,
182
+ impacts: null,
183
+ },
184
+ WS: {
185
+ id: "WS",
186
+ label: "Wind Speed",
187
+ name: "Wind Speed (WS)",
188
+ unit: "mph",
189
+ type: "Weather",
190
+ rfc: null,
191
+ origin: null,
192
+ impacts: null,
193
+ },
194
+ WD: {
195
+ id: "WD",
196
+ label: "Wind Direction",
197
+ name: "Wind Direction (WD)",
198
+ unit: "°",
199
+ type: "Weather",
200
+ rfc: null,
201
+ origin: null,
202
+ impacts: null,
203
+ },
204
+ };
205
+
206
+ // Parameters analyzed from physical air samples in a laboratory.
207
+ // These correspond to SampleSites.parameters and are not measured by real-time sensors.
208
+ // Note: Cobalt uses the key COBALT (not CO) to avoid collision with PARAMETERS.CO (Carbon Monoxide).
209
+ export const HEAVY_METALS = {
210
+ C6H6: {
211
+ id: "C6H6",
212
+ label: "Benzene",
213
+ name: "Benzene (C₆H₆)",
214
+ unit: "ppb",
215
+ type: "Volatile Organic Compound",
216
+ rfc: 30,
217
+ origin: "Benzene is a gas released when coal, oil, and gasoline are burned. It's found in car exhaust, at gas stations, and anywhere fossil fuels are burned.",
218
+ impacts: "Breathing in benzene for a short time can cause dizziness, drowsiness, or headaches. It may irritate the eyes, skin, or breathing passages. In extreme cases with very high exposure, it can cause loss of consciousness. Regular exposure over a long period can harm the blood, reducing red blood cell count and potentially causing serious blood disorders.",
219
+ },
220
+ AS: {
221
+ id: "AS",
222
+ label: "Arsenic",
223
+ name: "Arsenic (As)",
224
+ unit: "µg/m³",
225
+ type: "Heavy Metal",
226
+ rfc: 0.03,
227
+ origin: "Arsenic is naturally in rocks and soil. It gets into the air through dust blown by wind, metal factories, pesticides, and can leak into groundwater.",
228
+ impacts: "Short-term exposure to high amounts can cause nausea, vomiting, problems with blood cells, irregular heartbeat, and tingling in the nerves. Long-term exposure may cause skin discoloration or thickening (especially on the palms and feet), damage blood vessels, and increase the risk of skin, liver, bladder, and lung cancers.",
229
+ },
230
+ BA: {
231
+ id: "BA",
232
+ label: "Barium",
233
+ name: "Barium (Ba)",
234
+ unit: "µg/m³",
235
+ type: "Heavy Metal",
236
+ rfc: null,
237
+ origin: "This metal comes from mining operations, industrial facilities, and burning coal and oil.",
238
+ impacts: "Breathing barium dust can irritate the nose, throat, and lungs. It may cause coughing, difficulty breathing, and temporary increases in blood pressure. Over many years of high exposure, barium can affect heart and kidney function.",
239
+ },
240
+ BE: {
241
+ id: "BE",
242
+ label: "Beryllium",
243
+ name: "Beryllium (Be)",
244
+ unit: "µg/m³",
245
+ type: "Heavy Metal",
246
+ rfc: 0.02,
247
+ origin: "Beryllium occurs naturally in rocks, soil, coal, and oil. It gets into the air through mining and industrial processing, burning coal or fuel oil, and tobacco smoke.",
248
+ impacts: "Short-term exposure to high levels can cause lung inflammation, coughing, and difficulty breathing. Long-term exposure can cause permanent lung scarring, reduced lung capacity, shortness of breath, and fatigue. It has also been linked to an increased risk of lung cancer.",
249
+ },
250
+ COBALT: {
251
+ id: "COBALT",
252
+ label: "Cobalt",
253
+ name: "Cobalt (Co)",
254
+ unit: "µg/m³",
255
+ type: "Heavy Metal",
256
+ rfc: null,
257
+ origin: "This metal is a naturally occurring metal found throughout the environment. It gets into the air through industrial processing, manufacturing of metal alloys and pigments, and burning of coal and fuel oil.",
258
+ impacts: "Short-term exposure to high levels can cause coughing, wheezing, and shortness of breath. Long-term exposure may lead to reduced lung function, asthma, and lung scarring. It can also affect the heart and cause skin or respiratory allergic reactions in some people. Some studies suggest a possible link to lung cancer with prolonged exposure.",
259
+ },
260
+ NI: {
261
+ id: "NI",
262
+ label: "Nickel",
263
+ name: "Nickel (Ni)",
264
+ unit: "µg/m³",
265
+ type: "Heavy Metal",
266
+ rfc: null,
267
+ origin: "Nickel occurs naturally in the earth's crust. It enters the air through oil and coal combustion, metal refining, manufacturing facilities, and sewage sludge incineration.",
268
+ impacts: "Breathing nickel over long periods can irritate the lungs, cause reduced lung function, and trigger asthma-like symptoms. Skin contact with nickel is the most common source of reactions, causing rash and itching on the hands and forearms. Long-term inhalation exposure to certain forms of nickel — particularly those found in refinery dust — has been linked to an increased risk of lung and nasal cancers.",
269
+ },
270
+ CD: {
271
+ id: "CD",
272
+ label: "Cadmium",
273
+ name: "Cadmium (Cd)",
274
+ unit: "µg/m³",
275
+ type: "Heavy Metal",
276
+ rfc: 0.01,
277
+ origin: "Cadmium is released when coal and oil are burned, waste is incinerated, or metals are processed. It's used in batteries, paints, metal coatings, and some plastics.",
278
+ impacts: "Breathing cadmium can irritate and damage the lungs immediately. Over time, cadmium builds up in the kidneys and can cause kidney damage and increase the likelihood of developing kidney stones. Some research shows it may increase lung cancer risk with long-term exposure.",
279
+ },
280
+ CR: {
281
+ id: "CR",
282
+ label: "Chromium",
283
+ name: "Chromium (Cr)",
284
+ unit: "µg/m³",
285
+ type: "Heavy Metal",
286
+ rfc: 0.1,
287
+ origin: "Chromium is naturally in rocks, soil, plants, and volcanic dust. Industries like steel making, metal plating, leather tanning, and improper waste disposal release it into the environment.",
288
+ impacts: "Certain forms of chromium can irritate the nose, throat, and lungs when inhaled. It can also cause skin rashes or irritation upon contact. Long-term exposure to high levels has been linked to respiratory problems and an increased risk of lung cancer.",
289
+ },
290
+ PB: {
291
+ id: "PB",
292
+ label: "Lead",
293
+ name: "Lead (Pb)",
294
+ unit: "µg/m³",
295
+ type: "Heavy Metal",
296
+ rfc: 0, // 0 = no safe level of exposure (not the same as null/unmeasured)
297
+ origin: "Lead comes from old paint containing lead, contaminated soil, water pipes made with lead, factory emissions, and from when leaded gasoline was used.",
298
+ impacts: "Lead is especially dangerous for children. Even small amounts can harm brain development, affecting learning, behavior, and growth. There is no safe level of lead exposure for children. For adults, long-term exposure can contribute to high blood pressure, kidney problems, and reproductive issues.",
299
+ },
300
+ FE: {
301
+ id: "FE",
302
+ label: "Iron",
303
+ name: "Iron (Fe)",
304
+ unit: "µg/m³",
305
+ type: "Heavy Metal - Essential Nutrient",
306
+ rfc: null,
307
+ origin: "Iron is naturally in soil, water, and dust. Airborne iron often comes from factories, construction sites, and wear on roads from vehicles.",
308
+ impacts: "The human body needs iron to function properly. However, breathing iron-rich dust over long periods can cause coughing or lung irritation. Consuming too much iron can cause stomach problems, vomiting, and in severe cases, organ damage.",
309
+ },
310
+ MN: {
311
+ id: "MN",
312
+ label: "Manganese",
313
+ name: "Manganese (Mn)",
314
+ unit: "µg/m³",
315
+ type: "Heavy Metal - Essential Nutrient",
316
+ rfc: 0.05,
317
+ origin: "Manganese occurs naturally in rocks, soil, and water. It enters the air through steel and iron production, mining operations, power plants, and coke ovens.",
318
+ impacts: "Manganese is an essential nutrient at low levels, but breathing elevated concentrations over time can affect the nervous system. Long-term exposure may slow reaction time, reduce hand steadiness, and impair coordination. At higher levels, it can cause tremors, difficulty walking, muscle stiffness, and mood or behavioral changes. Prolonged exposure may also lead to coughing and bronchitis.",
319
+ },
320
+ SE: {
321
+ id: "SE",
322
+ label: "Selenium",
323
+ name: "Selenium (Se)",
324
+ unit: "µg/m³",
325
+ type: "Heavy Metal - Essential Nutrient",
326
+ rfc: null,
327
+ origin: "Selenium occurs naturally in rocks, soil, and water. It enters the air through metal industries, mining, and selenium-recovery processes. Food and drinking water are the most common sources of everyday exposure.",
328
+ impacts: "Selenium is an essential nutrient at low levels, but exposure to elevated concentrations can be harmful. Breathing selenium dust or compounds can irritate the nose, throat, and lungs, causing coughing, nosebleeds, and difficulty breathing. Long-term exposure to high levels through food or water has been associated with skin discoloration, hair and nail loss, tooth decay, and reduced mental alertness.",
329
+ },
330
+ CU: {
331
+ id: "CU",
332
+ label: "Copper",
333
+ name: "Copper (Cu)",
334
+ unit: "µg/m³",
335
+ type: "Heavy Metal - Essential Nutrient",
336
+ rfc: null,
337
+ origin: "Copper occurs naturally in soil and water. Mining, factories, and burning waste release it into the air.",
338
+ impacts: "Breathing copper dust or fumes can irritate the nose, throat, and lungs, causing coughing or temporary flu-like symptoms. Long-term exposure to high airborne copper levels may lead to ongoing respiratory irritation and sometimes liver or kidney effects.",
339
+ },
340
+ ZN: {
341
+ id: "ZN",
342
+ label: "Zinc",
343
+ name: "Zinc (Zn)",
344
+ unit: "µg/m³",
345
+ type: "Heavy Metal - Essential Nutrient",
346
+ rfc: null,
347
+ origin: "Zinc is common in soil, water, and air. It's released from metal production, waste burning, and wear from vehicle tires and brakes.",
348
+ impacts: "The body needs zinc, but breathing high levels of zinc dust or fumes can irritate the throat and lungs. Consuming too much zinc over long periods can cause nausea, interfere with copper absorption in the body, and disrupt immune function.",
349
+ },
350
+ };
@@ -0,0 +1,80 @@
1
+ import { PARAMETERS, HEAVY_METALS } from "../pollutants.js";
2
+
3
+ const REQUIRED_FIELDS = ["id", "label", "name", "unit", "type"];
4
+ const VALID_TYPES = [
5
+ "Particulate Matter",
6
+ "Gas",
7
+ "Volatile Organic Compound",
8
+ "Weather",
9
+ "Heavy Metal",
10
+ "Heavy Metal - Essential Nutrient",
11
+ ];
12
+
13
+ function sharedAssertions(constants) {
14
+ const entries = Object.entries(constants);
15
+
16
+ test("has no duplicate ids", () => {
17
+ const ids = Object.values(constants).map((p) => p.id);
18
+ expect(new Set(ids).size).toBe(ids.length);
19
+ });
20
+
21
+ test.each(entries)("%s: key matches id", (key, pollutant) => {
22
+ expect(key).toBe(pollutant.id);
23
+ });
24
+
25
+ test.each(entries)("%s: has all required fields", (key, pollutant) => {
26
+ for (const field of REQUIRED_FIELDS) {
27
+ expect(pollutant).toHaveProperty(field);
28
+ }
29
+ });
30
+
31
+ test.each(entries)("%s: id is a non-empty string with no dots or spaces", (key, pollutant) => {
32
+ expect(typeof pollutant.id).toBe("string");
33
+ expect(pollutant.id.length).toBeGreaterThan(0);
34
+ expect(pollutant.id).not.toContain(".");
35
+ expect(pollutant.id).not.toContain(" ");
36
+ });
37
+
38
+ test.each(entries)("%s: label is a non-empty string", (key, pollutant) => {
39
+ expect(typeof pollutant.label).toBe("string");
40
+ expect(pollutant.label.length).toBeGreaterThan(0);
41
+ });
42
+
43
+ test.each(entries)("%s: name is a non-empty string", (key, pollutant) => {
44
+ expect(typeof pollutant.name).toBe("string");
45
+ expect(pollutant.name.length).toBeGreaterThan(0);
46
+ });
47
+
48
+ test.each(entries)("%s: unit is a non-empty string", (key, pollutant) => {
49
+ expect(typeof pollutant.unit).toBe("string");
50
+ expect(pollutant.unit.length).toBeGreaterThan(0);
51
+ });
52
+
53
+ test.each(entries)("%s: type is a recognized value", (key, pollutant) => {
54
+ expect(VALID_TYPES).toContain(pollutant.type);
55
+ });
56
+
57
+ test.each(entries)("%s: rfc is a number or null", (key, pollutant) => {
58
+ expect(pollutant.rfc === null || typeof pollutant.rfc === "number").toBe(true);
59
+ });
60
+
61
+ test.each(entries)("%s: origin is a string or null", (key, pollutant) => {
62
+ expect(pollutant.origin === null || typeof pollutant.origin === "string").toBe(true);
63
+ });
64
+
65
+ test.each(entries)("%s: impacts is a string or null", (key, pollutant) => {
66
+ expect(pollutant.impacts === null || typeof pollutant.impacts === "string").toBe(true);
67
+ });
68
+ }
69
+
70
+ describe("PARAMETERS", () => {
71
+ sharedAssertions(PARAMETERS);
72
+ });
73
+
74
+ describe("HEAVY_METALS", () => {
75
+ sharedAssertions(HEAVY_METALS);
76
+
77
+ test("PB.rfc is exactly 0, not null", () => {
78
+ expect(HEAVY_METALS.PB.rfc).toBe(0);
79
+ });
80
+ });
package/src/index.js CHANGED
@@ -19,6 +19,7 @@ import {
19
19
  monitorAuditSchema,
20
20
  MonitorAudit,
21
21
  parametersEnum,
22
+ legacyParametersEnum,
22
23
  deploymentTypesEnum,
23
24
  } from "./models/monitors.js";
24
25
  import { organizationsSchema, Organizations } from "./models/organizations.js";
@@ -55,6 +56,7 @@ import { NetworkMetrics, networkMetricsSchema } from "./models/networkMetrics.js
55
56
  import { RateOfChange, rateOfChangeSchema } from "./models/rateOfChange.js";
56
57
  import Database from "./config/db.js"; // Import the new Database class
57
58
  import CustomLogger from "./config/logger.js";
59
+ import { PARAMETERS, HEAVY_METALS } from "./constants/pollutants.js";
58
60
 
59
61
  // SampleSites related imports
60
62
  import {
@@ -119,6 +121,7 @@ export {
119
121
  MonitorAudit,
120
122
  monitorAuditSchema,
121
123
  parametersEnum,
124
+ legacyParametersEnum,
122
125
  deploymentTypesEnum,
123
126
  AlertsAudit,
124
127
  Alerts,
@@ -144,4 +147,7 @@ export {
144
147
  samplesAuditSchema,
145
148
  SamplesAudit,
146
149
  sampleParameterReferenceConcentrations,
150
+ // Pollutant constants
151
+ PARAMETERS,
152
+ HEAVY_METALS,
147
153
  };
@@ -1,27 +1,10 @@
1
1
  import mongoose from "mongoose";
2
- const parametersEnum = [
3
- "NO2",
4
- "SO2",
5
- "PM2.5",
6
- "PM2_5",
7
- "PM10",
8
- "Temperature",
9
- "Humidity",
10
- "OZONE",
11
- "O3",
12
- "VOC",
13
- "CO",
14
- "NO",
15
- "PM1",
16
- "WS",
17
- "WD",
18
- "WS And Direction",
19
- "DP",
20
- "CO2",
21
- "CH4",
22
- "H2S",
23
- "BC",
24
- ];
2
+ import { PARAMETERS } from "../constants/pollutants.js";
3
+
4
+ // Legacy values kept for backwards compatibility — remove after data migration
5
+ const legacyParametersEnum = ["PM2.5", "Temperature", "Humidity", "OZONE", "WS And Direction"];
6
+
7
+ const parametersEnum = [...Object.keys(PARAMETERS), ...legacyParametersEnum];
25
8
 
26
9
  const deploymentTypesEnum = {
27
10
  STATIONARY: "stationary",
@@ -440,4 +423,4 @@ monitorsSchema.pre("updateMany", async function () {
440
423
  // Create the Monitors model
441
424
  const Monitors = mongoose.model("Monitors", monitorsSchema);
442
425
 
443
- export { monitorsSchema, Monitors, monitorAuditSchema, MonitorAudit, parametersEnum, deploymentTypesEnum };
426
+ export { monitorsSchema, Monitors, monitorAuditSchema, MonitorAudit, parametersEnum, legacyParametersEnum, deploymentTypesEnum };