Skip to content

Commit ad730a2

Browse files
committed
chore: fix
1 parent 53b43d8 commit ad730a2

19 files changed

Lines changed: 175 additions & 94 deletions

File tree

packages/cubejs-api-gateway/src/sql-server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,8 @@ export class SQLServer {
361361
}
362362

363363
protected createDefaultCheckSqlAuthFn(options: SQLServerOptions): CheckSQLAuthFn {
364-
let allowedUser: string | null = options.sqlUser || getEnv('sqlUser');
365-
let allowedPassword: string | null = options.sqlPassword || getEnv('sqlPassword');
364+
let allowedUser: string | null = options.sqlUser || getEnv('sqlUser') || null;
365+
let allowedPassword: string | null = options.sqlPassword || getEnv('sqlPassword') || null;
366366

367367
if (!getEnv('devMode')) {
368368
if (!allowedUser) {

packages/cubejs-api-gateway/src/types/strings.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,7 @@ type QueryOrderType =
100100
'asc' |
101101
'desc';
102102

103-
/**
104-
* ApiScopes data type.
105-
*/
106-
type ApiScopes =
107-
'graphql' |
108-
'meta' |
109-
'data' |
110-
'sql' |
111-
'jobs';
103+
export type { ApiScopes } from '@cubejs-backend/shared';
112104

113105
export {
114106
RequestType,
@@ -121,5 +113,4 @@ export {
121113
FilterOperator,
122114
QueryTimeDimensionGranularity,
123115
QueryOrderType,
124-
ApiScopes,
125116
};

packages/cubejs-athena-driver/src/AthenaDriver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export class AthenaDriver extends BaseDriver implements DriverInterface {
8787

8888
private athena: Athena;
8989

90-
private schema: string;
90+
private schema: string | undefined;
9191

9292
/**
9393
* Class constructor.

packages/cubejs-backend-shared/src/env.ts

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import { get } from 'env-var';
33
import { displayCLIWarning } from './cli';
44
import { isNativeSupported } from './platform';
5+
import type { LogLevel } from './logger';
6+
import type { ApiScopes, ExportBucketType } from './shared-types';
57

68
export class InvalidConfiguration extends Error {
79
public constructor(key: string, value: any, description: string) {
@@ -163,7 +165,24 @@ const variables = {
163165
devMode: () => get('CUBEJS_DEV_MODE')
164166
.default('false')
165167
.asBoolStrict(),
166-
logLevel: () => get('CUBEJS_LOG_LEVEL').asString(),
168+
logLevel: (): LogLevel | undefined => {
169+
const value = get('CUBEJS_LOG_LEVEL').asString();
170+
if (value) {
171+
switch (value.toLowerCase()) {
172+
case 'trace':
173+
case 'info':
174+
case 'warn':
175+
case 'error':
176+
break;
177+
// not used, but let's allow
178+
case 'debug':
179+
break;
180+
default:
181+
throw new InvalidConfiguration('CUBEJS_LOG_LEVEL', value, 'Must be one of: trace, debug, info, warn, error');
182+
}
183+
}
184+
return value as LogLevel | undefined;
185+
},
167186
port: () => asPortOrSocket(process.env.PORT || '4000', 'PORT'),
168187
tls: () => get('CUBEJS_ENABLE_TLS')
169188
.default('false')
@@ -847,27 +866,28 @@ const variables = {
847866
/**
848867
* Export bucket storage type.
849868
*/
850-
dbExportBucketType: ({
869+
dbExportBucketType: <T extends ExportBucketType>({
851870
supported,
852871
dataSource,
853872
}: {
854-
supported: ('s3' | 'gcp' | 'azure')[],
873+
supported: readonly T[],
855874
dataSource: string,
856-
}) => {
875+
}): T | undefined => {
857876
const val = process.env[
858877
keyByDataSource('CUBEJS_DB_EXPORT_BUCKET_TYPE', dataSource)
859-
];
878+
] as T | undefined;
860879
if (
861880
val &&
862881
supported &&
863-
supported.indexOf(<'s3' | 'gcp' | 'azure'>val) === -1
882+
supported.indexOf(val) === -1
864883
) {
865884
throw new TypeError(
866885
`The ${
867886
keyByDataSource('CUBEJS_DB_EXPORT_BUCKET_TYPE', dataSource)
868887
} must be one of the [${supported.join(', ')}].`
869888
);
870889
}
890+
871891
return val;
872892
},
873893

@@ -2186,7 +2206,7 @@ const variables = {
21862206
cacheAndQueueDriver: () => get('CUBEJS_CACHE_AND_QUEUE_DRIVER')
21872207
.asString(),
21882208
defaultApiScope: () => get('CUBEJS_DEFAULT_API_SCOPES')
2189-
.asArray(','),
2209+
.asArray(',') as ApiScopes[] | undefined,
21902210
jwkUrl: () => get('CUBEJS_JWK_URL')
21912211
.asString(),
21922212
jwtKey: () => get('CUBEJS_JWT_KEY')
@@ -2333,6 +2353,20 @@ const variables = {
23332353

23342354
type Vars = typeof variables;
23352355

2356+
export function getEnvFn<T extends keyof Vars>(key: T): Vars[T] {
2357+
if (key in variables) {
2358+
return variables[key] as Vars[T];
2359+
}
2360+
2361+
throw new Error(
2362+
`Unsupported env variable: "${key}"`,
2363+
);
2364+
}
2365+
2366+
/**
2367+
* @deprecated Use getEnvFn instead. TypeScript cannot infer return types correctly
2368+
* for generic env functions through this wrapper, as ReturnType<> erases generics.
2369+
*/
23362370
export function getEnv<T extends keyof Vars>(key: T, ...args: Parameters<Vars[T]>): ReturnType<Vars[T]> {
23372371
if (key in variables) {
23382372
return (variables[key] as any)(...args);

packages/cubejs-backend-shared/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export {
22
getEnv,
3+
getEnvFn,
34
assertDataSource,
45
keyByDataSource,
56
isDockerImage,

packages/cubejs-backend-shared/src/shared-types.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,16 @@ no-cache — AKA “forceRefresh”
2020
Returns fresh data from the database, even if it takes minutes and many “Continue wait” intervals
2121
*/
2222
export type CacheMode = 'stale-if-slow' | 'stale-while-revalidate' | 'must-revalidate' | 'no-cache';
23+
24+
export type ApiScopes =
25+
'graphql' |
26+
'meta' |
27+
'data' |
28+
'sql' |
29+
'jobs';
30+
31+
export type ExportBucketType =
32+
's3' |
33+
'gcp' |
34+
'gcs' |
35+
'azure';

packages/cubejs-bigquery-driver/src/BigQueryDriver.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,19 @@ export class BigQueryDriver extends BaseDriver implements DriverInterface {
111111
config.dataSource ||
112112
assertDataSource('default');
113113

114+
const bigqueryCredentials = getEnv('bigqueryCredentials', { dataSource });
115+
114116
this.options = {
115117
scopes: [
116118
'https://www.googleapis.com/auth/bigquery',
117119
'https://www.googleapis.com/auth/drive',
118120
],
119121
projectId: getEnv('bigqueryProjectId', { dataSource }),
120122
keyFilename: getEnv('bigqueryKeyFile', { dataSource }),
121-
credentials: getEnv('bigqueryCredentials', { dataSource })
123+
credentials: bigqueryCredentials
122124
? JSON.parse(
123125
Buffer.from(
124-
getEnv('bigqueryCredentials', { dataSource }),
126+
bigqueryCredentials,
125127
'base64',
126128
).toString('utf8')
127129
)

packages/cubejs-clickhouse-driver/src/ClickHouseDriver.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import {
88
getEnv,
99
assertDataSource,
10+
ExportBucketType,
1011
} from '@cubejs-backend/shared';
1112
import {
1213
BaseDriver,
@@ -35,7 +36,7 @@ import sqlstring from 'sqlstring';
3536

3637
import { transformRow, transformStreamRow } from './HydrationStream';
3738

38-
const SUPPORTED_BUCKET_TYPES = ['s3'];
39+
const SUPPORTED_BUCKET_TYPES: ExportBucketType[] = ['s3'];
3940

4041
const ClickhouseTypeToGeneric: Record<string, string> = {
4142
enum: 'text',
@@ -94,23 +95,23 @@ export interface ClickHouseDriverOptions {
9495
}
9596

9697
interface ClickhouseDriverExportRequiredAWS {
97-
bucketType: 's3',
98+
bucketType: ExportBucketType,
9899
bucketName: string,
99100
region: string,
100101
}
101102

102103
interface ClickhouseDriverExportKeySecretAWS extends ClickhouseDriverExportRequiredAWS {
103-
keyId: string,
104-
secretKey: string,
104+
keyId?: string,
105+
secretKey?: string,
105106
}
106107

107108
interface ClickhouseDriverExportAWS extends ClickhouseDriverExportKeySecretAWS {
108109
}
109110

110111
type ClickHouseDriverConfig = {
111112
url: string,
112-
username: string,
113-
password: string,
113+
username?: string,
114+
password?: string,
114115
readOnly: boolean,
115116
database: string,
116117
requestTimeout: number,
@@ -505,7 +506,7 @@ export class ClickHouseDriver extends BaseDriver implements DriverInterface {
505506
protected getExportBucket(
506507
dataSource: string,
507508
): ClickhouseDriverExportAWS | null {
508-
const requiredExportBucket: ClickhouseDriverExportRequiredAWS = {
509+
const requiredExportBucket: Partial<ClickhouseDriverExportRequiredAWS> = {
509510
bucketType: getEnv('dbExportBucketType', {
510511
supported: SUPPORTED_BUCKET_TYPES,
511512
dataSource,
@@ -514,7 +515,7 @@ export class ClickHouseDriver extends BaseDriver implements DriverInterface {
514515
region: getEnv('dbExportBucketAwsRegion', { dataSource }),
515516
};
516517

517-
const exportBucket: ClickhouseDriverExportAWS = {
518+
const exportBucket: Partial<ClickhouseDriverExportAWS> = {
518519
...requiredExportBucket,
519520
keyId: getEnv('dbExportBucketAwsKey', { dataSource }),
520521
secretKey: getEnv('dbExportBucketAwsSecret', { dataSource }),
@@ -536,7 +537,7 @@ export class ClickHouseDriver extends BaseDriver implements DriverInterface {
536537
);
537538
}
538539

539-
return exportBucket;
540+
return exportBucket as ClickhouseDriverExportAWS;
540541
}
541542

542543
return null;
@@ -620,13 +621,13 @@ export class ClickHouseDriver extends BaseDriver implements DriverInterface {
620621

621622
await this.command(formattedQuery);
622623

624+
const { keyId, secretKey, region } = this.config.exportBucket;
623625
const csvFile = await this.extractUnloadedFilesFromS3(
624626
{
625-
credentials: {
626-
accessKeyId: this.config.exportBucket.keyId,
627-
secretAccessKey: this.config.exportBucket.secretKey,
628-
},
629-
region: this.config.exportBucket.region,
627+
credentials: keyId && secretKey
628+
? { accessKeyId: keyId, secretAccessKey: secretKey }
629+
: undefined,
630+
region,
630631
},
631632
bucketName,
632633
exportPrefix,

packages/cubejs-databricks-jdbc-driver/src/DatabricksDriver.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import fetch from 'node-fetch';
8-
import { assertDataSource, getEnv, LoggerFn } from '@cubejs-backend/shared';
8+
import { assertDataSource, getEnv, getEnvFn, LoggerFn, ExportBucketType } from '@cubejs-backend/shared';
99
import {
1010
DatabaseStructure,
1111
DriverCapabilities,
@@ -25,7 +25,7 @@ import {
2525
resolveJDBCDriver
2626
} from './helpers';
2727

28-
const SUPPORTED_BUCKET_TYPES = ['s3', 'gcs', 'azure'];
28+
const SUPPORTED_BUCKET_TYPES = ['s3', 'gcs', 'azure'] as const;
2929

3030
export type DatabricksDriverConfiguration = JDBCDriverConfiguration &
3131
{
@@ -37,7 +37,7 @@ export type DatabricksDriverConfiguration = JDBCDriverConfiguration &
3737
/**
3838
* Export bucket type.
3939
*/
40-
bucketType?: string,
40+
bucketType?: 's3' | 'gcs' | 'azure',
4141

4242
/**
4343
* Export bucket path.
@@ -204,10 +204,14 @@ export class DatabricksDriver extends JDBCDriver {
204204
assertDataSource('default');
205205

206206
let showSparkProtocolWarn = false;
207-
let url: string =
207+
let url =
208208
conf?.url ||
209209
getEnv('databricksUrl', { dataSource }) ||
210210
getEnv('jdbcUrl', { dataSource });
211+
if (!url) {
212+
throw new Error('url is required for Databricks');
213+
}
214+
211215
if (url.indexOf('jdbc:spark://') !== -1) {
212216
showSparkProtocolWarn = true;
213217
url = url.replace('jdbc:spark://', 'jdbc:databricks://');
@@ -265,7 +269,7 @@ export class DatabricksDriver extends JDBCDriver {
265269
// common export bucket config
266270
bucketType:
267271
conf?.bucketType ||
268-
getEnv('dbExportBucketType', { supported: SUPPORTED_BUCKET_TYPES, dataSource }),
272+
getEnvFn('dbExportBucketType')({ supported: SUPPORTED_BUCKET_TYPES, dataSource }),
269273
exportBucket:
270274
conf?.exportBucket ||
271275
getEnv('dbExportBucket', { dataSource }),
@@ -759,7 +763,7 @@ export class DatabricksDriver extends JDBCDriver {
759763
* export bucket data.
760764
*/
761765
public async unload(tableName: string, options: UnloadOptions) {
762-
if (!SUPPORTED_BUCKET_TYPES.includes(this.config.bucketType as string)) {
766+
if (!this.config.bucketType || !SUPPORTED_BUCKET_TYPES.includes(this.config.bucketType)) {
763767
throw new Error(`Unsupported export bucket type: ${
764768
this.config.bucketType
765769
}`);

packages/cubejs-duckdb-driver/src/DuckDBDriver.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
TableStructure,
99
TableColumnQueryResult,
1010
} from '@cubejs-backend/base-driver';
11-
import { getEnv } from '@cubejs-backend/shared';
11+
import { assertDataSource, getEnv } from '@cubejs-backend/shared';
1212
import { promisify } from 'util';
1313
import * as stream from 'stream';
1414
import { Connection, Database } from 'duckdb';
@@ -40,15 +40,19 @@ const DuckDBToGenericType: Record<string, GenericDataBaseType> = {
4040
};
4141

4242
export class DuckDBDriver extends BaseDriver implements DriverInterface {
43+
protected readonly config: DuckDBDriverConfiguration & { dataSource: string };
44+
4345
protected initPromise: Promise<InitPromise> | null = null;
4446

45-
private readonly schema: string;
47+
private readonly schema: string | undefined;
4648

4749
public constructor(
48-
protected readonly config: DuckDBDriverConfiguration = {},
50+
config: DuckDBDriverConfiguration = {},
4951
) {
5052
super();
5153

54+
const dataSource = config.dataSource || assertDataSource('default');
55+
this.config = { ...config, dataSource };
5256
this.schema = this.config.schema || getEnv('duckdbSchema', this.config);
5357
}
5458

0 commit comments

Comments
 (0)