@uptimizr/db 1.0.2 → 2.0.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/AGENTS.md +103 -1
- package/README.md +100 -3
- package/dist/cli/createProject.js +23 -6
- package/dist/cli/createProject.js.map +1 -1
- package/dist/cli/seed.js +12 -4
- package/dist/cli/seed.js.map +1 -1
- package/dist/duckdb/audit.d.ts +13 -0
- package/dist/duckdb/audit.d.ts.map +1 -0
- package/dist/duckdb/audit.js +67 -0
- package/dist/duckdb/audit.js.map +1 -0
- package/dist/duckdb/migrations.d.ts.map +1 -1
- package/dist/duckdb/migrations.js +97 -0
- package/dist/duckdb/migrations.js.map +1 -1
- package/dist/duckdb/projects.d.ts +9 -5
- package/dist/duckdb/projects.d.ts.map +1 -1
- package/dist/duckdb/projects.js +54 -24
- package/dist/duckdb/projects.js.map +1 -1
- package/dist/duckdb/queries.d.ts +7 -0
- package/dist/duckdb/queries.d.ts.map +1 -1
- package/dist/duckdb/queries.js +10 -1
- package/dist/duckdb/queries.js.map +1 -1
- package/dist/duckdb/sceneRegions.d.ts +24 -0
- package/dist/duckdb/sceneRegions.d.ts.map +1 -0
- package/dist/duckdb/sceneRegions.js +72 -0
- package/dist/duckdb/sceneRegions.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +195 -9
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +192 -0
- package/dist/metadata.js.map +1 -1
- package/dist/parity/compare.d.ts +22 -0
- package/dist/parity/compare.d.ts.map +1 -1
- package/dist/parity/compare.js +31 -0
- package/dist/parity/compare.js.map +1 -1
- package/dist/query/aggregations.d.ts +8 -0
- package/dist/query/aggregations.d.ts.map +1 -1
- package/dist/query/aggregations.js +78 -0
- package/dist/query/aggregations.js.map +1 -1
- package/dist/query/coerce.d.ts +94 -0
- package/dist/query/coerce.d.ts.map +1 -0
- package/dist/query/coerce.js +191 -0
- package/dist/query/coerce.js.map +1 -0
- package/dist/query/summary/cluster.d.ts +78 -0
- package/dist/query/summary/cluster.d.ts.map +1 -0
- package/dist/query/summary/cluster.js +200 -0
- package/dist/query/summary/cluster.js.map +1 -0
- package/dist/query/summary/columns.d.ts +66 -0
- package/dist/query/summary/columns.d.ts.map +1 -0
- package/dist/query/summary/columns.js +98 -0
- package/dist/query/summary/columns.js.map +1 -0
- package/dist/query/summary/format.d.ts +31 -0
- package/dist/query/summary/format.d.ts.map +1 -0
- package/dist/query/summary/format.js +119 -0
- package/dist/query/summary/format.js.map +1 -0
- package/dist/query/summary/index.d.ts +19 -0
- package/dist/query/summary/index.d.ts.map +1 -0
- package/dist/query/summary/index.js +16 -0
- package/dist/query/summary/index.js.map +1 -0
- package/dist/query/summary/reading.d.ts +26 -0
- package/dist/query/summary/reading.d.ts.map +1 -0
- package/dist/query/summary/reading.js +169 -0
- package/dist/query/summary/reading.js.map +1 -0
- package/dist/query/summary/schema.d.ts +217 -0
- package/dist/query/summary/schema.d.ts.map +1 -0
- package/dist/query/summary/schema.js +167 -0
- package/dist/query/summary/schema.js.map +1 -0
- package/dist/query/summary/stats.d.ts +33 -0
- package/dist/query/summary/stats.d.ts.map +1 -0
- package/dist/query/summary/stats.js +73 -0
- package/dist/query/summary/stats.js.map +1 -0
- package/dist/query/summary/summarize.d.ts +57 -0
- package/dist/query/summary/summarize.d.ts.map +1 -0
- package/dist/query/summary/summarize.js +424 -0
- package/dist/query/summary/summarize.js.map +1 -0
- package/dist/query/summary/types.d.ts +223 -0
- package/dist/query/summary/types.d.ts.map +1 -0
- package/dist/query/summary/types.js +8 -0
- package/dist/query/summary/types.js.map +1 -0
- package/dist/query/types.d.ts +13 -0
- package/dist/query/types.d.ts.map +1 -1
- package/llms.txt +7 -3
- package/package.json +8 -2
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `format=table | summary` result envelopes (ADR 0051 §2, design sketch §B.1).
|
|
3
|
+
*
|
|
4
|
+
* Pure, registry-driven and browser-safe — no store, no I/O, no `node:` import —
|
|
5
|
+
* so the same code shapes a collector response, a CLI result and (eventually) an
|
|
6
|
+
* in-browser demo store's output. Re-exported from both `@uptimizr/db` and the
|
|
7
|
+
* browser-safe `@uptimizr/db/query` subpath.
|
|
8
|
+
*/
|
|
9
|
+
export { summarizeRows, tableResult } from "./summarize.js";
|
|
10
|
+
export type { ResultRow } from "./summarize.js";
|
|
11
|
+
export { clusterCells } from "./cluster.js";
|
|
12
|
+
export type { ClusterOptions, ClusterResult, GridCell } from "./cluster.js";
|
|
13
|
+
export { wilsonInterval, leastSquaresSlope, trendOf, Z_95 } from "./stats.js";
|
|
14
|
+
export { sampleSizeOf } from "./columns.js";
|
|
15
|
+
export { isAdditiveUnit } from "./format.js";
|
|
16
|
+
export { RESULT_FORMATS } from "./types.js";
|
|
17
|
+
export type { AppliedFilters, ClusterRest, ClusterSummary, DrillHints, RankedRow, RankedSummary, RecordSummary, ResolvedRate, RestBucket, ResultFormat, ResultLimits, ResultRange, ResultSummary, SampleSize, SeriesDigest, SeriesSummary, ShareInterval, SpatialCluster, SummaryBase, SummaryConfidence, SummaryContext, SummaryMeasure, TableMeta, TableResult, TrendDirection, } from "./types.js";
|
|
18
|
+
export { resultEnvelopeSchema, resultFormatSchema, resultSummarySchema, tableResultSchema, } from "./schema.js";
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/query/summary/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5D,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EACV,cAAc,EACd,WAAW,EACX,cAAc,EACd,UAAU,EACV,SAAS,EACT,aAAa,EACb,aAAa,EACb,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,EACb,UAAU,EACV,YAAY,EACZ,aAAa,EACb,aAAa,EACb,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,SAAS,EACT,WAAW,EACX,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `format=table | summary` result envelopes (ADR 0051 §2, design sketch §B.1).
|
|
3
|
+
*
|
|
4
|
+
* Pure, registry-driven and browser-safe — no store, no I/O, no `node:` import —
|
|
5
|
+
* so the same code shapes a collector response, a CLI result and (eventually) an
|
|
6
|
+
* in-browser demo store's output. Re-exported from both `@uptimizr/db` and the
|
|
7
|
+
* browser-safe `@uptimizr/db/query` subpath.
|
|
8
|
+
*/
|
|
9
|
+
export { summarizeRows, tableResult } from "./summarize.js";
|
|
10
|
+
export { clusterCells } from "./cluster.js";
|
|
11
|
+
export { wilsonInterval, leastSquaresSlope, trendOf, Z_95 } from "./stats.js";
|
|
12
|
+
export { sampleSizeOf } from "./columns.js";
|
|
13
|
+
export { isAdditiveUnit } from "./format.js";
|
|
14
|
+
export { RESULT_FORMATS } from "./types.js";
|
|
15
|
+
export { resultEnvelopeSchema, resultFormatSchema, resultSummarySchema, tableResultSchema, } from "./schema.js";
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/query/summary/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA4B5C,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `reading` sentence: one plain-English statement of what the result says,
|
|
3
|
+
* assembled **only** from the registry's column semantics (design sketch §B.1).
|
|
4
|
+
*
|
|
5
|
+
* No model is involved, and none may be: `reading` is part of a deterministic
|
|
6
|
+
* API response, so the same rows have to produce the same words on every engine
|
|
7
|
+
* and every process. Everything it can say is therefore a function of the
|
|
8
|
+
* metric's `title`, `grain`, and the `unit` / `label` / `measure` / `axis` / `rateOf`
|
|
9
|
+
* flags on its columns — which is exactly the information the registry exists to
|
|
10
|
+
* hold.
|
|
11
|
+
*
|
|
12
|
+
* The one hard rule enforced by `__tests__/summary.test.ts`: a `reading` never
|
|
13
|
+
* contains `undefined` or `NaN`. Every number goes through the total formatters
|
|
14
|
+
* in `format.ts`, which render a missing or non-finite value as `n/a`.
|
|
15
|
+
*/
|
|
16
|
+
import type { MetricDefinition } from "@uptimizr/metrics";
|
|
17
|
+
import type { ResultSummary } from "./types.js";
|
|
18
|
+
/**
|
|
19
|
+
* A summary that has everything but its sentence. Distributive, so the `kind`
|
|
20
|
+
* discriminant survives — a bare `Omit<ResultSummary, "reading">` would collapse
|
|
21
|
+
* the union to its common keys and lose the switch below.
|
|
22
|
+
*/
|
|
23
|
+
export type UnreadSummary<T = ResultSummary> = T extends unknown ? Omit<T, "reading"> : never;
|
|
24
|
+
/** The templated `reading` for a summary that has everything but its sentence. */
|
|
25
|
+
export declare function readingFor(metric: MetricDefinition, summary: UnreadSummary): string;
|
|
26
|
+
//# sourceMappingURL=reading.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reading.d.ts","sourceRoot":"","sources":["../../../src/query/summary/reading.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAU1D,OAAO,KAAK,EAIV,aAAa,EAGd,MAAM,YAAY,CAAC;AA+JpB;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,aAAa,IAAI,CAAC,SAAS,OAAO,GAAG,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;AAE9F,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAWnF"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `reading` sentence: one plain-English statement of what the result says,
|
|
3
|
+
* assembled **only** from the registry's column semantics (design sketch §B.1).
|
|
4
|
+
*
|
|
5
|
+
* No model is involved, and none may be: `reading` is part of a deterministic
|
|
6
|
+
* API response, so the same rows have to produce the same words on every engine
|
|
7
|
+
* and every process. Everything it can say is therefore a function of the
|
|
8
|
+
* metric's `title`, `grain`, and the `unit` / `label` / `measure` / `axis` / `rateOf`
|
|
9
|
+
* flags on its columns — which is exactly the information the registry exists to
|
|
10
|
+
* hold.
|
|
11
|
+
*
|
|
12
|
+
* The one hard rule enforced by `__tests__/summary.test.ts`: a `reading` never
|
|
13
|
+
* contains `undefined` or `NaN`. Every number goes through the total formatters
|
|
14
|
+
* in `format.ts`, which render a missing or non-finite value as `n/a`.
|
|
15
|
+
*/
|
|
16
|
+
import { measureColumn } from "./columns.js";
|
|
17
|
+
import { formatLabel, formatNumber, formatQuantity, formatShare, grainNoun, humanizeColumn, } from "./format.js";
|
|
18
|
+
/** "Sample: 412 sessions over 9,130 events." — omitted when nothing is known. */
|
|
19
|
+
function sampleSentence(sample) {
|
|
20
|
+
const parts = [];
|
|
21
|
+
if (sample.sessions != null)
|
|
22
|
+
parts.push(`${formatNumber(sample.sessions)} sessions`);
|
|
23
|
+
if (sample.events != null)
|
|
24
|
+
parts.push(`${formatNumber(sample.events)} events`);
|
|
25
|
+
if (parts.length === 0)
|
|
26
|
+
return "";
|
|
27
|
+
return ` Sample: ${parts.join(" over ")}.`;
|
|
28
|
+
}
|
|
29
|
+
/** The empty-result sentence, shared by every grain. */
|
|
30
|
+
function nothingMatched(metric) {
|
|
31
|
+
return `${metric.title}: no rows matched the selected range and filters.`;
|
|
32
|
+
}
|
|
33
|
+
function rankedReading(metric, summary) {
|
|
34
|
+
if (summary.top.length === 0)
|
|
35
|
+
return nothingMatched(metric);
|
|
36
|
+
const measure = measureColumn(metric);
|
|
37
|
+
const unit = measure?.[1].unit;
|
|
38
|
+
const [first, second] = summary.top;
|
|
39
|
+
if (measure == null || first == null) {
|
|
40
|
+
const rows = summary.top.length + summary.rest.rows;
|
|
41
|
+
return (`${metric.title}: ${formatNumber(rows)} ${grainNoun(metric.grain, rows)} returned in store ` +
|
|
42
|
+
`order; the metric declares no measure column, so they cannot be ranked.` +
|
|
43
|
+
sampleSentence(summary.sampleSize));
|
|
44
|
+
}
|
|
45
|
+
const measureName = humanizeColumn(measure[0]);
|
|
46
|
+
let text = `${metric.title}: ${formatLabel(first.label)} leads on ${measureName} with ${formatQuantity(first.value, unit)}`;
|
|
47
|
+
if (first.share != null) {
|
|
48
|
+
text += ` (${formatShare(first.share)} of ${formatQuantity(summary.total, unit)})`;
|
|
49
|
+
}
|
|
50
|
+
if (second != null) {
|
|
51
|
+
text += `, followed by ${formatLabel(second.label)} with ${formatQuantity(second.value, unit)}`;
|
|
52
|
+
if (second.share != null)
|
|
53
|
+
text += ` (${formatShare(second.share)})`;
|
|
54
|
+
}
|
|
55
|
+
text += ".";
|
|
56
|
+
if (summary.rest.rows > 0) {
|
|
57
|
+
const held = summary.rest.share != null
|
|
58
|
+
? formatShare(summary.rest.share)
|
|
59
|
+
: formatQuantity(summary.rest.value, unit);
|
|
60
|
+
text +=
|
|
61
|
+
` The remaining ${formatNumber(summary.rest.rows)} ` +
|
|
62
|
+
`${grainNoun(metric.grain, summary.rest.rows)} hold ${held}.`;
|
|
63
|
+
}
|
|
64
|
+
if (summary.measure != null && !summary.measure.additive) {
|
|
65
|
+
const unitPhrase = summary.measure.unit == null
|
|
66
|
+
? "not an additive quantity"
|
|
67
|
+
: `measured in ${summary.measure.unit}`;
|
|
68
|
+
text +=
|
|
69
|
+
` Shares are not reported: ${measureName} is ${unitPhrase} and cannot be summed across ` +
|
|
70
|
+
`${grainNoun(metric.grain, 2)}.`;
|
|
71
|
+
}
|
|
72
|
+
return text + sampleSentence(summary.sampleSize);
|
|
73
|
+
}
|
|
74
|
+
function seriesReading(metric, summary) {
|
|
75
|
+
const { series } = summary;
|
|
76
|
+
if (series.points === 0)
|
|
77
|
+
return nothingMatched(metric);
|
|
78
|
+
const measure = measureColumn(metric);
|
|
79
|
+
const unit = measure?.[1].unit;
|
|
80
|
+
const measureName = measure == null ? "the measure" : humanizeColumn(measure[0]);
|
|
81
|
+
const axisName = humanizeColumn(series.axis);
|
|
82
|
+
if (series.points === 1) {
|
|
83
|
+
return (`${metric.title}: a single ${axisName} (${formatLabel(series.firstLabel)}) with ` +
|
|
84
|
+
`${measureName} ${formatQuantity(series.first, unit)} — too few points for a trend.` +
|
|
85
|
+
sampleSentence(summary.sampleSize));
|
|
86
|
+
}
|
|
87
|
+
const slope = series.slope == null ? "" : `, ${formatNumber(series.slope)} per ${axisName}`;
|
|
88
|
+
return (`${metric.title}: ${measureName} moved from ${formatQuantity(series.first, unit)} at ` +
|
|
89
|
+
`${formatLabel(series.firstLabel)} to ${formatQuantity(series.last, unit)} at ` +
|
|
90
|
+
`${formatLabel(series.lastLabel)} across ${formatNumber(series.points)} ` +
|
|
91
|
+
`${grainNoun("bucket", series.points)} — trend ${series.trend}${slope}. ` +
|
|
92
|
+
`Low ${formatQuantity(series.min, unit)} at ${formatLabel(series.minLabel)}, high ` +
|
|
93
|
+
`${formatQuantity(series.max, unit)} at ${formatLabel(series.maxLabel)}.` +
|
|
94
|
+
sampleSentence(summary.sampleSize));
|
|
95
|
+
}
|
|
96
|
+
function clusterReading(metric, summary) {
|
|
97
|
+
const cellNoun = grainNoun(metric.grain, summary.occupiedCells);
|
|
98
|
+
if (summary.occupiedCells === 0)
|
|
99
|
+
return nothingMatched(metric);
|
|
100
|
+
const densest = summary.clusters[0];
|
|
101
|
+
if (densest == null) {
|
|
102
|
+
return (`${metric.title}: ${formatNumber(summary.occupiedCells)} occupied ${cellNoun}, none of ` +
|
|
103
|
+
`which reached the density threshold of ${formatNumber(summary.densityThreshold)}.` +
|
|
104
|
+
sampleSentence(summary.sampleSize));
|
|
105
|
+
}
|
|
106
|
+
const centroid = densest.centroid.map((value) => formatNumber(value)).join(", ");
|
|
107
|
+
const extent = densest.extent.min
|
|
108
|
+
.map((min, axis) => formatNumber((densest.extent.max[axis] ?? min) - min + 1))
|
|
109
|
+
.join("x");
|
|
110
|
+
const weightUnit = summary.measure?.unit;
|
|
111
|
+
let text = `${metric.title}: ${formatNumber(summary.clusters.length)} ` +
|
|
112
|
+
`hotspot${summary.clusters.length === 1 ? "" : "s"} over ` +
|
|
113
|
+
`${formatNumber(summary.occupiedCells)} occupied ${cellNoun}. The densest spans ` +
|
|
114
|
+
`${extent} ${cellNoun} centred at (${centroid}) on ${summary.axes.join("/")}, holding ` +
|
|
115
|
+
`${formatQuantity(densest.weight, weightUnit)}`;
|
|
116
|
+
text += densest.share == null ? "." : ` (${formatShare(densest.share)}).`;
|
|
117
|
+
// Only name the part of `rest` that actually exists — "0 further clusters" is
|
|
118
|
+
// noise in a sentence meant to be read at a glance.
|
|
119
|
+
const rest = [];
|
|
120
|
+
if (summary.rest.clusters > 0) {
|
|
121
|
+
rest.push(`${formatNumber(summary.rest.clusters)} further cluster${summary.rest.clusters === 1 ? "" : "s"}`);
|
|
122
|
+
}
|
|
123
|
+
if (summary.rest.cells > 0) {
|
|
124
|
+
rest.push(`${formatNumber(summary.rest.cells)} looser ${grainNoun(metric.grain, summary.rest.cells)}`);
|
|
125
|
+
}
|
|
126
|
+
if (rest.length > 0) {
|
|
127
|
+
text += ` ${rest.join(" and ")} hold ${formatShare(summary.rest.share)}.`;
|
|
128
|
+
}
|
|
129
|
+
return text + sampleSentence(summary.sampleSize);
|
|
130
|
+
}
|
|
131
|
+
function recordReading(metric, summary) {
|
|
132
|
+
const columns = Object.keys(summary.record);
|
|
133
|
+
if (columns.length === 0)
|
|
134
|
+
return nothingMatched(metric);
|
|
135
|
+
const measure = measureColumn(metric);
|
|
136
|
+
let text;
|
|
137
|
+
if (measure == null) {
|
|
138
|
+
const listed = columns
|
|
139
|
+
.slice(0, 3)
|
|
140
|
+
.map((column) => `${humanizeColumn(column)} ${formatLabel(summary.record[column])}`)
|
|
141
|
+
.join(", ");
|
|
142
|
+
text = `${metric.title}: ${listed}.`;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
text =
|
|
146
|
+
`${metric.title}: ${humanizeColumn(measure[0])} is ` +
|
|
147
|
+
`${formatQuantity(summary.total, measure[1].unit)}.`;
|
|
148
|
+
}
|
|
149
|
+
for (const [column, rate] of Object.entries(summary.rates)) {
|
|
150
|
+
text +=
|
|
151
|
+
` ${humanizeColumn(column)} is ${formatShare(rate.value)} of ` +
|
|
152
|
+
`${humanizeColumn(rate.denominator)}.`;
|
|
153
|
+
}
|
|
154
|
+
return text + sampleSentence(summary.sampleSize);
|
|
155
|
+
}
|
|
156
|
+
/** The templated `reading` for a summary that has everything but its sentence. */
|
|
157
|
+
export function readingFor(metric, summary) {
|
|
158
|
+
switch (summary.kind) {
|
|
159
|
+
case "ranked":
|
|
160
|
+
return rankedReading(metric, { ...summary, reading: "" });
|
|
161
|
+
case "series":
|
|
162
|
+
return seriesReading(metric, { ...summary, reading: "" });
|
|
163
|
+
case "clusters":
|
|
164
|
+
return clusterReading(metric, { ...summary, reading: "" });
|
|
165
|
+
case "record":
|
|
166
|
+
return recordReading(metric, { ...summary, reading: "" });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=reading.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reading.js","sourceRoot":"","sources":["../../../src/query/summary/reading.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,YAAY,EACZ,cAAc,EACd,WAAW,EACX,SAAS,EACT,cAAc,GACf,MAAM,aAAa,CAAC;AAUrB,iFAAiF;AACjF,SAAS,cAAc,CAAC,MAAkB;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACrF,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,OAAO,YAAY,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;AAC7C,CAAC;AAED,wDAAwD;AACxD,SAAS,cAAc,CAAC,MAAwB;IAC9C,OAAO,GAAG,MAAM,CAAC,KAAK,mDAAmD,CAAC;AAC5E,CAAC;AAED,SAAS,aAAa,CAAC,MAAwB,EAAE,OAAsB;IACrE,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/B,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IACpC,IAAI,OAAO,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QACpD,OAAO,CACL,GAAG,MAAM,CAAC,KAAK,KAAK,YAAY,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,qBAAqB;YAC5F,yEAAyE;YACzE,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CACnC,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,IAAI,IAAI,GAAG,GAAG,MAAM,CAAC,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,WAAW,SAAS,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;IAC5H,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,IAAI,KAAK,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC;IACrF,CAAC;IACD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,IAAI,IAAI,iBAAiB,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;QAChG,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI;YAAE,IAAI,IAAI,KAAK,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;IACtE,CAAC;IACD,IAAI,IAAI,GAAG,CAAC;IAEZ,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,GACR,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI;YACxB,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YACjC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC/C,IAAI;YACF,kBAAkB,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;gBACpD,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC;IAClE,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzD,MAAM,UAAU,GACd,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI;YAC1B,CAAC,CAAC,0BAA0B;YAC5B,CAAC,CAAC,eAAe,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI;YACF,6BAA6B,WAAW,OAAO,UAAU,+BAA+B;gBACxF,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC;IACrC,CAAC;IACD,OAAO,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,aAAa,CAAC,MAAwB,EAAE,OAAsB;IACrE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC3B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/B,MAAM,WAAW,GAAG,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAE7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CACL,GAAG,MAAM,CAAC,KAAK,cAAc,QAAQ,KAAK,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS;YACjF,GAAG,WAAW,IAAI,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,gCAAgC;YACpF,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CACnC,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,QAAQ,EAAE,CAAC;IAC5F,OAAO,CACL,GAAG,MAAM,CAAC,KAAK,KAAK,WAAW,eAAe,cAAc,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM;QACtF,GAAG,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM;QAC/E,GAAG,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG;QACzE,GAAG,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,MAAM,CAAC,KAAK,GAAG,KAAK,IAAI;QACzE,OAAO,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS;QACnF,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG;QACzE,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CACnC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,MAAwB,EAAE,OAAuB;IACvE,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,aAAa,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,OAAO,CACL,GAAG,MAAM,CAAC,KAAK,KAAK,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,QAAQ,YAAY;YACxF,0CAA0C,YAAY,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG;YACnF,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CACnC,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG;SAC9B,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;SAC7E,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC;IACzC,IAAI,IAAI,GACN,GAAG,MAAM,CAAC,KAAK,KAAK,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG;QAC5D,UAAU,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ;QAC1D,GAAG,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,QAAQ,sBAAsB;QACjF,GAAG,MAAM,IAAI,QAAQ,gBAAgB,QAAQ,QAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY;QACvF,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;IAClD,IAAI,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;IAC1E,8EAA8E;IAC9E,oDAAoD;IACpD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CACP,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,OAAO,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAClG,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CACP,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAC5F,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;IAC5E,CAAC;IACD,OAAO,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,aAAa,CAAC,MAAwB,EAAE,OAAsB;IACrE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAEtC,IAAI,IAAY,CAAC;IACjB,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,OAAO;aACnB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;aACnF,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,IAAI,GAAG,GAAG,MAAM,CAAC,KAAK,KAAK,MAAM,GAAG,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,IAAI;YACF,GAAG,MAAM,CAAC,KAAK,KAAK,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM;gBACpD,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;IACzD,CAAC;IAED,KAAK,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3D,IAAI;YACF,IAAI,cAAc,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;gBAC9D,GAAG,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AACnD,CAAC;AASD,kFAAkF;AAClF,MAAM,UAAU,UAAU,CAAC,MAAwB,EAAE,OAAsB;IACzE,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5D,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5D,KAAK,UAAU;YACb,OAAO,cAAc,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7D,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod mirrors of the three result envelopes.
|
|
3
|
+
*
|
|
4
|
+
* The collector attaches each route's 200 response schema from the registry so
|
|
5
|
+
* the Zod type provider **serialises through it** — which means the `table` and
|
|
6
|
+
* `summary` envelopes need schemas too, or a formatted response would be
|
|
7
|
+
* stripped down to nothing on its way out. `resultEnvelopeSchema(row)` builds
|
|
8
|
+
* the union a formatted route responds with: the untouched `full` shape first,
|
|
9
|
+
* so a default request is validated by exactly the schema it has always been
|
|
10
|
+
* validated by, then the two envelopes.
|
|
11
|
+
*
|
|
12
|
+
* These live next to the types rather than in the collector so the shapes have
|
|
13
|
+
* one definition — the same reason the row schemas live in the registry.
|
|
14
|
+
*/
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
import type { ResultFormat } from "./types.js";
|
|
17
|
+
/**
|
|
18
|
+
* `format=full | table | summary`, the shared querystring value every
|
|
19
|
+
* registry-served aggregate endpoint accepts. Spelled out literally rather than
|
|
20
|
+
* built from `RESULT_FORMATS` so the inferred type is the `ResultFormat` union
|
|
21
|
+
* and a route handler keeps its narrowing.
|
|
22
|
+
*/
|
|
23
|
+
export declare const resultFormatSchema: z.ZodEnum<{
|
|
24
|
+
table: "table";
|
|
25
|
+
full: "full";
|
|
26
|
+
summary: "summary";
|
|
27
|
+
}>;
|
|
28
|
+
/** Fails to compile if the schema and {@link ResultFormat} ever drift apart. */
|
|
29
|
+
type AssertFormatsAgree = [
|
|
30
|
+
z.infer<typeof resultFormatSchema> extends ResultFormat ? true : never,
|
|
31
|
+
ResultFormat extends z.infer<typeof resultFormatSchema> ? true : never
|
|
32
|
+
];
|
|
33
|
+
export type ResultFormatsAgree = AssertFormatsAgree;
|
|
34
|
+
/** `format=summary`: one of the four grain-driven shapes. */
|
|
35
|
+
export declare const resultSummarySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
36
|
+
kind: z.ZodLiteral<"ranked">;
|
|
37
|
+
top: z.ZodArray<z.ZodObject<{
|
|
38
|
+
label: z.ZodString;
|
|
39
|
+
value: z.ZodNullable<z.ZodNumber>;
|
|
40
|
+
share: z.ZodNullable<z.ZodNumber>;
|
|
41
|
+
shareInterval: z.ZodOptional<z.ZodObject<{
|
|
42
|
+
low: z.ZodNumber;
|
|
43
|
+
high: z.ZodNumber;
|
|
44
|
+
}, z.core.$strip>>;
|
|
45
|
+
drill: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
46
|
+
}, z.core.$strip>>;
|
|
47
|
+
rest: z.ZodObject<{
|
|
48
|
+
rows: z.ZodNumber;
|
|
49
|
+
value: z.ZodNullable<z.ZodNumber>;
|
|
50
|
+
share: z.ZodNullable<z.ZodNumber>;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
metric: z.ZodEnum<{
|
|
53
|
+
[x: string]: string;
|
|
54
|
+
}>;
|
|
55
|
+
range: z.ZodObject<{
|
|
56
|
+
since: z.ZodNullable<z.ZodNumber>;
|
|
57
|
+
until: z.ZodNullable<z.ZodNumber>;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
filters: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
60
|
+
sampleSize: z.ZodObject<{
|
|
61
|
+
sessions: z.ZodNullable<z.ZodNumber>;
|
|
62
|
+
events: z.ZodNullable<z.ZodNumber>;
|
|
63
|
+
}, z.core.$strip>;
|
|
64
|
+
total: z.ZodNullable<z.ZodNumber>;
|
|
65
|
+
measure: z.ZodNullable<z.ZodObject<{
|
|
66
|
+
column: z.ZodString;
|
|
67
|
+
unit: z.ZodNullable<z.ZodString>;
|
|
68
|
+
additive: z.ZodBoolean;
|
|
69
|
+
}, z.core.$strip>>;
|
|
70
|
+
confidence: z.ZodOptional<z.ZodObject<{
|
|
71
|
+
kind: z.ZodLiteral<"wilson">;
|
|
72
|
+
level: z.ZodNumber;
|
|
73
|
+
note: z.ZodString;
|
|
74
|
+
}, z.core.$strip>>;
|
|
75
|
+
reading: z.ZodString;
|
|
76
|
+
caveats: z.ZodArray<z.ZodString>;
|
|
77
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
78
|
+
kind: z.ZodLiteral<"series">;
|
|
79
|
+
series: z.ZodObject<{
|
|
80
|
+
axis: z.ZodString;
|
|
81
|
+
points: z.ZodNumber;
|
|
82
|
+
first: z.ZodNullable<z.ZodNumber>;
|
|
83
|
+
last: z.ZodNullable<z.ZodNumber>;
|
|
84
|
+
min: z.ZodNullable<z.ZodNumber>;
|
|
85
|
+
max: z.ZodNullable<z.ZodNumber>;
|
|
86
|
+
firstLabel: z.ZodNullable<z.ZodString>;
|
|
87
|
+
lastLabel: z.ZodNullable<z.ZodString>;
|
|
88
|
+
minLabel: z.ZodNullable<z.ZodString>;
|
|
89
|
+
maxLabel: z.ZodNullable<z.ZodString>;
|
|
90
|
+
trend: z.ZodEnum<{
|
|
91
|
+
flat: "flat";
|
|
92
|
+
up: "up";
|
|
93
|
+
down: "down";
|
|
94
|
+
}>;
|
|
95
|
+
slope: z.ZodNullable<z.ZodNumber>;
|
|
96
|
+
}, z.core.$strip>;
|
|
97
|
+
metric: z.ZodEnum<{
|
|
98
|
+
[x: string]: string;
|
|
99
|
+
}>;
|
|
100
|
+
range: z.ZodObject<{
|
|
101
|
+
since: z.ZodNullable<z.ZodNumber>;
|
|
102
|
+
until: z.ZodNullable<z.ZodNumber>;
|
|
103
|
+
}, z.core.$strip>;
|
|
104
|
+
filters: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
105
|
+
sampleSize: z.ZodObject<{
|
|
106
|
+
sessions: z.ZodNullable<z.ZodNumber>;
|
|
107
|
+
events: z.ZodNullable<z.ZodNumber>;
|
|
108
|
+
}, z.core.$strip>;
|
|
109
|
+
total: z.ZodNullable<z.ZodNumber>;
|
|
110
|
+
measure: z.ZodNullable<z.ZodObject<{
|
|
111
|
+
column: z.ZodString;
|
|
112
|
+
unit: z.ZodNullable<z.ZodString>;
|
|
113
|
+
additive: z.ZodBoolean;
|
|
114
|
+
}, z.core.$strip>>;
|
|
115
|
+
confidence: z.ZodOptional<z.ZodObject<{
|
|
116
|
+
kind: z.ZodLiteral<"wilson">;
|
|
117
|
+
level: z.ZodNumber;
|
|
118
|
+
note: z.ZodString;
|
|
119
|
+
}, z.core.$strip>>;
|
|
120
|
+
reading: z.ZodString;
|
|
121
|
+
caveats: z.ZodArray<z.ZodString>;
|
|
122
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
123
|
+
kind: z.ZodLiteral<"clusters">;
|
|
124
|
+
axes: z.ZodArray<z.ZodString>;
|
|
125
|
+
occupiedCells: z.ZodNumber;
|
|
126
|
+
densityThreshold: z.ZodNumber;
|
|
127
|
+
clusters: z.ZodArray<z.ZodObject<{
|
|
128
|
+
centroid: z.ZodArray<z.ZodNumber>;
|
|
129
|
+
extent: z.ZodObject<{
|
|
130
|
+
min: z.ZodArray<z.ZodNumber>;
|
|
131
|
+
max: z.ZodArray<z.ZodNumber>;
|
|
132
|
+
}, z.core.$strip>;
|
|
133
|
+
cells: z.ZodNumber;
|
|
134
|
+
weight: z.ZodNumber;
|
|
135
|
+
share: z.ZodNullable<z.ZodNumber>;
|
|
136
|
+
drill: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
137
|
+
}, z.core.$strip>>;
|
|
138
|
+
rest: z.ZodObject<{
|
|
139
|
+
clusters: z.ZodNumber;
|
|
140
|
+
cells: z.ZodNumber;
|
|
141
|
+
weight: z.ZodNullable<z.ZodNumber>;
|
|
142
|
+
share: z.ZodNullable<z.ZodNumber>;
|
|
143
|
+
}, z.core.$strip>;
|
|
144
|
+
metric: z.ZodEnum<{
|
|
145
|
+
[x: string]: string;
|
|
146
|
+
}>;
|
|
147
|
+
range: z.ZodObject<{
|
|
148
|
+
since: z.ZodNullable<z.ZodNumber>;
|
|
149
|
+
until: z.ZodNullable<z.ZodNumber>;
|
|
150
|
+
}, z.core.$strip>;
|
|
151
|
+
filters: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
152
|
+
sampleSize: z.ZodObject<{
|
|
153
|
+
sessions: z.ZodNullable<z.ZodNumber>;
|
|
154
|
+
events: z.ZodNullable<z.ZodNumber>;
|
|
155
|
+
}, z.core.$strip>;
|
|
156
|
+
total: z.ZodNullable<z.ZodNumber>;
|
|
157
|
+
measure: z.ZodNullable<z.ZodObject<{
|
|
158
|
+
column: z.ZodString;
|
|
159
|
+
unit: z.ZodNullable<z.ZodString>;
|
|
160
|
+
additive: z.ZodBoolean;
|
|
161
|
+
}, z.core.$strip>>;
|
|
162
|
+
confidence: z.ZodOptional<z.ZodObject<{
|
|
163
|
+
kind: z.ZodLiteral<"wilson">;
|
|
164
|
+
level: z.ZodNumber;
|
|
165
|
+
note: z.ZodString;
|
|
166
|
+
}, z.core.$strip>>;
|
|
167
|
+
reading: z.ZodString;
|
|
168
|
+
caveats: z.ZodArray<z.ZodString>;
|
|
169
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
170
|
+
kind: z.ZodLiteral<"record">;
|
|
171
|
+
record: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>;
|
|
172
|
+
rates: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
173
|
+
value: z.ZodNullable<z.ZodNumber>;
|
|
174
|
+
numerator: z.ZodString;
|
|
175
|
+
denominator: z.ZodString;
|
|
176
|
+
}, z.core.$strip>>;
|
|
177
|
+
metric: z.ZodEnum<{
|
|
178
|
+
[x: string]: string;
|
|
179
|
+
}>;
|
|
180
|
+
range: z.ZodObject<{
|
|
181
|
+
since: z.ZodNullable<z.ZodNumber>;
|
|
182
|
+
until: z.ZodNullable<z.ZodNumber>;
|
|
183
|
+
}, z.core.$strip>;
|
|
184
|
+
filters: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
185
|
+
sampleSize: z.ZodObject<{
|
|
186
|
+
sessions: z.ZodNullable<z.ZodNumber>;
|
|
187
|
+
events: z.ZodNullable<z.ZodNumber>;
|
|
188
|
+
}, z.core.$strip>;
|
|
189
|
+
total: z.ZodNullable<z.ZodNumber>;
|
|
190
|
+
measure: z.ZodNullable<z.ZodObject<{
|
|
191
|
+
column: z.ZodString;
|
|
192
|
+
unit: z.ZodNullable<z.ZodString>;
|
|
193
|
+
additive: z.ZodBoolean;
|
|
194
|
+
}, z.core.$strip>>;
|
|
195
|
+
confidence: z.ZodOptional<z.ZodObject<{
|
|
196
|
+
kind: z.ZodLiteral<"wilson">;
|
|
197
|
+
level: z.ZodNumber;
|
|
198
|
+
note: z.ZodString;
|
|
199
|
+
}, z.core.$strip>>;
|
|
200
|
+
reading: z.ZodString;
|
|
201
|
+
caveats: z.ZodArray<z.ZodString>;
|
|
202
|
+
}, z.core.$strip>], "kind">;
|
|
203
|
+
/** `format=table`: the `meta` envelope around a metric's own row schema. */
|
|
204
|
+
export declare function tableResultSchema(row: z.ZodType): z.ZodObject;
|
|
205
|
+
/**
|
|
206
|
+
* The 200 response schema of a route that honours `format`: the union of the
|
|
207
|
+
* three envelopes.
|
|
208
|
+
*
|
|
209
|
+
* Order matters. `full` is first, so a default request is parsed by precisely
|
|
210
|
+
* the schema it was parsed by before this existed and its bytes cannot drift.
|
|
211
|
+
* The envelopes are unambiguous against it — `table` is an object with `meta`
|
|
212
|
+
* and `rows`, `summary` an object with `kind` and `reading`, and neither can
|
|
213
|
+
* satisfy a row array or a stats row's required numeric columns.
|
|
214
|
+
*/
|
|
215
|
+
export declare function resultEnvelopeSchema(full: z.ZodType, row: z.ZodType): z.ZodType;
|
|
216
|
+
export {};
|
|
217
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/query/summary/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;EAAuC,CAAC;AAEvE,gFAAgF;AAChF,KAAK,kBAAkB,GAAG;IACxB,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,SAAS,YAAY,GAAG,IAAI,GAAG,KAAK;IACtE,YAAY,SAAS,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,GAAG,IAAI,GAAG,KAAK;CACvE,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAoIpD,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAK9B,CAAC;AAEH,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,SAAS,CAa7D;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAE/E"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod mirrors of the three result envelopes.
|
|
3
|
+
*
|
|
4
|
+
* The collector attaches each route's 200 response schema from the registry so
|
|
5
|
+
* the Zod type provider **serialises through it** — which means the `table` and
|
|
6
|
+
* `summary` envelopes need schemas too, or a formatted response would be
|
|
7
|
+
* stripped down to nothing on its way out. `resultEnvelopeSchema(row)` builds
|
|
8
|
+
* the union a formatted route responds with: the untouched `full` shape first,
|
|
9
|
+
* so a default request is validated by exactly the schema it has always been
|
|
10
|
+
* validated by, then the two envelopes.
|
|
11
|
+
*
|
|
12
|
+
* These live next to the types rather than in the collector so the shapes have
|
|
13
|
+
* one definition — the same reason the row schemas live in the registry.
|
|
14
|
+
*/
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
import { METRIC_IDS } from "@uptimizr/metrics";
|
|
17
|
+
/**
|
|
18
|
+
* `format=full | table | summary`, the shared querystring value every
|
|
19
|
+
* registry-served aggregate endpoint accepts. Spelled out literally rather than
|
|
20
|
+
* built from `RESULT_FORMATS` so the inferred type is the `ResultFormat` union
|
|
21
|
+
* and a route handler keeps its narrowing.
|
|
22
|
+
*/
|
|
23
|
+
export const resultFormatSchema = z.enum(["full", "table", "summary"]);
|
|
24
|
+
/** Any registry metric id. */
|
|
25
|
+
const metricIdSchema = z.enum(METRIC_IDS);
|
|
26
|
+
const rangeSchema = z.object({
|
|
27
|
+
since: z.number().nullable(),
|
|
28
|
+
until: z.number().nullable(),
|
|
29
|
+
});
|
|
30
|
+
/** Applied filter values are whatever the route's own schema produced. */
|
|
31
|
+
const filtersSchema = z.record(z.string(), z.unknown());
|
|
32
|
+
const sampleSizeSchema = z.object({
|
|
33
|
+
sessions: z.number().nullable(),
|
|
34
|
+
events: z.number().nullable(),
|
|
35
|
+
});
|
|
36
|
+
const limitsSchema = z.object({
|
|
37
|
+
maxRows: z.number().int(),
|
|
38
|
+
maxSummaryRows: z.number().int(),
|
|
39
|
+
});
|
|
40
|
+
const measureSchema = z
|
|
41
|
+
.object({
|
|
42
|
+
column: z.string(),
|
|
43
|
+
unit: z.string().nullable(),
|
|
44
|
+
additive: z.boolean(),
|
|
45
|
+
})
|
|
46
|
+
.nullable();
|
|
47
|
+
const shareIntervalSchema = z.object({ low: z.number(), high: z.number() });
|
|
48
|
+
const confidenceSchema = z.object({
|
|
49
|
+
kind: z.literal("wilson"),
|
|
50
|
+
level: z.number(),
|
|
51
|
+
note: z.string(),
|
|
52
|
+
});
|
|
53
|
+
const drillSchema = z.record(z.string(), z.string());
|
|
54
|
+
const restSchema = z.object({
|
|
55
|
+
rows: z.number().int(),
|
|
56
|
+
value: z.number().nullable(),
|
|
57
|
+
share: z.number().nullable(),
|
|
58
|
+
});
|
|
59
|
+
/** Fields every summary carries, whatever its grain. */
|
|
60
|
+
const summaryBase = {
|
|
61
|
+
metric: metricIdSchema,
|
|
62
|
+
range: rangeSchema,
|
|
63
|
+
filters: filtersSchema,
|
|
64
|
+
sampleSize: sampleSizeSchema,
|
|
65
|
+
total: z.number().nullable(),
|
|
66
|
+
measure: measureSchema,
|
|
67
|
+
confidence: confidenceSchema.optional(),
|
|
68
|
+
reading: z.string(),
|
|
69
|
+
caveats: z.array(z.string()),
|
|
70
|
+
};
|
|
71
|
+
const rankedSummarySchema = z.object({
|
|
72
|
+
...summaryBase,
|
|
73
|
+
kind: z.literal("ranked"),
|
|
74
|
+
top: z.array(z.object({
|
|
75
|
+
label: z.string(),
|
|
76
|
+
value: z.number().nullable(),
|
|
77
|
+
share: z.number().nullable(),
|
|
78
|
+
shareInterval: shareIntervalSchema.optional(),
|
|
79
|
+
drill: drillSchema.optional(),
|
|
80
|
+
})),
|
|
81
|
+
rest: restSchema,
|
|
82
|
+
});
|
|
83
|
+
const seriesSummarySchema = z.object({
|
|
84
|
+
...summaryBase,
|
|
85
|
+
kind: z.literal("series"),
|
|
86
|
+
series: z.object({
|
|
87
|
+
axis: z.string(),
|
|
88
|
+
points: z.number().int(),
|
|
89
|
+
first: z.number().nullable(),
|
|
90
|
+
last: z.number().nullable(),
|
|
91
|
+
min: z.number().nullable(),
|
|
92
|
+
max: z.number().nullable(),
|
|
93
|
+
firstLabel: z.string().nullable(),
|
|
94
|
+
lastLabel: z.string().nullable(),
|
|
95
|
+
minLabel: z.string().nullable(),
|
|
96
|
+
maxLabel: z.string().nullable(),
|
|
97
|
+
trend: z.enum(["up", "down", "flat"]),
|
|
98
|
+
slope: z.number().nullable(),
|
|
99
|
+
}),
|
|
100
|
+
});
|
|
101
|
+
const clusterSummarySchema = z.object({
|
|
102
|
+
...summaryBase,
|
|
103
|
+
kind: z.literal("clusters"),
|
|
104
|
+
axes: z.array(z.string()),
|
|
105
|
+
occupiedCells: z.number().int(),
|
|
106
|
+
densityThreshold: z.number(),
|
|
107
|
+
clusters: z.array(z.object({
|
|
108
|
+
centroid: z.array(z.number()),
|
|
109
|
+
extent: z.object({ min: z.array(z.number()), max: z.array(z.number()) }),
|
|
110
|
+
cells: z.number().int(),
|
|
111
|
+
weight: z.number(),
|
|
112
|
+
share: z.number().nullable(),
|
|
113
|
+
drill: drillSchema.optional(),
|
|
114
|
+
})),
|
|
115
|
+
rest: z.object({
|
|
116
|
+
clusters: z.number().int(),
|
|
117
|
+
cells: z.number().int(),
|
|
118
|
+
weight: z.number().nullable(),
|
|
119
|
+
share: z.number().nullable(),
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
const recordSummarySchema = z.object({
|
|
123
|
+
...summaryBase,
|
|
124
|
+
kind: z.literal("record"),
|
|
125
|
+
record: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.null()])),
|
|
126
|
+
rates: z.record(z.string(), z.object({
|
|
127
|
+
value: z.number().nullable(),
|
|
128
|
+
numerator: z.string(),
|
|
129
|
+
denominator: z.string(),
|
|
130
|
+
})),
|
|
131
|
+
});
|
|
132
|
+
/** `format=summary`: one of the four grain-driven shapes. */
|
|
133
|
+
export const resultSummarySchema = z.discriminatedUnion("kind", [
|
|
134
|
+
rankedSummarySchema,
|
|
135
|
+
seriesSummarySchema,
|
|
136
|
+
clusterSummarySchema,
|
|
137
|
+
recordSummarySchema,
|
|
138
|
+
]);
|
|
139
|
+
/** `format=table`: the `meta` envelope around a metric's own row schema. */
|
|
140
|
+
export function tableResultSchema(row) {
|
|
141
|
+
return z.object({
|
|
142
|
+
meta: z.object({
|
|
143
|
+
metric: metricIdSchema,
|
|
144
|
+
range: rangeSchema,
|
|
145
|
+
filters: filtersSchema,
|
|
146
|
+
sampleSize: sampleSizeSchema,
|
|
147
|
+
rows: z.number().int(),
|
|
148
|
+
truncated: z.boolean(),
|
|
149
|
+
limits: limitsSchema,
|
|
150
|
+
}),
|
|
151
|
+
rows: z.array(row),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* The 200 response schema of a route that honours `format`: the union of the
|
|
156
|
+
* three envelopes.
|
|
157
|
+
*
|
|
158
|
+
* Order matters. `full` is first, so a default request is parsed by precisely
|
|
159
|
+
* the schema it was parsed by before this existed and its bytes cannot drift.
|
|
160
|
+
* The envelopes are unambiguous against it — `table` is an object with `meta`
|
|
161
|
+
* and `rows`, `summary` an object with `kind` and `reading`, and neither can
|
|
162
|
+
* satisfy a row array or a stats row's required numeric columns.
|
|
163
|
+
*/
|
|
164
|
+
export function resultEnvelopeSchema(full, row) {
|
|
165
|
+
return z.union([full, tableResultSchema(row), resultSummarySchema]);
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/query/summary/schema.ts"],"names":[],"mappings":"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"}
|