@lightdash/common 0.1464.3 → 0.1466.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. package/LICENSE +6 -2
  2. package/dist/compiler/exploreCompiler.d.ts +1 -1
  3. package/dist/compiler/exploreCompiler.js +3 -7
  4. package/dist/compiler/exploreCompiler.mock.js +2 -0
  5. package/dist/compiler/lightdashProjectConfig.d.ts +19 -0
  6. package/dist/compiler/lightdashProjectConfig.js +41 -0
  7. package/dist/compiler/translator.js +9 -11
  8. package/dist/compiler/translator.mock.js +9 -0
  9. package/dist/ee/Ai/schemas.d.ts +2094 -0
  10. package/dist/ee/Ai/schemas.js +201 -0
  11. package/dist/ee/Ai/types.d.ts +136 -0
  12. package/dist/ee/Ai/types.js +12 -0
  13. package/dist/ee/commercialFeatureFlags.d.ts +5 -0
  14. package/dist/ee/commercialFeatureFlags.js +9 -0
  15. package/dist/ee/embed/index.d.ts +180 -0
  16. package/dist/ee/embed/index.js +73 -0
  17. package/dist/ee/index.d.ts +14 -0
  18. package/dist/ee/index.js +19 -0
  19. package/dist/ee/scim/errors.d.ts +32 -0
  20. package/dist/ee/scim/errors.js +24 -0
  21. package/dist/ee/scim/types.d.ts +119 -0
  22. package/dist/ee/scim/types.js +2 -0
  23. package/dist/index.d.ts +4 -1
  24. package/dist/index.js +3 -1
  25. package/dist/index.test.js +23 -0
  26. package/dist/schemas/json/lightdash-dbt-2.0.json +50 -6
  27. package/dist/schemas/json/lightdash-project-config-1.0.json +33 -1
  28. package/dist/types/analytics.d.ts +2 -0
  29. package/dist/types/analytics.js +2 -0
  30. package/dist/types/catalog.d.ts +3 -2
  31. package/dist/types/dashboard.d.ts +2 -2
  32. package/dist/types/dbt.d.ts +5 -2
  33. package/dist/types/dbt.js +7 -9
  34. package/dist/types/explore.d.ts +2 -1
  35. package/dist/types/field.d.ts +2 -1
  36. package/dist/types/lightdashProjectConfig.d.ts +8 -1
  37. package/dist/types/slack.d.ts +1 -0
  38. package/dist/types/slackSettings.js +1 -0
  39. package/dist/types/tags.d.ts +5 -0
  40. package/dist/utils/email.d.ts +1 -0
  41. package/dist/utils/email.js +3 -1
  42. package/dist/utils/item.d.ts +1 -0
  43. package/package.json +1 -1
