@hypequery/serve 0.2.0 → 0.3.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.
Files changed (77) hide show
  1. package/README.md +138 -879
  2. package/dist/adapters/node.d.ts.map +1 -1
  3. package/dist/adapters/node.js +3 -5
  4. package/dist/adapters/standalone.d.ts +41 -0
  5. package/dist/adapters/standalone.d.ts.map +1 -0
  6. package/dist/adapters/standalone.js +46 -0
  7. package/dist/auth.d.ts +59 -83
  8. package/dist/auth.d.ts.map +1 -1
  9. package/dist/auth.js +136 -102
  10. package/dist/client-config.d.ts +3 -2
  11. package/dist/client-config.d.ts.map +1 -1
  12. package/dist/client-config.js +4 -2
  13. package/dist/errors.js +3 -0
  14. package/dist/index.d.ts +2 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -0
  17. package/dist/openapi.js +1 -2
  18. package/dist/pipeline.d.ts.map +1 -1
  19. package/dist/pipeline.js +10 -22
  20. package/dist/query-logger.js +1 -3
  21. package/dist/rate-limit.js +4 -3
  22. package/dist/router.js +2 -1
  23. package/dist/semantic/datasets/dataset-endpoint.d.ts +85 -0
  24. package/dist/semantic/datasets/dataset-endpoint.d.ts.map +1 -0
  25. package/dist/semantic/datasets/dataset-endpoint.js +121 -0
  26. package/dist/semantic/datasets/index.d.ts +6 -0
  27. package/dist/semantic/datasets/index.d.ts.map +1 -0
  28. package/dist/semantic/datasets/index.js +5 -0
  29. package/dist/semantic/datasets/metric-endpoint.d.ts +82 -0
  30. package/dist/semantic/datasets/metric-endpoint.d.ts.map +1 -0
  31. package/dist/semantic/datasets/metric-endpoint.js +159 -0
  32. package/dist/semantic/datasets/utils/dataset-entry.d.ts +24 -0
  33. package/dist/semantic/datasets/utils/dataset-entry.d.ts.map +1 -0
  34. package/dist/semantic/datasets/utils/dataset-entry.js +15 -0
  35. package/dist/semantic/datasets/utils/dataset-query-metadata.d.ts +3 -0
  36. package/dist/semantic/datasets/utils/dataset-query-metadata.d.ts.map +1 -0
  37. package/dist/semantic/datasets/utils/dataset-query-metadata.js +12 -0
  38. package/dist/semantic/datasets/utils/semantic-input-schema.d.ts +107 -0
  39. package/dist/semantic/datasets/utils/semantic-input-schema.d.ts.map +1 -0
  40. package/dist/semantic/datasets/utils/semantic-input-schema.js +87 -0
  41. package/dist/semantic/index.d.ts +2 -0
  42. package/dist/semantic/index.d.ts.map +1 -0
  43. package/dist/semantic/index.js +1 -0
  44. package/dist/semantic/query-builder-context.d.ts +20 -0
  45. package/dist/semantic/query-builder-context.d.ts.map +1 -0
  46. package/dist/semantic/query-builder-context.js +66 -0
  47. package/dist/semantic/utils/tenant-runtime.d.ts +11 -0
  48. package/dist/semantic/utils/tenant-runtime.d.ts.map +1 -0
  49. package/dist/semantic/utils/tenant-runtime.js +48 -0
  50. package/dist/serve.d.ts +2 -2
  51. package/dist/serve.d.ts.map +1 -1
  52. package/dist/server/api-builder.d.ts +5 -0
  53. package/dist/server/api-builder.d.ts.map +1 -0
  54. package/dist/server/api-builder.js +76 -0
  55. package/dist/server/builder.d.ts.map +1 -1
  56. package/dist/server/builder.js +11 -1
  57. package/dist/server/create-api.d.ts +32 -0
  58. package/dist/server/create-api.d.ts.map +1 -0
  59. package/dist/server/create-api.js +211 -0
  60. package/dist/server/define-serve.d.ts +21 -2
  61. package/dist/server/define-serve.d.ts.map +1 -1
  62. package/dist/server/define-serve.js +53 -84
  63. package/dist/server/index.d.ts +2 -0
  64. package/dist/server/index.d.ts.map +1 -1
  65. package/dist/server/index.js +2 -0
  66. package/dist/server/init-serve.d.ts +1 -1
  67. package/dist/server/init-serve.d.ts.map +1 -1
  68. package/dist/server/init-serve.js +7 -2
  69. package/dist/type-tests/builder.test-d.d.ts +4 -0
  70. package/dist/type-tests/builder.test-d.d.ts.map +1 -1
  71. package/dist/type-tests/builder.test-d.js +16 -1
  72. package/dist/type-tests/semantic.test-d.d.ts +2 -0
  73. package/dist/type-tests/semantic.test-d.d.ts.map +1 -0
  74. package/dist/type-tests/semantic.test-d.js +59 -0
  75. package/dist/types.d.ts +227 -6
  76. package/dist/types.d.ts.map +1 -1
  77. package/package.json +6 -3
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Converts a MetricRef into a standard ServeEndpoint.
3
+ *
4
+ * The generated endpoint is a POST handler that:
5
+ * - Validates dimensions/filters against the metric's contract
6
+ * - Calls DatasetClient.execute() with the parsed query + tenant context
7
+ * - Returns { data } or { data, meta } based on headers
8
+ */
9
+ import { z } from 'zod';
10
+ import { ServeHttpError } from '../../errors.js';
11
+ import { resolveSemanticExecutionRuntime, resolveSemanticQueryBuilder, } from '../query-builder-context.js';
12
+ import { buildMetricInputSchema } from './utils/semantic-input-schema.js';
13
+ // ---------------------------------------------------------------------------
14
+ // Zod schemas for metric query input / output
15
+ // ---------------------------------------------------------------------------
16
+ const metricResultMetaSchema = z.object({
17
+ timingMs: z.number().optional(),
18
+ sql: z.string().optional(),
19
+ tenant: z.string().optional(),
20
+ rowCount: z.number().optional(),
21
+ pagination: z.object({
22
+ limit: z.number(),
23
+ offset: z.number(),
24
+ hasMore: z.boolean(),
25
+ }).optional(),
26
+ }).optional();
27
+ const metricResultSchema = z.object({
28
+ data: z.array(z.record(z.unknown())),
29
+ meta: metricResultMetaSchema,
30
+ });
31
+ function isMetricHandleEntry(entry) {
32
+ return (!!entry &&
33
+ typeof entry === 'object' &&
34
+ '__type' in entry &&
35
+ (entry.__type === 'metric_ref' || entry.__type === 'grained_metric_ref'));
36
+ }
37
+ function isMetricEntryOptions(entry) {
38
+ return !!entry && typeof entry === 'object' && 'metric' in entry;
39
+ }
40
+ function resolveMetricEntry(entry) {
41
+ if (isMetricHandleEntry(entry)) {
42
+ return { metric: entry };
43
+ }
44
+ if (isMetricEntryOptions(entry)) {
45
+ return entry;
46
+ }
47
+ throw new Error('Invalid metric entry.');
48
+ }
49
+ // ---------------------------------------------------------------------------
50
+ // Factory
51
+ // ---------------------------------------------------------------------------
52
+ export function createMetricEndpoint(name, entry, analytics, defaultBuilderFactory) {
53
+ const resolved = resolveMetricEntry(entry);
54
+ const metricRef = resolved.metric;
55
+ const contract = metricRef.contract();
56
+ // The metric's underlying dataset, used to enumerate valid query fields and
57
+ // page-size defaults.
58
+ const ds = (metricRef.__type === 'metric_ref' ? metricRef.dataset : metricRef.metric.dataset);
59
+ const metricQueryInputSchema = buildMetricInputSchema(ds, contract.name);
60
+ // Page-size cap, mirroring datasets: clamp (don't reject) and apply a default
61
+ // so a metric query is never unbounded.
62
+ const effectiveMaxLimit = resolved.maxLimit ?? ds.limits?.maxResultSize ?? 1000;
63
+ const metadata = {
64
+ path: '', // filled by router.register
65
+ method: 'POST',
66
+ name: contract.label ?? name,
67
+ summary: `Query the "${name}" metric`,
68
+ description: buildDescription(contract, effectiveMaxLimit),
69
+ tags: ['metrics'],
70
+ requiresAuth: resolved.auth !== null ? undefined : false,
71
+ requiredRoles: resolved.requiredRoles,
72
+ requiredScopes: resolved.requiredScopes,
73
+ cacheTtlMs: resolved.cache,
74
+ visibility: 'public',
75
+ custom: {
76
+ usesServeTenantRuntime: true,
77
+ },
78
+ };
79
+ const handler = async (ctx) => {
80
+ const semanticContext = ctx;
81
+ const input = ctx.input ?? {};
82
+ const runtime = resolveSemanticExecutionRuntime(semanticContext);
83
+ const runtimeBuilderFactory = resolveSemanticQueryBuilder(semanticContext, defaultBuilderFactory);
84
+ // Build the metric query
85
+ const query = {
86
+ dimensions: input.dimensions,
87
+ filters: input.filters,
88
+ orderBy: input.orderBy,
89
+ limit: Math.min(input.limit ?? effectiveMaxLimit, effectiveMaxLimit),
90
+ offset: input.offset,
91
+ by: input.by,
92
+ };
93
+ if (ctx.tenantId && !runtime?.tenant) {
94
+ throw new ServeHttpError(500, 'INTERNAL_SERVER_ERROR', `Metric endpoint "${name}" requires serve tenant runtime when tenant isolation is enabled.`);
95
+ }
96
+ const validationContext = ctx.tenantId && runtime?.tenant
97
+ ? {
98
+ runtime: {
99
+ tenant: runtime.tenant,
100
+ },
101
+ }
102
+ : undefined;
103
+ const validation = analytics.validate(metricRef, query, validationContext);
104
+ if (!validation.valid) {
105
+ throw new ServeHttpError(400, 'VALIDATION_ERROR', validation.errors.join('; '));
106
+ }
107
+ // Execute with tenant context
108
+ const result = await analytics.execute(metricRef, query, {
109
+ runtime: {
110
+ ...runtime,
111
+ builderFactory: runtimeBuilderFactory,
112
+ tenant: runtime?.tenant,
113
+ },
114
+ });
115
+ // Decide whether to include meta — `includeMeta` input field or x-include-meta header.
116
+ const includeMeta = input.includeMeta === true
117
+ || ctx.request?.headers?.['x-include-meta'] === 'true';
118
+ return {
119
+ data: result.data,
120
+ meta: includeMeta ? result.meta : undefined,
121
+ };
122
+ };
123
+ return {
124
+ key: name,
125
+ method: 'POST',
126
+ inputSchema: metricQueryInputSchema,
127
+ outputSchema: metricResultSchema,
128
+ handler,
129
+ query: undefined,
130
+ middlewares: (resolved.middlewares ?? []),
131
+ auth: resolved.auth ?? null,
132
+ tenant: resolved.tenant,
133
+ metadata,
134
+ cacheTtlMs: resolved.cache ?? null,
135
+ defaultHeaders: undefined,
136
+ requiredRoles: resolved.requiredRoles,
137
+ requiredScopes: resolved.requiredScopes,
138
+ };
139
+ }
140
+ function buildDescription(contract, maxLimit) {
141
+ const lines = [
142
+ contract.description ?? `${contract.name} metric on the ${contract.dataset} dataset.`,
143
+ '',
144
+ `**Type:** ${contract.kind}`,
145
+ `**Dataset:** ${contract.dataset}`,
146
+ `**Dimensions:** ${contract.dimensions.join(', ') || 'none'}`,
147
+ `**Max limit:** ${maxLimit}`,
148
+ ];
149
+ if (contract.grains.length > 0) {
150
+ lines.push(`**Time grains:** ${contract.grains.join(', ')}`);
151
+ }
152
+ if (contract.requires && contract.requires.length > 0) {
153
+ lines.push(`**Requires:** ${contract.requires.join(', ')}`);
154
+ }
155
+ if (contract.tenantScoped) {
156
+ lines.push('**Tenant scoped:** yes');
157
+ }
158
+ return lines.join('\n');
159
+ }
@@ -0,0 +1,24 @@
1
+ import type { AuthContext, AuthStrategy, ServeMiddleware, TenantConfigOverride } from '../../../types.js';
2
+ import type { AnyDatasetInstance } from '@hypequery/datasets';
3
+ export type DatasetEntry<TAuth extends AuthContext = AuthContext> = AnyDatasetInstance | {
4
+ dataset: AnyDatasetInstance;
5
+ auth?: AuthStrategy<TAuth> | null;
6
+ tenant?: TenantConfigOverride<TAuth>;
7
+ cache?: number | null;
8
+ requiredRoles?: string[];
9
+ requiredScopes?: string[];
10
+ /** Middleware applied to this dataset endpoint. */
11
+ middlewares?: ServeMiddleware<any, any, any, TAuth>[];
12
+ maxLimit?: number;
13
+ };
14
+ export declare function resolveDatasetEntry<TAuth extends AuthContext>(entry: DatasetEntry<TAuth>): {
15
+ dataset: AnyDatasetInstance;
16
+ auth?: AuthStrategy<TAuth> | null;
17
+ tenant?: TenantConfigOverride<TAuth>;
18
+ cache?: number | null;
19
+ requiredRoles?: string[];
20
+ requiredScopes?: string[];
21
+ middlewares?: ServeMiddleware<any, any, any, TAuth>[];
22
+ maxLimit?: number;
23
+ };
24
+ //# sourceMappingURL=dataset-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset-entry.d.ts","sourceRoot":"","sources":["../../../../src/semantic/datasets/utils/dataset-entry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,eAAe,EACf,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,MAAM,MAAM,YAAY,CAAC,KAAK,SAAS,WAAW,GAAG,WAAW,IAC5D,kBAAkB,GAClB;IACE,OAAO,EAAE,kBAAkB,CAAC;IAC5B,IAAI,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IAClC,MAAM,CAAC,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,mDAAmD;IACnD,WAAW,CAAC,EAAE,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAgBN,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,WAAW,EAC3D,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,GACzB;IACD,OAAO,EAAE,kBAAkB,CAAC;IAC5B,IAAI,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IAClC,MAAM,CAAC,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAUA"}
@@ -0,0 +1,15 @@
1
+ function isDatasetInstance(entry) {
2
+ return !!entry && typeof entry === 'object' && '__type' in entry && entry.__type === 'dataset';
3
+ }
4
+ function isDatasetEntryOptions(entry) {
5
+ return !!entry && typeof entry === 'object' && 'dataset' in entry;
6
+ }
7
+ export function resolveDatasetEntry(entry) {
8
+ if (isDatasetInstance(entry)) {
9
+ return { dataset: entry };
10
+ }
11
+ if (isDatasetEntryOptions(entry)) {
12
+ return entry;
13
+ }
14
+ throw new Error('Invalid dataset entry.');
15
+ }
@@ -0,0 +1,3 @@
1
+ import type { AnyDatasetInstance } from '@hypequery/datasets';
2
+ export declare function buildDatasetQueryDescription(ds: AnyDatasetInstance, maxLimit: number): string;
3
+ //# sourceMappingURL=dataset-query-metadata.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,12 @@
1
+ export function buildDatasetQueryDescription(ds, maxLimit) {
2
+ const dimensionNames = Object.keys(ds.dimensions);
3
+ const measureNames = Object.keys(ds.measures);
4
+ const lines = [
5
+ `Query the ${ds.name} semantic dataset (source: ${ds.source}).`,
6
+ '',
7
+ `**Dimensions:** ${dimensionNames.join(', ') || 'none'}`,
8
+ `**Measures:** ${measureNames.join(', ') || 'none'}`,
9
+ `**Max limit:** ${maxLimit}`,
10
+ ];
11
+ return lines.join('\n');
12
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Builds per-dataset / per-metric Zod input schemas whose dimension, measure,
3
+ * filter, and orderBy fields are constrained to the names the semantic
4
+ * validators accept. This upgrades the generated OpenAPI/docs from "array of
5
+ * arbitrary strings" to enumerated fields and enables typed client codegen.
6
+ *
7
+ * The enums are deliberately a *superset-safe* mirror of the runtime validators
8
+ * (`validateDatasetQueryInput` / the metric `validateQuery`): they never reject
9
+ * a field the validator would accept. Where a list would be empty (e.g. a
10
+ * dataset with no declared filters) we fall back to `z.string()` and let the
11
+ * validator produce the precise error, rather than emitting an empty enum.
12
+ */
13
+ import { z } from 'zod';
14
+ import type { AnyDatasetInstance } from '@hypequery/datasets';
15
+ /**
16
+ * Input schema for a dataset query endpoint, mirroring
17
+ * `validateDatasetQueryInput`.
18
+ */
19
+ export declare function buildDatasetInputSchema(ds: AnyDatasetInstance): z.ZodObject<{
20
+ dimensions: z.ZodOptional<z.ZodArray<z.ZodTypeAny, "many">>;
21
+ measures: z.ZodOptional<z.ZodArray<z.ZodTypeAny, "many">>;
22
+ filters: z.ZodOptional<z.ZodArray<z.ZodTypeAny, "many">>;
23
+ orderBy: z.ZodOptional<z.ZodArray<z.ZodObject<{
24
+ field: z.ZodTypeAny;
25
+ direction: z.ZodEnum<["asc", "desc"]>;
26
+ }, "strip", z.ZodTypeAny, {
27
+ direction: "asc" | "desc";
28
+ field?: any;
29
+ }, {
30
+ direction: "asc" | "desc";
31
+ field?: any;
32
+ }>, "many">>;
33
+ limit: z.ZodOptional<z.ZodNumber>;
34
+ offset: z.ZodOptional<z.ZodNumber>;
35
+ by: z.ZodOptional<z.ZodEnum<["day", "week", "month", "quarter", "year"]>>;
36
+ includeMeta: z.ZodOptional<z.ZodBoolean>;
37
+ }, "strict", z.ZodTypeAny, {
38
+ dimensions?: any[] | undefined;
39
+ measures?: any[] | undefined;
40
+ filters?: any[] | undefined;
41
+ orderBy?: {
42
+ direction: "asc" | "desc";
43
+ field?: any;
44
+ }[] | undefined;
45
+ limit?: number | undefined;
46
+ offset?: number | undefined;
47
+ by?: "day" | "week" | "month" | "quarter" | "year" | undefined;
48
+ includeMeta?: boolean | undefined;
49
+ }, {
50
+ dimensions?: any[] | undefined;
51
+ measures?: any[] | undefined;
52
+ filters?: any[] | undefined;
53
+ orderBy?: {
54
+ direction: "asc" | "desc";
55
+ field?: any;
56
+ }[] | undefined;
57
+ limit?: number | undefined;
58
+ offset?: number | undefined;
59
+ by?: "day" | "week" | "month" | "quarter" | "year" | undefined;
60
+ includeMeta?: boolean | undefined;
61
+ }>;
62
+ /**
63
+ * Input schema for a metric query endpoint, mirroring the metric `validateQuery`.
64
+ * Metrics select a single value, so there is no `measures` field; `orderBy` may
65
+ * reference the metric's own output column (`metricName`).
66
+ */
67
+ export declare function buildMetricInputSchema(ds: AnyDatasetInstance, metricName: string): z.ZodObject<{
68
+ dimensions: z.ZodOptional<z.ZodArray<z.ZodTypeAny, "many">>;
69
+ filters: z.ZodOptional<z.ZodArray<z.ZodTypeAny, "many">>;
70
+ orderBy: z.ZodOptional<z.ZodArray<z.ZodObject<{
71
+ field: z.ZodTypeAny;
72
+ direction: z.ZodEnum<["asc", "desc"]>;
73
+ }, "strip", z.ZodTypeAny, {
74
+ direction: "asc" | "desc";
75
+ field?: any;
76
+ }, {
77
+ direction: "asc" | "desc";
78
+ field?: any;
79
+ }>, "many">>;
80
+ limit: z.ZodOptional<z.ZodNumber>;
81
+ offset: z.ZodOptional<z.ZodNumber>;
82
+ by: z.ZodOptional<z.ZodEnum<["day", "week", "month", "quarter", "year"]>>;
83
+ includeMeta: z.ZodOptional<z.ZodBoolean>;
84
+ }, "strip", z.ZodTypeAny, {
85
+ dimensions?: any[] | undefined;
86
+ filters?: any[] | undefined;
87
+ orderBy?: {
88
+ direction: "asc" | "desc";
89
+ field?: any;
90
+ }[] | undefined;
91
+ limit?: number | undefined;
92
+ offset?: number | undefined;
93
+ by?: "day" | "week" | "month" | "quarter" | "year" | undefined;
94
+ includeMeta?: boolean | undefined;
95
+ }, {
96
+ dimensions?: any[] | undefined;
97
+ filters?: any[] | undefined;
98
+ orderBy?: {
99
+ direction: "asc" | "desc";
100
+ field?: any;
101
+ }[] | undefined;
102
+ limit?: number | undefined;
103
+ offset?: number | undefined;
104
+ by?: "day" | "week" | "month" | "quarter" | "year" | undefined;
105
+ includeMeta?: boolean | undefined;
106
+ }>;
107
+ //# sourceMappingURL=semantic-input-schema.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Builds per-dataset / per-metric Zod input schemas whose dimension, measure,
3
+ * filter, and orderBy fields are constrained to the names the semantic
4
+ * validators accept. This upgrades the generated OpenAPI/docs from "array of
5
+ * arbitrary strings" to enumerated fields and enables typed client codegen.
6
+ *
7
+ * The enums are deliberately a *superset-safe* mirror of the runtime validators
8
+ * (`validateDatasetQueryInput` / the metric `validateQuery`): they never reject
9
+ * a field the validator would accept. Where a list would be empty (e.g. a
10
+ * dataset with no declared filters) we fall back to `z.string()` and let the
11
+ * validator produce the precise error, rather than emitting an empty enum.
12
+ */
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'];
18
+ /** An enum over the given field names, or a plain string when none are known. */
19
+ function fieldEnum(values) {
20
+ const unique = Array.from(new Set(values));
21
+ return unique.length > 0
22
+ ? z.enum(unique)
23
+ : z.string();
24
+ }
25
+ function filterSchema(fieldNames) {
26
+ return z.object({
27
+ field: fieldEnum(fieldNames),
28
+ operator: z.enum(OPERATORS),
29
+ value: z.unknown(),
30
+ });
31
+ }
32
+ function orderBySchema(fieldNames) {
33
+ return z.object({
34
+ field: fieldEnum(fieldNames),
35
+ direction: z.enum(['asc', 'desc']),
36
+ });
37
+ }
38
+ /** Apply a `.max()` bound only when the dataset declares one. */
39
+ function boundedArray(item, max) {
40
+ const arr = z.array(item);
41
+ return (max != null ? arr.max(max) : arr).optional();
42
+ }
43
+ /**
44
+ * Input schema for a dataset query endpoint, mirroring
45
+ * `validateDatasetQueryInput`.
46
+ */
47
+ 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'];
55
+ return z.object({
56
+ dimensions: boundedArray(fieldEnum(dimensionNames), ds.limits?.maxDimensions),
57
+ measures: boundedArray(fieldEnum(measureNames), ds.limits?.maxMeasures),
58
+ filters: boundedArray(filterSchema(filterNames), ds.limits?.maxFilters),
59
+ orderBy: z.array(orderBySchema(orderableNames)).optional(),
60
+ limit: z.number().int().positive().optional(),
61
+ offset: z.number().int().nonnegative().optional(),
62
+ by: z.enum(GRAINS).optional(),
63
+ includeMeta: z.boolean().optional(),
64
+ }).strict();
65
+ }
66
+ /**
67
+ * Input schema for a metric query endpoint, mirroring the metric `validateQuery`.
68
+ * Metrics select a single value, so there is no `measures` field; `orderBy` may
69
+ * reference the metric's own output column (`metricName`).
70
+ */
71
+ 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'];
78
+ return z.object({
79
+ dimensions: boundedArray(fieldEnum(dimensionNames), ds.limits?.maxDimensions),
80
+ filters: boundedArray(filterSchema(filterNames), ds.limits?.maxFilters),
81
+ orderBy: z.array(orderBySchema(orderableNames)).optional(),
82
+ limit: z.number().int().positive().optional(),
83
+ offset: z.number().int().nonnegative().optional(),
84
+ by: z.enum(GRAINS).optional(),
85
+ includeMeta: z.boolean().optional(),
86
+ });
87
+ }
@@ -0,0 +1,2 @@
1
+ export * from './datasets/index.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/semantic/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './datasets/index.js';
@@ -0,0 +1,20 @@
1
+ import type { QueryBuilderFactoryLike, SemanticExecutionRuntime } from "@hypequery/datasets";
2
+ export declare const INTERNAL_SEMANTIC_RUNTIME_KEY = "__hypequerySemanticRuntime";
3
+ /**
4
+ * Type guard to check if a value is a QueryBuilderFactoryLike.
5
+ * Uses duck-typing to detect the required methods.
6
+ */
7
+ export declare function isQueryBuilderFactoryLike(value: unknown): value is QueryBuilderFactoryLike;
8
+ /**
9
+ * Extract queryBuilder from context.db if available.
10
+ * This allows users to pass queryBuilder via context instead of top-level config.
11
+ */
12
+ export declare function extractQueryBuilderFromContext(context: Record<string, unknown>): QueryBuilderFactoryLike | undefined;
13
+ export declare function attachSemanticQueryBuilder<TContext extends Record<string, unknown>>(context: TContext, builderFactory: QueryBuilderFactoryLike | undefined): TContext;
14
+ export declare function attachSemanticRuntime<TContext extends Record<string, unknown>>(context: TContext, runtime: SemanticExecutionRuntime): TContext;
15
+ export declare function resolveSemanticExecutionRuntime(context: Record<string, unknown>): SemanticExecutionRuntime | undefined;
16
+ export declare function resolveSemanticQueryBuilder(context: Record<string, unknown>, fallback: QueryBuilderFactoryLike): QueryBuilderFactoryLike;
17
+ export declare function attachSemanticTenantRuntime<TContext extends Record<string, unknown>>(context: TContext, options: {
18
+ tenantId: string;
19
+ }): TContext;
20
+ //# sourceMappingURL=query-builder-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-builder-context.d.ts","sourceRoot":"","sources":["../../src/semantic/query-builder-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE7F,eAAO,MAAM,6BAA6B,+BAA+B,CAAC;AAM1E;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,uBAAuB,CAS1F;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,uBAAuB,GAAG,SAAS,CAarC;AAED,wBAAgB,0BAA0B,CACxC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAExC,OAAO,EAAE,QAAQ,EACjB,cAAc,EAAE,uBAAuB,GAAG,SAAS,GAClD,QAAQ,CAMV;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5E,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,wBAAwB,GAChC,QAAQ,CAUV;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,wBAAwB,GAAG,SAAS,CAMtC;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,uBAAuB,GAChC,uBAAuB,CAEzB;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClF,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE;IACP,QAAQ,EAAE,MAAM,CAAC;CAClB,GACA,QAAQ,CAMV"}
@@ -0,0 +1,66 @@
1
+ export const INTERNAL_SEMANTIC_RUNTIME_KEY = "__hypequerySemanticRuntime";
2
+ function isSemanticExecutionRuntime(value) {
3
+ return typeof value === 'object' && value !== null;
4
+ }
5
+ /**
6
+ * Type guard to check if a value is a QueryBuilderFactoryLike.
7
+ * Uses duck-typing to detect the required methods.
8
+ */
9
+ export function isQueryBuilderFactoryLike(value) {
10
+ return (typeof value === 'object' &&
11
+ value !== null &&
12
+ 'table' in value &&
13
+ typeof value.table === 'function' &&
14
+ 'rawQuery' in value &&
15
+ typeof value.rawQuery === 'function');
16
+ }
17
+ /**
18
+ * Extract queryBuilder from context.db if available.
19
+ * This allows users to pass queryBuilder via context instead of top-level config.
20
+ */
21
+ export function extractQueryBuilderFromContext(context) {
22
+ // Check if context.db is a queryBuilder
23
+ if ('db' in context && isQueryBuilderFactoryLike(context.db)) {
24
+ return context.db;
25
+ }
26
+ // Check if it's already in the semantic runtime
27
+ const runtime = resolveSemanticExecutionRuntime(context);
28
+ if (runtime?.builderFactory) {
29
+ return runtime.builderFactory;
30
+ }
31
+ return undefined;
32
+ }
33
+ export function attachSemanticQueryBuilder(context, builderFactory) {
34
+ if (!builderFactory) {
35
+ return context;
36
+ }
37
+ return attachSemanticRuntime(context, { builderFactory });
38
+ }
39
+ export function attachSemanticRuntime(context, runtime) {
40
+ const current = resolveSemanticExecutionRuntime(context);
41
+ return {
42
+ ...context,
43
+ [INTERNAL_SEMANTIC_RUNTIME_KEY]: {
44
+ ...(current ?? {}),
45
+ ...runtime,
46
+ tenant: runtime.tenant ?? current?.tenant,
47
+ },
48
+ };
49
+ }
50
+ export function resolveSemanticExecutionRuntime(context) {
51
+ const candidate = context[INTERNAL_SEMANTIC_RUNTIME_KEY];
52
+ if (!isSemanticExecutionRuntime(candidate)) {
53
+ return undefined;
54
+ }
55
+ return candidate;
56
+ }
57
+ export function resolveSemanticQueryBuilder(context, fallback) {
58
+ return resolveSemanticExecutionRuntime(context)?.builderFactory ?? fallback;
59
+ }
60
+ export function attachSemanticTenantRuntime(context, options) {
61
+ return attachSemanticRuntime(context, {
62
+ tenant: {
63
+ id: options.tenantId,
64
+ },
65
+ });
66
+ }
@@ -0,0 +1,11 @@
1
+ import type { EndpointMetadata } from '../../types.js';
2
+ export declare function applySemanticTenantRuntime<TContext extends Record<string, unknown>>(context: TContext & {
3
+ tenantId?: string;
4
+ }, options: {
5
+ queryKey: string;
6
+ metadata: EndpointMetadata;
7
+ tenantId: string;
8
+ mode: 'manual' | 'auto-inject';
9
+ column?: string;
10
+ }): void;
11
+ //# sourceMappingURL=tenant-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-runtime.d.ts","sourceRoot":"","sources":["../../../src/semantic/utils/tenant-runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAyBvD,wBAAgB,0BAA0B,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjF,OAAO,EAAE,QAAQ,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EACzC,OAAO,EAAE;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,QAAQ,GAAG,aAAa,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,IAAI,CAyCN"}
@@ -0,0 +1,48 @@
1
+ import { createTenantScope, warnTenantMisconfiguration } from '../../tenant.js';
2
+ import { attachSemanticRuntime, attachSemanticTenantRuntime, resolveSemanticExecutionRuntime, } from '../query-builder-context.js';
3
+ function usesServeTenantRuntimeMetadata(metadata) {
4
+ return Boolean(metadata.custom
5
+ && typeof metadata.custom === 'object'
6
+ && metadata.custom !== null
7
+ && 'usesServeTenantRuntime' in metadata.custom
8
+ && metadata.custom.usesServeTenantRuntime === true);
9
+ }
10
+ function hasTableFactory(value) {
11
+ return !!value && typeof value === 'object' && 'table' in value && typeof value.table === 'function';
12
+ }
13
+ export function applySemanticTenantRuntime(context, options) {
14
+ const mutableContext = context;
15
+ const usesServeTenantRuntime = usesServeTenantRuntimeMetadata(options.metadata);
16
+ const semanticRuntime = resolveSemanticExecutionRuntime(context);
17
+ if (options.mode === 'auto-inject' && options.column && semanticRuntime?.builderFactory) {
18
+ Object.assign(context, attachSemanticRuntime(context, {
19
+ tenant: {
20
+ id: options.tenantId,
21
+ },
22
+ }));
23
+ }
24
+ else {
25
+ Object.assign(context, attachSemanticTenantRuntime(context, {
26
+ tenantId: options.tenantId,
27
+ }));
28
+ }
29
+ if (options.mode === 'auto-inject' && options.column) {
30
+ for (const key of Object.keys(mutableContext)) {
31
+ const value = mutableContext[key];
32
+ if (hasTableFactory(value)) {
33
+ mutableContext[key] = createTenantScope(value, {
34
+ tenantId: options.tenantId,
35
+ column: options.column,
36
+ });
37
+ }
38
+ }
39
+ }
40
+ else if (options.mode === 'manual' && !usesServeTenantRuntime) {
41
+ warnTenantMisconfiguration({
42
+ queryKey: options.queryKey,
43
+ hasTenantConfig: true,
44
+ hasTenantId: true,
45
+ mode: 'manual',
46
+ });
47
+ }
48
+ }
package/dist/serve.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AuthContext, QueryObjectConfig, SchemaOutput, ServeBuilder, ServeConfig, ServeContextFactory, ServeEndpointMap, ServeQueriesMap, StandaloneQueryDefinition } from "./types.js";
1
+ import type { AuthContext, QueryObjectConfig, SchemaOutput, ServeBuilder, ServeConfig, ServeContextFactory, ServeEndpointMap, ServeSemanticEndpointMap, ServeQueriesMap, StandaloneQueryDefinition, MetricsConfig, DatasetsConfig } from "./types.js";
2
2
  import type { ZodTypeAny } from "zod";
