@lightdash/common 0.1471.0 → 0.1473.0

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.d.ts CHANGED
@@ -130,6 +130,7 @@ export * from './types/userAttributes';
130
130
  export * from './types/userWarehouseCredentials';
131
131
  export * from './types/validation';
132
132
  export * from './types/warehouse';
133
+ export * from './utils/accessors';
133
134
  export * from './utils/additionalMetrics';
134
135
  export * from './utils/api';
135
136
  export { default as assertUnreachable } from './utils/assertUnreachable';
package/dist/index.js CHANGED
@@ -97,6 +97,7 @@ tslib_1.__exportStar(require("./types/userAttributes"), exports);
97
97
  tslib_1.__exportStar(require("./types/userWarehouseCredentials"), exports);
98
98
  tslib_1.__exportStar(require("./types/validation"), exports);
99
99
  tslib_1.__exportStar(require("./types/warehouse"), exports);
100
+ tslib_1.__exportStar(require("./utils/accessors"), exports);
100
101
  tslib_1.__exportStar(require("./utils/additionalMetrics"), exports);
101
102
  tslib_1.__exportStar(require("./utils/api"), exports);
102
103
  var assertUnreachable_1 = require("./utils/assertUnreachable");
@@ -340,14 +341,13 @@ const getDateGroupLabel = (axisItem) => {
340
341
  };
341
342
  exports.getDateGroupLabel = getDateGroupLabel;
342
343
  const getAxisName = ({ isAxisTheSameForAllSeries, selectedAxisIndex, axisReference, axisIndex, axisName, series, itemsMap, }) => {
343
- const defaultItem = itemsMap
344
- ? itemsMap[(series || [])[0]?.encode[axisReference].field]
345
- : undefined;
344
+ const itemIndex = (series || [])[0]?.encode[axisReference].field;
345
+ const defaultItem = itemsMap && itemIndex ? itemsMap[itemIndex] : undefined;
346
346
  const dateGroupName = defaultItem
347
347
  ? (0, exports.getDateGroupLabel)(defaultItem)
348
348
  : undefined;
349
349
  const fallbackSeriesName = series && series.length === 1
350
- ? series[0].name ||
350
+ ? series[0]?.name ||
351
351
  (defaultItem && (0, item_1.getItemLabelWithoutTableName)(defaultItem))
352
352
  : undefined;
353
353
  return !isAxisTheSameForAllSeries || selectedAxisIndex === axisIndex
@@ -4,7 +4,9 @@ exports.pivotResultsAsCsv = exports.pivotQueryResults = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const isNumber_1 = tslib_1.__importDefault(require("lodash/isNumber"));
6
6
  const last_1 = tslib_1.__importDefault(require("lodash/last"));
7
+ const errors_1 = require("../types/errors");
7
8
  const field_1 = require("../types/field");
9
+ const accessors_1 = require("../utils/accessors");
8
10
  const formatting_1 = require("../utils/formatting");
9
11
  const isRecursiveRecord = (value) => typeof value === 'object' && value !== null;
10
12
  const create2DArray = (rows, columns, value = null) => Array.from({ length: rows }, () => Array.from({ length: columns }, () => value));
@@ -19,6 +21,9 @@ const setIndexByKey = (obj, keys, value) => {
19
21
  return false;
20
22
  }
21
23
  const [key, ...rest] = keys;
24
+ if (key === undefined) {
25
+ throw new errors_1.UnexpectedIndexError(`setIndexByKey: Cannot get key from keys ${keys.length}`);
26
+ }
22
27
  if (rest.length === 0) {
23
28
  if (obj[key] === undefined) {
24
29
  // eslint-disable-next-line no-param-reassign
@@ -42,6 +47,9 @@ const getIndexByKey = (obj, keys) => {
42
47
  throw new Error('Cannot get key from empty keys array');
43
48
  }
44
49
  const [key, ...rest] = keys;
50
+ if (key === undefined) {
51
+ throw new errors_1.UnexpectedServerError(`getIndexByKey: Cannot get key from keys ${keys.length}`);
52
+ }
45
53
  if (rest.length === 0) {
46
54
  const value = obj[key];
47
55
  if (typeof value !== 'number') {
@@ -79,8 +87,11 @@ const getAllIndices = (obj) => Object.values(obj).reduce((acc, value) => {
79
87
  }, []);
80
88
  const getAllIndicesByKey = (obj, keys) => {
81
89
  const [key, ...rest] = keys;
90
+ if (key === undefined) {
91
+ throw new errors_1.UnexpectedIndexError('Cannot set key on undefined');
92
+ }
82
93
  if (rest.length === 0) {
83
- const value = obj[key];
94
+ const value = (0, accessors_1.getObjectValue)(obj, key);
84
95
  if ((0, isNumber_1.default)(value)) {
85
96
  return [value];
86
97
  }
@@ -119,7 +130,10 @@ const getColSpanByKey = (currentColumnPosition, obj, keys) => {
119
130
  const combinedRetrofit = (data, getField, getFieldLabel) => {
120
131
  const indexValues = data.indexValues.length ? data.indexValues : [[]];
121
132
  const baseIdInfo = (0, last_1.default)(data.headerValues);
122
- const uniqueIdsForDataValueColumns = Array(data.headerValues[0].length);
133
+ if (data.headerValues[0] === undefined) {
134
+ throw new errors_1.UnexpectedIndexError('combinedRetrofit: Cannot get header values');
135
+ }
136
+ const uniqueIdsForDataValueColumns = Array((0, accessors_1.getArrayValue)(data.headerValues, 0).length);
123
137
  data.headerValues.forEach((headerRow) => {
124
138
  headerRow.forEach((headerColValue, colIndex) => {
125
139
  uniqueIdsForDataValueColumns[colIndex] = `${(uniqueIdsForDataValueColumns[colIndex] ?? '') +
@@ -170,12 +184,13 @@ const combinedRetrofit = (data, getField, getFieldLabel) => {
170
184
  columnType: 'indexValue',
171
185
  };
172
186
  });
173
- const remappedDataValues = data.dataValues[rowIndex].map((dataValue, colIndex) => {
187
+ const remappedDataValues = (0, accessors_1.getArrayValue)(data.dataValues, rowIndex).map((dataValue, colIndex) => {
174
188
  const baseIdInfoForCol = baseIdInfo
175
189
  ? baseIdInfo[colIndex]
176
190
  : undefined;
177
191
  const baseId = baseIdInfoForCol?.fieldId;
178
- const id = uniqueIdsForDataValueColumns[colIndex] + colIndex;
192
+ const id = (0, accessors_1.getArrayValue)(uniqueIdsForDataValueColumns, colIndex) +
193
+ colIndex;
179
194
  return {
180
195
  baseId,
181
196
  fieldId: id,
@@ -286,19 +301,19 @@ const pivotQueryResults = ({ pivotConfig, metricQuery, rows, options, getField,
286
301
  for (let nRow = 0; nRow < N_ROWS; nRow += 1) {
287
302
  const row = rows[nRow];
288
303
  for (let nMetric = 0; nMetric < metrics.length; nMetric += 1) {
289
- const metric = metrics[nMetric];
290
304
  const indexRowValues = indexDimensions
291
305
  .map((fieldId) => ({
292
306
  type: 'value',
293
307
  fieldId,
294
- value: row[fieldId].value,
308
+ value: (0, accessors_1.getObjectValue)(row, fieldId).value,
295
309
  colSpan: 1,
296
310
  }))
297
311
  .concat(pivotConfig.metricsAsRows
298
312
  ? [
299
313
  {
300
314
  type: 'label',
301
- fieldId: metric.fieldId,
315
+ fieldId: (0, accessors_1.getArrayValue)(metrics, nMetric)
316
+ .fieldId,
302
317
  },
303
318
  ]
304
319
  : []);
@@ -306,7 +321,7 @@ const pivotQueryResults = ({ pivotConfig, metricQuery, rows, options, getField,
306
321
  .map((fieldId) => ({
307
322
  type: 'value',
308
323
  fieldId,
309
- value: row[fieldId].value,
324
+ value: (0, accessors_1.getObjectValue)(row, fieldId).value,
310
325
  colSpan: 1,
311
326
  }))
312
327
  .concat(pivotConfig.metricsAsRows
@@ -314,7 +329,8 @@ const pivotQueryResults = ({ pivotConfig, metricQuery, rows, options, getField,
314
329
  : [
315
330
  {
316
331
  type: 'label',
317
- fieldId: metric.fieldId,
332
+ fieldId: (0, accessors_1.getArrayValue)(metrics, nMetric)
333
+ .fieldId,
318
334
  },
319
335
  ]);
320
336
  // Write the index values
@@ -333,7 +349,7 @@ const pivotQueryResults = ({ pivotConfig, metricQuery, rows, options, getField,
333
349
  }
334
350
  }
335
351
  const headerValues = headerValuesT[0]?.map((_, colIndex) => headerValuesT.map((row, rowIndex) => {
336
- const cell = row[colIndex];
352
+ const cell = (0, accessors_1.getArrayValue)(row, colIndex);
337
353
  if (cell.type === 'label') {
338
354
  return cell;
339
355
  }
@@ -363,7 +379,7 @@ const pivotQueryResults = ({ pivotConfig, metricQuery, rows, options, getField,
363
379
  const row = rows[nRow];
364
380
  for (let nMetric = 0; nMetric < metrics.length; nMetric += 1) {
365
381
  const metric = metrics[nMetric];
366
- const { value } = row[metric.fieldId];
382
+ const { value } = row?.[metric.fieldId] ?? {};
367
383
  const rowKeys = [
368
384
  ...indexDimensions.map((d) => row[d].value.raw),
369
385
  ...(pivotConfig.metricsAsRows ? [metric.fieldId] : []),
@@ -57,6 +57,11 @@ export declare class UnexpectedServerError extends LightdashError {
57
57
  [key: string]: AnyType;
58
58
  });
59
59
  }
60
+ export declare class UnexpectedIndexError extends LightdashError {
61
+ constructor(message?: string, data?: {
62
+ [key: string]: AnyType;
63
+ });
64
+ }
60
65
  export declare class UnexpectedGitError extends LightdashError {
61
66
  constructor(message?: string, data?: {
62
67
  [key: string]: AnyType;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getErrorMessage = exports.UnexpectedGoogleSheetsError = exports.SlackInstallationNotFoundError = exports.KnexPaginationError = exports.NotEnoughResults = exports.MissingConfigError = exports.AlreadyExistsError = exports.AlreadyProcessingError = exports.SmptError = exports.WarehouseQueryError = exports.WarehouseConnectionError = exports.InvalidUser = exports.NotFoundError = exports.DbtError = exports.FieldReferenceError = exports.CompileError = exports.ParseError = exports.UnexpectedDatabaseError = exports.UnexpectedGitError = exports.UnexpectedServerError = exports.MissingWarehouseCredentialsError = exports.MissingCatalogEntryError = exports.NonCompiledModelError = exports.ParameterError = exports.ExpiredError = exports.NotExistsError = exports.AuthorizationError = exports.DeactivatedAccountError = exports.ForbiddenError = exports.LightdashError = void 0;
3
+ exports.getErrorMessage = exports.UnexpectedGoogleSheetsError = exports.SlackInstallationNotFoundError = exports.KnexPaginationError = exports.NotEnoughResults = exports.MissingConfigError = exports.AlreadyExistsError = exports.AlreadyProcessingError = exports.SmptError = exports.WarehouseQueryError = exports.WarehouseConnectionError = exports.InvalidUser = exports.NotFoundError = exports.DbtError = exports.FieldReferenceError = exports.CompileError = exports.ParseError = exports.UnexpectedDatabaseError = exports.UnexpectedGitError = exports.UnexpectedIndexError = exports.UnexpectedServerError = exports.MissingWarehouseCredentialsError = exports.MissingCatalogEntryError = exports.NonCompiledModelError = exports.ParameterError = exports.ExpiredError = exports.NotExistsError = exports.AuthorizationError = exports.DeactivatedAccountError = exports.ForbiddenError = exports.LightdashError = void 0;
4
4
  class LightdashError extends Error {
5
5
  constructor({ message, name, statusCode, data }) {
6
6
  super(message);
@@ -120,6 +120,17 @@ class UnexpectedServerError extends LightdashError {
120
120
  }
121
121
  }
122
122
  exports.UnexpectedServerError = UnexpectedServerError;
123
+ class UnexpectedIndexError extends LightdashError {
124
+ constructor(message = 'Invalid index in array.', data = {}) {
125
+ super({
126
+ message,
127
+ name: 'UnexpectedIndexError',
128
+ statusCode: 500,
129
+ data,
130
+ });
131
+ }
132
+ }
133
+ exports.UnexpectedIndexError = UnexpectedIndexError;
123
134
  class UnexpectedGitError extends LightdashError {
124
135
  constructor(message = 'Unexpected error in Git adapter', data = {}) {
125
136
  super({
@@ -174,6 +174,7 @@ export interface DbtCloudIDEProjectConfig extends DbtProjectConfigBase {
174
174
  api_key: string;
175
175
  environment_id: string;
176
176
  discovery_api_endpoint?: string;
177
+ tags?: string[];
177
178
  }
178
179
  export interface DbtGithubProjectConfig extends DbtProjectCompilerBase {
179
180
  type: DbtProjectType.GITHUB;
@@ -0,0 +1,2 @@
1
+ export declare const getArrayValue: <T>(obj: ArrayLike<T> | undefined, key: number, errorMessage?: string) => T;
2
+ export declare const getObjectValue: <T>(obj: Record<string | number, T> | undefined, key: string | number, errorMessage?: string) => T;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getObjectValue = exports.getArrayValue = void 0;
4
+ const errors_1 = require("../types/errors");
5
+ const getArrayValue = (obj, key, errorMessage) => {
6
+ if (obj === undefined) {
7
+ throw new errors_1.UnexpectedIndexError(errorMessage || `Cannot get key "${key}" value from empty array`);
8
+ }
9
+ const value = obj[key];
10
+ if (value === undefined) {
11
+ console.trace();
12
+ throw new errors_1.UnexpectedIndexError(errorMessage || `Cannot get key "${key}" value from array`);
13
+ }
14
+ return value;
15
+ };
16
+ exports.getArrayValue = getArrayValue;
17
+ const getObjectValue = (obj, key, errorMessage) => {
18
+ if (obj === undefined) {
19
+ throw new errors_1.UnexpectedIndexError(errorMessage || `Cannot get key "${key}" value from empty object`);
20
+ }
21
+ const value = obj[key];
22
+ if (value === undefined) {
23
+ console.trace();
24
+ throw new errors_1.UnexpectedIndexError(errorMessage || `Cannot get key "${key}" value from object`);
25
+ }
26
+ return value;
27
+ };
28
+ exports.getObjectValue = getObjectValue;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isValidTimezone = exports.isValidFrequency = exports.getHumanReadableCronExpression = exports.getTimezoneLabel = exports.formatMinutesOffset = exports.getTzMinutesOffset = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const cronstrue_1 = tslib_1.__importDefault(require("cronstrue"));
6
+ const accessors_1 = require("./accessors");
6
7
  function getTzMinutesOffset(oldTz, newTz) {
7
8
  const date = new Date();
8
9
  const oldFormattedString = date.toLocaleString('en-US', {
@@ -48,7 +49,8 @@ function getHumanReadableCronExpression(cronExpression, timezone) {
48
49
  const valueWithTimezone = value
49
50
  .replaceAll(' PM', ` PM (UTC ${offsetString})`)
50
51
  .replaceAll(' AM', ` AM (UTC ${offsetString})`);
51
- return valueWithTimezone[0].toLowerCase() + valueWithTimezone.slice(1);
52
+ return ((0, accessors_1.getArrayValue)(valueWithTimezone, 0).toLowerCase() +
53
+ valueWithTimezone.slice(1));
52
54
  }
53
55
  exports.getHumanReadableCronExpression = getHumanReadableCronExpression;
54
56
  function isValidFrequency(cronExpression) {
@@ -62,6 +64,9 @@ function isValidFrequency(cronExpression) {
62
64
  return false;
63
65
  }
64
66
  const [minutePart] = cronParts;
67
+ if (minutePart === undefined) {
68
+ return false;
69
+ }
65
70
  if (minutePart.includes('/') ||
66
71
  minutePart.includes(',') ||
67
72
  minutePart.includes('-')) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/common",
3
- "version": "0.1471.0",
3
+ "version": "0.1473.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [