Skip to content

Commit 959e9c5

Browse files
author
Debjit Mandal
committed
fix(client-core): Isolate internalDayjs instance to prevent global dayjs pollution
- Register custom locale 'cube-internal-en' with weekStart: 1 - Restore original global locale after registration - Prevents internalDayjs from affecting global dayjs instance - Add comprehensive test suite for dayjs instance isolation - Fixes issue where calling internalDayjs changed global week start Closes issue where customizing internal dayjs instance affected the default dayjs instance behavior (weekStart changed from 0 to 1)
1 parent ee02a4f commit 959e9c5

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

packages/cubejs-client-core/src/time.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ dayjs.extend(quarterOfYear);
88
dayjs.extend(duration);
99
dayjs.extend(isoWeek);
1010

11+
// A custom locale for internal use that doesn't affect the global dayjs instance
12+
const cubeInternalLocale = 'cube-internal-en';
13+
const currentGlobalLocale = dayjs.locale();
14+
dayjs.locale({
15+
...en,
16+
name: cubeInternalLocale,
17+
weekStart: 1
18+
});
19+
dayjs.locale(currentGlobalLocale);
20+
1121
export type SqlInterval = string;
1222

1323
// TODO: Define a better type as unitOfTime.DurationConstructor in moment.js
@@ -59,7 +69,7 @@ export const DEFAULT_GRANULARITY = 'day';
5969

6070
// When granularity is week, weekStart Value must be 1. However, since the client can change it globally
6171
// (https://day.js.org/docs/en/i18n/changing-locale) So the function below has been added.
62-
export const internalDayjs = (...args: any[]): dayjs.Dayjs => dayjs(...args).locale({ ...en, weekStart: 1 });
72+
export const internalDayjs = (...args: any[]): dayjs.Dayjs => dayjs(...args).locale(cubeInternalLocale);
6373

6474
export const TIME_SERIES: Record<string, (range: DayRange) => string[]> = {
6575
day: (range) => range.by('d').map(d => d.format('YYYY-MM-DDT00:00:00.000')),
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/* globals describe,test,expect */
2+
3+
import 'jest';
4+
import dayjs from 'dayjs';
5+
import { internalDayjs } from '../src/time';
6+
7+
describe('Dayjs Instance Isolation', () => {
8+
test('internalDayjs should not affect global dayjs instance week start', () => {
9+
const initialWeekStart = dayjs().startOf('week').format('dddd');
10+
const cubeDayjs = internalDayjs();
11+
expect(cubeDayjs.startOf('week').format('dddd')).toBe('Monday');
12+
const afterWeekStart = dayjs().startOf('week').format('dddd');
13+
expect(afterWeekStart).toBe(initialWeekStart);
14+
expect(afterWeekStart).toBe('Sunday');
15+
});
16+
17+
test('internalDayjs week calculation should use Monday as week start', () => {
18+
const testDate = '2024-01-10';
19+
20+
const internalWeekStart = internalDayjs(testDate).startOf('week');
21+
expect(internalWeekStart.format('YYYY-MM-DD')).toBe('2024-01-08');
22+
expect(internalWeekStart.format('dddd')).toBe('Monday');
23+
24+
const globalWeekStart = dayjs(testDate).startOf('week');
25+
expect(globalWeekStart.format('YYYY-MM-DD')).toBe('2024-01-07');
26+
expect(globalWeekStart.format('dddd')).toBe('Sunday');
27+
});
28+
29+
test('multiple calls to internalDayjs should not affect global instance', () => {
30+
const initialWeekStart = dayjs().startOf('week').format('dddd');
31+
32+
internalDayjs('2024-01-01');
33+
internalDayjs('2024-02-01');
34+
internalDayjs('2024-03-01');
35+
36+
expect(dayjs().startOf('week').format('dddd')).toBe(initialWeekStart);
37+
});
38+
39+
test('internalDayjs should consistently use weekStart: 1', () => {
40+
const dates = [
41+
'2024-01-10', // Wednesday
42+
'2024-02-15', // Thursday
43+
'2024-03-20', // Wednesday
44+
'2024-04-25', // Thursday
45+
];
46+
47+
dates.forEach((date) => {
48+
const weekStart = internalDayjs(date).startOf('week');
49+
expect(weekStart.format('dddd')).toBe('Monday');
50+
});
51+
});
52+
});

0 commit comments

Comments
 (0)