@hypequery/serve 0.3.0 → 0.4.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.
@@ -1,3 +1,3 @@
1
- import type { AnyDatasetInstance } from '@hypequery/datasets';
1
+ import { type AnyDatasetInstance } from '@hypequery/datasets';
2
2
  export declare function buildDatasetQueryDescription(ds: AnyDatasetInstance, maxLimit: number): string;
3
3
  //# sourceMappingURL=dataset-query-metadata.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dataset-query-metadata.d.ts","sourceRoot":"","sources":["../../../../src/semantic/datasets/utils/dataset-query-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,kBAAkB,EACtB,QAAQ,EAAE,MAAM,GACf,MAAM,CAYR"}
1
+ {"version":3,"file":"dataset-query-metadata.d.ts","sourceRoot":"","sources":["../../../../src/semantic/datasets/utils/dataset-query-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,kBAAkB,EACtB,QAAQ,EAAE,MAAM,GACf,MAAM,CAmBR"}
@@ -1,11 +1,19 @@
1
+ import { getDatasetCatalog } from '@hypequery/datasets';
1
2
  export function buildDatasetQueryDescription(ds, maxLimit) {
2
- const dimensionNames = Object.keys(ds.dimensions);
3
- const measureNames = Object.keys(ds.measures);
3
+ const catalog = getDatasetCatalog(ds);
4
+ const dimensionNames = Object.keys(catalog.dimensions);
5
+ const measureNames = Object.keys(catalog.measures);
6
+ const filterNames = Object.keys(catalog.filters);
7
+ const relationshipNames = Object.keys(catalog.relationships);
4
8
  const lines = [
5
- `Query the ${ds.name} semantic dataset (source: ${ds.source}).`,
9
+ `Query the ${catalog.name} semantic dataset (source: ${catalog.source}).`,
6
10
  '',
7
11
  `**Dimensions:** ${dimensionNames.join(', ') || 'none'}`,
8
12
  `**Measures:** ${measureNames.join(', ') || 'none'}`,
13
+ `**Filters:** ${filterNames.join(', ') || 'none'}`,
14
+ `**Time grains:** ${catalog.supportedGrains.join(', ') || 'none'}`,
15
+ `**Relationships:** ${relationshipNames.join(', ') || 'none'}`,
16
+ `**Tenant scoped:** ${catalog.requiresTenant ? 'yes' : 'no'}`,
9
17
  `**Max limit:** ${maxLimit}`,
10
18
  ];
11
19
  return lines.join('\n');
@@ -11,7 +11,7 @@
11
11
  * validator produce the precise error, rather than emitting an empty enum.
12
12
  */
13
13
  import { z } from 'zod';
14
- import type { AnyDatasetInstance } from '@hypequery/datasets';
14
+ import { type AnyDatasetInstance } from '@hypequery/datasets';
15
15
  /**
16
16
  * Input schema for a dataset query endpoint, mirroring
17
17
  * `validateDatasetQueryInput`.
@@ -32,7 +32,7 @@ export declare function buildDatasetInputSchema(ds: AnyDatasetInstance): z.ZodOb
32
32
  }>, "many">>;
33
33
  limit: z.ZodOptional<z.ZodNumber>;
34
34
  offset: z.ZodOptional<z.ZodNumber>;
35
- by: z.ZodOptional<z.ZodEnum<["day", "week", "month", "quarter", "year"]>>;
35
+ by: z.ZodOptional<z.ZodTypeAny>;
36
36
  includeMeta: z.ZodOptional<z.ZodBoolean>;
37
37
  }, "strict", z.ZodTypeAny, {
38
38
  dimensions?: any[] | undefined;
@@ -44,7 +44,7 @@ export declare function buildDatasetInputSchema(ds: AnyDatasetInstance): z.ZodOb
44
44
  }[] | undefined;
45
45
  limit?: number | undefined;
46
46
  offset?: number | undefined;
47
- by?: "day" | "week" | "month" | "quarter" | "year" | undefined;
47
+ by?: any;
48
48
  includeMeta?: boolean | undefined;
49
49
  }, {
50
50
  dimensions?: any[] | undefined;
@@ -56,7 +56,7 @@ export declare function buildDatasetInputSchema(ds: AnyDatasetInstance): z.ZodOb
56
56
  }[] | undefined;
57
57
  limit?: number | undefined;
58
58
  offset?: number | undefined;
59
- by?: "day" | "week" | "month" | "quarter" | "year" | undefined;
59
+ by?: any;
60
60
  includeMeta?: boolean | undefined;
61
61
  }>;
62
62
  /**
@@ -79,7 +79,7 @@ export declare function buildMetricInputSchema(ds: AnyDatasetInstance, metricNam
79
79
  }>, "many">>;
80
80
  limit: z.ZodOptional<z.ZodNumber>;
81
81
  offset: z.ZodOptional<z.ZodNumber>;
82
- by: z.ZodOptional<z.ZodEnum<["day", "week", "month", "quarter", "year"]>>;
82
+ by: z.ZodOptional<z.ZodTypeAny>;
83
83
  includeMeta: z.ZodOptional<z.ZodBoolean>;
84
84
  }, "strip", z.ZodTypeAny, {
85
85
  dimensions?: any[] | undefined;
@@ -90,7 +90,7 @@ export declare function buildMetricInputSchema(ds: AnyDatasetInstance, metricNam
90
90
  }[] | undefined;
91
91
  limit?: number | undefined;
92
92
  offset?: number | undefined;
93
- by?: "day" | "week" | "month" | "quarter" | "year" | undefined;
93
+ by?: any;
94
94
  includeMeta?: boolean | undefined;
95
95
  }, {
96
96
  dimensions?: any[] | undefined;
@@ -101,7 +101,7 @@ export declare function buildMetricInputSchema(ds: AnyDatasetInstance, metricNam
101
101
  }[] | undefined;
102
102
  limit?: number | undefined;
103
103
  offset?: number | undefined;
104
- by?: "day" | "week" | "month" | "quarter" | "year" | undefined;
104
+ by?: any;
105
105
  includeMeta?: boolean | undefined;
106
106
  }>;
107
107
  //# sourceMappingURL=semantic-input-schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-input-schema.d.ts","sourceRoot":"","sources":["../../../../src/semantic/datasets/utils/semantic-input-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAqC9D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmB7D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiBhF"}
1
+ {"version":3,"file":"semantic-input-schema.d.ts","sourceRoot":"","sources":["../../../../src/semantic/datasets/utils/semantic-input-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,qBAAqB,CAAC;AAoC7B;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAe7D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkBhF"}
@@ -11,10 +11,7 @@
11
11
  * validator produce the precise error, rather than emitting an empty enum.
12
12
  */
13
13
  import { z } from 'zod';
14
- const OPERATORS = [
15
- 'eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'notIn', 'between', 'like',
16
- ];
17
- const GRAINS = ['day', 'week', 'month', 'quarter', 'year'];
14
+ import { getDatasetCatalog, SEMANTIC_FILTER_OPERATORS, } from '@hypequery/datasets';
18
15
  /** An enum over the given field names, or a plain string when none are known. */
19
16
  function fieldEnum(values) {
20
17
  const unique = Array.from(new Set(values));
@@ -22,10 +19,14 @@ function fieldEnum(values) {
22
19
  ? z.enum(unique)
23
20
  : z.string();
24
21
  }
25
- function filterSchema(fieldNames) {
22
+ function grainEnum(catalog) {
23
+ return fieldEnum(catalog.supportedGrains);
24
+ }
25
+ function filterSchema(catalog) {
26
+ const fieldNames = Object.keys(catalog.filters);
26
27
  return z.object({
27
28
  field: fieldEnum(fieldNames),
28
- operator: z.enum(OPERATORS),
29
+ operator: z.enum(SEMANTIC_FILTER_OPERATORS),
29
30
  value: z.unknown(),
30
31
  });
31
32
  }
@@ -45,21 +46,17 @@ function boundedArray(item, max) {
45
46
  * `validateDatasetQueryInput`.
46
47
  */
47
48
  export function buildDatasetInputSchema(ds) {
48
- const dimensionNames = Object.keys(ds.dimensions);
49
- const measureNames = Object.keys(ds.measures);
50
- // Dataset filters are keyed by filter-definition name (no dimension fallback).
51
- const filterNames = Object.keys(ds.filters);
52
- // orderBy is query-dependent at runtime; the static superset is every
53
- // dimension/measure plus the synthetic `period` column when grained.
54
- const orderableNames = [...dimensionNames, ...measureNames, 'period'];
49
+ const catalog = getDatasetCatalog(ds);
50
+ const dimensionNames = Object.keys(catalog.dimensions);
51
+ const measureNames = Object.keys(catalog.measures);
55
52
  return z.object({
56
53
  dimensions: boundedArray(fieldEnum(dimensionNames), ds.limits?.maxDimensions),
57
54
  measures: boundedArray(fieldEnum(measureNames), ds.limits?.maxMeasures),
58
- filters: boundedArray(filterSchema(filterNames), ds.limits?.maxFilters),
59
- orderBy: z.array(orderBySchema(orderableNames)).optional(),
55
+ filters: boundedArray(filterSchema(catalog), ds.limits?.maxFilters),
56
+ orderBy: z.array(orderBySchema(catalog.orderableFields)).optional(),
60
57
  limit: z.number().int().positive().optional(),
61
58
  offset: z.number().int().nonnegative().optional(),
62
- by: z.enum(GRAINS).optional(),
59
+ by: grainEnum(catalog).optional(),
63
60
  includeMeta: z.boolean().optional(),
64
61
  }).strict();
65
62
  }
@@ -69,19 +66,20 @@ export function buildDatasetInputSchema(ds) {
69
66
  * reference the metric's own output column (`metricName`).
70
67
  */
71
68
  export function buildMetricInputSchema(ds, metricName) {
72
- const dimensionNames = Object.keys(ds.dimensions);
73
- // Metric validator falls back to dimension names when no filters are declared.
74
- const filterNames = Object.keys(ds.filters).length > 0
75
- ? Object.keys(ds.filters)
76
- : dimensionNames;
77
- const orderableNames = [...dimensionNames, metricName, 'period'];
69
+ const catalog = getDatasetCatalog(ds);
70
+ const dimensionNames = Object.keys(catalog.dimensions);
71
+ const orderableNames = [
72
+ ...dimensionNames,
73
+ metricName,
74
+ ...(catalog.timeKey ? ['period'] : []),
75
+ ];
78
76
  return z.object({
79
77
  dimensions: boundedArray(fieldEnum(dimensionNames), ds.limits?.maxDimensions),
80
- filters: boundedArray(filterSchema(filterNames), ds.limits?.maxFilters),
78
+ filters: boundedArray(filterSchema(catalog), ds.limits?.maxFilters),
81
79
  orderBy: z.array(orderBySchema(orderableNames)).optional(),
82
80
  limit: z.number().int().positive().optional(),
83
81
  offset: z.number().int().nonnegative().optional(),
84
- by: z.enum(GRAINS).optional(),
82
+ by: grainEnum(catalog).optional(),
85
83
  includeMeta: z.boolean().optional(),
86
84
  });
87
85
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypequery/serve",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Declarative HTTP server for exposing hypequery analytics endpoints",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -21,7 +21,7 @@
21
21
  "openapi-typescript": "^7.13.0",
22
22
  "zod": "^3.23.8",
23
23
  "zod-to-json-schema": "^3.23.5",
24
- "@hypequery/datasets": "^0.2.0"
24
+ "@hypequery/datasets": "^0.3.0"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "tsx": "^4.0.0"