3
3
  export declare const createQueryFactory: <TContext extends Record<string, unknown> = Record<string, unknown>, TAuth extends AuthContext = AuthContext>(contextFactory?: ServeContextFactory<TContext, TAuth>) => <TInputSchema extends ZodTypeAny | undefined = undefined, TOutputSchema extends ZodTypeAny | undefined = undefined, TResult = TOutputSchema extends ZodTypeAny ? SchemaOutput<TOutputSchema> : unknown>(config: QueryObjectConfig<TInputSchema, TOutputSchema, TContext, TAuth, TResult>) => StandaloneQueryDefinition<TInputSchema, TOutputSchema extends ZodTypeAny ? TOutputSchema : ZodTypeAny, TContext, TAuth, TResult>;
4
4
  /**
@@ -12,5 +12,5 @@ export declare const query: <TInputSchema extends ZodTypeAny | undefined = undef
12
12
  *
13
13
  * This is the unbound version. Use `initServe().serve(...)` when you want shared context and config.
14
14
  */
15
- export declare function serve<TContext extends Record<string, unknown> = Record<string, unknown>, TAuth extends AuthContext = AuthContext, TQueries extends ServeQueriesMap<TContext, TAuth> = ServeQueriesMap<TContext, TAuth>>(config: ServeConfig<TContext, TAuth, TQueries>): ServeBuilder<ServeEndpointMap<TQueries, TContext, TAuth>, TContext, TAuth>;
15
+ export declare function serve<TContext extends Record<string, unknown> = Record<string, unknown>, TAuth extends AuthContext = AuthContext, TQueries extends ServeQueriesMap<TContext, TAuth> = Record<never, never>, TMetrics extends MetricsConfig<TAuth> = Record<never, never>, TDatasets extends DatasetsConfig<TAuth> = Record<never, never>>(config: ServeConfig<TContext, TAuth, TQueries, TMetrics, TDatasets>): ServeBuilder<ServeEndpointMap<TQueries, TContext, TAuth> & ServeSemanticEndpointMap<TMetrics, TDatasets, TContext, TAuth>, TContext, TAuth>;
16
16
  //# sourceMappingURL=serve.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAEX,iBAAiB,EAGjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EAEf,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAgGtC,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,KAAK,SAAS,WAAW,GAAG,WAAW,EAEvC,iBAAiB,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,MAGnD,YAAY,SAAS,UAAU,GAAG,SAAS,GAAG,SAAS,EACvD,aAAa,SAAS,UAAU,GAAG,SAAS,GAAG,SAAS,EACxD,OAAO,GAAG,aAAa,SAAS,UAAU,GAAG,YAAY,CAAC,aAAa,CAAC,GAAG,OAAO,EAElF,QAAQ,iBAAiB,CAAC,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAC/E,yBAAyB,CAC1B,YAAY,EACZ,aAAa,SAAS,UAAU,GAAG,aAAa,GAAG,UAAU,EAC7D,QAAQ,EACR,KAAK,EACL,OAAO,CAIV,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,KAAK,GArBd,YAAY,SAAS,UAAU,GAAG,SAAS,cAC3C,aAAa,SAAS,UAAU,GAAG,SAAS,cAC5C,OAAO,4UAmB8B,CAAC;AAE1C;;;;GAIG;AACH,wBAAgB,KAAK,CACnB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,KAAK,SAAS,WAAW,GAAG,WAAW,EACvC,QAAQ,SAAS,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,EACpF,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAE5H"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAEX,iBAAiB,EAGjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,EAEf,yBAAyB,EACzB,aAAa,EACb,cAAc,EACf,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAgGtC,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,KAAK,SAAS,WAAW,GAAG,WAAW,EAEvC,iBAAiB,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,MAGnD,YAAY,SAAS,UAAU,GAAG,SAAS,GAAG,SAAS,EACvD,aAAa,SAAS,UAAU,GAAG,SAAS,GAAG,SAAS,EACxD,OAAO,GAAG,aAAa,SAAS,UAAU,GAAG,YAAY,CAAC,aAAa,CAAC,GAAG,OAAO,EAElF,QAAQ,iBAAiB,CAAC,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAC/E,yBAAyB,CAC1B,YAAY,EACZ,aAAa,SAAS,UAAU,GAAG,aAAa,GAAG,UAAU,EAC7D,QAAQ,EACR,KAAK,EACL,OAAO,CAIV,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,KAAK,GArBd,YAAY,SAAS,UAAU,GAAG,SAAS,cAC3C,aAAa,SAAS,UAAU,GAAG,SAAS,cAC5C,OAAO,4UAmB8B,CAAC;AAE1C;;;;GAIG;AACH,wBAAgB,KAAK,CACnB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,KAAK,SAAS,WAAW,GAAG,WAAW,EACvC,QAAQ,SAAS,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EACxE,QAAQ,SAAS,aAAa,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAC5D,SAAS,SAAS,cAAc,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAE9D,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,GAClE,YAAY,CACb,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,GACvC,wBAAwB,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,EAClE,QAAQ,EACR,KAAK,CACN,CAEA"}
