@bayoudhi/moose-lib-serverless 0.7.12 → 0.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browserCompatible.d.ts +5 -4
- package/dist/compilerPlugin.js +115 -9
- package/dist/index-Cs6mRtl7.d.ts +1305 -0
- package/dist/index.d.mts +771 -17
- package/dist/index.d.ts +771 -17
- package/dist/index.js +5523 -96
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5572 -195
- package/dist/index.mjs.map +1 -1
- package/dist/moose-runner.js +10364 -4240
- package/dist/moose-tspc.js +7 -56
- package/dist/view-CNYx8kUh.d.ts +1327 -0
- package/package.json +2 -2
- package/dist/index-DdE-_e4q.d.ts +0 -2412
package/dist/index.d.mts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
export { JWT, Key } from './browserCompatible';
|
|
2
2
|
import * as _clickhouse_client from '@clickhouse/client';
|
|
3
|
-
import {
|
|
4
|
-
export { A as Aggregated,
|
|
3
|
+
import { V as MooseUtils, X as MooseClient, M as MaterializedView } from './index-Cs6mRtl7';
|
|
4
|
+
export { A as Aggregated, f as Api, g as ApiConfig, a3 as ApiHelpers, R as ApiUtil, C as ConsumptionApi, a4 as ConsumptionHelpers, U as ConsumptionUtil, c as DeadLetter, D as DeadLetterModel, d as DeadLetterQueue, l as ETLPipeline, m as ETLPipelineConfig, E as EgressConfig, F as FrameworkApp, I as IngestApi, e as IngestConfig, h as IngestPipeline, Y as MOOSE_RLS_ROLE, _ as MOOSE_RLS_SETTING_PREFIX, Z as MOOSE_RLS_USER, $ as RowPoliciesConfig, j as SelectRowPolicy, k as SelectRowPolicyConfig, S as SimpleAggregated, i as SqlResource, a as Stream, b as StreamConfig, T as Task, n as WebApp, o as WebAppConfig, p as WebAppHandler, W as Workflow, a1 as WorkflowClient, a0 as buildRowPolicyOptionsFromClaims, x as getApi, w as getApis, v as getIngestApi, u as getIngestApis, N as getMaterializedView, O as getMaterializedViews, P as getSelectRowPolicies, Q as getSelectRowPolicy, z as getSqlResource, y as getSqlResources, t as getStream, s as getStreams, r as getTable, q as getTables, a2 as getTemporalClient, K as getView, L as getViews, J as getWebApp, H as getWebApps, G as getWorkflow, B as getWorkflows, a5 as joinQueries } from './index-Cs6mRtl7';
|
|
5
5
|
import http from 'http';
|
|
6
|
+
import { M as Sql, O as OlapTable, a0 as Column, _ as QueryClient, a3 as DataType } from './view-CNYx8kUh';
|
|
7
|
+
export { n as ClickHouseAlias, d as ClickHouseByteSize, o as ClickHouseCodec, c as ClickHouseDecimal, k as ClickHouseDefault, C as ClickHouseEngines, e as ClickHouseFixedStringSize, f as ClickHouseFloat, g as ClickHouseInt, h as ClickHouseJson, a6 as ClickHouseLineString, m as ClickHouseMaterialized, a7 as ClickHouseMultiLineString, a9 as ClickHouseMultiPolygon, j as ClickHouseNamedTuple, a4 as ClickHousePoint, a8 as ClickHousePolygon, b as ClickHousePrecision, a5 as ClickHouseRing, l as ClickHouseTTL, D as DateTime, p as DateTime64, r as DateTime64String, q as DateTimeString, A as Decimal, F as FixedString, s as Float32, t as Float64, G as IdentifierBrandedString, B as Insertable, u as Int16, v as Int32, w as Int64, I as Int8, L as LifeCycle, i as LowCardinality, N as NonIdentifierBrandedString, a as OlapConfig, R as RawValue, a1 as RowPolicyOptions, S as S3QueueTableSettings, J as SqlTemplateTag, x as UInt16, y as UInt32, z as UInt64, U as UInt8, H as Value, V as View, W as WithDefault, Y as createClickhouseParameter, X as getValueFromParameter, Z as mapToClickHouseType, E as quoteIdentifier, K as sql, Q as toQuery, T as toQueryPreview, P as toStaticQuery } from './view-CNYx8kUh';
|
|
6
8
|
import { IsTuple } from 'typia/lib/typings/IsTuple';
|
|
7
9
|
import { Readable } from 'node:stream';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
declare namespace z { type ZodType = any; }
|
|
11
|
+
type McpServer = any;
|
|
12
|
+
import { IValidation } from 'typia';
|
|
10
13
|
import 'jose';
|
|
14
|
+
import 'typia/lib/tags';
|
|
11
15
|
|
|
12
16
|
declare const Kafka: any;
|
|
13
17
|
type Kafka = any;
|
|
@@ -371,8 +375,14 @@ interface RuntimeClickHouseConfig {
|
|
|
371
375
|
password: string;
|
|
372
376
|
database: string;
|
|
373
377
|
useSSL: boolean;
|
|
378
|
+
rlsUser?: string;
|
|
379
|
+
rlsPassword?: string;
|
|
374
380
|
}
|
|
375
381
|
|
|
382
|
+
interface GetMooseUtilsOptions {
|
|
383
|
+
/** Map of JWT claim names to their values for row policy scoping */
|
|
384
|
+
rlsContext?: Record<string, string>;
|
|
385
|
+
}
|
|
376
386
|
/**
|
|
377
387
|
* Get Moose utilities for database access and SQL queries.
|
|
378
388
|
* Works in both Moose runtime and standalone contexts.
|
|
@@ -383,21 +393,17 @@ interface RuntimeClickHouseConfig {
|
|
|
383
393
|
* const moose = getMooseUtils(); // WRONG - returns Promise, not MooseUtils!
|
|
384
394
|
* ```
|
|
385
395
|
*
|
|
386
|
-
*
|
|
387
|
-
* If you were using the old sync API that extracted utils from a request object,
|
|
388
|
-
* use `getMooseUtilsFromRequest(req)` for backward compatibility (deprecated).
|
|
389
|
-
*
|
|
390
|
-
* @param req - DEPRECATED: Request parameter is no longer needed and will be ignored.
|
|
391
|
-
* If you need to extract moose from a request, use getMooseUtilsFromRequest().
|
|
392
|
-
* @returns Promise resolving to MooseUtils with client and sql utilities.
|
|
393
|
-
*
|
|
394
|
-
* @example
|
|
396
|
+
* Pass `{ rlsContext }` to get a scoped client that enforces ClickHouse row policies:
|
|
395
397
|
* ```typescript
|
|
396
|
-
* const { client, sql } = await getMooseUtils();
|
|
397
|
-
*
|
|
398
|
+
* const { client, sql } = await getMooseUtils({ rlsContext: { org_id: orgId } });
|
|
399
|
+
* // All queries through this client are filtered by org_id
|
|
398
400
|
* ```
|
|
401
|
+
*
|
|
402
|
+
* @param options - Optional. Pass `{ rlsContext }` to scope queries via row policies.
|
|
403
|
+
* DEPRECATED: Passing a request object is no longer needed and will be ignored.
|
|
404
|
+
* @returns Promise resolving to MooseUtils with client and sql utilities.
|
|
399
405
|
*/
|
|
400
|
-
declare function getMooseUtils(
|
|
406
|
+
declare function getMooseUtils(options?: GetMooseUtilsOptions | any): Promise<MooseUtils>;
|
|
401
407
|
/**
|
|
402
408
|
* @deprecated Use getMooseUtils() instead.
|
|
403
409
|
* Creates a Moose client for database access.
|
|
@@ -627,6 +633,754 @@ interface ExtractionResult<T = any> {
|
|
|
627
633
|
metadata: Record<string, any>;
|
|
628
634
|
}
|
|
629
635
|
|
|
636
|
+
/**
|
|
637
|
+
* Query Layer Types
|
|
638
|
+
*
|
|
639
|
+
* Consolidated type definitions for the query layer.
|
|
640
|
+
*
|
|
641
|
+
* @module query-layer/types
|
|
642
|
+
*/
|
|
643
|
+
|
|
644
|
+
/** Valid SQL values that can be parameterized */
|
|
645
|
+
type SqlValue = string | number | boolean | Date;
|
|
646
|
+
/**
|
|
647
|
+
* Column reference — a Column object from OlapTable.columns.* or a raw Sql expression.
|
|
648
|
+
*
|
|
649
|
+
* @example
|
|
650
|
+
* const col = Events.columns.amount; // Column
|
|
651
|
+
* const expr = sql`CASE WHEN ... END`; // Sql
|
|
652
|
+
*/
|
|
653
|
+
type ColRef = Column | Sql;
|
|
654
|
+
/**
|
|
655
|
+
* Supported filter operators for building WHERE conditions.
|
|
656
|
+
*
|
|
657
|
+
* Each operator has specific value type requirements:
|
|
658
|
+
* - Scalar operators (eq, ne, gt, gte, lt, lte, like, ilike): single value
|
|
659
|
+
* - List operators (in, notIn): array of values
|
|
660
|
+
* - Range operators (between): tuple [low, high]
|
|
661
|
+
* - Null operators (isNull, isNotNull): boolean flag
|
|
662
|
+
*/
|
|
663
|
+
type FilterOperator = "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "like" | "ilike" | "in" | "notIn" | "between" | "isNull" | "isNotNull";
|
|
664
|
+
/** Sort direction for ORDER BY clauses */
|
|
665
|
+
type SortDir = "ASC" | "DESC";
|
|
666
|
+
/**
|
|
667
|
+
* Dimension definition — a column or expression used for grouping.
|
|
668
|
+
*
|
|
669
|
+
* @template TModel - The table's model type
|
|
670
|
+
* @template TKey - The column key (must be a key of TModel)
|
|
671
|
+
*
|
|
672
|
+
* @example
|
|
673
|
+
* dimensions: {
|
|
674
|
+
* status: { column: "status" },
|
|
675
|
+
* day: { expression: sql`toDate(timestamp)`, as: "day" },
|
|
676
|
+
* }
|
|
677
|
+
*/
|
|
678
|
+
interface DimensionDef<TModel = any, TKey extends keyof TModel = keyof TModel> {
|
|
679
|
+
column?: TKey;
|
|
680
|
+
expression?: Sql;
|
|
681
|
+
as?: string;
|
|
682
|
+
description?: string;
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Metric definition — an aggregate or computed value.
|
|
686
|
+
*
|
|
687
|
+
* @example
|
|
688
|
+
* metrics: {
|
|
689
|
+
* totalAmount: { agg: sql`sum(amount)` },
|
|
690
|
+
* totalEvents: { agg: sql`count(*)` },
|
|
691
|
+
* revenue: { agg: sql`sum(amount)`, as: "total_revenue" },
|
|
692
|
+
* }
|
|
693
|
+
*/
|
|
694
|
+
interface MetricDef {
|
|
695
|
+
agg: Sql;
|
|
696
|
+
as?: string;
|
|
697
|
+
description?: string;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Column definition for detail (non-aggregated) queries.
|
|
701
|
+
*
|
|
702
|
+
* @template TModel - The table's model type
|
|
703
|
+
* @template TKey - The column key (must be a key of TModel)
|
|
704
|
+
*
|
|
705
|
+
* @example
|
|
706
|
+
* columns: {
|
|
707
|
+
* visitId: { column: "id" },
|
|
708
|
+
* firstName: { join: "user", column: "first_name" },
|
|
709
|
+
* }
|
|
710
|
+
*/
|
|
711
|
+
interface ColumnDef<TModel = any, TKey extends keyof TModel = keyof TModel> {
|
|
712
|
+
column: TKey | string;
|
|
713
|
+
join?: string;
|
|
714
|
+
as?: string;
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Join definition for lookup JOINs.
|
|
718
|
+
*
|
|
719
|
+
* @example
|
|
720
|
+
* joins: {
|
|
721
|
+
* user: {
|
|
722
|
+
* table: UsersTable,
|
|
723
|
+
* leftKey: "user_id",
|
|
724
|
+
* rightKey: "id",
|
|
725
|
+
* type: "LEFT",
|
|
726
|
+
* },
|
|
727
|
+
* }
|
|
728
|
+
*/
|
|
729
|
+
interface JoinDef {
|
|
730
|
+
table: OlapTable<any> | MaterializedView<any>;
|
|
731
|
+
on?: Sql;
|
|
732
|
+
leftKey?: string;
|
|
733
|
+
rightKey?: string;
|
|
734
|
+
type?: "LEFT" | "INNER";
|
|
735
|
+
}
|
|
736
|
+
/** Input type hint for filter UI rendering */
|
|
737
|
+
type FilterInputTypeHint = "text" | "number" | "date" | "select" | "multiselect";
|
|
738
|
+
/**
|
|
739
|
+
* Filter definition for use in defineQueryModel configuration.
|
|
740
|
+
*
|
|
741
|
+
* @template TModel - The table's model type
|
|
742
|
+
* @template TKey - The column key (must be a key of TModel)
|
|
743
|
+
*
|
|
744
|
+
* @example
|
|
745
|
+
* filters: {
|
|
746
|
+
* status: { column: "status", operators: ["eq", "in"] as const },
|
|
747
|
+
* amount: { column: "amount", operators: ["gte", "lte"] as const },
|
|
748
|
+
* }
|
|
749
|
+
*/
|
|
750
|
+
interface ModelFilterDef<TModel, TKey extends keyof TModel = keyof TModel> {
|
|
751
|
+
column?: TKey;
|
|
752
|
+
/** Metric name — filters referencing a metric are auto-routed to HAVING */
|
|
753
|
+
metric?: string;
|
|
754
|
+
operators: readonly FilterOperator[];
|
|
755
|
+
transform?: (value: TModel[TKey]) => SqlValue;
|
|
756
|
+
inputType?: FilterInputTypeHint;
|
|
757
|
+
/** When true, this filter's `eq` param is required in MCP tool schemas */
|
|
758
|
+
required?: true;
|
|
759
|
+
description?: string;
|
|
760
|
+
}
|
|
761
|
+
/** Extract string keys from a record type */
|
|
762
|
+
type Names<T> = Extract<keyof T, string>;
|
|
763
|
+
/**
|
|
764
|
+
* Infer the value type for a given operator and base value type.
|
|
765
|
+
*
|
|
766
|
+
* Maps filter operators to their required value types:
|
|
767
|
+
* - Scalar operators: single value
|
|
768
|
+
* - List operators (in, notIn): array of values
|
|
769
|
+
* - Range operators (between): tuple [low, high]
|
|
770
|
+
* - Null operators (isNull, isNotNull): boolean flag
|
|
771
|
+
*/
|
|
772
|
+
type OperatorValueType<Op extends FilterOperator, TValue = SqlValue> = Op extends "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "like" | "ilike" ? TValue : Op extends "in" | "notIn" ? TValue[] : Op extends "between" ? [TValue, TValue] : Op extends "isNull" | "isNotNull" ? boolean : never;
|
|
773
|
+
/** Base constraint for filter definitions */
|
|
774
|
+
type FilterDefBase = {
|
|
775
|
+
operators: readonly FilterOperator[];
|
|
776
|
+
};
|
|
777
|
+
/** Filter parameters structure derived from filter definitions */
|
|
778
|
+
type FilterParams<TFilters extends Record<string, FilterDefBase>, TTable = any> = {
|
|
779
|
+
[K in keyof TFilters]?: {
|
|
780
|
+
[Op in TFilters[K]["operators"][number]]?: OperatorValueType<Op, TFilters[K] extends {
|
|
781
|
+
column: infer TKey extends keyof TTable;
|
|
782
|
+
} ? TTable[TKey] : SqlValue>;
|
|
783
|
+
};
|
|
784
|
+
};
|
|
785
|
+
/**
|
|
786
|
+
* User-facing query request specification.
|
|
787
|
+
*
|
|
788
|
+
* Users specify dimensions and metrics — semantic concepts, not SQL concepts.
|
|
789
|
+
* The query model handles the translation to actual SQL.
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* const request: QueryRequest = {
|
|
793
|
+
* dimensions: ["status", "day"],
|
|
794
|
+
* metrics: ["totalEvents", "totalAmount"],
|
|
795
|
+
* filters: { status: { eq: "active" } },
|
|
796
|
+
* orderBy: [["totalAmount", "DESC"]],
|
|
797
|
+
* limit: 10,
|
|
798
|
+
* };
|
|
799
|
+
*/
|
|
800
|
+
type QueryRequest<TMetrics extends string = string, TDimensions extends string = string, TFilters extends Record<string, FilterDefBase> = Record<string, FilterDefBase>, TSortable extends string = string, TColumns extends string = string, TTable = any> = {
|
|
801
|
+
filters?: FilterParams<TFilters, TTable>;
|
|
802
|
+
dimensions?: TDimensions[];
|
|
803
|
+
metrics?: TMetrics[];
|
|
804
|
+
/** Columns for detail mode (no aggregation). Mutually exclusive with dimensions/metrics. */
|
|
805
|
+
columns?: TColumns[];
|
|
806
|
+
orderBy?: Array<[TSortable, SortDir]>;
|
|
807
|
+
limit?: number;
|
|
808
|
+
/** Page number (0-indexed). Mutually exclusive with offset. */
|
|
809
|
+
page?: number;
|
|
810
|
+
/** Row offset. Mutually exclusive with page. */
|
|
811
|
+
offset?: number;
|
|
812
|
+
};
|
|
813
|
+
/** Individual SQL clauses for custom query assembly */
|
|
814
|
+
interface QueryParts {
|
|
815
|
+
select: Sql;
|
|
816
|
+
dimensions: Sql;
|
|
817
|
+
metrics: Sql;
|
|
818
|
+
columns: Sql;
|
|
819
|
+
from: Sql;
|
|
820
|
+
conditions: Sql[];
|
|
821
|
+
where: Sql;
|
|
822
|
+
groupBy: Sql;
|
|
823
|
+
having: Sql;
|
|
824
|
+
orderBy: Sql;
|
|
825
|
+
/** Composed LIMIT + OFFSET clause */
|
|
826
|
+
pagination: Sql;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* Query Model — Core query building interface and implementation.
|
|
831
|
+
*
|
|
832
|
+
* @module query-layer/query-model
|
|
833
|
+
*/
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* Configuration for defining a query model.
|
|
837
|
+
*
|
|
838
|
+
* @template TTable - The table's model type (row type)
|
|
839
|
+
* @template TMetrics - Record of metric definitions
|
|
840
|
+
* @template TDimensions - Record of dimension definitions
|
|
841
|
+
* @template TFilters - Record of filter definitions
|
|
842
|
+
* @template TSortable - Union type of sortable field names
|
|
843
|
+
*/
|
|
844
|
+
interface QueryModelConfig<TTable, TMetrics extends Record<string, MetricDef>, TDimensions extends Record<string, DimensionDef<TTable, keyof TTable>>, TFilters extends Record<string, ModelFilterDef<TTable, keyof TTable>>, TSortable extends string, TColumns extends Record<string, ColumnDef<TTable>> = Record<string, never>, TJoins extends Record<string, JoinDef> = Record<string, never>> {
|
|
845
|
+
/** Tool name used by registerModelTools (e.g. "query_visits") */
|
|
846
|
+
name?: string;
|
|
847
|
+
/** Tool description used by registerModelTools */
|
|
848
|
+
description?: string;
|
|
849
|
+
/** The OlapTable or MaterializedView to query. If a MaterializedView is passed, its targetTable is used. */
|
|
850
|
+
table: OlapTable<TTable> | MaterializedView<TTable>;
|
|
851
|
+
/**
|
|
852
|
+
* Dimension fields — columns used for grouping, filtering, and display.
|
|
853
|
+
*
|
|
854
|
+
* @example
|
|
855
|
+
* dimensions: {
|
|
856
|
+
* status: { column: "status" },
|
|
857
|
+
* day: { expression: sql`toDate(timestamp)`, as: "day" },
|
|
858
|
+
* }
|
|
859
|
+
*/
|
|
860
|
+
dimensions?: TDimensions;
|
|
861
|
+
/**
|
|
862
|
+
* Metric fields — aggregate values computed over dimensions.
|
|
863
|
+
*
|
|
864
|
+
* @example
|
|
865
|
+
* metrics: {
|
|
866
|
+
* totalAmount: { agg: sum(Events.columns.amount), as: "total_amount" },
|
|
867
|
+
* totalEvents: { agg: count(), as: "total_events" },
|
|
868
|
+
* }
|
|
869
|
+
*/
|
|
870
|
+
metrics?: TMetrics;
|
|
871
|
+
/**
|
|
872
|
+
* Column fields for detail (non-aggregated) queries.
|
|
873
|
+
*
|
|
874
|
+
* @example
|
|
875
|
+
* columns: {
|
|
876
|
+
* visitId: { column: "id" },
|
|
877
|
+
* firstName: { join: "user", column: "first_name" },
|
|
878
|
+
* }
|
|
879
|
+
*/
|
|
880
|
+
columns?: TColumns;
|
|
881
|
+
/**
|
|
882
|
+
* Lookup JOIN definitions.
|
|
883
|
+
*
|
|
884
|
+
* @example
|
|
885
|
+
* joins: {
|
|
886
|
+
* user: {
|
|
887
|
+
* table: UsersTable,
|
|
888
|
+
* leftKey: "user_id",
|
|
889
|
+
* rightKey: "id",
|
|
890
|
+
* type: "LEFT",
|
|
891
|
+
* },
|
|
892
|
+
* }
|
|
893
|
+
*/
|
|
894
|
+
joins?: TJoins;
|
|
895
|
+
/**
|
|
896
|
+
* Filterable fields with allowed operators.
|
|
897
|
+
*
|
|
898
|
+
* @example
|
|
899
|
+
* filters: {
|
|
900
|
+
* status: { column: "status", operators: ["eq", "in"] as const },
|
|
901
|
+
* amount: { column: "amount", operators: ["gte", "lte"] as const },
|
|
902
|
+
* }
|
|
903
|
+
*/
|
|
904
|
+
filters: TFilters;
|
|
905
|
+
/**
|
|
906
|
+
* Which fields can be sorted.
|
|
907
|
+
*
|
|
908
|
+
* @example
|
|
909
|
+
* sortable: ["timestamp", "amount", "status"] as const
|
|
910
|
+
*/
|
|
911
|
+
sortable: readonly TSortable[];
|
|
912
|
+
/** Default query behavior */
|
|
913
|
+
defaults?: {
|
|
914
|
+
orderBy?: Array<[TSortable, SortDir]>;
|
|
915
|
+
groupBy?: string[];
|
|
916
|
+
limit?: number;
|
|
917
|
+
maxLimit?: number;
|
|
918
|
+
dimensions?: string[];
|
|
919
|
+
metrics?: string[];
|
|
920
|
+
columns?: string[];
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Query model interface providing type-safe query building and execution.
|
|
925
|
+
*/
|
|
926
|
+
interface QueryModel<TTable, TMetrics extends Record<string, MetricDef>, TDimensions extends Record<string, DimensionDef>, TFilters extends Record<string, FilterDefBase>, TSortable extends string, TResult, TColumns extends Record<string, ColumnDef> = Record<string, never>> {
|
|
927
|
+
readonly name?: string;
|
|
928
|
+
readonly description?: string;
|
|
929
|
+
readonly defaults: {
|
|
930
|
+
orderBy?: Array<[TSortable, SortDir]>;
|
|
931
|
+
groupBy?: string[];
|
|
932
|
+
limit?: number;
|
|
933
|
+
maxLimit?: number;
|
|
934
|
+
dimensions?: string[];
|
|
935
|
+
metrics?: string[];
|
|
936
|
+
columns?: string[];
|
|
937
|
+
};
|
|
938
|
+
readonly filters: TFilters;
|
|
939
|
+
readonly sortable: readonly TSortable[];
|
|
940
|
+
readonly dimensions?: TDimensions;
|
|
941
|
+
readonly metrics?: TMetrics;
|
|
942
|
+
readonly columns?: TColumns;
|
|
943
|
+
readonly columnNames: readonly string[];
|
|
944
|
+
/** Type inference helpers (similar to Drizzle's $inferSelect pattern). */
|
|
945
|
+
readonly $inferDimensions: Names<TDimensions>;
|
|
946
|
+
readonly $inferMetrics: Names<TMetrics>;
|
|
947
|
+
readonly $inferColumns: Names<TColumns>;
|
|
948
|
+
readonly $inferFilters: FilterParams<TFilters, TTable>;
|
|
949
|
+
readonly $inferRequest: QueryRequest<Names<TMetrics>, Names<TDimensions>, TFilters, TSortable, Names<TColumns>, TTable>;
|
|
950
|
+
readonly $inferResult: TResult;
|
|
951
|
+
/** Execute query with Moose QueryClient. */
|
|
952
|
+
query(request: QueryRequest<Names<TMetrics>, Names<TDimensions>, TFilters, TSortable, Names<TColumns>, TTable>, client: QueryClient): Promise<TResult[]>;
|
|
953
|
+
/** Build complete SQL query from request. */
|
|
954
|
+
toSql(request: QueryRequest<Names<TMetrics>, Names<TDimensions>, TFilters, TSortable, Names<TColumns>, TTable>): Sql;
|
|
955
|
+
/** Get individual SQL parts for custom assembly. */
|
|
956
|
+
toParts(request: QueryRequest<Names<TMetrics>, Names<TDimensions>, TFilters, TSortable, Names<TColumns>, TTable>): QueryParts;
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Define a query model with controlled field selection, filtering, and sorting.
|
|
960
|
+
*
|
|
961
|
+
* @example
|
|
962
|
+
* const model = defineQueryModel({
|
|
963
|
+
* table: Events,
|
|
964
|
+
* dimensions: {
|
|
965
|
+
* status: { column: "status" },
|
|
966
|
+
* day: { expression: sql`toDate(timestamp)`, as: "day" },
|
|
967
|
+
* },
|
|
968
|
+
* metrics: {
|
|
969
|
+
* totalEvents: { agg: count(), as: "total_events" },
|
|
970
|
+
* totalAmount: { agg: sum(Events.columns.amount), as: "total_amount" },
|
|
971
|
+
* },
|
|
972
|
+
* filters: {
|
|
973
|
+
* status: { column: "status", operators: ["eq", "in"] as const },
|
|
974
|
+
* },
|
|
975
|
+
* sortable: ["amount", "timestamp"] as const,
|
|
976
|
+
* });
|
|
977
|
+
*/
|
|
978
|
+
declare function defineQueryModel<TTable, TMetrics extends Record<string, MetricDef>, TDimensions extends Record<string, DimensionDef<TTable, keyof TTable>>, TFilters extends Record<string, ModelFilterDef<TTable, keyof TTable>>, TSortable extends string, TColumns extends Record<string, ColumnDef<TTable>> = Record<string, never>, TJoins extends Record<string, JoinDef> = Record<string, never>, TResult = TTable>(config: QueryModelConfig<TTable, TMetrics, TDimensions, TFilters, TSortable, TColumns, TJoins>): QueryModel<TTable, TMetrics, TDimensions, TFilters, TSortable, TResult, TColumns>;
|
|
979
|
+
|
|
980
|
+
/**
|
|
981
|
+
* Composable helpers that leverage moose-lib table metadata to reduce
|
|
982
|
+
* boilerplate in QueryModel definitions.
|
|
983
|
+
*
|
|
984
|
+
* @module query-layer/helpers
|
|
985
|
+
*/
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* Derive FilterInputTypeHint from a ClickHouse column data_type.
|
|
989
|
+
*/
|
|
990
|
+
declare function deriveInputTypeFromDataType(dataType: DataType): FilterInputTypeHint;
|
|
991
|
+
type DefaultTimePeriods = {
|
|
992
|
+
day: DimensionDef;
|
|
993
|
+
month: DimensionDef;
|
|
994
|
+
week: DimensionDef;
|
|
995
|
+
};
|
|
996
|
+
/**
|
|
997
|
+
* Generate day/month/week dimension definitions from a date column reference.
|
|
998
|
+
*
|
|
999
|
+
* @param dateColumn - A Column reference from `Table.columns.some_date`
|
|
1000
|
+
* @returns `{ day, month, week }` dimension definitions
|
|
1001
|
+
*
|
|
1002
|
+
* @example
|
|
1003
|
+
* dimensions: {
|
|
1004
|
+
* status: { column: "status" },
|
|
1005
|
+
* ...timeDimensions(VisitsTable.columns.start_date),
|
|
1006
|
+
* }
|
|
1007
|
+
*/
|
|
1008
|
+
declare function timeDimensions(dateColumn: Column): DefaultTimePeriods;
|
|
1009
|
+
declare function timeDimensions(dateColumn: Column, options: {
|
|
1010
|
+
periods: string[];
|
|
1011
|
+
}): Record<string, DimensionDef>;
|
|
1012
|
+
interface TableFieldOptions {
|
|
1013
|
+
/** Only include these column names (snake_case as in the table) */
|
|
1014
|
+
include?: string[];
|
|
1015
|
+
/** Exclude these column names */
|
|
1016
|
+
exclude?: string[];
|
|
1017
|
+
/** Convert snake_case keys to camelCase (default: true) */
|
|
1018
|
+
camelCase?: boolean;
|
|
1019
|
+
}
|
|
1020
|
+
/**
|
|
1021
|
+
* Generate ColumnDef records from a table's columnArray metadata.
|
|
1022
|
+
*
|
|
1023
|
+
* @example
|
|
1024
|
+
* columns: {
|
|
1025
|
+
* ...columnsFromTable(VisitsTable, { include: ["id", "name", "status"] }),
|
|
1026
|
+
* firstName: { join: "user", column: "first_name" },
|
|
1027
|
+
* }
|
|
1028
|
+
*/
|
|
1029
|
+
declare function columnsFromTable<T>(table: OlapTable<T>, options?: TableFieldOptions): Record<string, ColumnDef<T>>;
|
|
1030
|
+
/**
|
|
1031
|
+
* Generate ModelFilterDef records from a table's columnArray metadata.
|
|
1032
|
+
*
|
|
1033
|
+
* **Conservative defaults**: all filters get `["eq"]` operators only.
|
|
1034
|
+
* Consumers widen operators explicitly via spread overrides.
|
|
1035
|
+
*
|
|
1036
|
+
* @example
|
|
1037
|
+
* filters: {
|
|
1038
|
+
* ...filtersFromTable(VisitsTable, { include: ["studio_id", "start_date", "status"] }),
|
|
1039
|
+
* status: { column: "status", operators: ["eq", "ne", "in"] as const },
|
|
1040
|
+
* }
|
|
1041
|
+
*/
|
|
1042
|
+
declare function filtersFromTable<T>(table: OlapTable<T>, options?: TableFieldOptions): Record<string, ModelFilterDef<T, keyof T>>;
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* Fluent Query Builder API
|
|
1046
|
+
*
|
|
1047
|
+
* Provides a chainable API for building QueryRequest objects.
|
|
1048
|
+
*
|
|
1049
|
+
* @module query-layer/query-builder
|
|
1050
|
+
*/
|
|
1051
|
+
|
|
1052
|
+
/**
|
|
1053
|
+
* Fluent builder for constructing query requests.
|
|
1054
|
+
*
|
|
1055
|
+
* @example
|
|
1056
|
+
* const results = await buildQuery(model)
|
|
1057
|
+
* .dimensions(["status"])
|
|
1058
|
+
* .metrics(["totalEvents", "totalAmount"])
|
|
1059
|
+
* .filter("status", "eq", "active")
|
|
1060
|
+
* .orderBy(["totalAmount", "DESC"])
|
|
1061
|
+
* .limit(10)
|
|
1062
|
+
* .execute(client.query);
|
|
1063
|
+
*/
|
|
1064
|
+
interface QueryBuilder<TMetrics extends string, TDimensions extends string, TFilters extends Record<string, FilterDefBase>, TSortable extends string, TResult, TTable = any, TColumns extends string = string> {
|
|
1065
|
+
/** Add a filter condition. Automatically skips if value is undefined or null. */
|
|
1066
|
+
filter<K extends keyof TFilters, Op extends TFilters[K]["operators"][number]>(filterName: K, op: Op, value: OperatorValueType<Op, SqlValue> | undefined): this;
|
|
1067
|
+
/** Set dimensions to include in query (aggregate mode) */
|
|
1068
|
+
dimensions(fields: TDimensions[]): this;
|
|
1069
|
+
/** Set metrics to include in query (aggregate mode) */
|
|
1070
|
+
metrics(fields: TMetrics[]): this;
|
|
1071
|
+
/** Set columns for detail mode (no aggregation, no GROUP BY) */
|
|
1072
|
+
columns(fields: TColumns[]): this;
|
|
1073
|
+
/** Set multi-column sort */
|
|
1074
|
+
orderBy(...orders: Array<[TSortable, SortDir]>): this;
|
|
1075
|
+
/** Set maximum number of rows to return */
|
|
1076
|
+
limit(n: number): this;
|
|
1077
|
+
/** Set page number (0-indexed) for pagination */
|
|
1078
|
+
page(n: number): this;
|
|
1079
|
+
/** Set row offset for pagination */
|
|
1080
|
+
offset(n: number): this;
|
|
1081
|
+
/** Build the QueryRequest object */
|
|
1082
|
+
build(): QueryRequest<TMetrics, TDimensions, TFilters, TSortable, TColumns, TTable>;
|
|
1083
|
+
/** Build the SQL query */
|
|
1084
|
+
toSql(): Sql;
|
|
1085
|
+
/** Get query parts for custom assembly */
|
|
1086
|
+
toParts(): QueryParts;
|
|
1087
|
+
/** Build SQL with custom assembly function */
|
|
1088
|
+
assemble(fn: (parts: QueryParts) => Sql): Sql;
|
|
1089
|
+
/** Execute the query with Moose QueryClient. */
|
|
1090
|
+
execute(client: QueryClient): Promise<TResult[]>;
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Create a fluent query builder for a model.
|
|
1094
|
+
*
|
|
1095
|
+
* @param model - QueryModel instance to build queries for
|
|
1096
|
+
* @returns QueryBuilder instance with chainable methods
|
|
1097
|
+
*
|
|
1098
|
+
* @example
|
|
1099
|
+
* const results = await buildQuery(model)
|
|
1100
|
+
* .dimensions(["status"])
|
|
1101
|
+
* .metrics(["totalEvents", "totalAmount"])
|
|
1102
|
+
* .filter("status", "eq", "active")
|
|
1103
|
+
* .orderBy(["totalAmount", "DESC"])
|
|
1104
|
+
* .limit(10)
|
|
1105
|
+
* .execute(client.query);
|
|
1106
|
+
*/
|
|
1107
|
+
declare function buildQuery<TTable, TMetrics extends Record<string, MetricDef>, TDimensions extends Record<string, DimensionDef>, TFilters extends Record<string, FilterDefBase>, TSortable extends string, TResult, TColumns extends Record<string, ColumnDef> = Record<string, never>>(model: QueryModel<TTable, TMetrics, TDimensions, TFilters, TSortable, TResult, TColumns>): QueryBuilder<Names<TMetrics>, Names<TDimensions>, TFilters, TSortable, TResult, TTable, Names<TColumns>>;
|
|
1108
|
+
|
|
1109
|
+
/**
|
|
1110
|
+
* MCP Schema Generation from QueryModel
|
|
1111
|
+
*
|
|
1112
|
+
* Auto-generates Zod schemas and request builders for MCP tools
|
|
1113
|
+
* directly from QueryModel metadata (filters, dimensions, metrics, columns).
|
|
1114
|
+
*
|
|
1115
|
+
* @module query-layer/model-tools
|
|
1116
|
+
*/
|
|
1117
|
+
|
|
1118
|
+
/** Filter definition shape expected by MCP utilities. */
|
|
1119
|
+
interface QueryModelFilter {
|
|
1120
|
+
operators: readonly string[];
|
|
1121
|
+
inputType?: FilterInputTypeHint;
|
|
1122
|
+
required?: true;
|
|
1123
|
+
description?: string;
|
|
1124
|
+
}
|
|
1125
|
+
/**
|
|
1126
|
+
* Minimal model interface consumed by createModelTool / registerModelTools.
|
|
1127
|
+
*
|
|
1128
|
+
* Any QueryModel from defineQueryModel() satisfies this structurally —
|
|
1129
|
+
* no explicit `implements` needed. This avoids propagating generic
|
|
1130
|
+
* type parameters into the MCP layer.
|
|
1131
|
+
*/
|
|
1132
|
+
interface QueryModelBase {
|
|
1133
|
+
readonly name?: string;
|
|
1134
|
+
readonly description?: string;
|
|
1135
|
+
readonly defaults: {
|
|
1136
|
+
orderBy?: Array<[string, SortDir]>;
|
|
1137
|
+
groupBy?: string[];
|
|
1138
|
+
limit?: number;
|
|
1139
|
+
maxLimit?: number;
|
|
1140
|
+
dimensions?: string[];
|
|
1141
|
+
metrics?: string[];
|
|
1142
|
+
columns?: string[];
|
|
1143
|
+
};
|
|
1144
|
+
readonly filters: Record<string, QueryModelFilter>;
|
|
1145
|
+
readonly sortable: readonly string[];
|
|
1146
|
+
readonly dimensions?: Record<string, {
|
|
1147
|
+
description?: string;
|
|
1148
|
+
}>;
|
|
1149
|
+
readonly metrics?: Record<string, {
|
|
1150
|
+
description?: string;
|
|
1151
|
+
}>;
|
|
1152
|
+
readonly columnNames: readonly string[];
|
|
1153
|
+
toSql(request: Record<string, unknown>): Sql;
|
|
1154
|
+
}
|
|
1155
|
+
interface ModelToolOptions {
|
|
1156
|
+
/** Filter names whose `eq` param is required (not optional). Merged with model-level `required` flags. */
|
|
1157
|
+
requiredFilters?: string[];
|
|
1158
|
+
/** Maximum limit for the tool. Falls back to model.defaults.maxLimit, then 1000. */
|
|
1159
|
+
maxLimit?: number;
|
|
1160
|
+
/** Default limit for the tool. Falls back to model.defaults.limit, then 100. */
|
|
1161
|
+
defaultLimit?: number;
|
|
1162
|
+
/** Default values applied when params are absent. Merged with model.defaults. */
|
|
1163
|
+
defaults?: {
|
|
1164
|
+
dimensions?: string[];
|
|
1165
|
+
metrics?: string[];
|
|
1166
|
+
columns?: string[];
|
|
1167
|
+
limit?: number;
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
interface ModelToolResult {
|
|
1171
|
+
/** Zod shape object to pass to server.tool() */
|
|
1172
|
+
schema: Record<string, z.ZodType>;
|
|
1173
|
+
/** Convert flat MCP params into a nested QueryRequest */
|
|
1174
|
+
buildRequest: (params: Record<string, unknown>) => Record<string, unknown>;
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Generate a Zod schema and request builder from a QueryModel.
|
|
1178
|
+
*
|
|
1179
|
+
* Required filters, maxLimit, and default selections are first read from the
|
|
1180
|
+
* model itself (via `required: true` on filter defs and `model.defaults`).
|
|
1181
|
+
* The optional `options` param can override or extend any of these.
|
|
1182
|
+
*
|
|
1183
|
+
* @param model - A QueryModel instance (from defineQueryModel)
|
|
1184
|
+
* @param options - Optional overrides for required filters, limits, defaults
|
|
1185
|
+
* @returns `{ schema, buildRequest }` ready for `server.tool()`
|
|
1186
|
+
*/
|
|
1187
|
+
declare function createModelTool(model: QueryModelBase, options?: ModelToolOptions): ModelToolResult;
|
|
1188
|
+
/**
|
|
1189
|
+
* Register MCP tools for all models that have a `name` defined.
|
|
1190
|
+
*
|
|
1191
|
+
* Each model with a `name` property becomes an MCP tool. The library handles
|
|
1192
|
+
* everything: schema generation from model metadata, request building from
|
|
1193
|
+
* flat MCP params, SQL generation via `model.toSql()`, parameterized
|
|
1194
|
+
* execution with readonly enforcement, and MCP response formatting.
|
|
1195
|
+
*
|
|
1196
|
+
* Models without a `name` are silently skipped.
|
|
1197
|
+
*
|
|
1198
|
+
* @param server - McpServer instance
|
|
1199
|
+
* @param models - Array of QueryModel instances (from `defineQueryModel`)
|
|
1200
|
+
* @param queryClient - The QueryClient from `mooseUtils.client.query`.
|
|
1201
|
+
* Queries are executed in readonly mode with parameterized SQL.
|
|
1202
|
+
*
|
|
1203
|
+
* @example
|
|
1204
|
+
* import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
1205
|
+
* import { getMooseUtils, MooseUtils } from "@514labs/moose-lib";
|
|
1206
|
+
* import { registerModelTools } from "@514labs/moose-lib";
|
|
1207
|
+
* import { visitsModel, usersModel } from "./models";
|
|
1208
|
+
*
|
|
1209
|
+
* const serverFactory = (mooseUtils: MooseUtils) => {
|
|
1210
|
+
* const server = new McpServer({ name: "my-tools", version: "1.0.0" });
|
|
1211
|
+
*
|
|
1212
|
+
* // One line registers all named models as MCP tools
|
|
1213
|
+
* registerModelTools(server, [visitsModel, usersModel], mooseUtils.client.query);
|
|
1214
|
+
*
|
|
1215
|
+
* return server;
|
|
1216
|
+
* };
|
|
1217
|
+
*/
|
|
1218
|
+
declare function registerModelTools(server: McpServer, models: QueryModelBase[], queryClient: QueryClient): void;
|
|
1219
|
+
|
|
1220
|
+
/**
|
|
1221
|
+
* SQL Utilities
|
|
1222
|
+
*
|
|
1223
|
+
* Low-level SQL building utilities for constructing type-safe queries.
|
|
1224
|
+
* These are the building blocks used by QueryModel and can also be used
|
|
1225
|
+
* directly for custom query construction.
|
|
1226
|
+
*
|
|
1227
|
+
* @module query-layer/sql-utils
|
|
1228
|
+
*/
|
|
1229
|
+
|
|
1230
|
+
/**
|
|
1231
|
+
* Create raw SQL (literal string, no parameterization).
|
|
1232
|
+
* Delegates to sql.raw from sqlHelpers.
|
|
1233
|
+
*
|
|
1234
|
+
* Only for developer-defined constants (column names, expressions, sort
|
|
1235
|
+
* directions) that originate from model config — never for HTTP/user input.
|
|
1236
|
+
*/
|
|
1237
|
+
declare const raw: (text: string) => Sql;
|
|
1238
|
+
/** Empty SQL fragment — useful as a no-op. */
|
|
1239
|
+
declare const empty: Sql;
|
|
1240
|
+
/**
|
|
1241
|
+
* Join SQL fragments with a separator.
|
|
1242
|
+
* Delegates to sql.join from sqlHelpers.
|
|
1243
|
+
*/
|
|
1244
|
+
declare const join: (fragments: Sql[], separator?: string) => Sql;
|
|
1245
|
+
/** Check if a Sql fragment is empty */
|
|
1246
|
+
declare function isEmpty(fragment: Sql): boolean;
|
|
1247
|
+
/**
|
|
1248
|
+
* Create a filter condition. Automatically skips if value is undefined/null.
|
|
1249
|
+
* This is the recommended way to build conditional WHERE clauses.
|
|
1250
|
+
*
|
|
1251
|
+
* @example
|
|
1252
|
+
* where(
|
|
1253
|
+
* filter(Events.columns.amount, "gte", params.minAmount),
|
|
1254
|
+
* filter(Events.columns.amount, "lte", params.maxAmount),
|
|
1255
|
+
* filter(Events.columns.status, "eq", params.status),
|
|
1256
|
+
* )
|
|
1257
|
+
*/
|
|
1258
|
+
declare function filter(col: ColRef, op: "between", value: [SqlValue, SqlValue] | undefined): Sql;
|
|
1259
|
+
declare function filter(col: ColRef, op: "in" | "notIn", value: SqlValue[] | undefined): Sql;
|
|
1260
|
+
declare function filter(col: ColRef, op: "isNull" | "isNotNull", value: boolean | undefined): Sql;
|
|
1261
|
+
declare function filter(col: ColRef, op: "like" | "ilike", value: string | undefined): Sql;
|
|
1262
|
+
declare function filter(col: ColRef, op: Exclude<FilterOperator, "between" | "in" | "notIn" | "isNull" | "isNotNull" | "like" | "ilike">, value: SqlValue | undefined): Sql;
|
|
1263
|
+
/** Equal: column = value */
|
|
1264
|
+
declare function eq(col: ColRef, value: SqlValue): Sql;
|
|
1265
|
+
/** Not equal: column != value */
|
|
1266
|
+
declare function ne(col: ColRef, value: SqlValue): Sql;
|
|
1267
|
+
/** Greater than: column > value */
|
|
1268
|
+
declare function gt(col: ColRef, value: SqlValue): Sql;
|
|
1269
|
+
/** Greater than or equal: column >= value */
|
|
1270
|
+
declare function gte(col: ColRef, value: SqlValue): Sql;
|
|
1271
|
+
/** Less than: column < value */
|
|
1272
|
+
declare function lt(col: ColRef, value: SqlValue): Sql;
|
|
1273
|
+
/** Less than or equal: column <= value */
|
|
1274
|
+
declare function lte(col: ColRef, value: SqlValue): Sql;
|
|
1275
|
+
/** LIKE pattern match (case-sensitive) */
|
|
1276
|
+
declare function like(col: ColRef, pattern: string): Sql;
|
|
1277
|
+
/** ILIKE pattern match (case-insensitive, ClickHouse) */
|
|
1278
|
+
declare function ilike(col: ColRef, pattern: string): Sql;
|
|
1279
|
+
/** IN list: column IN (a, b, c) */
|
|
1280
|
+
declare function inList(col: ColRef, values: SqlValue[]): Sql;
|
|
1281
|
+
/** NOT IN list */
|
|
1282
|
+
declare function notIn(col: ColRef, values: SqlValue[]): Sql;
|
|
1283
|
+
/** BETWEEN: column BETWEEN low AND high */
|
|
1284
|
+
declare function between(col: ColRef, low: SqlValue, high: SqlValue): Sql;
|
|
1285
|
+
/** IS NULL */
|
|
1286
|
+
declare function isNull(col: ColRef): Sql;
|
|
1287
|
+
/** IS NOT NULL */
|
|
1288
|
+
declare function isNotNull(col: ColRef): Sql;
|
|
1289
|
+
/** Combine conditions with AND, filtering out empty fragments */
|
|
1290
|
+
declare function and(...conditions: Sql[]): Sql;
|
|
1291
|
+
/** Combine conditions with OR, filtering out empty fragments */
|
|
1292
|
+
declare function or(...conditions: Sql[]): Sql;
|
|
1293
|
+
/** Negate a condition: NOT (condition) */
|
|
1294
|
+
declare function not(condition: Sql): Sql;
|
|
1295
|
+
/** Build WHERE clause — returns empty if no conditions */
|
|
1296
|
+
declare function where(...conditions: Sql[]): Sql;
|
|
1297
|
+
/** Build ORDER BY clause */
|
|
1298
|
+
declare function orderBy(...cols: Array<ColRef | [ColRef, "ASC" | "DESC"]>): Sql;
|
|
1299
|
+
/** Build LIMIT clause */
|
|
1300
|
+
declare function limit(n: number): Sql;
|
|
1301
|
+
/** Build OFFSET clause */
|
|
1302
|
+
declare function offset(n: number): Sql;
|
|
1303
|
+
/** Build LIMIT + OFFSET for pagination */
|
|
1304
|
+
declare function paginate(pageSize: number, page?: number): Sql;
|
|
1305
|
+
/** Build GROUP BY clause */
|
|
1306
|
+
declare function groupBy(...cols: ColRef[]): Sql;
|
|
1307
|
+
/** Build HAVING clause */
|
|
1308
|
+
declare function having(...conditions: Sql[]): Sql;
|
|
1309
|
+
/** SQL expression with fluent `.as()` method */
|
|
1310
|
+
interface Expr extends Sql {
|
|
1311
|
+
as(alias: string): Sql;
|
|
1312
|
+
}
|
|
1313
|
+
/** COUNT(*) or COUNT(column) */
|
|
1314
|
+
declare function count(col?: ColRef): Expr;
|
|
1315
|
+
/** COUNT(DISTINCT column) */
|
|
1316
|
+
declare function countDistinct(col: ColRef): Expr;
|
|
1317
|
+
/** SUM(column) */
|
|
1318
|
+
declare function sum(col: ColRef): Expr;
|
|
1319
|
+
/** AVG(column) */
|
|
1320
|
+
declare function avg(col: ColRef): Expr;
|
|
1321
|
+
/** MIN(column) */
|
|
1322
|
+
declare function min(col: ColRef): Expr;
|
|
1323
|
+
/** MAX(column) */
|
|
1324
|
+
declare function max(col: ColRef): Expr;
|
|
1325
|
+
/** Build SELECT clause with columns */
|
|
1326
|
+
declare function select(...cols: Array<ColRef | [ColRef, string]>): Sql;
|
|
1327
|
+
/** Alias a column or expression */
|
|
1328
|
+
declare function as(expression: Sql, alias: string): Sql;
|
|
1329
|
+
|
|
1330
|
+
/**
|
|
1331
|
+
* Validation Utilities
|
|
1332
|
+
*
|
|
1333
|
+
* Request validation and error handling for API endpoints.
|
|
1334
|
+
*
|
|
1335
|
+
* @module query-layer/validation
|
|
1336
|
+
*/
|
|
1337
|
+
|
|
1338
|
+
/** Frontend-friendly validation error structure */
|
|
1339
|
+
interface ValidationError {
|
|
1340
|
+
path: string;
|
|
1341
|
+
message: string;
|
|
1342
|
+
expected: string;
|
|
1343
|
+
received: string;
|
|
1344
|
+
}
|
|
1345
|
+
/** Error thrown when validation fails */
|
|
1346
|
+
declare class BadRequestError extends Error {
|
|
1347
|
+
readonly errors: ValidationError[];
|
|
1348
|
+
constructor(typiaErrors: IValidation.IError[]);
|
|
1349
|
+
toJSON(): {
|
|
1350
|
+
error: string;
|
|
1351
|
+
details: ValidationError[];
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
/** Assert validation result, throw BadRequestError if invalid */
|
|
1355
|
+
declare function assertValid<T>(result: IValidation<T>): T;
|
|
1356
|
+
/**
|
|
1357
|
+
* Query handler with three entry points for queries.
|
|
1358
|
+
* Use this when writing raw SQL without a query model.
|
|
1359
|
+
*/
|
|
1360
|
+
interface QueryHandler<P, R> {
|
|
1361
|
+
run: (params: P) => Promise<R>;
|
|
1362
|
+
fromObject: (input: unknown) => Promise<R>;
|
|
1363
|
+
fromUrl: (url: string | URL) => Promise<R>;
|
|
1364
|
+
}
|
|
1365
|
+
/**
|
|
1366
|
+
* Create a simple query handler with validation.
|
|
1367
|
+
*
|
|
1368
|
+
* @example
|
|
1369
|
+
* const handler = createQueryHandler({
|
|
1370
|
+
* fromUrl: typia.http.createValidateQuery<MyParams>(),
|
|
1371
|
+
* fromObject: typia.createValidate<MyParams>(),
|
|
1372
|
+
* queryFn: async (params) => {
|
|
1373
|
+
* const query = sql`SELECT * FROM ${Table} ${where(...)}`;
|
|
1374
|
+
* return executeQuery(query);
|
|
1375
|
+
* },
|
|
1376
|
+
* });
|
|
1377
|
+
*/
|
|
1378
|
+
declare function createQueryHandler<P, R>(config: {
|
|
1379
|
+
fromUrl: (input: string | URLSearchParams) => IValidation<P>;
|
|
1380
|
+
fromObject: (input: unknown) => IValidation<P>;
|
|
1381
|
+
queryFn: (params: P) => Promise<R>;
|
|
1382
|
+
}): QueryHandler<P, R>;
|
|
1383
|
+
|
|
630
1384
|
type DataModelConfig<T> = Partial<{
|
|
631
1385
|
ingestion: true;
|
|
632
1386
|
storage: {
|
|
@@ -638,7 +1392,7 @@ type DataModelConfig<T> = Partial<{
|
|
|
638
1392
|
parallelism?: number;
|
|
639
1393
|
}>;
|
|
640
1394
|
|
|
641
|
-
export { ACKs, type CSVParsingConfig, CSV_DELIMITERS, type CliLogData, DEFAULT_CSV_CONFIG, DEFAULT_JSON_CONFIG, type DataModelConfig, DataSource, type DataSourceConfig, type ExpressRequestWithMoose, type ExtractionResult, type JSONParsingConfig, type KafkaClientConfig, type Logger, MAX_RETRIES, MAX_RETRIES_PRODUCER, MAX_RETRY_TIME_MS, MOOSE_RUNTIME_ENV_PREFIX, MooseCache, MooseClient, MooseUtils, type Producer, RETRY_FACTOR_PRODUCER, RETRY_INITIAL_TIME_MS, type StripDateIntersection, type TaskConfig, type TaskDefinition, type TaskFunction, antiCachePath, cliLog, compilerLog, createProducerConfig, expressMiddleware, getClickhouseClient, getFileName, getKafkaClient, getKafkaProducer, getLegacyMooseUtils, getMooseClients, getMooseUtils, getMooseUtilsFromRequest, isValidCSVDelimiter, logError, mapTstoJs, mooseEnvSecrets, mooseRuntimeEnv, parseCSV, parseJSON, parseJSONWithDates, rewriteImportExtensions };
|
|
1395
|
+
export { ACKs, BadRequestError, type CSVParsingConfig, CSV_DELIMITERS, type CliLogData, type ColRef, Column, type ColumnDef, DEFAULT_CSV_CONFIG, DEFAULT_JSON_CONFIG, type DataModelConfig, DataSource, type DataSourceConfig, type DimensionDef, type Expr, type ExpressRequestWithMoose, type ExtractionResult, type FilterDefBase, type FilterInputTypeHint, type FilterOperator, type FilterParams, type GetMooseUtilsOptions, type JSONParsingConfig, type JoinDef, type KafkaClientConfig, type Logger, MAX_RETRIES, MAX_RETRIES_PRODUCER, MAX_RETRY_TIME_MS, MOOSE_RUNTIME_ENV_PREFIX, MaterializedView, type MetricDef, type ModelFilterDef, type ModelToolOptions, type ModelToolResult, MooseCache, MooseClient, MooseUtils, type Names, OlapTable, type OperatorValueType, type Producer, type QueryBuilder, QueryClient, type QueryHandler, type QueryModel, type QueryModelBase, type QueryModelConfig, type QueryModelFilter, type QueryParts, type QueryRequest, RETRY_FACTOR_PRODUCER, RETRY_INITIAL_TIME_MS, type SortDir, Sql, type SqlValue, type StripDateIntersection, type TaskConfig, type TaskDefinition, type TaskFunction, type ValidationError, and, antiCachePath, as, assertValid, avg, between, buildQuery, cliLog, columnsFromTable, compilerLog, count, countDistinct, createModelTool, createProducerConfig, createQueryHandler, defineQueryModel, deriveInputTypeFromDataType, empty, eq, expressMiddleware, filter, filtersFromTable, getClickhouseClient, getFileName, getKafkaClient, getKafkaProducer, getLegacyMooseUtils, getMooseClients, getMooseUtils, getMooseUtilsFromRequest, groupBy, gt, gte, having, ilike, inList, isEmpty, isNotNull, isNull, isValidCSVDelimiter, join, like, limit, logError, lt, lte, mapTstoJs, max, min, mooseEnvSecrets, mooseRuntimeEnv, ne, not, notIn, offset, or, orderBy, paginate, parseCSV, parseJSON, parseJSONWithDates, raw, registerModelTools, rewriteImportExtensions, select, sum, timeDimensions, where };
|
|
642
1396
|
|
|
643
1397
|
// ── @bayoudhi/moose-lib-serverless additions ──────────────────────────────
|
|
644
1398
|
|