@hypequery/clickhouse 0.2.1 → 0.2.2-beta.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 (69) hide show
  1. package/README-CLI.md +1 -1
  2. package/dist/cli/bin.js +129 -37
  3. package/dist/cli/generate-types.js +104 -15
  4. package/dist/core/connection.d.ts +112 -0
  5. package/dist/core/connection.d.ts.map +1 -1
  6. package/dist/core/connection.js +148 -25
  7. package/dist/core/cross-filter.d.ts +69 -0
  8. package/dist/core/cross-filter.d.ts.map +1 -1
  9. package/dist/core/cross-filter.js +1 -83
  10. package/dist/core/features/aggregations.d.ts +102 -0
  11. package/dist/core/features/analytics.d.ts +66 -0
  12. package/dist/core/features/analytics.d.ts.map +1 -1
  13. package/dist/core/features/cross-filtering.d.ts +31 -0
  14. package/dist/core/features/cross-filtering.d.ts.map +1 -0
  15. package/dist/core/features/cross-filtering.js +123 -0
  16. package/dist/core/features/executor.d.ts +19 -0
  17. package/dist/core/features/executor.js +3 -3
  18. package/dist/core/features/filtering.d.ts +95 -0
  19. package/dist/core/features/filtering.d.ts.map +1 -1
  20. package/dist/core/features/filtering.js +89 -3
  21. package/dist/core/features/joins.d.ts +29 -0
  22. package/dist/core/features/pagination.d.ts +23 -0
  23. package/dist/core/features/query-modifiers.d.ts +119 -0
  24. package/dist/core/formatters/sql-formatter.d.ts +9 -0
  25. package/dist/core/formatters/sql-formatter.d.ts.map +1 -1
  26. package/dist/core/formatters/sql-formatter.js +61 -5
  27. package/dist/core/join-relationships.d.ts +50 -0
  28. package/dist/core/join-relationships.d.ts.map +1 -1
  29. package/dist/core/query-builder.d.ts +258 -0
  30. package/dist/core/query-builder.d.ts.map +1 -1
  31. package/dist/core/query-builder.js +88 -27
  32. package/dist/core/tests/index.d.ts +2 -0
  33. package/dist/core/tests/integration/pagination-test-tbc.d.ts +2 -0
  34. package/dist/core/tests/integration/pagination-test-tbc.d.ts.map +1 -0
  35. package/dist/core/tests/integration/pagination-test-tbc.js +189 -0
  36. package/dist/core/tests/integration/setup.d.ts +40 -0
  37. package/dist/core/tests/integration/setup.d.ts.map +1 -1
  38. package/dist/core/tests/integration/setup.js +279 -238
  39. package/dist/core/tests/integration/test-config.d.ts +15 -0
  40. package/dist/core/tests/integration/test-config.d.ts.map +1 -0
  41. package/dist/core/tests/integration/test-config.js +15 -0
  42. package/dist/core/tests/integration/test-initializer.d.ts +7 -0
  43. package/dist/core/tests/integration/test-initializer.d.ts.map +1 -0
  44. package/dist/core/tests/integration/test-initializer.js +32 -0
  45. package/dist/core/tests/test-utils.d.ts +29 -0
  46. package/dist/core/tests/test-utils.d.ts.map +1 -1
  47. package/dist/core/tests/test-utils.js +6 -2
  48. package/dist/core/utils/logger.d.ts +37 -0
  49. package/dist/core/utils/logger.js +6 -6
  50. package/dist/core/utils/sql-expressions.d.ts +63 -0
  51. package/dist/core/utils/sql-expressions.d.ts.map +1 -1
  52. package/dist/core/utils/sql-expressions.js +9 -5
  53. package/dist/core/utils.d.ts +3 -0
  54. package/dist/core/validators/filter-validator.d.ts +8 -0
  55. package/dist/core/validators/filter-validator.js +1 -1
  56. package/dist/core/validators/value-validator.d.ts +6 -0
  57. package/dist/formatters/index.d.ts +1 -0
  58. package/dist/index.d.ts +12 -27
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +14 -2
  61. package/dist/types/base.d.ts +77 -0
  62. package/dist/types/base.d.ts.map +1 -1
  63. package/dist/types/clickhouse-types.d.ts +13 -0
  64. package/dist/types/clickhouse-types.d.ts.map +1 -1
  65. package/dist/types/filters.d.ts +53 -0
  66. package/dist/types/filters.d.ts.map +1 -1
  67. package/dist/types/index.d.ts +3 -0
  68. package/package.json +36 -13
  69. package/README.md +0 -276
