@owox/backend 0.37.0 → 0.38.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/src/common/search/search.facade.d.ts +1 -0
- package/dist/src/data-marts/data-destination-types/ee/email/services/email-credentials-validator.js +1 -3
- package/dist/src/data-marts/data-destination-types/ee/google-chat/services/google-chat-credentials-validator.js +1 -3
- package/dist/src/data-marts/data-destination-types/google-sheets/services/google-sheets-credentials-validator.js +1 -3
- package/dist/src/data-marts/data-destination-types/google-sheets/services/google-sheets-report-writer.d.ts +1 -0
- package/dist/src/data-marts/data-destination-types/google-sheets/services/google-sheets-report-writer.js +13 -1
- package/dist/src/data-marts/data-destination-types/interfaces/data-destination-credentials-validator.interface.d.ts +2 -0
- package/dist/src/data-marts/data-destination-types/interfaces/data-destination-credentials-validator.interface.js +7 -0
- package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-connector-credentials-validator.js +1 -3
- package/dist/src/data-marts/data-marts.module.js +4 -0
- package/dist/src/data-marts/data-storage-types/athena/adapters/athena-api.adapter.js +2 -1
- package/dist/src/data-marts/data-storage-types/athena/adapters/s3-api.adapter.js +5 -3
- package/dist/src/data-marts/data-storage-types/athena/services/athena-access.validator.js +2 -4
- package/dist/src/data-marts/data-storage-types/athena/utils/athena-output-location.util.d.ts +5 -0
- package/dist/src/data-marts/data-storage-types/athena/utils/athena-output-location.util.js +13 -0
- package/dist/src/data-marts/data-storage-types/bigquery/services/bigquery-access.validator.js +2 -4
- package/dist/src/data-marts/data-storage-types/bigquery/services/bigquery-resource-location.util.d.ts +3 -0
- package/dist/src/data-marts/data-storage-types/bigquery/services/bigquery-resource-location.util.js +18 -0
- package/dist/src/data-marts/data-storage-types/bigquery/services/bigquery-sharded-tables.util.d.ts +1 -0
- package/dist/src/data-marts/data-storage-types/bigquery/services/bigquery-sharded-tables.util.js +4 -1
- package/dist/src/data-marts/data-storage-types/bigquery/services/bigquery-storage-resource-browser.service.js +12 -5
- package/dist/src/data-marts/data-storage-types/databricks/services/databricks-access.validator.js +2 -4
- package/dist/src/data-marts/data-storage-types/interfaces/data-storage-access-validator.interface.d.ts +3 -0
- package/dist/src/data-marts/data-storage-types/interfaces/data-storage-access-validator.interface.js +7 -0
- package/dist/src/data-marts/data-storage-types/interfaces/storage-resource-browser.interface.d.ts +2 -0
- package/dist/src/data-marts/data-storage-types/redshift/services/redshift-access.validator.js +2 -6
- package/dist/src/data-marts/data-storage-types/snowflake/services/snowflake-access.validator.js +2 -4
- package/dist/src/data-marts/dto/domain/list-data-marts.command.d.ts +2 -1
- package/dist/src/data-marts/dto/domain/list-data-marts.command.js +3 -1
- package/dist/src/data-marts/dto/presentation/sql-dry-run-request-api.dto.js +3 -0
- package/dist/src/data-marts/dto/presentation/storage-resources/list-storage-resources-response.dto.d.ts +2 -0
- package/dist/src/data-marts/dto/presentation/storage-resources/list-storage-resources-response.dto.js +17 -0
- package/dist/src/data-marts/errors/google-sheets-api-call.error.d.ts +6 -0
- package/dist/src/data-marts/errors/google-sheets-api-call.error.js +34 -0
- package/dist/src/data-marts/facades/mcp-contexts.facade.d.ts +13 -0
- package/dist/src/data-marts/facades/mcp-contexts.facade.impl.d.ts +9 -0
- package/dist/src/data-marts/facades/mcp-contexts.facade.impl.js +35 -0
- package/dist/src/data-marts/facades/mcp-contexts.facade.js +5 -0
- package/dist/src/data-marts/facades/mcp-data-marts.facade.d.ts +9 -0
- package/dist/src/data-marts/facades/mcp-data-marts.facade.impl.js +4 -1
- package/dist/src/data-marts/mappers/context.mapper.d.ts +4 -0
- package/dist/src/data-marts/mappers/context.mapper.js +12 -0
- package/dist/src/data-marts/search/engine/advanced-search.service.js +1 -0
- package/dist/src/data-marts/search/engine/in-memory-paginated.search.js +17 -1
- package/dist/src/data-marts/search/engine/vector-search.port.d.ts +1 -0
- package/dist/src/data-marts/services/context/context.service.d.ts +2 -0
- package/dist/src/data-marts/services/context/context.service.js +21 -0
- package/dist/src/data-marts/services/data-mart.service.d.ts +1 -0
- package/dist/src/data-marts/services/data-mart.service.js +3 -0
- package/dist/src/data-marts/use-cases/list-data-marts.service.js +1 -0
- package/dist/src/data-marts/use-cases/stream-http-data.service.d.ts +0 -1
- package/dist/src/data-marts/use-cases/stream-http-data.service.js +2 -6
- package/dist/src/data-marts/use-cases/update-data-storage.service.js +7 -7
- package/dist/src/data-marts/utils/field-errors.utils.d.ts +9 -0
- package/dist/src/data-marts/utils/field-errors.utils.js +51 -0
- package/dist/src/ee/mcp/instructions/mcp-system-instructions.d.ts +1 -1
- package/dist/src/ee/mcp/instructions/mcp-system-instructions.js +3 -0
- package/dist/src/ee/mcp/sdk/mcp-output-schema.d.ts +3 -0
- package/dist/src/ee/mcp/sdk/mcp-output-schema.js +53 -0
- package/dist/src/ee/mcp/sdk/mcp-schema-refresh.d.ts +8 -0
- package/dist/src/ee/mcp/sdk/mcp-schema-refresh.js +44 -0
- package/dist/src/ee/mcp/sdk/mcp-sdk-server.factory.d.ts +8 -1
- package/dist/src/ee/mcp/sdk/mcp-sdk-server.factory.js +35 -4
- package/dist/src/ee/mcp/tools/context-input.d.ts +6 -0
- package/dist/src/ee/mcp/tools/context-input.js +13 -0
- package/dist/src/ee/mcp/tools/data-mart-catalog.tool.d.ts +10 -2
- package/dist/src/ee/mcp/tools/data-mart-catalog.tool.js +17 -5
- package/dist/src/ee/mcp/tools/data-mart-details.tool.d.ts +5 -1
- package/dist/src/ee/mcp/tools/data-mart-details.tool.js +4 -1
- package/dist/src/ee/mcp/tools/list-contexts.tool.d.ts +131 -0
- package/dist/src/ee/mcp/tools/list-contexts.tool.js +50 -0
- package/dist/src/ee/mcp/tools/mcp-tool.providers.js +2 -0
- package/dist/src/ee/mcp/tools/search-data-marts.tool.d.ts +10 -2
- package/dist/src/ee/mcp/tools/search-data-marts.tool.js +17 -3
- package/dist/src/ee/mcp/transport/mcp-http-entry.service.js +1 -1
- package/dist/src/migrations/1790830000000-widen-sql-dry-run-trigger-sql-column.d.ts +6 -0
- package/dist/src/migrations/1790830000000-widen-sql-dry-run-trigger-sql-column.js +21 -0
- package/dist/src/plugin-host/controllers/plugin-gallery.controller.d.ts +5 -1
- package/dist/src/plugin-host/controllers/plugin-gallery.controller.js +25 -1
- package/dist/src/plugin-host/dto/domain/find-plugin-by-repository.command.d.ts +6 -0
- package/dist/src/plugin-host/dto/domain/find-plugin-by-repository.command.js +13 -0
- package/dist/src/plugin-host/dto/presentation/plugin-lookup-api.dto.d.ts +3 -0
- package/dist/src/plugin-host/dto/presentation/plugin-lookup-api.dto.js +22 -0
- package/dist/src/plugin-host/mappers/plugin-presentation.mapper.d.ts +6 -0
- package/dist/src/plugin-host/mappers/plugin-presentation.mapper.js +7 -0
- package/dist/src/plugin-host/plugin-host.module.js +2 -0
- package/dist/src/plugin-host/services/plugin-publication.service.d.ts +2 -0
- package/dist/src/plugin-host/services/plugin-publication.service.js +36 -16
- package/dist/src/plugin-host/use-cases/find-plugin-by-repository.service.d.ts +9 -0
- package/dist/src/plugin-host/use-cases/find-plugin-by-repository.service.js +35 -0
- package/dist/src/plugin-host/use-cases/list-installations.service.d.ts +3 -1
- package/dist/src/plugin-host/use-cases/list-installations.service.js +14 -3
- package/dist/src/plugin-host/utils/github-repo-locator.util.js +1 -1
- package/package.json +4 -4
|
@@ -37,6 +37,7 @@ export interface SearchOptions {
|
|
|
37
37
|
topK?: number;
|
|
38
38
|
entityTypes?: SearchableEntityType[];
|
|
39
39
|
excludeDrafts?: boolean;
|
|
40
|
+
contextIds?: string[];
|
|
40
41
|
}
|
|
41
42
|
export interface SearchEngine {
|
|
42
43
|
search(projectId: string, prompt: string, options: SearchOptions): Promise<SearchResult[]>;
|
package/dist/src/data-marts/data-destination-types/ee/email/services/email-credentials-validator.js
CHANGED
|
@@ -17,9 +17,7 @@ class BaseEmailCredentialsValidator {
|
|
|
17
17
|
const credentialsOpt = email_credentials_schema_1.EmailCredentialsSchema.safeParse(credentials);
|
|
18
18
|
if (!credentialsOpt.success) {
|
|
19
19
|
this.logger.warn('Invalid credentials format', credentialsOpt.error);
|
|
20
|
-
return
|
|
21
|
-
errors: credentialsOpt.error.errors,
|
|
22
|
-
});
|
|
20
|
+
return data_destination_credentials_validator_interface_1.ValidationResult.invalidCredentials(credentialsOpt.error);
|
|
23
21
|
}
|
|
24
22
|
return new data_destination_credentials_validator_interface_1.ValidationResult(true);
|
|
25
23
|
}
|
|
@@ -22,9 +22,7 @@ let GoogleChatCredentialsValidator = GoogleChatCredentialsValidator_1 = class Go
|
|
|
22
22
|
: google_chat_credentials_schema_1.GoogleChatCredentialsSchema.safeParse(credentials);
|
|
23
23
|
if (!credentialsValidation.success) {
|
|
24
24
|
this.logger.warn('Invalid Google Chat credentials format', credentialsValidation.error);
|
|
25
|
-
return
|
|
26
|
-
errors: credentialsValidation.error.errors,
|
|
27
|
-
});
|
|
25
|
+
return data_destination_credentials_validator_interface_1.ValidationResult.invalidCredentials(credentialsValidation.error);
|
|
28
26
|
}
|
|
29
27
|
return new data_destination_credentials_validator_interface_1.ValidationResult(true);
|
|
30
28
|
}
|
|
@@ -20,9 +20,7 @@ let GoogleSheetsCredentialsValidator = GoogleSheetsCredentialsValidator_1 = clas
|
|
|
20
20
|
const credentialsOpt = google_sheets_credentials_schema_1.GoogleSheetsCredentialsSchema.safeParse(credentials);
|
|
21
21
|
if (!credentialsOpt.success) {
|
|
22
22
|
this.logger.warn('Invalid credentials format', credentialsOpt.error);
|
|
23
|
-
return
|
|
24
|
-
errors: credentialsOpt.error.errors,
|
|
25
|
-
});
|
|
23
|
+
return data_destination_credentials_validator_interface_1.ValidationResult.invalidCredentials(credentialsOpt.error);
|
|
26
24
|
}
|
|
27
25
|
try {
|
|
28
26
|
const isValid = await google_sheets_api_adapter_1.GoogleSheetsApiAdapter.validateCredentials(credentialsOpt.data);
|
|
@@ -26,6 +26,7 @@ const sheets_report_run_event_1 = require("../../../events/sheets-report-run.eve
|
|
|
26
26
|
const owox_event_dispatcher_1 = require("../../../../common/event-dispatcher/owox-event-dispatcher");
|
|
27
27
|
const google_sheet_not_found_error_1 = require("../../../errors/google-sheet-not-found.error");
|
|
28
28
|
const business_violation_exception_1 = require("../../../../common/exceptions/business-violation.exception");
|
|
29
|
+
const google_sheets_api_call_error_1 = require("../../../errors/google-sheets-api-call.error");
|
|
29
30
|
const app_edition_config_service_1 = require("../../../../common/config/app-edition-config.service");
|
|
30
31
|
const public_origin_service_1 = require("../../../../common/config/public-origin.service");
|
|
31
32
|
const data_mart_url_helper_1 = require("../../../../common/helpers/data-mart-url.helper");
|
|
@@ -538,9 +539,20 @@ let GoogleSheetsReportWriter = GoogleSheetsReportWriter_1 = class GoogleSheetsRe
|
|
|
538
539
|
else {
|
|
539
540
|
this.logger.error(`${operationName} failed: ${error.message}`, error.stack);
|
|
540
541
|
}
|
|
541
|
-
throw error;
|
|
542
|
+
throw this.describeGoogleApiError(error, operationName) ?? error;
|
|
542
543
|
}
|
|
543
544
|
}
|
|
545
|
+
describeGoogleApiError(error, operationName) {
|
|
546
|
+
if (error instanceof google_sheets_api_call_error_1.GoogleSheetsApiCallError || error instanceof business_violation_exception_1.BusinessViolationException) {
|
|
547
|
+
return undefined;
|
|
548
|
+
}
|
|
549
|
+
const status = google_sheets_api_adapter_1.GoogleSheetsApiAdapter.httpStatusOf(error);
|
|
550
|
+
if (status === undefined || status < 400) {
|
|
551
|
+
return undefined;
|
|
552
|
+
}
|
|
553
|
+
const googleMessage = error instanceof Error ? error.message : String(error);
|
|
554
|
+
return new google_sheets_api_call_error_1.GoogleSheetsApiCallError((0, google_sheets_api_call_error_1.googleSheetsApiCallMessage)(operationName, status, googleMessage), status, error);
|
|
555
|
+
}
|
|
544
556
|
};
|
|
545
557
|
exports.GoogleSheetsReportWriter = GoogleSheetsReportWriter;
|
|
546
558
|
exports.GoogleSheetsReportWriter = GoogleSheetsReportWriter = GoogleSheetsReportWriter_1 = __decorate([
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ZodError } from 'zod';
|
|
1
2
|
import { TypedComponent } from '../../../common/resolver/typed-component.resolver';
|
|
2
3
|
import { DataDestinationType } from '../enums/data-destination-type.enum';
|
|
3
4
|
import { DataDestinationCredentials } from '../data-destination-credentials.type';
|
|
@@ -9,4 +10,5 @@ export declare class ValidationResult {
|
|
|
9
10
|
readonly errorMessage?: string | undefined;
|
|
10
11
|
readonly reason?: Record<string, unknown> | undefined;
|
|
11
12
|
constructor(valid: boolean, errorMessage?: string | undefined, reason?: Record<string, unknown> | undefined);
|
|
13
|
+
static invalidCredentials(error: ZodError): ValidationResult;
|
|
12
14
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ValidationResult = void 0;
|
|
4
|
+
const field_errors_utils_1 = require("../../utils/field-errors.utils");
|
|
4
5
|
class ValidationResult {
|
|
5
6
|
valid;
|
|
6
7
|
errorMessage;
|
|
@@ -10,6 +11,12 @@ class ValidationResult {
|
|
|
10
11
|
this.errorMessage = errorMessage;
|
|
11
12
|
this.reason = reason;
|
|
12
13
|
}
|
|
14
|
+
static invalidCredentials(error) {
|
|
15
|
+
return new ValidationResult(false, (0, field_errors_utils_1.describeInvalidInput)('credentials', error), {
|
|
16
|
+
errors: (0, field_errors_utils_1.sanitizeIssues)(error.errors),
|
|
17
|
+
fieldErrors: (0, field_errors_utils_1.toFieldErrors)('credentials', error),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
13
20
|
}
|
|
14
21
|
exports.ValidationResult = ValidationResult;
|
|
15
22
|
//# sourceMappingURL=data-destination-credentials-validator.interface.js.map
|
|
@@ -19,9 +19,7 @@ let LookerStudioConnectorCredentialsValidator = LookerStudioConnectorCredentials
|
|
|
19
19
|
const credentialsOpt = looker_studio_connector_credentials_schema_1.LookerStudioConnectorCredentialsSchema.safeParse(credentials);
|
|
20
20
|
if (!credentialsOpt.success) {
|
|
21
21
|
this.logger.warn('Invalid credentials format', credentialsOpt.error);
|
|
22
|
-
return
|
|
23
|
-
errors: credentialsOpt.error.errors,
|
|
24
|
-
});
|
|
22
|
+
return data_destination_credentials_validator_interface_1.ValidationResult.invalidCredentials(credentialsOpt.error);
|
|
25
23
|
}
|
|
26
24
|
return new data_destination_credentials_validator_interface_1.ValidationResult(true);
|
|
27
25
|
}
|
|
@@ -63,6 +63,8 @@ const preview_data_mart_service_1 = require("./use-cases/preview-data-mart.servi
|
|
|
63
63
|
const data_mart_preview_controller_1 = require("./controllers/data-mart-preview.controller");
|
|
64
64
|
const summarize_mcp_data_catalog_service_1 = require("./use-cases/summarize-mcp-data-catalog.service");
|
|
65
65
|
const mcp_data_marts_facade_1 = require("./facades/mcp-data-marts.facade");
|
|
66
|
+
const mcp_contexts_facade_1 = require("./facades/mcp-contexts.facade");
|
|
67
|
+
const mcp_contexts_facade_impl_1 = require("./facades/mcp-contexts.facade.impl");
|
|
66
68
|
const mcp_data_marts_facade_impl_1 = require("./facades/mcp-data-marts.facade.impl");
|
|
67
69
|
const mcp_data_destinations_facade_1 = require("./facades/mcp-data-destinations.facade");
|
|
68
70
|
const mcp_data_destinations_facade_impl_1 = require("./facades/mcp-data-destinations.facade.impl");
|
|
@@ -642,6 +644,7 @@ exports.DataMartsModule = DataMartsModule = __decorate([
|
|
|
642
644
|
data_quality_api_service_1.DataQualityApiService,
|
|
643
645
|
data_quality_summary_service_1.DataQualitySummaryService,
|
|
644
646
|
mcp_data_catalog_summary_service_1.McpDataCatalogSummaryService,
|
|
647
|
+
{ provide: mcp_contexts_facade_1.MCP_CONTEXTS_FACADE, useClass: mcp_contexts_facade_impl_1.McpContextsFacadeImpl },
|
|
645
648
|
create_data_mart_service_1.CreateDataMartService,
|
|
646
649
|
list_data_marts_service_1.ListDataMartsService,
|
|
647
650
|
get_model_canvas_data_marts_service_1.GetModelCanvasDataMartsService,
|
|
@@ -997,6 +1000,7 @@ exports.DataMartsModule = DataMartsModule = __decorate([
|
|
|
997
1000
|
consent_credential_definition_service_1.ConsentCredentialDefinitionService,
|
|
998
1001
|
],
|
|
999
1002
|
exports: [
|
|
1003
|
+
mcp_contexts_facade_1.MCP_CONTEXTS_FACADE,
|
|
1000
1004
|
credential_consumer_binding_facade_1.CREDENTIAL_CONSUMER_BINDING_FACADE,
|
|
1001
1005
|
credential_fetch_service_1.CredentialFetchService,
|
|
1002
1006
|
credential_ai_service_1.CredentialAiService,
|
|
@@ -4,6 +4,7 @@ exports.AthenaApiAdapter = void 0;
|
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
5
|
const client_athena_1 = require("@aws-sdk/client-athena");
|
|
6
6
|
const athena_execution_parameters_utils_1 = require("./athena-execution-parameters.utils");
|
|
7
|
+
const athena_output_location_util_1 = require("../utils/athena-output-location.util");
|
|
7
8
|
class AthenaApiAdapter {
|
|
8
9
|
static ATHENA_QUERY_ERROR_PREFIX = 'Query execution failed:';
|
|
9
10
|
static DEFAULT_POLL_INTERVAL_MS = 1000;
|
|
@@ -23,7 +24,7 @@ class AthenaApiAdapter {
|
|
|
23
24
|
const startQueryCommand = new client_athena_1.StartQueryExecutionCommand({
|
|
24
25
|
QueryString: query,
|
|
25
26
|
ResultConfiguration: {
|
|
26
|
-
OutputLocation:
|
|
27
|
+
OutputLocation: (0, athena_output_location_util_1.athenaOutputLocation)(outputBucket, outputPrefix).uri,
|
|
27
28
|
},
|
|
28
29
|
ExecutionParameters: (0, athena_execution_parameters_utils_1.toAthenaExecutionParameters)(params),
|
|
29
30
|
});
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.S3ApiAdapter = void 0;
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
5
|
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
6
|
+
const athena_output_location_util_1 = require("../utils/athena-output-location.util");
|
|
6
7
|
class S3ApiAdapter {
|
|
7
8
|
logger = new common_1.Logger(S3ApiAdapter.name);
|
|
8
9
|
s3Client;
|
|
@@ -21,10 +22,11 @@ class S3ApiAdapter {
|
|
|
21
22
|
this.logger.debug('No output location to clean up');
|
|
22
23
|
return;
|
|
23
24
|
}
|
|
25
|
+
const { bucket, keyPrefix } = (0, athena_output_location_util_1.athenaOutputLocation)(outputBucket, outputPrefix);
|
|
24
26
|
try {
|
|
25
27
|
const listCommand = new client_s3_1.ListObjectsV2Command({
|
|
26
|
-
Bucket:
|
|
27
|
-
Prefix:
|
|
28
|
+
Bucket: bucket,
|
|
29
|
+
Prefix: keyPrefix,
|
|
28
30
|
});
|
|
29
31
|
const listedObjects = await this.s3Client.send(listCommand);
|
|
30
32
|
if (!listedObjects.Contents || listedObjects.Contents.length === 0) {
|
|
@@ -35,7 +37,7 @@ class S3ApiAdapter {
|
|
|
35
37
|
if (!object.Key)
|
|
36
38
|
continue;
|
|
37
39
|
const deleteCommand = new client_s3_1.DeleteObjectCommand({
|
|
38
|
-
Bucket:
|
|
40
|
+
Bucket: bucket,
|
|
39
41
|
Key: object.Key,
|
|
40
42
|
});
|
|
41
43
|
await this.s3Client.send(deleteCommand);
|
|
@@ -28,14 +28,12 @@ let AthenaAccessValidator = AthenaAccessValidator_1 = class AthenaAccessValidato
|
|
|
28
28
|
const configOpt = athena_config_schema_1.AthenaConfigSchema.safeParse(config);
|
|
29
29
|
if (!configOpt.success) {
|
|
30
30
|
this.logger.warn('Invalid config', configOpt.error);
|
|
31
|
-
return
|
|
31
|
+
return data_storage_access_validator_interface_1.ValidationResult.invalidInput('config', configOpt.error);
|
|
32
32
|
}
|
|
33
33
|
const credentialsOpt = athena_credentials_schema_1.AthenaCredentialsSchema.safeParse(credentials);
|
|
34
34
|
if (!credentialsOpt.success) {
|
|
35
35
|
this.logger.warn('Invalid credentials', credentialsOpt.error);
|
|
36
|
-
return
|
|
37
|
-
errors: credentialsOpt.error.errors,
|
|
38
|
-
});
|
|
36
|
+
return data_storage_access_validator_interface_1.ValidationResult.invalidInput('credentials', credentialsOpt.error);
|
|
39
37
|
}
|
|
40
38
|
const athenaConfig = configOpt.data;
|
|
41
39
|
const apiAdapter = this.adapterFactory.create(credentialsOpt.data, athenaConfig);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.athenaOutputLocation = athenaOutputLocation;
|
|
4
|
+
function athenaOutputLocation(outputBucket, outputPrefix) {
|
|
5
|
+
const location = `${outputBucket}/${outputPrefix}`;
|
|
6
|
+
const slash = location.indexOf('/');
|
|
7
|
+
return {
|
|
8
|
+
uri: `s3://${location}`,
|
|
9
|
+
bucket: location.slice(0, slash),
|
|
10
|
+
keyPrefix: location.slice(slash + 1),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=athena-output-location.util.js.map
|
package/dist/src/data-marts/data-storage-types/bigquery/services/bigquery-access.validator.js
CHANGED
|
@@ -37,7 +37,7 @@ let BigQueryAccessValidator = BigQueryAccessValidator_1 = class BigQueryAccessVa
|
|
|
37
37
|
const configOpt = bigquery_config_schema_1.BigQueryConfigSchema.safeParse(config);
|
|
38
38
|
if (!configOpt.success) {
|
|
39
39
|
this.logger.warn('Invalid config', configOpt.error);
|
|
40
|
-
return
|
|
40
|
+
return data_storage_access_validator_interface_1.ValidationResult.invalidInput('config', configOpt.error);
|
|
41
41
|
}
|
|
42
42
|
const bigQueryConfig = configOpt.data;
|
|
43
43
|
if (credentials.type === bigquery_credentials_schema_1.BIGQUERY_OAUTH_TYPE) {
|
|
@@ -58,9 +58,7 @@ let BigQueryAccessValidator = BigQueryAccessValidator_1 = class BigQueryAccessVa
|
|
|
58
58
|
const credentialsOpt = bigquery_credentials_schema_1.BigQueryServiceAccountCredentialsSchema.safeParse(credentials);
|
|
59
59
|
if (!credentialsOpt.success) {
|
|
60
60
|
this.logger.warn('Invalid credentials', credentialsOpt.error);
|
|
61
|
-
return
|
|
62
|
-
errors: credentialsOpt.error.errors,
|
|
63
|
-
});
|
|
61
|
+
return data_storage_access_validator_interface_1.ValidationResult.invalidInput('credentials', credentialsOpt.error);
|
|
64
62
|
}
|
|
65
63
|
const apiAdapter = new bigquery_api_adapter_1.BigQueryApiAdapter(credentialsOpt.data, bigQueryConfig);
|
|
66
64
|
try {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { StorageResourceLeaf } from '../../interfaces/storage-resource-browser.interface';
|
|
2
|
+
export declare function isOutsideStorageLocation(resourceLocation: string | undefined, storageLocation: string | undefined): boolean | undefined;
|
|
3
|
+
export declare function flagLocationMismatches(leaves: StorageResourceLeaf[], storageLocation: string | undefined): StorageResourceLeaf[];
|
package/dist/src/data-marts/data-storage-types/bigquery/services/bigquery-resource-location.util.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isOutsideStorageLocation = isOutsideStorageLocation;
|
|
4
|
+
exports.flagLocationMismatches = flagLocationMismatches;
|
|
5
|
+
function isOutsideStorageLocation(resourceLocation, storageLocation) {
|
|
6
|
+
if (!resourceLocation || !storageLocation)
|
|
7
|
+
return undefined;
|
|
8
|
+
return resourceLocation.toLowerCase() !== storageLocation.toLowerCase();
|
|
9
|
+
}
|
|
10
|
+
function flagLocationMismatches(leaves, storageLocation) {
|
|
11
|
+
if (!storageLocation)
|
|
12
|
+
return leaves;
|
|
13
|
+
return leaves.map(leaf => {
|
|
14
|
+
const locationMismatch = isOutsideStorageLocation(leaf.location, storageLocation);
|
|
15
|
+
return locationMismatch === undefined ? leaf : { ...leaf, locationMismatch };
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=bigquery-resource-location.util.js.map
|
package/dist/src/data-marts/data-storage-types/bigquery/services/bigquery-sharded-tables.util.js
CHANGED
|
@@ -28,12 +28,13 @@ function buildWildcardRollups(rawTables, projectId) {
|
|
|
28
28
|
groups.set(key, {
|
|
29
29
|
datasetId: t.datasetId,
|
|
30
30
|
prefix,
|
|
31
|
+
location: t.location,
|
|
31
32
|
shardIds: [shardKey],
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
const rollups = [];
|
|
36
|
-
for (const { datasetId, prefix, shardIds } of groups.values()) {
|
|
37
|
+
for (const { datasetId, prefix, location, shardIds } of groups.values()) {
|
|
37
38
|
if (shardIds.length < exports.GBQ_MIN_SHARDS_FOR_WILDCARD)
|
|
38
39
|
continue;
|
|
39
40
|
const wildcardId = `${prefix}_*`;
|
|
@@ -43,6 +44,7 @@ function buildWildcardRollups(rawTables, projectId) {
|
|
|
43
44
|
groupId: datasetId,
|
|
44
45
|
type: 'TABLE',
|
|
45
46
|
fullyQualifiedName: `${projectId}.${datasetId}.${wildcardId}`,
|
|
47
|
+
...(location ? { location } : {}),
|
|
46
48
|
},
|
|
47
49
|
shardIds,
|
|
48
50
|
});
|
|
@@ -63,6 +65,7 @@ function applyResourceFilter(rawTables, projectId, filter) {
|
|
|
63
65
|
groupId: t.datasetId,
|
|
64
66
|
type: t.type,
|
|
65
67
|
fullyQualifiedName: t.fullyQualifiedName,
|
|
68
|
+
...(t.location ? { location: t.location } : {}),
|
|
66
69
|
};
|
|
67
70
|
if (t.type === 'VIEW') {
|
|
68
71
|
viewLeaves.push(leaf);
|
|
@@ -20,6 +20,7 @@ const data_storage_credentials_resolver_service_1 = require("../../data-storage-
|
|
|
20
20
|
const data_storage_type_enum_1 = require("../../enums/data-storage-type.enum");
|
|
21
21
|
const bigquery_config_schema_1 = require("../schemas/bigquery-config.schema");
|
|
22
22
|
const bigquery_credentials_schema_1 = require("../schemas/bigquery-credentials.schema");
|
|
23
|
+
const bigquery_resource_location_util_1 = require("./bigquery-resource-location.util");
|
|
23
24
|
const bigquery_sharded_tables_util_1 = require("./bigquery-sharded-tables.util");
|
|
24
25
|
const GBQ_LIST_PAGE_SIZE = 500;
|
|
25
26
|
const GBQ_LIST_RESULT_CAP = 2000;
|
|
@@ -48,7 +49,7 @@ let BigQueryStorageResourceBrowser = BigQueryStorageResourceBrowser_1 = class Bi
|
|
|
48
49
|
const rawTables = await this.listTablesInProject(clients, namespaceId);
|
|
49
50
|
this.logger.debug?.(`listLeafResources(${namespaceId}, ${filter ?? 'unfiltered'}): ` +
|
|
50
51
|
`${rawTables.length} raw rows from BQ`);
|
|
51
|
-
const result = (0, bigquery_sharded_tables_util_1.applyResourceFilter)(rawTables, namespaceId, filter);
|
|
52
|
+
const result = (0, bigquery_resource_location_util_1.flagLocationMismatches)((0, bigquery_sharded_tables_util_1.applyResourceFilter)(rawTables, namespaceId, filter), clients.location);
|
|
52
53
|
this.logger.debug?.(`listLeafResources(${namespaceId}, ${filter ?? 'unfiltered'}): ` +
|
|
53
54
|
`${result.length} leaves after wildcard collapsing`);
|
|
54
55
|
return result;
|
|
@@ -144,11 +145,11 @@ let BigQueryStorageResourceBrowser = BigQueryStorageResourceBrowser_1 = class Bi
|
|
|
144
145
|
.map(dataset => {
|
|
145
146
|
const metadata = (dataset.metadata ?? {});
|
|
146
147
|
const id = dataset.id ?? metadata.datasetReference?.datasetId ?? '';
|
|
147
|
-
return { id, location:
|
|
148
|
+
return { id, location: metadata.location };
|
|
148
149
|
})
|
|
149
150
|
.filter(dataset => dataset.id);
|
|
150
151
|
}
|
|
151
|
-
async listTables(clients, projectId, datasetId) {
|
|
152
|
+
async listTables(clients, projectId, { id: datasetId, location }) {
|
|
152
153
|
const bq = this.cloneForProject(clients, projectId);
|
|
153
154
|
const [tables] = await bq
|
|
154
155
|
.dataset(datasetId, { projectId })
|
|
@@ -160,7 +161,13 @@ let BigQueryStorageResourceBrowser = BigQueryStorageResourceBrowser_1 = class Bi
|
|
|
160
161
|
const id = table.id ?? metadata.tableReference?.tableId ?? '';
|
|
161
162
|
const rawType = metadata.type;
|
|
162
163
|
const type = rawType === 'VIEW' || rawType === 'MATERIALIZED_VIEW' ? 'VIEW' : 'TABLE';
|
|
163
|
-
return {
|
|
164
|
+
return {
|
|
165
|
+
id,
|
|
166
|
+
datasetId,
|
|
167
|
+
type,
|
|
168
|
+
fullyQualifiedName: `${projectId}.${datasetId}.${id}`,
|
|
169
|
+
location,
|
|
170
|
+
};
|
|
164
171
|
})
|
|
165
172
|
.filter(table => table.id);
|
|
166
173
|
}
|
|
@@ -179,7 +186,7 @@ let BigQueryStorageResourceBrowser = BigQueryStorageResourceBrowser_1 = class Bi
|
|
|
179
186
|
break;
|
|
180
187
|
}
|
|
181
188
|
const batch = datasets.slice(i, i + GBQ_PROJECT_FANOUT_CONCURRENCY);
|
|
182
|
-
const settled = await Promise.allSettled(batch.map(dataset => (0, promise_util_1.raceWithTimeout)(this.listTables(clients, projectId, dataset
|
|
189
|
+
const settled = await Promise.allSettled(batch.map(dataset => (0, promise_util_1.raceWithTimeout)(this.listTables(clients, projectId, dataset), GBQ_PROJECT_TABLES_PER_DATASET_TIMEOUT_MS, `listTables ${projectId}.${dataset.id}`)));
|
|
183
190
|
for (const outcome of settled) {
|
|
184
191
|
if (outcome.status === 'fulfilled') {
|
|
185
192
|
for (const table of outcome.value) {
|
package/dist/src/data-marts/data-storage-types/databricks/services/databricks-access.validator.js
CHANGED
|
@@ -28,14 +28,12 @@ let DatabricksAccessValidator = DatabricksAccessValidator_1 = class DatabricksAc
|
|
|
28
28
|
const configOpt = databricks_config_schema_1.DatabricksConfigSchema.safeParse(config);
|
|
29
29
|
if (!configOpt.success) {
|
|
30
30
|
this.logger.log('Invalid config', configOpt.error);
|
|
31
|
-
return
|
|
31
|
+
return data_storage_access_validator_interface_1.ValidationResult.invalidInput('config', configOpt.error);
|
|
32
32
|
}
|
|
33
33
|
const credentialsOpt = databricks_credentials_schema_1.DatabricksCredentialsSchema.safeParse(credentials);
|
|
34
34
|
if (!credentialsOpt.success) {
|
|
35
35
|
this.logger.log('Invalid credentials', credentialsOpt.error);
|
|
36
|
-
return
|
|
37
|
-
errors: credentialsOpt.error.errors,
|
|
38
|
-
});
|
|
36
|
+
return data_storage_access_validator_interface_1.ValidationResult.invalidInput('credentials', credentialsOpt.error);
|
|
39
37
|
}
|
|
40
38
|
const apiAdapter = this.adapterFactory.create(credentialsOpt.data, configOpt.data);
|
|
41
39
|
try {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { ZodError } from 'zod';
|
|
1
2
|
import { TypedComponent } from '../../../common/resolver/typed-component.resolver';
|
|
3
|
+
import { FieldErrorScope } from '../../utils/field-errors.utils';
|
|
2
4
|
import { DataStorageType } from '../enums/data-storage-type.enum';
|
|
3
5
|
import { DataStorageConfig } from '../data-storage-config.type';
|
|
4
6
|
import { DataStorageCredentials } from '../data-storage-credentials.type';
|
|
@@ -17,6 +19,7 @@ export declare class ValidationResult {
|
|
|
17
19
|
constructor(valid: boolean, errorMessage?: string | undefined, reason?: Record<string, unknown> | undefined, code?: ValidationResultCode | undefined);
|
|
18
20
|
static success(): ValidationResult;
|
|
19
21
|
static failure(errorMessage?: string, reason?: Record<string, unknown>): ValidationResult;
|
|
22
|
+
static invalidInput(scope: FieldErrorScope, error: ZodError): ValidationResult;
|
|
20
23
|
static unconfigured(errorMessage: string): ValidationResult;
|
|
21
24
|
static oauthReauthRequired(errorMessage: string): ValidationResult;
|
|
22
25
|
}
|
package/dist/src/data-marts/data-storage-types/interfaces/data-storage-access-validator.interface.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ValidationResult = exports.ValidationResultCode = void 0;
|
|
4
|
+
const field_errors_utils_1 = require("../../utils/field-errors.utils");
|
|
4
5
|
var ValidationResultCode;
|
|
5
6
|
(function (ValidationResultCode) {
|
|
6
7
|
ValidationResultCode["UNCONFIGURED"] = "UNCONFIGURED";
|
|
@@ -23,6 +24,12 @@ class ValidationResult {
|
|
|
23
24
|
static failure(errorMessage, reason) {
|
|
24
25
|
return new ValidationResult(false, errorMessage, reason);
|
|
25
26
|
}
|
|
27
|
+
static invalidInput(scope, error) {
|
|
28
|
+
return new ValidationResult(false, (0, field_errors_utils_1.describeInvalidInput)(scope, error), {
|
|
29
|
+
errors: (0, field_errors_utils_1.sanitizeIssues)(error.errors),
|
|
30
|
+
fieldErrors: (0, field_errors_utils_1.toFieldErrors)(scope, error),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
26
33
|
static unconfigured(errorMessage) {
|
|
27
34
|
return new ValidationResult(false, errorMessage, undefined, ValidationResultCode.UNCONFIGURED);
|
|
28
35
|
}
|
package/dist/src/data-marts/data-storage-types/interfaces/storage-resource-browser.interface.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export interface StorageResourceLeaf extends StorageResourceNode {
|
|
|
9
9
|
groupId: string;
|
|
10
10
|
type: 'TABLE' | 'VIEW';
|
|
11
11
|
fullyQualifiedName: string;
|
|
12
|
+
location?: string;
|
|
13
|
+
locationMismatch?: boolean;
|
|
12
14
|
}
|
|
13
15
|
export type StorageResourceFilter = 'TABLE' | 'VIEW' | 'TABLE_PATTERN';
|
|
14
16
|
export interface IStorageResourceBrowserProvider extends TypedComponent<DataStorageType> {
|
package/dist/src/data-marts/data-storage-types/redshift/services/redshift-access.validator.js
CHANGED
|
@@ -25,15 +25,11 @@ let RedshiftAccessValidator = class RedshiftAccessValidator {
|
|
|
25
25
|
async validate(config, credentials) {
|
|
26
26
|
const configResult = redshift_config_schema_1.RedshiftConfigSchema.safeParse(config);
|
|
27
27
|
if (!configResult.success) {
|
|
28
|
-
return
|
|
29
|
-
errors: configResult.error.errors,
|
|
30
|
-
});
|
|
28
|
+
return data_storage_access_validator_interface_1.ValidationResult.invalidInput('config', configResult.error);
|
|
31
29
|
}
|
|
32
30
|
const credentialsResult = redshift_credentials_schema_1.RedshiftCredentialsSchema.safeParse(credentials);
|
|
33
31
|
if (!credentialsResult.success) {
|
|
34
|
-
return
|
|
35
|
-
errors: credentialsResult.error.errors,
|
|
36
|
-
});
|
|
32
|
+
return data_storage_access_validator_interface_1.ValidationResult.invalidInput('credentials', credentialsResult.error);
|
|
37
33
|
}
|
|
38
34
|
const adapter = this.adapterFactory.create(credentialsResult.data, configResult.data);
|
|
39
35
|
try {
|
package/dist/src/data-marts/data-storage-types/snowflake/services/snowflake-access.validator.js
CHANGED
|
@@ -21,14 +21,12 @@ let SnowflakeAccessValidator = SnowflakeAccessValidator_1 = class SnowflakeAcces
|
|
|
21
21
|
const configOpt = snowflake_config_schema_1.SnowflakeConfigSchema.safeParse(config);
|
|
22
22
|
if (!configOpt.success) {
|
|
23
23
|
this.logger.log('Invalid config', configOpt.error);
|
|
24
|
-
return
|
|
24
|
+
return data_storage_access_validator_interface_1.ValidationResult.invalidInput('config', configOpt.error);
|
|
25
25
|
}
|
|
26
26
|
const credentialsOpt = snowflake_credentials_schema_1.SnowflakeCredentialsSchema.safeParse(credentials);
|
|
27
27
|
if (!credentialsOpt.success) {
|
|
28
28
|
this.logger.log('Invalid credentials', credentialsOpt.error);
|
|
29
|
-
return
|
|
30
|
-
errors: credentialsOpt.error.errors,
|
|
31
|
-
});
|
|
29
|
+
return data_storage_access_validator_interface_1.ValidationResult.invalidInput('credentials', credentialsOpt.error);
|
|
32
30
|
}
|
|
33
31
|
const snowflakeConfig = configOpt.data;
|
|
34
32
|
const apiAdapter = new snowflake_api_adapter_1.SnowflakeApiAdapter(credentialsOpt.data, snowflakeConfig);
|
|
@@ -7,5 +7,6 @@ export declare class ListDataMartsCommand {
|
|
|
7
7
|
readonly offset?: number | undefined;
|
|
8
8
|
readonly ownerFilter?: OwnerFilter | undefined;
|
|
9
9
|
readonly status?: DataMartStatus | undefined;
|
|
10
|
-
|
|
10
|
+
readonly contextIds?: string[] | undefined;
|
|
11
|
+
constructor(projectId: string, userId: string, roles: string[], offset?: number | undefined, ownerFilter?: OwnerFilter | undefined, status?: DataMartStatus | undefined, contextIds?: string[] | undefined);
|
|
11
12
|
}
|
|
@@ -8,13 +8,15 @@ class ListDataMartsCommand {
|
|
|
8
8
|
offset;
|
|
9
9
|
ownerFilter;
|
|
10
10
|
status;
|
|
11
|
-
|
|
11
|
+
contextIds;
|
|
12
|
+
constructor(projectId, userId, roles, offset, ownerFilter, status, contextIds) {
|
|
12
13
|
this.projectId = projectId;
|
|
13
14
|
this.userId = userId;
|
|
14
15
|
this.roles = roles;
|
|
15
16
|
this.offset = offset;
|
|
16
17
|
this.ownerFilter = ownerFilter;
|
|
17
18
|
this.status = status;
|
|
19
|
+
this.contextIds = contextIds;
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
exports.ListDataMartsCommand = ListDataMartsCommand;
|
|
@@ -12,6 +12,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.SqlDryRunRequestApiDto = void 0;
|
|
13
13
|
const swagger_1 = require("@nestjs/swagger");
|
|
14
14
|
const class_validator_1 = require("class-validator");
|
|
15
|
+
const max_byte_length_validator_1 = require("../../../common/validators/max-byte-length.validator");
|
|
16
|
+
const MAX_MEDIUMTEXT_COLUMN_BYTES = 16777215;
|
|
15
17
|
class SqlDryRunRequestApiDto {
|
|
16
18
|
sql;
|
|
17
19
|
}
|
|
@@ -23,6 +25,7 @@ __decorate([
|
|
|
23
25
|
}),
|
|
24
26
|
(0, class_validator_1.IsString)(),
|
|
25
27
|
(0, class_validator_1.IsNotEmpty)(),
|
|
28
|
+
(0, max_byte_length_validator_1.MaxByteLength)(MAX_MEDIUMTEXT_COLUMN_BYTES),
|
|
26
29
|
__metadata("design:type", String)
|
|
27
30
|
], SqlDryRunRequestApiDto.prototype, "sql", void 0);
|
|
28
31
|
//# sourceMappingURL=sql-dry-run-request-api.dto.js.map
|
|
@@ -7,6 +7,8 @@ export declare class StorageResourceLeafDto {
|
|
|
7
7
|
groupId: string;
|
|
8
8
|
type: 'TABLE' | 'VIEW';
|
|
9
9
|
fullyQualifiedName: string;
|
|
10
|
+
location?: string;
|
|
11
|
+
locationMismatch?: boolean;
|
|
10
12
|
}
|
|
11
13
|
export declare class ListStorageResourcesResponseDto {
|
|
12
14
|
namespaces?: StorageNamespaceNodeDto[];
|
|
@@ -35,6 +35,8 @@ class StorageResourceLeafDto {
|
|
|
35
35
|
groupId;
|
|
36
36
|
type;
|
|
37
37
|
fullyQualifiedName;
|
|
38
|
+
location;
|
|
39
|
+
locationMismatch;
|
|
38
40
|
}
|
|
39
41
|
exports.StorageResourceLeafDto = StorageResourceLeafDto;
|
|
40
42
|
__decorate([
|
|
@@ -59,6 +61,21 @@ __decorate([
|
|
|
59
61
|
}),
|
|
60
62
|
__metadata("design:type", String)
|
|
61
63
|
], StorageResourceLeafDto.prototype, "fullyQualifiedName", void 0);
|
|
64
|
+
__decorate([
|
|
65
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
66
|
+
description: "Where the resource's data lives, e.g. a BigQuery dataset location",
|
|
67
|
+
example: 'EU',
|
|
68
|
+
}),
|
|
69
|
+
__metadata("design:type", String)
|
|
70
|
+
], StorageResourceLeafDto.prototype, "location", void 0);
|
|
71
|
+
__decorate([
|
|
72
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
73
|
+
description: 'True when the resource lives in a different location than the one the storage runs ' +
|
|
74
|
+
'queries in, so a data mart on this storage cannot read it. Omitted when either ' +
|
|
75
|
+
'location is unknown.',
|
|
76
|
+
}),
|
|
77
|
+
__metadata("design:type", Boolean)
|
|
78
|
+
], StorageResourceLeafDto.prototype, "locationMismatch", void 0);
|
|
62
79
|
class ListStorageResourcesResponseDto {
|
|
63
80
|
namespaces;
|
|
64
81
|
resources;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare class GoogleSheetsApiCallError extends Error {
|
|
2
|
+
readonly status: number;
|
|
3
|
+
readonly cause: unknown;
|
|
4
|
+
constructor(message: string, status: number, cause: unknown);
|
|
5
|
+
}
|
|
6
|
+
export declare function googleSheetsApiCallMessage(step: string, status: number, googleMessage: string): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GoogleSheetsApiCallError = void 0;
|
|
4
|
+
exports.googleSheetsApiCallMessage = googleSheetsApiCallMessage;
|
|
5
|
+
class GoogleSheetsApiCallError extends Error {
|
|
6
|
+
status;
|
|
7
|
+
cause;
|
|
8
|
+
constructor(message, status, cause) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.cause = cause;
|
|
12
|
+
this.name = 'GoogleSheetsApiCallError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.GoogleSheetsApiCallError = GoogleSheetsApiCallError;
|
|
16
|
+
function isUnfinishedUpdate(status) {
|
|
17
|
+
return status === 404 || status >= 500;
|
|
18
|
+
}
|
|
19
|
+
function googleSheetsApiCallMessage(step, status, googleMessage) {
|
|
20
|
+
const details = `Details: ${googleMessage.trim()}`;
|
|
21
|
+
if (isUnfinishedUpdate(status)) {
|
|
22
|
+
return (`Google Sheets couldn't finish updating the spreadsheet this report writes to. ` +
|
|
23
|
+
`A single failure can be a temporary problem on Google's side — run the report ` +
|
|
24
|
+
`again. If it fails on every run, the spreadsheet most likely recalculates heavy ` +
|
|
25
|
+
`formulas after every change, for example formulas on other sheets that read whole ` +
|
|
26
|
+
`columns of the report's sheet: limit them to the rows they need or send the report ` +
|
|
27
|
+
`to a separate spreadsheet. Circular references can cause this too: fix the formulas ` +
|
|
28
|
+
`that show a circular dependency error, and turn on Iterative calculation ` +
|
|
29
|
+
`(File → Settings → Calculation) only if a circular reference is intentional. ${details}`);
|
|
30
|
+
}
|
|
31
|
+
const whileStep = `while ${step.charAt(0).toLowerCase()}${step.slice(1)}`;
|
|
32
|
+
return `Google Sheets rejected an update ${whileStep}. ${details}`;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=google-sheets-api-call.error.js.map
|