drizzle-cube 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { Hono as D } from "hono";
2
2
  var S = (q) => {
3
- const d = {
3
+ const c = {
4
4
  ...{
5
5
  origin: "*",
6
6
  allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
@@ -8,22 +8,22 @@ var S = (q) => {
8
8
  exposeHeaders: []
9
9
  },
10
10
  ...q
11
- }, A = /* @__PURE__ */ ((u) => typeof u == "string" ? u === "*" ? () => u : (n) => u === n ? n : null : typeof u == "function" ? u : (n) => u.includes(n) ? n : null)(d.origin), j = ((u) => typeof u == "function" ? u : Array.isArray(u) ? () => u : () => [])(d.allowMethods);
11
+ }, v = /* @__PURE__ */ ((u) => typeof u == "string" ? u === "*" ? () => u : (n) => u === n ? n : null : typeof u == "function" ? u : (n) => u.includes(n) ? n : null)(c.origin), j = ((u) => typeof u == "function" ? u : Array.isArray(u) ? () => u : () => [])(c.allowMethods);
12
12
  return async function(n, m) {
13
13
  var x;
14
14
  function p(h, f) {
15
15
  n.res.headers.set(h, f);
16
16
  }
17
- const b = A(n.req.header("origin") || "", n);
18
- if (b && p("Access-Control-Allow-Origin", b), d.origin !== "*") {
17
+ const b = v(n.req.header("origin") || "", n);
18
+ if (b && p("Access-Control-Allow-Origin", b), c.origin !== "*") {
19
19
  const h = n.req.header("Vary");
20
20
  h ? p("Vary", h) : p("Vary", "Origin");
21
21
  }
22
- if (d.credentials && p("Access-Control-Allow-Credentials", "true"), (x = d.exposeHeaders) != null && x.length && p("Access-Control-Expose-Headers", d.exposeHeaders.join(",")), n.req.method === "OPTIONS") {
23
- d.maxAge != null && p("Access-Control-Max-Age", d.maxAge.toString());
22
+ if (c.credentials && p("Access-Control-Allow-Credentials", "true"), (x = c.exposeHeaders) != null && x.length && p("Access-Control-Expose-Headers", c.exposeHeaders.join(",")), n.req.method === "OPTIONS") {
23
+ c.maxAge != null && p("Access-Control-Max-Age", c.maxAge.toString());
24
24
  const h = j(n.req.header("origin") || "", n);
25
25
  h.length && p("Access-Control-Allow-Methods", h.join(","));
26
- let f = d.allowHeaders;
26
+ let f = c.allowHeaders;
27
27
  if (!(f != null && f.length)) {
28
28
  const e = n.req.header("Access-Control-Request-Headers");
29
29
  e && (f = e.split(/\s*,\s*/));
@@ -40,13 +40,13 @@ var S = (q) => {
40
40
  function E(q) {
41
41
  const {
42
42
  semanticLayer: a,
43
- drizzle: d,
44
- schema: A,
43
+ drizzle: c,
44
+ schema: v,
45
45
  getSecurityContext: j,
46
46
  cors: u,
47
47
  basePath: n = "/cubejs-api/v1"
48
48
  } = q, m = new D();
49
- u && m.use("/*", S(u)), a.hasExecutor() || a.setDrizzle(d, A), m.post(`${n}/load`, async (e) => {
49
+ u && m.use("/*", S(u)), a.hasExecutor() || a.setDrizzle(c, v), m.post(`${n}/load`, async (e) => {
50
50
  try {
51
51
  const r = await e.req.json(), s = r.query || r, t = await j(e), o = a.validateQuery(s);
52
52
  if (!o.isValid)
@@ -88,7 +88,15 @@ function E(q) {
88
88
  return e.json({
89
89
  error: "Query parameter is required"
90
90
  }, 400);
91
- const s = JSON.parse(r), t = await j(e), o = a.validateQuery(s);
91
+ let s;
92
+ try {
93
+ s = JSON.parse(r);
94
+ } catch {
95
+ return e.json({
96
+ error: "Invalid JSON in query parameter"
97
+ }, 400);
98
+ }
99
+ const t = await j(e), o = a.validateQuery(s);
92
100
  if (!o.isValid)
93
101
  return e.json({
94
102
  error: `Query validation failed: ${o.errors.join(", ")}`
@@ -229,23 +237,23 @@ function E(q) {
229
237
  return "postgres";
230
238
  }
231
239
  async function f(e, r) {
232
- var y, g, Q, v;
240
+ var y, g, Q, A;
233
241
  const s = a.validateQuery(e);
234
242
  if (!s.isValid)
235
243
  throw new Error(`Query validation failed: ${s.errors.join(", ")}`);
236
244
  const t = /* @__PURE__ */ new Set();
237
- (y = e.measures) == null || y.forEach((c) => {
238
- const w = c.split(".")[0];
245
+ (y = e.measures) == null || y.forEach((d) => {
246
+ const w = d.split(".")[0];
239
247
  t.add(w);
240
- }), (g = e.dimensions) == null || g.forEach((c) => {
241
- const w = c.split(".")[0];
248
+ }), (g = e.dimensions) == null || g.forEach((d) => {
249
+ const w = d.split(".")[0];
242
250
  t.add(w);
243
- }), (Q = e.timeDimensions) == null || Q.forEach((c) => {
244
- const w = c.dimension.split(".")[0];
251
+ }), (Q = e.timeDimensions) == null || Q.forEach((d) => {
252
+ const w = d.dimension.split(".")[0];
245
253
  t.add(w);
246
- }), (v = e.filters) == null || v.forEach((c) => {
247
- if ("member" in c) {
248
- const w = c.member.split(".")[0];
254
+ }), (A = e.filters) == null || A.forEach((d) => {
255
+ if ("member" in d) {
256
+ const w = d.member.split(".")[0];
249
257
  t.add(w);
250
258
  }
251
259
  });
@@ -254,16 +262,16 @@ function E(q) {
254
262
  if (o)
255
263
  i = await a.generateMultiCubeSQL(e, r);
256
264
  else {
257
- const c = Array.from(t)[0];
258
- i = await a.generateSQL(c, e, r);
265
+ const d = Array.from(t)[0];
266
+ i = await a.generateSQL(d, e, r);
259
267
  }
260
- const l = Array.from(t).map((c) => {
268
+ const l = Array.from(t).map((d) => {
261
269
  var w, T;
262
270
  return {
263
- cube: c,
271
+ cube: d,
264
272
  query: {
265
- measures: ((w = e.measures) == null ? void 0 : w.filter((C) => C.startsWith(c + "."))) || [],
266
- dimensions: ((T = e.dimensions) == null ? void 0 : T.filter((C) => C.startsWith(c + "."))) || [],
273
+ measures: ((w = e.measures) == null ? void 0 : w.filter((C) => C.startsWith(d + "."))) || [],
274
+ dimensions: ((T = e.dimensions) == null ? void 0 : T.filter((C) => C.startsWith(d + "."))) || [],
267
275
  filters: e.filters || [],
268
276
  timeDimensions: e.timeDimensions || [],
269
277
  order: e.order || {},
@@ -321,15 +329,15 @@ function E(q) {
321
329
  }), m;
322
330
  }
323
331
  function M(q, a) {
324
- const d = E(a);
325
- return q.route("/", d), q;
332
+ const c = E(a);
333
+ return q.route("/", c), q;
326
334
  }
327
- function R(q) {
335
+ function N(q) {
328
336
  const a = new D();
329
337
  return M(a, q);
330
338
  }
331
339
  export {
332
- R as createCubeApp,
340
+ N as createCubeApp,
333
341
  E as createCubeRoutes,
334
342
  M as mountCubeRoutes
335
343
  };
@@ -3,7 +3,7 @@ export interface ModalProps {
3
3
  isOpen: boolean;
4
4
  onClose: () => void;
5
5
  title?: string;
6
- size?: 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'fullscreen';
6
+ size?: 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'fullscreen' | 'fullscreen-mobile';
7
7
  closeOnBackdropClick?: boolean;
8
8
  closeOnEscape?: boolean;
9
9
  showCloseButton?: boolean;
@@ -0,0 +1,4 @@
1
+ import { default as React } from 'react';
2
+ import { FilterBuilderProps } from './types';
3
+ declare const FilterBuilder: React.FC<FilterBuilderProps>;
4
+ export default FilterBuilder;
@@ -0,0 +1,4 @@
1
+ import { default as React } from 'react';
2
+ import { FilterGroupProps } from './types';
3
+ declare const FilterGroup: React.FC<FilterGroupProps>;
4
+ export default FilterGroup;
@@ -0,0 +1,4 @@
1
+ import { default as React } from 'react';
2
+ import { FilterItemProps } from './types';
3
+ declare const FilterItem: React.FC<FilterItemProps>;
4
+ export default FilterItem;
@@ -0,0 +1,4 @@
1
+ import { default as React } from 'react';
2
+ import { FilterValueSelectorProps } from './types';
3
+ declare const FilterValueSelector: React.FC<FilterValueSelectorProps>;
4
+ export default FilterValueSelector;
@@ -1,4 +1,4 @@
1
- import { CubeQuery } from '../../types';
1
+ import { CubeQuery, FilterOperator, Filter, SimpleFilter, GroupFilter } from '../../types';
2
2
  export interface MetaField {
3
3
  name: string;
4
4
  title: string;
@@ -89,6 +89,7 @@ export interface CubeMetaExplorerProps {
89
89
  }
90
90
  export interface QueryPanelProps {
91
91
  query: CubeQuery;
92
+ schema: MetaResponse | null;
92
93
  validationStatus: ValidationStatus;
93
94
  validationError: string | null;
94
95
  validationSql: {
@@ -99,6 +100,7 @@ export interface QueryPanelProps {
99
100
  onExecute: () => void;
100
101
  onRemoveField: (fieldName: string, fieldType: 'measures' | 'dimensions' | 'timeDimensions') => void;
101
102
  onTimeDimensionGranularityChange: (dimensionName: string, granularity: string) => void;
103
+ onFiltersChange: (filters: Filter[]) => void;
102
104
  onClearQuery?: () => void;
103
105
  showSettings?: boolean;
104
106
  onSettingsClick?: () => void;
@@ -130,3 +132,43 @@ export declare const TIME_GRANULARITIES: readonly [{
130
132
  readonly label: "Year";
131
133
  }];
132
134
  export type TimeGranularity = typeof TIME_GRANULARITIES[number]['value'];
135
+ export interface FilterOperatorMeta {
136
+ label: string;
137
+ description: string;
138
+ requiresValues: boolean;
139
+ supportsMultipleValues: boolean;
140
+ valueType: 'string' | 'number' | 'date' | 'boolean' | 'any';
141
+ fieldTypes: string[];
142
+ }
143
+ export declare const FILTER_OPERATORS: Record<FilterOperator, FilterOperatorMeta>;
144
+ export interface FilterBuilderProps {
145
+ filters: Filter[];
146
+ schema: MetaResponse | null;
147
+ query: CubeQuery;
148
+ onFiltersChange: (filters: Filter[]) => void;
149
+ }
150
+ export interface FilterItemProps {
151
+ filter: SimpleFilter;
152
+ index: number;
153
+ onFilterChange: (index: number, filter: SimpleFilter) => void;
154
+ onFilterRemove: (index: number) => void;
155
+ schema: MetaResponse | null;
156
+ query: CubeQuery;
157
+ }
158
+ export interface FilterGroupProps {
159
+ group: GroupFilter;
160
+ index: number;
161
+ onGroupChange: (index: number, group: GroupFilter) => void;
162
+ onGroupChangeWithUnwrap?: (index: number, group: GroupFilter) => void;
163
+ onGroupRemove: (index: number) => void;
164
+ schema: MetaResponse | null;
165
+ query: CubeQuery;
166
+ depth: number;
167
+ }
168
+ export interface FilterValueSelectorProps {
169
+ fieldName: string;
170
+ operator: FilterOperator;
171
+ values: any[];
172
+ onValuesChange: (values: any[]) => void;
173
+ schema: MetaResponse | null;
174
+ }
@@ -1,4 +1,4 @@
1
- import { CubeQuery } from '../../types';
1
+ import { CubeQuery, Filter, SimpleFilter, GroupFilter } from '../../types';
2
2
  import { MetaField, MetaResponse } from './types';
3
3
  /**
4
4
  * Check if a field is selected in the current query
@@ -36,7 +36,82 @@ export declare function groupFieldsByCube(fields: MetaField[]): Record<string, M
36
36
  * Clean query object by removing empty arrays
37
37
  */
38
38
  export declare function cleanQuery(query: CubeQuery): CubeQuery;
39
+ /**
40
+ * Clean a query and transform filters for server compatibility
41
+ * This version transforms GroupFilter to legacy and/or format
42
+ */
43
+ export declare function cleanQueryForServer(query: CubeQuery): CubeQuery;
39
44
  /**
40
45
  * Create an empty query object
41
46
  */
42
47
  export declare function createEmptyQuery(): CubeQuery;
48
+ /**
49
+ * Filter utility functions
50
+ */
51
+ /**
52
+ * Check if a filter is a simple filter
53
+ */
54
+ export declare function isSimpleFilter(filter: Filter): filter is SimpleFilter;
55
+ /**
56
+ * Check if a filter is a group filter
57
+ */
58
+ export declare function isGroupFilter(filter: Filter): filter is GroupFilter;
59
+ /**
60
+ * Check if a filter is an AND filter
61
+ */
62
+ export declare function isAndFilter(filter: Filter): filter is GroupFilter;
63
+ /**
64
+ * Check if a filter is an OR filter
65
+ */
66
+ export declare function isOrFilter(filter: Filter): filter is GroupFilter;
67
+ /**
68
+ * Flatten all simple filters from a hierarchical filter structure
69
+ */
70
+ export declare function flattenFilters(filters: Filter[]): SimpleFilter[];
71
+ /**
72
+ * Get all filterable fields from schema (measures, dimensions, and time dimensions)
73
+ */
74
+ export declare function getFilterableFields(schema: MetaResponse, query?: CubeQuery): MetaField[];
75
+ /**
76
+ * Get available operators for a field type
77
+ */
78
+ export declare function getAvailableOperators(fieldType: string): Array<{
79
+ operator: string;
80
+ label: string;
81
+ }>;
82
+ /**
83
+ * Get field type from schema
84
+ */
85
+ export declare function getFieldType(fieldName: string, schema: MetaResponse): string;
86
+ /**
87
+ * Validate a filter
88
+ */
89
+ export declare function validateFilter(filter: SimpleFilter, schema: MetaResponse): {
90
+ isValid: boolean;
91
+ errors: string[];
92
+ };
93
+ /**
94
+ * Count total filters in hierarchical structure
95
+ */
96
+ export declare function countFilters(filters: Filter[]): number;
97
+ /**
98
+ * Create a new simple filter
99
+ */
100
+ export declare function createSimpleFilter(member: string, operator?: string, values?: any[]): SimpleFilter;
101
+ /**
102
+ * Create a new AND filter group
103
+ */
104
+ export declare function createAndFilter(filters?: Filter[]): GroupFilter;
105
+ /**
106
+ * Create a new OR filter group
107
+ */
108
+ export declare function createOrFilter(filters?: Filter[]): GroupFilter;
109
+ /**
110
+ * Clean up filters by removing any that reference fields not in the current query
111
+ */
112
+ export declare function cleanupFilters(filters: Filter[], query: CubeQuery): Filter[];
113
+ /**
114
+ * Transform filters from new GroupFilter format to legacy server format
115
+ * Server expects { and: [...] } and { or: [...] } instead of { type: 'and', filters: [...] }
116
+ */
117
+ export declare function transformFiltersForServer(filters: Filter[]): any[];
@@ -3,6 +3,7 @@ interface UseCubeQueryResult {
3
3
  resultSet: CubeResultSet | null;
4
4
  isLoading: boolean;
5
5
  error: Error | null;
6
+ queryId: string | null;
6
7
  }
7
8
  export declare function useCubeQuery(query: CubeQuery | null, options?: CubeQueryOptions): UseCubeQueryResult;
8
9
  export {};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Custom hook for debouncing values
3
+ * Delays updating the value until after the specified delay has passed
4
+ * since the last change
5
+ */
6
+ /**
7
+ * Debounces a value by the specified delay
8
+ * @param value The value to debounce
9
+ * @param delay The delay in milliseconds
10
+ * @returns The debounced value
11
+ */
12
+ export declare function useDebounce<T>(value: T, delay: number): T;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Hook for fetching distinct field values for filter dropdowns
3
+ * Uses the /load API to get actual data values
4
+ */
5
+ interface UseFilterValuesResult {
6
+ values: any[];
7
+ loading: boolean;
8
+ error: string | null;
9
+ refetch: () => void;
10
+ searchValues: (searchTerm: string, force?: boolean) => void;
11
+ }
12
+ /**
13
+ * Custom hook to fetch distinct values for a field
14
+ */
15
+ export declare function useFilterValues(fieldName: string | null, enabled?: boolean): UseFilterValuesResult;
16
+ export {};