@hypequery/serve 0.2.1 → 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 -1
  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 +5 -2
@@ -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"}
@@ -0,0 +1,76 @@
1
+ import { mergeTags } from "../utils.js";
2
+ import { applyBasePath, normalizeRoutePath } from "../router.js";
3
+ import { mapEndpointToToolkit } from "./mapper.js";
4
+ export const createAPImethods = (queryEntries, queryLogger, router, authStrategies, globalMiddlewares, executeQuery, handler, basePath) => {
5
+ const api = {
6
+ queries: queryEntries,
7
+ queryLogger,
8
+ manifest: () => {
9
+ const manifest = {};
10
+ for (const [key, endpoint] of Object.entries(queryEntries)) {
11
+ manifest[key] = {
12
+ method: endpoint.method,
13
+ // queryEntries store the pre-basePath route; re-apply so the manifest
14
+ // carries the full request path clients should call.
15
+ path: applyBasePath(basePath, endpoint.metadata.path),
16
+ };
17
+ }
18
+ return manifest;
19
+ },
20
+ route: (path, endpoint, options = {}) => {
21
+ if (!endpoint) {
22
+ throw new Error("Endpoint definition is required when registering a route");
23
+ }
24
+ const method = options?.method ?? endpoint.method;
25
+ const normalizedPath = normalizeRoutePath(path);
26
+ const fallbackRequiresAuth = endpoint.auth
27
+ ? true
28
+ : authStrategies.length > 0
29
+ ? true
30
+ : undefined;
31
+ const requiresAuth = options?.requiresAuth ?? endpoint.metadata.requiresAuth ?? fallbackRequiresAuth;
32
+ const visibility = options?.visibility ?? endpoint.metadata.visibility ?? "public";
33
+ const metadata = {
34
+ ...endpoint.metadata,
35
+ path: normalizedPath,
36
+ method,
37
+ name: options?.name ?? endpoint.metadata.name ?? endpoint.key,
38
+ summary: options?.summary ?? endpoint.metadata.summary,
39
+ description: options?.description ?? endpoint.metadata.description,
40
+ tags: mergeTags(endpoint.metadata.tags, options?.tags),
41
+ requiresAuth,
42
+ visibility,
43
+ };
44
+ const middlewares = [...endpoint.middlewares, ...(options?.middlewares ?? [])];
45
+ const registeredEndpoint = {
46
+ ...endpoint,
47
+ method,
48
+ metadata,
49
+ middlewares,
50
+ };
51
+ router.register(registeredEndpoint);
52
+ return api;
53
+ },
54
+ use: (middleware) => {
55
+ globalMiddlewares.push(middleware);
56
+ return api;
57
+ },
58
+ useAuth: (strategy) => {
59
+ authStrategies.push(strategy);
60
+ router.markRoutesRequireAuth();
61
+ return api;
62
+ },
63
+ execute: executeQuery,
64
+ client: executeQuery,
65
+ run: executeQuery,
66
+ describe: () => {
67
+ const description = {
68
+ basePath: basePath || undefined,
69
+ queries: router.list().map(mapEndpointToToolkit),
70
+ };
71
+ return description;
72
+ },
73
+ handler,
74
+ };
75
+ return api;
76
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/server/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,UAAU,EACV,YAAY,EAEZ,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,oBAAoB,EAGrB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAYtD,eAAO,MAAM,oBAAoB,GAC/B,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,aAAa,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,EACnD,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,CAsF3E,CAAC"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/server/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,UAAU,EAEV,YAAY,EAEZ,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,oBAAoB,EAGrB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAYtD,eAAO,MAAM,oBAAoB,GAC/B,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,aAAa,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,EACnD,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,CAoG3E,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { mergeTags } from "../utils.js";
2
- import { normalizeRoutePath } from "../router.js";
2
+ import { applyBasePath, normalizeRoutePath } from "../router.js";
3
3
  import { mapEndpointToToolkit } from "./mapper.js";
4
4
  const loadNodeAdapter = async () => {
5
5
  if (typeof require !== "undefined") {
@@ -13,6 +13,16 @@ export const createBuilderMethods = (queryEntries, queryLogger, routeConfig, rou
13
13
  basePath: basePath || undefined,
14
14
  queryLogger,
15
15
  _routeConfig: routeConfig,
16
+ manifest: () => {
17
+ const manifest = {};
18
+ for (const [key, endpoint] of Object.entries(queryEntries)) {
19
+ manifest[key] = {
20
+ method: routeConfig[key]?.method ?? endpoint.method,
21
+ path: applyBasePath(basePath, endpoint.metadata.path),
22
+ };
23
+ }
24
+ return manifest;
25
+ },
16
26
  route: (path, endpoint, options = {}) => {
17
27
  if (!endpoint) {
18
28
  throw new Error("Endpoint definition is required when registering a route");
@@ -0,0 +1,32 @@
1
+ import type { AuthContext, HypeQueryAPI, ServeEndpointMap, ServeQueriesMap, ServeConfig, MetricsConfig, DatasetsConfig, ServeSemanticEndpointMap } from "../types.js";
2
+ /**
3
+ * Create a transport-agnostic API definition.
4
+ *
5
+ * `createAPI` sets up queries, auth, tenancy, caching, and middleware —
6
+ * without binding to any HTTP server or runtime. Use standalone transport
7
+ * functions to serve the API:
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { createAPI } from '@hypequery/serve';
12
+ * import { startServer, toFetchHandler, toNodeHandler } from '@hypequery/serve';
13
+ *
14
+ * const api = createAPI({
15
+ * auth: jwtStrategy,
16
+ * queries: {
17
+ * revenue: { query: async () => db.table('orders').sum('amount').execute() },
18
+ * },
19
+ * });
20
+ *
21
+ * // Standalone server
22
+ * startServer(api, { port: 3000 });
23
+ *
24
+ * // Express / Node.js middleware
25
+ * app.use('/analytics', toNodeHandler(api));
26
+ *
27
+ * // Serverless (Vercel, Cloudflare, etc.)
28
+ * export default toFetchHandler(api);
29
+ * ```
30
+ */
31
+ export declare const createAPI: <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>) => HypeQueryAPI<ServeEndpointMap<TQueries, TContext, TAuth> & ServeSemanticEndpointMap<TMetrics, TDatasets, TContext, TAuth>, TContext, TAuth>;
32
+ //# sourceMappingURL=create-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-api.d.ts","sourceRoot":"","sources":["../../src/server/create-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAEX,YAAY,EAGZ,gBAAgB,EAIhB,eAAe,EACf,WAAW,EACX,aAAa,EACb,cAAc,EACd,wBAAwB,EACzB,MAAM,aAAa,CAAC;AA2BrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,SAAS,GACpB,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,QAAQ,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,KAClE,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,CA8ON,CAAC"}
@@ -0,0 +1,211 @@
1
+ import { createEndpoint } from "../endpoint.js";
2
+ import { ServeRouter, applyBasePath, normalizeRoutePath } from "../router.js";
3
+ import { ensureArray } from "../utils.js";
4
+ import { ServeQueryLogger, formatQueryEvent, formatQueryEventJSON } from "../query-logger.js";
5
+ import { createServeHandler } from "../pipeline.js";
6
+ import { createDocsEndpoint, createOpenApiEndpoint } from "../pipeline.js";
7
+ import { resolveCorsConfig } from "../cors.js";
8
+ import { createExecuteQuery } from "./execute-query.js";
9
+ import { createAPImethods } from "./api-builder.js";
10
+ import { createDatasetClient } from "@hypequery/datasets";
11
+ import { createMetricEndpoint, createDatasetEndpoint } from "../semantic/datasets/index.js";
12
+ import { attachSemanticQueryBuilder, extractQueryBuilderFromContext } from "../semantic/query-builder-context.js";
13
+ const assertSemanticKeyAvailable = (queryEntries, key, kind) => {
14
+ if (key in queryEntries) {
15
+ throw new Error(`createAPI: ${kind} "${key}" collides with an existing query key. ` +
16
+ `Rename the ${kind} or the query to keep api.queries and api.execute() unambiguous.`);
17
+ }
18
+ };
19
+ /**
20
+ * Create a transport-agnostic API definition.
21
+ *
22
+ * `createAPI` sets up queries, auth, tenancy, caching, and middleware —
23
+ * without binding to any HTTP server or runtime. Use standalone transport
24
+ * functions to serve the API:
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * import { createAPI } from '@hypequery/serve';
29
+ * import { startServer, toFetchHandler, toNodeHandler } from '@hypequery/serve';
30
+ *
31
+ * const api = createAPI({
32
+ * auth: jwtStrategy,
33
+ * queries: {
34
+ * revenue: { query: async () => db.table('orders').sum('amount').execute() },
35
+ * },
36
+ * });
37
+ *
38
+ * // Standalone server
39
+ * startServer(api, { port: 3000 });
40
+ *
41
+ * // Express / Node.js middleware
42
+ * app.use('/analytics', toNodeHandler(api));
43
+ *
44
+ * // Serverless (Vercel, Cloudflare, etc.)
45
+ * export default toFetchHandler(api);
46
+ * ```
47
+ */
48
+ export const createAPI = (config) => {
49
+ const basePath = config.basePath ?? "/api/analytics";
50
+ const router = new ServeRouter(basePath);
51
+ const globalMiddlewares = [
52
+ ...(config.middlewares ?? []),
53
+ ];
54
+ const authStrategies = ensureArray(config.auth);
55
+ const globalTenantConfig = config.tenant;
56
+ const baseContextFactory = config.context;
57
+ // Extract queryBuilder from context.db if not provided in config
58
+ let resolvedQueryBuilder = config.queryBuilder;
59
+ let extractedFromContext = false;
60
+ if (!resolvedQueryBuilder && baseContextFactory && (config.metrics || config.datasets)) {
61
+ // If context is a static object (not a function), we can extract queryBuilder synchronously
62
+ if (typeof baseContextFactory !== "function") {
63
+ resolvedQueryBuilder = extractQueryBuilderFromContext(baseContextFactory);
64
+ if (resolvedQueryBuilder) {
65
+ extractedFromContext = true;
66
+ }
67
+ }
68
+ }
69
+ const contextFactory = baseContextFactory || resolvedQueryBuilder
70
+ ? async ({ request, auth }) => {
71
+ const baseContext = baseContextFactory
72
+ ? typeof baseContextFactory === "function"
73
+ ? await baseContextFactory({ request, auth })
74
+ : baseContextFactory
75
+ : {};
76
+ // If queryBuilder was explicitly passed in config (not extracted from context),
77
+ // attach it to context for backward compatibility
78
+ if (config.queryBuilder) {
79
+ return attachSemanticQueryBuilder({ ...baseContext }, config.queryBuilder);
80
+ }
81
+ // If context.db is a queryBuilder but we haven't extracted it yet,
82
+ // also check and attach it to the semantic runtime for consistency
83
+ if (!extractedFromContext && typeof baseContextFactory === "function") {
84
+ const maybeQueryBuilder = extractQueryBuilderFromContext(baseContext);
85
+ if (maybeQueryBuilder) {
86
+ return attachSemanticQueryBuilder({ ...baseContext }, maybeQueryBuilder);
87
+ }
88
+ }
89
+ return baseContext;
90
+ }
91
+ : undefined;
92
+ const hooks = (config.hooks ?? {});
93
+ const queryLogger = new ServeQueryLogger();
94
+ // Wire up production query logging if configured
95
+ if (config.queryLogging) {
96
+ if (typeof config.queryLogging === 'function') {
97
+ queryLogger.on(config.queryLogging);
98
+ }
99
+ else if (config.queryLogging === 'json') {
100
+ queryLogger.on((event) => {
101
+ const line = formatQueryEventJSON(event);
102
+ if (line)
103
+ console.log(line);
104
+ });
105
+ }
106
+ else {
107
+ queryLogger.on((event) => {
108
+ const line = formatQueryEvent(event);
109
+ if (line)
110
+ console.log(line);
111
+ });
112
+ }
113
+ }
114
+ // Slow query warning
115
+ if (config.slowQueryThreshold != null) {
116
+ queryLogger.on((event) => {
117
+ if (event.status === 'completed' && event.durationMs && event.durationMs > config.slowQueryThreshold) {
118
+ console.warn(`[hypequery/slow-query] ${event.method} ${event.path} took ${event.durationMs}ms (threshold: ${config.slowQueryThreshold}ms)`);
119
+ }
120
+ });
121
+ }
122
+ const openapiConfig = {
123
+ enabled: config.openapi?.enabled ?? true,
124
+ path: config.openapi?.path ?? "/openapi.json",
125
+ };
126
+ const docsConfig = {
127
+ enabled: config.docs?.enabled ?? true,
128
+ path: config.docs?.path ?? "/docs",
129
+ };
130
+ const openapiPublicPath = applyBasePath(basePath, openapiConfig.path);
131
+ const configuredQueries = config.queries ?? {};
132
+ const queryEntries = {};
133
+ for (const key of Object.keys(configuredQueries)) {
134
+ const endpoint = createEndpoint(String(key), configuredQueries[key]);
135
+ const routePath = normalizeRoutePath(`/queries/${String(key)}`);
136
+ const registeredEndpoint = {
137
+ ...endpoint,
138
+ metadata: { ...endpoint.metadata, path: routePath },
139
+ };
140
+ queryEntries[key] = registeredEndpoint;
141
+ router.register(registeredEndpoint);
142
+ }
143
+ // Process metrics — auto-generate POST endpoints
144
+ if (config.metrics) {
145
+ const metricsEntries = config.metrics;
146
+ const builderFactory = resolvedQueryBuilder;
147
+ if (!builderFactory) {
148
+ throw new Error('createAPI: `queryBuilder` is required when `metrics` is provided. ' +
149
+ 'Pass the createQueryBuilder(config) return value as `queryBuilder`, ' +
150
+ 'or provide it via context as `context: () => ({ db: queryBuilder })`.');
151
+ }
152
+ const analytics = createDatasetClient({ queryBuilder: builderFactory });
153
+ for (const [name, entry] of Object.entries(metricsEntries)) {
154
+ assertSemanticKeyAvailable(queryEntries, name, "metric");
155
+ const metricEndpoint = createMetricEndpoint(name, entry, analytics, builderFactory);
156
+ const metricsPath = config.semanticPaths?.metrics ?? '/metrics';
157
+ const routePath = normalizeRoutePath(`${metricsPath}/${name}`);
158
+ const registeredEndpoint = {
159
+ ...metricEndpoint,
160
+ metadata: { ...metricEndpoint.metadata, path: routePath },
161
+ };
162
+ queryEntries[name] = registeredEndpoint;
163
+ router.register(registeredEndpoint);
164
+ }
165
+ }
166
+ // Process datasets — auto-generate POST endpoints for semantic dataset queries
167
+ if (config.datasets) {
168
+ const datasetEntries = config.datasets;
169
+ const builderFactory = resolvedQueryBuilder;
170
+ if (!builderFactory) {
171
+ throw new Error('createAPI: `queryBuilder` is required when `datasets` is provided. ' +
172
+ 'Pass the createQueryBuilder(config) return value as `queryBuilder`, ' +
173
+ 'or provide it via context as `context: () => ({ db: queryBuilder })`.');
174
+ }
175
+ for (const [name, entry] of Object.entries(datasetEntries)) {
176
+ assertSemanticKeyAvailable(queryEntries, `dataset:${name}`, "dataset");
177
+ const datasetEndpoint = createDatasetEndpoint(name, entry, builderFactory);
178
+ const datasetsPath = config.semanticPaths?.datasets ?? '/datasets';
179
+ const routePath = normalizeRoutePath(`${datasetsPath}/${name}/query`);
180
+ const registeredEndpoint = {
181
+ ...datasetEndpoint,
182
+ metadata: { ...datasetEndpoint.metadata, path: routePath },
183
+ };
184
+ queryEntries[`dataset:${name}`] = registeredEndpoint;
185
+ router.register(registeredEndpoint);
186
+ }
187
+ }
188
+ const corsConfig = resolveCorsConfig(config.cors);
189
+ const handler = createServeHandler({
190
+ router,
191
+ globalMiddlewares,
192
+ authStrategies,
193
+ tenantConfig: globalTenantConfig,
194
+ contextFactory,
195
+ hooks,
196
+ queryLogger,
197
+ verboseAuthErrors: config.security?.verboseAuthErrors ?? false,
198
+ corsConfig,
199
+ });
200
+ const executeQuery = createExecuteQuery(queryEntries, authStrategies, contextFactory, globalMiddlewares, globalTenantConfig, hooks, queryLogger, config.security?.verboseAuthErrors ?? false);
201
+ const api = createAPImethods(queryEntries, queryLogger, router, authStrategies, globalMiddlewares, executeQuery, handler, basePath);
202
+ if (openapiConfig.enabled) {
203
+ const openapiEndpoint = createOpenApiEndpoint(openapiConfig.path, () => router.list(), config.openapi);
204
+ router.register(openapiEndpoint);
205
+ }
206
+ if (docsConfig.enabled) {
207
+ const docsEndpoint = createDocsEndpoint(docsConfig.path, openapiPublicPath, config.docs);
208
+ router.register(docsEndpoint);
209
+ }
210
+ return api;
211
+ };
@@ -1,3 +1,22 @@
1
- import type { AuthContext, ServeBuilder, ServeConfig, ServeEndpointMap, ServeQueriesMap } from "../types.js";
2
- export declare const defineServe: <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>;
1
+ import type { AuthContext, ServeBuilder, ServeConfig, ServeEndpointMap, ServeSemanticEndpointMap, ServeQueriesMap, MetricsConfig, DatasetsConfig } from "../types.js";
2
+ /**
3
+ * Define and configure a serve API with embedded transport.
4
+ *
5
+ * @deprecated Prefer `createAPI()` with standalone transport functions for
6
+ * better separation of concerns. `defineServe()` couples API definition
7
+ * with the Node.js HTTP server via `.start()`.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // Before (defineServe)
12
+ * const api = defineServe({ queries: { ... } });
13
+ * api.start({ port: 3000 });
14
+ *
15
+ * // After (createAPI + serve)
16
+ * import { createAPI, startServer } from '@hypequery/serve';
17
+ * const api = createAPI({ queries: { ... } });
18
+ * startServer(api, { port: 3000 });
19
+ * ```
20
+ */
21
+ export declare const defineServe: <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>;
3
22
  //# sourceMappingURL=define-serve.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"define-serve.d.ts","sourceRoot":"","sources":["../../src/server/define-serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAGX,YAAY,EACZ,WAAW,EAEX,gBAAgB,EAIhB,eAAe,EAEhB,MAAM,aAAa,CAAC;AAWrB,eAAO,MAAM,WAAW,GACtB,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,EAEpF,QAAQ,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,KAC7C,YAAY,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,CAoH3E,CAAC"}
1
+ {"version":3,"file":"define-serve.d.ts","sourceRoot":"","sources":["../../src/server/define-serve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,EAEf,aAAa,EACb,cAAc,EACf,MAAM,aAAa,CAAC;AAGrB;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,WAAW,GACtB,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,QAAQ,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,KAClE,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,CAqDN,CAAC"}