diff --git a/apps/sim/lib/selectors/server/providers/powerbi.test.ts b/apps/sim/lib/selectors/server/providers/powerbi.test.ts index 2dd0c28cf8d..d42c9984652 100644 --- a/apps/sim/lib/selectors/server/providers/powerbi.test.ts +++ b/apps/sim/lib/selectors/server/providers/powerbi.test.ts @@ -136,7 +136,8 @@ describe('Power BI selector provider boundary', () => { manualWorkspaceId: 'stale-manual-workspace', [field]: workspace, } - const picker = PowerBIBlock.subBlocks.find((subBlock) => subBlock.id === 'datasetSelector')! + const picker = PowerBIBlock.subBlocks.find((subBlock) => subBlock.id === 'datasetSelector') + if (!picker) throw new Error('Power BI block has no datasetSelector') const context = buildSelectorContextFromValues({ selectorKey: 'powerbi.datasets', contextConfigs: getSelectorContextSubBlocks(PowerBIBlock.subBlocks, values), diff --git a/apps/sim/tools/powerbi/__fixtures__/provider-fixture.ts b/apps/sim/tools/powerbi/__fixtures__/provider-fixture.ts index b777ffa0b49..f59f8bf3db2 100644 --- a/apps/sim/tools/powerbi/__fixtures__/provider-fixture.ts +++ b/apps/sim/tools/powerbi/__fixtures__/provider-fixture.ts @@ -31,7 +31,7 @@ export type PowerBIFixtureScenario = | 'missing-identity' | 'missing-query' -export interface PowerBIFixtureRequest { +interface PowerBIFixtureRequest { method: string path: string body: unknown diff --git a/apps/sim/tools/powerbi/execute-query.test.ts b/apps/sim/tools/powerbi/execute-query.test.ts index 8da6dcd256a..02da7fed282 100644 --- a/apps/sim/tools/powerbi/execute-query.test.ts +++ b/apps/sim/tools/powerbi/execute-query.test.ts @@ -2,6 +2,9 @@ import { jsonResponse } from '@sim/testing/helpers/http' import { describe, expect, it } from 'vitest' import { powerbiExecuteQueryTool } from '@/tools/powerbi/execute-query' +const { transformResponse } = powerbiExecuteQueryTool +if (!transformResponse) throw new Error('powerbi_execute_query has no transformResponse') + const params = { accessToken: 'provider-token', groupId: 'workspace-id', @@ -32,7 +35,7 @@ describe('Power BI DAX result handling', () => { ], }) - const result = await powerbiExecuteQueryTool.transformResponse!(response, params) + const result = await transformResponse(response, params) expect(result).toMatchObject({ success: false, @@ -52,7 +55,7 @@ describe('Power BI DAX result handling', () => { }) it('preserves provider column names, blank values and falsy values in complete results', async () => { - const result = await powerbiExecuteQueryTool.transformResponse!( + const result = await transformResponse( jsonResponse({ results: [ { @@ -79,7 +82,7 @@ describe('Power BI DAX result handling', () => { }) it('does not fabricate a query error message when Microsoft supplies only a code', async () => { - const result = await powerbiExecuteQueryTool.transformResponse!( + const result = await transformResponse( jsonResponse({ error: { code: 'DatasetExecuteQueriesError' } }), params ) @@ -98,7 +101,7 @@ describe('Power BI DAX result handling', () => { }) it.each(['omitted', 'empty'])('accepts one result table with %s rows', async (kind) => { - const result = await powerbiExecuteQueryTool.transformResponse!( + const result = await transformResponse( jsonResponse({ results: [{ tables: [kind === 'empty' ? { rows: [] } : {}] }] }), params ) @@ -117,7 +120,7 @@ describe('Power BI DAX result handling', () => { { code: 'AnalysisServicesErrorCode', detail: { type: 1, value: '3238920194' } }, { code: 'DetailsMessage', detail: { type: 1, value: 'The DAX query is invalid.' } }, ] - const result = await powerbiExecuteQueryTool.transformResponse!( + const result = await transformResponse( jsonResponse({ error: { code: 'DatasetExecuteQueriesError', @@ -174,9 +177,7 @@ describe('Power BI DAX result handling', () => { : undefined ) - await expect(powerbiExecuteQueryTool.transformResponse!(response, params)).rejects.toThrow( - /maximum size.*20971520/ - ) + await expect(transformResponse(response, params)).rejects.toThrow(/maximum size.*20971520/) expect(canceled).toBe(true) } ) @@ -191,7 +192,7 @@ describe('Power BI DAX result handling', () => { }, }) ) - const transformed = powerbiExecuteQueryTool.transformResponse!(response, params, { + const transformed = transformResponse(response, params, { signal: abort.signal, }) abort.abort(new Error('Execution canceled')) diff --git a/apps/sim/tools/powerbi/types.ts b/apps/sim/tools/powerbi/types.ts index 01a9c517cdc..cf586c585a0 100644 --- a/apps/sim/tools/powerbi/types.ts +++ b/apps/sim/tools/powerbi/types.ts @@ -1,6 +1,6 @@ import type { OutputProperty, ToolResponse } from '@/tools/types' -export interface PowerBIAuthParams { +interface PowerBIAuthParams { accessToken: string } @@ -27,7 +27,7 @@ export interface PowerBIExecuteQueryParams extends PowerBIDatasetParams { includeNulls?: boolean } -export type PowerBINotifyOption = 'NoNotification' | 'MailOnFailure' | 'MailOnCompletion' +type PowerBINotifyOption = 'NoNotification' | 'MailOnFailure' | 'MailOnCompletion' export interface PowerBIRefreshDatasetParams extends PowerBIDatasetParams { notifyOption?: PowerBINotifyOption @@ -71,7 +71,7 @@ export interface PowerBIDataset { webUrl: string | null } -export interface PowerBIRefreshAttempt { +interface PowerBIRefreshAttempt { attemptId: number | null type: string | null startTime: string | null @@ -96,7 +96,7 @@ export interface PowerBIQueryError { details: unknown | null } -export interface PowerBIInformationProtectionLabel { +interface PowerBIInformationProtectionLabel { id: string | null name: string | null } @@ -206,21 +206,6 @@ export const POWERBI_DATASET_OUTPUT_PROPERTIES = { webUrl: { ...nullableString, description: 'Semantic model URL in Power BI, when available' }, } satisfies Record -export const POWERBI_REFRESH_ATTEMPT_OUTPUT_PROPERTIES = { - attemptId: { - type: 'number', - nullable: true, - description: 'Refresh attempt index', - }, - type: { ...nullableString, description: 'Provider refresh attempt type' }, - startTime: { ...nullableString, description: 'Attempt start timestamp' }, - endTime: { ...nullableString, description: 'Attempt end timestamp, when available' }, - serviceExceptionJson: { - ...nullableString, - description: 'Serialized provider failure details, when available', - }, -} satisfies Record - export const POWERBI_REFRESH_OUTPUT_PROPERTIES = { requestId: { ...nullableString, description: 'Provider refresh request ID' }, refreshType: { ...nullableString, description: 'Provider refresh trigger type' }, @@ -237,7 +222,23 @@ export const POWERBI_REFRESH_OUTPUT_PROPERTIES = { refreshAttempts: { type: 'array', description: 'Refresh attempts supplied by the provider', - items: { type: 'object', properties: POWERBI_REFRESH_ATTEMPT_OUTPUT_PROPERTIES }, + items: { + type: 'object', + properties: { + attemptId: { + type: 'number', + nullable: true, + description: 'Refresh attempt index', + }, + type: { ...nullableString, description: 'Provider refresh attempt type' }, + startTime: { ...nullableString, description: 'Attempt start timestamp' }, + endTime: { ...nullableString, description: 'Attempt end timestamp, when available' }, + serviceExceptionJson: { + ...nullableString, + description: 'Serialized provider failure details, when available', + }, + }, + }, }, } satisfies Record diff --git a/apps/sim/tools/powerbi/utils.ts b/apps/sim/tools/powerbi/utils.ts index 6dc2b55e615..76076fd36d1 100644 --- a/apps/sim/tools/powerbi/utils.ts +++ b/apps/sim/tools/powerbi/utils.ts @@ -10,7 +10,7 @@ import type { } from '@/tools/powerbi/types' import { safeUrlPathSegment } from '@/tools/url-path' -export const MAX_POWERBI_RESPONSE_BYTES = 20 * 1024 * 1024 +const MAX_POWERBI_RESPONSE_BYTES = 20 * 1024 * 1024 export const POWERBI_ACCESS_TOKEN_PARAM = { type: 'string',