@mostlyrightmd/core 0.1.0-rc.7

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 (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/dist/discovery/index.cjs +1646 -0
  4. package/dist/discovery/index.cjs.map +1 -0
  5. package/dist/discovery/index.d.cts +313 -0
  6. package/dist/discovery/index.d.ts +313 -0
  7. package/dist/discovery/index.mjs +1609 -0
  8. package/dist/discovery/index.mjs.map +1 -0
  9. package/dist/formats/index.cjs +498 -0
  10. package/dist/formats/index.cjs.map +1 -0
  11. package/dist/formats/index.d.cts +97 -0
  12. package/dist/formats/index.d.ts +97 -0
  13. package/dist/formats/index.mjs +465 -0
  14. package/dist/formats/index.mjs.map +1 -0
  15. package/dist/index.cjs +1624 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.cts +559 -0
  18. package/dist/index.d.ts +559 -0
  19. package/dist/index.global.js +1582 -0
  20. package/dist/index.global.js.map +1 -0
  21. package/dist/index.mjs +1557 -0
  22. package/dist/index.mjs.map +1 -0
  23. package/dist/internal/bounds.cjs +125 -0
  24. package/dist/internal/bounds.cjs.map +1 -0
  25. package/dist/internal/bounds.d.cts +36 -0
  26. package/dist/internal/bounds.d.ts +36 -0
  27. package/dist/internal/bounds.mjs +81 -0
  28. package/dist/internal/bounds.mjs.map +1 -0
  29. package/dist/internal/cache/fs.cjs +217 -0
  30. package/dist/internal/cache/fs.cjs.map +1 -0
  31. package/dist/internal/cache/fs.d.cts +57 -0
  32. package/dist/internal/cache/fs.d.ts +57 -0
  33. package/dist/internal/cache/fs.mjs +179 -0
  34. package/dist/internal/cache/fs.mjs.map +1 -0
  35. package/dist/internal/cache/index.browser.cjs +1184 -0
  36. package/dist/internal/cache/index.browser.cjs.map +1 -0
  37. package/dist/internal/cache/index.browser.d.cts +20 -0
  38. package/dist/internal/cache/index.browser.d.ts +20 -0
  39. package/dist/internal/cache/index.browser.mjs +36 -0
  40. package/dist/internal/cache/index.browser.mjs.map +1 -0
  41. package/dist/internal/cache/index.cjs +1389 -0
  42. package/dist/internal/cache/index.cjs.map +1 -0
  43. package/dist/internal/cache/index.d.cts +16 -0
  44. package/dist/internal/cache/index.d.ts +16 -0
  45. package/dist/internal/cache/index.mjs +40 -0
  46. package/dist/internal/cache/index.mjs.map +1 -0
  47. package/dist/internal/chunk-PKJXHY27.mjs +1137 -0
  48. package/dist/internal/chunk-PKJXHY27.mjs.map +1 -0
  49. package/dist/internal/convert.cjs +161 -0
  50. package/dist/internal/convert.cjs.map +1 -0
  51. package/dist/internal/convert.d.cts +44 -0
  52. package/dist/internal/convert.d.ts +44 -0
  53. package/dist/internal/convert.mjs +117 -0
  54. package/dist/internal/convert.mjs.map +1 -0
  55. package/dist/internal/fs-O6XR4WWW.mjs +183 -0
  56. package/dist/internal/fs-O6XR4WWW.mjs.map +1 -0
  57. package/dist/internal/keys-B7C8C88N.d.cts +191 -0
  58. package/dist/internal/keys-B7C8C88N.d.ts +191 -0
  59. package/dist/internal/merge/index.cjs +75 -0
  60. package/dist/internal/merge/index.cjs.map +1 -0
  61. package/dist/internal/merge/index.d.cts +74 -0
  62. package/dist/internal/merge/index.d.ts +74 -0
  63. package/dist/internal/merge/index.mjs +46 -0
  64. package/dist/internal/merge/index.mjs.map +1 -0
  65. package/dist/internal/pairs.cjs +328 -0
  66. package/dist/internal/pairs.cjs.map +1 -0
  67. package/dist/internal/pairs.d.cts +105 -0
  68. package/dist/internal/pairs.d.ts +105 -0
  69. package/dist/internal/pairs.mjs +298 -0
  70. package/dist/internal/pairs.mjs.map +1 -0
  71. package/dist/qc/index.cjs +247 -0
  72. package/dist/qc/index.cjs.map +1 -0
  73. package/dist/qc/index.d.cts +140 -0
  74. package/dist/qc/index.d.ts +140 -0
  75. package/dist/qc/index.mjs +212 -0
  76. package/dist/qc/index.mjs.map +1 -0
  77. package/dist/temporal/index.cjs +504 -0
  78. package/dist/temporal/index.cjs.map +1 -0
  79. package/dist/temporal/index.d.cts +121 -0
  80. package/dist/temporal/index.d.ts +121 -0
  81. package/dist/temporal/index.mjs +474 -0
  82. package/dist/temporal/index.mjs.map +1 -0
  83. package/dist/transforms/index.cjs +399 -0
  84. package/dist/transforms/index.cjs.map +1 -0
  85. package/dist/transforms/index.d.cts +193 -0
  86. package/dist/transforms/index.d.ts +193 -0
  87. package/dist/transforms/index.mjs +362 -0
  88. package/dist/transforms/index.mjs.map +1 -0
  89. package/dist/validator.cjs +1870 -0
  90. package/dist/validator.cjs.map +1 -0
  91. package/dist/validator.d.cts +30 -0
  92. package/dist/validator.d.ts +30 -0
  93. package/dist/validator.mjs +1843 -0
  94. package/dist/validator.mjs.map +1 -0
  95. package/package.json +115 -0
@@ -0,0 +1,1870 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/validator.ts
21
+ var validator_exports = {};
22
+ __export(validator_exports, {
23
+ validateRows: () => validateRows
24
+ });
25
+ module.exports = __toCommonJS(validator_exports);
26
+
27
+ // src/exceptions/index.ts
28
+ function toJsonSafe(value, seen) {
29
+ const visited = seen ?? /* @__PURE__ */ new WeakSet();
30
+ if (value === null || value === void 0) {
31
+ return null;
32
+ }
33
+ if (typeof value === "boolean") {
34
+ return value;
35
+ }
36
+ if (typeof value === "string") {
37
+ return value;
38
+ }
39
+ if (typeof value === "number") {
40
+ return Number.isFinite(value) ? value : null;
41
+ }
42
+ if (typeof value === "bigint") {
43
+ if (value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER)) {
44
+ return Number(value);
45
+ }
46
+ return { _repr_only: true, value: value.toString() };
47
+ }
48
+ if (value instanceof Date) {
49
+ if (Number.isNaN(value.getTime())) {
50
+ return null;
51
+ }
52
+ return value.toISOString();
53
+ }
54
+ if (Array.isArray(value)) {
55
+ if (visited.has(value)) {
56
+ return { _cycle: true, value: String(value) };
57
+ }
58
+ visited.add(value);
59
+ try {
60
+ return value.map((item) => toJsonSafe(item, visited));
61
+ } finally {
62
+ visited.delete(value);
63
+ }
64
+ }
65
+ if (typeof value === "object") {
66
+ if (visited.has(value)) {
67
+ return { _cycle: true, value: String(value) };
68
+ }
69
+ visited.add(value);
70
+ try {
71
+ const out = {};
72
+ for (const key of Object.keys(value)) {
73
+ if (typeof key !== "string") {
74
+ throw new TypeError(`toJsonSafe dict keys must be string; got ${typeof key}`);
75
+ }
76
+ out[key] = toJsonSafe(value[key], visited);
77
+ }
78
+ return out;
79
+ } finally {
80
+ visited.delete(value);
81
+ }
82
+ }
83
+ return { _repr_only: true, value: String(value) };
84
+ }
85
+ var TradewindsError = class extends Error {
86
+ /** Subclass override — the stable string enum surfaced via `errorCode`. */
87
+ static defaultErrorCode = "TRADEWINDS_ERROR";
88
+ errorCode;
89
+ source;
90
+ requestId;
91
+ constructor(message = "", options = {}) {
92
+ super(message);
93
+ this.name = new.target.name;
94
+ const ctor = this.constructor;
95
+ this.errorCode = options.errorCode ?? ctor.defaultErrorCode;
96
+ this.source = options.source ?? null;
97
+ this.requestId = options.requestId ?? null;
98
+ Object.setPrototypeOf(this, new.target.prototype);
99
+ }
100
+ /**
101
+ * Subclass hook returning the structured attributes for `toDict`.
102
+ * Values are passed through `toJsonSafe` by `toDict()`, so subclasses
103
+ * don't need to coerce values themselves.
104
+ */
105
+ payload() {
106
+ return {
107
+ error_code: this.errorCode,
108
+ message: this.message,
109
+ source: this.source,
110
+ request_id: this.requestId
111
+ };
112
+ }
113
+ /** Return a JSON-safe dict suitable for MCP `error.data`. */
114
+ toDict() {
115
+ const safe = toJsonSafe(this.payload());
116
+ return safe;
117
+ }
118
+ };
119
+ var SchemaValidationError = class extends TradewindsError {
120
+ static defaultErrorCode = "SCHEMA_VALIDATION_FAILED";
121
+ schemaId;
122
+ violations;
123
+ quarantineCount;
124
+ sampleViolations;
125
+ constructor(message, options) {
126
+ super(message, options);
127
+ this.schemaId = options.schemaId;
128
+ this.violations = [...options.violations ?? []];
129
+ this.quarantineCount = options.quarantineCount ?? 0;
130
+ this.sampleViolations = [...options.sampleViolations ?? []];
131
+ }
132
+ payload() {
133
+ return {
134
+ ...super.payload(),
135
+ schema_id: this.schemaId,
136
+ violations: this.violations,
137
+ quarantine_count: this.quarantineCount,
138
+ sample_violations: this.sampleViolations
139
+ };
140
+ }
141
+ };
142
+ var SourceMismatchError = class extends TradewindsError {
143
+ static defaultErrorCode = "SOURCE_MISMATCH";
144
+ /** Canonical role-name vocabulary (design.md §R). */
145
+ static VALID_ROLES = /* @__PURE__ */ new Set([
146
+ "observations",
147
+ "forecasts",
148
+ "settlement"
149
+ ]);
150
+ schemaSource;
151
+ dataSource;
152
+ role;
153
+ catalogWarning;
154
+ constructor(message, options) {
155
+ super(message, options);
156
+ this.schemaSource = options.schemaSource;
157
+ this.dataSource = options.dataSource;
158
+ this.role = options.role ?? null;
159
+ this.catalogWarning = options.catalogWarning ?? null;
160
+ }
161
+ payload() {
162
+ return {
163
+ ...super.payload(),
164
+ schema_source: this.schemaSource,
165
+ data_source: this.dataSource,
166
+ role: this.role,
167
+ catalog_warning: this.catalogWarning
168
+ };
169
+ }
170
+ };
171
+
172
+ // src/schemas/validators/schema_forecast_iem_mos_v1.js
173
+ var schema_forecast_iem_mos_v1 = validate21;
174
+ var schema32 = { "$id": "https://mostlyright.dev/schemas/schema.forecast.iem_mos.v1.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "imperialRenames": { "dew_point_c": "dew_point_F", "temp_c": "temp_F", "wind_speed_ms": "wind_speed_kt" }, "properties": { "dew_point_c": { "description": "units: celsius", "type": ["null", "number"] }, "forecast_hour": { "description": "units: hours \u2014 (valid_at - issued_at).total_seconds() / 3600", "type": "integer" }, "issued_at": { "description": "model run time (from source `runtime` field)", "format": "date-time", "type": "string" }, "model": { "description": "e.g. NBE, GFS, LAV, MET", "type": "string" }, "precip_probability": { "description": "units: probability \u2014 bounded [0, 1]", "type": ["null", "number"] }, "sky_cover_pct": { "description": "units: percent \u2014 bounded [0, 100]", "type": ["integer", "null"] }, "station": { "type": "string" }, "temp_c": { "description": "units: celsius", "type": ["null", "number"] }, "valid_at": { "description": "forecast target time (from source `ftime`)", "format": "date-time", "type": "string" }, "wind_dir_deg": { "description": "units: degrees", "type": ["integer", "null"] }, "wind_speed_ms": { "description": "units: m/s", "type": ["null", "number"] } }, "required": ["forecast_hour", "issued_at", "model", "station", "valid_at"], "title": "schema.forecast.iem_mos.v1", "type": "object", "version": "v1" };
175
+ function validate21(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
176
+ ;
177
+ let vErrors = null;
178
+ let errors = 0;
179
+ const evaluated0 = validate21.evaluated;
180
+ if (evaluated0.dynamicProps) {
181
+ evaluated0.props = void 0;
182
+ }
183
+ if (evaluated0.dynamicItems) {
184
+ evaluated0.items = void 0;
185
+ }
186
+ if (data && typeof data == "object" && !Array.isArray(data)) {
187
+ if (data.forecast_hour === void 0) {
188
+ const err0 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "forecast_hour" }, message: "must have required property 'forecast_hour'" };
189
+ if (vErrors === null) {
190
+ vErrors = [err0];
191
+ } else {
192
+ vErrors.push(err0);
193
+ }
194
+ errors++;
195
+ }
196
+ if (data.issued_at === void 0) {
197
+ const err1 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "issued_at" }, message: "must have required property 'issued_at'" };
198
+ if (vErrors === null) {
199
+ vErrors = [err1];
200
+ } else {
201
+ vErrors.push(err1);
202
+ }
203
+ errors++;
204
+ }
205
+ if (data.model === void 0) {
206
+ const err2 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "model" }, message: "must have required property 'model'" };
207
+ if (vErrors === null) {
208
+ vErrors = [err2];
209
+ } else {
210
+ vErrors.push(err2);
211
+ }
212
+ errors++;
213
+ }
214
+ if (data.station === void 0) {
215
+ const err3 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "station" }, message: "must have required property 'station'" };
216
+ if (vErrors === null) {
217
+ vErrors = [err3];
218
+ } else {
219
+ vErrors.push(err3);
220
+ }
221
+ errors++;
222
+ }
223
+ if (data.valid_at === void 0) {
224
+ const err4 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "valid_at" }, message: "must have required property 'valid_at'" };
225
+ if (vErrors === null) {
226
+ vErrors = [err4];
227
+ } else {
228
+ vErrors.push(err4);
229
+ }
230
+ errors++;
231
+ }
232
+ if (data.dew_point_c !== void 0) {
233
+ let data0 = data.dew_point_c;
234
+ if (data0 !== null && !(typeof data0 == "number")) {
235
+ const err5 = { instancePath: instancePath + "/dew_point_c", schemaPath: "#/properties/dew_point_c/type", keyword: "type", params: { type: schema32.properties.dew_point_c.type }, message: "must be null,number" };
236
+ if (vErrors === null) {
237
+ vErrors = [err5];
238
+ } else {
239
+ vErrors.push(err5);
240
+ }
241
+ errors++;
242
+ }
243
+ }
244
+ if (data.forecast_hour !== void 0) {
245
+ let data1 = data.forecast_hour;
246
+ if (!(typeof data1 == "number" && (!(data1 % 1) && !isNaN(data1)))) {
247
+ const err6 = { instancePath: instancePath + "/forecast_hour", schemaPath: "#/properties/forecast_hour/type", keyword: "type", params: { type: "integer" }, message: "must be integer" };
248
+ if (vErrors === null) {
249
+ vErrors = [err6];
250
+ } else {
251
+ vErrors.push(err6);
252
+ }
253
+ errors++;
254
+ }
255
+ }
256
+ if (data.issued_at !== void 0) {
257
+ if (!(typeof data.issued_at === "string")) {
258
+ const err7 = { instancePath: instancePath + "/issued_at", schemaPath: "#/properties/issued_at/type", keyword: "type", params: { type: "string" }, message: "must be string" };
259
+ if (vErrors === null) {
260
+ vErrors = [err7];
261
+ } else {
262
+ vErrors.push(err7);
263
+ }
264
+ errors++;
265
+ }
266
+ }
267
+ if (data.model !== void 0) {
268
+ if (typeof data.model !== "string") {
269
+ const err8 = { instancePath: instancePath + "/model", schemaPath: "#/properties/model/type", keyword: "type", params: { type: "string" }, message: "must be string" };
270
+ if (vErrors === null) {
271
+ vErrors = [err8];
272
+ } else {
273
+ vErrors.push(err8);
274
+ }
275
+ errors++;
276
+ }
277
+ }
278
+ if (data.precip_probability !== void 0) {
279
+ let data4 = data.precip_probability;
280
+ if (data4 !== null && !(typeof data4 == "number")) {
281
+ const err9 = { instancePath: instancePath + "/precip_probability", schemaPath: "#/properties/precip_probability/type", keyword: "type", params: { type: schema32.properties.precip_probability.type }, message: "must be null,number" };
282
+ if (vErrors === null) {
283
+ vErrors = [err9];
284
+ } else {
285
+ vErrors.push(err9);
286
+ }
287
+ errors++;
288
+ }
289
+ }
290
+ if (data.sky_cover_pct !== void 0) {
291
+ let data5 = data.sky_cover_pct;
292
+ if (!(typeof data5 == "number" && (!(data5 % 1) && !isNaN(data5))) && data5 !== null) {
293
+ const err10 = { instancePath: instancePath + "/sky_cover_pct", schemaPath: "#/properties/sky_cover_pct/type", keyword: "type", params: { type: schema32.properties.sky_cover_pct.type }, message: "must be integer,null" };
294
+ if (vErrors === null) {
295
+ vErrors = [err10];
296
+ } else {
297
+ vErrors.push(err10);
298
+ }
299
+ errors++;
300
+ }
301
+ }
302
+ if (data.station !== void 0) {
303
+ if (typeof data.station !== "string") {
304
+ const err11 = { instancePath: instancePath + "/station", schemaPath: "#/properties/station/type", keyword: "type", params: { type: "string" }, message: "must be string" };
305
+ if (vErrors === null) {
306
+ vErrors = [err11];
307
+ } else {
308
+ vErrors.push(err11);
309
+ }
310
+ errors++;
311
+ }
312
+ }
313
+ if (data.temp_c !== void 0) {
314
+ let data7 = data.temp_c;
315
+ if (data7 !== null && !(typeof data7 == "number")) {
316
+ const err12 = { instancePath: instancePath + "/temp_c", schemaPath: "#/properties/temp_c/type", keyword: "type", params: { type: schema32.properties.temp_c.type }, message: "must be null,number" };
317
+ if (vErrors === null) {
318
+ vErrors = [err12];
319
+ } else {
320
+ vErrors.push(err12);
321
+ }
322
+ errors++;
323
+ }
324
+ }
325
+ if (data.valid_at !== void 0) {
326
+ if (!(typeof data.valid_at === "string")) {
327
+ const err13 = { instancePath: instancePath + "/valid_at", schemaPath: "#/properties/valid_at/type", keyword: "type", params: { type: "string" }, message: "must be string" };
328
+ if (vErrors === null) {
329
+ vErrors = [err13];
330
+ } else {
331
+ vErrors.push(err13);
332
+ }
333
+ errors++;
334
+ }
335
+ }
336
+ if (data.wind_dir_deg !== void 0) {
337
+ let data9 = data.wind_dir_deg;
338
+ if (!(typeof data9 == "number" && (!(data9 % 1) && !isNaN(data9))) && data9 !== null) {
339
+ const err14 = { instancePath: instancePath + "/wind_dir_deg", schemaPath: "#/properties/wind_dir_deg/type", keyword: "type", params: { type: schema32.properties.wind_dir_deg.type }, message: "must be integer,null" };
340
+ if (vErrors === null) {
341
+ vErrors = [err14];
342
+ } else {
343
+ vErrors.push(err14);
344
+ }
345
+ errors++;
346
+ }
347
+ }
348
+ if (data.wind_speed_ms !== void 0) {
349
+ let data10 = data.wind_speed_ms;
350
+ if (data10 !== null && !(typeof data10 == "number")) {
351
+ const err15 = { instancePath: instancePath + "/wind_speed_ms", schemaPath: "#/properties/wind_speed_ms/type", keyword: "type", params: { type: schema32.properties.wind_speed_ms.type }, message: "must be null,number" };
352
+ if (vErrors === null) {
353
+ vErrors = [err15];
354
+ } else {
355
+ vErrors.push(err15);
356
+ }
357
+ errors++;
358
+ }
359
+ }
360
+ } else {
361
+ const err16 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
362
+ if (vErrors === null) {
363
+ vErrors = [err16];
364
+ } else {
365
+ vErrors.push(err16);
366
+ }
367
+ errors++;
368
+ }
369
+ validate21.errors = vErrors;
370
+ return errors === 0;
371
+ }
372
+ validate21.evaluated = { "props": { "dew_point_c": true, "forecast_hour": true, "issued_at": true, "model": true, "precip_probability": true, "sky_cover_pct": true, "station": true, "temp_c": true, "valid_at": true, "wind_dir_deg": true, "wind_speed_ms": true }, "dynamicProps": false, "dynamicItems": false };
373
+
374
+ // src/schemas/validators/schema_observation_ledger_v1.js
375
+ var schema_observation_ledger_v1 = validate23;
376
+ var schema34 = { "$id": "https://mostlyright.dev/schemas/schema.observation_ledger.v1.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "as_of_time": { "format": "date-time", "type": ["null", "string"] }, "dewpoint_c": { "description": "units: celsius", "type": ["null", "number"] }, "ingestion_id": { "type": ["null", "string"] }, "observation_kind": { "enum": ["METAR", "SPECI", null], "type": ["null", "string"] }, "observation_quality": { "description": "Lineage row-quality flag per LINEAGE-01; distinct from qc_status enum slot AND distinct from the obs_qc_status bitmask column per QC-05.", "enum": ["clean", "flagged", "suspect", null], "type": ["null", "string"] }, "observation_type": { "enum": ["METAR", "SPECI"], "type": "string" }, "observed_at": { "format": "date-time", "type": "string" }, "parser_name": { "enum": ["ghcnh", "iem", "mostlyright_v1", "ncei", null], "type": ["null", "string"] }, "parser_version": { "type": ["null", "string"] }, "provenance": { "enum": ["legacy", "reingested", null], "type": ["null", "string"] }, "qc_status": { "enum": ["clean", "flagged", "suspect", null], "type": ["null", "string"] }, "source": { "description": "ncei reserved per D-2.1-09; never written in v0.1.0.", "enum": ["awc", "ghcnh", "iem", "ncei"], "type": "string" }, "source_received_at": { "type": ["null", "string"] }, "station_code": { "type": "string" }, "temp_c": { "description": "units: celsius", "type": ["null", "number"] } }, "required": ["observation_type", "observed_at", "source", "station_code"], "title": "schema.observation_ledger.v1", "type": "object", "version": "v1" };
377
+ function validate23(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
378
+ ;
379
+ let vErrors = null;
380
+ let errors = 0;
381
+ const evaluated0 = validate23.evaluated;
382
+ if (evaluated0.dynamicProps) {
383
+ evaluated0.props = void 0;
384
+ }
385
+ if (evaluated0.dynamicItems) {
386
+ evaluated0.items = void 0;
387
+ }
388
+ if (data && typeof data == "object" && !Array.isArray(data)) {
389
+ if (data.observation_type === void 0) {
390
+ const err0 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "observation_type" }, message: "must have required property 'observation_type'" };
391
+ if (vErrors === null) {
392
+ vErrors = [err0];
393
+ } else {
394
+ vErrors.push(err0);
395
+ }
396
+ errors++;
397
+ }
398
+ if (data.observed_at === void 0) {
399
+ const err1 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "observed_at" }, message: "must have required property 'observed_at'" };
400
+ if (vErrors === null) {
401
+ vErrors = [err1];
402
+ } else {
403
+ vErrors.push(err1);
404
+ }
405
+ errors++;
406
+ }
407
+ if (data.source === void 0) {
408
+ const err2 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "source" }, message: "must have required property 'source'" };
409
+ if (vErrors === null) {
410
+ vErrors = [err2];
411
+ } else {
412
+ vErrors.push(err2);
413
+ }
414
+ errors++;
415
+ }
416
+ if (data.station_code === void 0) {
417
+ const err3 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "station_code" }, message: "must have required property 'station_code'" };
418
+ if (vErrors === null) {
419
+ vErrors = [err3];
420
+ } else {
421
+ vErrors.push(err3);
422
+ }
423
+ errors++;
424
+ }
425
+ if (data.as_of_time !== void 0) {
426
+ let data0 = data.as_of_time;
427
+ if (data0 !== null && typeof data0 !== "string") {
428
+ const err4 = { instancePath: instancePath + "/as_of_time", schemaPath: "#/properties/as_of_time/type", keyword: "type", params: { type: schema34.properties.as_of_time.type }, message: "must be null,string" };
429
+ if (vErrors === null) {
430
+ vErrors = [err4];
431
+ } else {
432
+ vErrors.push(err4);
433
+ }
434
+ errors++;
435
+ }
436
+ }
437
+ if (data.dewpoint_c !== void 0) {
438
+ let data1 = data.dewpoint_c;
439
+ if (data1 !== null && !(typeof data1 == "number")) {
440
+ const err5 = { instancePath: instancePath + "/dewpoint_c", schemaPath: "#/properties/dewpoint_c/type", keyword: "type", params: { type: schema34.properties.dewpoint_c.type }, message: "must be null,number" };
441
+ if (vErrors === null) {
442
+ vErrors = [err5];
443
+ } else {
444
+ vErrors.push(err5);
445
+ }
446
+ errors++;
447
+ }
448
+ }
449
+ if (data.ingestion_id !== void 0) {
450
+ let data2 = data.ingestion_id;
451
+ if (data2 !== null && typeof data2 !== "string") {
452
+ const err6 = { instancePath: instancePath + "/ingestion_id", schemaPath: "#/properties/ingestion_id/type", keyword: "type", params: { type: schema34.properties.ingestion_id.type }, message: "must be null,string" };
453
+ if (vErrors === null) {
454
+ vErrors = [err6];
455
+ } else {
456
+ vErrors.push(err6);
457
+ }
458
+ errors++;
459
+ }
460
+ }
461
+ if (data.observation_kind !== void 0) {
462
+ let data3 = data.observation_kind;
463
+ if (data3 !== null && typeof data3 !== "string") {
464
+ const err7 = { instancePath: instancePath + "/observation_kind", schemaPath: "#/properties/observation_kind/type", keyword: "type", params: { type: schema34.properties.observation_kind.type }, message: "must be null,string" };
465
+ if (vErrors === null) {
466
+ vErrors = [err7];
467
+ } else {
468
+ vErrors.push(err7);
469
+ }
470
+ errors++;
471
+ }
472
+ if (!(data3 === "METAR" || data3 === "SPECI" || data3 === null)) {
473
+ const err8 = { instancePath: instancePath + "/observation_kind", schemaPath: "#/properties/observation_kind/enum", keyword: "enum", params: { allowedValues: schema34.properties.observation_kind.enum }, message: "must be equal to one of the allowed values" };
474
+ if (vErrors === null) {
475
+ vErrors = [err8];
476
+ } else {
477
+ vErrors.push(err8);
478
+ }
479
+ errors++;
480
+ }
481
+ }
482
+ if (data.observation_quality !== void 0) {
483
+ let data4 = data.observation_quality;
484
+ if (data4 !== null && typeof data4 !== "string") {
485
+ const err9 = { instancePath: instancePath + "/observation_quality", schemaPath: "#/properties/observation_quality/type", keyword: "type", params: { type: schema34.properties.observation_quality.type }, message: "must be null,string" };
486
+ if (vErrors === null) {
487
+ vErrors = [err9];
488
+ } else {
489
+ vErrors.push(err9);
490
+ }
491
+ errors++;
492
+ }
493
+ if (!(data4 === "clean" || data4 === "flagged" || data4 === "suspect" || data4 === null)) {
494
+ const err10 = { instancePath: instancePath + "/observation_quality", schemaPath: "#/properties/observation_quality/enum", keyword: "enum", params: { allowedValues: schema34.properties.observation_quality.enum }, message: "must be equal to one of the allowed values" };
495
+ if (vErrors === null) {
496
+ vErrors = [err10];
497
+ } else {
498
+ vErrors.push(err10);
499
+ }
500
+ errors++;
501
+ }
502
+ }
503
+ if (data.observation_type !== void 0) {
504
+ let data5 = data.observation_type;
505
+ if (typeof data5 !== "string") {
506
+ const err11 = { instancePath: instancePath + "/observation_type", schemaPath: "#/properties/observation_type/type", keyword: "type", params: { type: "string" }, message: "must be string" };
507
+ if (vErrors === null) {
508
+ vErrors = [err11];
509
+ } else {
510
+ vErrors.push(err11);
511
+ }
512
+ errors++;
513
+ }
514
+ if (!(data5 === "METAR" || data5 === "SPECI")) {
515
+ const err12 = { instancePath: instancePath + "/observation_type", schemaPath: "#/properties/observation_type/enum", keyword: "enum", params: { allowedValues: schema34.properties.observation_type.enum }, message: "must be equal to one of the allowed values" };
516
+ if (vErrors === null) {
517
+ vErrors = [err12];
518
+ } else {
519
+ vErrors.push(err12);
520
+ }
521
+ errors++;
522
+ }
523
+ }
524
+ if (data.observed_at !== void 0) {
525
+ if (!(typeof data.observed_at === "string")) {
526
+ const err13 = { instancePath: instancePath + "/observed_at", schemaPath: "#/properties/observed_at/type", keyword: "type", params: { type: "string" }, message: "must be string" };
527
+ if (vErrors === null) {
528
+ vErrors = [err13];
529
+ } else {
530
+ vErrors.push(err13);
531
+ }
532
+ errors++;
533
+ }
534
+ }
535
+ if (data.parser_name !== void 0) {
536
+ let data7 = data.parser_name;
537
+ if (data7 !== null && typeof data7 !== "string") {
538
+ const err14 = { instancePath: instancePath + "/parser_name", schemaPath: "#/properties/parser_name/type", keyword: "type", params: { type: schema34.properties.parser_name.type }, message: "must be null,string" };
539
+ if (vErrors === null) {
540
+ vErrors = [err14];
541
+ } else {
542
+ vErrors.push(err14);
543
+ }
544
+ errors++;
545
+ }
546
+ if (!(data7 === "ghcnh" || data7 === "iem" || data7 === "mostlyright_v1" || data7 === "ncei" || data7 === null)) {
547
+ const err15 = { instancePath: instancePath + "/parser_name", schemaPath: "#/properties/parser_name/enum", keyword: "enum", params: { allowedValues: schema34.properties.parser_name.enum }, message: "must be equal to one of the allowed values" };
548
+ if (vErrors === null) {
549
+ vErrors = [err15];
550
+ } else {
551
+ vErrors.push(err15);
552
+ }
553
+ errors++;
554
+ }
555
+ }
556
+ if (data.parser_version !== void 0) {
557
+ let data8 = data.parser_version;
558
+ if (data8 !== null && typeof data8 !== "string") {
559
+ const err16 = { instancePath: instancePath + "/parser_version", schemaPath: "#/properties/parser_version/type", keyword: "type", params: { type: schema34.properties.parser_version.type }, message: "must be null,string" };
560
+ if (vErrors === null) {
561
+ vErrors = [err16];
562
+ } else {
563
+ vErrors.push(err16);
564
+ }
565
+ errors++;
566
+ }
567
+ }
568
+ if (data.provenance !== void 0) {
569
+ let data9 = data.provenance;
570
+ if (data9 !== null && typeof data9 !== "string") {
571
+ const err17 = { instancePath: instancePath + "/provenance", schemaPath: "#/properties/provenance/type", keyword: "type", params: { type: schema34.properties.provenance.type }, message: "must be null,string" };
572
+ if (vErrors === null) {
573
+ vErrors = [err17];
574
+ } else {
575
+ vErrors.push(err17);
576
+ }
577
+ errors++;
578
+ }
579
+ if (!(data9 === "legacy" || data9 === "reingested" || data9 === null)) {
580
+ const err18 = { instancePath: instancePath + "/provenance", schemaPath: "#/properties/provenance/enum", keyword: "enum", params: { allowedValues: schema34.properties.provenance.enum }, message: "must be equal to one of the allowed values" };
581
+ if (vErrors === null) {
582
+ vErrors = [err18];
583
+ } else {
584
+ vErrors.push(err18);
585
+ }
586
+ errors++;
587
+ }
588
+ }
589
+ if (data.qc_status !== void 0) {
590
+ let data10 = data.qc_status;
591
+ if (data10 !== null && typeof data10 !== "string") {
592
+ const err19 = { instancePath: instancePath + "/qc_status", schemaPath: "#/properties/qc_status/type", keyword: "type", params: { type: schema34.properties.qc_status.type }, message: "must be null,string" };
593
+ if (vErrors === null) {
594
+ vErrors = [err19];
595
+ } else {
596
+ vErrors.push(err19);
597
+ }
598
+ errors++;
599
+ }
600
+ if (!(data10 === "clean" || data10 === "flagged" || data10 === "suspect" || data10 === null)) {
601
+ const err20 = { instancePath: instancePath + "/qc_status", schemaPath: "#/properties/qc_status/enum", keyword: "enum", params: { allowedValues: schema34.properties.qc_status.enum }, message: "must be equal to one of the allowed values" };
602
+ if (vErrors === null) {
603
+ vErrors = [err20];
604
+ } else {
605
+ vErrors.push(err20);
606
+ }
607
+ errors++;
608
+ }
609
+ }
610
+ if (data.source !== void 0) {
611
+ let data11 = data.source;
612
+ if (typeof data11 !== "string") {
613
+ const err21 = { instancePath: instancePath + "/source", schemaPath: "#/properties/source/type", keyword: "type", params: { type: "string" }, message: "must be string" };
614
+ if (vErrors === null) {
615
+ vErrors = [err21];
616
+ } else {
617
+ vErrors.push(err21);
618
+ }
619
+ errors++;
620
+ }
621
+ if (!(data11 === "awc" || data11 === "ghcnh" || data11 === "iem" || data11 === "ncei")) {
622
+ const err22 = { instancePath: instancePath + "/source", schemaPath: "#/properties/source/enum", keyword: "enum", params: { allowedValues: schema34.properties.source.enum }, message: "must be equal to one of the allowed values" };
623
+ if (vErrors === null) {
624
+ vErrors = [err22];
625
+ } else {
626
+ vErrors.push(err22);
627
+ }
628
+ errors++;
629
+ }
630
+ }
631
+ if (data.source_received_at !== void 0) {
632
+ let data12 = data.source_received_at;
633
+ if (data12 !== null && typeof data12 !== "string") {
634
+ const err23 = { instancePath: instancePath + "/source_received_at", schemaPath: "#/properties/source_received_at/type", keyword: "type", params: { type: schema34.properties.source_received_at.type }, message: "must be null,string" };
635
+ if (vErrors === null) {
636
+ vErrors = [err23];
637
+ } else {
638
+ vErrors.push(err23);
639
+ }
640
+ errors++;
641
+ }
642
+ }
643
+ if (data.station_code !== void 0) {
644
+ if (typeof data.station_code !== "string") {
645
+ const err24 = { instancePath: instancePath + "/station_code", schemaPath: "#/properties/station_code/type", keyword: "type", params: { type: "string" }, message: "must be string" };
646
+ if (vErrors === null) {
647
+ vErrors = [err24];
648
+ } else {
649
+ vErrors.push(err24);
650
+ }
651
+ errors++;
652
+ }
653
+ }
654
+ if (data.temp_c !== void 0) {
655
+ let data14 = data.temp_c;
656
+ if (data14 !== null && !(typeof data14 == "number")) {
657
+ const err25 = { instancePath: instancePath + "/temp_c", schemaPath: "#/properties/temp_c/type", keyword: "type", params: { type: schema34.properties.temp_c.type }, message: "must be null,number" };
658
+ if (vErrors === null) {
659
+ vErrors = [err25];
660
+ } else {
661
+ vErrors.push(err25);
662
+ }
663
+ errors++;
664
+ }
665
+ }
666
+ } else {
667
+ const err26 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
668
+ if (vErrors === null) {
669
+ vErrors = [err26];
670
+ } else {
671
+ vErrors.push(err26);
672
+ }
673
+ errors++;
674
+ }
675
+ validate23.errors = vErrors;
676
+ return errors === 0;
677
+ }
678
+ validate23.evaluated = { "props": { "as_of_time": true, "dewpoint_c": true, "ingestion_id": true, "observation_kind": true, "observation_quality": true, "observation_type": true, "observed_at": true, "parser_name": true, "parser_version": true, "provenance": true, "qc_status": true, "source": true, "source_received_at": true, "station_code": true, "temp_c": true }, "dynamicProps": false, "dynamicItems": false };
679
+
680
+ // src/schemas/validators/schema_observation_qc_v1.js
681
+ var schema_observation_qc_v1 = validate24;
682
+ var schema35 = { "$id": "https://mostlyright.dev/schemas/schema.observation_qc.v1.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "as_of_time": { "format": "date-time", "type": ["null", "string"] }, "detector_metadata": { "description": "JSON-serialized detector payload; shape per qc_system.", "type": ["null", "string"] }, "field": { "description": "Observation column the rule evaluated (e.g. temp_c).", "type": "string" }, "flag": { "enum": ["clean", "flagged", "suspect"], "type": "string" }, "ingestion_id": { "type": ["null", "string"] }, "observation_kind": { "enum": ["METAR", "SPECI", null], "type": ["null", "string"] }, "observed_at": { "format": "date-time", "type": "string" }, "parser_name": { "type": ["null", "string"] }, "qc_system": { "type": "string" }, "qc_version": { "type": "string" }, "rule_id": { "type": "string" }, "source": { "enum": ["awc", "ghcnh", "iem", "ncei"], "type": "string" }, "station_code": { "type": "string" } }, "required": ["field", "flag", "observed_at", "qc_system", "qc_version", "rule_id", "source", "station_code"], "title": "schema.observation_qc.v1", "type": "object", "version": "v1" };
683
+ function validate24(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
684
+ ;
685
+ let vErrors = null;
686
+ let errors = 0;
687
+ const evaluated0 = validate24.evaluated;
688
+ if (evaluated0.dynamicProps) {
689
+ evaluated0.props = void 0;
690
+ }
691
+ if (evaluated0.dynamicItems) {
692
+ evaluated0.items = void 0;
693
+ }
694
+ if (data && typeof data == "object" && !Array.isArray(data)) {
695
+ if (data.field === void 0) {
696
+ const err0 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "field" }, message: "must have required property 'field'" };
697
+ if (vErrors === null) {
698
+ vErrors = [err0];
699
+ } else {
700
+ vErrors.push(err0);
701
+ }
702
+ errors++;
703
+ }
704
+ if (data.flag === void 0) {
705
+ const err1 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "flag" }, message: "must have required property 'flag'" };
706
+ if (vErrors === null) {
707
+ vErrors = [err1];
708
+ } else {
709
+ vErrors.push(err1);
710
+ }
711
+ errors++;
712
+ }
713
+ if (data.observed_at === void 0) {
714
+ const err2 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "observed_at" }, message: "must have required property 'observed_at'" };
715
+ if (vErrors === null) {
716
+ vErrors = [err2];
717
+ } else {
718
+ vErrors.push(err2);
719
+ }
720
+ errors++;
721
+ }
722
+ if (data.qc_system === void 0) {
723
+ const err3 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "qc_system" }, message: "must have required property 'qc_system'" };
724
+ if (vErrors === null) {
725
+ vErrors = [err3];
726
+ } else {
727
+ vErrors.push(err3);
728
+ }
729
+ errors++;
730
+ }
731
+ if (data.qc_version === void 0) {
732
+ const err4 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "qc_version" }, message: "must have required property 'qc_version'" };
733
+ if (vErrors === null) {
734
+ vErrors = [err4];
735
+ } else {
736
+ vErrors.push(err4);
737
+ }
738
+ errors++;
739
+ }
740
+ if (data.rule_id === void 0) {
741
+ const err5 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "rule_id" }, message: "must have required property 'rule_id'" };
742
+ if (vErrors === null) {
743
+ vErrors = [err5];
744
+ } else {
745
+ vErrors.push(err5);
746
+ }
747
+ errors++;
748
+ }
749
+ if (data.source === void 0) {
750
+ const err6 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "source" }, message: "must have required property 'source'" };
751
+ if (vErrors === null) {
752
+ vErrors = [err6];
753
+ } else {
754
+ vErrors.push(err6);
755
+ }
756
+ errors++;
757
+ }
758
+ if (data.station_code === void 0) {
759
+ const err7 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "station_code" }, message: "must have required property 'station_code'" };
760
+ if (vErrors === null) {
761
+ vErrors = [err7];
762
+ } else {
763
+ vErrors.push(err7);
764
+ }
765
+ errors++;
766
+ }
767
+ if (data.as_of_time !== void 0) {
768
+ let data0 = data.as_of_time;
769
+ if (data0 !== null && typeof data0 !== "string") {
770
+ const err8 = { instancePath: instancePath + "/as_of_time", schemaPath: "#/properties/as_of_time/type", keyword: "type", params: { type: schema35.properties.as_of_time.type }, message: "must be null,string" };
771
+ if (vErrors === null) {
772
+ vErrors = [err8];
773
+ } else {
774
+ vErrors.push(err8);
775
+ }
776
+ errors++;
777
+ }
778
+ }
779
+ if (data.detector_metadata !== void 0) {
780
+ let data1 = data.detector_metadata;
781
+ if (data1 !== null && typeof data1 !== "string") {
782
+ const err9 = { instancePath: instancePath + "/detector_metadata", schemaPath: "#/properties/detector_metadata/type", keyword: "type", params: { type: schema35.properties.detector_metadata.type }, message: "must be null,string" };
783
+ if (vErrors === null) {
784
+ vErrors = [err9];
785
+ } else {
786
+ vErrors.push(err9);
787
+ }
788
+ errors++;
789
+ }
790
+ }
791
+ if (data.field !== void 0) {
792
+ if (typeof data.field !== "string") {
793
+ const err10 = { instancePath: instancePath + "/field", schemaPath: "#/properties/field/type", keyword: "type", params: { type: "string" }, message: "must be string" };
794
+ if (vErrors === null) {
795
+ vErrors = [err10];
796
+ } else {
797
+ vErrors.push(err10);
798
+ }
799
+ errors++;
800
+ }
801
+ }
802
+ if (data.flag !== void 0) {
803
+ let data3 = data.flag;
804
+ if (typeof data3 !== "string") {
805
+ const err11 = { instancePath: instancePath + "/flag", schemaPath: "#/properties/flag/type", keyword: "type", params: { type: "string" }, message: "must be string" };
806
+ if (vErrors === null) {
807
+ vErrors = [err11];
808
+ } else {
809
+ vErrors.push(err11);
810
+ }
811
+ errors++;
812
+ }
813
+ if (!(data3 === "clean" || data3 === "flagged" || data3 === "suspect")) {
814
+ const err12 = { instancePath: instancePath + "/flag", schemaPath: "#/properties/flag/enum", keyword: "enum", params: { allowedValues: schema35.properties.flag.enum }, message: "must be equal to one of the allowed values" };
815
+ if (vErrors === null) {
816
+ vErrors = [err12];
817
+ } else {
818
+ vErrors.push(err12);
819
+ }
820
+ errors++;
821
+ }
822
+ }
823
+ if (data.ingestion_id !== void 0) {
824
+ let data4 = data.ingestion_id;
825
+ if (data4 !== null && typeof data4 !== "string") {
826
+ const err13 = { instancePath: instancePath + "/ingestion_id", schemaPath: "#/properties/ingestion_id/type", keyword: "type", params: { type: schema35.properties.ingestion_id.type }, message: "must be null,string" };
827
+ if (vErrors === null) {
828
+ vErrors = [err13];
829
+ } else {
830
+ vErrors.push(err13);
831
+ }
832
+ errors++;
833
+ }
834
+ }
835
+ if (data.observation_kind !== void 0) {
836
+ let data5 = data.observation_kind;
837
+ if (data5 !== null && typeof data5 !== "string") {
838
+ const err14 = { instancePath: instancePath + "/observation_kind", schemaPath: "#/properties/observation_kind/type", keyword: "type", params: { type: schema35.properties.observation_kind.type }, message: "must be null,string" };
839
+ if (vErrors === null) {
840
+ vErrors = [err14];
841
+ } else {
842
+ vErrors.push(err14);
843
+ }
844
+ errors++;
845
+ }
846
+ if (!(data5 === "METAR" || data5 === "SPECI" || data5 === null)) {
847
+ const err15 = { instancePath: instancePath + "/observation_kind", schemaPath: "#/properties/observation_kind/enum", keyword: "enum", params: { allowedValues: schema35.properties.observation_kind.enum }, message: "must be equal to one of the allowed values" };
848
+ if (vErrors === null) {
849
+ vErrors = [err15];
850
+ } else {
851
+ vErrors.push(err15);
852
+ }
853
+ errors++;
854
+ }
855
+ }
856
+ if (data.observed_at !== void 0) {
857
+ if (!(typeof data.observed_at === "string")) {
858
+ const err16 = { instancePath: instancePath + "/observed_at", schemaPath: "#/properties/observed_at/type", keyword: "type", params: { type: "string" }, message: "must be string" };
859
+ if (vErrors === null) {
860
+ vErrors = [err16];
861
+ } else {
862
+ vErrors.push(err16);
863
+ }
864
+ errors++;
865
+ }
866
+ }
867
+ if (data.parser_name !== void 0) {
868
+ let data7 = data.parser_name;
869
+ if (data7 !== null && typeof data7 !== "string") {
870
+ const err17 = { instancePath: instancePath + "/parser_name", schemaPath: "#/properties/parser_name/type", keyword: "type", params: { type: schema35.properties.parser_name.type }, message: "must be null,string" };
871
+ if (vErrors === null) {
872
+ vErrors = [err17];
873
+ } else {
874
+ vErrors.push(err17);
875
+ }
876
+ errors++;
877
+ }
878
+ }
879
+ if (data.qc_system !== void 0) {
880
+ if (typeof data.qc_system !== "string") {
881
+ const err18 = { instancePath: instancePath + "/qc_system", schemaPath: "#/properties/qc_system/type", keyword: "type", params: { type: "string" }, message: "must be string" };
882
+ if (vErrors === null) {
883
+ vErrors = [err18];
884
+ } else {
885
+ vErrors.push(err18);
886
+ }
887
+ errors++;
888
+ }
889
+ }
890
+ if (data.qc_version !== void 0) {
891
+ if (typeof data.qc_version !== "string") {
892
+ const err19 = { instancePath: instancePath + "/qc_version", schemaPath: "#/properties/qc_version/type", keyword: "type", params: { type: "string" }, message: "must be string" };
893
+ if (vErrors === null) {
894
+ vErrors = [err19];
895
+ } else {
896
+ vErrors.push(err19);
897
+ }
898
+ errors++;
899
+ }
900
+ }
901
+ if (data.rule_id !== void 0) {
902
+ if (typeof data.rule_id !== "string") {
903
+ const err20 = { instancePath: instancePath + "/rule_id", schemaPath: "#/properties/rule_id/type", keyword: "type", params: { type: "string" }, message: "must be string" };
904
+ if (vErrors === null) {
905
+ vErrors = [err20];
906
+ } else {
907
+ vErrors.push(err20);
908
+ }
909
+ errors++;
910
+ }
911
+ }
912
+ if (data.source !== void 0) {
913
+ let data11 = data.source;
914
+ if (typeof data11 !== "string") {
915
+ const err21 = { instancePath: instancePath + "/source", schemaPath: "#/properties/source/type", keyword: "type", params: { type: "string" }, message: "must be string" };
916
+ if (vErrors === null) {
917
+ vErrors = [err21];
918
+ } else {
919
+ vErrors.push(err21);
920
+ }
921
+ errors++;
922
+ }
923
+ if (!(data11 === "awc" || data11 === "ghcnh" || data11 === "iem" || data11 === "ncei")) {
924
+ const err22 = { instancePath: instancePath + "/source", schemaPath: "#/properties/source/enum", keyword: "enum", params: { allowedValues: schema35.properties.source.enum }, message: "must be equal to one of the allowed values" };
925
+ if (vErrors === null) {
926
+ vErrors = [err22];
927
+ } else {
928
+ vErrors.push(err22);
929
+ }
930
+ errors++;
931
+ }
932
+ }
933
+ if (data.station_code !== void 0) {
934
+ if (typeof data.station_code !== "string") {
935
+ const err23 = { instancePath: instancePath + "/station_code", schemaPath: "#/properties/station_code/type", keyword: "type", params: { type: "string" }, message: "must be string" };
936
+ if (vErrors === null) {
937
+ vErrors = [err23];
938
+ } else {
939
+ vErrors.push(err23);
940
+ }
941
+ errors++;
942
+ }
943
+ }
944
+ } else {
945
+ const err24 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
946
+ if (vErrors === null) {
947
+ vErrors = [err24];
948
+ } else {
949
+ vErrors.push(err24);
950
+ }
951
+ errors++;
952
+ }
953
+ validate24.errors = vErrors;
954
+ return errors === 0;
955
+ }
956
+ validate24.evaluated = { "props": { "as_of_time": true, "detector_metadata": true, "field": true, "flag": true, "ingestion_id": true, "observation_kind": true, "observed_at": true, "parser_name": true, "qc_system": true, "qc_version": true, "rule_id": true, "source": true, "station_code": true }, "dynamicProps": false, "dynamicItems": false };
957
+
958
+ // src/schemas/validators/schema_observation_v1.js
959
+ var schema_observation_v1 = validate20;
960
+ var schema31 = { "$id": "https://mostlyright.dev/schemas/schema.observation.v1.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "imperialRenames": { "dew_point_c": "dew_point_F", "event_time": "utc_datetime", "precip_mm_1h": "precip_in_1h", "sky_base_1_m": "sky_base_1_ft", "sky_base_2_m": "sky_base_2_ft", "sky_base_3_m": "sky_base_3_ft", "sky_base_4_m": "sky_base_4_ft", "temp_c": "temp_F", "visibility_m": "vsby", "wind_gust_ms": "gust_kt", "wind_speed_ms": "wind_speed_kt" }, "properties": { "dew_point_c": { "description": "units: celsius \u2014 bounded", "type": ["null", "number"] }, "event_time": { "description": "observation valid time", "format": "date-time", "type": "string" }, "metar_raw": { "description": "raw METAR text if source has it; null for AWC JSON (structured-only)", "type": ["null", "string"] }, "observation_type": { "description": "METAR | SPECI; defaults METAR when source can't distinguish (e.g. AWC JSON)", "enum": ["METAR", "SPECI"], "type": "string" }, "precip_mm_1h": { "description": "units: mm \u2014 hourly precip (METAR p01i, converted from inches)", "type": ["null", "number"] }, "sky_base_1_m": { "description": "units: meters \u2014 first cloud layer base height (converted from feet)", "type": ["null", "number"] }, "sky_base_2_m": { "description": "units: meters", "type": ["null", "number"] }, "sky_base_3_m": { "description": "units: meters", "type": ["null", "number"] }, "sky_base_4_m": { "description": "units: meters", "type": ["null", "number"] }, "sky_cover_1": { "description": "first cloud layer cover code", "enum": ["BKN", "CLR", "FEW", "OVC", "SCT", "VV", null], "type": ["null", "string"] }, "sky_cover_2": { "description": "second layer; null if not present", "enum": ["BKN", "CLR", "FEW", "OVC", "SCT", "VV", null], "type": ["null", "string"] }, "sky_cover_3": { "description": "third layer; null if not present", "enum": ["BKN", "CLR", "FEW", "OVC", "SCT", "VV", null], "type": ["null", "string"] }, "sky_cover_4": { "description": "fourth layer; null if not present", "enum": ["BKN", "CLR", "FEW", "OVC", "SCT", "VV", null], "type": ["null", "string"] }, "slp_hpa": { "description": "units: hPa \u2014 sea-level pressure (canonical aviation unit, not converted across modes)", "type": ["null", "number"] }, "station": { "description": "ICAO/ASOS station ID (e.g. KORD)", "type": "string" }, "temp_c": { "description": "units: celsius \u2014 bounded TEMP_MIN_C..TEMP_MAX_C", "type": ["null", "number"] }, "visibility_m": { "description": "units: meters \u2014 converted from statute miles", "type": ["null", "number"] }, "wind_dir_deg": { "description": "units: degrees \u2014 0-360, bounded", "type": ["integer", "null"] }, "wind_gust_ms": { "description": "units: m/s \u2014 converted from kt", "type": ["null", "number"] }, "wind_speed_ms": { "description": "units: m/s \u2014 converted from kt", "type": ["null", "number"] } }, "required": ["event_time", "observation_type", "station"], "title": "schema.observation.v1", "type": "object", "version": "v1" };
961
+ function validate20(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
962
+ ;
963
+ let vErrors = null;
964
+ let errors = 0;
965
+ const evaluated0 = validate20.evaluated;
966
+ if (evaluated0.dynamicProps) {
967
+ evaluated0.props = void 0;
968
+ }
969
+ if (evaluated0.dynamicItems) {
970
+ evaluated0.items = void 0;
971
+ }
972
+ if (data && typeof data == "object" && !Array.isArray(data)) {
973
+ if (data.event_time === void 0) {
974
+ const err0 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "event_time" }, message: "must have required property 'event_time'" };
975
+ if (vErrors === null) {
976
+ vErrors = [err0];
977
+ } else {
978
+ vErrors.push(err0);
979
+ }
980
+ errors++;
981
+ }
982
+ if (data.observation_type === void 0) {
983
+ const err1 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "observation_type" }, message: "must have required property 'observation_type'" };
984
+ if (vErrors === null) {
985
+ vErrors = [err1];
986
+ } else {
987
+ vErrors.push(err1);
988
+ }
989
+ errors++;
990
+ }
991
+ if (data.station === void 0) {
992
+ const err2 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "station" }, message: "must have required property 'station'" };
993
+ if (vErrors === null) {
994
+ vErrors = [err2];
995
+ } else {
996
+ vErrors.push(err2);
997
+ }
998
+ errors++;
999
+ }
1000
+ if (data.dew_point_c !== void 0) {
1001
+ let data0 = data.dew_point_c;
1002
+ if (data0 !== null && !(typeof data0 == "number")) {
1003
+ const err3 = { instancePath: instancePath + "/dew_point_c", schemaPath: "#/properties/dew_point_c/type", keyword: "type", params: { type: schema31.properties.dew_point_c.type }, message: "must be null,number" };
1004
+ if (vErrors === null) {
1005
+ vErrors = [err3];
1006
+ } else {
1007
+ vErrors.push(err3);
1008
+ }
1009
+ errors++;
1010
+ }
1011
+ }
1012
+ if (data.event_time !== void 0) {
1013
+ if (!(typeof data.event_time === "string")) {
1014
+ const err4 = { instancePath: instancePath + "/event_time", schemaPath: "#/properties/event_time/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1015
+ if (vErrors === null) {
1016
+ vErrors = [err4];
1017
+ } else {
1018
+ vErrors.push(err4);
1019
+ }
1020
+ errors++;
1021
+ }
1022
+ }
1023
+ if (data.metar_raw !== void 0) {
1024
+ let data2 = data.metar_raw;
1025
+ if (data2 !== null && typeof data2 !== "string") {
1026
+ const err5 = { instancePath: instancePath + "/metar_raw", schemaPath: "#/properties/metar_raw/type", keyword: "type", params: { type: schema31.properties.metar_raw.type }, message: "must be null,string" };
1027
+ if (vErrors === null) {
1028
+ vErrors = [err5];
1029
+ } else {
1030
+ vErrors.push(err5);
1031
+ }
1032
+ errors++;
1033
+ }
1034
+ }
1035
+ if (data.observation_type !== void 0) {
1036
+ let data3 = data.observation_type;
1037
+ if (typeof data3 !== "string") {
1038
+ const err6 = { instancePath: instancePath + "/observation_type", schemaPath: "#/properties/observation_type/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1039
+ if (vErrors === null) {
1040
+ vErrors = [err6];
1041
+ } else {
1042
+ vErrors.push(err6);
1043
+ }
1044
+ errors++;
1045
+ }
1046
+ if (!(data3 === "METAR" || data3 === "SPECI")) {
1047
+ const err7 = { instancePath: instancePath + "/observation_type", schemaPath: "#/properties/observation_type/enum", keyword: "enum", params: { allowedValues: schema31.properties.observation_type.enum }, message: "must be equal to one of the allowed values" };
1048
+ if (vErrors === null) {
1049
+ vErrors = [err7];
1050
+ } else {
1051
+ vErrors.push(err7);
1052
+ }
1053
+ errors++;
1054
+ }
1055
+ }
1056
+ if (data.precip_mm_1h !== void 0) {
1057
+ let data4 = data.precip_mm_1h;
1058
+ if (data4 !== null && !(typeof data4 == "number")) {
1059
+ const err8 = { instancePath: instancePath + "/precip_mm_1h", schemaPath: "#/properties/precip_mm_1h/type", keyword: "type", params: { type: schema31.properties.precip_mm_1h.type }, message: "must be null,number" };
1060
+ if (vErrors === null) {
1061
+ vErrors = [err8];
1062
+ } else {
1063
+ vErrors.push(err8);
1064
+ }
1065
+ errors++;
1066
+ }
1067
+ }
1068
+ if (data.sky_base_1_m !== void 0) {
1069
+ let data5 = data.sky_base_1_m;
1070
+ if (data5 !== null && !(typeof data5 == "number")) {
1071
+ const err9 = { instancePath: instancePath + "/sky_base_1_m", schemaPath: "#/properties/sky_base_1_m/type", keyword: "type", params: { type: schema31.properties.sky_base_1_m.type }, message: "must be null,number" };
1072
+ if (vErrors === null) {
1073
+ vErrors = [err9];
1074
+ } else {
1075
+ vErrors.push(err9);
1076
+ }
1077
+ errors++;
1078
+ }
1079
+ }
1080
+ if (data.sky_base_2_m !== void 0) {
1081
+ let data6 = data.sky_base_2_m;
1082
+ if (data6 !== null && !(typeof data6 == "number")) {
1083
+ const err10 = { instancePath: instancePath + "/sky_base_2_m", schemaPath: "#/properties/sky_base_2_m/type", keyword: "type", params: { type: schema31.properties.sky_base_2_m.type }, message: "must be null,number" };
1084
+ if (vErrors === null) {
1085
+ vErrors = [err10];
1086
+ } else {
1087
+ vErrors.push(err10);
1088
+ }
1089
+ errors++;
1090
+ }
1091
+ }
1092
+ if (data.sky_base_3_m !== void 0) {
1093
+ let data7 = data.sky_base_3_m;
1094
+ if (data7 !== null && !(typeof data7 == "number")) {
1095
+ const err11 = { instancePath: instancePath + "/sky_base_3_m", schemaPath: "#/properties/sky_base_3_m/type", keyword: "type", params: { type: schema31.properties.sky_base_3_m.type }, message: "must be null,number" };
1096
+ if (vErrors === null) {
1097
+ vErrors = [err11];
1098
+ } else {
1099
+ vErrors.push(err11);
1100
+ }
1101
+ errors++;
1102
+ }
1103
+ }
1104
+ if (data.sky_base_4_m !== void 0) {
1105
+ let data8 = data.sky_base_4_m;
1106
+ if (data8 !== null && !(typeof data8 == "number")) {
1107
+ const err12 = { instancePath: instancePath + "/sky_base_4_m", schemaPath: "#/properties/sky_base_4_m/type", keyword: "type", params: { type: schema31.properties.sky_base_4_m.type }, message: "must be null,number" };
1108
+ if (vErrors === null) {
1109
+ vErrors = [err12];
1110
+ } else {
1111
+ vErrors.push(err12);
1112
+ }
1113
+ errors++;
1114
+ }
1115
+ }
1116
+ if (data.sky_cover_1 !== void 0) {
1117
+ let data9 = data.sky_cover_1;
1118
+ if (data9 !== null && typeof data9 !== "string") {
1119
+ const err13 = { instancePath: instancePath + "/sky_cover_1", schemaPath: "#/properties/sky_cover_1/type", keyword: "type", params: { type: schema31.properties.sky_cover_1.type }, message: "must be null,string" };
1120
+ if (vErrors === null) {
1121
+ vErrors = [err13];
1122
+ } else {
1123
+ vErrors.push(err13);
1124
+ }
1125
+ errors++;
1126
+ }
1127
+ if (!(data9 === "BKN" || data9 === "CLR" || data9 === "FEW" || data9 === "OVC" || data9 === "SCT" || data9 === "VV" || data9 === null)) {
1128
+ const err14 = { instancePath: instancePath + "/sky_cover_1", schemaPath: "#/properties/sky_cover_1/enum", keyword: "enum", params: { allowedValues: schema31.properties.sky_cover_1.enum }, message: "must be equal to one of the allowed values" };
1129
+ if (vErrors === null) {
1130
+ vErrors = [err14];
1131
+ } else {
1132
+ vErrors.push(err14);
1133
+ }
1134
+ errors++;
1135
+ }
1136
+ }
1137
+ if (data.sky_cover_2 !== void 0) {
1138
+ let data10 = data.sky_cover_2;
1139
+ if (data10 !== null && typeof data10 !== "string") {
1140
+ const err15 = { instancePath: instancePath + "/sky_cover_2", schemaPath: "#/properties/sky_cover_2/type", keyword: "type", params: { type: schema31.properties.sky_cover_2.type }, message: "must be null,string" };
1141
+ if (vErrors === null) {
1142
+ vErrors = [err15];
1143
+ } else {
1144
+ vErrors.push(err15);
1145
+ }
1146
+ errors++;
1147
+ }
1148
+ if (!(data10 === "BKN" || data10 === "CLR" || data10 === "FEW" || data10 === "OVC" || data10 === "SCT" || data10 === "VV" || data10 === null)) {
1149
+ const err16 = { instancePath: instancePath + "/sky_cover_2", schemaPath: "#/properties/sky_cover_2/enum", keyword: "enum", params: { allowedValues: schema31.properties.sky_cover_2.enum }, message: "must be equal to one of the allowed values" };
1150
+ if (vErrors === null) {
1151
+ vErrors = [err16];
1152
+ } else {
1153
+ vErrors.push(err16);
1154
+ }
1155
+ errors++;
1156
+ }
1157
+ }
1158
+ if (data.sky_cover_3 !== void 0) {
1159
+ let data11 = data.sky_cover_3;
1160
+ if (data11 !== null && typeof data11 !== "string") {
1161
+ const err17 = { instancePath: instancePath + "/sky_cover_3", schemaPath: "#/properties/sky_cover_3/type", keyword: "type", params: { type: schema31.properties.sky_cover_3.type }, message: "must be null,string" };
1162
+ if (vErrors === null) {
1163
+ vErrors = [err17];
1164
+ } else {
1165
+ vErrors.push(err17);
1166
+ }
1167
+ errors++;
1168
+ }
1169
+ if (!(data11 === "BKN" || data11 === "CLR" || data11 === "FEW" || data11 === "OVC" || data11 === "SCT" || data11 === "VV" || data11 === null)) {
1170
+ const err18 = { instancePath: instancePath + "/sky_cover_3", schemaPath: "#/properties/sky_cover_3/enum", keyword: "enum", params: { allowedValues: schema31.properties.sky_cover_3.enum }, message: "must be equal to one of the allowed values" };
1171
+ if (vErrors === null) {
1172
+ vErrors = [err18];
1173
+ } else {
1174
+ vErrors.push(err18);
1175
+ }
1176
+ errors++;
1177
+ }
1178
+ }
1179
+ if (data.sky_cover_4 !== void 0) {
1180
+ let data12 = data.sky_cover_4;
1181
+ if (data12 !== null && typeof data12 !== "string") {
1182
+ const err19 = { instancePath: instancePath + "/sky_cover_4", schemaPath: "#/properties/sky_cover_4/type", keyword: "type", params: { type: schema31.properties.sky_cover_4.type }, message: "must be null,string" };
1183
+ if (vErrors === null) {
1184
+ vErrors = [err19];
1185
+ } else {
1186
+ vErrors.push(err19);
1187
+ }
1188
+ errors++;
1189
+ }
1190
+ if (!(data12 === "BKN" || data12 === "CLR" || data12 === "FEW" || data12 === "OVC" || data12 === "SCT" || data12 === "VV" || data12 === null)) {
1191
+ const err20 = { instancePath: instancePath + "/sky_cover_4", schemaPath: "#/properties/sky_cover_4/enum", keyword: "enum", params: { allowedValues: schema31.properties.sky_cover_4.enum }, message: "must be equal to one of the allowed values" };
1192
+ if (vErrors === null) {
1193
+ vErrors = [err20];
1194
+ } else {
1195
+ vErrors.push(err20);
1196
+ }
1197
+ errors++;
1198
+ }
1199
+ }
1200
+ if (data.slp_hpa !== void 0) {
1201
+ let data13 = data.slp_hpa;
1202
+ if (data13 !== null && !(typeof data13 == "number")) {
1203
+ const err21 = { instancePath: instancePath + "/slp_hpa", schemaPath: "#/properties/slp_hpa/type", keyword: "type", params: { type: schema31.properties.slp_hpa.type }, message: "must be null,number" };
1204
+ if (vErrors === null) {
1205
+ vErrors = [err21];
1206
+ } else {
1207
+ vErrors.push(err21);
1208
+ }
1209
+ errors++;
1210
+ }
1211
+ }
1212
+ if (data.station !== void 0) {
1213
+ if (typeof data.station !== "string") {
1214
+ const err22 = { instancePath: instancePath + "/station", schemaPath: "#/properties/station/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1215
+ if (vErrors === null) {
1216
+ vErrors = [err22];
1217
+ } else {
1218
+ vErrors.push(err22);
1219
+ }
1220
+ errors++;
1221
+ }
1222
+ }
1223
+ if (data.temp_c !== void 0) {
1224
+ let data15 = data.temp_c;
1225
+ if (data15 !== null && !(typeof data15 == "number")) {
1226
+ const err23 = { instancePath: instancePath + "/temp_c", schemaPath: "#/properties/temp_c/type", keyword: "type", params: { type: schema31.properties.temp_c.type }, message: "must be null,number" };
1227
+ if (vErrors === null) {
1228
+ vErrors = [err23];
1229
+ } else {
1230
+ vErrors.push(err23);
1231
+ }
1232
+ errors++;
1233
+ }
1234
+ }
1235
+ if (data.visibility_m !== void 0) {
1236
+ let data16 = data.visibility_m;
1237
+ if (data16 !== null && !(typeof data16 == "number")) {
1238
+ const err24 = { instancePath: instancePath + "/visibility_m", schemaPath: "#/properties/visibility_m/type", keyword: "type", params: { type: schema31.properties.visibility_m.type }, message: "must be null,number" };
1239
+ if (vErrors === null) {
1240
+ vErrors = [err24];
1241
+ } else {
1242
+ vErrors.push(err24);
1243
+ }
1244
+ errors++;
1245
+ }
1246
+ }
1247
+ if (data.wind_dir_deg !== void 0) {
1248
+ let data17 = data.wind_dir_deg;
1249
+ if (!(typeof data17 == "number" && (!(data17 % 1) && !isNaN(data17))) && data17 !== null) {
1250
+ const err25 = { instancePath: instancePath + "/wind_dir_deg", schemaPath: "#/properties/wind_dir_deg/type", keyword: "type", params: { type: schema31.properties.wind_dir_deg.type }, message: "must be integer,null" };
1251
+ if (vErrors === null) {
1252
+ vErrors = [err25];
1253
+ } else {
1254
+ vErrors.push(err25);
1255
+ }
1256
+ errors++;
1257
+ }
1258
+ }
1259
+ if (data.wind_gust_ms !== void 0) {
1260
+ let data18 = data.wind_gust_ms;
1261
+ if (data18 !== null && !(typeof data18 == "number")) {
1262
+ const err26 = { instancePath: instancePath + "/wind_gust_ms", schemaPath: "#/properties/wind_gust_ms/type", keyword: "type", params: { type: schema31.properties.wind_gust_ms.type }, message: "must be null,number" };
1263
+ if (vErrors === null) {
1264
+ vErrors = [err26];
1265
+ } else {
1266
+ vErrors.push(err26);
1267
+ }
1268
+ errors++;
1269
+ }
1270
+ }
1271
+ if (data.wind_speed_ms !== void 0) {
1272
+ let data19 = data.wind_speed_ms;
1273
+ if (data19 !== null && !(typeof data19 == "number")) {
1274
+ const err27 = { instancePath: instancePath + "/wind_speed_ms", schemaPath: "#/properties/wind_speed_ms/type", keyword: "type", params: { type: schema31.properties.wind_speed_ms.type }, message: "must be null,number" };
1275
+ if (vErrors === null) {
1276
+ vErrors = [err27];
1277
+ } else {
1278
+ vErrors.push(err27);
1279
+ }
1280
+ errors++;
1281
+ }
1282
+ }
1283
+ } else {
1284
+ const err28 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
1285
+ if (vErrors === null) {
1286
+ vErrors = [err28];
1287
+ } else {
1288
+ vErrors.push(err28);
1289
+ }
1290
+ errors++;
1291
+ }
1292
+ validate20.errors = vErrors;
1293
+ return errors === 0;
1294
+ }
1295
+ validate20.evaluated = { "props": { "dew_point_c": true, "event_time": true, "metar_raw": true, "observation_type": true, "precip_mm_1h": true, "sky_base_1_m": true, "sky_base_2_m": true, "sky_base_3_m": true, "sky_base_4_m": true, "sky_cover_1": true, "sky_cover_2": true, "sky_cover_3": true, "sky_cover_4": true, "slp_hpa": true, "station": true, "temp_c": true, "visibility_m": true, "wind_dir_deg": true, "wind_gust_ms": true, "wind_speed_ms": true }, "dynamicProps": false, "dynamicItems": false };
1296
+
1297
+ // src/schemas/validators/schema_settlement_cli_v1.js
1298
+ var schema_settlement_cli_v1 = validate22;
1299
+ var schema33 = { "$id": "https://mostlyright.dev/schemas/schema.settlement.cli.v1.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "cli_data_quality": { "description": "NWS CLI data-quality marker (Pitfall 6/16). Allows downstream code to filter or weight settlement rows by issuer quality without re-parsing the product header.", "enum": ["clean", "flagged_instrument", "flagged_late", "flagged_other", "missing"], "type": "string" }, "event_time": { "description": "00:00 local time on observation_date converted to UTC; for sort/join only", "format": "date-time", "type": "string" }, "observation_date": { "description": "local climate day per NWS convention (no timezone applied to the date itself)", "format": "date", "type": "string" }, "precipitation_in": { "description": "units: inches", "type": ["null", "number"] }, "product_release_time": { "description": "parsed from CLI product header (_climate.py::_parse_product_timestamp)", "format": "date-time", "type": "string" }, "report_type": { "description": "preliminary | final | correction; dedup priority preliminary < final < correction", "enum": ["correction", "final", "preliminary"], "type": "string" }, "settlement_finality": { "description": "provisional | final | superseded. Kalshi NHIGH/NLOW settlement contractually requires 'final'; 'provisional' values are kept for early-look research only.", "enum": ["final", "provisional", "superseded"], "type": "string" }, "snowfall_in": { "description": "units: inches", "type": ["null", "number"] }, "station": { "description": "ICAO/ASOS station ID", "type": "string" }, "station_tz": { "description": "IANA timezone for the station (e.g. America/Chicago for KORD). Required for local-climate-day semantics; see \xA7U.", "type": "string" }, "temp_max_F": { "description": "units: fahrenheit \u2014 daily high (uppercase F for consistency with obs imperial mode)", "type": ["null", "number"] }, "temp_min_F": { "description": "units: fahrenheit \u2014 daily low", "type": ["null", "number"] } }, "required": ["cli_data_quality", "event_time", "observation_date", "product_release_time", "report_type", "settlement_finality", "station", "station_tz"], "title": "schema.settlement.cli.v1", "type": "object", "version": "v1" };
1300
+ function validate22(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
1301
+ ;
1302
+ let vErrors = null;
1303
+ let errors = 0;
1304
+ const evaluated0 = validate22.evaluated;
1305
+ if (evaluated0.dynamicProps) {
1306
+ evaluated0.props = void 0;
1307
+ }
1308
+ if (evaluated0.dynamicItems) {
1309
+ evaluated0.items = void 0;
1310
+ }
1311
+ if (data && typeof data == "object" && !Array.isArray(data)) {
1312
+ if (data.cli_data_quality === void 0) {
1313
+ const err0 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "cli_data_quality" }, message: "must have required property 'cli_data_quality'" };
1314
+ if (vErrors === null) {
1315
+ vErrors = [err0];
1316
+ } else {
1317
+ vErrors.push(err0);
1318
+ }
1319
+ errors++;
1320
+ }
1321
+ if (data.event_time === void 0) {
1322
+ const err1 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "event_time" }, message: "must have required property 'event_time'" };
1323
+ if (vErrors === null) {
1324
+ vErrors = [err1];
1325
+ } else {
1326
+ vErrors.push(err1);
1327
+ }
1328
+ errors++;
1329
+ }
1330
+ if (data.observation_date === void 0) {
1331
+ const err2 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "observation_date" }, message: "must have required property 'observation_date'" };
1332
+ if (vErrors === null) {
1333
+ vErrors = [err2];
1334
+ } else {
1335
+ vErrors.push(err2);
1336
+ }
1337
+ errors++;
1338
+ }
1339
+ if (data.product_release_time === void 0) {
1340
+ const err3 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "product_release_time" }, message: "must have required property 'product_release_time'" };
1341
+ if (vErrors === null) {
1342
+ vErrors = [err3];
1343
+ } else {
1344
+ vErrors.push(err3);
1345
+ }
1346
+ errors++;
1347
+ }
1348
+ if (data.report_type === void 0) {
1349
+ const err4 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "report_type" }, message: "must have required property 'report_type'" };
1350
+ if (vErrors === null) {
1351
+ vErrors = [err4];
1352
+ } else {
1353
+ vErrors.push(err4);
1354
+ }
1355
+ errors++;
1356
+ }
1357
+ if (data.settlement_finality === void 0) {
1358
+ const err5 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "settlement_finality" }, message: "must have required property 'settlement_finality'" };
1359
+ if (vErrors === null) {
1360
+ vErrors = [err5];
1361
+ } else {
1362
+ vErrors.push(err5);
1363
+ }
1364
+ errors++;
1365
+ }
1366
+ if (data.station === void 0) {
1367
+ const err6 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "station" }, message: "must have required property 'station'" };
1368
+ if (vErrors === null) {
1369
+ vErrors = [err6];
1370
+ } else {
1371
+ vErrors.push(err6);
1372
+ }
1373
+ errors++;
1374
+ }
1375
+ if (data.station_tz === void 0) {
1376
+ const err7 = { instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: "station_tz" }, message: "must have required property 'station_tz'" };
1377
+ if (vErrors === null) {
1378
+ vErrors = [err7];
1379
+ } else {
1380
+ vErrors.push(err7);
1381
+ }
1382
+ errors++;
1383
+ }
1384
+ if (data.cli_data_quality !== void 0) {
1385
+ let data0 = data.cli_data_quality;
1386
+ if (typeof data0 !== "string") {
1387
+ const err8 = { instancePath: instancePath + "/cli_data_quality", schemaPath: "#/properties/cli_data_quality/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1388
+ if (vErrors === null) {
1389
+ vErrors = [err8];
1390
+ } else {
1391
+ vErrors.push(err8);
1392
+ }
1393
+ errors++;
1394
+ }
1395
+ if (!(data0 === "clean" || data0 === "flagged_instrument" || data0 === "flagged_late" || data0 === "flagged_other" || data0 === "missing")) {
1396
+ const err9 = { instancePath: instancePath + "/cli_data_quality", schemaPath: "#/properties/cli_data_quality/enum", keyword: "enum", params: { allowedValues: schema33.properties.cli_data_quality.enum }, message: "must be equal to one of the allowed values" };
1397
+ if (vErrors === null) {
1398
+ vErrors = [err9];
1399
+ } else {
1400
+ vErrors.push(err9);
1401
+ }
1402
+ errors++;
1403
+ }
1404
+ }
1405
+ if (data.event_time !== void 0) {
1406
+ if (!(typeof data.event_time === "string")) {
1407
+ const err10 = { instancePath: instancePath + "/event_time", schemaPath: "#/properties/event_time/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1408
+ if (vErrors === null) {
1409
+ vErrors = [err10];
1410
+ } else {
1411
+ vErrors.push(err10);
1412
+ }
1413
+ errors++;
1414
+ }
1415
+ }
1416
+ if (data.observation_date !== void 0) {
1417
+ if (!(typeof data.observation_date === "string")) {
1418
+ const err11 = { instancePath: instancePath + "/observation_date", schemaPath: "#/properties/observation_date/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1419
+ if (vErrors === null) {
1420
+ vErrors = [err11];
1421
+ } else {
1422
+ vErrors.push(err11);
1423
+ }
1424
+ errors++;
1425
+ }
1426
+ }
1427
+ if (data.precipitation_in !== void 0) {
1428
+ let data3 = data.precipitation_in;
1429
+ if (data3 !== null && !(typeof data3 == "number")) {
1430
+ const err12 = { instancePath: instancePath + "/precipitation_in", schemaPath: "#/properties/precipitation_in/type", keyword: "type", params: { type: schema33.properties.precipitation_in.type }, message: "must be null,number" };
1431
+ if (vErrors === null) {
1432
+ vErrors = [err12];
1433
+ } else {
1434
+ vErrors.push(err12);
1435
+ }
1436
+ errors++;
1437
+ }
1438
+ }
1439
+ if (data.product_release_time !== void 0) {
1440
+ if (!(typeof data.product_release_time === "string")) {
1441
+ const err13 = { instancePath: instancePath + "/product_release_time", schemaPath: "#/properties/product_release_time/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1442
+ if (vErrors === null) {
1443
+ vErrors = [err13];
1444
+ } else {
1445
+ vErrors.push(err13);
1446
+ }
1447
+ errors++;
1448
+ }
1449
+ }
1450
+ if (data.report_type !== void 0) {
1451
+ let data5 = data.report_type;
1452
+ if (typeof data5 !== "string") {
1453
+ const err14 = { instancePath: instancePath + "/report_type", schemaPath: "#/properties/report_type/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1454
+ if (vErrors === null) {
1455
+ vErrors = [err14];
1456
+ } else {
1457
+ vErrors.push(err14);
1458
+ }
1459
+ errors++;
1460
+ }
1461
+ if (!(data5 === "correction" || data5 === "final" || data5 === "preliminary")) {
1462
+ const err15 = { instancePath: instancePath + "/report_type", schemaPath: "#/properties/report_type/enum", keyword: "enum", params: { allowedValues: schema33.properties.report_type.enum }, message: "must be equal to one of the allowed values" };
1463
+ if (vErrors === null) {
1464
+ vErrors = [err15];
1465
+ } else {
1466
+ vErrors.push(err15);
1467
+ }
1468
+ errors++;
1469
+ }
1470
+ }
1471
+ if (data.settlement_finality !== void 0) {
1472
+ let data6 = data.settlement_finality;
1473
+ if (typeof data6 !== "string") {
1474
+ const err16 = { instancePath: instancePath + "/settlement_finality", schemaPath: "#/properties/settlement_finality/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1475
+ if (vErrors === null) {
1476
+ vErrors = [err16];
1477
+ } else {
1478
+ vErrors.push(err16);
1479
+ }
1480
+ errors++;
1481
+ }
1482
+ if (!(data6 === "final" || data6 === "provisional" || data6 === "superseded")) {
1483
+ const err17 = { instancePath: instancePath + "/settlement_finality", schemaPath: "#/properties/settlement_finality/enum", keyword: "enum", params: { allowedValues: schema33.properties.settlement_finality.enum }, message: "must be equal to one of the allowed values" };
1484
+ if (vErrors === null) {
1485
+ vErrors = [err17];
1486
+ } else {
1487
+ vErrors.push(err17);
1488
+ }
1489
+ errors++;
1490
+ }
1491
+ }
1492
+ if (data.snowfall_in !== void 0) {
1493
+ let data7 = data.snowfall_in;
1494
+ if (data7 !== null && !(typeof data7 == "number")) {
1495
+ const err18 = { instancePath: instancePath + "/snowfall_in", schemaPath: "#/properties/snowfall_in/type", keyword: "type", params: { type: schema33.properties.snowfall_in.type }, message: "must be null,number" };
1496
+ if (vErrors === null) {
1497
+ vErrors = [err18];
1498
+ } else {
1499
+ vErrors.push(err18);
1500
+ }
1501
+ errors++;
1502
+ }
1503
+ }
1504
+ if (data.station !== void 0) {
1505
+ if (typeof data.station !== "string") {
1506
+ const err19 = { instancePath: instancePath + "/station", schemaPath: "#/properties/station/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1507
+ if (vErrors === null) {
1508
+ vErrors = [err19];
1509
+ } else {
1510
+ vErrors.push(err19);
1511
+ }
1512
+ errors++;
1513
+ }
1514
+ }
1515
+ if (data.station_tz !== void 0) {
1516
+ if (typeof data.station_tz !== "string") {
1517
+ const err20 = { instancePath: instancePath + "/station_tz", schemaPath: "#/properties/station_tz/type", keyword: "type", params: { type: "string" }, message: "must be string" };
1518
+ if (vErrors === null) {
1519
+ vErrors = [err20];
1520
+ } else {
1521
+ vErrors.push(err20);
1522
+ }
1523
+ errors++;
1524
+ }
1525
+ }
1526
+ if (data.temp_max_F !== void 0) {
1527
+ let data10 = data.temp_max_F;
1528
+ if (data10 !== null && !(typeof data10 == "number")) {
1529
+ const err21 = { instancePath: instancePath + "/temp_max_F", schemaPath: "#/properties/temp_max_F/type", keyword: "type", params: { type: schema33.properties.temp_max_F.type }, message: "must be null,number" };
1530
+ if (vErrors === null) {
1531
+ vErrors = [err21];
1532
+ } else {
1533
+ vErrors.push(err21);
1534
+ }
1535
+ errors++;
1536
+ }
1537
+ }
1538
+ if (data.temp_min_F !== void 0) {
1539
+ let data11 = data.temp_min_F;
1540
+ if (data11 !== null && !(typeof data11 == "number")) {
1541
+ const err22 = { instancePath: instancePath + "/temp_min_F", schemaPath: "#/properties/temp_min_F/type", keyword: "type", params: { type: schema33.properties.temp_min_F.type }, message: "must be null,number" };
1542
+ if (vErrors === null) {
1543
+ vErrors = [err22];
1544
+ } else {
1545
+ vErrors.push(err22);
1546
+ }
1547
+ errors++;
1548
+ }
1549
+ }
1550
+ } else {
1551
+ const err23 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
1552
+ if (vErrors === null) {
1553
+ vErrors = [err23];
1554
+ } else {
1555
+ vErrors.push(err23);
1556
+ }
1557
+ errors++;
1558
+ }
1559
+ validate22.errors = vErrors;
1560
+ return errors === 0;
1561
+ }
1562
+ validate22.evaluated = { "props": { "cli_data_quality": true, "event_time": true, "observation_date": true, "precipitation_in": true, "product_release_time": true, "report_type": true, "settlement_finality": true, "snowfall_in": true, "station": true, "station_tz": true, "temp_max_F": true, "temp_min_F": true }, "dynamicProps": false, "dynamicItems": false };
1563
+
1564
+ // src/schemas/validators/format-map.ts
1565
+ var FORMAT_MAPS = Object.freeze({
1566
+ "schema.forecast.iem_mos.v1": Object.freeze({
1567
+ "issued_at": "date-time",
1568
+ "valid_at": "date-time"
1569
+ }),
1570
+ "schema.observation_ledger.v1": Object.freeze({
1571
+ "as_of_time": "date-time",
1572
+ "observed_at": "date-time"
1573
+ }),
1574
+ "schema.observation_qc.v1": Object.freeze({
1575
+ "as_of_time": "date-time",
1576
+ "observed_at": "date-time"
1577
+ }),
1578
+ "schema.observation.v1": Object.freeze({
1579
+ "event_time": "date-time"
1580
+ }),
1581
+ "schema.settlement.cli.v1": Object.freeze({
1582
+ "event_time": "date-time",
1583
+ "observation_date": "date",
1584
+ "product_release_time": "date-time"
1585
+ })
1586
+ });
1587
+ function getFormatMap(schemaId) {
1588
+ return FORMAT_MAPS[schemaId] ?? null;
1589
+ }
1590
+
1591
+ // src/schemas/validators/index.ts
1592
+ var VALIDATORS = {
1593
+ "schema.forecast.iem_mos.v1": schema_forecast_iem_mos_v1,
1594
+ "schema.observation_ledger.v1": schema_observation_ledger_v1,
1595
+ "schema.observation_qc.v1": schema_observation_qc_v1,
1596
+ "schema.observation.v1": schema_observation_v1,
1597
+ "schema.settlement.cli.v1": schema_settlement_cli_v1
1598
+ };
1599
+ function getValidator(schemaId) {
1600
+ return VALIDATORS[schemaId] ?? null;
1601
+ }
1602
+
1603
+ // src/validator.ts
1604
+ var SAMPLE_CAP = 10;
1605
+ var ISO_DATE_ONLY_REGEX = /^\d{4}-\d{2}-\d{2}$/;
1606
+ var ISO_DATETIME_SEPARATOR_REGEX = /[T ]/;
1607
+ var ISO_DATETIME_TZ_SUFFIX_REGEX = /(?:Z|[+-]\d{2}:?\d{2})$/;
1608
+ var ISO_DATETIME_DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
1609
+ function isIsoDate(v) {
1610
+ if (typeof v !== "string") return false;
1611
+ if (!ISO_DATE_ONLY_REGEX.test(v)) return false;
1612
+ const ms = Date.parse(`${v}T00:00:00Z`);
1613
+ if (!Number.isFinite(ms)) return false;
1614
+ const reparsed = new Date(ms).toISOString().slice(0, 10);
1615
+ return reparsed === v;
1616
+ }
1617
+ function isIsoDateTime(v) {
1618
+ if (typeof v !== "string") return false;
1619
+ const trimmed = v.trim();
1620
+ if (trimmed.length === 0) return false;
1621
+ if (!ISO_DATETIME_DATE_PREFIX_REGEX.test(trimmed)) return false;
1622
+ if (!ISO_DATETIME_SEPARATOR_REGEX.test(trimmed)) return false;
1623
+ if (!ISO_DATETIME_TZ_SUFFIX_REGEX.test(trimmed)) return false;
1624
+ const ms = Date.parse(trimmed);
1625
+ if (!Number.isFinite(ms)) return false;
1626
+ const dateMatch = /^(\d{4})-(\d{2})-(\d{2})/.exec(trimmed);
1627
+ if (dateMatch === null) return false;
1628
+ const litYear = Number(dateMatch[1]);
1629
+ const litMonth = Number(dateMatch[2]);
1630
+ const litDay = Number(dateMatch[3]);
1631
+ let offsetMin = 0;
1632
+ const tzMatch = /(Z|[+-]\d{2}:?\d{2})$/.exec(trimmed);
1633
+ const tz = tzMatch === null ? void 0 : tzMatch[1];
1634
+ if (tz !== void 0 && tz !== "Z") {
1635
+ const sign = tz.startsWith("-") ? -1 : 1;
1636
+ const body = tz.slice(1).replace(":", "");
1637
+ const hh = Number(body.slice(0, 2));
1638
+ const mm = Number(body.slice(2, 4));
1639
+ offsetMin = sign * (hh * 60 + mm);
1640
+ }
1641
+ const sourceMs = ms + offsetMin * 6e4;
1642
+ const sourceDate = new Date(sourceMs);
1643
+ return sourceDate.getUTCFullYear() === litYear && sourceDate.getUTCMonth() + 1 === litMonth && sourceDate.getUTCDate() === litDay;
1644
+ }
1645
+ var SCHEMA_REGISTERED_SOURCE = Object.freeze({
1646
+ "schema.observation.v1": "iem.archive",
1647
+ "schema.settlement.cli.v1": "cli.archive",
1648
+ "schema.forecast.iem_mos.v1": "iem.archive",
1649
+ "schema.observation_ledger.v1": "iem.archive",
1650
+ "schema.observation_qc.v1": "iem.archive"
1651
+ });
1652
+ function mapAjvErrorToViolation(err, rowIdx) {
1653
+ const keyword = err.keyword;
1654
+ if (keyword === "required") {
1655
+ const missing = err.params.missingProperty;
1656
+ if (typeof missing === "string") {
1657
+ return { rule: "required_column_missing", column: missing, row_idx: rowIdx };
1658
+ }
1659
+ return { rule: "required_column_missing", row_idx: rowIdx };
1660
+ }
1661
+ if (keyword === "type") {
1662
+ const column2 = err.instancePath.replace(/^\//, "").replace(/\//g, ".");
1663
+ return {
1664
+ rule: "dtype_mismatch",
1665
+ column: column2,
1666
+ row_idx: rowIdx
1667
+ };
1668
+ }
1669
+ if (keyword === "enum") {
1670
+ const column2 = err.instancePath.replace(/^\//, "").replace(/\//g, ".");
1671
+ return {
1672
+ rule: "enum_value_violation",
1673
+ column: column2,
1674
+ row_idx: rowIdx
1675
+ };
1676
+ }
1677
+ const column = err.instancePath.replace(/^\//, "").replace(/\//g, ".");
1678
+ if (column.length > 0) {
1679
+ return { rule: "dtype_mismatch", column, row_idx: rowIdx };
1680
+ }
1681
+ return { rule: "dtype_mismatch", row_idx: rowIdx };
1682
+ }
1683
+ function detectMixedNullSentinels(rows) {
1684
+ const cols = /* @__PURE__ */ new Map();
1685
+ for (const row of rows) {
1686
+ for (const [k, v] of Object.entries(row)) {
1687
+ const entry = cols.get(k) ?? { hasNull: false, hasUndef: false };
1688
+ if (v === null) entry.hasNull = true;
1689
+ if (v === void 0) entry.hasUndef = true;
1690
+ cols.set(k, entry);
1691
+ }
1692
+ }
1693
+ const mixed = [];
1694
+ for (const [k, e] of cols) {
1695
+ if (e.hasNull && e.hasUndef) mixed.push(k);
1696
+ }
1697
+ return mixed;
1698
+ }
1699
+ function validateRows(rows, schemaId, opts = {}) {
1700
+ const validate = getValidator(schemaId);
1701
+ if (validate == null) {
1702
+ throw new SchemaValidationError(`Unknown schema_id ${JSON.stringify(schemaId)}`, {
1703
+ schemaId,
1704
+ violations: [{ rule: "unknown_schema_id" }],
1705
+ quarantineCount: rows.length,
1706
+ sampleViolations: []
1707
+ });
1708
+ }
1709
+ if (opts.allowSourceDrift !== void 0) {
1710
+ if (typeof opts.allowSourceDrift !== "string") {
1711
+ throw new TypeError(
1712
+ `allowSourceDrift must be a non-empty reason string; got ${typeof opts.allowSourceDrift}`
1713
+ );
1714
+ }
1715
+ if (opts.allowSourceDrift.trim().length === 0) {
1716
+ throw new RangeError(
1717
+ "allowSourceDrift must be a non-empty reason string (stripped whitespace)"
1718
+ );
1719
+ }
1720
+ }
1721
+ const firstRow = rows.length > 0 ? rows[0] : void 0;
1722
+ const resolvedSource = opts.source ?? (firstRow !== void 0 ? firstRow.source : void 0);
1723
+ if (resolvedSource === void 0 || resolvedSource === null) {
1724
+ throw new SchemaValidationError(
1725
+ "DataFrame missing source attribute; cannot validate source-identity",
1726
+ {
1727
+ schemaId,
1728
+ violations: [{ rule: "source_attr_required" }],
1729
+ quarantineCount: rows.length,
1730
+ sampleViolations: []
1731
+ }
1732
+ );
1733
+ }
1734
+ const registeredSource = SCHEMA_REGISTERED_SOURCE[schemaId];
1735
+ if (registeredSource !== void 0 && resolvedSource !== registeredSource && opts.allowSourceDrift === void 0) {
1736
+ throw new SourceMismatchError(
1737
+ `Source drift: data is ${JSON.stringify(resolvedSource)}, schema expects ${JSON.stringify(registeredSource)}`,
1738
+ {
1739
+ schemaSource: registeredSource,
1740
+ dataSource: resolvedSource
1741
+ }
1742
+ );
1743
+ }
1744
+ if (rows.length > 0) {
1745
+ const hasSourceColumn = rows.some((r) => "source" in r);
1746
+ if (!hasSourceColumn) {
1747
+ throw new SchemaValidationError(
1748
+ "Rows are missing the per-row 'source' overlay column required by canonical-schema producers.",
1749
+ {
1750
+ schemaId,
1751
+ violations: [{ column: "source", rule: "source_column_required" }],
1752
+ quarantineCount: rows.length,
1753
+ sampleViolations: []
1754
+ }
1755
+ );
1756
+ }
1757
+ const badRows = [];
1758
+ for (let i = 0; i < rows.length; i++) {
1759
+ const r = rows[i];
1760
+ const v = r.source;
1761
+ if (v == null || v !== resolvedSource) {
1762
+ badRows.push({ row_idx: i, source: v ?? null });
1763
+ }
1764
+ }
1765
+ if (badRows.length > 0) {
1766
+ const distinctBad = Array.from(
1767
+ new Set(badRows.map(({ source }) => source == null ? "<null>" : String(source)))
1768
+ ).slice(0, SAMPLE_CAP);
1769
+ throw new SourceMismatchError(
1770
+ `Per-row 'source' column has ${badRows.length} row(s) not matching resolved source=${JSON.stringify(resolvedSource)}; distinct bad values: ${JSON.stringify(distinctBad)}`,
1771
+ {
1772
+ schemaSource: resolvedSource,
1773
+ dataSource: distinctBad[0] ?? "<null>"
1774
+ }
1775
+ );
1776
+ }
1777
+ }
1778
+ const violations = [];
1779
+ for (let i = 0; i < rows.length; i++) {
1780
+ const r = rows[i];
1781
+ const ok = validate(r);
1782
+ if (!ok && validate.errors != null) {
1783
+ for (const err of validate.errors) {
1784
+ const value = r;
1785
+ const column = err.instancePath.replace(/^\//, "");
1786
+ if (err.keyword === "type" && value !== void 0 && column.length > 0 && value[column] === null) {
1787
+ violations.push({
1788
+ rule: "non_nullable_has_nulls",
1789
+ column,
1790
+ row_idx: i
1791
+ });
1792
+ } else {
1793
+ violations.push(mapAjvErrorToViolation(err, i));
1794
+ }
1795
+ if (violations.length >= SAMPLE_CAP * 2) break;
1796
+ }
1797
+ }
1798
+ }
1799
+ const formatMap = getFormatMap(schemaId);
1800
+ if (formatMap !== null) {
1801
+ for (let i = 0; i < rows.length; i++) {
1802
+ const r = rows[i];
1803
+ for (const [propName, kind] of Object.entries(formatMap)) {
1804
+ if (!(propName in r)) continue;
1805
+ const v = r[propName];
1806
+ if (v == null) continue;
1807
+ const valid = kind === "date" ? isIsoDate(v) : isIsoDateTime(v);
1808
+ if (!valid) {
1809
+ violations.push({
1810
+ rule: "dtype_mismatch",
1811
+ column: propName,
1812
+ row_idx: i,
1813
+ value: v
1814
+ });
1815
+ }
1816
+ if (violations.length >= SAMPLE_CAP * 2) break;
1817
+ }
1818
+ if (violations.length >= SAMPLE_CAP * 2) break;
1819
+ }
1820
+ }
1821
+ const mixedColumns = detectMixedNullSentinels(rows);
1822
+ for (const col of mixedColumns) {
1823
+ violations.push({ rule: "mixed_null_sentinels", column: col });
1824
+ }
1825
+ let resolvedRetrievedAt = opts.retrievedAt;
1826
+ if (resolvedRetrievedAt === void 0) {
1827
+ let maxInstantMs = Number.NEGATIVE_INFINITY;
1828
+ let maxValue;
1829
+ for (const r of rows) {
1830
+ const v = r.retrieved_at;
1831
+ if (typeof v !== "string" || v.length === 0) continue;
1832
+ const ms = Date.parse(v);
1833
+ if (!Number.isFinite(ms)) continue;
1834
+ if (ms > maxInstantMs) {
1835
+ maxInstantMs = ms;
1836
+ maxValue = v;
1837
+ }
1838
+ }
1839
+ if (maxValue !== void 0) resolvedRetrievedAt = maxValue;
1840
+ }
1841
+ if (resolvedRetrievedAt === void 0) {
1842
+ violations.push({ rule: "retrieved_at_required" });
1843
+ }
1844
+ if (violations.length > 0) {
1845
+ throw new SchemaValidationError(
1846
+ `Schema validation failed with ${violations.length} violation(s) under ${schemaId}`,
1847
+ {
1848
+ schemaId,
1849
+ violations,
1850
+ quarantineCount: rows.length,
1851
+ sampleViolations: violations.slice(0, SAMPLE_CAP)
1852
+ }
1853
+ );
1854
+ }
1855
+ if (resolvedRetrievedAt === void 0) {
1856
+ throw new Error(
1857
+ "internal invariant: resolvedRetrievedAt is undefined but violations array was empty"
1858
+ );
1859
+ }
1860
+ return {
1861
+ rowCount: rows.length,
1862
+ source: resolvedSource,
1863
+ retrievedAt: resolvedRetrievedAt
1864
+ };
1865
+ }
1866
+ // Annotate the CommonJS export names for ESM import in node:
1867
+ 0 && (module.exports = {
1868
+ validateRows
1869
+ });
1870
+ //# sourceMappingURL=validator.cjs.map