@lightdash/cli 2.228.1 → 2.229.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.build +1 -0
- package/package.json +4 -4
- package/dist/.tsbuildinfo +0 -1
- package/dist/config.test.d.ts +0 -2
- package/dist/config.test.d.ts.map +0 -1
- package/dist/config.test.js +0 -72
- package/dist/dbt/context.test.d.ts +0 -2
- package/dist/dbt/context.test.d.ts.map +0 -1
- package/dist/dbt/context.test.js +0 -152
- package/dist/dbt/manifest.test.d.ts +0 -2
- package/dist/dbt/manifest.test.d.ts.map +0 -1
- package/dist/dbt/manifest.test.js +0 -170
- package/dist/dbt/models.test.d.ts +0 -2
- package/dist/dbt/models.test.d.ts.map +0 -1
- package/dist/dbt/models.test.js +0 -139
- package/dist/dbt/profiles.test.d.ts +0 -2
- package/dist/dbt/profiles.test.d.ts.map +0 -1
- package/dist/dbt/profiles.test.js +0 -50
- package/dist/dbt/targets/athena.test.d.ts +0 -2
- package/dist/dbt/targets/athena.test.d.ts.map +0 -1
- package/dist/dbt/targets/athena.test.js +0 -78
- package/dist/dbt/targets/duckdb.test.d.ts +0 -2
- package/dist/dbt/targets/duckdb.test.d.ts.map +0 -1
- package/dist/dbt/targets/duckdb.test.js +0 -149
- package/dist/dbt/targets/redshift.test.d.ts +0 -2
- package/dist/dbt/targets/redshift.test.d.ts.map +0 -1
- package/dist/dbt/targets/redshift.test.js +0 -198
- package/dist/dbt/templating.test.d.ts +0 -2
- package/dist/dbt/templating.test.d.ts.map +0 -1
- package/dist/dbt/templating.test.js +0 -51
- package/dist/dbt/validation.test.d.ts +0 -2
- package/dist/dbt/validation.test.d.ts.map +0 -1
- package/dist/dbt/validation.test.js +0 -67
- package/dist/handlers/apps/appCodeFiles.test.d.ts +0 -2
- package/dist/handlers/apps/appCodeFiles.test.d.ts.map +0 -1
- package/dist/handlers/apps/appCodeFiles.test.js +0 -391
- package/dist/handlers/apps/appsDownload.test.d.ts +0 -2
- package/dist/handlers/apps/appsDownload.test.d.ts.map +0 -1
- package/dist/handlers/apps/appsDownload.test.js +0 -639
- package/dist/handlers/apps/build.test.d.ts +0 -2
- package/dist/handlers/apps/build.test.d.ts.map +0 -1
- package/dist/handlers/apps/build.test.js +0 -252
- package/dist/handlers/apps/createApp.test.d.ts +0 -2
- package/dist/handlers/apps/createApp.test.d.ts.map +0 -1
- package/dist/handlers/apps/createApp.test.js +0 -340
- package/dist/handlers/apps/pathContainment.test.d.ts +0 -2
- package/dist/handlers/apps/pathContainment.test.d.ts.map +0 -1
- package/dist/handlers/apps/pathContainment.test.js +0 -66
- package/dist/handlers/apps/preview.test.d.ts +0 -2
- package/dist/handlers/apps/preview.test.d.ts.map +0 -1
- package/dist/handlers/apps/preview.test.js +0 -353
- package/dist/handlers/apps/previewProxy.test.d.ts +0 -2
- package/dist/handlers/apps/previewProxy.test.d.ts.map +0 -1
- package/dist/handlers/apps/previewProxy.test.js +0 -178
- package/dist/handlers/apps/scaffolding.test.d.ts +0 -2
- package/dist/handlers/apps/scaffolding.test.d.ts.map +0 -1
- package/dist/handlers/apps/scaffolding.test.js +0 -151
- package/dist/handlers/apps/uploadRetry.test.d.ts +0 -2
- package/dist/handlers/apps/uploadRetry.test.d.ts.map +0 -1
- package/dist/handlers/apps/uploadRetry.test.js +0 -103
- package/dist/handlers/apps/validate.test.d.ts +0 -2
- package/dist/handlers/apps/validate.test.d.ts.map +0 -1
- package/dist/handlers/apps/validate.test.js +0 -526
- package/dist/handlers/compile.test.d.ts +0 -2
- package/dist/handlers/compile.test.d.ts.map +0 -1
- package/dist/handlers/compile.test.js +0 -151
- package/dist/handlers/compileProject.test.d.ts +0 -2
- package/dist/handlers/compileProject.test.d.ts.map +0 -1
- package/dist/handlers/compileProject.test.js +0 -637
- package/dist/handlers/compileWarehouseColumnValidation.test.d.ts +0 -2
- package/dist/handlers/compileWarehouseColumnValidation.test.d.ts.map +0 -1
- package/dist/handlers/compileWarehouseColumnValidation.test.js +0 -493
- package/dist/handlers/connectSnowflake.test.d.ts +0 -2
- package/dist/handlers/connectSnowflake.test.d.ts.map +0 -1
- package/dist/handlers/connectSnowflake.test.js +0 -320
- package/dist/handlers/contentAsCode/fileNames.test.d.ts +0 -2
- package/dist/handlers/contentAsCode/fileNames.test.d.ts.map +0 -1
- package/dist/handlers/contentAsCode/fileNames.test.js +0 -79
- package/dist/handlers/contentAsCode/registry.test.d.ts +0 -2
- package/dist/handlers/contentAsCode/registry.test.d.ts.map +0 -1
- package/dist/handlers/contentAsCode/registry.test.js +0 -18
- package/dist/handlers/contentAsCode/resource.test.d.ts +0 -2
- package/dist/handlers/contentAsCode/resource.test.d.ts.map +0 -1
- package/dist/handlers/contentAsCode/resource.test.js +0 -121
- package/dist/handlers/dbt/getDbtVersion.test.d.ts +0 -2
- package/dist/handlers/dbt/getDbtVersion.test.d.ts.map +0 -1
- package/dist/handlers/dbt/getDbtVersion.test.js +0 -106
- package/dist/handlers/deploy.test.d.ts +0 -2
- package/dist/handlers/deploy.test.d.ts.map +0 -1
- package/dist/handlers/deploy.test.js +0 -244
- package/dist/handlers/download.test.d.ts +0 -2
- package/dist/handlers/download.test.d.ts.map +0 -1
- package/dist/handlers/download.test.js +0 -1739
- package/dist/handlers/exportChartImage.test.d.ts +0 -2
- package/dist/handlers/exportChartImage.test.d.ts.map +0 -1
- package/dist/handlers/exportChartImage.test.js +0 -55
- package/dist/handlers/homepagesAsCode.test.d.ts +0 -2
- package/dist/handlers/homepagesAsCode.test.d.ts.map +0 -1
- package/dist/handlers/homepagesAsCode.test.js +0 -72
- package/dist/handlers/lint.test.d.ts +0 -2
- package/dist/handlers/lint.test.d.ts.map +0 -1
- package/dist/handlers/lint.test.js +0 -221
- package/dist/handlers/login.test.d.ts +0 -2
- package/dist/handlers/login.test.d.ts.map +0 -1
- package/dist/handlers/login.test.js +0 -24
- package/dist/handlers/metadataFile.test.d.ts +0 -2
- package/dist/handlers/metadataFile.test.d.ts.map +0 -1
- package/dist/handlers/metadataFile.test.js +0 -46
- package/dist/handlers/organizationContent/customRoles.test.d.ts +0 -2
- package/dist/handlers/organizationContent/customRoles.test.d.ts.map +0 -1
- package/dist/handlers/organizationContent/customRoles.test.js +0 -179
- package/dist/handlers/organizationContent/groups.test.d.ts +0 -2
- package/dist/handlers/organizationContent/groups.test.d.ts.map +0 -1
- package/dist/handlers/organizationContent/groups.test.js +0 -135
- package/dist/handlers/organizationContent/index.test.d.ts +0 -2
- package/dist/handlers/organizationContent/index.test.d.ts.map +0 -1
- package/dist/handlers/organizationContent/index.test.js +0 -212
- package/dist/handlers/organizationContent/themes.test.d.ts +0 -2
- package/dist/handlers/organizationContent/themes.test.d.ts.map +0 -1
- package/dist/handlers/organizationContent/themes.test.js +0 -180
- package/dist/handlers/organizationContent/users.test.d.ts +0 -2
- package/dist/handlers/organizationContent/users.test.d.ts.map +0 -1
- package/dist/handlers/organizationContent/users.test.js +0 -155
- package/dist/handlers/preAggregateAudit.test.d.ts +0 -2
- package/dist/handlers/preAggregateAudit.test.d.ts.map +0 -1
- package/dist/handlers/preAggregateAudit.test.js +0 -102
- package/dist/handlers/renameHandler.test.d.ts +0 -2
- package/dist/handlers/renameHandler.test.d.ts.map +0 -1
- package/dist/handlers/renameHandler.test.js +0 -189
- package/dist/handlers/resolveProjectFlag.test.d.ts +0 -2
- package/dist/handlers/resolveProjectFlag.test.d.ts.map +0 -1
- package/dist/handlers/resolveProjectFlag.test.js +0 -48
- package/dist/handlers/selectProject.test.d.ts +0 -2
- package/dist/handlers/selectProject.test.d.ts.map +0 -1
- package/dist/handlers/selectProject.test.js +0 -224
- package/dist/handlers/setProject.test.d.ts +0 -2
- package/dist/handlers/setProject.test.d.ts.map +0 -1
- package/dist/handlers/setProject.test.js +0 -63
- package/dist/handlers/slugUpdate.test.d.ts +0 -2
- package/dist/handlers/slugUpdate.test.d.ts.map +0 -1
- package/dist/handlers/slugUpdate.test.js +0 -265
- package/dist/handlers/timestampConversion.test.d.ts +0 -2
- package/dist/handlers/timestampConversion.test.d.ts.map +0 -1
- package/dist/handlers/timestampConversion.test.js +0 -87
- package/dist/handlers/upgradeCheck.test.d.ts +0 -2
- package/dist/handlers/upgradeCheck.test.d.ts.map +0 -1
- package/dist/handlers/upgradeCheck.test.js +0 -227
- package/dist/handlers/validate.test.d.ts +0 -2
- package/dist/handlers/validate.test.d.ts.map +0 -1
- package/dist/handlers/validate.test.js +0 -318
- package/dist/handlers/validateSpaceFilter.test.d.ts +0 -2
- package/dist/handlers/validateSpaceFilter.test.d.ts.map +0 -1
- package/dist/handlers/validateSpaceFilter.test.js +0 -79
- package/dist/handlers/warehouseConnection.test.d.ts +0 -2
- package/dist/handlers/warehouseConnection.test.d.ts.map +0 -1
- package/dist/handlers/warehouseConnection.test.js +0 -75
- package/dist/lightdash-config/lightdash-config.test.d.ts +0 -2
- package/dist/lightdash-config/lightdash-config.test.d.ts.map +0 -1
- package/dist/lightdash-config/lightdash-config.test.js +0 -69
- package/dist/prompts/fuzzySearchPrompt.test.d.ts +0 -2
- package/dist/prompts/fuzzySearchPrompt.test.d.ts.map +0 -1
- package/dist/prompts/fuzzySearchPrompt.test.js +0 -53
- package/dist/refsArgument.test.d.ts +0 -2
- package/dist/refsArgument.test.d.ts.map +0 -1
- package/dist/refsArgument.test.js +0 -42
- package/dist/releaseSafety/index.test.d.ts +0 -2
- package/dist/releaseSafety/index.test.d.ts.map +0 -1
- package/dist/releaseSafety/index.test.js +0 -154
- package/dist/releaseSafety/version.test.d.ts +0 -2
- package/dist/releaseSafety/version.test.d.ts.map +0 -1
- package/dist/releaseSafety/version.test.js +0 -22
- package/dist/skills.test.d.ts +0 -2
- package/dist/skills.test.d.ts.map +0 -1
- package/dist/skills.test.js +0 -112
- package/dist/terminal/contentAsCodeOutput.test.d.ts +0 -2
- package/dist/terminal/contentAsCodeOutput.test.d.ts.map +0 -1
- package/dist/terminal/contentAsCodeOutput.test.js +0 -231
|
@@ -1,493 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const common_1 = require("@lightdash/common");
|
|
5
|
-
const warehouses_1 = require("@lightdash/warehouses");
|
|
6
|
-
const promises_1 = tslib_1.__importDefault(require("fs/promises"));
|
|
7
|
-
const os = tslib_1.__importStar(require("os"));
|
|
8
|
-
const path = tslib_1.__importStar(require("path"));
|
|
9
|
-
const context_1 = require("../dbt/context");
|
|
10
|
-
const manifest_1 = require("../dbt/manifest");
|
|
11
|
-
const validation_1 = require("../dbt/validation");
|
|
12
|
-
const loader_1 = require("../lightdash/loader");
|
|
13
|
-
const compile_1 = require("./compile");
|
|
14
|
-
const apiClient_1 = require("./dbt/apiClient");
|
|
15
|
-
const compile_2 = require("./dbt/compile");
|
|
16
|
-
const getDbtVersion_1 = require("./dbt/getDbtVersion");
|
|
17
|
-
const getWarehouseClient_1 = tslib_1.__importDefault(require("./dbt/getWarehouseClient"));
|
|
18
|
-
const deploy_1 = require("./deploy");
|
|
19
|
-
vi.mock('../analytics/analytics');
|
|
20
|
-
vi.mock('../config', () => ({
|
|
21
|
-
getConfig: vi.fn().mockResolvedValue({ user: null, context: null }),
|
|
22
|
-
}));
|
|
23
|
-
vi.mock('../dbt/context');
|
|
24
|
-
vi.mock('../dbt/manifest');
|
|
25
|
-
vi.mock('../dbt/validation');
|
|
26
|
-
vi.mock('../lightdash/loader');
|
|
27
|
-
vi.mock('./dbt/compile');
|
|
28
|
-
vi.mock('./dbt/apiClient', async (importOriginal) => {
|
|
29
|
-
const original = await importOriginal();
|
|
30
|
-
return { ...original, lightdashApi: vi.fn().mockResolvedValue(undefined) };
|
|
31
|
-
});
|
|
32
|
-
vi.mock('./dbt/getDbtVersion');
|
|
33
|
-
vi.mock('./dbt/getWarehouseClient');
|
|
34
|
-
vi.mock('@lightdash/warehouses', async (importOriginal) => {
|
|
35
|
-
const original = await importOriginal();
|
|
36
|
-
return {
|
|
37
|
-
...original,
|
|
38
|
-
validateWarehouseColumnReferences: vi.fn(),
|
|
39
|
-
};
|
|
40
|
-
});
|
|
41
|
-
const model = {
|
|
42
|
-
checksum: { name: '', checksum: '' },
|
|
43
|
-
fqn: [],
|
|
44
|
-
language: '',
|
|
45
|
-
package_name: '',
|
|
46
|
-
path: '',
|
|
47
|
-
raw_code: '',
|
|
48
|
-
compiled: true,
|
|
49
|
-
unique_id: 'model.test.my_model',
|
|
50
|
-
description: '',
|
|
51
|
-
resource_type: 'model',
|
|
52
|
-
columns: {
|
|
53
|
-
id: {
|
|
54
|
-
name: 'id',
|
|
55
|
-
data_type: common_1.DimensionType.NUMBER,
|
|
56
|
-
meta: {},
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
meta: {},
|
|
60
|
-
database: 'my_database',
|
|
61
|
-
schema: 'my_schema',
|
|
62
|
-
name: 'my_model',
|
|
63
|
-
alias: 'my_model',
|
|
64
|
-
tags: [],
|
|
65
|
-
relation_name: '"my_database"."my_schema"."my_model"',
|
|
66
|
-
depends_on: { nodes: [] },
|
|
67
|
-
patch_path: null,
|
|
68
|
-
original_file_path: '',
|
|
69
|
-
};
|
|
70
|
-
// Metric name collides with the `id` dimension, producing an unconditional
|
|
71
|
-
// DUPLICATE_FIELD_NAME warning even when partial compilation is disabled
|
|
72
|
-
const modelWithDuplicateMetricName = {
|
|
73
|
-
...model,
|
|
74
|
-
columns: {
|
|
75
|
-
id: {
|
|
76
|
-
name: 'id',
|
|
77
|
-
data_type: common_1.DimensionType.NUMBER,
|
|
78
|
-
meta: { metrics: { id: { type: common_1.MetricType.COUNT } } },
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
const lightdashYmlModel = {
|
|
83
|
-
type: 'model',
|
|
84
|
-
name: 'yml_model',
|
|
85
|
-
sql_from: '"my_database"."my_schema"."yml_model"',
|
|
86
|
-
dimensions: [{ name: 'id', type: common_1.DimensionType.NUMBER, sql: 'id' }],
|
|
87
|
-
};
|
|
88
|
-
// Models are injected through the mocked validateDbtModel, so nodes stay empty
|
|
89
|
-
const manifest = {
|
|
90
|
-
nodes: {},
|
|
91
|
-
metadata: {
|
|
92
|
-
dbt_schema_version: 'https://schemas.getdbt.com/dbt/manifest/v12.json',
|
|
93
|
-
generated_at: '2026-01-01T00:00:00Z',
|
|
94
|
-
adapter_type: 'postgres',
|
|
95
|
-
},
|
|
96
|
-
metrics: {},
|
|
97
|
-
docs: {},
|
|
98
|
-
};
|
|
99
|
-
const baseOptions = (projectDir) => ({
|
|
100
|
-
projectDir,
|
|
101
|
-
profilesDir: '',
|
|
102
|
-
target: undefined,
|
|
103
|
-
profile: undefined,
|
|
104
|
-
vars: undefined,
|
|
105
|
-
verbose: false,
|
|
106
|
-
startOfWeek: 0,
|
|
107
|
-
skipWarehouseCatalog: undefined,
|
|
108
|
-
skipDbtCompile: true,
|
|
109
|
-
useDbtList: false,
|
|
110
|
-
select: undefined,
|
|
111
|
-
models: undefined,
|
|
112
|
-
threads: undefined,
|
|
113
|
-
noVersionCheck: false,
|
|
114
|
-
exclude: undefined,
|
|
115
|
-
selector: undefined,
|
|
116
|
-
state: undefined,
|
|
117
|
-
fullRefresh: false,
|
|
118
|
-
defer: false,
|
|
119
|
-
targetPath: undefined,
|
|
120
|
-
favorState: false,
|
|
121
|
-
combineManifest: undefined,
|
|
122
|
-
warehouseCredentials: false,
|
|
123
|
-
disableTimestampConversion: false,
|
|
124
|
-
});
|
|
125
|
-
const SKIP_WARNING = 'Skipping warehouse column validation because the warehouse catalog is skipped';
|
|
126
|
-
const YML_SKIP_WARNING = 'Skipping warehouse column validation because it is not supported for Lightdash YAML projects';
|
|
127
|
-
const DBT_CLOUD_SKIP_WARNING = 'Skipping warehouse column validation because dbt Cloud CLI cannot run warehouse queries';
|
|
128
|
-
const setupWarehouseClient = () => {
|
|
129
|
-
const credentials = {
|
|
130
|
-
type: common_1.WarehouseTypes.POSTGRES,
|
|
131
|
-
host: 'localhost',
|
|
132
|
-
user: 'test_user',
|
|
133
|
-
password: 'test_password',
|
|
134
|
-
port: 5432,
|
|
135
|
-
dbname: 'my_database',
|
|
136
|
-
schema: 'my_schema',
|
|
137
|
-
};
|
|
138
|
-
const warehouseClient = new warehouses_1.PostgresWarehouseClient(credentials);
|
|
139
|
-
vi.spyOn(warehouseClient, 'getCatalog').mockResolvedValue({});
|
|
140
|
-
vi.mocked(getWarehouseClient_1.default).mockResolvedValue({
|
|
141
|
-
warehouseClient,
|
|
142
|
-
credentials,
|
|
143
|
-
});
|
|
144
|
-
return warehouseClient;
|
|
145
|
-
};
|
|
146
|
-
const mockProberToAppendWarning = (message) => {
|
|
147
|
-
vi.mocked(warehouses_1.validateWarehouseColumnReferences).mockImplementation(async ({ explores }) => explores.map((explore) => (0, common_1.isExploreError)(explore)
|
|
148
|
-
? explore
|
|
149
|
-
: {
|
|
150
|
-
...explore,
|
|
151
|
-
warnings: [
|
|
152
|
-
...(explore.warnings ?? []),
|
|
153
|
-
{
|
|
154
|
-
type: common_1.InlineErrorType.WAREHOUSE_COLUMN_ERROR,
|
|
155
|
-
message,
|
|
156
|
-
},
|
|
157
|
-
],
|
|
158
|
-
}));
|
|
159
|
-
};
|
|
160
|
-
describe('compile warehouse column validation', () => {
|
|
161
|
-
let tempDir;
|
|
162
|
-
let errorOutput;
|
|
163
|
-
beforeEach(async () => {
|
|
164
|
-
vi.clearAllMocks();
|
|
165
|
-
tempDir = await promises_1.default.mkdtemp(path.join(os.tmpdir(), 'lightdash-compile-validation-test-'));
|
|
166
|
-
vi.mocked(getDbtVersion_1.tryGetDbtVersion).mockResolvedValue({
|
|
167
|
-
success: true,
|
|
168
|
-
version: {
|
|
169
|
-
verboseVersion: '1.8.0',
|
|
170
|
-
versionOption: common_1.SupportedDbtVersions.V1_8,
|
|
171
|
-
isDbtCloudCLI: false,
|
|
172
|
-
isDbtFusion: false,
|
|
173
|
-
},
|
|
174
|
-
});
|
|
175
|
-
vi.mocked(context_1.getDbtContext).mockResolvedValue({
|
|
176
|
-
projectName: 'test_project',
|
|
177
|
-
profileName: 'test_profile',
|
|
178
|
-
targetDir: path.join(tempDir, 'target'),
|
|
179
|
-
modelsDir: 'models',
|
|
180
|
-
});
|
|
181
|
-
vi.mocked(compile_2.maybeCompileModelsAndJoins).mockResolvedValue({
|
|
182
|
-
compiledModelIds: undefined,
|
|
183
|
-
originallySelectedModelIds: undefined,
|
|
184
|
-
});
|
|
185
|
-
vi.mocked(manifest_1.loadManifest).mockResolvedValue(manifest);
|
|
186
|
-
vi.mocked(loader_1.loadLightdashModels).mockResolvedValue([]);
|
|
187
|
-
vi.mocked(validation_1.validateDbtModel).mockResolvedValue({
|
|
188
|
-
valid: [model],
|
|
189
|
-
invalid: [],
|
|
190
|
-
skipped: [],
|
|
191
|
-
});
|
|
192
|
-
vi.mocked(warehouses_1.validateWarehouseColumnReferences).mockImplementation(async ({ explores }) => explores);
|
|
193
|
-
errorOutput = [];
|
|
194
|
-
vi.spyOn(console, 'error').mockImplementation((...args) => {
|
|
195
|
-
errorOutput.push(args.map(String).join(' '));
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
afterEach(async () => {
|
|
199
|
-
vi.restoreAllMocks();
|
|
200
|
-
await promises_1.default.rm(tempDir, { recursive: true, force: true });
|
|
201
|
-
});
|
|
202
|
-
test('skips warehouse client and column validation when skipWarehouseCatalog is set', async () => {
|
|
203
|
-
const result = await (0, compile_1.compile)({
|
|
204
|
-
...baseOptions(tempDir),
|
|
205
|
-
skipWarehouseCatalog: true,
|
|
206
|
-
validateWarehouseColumns: true,
|
|
207
|
-
});
|
|
208
|
-
// Credential-less CI flow: no warehouse client is ever created
|
|
209
|
-
expect(getWarehouseClient_1.default).not.toHaveBeenCalled();
|
|
210
|
-
expect(warehouses_1.validateWarehouseColumnReferences).not.toHaveBeenCalled();
|
|
211
|
-
expect(result.filter(common_1.isExploreError)).toEqual([]);
|
|
212
|
-
expect(result.map((explore) => explore.name)).toEqual(['my_model']);
|
|
213
|
-
expect(errorOutput).toEqual(expect.arrayContaining([expect.stringContaining(SKIP_WARNING)]));
|
|
214
|
-
});
|
|
215
|
-
test('validates warehouse column references when warehouse catalog is not skipped', async () => {
|
|
216
|
-
const warehouseClient = setupWarehouseClient();
|
|
217
|
-
const result = await (0, compile_1.compile)({
|
|
218
|
-
...baseOptions(tempDir),
|
|
219
|
-
skipWarehouseCatalog: false,
|
|
220
|
-
validateWarehouseColumns: true,
|
|
221
|
-
});
|
|
222
|
-
expect(getWarehouseClient_1.default).toHaveBeenCalledTimes(1);
|
|
223
|
-
expect(warehouseClient.getCatalog).toHaveBeenCalledTimes(1);
|
|
224
|
-
expect(warehouses_1.validateWarehouseColumnReferences).toHaveBeenCalledTimes(1);
|
|
225
|
-
expect(warehouses_1.validateWarehouseColumnReferences).toHaveBeenCalledWith(expect.objectContaining({ client: warehouseClient }));
|
|
226
|
-
expect(result.filter(common_1.isExploreError)).toEqual([]);
|
|
227
|
-
expect(errorOutput).not.toEqual(expect.arrayContaining([
|
|
228
|
-
expect.stringContaining('Skipping warehouse column validation'),
|
|
229
|
-
]));
|
|
230
|
-
});
|
|
231
|
-
test('does not warn about column validation when it was not requested', async () => {
|
|
232
|
-
const result = await (0, compile_1.compile)({
|
|
233
|
-
...baseOptions(tempDir),
|
|
234
|
-
skipWarehouseCatalog: true,
|
|
235
|
-
});
|
|
236
|
-
expect(getWarehouseClient_1.default).not.toHaveBeenCalled();
|
|
237
|
-
expect(warehouses_1.validateWarehouseColumnReferences).not.toHaveBeenCalled();
|
|
238
|
-
expect(result.filter(common_1.isExploreError)).toEqual([]);
|
|
239
|
-
expect(errorOutput).not.toEqual(expect.arrayContaining([expect.stringContaining(SKIP_WARNING)]));
|
|
240
|
-
});
|
|
241
|
-
describe('compile output for warehouse column warnings', () => {
|
|
242
|
-
const WAREHOUSE_WARNING = 'Warehouse rejected column reference TABLE.rolling_30d_avg_sales in model "my_model"';
|
|
243
|
-
test('renders ERROR for a warehouse rejection by default', async () => {
|
|
244
|
-
setupWarehouseClient();
|
|
245
|
-
mockProberToAppendWarning(WAREHOUSE_WARNING);
|
|
246
|
-
await (0, compile_1.compile)({
|
|
247
|
-
...baseOptions(tempDir),
|
|
248
|
-
validateWarehouseColumns: true,
|
|
249
|
-
});
|
|
250
|
-
expect(errorOutput).toEqual(expect.arrayContaining([
|
|
251
|
-
expect.stringContaining(`- ERROR> my_model : ${WAREHOUSE_WARNING}`),
|
|
252
|
-
expect.stringContaining('Compiled 1 explores, SUCCESS=0 ERRORS=1'),
|
|
253
|
-
]));
|
|
254
|
-
});
|
|
255
|
-
test('renders ERROR for a warehouse rejection when partial compilation is disabled', async () => {
|
|
256
|
-
setupWarehouseClient();
|
|
257
|
-
mockProberToAppendWarning(WAREHOUSE_WARNING);
|
|
258
|
-
const result = await (0, compile_1.compile)({
|
|
259
|
-
...baseOptions(tempDir),
|
|
260
|
-
validateWarehouseColumns: true,
|
|
261
|
-
partialCompilation: false,
|
|
262
|
-
});
|
|
263
|
-
expect(errorOutput).toEqual(expect.arrayContaining([
|
|
264
|
-
expect.stringContaining(`- ERROR> my_model : ${WAREHOUSE_WARNING}`),
|
|
265
|
-
expect.stringContaining('Compiled 1 explores, SUCCESS=0 ERRORS=1'),
|
|
266
|
-
]));
|
|
267
|
-
// The typed diagnostic must still reach backend validation untouched
|
|
268
|
-
expect(result.filter(common_1.isExploreError)).toEqual([]);
|
|
269
|
-
const warningTypes = result.flatMap((explore) => (0, common_1.isExploreError)(explore)
|
|
270
|
-
? []
|
|
271
|
-
: (explore.warnings ?? []).map((warning) => warning.type));
|
|
272
|
-
expect(warningTypes).toEqual([
|
|
273
|
-
common_1.InlineErrorType.WAREHOUSE_COLUMN_ERROR,
|
|
274
|
-
]);
|
|
275
|
-
expect(result.filter(compile_1.hasBlockingCompileError)).toHaveLength(1);
|
|
276
|
-
expect(result
|
|
277
|
-
.map(compile_1.stripWarehouseColumnErrors)
|
|
278
|
-
.flatMap((explore) => (0, common_1.isExploreError)(explore) ? [] : (explore.warnings ?? []))).toEqual([]);
|
|
279
|
-
});
|
|
280
|
-
test('blocks deploy when the warehouse rejects a column', async () => {
|
|
281
|
-
setupWarehouseClient();
|
|
282
|
-
mockProberToAppendWarning(WAREHOUSE_WARNING);
|
|
283
|
-
const explores = await (0, compile_1.compile)({
|
|
284
|
-
...baseOptions(tempDir),
|
|
285
|
-
validateWarehouseColumns: true,
|
|
286
|
-
});
|
|
287
|
-
vi.spyOn(process, 'exit').mockImplementation(() => {
|
|
288
|
-
throw new Error('process.exit');
|
|
289
|
-
});
|
|
290
|
-
await expect((0, deploy_1.deploy)(explores, {
|
|
291
|
-
...baseOptions(tempDir),
|
|
292
|
-
projectUuid: 'projectUuid',
|
|
293
|
-
ignoreErrors: false,
|
|
294
|
-
validateWarehouseColumns: true,
|
|
295
|
-
})).rejects.toThrow('process.exit');
|
|
296
|
-
expect(process.exit).toHaveBeenCalledWith(1);
|
|
297
|
-
});
|
|
298
|
-
test('does not persist warehouse diagnostics when deploy errors are ignored', async () => {
|
|
299
|
-
setupWarehouseClient();
|
|
300
|
-
mockProberToAppendWarning(WAREHOUSE_WARNING);
|
|
301
|
-
const explores = await (0, compile_1.compile)({
|
|
302
|
-
...baseOptions(tempDir),
|
|
303
|
-
validateWarehouseColumns: true,
|
|
304
|
-
});
|
|
305
|
-
await (0, deploy_1.deploy)(explores, {
|
|
306
|
-
...baseOptions(tempDir),
|
|
307
|
-
projectUuid: 'projectUuid',
|
|
308
|
-
ignoreErrors: true,
|
|
309
|
-
validateWarehouseColumns: true,
|
|
310
|
-
batchedDeploy: false,
|
|
311
|
-
});
|
|
312
|
-
const deployRequest = vi
|
|
313
|
-
.mocked(apiClient_1.lightdashApi)
|
|
314
|
-
.mock.calls.find(([request]) => request.url ===
|
|
315
|
-
'/api/v1/projects/projectUuid/explores?complete=false');
|
|
316
|
-
if (deployRequest === undefined) {
|
|
317
|
-
throw new Error('Expected explores deploy request');
|
|
318
|
-
}
|
|
319
|
-
expect(deployRequest[0].body).not.toContain(common_1.InlineErrorType.WAREHOUSE_COLUMN_ERROR);
|
|
320
|
-
});
|
|
321
|
-
test('keeps generic warnings hidden when partial compilation is disabled', async () => {
|
|
322
|
-
vi.mocked(validation_1.validateDbtModel).mockResolvedValue({
|
|
323
|
-
valid: [modelWithDuplicateMetricName],
|
|
324
|
-
invalid: [],
|
|
325
|
-
skipped: [],
|
|
326
|
-
});
|
|
327
|
-
await (0, compile_1.compile)({
|
|
328
|
-
...baseOptions(tempDir),
|
|
329
|
-
skipWarehouseCatalog: true,
|
|
330
|
-
partialCompilation: false,
|
|
331
|
-
});
|
|
332
|
-
expect(errorOutput).toEqual(expect.arrayContaining([
|
|
333
|
-
expect.stringContaining('- SUCCESS> my_model'),
|
|
334
|
-
expect.stringContaining('Compiled 1 explores, SUCCESS=1 ERRORS=0'),
|
|
335
|
-
]));
|
|
336
|
-
expect(errorOutput).not.toEqual(expect.arrayContaining([
|
|
337
|
-
expect.stringContaining('PARTIAL_SUCCESS'),
|
|
338
|
-
]));
|
|
339
|
-
expect(errorOutput).not.toEqual(expect.arrayContaining([
|
|
340
|
-
expect.stringContaining('Skipped metric "id"'),
|
|
341
|
-
]));
|
|
342
|
-
});
|
|
343
|
-
test('renders generic warnings by default', async () => {
|
|
344
|
-
vi.mocked(validation_1.validateDbtModel).mockResolvedValue({
|
|
345
|
-
valid: [modelWithDuplicateMetricName],
|
|
346
|
-
invalid: [],
|
|
347
|
-
skipped: [],
|
|
348
|
-
});
|
|
349
|
-
await (0, compile_1.compile)({
|
|
350
|
-
...baseOptions(tempDir),
|
|
351
|
-
skipWarehouseCatalog: true,
|
|
352
|
-
});
|
|
353
|
-
expect(errorOutput).toEqual(expect.arrayContaining([
|
|
354
|
-
expect.stringContaining('- PARTIAL_SUCCESS> my_model'),
|
|
355
|
-
expect.stringContaining('Skipped metric "id"'),
|
|
356
|
-
expect.stringContaining('Compiled 1 explores, SUCCESS=0 PARTIAL_SUCCESS=1 ERRORS=0'),
|
|
357
|
-
]));
|
|
358
|
-
});
|
|
359
|
-
test('renders the warehouse error and generic warnings by default', async () => {
|
|
360
|
-
vi.mocked(validation_1.validateDbtModel).mockResolvedValue({
|
|
361
|
-
valid: [modelWithDuplicateMetricName],
|
|
362
|
-
invalid: [],
|
|
363
|
-
skipped: [],
|
|
364
|
-
});
|
|
365
|
-
setupWarehouseClient();
|
|
366
|
-
mockProberToAppendWarning(WAREHOUSE_WARNING);
|
|
367
|
-
const result = await (0, compile_1.compile)({
|
|
368
|
-
...baseOptions(tempDir),
|
|
369
|
-
validateWarehouseColumns: true,
|
|
370
|
-
});
|
|
371
|
-
expect(errorOutput).toEqual(expect.arrayContaining([
|
|
372
|
-
expect.stringContaining(`- ERROR> my_model : ${WAREHOUSE_WARNING}`),
|
|
373
|
-
expect.stringContaining('Skipped metric "id"'),
|
|
374
|
-
expect.stringContaining('Compiled 1 explores, SUCCESS=0 ERRORS=1'),
|
|
375
|
-
]));
|
|
376
|
-
expect(result
|
|
377
|
-
.map(compile_1.stripWarehouseColumnErrors)
|
|
378
|
-
.flatMap((explore) => (0, common_1.isExploreError)(explore)
|
|
379
|
-
? []
|
|
380
|
-
: (explore.warnings ?? []).map((warning) => warning.type))).toEqual([common_1.InlineErrorType.DUPLICATE_FIELD_NAME]);
|
|
381
|
-
});
|
|
382
|
-
test('renders only the warehouse error when partial compilation is disabled', async () => {
|
|
383
|
-
vi.mocked(validation_1.validateDbtModel).mockResolvedValue({
|
|
384
|
-
valid: [modelWithDuplicateMetricName],
|
|
385
|
-
invalid: [],
|
|
386
|
-
skipped: [],
|
|
387
|
-
});
|
|
388
|
-
setupWarehouseClient();
|
|
389
|
-
mockProberToAppendWarning(WAREHOUSE_WARNING);
|
|
390
|
-
await (0, compile_1.compile)({
|
|
391
|
-
...baseOptions(tempDir),
|
|
392
|
-
validateWarehouseColumns: true,
|
|
393
|
-
partialCompilation: false,
|
|
394
|
-
});
|
|
395
|
-
expect(errorOutput).toEqual(expect.arrayContaining([
|
|
396
|
-
expect.stringContaining(`- ERROR> my_model : ${WAREHOUSE_WARNING}`),
|
|
397
|
-
expect.stringContaining('Compiled 1 explores, SUCCESS=0 ERRORS=1'),
|
|
398
|
-
]));
|
|
399
|
-
expect(errorOutput).not.toEqual(expect.arrayContaining([
|
|
400
|
-
expect.stringContaining('Skipped metric "id"'),
|
|
401
|
-
]));
|
|
402
|
-
});
|
|
403
|
-
});
|
|
404
|
-
describe('dbt cloud cli', () => {
|
|
405
|
-
beforeEach(() => {
|
|
406
|
-
vi.mocked(getDbtVersion_1.tryGetDbtVersion).mockResolvedValue({
|
|
407
|
-
success: true,
|
|
408
|
-
version: {
|
|
409
|
-
verboseVersion: 'dbt Cloud CLI - 0.38.0',
|
|
410
|
-
versionOption: common_1.DbtVersionOptionLatest.LATEST,
|
|
411
|
-
isDbtCloudCLI: true,
|
|
412
|
-
isDbtFusion: false,
|
|
413
|
-
},
|
|
414
|
-
});
|
|
415
|
-
});
|
|
416
|
-
test('skips column probing and warns when validation was requested', async () => {
|
|
417
|
-
const warehouseClient = setupWarehouseClient();
|
|
418
|
-
const result = await (0, compile_1.compile)({
|
|
419
|
-
...baseOptions(tempDir),
|
|
420
|
-
validateWarehouseColumns: true,
|
|
421
|
-
});
|
|
422
|
-
// Catalog fetching required by dbt Cloud CLI is preserved
|
|
423
|
-
expect(getWarehouseClient_1.default).toHaveBeenCalledWith(expect.objectContaining({ isDbtCloudCLI: true }));
|
|
424
|
-
expect(warehouseClient.getCatalog).toHaveBeenCalledTimes(1);
|
|
425
|
-
expect(warehouses_1.validateWarehouseColumnReferences).not.toHaveBeenCalled();
|
|
426
|
-
expect(result.filter(common_1.isExploreError)).toEqual([]);
|
|
427
|
-
expect(result.map((explore) => explore.name)).toEqual(['my_model']);
|
|
428
|
-
expect(errorOutput).toEqual(expect.arrayContaining([
|
|
429
|
-
expect.stringContaining(DBT_CLOUD_SKIP_WARNING),
|
|
430
|
-
]));
|
|
431
|
-
});
|
|
432
|
-
test('does not warn or probe when validation was not requested', async () => {
|
|
433
|
-
const warehouseClient = setupWarehouseClient();
|
|
434
|
-
await (0, compile_1.compile)(baseOptions(tempDir));
|
|
435
|
-
expect(warehouseClient.getCatalog).toHaveBeenCalledTimes(1);
|
|
436
|
-
expect(warehouses_1.validateWarehouseColumnReferences).not.toHaveBeenCalled();
|
|
437
|
-
expect(errorOutput).not.toEqual(expect.arrayContaining([
|
|
438
|
-
expect.stringContaining('Skipping warehouse column validation'),
|
|
439
|
-
]));
|
|
440
|
-
});
|
|
441
|
-
test('prefers the skip-warehouse-catalog warning when both apply', async () => {
|
|
442
|
-
await (0, compile_1.compile)({
|
|
443
|
-
...baseOptions(tempDir),
|
|
444
|
-
skipWarehouseCatalog: true,
|
|
445
|
-
validateWarehouseColumns: true,
|
|
446
|
-
});
|
|
447
|
-
expect(getWarehouseClient_1.default).not.toHaveBeenCalled();
|
|
448
|
-
expect(warehouses_1.validateWarehouseColumnReferences).not.toHaveBeenCalled();
|
|
449
|
-
const skipWarnings = errorOutput.filter((line) => line.includes('Skipping warehouse column validation'));
|
|
450
|
-
expect(skipWarnings).toHaveLength(1);
|
|
451
|
-
expect(skipWarnings[0]).toContain(SKIP_WARNING);
|
|
452
|
-
});
|
|
453
|
-
});
|
|
454
|
-
describe('lightdash yml projects', () => {
|
|
455
|
-
beforeEach(async () => {
|
|
456
|
-
vi.mocked(loader_1.loadLightdashModels).mockResolvedValue([
|
|
457
|
-
{ ...lightdashYmlModel, sourcePath: 'models/test_model.yml' },
|
|
458
|
-
]);
|
|
459
|
-
await promises_1.default.writeFile(path.join(tempDir, 'lightdash.config.yml'), 'warehouse:\n type: postgres\n');
|
|
460
|
-
});
|
|
461
|
-
test('warns that warehouse column validation is not supported', async () => {
|
|
462
|
-
const result = await (0, compile_1.compile)({
|
|
463
|
-
...baseOptions(tempDir),
|
|
464
|
-
validateWarehouseColumns: true,
|
|
465
|
-
});
|
|
466
|
-
expect(result.filter(common_1.isExploreError)).toEqual([]);
|
|
467
|
-
expect(result.map((explore) => explore.name)).toEqual([
|
|
468
|
-
'yml_model',
|
|
469
|
-
]);
|
|
470
|
-
expect(getWarehouseClient_1.default).not.toHaveBeenCalled();
|
|
471
|
-
expect(warehouses_1.validateWarehouseColumnReferences).not.toHaveBeenCalled();
|
|
472
|
-
expect(errorOutput).toEqual(expect.arrayContaining([
|
|
473
|
-
expect.stringContaining(YML_SKIP_WARNING),
|
|
474
|
-
]));
|
|
475
|
-
});
|
|
476
|
-
test('does not warn when warehouse column validation was not requested', async () => {
|
|
477
|
-
await (0, compile_1.compile)(baseOptions(tempDir));
|
|
478
|
-
expect(errorOutput).not.toEqual(expect.arrayContaining([
|
|
479
|
-
expect.stringContaining('Skipping warehouse column validation'),
|
|
480
|
-
]));
|
|
481
|
-
});
|
|
482
|
-
test('warns exactly once when --skip-warehouse-catalog is also supplied', async () => {
|
|
483
|
-
await (0, compile_1.compile)({
|
|
484
|
-
...baseOptions(tempDir),
|
|
485
|
-
skipWarehouseCatalog: true,
|
|
486
|
-
validateWarehouseColumns: true,
|
|
487
|
-
});
|
|
488
|
-
const skipWarnings = errorOutput.filter((line) => line.includes('Skipping warehouse column validation'));
|
|
489
|
-
expect(skipWarnings).toHaveLength(1);
|
|
490
|
-
expect(skipWarnings[0]).toContain(YML_SKIP_WARNING);
|
|
491
|
-
});
|
|
492
|
-
});
|
|
493
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connectSnowflake.test.d.ts","sourceRoot":"","sources":["../../src/handlers/connectSnowflake.test.ts"],"names":[],"mappings":""}
|