@lightdash/common 0.1418.2 → 0.1419.1

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/index.d.ts CHANGED
@@ -37,7 +37,7 @@ import { type LightdashUser, type LoginOptions, type UserAllowedOrganization } f
37
37
  import { type UserWarehouseCredentials } from './types/userWarehouseCredentials';
38
38
  import { type ValidationResponse } from './types/validation';
39
39
  import { type ApiCatalogAnalyticsResults, type ApiCatalogMetadataResults, type ApiGetMetricsTree, type ApiMetricsCatalog } from './types/catalog';
40
- import { type ApiChartAsCodeListResponse, type ApiChartAsCodeUpsertResponse } from './types/coder';
40
+ import { type ApiChartAsCodeListResponse, type ApiChartAsCodeUpsertResponse, type ApiDashboardAsCodeListResponse } from './types/coder';
41
41
  import { type ApiChartContentResponse, type ApiContentResponse } from './types/content';
42
42
  import type { ApiGroupListResponse } from './types/groups';
43
43
  import type { ApiMetricsExplorerQueryResults, ApiMetricsExplorerTotalResults } from './types/metricsExplorer';
@@ -382,7 +382,7 @@ export type ApiAiGetDashboardSummaryResponse = {
382
382
  status: 'ok';
383
383
  results: DashboardSummary;
384
384
  };
