@lightdash/cli 2.152.0 → 2.153.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/.tsbuildinfo +1 -1
- package/dist/dbt/models.d.ts +12 -1
- package/dist/dbt/models.d.ts.map +1 -1
- package/dist/dbt/models.js +25 -1
- package/dist/dbt/models.test.js +41 -0
- package/dist/handlers/compile.d.ts.map +1 -1
- package/dist/handlers/compile.js +17 -0
- package/package.json +3 -3
package/dist/dbt/models.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DbtDoc, DbtModelNode, DbtSchemaEditor, SupportedDbtVersions } from '@lightdash/common';
|
|
1
|
+
import { DbtDoc, DbtModelNode, DbtSchemaEditor, SupportedDbtVersions, type WarehouseCatalog } from '@lightdash/common';
|
|
2
2
|
import { WarehouseClient, WarehouseTableSchema } from '@lightdash/warehouses';
|
|
3
3
|
type CompiledModel = {
|
|
4
4
|
name: string;
|
|
@@ -14,6 +14,17 @@ type GetDatabaseTableForModelArgs = {
|
|
|
14
14
|
warehouseClient: WarehouseClient;
|
|
15
15
|
preserveColumnCase: boolean;
|
|
16
16
|
};
|
|
17
|
+
type TableRef = {
|
|
18
|
+
database: string;
|
|
19
|
+
schema: string;
|
|
20
|
+
table: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Only scalar leaves reachable through non-repeated structs can be queried as
|
|
24
|
+
* plain columns today, so generated YAML skips container nodes and anything
|
|
25
|
+
* inside a repeated node.
|
|
26
|
+
*/
|
|
27
|
+
export declare const isGeneratableColumn: (catalog: WarehouseCatalog, { database, schema, table }: TableRef, columnPath: string) => boolean;
|
|
17
28
|
export declare const getWarehouseTableForModel: ({ model, warehouseClient, preserveColumnCase, }: GetDatabaseTableForModelArgs) => Promise<WarehouseTableSchema>;
|
|
18
29
|
export declare const isDocBlock: (text?: string | undefined) => boolean;
|
|
19
30
|
type FindAndUpdateModelYamlArgs = {
|
package/dist/dbt/models.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/dbt/models.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,MAAM,EACN,YAAY,EACZ,eAAe,
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/dbt/models.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,MAAM,EACN,YAAY,EACZ,eAAe,EAKf,oBAAoB,EACpB,KAAK,gBAAgB,EACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAQ9E,KAAK,aAAa,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,KAAK,4BAA4B,GAAG;IAChC,KAAK,EAAE,aAAa,CAAC;IACrB,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,OAAO,CAAC;CAC/B,CAAC;AACF,KAAK,QAAQ,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,YACnB,gBAAgB,+BACI,QAAQ,cACzB,MAAM,KACnB,OAqBF,CAAC;AAEF,eAAO,MAAM,yBAAyB,oDAInC,4BAA4B,KAAG,OAAO,CAAC,oBAAoB,CAgC7D,CAAC;AAyDF,eAAO,MAAM,UAAU,UAAU,MAAM,GAAG,SAAS,KAAQ,OACX,CAAC;AA8BjD,KAAK,0BAA0B,GAAG;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,oBAAoB,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,oBAAoB,CAAC;CACrC,CAAC;AACF,eAAO,MAAM,sBAAsB,yFAShC,0BAA0B,KAAG,OAAO,CAAC;IACpC,UAAU,EAAE,eAAe,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;CAC1B,CAoKA,CAAC;AAEF,eAAO,MAAM,iBAAiB,WAClB,YAAY,EAAE,QAChB;IACF,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,KACF,OAAO,CAAC,aAAa,EAAE,CAoEzB,CAAC"}
|
package/dist/dbt/models.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCompiledModels = exports.findAndUpdateModelYaml = exports.isDocBlock = exports.getWarehouseTableForModel = void 0;
|
|
3
|
+
exports.getCompiledModels = exports.findAndUpdateModelYaml = exports.isDocBlock = exports.getWarehouseTableForModel = exports.isGeneratableColumn = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const common_1 = require("@lightdash/common");
|
|
6
6
|
const execa_1 = tslib_1.__importDefault(require("execa"));
|
|
@@ -9,6 +9,27 @@ const path = tslib_1.__importStar(require("path"));
|
|
|
9
9
|
const globalState_1 = tslib_1.__importDefault(require("../globalState"));
|
|
10
10
|
const styles = tslib_1.__importStar(require("../styles"));
|
|
11
11
|
const schema_1 = require("./schema");
|
|
12
|
+
/**
|
|
13
|
+
* Only scalar leaves reachable through non-repeated structs can be queried as
|
|
14
|
+
* plain columns today, so generated YAML skips container nodes and anything
|
|
15
|
+
* inside a repeated node.
|
|
16
|
+
*/
|
|
17
|
+
const isGeneratableColumn = (catalog, { database, schema, table }, columnPath) => {
|
|
18
|
+
const segments = columnPath.split('.');
|
|
19
|
+
return segments.every((_, index) => {
|
|
20
|
+
const prefix = segments.slice(0, index + 1).join('.');
|
|
21
|
+
const shape = (0, common_1.getCatalogNestedColumnShape)(catalog, database, schema, table, prefix);
|
|
22
|
+
const isLeaf = index === segments.length - 1;
|
|
23
|
+
// An array of scalars is exposed through its container entry, so it
|
|
24
|
+
// is generated like a leaf; every other container and anything under
|
|
25
|
+
// an array is left for the user to document by hand.
|
|
26
|
+
const isScalarArray = shape?.repeated === true && shape.record === false;
|
|
27
|
+
return isLeaf
|
|
28
|
+
? shape === undefined || isScalarArray
|
|
29
|
+
: shape?.repeated === false;
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
exports.isGeneratableColumn = isGeneratableColumn;
|
|
12
33
|
const getWarehouseTableForModel = async ({ model, warehouseClient, preserveColumnCase, }) => {
|
|
13
34
|
const tableRef = {
|
|
14
35
|
database: model.database,
|
|
@@ -26,6 +47,9 @@ const getWarehouseTableForModel = async ({ model, warehouseClient, preserveColum
|
|
|
26
47
|
throw new common_1.ParseError(`Expected to find materialised model at ${tableRef.database}.${tableRef.schema}.${tableRef.table} but couldn't find (or cannot access) ${missing}`);
|
|
27
48
|
}
|
|
28
49
|
return Object.entries(table).reduce((accumulator, [key, value]) => {
|
|
50
|
+
if (!(0, exports.isGeneratableColumn)(catalog, tableRef, key)) {
|
|
51
|
+
return accumulator;
|
|
52
|
+
}
|
|
29
53
|
const columnName = preserveColumnCase ? key : key.toLowerCase();
|
|
30
54
|
accumulator[columnName] = value;
|
|
31
55
|
return accumulator;
|
package/dist/dbt/models.test.js
CHANGED
|
@@ -1,7 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const common_1 = require("@lightdash/common");
|
|
3
4
|
const models_1 = require("./models");
|
|
4
5
|
describe('Models', () => {
|
|
6
|
+
describe('isGeneratableColumn', () => {
|
|
7
|
+
const ref = { database: 'db', schema: 'ds', table: 'sessions' };
|
|
8
|
+
const catalog = {
|
|
9
|
+
db: {
|
|
10
|
+
ds: {
|
|
11
|
+
sessions: {
|
|
12
|
+
visitId: common_1.DimensionType.NUMBER,
|
|
13
|
+
totals: common_1.DimensionType.STRING,
|
|
14
|
+
'totals.pageviews': common_1.DimensionType.NUMBER,
|
|
15
|
+
hits: common_1.DimensionType.STRING,
|
|
16
|
+
'hits.page': common_1.DimensionType.STRING,
|
|
17
|
+
'hits.page.pagePath': common_1.DimensionType.STRING,
|
|
18
|
+
tags: common_1.DimensionType.STRING,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
const shapes = {
|
|
24
|
+
totals: { repeated: false, record: true },
|
|
25
|
+
hits: { repeated: true, record: true },
|
|
26
|
+
'hits.page': { repeated: false, record: true },
|
|
27
|
+
tags: { repeated: true, record: false },
|
|
28
|
+
};
|
|
29
|
+
Object.entries(shapes).forEach(([path, shape]) => (0, common_1.setCatalogNestedColumnShape)(catalog, ref.database, ref.schema, ref.table, path, shape));
|
|
30
|
+
test('keeps scalar columns and leaves under plain structs', () => {
|
|
31
|
+
expect((0, models_1.isGeneratableColumn)(catalog, ref, 'visitId')).toBe(true);
|
|
32
|
+
expect((0, models_1.isGeneratableColumn)(catalog, ref, 'totals.pageviews')).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
test('keeps an array of scalars, exposed through its container entry', () => {
|
|
35
|
+
expect((0, models_1.isGeneratableColumn)(catalog, ref, 'tags')).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
test('skips struct and repeated record containers', () => {
|
|
38
|
+
expect((0, models_1.isGeneratableColumn)(catalog, ref, 'totals')).toBe(false);
|
|
39
|
+
expect((0, models_1.isGeneratableColumn)(catalog, ref, 'hits')).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
test('skips leaves beneath a repeated node', () => {
|
|
42
|
+
expect((0, models_1.isGeneratableColumn)(catalog, ref, 'hits.page')).toBe(false);
|
|
43
|
+
expect((0, models_1.isGeneratableColumn)(catalog, ref, 'hits.page.pagePath')).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
5
46
|
describe('isDocBlock', () => {
|
|
6
47
|
test('should match all doc block variations', () => {
|
|
7
48
|
expect((0, models_1.isDocBlock)("{{doc('user_id')}}")).toBe(true); // single quote
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/handlers/compile.ts"],"names":[],"mappings":"AAAA,OAAO,EAOH,OAAO,EACP,YAAY,
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/handlers/compile.ts"],"names":[],"mappings":"AAAA,OAAO,EAOH,OAAO,EACP,YAAY,EAkBf,MAAM,mBAAmB,CAAC;AAqB3B,OAAO,EAAE,iBAAiB,EAA8B,MAAM,eAAe,CAAC;AAsB9E,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAC/B,QAAQ,EAAE,CAAC,OAAO,GAAG,YAAY,CAAC,EAAE,CAAC;IACrC,iBAAiB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,uBAAuB,YACvB,OAAO,GAAG,YAAY,KAChC,OAIW,CAAC;AAEf,eAAO,MAAM,0BAA0B,YAC1B,OAAO,GAAG,YAAY,KAChC,OAAO,GAAG,YAiBZ,CAAC;AA6TF,eAAO,MAAM,cAAc,YACd,qBAAqB,KAC/B,OAAO,CAAC,oBAAoB,CA2a9B,CAAC;AAEF,eAAO,MAAM,OAAO,YACP,qBAAqB,KAC/B,OAAO,CAAC,CAAC,OAAO,GAAG,YAAY,CAAC,EAAE,CACO,CAAC;AAE7C,eAAO,MAAM,cAAc,oBACN,qBAAqB,kBAmCzC,CAAC"}
|
package/dist/handlers/compile.js
CHANGED
|
@@ -19,6 +19,22 @@ const apiClient_1 = require("./dbt/apiClient");
|
|
|
19
19
|
const compile_1 = require("./dbt/compile");
|
|
20
20
|
const getDbtVersion_1 = require("./dbt/getDbtVersion");
|
|
21
21
|
const getWarehouseClient_1 = tslib_1.__importDefault(require("./dbt/getWarehouseClient"));
|
|
22
|
+
// Compile-time behaviour the server gates behind a feature flag. Unreachable
|
|
23
|
+
// servers and older ones that don't know the flag both mean "off".
|
|
24
|
+
const getUnnestRepeatedColumns = async () => {
|
|
25
|
+
try {
|
|
26
|
+
const flag = await (0, apiClient_1.lightdashApi)({
|
|
27
|
+
method: 'GET',
|
|
28
|
+
url: `/api/v2/feature-flag/${common_1.FeatureFlags.UnnestRepeatedColumns}`,
|
|
29
|
+
body: undefined,
|
|
30
|
+
});
|
|
31
|
+
return flag.enabled;
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
globalState_1.default.debug(`> Could not read the ${common_1.FeatureFlags.UnnestRepeatedColumns} flag, compiling without it: ${(0, common_1.getErrorMessage)(e)}`);
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
22
38
|
const hasBlockingCompileError = (explore) => (0, common_1.isExploreError)(explore) ||
|
|
23
39
|
explore.warnings?.some((warning) => warning.type === common_1.InlineErrorType.WAREHOUSE_COLUMN_ERROR) === true;
|
|
24
40
|
exports.hasBlockingCompileError = hasBlockingCompileError;
|
|
@@ -414,6 +430,7 @@ const compileProject = async (options) => {
|
|
|
414
430
|
disableTimestampConversion: options.disableTimestampConversion,
|
|
415
431
|
allowPartialCompilation,
|
|
416
432
|
postProcessors: [common_1.preAggregatePostProcessor],
|
|
433
|
+
unnestRepeatedColumns: await getUnnestRepeatedColumns(),
|
|
417
434
|
});
|
|
418
435
|
const validatedExplores = options.validateWarehouseColumns === true &&
|
|
419
436
|
validationWarehouseClient
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightdash/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.153.1",
|
|
4
4
|
"description": "Lightdash CLI tool",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"unique-names-generator": "4.7.1",
|
|
46
46
|
"uuid": "11.1.1",
|
|
47
47
|
"yaml": "2.8.3",
|
|
48
|
-
"@lightdash/common": "2.
|
|
49
|
-
"@lightdash/warehouses": "2.
|
|
48
|
+
"@lightdash/common": "2.153.1",
|
|
49
|
+
"@lightdash/warehouses": "2.153.1"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/inquirer": "8.2.4",
|