@@ -0,0 +1,32 @@
1
+ import { type ScimSchemaType } from '..';
2
+ import { type ScimErrorPayload } from './types';
3
+ export declare class ScimError extends Error {
4
+ /**
5
+ * a SCIM-specific error type that provides additional context for the error.
6
+ * @type {ScimErrorPayload['scimType']}
7
+ */
8
+ scimType?: ScimErrorPayload['scimType'];
9
+ /**
10
+ * The "schemas" attribute is an array of Strings which allows the service provider to declare
11
+ * the schemas it supports. Each String is a URI and can be used to declare both standard and
12
+ * custom schemas.
13
+ * @type {ScimSchemaType[]}
14
+ */
15
+ schemas: ScimSchemaType.ERROR[];
16
+ /**
17
+ * A human-readable message in English, providing more information about the error.
18
+ * @type {string}
19
+ */
20
+ detail: string;
21
+ /**
22
+ * The HTTP status code applicable to this error, expressed as a string value.
23
+ * @type {string}
24
+ * */
25
+ status: string;
26
+ constructor({ detail, scimType, status, }: {
27
+ detail: string;
28
+ scimType?: ScimErrorPayload['scimType'];
29
+ status: number;
30
+ });
31
+ toJSON(): ScimErrorPayload;
32
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScimError = void 0;
4
+ class ScimError extends Error {
5
+ constructor({ detail, scimType, status, }) {
6
+ super(detail);
7
+ this.scimType = scimType;
8
+ this.schemas = [
9
+ 'urn:ietf:params:scim:api:messages:2.0:Error',
10
+ ];
11
+ this.detail = detail;
12
+ this.status = status.toString();
13
+ }
14
+ // Override the toJSON method to return the desired structure directly
15
+ toJSON() {
16
+ return {
17
+ ...(this.scimType && { scimType: this.scimType }),
18
+ schemas: this.schemas,
19
+ detail: this.detail,
20
+ status: this.status,
21
+ };
22
+ }
23
+ }
24
+ exports.ScimError = ScimError;
@@ -0,0 +1,119 @@
1
+ import { type ScimSchemaType } from '..';
2
+ export type SessionServiceAccount = {
3
+ organizationUuid: string;
4
+ };
5
+ export interface ScimResource {
6
+ schemas: string[];
7
+ id: string;
8
+ meta?: {
9
+ resourceType?: string;
10
+ created?: Date;
11
+ lastModified?: Date;
12
+ location?: string;
13
+ version?: string;
14
+ };
15
+ }
16
+ export interface ScimUser extends ScimResource {
17
+ schemas: string[];
18
+ userName: string;
19
+ name: {
20
+ givenName: string;
21
+ familyName: string;
22
+ };
23
+ active: boolean;
24
+ emails?: {
25
+ value: string;
26
+ primary: boolean;
27
+ }[];
28
+ }
29
+ export interface ScimGroup extends ScimResource {
30
+ schemas: string[];
31
+ id: string;
32
+ displayName: string;
33
+ members: ScimGroupMember[];
34
+ meta: ScimResource['meta'] & {
35
+ resourceType: 'Group';
36
+ created: Date;
37
+ lastModified: Date;
38
+ location: string;
39
+ };
40
+ }
41
+ export interface ScimGroupMember {
42
+ value: string;
43
+ display: string;
44
+ }
45
+ export type ScimErrorPayload = {
46
+ /**
47
+ * NOTE: this is taken from the SCIM spec here: https://datatracker.ietf.org/doc/html/rfc7644#section-3.7.3
48
+ * A SCIM-specific error type that provides additional context for the error.
49
+ * - 'invalidFilter': The specified filter syntax was invalid or the attribute and comparison combination is not supported.
50
+ * Applicable for GET (Section 3.4.2), POST (Search - Section 3.4.3), PATCH (Path Filter - Section 3.5.2).
51
+ * - 'tooMany': The filter yields too many results for the server to process.
52
+ * Applicable for GET (Section 3.4.2), POST (Search - Section 3.4.3).
53
+ * - 'uniqueness': One or more attribute values are already in use or reserved.
54
+ * Applicable for POST (Create - Section 3.3), PUT (Section 3.5.1), PATCH (Section 3.5.2).
55
+ * - 'mutability': The modification is incompatible with the target attribute's mutability.
56
+ * Applicable for PUT (Section 3.5.1), PATCH (Section 3.5.2).
57
+ * - 'invalidSyntax': The request body structure was invalid or did not conform to the schema.
58
+ * Applicable for POST (Search - Section 3.4.3, Create - Section 3.3, Bulk - Section 3.7), PUT (Section 3.5.1).
59
+ * - 'invalidPath': The "path" attribute was invalid or malformed.
60
+ * Applicable for PATCH (Section 3.5.2).
61
+ * - 'noTarget': The specified "path" did not yield an attribute that could be operated on.
62
+ * Applicable for PATCH (Section 3.5.2).
63
+ * - 'invalidValue': A required value was missing, or the value specified was not compatible with the operation.
64
+ * Applicable for GET (Section 3.4.2), POST (Create - Section 3.3, Query - Section 3.4.3), PUT (Section 3.5.1), PATCH (Section 3.5.2).
65
+ * - 'invalidVers': The specified SCIM protocol version is not supported.
66
+ * Applicable for GET (Section 3.4.2), POST (ALL), PUT (Section 3.5.1), PATCH (Section 3.5.2), DELETE (Section 3.6).
67
+ * - 'sensitive': The request cannot be completed due to sensitive information passed in the URI.
68
+ * Applicable for GET (Section 3.4.2).
69
+ */
70
+ scimType?: 'invalidFilter' | 'tooMany' | 'uniqueness' | 'mutability' | 'invalidSyntax' | 'invalidPath' | 'noTarget' | 'invalidValue' | 'invalidVers' | 'sensitive';
71
+ /**
72
+ * Array of schema URIs that describe the structure of the SCIM error response.
73
+ * Typically includes "urn:ietf:params:scim:api:messages:2.0:Error".
74
+ */
75
+ schemas: ScimSchemaType.ERROR[];
76
+ /**
77
+ * Human-readable description of the error, providing details about why the error occurred.
78
+ */
79
+ detail: string;
80
+ /**
81
+ * HTTP status code as a string, indicating the status of the response.
82
+ * For example: "400" for bad requests, "404" for not found, "500" for server errors.
83
+ */
84
+ status: string;
85
+ };
86
+ export interface ScimListResponse<T extends ScimResource> {
87
+ schemas: ScimSchemaType.LIST_RESPONSE[];
88
+ totalResults: number;
89
+ itemsPerPage: number;
90
+ startIndex: number;
91
+ Resources: T[];
92
+ }
93
+ export interface ScimUpsertGroup {
94
+ schemas: ScimSchemaType.GROUP[];
95
+ displayName: string;
96
+ members: ScimGroupMember[];
97
+ }
98
+ export type ScimUpsertUser = Omit<ScimUser, 'id'> & {
99
+ password?: string;
100
+ title?: string;
101
+ };
102
+ export type ScimOrganizationAccessToken = {
103
+ uuid: string;
104
+ organizationUuid: string;
105
+ createdAt: Date;
106
+ expiresAt: Date | null;
107
+ description: string;
108
+ lastUsedAt: Date | null;
109
+ rotatedAt: Date | null;
110
+ };
111
+ export type ScimOrganizationAccessTokenWithToken = ScimOrganizationAccessToken & {
112
+ token: string;
113
+ };
114
+ export type ApiCreateScimTokenRequest = Pick<ScimOrganizationAccessToken, 'expiresAt' | 'description'>;
115
+ export type ApiCreateScimTokenResponse = {
116
+ token: string;
117
+ expiresAt: Date;
118
+ };
119
+ export type CreateScimOrganizationAccessToken = Pick<ScimOrganizationAccessToken, 'organizationUuid' | 'expiresAt' | 'description'>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/index.d.ts CHANGED
@@ -36,6 +36,7 @@ import { type TableBase } from './types/table';
36
36
  import { type LightdashUser, type LoginOptions, type UserAllowedOrganization } from './types/user';
37
37
  import { type UserWarehouseCredentials } from './types/userWarehouseCredentials';
38
38
  import { type ValidationResponse } from './types/validation';
39
+ import type { ApiAiConversationMessages, ApiAiConversationResponse, ApiAiConversations, DecodedEmbed, EmbedUrl } from './ee';
39
40
  import { type AnyType } from './types/any';
40
41
  import { type ApiGetSpotlightTableConfig } from './types/api/spotlight';
41
42
  import { type ApiCatalogAnalyticsResults, type ApiCatalogMetadataResults, type ApiGetMetricsTree, type ApiMetricsCatalog } from './types/catalog';
@@ -53,6 +54,7 @@ export * from './compiler/exploreCompiler';
53
54
  export * from './compiler/filtersCompiler';
54
55
  export * from './compiler/translator';
55
56
  export * from './dbt/validation';
57
+ export * from './ee/index';
56
58
  export * from './pivotTable/pivotQueryResults';
57
59
  export { default as lightdashDbtYamlSchema } from './schemas/json/lightdash-dbt-2.0.json';
58
60
  export { default as lightdashProjectConfigSchema } from './schemas/json/lightdash-project-config-1.0.json';
@@ -216,6 +218,7 @@ export declare const SEED_ORG_2_ADMIN_EMAIL: {
216
218
  export declare const SEED_ORG_2_ADMIN_PASSWORD: {
217
219
  password: string;
218
220
  };
221
+ export declare const SEED_EMBED_SECRET = "zU3h50saDOO20czNFNRok";
219
222
  export declare const SEED_PROJECT: {
220
223
  project_uuid: string;
221
224
  name: string;
@@ -390,7 +393,7 @@ export type ApiAiGetDashboardSummaryResponse = {
390
393
  status: 'ok';
391
394
  results: DashboardSummary;
392
395
  };
393
- 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'] | ApiGetSpotlightTableConfig['results'];
396
+ 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 | EmbedUrl | DecodedEmbed | 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 | ApiAiConversations['results'] | ApiAiConversationMessages['results'] | ApiAiConversationResponse['results'] | 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'] | ApiGetSpotlightTableConfig['results'];
394
397
  export type ApiResponse<T extends ApiResults = ApiResults> = {
395
398
  status: 'ok';
396
399
  results: T;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getProjectDirectory = exports.deepEqual = exports.removeEmptyProperties = exports.formatRows = exports.itemsInMetricQuery = exports.getTableCalculationsFromItemsMap = exports.getMetricsFromItemsMap = exports.getFilterableDimensionsFromItemsMap = exports.getDimensionsFromItemsMap = exports.getItemMap = exports.getFieldMap = exports.getAxisName = exports.getDateGroupLabel = exports.getResultValueArray = exports.DbtProjectTypeLabels = exports.sensitiveDbtCredentialsFieldNames = exports.DBFieldTypes = exports.LightdashInstallType = exports.isLightdashMode = exports.LightdashMode = exports.isApiError = exports.hasInviteCode = exports.TableSelectionType = exports.hasSpecialCharacters = exports.snakeCaseName = exports.findFieldByIdInExplore = exports.getVisibleFields = exports.SEED_GROUP = exports.SEED_SPACE = exports.SEED_PROJECT = exports.SEED_ORG_2_ADMIN_PASSWORD = exports.SEED_ORG_2_ADMIN_EMAIL = exports.SEED_ORG_2_ADMIN = exports.SEED_ORG_2 = exports.SEED_ORG_1_ADMIN_PASSWORD = exports.SEED_ORG_1_ADMIN_EMAIL = exports.SEED_ORG_1_ADMIN = exports.SEED_ORG_1 = exports.hexToRGB = exports.replaceStringInArray = exports.toggleArrayValue = exports.hasIntersection = exports.validatePassword = exports.getPasswordSchema = exports.getEmailSchema = exports.validateEmail = exports.assertUnreachable = exports.lightdashProjectConfigSchema = exports.lightdashDbtYamlSchema = void 0;
3
+ exports.getProjectDirectory = exports.deepEqual = exports.removeEmptyProperties = exports.formatRows = exports.itemsInMetricQuery = exports.getTableCalculationsFromItemsMap = exports.getMetricsFromItemsMap = exports.getFilterableDimensionsFromItemsMap = exports.getDimensionsFromItemsMap = exports.getItemMap = exports.getFieldMap = exports.getAxisName = exports.getDateGroupLabel = exports.getResultValueArray = exports.DbtProjectTypeLabels = exports.sensitiveDbtCredentialsFieldNames = exports.DBFieldTypes = exports.LightdashInstallType = exports.isLightdashMode = exports.LightdashMode = exports.isApiError = exports.hasInviteCode = exports.TableSelectionType = exports.hasSpecialCharacters = exports.snakeCaseName = exports.findFieldByIdInExplore = exports.getVisibleFields = exports.SEED_GROUP = exports.SEED_SPACE = exports.SEED_PROJECT = exports.SEED_EMBED_SECRET = exports.SEED_ORG_2_ADMIN_PASSWORD = exports.SEED_ORG_2_ADMIN_EMAIL = exports.SEED_ORG_2_ADMIN = exports.SEED_ORG_2 = exports.SEED_ORG_1_ADMIN_PASSWORD = exports.SEED_ORG_1_ADMIN_EMAIL = exports.SEED_ORG_1_ADMIN = exports.SEED_ORG_1 = exports.hexToRGB = exports.replaceStringInArray = exports.toggleArrayValue = exports.hasIntersection = exports.validatePassword = exports.getPasswordSchema = exports.getEmailSchema = exports.validateEmail = exports.assertUnreachable = exports.lightdashProjectConfigSchema = exports.lightdashDbtYamlSchema = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
6
6
  const utc_1 = tslib_1.__importDefault(require("dayjs/plugin/utc"));
@@ -19,6 +19,7 @@ tslib_1.__exportStar(require("./compiler/exploreCompiler"), exports);
19
19
  tslib_1.__exportStar(require("./compiler/filtersCompiler"), exports);
20
20
  tslib_1.__exportStar(require("./compiler/translator"), exports);
21
21
  tslib_1.__exportStar(require("./dbt/validation"), exports);
22
+ tslib_1.__exportStar(require("./ee/index"), exports);
22
23
  tslib_1.__exportStar(require("./pivotTable/pivotQueryResults"), exports);
23
24
  var lightdash_dbt_2_0_json_1 = require("./schemas/json/lightdash-dbt-2.0.json");
24
25
  Object.defineProperty(exports, "lightdashDbtYamlSchema", { enumerable: true, get: function () { return tslib_1.__importDefault(lightdash_dbt_2_0_json_1).default; } });
@@ -222,6 +223,7 @@ exports.SEED_ORG_2_ADMIN_EMAIL = {
222
223
  exports.SEED_ORG_2_ADMIN_PASSWORD = {
223
224
  password: 'demo_password!',
224
225
  };
226
+ exports.SEED_EMBED_SECRET = 'zU3h50saDOO20czNFNRok';
225
227
  exports.SEED_PROJECT = {
226
228
  project_uuid: '3675b69e-8324-4110-bdca-059031aa8da3',
227
229
  name: 'Jaffle shop',
@@ -100,3 +100,26 @@ describe('getDateGroupLabel', () => {
100
100
  })).toEqual('Day date day'); // doesn't recognize (day) as a valid time frame
101
101
  });
102
102
  });
103
+ describe('email validation', () => {
104
+ test.each([
105
+ 'demo@lightdash.com',
106
+ 'de.mo@lightdash.com',
107
+ 'Demo@lightdash.com',
108
+ 'user+tag@domain.co.uk',
109
+ 'user@sub.domain.com',
110
+ 'user@domain.info',
111
+ 'user123@domain.org',
112
+ ])('valid email: %s', (email) => {
113
+ expect((0, _1.isValidEmailAddress)(email)).toBe(true);
114
+ });
115
+ test.each([
116
+ ['demo@lightdash', 'Missing top-level domain'],
117
+ ['de mo@lightdash.com', 'Whitespace in email'],
118
+ ['demo@lightdash..com', 'Double dot in domain'],
119
+ ['@lightdash.com', 'Missing local part'],
120
+ ['demo@.com', 'Missing domain name'],
121
+ ['demo@lightdash.c', 'Top-level domain too short'],
122
+ ])('invalid email: %s - %s', (email) => {
123
+ expect((0, _1.isValidEmailAddress)(email)).toBe(false);
124
+ });
125
+ });
@@ -190,11 +190,18 @@
190
190
  },
191
191
  "spotlight": {
192
192
  "type": "object",
193
- "description": "Set the visibility of a metric in Spotlight",
193
+ "description": "Set the visibility and/or categories of a metric in Spotlight",
194
194
  "properties": {
195
195
  "visibility": {
196
196
  "type": "string",
197
197
  "enum": ["show", "hide"]
198
+ },
199
+ "categories": {
200
+ "type": "array",
201
+ "items": {
202
+ "type": "string"
203
+ },
204
+ "description": "An array of categories for the metric in Spotlight"
198
205
  }
199
206
  },
200
207
  "anyOf": [
@@ -202,6 +209,11 @@
202
209
  "required": [
203
210
  "visibility"
204
211
  ]
212
+ },
213
+ {
214
+ "required": [
215
+ "categories"
216
+ ]
205
217
  }
206
218
  ]
207
219
  }
@@ -233,14 +245,24 @@
233
245
  },
234
246
  "spotlight": {
235
247
  "type": "object",
236
- "description": "Set the visibility of all metrics in this model in Spotlight",
248
+ "description": "Set the visibility and/or categories of a metric in Spotlight",
237
249
  "properties": {
238
250
  "visibility": {
239
251
  "type": "string",
240
252
  "enum": ["show", "hide"]
253
+ },
254
+ "categories": {
255
+ "type": "array",
256
+ "items": {
257
+ "type": "string"
258
+ },
259
+ "description": "An optional array of categories for all metrics in this model in Spotlight"
241
260
  }
242
261
  },
243
- "anyOf": [{ "required": ["visibility"] }]
262
+ "anyOf": [
263
+ { "required": ["visibility"] },
264
+ { "required": ["categories"] }
265
+ ]
244
266
  }
245
267
  }
246
268
  },
@@ -387,7 +409,7 @@
387
409
  },
388
410
  "spotlight": {
389
411
  "type": "object",
390
- "description": "Set the visibility of a metric in Spotlight",
412
+ "description": "Set the visibility and/or categories of a metric in Spotlight",
391
413
  "properties": {
392
414
  "visibility": {
393
415
  "type": "string",
@@ -395,6 +417,13 @@
395
417
  "show",
396
418
  "hide"
397
419
  ]
420
+ },
421
+ "categories": {
422
+ "type": "array",
423
+ "items": {
424
+ "type": "string"
425
+ },
426
+ "description": "An array of categories for the metric in Spotlight"
398
427
  }
399
428
  },
400
429
  "anyOf": [
@@ -402,6 +431,11 @@
402
431
  "required": [
403
432
  "visibility"
404
433
  ]
434
+ },
435
+ {
436
+ "required": [
437
+ "categories"
438
+ ]
405
439
  }
406
440
  ]
407
441
  }
@@ -681,14 +715,24 @@
681
715
  },
682
716
  "spotlight": {
683
717
  "type": "object",
684
- "description": "Set the visibility of a metric in Spotlight",
718
+ "description": "Set the visibility and/or categories of a metric in Spotlight",
685
719
  "properties": {
686
720
  "visibility": {
687
721
  "type": "string",
688
722
  "enum": ["show", "hide"]
723
+ },
724
+ "categories": {
725
+ "type": "array",
726
+ "items": {
727
+ "type": "string"
728
+ },
729
+ "description": "An array of categories for the metric in Spotlight"
689
730
  }
690
731
  },
691
- "anyOf": [{ "required": ["visibility"] }]
732
+ "anyOf": [
733
+ { "required": ["visibility"] },
734
+ { "required": ["categories"] }
735
+ ]
692
736
  }
693
737
  }
694
738
  }
@@ -9,7 +9,39 @@
9
9
  "default_visibility": {
10
10
  "type": "string",
11
11
  "enum": ["show", "hide"],
12
- "default": "show"
12
+ "default": "show",
13
+ "description": "The visibility of Spotlight metrics by default - if not provided, it will be set to 'show'"
14
+ },
15
+ "categories": {
16
+ "type": "object",
17
+ "description": "Define the categories that can be used in Spotlight on your model yml files",
18
+ "patternProperties": {
19
+ "^[a-zA-Z0-9_-]+$": {
20
+ "type": "object",
21
+ "properties": {
22
+ "label": {
23
+ "description": "The label of the category as it will be displayed in Spotlight",
24
+ "type": "string"
25
+ },
26
+ "color": {
27
+ "description": "The color of the category, if not provided, it will be set to gray",
28
+ "type": "string",
29
+ "enum": [
30
+ "gray",
31
+ "violet",
32
+ "red",
33
+ "orange",
34
+ "green",
35
+ "blue",
36
+ "indigo",
37
+ "pink",
38
+ "yellow"
39
+ ]
40
+ }
41
+ },
42
+ "required": ["label"]
43
+ }
44
+ }
13
45
  }
14
46
  }
15
47
  }
@@ -55,6 +55,8 @@ export declare enum QueryExecutionContext {
55
55
  SCHEDULED_CHART = "scheduledChart",
56
56
  SCHEDULED_DASHBOARD = "scheduledDashboard",
57
57
  CALCULATE_TOTAL = "calculateTotal",
58
+ EMBED = "embed",
59
+ AI = "ai",
58
60
  API = "api",
59
61
  CLI = "cli",
60
62
  SEMANTIC_VIEWER = "semanticViewer",
@@ -19,6 +19,8 @@ var QueryExecutionContext;
19
19
  QueryExecutionContext["SCHEDULED_CHART"] = "scheduledChart";
20
20
  QueryExecutionContext["SCHEDULED_DASHBOARD"] = "scheduledDashboard";
21
21
  QueryExecutionContext["CALCULATE_TOTAL"] = "calculateTotal";
22
+ QueryExecutionContext["EMBED"] = "embed";
23
+ QueryExecutionContext["AI"] = "ai";
22
24
  QueryExecutionContext["API"] = "api";
23
25
  QueryExecutionContext["CLI"] = "cli";
24
26
  QueryExecutionContext["SEMANTIC_VIEWER"] = "semanticViewer";
@@ -41,7 +41,7 @@ export type CatalogField = Pick<Field, 'name' | 'label' | 'fieldType' | 'tableLa
41
41
  tableName: string;
42
42
  tableGroupLabel?: string;
43
43
  tags?: string[];
44
- categories: Pick<Tag, 'name' | 'color' | 'tagUuid'>[];
44
+ categories: Pick<Tag, 'name' | 'color' | 'tagUuid' | 'yamlReference'>[];
45
45
  chartUsage: number | undefined;
46
46
  icon: CatalogItemIcon | null;
47
47
  };
