@jeffjassky/telemetry 0.6.0 → 0.7.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/dist/index.js CHANGED
@@ -62,6 +62,8 @@ var newCounters = () => ({
62
62
  truncated: 0,
63
63
  rollupSkippedBy: {},
64
64
  undeclaredAttrs: {},
65
+ attrsDropped: {},
66
+ metricsDropped: {},
65
67
  subjectsLinked: 0,
66
68
  subjectLinkMisses: 0,
67
69
  subjectLinkErrors: 0,
@@ -271,6 +273,7 @@ var UsageDetailSchema = new Schema(
271
273
  { _id: false }
272
274
  );
273
275
  function buildBaseSchema(collection, registry, counters, opts) {
276
+ const validation = opts.validation;
274
277
  const schema = new Schema(
275
278
  {
276
279
  /** UUIDv7 — sortable, insertion-local, replaces the ObjectId */
@@ -412,13 +415,39 @@ function buildBaseSchema(collection, registry, counters, opts) {
412
415
  }
413
416
  const check = (label3, m, zschema) => {
414
417
  const obj = Object.fromEntries(m ?? []);
418
+ const dropped = label3 === "attrs" ? counters.attrsDropped : counters.metricsDropped;
419
+ const note = (key) => bumpCounterMap(dropped, `${this.name}|${key}`);
415
420
  if (!zschema) {
416
- if (Object.keys(obj).length) throw new Error(`telemetry: "${this.name}" declares no ${label3}`);
421
+ if (!Object.keys(obj).length) return;
422
+ if (validation === "strict") throw new Error(`telemetry: "${this.name}" declares no ${label3}`);
423
+ for (const key of Object.keys(obj)) {
424
+ note(key);
425
+ m?.delete(key);
426
+ }
417
427
  return;
418
428
  }
419
429
  const s = zschema.strict?.() ?? zschema;
420
430
  const r = s.safeParse(obj);
421
- if (!r.success) throw new Error(`telemetry: ${label3} invalid for "${this.name}": ${r.error.message}`);
431
+ if (r.success) return;
432
+ if (validation === "strict") {
433
+ throw new Error(`telemetry: ${label3} invalid for "${this.name}": ${r.error.message}`);
434
+ }
435
+ const bad = /* @__PURE__ */ new Set();
436
+ for (const issue of r.error.issues) {
437
+ if (issue.code === "unrecognized_keys" && Array.isArray(issue.keys)) {
438
+ for (const k of issue.keys) bad.add(String(k));
439
+ } else if (Array.isArray(issue.path) && issue.path.length) {
440
+ bad.add(String(issue.path[0]));
441
+ }
442
+ }
443
+ for (const key of bad) {
444
+ if (m?.has(key)) {
445
+ note(key);
446
+ m.delete(key);
447
+ } else {
448
+ note("(missing)");
449
+ }
450
+ }
422
451
  };
423
452
  check("attrs", this.attrs, spec.attrs);
424
453
  check("metrics", this.metrics, spec.metrics);
@@ -451,7 +480,11 @@ function buildTelemetryModels(opts) {
451
480
  )
452
481
  };
453
482
  }
454
- const base = buildBaseSchema(collection, registry, counters, { platforms, bodyMax });
483
+ const base = buildBaseSchema(collection, registry, counters, {
484
+ platforms,
485
+ bodyMax,
486
+ validation: opts.validation ?? "lenient"
487
+ });
455
488
  const TelemetryModel = connection.model(modelName, base);
456
489
  const disc = (kind, build) => TelemetryModel.discriminator(`${modelName}_${kind}`, build(), kind);
457
490
  const byKind = {
@@ -3834,7 +3867,8 @@ function createTelemetry(config) {
3834
3867
  modelName,
3835
3868
  collection,
3836
3869
  platforms: config.platforms,
3837
- bodyMax: config.bodyMax
3870
+ bodyMax: config.bodyMax,
3871
+ validation: config.validation
3838
3872
  });
3839
3873
  const RollupModel = buildRollupModel(conn, `${modelName}Rollup`, `${collection}_rollups`);
3840
3874
  const CheckpointModel = buildCheckpointModel(conn, `${modelName}Checkpoint`, `${collection}_checkpoints`);