@cubejs-client/core 1.6.32 → 1.6.33

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 (54) hide show
  1. package/dist/cubejs-client-core.cjs.js +20 -14
  2. package/dist/cubejs-client-core.cjs.js.map +1 -1
  3. package/dist/cubejs-client-core.umd.js +20 -14
  4. package/dist/cubejs-client-core.umd.js.map +1 -1
  5. package/dist/src/ResultSet.d.ts.map +1 -1
  6. package/dist/src/ResultSet.js +20 -13
  7. package/dist/src/format-d3-numeric-locale.d.ts +4 -0
  8. package/dist/src/format-d3-numeric-locale.d.ts.map +1 -0
  9. package/dist/src/format-d3-numeric-locale.js +103 -0
  10. package/dist/src/format.d.ts +17 -0
  11. package/dist/src/format.d.ts.map +1 -0
  12. package/dist/src/format.js +89 -0
  13. package/dist/src/index.js +2 -0
  14. package/dist/test/CubeApi.test.js +37 -37
  15. package/dist/test/HttpTransport.test.js +3 -3
  16. package/dist/test/ResultSet.bench.d.ts +2 -0
  17. package/dist/test/ResultSet.bench.d.ts.map +1 -0
  18. package/dist/test/ResultSet.bench.js +109 -0
  19. package/dist/test/ResultSet.test.d.ts +1 -1
  20. package/dist/test/ResultSet.test.d.ts.map +1 -1
  21. package/dist/test/ResultSet.test.js +0 -2
  22. package/dist/test/SqlQuery.test.js +0 -1
  23. package/dist/test/compare-date-range.test.d.ts +1 -1
  24. package/dist/test/compare-date-range.test.d.ts.map +1 -1
  25. package/dist/test/compare-date-range.test.js +0 -2
  26. package/dist/test/data-blending.test.d.ts +1 -1
  27. package/dist/test/data-blending.test.d.ts.map +1 -1
  28. package/dist/test/data-blending.test.js +0 -2
  29. package/dist/test/dayjs-isolation.test.d.ts +1 -1
  30. package/dist/test/dayjs-isolation.test.d.ts.map +1 -1
  31. package/dist/test/dayjs-isolation.test.js +0 -2
  32. package/dist/test/default-heuristics.test.d.ts +1 -1
  33. package/dist/test/default-heuristics.test.d.ts.map +1 -1
  34. package/dist/test/default-heuristics.test.js +4 -5
  35. package/dist/test/drill-down.test.d.ts +1 -1
  36. package/dist/test/drill-down.test.d.ts.map +1 -1
  37. package/dist/test/drill-down.test.js +4 -5
  38. package/dist/test/format-no-intl.test.d.ts +2 -0
  39. package/dist/test/format-no-intl.test.d.ts.map +1 -0
  40. package/dist/test/format-no-intl.test.js +49 -0
  41. package/dist/test/format.test.d.ts +2 -0
  42. package/dist/test/format.test.d.ts.map +1 -0
  43. package/dist/test/format.test.js +87 -0
  44. package/dist/test/granularity.test.d.ts +1 -1
  45. package/dist/test/granularity.test.d.ts.map +1 -1
  46. package/dist/test/granularity.test.js +0 -2
  47. package/dist/test/index.test.js +2 -2
  48. package/dist/test/table.test.d.ts +1 -1
  49. package/dist/test/table.test.d.ts.map +1 -1
  50. package/dist/test/table.test.js +0 -2
  51. package/dist/test/utils.test.d.ts +1 -1
  52. package/dist/test/utils.test.d.ts.map +1 -1
  53. package/dist/test/utils.test.js +0 -2
  54. package/package.json +12 -9