@@ -51,7 +51,7 @@ export type CatalogTable = Pick<TableBase, 'name' | 'label' | 'groupLabel' | 'de
51
51
  type: CatalogType.Table;
52
52
  groupLabel?: string;
53
53
  tags?: string[];
54
- categories: Pick<Tag, 'name' | 'color' | 'tagUuid'>[];
54
+ categories: Pick<Tag, 'name' | 'color' | 'tagUuid' | 'yamlReference'>[];
55
55
  joinedTables?: CompiledExploreJoin[];
56
56
  chartUsage: number | undefined;
57
57
  icon: CatalogItemIcon | null;
@@ -129,6 +129,7 @@ export type CatalogItemWithTagUuids = CatalogItemSummary & {
129
129
  tagUuid: string;
130
130
  createdByUserUuid: string | null;
131
131
  createdAt: Date;
132
+ taggedViaYaml: boolean;
132
133
  }[];
133
134
  };
134
135
  export type CatalogItemsWithIcons = CatalogItemSummary & Pick<CatalogItem, 'icon'>;
@@ -165,8 +165,8 @@ export type DashboardAvailableFilters = {
165
165
  allFilterableFields: FilterableDimension[];
166
166
  };
167
167
  export type SavedChartsInfoForDashboardAvailableFilters = {
168
- tileUuid: DashboardChartTile['uuid'];
169
- savedChartUuid: NonNullable<DashboardChartTile['properties']['savedChartUuid']>;
168
+ tileUuid: string;
169
+ savedChartUuid: string;
170
170
  }[];