@@ -0,0 +1,5 @@
1
+ import type { AuthContext, AuthStrategy, HypeQueryAPI, ServeEndpointMap, ServeMiddleware, ServeQueriesMap, ServeHandler, ExecuteQueryFunction } from "../types.js";
2
+ import type { ServeRouter } from "../router.js";
3
+ import { ServeQueryLogger } from "../query-logger.js";
4
+ export declare const createAPImethods: <TQueries extends ServeQueriesMap<TContext, TAuth>, TContext extends Record<string, unknown>, TAuth extends AuthContext>(queryEntries: ServeEndpointMap<TQueries, TContext, TAuth>, queryLogger: ServeQueryLogger, router: ServeRouter, authStrategies: AuthStrategy<TAuth>[], globalMiddlewares: ServeMiddleware<any, any, TContext, TAuth>[], executeQuery: ExecuteQueryFunction<ServeEndpointMap<TQueries, TContext, TAuth>, TContext>, handler: ServeHandler, basePath: string) => HypeQueryAPI<ServeEndpointMap<TQueries, TContext, TAuth>, TContext, TAuth>;
5
+ //# sourceMappingURL=api-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-builder.d.ts","sourceRoot":"","sources":["../../src/server/api-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,YAAY,EAIZ,gBAAgB,EAChB,eAAe,EAEf,eAAe,EACf,YAAY,EACZ,oBAAoB,EAErB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKtD,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,SAAS,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,EACjD,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACxC,KAAK,SAAS,WAAW,EAEzB,cAAc,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EACzD,aAAa,gBAAgB,EAC7B,QAAQ,WAAW,EACnB,gBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,EACrC,mBAAmB,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAC/D,cAAc,oBAAoB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,QAAQ,CAAC,EACzF,SAAS,YAAY,EACrB,UAAU,MAAM,KACf,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,CA0F3E,CAAC"}