@welldot/core 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -19
- package/dist/index.cjs +344 -178
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9203 -5704
- package/dist/index.d.ts +9203 -5704
- package/dist/index.js +334 -178
- package/dist/index.js.map +1 -1
- package/docs/reference/fgdc-textures.md +15 -0
- package/docs/schema/v2/well.schema.json +128 -11
- package/docs/spec/v1/well-format.md +26 -0
- package/docs/spec/v2/format-reference.md +170 -45
- package/docs/spec/v2/interoperability.md +25 -4
- package/docs/spec/v2/object-schemas.md +243 -96
- package/docs/spec/v2/overview.md +92 -9
- package/docs/spec/v2/water-quality.md +26 -3
- package/examples/README.md +12 -0
- package/examples/belem-pa-condominio-outorga.well +2 -1
- package/examples/belem-pa-monitoramento-posto.well +2 -1
- package/examples/belem-pa-pirabas-abastecimento.well +2 -2
- package/examples/belem-pa-poco-colmatado.well +2 -1
- package/examples/belem-pa-poco-raso-abandonado.well +2 -1
- package/examples/belem-pa-qualidade-agua-acida.well +2 -1
- package/examples/colatina-es-gnaisse-rural.well +2 -2
- package/examples/coluna-mg-cristalino-abastecimento.well +2 -2
- package/examples/estrela-doeste-sp-bauru-serra-geral.well +2 -1
- package/examples/extremoz-rn-barreiras-raso.well +2 -1
- package/examples/gastao-vidigal-sp-dados-inconsistentes.well +2 -1
- package/examples/irece-ba-carste-bambui.well +2 -1
- package/examples/lagoa-santa-mg-carste-abastecimento.well +2 -2
- package/examples/minas-novas-mg-cadastro-incompleto.well +2 -1
- package/examples/quixeramobim-ce-cristalino-salobro.well +2 -2
- package/examples/rinopolis-sp-estratigrafico-guarani.well +2 -1
- package/examples/santarem-pa-jorrante-alter-do-chao.well +2 -1
- package/examples/sao-gabriel-rs-cacimba.well +2 -1
- package/examples/sete-lagoas-mg-carste-industrial.well +2 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,215 @@
|
|
|
1
1
|
// src/validators/well.validators.ts
|
|
2
2
|
import { createDefu } from "defu";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
// src/utils/timezone.utils.ts
|
|
6
|
+
var IANA_SHAPE = /^[A-Za-z][A-Za-z0-9_+\-/]*$/;
|
|
7
|
+
function isIanaTimeZone(value) {
|
|
8
|
+
if (!IANA_SHAPE.test(value)) return false;
|
|
9
|
+
try {
|
|
10
|
+
new Intl.DateTimeFormat("en-US", { timeZone: value });
|
|
11
|
+
return true;
|
|
12
|
+
} catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/utils/version.utils.ts
|
|
18
|
+
var WELL_FORMAT_VERSION = "2.4";
|
|
19
|
+
var VERSION_PATTERN = /^(\d+)\.(\d+)$/;
|
|
20
|
+
function parseFormatVersion(value) {
|
|
21
|
+
if (typeof value === "number") {
|
|
22
|
+
return Number.isInteger(value) && value >= 0 ? { major: value, minor: void 0 } : void 0;
|
|
23
|
+
}
|
|
24
|
+
if (typeof value === "string") {
|
|
25
|
+
const match = VERSION_PATTERN.exec(value);
|
|
26
|
+
if (match) return { major: Number(match[1]), minor: Number(match[2]) };
|
|
27
|
+
}
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
function compareFormatVersions(a, b) {
|
|
31
|
+
const pa = parseFormatVersion(a);
|
|
32
|
+
const pb = parseFormatVersion(b);
|
|
33
|
+
if (!pa || pb === void 0 || pa.minor === void 0 || pb.minor === void 0) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`Malformed .well format version: ${JSON.stringify(pa?.minor === void 0 ? a : b)}`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
return pa.major - pb.major || pa.minor - pb.minor;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/vocab/closed.vocab.ts
|
|
42
|
+
function closedVocab() {
|
|
43
|
+
return (entries) => entries;
|
|
44
|
+
}
|
|
45
|
+
var valuesOf = (vocab) => vocab.map((entry) => entry.value);
|
|
46
|
+
var WELL_STATUSES = closedVocab()([
|
|
47
|
+
{ value: "active", label: { en: "Active", pt: "Ativo" } },
|
|
48
|
+
{
|
|
49
|
+
value: "maintenance",
|
|
50
|
+
label: { en: "Under maintenance", pt: "Em manuten\xE7\xE3o" }
|
|
51
|
+
},
|
|
52
|
+
{ value: "inactive", label: { en: "Inactive", pt: "Paralisado" } },
|
|
53
|
+
{
|
|
54
|
+
value: "decommissioned",
|
|
55
|
+
label: { en: "Decommissioned", pt: "Desativado" }
|
|
56
|
+
},
|
|
57
|
+
{ value: "abandoned", label: { en: "Abandoned", pt: "Abandonado" } }
|
|
58
|
+
]);
|
|
59
|
+
var PERMIT_ADMINISTRATIVE_STATUSES = closedVocab()([
|
|
60
|
+
{ value: "requested", label: { en: "Requested", pt: "Requerida" } },
|
|
61
|
+
{ value: "granted", label: { en: "Granted", pt: "Concedida" } },
|
|
62
|
+
{ value: "suspended", label: { en: "Suspended", pt: "Suspensa" } },
|
|
63
|
+
{ value: "revoked", label: { en: "Revoked", pt: "Revogada" } },
|
|
64
|
+
{ value: "denied", label: { en: "Denied", pt: "Indeferida" } },
|
|
65
|
+
{ value: "withdrawn", label: { en: "Withdrawn", pt: "Cancelada" } }
|
|
66
|
+
]);
|
|
67
|
+
var VOLUME_LIMIT_PERIODS = closedVocab()([
|
|
68
|
+
{ value: "daily", label: { en: "Daily", pt: "Di\xE1rio" } },
|
|
69
|
+
{ value: "monthly", label: { en: "Monthly", pt: "Mensal" } },
|
|
70
|
+
{ value: "annual", label: { en: "Annual", pt: "Anual" } }
|
|
71
|
+
]);
|
|
72
|
+
var PRODUCTION_ENTRY_TYPES = closedVocab()([
|
|
73
|
+
{
|
|
74
|
+
value: "meter_reading",
|
|
75
|
+
label: { en: "Meter reading", pt: "Leitura de hidr\xF4metro" }
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
value: "estimated_volume",
|
|
79
|
+
label: { en: "Estimated volume", pt: "Volume estimado" }
|
|
80
|
+
}
|
|
81
|
+
]);
|
|
82
|
+
var RESULT_QUALIFIERS = closedVocab()([
|
|
83
|
+
{ value: "<", label: { en: "< less than", pt: "< menor que" } },
|
|
84
|
+
{ value: ">", label: { en: "> greater than", pt: "> maior que" } },
|
|
85
|
+
{ value: "not_detected", label: { en: "Not detected", pt: "N\xE3o detectado" } },
|
|
86
|
+
{ value: "estimated", label: { en: "Estimated", pt: "Estimado" } }
|
|
87
|
+
]);
|
|
88
|
+
var RESULT_FRACTIONS = closedVocab()([
|
|
89
|
+
{ value: "total", label: { en: "Total", pt: "Total" } },
|
|
90
|
+
{ value: "dissolved", label: { en: "Dissolved", pt: "Dissolvida" } },
|
|
91
|
+
{ value: "suspended", label: { en: "Suspended", pt: "Suspensa" } }
|
|
92
|
+
]);
|
|
93
|
+
var MEASUREMENT_LOCATIONS = closedVocab()([
|
|
94
|
+
{ value: "field", label: { en: "Field", pt: "Campo" } },
|
|
95
|
+
{ value: "lab", label: { en: "Lab", pt: "Laborat\xF3rio" } }
|
|
96
|
+
]);
|
|
97
|
+
var VALIDATION_STATUSES = closedVocab()([
|
|
98
|
+
{ value: "unvalidated", label: { en: "Unvalidated", pt: "N\xE3o validado" } },
|
|
99
|
+
{ value: "validated", label: { en: "Validated", pt: "Validado" } },
|
|
100
|
+
{ value: "qualified", label: { en: "Qualified", pt: "Qualificado" } },
|
|
101
|
+
{ value: "rejected", label: { en: "Rejected", pt: "Rejeitado" } }
|
|
102
|
+
]);
|
|
103
|
+
var PARAMETER_GROUPS = closedVocab()([
|
|
104
|
+
{
|
|
105
|
+
value: "physical",
|
|
106
|
+
label: { en: "Physical / field", pt: "F\xEDsico / campo" }
|
|
107
|
+
},
|
|
108
|
+
{ value: "aggregate", label: { en: "Aggregate", pt: "Agregados" } },
|
|
109
|
+
{ value: "major_ion", label: { en: "Major ions", pt: "\xCDons maiores" } },
|
|
110
|
+
{ value: "nutrient", label: { en: "Nutrients", pt: "Nutrientes" } },
|
|
111
|
+
{ value: "organic", label: { en: "Organic", pt: "Org\xE2nicos" } },
|
|
112
|
+
{ value: "disinfection", label: { en: "Disinfection", pt: "Desinfec\xE7\xE3o" } },
|
|
113
|
+
{
|
|
114
|
+
value: "mining_redox",
|
|
115
|
+
label: { en: "Mining and redox", pt: "Minera\xE7\xE3o e redox" }
|
|
116
|
+
},
|
|
117
|
+
{ value: "metal", label: { en: "Metals / trace", pt: "Metais / tra\xE7o" } },
|
|
118
|
+
{ value: "microbiology", label: { en: "Microbiology", pt: "Microbiologia" } },
|
|
119
|
+
{
|
|
120
|
+
value: "radioactivity",
|
|
121
|
+
label: { en: "Radioactivity", pt: "Radioatividade" }
|
|
122
|
+
}
|
|
123
|
+
]);
|
|
124
|
+
var BAROMETRIC_COMPENSATIONS = closedVocab()([
|
|
125
|
+
{ value: "barologger", label: { en: "Barologger", pt: "Barologger" } },
|
|
126
|
+
{ value: "vented", label: { en: "Vented cable", pt: "Cabo ventilado" } },
|
|
127
|
+
{ value: "none", label: { en: "None", pt: "Nenhuma" } }
|
|
128
|
+
]);
|
|
129
|
+
var READING_AGGREGATIONS = closedVocab()([
|
|
130
|
+
{ value: "none", label: { en: "Raw readings", pt: "Leituras brutas" } },
|
|
131
|
+
{ value: "hourly", label: { en: "Hourly", pt: "Hor\xE1ria" } },
|
|
132
|
+
{ value: "daily", label: { en: "Daily", pt: "Di\xE1ria" } }
|
|
133
|
+
]);
|
|
134
|
+
var WELL_STATUS_VALUES = valuesOf(WELL_STATUSES);
|
|
135
|
+
var PERMIT_ADMINISTRATIVE_STATUS_VALUES = valuesOf(
|
|
136
|
+
PERMIT_ADMINISTRATIVE_STATUSES
|
|
137
|
+
);
|
|
138
|
+
var QUALIFIER_VALUES = valuesOf(RESULT_QUALIFIERS);
|
|
139
|
+
var FRACTION_VALUES = valuesOf(RESULT_FRACTIONS);
|
|
140
|
+
var MEASURED_IN_VALUES = valuesOf(MEASUREMENT_LOCATIONS);
|
|
141
|
+
var FILTRATION_LOCATION_VALUES = valuesOf(MEASUREMENT_LOCATIONS);
|
|
142
|
+
var VALIDATION_STATUS_VALUES = valuesOf(VALIDATION_STATUSES);
|
|
143
|
+
var PARAMETER_GROUP_VALUES = valuesOf(PARAMETER_GROUPS);
|
|
144
|
+
var BAROMETRIC_COMPENSATION_VALUES = valuesOf(
|
|
145
|
+
BAROMETRIC_COMPENSATIONS
|
|
146
|
+
);
|
|
147
|
+
var READING_AGGREGATION_VALUES = valuesOf(READING_AGGREGATIONS);
|
|
148
|
+
var NUMERIC_QUALIFIERS = [
|
|
149
|
+
"<",
|
|
150
|
+
">",
|
|
151
|
+
"estimated"
|
|
152
|
+
];
|
|
153
|
+
var PARENT_SAMPLE_TYPES = [
|
|
154
|
+
"field_duplicate",
|
|
155
|
+
"split_sample"
|
|
156
|
+
];
|
|
157
|
+
var BLANK_SAMPLE_TYPES = [
|
|
158
|
+
"field_blank",
|
|
159
|
+
"trip_blank",
|
|
160
|
+
"equipment_blank"
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
// src/vocab/hydrodynamic.vocab.ts
|
|
164
|
+
var HYDRODYNAMIC_EVENT_TYPES = [
|
|
165
|
+
{
|
|
166
|
+
value: "spot_measurement",
|
|
167
|
+
label: { en: "Spot measurement", pt: "Medi\xE7\xE3o pontual" }
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
value: "constant_rate",
|
|
171
|
+
label: { en: "Constant rate", pt: "Vaz\xE3o constante" }
|
|
172
|
+
},
|
|
173
|
+
{ value: "step_drawdown", label: { en: "Step drawdown", pt: "Escalonada" } },
|
|
174
|
+
{ value: "airlift", label: { en: "Air-lift", pt: "Air-lift" } },
|
|
175
|
+
{
|
|
176
|
+
value: "recovery_only",
|
|
177
|
+
label: { en: "Recovery only", pt: "Recupera\xE7\xE3o" }
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
value: "logger_series",
|
|
181
|
+
label: { en: "Logger series", pt: "S\xE9rie de datalogger" }
|
|
182
|
+
}
|
|
183
|
+
];
|
|
184
|
+
var MEASUREMENT_METHODS = [
|
|
185
|
+
{
|
|
186
|
+
value: "electric_probe",
|
|
187
|
+
label: { en: "Electric probe", pt: "Sonda el\xE9trica" }
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
value: "pressure_transducer",
|
|
191
|
+
label: { en: "Pressure transducer", pt: "Transdutor de press\xE3o" }
|
|
192
|
+
},
|
|
193
|
+
{ value: "air_line", label: { en: "Air line", pt: "Linha de ar" } },
|
|
194
|
+
{ value: "tape", label: { en: "Tape", pt: "Trena" } }
|
|
195
|
+
];
|
|
196
|
+
var AQUIFER_ANALYSIS_METHODS = [
|
|
197
|
+
{ value: "cooper_jacob", label: { en: "Cooper-Jacob", pt: "Cooper-Jacob" } },
|
|
198
|
+
{ value: "theis", label: { en: "Theis", pt: "Theis" } },
|
|
199
|
+
{ value: "neuman", label: { en: "Neuman", pt: "Neuman" } },
|
|
200
|
+
{ value: "hantush", label: { en: "Hantush", pt: "Hantush" } },
|
|
201
|
+
{
|
|
202
|
+
value: "birsoy_summers",
|
|
203
|
+
label: { en: "Birsoy-Summers", pt: "Birsoy-Summers" }
|
|
204
|
+
},
|
|
205
|
+
{ value: "eden_hazel", label: { en: "Eden-Hazel", pt: "Eden-Hazel" } },
|
|
206
|
+
{
|
|
207
|
+
value: "visual_inspection",
|
|
208
|
+
label: { en: "Visual inspection", pt: "Inspe\xE7\xE3o visual" }
|
|
209
|
+
}
|
|
210
|
+
];
|
|
211
|
+
|
|
212
|
+
// src/validators/well.validators.ts
|
|
4
213
|
var mergeWell = createDefu((obj, key, value) => {
|
|
5
214
|
if (Array.isArray(value)) {
|
|
6
215
|
obj[key] = value;
|
|
@@ -43,7 +252,8 @@ var LocationPropertiesSchema = z.object({
|
|
|
43
252
|
lat_precision: z.number().optional(),
|
|
44
253
|
lng_precision: z.number().optional(),
|
|
45
254
|
elevation_precision: z.number().optional(),
|
|
46
|
-
original_crs: z.string().optional()
|
|
255
|
+
original_crs: z.string().optional(),
|
|
256
|
+
timezone: z.string().refine(isIanaTimeZone, "timezone must be an IANA time zone name").optional()
|
|
47
257
|
});
|
|
48
258
|
var LocationSchema = z.object({
|
|
49
259
|
lat: z.number(),
|
|
@@ -134,6 +344,7 @@ var CaveSchema = z.object({
|
|
|
134
344
|
});
|
|
135
345
|
var LevelReadingSchema = z.object({
|
|
136
346
|
elapsed: z.number(),
|
|
347
|
+
datetime: rfc3339().optional(),
|
|
137
348
|
depth: z.number(),
|
|
138
349
|
depth_precision: z.number().optional(),
|
|
139
350
|
pressure: z.number().optional()
|
|
@@ -163,14 +374,16 @@ var SpotMeasurementEventSchema = HydrodynamicEventBaseSchema.extend({
|
|
|
163
374
|
static_level: z.number(),
|
|
164
375
|
static_level_precision: z.number().optional(),
|
|
165
376
|
measurement_method: z.string().optional(),
|
|
166
|
-
|
|
377
|
+
// SHOULD carry at most one step; another count is valid (v2.4).
|
|
378
|
+
steps: z.array(PumpingStepSchema).optional(),
|
|
167
379
|
recovery: RecoveryPhaseSchema.optional()
|
|
168
380
|
});
|
|
169
381
|
var ConstantRateEventSchema = HydrodynamicEventBaseSchema.extend({
|
|
170
382
|
type: z.literal("constant_rate"),
|
|
171
383
|
static_level: z.number().optional(),
|
|
172
384
|
static_level_precision: z.number().optional(),
|
|
173
|
-
|
|
385
|
+
// SHOULD carry exactly one step; another count is valid (v2.4).
|
|
386
|
+
steps: z.array(PumpingStepSchema).optional(),
|
|
174
387
|
recovery: RecoveryPhaseSchema.optional()
|
|
175
388
|
});
|
|
176
389
|
var StepDrawdownEventSchema = HydrodynamicEventBaseSchema.extend({
|
|
@@ -191,13 +404,62 @@ var RecoveryOnlyEventSchema = HydrodynamicEventBaseSchema.extend({
|
|
|
191
404
|
pumping_duration: z.number().optional(),
|
|
192
405
|
recovery: RecoveryPhaseSchema
|
|
193
406
|
});
|
|
407
|
+
var LoggerReadingSchema = z.object({
|
|
408
|
+
datetime: rfc3339(),
|
|
409
|
+
elapsed: z.undefined({ message: "logger_series readings use datetime, not elapsed" }).optional(),
|
|
410
|
+
depth: z.number(),
|
|
411
|
+
depth_precision: z.number().optional(),
|
|
412
|
+
pressure: z.number().optional(),
|
|
413
|
+
depth_min: z.number().optional(),
|
|
414
|
+
depth_max: z.number().optional()
|
|
415
|
+
});
|
|
416
|
+
var closedEnum = (values) => z.enum(values);
|
|
417
|
+
var LoggerSeriesEventSchema = HydrodynamicEventBaseSchema.extend({
|
|
418
|
+
type: z.literal("logger_series"),
|
|
419
|
+
measurement_method: z.string().optional(),
|
|
420
|
+
sensor_depth: z.number().optional(),
|
|
421
|
+
interval: z.number().positive().optional(),
|
|
422
|
+
barometric_compensation: closedEnum(
|
|
423
|
+
BAROMETRIC_COMPENSATION_VALUES
|
|
424
|
+
).optional(),
|
|
425
|
+
aggregation: closedEnum(READING_AGGREGATION_VALUES).optional(),
|
|
426
|
+
readings: z.array(LoggerReadingSchema).min(1),
|
|
427
|
+
steps: z.undefined({ message: "logger_series carries no steps" }).optional(),
|
|
428
|
+
recovery: z.undefined({ message: "logger_series carries no recovery" }).optional()
|
|
429
|
+
});
|
|
430
|
+
var HYDRODYNAMIC_TYPES = HYDRODYNAMIC_EVENT_TYPES.map(
|
|
431
|
+
(t) => t.value
|
|
432
|
+
);
|
|
194
433
|
var HydrodynamicEventSchema = z.discriminatedUnion("type", [
|
|
195
434
|
SpotMeasurementEventSchema,
|
|
196
435
|
ConstantRateEventSchema,
|
|
197
436
|
StepDrawdownEventSchema,
|
|
198
437
|
AirliftEventSchema,
|
|
199
|
-
RecoveryOnlyEventSchema
|
|
200
|
-
|
|
438
|
+
RecoveryOnlyEventSchema,
|
|
439
|
+
LoggerSeriesEventSchema
|
|
440
|
+
]).or(
|
|
441
|
+
HydrodynamicEventBaseSchema.passthrough().refine(
|
|
442
|
+
(e) => !HYDRODYNAMIC_TYPES.includes(e.type),
|
|
443
|
+
{ message: "malformed hydrodynamic event" }
|
|
444
|
+
)
|
|
445
|
+
).superRefine((e, ctx) => {
|
|
446
|
+
if (e.type !== "logger_series") return;
|
|
447
|
+
const series = e;
|
|
448
|
+
if (series.aggregation !== "hourly" && series.aggregation !== "daily") {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
series.readings.forEach((r, i) => {
|
|
452
|
+
for (const key of ["depth_min", "depth_max"]) {
|
|
453
|
+
if (r[key] === void 0) {
|
|
454
|
+
ctx.addIssue({
|
|
455
|
+
code: z.ZodIssueCode.custom,
|
|
456
|
+
path: ["readings", i, key],
|
|
457
|
+
message: `${key} is required in an aggregated logger_series`
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
});
|
|
201
463
|
var WellStatusSchema = z.enum([
|
|
202
464
|
"active",
|
|
203
465
|
"maintenance",
|
|
@@ -239,7 +501,7 @@ var AquiferAnalysisSchema = z.object({
|
|
|
239
501
|
max_flow_rate_basis: z.string().optional(),
|
|
240
502
|
specific_capacity: z.number().optional(),
|
|
241
503
|
transmissivity: z.number().optional(),
|
|
242
|
-
storativity: z.number().
|
|
504
|
+
storativity: z.number().optional(),
|
|
243
505
|
hydraulic_conductivity: z.number().optional(),
|
|
244
506
|
aquifer_thickness: z.number().optional(),
|
|
245
507
|
jacob_b: z.number().optional(),
|
|
@@ -400,7 +662,7 @@ var OperatingRegimeSchema = z.object({
|
|
|
400
662
|
id: z.string(),
|
|
401
663
|
effective_from: rfc3339(),
|
|
402
664
|
flow_rate: z.number().nonnegative().optional(),
|
|
403
|
-
daily_operating_time: z.number().
|
|
665
|
+
daily_operating_time: z.number().nonnegative().optional(),
|
|
404
666
|
days_per_week: z.number().int().min(1).max(7).optional(),
|
|
405
667
|
notes: z.string().optional(),
|
|
406
668
|
updated_at: rfc3339().optional()
|
|
@@ -537,7 +799,10 @@ var WaterSampleSchema = z.object({
|
|
|
537
799
|
results: z.array(WaterQualityResultSchema).min(1)
|
|
538
800
|
});
|
|
539
801
|
var WellSchema = z.object({
|
|
540
|
-
version: z.
|
|
802
|
+
version: z.union([
|
|
803
|
+
z.number().int().nonnegative(),
|
|
804
|
+
z.string().regex(/^\d+\.\d+$/, 'version must be "M.m"')
|
|
805
|
+
]),
|
|
541
806
|
"@context": z.union([z.string(), z.array(z.unknown()), z.record(z.unknown())]).optional(),
|
|
542
807
|
well_id: z.array(WellIdSchema).optional(),
|
|
543
808
|
location: LocationSchema.optional(),
|
|
@@ -641,28 +906,39 @@ function normalizeV1Fields(raw) {
|
|
|
641
906
|
}
|
|
642
907
|
function parseWell(json) {
|
|
643
908
|
const raw = JSON.parse(json);
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
909
|
+
if (raw.version === void 0) {
|
|
910
|
+
raw.version = 2;
|
|
911
|
+
} else {
|
|
912
|
+
const parsed = parseFormatVersion(raw.version);
|
|
913
|
+
if (!parsed) {
|
|
914
|
+
throw new Error(
|
|
915
|
+
`Malformed .well format version: ${JSON.stringify(raw.version)}`
|
|
916
|
+
);
|
|
648
917
|
}
|
|
649
|
-
if (
|
|
918
|
+
if (parsed.major === 1) {
|
|
650
919
|
const normalized = normalizeV1Fields(raw);
|
|
651
920
|
return mergeParsed(
|
|
652
921
|
WellSchema.parse(normalized),
|
|
653
922
|
normalized
|
|
654
923
|
);
|
|
655
924
|
}
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
925
|
+
if (parsed.major !== 2) {
|
|
926
|
+
throw new Error(
|
|
927
|
+
`Unsupported .well format version: ${JSON.stringify(raw.version)}`
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
if (raw.version === 2 && Array.isArray(raw.aquifer_analysis)) {
|
|
932
|
+
for (const item of raw.aquifer_analysis) {
|
|
933
|
+
if (isPlainObject(item) && item.storativity === null) {
|
|
934
|
+
delete item.storativity;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
660
937
|
}
|
|
661
938
|
return mergeParsed(WellSchema.parse(raw), raw);
|
|
662
939
|
}
|
|
663
940
|
|
|
664
941
|
// src/utils/well.utils.ts
|
|
665
|
-
var WELL_FORMAT_VERSION = 2;
|
|
666
942
|
var INCHES_TO_MM = 25.4;
|
|
667
943
|
var LEGACY_ROOT_KEYS = /* @__PURE__ */ new Set([
|
|
668
944
|
"lat",
|
|
@@ -709,7 +985,7 @@ var VISIBILITY_LEAF_KEYS = SECTION_KEYS.flatMap(
|
|
|
709
985
|
(section) => VISIBILITY_TREE[section].length ? VISIBILITY_TREE[section] : [section]
|
|
710
986
|
);
|
|
711
987
|
var EMPTY_WELL = {
|
|
712
|
-
version:
|
|
988
|
+
version: WELL_FORMAT_VERSION,
|
|
713
989
|
bore_hole: [],
|
|
714
990
|
well_case: [],
|
|
715
991
|
reduction: [],
|
|
@@ -805,7 +1081,9 @@ function decodeV2Well(raw) {
|
|
|
805
1081
|
const rawScreens = raw.well_screen ?? [];
|
|
806
1082
|
const decoded = {
|
|
807
1083
|
...createEmptyWell(),
|
|
808
|
-
...raw.version !== void 0 && {
|
|
1084
|
+
...raw.version !== void 0 && {
|
|
1085
|
+
version: raw.version
|
|
1086
|
+
},
|
|
809
1087
|
...raw["@context"] !== void 0 && {
|
|
810
1088
|
"@context": raw["@context"]
|
|
811
1089
|
},
|
|
@@ -921,6 +1199,19 @@ function unknownRootKeys(well) {
|
|
|
921
1199
|
(key) => !(key in WellSchema.shape) && !LEGACY_ROOT_KEYS.has(key)
|
|
922
1200
|
);
|
|
923
1201
|
}
|
|
1202
|
+
function omitNulls(value) {
|
|
1203
|
+
if (Array.isArray(value)) return value.map(omitNulls);
|
|
1204
|
+
if (typeof value !== "object" || value === null) return value;
|
|
1205
|
+
const out = {};
|
|
1206
|
+
for (const [key, member] of Object.entries(value)) {
|
|
1207
|
+
if (key.startsWith("x-") || key === "@context") {
|
|
1208
|
+
out[key] = member;
|
|
1209
|
+
} else if (member !== null) {
|
|
1210
|
+
out[key] = omitNulls(member);
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
return out;
|
|
1214
|
+
}
|
|
924
1215
|
function serializeWell(well) {
|
|
925
1216
|
const payload = {
|
|
926
1217
|
version: WELL_FORMAT_VERSION,
|
|
@@ -977,7 +1268,7 @@ function serializeWell(well) {
|
|
|
977
1268
|
const value = well[key];
|
|
978
1269
|
if (value !== void 0) payload[key] = value;
|
|
979
1270
|
}
|
|
980
|
-
return JSON.stringify(payload);
|
|
1271
|
+
return JSON.stringify(omitNulls(payload));
|
|
981
1272
|
}
|
|
982
1273
|
function isWellEmpty(well) {
|
|
983
1274
|
if (!well) return true;
|
|
@@ -1060,10 +1351,18 @@ function deserializeWell(jsonString) {
|
|
|
1060
1351
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
1061
1352
|
throw new Error("Invalid profile format");
|
|
1062
1353
|
}
|
|
1063
|
-
if (
|
|
1064
|
-
|
|
1065
|
-
if (
|
|
1066
|
-
|
|
1354
|
+
if (raw.version !== void 0) {
|
|
1355
|
+
const parsed = parseFormatVersion(raw.version);
|
|
1356
|
+
if (!parsed) {
|
|
1357
|
+
throw new Error(
|
|
1358
|
+
`Malformed .well format version: ${JSON.stringify(raw.version)}`
|
|
1359
|
+
);
|
|
1360
|
+
}
|
|
1361
|
+
if (parsed.major === 2) return withCalculatedWellDepth(decodeV2Well(raw));
|
|
1362
|
+
if (parsed.major === 1) return withCalculatedWellDepth(decodeV1Well(raw));
|
|
1363
|
+
throw new Error(
|
|
1364
|
+
`Unsupported .well format version: ${JSON.stringify(raw.version)}`
|
|
1365
|
+
);
|
|
1067
1366
|
}
|
|
1068
1367
|
if (isWellEmpty(raw)) return null;
|
|
1069
1368
|
const constructiveSource = raw.constructive ?? raw;
|
|
@@ -2473,51 +2772,6 @@ var HISTORY_LOG_SEVERITIES = [
|
|
|
2473
2772
|
{ value: "critical", label: { en: "Critical", pt: "Cr\xEDtica" } }
|
|
2474
2773
|
];
|
|
2475
2774
|
|
|
2476
|
-
// src/vocab/hydrodynamic.vocab.ts
|
|
2477
|
-
var HYDRODYNAMIC_EVENT_TYPES = [
|
|
2478
|
-
{
|
|
2479
|
-
value: "spot_measurement",
|
|
2480
|
-
label: { en: "Spot measurement", pt: "Medi\xE7\xE3o pontual" }
|
|
2481
|
-
},
|
|
2482
|
-
{
|
|
2483
|
-
value: "constant_rate",
|
|
2484
|
-
label: { en: "Constant rate", pt: "Vaz\xE3o constante" }
|
|
2485
|
-
},
|
|
2486
|
-
{ value: "step_drawdown", label: { en: "Step drawdown", pt: "Escalonada" } },
|
|
2487
|
-
{ value: "airlift", label: { en: "Air-lift", pt: "Air-lift" } },
|
|
2488
|
-
{
|
|
2489
|
-
value: "recovery_only",
|
|
2490
|
-
label: { en: "Recovery only", pt: "Recupera\xE7\xE3o" }
|
|
2491
|
-
}
|
|
2492
|
-
];
|
|
2493
|
-
var MEASUREMENT_METHODS = [
|
|
2494
|
-
{
|
|
2495
|
-
value: "electric_probe",
|
|
2496
|
-
label: { en: "Electric probe", pt: "Sonda el\xE9trica" }
|
|
2497
|
-
},
|
|
2498
|
-
{
|
|
2499
|
-
value: "pressure_transducer",
|
|
2500
|
-
label: { en: "Pressure transducer", pt: "Transdutor de press\xE3o" }
|
|
2501
|
-
},
|
|
2502
|
-
{ value: "air_line", label: { en: "Air line", pt: "Linha de ar" } },
|
|
2503
|
-
{ value: "tape", label: { en: "Tape", pt: "Trena" } }
|
|
2504
|
-
];
|
|
2505
|
-
var AQUIFER_ANALYSIS_METHODS = [
|
|
2506
|
-
{ value: "cooper_jacob", label: { en: "Cooper-Jacob", pt: "Cooper-Jacob" } },
|
|
2507
|
-
{ value: "theis", label: { en: "Theis", pt: "Theis" } },
|
|
2508
|
-
{ value: "neuman", label: { en: "Neuman", pt: "Neuman" } },
|
|
2509
|
-
{ value: "hantush", label: { en: "Hantush", pt: "Hantush" } },
|
|
2510
|
-
{
|
|
2511
|
-
value: "birsoy_summers",
|
|
2512
|
-
label: { en: "Birsoy-Summers", pt: "Birsoy-Summers" }
|
|
2513
|
-
},
|
|
2514
|
-
{ value: "eden_hazel", label: { en: "Eden-Hazel", pt: "Eden-Hazel" } },
|
|
2515
|
-
{
|
|
2516
|
-
value: "visual_inspection",
|
|
2517
|
-
label: { en: "Visual inspection", pt: "Inspe\xE7\xE3o visual" }
|
|
2518
|
-
}
|
|
2519
|
-
];
|
|
2520
|
-
|
|
2521
2775
|
// src/vocab/operation.vocab.ts
|
|
2522
2776
|
var PUMP_TYPES = [
|
|
2523
2777
|
{
|
|
@@ -2728,114 +2982,6 @@ function vocabValues(vocab, { includeDeprecated = false } = {}) {
|
|
|
2728
2982
|
return vocab.filter((entry) => includeDeprecated || !entry.deprecated).map((entry) => entry.value);
|
|
2729
2983
|
}
|
|
2730
2984
|
|
|
2731
|
-
// src/vocab/closed.vocab.ts
|
|
2732
|
-
function closedVocab() {
|
|
2733
|
-
return (entries) => entries;
|
|
2734
|
-
}
|
|
2735
|
-
var valuesOf = (vocab) => vocab.map((entry) => entry.value);
|
|
2736
|
-
var WELL_STATUSES = closedVocab()([
|
|
2737
|
-
{ value: "active", label: { en: "Active", pt: "Ativo" } },
|
|
2738
|
-
{
|
|
2739
|
-
value: "maintenance",
|
|
2740
|
-
label: { en: "Under maintenance", pt: "Em manuten\xE7\xE3o" }
|
|
2741
|
-
},
|
|
2742
|
-
{ value: "inactive", label: { en: "Inactive", pt: "Paralisado" } },
|
|
2743
|
-
{
|
|
2744
|
-
value: "decommissioned",
|
|
2745
|
-
label: { en: "Decommissioned", pt: "Desativado" }
|
|
2746
|
-
},
|
|
2747
|
-
{ value: "abandoned", label: { en: "Abandoned", pt: "Abandonado" } }
|
|
2748
|
-
]);
|
|
2749
|
-
var PERMIT_ADMINISTRATIVE_STATUSES = closedVocab()([
|
|
2750
|
-
{ value: "requested", label: { en: "Requested", pt: "Requerida" } },
|
|
2751
|
-
{ value: "granted", label: { en: "Granted", pt: "Concedida" } },
|
|
2752
|
-
{ value: "suspended", label: { en: "Suspended", pt: "Suspensa" } },
|
|
2753
|
-
{ value: "revoked", label: { en: "Revoked", pt: "Revogada" } },
|
|
2754
|
-
{ value: "denied", label: { en: "Denied", pt: "Indeferida" } },
|
|
2755
|
-
{ value: "withdrawn", label: { en: "Withdrawn", pt: "Cancelada" } }
|
|
2756
|
-
]);
|
|
2757
|
-
var VOLUME_LIMIT_PERIODS = closedVocab()([
|
|
2758
|
-
{ value: "daily", label: { en: "Daily", pt: "Di\xE1rio" } },
|
|
2759
|
-
{ value: "monthly", label: { en: "Monthly", pt: "Mensal" } },
|
|
2760
|
-
{ value: "annual", label: { en: "Annual", pt: "Anual" } }
|
|
2761
|
-
]);
|
|
2762
|
-
var PRODUCTION_ENTRY_TYPES = closedVocab()([
|
|
2763
|
-
{
|
|
2764
|
-
value: "meter_reading",
|
|
2765
|
-
label: { en: "Meter reading", pt: "Leitura de hidr\xF4metro" }
|
|
2766
|
-
},
|
|
2767
|
-
{
|
|
2768
|
-
value: "estimated_volume",
|
|
2769
|
-
label: { en: "Estimated volume", pt: "Volume estimado" }
|
|
2770
|
-
}
|
|
2771
|
-
]);
|
|
2772
|
-
var RESULT_QUALIFIERS = closedVocab()([
|
|
2773
|
-
{ value: "<", label: { en: "< less than", pt: "< menor que" } },
|
|
2774
|
-
{ value: ">", label: { en: "> greater than", pt: "> maior que" } },
|
|
2775
|
-
{ value: "not_detected", label: { en: "Not detected", pt: "N\xE3o detectado" } },
|
|
2776
|
-
{ value: "estimated", label: { en: "Estimated", pt: "Estimado" } }
|
|
2777
|
-
]);
|
|
2778
|
-
var RESULT_FRACTIONS = closedVocab()([
|
|
2779
|
-
{ value: "total", label: { en: "Total", pt: "Total" } },
|
|
2780
|
-
{ value: "dissolved", label: { en: "Dissolved", pt: "Dissolvida" } },
|
|
2781
|
-
{ value: "suspended", label: { en: "Suspended", pt: "Suspensa" } }
|
|
2782
|
-
]);
|
|
2783
|
-
var MEASUREMENT_LOCATIONS = closedVocab()([
|
|
2784
|
-
{ value: "field", label: { en: "Field", pt: "Campo" } },
|
|
2785
|
-
{ value: "lab", label: { en: "Lab", pt: "Laborat\xF3rio" } }
|
|
2786
|
-
]);
|
|
2787
|
-
var VALIDATION_STATUSES = closedVocab()([
|
|
2788
|
-
{ value: "unvalidated", label: { en: "Unvalidated", pt: "N\xE3o validado" } },
|
|
2789
|
-
{ value: "validated", label: { en: "Validated", pt: "Validado" } },
|
|
2790
|
-
{ value: "qualified", label: { en: "Qualified", pt: "Qualificado" } },
|
|
2791
|
-
{ value: "rejected", label: { en: "Rejected", pt: "Rejeitado" } }
|
|
2792
|
-
]);
|
|
2793
|
-
var PARAMETER_GROUPS = closedVocab()([
|
|
2794
|
-
{
|
|
2795
|
-
value: "physical",
|
|
2796
|
-
label: { en: "Physical / field", pt: "F\xEDsico / campo" }
|
|
2797
|
-
},
|
|
2798
|
-
{ value: "aggregate", label: { en: "Aggregate", pt: "Agregados" } },
|
|
2799
|
-
{ value: "major_ion", label: { en: "Major ions", pt: "\xCDons maiores" } },
|
|
2800
|
-
{ value: "nutrient", label: { en: "Nutrients", pt: "Nutrientes" } },
|
|
2801
|
-
{ value: "organic", label: { en: "Organic", pt: "Org\xE2nicos" } },
|
|
2802
|
-
{ value: "disinfection", label: { en: "Disinfection", pt: "Desinfec\xE7\xE3o" } },
|
|
2803
|
-
{
|
|
2804
|
-
value: "mining_redox",
|
|
2805
|
-
label: { en: "Mining and redox", pt: "Minera\xE7\xE3o e redox" }
|
|
2806
|
-
},
|
|
2807
|
-
{ value: "metal", label: { en: "Metals / trace", pt: "Metais / tra\xE7o" } },
|
|
2808
|
-
{ value: "microbiology", label: { en: "Microbiology", pt: "Microbiologia" } },
|
|
2809
|
-
{
|
|
2810
|
-
value: "radioactivity",
|
|
2811
|
-
label: { en: "Radioactivity", pt: "Radioatividade" }
|
|
2812
|
-
}
|
|
2813
|
-
]);
|
|
2814
|
-
var WELL_STATUS_VALUES = valuesOf(WELL_STATUSES);
|
|
2815
|
-
var PERMIT_ADMINISTRATIVE_STATUS_VALUES = valuesOf(
|
|
2816
|
-
PERMIT_ADMINISTRATIVE_STATUSES
|
|
2817
|
-
);
|
|
2818
|
-
var QUALIFIER_VALUES = valuesOf(RESULT_QUALIFIERS);
|
|
2819
|
-
var FRACTION_VALUES = valuesOf(RESULT_FRACTIONS);
|
|
2820
|
-
var MEASURED_IN_VALUES = valuesOf(MEASUREMENT_LOCATIONS);
|
|
2821
|
-
var FILTRATION_LOCATION_VALUES = valuesOf(MEASUREMENT_LOCATIONS);
|
|
2822
|
-
var VALIDATION_STATUS_VALUES = valuesOf(VALIDATION_STATUSES);
|
|
2823
|
-
var PARAMETER_GROUP_VALUES = valuesOf(PARAMETER_GROUPS);
|
|
2824
|
-
var NUMERIC_QUALIFIERS = [
|
|
2825
|
-
"<",
|
|
2826
|
-
">",
|
|
2827
|
-
"estimated"
|
|
2828
|
-
];
|
|
2829
|
-
var PARENT_SAMPLE_TYPES = [
|
|
2830
|
-
"field_duplicate",
|
|
2831
|
-
"split_sample"
|
|
2832
|
-
];
|
|
2833
|
-
var BLANK_SAMPLE_TYPES = [
|
|
2834
|
-
"field_blank",
|
|
2835
|
-
"trip_blank",
|
|
2836
|
-
"equipment_blank"
|
|
2837
|
-
];
|
|
2838
|
-
|
|
2839
2985
|
// src/vocab/waterSample.vocab.ts
|
|
2840
2986
|
var SAMPLE_TYPES = [
|
|
2841
2987
|
{ value: "routine", label: { en: "Routine", pt: "Rotina" } },
|
|
@@ -3100,6 +3246,8 @@ export {
|
|
|
3100
3246
|
AirliftEventSchema,
|
|
3101
3247
|
AquiferAnalysisSchema,
|
|
3102
3248
|
AttachmentSchema,
|
|
3249
|
+
BAROMETRIC_COMPENSATIONS,
|
|
3250
|
+
BAROMETRIC_COMPENSATION_VALUES,
|
|
3103
3251
|
BLANK_SAMPLE_TYPES,
|
|
3104
3252
|
BR_GM_MS_888_2021,
|
|
3105
3253
|
BoreHoleSchema,
|
|
@@ -3135,6 +3283,8 @@ export {
|
|
|
3135
3283
|
LithologySchema,
|
|
3136
3284
|
LocationPropertiesSchema,
|
|
3137
3285
|
LocationSchema,
|
|
3286
|
+
LoggerReadingSchema,
|
|
3287
|
+
LoggerSeriesEventSchema,
|
|
3138
3288
|
MAINTENANCE_TYPES,
|
|
3139
3289
|
MEASURED_IN_VALUES,
|
|
3140
3290
|
MEASUREMENT_LOCATIONS,
|
|
@@ -3169,6 +3319,8 @@ export {
|
|
|
3169
3319
|
PurgeReadingSchema,
|
|
3170
3320
|
PurgeSchema,
|
|
3171
3321
|
QUALIFIER_VALUES,
|
|
3322
|
+
READING_AGGREGATIONS,
|
|
3323
|
+
READING_AGGREGATION_VALUES,
|
|
3172
3324
|
READING_SOURCES,
|
|
3173
3325
|
RESULT_FRACTIONS,
|
|
3174
3326
|
RESULT_QUALIFIERS,
|
|
@@ -3200,6 +3352,7 @@ export {
|
|
|
3200
3352
|
WATER_QUALITY_UNITS,
|
|
3201
3353
|
WATER_QUALITY_VOCABULARY_VERSION,
|
|
3202
3354
|
WATER_USES,
|
|
3355
|
+
WELL_FORMAT_VERSION,
|
|
3203
3356
|
WELL_PURPOSES,
|
|
3204
3357
|
WELL_STATUSES,
|
|
3205
3358
|
WELL_STATUS_VALUES,
|
|
@@ -3214,6 +3367,7 @@ export {
|
|
|
3214
3367
|
WellStatusSchema,
|
|
3215
3368
|
calculatedWellDepth,
|
|
3216
3369
|
checkIfProfileIsEmpty,
|
|
3370
|
+
compareFormatVersions,
|
|
3217
3371
|
concentrationFromCanonical,
|
|
3218
3372
|
concentrationToCanonical,
|
|
3219
3373
|
convertProfileFromJSON,
|
|
@@ -3241,6 +3395,7 @@ export {
|
|
|
3241
3395
|
hoursToMinutes,
|
|
3242
3396
|
hpToKilowatts,
|
|
3243
3397
|
inchesToMm,
|
|
3398
|
+
isIanaTimeZone,
|
|
3244
3399
|
isKnownParameter,
|
|
3245
3400
|
isVocabValue,
|
|
3246
3401
|
isWellEmpty,
|
|
@@ -3257,6 +3412,7 @@ export {
|
|
|
3257
3412
|
mmToSlotNumber,
|
|
3258
3413
|
normalizeColorUnit,
|
|
3259
3414
|
parameterKey,
|
|
3415
|
+
parseFormatVersion,
|
|
3260
3416
|
parseWell,
|
|
3261
3417
|
powerFromCanonical,
|
|
3262
3418
|
powerToCanonical,
|