@owox/backend 0.24.0 → 0.25.0-next-20260430151351
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/src/data-marts/data-destination-types/data-destination-providers.d.ts +2 -1
- package/dist/src/data-marts/data-destination-types/data-destination-providers.js +2 -0
- package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-aggregation-mapper.service.d.ts +12 -0
- package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-aggregation-mapper.service.js +72 -0
- package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-connector-api-data.service.js +4 -4
- package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-connector-api-schema.service.d.ts +4 -2
- package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-connector-api-schema.service.js +1 -24
- package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-type-mapper.service.d.ts +8 -6
- package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-type-mapper.service.js +30 -1
- package/dist/src/data-marts/data-storage-types/field-aggregation.d.ts +4 -0
- package/dist/src/data-marts/data-storage-types/field-aggregation.js +60 -0
- package/dist/src/data-marts/dto/domain/report-data-header.dto.d.ts +5 -7
- package/dist/src/data-marts/dto/domain/report-data-header.dto.js +3 -1
- package/dist/src/data-marts/dto/domain/storage-field-type.d.ts +6 -0
- package/dist/src/data-marts/dto/domain/storage-field-type.js +3 -0
- package/dist/src/data-marts/services/blended-report-data.service.js +5 -3
- package/package.json +5 -5
|
@@ -27,6 +27,7 @@ import { LookerStudioConnectorApiService } from './looker-studio-connector/servi
|
|
|
27
27
|
import { LookerStudioConnectorCredentialsValidator } from './looker-studio-connector/services/looker-studio-connector-credentials-validator';
|
|
28
28
|
import { LookerStudioConnectorCredentialsProcessor } from './looker-studio-connector/services/looker-studio-connector-credentials-processor';
|
|
29
29
|
import { LookerStudioConnectorSecretKeyRotator } from './looker-studio-connector/services/looker-studio-connector-secret-key-rotator';
|
|
30
|
+
import { LookerStudioAggregationMapperService } from './looker-studio-connector/services/looker-studio-aggregation-mapper.service';
|
|
30
31
|
import { LookerStudioTypeMapperService } from './looker-studio-connector/services/looker-studio-type-mapper.service';
|
|
31
32
|
import { EmailAccessValidator, GoogleChatAccessValidator, MsTeamsAccessValidator, SlackAccessValidator } from './ee/email/services/email-access-validator';
|
|
32
33
|
import { EmailCredentialsValidator, GoogleChatCredentialsValidator, MsTeamsCredentialsValidator, SlackCredentialsValidator } from './ee/email/services/email-credentials-validator';
|
|
@@ -35,7 +36,7 @@ export declare const DATA_DESTINATION_CREDENTIALS_VALIDATOR_RESOLVER: unique sym
|
|
|
35
36
|
export declare const DATA_DESTINATION_CREDENTIALS_PROCESSOR_RESOLVER: unique symbol;
|
|
36
37
|
export declare const DATA_DESTINATION_REPORT_WRITER_RESOLVER: unique symbol;
|
|
37
38
|
export declare const DATA_DESTINATION_SECRET_KEY_ROTATOR_RESOLVER: unique symbol;
|
|
38
|
-
export declare const dataDestinationResolverProviders: (typeof AvailableDestinationTypesService | typeof DataDestinationPublicCredentialsFactory | typeof DataDestinationCredentialsUtils | typeof EmailReportWriter | typeof SlackReportWriter | typeof MsTeamsReportWriter | typeof GoogleChatReportWriter | typeof GoogleSheetsApiAdapterFactory | typeof SheetMetadataFormatter | typeof GoogleSheetsReportCreatedListener | typeof GoogleSheetsReportDeletedListener | typeof GoogleSheetsAccessValidator | typeof GoogleSheetsCredentialsValidator | typeof SheetHeaderFormatter | typeof SheetValuesFormatter | typeof GoogleSheetsReportWriter | typeof LookerStudioConnectorAccessValidator | typeof LookerStudioConnectorApiConfigService | typeof LookerStudioTypeMapperService | typeof LookerStudioConnectorApiDataService | typeof LookerStudioConnectorApiSchemaService | typeof LookerStudioConnectorApiService | typeof LookerStudioConnectorCredentialsValidator | typeof LookerStudioConnectorCredentialsProcessor | typeof LookerStudioConnectorSecretKeyRotator | typeof EmailAccessValidator | typeof SlackAccessValidator | typeof MsTeamsAccessValidator | typeof GoogleChatAccessValidator | typeof EmailCredentialsValidator | typeof SlackCredentialsValidator | typeof MsTeamsCredentialsValidator | typeof GoogleChatCredentialsValidator | {
|
|
39
|
+
export declare const dataDestinationResolverProviders: (typeof AvailableDestinationTypesService | typeof DataDestinationPublicCredentialsFactory | typeof DataDestinationCredentialsUtils | typeof EmailReportWriter | typeof SlackReportWriter | typeof MsTeamsReportWriter | typeof GoogleChatReportWriter | typeof GoogleSheetsApiAdapterFactory | typeof SheetMetadataFormatter | typeof GoogleSheetsReportCreatedListener | typeof GoogleSheetsReportDeletedListener | typeof GoogleSheetsAccessValidator | typeof GoogleSheetsCredentialsValidator | typeof SheetHeaderFormatter | typeof SheetValuesFormatter | typeof GoogleSheetsReportWriter | typeof LookerStudioConnectorAccessValidator | typeof LookerStudioConnectorApiConfigService | typeof LookerStudioAggregationMapperService | typeof LookerStudioTypeMapperService | typeof LookerStudioConnectorApiDataService | typeof LookerStudioConnectorApiSchemaService | typeof LookerStudioConnectorApiService | typeof LookerStudioConnectorCredentialsValidator | typeof LookerStudioConnectorCredentialsProcessor | typeof LookerStudioConnectorSecretKeyRotator | typeof EmailAccessValidator | typeof SlackAccessValidator | typeof MsTeamsAccessValidator | typeof GoogleChatAccessValidator | typeof EmailCredentialsValidator | typeof SlackCredentialsValidator | typeof MsTeamsCredentialsValidator | typeof GoogleChatCredentialsValidator | {
|
|
39
40
|
provide: symbol;
|
|
40
41
|
useFactory: (available: AvailableDestinationTypesService, ...validators: DataDestinationAccessValidator[]) => TypeResolver<DataDestinationType, DataDestinationAccessValidator>;
|
|
41
42
|
inject: (typeof AvailableDestinationTypesService | typeof GoogleSheetsAccessValidator | typeof LookerStudioConnectorAccessValidator | typeof EmailAccessValidator | typeof SlackAccessValidator | typeof MsTeamsAccessValidator | typeof GoogleChatAccessValidator)[];
|
|
@@ -24,6 +24,7 @@ const looker_studio_connector_api_service_1 = require("./looker-studio-connector
|
|
|
24
24
|
const looker_studio_connector_credentials_validator_1 = require("./looker-studio-connector/services/looker-studio-connector-credentials-validator");
|
|
25
25
|
const looker_studio_connector_credentials_processor_1 = require("./looker-studio-connector/services/looker-studio-connector-credentials-processor");
|
|
26
26
|
const looker_studio_connector_secret_key_rotator_1 = require("./looker-studio-connector/services/looker-studio-connector-secret-key-rotator");
|
|
27
|
+
const looker_studio_aggregation_mapper_service_1 = require("./looker-studio-connector/services/looker-studio-aggregation-mapper.service");
|
|
27
28
|
const looker_studio_type_mapper_service_1 = require("./looker-studio-connector/services/looker-studio-type-mapper.service");
|
|
28
29
|
const email_access_validator_1 = require("./ee/email/services/email-access-validator");
|
|
29
30
|
const email_credentials_validator_1 = require("./ee/email/services/email-credentials-validator");
|
|
@@ -82,6 +83,7 @@ exports.dataDestinationResolverProviders = [
|
|
|
82
83
|
looker_studio_connector_api_schema_service_1.LookerStudioConnectorApiSchemaService,
|
|
83
84
|
looker_studio_connector_api_data_service_1.LookerStudioConnectorApiDataService,
|
|
84
85
|
looker_studio_connector_api_service_1.LookerStudioConnectorApiService,
|
|
86
|
+
looker_studio_aggregation_mapper_service_1.LookerStudioAggregationMapperService,
|
|
85
87
|
looker_studio_type_mapper_service_1.LookerStudioTypeMapperService,
|
|
86
88
|
{
|
|
87
89
|
provide: exports.DATA_DESTINATION_ACCESS_VALIDATOR_RESOLVER,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AggregateFunction } from '../../../dto/schemas/aggregate-function.schema';
|
|
2
|
+
import { AggregationType } from '../enums/aggregation-type.enum';
|
|
3
|
+
import { FieldConceptType } from '../enums/field-concept-type.enum';
|
|
4
|
+
import { FieldDataType } from '../enums/field-data-type.enum';
|
|
5
|
+
export interface AggregationSemantics {
|
|
6
|
+
conceptType: FieldConceptType;
|
|
7
|
+
defaultAggregationType?: AggregationType;
|
|
8
|
+
isReaggregatable?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare class LookerStudioAggregationMapperService {
|
|
11
|
+
mapAggregateFunctionToLookerType(aggFunc: AggregateFunction | undefined, dataType: FieldDataType): AggregationSemantics;
|
|
12
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.LookerStudioAggregationMapperService = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const aggregation_type_enum_1 = require("../enums/aggregation-type.enum");
|
|
12
|
+
const field_concept_type_enum_1 = require("../enums/field-concept-type.enum");
|
|
13
|
+
const field_data_type_enum_1 = require("../enums/field-data-type.enum");
|
|
14
|
+
let LookerStudioAggregationMapperService = class LookerStudioAggregationMapperService {
|
|
15
|
+
mapAggregateFunctionToLookerType(aggFunc, dataType) {
|
|
16
|
+
if (aggFunc === undefined) {
|
|
17
|
+
return dataType === field_data_type_enum_1.FieldDataType.NUMBER
|
|
18
|
+
? {
|
|
19
|
+
conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
|
|
20
|
+
defaultAggregationType: aggregation_type_enum_1.AggregationType.SUM,
|
|
21
|
+
isReaggregatable: true,
|
|
22
|
+
}
|
|
23
|
+
: { conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION };
|
|
24
|
+
}
|
|
25
|
+
switch (aggFunc) {
|
|
26
|
+
case 'SUM':
|
|
27
|
+
return dataType === field_data_type_enum_1.FieldDataType.NUMBER
|
|
28
|
+
? {
|
|
29
|
+
conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
|
|
30
|
+
defaultAggregationType: aggregation_type_enum_1.AggregationType.SUM,
|
|
31
|
+
isReaggregatable: true,
|
|
32
|
+
}
|
|
33
|
+
: { conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION };
|
|
34
|
+
case 'MIN':
|
|
35
|
+
return dataType === field_data_type_enum_1.FieldDataType.NUMBER
|
|
36
|
+
? {
|
|
37
|
+
conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
|
|
38
|
+
defaultAggregationType: aggregation_type_enum_1.AggregationType.MIN,
|
|
39
|
+
isReaggregatable: true,
|
|
40
|
+
}
|
|
41
|
+
: { conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION };
|
|
42
|
+
case 'MAX':
|
|
43
|
+
return dataType === field_data_type_enum_1.FieldDataType.NUMBER
|
|
44
|
+
? {
|
|
45
|
+
conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
|
|
46
|
+
defaultAggregationType: aggregation_type_enum_1.AggregationType.MAX,
|
|
47
|
+
isReaggregatable: true,
|
|
48
|
+
}
|
|
49
|
+
: { conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION };
|
|
50
|
+
case 'COUNT':
|
|
51
|
+
return {
|
|
52
|
+
conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
|
|
53
|
+
defaultAggregationType: aggregation_type_enum_1.AggregationType.SUM,
|
|
54
|
+
isReaggregatable: true,
|
|
55
|
+
};
|
|
56
|
+
case 'COUNT_DISTINCT':
|
|
57
|
+
return { conceptType: field_concept_type_enum_1.FieldConceptType.METRIC, isReaggregatable: false };
|
|
58
|
+
case 'STRING_AGG':
|
|
59
|
+
case 'ANY_VALUE':
|
|
60
|
+
return { conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION };
|
|
61
|
+
default: {
|
|
62
|
+
const _exhaustive = aggFunc;
|
|
63
|
+
return _exhaustive;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
exports.LookerStudioAggregationMapperService = LookerStudioAggregationMapperService;
|
|
69
|
+
exports.LookerStudioAggregationMapperService = LookerStudioAggregationMapperService = __decorate([
|
|
70
|
+
(0, common_1.Injectable)()
|
|
71
|
+
], LookerStudioAggregationMapperService);
|
|
72
|
+
//# sourceMappingURL=looker-studio-aggregation-mapper.service.js.map
|
|
@@ -93,10 +93,10 @@ let LookerStudioConnectorApiDataService = LookerStudioConnectorApiDataService_1
|
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
95
|
buildResponseSchema(filteredHeaders, storageType) {
|
|
96
|
-
return filteredHeaders.map(header =>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
})
|
|
96
|
+
return filteredHeaders.map(header => {
|
|
97
|
+
const field = this.typeMapperService.buildSchemaField(header, storageType);
|
|
98
|
+
return { name: field.name, dataType: field.dataType };
|
|
99
|
+
});
|
|
100
100
|
}
|
|
101
101
|
async readAndProcessData(reportReader, fieldIndexMap, rowLimit) {
|
|
102
102
|
const allRows = [];
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { DataStorageType } from '../../../data-storage-types/enums/data-storage-type.enum';
|
|
1
2
|
import { CachedReaderData } from '../../../dto/domain/cached-reader-data.dto';
|
|
3
|
+
import { ReportDataHeader } from '../../../dto/domain/report-data-header.dto';
|
|
2
4
|
import { Report } from '../../../entities/report.entity';
|
|
3
5
|
import { DataMartService } from '../../../services/data-mart.service';
|
|
4
|
-
import { GetSchemaRequest, GetSchemaResponse } from '../schemas/get-schema.schema';
|
|
6
|
+
import { GetSchemaRequest, GetSchemaResponse, SchemaField } from '../schemas/get-schema.schema';
|
|
5
7
|
import { LookerStudioTypeMapperService } from './looker-studio-type-mapper.service';
|
|
6
8
|
export declare class LookerStudioConnectorApiSchemaService {
|
|
7
9
|
private readonly dataMartService;
|
|
@@ -9,5 +11,5 @@ export declare class LookerStudioConnectorApiSchemaService {
|
|
|
9
11
|
private readonly logger;
|
|
10
12
|
constructor(dataMartService: DataMartService, typeMapperService: LookerStudioTypeMapperService);
|
|
11
13
|
getSchema(request: GetSchemaRequest, report: Report, cachedReader: CachedReaderData): Promise<GetSchemaResponse>;
|
|
12
|
-
|
|
14
|
+
getSchemaFields(reportDataHeaders: ReportDataHeader[], storageType: DataStorageType): SchemaField[];
|
|
13
15
|
}
|
|
@@ -13,9 +13,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
13
13
|
exports.LookerStudioConnectorApiSchemaService = void 0;
|
|
14
14
|
const common_1 = require("@nestjs/common");
|
|
15
15
|
const data_mart_service_1 = require("../../../services/data-mart.service");
|
|
16
|
-
const aggregation_type_enum_1 = require("../enums/aggregation-type.enum");
|
|
17
|
-
const field_concept_type_enum_1 = require("../enums/field-concept-type.enum");
|
|
18
|
-
const field_data_type_enum_1 = require("../enums/field-data-type.enum");
|
|
19
16
|
const looker_studio_type_mapper_service_1 = require("./looker-studio-type-mapper.service");
|
|
20
17
|
let LookerStudioConnectorApiSchemaService = LookerStudioConnectorApiSchemaService_1 = class LookerStudioConnectorApiSchemaService {
|
|
21
18
|
dataMartService;
|
|
@@ -37,27 +34,7 @@ let LookerStudioConnectorApiSchemaService = LookerStudioConnectorApiSchemaServic
|
|
|
37
34
|
};
|
|
38
35
|
}
|
|
39
36
|
getSchemaFields(reportDataHeaders, storageType) {
|
|
40
|
-
return reportDataHeaders.map(header =>
|
|
41
|
-
const schemaField = {
|
|
42
|
-
name: header.name,
|
|
43
|
-
label: header.alias || header.name,
|
|
44
|
-
description: header.description,
|
|
45
|
-
dataType: this.typeMapperService.mapToLookerStudioDataType(header.storageFieldType, storageType),
|
|
46
|
-
};
|
|
47
|
-
if (schemaField.dataType === field_data_type_enum_1.FieldDataType.NUMBER) {
|
|
48
|
-
schemaField.semantics = {
|
|
49
|
-
conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
|
|
50
|
-
isReaggregatable: true,
|
|
51
|
-
};
|
|
52
|
-
schemaField.defaultAggregationType = aggregation_type_enum_1.AggregationType.SUM;
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
schemaField.semantics = {
|
|
56
|
-
conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
return schemaField;
|
|
60
|
-
});
|
|
37
|
+
return reportDataHeaders.map(header => this.typeMapperService.buildSchemaField(header, storageType));
|
|
61
38
|
}
|
|
62
39
|
};
|
|
63
40
|
exports.LookerStudioConnectorApiSchemaService = LookerStudioConnectorApiSchemaService;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { AthenaFieldType } from '../../../data-storage-types/athena/enums/athena-field-type.enum';
|
|
2
|
-
import { BigQueryFieldType } from '../../../data-storage-types/bigquery/enums/bigquery-field-type.enum';
|
|
3
|
-
import { DatabricksFieldType } from '../../../data-storage-types/databricks/enums/databricks-field-type.enum';
|
|
4
1
|
import { DataStorageType } from '../../../data-storage-types/enums/data-storage-type.enum';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { ReportDataHeader } from '../../../dto/domain/report-data-header.dto';
|
|
3
|
+
import { StorageFieldType } from '../../../dto/domain/storage-field-type';
|
|
7
4
|
import { FieldDataType } from '../enums/field-data-type.enum';
|
|
5
|
+
import { SchemaField } from '../schemas/get-schema.schema';
|
|
6
|
+
import { LookerStudioAggregationMapperService } from './looker-studio-aggregation-mapper.service';
|
|
8
7
|
export declare class LookerStudioTypeMapperService {
|
|
9
|
-
|
|
8
|
+
private readonly aggregationMapper;
|
|
9
|
+
constructor(aggregationMapper: LookerStudioAggregationMapperService);
|
|
10
|
+
mapToLookerStudioDataType(fieldType: StorageFieldType, storageType: DataStorageType): FieldDataType;
|
|
11
|
+
buildSchemaField(header: ReportDataHeader, storageType: DataStorageType): SchemaField;
|
|
10
12
|
private mapBigQueryTypeToLookerStudio;
|
|
11
13
|
private mapAthenaTypeToLookerStudio;
|
|
12
14
|
private mapSnowflakeTypeToLookerStudio;
|
|
@@ -5,6 +5,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
7
|
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
8
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
12
|
exports.LookerStudioTypeMapperService = void 0;
|
|
10
13
|
const common_1 = require("@nestjs/common");
|
|
@@ -15,7 +18,12 @@ const data_storage_type_enum_1 = require("../../../data-storage-types/enums/data
|
|
|
15
18
|
const redshift_field_type_enum_1 = require("../../../data-storage-types/redshift/enums/redshift-field-type.enum");
|
|
16
19
|
const snowflake_field_type_enum_1 = require("../../../data-storage-types/snowflake/enums/snowflake-field-type.enum");
|
|
17
20
|
const field_data_type_enum_1 = require("../enums/field-data-type.enum");
|
|
21
|
+
const looker_studio_aggregation_mapper_service_1 = require("./looker-studio-aggregation-mapper.service");
|
|
18
22
|
let LookerStudioTypeMapperService = class LookerStudioTypeMapperService {
|
|
23
|
+
aggregationMapper;
|
|
24
|
+
constructor(aggregationMapper) {
|
|
25
|
+
this.aggregationMapper = aggregationMapper;
|
|
26
|
+
}
|
|
19
27
|
mapToLookerStudioDataType(fieldType, storageType) {
|
|
20
28
|
if (storageType === data_storage_type_enum_1.DataStorageType.GOOGLE_BIGQUERY ||
|
|
21
29
|
storageType === data_storage_type_enum_1.DataStorageType.LEGACY_GOOGLE_BIGQUERY) {
|
|
@@ -35,6 +43,26 @@ let LookerStudioTypeMapperService = class LookerStudioTypeMapperService {
|
|
|
35
43
|
}
|
|
36
44
|
return field_data_type_enum_1.FieldDataType.STRING;
|
|
37
45
|
}
|
|
46
|
+
buildSchemaField(header, storageType) {
|
|
47
|
+
const dataType = header.storageFieldType
|
|
48
|
+
? this.mapToLookerStudioDataType(header.storageFieldType, storageType)
|
|
49
|
+
: field_data_type_enum_1.FieldDataType.STRING;
|
|
50
|
+
const { conceptType, defaultAggregationType, isReaggregatable } = this.aggregationMapper.mapAggregateFunctionToLookerType(header.aggregateFunction, dataType);
|
|
51
|
+
const field = {
|
|
52
|
+
name: header.name,
|
|
53
|
+
label: header.alias || header.name,
|
|
54
|
+
description: header.description,
|
|
55
|
+
dataType,
|
|
56
|
+
semantics: {
|
|
57
|
+
conceptType,
|
|
58
|
+
...(isReaggregatable !== undefined && { isReaggregatable }),
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
if (defaultAggregationType !== undefined) {
|
|
62
|
+
field.defaultAggregationType = defaultAggregationType;
|
|
63
|
+
}
|
|
64
|
+
return field;
|
|
65
|
+
}
|
|
38
66
|
mapBigQueryTypeToLookerStudio(type) {
|
|
39
67
|
switch (type) {
|
|
40
68
|
case bigquery_field_type_enum_1.BigQueryFieldType.INTEGER:
|
|
@@ -172,6 +200,7 @@ let LookerStudioTypeMapperService = class LookerStudioTypeMapperService {
|
|
|
172
200
|
};
|
|
173
201
|
exports.LookerStudioTypeMapperService = LookerStudioTypeMapperService;
|
|
174
202
|
exports.LookerStudioTypeMapperService = LookerStudioTypeMapperService = __decorate([
|
|
175
|
-
(0, common_1.Injectable)()
|
|
203
|
+
(0, common_1.Injectable)(),
|
|
204
|
+
__metadata("design:paramtypes", [looker_studio_aggregation_mapper_service_1.LookerStudioAggregationMapperService])
|
|
176
205
|
], LookerStudioTypeMapperService);
|
|
177
206
|
//# sourceMappingURL=looker-studio-type-mapper.service.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { DataStorageType } from './enums/data-storage-type.enum';
|
|
2
|
+
import { AggregateFunction } from '../dto/schemas/aggregate-function.schema';
|
|
3
|
+
import { StorageFieldType } from '../dto/domain/storage-field-type';
|
|
4
|
+
export declare function computeEffectiveType(rawType: StorageFieldType, aggFunc: AggregateFunction | undefined, storageType: DataStorageType): StorageFieldType;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeEffectiveType = computeEffectiveType;
|
|
4
|
+
const athena_field_type_enum_1 = require("./athena/enums/athena-field-type.enum");
|
|
5
|
+
const bigquery_field_type_enum_1 = require("./bigquery/enums/bigquery-field-type.enum");
|
|
6
|
+
const databricks_field_type_enum_1 = require("./databricks/enums/databricks-field-type.enum");
|
|
7
|
+
const data_storage_type_enum_1 = require("./enums/data-storage-type.enum");
|
|
8
|
+
const redshift_field_type_enum_1 = require("./redshift/enums/redshift-field-type.enum");
|
|
9
|
+
const snowflake_field_type_enum_1 = require("./snowflake/enums/snowflake-field-type.enum");
|
|
10
|
+
function computeEffectiveType(rawType, aggFunc, storageType) {
|
|
11
|
+
if (!aggFunc)
|
|
12
|
+
return rawType;
|
|
13
|
+
switch (aggFunc) {
|
|
14
|
+
case 'COUNT':
|
|
15
|
+
case 'COUNT_DISTINCT':
|
|
16
|
+
return getIntegerType(storageType);
|
|
17
|
+
case 'STRING_AGG':
|
|
18
|
+
return getStringType(storageType);
|
|
19
|
+
case 'SUM':
|
|
20
|
+
case 'MIN':
|
|
21
|
+
case 'MAX':
|
|
22
|
+
case 'ANY_VALUE':
|
|
23
|
+
return rawType;
|
|
24
|
+
default: {
|
|
25
|
+
const _exhaustive = aggFunc;
|
|
26
|
+
return _exhaustive;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function getIntegerType(storageType) {
|
|
31
|
+
switch (storageType) {
|
|
32
|
+
case data_storage_type_enum_1.DataStorageType.GOOGLE_BIGQUERY:
|
|
33
|
+
case data_storage_type_enum_1.DataStorageType.LEGACY_GOOGLE_BIGQUERY:
|
|
34
|
+
return bigquery_field_type_enum_1.BigQueryFieldType.INTEGER;
|
|
35
|
+
case data_storage_type_enum_1.DataStorageType.AWS_ATHENA:
|
|
36
|
+
return athena_field_type_enum_1.AthenaFieldType.INTEGER;
|
|
37
|
+
case data_storage_type_enum_1.DataStorageType.SNOWFLAKE:
|
|
38
|
+
return snowflake_field_type_enum_1.SnowflakeFieldType.INTEGER;
|
|
39
|
+
case data_storage_type_enum_1.DataStorageType.AWS_REDSHIFT:
|
|
40
|
+
return redshift_field_type_enum_1.RedshiftFieldType.INTEGER;
|
|
41
|
+
case data_storage_type_enum_1.DataStorageType.DATABRICKS:
|
|
42
|
+
return databricks_field_type_enum_1.DatabricksFieldType.INT;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function getStringType(storageType) {
|
|
46
|
+
switch (storageType) {
|
|
47
|
+
case data_storage_type_enum_1.DataStorageType.GOOGLE_BIGQUERY:
|
|
48
|
+
case data_storage_type_enum_1.DataStorageType.LEGACY_GOOGLE_BIGQUERY:
|
|
49
|
+
return bigquery_field_type_enum_1.BigQueryFieldType.STRING;
|
|
50
|
+
case data_storage_type_enum_1.DataStorageType.AWS_ATHENA:
|
|
51
|
+
return athena_field_type_enum_1.AthenaFieldType.STRING;
|
|
52
|
+
case data_storage_type_enum_1.DataStorageType.SNOWFLAKE:
|
|
53
|
+
return snowflake_field_type_enum_1.SnowflakeFieldType.STRING;
|
|
54
|
+
case data_storage_type_enum_1.DataStorageType.AWS_REDSHIFT:
|
|
55
|
+
return redshift_field_type_enum_1.RedshiftFieldType.VARCHAR;
|
|
56
|
+
case data_storage_type_enum_1.DataStorageType.DATABRICKS:
|
|
57
|
+
return databricks_field_type_enum_1.DatabricksFieldType.STRING;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=field-aggregation.js.map
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { SnowflakeFieldType } from '../../data-storage-types/snowflake/enums/snowflake-field-type.enum';
|
|
4
|
-
import { RedshiftFieldType } from '../../data-storage-types/redshift/enums/redshift-field-type.enum';
|
|
5
|
-
import { DatabricksFieldType } from '../../data-storage-types/databricks/enums/databricks-field-type.enum';
|
|
1
|
+
import { AggregateFunction } from '../schemas/aggregate-function.schema';
|
|
2
|
+
import { StorageFieldType } from './storage-field-type';
|
|
6
3
|
export declare class ReportDataHeader {
|
|
7
4
|
readonly name: string;
|
|
8
5
|
readonly alias?: string | undefined;
|
|
9
6
|
readonly description?: string | undefined;
|
|
10
|
-
readonly storageFieldType?:
|
|
11
|
-
|
|
7
|
+
readonly storageFieldType?: StorageFieldType | undefined;
|
|
8
|
+
readonly aggregateFunction?: AggregateFunction | undefined;
|
|
9
|
+
constructor(name: string, alias?: string | undefined, description?: string | undefined, storageFieldType?: StorageFieldType | undefined, aggregateFunction?: AggregateFunction | undefined);
|
|
12
10
|
}
|
|
@@ -6,11 +6,13 @@ class ReportDataHeader {
|
|
|
6
6
|
alias;
|
|
7
7
|
description;
|
|
8
8
|
storageFieldType;
|
|
9
|
-
|
|
9
|
+
aggregateFunction;
|
|
10
|
+
constructor(name, alias, description, storageFieldType, aggregateFunction) {
|
|
10
11
|
this.name = name;
|
|
11
12
|
this.alias = alias;
|
|
12
13
|
this.description = description;
|
|
13
14
|
this.storageFieldType = storageFieldType;
|
|
15
|
+
this.aggregateFunction = aggregateFunction;
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
18
|
exports.ReportDataHeader = ReportDataHeader;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AthenaFieldType } from '../../data-storage-types/athena/enums/athena-field-type.enum';
|
|
2
|
+
import { BigQueryFieldType } from '../../data-storage-types/bigquery/enums/bigquery-field-type.enum';
|
|
3
|
+
import { DatabricksFieldType } from '../../data-storage-types/databricks/enums/databricks-field-type.enum';
|
|
4
|
+
import { RedshiftFieldType } from '../../data-storage-types/redshift/enums/redshift-field-type.enum';
|
|
5
|
+
import { SnowflakeFieldType } from '../../data-storage-types/snowflake/enums/snowflake-field-type.enum';
|
|
6
|
+
export type StorageFieldType = BigQueryFieldType | AthenaFieldType | SnowflakeFieldType | RedshiftFieldType | DatabricksFieldType;
|
|
@@ -16,6 +16,7 @@ const data_mart_relationship_service_1 = require("./data-mart-relationship.servi
|
|
|
16
16
|
const data_mart_table_reference_service_1 = require("./data-mart-table-reference.service");
|
|
17
17
|
const blended_query_builder_facade_1 = require("../data-storage-types/facades/blended-query-builder.facade");
|
|
18
18
|
const report_data_header_dto_1 = require("../dto/domain/report-data-header.dto");
|
|
19
|
+
const field_aggregation_1 = require("../data-storage-types/field-aggregation");
|
|
19
20
|
const public_origin_service_1 = require("../../common/config/public-origin.service");
|
|
20
21
|
const business_violation_exception_1 = require("../../common/exceptions/business-violation.exception");
|
|
21
22
|
const data_mart_url_helper_1 = require("../../common/helpers/data-mart-url.helper");
|
|
@@ -40,7 +41,7 @@ let BlendedReportDataService = class BlendedReportDataService {
|
|
|
40
41
|
const blendableSchema = await this.blendableSchemaService.computeBlendableSchema(dataMart.id, dataMart.projectId);
|
|
41
42
|
const blendedFieldsByName = new Map(blendableSchema.blendedFields.map(f => [f.name, f]));
|
|
42
43
|
const hasBlendedColumns = columnConfig.some(col => blendedFieldsByName.has(col));
|
|
43
|
-
const blendedDataHeaders = this.buildBlendedDataHeaders(columnConfig, blendedFieldsByName);
|
|
44
|
+
const blendedDataHeaders = this.buildBlendedDataHeaders(columnConfig, blendedFieldsByName, dataMart.storage.type);
|
|
44
45
|
if (!hasBlendedColumns) {
|
|
45
46
|
return {
|
|
46
47
|
needsBlending: false,
|
|
@@ -67,12 +68,13 @@ let BlendedReportDataService = class BlendedReportDataService {
|
|
|
67
68
|
blendedDataHeaders,
|
|
68
69
|
};
|
|
69
70
|
}
|
|
70
|
-
buildBlendedDataHeaders(columnConfig, blendedFieldsByName) {
|
|
71
|
+
buildBlendedDataHeaders(columnConfig, blendedFieldsByName, storageType) {
|
|
71
72
|
const headers = [];
|
|
72
73
|
for (const col of columnConfig) {
|
|
73
74
|
const blendedField = blendedFieldsByName.get(col);
|
|
74
75
|
if (blendedField) {
|
|
75
|
-
|
|
76
|
+
const effectiveType = (0, field_aggregation_1.computeEffectiveType)(blendedField.type, blendedField.aggregateFunction, storageType);
|
|
77
|
+
headers.push(new report_data_header_dto_1.ReportDataHeader(blendedField.name, `${blendedField.outputPrefix} ${blendedField.alias || blendedField.originalFieldName}`, blendedField.description || undefined, effectiveType, blendedField.aggregateFunction));
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
return headers;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owox/backend",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0-next-20260430151351",
|
|
4
4
|
"description": "OWOX Data Marts Backend - Full-stack data orchestration platform",
|
|
5
5
|
"author": "OWOX",
|
|
6
6
|
"license": "ELv2",
|
|
@@ -78,9 +78,9 @@
|
|
|
78
78
|
"@nestjs/schedule": "^6.0.0",
|
|
79
79
|
"@nestjs/swagger": "^11.2.0",
|
|
80
80
|
"@nestjs/typeorm": "^11.0.0",
|
|
81
|
-
"@owox/connectors": "0.
|
|
82
|
-
"@owox/idp-protocol": "0.
|
|
83
|
-
"@owox/internal-helpers": "0.
|
|
81
|
+
"@owox/connectors": "0.25.0-next-20260430151351",
|
|
82
|
+
"@owox/idp-protocol": "0.25.0-next-20260430151351",
|
|
83
|
+
"@owox/internal-helpers": "0.25.0-next-20260430151351",
|
|
84
84
|
"better-sqlite3": "^12.2.0",
|
|
85
85
|
"class-transformer": "^0.5.1",
|
|
86
86
|
"class-validator": "^0.14.2",
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
"ts-node": "^10.9.2",
|
|
140
140
|
"tsconfig-paths": "^4.2.0",
|
|
141
141
|
"typeorm-ts-node-commonjs": "^0.3.20",
|
|
142
|
-
"@owox/test-utils": "
|
|
142
|
+
"@owox/test-utils": "4.0.0-next-20260430151351"
|
|
143
143
|
},
|
|
144
144
|
"jest": {
|
|
145
145
|
"moduleFileExtensions": [
|