171
171
  export declare const isDashboardUnversionedFields: (data: UpdateDashboard) => data is DashboardUnversionedFields;
172
172
  export declare const isDashboardVersionedFields: (data: UpdateDashboard) => data is DashboardVersionedFields;
@@ -68,6 +68,7 @@ type DbtModelLightdashConfig = {
68
68
  };
69
69
  spotlight?: {
70
70
  visibility?: NonNullable<LightdashProjectConfig['spotlight']>['default_visibility'];
71
+ categories?: string[];
71
72
  };
72
73
  };
73
74
  export type DbtModelGroup = {
@@ -133,6 +134,7 @@ export type DbtColumnLightdashMetric = {
133
134
  default_time_dimension?: DefaultTimeDimension;
134
135
  spotlight?: {
135
136
  visibility?: NonNullable<LightdashProjectConfig['spotlight']>['default_visibility'];
137
+ categories?: string[];
136
138
  };
137
139
  } & DbtLightdashFieldTags;
138
140
  export type DbtModelLightdashMetric = DbtColumnLightdashMetric & Required<Pick<DbtColumnLightdashMetric, 'sql'>>;
@@ -248,8 +250,9 @@ type ConvertModelMetricArgs = {
248
250
  dimensionReference?: string;
249
251
  requiredAttributes?: Record<string, string | string[]>;
250
252
  spotlightConfig?: LightdashProjectConfig['spotlight'];
253
+ modelCategories?: string[];
251
254
  };
252
- export declare const convertModelMetric: ({ modelName, name, metric, source, tableLabel, dimensionReference, requiredAttributes, spotlightConfig, }: ConvertModelMetricArgs) => Metric;
255
+ export declare const convertModelMetric: ({ modelName, name, metric, source, tableLabel, dimensionReference, requiredAttributes, spotlightConfig, modelCategories, }: ConvertModelMetricArgs) => Metric;
253
256
  type ConvertColumnMetricArgs = Omit<ConvertModelMetricArgs, 'metric'> & {
254
257
  metric: DbtColumnLightdashMetric;
255
258
  dimensionName?: string;
@@ -257,7 +260,7 @@ type ConvertColumnMetricArgs = Omit<ConvertModelMetricArgs, 'metric'> & {
257
260
  requiredAttributes?: Record<string, string | string[]>;
258
261
  modelCategories?: string[];
259
262
  };
260
- export declare const convertColumnMetric: ({ modelName, dimensionName, dimensionSql, name, metric, source, tableLabel, requiredAttributes, spotlightConfig, }: ConvertColumnMetricArgs) => Metric;
263
+ export declare const convertColumnMetric: ({ modelName, dimensionName, dimensionSql, name, metric, source, tableLabel, requiredAttributes, spotlightConfig, modelCategories, }: ConvertColumnMetricArgs) => Metric;
261
264
  export declare enum DbtManifestVersion {
262
265
  V7 = "v7",
263
266
  V8 = "v8",
package/dist/types/dbt.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCompiledModels = exports.getModelsFromManifest = exports.DbtExposureType = exports.getLatestSupportedDbtManifestVersion = exports.getDbtManifestVersion = exports.DbtManifestVersion = exports.convertColumnMetric = exports.convertModelMetric = exports.isDbtRpcRunSqlResults = exports.convertToGroups = exports.isDbtRpcCompileResults = exports.isDbtRpcManifestResults = exports.isSupportedDbtAdapterType = exports.isSupportedDbtAdapter = exports.isV9MetricRef = exports.isDbtPackages = exports.isDbtRpcDocsGenerateResults = exports.buildModelGraph = exports.patchPathParts = exports.normaliseModelDatabase = exports.SupportedDbtAdapter = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const dependency_graph_1 = require("dependency-graph");
6
+ const lightdashProjectConfig_1 = require("../compiler/lightdashProjectConfig");
6
7
  const assertUnreachable_1 = tslib_1.__importDefault(require("../utils/assertUnreachable"));
7
8
  const item_1 = require("../utils/item");
8
9
  const errors_1 = require("./errors");
@@ -136,9 +137,11 @@ results) => 'results' in results &&
136
137
  'rows' in result.table &&
137
138
  Array.isArray(result.table.rows));
138
139
  exports.isDbtRpcRunSqlResults = isDbtRpcRunSqlResults;
139
- const convertModelMetric = ({ modelName, name, metric, source, tableLabel, dimensionReference, requiredAttributes, spotlightConfig, }) => {
140
+ const convertModelMetric = ({ modelName, name, metric, source, tableLabel, dimensionReference, requiredAttributes, spotlightConfig, modelCategories = [], }) => {
140
141
  const groups = (0, exports.convertToGroups)(metric.groups, metric.group_label);
141
142
  const spotlightVisibility = metric.spotlight?.visibility ?? spotlightConfig?.default_visibility;
143
+ const metricCategories = Array.from(new Set([...modelCategories, ...(metric.spotlight?.categories || [])]));
144
+ const spotlightCategories = (0, lightdashProjectConfig_1.getCategoriesFromResource)('metric', name, spotlightConfig, metricCategories);
142
145
  return {
143
146
  fieldType: field_1.FieldType.METRIC,
144
147
  name,
@@ -176,17 +179,11 @@ const convertModelMetric = ({ modelName, name, metric, source, tableLabel, dimen
176
179
  },
177
180
  }
178
181
  : null),
179
- ...(spotlightVisibility !== undefined
180
- ? {
181
- spotlight: {
182
- visibility: spotlightVisibility,
183
- },
184
- }
185
- : {}),
182
+ ...(0, lightdashProjectConfig_1.getSpotlightConfigurationForResource)(spotlightVisibility, spotlightCategories),
186
183
  };
187
184
  };
188
185
  exports.convertModelMetric = convertModelMetric;
189
- const convertColumnMetric = ({ modelName, dimensionName, dimensionSql, name, metric, source, tableLabel, requiredAttributes, spotlightConfig, }) => (0, exports.convertModelMetric)({
186
+ const convertColumnMetric = ({ modelName, dimensionName, dimensionSql, name, metric, source, tableLabel, requiredAttributes, spotlightConfig, modelCategories = [], }) => (0, exports.convertModelMetric)({
190
187
  modelName,
191
188
  name,
192
189
  metric: {
@@ -212,6 +209,7 @@ const convertColumnMetric = ({ modelName, dimensionName, dimensionSql, name, met
212
209
  }
213
210
  : null),
214
211
  spotlightConfig,
212
+ modelCategories,
215
213
  });
216
214
  exports.convertColumnMetric = convertColumnMetric;
217
215
  var DbtManifestVersion;
@@ -45,7 +45,8 @@ export type Explore = {
45
45
  sqlPath?: string;
46
46
  type?: ExploreType;
47
47
  spotlight?: {
48
- visibility: Required<NonNullable<LightdashProjectConfig['spotlight']>>['default_visibility'];
48
+ visibility: LightdashProjectConfig['spotlight']['default_visibility'];
49
+ categories?: string[];
49
50
  };
50
51
  };
51
52
  export declare enum InlineErrorType {
@@ -243,7 +243,8 @@ export interface Metric extends Field {
243
243
  requiredAttributes?: Record<string, string | string[]>;
244
244
  defaultTimeDimension?: DefaultTimeDimension;
245
245
  spotlight?: {
246
- visibility: Required<NonNullable<LightdashProjectConfig['spotlight']>>['default_visibility'];
246
+ visibility: LightdashProjectConfig['spotlight']['default_visibility'];
247
+ categories?: string[];
247
248
  };
248
249
  }
249
250
  export declare const isFilterableDimension: (dimension: Dimension) => dimension is FilterableDimension;
@@ -1,8 +1,15 @@
1
+ type SpotlightCategory = {
2
+ label: string;
3
+ color?: string;
4
+ };
1
5
  type SpotlightConfig = {
2
6
  default_visibility: 'show' | 'hide';
7
+ categories?: {
8
+ [yaml_reference: string]: SpotlightCategory;
9
+ };
3
10
  };
4
11
  export type LightdashProjectConfig = {
5
12
  spotlight: SpotlightConfig;
6
13
  };
7
- export declare const DEFAULT_SPOTLIGHT_CONFIG: Required<SpotlightConfig>;
14
+ export declare const DEFAULT_SPOTLIGHT_CONFIG: SpotlightConfig;
8
15
  export {};
@@ -13,6 +13,7 @@ export type ApiSlackCustomSettingsResponse = {
13
13
  export type SlackChannelProjectMapping = {
14
14
  projectUuid: string;
15
15
  slackChannelId: string;
16
+ availableTags: string[] | null;
16
17
  };
17
18
  export type SlackAppCustomSettings = {
18
19
  notificationChannel: string | null;
@@ -10,6 +10,7 @@ exports.slackRequiredScopes = [
10
10
  'channels:join',
11
11
  'groups:read',
12
12
  'users:read',
13
+ 'app_mentions:read',
13
14
  'files:write',
14
15
  'files:read',
15
16
  ];