@@ -1,34 +1,157 @@
1
- import { createClient } from '@clickhouse/client-web';
1
+ import { isClientConfig } from './query-builder.js';
2
+ // Function to synchronously get the appropriate client
3
+ function getClickHouseClientSync() {
4
+ const isDev = process.env.NODE_ENV === 'development';
5
+ const isNode = typeof process !== 'undefined' && process.versions && process.versions.node;
6
+ // In Node.js environment, use Node.js client only
7
+ if (isNode) {
8
+ try {
9
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
10
+ const clientNode = require('@clickhouse/client');
11
+ if (isDev) {
12
+ console.log('hypequery: Using @clickhouse/client for Node.js environment');
13
+ }
14
+ return {
15
+ createClient: clientNode.createClient,
16
+ ClickHouseSettings: clientNode.ClickHouseSettings || {}
17
+ };
18
+ }
19
+ catch (error) {
20
+ throw new Error('@clickhouse/client is required for Node.js environments.\n\n' +
21
+ 'Install with: npm install @clickhouse/client\n\n' +
22
+ 'Alternatively, you can provide a client instance directly in the config.client option.');
23
+ }
24
+ }
25
+ // For browser environments, require() doesn't work, so we can't auto-detect
26
+ // Users must use manual injection in browser environments
27
+ throw new Error('Unable to auto-detect ClickHouse client in browser environment. ' +
28
+ 'Please use manual injection by providing a client instance:\n\n' +
29
+ '```typescript\n' +
30
+ 'import { createClient } from \'@clickhouse/client-web\';\n' +
31
+ 'const client = createClient({ host: \'http://localhost:8123\' });\n' +
32
+ 'ClickHouseConnection.initialize({ host: \'http://localhost:8123\', client });\n' +
33
+ '```\n\n' +
34
+ 'This is required because browser environments cannot use require() to load modules.');
35
+ }
36
+ /**
37
+ * The main entry point for connecting to a ClickHouse database.
38
+ * Provides static methods to initialize the connection and retrieve the client.
39
+ *
40
+ * Supports two modes of operation:
41
+ * 1. **Manual injection**: Provide a client instance via `config.client` (required for browser environments)
42
+ * 2. **Auto-detection**: Automatically uses @clickhouse/client for Node.js environments
43
+ *
44
+ * @category Core
45
+ * @example
46
+ * ```typescript
47
+ * // Method 1: Manual injection (required for browser environments)
48
+ * import { createClient } from '@clickhouse/client-web';
49
+ * const client = createClient({
50
+ * host: 'http://localhost:8123',
51
+ * username: 'default',
52
+ * password: 'password'
53
+ * });
54
+ *
55
+ * ClickHouseConnection.initialize({
56
+ * host: 'http://localhost:8123',
57
+ * database: 'my_database',
58
+ * client // Explicitly provide the client
59
+ * });
60
+ *
61
+ * // Method 2: Auto-detection (Node.js environments only)
62
+ * ClickHouseConnection.initialize({
63
+ * host: 'http://localhost:8123',
64
+ * username: 'default',
65
+ * password: 'password',
66
+ * database: 'my_database'
67
+ * });
68
+ *
69
+ * // Get the client to execute queries directly
70
+ * const client = ClickHouseConnection.getClient();
71
+ * const result = await client.query({
72
+ * query: 'SELECT * FROM my_table',
73
+ * format: 'JSONEachRow'
74
+ * });
75
+ * ```
76
+ *
77
+ * @note This library requires one of the following peer dependencies:
78
+ * - @clickhouse/client (for Node.js environments)
79
+ * - @clickhouse/client-web (for browser environments)
80
+ *
81
+ * **Important**: Browser environments require manual injection because `require()` calls don't work in browsers.
82
+ */
2
83
  export class ClickHouseConnection {
84
+ /**
85
+ * Initializes the ClickHouse connection with the provided configuration.
86
+ * This method must be called before any queries can be executed.
87
+ *
88
+ * **Priority order:**
89
+ * 1. If `config.client` is provided, use it directly (manual injection)
90
+ * 2. Otherwise, auto-detect @clickhouse/client for Node.js environments
91
+ *
92
+ * **Note**: Browser environments require manual injection because `require()` calls don't work in browsers.
93
+ *
94
+ * @param config - The connection configuration options
95
+ * @returns The ClickHouseConnection class for method chaining
96
+ * @throws Will throw an error if no ClickHouse client is available
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * // Manual injection (required for browser environments)
101
+ * import { createClient } from '@clickhouse/client-web';
102
+ * const client = createClient({ host: 'http://localhost:8123' });
103
+ * ClickHouseConnection.initialize({ host: 'http://localhost:8123', client });
104
+ *
105
+ * // Auto-detection (Node.js environments only)
106
+ * ClickHouseConnection.initialize({
107
+ * host: 'http://localhost:8123',
108
+ * username: 'default',
109
+ * password: 'password',
110
+ * database: 'my_database'
111
+ * });
112
+ * ```
113
+ */
3
114
  static initialize(config) {
4
- // Create a client config object with only the standard options
5
- const clientConfig = {
6
- host: config.host,
7
- username: config.username,
8
- password: config.password,
9
- database: config.database,
10
- };
11
- // Add the extended options if provided
12
- if (config.http_headers)
13
- clientConfig.http_headers = config.http_headers;
14
- if (config.request_timeout)
15
- clientConfig.request_timeout = config.request_timeout;
16
- if (config.compression)
17
- clientConfig.compression = config.compression;
18
- if (config.application)
19
- clientConfig.application = config.application;
20
- if (config.keep_alive)
21
- clientConfig.keep_alive = config.keep_alive;
22
- if (config.log)
23
- clientConfig.log = config.log;
24
- if (config.clickhouse_settings)
25
- clientConfig.clickhouse_settings = config.clickhouse_settings;
26
- this.instance = createClient(clientConfig);
115
+ // If a client is explicitly provided, use it directly
116
+ if (isClientConfig(config)) {
117
+ this.instance = config.client;
118
+ return ClickHouseConnection;
119
+ }
120
+ // Otherwise, auto-detect the client (we know we have a host-based config)
121
+ this.clientModule = getClickHouseClientSync();
122
+ this.instance = this.clientModule.createClient(config);
123
+ return ClickHouseConnection;
27
124
  }
125
+ /**
126
+ * Retrieves the ClickHouse client instance for direct query execution.
127
+ *
128
+ * @returns The ClickHouse client instance
129
+ * @throws Will throw an error if the connection has not been initialized
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * const client = ClickHouseConnection.getClient();
134
+ * const result = await client.query({
135
+ * query: 'SELECT * FROM my_table',
136
+ * format: 'JSONEachRow'
137
+ * });
138
+ * ```
139
+ */
28
140
  static getClient() {
29
141
  if (!this.instance) {
30
- throw new Error('ClickHouse connection not initialized');
142
+ throw new Error('ClickHouse connection not initialized. Call ClickHouseConnection.initialize() first.');
31
143
  }
32
144
  return this.instance;
33
145
  }
146
+ /**
147
+ * Gets the ClickHouseSettings type from the loaded client module.
148
+ * Only available when using auto-detection (not manual injection).
149
+ *
150
+ * @returns The ClickHouseSettings type or an empty object if not available
151
+ */
152
+ static getClickHouseSettings() {
153
+ return this.clientModule?.ClickHouseSettings || {};
154
+ }
34
155
  }