385
- type ApiResults = ApiQueryResults | ApiSqlQueryResults | ApiCompiledQueryResults | ApiExploresResults | ApiExploreResults | ApiStatusResults | ApiRefreshResults | ApiHealthResults | Organization | LightdashUser | LoginOptions | SavedChart | SavedChart[] | Space[] | InviteLink | OrganizationProject[] | Project | WarehouseCredentials | OrganizationMemberProfile[] | ProjectCatalog | TablesConfiguration | Dashboard | DashboardBasicDetails[] | OnboardingStatus | Dashboard[] | DeleteOpenIdentity | ApiFlashResults | Record<OpenIdIdentitySummary['issuerType'], OpenIdIdentitySummary[]> | FilterableField[] | DashboardAvailableFilters | ProjectSavedChartStatus | null | Array<unknown> | ApiJobStartedResults | ApiCreateUserTokenResults | CreatePersonalAccessToken | PersonalAccessToken | ProjectMemberProfile[] | ProjectGroupAccess | SearchResults | Space | ShareUrl | SlackSettings | ApiSlackChannelsResponse['results'] | UserActivity | SchedulerAndTargets | SchedulerAndTargets[] | FieldValueSearchResult | ApiDownloadCsv | AllowedEmailDomains | UpdateAllowedEmailDomains | UserAllowedOrganization[] | EmailStatusExpiring | ApiScheduledDownloadCsv | PinnedItems | ViewStatistics | SchedulerWithLogs | ValidationResponse[] | ChartHistory | ChartVersion | Array<GitRepo> | PullRequestCreated | GitIntegrationConfiguration | UserWarehouseCredentials | ApiJobStatusResponse['results'] | ApiJobScheduledResponse['results'] | ApiSshKeyPairResponse['results'] | MostPopularAndRecentlyUpdated | ApiCalculateTotalResponse['results'] | Record<string, DbtExposure> | ApiCreateComment['results'] | ApiGetComments['results'] | ApiDeleteComment | ApiSuccessEmpty | ApiCreateProjectResults | ApiAiDashboardSummaryResponse['results'] | ApiAiGetDashboardSummaryResponse['results'] | ApiCatalogMetadataResults | ApiCatalogAnalyticsResults | ApiPromotionChangesResponse['results'] | ApiWarehouseTableFields['results'] | ApiTogglePinnedItem['results'] | ApiOrganizationMemberProfiles['results'] | ApiSqlChart['results'] | ApiCreateSqlChart['results'] | ApiUpdateSqlChart['results'] | ApiContentResponse['results'] | ApiChartContentResponse['results'] | ApiSqlRunnerJobStatusResponse['results'] | ApiSemanticLayerClientInfo['results'] | ApiSemanticViewerChartCreate['results'] | ApiSemanticViewerChartGet['results'] | ApiSemanticViewerChartUpdate['results'] | ApiCreateVirtualView['results'] | ApiGithubDbtWritePreview['results'] | ApiMetricsCatalog['results'] | ApiMetricsExplorerQueryResults['results'] | ApiGroupListResponse['results'] | ApiCreateTagResponse['results'] | ApiChartAsCodeListResponse['results'] | ApiChartAsCodeUpsertResponse['results'] | ApiGetMetricsTree['results'] | ApiMetricsExplorerTotalResults['results'];
385
+ type ApiResults = ApiQueryResults | ApiSqlQueryResults | ApiCompiledQueryResults | ApiExploresResults | ApiExploreResults | ApiStatusResults | ApiRefreshResults | ApiHealthResults | Organization | LightdashUser | LoginOptions | SavedChart | SavedChart[] | Space[] | InviteLink | OrganizationProject[] | Project | WarehouseCredentials | OrganizationMemberProfile[] | ProjectCatalog | TablesConfiguration | Dashboard | DashboardBasicDetails[] | OnboardingStatus | Dashboard[] | DeleteOpenIdentity | ApiFlashResults | Record<OpenIdIdentitySummary['issuerType'], OpenIdIdentitySummary[]> | FilterableField[] | DashboardAvailableFilters | ProjectSavedChartStatus | null | Array<unknown> | ApiJobStartedResults | ApiCreateUserTokenResults | CreatePersonalAccessToken | PersonalAccessToken | ProjectMemberProfile[] | ProjectGroupAccess | SearchResults | Space | ShareUrl | SlackSettings | ApiSlackChannelsResponse['results'] | UserActivity | SchedulerAndTargets | SchedulerAndTargets[] | FieldValueSearchResult | ApiDownloadCsv | AllowedEmailDomains | UpdateAllowedEmailDomains | UserAllowedOrganization[] | EmailStatusExpiring | ApiScheduledDownloadCsv | PinnedItems | ViewStatistics | SchedulerWithLogs | ValidationResponse[] | ChartHistory | ChartVersion | Array<GitRepo> | PullRequestCreated | GitIntegrationConfiguration | UserWarehouseCredentials | ApiJobStatusResponse['results'] | ApiJobScheduledResponse['results'] | ApiSshKeyPairResponse['results'] | MostPopularAndRecentlyUpdated | ApiCalculateTotalResponse['results'] | Record<string, DbtExposure> | ApiCreateComment['results'] | ApiGetComments['results'] | ApiDeleteComment | ApiSuccessEmpty | ApiCreateProjectResults | ApiAiDashboardSummaryResponse['results'] | ApiAiGetDashboardSummaryResponse['results'] | ApiCatalogMetadataResults | ApiCatalogAnalyticsResults | ApiPromotionChangesResponse['results'] | ApiWarehouseTableFields['results'] | ApiTogglePinnedItem['results'] | ApiOrganizationMemberProfiles['results'] | ApiSqlChart['results'] | ApiCreateSqlChart['results'] | ApiUpdateSqlChart['results'] | ApiContentResponse['results'] | ApiChartContentResponse['results'] | ApiSqlRunnerJobStatusResponse['results'] | ApiSemanticLayerClientInfo['results'] | ApiSemanticViewerChartCreate['results'] | ApiSemanticViewerChartGet['results'] | ApiSemanticViewerChartUpdate['results'] | ApiCreateVirtualView['results'] | ApiGithubDbtWritePreview['results'] | ApiMetricsCatalog['results'] | ApiMetricsExplorerQueryResults['results'] | ApiGroupListResponse['results'] | ApiCreateTagResponse['results'] | ApiChartAsCodeListResponse['results'] | ApiDashboardAsCodeListResponse['results'] | ApiChartAsCodeUpsertResponse['results'] | ApiGetMetricsTree['results'] | ApiMetricsExplorerTotalResults['results'];
386
386
  export type ApiResponse<T extends ApiResults = ApiResults> = {
387
387
  status: 'ok';
388
388
  results: T;
@@ -7,7 +7,10 @@ export type ChartAsCode = Pick<SavedChart, 'name' | 'description' | 'tableName'
7
7
  };
