@lightdash/cli 2.228.1 → 2.229.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.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
package/dist/config.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../src/config.test.ts"],"names":[],"mappings":""}
|
package/dist/config.test.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const fs_1 = require("fs");
|
|
5
|
-
const yaml = tslib_1.__importStar(require("js-yaml"));
|
|
6
|
-
const os = tslib_1.__importStar(require("os"));
|
|
7
|
-
const path = tslib_1.__importStar(require("path"));
|
|
8
|
-
const config_1 = require("./config");
|
|
9
|
-
// Masking file-type bits is the standard way to assert POSIX permissions.
|
|
10
|
-
// eslint-disable-next-line no-bitwise
|
|
11
|
-
const permissionBits = (mode) => mode & 0o777;
|
|
12
|
-
const describePosix = process.platform === 'win32' ? describe.skip : describe;
|
|
13
|
-
describePosix('CLI config permissions', () => {
|
|
14
|
-
let tempDir;
|
|
15
|
-
let configDir;
|
|
16
|
-
let configPath;
|
|
17
|
-
beforeEach(async () => {
|
|
18
|
-
tempDir = await fs_1.promises.mkdtemp(path.join(os.tmpdir(), 'ld-config-'));
|
|
19
|
-
configDir = path.join(tempDir, 'lightdash');
|
|
20
|
-
configPath = path.join(configDir, 'config.yaml');
|
|
21
|
-
});
|
|
22
|
-
afterEach(async () => {
|
|
23
|
-
await fs_1.promises.rm(tempDir, { recursive: true, force: true });
|
|
24
|
-
});
|
|
25
|
-
it('creates the config directory and file with private permissions', async () => {
|
|
26
|
-
await (0, config_1.writeConfigToFile)(configPath, {
|
|
27
|
-
context: { apiKey: 'ldpat_secret' },
|
|
28
|
-
});
|
|
29
|
-
expect(permissionBits((await fs_1.promises.stat(configDir)).mode)).toBe(0o700);
|
|
30
|
-
expect(permissionBits((await fs_1.promises.stat(configPath)).mode)).toBe(0o600);
|
|
31
|
-
});
|
|
32
|
-
it('tightens permissions on an existing config path', async () => {
|
|
33
|
-
await fs_1.promises.mkdir(configDir, { recursive: true, mode: 0o755 });
|
|
34
|
-
await fs_1.promises.writeFile(configPath, 'context: {}', { mode: 0o644 });
|
|
35
|
-
await fs_1.promises.chmod(configDir, 0o755);
|
|
36
|
-
await fs_1.promises.chmod(configPath, 0o644);
|
|
37
|
-
await (0, config_1.ensureConfigFilePermissions)(configPath);
|
|
38
|
-
expect(permissionBits((await fs_1.promises.stat(configDir)).mode)).toBe(0o700);
|
|
39
|
-
expect(permissionBits((await fs_1.promises.stat(configPath)).mode)).toBe(0o600);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
describe('CLI project environment override', () => {
|
|
43
|
-
afterEach(() => {
|
|
44
|
-
vi.restoreAllMocks();
|
|
45
|
-
vi.unstubAllEnvs();
|
|
46
|
-
});
|
|
47
|
-
it.each([
|
|
48
|
-
['other-project', undefined],
|
|
49
|
-
['stored-project', 'Stored project'],
|
|
50
|
-
['', 'Stored project'],
|
|
51
|
-
[undefined, 'Stored project'],
|
|
52
|
-
])('only retains the cached name for its own project (override: %s)', async (projectOverride, expectedName) => {
|
|
53
|
-
vi.stubEnv('LIGHTDASH_PROJECT', projectOverride);
|
|
54
|
-
vi.spyOn(fs_1.promises, 'chmod').mockResolvedValue(undefined);
|
|
55
|
-
vi.spyOn(fs_1.promises, 'readFile').mockResolvedValue(yaml.dump({
|
|
56
|
-
user: { anonymousUuid: 'anonymous-user' },
|
|
57
|
-
context: {
|
|
58
|
-
project: 'stored-project',
|
|
59
|
-
projectName: 'Stored project',
|
|
60
|
-
previewProject: 'preview-project',
|
|
61
|
-
previewName: 'Preview project',
|
|
62
|
-
},
|
|
63
|
-
}));
|
|
64
|
-
const config = await (0, config_1.getConfig)();
|
|
65
|
-
expect(config.context).toMatchObject({
|
|
66
|
-
project: projectOverride || 'stored-project',
|
|
67
|
-
projectName: expectedName,
|
|
68
|
-
previewProject: 'preview-project',
|
|
69
|
-
previewName: 'Preview project',
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.test.d.ts","sourceRoot":"","sources":["../../src/dbt/context.test.ts"],"names":[],"mappings":""}
|
package/dist/dbt/context.test.js
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const fs_1 = require("fs");
|
|
5
|
-
const os = tslib_1.__importStar(require("os"));
|
|
6
|
-
const path = tslib_1.__importStar(require("path"));
|
|
7
|
-
const context_1 = require("./context");
|
|
8
|
-
describe('getDbtContext', () => {
|
|
9
|
-
const { env } = process;
|
|
10
|
-
let tempDir;
|
|
11
|
-
beforeEach(async () => {
|
|
12
|
-
vi.resetModules();
|
|
13
|
-
process.env = { ...env };
|
|
14
|
-
// Create a temporary directory for test files
|
|
15
|
-
tempDir = await fs_1.promises.mkdtemp(path.join(os.tmpdir(), 'dbt-context-test-'));
|
|
16
|
-
});
|
|
17
|
-
afterEach(async () => {
|
|
18
|
-
process.env = env;
|
|
19
|
-
// Clean up temporary directory
|
|
20
|
-
await fs_1.promises.rm(tempDir, { recursive: true, force: true });
|
|
21
|
-
});
|
|
22
|
-
describe('target-path with env_var templating', () => {
|
|
23
|
-
test('should resolve env_var in target-path', async () => {
|
|
24
|
-
process.env.DBT_ENV__TARGET_FOLDER = 'custom-target';
|
|
25
|
-
const dbtProjectContent = `name: test_project
|
|
26
|
-
profile: test_profile
|
|
27
|
-
target-path: "{{ env_var('DBT_ENV__TARGET_FOLDER', 'target') }}"
|
|
28
|
-
models-path: "models"
|
|
29
|
-
`;
|
|
30
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
31
|
-
const context = await (0, context_1.getDbtContext)({ projectDir: tempDir });
|
|
32
|
-
expect(context.targetDir).toBe(path.join(tempDir, 'custom-target'));
|
|
33
|
-
expect(context.projectName).toBe('test_project');
|
|
34
|
-
expect(context.profileName).toBe('test_profile');
|
|
35
|
-
});
|
|
36
|
-
test('should use default value when env_var is not set', async () => {
|
|
37
|
-
const dbtProjectContent = `name: test_project
|
|
38
|
-
profile: test_profile
|
|
39
|
-
target-path: "{{ env_var('DBT_ENV__TARGET_FOLDER', 'target') }}"
|
|
40
|
-
models-path: "models"
|
|
41
|
-
`;
|
|
42
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
43
|
-
const context = await (0, context_1.getDbtContext)({ projectDir: tempDir });
|
|
44
|
-
expect(context.targetDir).toBe(path.join(tempDir, 'target'));
|
|
45
|
-
});
|
|
46
|
-
test('should work with models-path env_var', async () => {
|
|
47
|
-
process.env.DBT_MODELS_PATH = 'custom-models';
|
|
48
|
-
const dbtProjectContent = `name: test_project
|
|
49
|
-
profile: test_profile
|
|
50
|
-
target-path: "target"
|
|
51
|
-
models-path: "{{ env_var('DBT_MODELS_PATH', 'models') }}"
|
|
52
|
-
`;
|
|
53
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
54
|
-
const context = await (0, context_1.getDbtContext)({ projectDir: tempDir });
|
|
55
|
-
expect(context.modelsDir).toBe(path.join(tempDir, 'custom-models'));
|
|
56
|
-
});
|
|
57
|
-
test('should work without any templating', async () => {
|
|
58
|
-
const dbtProjectContent = `name: test_project
|
|
59
|
-
profile: test_profile
|
|
60
|
-
target-path: "target"
|
|
61
|
-
models-path: "models"
|
|
62
|
-
`;
|
|
63
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
64
|
-
const context = await (0, context_1.getDbtContext)({ projectDir: tempDir });
|
|
65
|
-
expect(context.targetDir).toBe(path.join(tempDir, 'target'));
|
|
66
|
-
expect(context.modelsDir).toBe(path.join(tempDir, 'models'));
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
describe('target-path precedence', () => {
|
|
70
|
-
test('should use DBT_TARGET_PATH env var when set', async () => {
|
|
71
|
-
process.env.DBT_TARGET_PATH = 'env-target';
|
|
72
|
-
const dbtProjectContent = `name: test_project
|
|
73
|
-
profile: test_profile
|
|
74
|
-
target-path: "yml-target"
|
|
75
|
-
models-path: "models"
|
|
76
|
-
`;
|
|
77
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
78
|
-
const context = await (0, context_1.getDbtContext)({ projectDir: tempDir });
|
|
79
|
-
expect(context.targetDir).toBe(path.join(tempDir, 'env-target'));
|
|
80
|
-
});
|
|
81
|
-
test('should use CLI option over DBT_TARGET_PATH env var', async () => {
|
|
82
|
-
process.env.DBT_TARGET_PATH = 'env-target';
|
|
83
|
-
const dbtProjectContent = `name: test_project
|
|
84
|
-
profile: test_profile
|
|
85
|
-
target-path: "yml-target"
|
|
86
|
-
models-path: "models"
|
|
87
|
-
`;
|
|
88
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
89
|
-
const context = await (0, context_1.getDbtContext)({
|
|
90
|
-
projectDir: tempDir,
|
|
91
|
-
targetPath: 'cli-target',
|
|
92
|
-
});
|
|
93
|
-
expect(context.targetDir).toBe(path.join(tempDir, 'cli-target'));
|
|
94
|
-
});
|
|
95
|
-
test('should use CLI option over dbt_project.yml', async () => {
|
|
96
|
-
const dbtProjectContent = `name: test_project
|
|
97
|
-
profile: test_profile
|
|
98
|
-
target-path: "yml-target"
|
|
99
|
-
models-path: "models"
|
|
100
|
-
`;
|
|
101
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
102
|
-
const context = await (0, context_1.getDbtContext)({
|
|
103
|
-
projectDir: tempDir,
|
|
104
|
-
targetPath: 'cli-target',
|
|
105
|
-
});
|
|
106
|
-
expect(context.targetDir).toBe(path.join(tempDir, 'cli-target'));
|
|
107
|
-
});
|
|
108
|
-
test('should use dbt_project.yml when no env var or CLI option', async () => {
|
|
109
|
-
const dbtProjectContent = `name: test_project
|
|
110
|
-
profile: test_profile
|
|
111
|
-
target-path: "yml-target"
|
|
112
|
-
models-path: "models"
|
|
113
|
-
`;
|
|
114
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
115
|
-
const context = await (0, context_1.getDbtContext)({ projectDir: tempDir });
|
|
116
|
-
expect(context.targetDir).toBe(path.join(tempDir, 'yml-target'));
|
|
117
|
-
});
|
|
118
|
-
test('should use default target when nothing is set', async () => {
|
|
119
|
-
const dbtProjectContent = `name: test_project
|
|
120
|
-
profile: test_profile
|
|
121
|
-
models-path: "models"
|
|
122
|
-
`;
|
|
123
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
124
|
-
const context = await (0, context_1.getDbtContext)({ projectDir: tempDir });
|
|
125
|
-
expect(context.targetDir).toBe(path.join(tempDir, './target'));
|
|
126
|
-
});
|
|
127
|
-
test('should use absolute path from DBT_TARGET_PATH without joining', async () => {
|
|
128
|
-
const absoluteTargetPath = '/usr/app/examples/full-jaffle-shop/dbt/test_target';
|
|
129
|
-
process.env.DBT_TARGET_PATH = absoluteTargetPath;
|
|
130
|
-
const dbtProjectContent = `name: test_project
|
|
131
|
-
profile: test_profile
|
|
132
|
-
models-path: "models"
|
|
133
|
-
`;
|
|
134
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
135
|
-
const context = await (0, context_1.getDbtContext)({ projectDir: tempDir });
|
|
136
|
-
expect(context.targetDir).toBe(absoluteTargetPath);
|
|
137
|
-
});
|
|
138
|
-
test('should use absolute path from CLI option without joining', async () => {
|
|
139
|
-
const absoluteTargetPath = '/usr/app/examples/full-jaffle-shop/dbt/test_target';
|
|
140
|
-
const dbtProjectContent = `name: test_project
|
|
141
|
-
profile: test_profile
|
|
142
|
-
models-path: "models"
|
|
143
|
-
`;
|
|
144
|
-
await fs_1.promises.writeFile(path.join(tempDir, 'dbt_project.yml'), dbtProjectContent);
|
|
145
|
-
const context = await (0, context_1.getDbtContext)({
|
|
146
|
-
projectDir: tempDir,
|
|
147
|
-
targetPath: absoluteTargetPath,
|
|
148
|
-
});
|
|
149
|
-
expect(context.targetDir).toBe(absoluteTargetPath);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.test.d.ts","sourceRoot":"","sources":["../../src/dbt/manifest.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const fs_1 = require("fs");
|
|
5
|
-
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
6
|
-
const manifest_1 = require("./manifest");
|
|
7
|
-
vi.mock('node-fetch');
|
|
8
|
-
vi.mock('fs', () => ({
|
|
9
|
-
promises: {
|
|
10
|
-
readFile: vi.fn(),
|
|
11
|
-
},
|
|
12
|
-
}));
|
|
13
|
-
const mockedFetch = node_fetch_1.default;
|
|
14
|
-
const mockedReadFile = fs_1.promises.readFile;
|
|
15
|
-
const modelNode = (uniqueId, extra = {}) => ({
|
|
16
|
-
unique_id: uniqueId,
|
|
17
|
-
resource_type: 'model',
|
|
18
|
-
compiled: true,
|
|
19
|
-
...extra,
|
|
20
|
-
});
|
|
21
|
-
const buildManifest = (nodes, overrides = {}) => ({
|
|
22
|
-
nodes,
|
|
23
|
-
metadata: {
|
|
24
|
-
adapter_type: 'postgres',
|
|
25
|
-
},
|
|
26
|
-
metrics: {},
|
|
27
|
-
docs: {},
|
|
28
|
-
...overrides,
|
|
29
|
-
});
|
|
30
|
-
describe('isHttpUrl', () => {
|
|
31
|
-
test('returns true for http and https urls', () => {
|
|
32
|
-
expect((0, manifest_1.isHttpUrl)('http://example.com/manifest.json')).toBe(true);
|
|
33
|
-
expect((0, manifest_1.isHttpUrl)('https://bucket.s3.amazonaws.com/manifest.json')).toBe(true);
|
|
34
|
-
});
|
|
35
|
-
test('returns false for local paths and bare strings', () => {
|
|
36
|
-
expect((0, manifest_1.isHttpUrl)('./target/manifest.json')).toBe(false);
|
|
37
|
-
expect((0, manifest_1.isHttpUrl)('/abs/path/manifest.json')).toBe(false);
|
|
38
|
-
expect((0, manifest_1.isHttpUrl)('manifest.json')).toBe(false);
|
|
39
|
-
expect((0, manifest_1.isHttpUrl)('s3://bucket/manifest.json')).toBe(false);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
describe('loadCombineManifest', () => {
|
|
43
|
-
beforeEach(() => {
|
|
44
|
-
mockedFetch.mockReset();
|
|
45
|
-
mockedReadFile.mockReset();
|
|
46
|
-
});
|
|
47
|
-
test('fetches and parses a manifest from an http url', async () => {
|
|
48
|
-
const manifest = buildManifest({
|
|
49
|
-
'model.proj.a': modelNode('model.proj.a'),
|
|
50
|
-
});
|
|
51
|
-
mockedFetch.mockResolvedValue({
|
|
52
|
-
ok: true,
|
|
53
|
-
headers: {
|
|
54
|
-
get: (name) => name === 'content-type' ? 'application/json' : null,
|
|
55
|
-
},
|
|
56
|
-
text: async () => JSON.stringify(manifest),
|
|
57
|
-
});
|
|
58
|
-
const result = await (0, manifest_1.loadCombineManifest)('https://example.com/manifest.json');
|
|
59
|
-
expect(mockedFetch).toHaveBeenCalledWith('https://example.com/manifest.json');
|
|
60
|
-
expect(Object.keys(result.nodes)).toEqual(['model.proj.a']);
|
|
61
|
-
expect(mockedReadFile).not.toHaveBeenCalled();
|
|
62
|
-
});
|
|
63
|
-
test('throws a wrapped error when the http response is not ok', async () => {
|
|
64
|
-
mockedFetch.mockResolvedValue({
|
|
65
|
-
ok: false,
|
|
66
|
-
status: 404,
|
|
67
|
-
statusText: 'Not Found',
|
|
68
|
-
headers: {
|
|
69
|
-
get: () => 'application/json',
|
|
70
|
-
},
|
|
71
|
-
text: async () => '',
|
|
72
|
-
});
|
|
73
|
-
await expect((0, manifest_1.loadCombineManifest)('https://example.com/manifest.json')).rejects.toThrow('Could not load manifest from https://example.com/manifest.json');
|
|
74
|
-
});
|
|
75
|
-
test('reports the Lightdash dev app fallback as a missing manifest', async () => {
|
|
76
|
-
mockedFetch.mockResolvedValue({
|
|
77
|
-
ok: false,
|
|
78
|
-
status: 500,
|
|
79
|
-
statusText: 'Internal Server Error',
|
|
80
|
-
headers: {
|
|
81
|
-
get: (name) => {
|
|
82
|
-
if (name === 'content-type') {
|
|
83
|
-
return 'application/json; charset=utf-8';
|
|
84
|
-
}
|
|
85
|
-
if (name === 'lightdash-version')
|
|
86
|
-
return '1.163.2';
|
|
87
|
-
return null;
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
text: async () => JSON.stringify({
|
|
91
|
-
status: 'error',
|
|
92
|
-
error: {
|
|
93
|
-
statusCode: 500,
|
|
94
|
-
name: 'UnexpectedServerError',
|
|
95
|
-
message: 'Something went wrong.',
|
|
96
|
-
data: {},
|
|
97
|
-
},
|
|
98
|
-
}),
|
|
99
|
-
});
|
|
100
|
-
const promise = (0, manifest_1.loadCombineManifest)('http://localhost:8080/charter5-does-not-exist/manifest.json');
|
|
101
|
-
await expect(promise).rejects.toThrow('Manifest not found');
|
|
102
|
-
await expect(promise).rejects.not.toThrow('500 Internal Server Error');
|
|
103
|
-
});
|
|
104
|
-
test('reports the Lightdash production html fallback as a missing manifest', async () => {
|
|
105
|
-
mockedFetch.mockResolvedValue({
|
|
106
|
-
ok: true,
|
|
107
|
-
status: 200,
|
|
108
|
-
statusText: 'OK',
|
|
109
|
-
headers: {
|
|
110
|
-
get: (name) => {
|
|
111
|
-
if (name === 'content-type') {
|
|
112
|
-
return 'text/html; charset=utf-8';
|
|
113
|
-
}
|
|
114
|
-
if (name === 'lightdash-version')
|
|
115
|
-
return '1.163.2';
|
|
116
|
-
return null;
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
text: async () => '<!DOCTYPE html><html><body><div id="root"></div></body></html>',
|
|
120
|
-
});
|
|
121
|
-
await expect((0, manifest_1.loadCombineManifest)('https://lightdash.example.com/missing/manifest.json')).rejects.toThrow('Manifest not found');
|
|
122
|
-
});
|
|
123
|
-
test.each([
|
|
124
|
-
[
|
|
125
|
-
'a Lightdash API error',
|
|
126
|
-
'https://lightdash.example.com/api/v1/missing/manifest.json',
|
|
127
|
-
'1.163.2',
|
|
128
|
-
],
|
|
129
|
-
[
|
|
130
|
-
'an unmarked external error',
|
|
131
|
-
'https://example.com/missing/manifest.json',
|
|
132
|
-
null,
|
|
133
|
-
],
|
|
134
|
-
])('preserves %s', async (_description, url, lightdashVersion) => {
|
|
135
|
-
mockedFetch.mockResolvedValue({
|
|
136
|
-
ok: false,
|
|
137
|
-
status: 500,
|
|
138
|
-
statusText: 'Internal Server Error',
|
|
139
|
-
headers: {
|
|
140
|
-
get: (name) => {
|
|
141
|
-
if (name === 'content-type')
|
|
142
|
-
return 'application/json';
|
|
143
|
-
if (name === 'lightdash-version')
|
|
144
|
-
return lightdashVersion;
|
|
145
|
-
return null;
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
text: async () => JSON.stringify({
|
|
149
|
-
status: 'error',
|
|
150
|
-
error: {
|
|
151
|
-
statusCode: 500,
|
|
152
|
-
name: 'UnexpectedServerError',
|
|
153
|
-
message: 'Something went wrong.',
|
|
154
|
-
data: {},
|
|
155
|
-
},
|
|
156
|
-
}),
|
|
157
|
-
});
|
|
158
|
-
await expect((0, manifest_1.loadCombineManifest)(url)).rejects.toThrow('500 Internal Server Error');
|
|
159
|
-
});
|
|
160
|
-
test('reads a manifest from a local path', async () => {
|
|
161
|
-
const manifest = buildManifest({
|
|
162
|
-
'model.proj.b': modelNode('model.proj.b'),
|
|
163
|
-
});
|
|
164
|
-
mockedReadFile.mockResolvedValue(JSON.stringify(manifest));
|
|
165
|
-
const result = await (0, manifest_1.loadCombineManifest)('./target/manifest.json');
|
|
166
|
-
expect(mockedReadFile).toHaveBeenCalled();
|
|
167
|
-
expect(Object.keys(result.nodes)).toEqual(['model.proj.b']);
|
|
168
|
-
expect(mockedFetch).not.toHaveBeenCalled();
|
|
169
|
-
});
|
|
170
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"models.test.d.ts","sourceRoot":"","sources":["../../src/dbt/models.test.ts"],"names":[],"mappings":""}
|
package/dist/dbt/models.test.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const common_1 = require("@lightdash/common");
|
|
4
|
-
const models_1 = require("./models");
|
|
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
|
-
});
|
|
46
|
-
describe('getWarehouseTableForModel', () => {
|
|
47
|
-
const catalog = {
|
|
48
|
-
db: {
|
|
49
|
-
ds: {
|
|
50
|
-
orders: {
|
|
51
|
-
order_id: common_1.DimensionType.STRING,
|
|
52
|
-
product: common_1.DimensionType.STRING,
|
|
53
|
-
'product.sku': common_1.DimensionType.STRING,
|
|
54
|
-
'product.price': common_1.DimensionType.NUMBER,
|
|
55
|
-
'product.variants': common_1.DimensionType.STRING,
|
|
56
|
-
'product.variants.size': common_1.DimensionType.STRING,
|
|
57
|
-
customer: common_1.DimensionType.STRING,
|
|
58
|
-
'customer.location': common_1.DimensionType.STRING,
|
|
59
|
-
tags: common_1.DimensionType.STRING,
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
Object.entries({
|
|
65
|
-
product: { repeated: true, record: true },
|
|
66
|
-
'product.variants': { repeated: true, record: true },
|
|
67
|
-
customer: { repeated: false, record: true },
|
|
68
|
-
tags: { repeated: true, record: false },
|
|
69
|
-
}).forEach(([path, shape]) => (0, common_1.setCatalogNestedColumnShape)(catalog, 'db', 'ds', 'orders', path, shape));
|
|
70
|
-
const warehouseClient = {
|
|
71
|
-
getCatalog: vi.fn(async () => catalog),
|
|
72
|
-
};
|
|
73
|
-
const model = {
|
|
74
|
-
name: 'orders',
|
|
75
|
-
schema: 'ds',
|
|
76
|
-
database: 'db',
|
|
77
|
-
alias: 'orders',
|
|
78
|
-
originalFilePath: 'models/orders.sql',
|
|
79
|
-
patchPath: null,
|
|
80
|
-
packageName: 'p',
|
|
81
|
-
uniqueId: 'model.p.orders',
|
|
82
|
-
};
|
|
83
|
-
test('generates scalars, struct leaves and arrays of scalars but reports every warehouse path', async () => {
|
|
84
|
-
const result = await (0, models_1.getWarehouseTableForModel)({
|
|
85
|
-
model,
|
|
86
|
-
warehouseClient,
|
|
87
|
-
preserveColumnCase: false,
|
|
88
|
-
});
|
|
89
|
-
expect(Object.keys(result.table).sort()).toEqual([
|
|
90
|
-
'customer.location',
|
|
91
|
-
'order_id',
|
|
92
|
-
'tags',
|
|
93
|
-
]);
|
|
94
|
-
expect(result.warehouseColumnPaths.sort()).toEqual([
|
|
95
|
-
'customer',
|
|
96
|
-
'customer.location',
|
|
97
|
-
'order_id',
|
|
98
|
-
'product',
|
|
99
|
-
'product.price',
|
|
100
|
-
'product.sku',
|
|
101
|
-
'product.variants',
|
|
102
|
-
'product.variants.size',
|
|
103
|
-
'tags',
|
|
104
|
-
]);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
describe('getColumnsMissingFromWarehouse', () => {
|
|
108
|
-
test('keeps documented nested leaves and containers, drops only paths the warehouse lacks', () => {
|
|
109
|
-
expect((0, models_1.getColumnsMissingFromWarehouse)([
|
|
110
|
-
'order_id',
|
|
111
|
-
'Product',
|
|
112
|
-
'product.sku',
|
|
113
|
-
'product.variants.size',
|
|
114
|
-
'legacy_status',
|
|
115
|
-
'product.colour',
|
|
116
|
-
], [
|
|
117
|
-
'order_id',
|
|
118
|
-
'product',
|
|
119
|
-
'product.sku',
|
|
120
|
-
'product.variants',
|
|
121
|
-
'product.variants.size',
|
|
122
|
-
])).toEqual(['legacy_status', 'product.colour']);
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
describe('isDocBlock', () => {
|
|
126
|
-
test('should match all doc block variations', () => {
|
|
127
|
-
expect((0, models_1.isDocBlock)("{{doc('user_id')}}")).toBe(true); // single quote
|
|
128
|
-
expect((0, models_1.isDocBlock)('{{doc("user_id")}}')).toBe(true); // double quote
|
|
129
|
-
expect((0, models_1.isDocBlock)("{{ doc('user_id') }}")).toBe(true); // white spaces
|
|
130
|
-
expect((0, models_1.isDocBlock)("{{ doc('user_id')}}")).toBe(true); // inconsistent white space
|
|
131
|
-
});
|
|
132
|
-
test('should return false when value doesnt match doc block', () => {
|
|
133
|
-
expect((0, models_1.isDocBlock)()).toBe(false);
|
|
134
|
-
expect((0, models_1.isDocBlock)('{{ref("user_id")}}')).toBe(false);
|
|
135
|
-
expect((0, models_1.isDocBlock)("doc('user_id')")).toBe(false);
|
|
136
|
-
expect((0, models_1.isDocBlock)('my description')).toBe(false);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"profiles.test.d.ts","sourceRoot":"","sources":["../../src/dbt/profiles.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const fs = tslib_1.__importStar(require("fs"));
|
|
5
|
-
const os = tslib_1.__importStar(require("os"));
|
|
6
|
-
const path = tslib_1.__importStar(require("path"));
|
|
7
|
-
const profile_1 = require("./profile");
|
|
8
|
-
vi.mock('os');
|
|
9
|
-
vi.mock('fs');
|
|
10
|
-
vi.mock('path');
|
|
11
|
-
describe('Profile', () => {
|
|
12
|
-
const { env, cwd } = process;
|
|
13
|
-
const mockAccessSync = fs.accessSync;
|
|
14
|
-
const mockHomedir = os.homedir;
|
|
15
|
-
const mockJoin = path.join;
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
vi.resetAllMocks();
|
|
18
|
-
vi.resetModules();
|
|
19
|
-
process.cwd = vi.fn(() => '/current/dir');
|
|
20
|
-
mockHomedir.mockReturnValue('/root');
|
|
21
|
-
mockJoin.mockImplementation((...paths) => paths.join('/'));
|
|
22
|
-
process.env = { ...env };
|
|
23
|
-
});
|
|
24
|
-
afterEach(() => {
|
|
25
|
-
process.env = env;
|
|
26
|
-
process.cwd = cwd;
|
|
27
|
-
});
|
|
28
|
-
describe('findDbtDefaultProfile', () => {
|
|
29
|
-
test('should return path from DBT_PROFILE_DIR when set', () => {
|
|
30
|
-
process.env.DBT_PROFILES_DIR = '/path/to/profiles';
|
|
31
|
-
const result = (0, profile_1.findDbtDefaultProfile)();
|
|
32
|
-
expect(result).toBe('/path/to/profiles');
|
|
33
|
-
});
|
|
34
|
-
test('should return cwd when profile.yml exists and DBT_PROFILE_DIR is undefined', () => {
|
|
35
|
-
delete process.env.DBT_PROFILES_DIR;
|
|
36
|
-
mockAccessSync.mockImplementation(() => undefined);
|
|
37
|
-
expect((0, profile_1.findDbtDefaultProfile)()).toBe('/current/dir');
|
|
38
|
-
expect(mockAccessSync).toHaveBeenCalledWith('/current/dir/profiles.yml', fs.constants.F_OK);
|
|
39
|
-
});
|
|
40
|
-
test('should return homedir when profile.yml does not exist in cwd', () => {
|
|
41
|
-
delete process.env.DBT_PROFILE_DIR;
|
|
42
|
-
mockAccessSync.mockImplementation(() => {
|
|
43
|
-
throw new Error('File not found');
|
|
44
|
-
});
|
|
45
|
-
expect((0, profile_1.findDbtDefaultProfile)()).toBe('/root/.dbt');
|
|
46
|
-
expect(mockAccessSync).toHaveBeenCalledWith('/current/dir/profiles.yml', fs.constants.F_OK);
|
|
47
|
-
expect(mockHomedir).toHaveBeenCalled();
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"athena.test.d.ts","sourceRoot":"","sources":["../../../src/dbt/targets/athena.test.ts"],"names":[],"mappings":""}
|