@lightdash/cli 2.174.0 → 2.176.0
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/handlers/compile.d.ts.map +1 -1
- package/dist/handlers/compile.js +4 -7
- package/dist/handlers/compile.test.js +5 -1
- package/dist/handlers/compileProject.test.js +31 -0
- package/dist/handlers/compileWarehouseColumnValidation.test.js +1 -1
- package/dist/lightdash/loader.d.ts +3 -12
- package/dist/lightdash/loader.d.ts.map +1 -1
- package/dist/lightdash/loader.js +8 -49
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAgTF,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
|
@@ -133,14 +133,11 @@ const getExploresFromLightdashYmlProject = async ({ projectDir, lightdashProject
|
|
|
133
133
|
}
|
|
134
134
|
const adapterType = lightdashProjectConfig.warehouse.type;
|
|
135
135
|
globalState_1.default.debug(`> Using adapter type from lightdash.config.yml: ${adapterType}`);
|
|
136
|
-
// Convert Lightdash models to DbtModelNode format
|
|
137
|
-
const validModels = (0, common_1.convertLightdashModelsToDbtModels)(lightdashModels);
|
|
138
|
-
if (validModels.length === 0) {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
globalState_1.default.debug('> Skipping warehouse catalog (types in YAML)');
|
|
142
136
|
const warehouseSqlBuilder = (0, warehouses_1.warehouseSqlBuilderFromType)(adapterType, startOfWeek);
|
|
143
|
-
const validExplores = await (0, common_1.
|
|
137
|
+
const validExplores = await (0, common_1.compileLightdashModels)({
|
|
138
|
+
models: lightdashModels,
|
|
139
|
+
warehouseSqlBuilder,
|
|
140
|
+
lightdashProjectConfig,
|
|
144
141
|
disableTimestampConversion,
|
|
145
142
|
allowPartialCompilation,
|
|
146
143
|
postProcessors: [common_1.preAggregatePostProcessor],
|
|
@@ -116,7 +116,7 @@ dimensions:
|
|
|
116
116
|
});
|
|
117
117
|
test('should allow partial compilation by default and allow it to be disabled explicitly', async () => {
|
|
118
118
|
vi.spyOn(lightdashLoader, 'loadLightdashModels').mockResolvedValue([
|
|
119
|
-
modelWithBrokenMetric,
|
|
119
|
+
{ ...modelWithBrokenMetric, sourcePath: 'models/test_model.yml' },
|
|
120
120
|
]);
|
|
121
121
|
const errorOutput = [];
|
|
122
122
|
vi.spyOn(console, 'error').mockImplementation((...args) => {
|
|
@@ -144,4 +144,8 @@ dimensions:
|
|
|
144
144
|
expect.stringContaining('Compiled 1 explores, SUCCESS=0 ERRORS=1'),
|
|
145
145
|
]));
|
|
146
146
|
});
|
|
147
|
+
test('rejects malformed native YAML instead of compiling only the valid models', async () => {
|
|
148
|
+
await promises_1.default.writeFile(path.join(tempDir, 'lightdash/models/broken.yml'), 'type: model\ndimensions: [');
|
|
149
|
+
await expect((0, compile_1.compile)(getCompileOptions(tempDir))).rejects.toThrow(/broken.yml/);
|
|
150
|
+
});
|
|
147
151
|
});
|
|
@@ -10,6 +10,7 @@ const context_1 = require("../dbt/context");
|
|
|
10
10
|
const manifest_1 = require("../dbt/manifest");
|
|
11
11
|
const validation_1 = require("../dbt/validation");
|
|
12
12
|
const loader_1 = require("../lightdash/loader");
|
|
13
|
+
const projectType_1 = require("../lightdash/projectType");
|
|
13
14
|
const compile_1 = require("./compile");
|
|
14
15
|
const apiClient_1 = require("./dbt/apiClient");
|
|
15
16
|
const compile_2 = require("./dbt/compile");
|
|
@@ -138,6 +139,36 @@ describe('compileProject completeness', () => {
|
|
|
138
139
|
vi.restoreAllMocks();
|
|
139
140
|
await promises_1.default.rm(tempDir, { recursive: true, force: true });
|
|
140
141
|
});
|
|
142
|
+
test.each([false, true])('compiles dbt when ignored YAML is malformed, symlinked models: %s', async (symlinkedModels) => {
|
|
143
|
+
const projectDir = path_1.default.join(tempDir, 'dbt-project');
|
|
144
|
+
const modelsDir = symlinkedModels
|
|
145
|
+
? path_1.default.join(tempDir, 'shared-models')
|
|
146
|
+
: path_1.default.join(projectDir, 'models');
|
|
147
|
+
await promises_1.default.mkdir(projectDir);
|
|
148
|
+
await promises_1.default.mkdir(modelsDir);
|
|
149
|
+
if (symlinkedModels)
|
|
150
|
+
await promises_1.default.symlink(modelsDir, path_1.default.join(projectDir, 'models'));
|
|
151
|
+
await promises_1.default.writeFile(path_1.default.join(projectDir, 'dbt_project.yml'), 'name: test_project\nversion: "1.0"\nconfig-version: 2\n');
|
|
152
|
+
await promises_1.default.writeFile(path_1.default.join(projectDir, '.dbtignore'), 'models/archived.yml\n');
|
|
153
|
+
await promises_1.default.writeFile(path_1.default.join(modelsDir, 'schema.yml'), 'version: 2\nmodels:\n - name: orders\n');
|
|
154
|
+
await promises_1.default.writeFile(path_1.default.join(modelsDir, 'archived.yml'), 'archived: [unfinished\n');
|
|
155
|
+
const loader = await vi.importActual('../lightdash/loader');
|
|
156
|
+
vi.mocked(loader_1.findLightdashModelFiles).mockImplementationOnce(loader.findLightdashModelFiles);
|
|
157
|
+
vi.mocked(loader_1.loadLightdashModels).mockImplementationOnce(loader.loadLightdashModels);
|
|
158
|
+
vi.mocked(manifest_1.loadManifest).mockResolvedValue(manifest({
|
|
159
|
+
'model.test.orders': dbtNode('model.test.orders', 'model', true),
|
|
160
|
+
}));
|
|
161
|
+
vi.mocked(compile_2.maybeCompileModelsAndJoins).mockResolvedValue({
|
|
162
|
+
compiledModelIds: ['model.test.orders'],
|
|
163
|
+
originallySelectedModelIds: undefined,
|
|
164
|
+
});
|
|
165
|
+
await expect((0, projectType_1.detectProjectType)({ projectDir })).resolves.toMatchObject({ type: projectType_1.CliProjectType.Dbt });
|
|
166
|
+
const result = await (0, compile_1.compileProject)(compileOptions(projectDir));
|
|
167
|
+
expect(result.explores.map((explore) => explore.name)).toEqual([
|
|
168
|
+
'orders',
|
|
169
|
+
]);
|
|
170
|
+
expect(compile_2.maybeCompileModelsAndJoins).toHaveBeenCalled();
|
|
171
|
+
});
|
|
141
172
|
test('reports an unselected model and seed manifest as complete', async () => {
|
|
142
173
|
const projectManifest = manifest({
|
|
143
174
|
'model.test.orders': dbtNode('model.test.orders', 'model', true),
|
|
@@ -454,7 +454,7 @@ describe('compile warehouse column validation', () => {
|
|
|
454
454
|
describe('lightdash yml projects', () => {
|
|
455
455
|
beforeEach(async () => {
|
|
456
456
|
vi.mocked(loader_1.loadLightdashModels).mockResolvedValue([
|
|
457
|
-
lightdashYmlModel,
|
|
457
|
+
{ ...lightdashYmlModel, sourcePath: 'models/test_model.yml' },
|
|
458
458
|
]);
|
|
459
459
|
await promises_1.default.writeFile(path.join(tempDir, 'lightdash.config.yml'), 'warehouse:\n type: postgres\n');
|
|
460
460
|
});
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
import { type LightdashModel } from '@lightdash/common';
|
|
5
|
-
/**
|
|
6
|
-
* Load a single Lightdash YAML model file
|
|
7
|
-
*/
|
|
8
|
-
export declare function loadLightdashModel(filePath: string): Promise<LightdashModel>;
|
|
1
|
+
import { type LightdashModelWithSource } from '@lightdash/common';
|
|
2
|
+
export { loadLightdashModel } from '@lightdash/common/lightdash/loader';
|
|
9
3
|
/**
|
|
10
4
|
* Find all Lightdash YAML model files in a directory
|
|
11
5
|
* Looks for files in models/ or lightdash/models/ directory that contain `type: model`
|
|
@@ -14,8 +8,5 @@ export declare function loadLightdashModel(filePath: string): Promise<LightdashM
|
|
|
14
8
|
* to avoid false positives from other YAML files (e.g., content-as-code spaces).
|
|
15
9
|
*/
|
|
16
10
|
export declare function findLightdashModelFiles(projectDir: string): Promise<string[]>;
|
|
17
|
-
|
|
18
|
-
* Load all Lightdash YAML models from a project directory
|
|
19
|
-
*/
|
|
20
|
-
export declare function loadLightdashModels(projectDir: string): Promise<LightdashModel[]>;
|
|
11
|
+
export declare function loadLightdashModels(projectDir: string): Promise<LightdashModelWithSource[]>;
|
|
21
12
|
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/lightdash/loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/lightdash/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAOlE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAoBxE;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CACzC,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CAqDnB;AAED,wBAAsB,mBAAmB,CACrC,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAGrC"}
|
package/dist/lightdash/loader.js
CHANGED
|
@@ -1,44 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Loader for Lightdash YAML model files
|
|
4
|
-
*/
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.loadLightdashModel =
|
|
3
|
+
exports.loadLightdashModel = void 0;
|
|
7
4
|
exports.findLightdashModelFiles = findLightdashModelFiles;
|
|
8
5
|
exports.loadLightdashModels = loadLightdashModels;
|
|
9
6
|
const tslib_1 = require("tslib");
|
|
10
|
-
const
|
|
7
|
+
const loader_1 = require("@lightdash/common/lightdash/loader");
|
|
11
8
|
const fs = tslib_1.__importStar(require("fs"));
|
|
12
9
|
const yaml = tslib_1.__importStar(require("js-yaml"));
|
|
13
10
|
const path = tslib_1.__importStar(require("path"));
|
|
14
11
|
const globalState_1 = tslib_1.__importDefault(require("../globalState"));
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
async function loadLightdashModel(filePath) {
|
|
19
|
-
try {
|
|
20
|
-
const fileContents = await fs.promises.readFile(filePath, 'utf8');
|
|
21
|
-
const parsed = yaml.load(fileContents);
|
|
22
|
-
// Basic validation
|
|
23
|
-
if (!parsed.type || !parsed.name || !parsed.dimensions) {
|
|
24
|
-
throw new common_1.ParseError(`Invalid Lightdash model in ${filePath}: must have type, name, and dimensions`);
|
|
25
|
-
}
|
|
26
|
-
if (!parsed.sql_from) {
|
|
27
|
-
throw new common_1.ParseError(`Invalid Lightdash model in ${filePath}: must have sql_from`);
|
|
28
|
-
}
|
|
29
|
-
return parsed;
|
|
30
|
-
}
|
|
31
|
-
catch (error) {
|
|
32
|
-
if (error instanceof common_1.ParseError) {
|
|
33
|
-
throw error;
|
|
34
|
-
}
|
|
35
|
-
throw new common_1.ParseError(`Failed to load Lightdash model from ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Check if a YAML file contains a Lightdash model definition
|
|
40
|
-
* A valid model file must have a `type` field with value 'model', 'model/v1beta', or 'model/v1'
|
|
41
|
-
*/
|
|
12
|
+
var loader_2 = require("@lightdash/common/lightdash/loader");
|
|
13
|
+
Object.defineProperty(exports, "loadLightdashModel", { enumerable: true, get: function () { return loader_2.loadLightdashModel; } });
|
|
14
|
+
// Format detection must tolerate files that dbt may ignore or handle itself.
|
|
42
15
|
async function isLightdashModelFile(filePath) {
|
|
43
16
|
try {
|
|
44
17
|
const fileContents = await fs.promises.readFile(filePath, 'utf8');
|
|
@@ -101,22 +74,8 @@ async function findLightdashModelFiles(projectDir) {
|
|
|
101
74
|
}
|
|
102
75
|
return modelFiles;
|
|
103
76
|
}
|
|
104
|
-
/**
|
|
105
|
-
* Load all Lightdash YAML models from a project directory
|
|
106
|
-
*/
|
|
107
77
|
async function loadLightdashModels(projectDir) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
for await (const filePath of modelFiles) {
|
|
112
|
-
try {
|
|
113
|
-
const model = await loadLightdashModel(filePath);
|
|
114
|
-
models.push(model);
|
|
115
|
-
globalState_1.default.debug(`Loaded Lightdash model: ${model.name}`);
|
|
116
|
-
}
|
|
117
|
-
catch (error) {
|
|
118
|
-
console.error(`Warning: Failed to load ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return models;
|
|
78
|
+
if ((await findLightdashModelFiles(projectDir)).length === 0)
|
|
79
|
+
return [];
|
|
80
|
+
return (0, loader_1.loadLightdashModels)(projectDir);
|
|
122
81
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightdash/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.176.0",
|
|
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.176.0",
|
|
49
|
+
"@lightdash/warehouses": "2.176.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/inquirer": "8.2.4",
|