8
8
  export type ApiChartAsCodeListResponse = {
9
9
  status: 'ok';
10
- results: ChartAsCode[];
10
+ results: {
11
+ charts: ChartAsCode[];
12
+ missingIds: string[];
13
+ };
11
14
  };
12
15
  export type ApiChartAsCodeUpsertResponse = {
13
16
  status: 'ok';
@@ -25,7 +28,10 @@ export type DashboardAsCode = Pick<Dashboard, 'name' | 'description' | 'updatedA
25
28
  };
26
29
  export type ApiDashboardAsCodeListResponse = {
27
30
  status: 'ok';
28
- results: DashboardAsCode[];
31
+ results: {
32
+ dashboards: DashboardAsCode[];
33
+ missingIds: string[];
34
+ };
29
35
  };
30
36
  export type ApiDashboardAsCodeUpsertResponse = {
31
37
  status: 'ok';
@@ -12,7 +12,7 @@ type ImpelemntedTimeframe = TimeFrames.DAY | TimeFrames.WEEK | TimeFrames.MONTH
12
12
  type UnimplementedTimeframe = Exclude<TimeFrames, ImpelemntedTimeframe>;
13
13
  export declare const assertUnimplementedTimeframe: (timeframe: UnimplementedTimeframe) => never;
14
14
  export declare const getFieldIdForDateDimension: (fieldId: string, timeframe: TimeFrames) => string;
15
- export declare const getDateCalcUtils: (timeFrame: TimeFrames) => {
15
+ export declare const getDateCalcUtils: (timeFrame: TimeFrames, grain?: TimeFrames) => {
16
16
  forward: (date: Date) => Date;
17
17
  back: (date: Date) => Date;
18
18
  };
@@ -25,7 +25,7 @@ export declare const getMetricExplorerDataPoints: (dimension: Dimension, metric:
25
25
  dataPoints: Array<MetricExploreDataPoint>;
26
26
  isSegmentDimensionFiltered: boolean;
27
27
  };
28
- export declare const getMetricExplorerDataPointsWithCompare: (dimension: Dimension, compareDimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[], compareMetricRows: ResultRow[], query: MetricExplorerQuery) => {
28
+ export declare const getMetricExplorerDataPointsWithCompare: (dimension: Dimension, compareDimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[], compareMetricRows: ResultRow[], query: MetricExplorerQuery, timeFrame: TimeFrames) => {
29
29
  dataPoints: Array<MetricExploreDataPoint>;
30
30
  };
31
31
  /**
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAvailableCompareMetrics = exports.getAvailableSegmentDimensions = exports.getAvailableTimeDimensionsFromTables = exports.getDefaultTimeDimension = exports.getFirstAvailableTimeDimension = exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL = exports.getDefaultDateRangeForMetricTotal = exports.getDefaultDateRangeFromInterval = exports.getMetricExplorerDataPointsWithCompare = exports.getMetricExplorerDataPoints = exports.MAX_SEGMENT_DIMENSION_UNIQUE_VALUES = exports.getMetricExplorerDateRangeFilters = exports.getGrainForDateRange = exports.getDateRangeFromString = exports.METRICS_EXPLORER_DATE_FORMAT = exports.getDateCalcUtils = exports.getFieldIdForDateDimension = exports.assertUnimplementedTimeframe = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
6
+ const isoWeek_1 = tslib_1.__importDefault(require("dayjs/plugin/isoWeek"));
7
+ const weekOfYear_1 = tslib_1.__importDefault(require("dayjs/plugin/weekOfYear"));
6
8
  const lodash_1 = require("lodash");
7
9
  const uuid_1 = require("uuid");
8
10
  const conditionalRule_1 = require("../types/conditionalRule");
@@ -11,6 +13,8 @@ const metricsExplorer_1 = require("../types/metricsExplorer");
11
13
  const timeFrames_1 = require("../types/timeFrames");
12
14
  const assertUnreachable_1 = tslib_1.__importDefault(require("./assertUnreachable"));
13
15
  const item_1 = require("./item");
16
+ dayjs_1.default.extend(isoWeek_1.default);
17
+ dayjs_1.default.extend(weekOfYear_1.default);
14
18
  const assertUnimplementedTimeframe = (timeframe) => {
15
19
  switch (timeframe) {
16
20
  case timeFrames_1.TimeFrames.RAW:
@@ -52,28 +56,38 @@ const getFieldIdForDateDimension = (fieldId, timeframe) => {
52
56
  }
53
57
  };
54
58
  exports.getFieldIdForDateDimension = getFieldIdForDateDimension;
55
- const getDateCalcUtils = (timeFrame) => {
59
+ const getDateCalcUtils = (timeFrame, grain) => {
56
60
  switch (timeFrame) {
57
- case timeFrames_1.TimeFrames.DAY:
58
- return {
59
- forward: (date) => (0, dayjs_1.default)(date).add(1, 'day').toDate(),
60
- back: (date) => (0, dayjs_1.default)(date).subtract(1, 'day').toDate(),
61
- };
62
- case timeFrames_1.TimeFrames.WEEK:
63
- return {
64
- forward: (date) => (0, dayjs_1.default)(date).add(1, 'week').toDate(),
65
- back: (date) => (0, dayjs_1.default)(date).subtract(1, 'week').toDate(),
66
- };
67
61
  case timeFrames_1.TimeFrames.MONTH:
62
+ if (grain)
63
+ throw new Error(`Timeframe "${grain}" is not supported yet for this timeframe "${timeFrame}"`);
68
64
  return {
69
65
  forward: (date) => (0, dayjs_1.default)(date).add(1, 'month').toDate(),
70
66
  back: (date) => (0, dayjs_1.default)(date).subtract(1, 'month').toDate(),
71
67
  };
72
68
  case timeFrames_1.TimeFrames.YEAR:
69
+ // Handle week shift for previous year comparison and subtract what the amount of weeks is in a year
70
+ if (grain === timeFrames_1.TimeFrames.WEEK) {
71
+ return {
72
+ forward: (date) => (0, dayjs_1.default)(date)
73
+ // 52 weeks in a year
74
+ .add(52, 'weeks')
75
+ .startOf('isoWeek')
76
+ .toDate(),
77
+ back: (date) => (0, dayjs_1.default)(date)
78
+ // 52 weeks in a year
79
+ .subtract(52, 'weeks')
80
+ .startOf('isoWeek')
81
+ .toDate(),
82
+ };
83
+ }
73
84
  return {
74
85
  forward: (date) => (0, dayjs_1.default)(date).add(1, 'year').toDate(),
75
86
  back: (date) => (0, dayjs_1.default)(date).subtract(1, 'year').toDate(),
76
87
  };
88
+ case timeFrames_1.TimeFrames.DAY:
89
+ case timeFrames_1.TimeFrames.WEEK:
90
+ throw new Error(`Timeframe "${timeFrame}" is not supported yet`);
77
91
  default:
78
92
  return (0, exports.assertUnimplementedTimeframe)(timeFrame);
79
93
  }
@@ -176,7 +190,18 @@ const getMetricExplorerDataPoints = (dimension, metric, metricRows, segmentDimen
176
190
  };
177
191
  };
178
192
  exports.getMetricExplorerDataPoints = getMetricExplorerDataPoints;
179
- const getMetricExplorerDataPointsWithCompare = (dimension, compareDimension, metric, metricRows, compareMetricRows, query) => {
193
+ function offsetWeekCompareDates(groupByCompareMetricRows, timeFrame) {
194
+ return Object.fromEntries(Object.keys(groupByCompareMetricRows).map((compareDate) => {
195
+ const compareDateWeek = (0, dayjs_1.default)(compareDate).week();
196
+ const compareDateNextYear = (0, exports.getDateCalcUtils)(timeFrames_1.TimeFrames.YEAR, timeFrame).forward(new Date(compareDate));
197
+ const adjustedCompareDate = (0, dayjs_1.default)(compareDateNextYear)
198
+ .week(compareDateWeek)
199
+ .startOf('isoWeek')
200
+ .toISOString();
201
+ return [compareDate, adjustedCompareDate];
202
+ }));
203
+ }
204
+ const getMetricExplorerDataPointsWithCompare = (dimension, compareDimension, metric, metricRows, compareMetricRows, query, timeFrame) => {
180
205
  if (query.comparison === metricsExplorer_1.MetricExplorerComparison.NONE) {
181
206
  throw new Error('Comparison type is required');
182
207
  }
@@ -185,11 +210,17 @@ const getMetricExplorerDataPointsWithCompare = (dimension, compareDimension, met
185
210
  const compareDimensionId = (0, item_1.getItemId)(compareDimension);
186
211
  const groupByMetricRows = (0, lodash_1.groupBy)(metricRows, (row) => new Date(String(row[dimensionId].value.raw)).toISOString());
187
212
  const groupByCompareMetricRows = (0, lodash_1.groupBy)(compareMetricRows, (row) => new Date(String(row[compareDimensionId].value.raw)).toISOString());
188
- const offsetGroupByCompareMetricRows = (0, lodash_1.mapKeys)(groupByCompareMetricRows, (_, date) => query.comparison === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD
189
- ? (0, exports.getDateCalcUtils)(timeFrames_1.TimeFrames.YEAR)
190
- .forward(new Date(date))
191
- .toISOString()
192
- : date);
213
+ const offsetGroupByCompareMetricRows = (0, lodash_1.mapKeys)(groupByCompareMetricRows, (_, date) => {
214
+ if (query.comparison === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD) {
215
+ if (timeFrame === timeFrames_1.TimeFrames.WEEK) {
216
+ return offsetWeekCompareDates(groupByCompareMetricRows, timeFrame)[date];
217
+ }
218
+ return (0, exports.getDateCalcUtils)(timeFrames_1.TimeFrames.YEAR, timeFrame)
219
+ .forward(new Date(date))
220
+ .toISOString();
221
+ }
222
+ return date;
223
+ });
193
224
  const dates = new Set([
194
225
  ...Object.keys(groupByMetricRows),
195
226
  ...Object.keys(offsetGroupByCompareMetricRows),
@@ -245,7 +276,7 @@ const getDefaultDateRangeFromInterval = (timeInterval) => {
245
276
  ];
246
277
  case timeFrames_1.TimeFrames.WEEK:
247
278
  return [
248
- now.subtract(11, 'week').startOf('week').toDate(),
279
+ now.subtract(11, 'week').startOf('isoWeek').toDate(),
249
280
  now.toDate(),
250
281
  ];
251
282
  case timeFrames_1.TimeFrames.MONTH:
@@ -269,7 +300,10 @@ const getDefaultDateRangeForMetricTotal = (timeFrame) => {
269
300
  case timeFrames_1.TimeFrames.DAY:
270
301
  return [now.startOf('day').toDate(), now.endOf('day').toDate()];
271
302
  case timeFrames_1.TimeFrames.WEEK:
272
- return [now.startOf('week').toDate(), now.endOf('week').toDate()];
303
+ return [
304
+ now.startOf('isoWeek').toDate(),
305
+ now.endOf('isoWeek').toDate(),
306
+ ];
273
307
  case timeFrames_1.TimeFrames.MONTH:
274
308
  return [now.startOf('month').toDate(), now.endOf('month').toDate()];
275
309
  case timeFrames_1.TimeFrames.YEAR:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/common",
3
- "version": "0.1418.2",
3
+ "version": "0.1419.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [