@lightdash/common 0.1418.2 → 0.1419.1

Sign up to get free protection for your applications and to get access to all the features.
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": [