@@ -1 +1 @@
1
- {"version":3,"file":"ResultSet.d.ts","sourceRoot":"","sources":["../../src/ResultSet.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ResultSet.d.ts","sourceRoot":"","sources":["../../src/ResultSet.ts"],"names":[],"mappings":"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"}
@@ -259,16 +259,21 @@ export default class ResultSet {
259
259
  }
260
260
  axisValues(axis, resultIndex = 0) {
261
261
  const { query } = this.loadResponses[resultIndex];
262
+ const axisWithoutMeasures = axis.filter(d => d !== 'measures');
263
+ const measures = axis.includes('measures') ? (query.measures || []) : [];
262
264
  return (row) => {
263
- const value = (measure) => axis
264
- .filter(d => d !== 'measures')
265
- .map((d) => {
266
- const val = row[d];
267
- return val != null ? val : null;
268
- })
269
- .concat(measure ? [measure] : []);
270
- if (axis.find(d => d === 'measures') && (query.measures || []).length) {
271
- return (query.measures || []).map(value);
265
+ const value = (measure) => {
266
+ const result = axisWithoutMeasures.map((d) => {
267
+ const val = row[d];
268
+ return val != null ? val : null;
269
+ });
270
+ if (measure) {
271
+ result.push(measure);
272
+ }
273
+ return result;
274
+ };
275
+ if (measures.length > 0) {
276
+ return measures.map(value);
272
277
  }
273
278
  return [value()];
274
279
  };
@@ -427,11 +432,13 @@ export default class ResultSet {
427
432
  };
428
433
  }
429
434
  }
430
- const xGrouped = pipe(map((row) => this.axisValues(normalizedPivotConfig.x, resultIndex)(row).map(xValues => ({ xValues, row }))), unnest, groupByXAxis)(this.timeDimensionBackwardCompatibleData(resultIndex));
435
+ const xAxisValues = this.axisValues(normalizedPivotConfig.x, resultIndex);
436
+ const yAxisValues = this.axisValues(normalizedPivotConfig.y, resultIndex);
437
+ const xGrouped = pipe(map((row) => xAxisValues(row).map(xValues => ({ xValues, row }))), unnest, groupByXAxis)(this.timeDimensionBackwardCompatibleData(resultIndex));
431
438
  const yValuesMap = {};
432
439
  xGrouped.forEach(([, rows]) => {
433
440
  rows.forEach(({ row }) => {
434
- this.axisValues(normalizedPivotConfig.y, resultIndex)(row).forEach((values) => {
441
+ yAxisValues(row).forEach((values) => {
435
442
  if (Object.keys(row).length > 0) {
436
443
  yValuesMap[values.join()] = values;
437
444
  }
@@ -439,12 +446,12 @@ export default class ResultSet {
439
446
  });
440
447
  });
441
448
  const allYValues = Object.values(yValuesMap);
442
- const measureOnX = Boolean((normalizedPivotConfig.x).find(d => d === 'measures'));
449
+ const measureOnX = normalizedPivotConfig.x.includes('measures');
443
450
  return xGrouped.map(([, rows]) => {
444
451
  const { xValues } = rows[0];
445
452
  const yGrouped = {};
446
453
  rows.forEach(({ row }) => {
447
- const arr = this.axisValues(normalizedPivotConfig.y, resultIndex)(row).map(yValues => ({ yValues, row }));
454
+ const arr = yAxisValues(row).map(yValues => ({ yValues, row }));
448
455
  arr.forEach((res) => {
449
456
  yGrouped[this.axisValuesString(res.yValues)] = res;
450
457
  });
@@ -0,0 +1,4 @@
1
+ import type { FormatLocaleDefinition, FormatLocaleObject } from 'd3-format';
2
+ export declare const formatD3NumericLocale: Record<string, FormatLocaleDefinition>;
3
+ export declare function getD3NumericLocale(locale: string, currencyCode?: string): FormatLocaleObject;
4
+ //# sourceMappingURL=format-d3-numeric-locale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-d3-numeric-locale.d.ts","sourceRoot":"","sources":["../../src/format-d3-numeric-locale.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAkB5E,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAcxE,CAAC;AA8DF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,SAAQ,GAAG,kBAAkB,CAsB3F"}
@@ -0,0 +1,103 @@
1
+ import { formatLocale } from 'd3-format';
2
+ import enUS from 'd3-format/locale/en-US.json';
3
+ import enGB from 'd3-format/locale/en-GB.json';
4
+ import zhCN from 'd3-format/locale/zh-CN.json';
5
+ import esES from 'd3-format/locale/es-ES.json';
6
+ import esMX from 'd3-format/locale/es-MX.json';
7
+ import deDE from 'd3-format/locale/de-DE.json';
8
+ import jaJP from 'd3-format/locale/ja-JP.json';
9
+ import frFR from 'd3-format/locale/fr-FR.json';
10
+ import ptBR from 'd3-format/locale/pt-BR.json';
11
+ import koKR from 'd3-format/locale/ko-KR.json';
12
+ import itIT from 'd3-format/locale/it-IT.json';
13
+ import nlNL from 'd3-format/locale/nl-NL.json';
14
+ import ruRU from 'd3-format/locale/ru-RU.json';
15
+ // Pre-built d3 locale definitions for the most popular locales.
16
+ // Used as a fallback when Intl is unavailable (e.g. some edge runtimes).
17
+ export const formatD3NumericLocale = {
18
+ 'en-US': enUS,
19
+ 'en-GB': enGB,
20
+ 'zh-CN': zhCN,
21
+ 'es-ES': esES,
22
+ 'es-MX': esMX,
23
+ 'de-DE': deDE,
24
+ 'ja-JP': jaJP,
25
+ 'fr-FR': frFR,
26
+ 'pt-BR': ptBR,
27
+ 'ko-KR': koKR,
28
+ 'it-IT': itIT,
29
+ 'nl-NL': nlNL,
30
+ 'ru-RU': ruRU,
31
+ };
32
+ const currencySymbols = {
33
+ USD: '$',
34
+ EUR: '€',
35
+ GBP: '£',
36
+ JPY: '¥',
37
+ CNY: '¥',
38
+ KRW: '₩',
39
+ INR: '₹',
40
+ RUB: '₽',
41
+ };
42
+ function getCurrencySymbol(locale, currencyCode) {
43
+ try {
44
+ const cf = new Intl.NumberFormat(locale, { style: 'currency', currency: currencyCode });
45
+ const currencyParts = cf.formatToParts(1);
46
+ const currencySymbol = currencyParts.find((p) => p.type === 'currency')?.value ?? currencyCode;
47
+ const firstMeaningfulType = currencyParts.find((p) => !['literal', 'nan'].includes(p.type))?.type;
48
+ const symbolIsPrefix = firstMeaningfulType === 'currency';
49
+ return symbolIsPrefix ? [currencySymbol, ''] : ['', currencySymbol];
50
+ }
51
+ catch {
52
+ const symbol = currencySymbols[currencyCode] ?? currencyCode;
53
+ return [symbol, ''];
54
+ }
55
+ }
56
+ function deriveGrouping(locale) {
57
+ // en-US → "1,234,567,890" → sizes [1,3,3,3] → [3]
58
+ // en-IN → "1,23,45,67,890" → sizes [1,2,2,2,3] → [3,2]
59
+ const sizes = new Intl.NumberFormat(locale).formatToParts(1234567890)
60
+ .filter((p) => p.type === 'integer')
61
+ .map((p) => p.value.length);
62
+ if (sizes.length <= 1) {
63
+ return [3];
64
+ }
65
+ // d3 repeats the last array element for all remaining groups,
66
+ // so we only need the two rightmost (least-significant) group sizes.
67
+ const first = sizes[sizes.length - 1];
68
+ const second = sizes[sizes.length - 2];
69
+ return first === second ? [first] : [first, second];
70
+ }
71
+ function getD3NumericLocaleFromIntl(locale, currencyCode = 'USD') {
72
+ const nf = new Intl.NumberFormat(locale);
73
+ const numParts = nf.formatToParts(1234567.89);
74
+ const find = (type) => numParts.find((p) => p.type === type)?.value ?? '';
75
+ return {
76
+ decimal: find('decimal') || '.',
77
+ thousands: find('group') || ',',
78
+ grouping: deriveGrouping(locale),
79
+ currency: getCurrencySymbol(locale, currencyCode),
80
+ };
81
+ }
82
+ const localeCache = Object.create(null);
83
+ export function getD3NumericLocale(locale, currencyCode = 'USD') {
84
+ const key = `${locale}:${currencyCode}`;
85
+ if (localeCache[key]) {
86
+ return localeCache[key];
87
+ }
88
+ let definition;
89
+ if (formatD3NumericLocale[locale]) {
90
+ definition = { ...formatD3NumericLocale[locale], currency: getCurrencySymbol(locale, currencyCode) };
91
+ }
92
+ else {
93
+ try {
94
+ definition = getD3NumericLocaleFromIntl(locale, currencyCode);
95
+ }
96
+ catch (e) {
97
+ console.warn('Failed to generate d3 local via Intl, failing back to en-US', e);
98
+ definition = formatD3NumericLocale['en-US'];
99
+ }
100
+ }
101
+ localeCache[key] = formatLocale(definition);
102
+ return localeCache[key];
103
+ }
@@ -0,0 +1,17 @@
1
+ import type { DimensionFormat, MeasureFormat, TCubeMemberType } from './types';
2
+ export type FormatValueMember = {
3
+ type: TCubeMemberType;
4
+ format?: DimensionFormat | MeasureFormat;
5
+ /** ISO 4217 currency code (e.g. 'USD', 'EUR'). Used when format is 'currency'. */
6
+ currency?: string;
7
+ /** Time dimension granularity (e.g. 'day', 'month', 'year'). Used for time formatting when no explicit format is set. */
8
+ granularity?: string;
9
+ };
10
+ export type FormatValueOptions = FormatValueMember & {
11
+ /** Locale tag (e.g. 'en-US', 'de-DE', 'nl-NL'). Defaults to the runtime's locale via Intl.NumberFormat. */
12
+ locale?: string;
13
+ /** String to return for null/undefined values. Defaults to '∅'. */
14
+ emptyPlaceholder?: string;
15
+ };
16
+ export declare function formatValue(value: any, { type, format, currency, granularity, locale, emptyPlaceholder }: FormatValueOptions): string;
17
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/format.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAqD/E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,CAAC,EAAE,eAAe,GAAG,aAAa,CAAC;IACzC,kFAAkF;IAClF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yHAAyH;IACzH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG;IACnD,2GAA2G;IAC3G,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,wBAAgB,WAAW,CACzB,KAAK,EAAE,GAAG,EACV,EAAE,IAAI,EAAE,MAAM,EAAE,QAAgB,EAAE,WAAW,EAAE,MAAsB,EAAE,gBAAsB,EAAE,EAAE,kBAAkB,GAClH,MAAM,CAgDR"}
@@ -0,0 +1,89 @@
1
+ import { format as d3Format } from 'd3-format';
2
+ import { timeFormat } from 'd3-time-format';
3
+ import { getD3NumericLocale } from './format-d3-numeric-locale';
4
+ // Default d3-format specifiers — aligned with the named _2 formats
5
+ // (number_2, currency_2, percent_2) in named-numeric-formats.ts
6
+ const DEFAULT_NUMBER_FORMAT = ',.2f';
7
+ const DEFAULT_CURRENCY_FORMAT = '$,.2f';
8
+ const DEFAULT_PERCENT_FORMAT = '.2%';
9
+ function detectLocale() {
10
+ try {
11
+ return new Intl.NumberFormat().resolvedOptions().locale;
12
+ }
13
+ catch (e) {
14
+ console.warn('Failed to detect locale', e);
15
+ return 'en-US';
16
+ }
17
+ }
18
+ const currentLocale = detectLocale();
19
+ const DEFAULT_DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S';
20
+ const DEFAULT_DATE_FORMAT = '%Y-%m-%d';
21
+ const DEFAULT_DATE_MONTH_FORMAT = '%Y-%m';
22
+ const DEFAULT_DATE_QUARTER_FORMAT = '%Y-Q%q';
23
+ const DEFAULT_DATE_YEAR_FORMAT = '%Y';
24
+ function getTimeFormatByGrain(grain) {
25
+ switch (grain) {
26
+ case 'day':
27
+ case 'week':
28
+ return DEFAULT_DATE_FORMAT;
29
+ case 'month':
30
+ return DEFAULT_DATE_MONTH_FORMAT;
31
+ case 'quarter':
32
+ return DEFAULT_DATE_QUARTER_FORMAT;
33
+ case 'year':
34
+ return DEFAULT_DATE_YEAR_FORMAT;
35
+ case 'second':
36
+ case 'minute':
37
+ case 'hour':
38
+ default:
39
+ return DEFAULT_DATETIME_FORMAT;
40
+ }
41
+ }
42
+ function parseNumber(value) {
43
+ if (value === null || value === undefined) {
44
+ return 0;
45
+ }
46
+ return parseFloat(value);
47
+ }
48
+ export function formatValue(value, { type, format, currency = 'USD', granularity, locale = currentLocale, emptyPlaceholder = '∅' }) {
49
+ if (value === null || value === undefined) {
50
+ return emptyPlaceholder;
51
+ }
52
+ if (format && typeof format === 'object') {
53
+ if (format.type === 'custom-numeric') {
54
+ return d3Format(format.value)(parseNumber(value));
55
+ }
56
+ if (format.type === 'custom-time') {
57
+ const date = new Date(value);
58
+ return Number.isNaN(date.getTime()) ? 'Invalid date' : timeFormat(format.value)(date);
59
+ }
60
+ // { type: 'link', label: string } — return value as string
61
+ return String(value);
62
+ }
63
+ if (typeof format === 'string') {
64
+ switch (format) {
65
+ case 'currency':
66
+ return getD3NumericLocale(locale, currency).format(DEFAULT_CURRENCY_FORMAT)(parseNumber(value));
67
+ case 'percent':
68
+ return getD3NumericLocale(locale).format(DEFAULT_PERCENT_FORMAT)(parseNumber(value));
69
+ case 'number':
70
+ return getD3NumericLocale(locale).format(DEFAULT_NUMBER_FORMAT)(parseNumber(value));
71
+ case 'imageUrl':
72
+ case 'id':
73
+ case 'link':
74
+ default:
75
+ return String(value);
76
+ }
77
+ }
78
+ // No explicit format — infer from type
79
+ if (type === 'time') {
80
+ const date = new Date(value);
81
+ if (Number.isNaN(date.getTime()))
82
+ return 'Invalid date';
83
+ return timeFormat(getTimeFormatByGrain(granularity))(date);
84
+ }
85
+ if (type === 'number') {
86
+ return getD3NumericLocale(locale, currency).format(DEFAULT_NUMBER_FORMAT)(parseNumber(value));
87
+ }
88
+ return String(value);
89
+ }
package/dist/src/index.js CHANGED
@@ -570,3 +570,5 @@ export * from './HttpTransport';
570
570
  export * from './utils';
571
571
  export * from './time';
572
572
  export * from './types';
573
+ // We don't export it for now, because size of builds for cjs/umd users will be affected
574
+ // export * from './format';
@@ -3,8 +3,8 @@
3
3
  * @copyright Cube Dev, Inc.
4
4
  * @fileoverview Test signal parameter in CubeApi
5
5
  */
6
- /* globals describe,test,expect,jest,beforeEach */
7
6
  /* eslint-disable import/first */
7
+ import { vi } from 'vitest';
8
8
  import { CubeApi as CubeApiOriginal } from '../src';
9
9
  import HttpTransport from '../src/HttpTransport';
10
10
  import RequestError from '../src/RequestError';
@@ -31,12 +31,12 @@ describe('CubeApi Constructor', () => {
31
31
  });
32
32
  describe('CubeApi Load', () => {
33
33
  afterEach(() => {
34
- jest.clearAllMocks();
35
- jest.restoreAllMocks();
34
+ vi.clearAllMocks();
35
+ vi.restoreAllMocks();
36
36
  });
37
37
  test('simple query, no options', async () => {
38
38
  // Create a spy on the request method
39
- jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
39
+ vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
40
40
  subscribe: (cb) => Promise.resolve(cb({
41
41
  status: 200,
42
42
  text: () => Promise.resolve(JSON.stringify(DescriptiveQueryResponse)),
@@ -52,7 +52,7 @@ describe('CubeApi Load', () => {
52
52
  });
53
53
  test('simple query + { mutexKey, castNumerics }', async () => {
54
54
  // Create a spy on the request method
55
- jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
55
+ vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
56
56
  subscribe: (cb) => Promise.resolve(cb({
57
57
  status: 200,
58
58
  text: () => Promise.resolve(JSON.stringify(DescriptiveQueryResponse)),
@@ -68,7 +68,7 @@ describe('CubeApi Load', () => {
68
68
  });
69
69
  test('simple query + compact response format', async () => {
70
70
  // Create a spy on the request method
71
- jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
71
+ vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
72
72
  subscribe: (cb) => Promise.resolve(cb({
73
73
  status: 200,
74
74
  text: () => Promise.resolve(JSON.stringify(DescriptiveQueryResponse)),
@@ -84,7 +84,7 @@ describe('CubeApi Load', () => {
84
84
  });
85
85
  test('2 queries', async () => {
86
86
  // Create a spy on the request method
87
- jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
87
+ vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
88
88
  subscribe: (cb) => Promise.resolve(cb({
89
89
  status: 200,
90
90
  text: () => Promise.resolve(JSON.stringify(DescriptiveQueryResponse)),
@@ -99,7 +99,7 @@ describe('CubeApi Load', () => {
99
99
  expect(res.rawData()).toEqual(DescriptiveQueryResponse.results[0].data);
100
100
  });
101
101
  test('simple query + { cache: "no-cache" }', async () => {
102
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
102
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
103
103
  subscribe: (cb) => Promise.resolve(cb({
104
104
  status: 200,
105
105
  text: () => Promise.resolve(JSON.stringify(DescriptiveQueryResponse)),
@@ -115,7 +115,7 @@ describe('CubeApi Load', () => {
115
115
  expect(requestSpy.mock.calls[0]?.[1]?.cache).toBe('no-cache');
116
116
  });
117
117
  test('simple query + { cache: "must-revalidate" }', async () => {
118
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
118
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
119
119
  subscribe: (cb) => Promise.resolve(cb({
120
120
  status: 200,
121
121
  text: () => Promise.resolve(JSON.stringify(DescriptiveQueryResponse)),
@@ -132,7 +132,7 @@ describe('CubeApi Load', () => {
132
132
  });
133
133
  test('2 queries + compact response format', async () => {
134
134
  // Create a spy on the request method
135
- jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
135
+ vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
136
136
  subscribe: (cb) => Promise.resolve(cb({
137
137
  status: 200,
138
138
  text: () => Promise.resolve(JSON.stringify(DescriptiveQueryResponse)),
@@ -149,14 +149,14 @@ describe('CubeApi Load', () => {
149
149
  });
150
150
  describe('CubeApi with Abort Signal', () => {
151
151
  afterEach(() => {
152
- jest.clearAllMocks();
153
- jest.restoreAllMocks();
152
+ vi.clearAllMocks();
153
+ vi.restoreAllMocks();
154
154
  });
155
155
  test('should pass signal from constructor to request', async () => {
156
156
  const controller = new AbortController();
157
157
  const { signal } = controller;
158
158
  // Create a spy on the request method
159
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
159
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
160
160
  subscribe: (cb) => Promise.resolve(cb({
161
161
  status: 200,
162
162
  text: () => Promise.resolve('{"results":[]}'),
@@ -168,7 +168,7 @@ describe('CubeApi with Abort Signal', () => {
168
168
  signal
169
169
  });
170
170
  // Create a second spy on the load method to verify signal is passed to HttpTransport
171
- jest.spyOn(cubeApi, 'load');
171
+ vi.spyOn(cubeApi, 'load');
172
172
  await cubeApi.load({
173
173
  measures: ['Orders.count']
174
174
  });
@@ -187,7 +187,7 @@ describe('CubeApi with Abort Signal', () => {
187
187
  const controller = new AbortController();
188
188
  const { signal } = controller;
189
189
  // Mock for this specific test
190
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
190
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
191
191
  subscribe: (cb) => Promise.resolve(cb({
192
192
  status: 200,
193
193
  text: () => Promise.resolve('{"results":[]}'),
@@ -205,7 +205,7 @@ describe('CubeApi with Abort Signal', () => {
205
205
  const constructorController = new AbortController();
206
206
  const optionsController = new AbortController();
207
207
  // Mock for this specific test
208
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
208
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
209
209
  subscribe: (cb) => Promise.resolve(cb({
210
210
  status: 200,
211
211
  text: () => Promise.resolve('{"results":[]}'),
@@ -225,7 +225,7 @@ describe('CubeApi with Abort Signal', () => {
225
225
  const controller = new AbortController();
226
226
  const { signal } = controller;
227
227
  // Mock for meta with proper format - include dimensions, segments, and measures with required properties
228
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
228
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
229
229
  subscribe: (cb) => Promise.resolve(cb({
230
230
  status: 200,
231
231
  text: () => Promise.resolve(JSON.stringify({
@@ -277,7 +277,7 @@ describe('CubeApi with Abort Signal', () => {
277
277
  const controller = new AbortController();
278
278
  const { signal } = controller;
279
279
  // Mock for SQL response
280
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
280
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
281
281
  subscribe: (cb) => Promise.resolve(cb({
282
282
  status: 200,
283
283
  text: () => Promise.resolve('{"sql":{"sql":"SELECT * FROM orders"}}'),
@@ -295,7 +295,7 @@ describe('CubeApi with Abort Signal', () => {
295
295
  const controller = new AbortController();
296
296
  const { signal } = controller;
297
297
  // Mock for dryRun response
298
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
298
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
299
299
  subscribe: (cb) => Promise.resolve(cb({
300
300
  status: 200,
301
301
  text: () => Promise.resolve('{"queryType":"regular"}'),
@@ -312,8 +312,8 @@ describe('CubeApi with Abort Signal', () => {
312
312
  });
313
313
  describe('CubeApi cubeSql', () => {
314
314
  afterEach(() => {
315
- jest.clearAllMocks();
316
- jest.restoreAllMocks();
315
+ vi.clearAllMocks();
316
+ vi.restoreAllMocks();
317
317
  });
318
318
  const cubeSqlResponseBody = [
319
319
  JSON.stringify({
@@ -335,7 +335,7 @@ describe('CubeApi cubeSql', () => {
335
335
  JSON.stringify({ data: [['Active']] }),
336
336
  ].join('\n');
337
337
  test('should parse lastRefreshTime from response', async () => {
338
- jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
338
+ vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
339
339
  subscribe: (cb) => Promise.resolve(cb({
340
340
  status: 200,
341
341
  text: () => Promise.resolve(JSON.stringify({ error: cubeSqlResponseBody })),
@@ -357,7 +357,7 @@ describe('CubeApi cubeSql', () => {
357
357
  ]);
358
358
  });
359
359
  test('should omit lastRefreshTime when not present in response', async () => {
360
- jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
360
+ vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
361
361
  subscribe: (cb) => Promise.resolve(cb({
362
362
  status: 200,
363
363
  text: () => Promise.resolve(JSON.stringify({ error: cubeSqlResponseBodyNoRefreshTime })),
@@ -374,12 +374,12 @@ describe('CubeApi cubeSql', () => {
374
374
  });
375
375
  describe('CubeApi with baseRequestId', () => {
376
376
  afterEach(() => {
377
- jest.clearAllMocks();
378
- jest.restoreAllMocks();
377
+ vi.clearAllMocks();
378
+ vi.restoreAllMocks();
379
379
  });
380
380
  test('should pass baseRequestId from options to request', async () => {
381
381
  const baseRequestId = 'custom-request-id-123';
382
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
382
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
383
383
  subscribe: (cb) => Promise.resolve(cb({
384
384
  status: 200,
385
385
  text: () => Promise.resolve('{"results":[]}'),
@@ -394,7 +394,7 @@ describe('CubeApi with baseRequestId', () => {
394
394
  expect(requestSpy.mock.calls[0]?.[1]?.baseRequestId).toBe(baseRequestId);
395
395
  });
396
396
  test('should generate baseRequestId if not provided', async () => {
397
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
397
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
398
398
  subscribe: (cb) => Promise.resolve(cb({
399
399
  status: 200,
400
400
  text: () => Promise.resolve('{"results":[]}'),
@@ -412,7 +412,7 @@ describe('CubeApi with baseRequestId', () => {
412
412
  });
413
413
  test('should pass baseRequestId to sql request', async () => {
414
414
  const baseRequestId = 'sql-request-id-456';
415
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
415
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
416
416
  subscribe: (cb) => Promise.resolve(cb({
417
417
  status: 200,
418
418
  text: () => Promise.resolve('{"sql":{"sql":"SELECT * FROM orders"}}'),
@@ -428,7 +428,7 @@ describe('CubeApi with baseRequestId', () => {
428
428
  });
429
429
  test('should pass baseRequestId to dryRun request', async () => {
430
430
  const baseRequestId = 'dryrun-request-id-789';
431
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
431
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
432
432
  subscribe: (cb) => Promise.resolve(cb({
433
433
  status: 200,
434
434
  text: () => Promise.resolve('{"queryType":"regular"}'),
@@ -444,7 +444,7 @@ describe('CubeApi with baseRequestId', () => {
444
444
  });
445
445
  test('should pass baseRequestId to subscribe request', async () => {
446
446
  const baseRequestId = 'subscribe-request-id-abc';
447
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
447
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
448
448
  subscribe: (cb) => Promise.resolve(cb({
449
449
  status: 200,
450
450
  text: () => Promise.resolve('{"results":[]}'),
@@ -465,7 +465,7 @@ describe('CubeApi with baseRequestId', () => {
465
465
  });
466
466
  test('should pass baseRequestId with multiple queries', async () => {
467
467
  const baseRequestId = 'multi-query-request-id';
468
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
468
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
469
469
  subscribe: (cb) => Promise.resolve(cb({
470
470
  status: 200,
471
471
  text: () => Promise.resolve(JSON.stringify(DescriptiveQueryResponse)),
@@ -484,7 +484,7 @@ describe('CubeApi with baseRequestId', () => {
484
484
  });
485
485
  test('should pass baseRequestId to meta request', async () => {
486
486
  const baseRequestId = 'meta-request-id-def';
487
- const requestSpy = jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
487
+ const requestSpy = vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
488
488
  subscribe: (cb) => Promise.resolve(cb({
489
489
  status: 200,
490
490
  text: () => Promise.resolve(JSON.stringify({
@@ -535,11 +535,11 @@ describe('CubeApi with baseRequestId', () => {
535
535
  });
536
536
  describe('CubeApi Mutex Cancellation', () => {
537
537
  afterEach(() => {
538
- jest.clearAllMocks();
539
- jest.restoreAllMocks();
538
+ vi.clearAllMocks();
539
+ vi.restoreAllMocks();
540
540
  });
541
541
  test('should return null for cancelled query when a newer query invalidates it', async () => {
542
- jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
542
+ vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
543
543
  subscribe: (cb) => Promise.resolve(cb({
544
544
  status: 200,
545
545
  text: () => Promise.resolve(JSON.stringify(DescriptiveQueryResponse)),
@@ -562,7 +562,7 @@ describe('CubeApi Mutex Cancellation', () => {
562
562
  expect(second).toBeInstanceOf(ResultSet);
563
563
  });
564
564
  test('should return ResultSet when no mutex cancellation occurs', async () => {
565
- jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
565
+ vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
566
566
  subscribe: (cb) => Promise.resolve(cb({
567
567
  status: 200,
568
568
  text: () => Promise.resolve(JSON.stringify(DescriptiveQueryResponse)),
@@ -579,7 +579,7 @@ describe('CubeApi Mutex Cancellation', () => {
579
579
  });
580
580
  test('should propagate non-mutex errors', async () => {
581
581
  const errorBody = { error: 'Internal Server Error' };
582
- jest.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
582
+ vi.spyOn(HttpTransport.prototype, 'request').mockImplementation(() => ({
583
583
  subscribe: (cb) => Promise.resolve(cb({
584
584
  status: 500,
585
585
  text: () => Promise.resolve(JSON.stringify(errorBody)),
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable import/first */
2
- /* globals describe,test,expect,jest,afterEach,beforeAll,beforeEach */
2
+ import { vi } from 'vitest';
3
3
  import fetch from 'cross-fetch';
4
- jest.mock('cross-fetch');
4
+ vi.mock('cross-fetch');
5
5
  import HttpTransport from '../src/HttpTransport';
6
6
  const mockedFetch = fetch;
7
7
  describe('HttpTransport', () => {
@@ -183,7 +183,7 @@ describe('HttpTransport', () => {
183
183
  // Mock AbortSignal.timeout
184
184
  const originalTimeout = AbortSignal.timeout;
185
185
  const mockTimeoutSignal = {};
186
- AbortSignal.timeout = jest.fn().mockReturnValue(mockTimeoutSignal);
186
+ AbortSignal.timeout = vi.fn().mockReturnValue(mockTimeoutSignal);
187
187
  const transport = new HttpTransport({
188
188
  authorization: 'token',
189
189
  apiUrl: 'http://localhost:4000/cubejs-api/v1',
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ResultSet.bench.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResultSet.bench.d.ts","sourceRoot":"","sources":["../../test/ResultSet.bench.ts"],"names":[],"mappings":""}