156
+ ClickHouseConnection.instance = null;
157
+ ClickHouseConnection.clientModule = null;
@@ -0,0 +1,69 @@
1
+ import { ColumnType, FilterOperator, InferColumnType, OperatorValueMap, FilterConditionInput } from '../types';
2
+ export interface FilterGroup<Schema extends Record<string, Record<string, any>> = any, OriginalT extends Record<string, any> = any> {
3
+ operator: 'AND' | 'OR';
4
+ conditions: Array<FilterConditionInput<any, Schema, OriginalT> | FilterGroup<Schema, OriginalT>>;
5
+ limit?: number;
6
+ orderBy?: {
7
+ column: keyof OriginalT;
8
+ direction: 'ASC' | 'DESC';
9
+ };
10
+ }
11
+ /**
12
+ * A type-safe filter builder supporting both simple conditions and complex nested groups.
13
+ * @template Schema - The full database schema type
14
+ * @template TableName - The specific table being filtered
15
+ */
16
+ export declare class CrossFilter<Schema extends {
17
+ [tableName: string]: {
18
+ [columnName: string]: ColumnType;
19
+ };
20
+ } = any, TableName extends keyof Schema = Extract<keyof Schema, string>> {
21
+ private schema?;
22
+ private rootGroup;
23
+ constructor(schema?: Schema | undefined);
24
+ /**
25
+ * Adds a single filter condition to the root group with an implicit AND conjunction.
26
+ * Performs type-safe validation if a schema is provided.
27
+ */
28
+ add<ColumnName extends Extract<keyof Schema[TableName], string>, Op extends FilterOperator>(condition: FilterConditionInput<OperatorValueMap<InferColumnType<Schema[TableName][ColumnName]>>[Op], Schema, Schema[TableName]>): this;
29
+ /**
30
+ * Adds multiple filter conditions to the root group.
31
+ */
32
+ addMultiple(conditions: Array<FilterConditionInput<any, Schema, Schema[TableName]>>): this;
33
+ /**
34
+ * Adds a nested group of filter conditions to the root group using the specified logical operator.
35
+ * @param groupConditions - Array of filter conditions or nested groups to be grouped together.
36
+ * @param operator - Logical operator ('AND' or 'OR') to combine the conditions in the group.
37
+ */
38
+ addGroup(groupConditions: Array<FilterConditionInput<any, Schema, Schema[TableName]> | FilterGroup<Schema, Schema[TableName]>>, operator: 'AND' | 'OR'): this;
39
+ /**
40
+ * Returns the current filter tree representing all conditions and groups.
41
+ */
42
+ getConditions(): FilterGroup<Schema, Schema[TableName]>;
43
+ /**
44
+ * Looks up a column's type from the schema.
45
+ * Defaults to 'String' if no schema is provided.
46
+ * @param column - The column name as a string.
47
+ */
48
+ private getColumnType;
49
+ /**
50
+ * Validates the value of a filter condition against its expected column type.
51
+ */
52
+ private validateValueType;
53
+ /**
54
+ * Recursively validates an array of filter conditions and nested groups.
55
+ */
56
+ private validateGroup;
57
+ /**
58
+ * Type guard to check if an item is a FilterGroup.
59
+ */
60
+ private isGroup;
61
+ /**
62
+ * Creates a filter for top N records by a value column
63
+ * @param valueColumn - The column to filter and order by
64
+ * @param n - Number of records to return
65
+ * @param orderBy - Sort direction, defaults to 'desc'
66
+ */
67
+ topN<K extends keyof Schema[TableName]>(valueColumn: K, n: number, orderBy?: 'desc' | 'asc'): this;
68
+ }
69
+ //# sourceMappingURL=cross-filter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cross-filter.d.ts","sourceRoot":"","sources":["../../src/core/cross-filter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cross-filter.d.ts","sourceRoot":"","sources":["../../src/core/cross-filter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,UAAU,CAAC;AAIlB,MAAM,WAAW,WAAW,CAC1B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,GAAG,EACxD,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG;IAE3C,QAAQ,EAAE,KAAK,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,KAAK,CACf,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAC9E,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE;QACR,MAAM,EAAE,MAAM,SAAS,CAAC;QACxB,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;KAC3B,CAAC;CACH;AAED;;;;GAIG;AACH,qBAAa,WAAW,CACtB,MAAM,SAAS;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;CAAE,GAAG,GAAG,EAClF,SAAS,SAAS,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC;IAMlD,OAAO,CAAC,MAAM,CAAC;IAH3B,OAAO,CAAC,SAAS,CAAyC;gBAGtC,MAAM,CAAC,EAAE,MAAM,YAAA;IAInC;;;OAGG;IACH,GAAG,CACD,UAAU,SAAS,OAAO,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,EAC3D,EAAE,SAAS,cAAc,EAEzB,SAAS,EAAE,oBAAoB,CAC7B,gBAAgB,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EACpE,MAAM,EACN,MAAM,CAAC,SAAS,CAAC,CAClB,GACA,IAAI;IA0BP;;OAEG;IACH,WAAW,CACT,UAAU,EAAE,KAAK,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,GACtE,IAAI;IAQP;;;;OAIG;IACH,QAAQ,CACN,eAAe,EAAE,KAAK,CACpB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAC9F,EACD,QAAQ,EAAE,KAAK,GAAG,IAAI,GACrB,IAAI;IAYP;;OAEG;IACH,aAAa,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAIvD;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAarB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAazB;;OAEG;IACH,OAAO,CAAC,aAAa;IAqBrB;;OAEG;IACH,OAAO,CAAC,OAAO;IAMf;;;;;OAKG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,CAAC,SAAS,CAAC,EACpC,WAAW,EAAE,CAAC,EACd,CAAC,EAAE,MAAM,EACT,OAAO,GAAE,MAAM,GAAG,KAAc,GAC/B,IAAI;CAmBR"}
@@ -1,14 +1,4 @@
1
- import { FilterValidator } from './validators/filter-validator';
2
- export const DateRange = {
3
- TODAY: 'today',
4
- YESTERDAY: 'yesterday',
5
- LAST_7_DAYS: 'last_7_days',
6
- LAST_30_DAYS: 'last_30_days',
7
- THIS_MONTH: 'this_month',
8
- LAST_MONTH: 'last_month',
9
- THIS_QUARTER: 'this_quarter',
10
- YEAR_TO_DATE: 'year_to_date'
11
- };
1
+ import { FilterValidator } from './validators/filter-validator.js';
12
2
  /**
13
3
  * A type-safe filter builder supporting both simple conditions and complex nested groups.
14
4
  * @template Schema - The full database schema type
@@ -120,78 +110,6 @@ export class CrossFilter {
120
110
  isGroup(item) {
121
111
  return typeof item.conditions !== 'undefined';
122
112
  }
123
- addDateCondition(column, value) {
124
- this.rootGroup.conditions.push({
125
- column,
126
- operator: 'between',
127
- value: [value[0].toISOString(), value[1].toISOString()]
128
- });
129
- return this;
130
- }
131
- addDateRange(column, range) {
132
- const now = new Date();
133
- let start;
134
- let end;
135
- switch (range) {
136
- case 'today':
137
- start = new Date(now.setHours(0, 0, 0, 0));
138
- end = new Date(now.setHours(23, 59, 59, 999));
139
- break;
140
- case 'yesterday':
141
- start = new Date(now.setDate(now.getDate() - 1));
142
- start.setHours(0, 0, 0, 0);
143
- end = new Date(start);
144
- end.setHours(23, 59, 59, 999);
145
- break;
146
- case 'last_7_days':
147
- end = new Date(now);
148
- start = new Date(now.setDate(now.getDate() - 7));
149
- break;
150
- case 'last_30_days':
151
- end = new Date(now);
152
- start = new Date(now.setDate(now.getDate() - 30));
153
- break;
154
- case 'this_month':
155
- start = new Date(now.getFullYear(), now.getMonth(), 1);
156
- end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
157
- break;
158
- case 'last_month':
159
- start = new Date(now.getFullYear(), now.getMonth() - 1, 1);
160
- end = new Date(now.getFullYear(), now.getMonth(), 0);
161
- break;
162
- case 'this_quarter':
163
- const quarter = Math.floor(now.getMonth() / 3);
164
- start = new Date(now.getFullYear(), quarter * 3, 1);
165
- end = new Date(now.getFullYear(), (quarter + 1) * 3, 0);
166
- break;
167
- case 'year_to_date':
168
- start = new Date(now.getFullYear(), 0, 1);
169
- end = new Date(now);
170
- break;
171
- default:
172
- throw new Error(`Unsupported date range: ${range}`);
173
- }
174
- return this.addDateCondition(column, [start, end]);
175
- }
176
- lastNDays(column, days) {
177
- const end = new Date();
178
- const start = new Date();
179
- start.setDate(start.getDate() - days);
180
- return this.addDateCondition(column, [start, end]);
181
- }
182
- addComparisonPeriod(column, currentRange) {
183
- const periodLength = currentRange[1].getTime() - currentRange[0].getTime();
184
- const previousStart = new Date(currentRange[0].getTime() - periodLength);
185
- const previousEnd = new Date(currentRange[1].getTime() - periodLength);
186
- return this.addDateCondition(column, [previousStart, previousEnd]);
187
- }
188
- addYearOverYear(column, currentRange) {
189
- const previousStart = new Date(currentRange[0]);
190
- previousStart.setFullYear(previousStart.getFullYear() - 1);
191
- const previousEnd = new Date(currentRange[1]);
192
- previousEnd.setFullYear(previousEnd.getFullYear() - 1);
193
- return this.addDateCondition(column, [previousStart, previousEnd]);
194
- }
195
113
  /**
196
114
  * Creates a filter for top N records by a value column
197
115
  * @param valueColumn - The column to filter and order by
@@ -0,0 +1,102 @@
1
+ import { QueryBuilder } from '../query-builder';
2
+ import { ColumnType } from '../../types';
3
+ export declare class AggregationFeature<Schema extends {
4
+ [tableName: string]: {
5
+ [columnName: string]: ColumnType;
6
+ };
7
+ }, T, HasSelect extends boolean = false, Aggregations = {}, OriginalT = T> {
8
+ private builder;
9
+ constructor(builder: QueryBuilder<Schema, T, HasSelect, Aggregations, OriginalT>);
10
+ private createAggregation;
11
+ sum<Column extends keyof OriginalT, Alias extends string = `${Column & string}_sum`>(column: Column, alias?: Alias): {
12
+ select: string[];
13
+ where?: import("../../types").WhereCondition[];
14
+ groupBy?: string[];
15
+ having?: string[];
16
+ limit?: number;
17
+ offset?: number;
18
+ distinct?: boolean;
19
+ orderBy?: {
20
+ column: keyof T | import("../../types").TableColumn<Schema>;
21
+ direction: import("../../types").OrderDirection;
22
+ }[] | undefined;
23
+ joins?: import("../../types").JoinClause[];
24
+ parameters?: any[];
25
+ ctes?: string[];
26
+ unionQueries?: string[];
27
+ settings?: string;
28
+ };
29
+ count<Column extends keyof OriginalT, Alias extends string = `${Column & string}_count`>(column: Column, alias?: Alias): {
30
+ select: string[];
31
+ where?: import("../../types").WhereCondition[];
32
+ groupBy?: string[];
33
+ having?: string[];
34
+ limit?: number;
35
+ offset?: number;
36
+ distinct?: boolean;
37
+ orderBy?: {
38
+ column: keyof T | import("../../types").TableColumn<Schema>;
39
+ direction: import("../../types").OrderDirection;
40
+ }[] | undefined;
41
+ joins?: import("../../types").JoinClause[];
42
+ parameters?: any[];
43
+ ctes?: string[];
44
+ unionQueries?: string[];
45
+ settings?: string;
46
+ };
47
+ avg<Column extends keyof OriginalT, Alias extends string = `${Column & string}_avg`>(column: Column, alias?: Alias): {
48
+ select: string[];
49
+ where?: import("../../types").WhereCondition[];
50
+ groupBy?: string[];
51
+ having?: string[];
52
+ limit?: number;
53
+ offset?: number;
54
+ distinct?: boolean;
55
+ orderBy?: {
56
+ column: keyof T | import("../../types").TableColumn<Schema>;
57
+ direction: import("../../types").OrderDirection;
58
+ }[] | undefined;
59
+ joins?: import("../../types").JoinClause[];
60
+ parameters?: any[];
61
+ ctes?: string[];
62
+ unionQueries?: string[];
63
+ settings?: string;
64
+ };
65
+ min<Column extends keyof OriginalT, Alias extends string = `${Column & string}_min`>(column: Column, alias?: Alias): {
66
+ select: string[];
67
+ where?: import("../../types").WhereCondition[];
68
+ groupBy?: string[];
69
+ having?: string[];
70
+ limit?: number;
71
+ offset?: number;
72
+ distinct?: boolean;
73
+ orderBy?: {
74
+ column: keyof T | import("../../types").TableColumn<Schema>;
75
+ direction: import("../../types").OrderDirection;
76
+ }[] | undefined;
77
+ joins?: import("../../types").JoinClause[];
78
+ parameters?: any[];
79
+ ctes?: string[];
80
+ unionQueries?: string[];
81
+ settings?: string;
82
+ };
83
+ max<Column extends keyof OriginalT, Alias extends string = `${Column & string}_max`>(column: Column, alias?: Alias): {
84
+ select: string[];
85
+ where?: import("../../types").WhereCondition[];
86
+ groupBy?: string[];
87
+ having?: string[];
88
+ limit?: number;
89
+ offset?: number;
90
+ distinct?: boolean;
91
+ orderBy?: {
92
+ column: keyof T | import("../../types").TableColumn<Schema>;
93
+ direction: import("../../types").OrderDirection;
94
+ }[] | undefined;
95
+ joins?: import("../../types").JoinClause[];
96
+ parameters?: any[];
97
+ ctes?: string[];
98
+ unionQueries?: string[];
99
+ settings?: string;
100
+ };
101
+ }
102
+ //# sourceMappingURL=aggregations.d.ts.map
@@ -0,0 +1,66 @@
1
+ import { QueryBuilder } from '../query-builder';
2
+ import { ColumnType, TableColumn } from '../../types';
3
+ import { ClickHouseSettings } from '@clickhouse/client-common';
4
+ export declare class AnalyticsFeature<Schema extends {
5
+ [tableName: string]: {
6
+ [columnName: string]: ColumnType;
7
+ };
8
+ }, T, HasSelect extends boolean = false, Aggregations = {}, OriginalT = T> {
9
+ private builder;
10
+ constructor(builder: QueryBuilder<Schema, T, HasSelect, Aggregations, OriginalT>);
11
+ addCTE(alias: string, subquery: QueryBuilder<any, any> | string): {
12
+ ctes: string[];
13
+ select?: (string | keyof T)[] | undefined;
14
+ where?: import("../../types").WhereCondition[];
15
+ groupBy?: string[];
16
+ having?: string[];
17
+ limit?: number;
18
+ offset?: number;
19
+ distinct?: boolean;
20
+ orderBy?: {
21
+ column: keyof T | TableColumn<Schema>;
22
+ direction: import("../../types").OrderDirection;
23
+ }[] | undefined;
24
+ joins?: import("../../types").JoinClause[];
25
+ parameters?: any[];
26
+ unionQueries?: string[];
27
+ settings?: string;
28
+ };
29
+ addTimeInterval(column: keyof T | TableColumn<Schema>, interval: string, method: 'toStartOfInterval' | 'toStartOfMinute' | 'toStartOfHour' | 'toStartOfDay' | 'toStartOfWeek' | 'toStartOfMonth' | 'toStartOfQuarter' | 'toStartOfYear'): {
30
+ groupBy: string[];
31
+ select?: (string | keyof T)[] | undefined;
32
+ where?: import("../../types").WhereCondition[];
33
+ having?: string[];
34
+ limit?: number;
35
+ offset?: number;
36
+ distinct?: boolean;
37
+ orderBy?: {
38
+ column: keyof T | TableColumn<Schema>;
39
+ direction: import("../../types").OrderDirection;
40
+ }[] | undefined;
41
+ joins?: import("../../types").JoinClause[];
42
+ parameters?: any[];
43
+ ctes?: string[];
44
+ unionQueries?: string[];
45
+ settings?: string;
46
+ };
47
+ addSettings(opts: ClickHouseSettings): {
48
+ settings: string;
49
+ select?: (string | keyof T)[] | undefined;
50
+ where?: import("../../types").WhereCondition[];
51
+ groupBy?: string[];
52
+ having?: string[];
53
+ limit?: number;
54
+ offset?: number;
55
+ distinct?: boolean;
56
+ orderBy?: {
57
+ column: keyof T | TableColumn<Schema>;
58
+ direction: import("../../types").OrderDirection;
59
+ }[] | undefined;
60
+ joins?: import("../../types").JoinClause[];
61
+ parameters?: any[];
62
+ ctes?: string[];
63
+ unionQueries?: string[];
64
+ };
65
+ }
66
+ //# sourceMappingURL=analytics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../../src/core/features/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,qBAAa,gBAAgB,CAC3B,MAAM,SAAS;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;CAAE,EAC5E,CAAC,EACD,SAAS,SAAS,OAAO,GAAG,KAAK,EACjC,YAAY,GAAG,EAAE,EACjB,SAAS,GAAG,CAAC;IAED,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC;IAExF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM;;;;;;;;;;;;;;;;;;IAS/D,eAAe,CACb,MAAM,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,EACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAAG,iBAAiB,GAAG,eAAe,GAAG,cAAc,GAAG,eAAe,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,eAAe;;;;;;;;;;;;;;;;;;IAiBhK,WAAW,CAAC,IAAI,EAAE,kBAAkB;;;;;;;;;;;;;;;;;;CAQrC"}
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../../src/core/features/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAE9D,qBAAa,gBAAgB,CAC3B,MAAM,SAAS;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;CAAE,EAC5E,CAAC,EACD,SAAS,SAAS,OAAO,GAAG,KAAK,EACjC,YAAY,GAAG,EAAE,EACjB,SAAS,GAAG,CAAC;IAED,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC;IAExF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM;;;;;;;;;;;;;;;;;;IAS/D,eAAe,CACb,MAAM,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,EACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAAG,iBAAiB,GAAG,eAAe,GAAG,cAAc,GAAG,eAAe,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,eAAe;;;;;;;;;;;;;;;;;;IAiBhK,WAAW,CAAC,IAAI,EAAE,kBAAkB;;;;;;;;;;;;;;;;;;CAQrC"}
@@ -0,0 +1,31 @@
1
+ import { QueryBuilder } from '../query-builder';
2
+ import { CrossFilter } from '../cross-filter';
3
+ import { ColumnType } from '../../types';
4
+ /**
5
+ * Feature for handling cross-filter operations on queries
6
+ */
7
+ export declare class CrossFilteringFeature<Schema extends {
8
+ [tableName: string]: {
9
+ [columnName: string]: ColumnType;
10
+ };
11
+ }, T, HasSelect extends boolean = false, Aggregations = {}, OriginalT = T> {
12
+ private builder;
13
+ constructor(builder: QueryBuilder<Schema, T, HasSelect, Aggregations, OriginalT>);
14
+ /**
15
+ * Applies a set of cross filters to the query
16
+ * @param crossFilter - An instance of CrossFilter containing shared filter conditions
17
+ * @returns Updated query config
18
+ */
19
+ applyCrossFilters(crossFilter: CrossFilter<Schema, keyof Schema>): import("../../types").QueryConfig<T, Schema>;
20
+ /**
21
+ * Apply AND conditions - each condition is applied with WHERE
22
+ */
23
+ private applyAndConditions;
24
+ /**
25
+ * Apply direct OR conditions without adding extra conjunctions
26
+ * @param conditions The conditions to apply
27
+ * @param builder The builder to apply conditions to, defaults to this.builder
28
+ */
29
+ private applyOrConditions;
30
+ }
31
+ //# sourceMappingURL=cross-filtering.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-filtering.d.ts","sourceRoot":"","sources":["../../../src/core/features/cross-filtering.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAe,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAwB,UAAU,EAAe,MAAM,aAAa,CAAC;AAgB5E;;GAEG;AACH,qBAAa,qBAAqB,CAChC,MAAM,SAAS;IAAE,CAAC,SAAS,EAAE,MAAM,GAAG;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;CAAE,EAC5E,CAAC,EACD,SAAS,SAAS,OAAO,GAAG,KAAK,EACjC,YAAY,GAAG,EAAE,EACjB,SAAS,GAAG,CAAC;IAED,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC;IAExF;;;;OAIG;IACH,iBAAiB,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;IAsBhE;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA4B1B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;CAqD1B"}