push neon reactor

This commit is contained in:
2026-07-12 15:11:38 +02:00
parent 172e72dbcd
commit aeab5f7820
9597 changed files with 2407488 additions and 0 deletions
@@ -0,0 +1,6 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
/** @private */
export declare function loadConnections(): Promise<void>;
//# sourceMappingURL=ConnectionUtils.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"ConnectionUtils.d.ts","sourceRoot":"","sources":["../../../src/internal/data/ConnectionUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,eAAe;AACf,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAQrD"}
@@ -0,0 +1,21 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { executePluginAsync } from '../plugins';
let connectionsLoaded = false;
/** @private */
export async function loadConnections() {
if (connectionsLoaded) {
return;
}
connectionsLoaded = true;
await loadNonCompositeConnectionsAsync();
await resolveCompositeConnectionsAsync();
}
async function loadNonCompositeConnectionsAsync() {
return executePluginAsync('AppPowerAppsClientPlugin', 'loadNonCompositeConnectionsAsync', []);
}
async function resolveCompositeConnectionsAsync() {
return executePluginAsync('AppPowerAppsClientPlugin', 'resolveCompositeConnectionsAsync', []);
}
//# sourceMappingURL=ConnectionUtils.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ConnectionUtils.js","sourceRoot":"","sources":["../../../src/internal/data/ConnectionUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAE9B,eAAe;AACf,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO;IACT,CAAC;IAED,iBAAiB,GAAG,IAAI,CAAC;IACzB,MAAM,gCAAgC,EAAE,CAAC;IACzC,MAAM,gCAAgC,EAAE,CAAC;AAC3C,CAAC;AAED,KAAK,UAAU,gCAAgC;IAC7C,OAAO,kBAAkB,CAAC,0BAA0B,EAAE,kCAAkC,EAAE,EAAE,CAAC,CAAC;AAChG,CAAC;AAED,KAAK,UAAU,gCAAgC;IAC7C,OAAO,kBAAkB,CAAC,0BAA0B,EAAE,kCAAkC,EAAE,EAAE,CAAC,CAAC;AAChG,CAAC"}
@@ -0,0 +1,19 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { IOperationResult } from './core/types';
/**
* Executes operations using the plugin.
* @private
*/
export declare class OperationExecutor {
/**
* Executes an operation using the plugin.
* @param operationName The name of the operation.
* @param action The action to perform.
* @param params The parameters for the operation.
* @returns A promise resolving to the operation result.
*/
execute<T = string>(operationName: string, action: string, params: unknown[]): Promise<IOperationResult<T>>;
}
//# sourceMappingURL=OperationExecutor.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"OperationExecutor.d.ts","sourceRoot":"","sources":["../../../src/internal/data/OperationExecutor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIrD;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B;;;;;;OAMG;IACU,OAAO,CAAC,CAAC,GAAG,MAAM,EAC7B,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EAAE,GAChB,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAahC"}
@@ -0,0 +1,31 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { executePluginAsync } from '../plugins';
import { loadConnections } from './ConnectionUtils';
let loadConnectionsPromise;
/**
* Executes operations using the plugin.
* @private
*/
export class OperationExecutor {
/**
* Executes an operation using the plugin.
* @param operationName The name of the operation.
* @param action The action to perform.
* @param params The parameters for the operation.
* @returns A promise resolving to the operation result.
*/
async execute(operationName, action, params) {
if (!loadConnectionsPromise) {
loadConnectionsPromise = loadConnections();
}
await loadConnectionsPromise;
const result = await executePluginAsync(operationName, action, params);
return {
success: true,
data: result,
};
}
}
//# sourceMappingURL=OperationExecutor.js.map
@@ -0,0 +1 @@
{"version":3,"file":"OperationExecutor.js","sourceRoot":"","sources":["../../../src/internal/data/OperationExecutor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,IAAI,sBAAiD,CAAC;AAEtD;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAC5B;;;;;;OAMG;IACI,KAAK,CAAC,OAAO,CAClB,aAAqB,EACrB,MAAc,EACd,MAAiB;QAEjB,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAC5B,sBAAsB,GAAG,eAAe,EAAE,CAAC;QAC7C,CAAC;QAED,MAAM,sBAAsB,CAAC;QAE7B,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAI,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1E,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,MAAM;SACb,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,14 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IOperationResult } from '../types';
/**
* Creates a new record in the specified table.
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to create the record in.
* @param record - The record to create.
* @returns A promise that resolves to the created record.
* @private
*/
export declare function createRecordAsync<TInput, TResult>(dataSourcesInfo: DataSourcesInfo, tableName: string, record: TInput): Promise<IOperationResult<TResult>>;
//# sourceMappingURL=createRecord.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"createRecord.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/createRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElE;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EACrD,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAIpC"}
@@ -0,0 +1,16 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getPowerSdkInstance } from '../runtime/getRuntimeContext';
/**
* Creates a new record in the specified table.
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to create the record in.
* @param record - The record to create.
* @returns A promise that resolves to the created record.
* @private
*/
export async function createRecordAsync(dataSourcesInfo, tableName, record) {
return await (await getPowerSdkInstance(dataSourcesInfo)).Data.createRecordAsync(tableName, record);
}
//# sourceMappingURL=createRecord.js.map
@@ -0,0 +1 @@
{"version":3,"file":"createRecord.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/createRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,eAAgC,EAChC,SAAiB,EACjB,MAAc;IAEd,OAAO,MAAM,CACX,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAC3C,CAAC,IAAI,CAAC,iBAAiB,CAAkB,SAAS,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,17 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IOperationResult } from '../types';
/**
* Deletes the file or image data stored in a file/image column of an existing record.
* Sends a DELETE request to `/<tableName>(<recordId>)/<columnName>`.
* This API is intended for use with file and image columns in Dataverse.
* @param dataSourcesInfo - The data sources information.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The identifier of the record.
* @param columnName - The name of the file or image column whose data should be deleted.
* @returns - A promise that resolves to an operation result.
* @private
*/
export declare function deleteFileOrImageFromRecord(dataSourcesInfo: DataSourcesInfo, tableName: string, recordId: string, columnName: string): Promise<IOperationResult<void>>;
//# sourceMappingURL=deleteFileOrImageFromRecord.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"deleteFileOrImageFromRecord.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/deleteFileOrImageFromRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElE;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAC/C,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAIjC"}
@@ -0,0 +1,19 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getPowerSdkInstance } from '../runtime/getRuntimeContext';
/**
* Deletes the file or image data stored in a file/image column of an existing record.
* Sends a DELETE request to `/<tableName>(<recordId>)/<columnName>`.
* This API is intended for use with file and image columns in Dataverse.
* @param dataSourcesInfo - The data sources information.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The identifier of the record.
* @param columnName - The name of the file or image column whose data should be deleted.
* @returns - A promise that resolves to an operation result.
* @private
*/
export async function deleteFileOrImageFromRecord(dataSourcesInfo, tableName, recordId, columnName) {
return await (await getPowerSdkInstance(dataSourcesInfo)).Data.deleteFileOrImageFromRecord(tableName, recordId, columnName);
}
//# sourceMappingURL=deleteFileOrImageFromRecord.js.map
@@ -0,0 +1 @@
{"version":3,"file":"deleteFileOrImageFromRecord.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/deleteFileOrImageFromRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,eAAgC,EAChC,SAAiB,EACjB,QAAgB,EAChB,UAAkB;IAElB,OAAO,MAAM,CACX,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAC3C,CAAC,IAAI,CAAC,2BAA2B,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,14 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IOperationResult } from '../types';
/**
* Deletes a record from the specified table.
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to delete the record from.
* @param recordId - The ID of the record to delete.
* @returns A promise that resolves to the result of the delete operation.
* @private
*/
export declare function deleteRecordAsync(dataSourcesInfo: DataSourcesInfo, tableName: string, recordId: string): Promise<IOperationResult<void>>;
//# sourceMappingURL=deleteRecord.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"deleteRecord.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/deleteRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElE;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAIjC"}
@@ -0,0 +1,16 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getPowerSdkInstance } from '../runtime/getRuntimeContext';
/**
* Deletes a record from the specified table.
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to delete the record from.
* @param recordId - The ID of the record to delete.
* @returns A promise that resolves to the result of the delete operation.
* @private
*/
export async function deleteRecordAsync(dataSourcesInfo, tableName, recordId) {
return await (await getPowerSdkInstance(dataSourcesInfo)).Data.deleteRecordAsync(tableName, recordId);
}
//# sourceMappingURL=deleteRecord.js.map
@@ -0,0 +1 @@
{"version":3,"file":"deleteRecord.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/deleteRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,eAAgC,EAChC,SAAiB,EACjB,QAAgB;IAEhB,OAAO,MAAM,CACX,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAC3C,CAAC,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,20 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IOperationResult } from '../types';
/**
* Downloads binary data from a file column of an existing record (maximum size 128 MB).
* Returns the file contents as binary.
* This API is intended for use with file/image columns in Dataverse, and will not work with other column types.
* For file columns in Dataverse, the recordId is the ID of the Dataverse record, and the tableName is the logical name of the Dataverse table.
* See documentation for more details:
* https://learn.microsoft.com/en-us/power-apps/developer/data-platform/file-column-data?tabs=webapi#download-a-file-in-a-single-request-using-web-api
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to download the file from.
* @param recordId - The ID of the record to download from.
* @param columnName - The name of the file column to download from.
* @returns - A promise that resolves to an operation result with the file contents as binary.
* @private
*/
export declare function downloadFileFromRecord(dataSourcesInfo: DataSourcesInfo, tableName: string, recordId: string, columnName: string): Promise<IOperationResult<Uint8Array>>;
//# sourceMappingURL=downloadFileFromRecord.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"downloadFileFromRecord.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/downloadFileFromRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAC1C,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAIvC"}
@@ -0,0 +1,22 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getPowerSdkInstance } from '../runtime/getRuntimeContext';
/**
* Downloads binary data from a file column of an existing record (maximum size 128 MB).
* Returns the file contents as binary.
* This API is intended for use with file/image columns in Dataverse, and will not work with other column types.
* For file columns in Dataverse, the recordId is the ID of the Dataverse record, and the tableName is the logical name of the Dataverse table.
* See documentation for more details:
* https://learn.microsoft.com/en-us/power-apps/developer/data-platform/file-column-data?tabs=webapi#download-a-file-in-a-single-request-using-web-api
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to download the file from.
* @param recordId - The ID of the record to download from.
* @param columnName - The name of the file column to download from.
* @returns - A promise that resolves to an operation result with the file contents as binary.
* @private
*/
export async function downloadFileFromRecord(dataSourcesInfo, tableName, recordId, columnName) {
return await (await getPowerSdkInstance(dataSourcesInfo)).Data.downloadFileFromRecord(tableName, recordId, columnName);
}
//# sourceMappingURL=downloadFileFromRecord.js.map
@@ -0,0 +1 @@
{"version":3,"file":"downloadFileFromRecord.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/downloadFileFromRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,eAAgC,EAChC,SAAiB,EACjB,QAAgB,EAChB,UAAkB;IAElB,OAAO,MAAM,CACX,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAC3C,CAAC,IAAI,CAAC,sBAAsB,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,21 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IOperationResult } from '../types';
/**
* Downloads binary data from an image column of an existing record.
* Returns the image contents as binary.
* This API is intended for use with image columns in Dataverse, and will not work with other column types.
* For image columns in Dataverse, the imageRelativeUrl is the relative URL of the image, and the tableName is the logical name of the Dataverse table.
* See documentation for more details:
* https://learn.microsoft.com/en-us/power-apps/developer/data-platform/file-column-data?tabs=webapi#download-a-file-in-a-single-request-using-web-api
* @param dataSourcesInfo - The data sources information.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The identifier of the record containing the image.
* @param columnName - The name of the image column.
* @param fullSize - When true, requests the full-size image (`?size=full`). Defaults to false (thumbnail/smaller size image).
* @returns - A promise that resolves to an operation result with the image contents as binary.
* @private
*/
export declare function downloadImageFromRecord(dataSourcesInfo: DataSourcesInfo, tableName: string, recordId: string, columnName: string, fullSize?: boolean): Promise<IOperationResult<Uint8Array>>;
//# sourceMappingURL=downloadImageFromRecord.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"downloadImageFromRecord.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/downloadImageFromRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAIvC"}
@@ -0,0 +1,23 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getPowerSdkInstance } from '../runtime/getRuntimeContext';
/**
* Downloads binary data from an image column of an existing record.
* Returns the image contents as binary.
* This API is intended for use with image columns in Dataverse, and will not work with other column types.
* For image columns in Dataverse, the imageRelativeUrl is the relative URL of the image, and the tableName is the logical name of the Dataverse table.
* See documentation for more details:
* https://learn.microsoft.com/en-us/power-apps/developer/data-platform/file-column-data?tabs=webapi#download-a-file-in-a-single-request-using-web-api
* @param dataSourcesInfo - The data sources information.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The identifier of the record containing the image.
* @param columnName - The name of the image column.
* @param fullSize - When true, requests the full-size image (`?size=full`). Defaults to false (thumbnail/smaller size image).
* @returns - A promise that resolves to an operation result with the image contents as binary.
* @private
*/
export async function downloadImageFromRecord(dataSourcesInfo, tableName, recordId, columnName, fullSize) {
return await (await getPowerSdkInstance(dataSourcesInfo)).Data.downloadImageFromRecord(tableName, recordId, columnName, fullSize);
}
//# sourceMappingURL=downloadImageFromRecord.js.map
@@ -0,0 +1 @@
{"version":3,"file":"downloadImageFromRecord.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/downloadImageFromRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,eAAgC,EAChC,SAAiB,EACjB,QAAgB,EAChB,UAAkB,EAClB,QAAkB;IAElB,OAAO,MAAM,CACX,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAC3C,CAAC,IAAI,CAAC,uBAAuB,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,12 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IDataOperation, IOperationResult } from '../types';
/**
* Executes a data operation.
* @param operation - The data operation to execute.
* @returns - A promise that resolves to the result of the operation.
* @private
*/
export declare function executeAsync<TRequest, TResult>(dataSourcesInfo: DataSourcesInfo, operation: IDataOperation<TRequest>): Promise<IOperationResult<TResult>>;
//# sourceMappingURL=execute.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/execute.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElF;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAClD,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,cAAc,CAAC,QAAQ,CAAC,GAClC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAIpC"}
@@ -0,0 +1,14 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getPowerSdkInstance } from '../runtime/getRuntimeContext';
/**
* Executes a data operation.
* @param operation - The data operation to execute.
* @returns - A promise that resolves to the result of the operation.
* @private
*/
export async function executeAsync(dataSourcesInfo, operation) {
return await (await getPowerSdkInstance(dataSourcesInfo)).Data.executeAsync(operation);
}
//# sourceMappingURL=execute.js.map
@@ -0,0 +1 @@
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/execute.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,eAAgC,EAChC,SAAmC;IAEnC,OAAO,MAAM,CACX,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAC3C,CAAC,IAAI,CAAC,YAAY,CAAoB,SAAS,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,14 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IOperationOptions, IOperationResult } from '../types';
/**
* Retrieves multiple records from the specified table.
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to create the record in.
* @param options - Optional operation options.
* @returns - A promise that resolves to the created record.
* @private
*/
export declare function retrieveMultipleRecordsAsync<TResult>(dataSourcesInfo: DataSourcesInfo, tableName: string, options?: IOperationOptions): Promise<IOperationResult<TResult[]>>;
//# sourceMappingURL=retrieveMultipleRecords.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"retrieveMultipleRecords.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/retrieveMultipleRecords.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAErF;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAAC,OAAO,EACxD,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAItC"}
@@ -0,0 +1,16 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getPowerSdkInstance } from '../runtime/getRuntimeContext';
/**
* Retrieves multiple records from the specified table.
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to create the record in.
* @param options - Optional operation options.
* @returns - A promise that resolves to the created record.
* @private
*/
export async function retrieveMultipleRecordsAsync(dataSourcesInfo, tableName, options) {
return await (await getPowerSdkInstance(dataSourcesInfo)).Data.retrieveMultipleRecordsAsync(tableName, options);
}
//# sourceMappingURL=retrieveMultipleRecords.js.map
@@ -0,0 +1 @@
{"version":3,"file":"retrieveMultipleRecords.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/retrieveMultipleRecords.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,eAAgC,EAChC,SAAiB,EACjB,OAA2B;IAE3B,OAAO,MAAM,CACX,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAC3C,CAAC,IAAI,CAAC,4BAA4B,CAAU,SAAS,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,14 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IOperationOptions, IOperationResult } from '../types';
/**
* Retrieves a record from the specified table.
* @param tableName - The name of the table to retrieve the record from.
* @param recordId - The ID of the record to retrieve.
* @param options - Optional operation options.
* @returns A promise that resolves to the retrieved record.
* @private
*/
export declare function retrieveRecordAsync<TResult>(dataSourcesInfo: DataSourcesInfo, tableName: string, recordId: string, options?: IOperationOptions): Promise<IOperationResult<TResult>>;
//# sourceMappingURL=retrieveRecord.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"retrieveRecord.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/retrieveRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAErF;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAC/C,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAIpC"}
@@ -0,0 +1,16 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getPowerSdkInstance } from '../runtime/getRuntimeContext';
/**
* Retrieves a record from the specified table.
* @param tableName - The name of the table to retrieve the record from.
* @param recordId - The ID of the record to retrieve.
* @param options - Optional operation options.
* @returns A promise that resolves to the retrieved record.
* @private
*/
export async function retrieveRecordAsync(dataSourcesInfo, tableName, recordId, options) {
return await (await getPowerSdkInstance(dataSourcesInfo)).Data.retrieveRecordAsync(tableName, recordId, options);
}
//# sourceMappingURL=retrieveRecord.js.map
@@ -0,0 +1 @@
{"version":3,"file":"retrieveRecord.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/retrieveRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,eAAgC,EAChC,SAAiB,EACjB,QAAgB,EAChB,OAA2B;IAE3B,OAAO,MAAM,CACX,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAC3C,CAAC,IAAI,CAAC,mBAAmB,CAAU,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,15 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IOperationResult } from '../types';
/**
* Updates an existing record in the specified table.
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to create the record in.
* @param recordId - The ID of the record to update.
* @param changes - The changes to apply to the record.
* @returns - A promise that resolves to the created record.
* @private
*/
export declare function updateRecordAsync<TInput, TResult>(dataSourcesInfo: DataSourcesInfo, tableName: string, recordId: string, changes: TInput): Promise<IOperationResult<TResult>>;
//# sourceMappingURL=updateRecord.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"updateRecord.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/updateRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElE;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EACrD,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAIpC"}
@@ -0,0 +1,17 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getPowerSdkInstance } from '../runtime/getRuntimeContext';
/**
* Updates an existing record in the specified table.
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to create the record in.
* @param recordId - The ID of the record to update.
* @param changes - The changes to apply to the record.
* @returns - A promise that resolves to the created record.
* @private
*/
export async function updateRecordAsync(dataSourcesInfo, tableName, recordId, changes) {
return await (await getPowerSdkInstance(dataSourcesInfo)).Data.updateRecordAsync(tableName, recordId, changes);
}
//# sourceMappingURL=updateRecord.js.map
@@ -0,0 +1 @@
{"version":3,"file":"updateRecord.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/updateRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,eAAgC,EAChC,SAAiB,EACjB,QAAgB,EAChB,OAAe;IAEf,OAAO,MAAM,CACX,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAC3C,CAAC,IAAI,CAAC,iBAAiB,CAAkB,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,21 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IOperationResult } from '../types';
/**
* Uploads to an existing record in the specified table with binary data (maximum size 128 MB).
* Content type header must be application/octet-stream, and the binary data should be provided directly (e.g., as a Uint8Array or other binary type). This API is intended for use with file columns in Dataverse, and will not work with other column types.
* For file columns in Dataverse, the recordId is the ID of the Dataverse record, and the tableName is the logical name of the Dataverse table.
* See documentation for more details:
* https://learn.microsoft.com/en-us/power-apps/developer/data-platform/file-column-data?source=recommendations&tabs=webapi#upload-a-file-in-a-single-request-using-web-api
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to upload the record in.
* @param recordId - The ID of the record to upload.
* @param columnName - The name of the file column to upload to.
* @param fileName - The name of the file to upload (used for Dataverse file columns).
* @param data - The body of the request which should have the binary contents of the file to upload.
* @returns - A promise that resolves to an operation result indicating success or failure of the upload.
* @private
*/
export declare function uploadFileToRecord<TInput extends string | Uint8Array | ArrayBuffer | Blob>(dataSourcesInfo: DataSourcesInfo, tableName: string, recordId: string, columnName: string, fileName: string, data: TInput): Promise<IOperationResult<void>>;
//# sourceMappingURL=uploadRecord.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"uploadRecord.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/uploadRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,SAAS,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,EAC9F,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAIjC"}
@@ -0,0 +1,23 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getPowerSdkInstance } from '../runtime/getRuntimeContext';
/**
* Uploads to an existing record in the specified table with binary data (maximum size 128 MB).
* Content type header must be application/octet-stream, and the binary data should be provided directly (e.g., as a Uint8Array or other binary type). This API is intended for use with file columns in Dataverse, and will not work with other column types.
* For file columns in Dataverse, the recordId is the ID of the Dataverse record, and the tableName is the logical name of the Dataverse table.
* See documentation for more details:
* https://learn.microsoft.com/en-us/power-apps/developer/data-platform/file-column-data?source=recommendations&tabs=webapi#upload-a-file-in-a-single-request-using-web-api
* @param dataSourcesInfo - The data sources information.
* @param tableName - The name of the table to upload the record in.
* @param recordId - The ID of the record to upload.
* @param columnName - The name of the file column to upload to.
* @param fileName - The name of the file to upload (used for Dataverse file columns).
* @param data - The body of the request which should have the binary contents of the file to upload.
* @returns - A promise that resolves to an operation result indicating success or failure of the upload.
* @private
*/
export async function uploadFileToRecord(dataSourcesInfo, tableName, recordId, columnName, fileName, data) {
return await (await getPowerSdkInstance(dataSourcesInfo)).Data.uploadFileToRecord(tableName, recordId, columnName, fileName, data);
}
//# sourceMappingURL=uploadRecord.js.map
@@ -0,0 +1 @@
{"version":3,"file":"uploadRecord.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/api/uploadRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,eAAgC,EAChC,SAAiB,EACjB,QAAgB,EAChB,UAAkB,EAClB,QAAgB,EAChB,IAAY;IAEZ,OAAO,MAAM,CACX,MAAM,mBAAmB,CAAC,eAAe,CAAC,CAC3C,CAAC,IAAI,CAAC,kBAAkB,CAAS,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;AACrF,CAAC"}
@@ -0,0 +1,237 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { DataSourcesInfo, IOperationResult } from '../types';
import type { DataverseMetadataRequest } from '../types/dataverseMetadata';
/**
* Base interface for operation context
* @private
*/
export interface IOperationContext {
isExecuteAsync?: boolean;
clientConfig?: IClientConfig;
operationName?: string;
correlationId?: string;
timestamp?: Date;
responseInfo?: Record<string, IApiResponseInfo>;
batchId?: string;
datasetName?: string;
isDataVerseOperation?: boolean;
fileName?: string;
skipBatch?: boolean;
}
/**
* Interface for api response information
* @private
*/
export interface IApiResponseInfo {
type?: string | null;
format?: string | null;
}
/**
* Base interface for client configuration
* @private
*/
export interface IClientConfig {
baseUrl?: string;
timeout?: number;
retryAttempts?: number;
}
/**
* Interface for HTTP request configuration
* @private
*/
export interface IHttpRequestConfig {
url: string;
method: HttpMethod;
apiId: string;
tableName: string;
headers?: {
[key: string]: string;
};
body?: string | Uint8Array | ArrayBuffer | Blob;
}
/**
* Interface for HTTP request headers
* @private
*/
export interface IHttpHeaders {
Accept: string;
'x-ms-protocol-semantics': string;
ServiceNamespace: string;
Authorization: string;
'x-ms-pa-client-custom-headers-options': string;
'x-ms-enable-selects': string;
'x-ms-pa-client-telemetry-options': string;
'x-ms-pa-client-telemetry-additional-data': string;
BatchInfo?: string;
}
/**
* HTTP methods supported by the client
* @private
*/
export declare enum HttpMethod {
GET = "GET",
POST = "POST",
PUT = "PUT",
DELETE = "DELETE",
PATCH = "PATCH"
}
/**
* Interface for OData response format
* @template T The type of data in the response
* @private
*/
export interface ODataResponse<T> {
'@odata.context'?: string;
'@odata.count'?: number;
value: T;
}
/**
* Interface for metadata operation configuration
* @private
*/
export interface IMetadataOperationConfig {
service: string;
action: string;
params?: unknown[];
}
/**
* Interface for operation execution result
* @private
*/
export type OperationExecutionResponse = [Record<string, object>, ArrayBuffer];
/**
* Type alias for possible response data formats
* @private
*/
export type ResponseData = Record<string, unknown> | ArrayBuffer;
/**
* Type alias for request body in data operations
* @private
*/
export type RequestBody = Record<string, unknown>;
/**
* Interface for connection API details
* @private
*/
export interface IConnectionApi {
path: string;
method?: string;
parameters?: string[];
}
/**
* Interface for connection reference details
* @private
*/
export interface IConnectionReference {
apiId?: string;
connectionName?: string;
datasetName?: string;
datasetNameOverride?: string;
tableNameOverride?: string;
isShareableConnection?: string;
runtimePolicyName?: string;
runtimeUrl?: string;
}
/**
* Interface for table schema information
* @private
*/
export interface ITableSchema {
name: string;
displayName?: string;
fields: Record<string, IFieldSchema>;
}
/**
* Interface for field schema information
* @private
*/
export interface IFieldSchema {
name: string;
type: string;
required?: boolean;
maxLength?: number;
defaultValue?: unknown;
}
/**
* Dataverse custom action/function invocation request
* @private
*/
export type DataverseCustomApiRequest = {
action: 'customapi';
parameters: {
/** Schema name of the action or function to invoke */
operationName: string;
/** Logical name of the data source (used to resolve the environment) */
tableName: string;
/** Input parameters passed as the request body */
body?: unknown;
};
};
/**
* Interface for Dataverse-specific requests
* @private
*/
export type IDataverseRequest = DataverseMetadataRequest | DataverseCustomApiRequest;
/**
* Supported data source types in the PowerDataRuntime
* @private
*/
export declare enum DataSources {
/** Dataverse data source */
Dataverse = "Dataverse",
/** Generic connector data source */
Connector = "Connector"
}
/**
* Interface for metadata operations
* @private
*/
export interface IMetadataOperations {
/**
* Gets available connections
*/
getConnections(context?: IOperationContext): Promise<IOperationResult<IConnectionReference[]>>;
/**
* Gets APIs available for a connection
*/
getConnectionApis(connectionId: string, context?: IOperationContext): Promise<IOperationResult<IConnectionApi[]>>;
}
/**
* Interface for runtime client provider
* @private
*/
export interface IRuntimeClientProvider {
getDataClientAsync(config?: IClientConfig): Promise<IRuntimeDataClient>;
getMetadataClientAsync(config?: IClientConfig): Promise<IRuntimeMetadataClient>;
}
/**
* Interface for runtime data client
* @private
*/
export interface IRuntimeDataClient {
createDataAsync<TRequest, TResponse>(url: string, connectionApi: string, serviceNamespace: string, body: TRequest, context?: IOperationContext): Promise<IOperationResult<TResponse>>;
updateDataAsync<TRequest, TResponse>(url: string, connectionApi: string, serviceNamespace: string, body: TRequest, context?: IOperationContext): Promise<IOperationResult<TResponse>>;
uploadDataAsync<TRequest extends string | Uint8Array | ArrayBuffer | Blob>(url: string, connectionApi: string, serviceNamespace: string, body: TRequest, context?: IOperationContext): Promise<IOperationResult<void>>;
deleteDataAsync(url: string, connectionApi: string, serviceNamespace: string, context?: IOperationContext): Promise<IOperationResult<void>>;
retrieveDataAsync<TResponse>(url: string, connectionApi: string, serviceNamespace: string, method: HttpMethod, headers?: {
[key: string]: string;
}, body?: unknown, context?: IOperationContext): Promise<IOperationResult<TResponse>>;
}
/**
* Interface for runtime metadata client
* @private
*/
export interface IRuntimeMetadataClient {
getAppConnectionConfigsAsync(context?: IOperationContext): Promise<IOperationResult<IConnectionReference>>;
getAppDataSourceConfigsAsync(context?: IOperationContext): Promise<IOperationResult<IConnectionApi>>;
}
/**
* Interface for PowerDataSourcesInfoProvider
* @private
*/
export interface IPowerDataSourcesInfoProvider {
getDataSourcesInfo(): Promise<DataSourcesInfo>;
}
//# sourceMappingURL=types.d.ts.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,27 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
/**
* HTTP methods supported by the client
* @private
*/
export var HttpMethod;
(function (HttpMethod) {
HttpMethod["GET"] = "GET";
HttpMethod["POST"] = "POST";
HttpMethod["PUT"] = "PUT";
HttpMethod["DELETE"] = "DELETE";
HttpMethod["PATCH"] = "PATCH";
})(HttpMethod || (HttpMethod = {}));
/**
* Supported data source types in the PowerDataRuntime
* @private
*/
export var DataSources;
(function (DataSources) {
/** Dataverse data source */
DataSources["Dataverse"] = "Dataverse";
/** Generic connector data source */
DataSources["Connector"] = "Connector";
})(DataSources || (DataSources = {}));
//# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/common/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmFH;;;GAGG;AACH,MAAM,CAAN,IAAY,UAMX;AAND,WAAY,UAAU;IACpB,yBAAW,CAAA;IACX,2BAAa,CAAA;IACb,yBAAW,CAAA;IACX,+BAAiB,CAAA;IACjB,6BAAe,CAAA;AACjB,CAAC,EANW,UAAU,KAAV,UAAU,QAMrB;AAyHD;;;GAGG;AACH,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,4BAA4B;IAC5B,sCAAuB,CAAA;IACvB,oCAAoC;IACpC,sCAAuB,CAAA;AACzB,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB"}
@@ -0,0 +1,21 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
export declare function arrayBufferToBase64(buffer: ArrayBuffer): string;
export declare function convertArrayBufferToString(buf: ArrayBuffer): string;
/**
* Strict encode: encodeURIComponent, but also encode ( and )
* @private
*/
export declare function strictEncode(str: string): string;
/**
* Extracts the Dataverse base URL and encoded path from a full Dataverse API URL.
* @param url - The full Dataverse API URL (should contain /api/data/v9.x/)
* @returns An object with baseUrl (up to /api/data/v9.x) and encodedPath (strict encoded path after /api/data/v9.x/)
* @private
*/
export declare function extractDataverseUrlParts(url: string): {
baseUrl: string;
encodedPath: string;
};
//# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/common/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAE/D;AAQD,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAWnE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAO9F"}
@@ -0,0 +1,51 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
/*
* Converts an ArrayBuffer to a Base64 string
* @param buffer - The ArrayBuffer to convert
* @return The Base64 encoded string
* @private
*/
export function arrayBufferToBase64(buffer) {
return window.btoa(convertArrayBufferToString(buffer));
}
/*
* Converts an ArrayBuffer to a string
* @param buf - The ArrayBuffer to convert
* @return The converted string
* @private
*/
export function convertArrayBufferToString(buf) {
// String.fromCharCode range max is 65535
if (buf.byteLength <= 65535) {
return String.fromCharCode(...new Uint8Array(buf));
}
let binary = '';
for (let i = 0, bytes = new Uint8Array(buf); i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
return binary;
}
/**
* Strict encode: encodeURIComponent, but also encode ( and )
* @private
*/
export function strictEncode(str) {
return encodeURIComponent(str).replace(/\(/g, '%28').replace(/\)/g, '%29');
}
/**
* Extracts the Dataverse base URL and encoded path from a full Dataverse API URL.
* @param url - The full Dataverse API URL (should contain /api/data/v9.x/)
* @returns An object with baseUrl (up to /api/data/v9.x) and encodedPath (strict encoded path after /api/data/v9.x/)
* @private
*/
export function extractDataverseUrlParts(url) {
const baseUrlMatch = url.match(/^(https?:\/\/[^/]+\/api\/data\/v[\d.]+)/);
const baseUrl = baseUrlMatch ? baseUrlMatch[1] : '';
// Extract and encode the path after /api/data/v9.x/
const pathMatch = url.match(/\/api\/data\/v[\d.]+\/(.+)$/);
const encodedPath = pathMatch ? strictEncode(pathMatch[1]) : '';
return { baseUrl, encodedPath };
}
//# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/common/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAmB;IACrD,OAAO,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAAC,GAAgB;IACzD,yCAAyC;IACzC,IAAI,GAAG,CAAC,UAAU,IAAI,KAAK,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACvE,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAClD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,oDAAoD;IACpD,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AAClC,CAAC"}
@@ -0,0 +1,127 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { RuntimeDataSourceService } from '../metadata/runtimeDataSourceService';
import type { IDataOperation, IDataOperationOrchestrator, IOperationOptions, IOperationResult } from '../types';
import type { ConnectorDataOperationExecutor } from './executors/connectorDataOperationExecutor';
import type { DataverseDataOperationExecutor } from './executors/dataverseDataOperationExecutor';
/**
* RuntimeDataOperations provides a unified interface for performing data operations
* across different data sources.
* @private
*/
export declare class DefaultDataOperationOrchestrator implements IDataOperationOrchestrator {
private readonly _dataverseOperation;
private readonly _connectorOperation;
private readonly _connectionsService;
constructor(_dataverseOperation: DataverseDataOperationExecutor, _connectorOperation: ConnectorDataOperationExecutor, _connectionsService: RuntimeDataSourceService);
/**
* Creates a new record in the specified data source.
* @param tableName - The name of the table.
* @param data - The record data to create.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
createRecordAsync<TRequest, TResponse>(tableName: string, data: TRequest): Promise<IOperationResult<TResponse>>;
/**
* Updates an existing record in the specified data source.
* @param tableName - The name of the table.
* @param id - The ID of the record to update.
* @param data - The updated record data.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
updateRecordAsync<TRequest, TResponse>(tableName: string, id: string, data: TRequest): Promise<IOperationResult<TResponse>>;
/**
* Uploads data for an existing record in the specified data source.
* @param tableName - The name of the table.
* @param id - The ID of the record to upload data for.
* @param columnName - The name of the file column to upload to.
* @param fileName - The name of the file to upload (used for Dataverse file columns).
* @param data - The data to upload.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
uploadFileToRecord<TRequest extends string | Uint8Array | ArrayBuffer | Blob>(tableName: string, id: string, columnName: string, fileName: string, data: TRequest): Promise<IOperationResult<void>>;
/**
* Downloads binary data from a file column in the specified data source.
* @param tableName - The name of the table.
* @param id - The ID of the record to download from.
* @param columnName - The name of the file column to download from.
* @returns A promise that resolves to the operation result with file contents as binary data (Uint8Array).
* @throws DataOperationError if the operation fails.
*/
downloadFileFromRecord(tableName: string, id: string, columnName: string): Promise<IOperationResult<Uint8Array>>;
/**
* Downloads binary image data from an image column in the specified data source.
* Only applicable to Dataverse data sources.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The ID of the record containing the image.
* @param columnName - The name of the image column to download from.
* @param fullSize - When true, requests the full-size image (`?size=full`). Defaults to false.
* @returns A promise that resolves to the operation result with image contents as binary data (Uint8Array).
*/
downloadImageFromRecord(tableName: string, recordId: string, columnName: string, fullSize?: boolean): Promise<IOperationResult<Uint8Array>>;
/**
* Deletes the file or image data stored in a file/image column of an existing record.
* Only applicable to Dataverse data sources.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The ID of the record containing the file or image.
* @param columnName - The name of the file or image column whose data should be deleted.
* @returns A promise that resolves to the operation result.
*/
deleteFileOrImageFromRecord(tableName: string, recordId: string, columnName: string): Promise<IOperationResult<void>>;
/**
* Deletes a record from the specified data source.
* @param tableName - The name of the table.
* @param id - The ID of the record to delete.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
deleteRecordAsync(tableName: string, id: string): Promise<IOperationResult<void>>;
/**
* Retrieves a record from the specified data source.
* @param tableName - The name of the table.
* @param id - The ID of the record to retrieve.
* @param options - Optional operation options.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
retrieveRecordAsync<TResponse>(tableName: string, id: string, options?: IOperationOptions): Promise<IOperationResult<TResponse>>;
/**
* Retrieves multiple records from the specified data source.
* @param tableName - The name of the table.
* @param options - Optional operation options.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
retrieveMultipleRecordsAsync<TResponse>(tableName: string, options?: IOperationOptions): Promise<IOperationResult<TResponse[]>>;
/**
* Executes a data operation on the specified data source.
* @param operation - The operation to execute
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
executeAsync<TRequest, TResponse>(operation: IDataOperation<TRequest>): Promise<IOperationResult<TResponse>>;
/**
* Retrieves the appropriate executor based on the data source.
* @param dataSource - The data source to retrieve the executor for.
* @returns The corresponding executor instance.
* @throws DataOperationError if the data source is invalid.
* // TODO: Add Dataverse support
*/
private _getExecutor;
/**
* Validates the input parameters for data operations.
* @param params - The parameters to validate.
* @throws DataOperationError if validation fails.
*/
private _validateParams;
/**
* Validates the operation options.
* @param options - The operation options to validate.
* @throws Error if validation fails.
*/
private _validateOptions;
}
//# sourceMappingURL=defaultOperationOrchestrator.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"defaultOperationOrchestrator.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/data/defaultOperationOrchestrator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,KAAK,EACV,cAAc,EAEd,0BAA0B,EAC1B,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,4CAA4C,CAAC;AACjG,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,4CAA4C,CAAC;AAEjG;;;;GAIG;AACH,qBAAa,gCAAiC,YAAW,0BAA0B;IAI/E,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAFnB,mBAAmB,EAAE,8BAA8B,EACnD,mBAAmB,EAAE,8BAA8B,EACnD,mBAAmB,EAAE,wBAAwB;IAGhE;;;;;;OAMG;IACU,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAChD,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAUvC;;;;;;;OAOG;IACU,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAChD,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAUvC;;;;;;;;;OASG;IACU,kBAAkB,CAAC,QAAQ,SAAS,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,EACvF,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAUlC;;;;;;;OAOG;IACU,sBAAsB,CACjC,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAUxC;;;;;;;;OAQG;IACU,uBAAuB,CAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAUxC;;;;;;;OAOG;IACU,2BAA2B,CACtC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAUlC;;;;;;OAMG;IACU,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAU9F;;;;;;;OAOG;IACU,mBAAmB,CAAC,SAAS,EACxC,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAWvC;;;;;;OAMG;IACU,4BAA4B,CAAC,SAAS,EACjD,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC;IAWzC;;;;;OAKG;IACU,YAAY,CAAC,QAAQ,EAAE,SAAS,EAC3C,SAAS,EAAE,cAAc,CAAC,QAAQ,CAAC,GAClC,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAavC;;;;;;OAMG;YACW,YAAY;IAoB1B;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAUvB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;CAyEzB"}
@@ -0,0 +1,291 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { getDataOperationExecutor } from '../../../../data/powerAppsData';
import { DataSources } from '../common/types';
import { createErrorResponse, DataOperationErrorMessages } from '../error/error';
/**
* RuntimeDataOperations provides a unified interface for performing data operations
* across different data sources.
* @private
*/
export class DefaultDataOperationOrchestrator {
_dataverseOperation;
_connectorOperation;
_connectionsService;
// Static identifiers for services and actions
// Used to identify specific services and actions within the PowerApps environment
constructor(_dataverseOperation, _connectorOperation, _connectionsService) {
this._dataverseOperation = _dataverseOperation;
this._connectorOperation = _connectorOperation;
this._connectionsService = _connectionsService;
}
/**
* Creates a new record in the specified data source.
* @param tableName - The name of the table.
* @param data - The record data to create.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
async createRecordAsync(tableName, data) {
try {
this._validateParams({ tableName, data });
const executor = await this._getExecutor(tableName);
return await executor.createRecordAsync(tableName, data);
}
catch (error) {
return createErrorResponse(error, 'Create record operation failed');
}
}
/**
* Updates an existing record in the specified data source.
* @param tableName - The name of the table.
* @param id - The ID of the record to update.
* @param data - The updated record data.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
async updateRecordAsync(tableName, id, data) {
try {
this._validateParams({ tableName, id, data });
const executor = await this._getExecutor(tableName);
return await executor.updateRecordAsync(tableName, id, data);
}
catch (error) {
return createErrorResponse(error, 'Update record operation failed');
}
}
/**
* Uploads data for an existing record in the specified data source.
* @param tableName - The name of the table.
* @param id - The ID of the record to upload data for.
* @param columnName - The name of the file column to upload to.
* @param fileName - The name of the file to upload (used for Dataverse file columns).
* @param data - The data to upload.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
async uploadFileToRecord(tableName, id, columnName, fileName, data) {
try {
this._validateParams({ tableName, id, columnName, fileName, data });
const executor = await this._getExecutor(tableName);
return await executor.uploadFileToRecord(tableName, id, columnName, fileName, data);
}
catch (error) {
return createErrorResponse(error, 'Upload record operation failed');
}
}
/**
* Downloads binary data from a file column in the specified data source.
* @param tableName - The name of the table.
* @param id - The ID of the record to download from.
* @param columnName - The name of the file column to download from.
* @returns A promise that resolves to the operation result with file contents as binary data (Uint8Array).
* @throws DataOperationError if the operation fails.
*/
async downloadFileFromRecord(tableName, id, columnName) {
try {
this._validateParams({ tableName, id, columnName });
const executor = await this._getExecutor(tableName);
return await executor.downloadFileFromRecord(tableName, id, columnName);
}
catch (error) {
return createErrorResponse(error, 'Download record operation failed');
}
}
/**
* Downloads binary image data from an image column in the specified data source.
* Only applicable to Dataverse data sources.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The ID of the record containing the image.
* @param columnName - The name of the image column to download from.
* @param fullSize - When true, requests the full-size image (`?size=full`). Defaults to false.
* @returns A promise that resolves to the operation result with image contents as binary data (Uint8Array).
*/
async downloadImageFromRecord(tableName, recordId, columnName, fullSize) {
try {
this._validateParams({ tableName, recordId, columnName });
const executor = await this._getExecutor(tableName);
return await executor.downloadImageFromRecord(tableName, recordId, columnName, fullSize);
}
catch (error) {
return createErrorResponse(error, 'Download image operation failed');
}
}
/**
* Deletes the file or image data stored in a file/image column of an existing record.
* Only applicable to Dataverse data sources.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The ID of the record containing the file or image.
* @param columnName - The name of the file or image column whose data should be deleted.
* @returns A promise that resolves to the operation result.
*/
async deleteFileOrImageFromRecord(tableName, recordId, columnName) {
try {
this._validateParams({ tableName, recordId, columnName });
const executor = await this._getExecutor(tableName);
return await executor.deleteFileOrImageFromRecord(tableName, recordId, columnName);
}
catch (error) {
return createErrorResponse(error, 'Delete file or image operation failed');
}
}
/**
* Deletes a record from the specified data source.
* @param tableName - The name of the table.
* @param id - The ID of the record to delete.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
async deleteRecordAsync(tableName, id) {
try {
this._validateParams({ tableName, id });
const executor = await this._getExecutor(tableName);
return await executor.deleteRecordAsync(tableName, id);
}
catch (error) {
return createErrorResponse(error, 'Delete record operation failed');
}
}
/**
* Retrieves a record from the specified data source.
* @param tableName - The name of the table.
* @param id - The ID of the record to retrieve.
* @param options - Optional operation options.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
async retrieveRecordAsync(tableName, id, options) {
try {
this._validateParams({ tableName, id });
const executor = await this._getExecutor(tableName);
this._validateOptions(options);
return await executor.retrieveRecordAsync(tableName, id, options);
}
catch (error) {
return createErrorResponse(error, 'Retrieve record operation failed');
}
}
/**
* Retrieves multiple records from the specified data source.
* @param tableName - The name of the table.
* @param options - Optional operation options.
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
async retrieveMultipleRecordsAsync(tableName, options) {
try {
this._validateParams({ tableName });
const executor = await this._getExecutor(tableName);
this._validateOptions(options);
return await executor.retrieveMultipleRecordsAsync(tableName, options);
}
catch (error) {
return createErrorResponse(error, 'Retrieve multiple records operation failed');
}
}
/**
* Executes a data operation on the specified data source.
* @param operation - The operation to execute
* @returns A promise that resolves to the operation result.
* @throws DataOperationError if the operation fails.
*/
async executeAsync(operation) {
try {
this._validateParams({ operation });
const executor = await this._getExecutor('', operation.connectorOperation ? DataSources.Connector : DataSources.Dataverse);
return await executor.executeAsync(operation);
}
catch (error) {
return createErrorResponse(error, 'Execute operation failed');
}
}
/**
* Retrieves the appropriate executor based on the data source.
* @param dataSource - The data source to retrieve the executor for.
* @returns The corresponding executor instance.
* @throws DataOperationError if the data source is invalid.
* // TODO: Add Dataverse support
*/
async _getExecutor(tableName, dataSource) {
const dataOperationExecutorOverride = getDataOperationExecutor();
if (dataOperationExecutorOverride) {
return dataOperationExecutorOverride;
}
const dataSourceType = dataSource || (await this._connectionsService.getDataSource(tableName)).dataSourceType;
switch (dataSourceType) {
case DataSources.Dataverse:
return this._dataverseOperation;
case DataSources.Connector:
return this._connectorOperation;
default:
return this._connectorOperation;
}
}
/**
* Validates the input parameters for data operations.
* @param params - The parameters to validate.
* @throws DataOperationError if validation fails.
*/
_validateParams(params) {
for (const [key, value] of Object.entries(params)) {
if (!value) {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: ${key} is required`);
}
}
}
/**
* Validates the operation options.
* @param options - The operation options to validate.
* @throws Error if validation fails.
*/
_validateOptions(options) {
if (!options) {
return;
}
// maxPageSize must be a number
if (options.maxPageSize && typeof options.maxPageSize !== 'number') {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: maxPageSize must be a number`);
}
/*
select
- must be an array of string
- no empty strings allowed
- no null or undefined values allowed
*/
if (options.select) {
if (!Array.isArray(options.select)) {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: select must be an array of strings`);
}
if (options.select.some((s) => typeof s !== 'string' || s.trim() === '')) {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: select must contain only non-empty strings`);
}
}
// filter must be a string
if (options.filter && typeof options.filter !== 'string') {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: filter must be a string`);
}
// orderBy must be an array of strings
if (options.orderBy) {
if (!Array.isArray(options.orderBy)) {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: orderBy must be an array of strings`);
}
if (options.orderBy.some((s) => typeof s !== 'string' || s.trim() === '')) {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: orderBy must contain only non-empty strings`);
}
}
// top must be a number
if (options.top && typeof options.top !== 'number') {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: top must be a number`);
}
// skip must be a number
if (options.skip && typeof options.skip !== 'number') {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: skip must be a number`);
}
// count must be a boolean
if (options.count && typeof options.count !== 'boolean') {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: count must be a boolean`);
}
}
}
//# sourceMappingURL=defaultOperationOrchestrator.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,194 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { IConnectionReference, IRuntimeClientProvider } from '../../common/types';
import type { RuntimeDataSourceService } from '../../metadata/runtimeDataSourceService';
import type { IDataOperation, IDataOperationExecutor, IOperationOptions, IOperationResult } from '../../types';
/**
* Type for connection references mapping
* @private
*/
export type ConnectionReferences = Record<string, IConnectionReference>;
/**
* Interface for connector operation configuration
* @private
*/
export interface IConnectorOperationConfig {
tableName: string;
apiId: string;
runtimeUrl: string;
connectionName: string;
datasetName?: string;
tableId: string;
version?: string;
datasetNameOverride?: string;
}
/**
* ConnectorDataOperation provides functionality for performing CRUD operations
* against connector data sources using the Runtime Data Client.
* @private
*/
export declare class ConnectorDataOperationExecutor implements IDataOperationExecutor {
private readonly _clientProvider;
private readonly _connectionsService;
private _databaseReferences;
private _connectionReferences;
constructor(clientProvider: IRuntimeClientProvider, connectionsService: RuntimeDataSourceService);
/**
* Creates a new record in the specified table
*/
createRecordAsync<TRequest, TResponse>(tableName: string, data: TRequest): Promise<IOperationResult<TResponse>>;
/**
* Updates an existing record in the specified table
*/
updateRecordAsync<TRequest, TResponse>(tableName: string, id: string, data: TRequest): Promise<IOperationResult<TResponse>>;
/**
* Uploads binary data to a file column in the specified table
*/
uploadFileToRecord<TRequest extends string | Uint8Array | ArrayBuffer | Blob>(tableName: string, id: string, columnName: string, fileName: string, data: TRequest): Promise<IOperationResult<void>>;
/**
* Downloads binary data from a file column — not supported for connector data sources
*/
downloadFileFromRecord(tableName: string, id: string, columnName: string): Promise<IOperationResult<Uint8Array>>;
/**
* Deletes a file or image from a column — not supported for connector data sources
*/
deleteFileOrImageFromRecord(tableName: string, id: string, columnName: string): Promise<IOperationResult<void>>;
/**
* Downloads an image from an image column — not supported for connector data sources
*/
downloadImageFromRecord(tableName: string, id: string, columnName: string, _fullSize?: boolean): Promise<IOperationResult<Uint8Array>>;
/**
* Deletes a record from the specified table
*/
deleteRecordAsync(tableName: string, id: string): Promise<IOperationResult<void>>;
/**
* Retrieves a single record from the specified table
*/
retrieveRecordAsync<TResponse>(tableName: string, id: string, options?: IOperationOptions): Promise<IOperationResult<TResponse>>;
/**
* Retrieves multiple records from the specified table
*/
retrieveMultipleRecordsAsync<TResponse>(tableName: string, options?: IOperationOptions): Promise<IOperationResult<TResponse[]>>;
/**
* Executes a custom operation on the data source
*/
executeAsync<TRequest, TResponse>(operation: IDataOperation<TRequest>): Promise<IOperationResult<TResponse>>;
/**
* Determines the appropriate HTTP method for a request
* @param requestUrl - The URL for the request
* @param dataSourceInfo - The data source information
* @param operation - The operation name
* @returns The HTTP method to use
*/
private _getHttpMethod;
/**
* Builds the operation body parameters
*/
private _buildOperationBody;
/**
* Builds operation body parameters from the operation and data source info
*/
private _buildOperationBodyParam;
/**
* Builds the operation header for a given data operation if required.
*
* @template TRequest - The type of the request payload for the data operation.
* @param dataOperationRequest - The data operation containing details about the connector operation.
* @param tableName - The name of the table associated with the data operation.
* @returns A promise that resolves to the operation header as a string if a header parameter is required,
* or `undefined` if no header parameter is needed.
*/
private _buildOperationHeader;
/**
* Builds the operation header parameters as a JSON string for a given data operation.
*
* @template TRequest - The type of the request object for the data operation.
* @param dataOperationRequest - The data operation containing connector operation details and parameters.
* @param tableName - The name of the table associated with the data operation.
* @returns A promise that resolves to a JSON string representing the header parameters,
* or `undefined` if no `header` parameters are available.
*/
private _buildOperationHeaderParam;
/**
* Constructs the request URL for table operations
* @param tableName - The name of the table
* @param connectionReference - The connection reference
* @param options - Optional URL parameters
* @param encodeOptions - Whether to encode the options
* @returns The constructed URL
*/
private _buildTableUrl;
/**
* Builds the operation URL
*/
private _buildOperationUrl;
/**
* Gets the connection references
*/
private _getConnectionReferencesAsync;
/**
* Gets the database references
*/
private _getDatabaseReferencesAsync;
/**
* Gets the metadata client instance
*/
private _getMetadataClient;
/**
* Gets the connection reference for a table
*/
private _getConnectionReference;
/**
* Gets both the data client and connection reference
*/
private _getClientsAndConnection;
/**
* Builds the URL for shared SQL operations
*/
private _buildSharedSqlOperationUrl;
/**
* Builds the URL for standard operations
* Assumptions / Invariants:
* - The connector always defines a required path parameter for the connection id named 'connectionId'.
* - When a dataset is applicable, the parameter name is 'dataset'.
* - When a table is applicable, the parameter name is 'tableName'.
* - A lone string parameter maps to the first remaining (non-synthetic) required API parameter.
* - Array parameters map positionally to the remaining API parameters after filtering.
* - Object parameters map by (case-insensitive, hyphen/underscore agnostic) key.
* @param operation - The data operation containing connector operation details from runtime
* @param config - The connector operation configuration
* @param operationName - The name of the operation to be performed
* @param path - The path template for the operation
*/
private _buildStandardOperationUrl;
/**
* Normalizes the parameter name by replacing hyphens with underscores and performs case-insensitive matching
*/
private _getNormalizedParamValue;
/**
* Processes operation parameters into path and query parameters
* @param apiParams - The API parameter specifications from the data source info
* @param rawParamValues - The raw parameter values provided in the operation at runtime
* @param path - The initial path template
* @returns An object containing the processed path and query parameters
*/
private _processParameters;
/**
* Gets the operation configuration
*/
private _getOperationConfig;
/**
* Initializes the clients
*/
private _getReferences;
/**
* Validates constructor parameters
*/
private _validateConstructorParams;
/**
* Constructs the final URL
*/
private _constructUrl;
}
//# sourceMappingURL=connectorDataOperationExecutor.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"connectorDataOperationExecutor.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/data/core/data/executors/connectorDataOperationExecutor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,576 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { HttpMethod } from '../../common/types';
import { ConnectorOperationName } from '../../error/constants';
import { createErrorResponse, DataOperationErrorMessages, ErrorCodes, PowerDataRuntimeError, } from '../../error/error';
import { convertOptionsToQueryString } from './shared/stringQueryOptions';
// =====================================
// Main Class Implementation
// =====================================
/**
* ConnectorDataOperation provides functionality for performing CRUD operations
* against connector data sources using the Runtime Data Client.
* @private
*/
export class ConnectorDataOperationExecutor {
// =====================================
// Private Members
// =====================================
_clientProvider;
_connectionsService;
_databaseReferences;
_connectionReferences;
// =====================================
// Constructor
// =====================================
constructor(clientProvider, connectionsService) {
this._validateConstructorParams(clientProvider, connectionsService);
this._clientProvider = clientProvider;
this._connectionsService = connectionsService;
}
// =====================================
// Public Methods
// =====================================
/**
* Creates a new record in the specified table
*/
async createRecordAsync(tableName, data) {
try {
const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
const requestUrl = await this._buildTableUrl(tableName, connectionReference);
const result = await dataClient.createDataAsync(requestUrl, connectionReference.apiId, tableName, data, { operationName: ConnectorOperationName.CreateRecord });
return result;
}
catch (error) {
return createErrorResponse(error, DataOperationErrorMessages.CreateFailed);
}
}
/**
* Updates an existing record in the specified table
*/
async updateRecordAsync(tableName, id, data) {
try {
const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
const requestUrl = await this._buildTableUrl(tableName, connectionReference, `/${id}`);
const result = await dataClient.updateDataAsync(requestUrl, connectionReference.apiId, tableName, data, { operationName: ConnectorOperationName.UpdateRecord });
return result;
}
catch (error) {
return createErrorResponse(error, DataOperationErrorMessages.UpdateFailed);
}
}
/**
* Uploads binary data to a file column in the specified table
*/
async uploadFileToRecord(tableName, id, columnName, fileName, data) {
return createErrorResponse(new Error(`uploadFileToRecord is not implemented for connector data sources, ${tableName}, ${columnName}, ${fileName}, ${id}, ${JSON.stringify(data)}`), DataOperationErrorMessages.UploadFailed);
}
/**
* Downloads binary data from a file column — not supported for connector data sources
*/
async downloadFileFromRecord(tableName, id, columnName) {
return createErrorResponse(new Error(`downloadFileFromRecord is not implemented for connector data sources, ${tableName}, ${columnName}, ${id}`), DataOperationErrorMessages.DownloadFailed);
}
/**
* Deletes a file or image from a column — not supported for connector data sources
*/
async deleteFileOrImageFromRecord(tableName, id, columnName) {
return createErrorResponse(new Error(`deleteFileOrImageFromRecord is not implemented for connector data sources, ${tableName}, ${id}, ${columnName}`), DataOperationErrorMessages.DeleteFileOrImageFailed);
}
/**
* Downloads an image from an image column — not supported for connector data sources
*/
async downloadImageFromRecord(tableName, id, columnName, _fullSize) {
return createErrorResponse(new Error(`downloadImageFromRecord is not implemented for connector data sources, ${tableName}, ${id}, ${columnName}`), DataOperationErrorMessages.DownloadFailed);
}
/**
* Deletes a record from the specified table
*/
async deleteRecordAsync(tableName, id) {
try {
const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
const requestUrl = await this._buildTableUrl(tableName, connectionReference, `/${id}`);
const result = await dataClient.deleteDataAsync(requestUrl, connectionReference.apiId, tableName, { operationName: ConnectorOperationName.DeleteRecord });
return result;
}
catch (error) {
return createErrorResponse(error, DataOperationErrorMessages.DeleteFailed);
}
}
/**
* Retrieves a single record from the specified table
*/
async retrieveRecordAsync(tableName, id, options) {
try {
const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
const requestUrl = await this._buildTableUrl(tableName, connectionReference, `/${id}${convertOptionsToQueryString(options)}`);
const result = await dataClient.retrieveDataAsync(requestUrl, connectionReference.apiId, tableName, HttpMethod.GET, undefined, // body
{ operationName: ConnectorOperationName.RetrieveRecord });
return result;
}
catch (error) {
return createErrorResponse(error, DataOperationErrorMessages.RetrieveFailed);
}
}
/**
* Retrieves multiple records from the specified table
*/
async retrieveMultipleRecordsAsync(tableName, options) {
try {
const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
const requestUrl = await this._buildTableUrl(tableName, connectionReference, convertOptionsToQueryString(options), false);
const result = await dataClient.retrieveDataAsync(requestUrl, connectionReference.apiId, tableName, HttpMethod.GET, undefined, // body
{ operationName: ConnectorOperationName.RetrieveMultipleRecords });
return result;
}
catch (error) {
return createErrorResponse(error, DataOperationErrorMessages.RetrieveMultipleFailed);
}
}
/**
* Executes a custom operation on the data source
*/
async executeAsync(operation) {
try {
if (!operation?.connectorOperation) {
throw new Error(`${DataOperationErrorMessages.InvalidRequest}: ${DataOperationErrorMessages.MissingConnectorOperation}`);
}
const tableName = operation.connectorOperation.tableName;
const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
const { dataClient, connectionReference } = await this._getClientsAndConnection(tableName);
const config = await this._getOperationConfig(operation, connectionReference, tableName);
const requestUrl = await this._buildOperationUrl(operation, config);
const bodyParam = await this._buildOperationBody(operation, tableName);
const headers = await this._buildOperationHeader(operation, tableName);
const httpMethod = this._getHttpMethod(requestUrl, dataSourceInfo, operation.connectorOperation.operationName);
const responseInfo = dataSourceInfo.apis[operation.connectorOperation.operationName]?.responseInfo;
const result = await dataClient.retrieveDataAsync(requestUrl, config.apiId, tableName, httpMethod, headers, bodyParam, {
isExecuteAsync: true,
// Use the connector operation name for telemetry, may be a better idea to use executeAsync
// here and just log the connector operation name in the custom dimensions leaving comment for PR.
operationName: `connectorDataOperation.${operation.connectorOperation.operationName}`,
responseInfo,
});
return result;
}
catch (error) {
return createErrorResponse(error, DataOperationErrorMessages.ExecuteFailed);
}
}
// =====================================
// Private Methods
// =====================================
/**
* Determines the appropriate HTTP method for a request
* @param requestUrl - The URL for the request
* @param dataSourceInfo - The data source information
* @param operation - The operation name
* @returns The HTTP method to use
*/
_getHttpMethod(requestUrl, dataSourceInfo, operation) {
// Check if it's a SQL stored procedure (which requires POST)
const isSqlStoredProcedure = requestUrl.indexOf('apim/sql') > -1;
// Default to POST for SQL procedures, GET otherwise
if (isSqlStoredProcedure) {
return HttpMethod.POST;
}
const method = dataSourceInfo.apis[operation]?.method;
if (method) {
return method;
}
return HttpMethod.GET;
}
/**
* Builds the operation body parameters
*/
async _buildOperationBody(operation, tableName) {
const operationName = operation?.connectorOperation?.operationName;
if (operationName) {
const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
const hasBodyParameter = dataSourceInfo?.apis?.[operationName]?.parameters?.some((param) => param.in === 'body');
if (hasBodyParameter) {
return await this._buildOperationBodyParam(operation, tableName);
}
}
return undefined;
}
/**
* Builds operation body parameters from the operation and data source info
*/
async _buildOperationBodyParam(operation, tableName) {
const operationName = operation.connectorOperation?.operationName;
if (!operationName) {
return '{}';
}
const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
const apiParams = dataSourceInfo?.apis?.[operationName]?.parameters || [];
const rawParams = operation.connectorOperation?.parameters || [];
if (typeof rawParams !== 'object' || rawParams === null) {
return '{}';
}
// OpenAPI 2.0 allows only one body parameter per operation. The parameter's "name" field
// is just a label for documentation - the HTTP body should always be the schema value directly.
// Power Platform connectors use various names for body params (e.g., "body", "parameters",
// "workItem", "request"). The Azure DevOps connector, for example, uses "workItem" for
// CreateWorkItem and "parameters" for HttpRequest. Regardless of the name, we extract the
// value and send it directly as the HTTP body without wrapping.
const bodyParam = apiParams.find((param) => param.in === 'body');
if (bodyParam) {
const value = rawParams[bodyParam.name];
if (value !== undefined && value !== null) {
// For binary parameters, the value is a base64 string that must be sent as-is.
// JSON.stringify would wrap it in quotes ("\"base64...\"") which corrupts uploads.
if (bodyParam.format === 'binary' && typeof value === 'string') {
return value;
}
return JSON.stringify(value);
}
}
return '{}';
}
/**
* Builds the operation header for a given data operation if required.
*
* @template TRequest - The type of the request payload for the data operation.
* @param dataOperationRequest - The data operation containing details about the connector operation.
* @param tableName - The name of the table associated with the data operation.
* @returns A promise that resolves to the operation header as a string if a header parameter is required,
* or `undefined` if no header parameter is needed.
*/
async _buildOperationHeader(dataOperationRequest, tableName) {
const operationName = dataOperationRequest.connectorOperation?.operationName;
if (operationName) {
const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
const hasHeaderParameter = dataSourceInfo?.apis?.[operationName]?.parameters?.some((param) => param.in === 'header');
if (hasHeaderParameter) {
return await this._buildOperationHeaderParam(dataOperationRequest, tableName);
}
}
return undefined;
}
/**
* Builds the operation header parameters as a JSON string for a given data operation.
*
* @template TRequest - The type of the request object for the data operation.
* @param dataOperationRequest - The data operation containing connector operation details and parameters.
* @param tableName - The name of the table associated with the data operation.
* @returns A promise that resolves to a JSON string representing the header parameters,
* or `undefined` if no `header` parameters are available.
*/
async _buildOperationHeaderParam(dataOperationRequest, tableName) {
const operationName = dataOperationRequest.connectorOperation?.operationName;
if (!operationName) {
return {};
}
const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
const apiParamSpec = dataSourceInfo?.apis?.[operationName]?.parameters || [];
const inputParams = dataOperationRequest.connectorOperation?.parameters;
const headers = {};
// This method does not check for required header parameters
// If the header parameter is required & is not provided, the connector will throw an error
// when the operation is executed.
if (!inputParams) {
return undefined;
}
if (typeof inputParams === 'string') {
// Handle string parameter - often used for single parameter operations
if (apiParamSpec.length === 1 && apiParamSpec[0].in === 'header') {
headers[apiParamSpec[0].name] = inputParams;
}
}
if (typeof inputParams === 'object' && !Array.isArray(inputParams)) {
// Handle object parameters - match by parameter name
apiParamSpec.forEach((param) => {
const headerValue = inputParams[param.name];
if (param.in === 'header' && headerValue !== undefined) {
headers[param.name] = headerValue;
}
});
}
if (Array.isArray(inputParams)) {
// Handle array parameters - match by index
apiParamSpec.forEach((param, index) => {
if (param.in === 'header' && inputParams[index] !== undefined) {
headers[param.name] = inputParams[index];
}
});
}
return headers;
}
/**
* Constructs the request URL for table operations
* @param tableName - The name of the table
* @param connectionReference - The connection reference
* @param options - Optional URL parameters
* @param encodeOptions - Whether to encode the options
* @returns The constructed URL
*/
async _buildTableUrl(tableName, connectionReference, options = '', encodeOptions = true) {
const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
const isSharedSql = (connectionReference.apiId ?? '').indexOf('shared_sql') > -1;
const isSharePoint = (connectionReference.apiId ?? '').indexOf('shared_sharepointonline') > -1;
const datasetName = connectionReference.datasetNameOverride?.trim() || connectionReference.datasetName || '';
const rawTableId = connectionReference.tableNameOverride?.trim() || dataSourceInfo.tableId;
const urlBuilder = {
runtimeUrl: connectionReference.runtimeUrl ?? '',
connectionName: connectionReference.connectionName ?? '',
datasetName: isSharePoint
? encodeURIComponent(encodeURIComponent(datasetName))
: encodeURIComponent(datasetName),
tableId: encodeURIComponent(rawTableId),
version: dataSourceInfo.version,
isSharedSql,
};
return this._constructUrl(urlBuilder, options, encodeOptions);
}
/**
* Builds the operation URL
*/
async _buildOperationUrl(operation, config) {
const operationName = operation.connectorOperation?.operationName;
if (!operationName) {
throw new Error(`${DataOperationErrorMessages.InvalidOperationParameters}: ${DataOperationErrorMessages.MissingOperationName}`);
}
const dataSourceInfo = await this._connectionsService.getDataSource(config.tableName);
const isSharedSql = (config.apiId ?? '').indexOf('shared_sql') > -1;
const path = dataSourceInfo.apis[operationName].path;
if (isSharedSql) {
return this._buildSharedSqlOperationUrl(config, path);
}
return this._buildStandardOperationUrl(operation, config, operationName, path);
}
/**
* Gets the connection references
*/
async _getConnectionReferencesAsync() {
if (this._connectionReferences) {
return this._connectionReferences;
}
const metadataClient = await this._getMetadataClient();
const response = await metadataClient.getAppConnectionConfigsAsync();
this._connectionReferences = response.data;
return this._connectionReferences;
}
/**
* Gets the database references
*/
async _getDatabaseReferencesAsync() {
if (this._databaseReferences) {
return this._databaseReferences;
}
const metadataClient = await this._getMetadataClient();
const response = await metadataClient.getAppDataSourceConfigsAsync();
this._databaseReferences = response.data;
return this._databaseReferences;
}
/**
* Gets the metadata client instance
*/
async _getMetadataClient() {
const metadataClient = await this._clientProvider.getMetadataClientAsync();
if (!metadataClient) {
throw new PowerDataRuntimeError(ErrorCodes.MetadataClientNotAvailable);
}
return metadataClient;
}
/**
* Gets the connection reference for a table
*/
_getConnectionReference(tableName) {
const connectionReference = this._connectionReferences?.[tableName];
if (!connectionReference) {
throw new PowerDataRuntimeError(ErrorCodes.ConnectionReferenceNotFound, tableName);
}
return connectionReference;
}
/**
* Gets both the data client and connection reference
*/
async _getClientsAndConnection(tableName) {
await this._getReferences();
const dataClient = await this._clientProvider.getDataClientAsync();
if (!dataClient) {
throw new PowerDataRuntimeError(ErrorCodes.DataClientNotAvailable);
}
const connectionReference = this._getConnectionReference(tableName);
return { dataClient, connectionReference };
}
/**
* Builds the URL for shared SQL operations
*/
_buildSharedSqlOperationUrl(config, path) {
const version = config.version ? `/${config.version}/` : '/';
return `${config.runtimeUrl}/${config.connectionName}${version}datasets/${config.datasetName}/procedures${path}`;
}
/**
* Builds the URL for standard operations
* Assumptions / Invariants:
* - The connector always defines a required path parameter for the connection id named 'connectionId'.
* - When a dataset is applicable, the parameter name is 'dataset'.
* - When a table is applicable, the parameter name is 'tableName'.
* - A lone string parameter maps to the first remaining (non-synthetic) required API parameter.
* - Array parameters map positionally to the remaining API parameters after filtering.
* - Object parameters map by (case-insensitive, hyphen/underscore agnostic) key.
* @param operation - The data operation containing connector operation details from runtime
* @param config - The connector operation configuration
* @param operationName - The name of the operation to be performed
* @param path - The path template for the operation
*/
async _buildStandardOperationUrl(operation, config, operationName, path) {
const dataSourceInfo = await this._connectionsService.getDataSource(config.tableName);
let apiParams = dataSourceInfo.apis[operationName]?.parameters || [];
if (apiParams.length > 0) {
// remove special/synthetic parameters that the executor handles automatically below
apiParams = apiParams.filter((param) => param.name !== 'connectionId' && param.name !== 'dataset' && param.name !== 'tableName');
}
// Handle parameters that could be an object, array, or string
const operationParams = operation.connectorOperation?.parameters;
const rawParamValues = {
connectionId: config.connectionName,
dataset:
// The dataset name needs to be double encoded for sharepoint, once here and then once in the HTTP pipeline
// CRUD operations already handle this, so we need to do the same here
config.apiId.indexOf('shared_sharepointonline') !== -1 && config.datasetName
? encodeURIComponent(config.datasetName)
: config.datasetName,
tableName: config.tableName,
};
// Handle different parameter types
if (operationParams !== undefined) {
if (typeof operationParams === 'string') {
// Handle string parameter - often used for single parameter operations
if (apiParams.length > 0) {
// Map to the first required API parameter or if there are no required parameters, the first parameter
const requiredParams = apiParams.filter((param) => param.required);
rawParamValues[requiredParams?.[0]?.name ?? apiParams[0].name] = operationParams;
}
}
else if (typeof operationParams === 'object' && !Array.isArray(operationParams)) {
// Handle object parameters - match by parameter name (normalized)
apiParams.forEach((param) => {
if (operationParams) {
const value = this._getNormalizedParamValue(operationParams, param.name);
if (value !== undefined) {
rawParamValues[param.name] = value;
}
}
});
// Allow operationParams to override the synthetic 'dataset' and 'tableName' params when
// explicitly provided. Both are filtered from apiParams above so the loop never processes them.
const datasetOverride = this._getNormalizedParamValue(operationParams, 'dataset');
if (datasetOverride !== undefined) {
rawParamValues['dataset'] =
config.apiId.indexOf('shared_sharepointonline') !== -1
? encodeURIComponent(datasetOverride)
: datasetOverride;
}
const tableNameOverride = this._getNormalizedParamValue(operationParams, 'tableName');
if (tableNameOverride !== undefined) {
rawParamValues['tableName'] = tableNameOverride;
}
}
else if (Array.isArray(operationParams)) {
// Handle array parameters - match by index
apiParams.forEach((param, index) => {
rawParamValues[param.name] = operationParams[index];
});
}
}
const { processedPath, queryParams } = this._processParameters(
// deliberately pass the unfiltered list to _processParameters so path placeholders still see synthetic params.
dataSourceInfo.apis[operationName]?.parameters || [], rawParamValues, path);
const separator = queryParams ? (processedPath.includes('?') ? '&' : '?') : '';
return `${config.runtimeUrl}${processedPath}${separator}${queryParams}`;
}
/**
* Normalizes the parameter name by replacing hyphens with underscores and performs case-insensitive matching
*/
_getNormalizedParamValue(obj, paramName) {
const normalizedParamName = paramName.replace(/-/g, '_').toLowerCase();
const foundKey = Object.keys(obj).find((key) => key.replace(/-/g, '_').toLowerCase() === normalizedParamName);
return foundKey !== undefined ? obj[foundKey] : undefined;
}
/**
* Processes operation parameters into path and query parameters
* @param apiParams - The API parameter specifications from the data source info
* @param rawParamValues - The raw parameter values provided in the operation at runtime
* @param path - The initial path template
* @returns An object containing the processed path and query parameters
*/
_processParameters(apiParams, rawParamValues, path) {
const usedParams = new Set();
let processedPath = path;
const queryParams = [];
apiParams.forEach((param, _index) => {
const paramValue = rawParamValues[param.name];
if (paramValue === undefined) {
return;
}
if (param.in === 'path') {
const placeholder = `{${param.name}}`;
if (processedPath.includes(placeholder)) {
processedPath = processedPath.replace(placeholder, encodeURIComponent(String(paramValue)));
usedParams.add(param.name);
}
}
else if (param.in === 'query') {
queryParams.push(`${encodeURIComponent(param.name)}=${encodeURIComponent(String(paramValue))}`);
usedParams.add(param.name);
}
});
return {
processedPath,
queryParams: queryParams.join('&'),
};
}
/**
* Gets the operation configuration
*/
async _getOperationConfig(operation, connectionReference, tableName) {
if (!operation.connectorOperation) {
throw new Error(`${DataOperationErrorMessages.InvalidRequest}: ${DataOperationErrorMessages.MissingConnectorOperation}`);
}
const dataSourceInfo = await this._connectionsService.getDataSource(tableName);
const config = {
tableName,
apiId: connectionReference.apiId ?? '',
runtimeUrl: connectionReference.runtimeUrl ?? '',
connectionName: connectionReference.connectionName ?? '',
datasetName: connectionReference.datasetName ?? '',
tableId: connectionReference.tableNameOverride?.trim() || dataSourceInfo.tableId,
version: dataSourceInfo.version,
};
return config;
}
/**
* Initializes the clients
*/
async _getReferences() {
await this._getConnectionReferencesAsync();
await this._getDatabaseReferencesAsync();
}
/**
* Validates constructor parameters
*/
_validateConstructorParams(clientProvider, connectionsService) {
if (!clientProvider) {
throw new PowerDataRuntimeError(ErrorCodes.ClientProviderNotAvailable);
}
if (!connectionsService) {
throw new PowerDataRuntimeError(ErrorCodes.DataSourceServiceNotAvailable);
}
}
/**
* Constructs the final URL
*/
_constructUrl(urlBuilder, options = '', encodeOptions = true) {
const apiVersion = urlBuilder.version ? `/${urlBuilder.version}/` : '/';
const encodedOptions = encodeOptions && options ? options.charAt(0) + encodeURIComponent(options.slice(1)) : options;
if (urlBuilder.datasetName) {
return `${urlBuilder.runtimeUrl}/${urlBuilder.connectionName}${apiVersion}datasets/${urlBuilder.datasetName}/tables/${urlBuilder.tableId}/items${encodedOptions}`;
}
return `${urlBuilder.runtimeUrl}/${urlBuilder.connectionName}/tables/${urlBuilder.tableId}/items${encodedOptions}`;
}
}
//# sourceMappingURL=connectorDataOperationExecutor.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,208 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { IRuntimeClientProvider } from '../../common/types';
import type { RuntimeDataSourceService } from '../../metadata/runtimeDataSourceService';
import type { IDataOperation, IDataOperationExecutor, IDataSourceInfo, IOperationOptions, IOperationResult } from '../../types';
/** @private */
export declare const ODATA_CONTEXT = "@odata.context";
/** @private */
export declare const ODATA_NEXT_LINK = "@odata.nextLink";
/** @private */
export declare const CRM_TOTAL_RECORD_COUNT = "@Microsoft.Dynamics.CRM.totalrecordcount";
/** @private */
export declare const CRM_TOTAL_RECORD_COUNT_LIMIT_EXCEEDED = "@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded";
/** @private */
export declare const CRM_GLOBAL_METADATA_VERSION = "@Microsoft.Dynamics.CRM.globalmetadataversion";
/**
* DataverseDataOperation provides functionality for performing CRUD operations
* against the Dataverse data source using the XRM WebApi or runtime metadata client.
* @private
*/
export declare class DataverseDataOperationExecutor implements IDataOperationExecutor {
private readonly _clientProvider;
private readonly _dataSourceService;
private _databaseReferences;
constructor(clientProvider: IRuntimeClientProvider, dataSourceService: RuntimeDataSourceService);
/**
* Creates a new record in Dataverse
* @param tableName - The name of the table
* @param data - The record data to create
* @returns Promise resolving to operation result
*/
createRecordAsync<TRequest, TResponse>(tableName: string, data: TRequest): Promise<IOperationResult<TResponse>>;
/**
* Updates an existing record in Dataverse
* @param tableName - The name of the table
* @param id - The record identifier
* @param data - The updated record data
* @returns Promise resolving to operation result
*/
updateRecordAsync<TRequest, TResponse>(tableName: string, id: string, data: TRequest): Promise<IOperationResult<TResponse>>;
/**
* Uploads a record with binary data to Dataverse
* @param tableName - The name of the table
* @param id - The record identifier
* @param columnName - The name of the file column
* @param fileName - The name of the file (used for Dataverse file columns)
* @param data - The binary data to upload
* @returns Promise resolving to operation result
*/
uploadFileToRecord<TRequest extends string | Uint8Array | ArrayBuffer | Blob>(tableName: string, id: string, columnName: string, fileName: string, data: TRequest): Promise<IOperationResult<void>>;
/**
* Downloads binary data from a file column in Dataverse
* @param tableName - The name of the table
* @param id - The record identifier
* @param columnName - The name of the file column
* @returns Promise resolving to operation result with file contents as binary data (Uint8Array)
*/
downloadFileFromRecord(tableName: string, id: string, columnName: string): Promise<IOperationResult<Uint8Array>>;
/**
* Downloads an image from a Dataverse image column via the Web API $value endpoint.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The identifier of the record.
* @param columnName - The name of the image column.
*/
downloadImageFromRecord(tableName: string, recordId: string, columnName: string, fullSize?: boolean): Promise<IOperationResult<Uint8Array>>;
/**
* Deletes a record from Dataverse
* @param tableName - The name of the table
* @param id - The record identifier
* @returns Promise resolving to operation result
*/
deleteRecordAsync(tableName: string, id: string): Promise<IOperationResult<void>>;
/**
* Deletes the file or image data stored in a file/image column of an existing record.
* Sends a DELETE request to `/<tableName>(<recordId>)/<columnName>`.
* Only applicable to Dataverse data sources.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The identifier of the record.
* @param columnName - The name of the file or image column whose data should be deleted.
*/
deleteFileOrImageFromRecord(tableName: string, recordId: string, columnName: string): Promise<IOperationResult<void>>;
/**
* Retrieves a single record from Dataverse
* @param tableName - The name of the table
* @param id - The record identifier
* @param options - The retrieval options
* @returns Promise resolving to operation result
*/
retrieveRecordAsync<TResponse>(tableName: string, id: string, options?: IOperationOptions): Promise<IOperationResult<TResponse>>;
/**
* Retrieves multiple records from Dataverse
* @param tableName - The name of the table
* @param options - The retrieval options
* @param maxPageSize - Optional maximum page size
* @returns Promise resolving to operation result
*/
retrieveMultipleRecordsAsync<TResponse>(tableName: string, options?: IOperationOptions): Promise<IOperationResult<TResponse[]>>;
/**
* Executes a custom Dataverse operation
* @param operation - The operation to execute
* @returns Promise resolving to operation result
*/
executeAsync<TRequest, TResponse>(operation: IDataOperation<TRequest>): Promise<IOperationResult<TResponse>>;
private _getEntityMetadata;
/**
* Returns the database references for Dataverse, grouped by environment/database.
* These come from the launch app response via runtime metadata client.
*/
getDatabaseReferences(): Promise<DatabaseReferences>;
/**
* Loads database references from runtime metadata client (launch app response).
*/
private _loadDatabaseReferencesFromRuntime;
private _extractInstanceUrlFromRuntimeUrl;
/**
* Helper to get a native data client and database reference
*/
private _getDataClient;
/**
* Gets the metadata client instance
*/
private _getMetadataClient;
/**
* Template method for connector-style CRUD operations to reduce duplication.
* Handles client, dataSourceInfo, requestUrl, and error handling.
*/
private _executeNativeDataverseOperation;
/**
* Helper to get the Dataverse datasourceinfo from databaseReferences
*/
private _getDataverseDataSourceInfo;
/**
* Returns the Dataverse environment info from the default CDS database reference.
* Used for custom API operations where the data source name is not an entity table.
*/
private _getDefaultDataverseEnvironmentInfo;
private _getInstanceUrl;
private _getDataverseRequestUrl;
/**
* Constructs GET request URL for fetching metadata using options object.
* @param dataSourceInfo - The data source information for the Dataverse table.
* @param options - The options for the metadata request.
* @returns The constructed metadata request URL.
*/
private _generateMetadataRequestUrl;
}
export interface ILinkedEnvironmentMetadata {
resourceId: string;
friendlyName: string;
uniqueName: string;
domainName: string;
version: string;
instanceUrl: string;
instanceApiUrl: string;
baseLanguage: number;
instanceState: string;
createdTime: string;
platformSku: string;
}
export interface DataverseDataSourceInfo extends IDataSourceInfo {
datasetName: string;
referenceType?: string;
linkedEnvironmentMetadata?: ILinkedEnvironmentMetadata;
entitySetName?: string;
logicalName?: string;
isHidden?: boolean;
}
interface IDatabaseReference {
databaseDetails: {
referenceType: string;
environmentName: string;
overrideValues: {
status: string;
environmentVariableName: string;
};
linkedEnvironmentMetadata?: ILinkedEnvironmentMetadata;
};
dataSources: {
[dataSourceName: string]: {
entitySetName: string;
logicalName: string;
isHidden: boolean;
};
};
}
/**
* Extracts the skip token from the next link URL.
* @param nextLink - The @odata.nextLink URL containing the skip token
* @returns The extracted skip token or undefined if not found.
*/
export declare function extractSkipToken(nextLink: string | undefined): string | undefined;
export type DatabaseReferences = {
[key: string]: IDatabaseReference;
};
/**
* Derives a filename for a downloaded image by sniffing the magic bytes of the binary data.
* Falls back to "png" if the format is unrecognized, as PNG is the most common Dataverse image format.
*/
export declare function deriveImageFileName(columnName: string, data: Uint8Array): string;
/**
* Converts a JavaScript value to an OData primitive literal string for use in function call URLs.
* Strings are single-quoted with internal single quotes escaped by doubling.
* Numbers and booleans are serialized as-is. Null/undefined becomes 'null'.
*/
export declare function toODataLiteral(value: unknown, type: string): string;
export {};
//# sourceMappingURL=dataverseDataOperationExecutor.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"dataverseDataOperationExecutor.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/data/core/data/executors/dataverseDataOperationExecutor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,sBAAsB,EAGvB,MAAM,oBAAoB,CAAC;AAS5B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yCAAyC,CAAC;AAExF,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAQrB,eAAe;AACf,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAC9C,eAAe;AACf,eAAO,MAAM,eAAe,oBAAoB,CAAC;AACjD,eAAe;AACf,eAAO,MAAM,sBAAsB,6CAA6C,CAAC;AACjF,eAAe;AACf,eAAO,MAAM,qCAAqC,0DACO,CAAC;AAC1D,eAAe;AACf,eAAO,MAAM,2BAA2B,kDAAkD,CAAC;AAE3F;;;;GAIG;AACH,qBAAa,8BAA+B,YAAW,sBAAsB;IAG3E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyB;IACzD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;IAE9D,OAAO,CAAC,mBAAmB,CAAiC;gBAEhD,cAAc,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,wBAAwB;IAK/F;;;;;OAKG;IACU,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAChD,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IA2BvC;;;;;;OAMG;IACU,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAChD,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IA2BvC;;;;;;;;OAQG;IACU,kBAAkB,CAAC,QAAQ,SAAS,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,EACvF,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IA6BlC;;;;;;OAMG;IACU,sBAAsB,CACjC,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAgCxC;;;;;OAKG;IACU,uBAAuB,CAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,UAAQ,GACf,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IA+BxC;;;;;OAKG;IACU,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IA0B9F;;;;;;;OAOG;IACU,2BAA2B,CACtC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IA0BlC;;;;;;OAMG;IACU,mBAAmB,CAAC,SAAS,EACxC,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAkCvC;;;;;;OAMG;IACU,4BAA4B,CAAC,SAAS,EACjD,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC;IA0CzC;;;;OAIG;IACU,YAAY,CAAC,QAAQ,EAAE,SAAS,EAC3C,SAAS,EAAE,cAAc,CAAC,QAAQ,CAAC,GAClC,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAkHzB,kBAAkB;IAwBhC;;;OAGG;IACU,qBAAqB,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAmBjE;;OAEG;YACW,kCAAkC;IAkFhD,OAAO,CAAC,iCAAiC;IAiBzC;;OAEG;YACW,cAAc;IAc5B;;OAEG;YACW,kBAAkB;IAWhC;;;OAGG;YACW,gCAAgC;IAoB9C;;OAEG;YACW,2BAA2B;IA+CzC;;;OAGG;YACW,mCAAmC;IAkBjD,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,uBAAuB;IAS/B;;;;;OAKG;IACH,OAAO,CAAC,2BAA2B;CAiDpC;AAED,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yBAAyB,CAAC,EAAE,0BAA0B,CAAC;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,kBAAkB;IAC1B,eAAe,EAAE;QACf,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE;YACd,MAAM,EAAE,MAAM,CAAC;YACf,uBAAuB,EAAE,MAAM,CAAC;SACjC,CAAC;QACF,yBAAyB,CAAC,EAAE,0BAA0B,CAAC;KACxD,CAAC;IACF,WAAW,EAAE;QACX,CAAC,cAAc,EAAE,MAAM,GAAG;YACxB,aAAa,EAAE,MAAM,CAAC;YACtB,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,OAAO,CAAC;SACnB,CAAC;KACH,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOjF;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAAA;CAAE,CAAC;AA8CvE;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAGhF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAQnE"}
@@ -0,0 +1,689 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { DataSources, HttpMethod } from '../../common/types';
import { DataverseOperationName } from '../../error/constants';
import { createErrorResponse, DataOperationErrorMessages, ErrorCodes, PowerDataRuntimeError, } from '../../error/error';
import { Log } from '../../telemetry/log';
import { convertOptionsToQueryString } from './shared/stringQueryOptions';
/** @private */
export const ODATA_CONTEXT = '@odata.context';
/** @private */
export const ODATA_NEXT_LINK = '@odata.nextLink';
/** @private */
export const CRM_TOTAL_RECORD_COUNT = '@Microsoft.Dynamics.CRM.totalrecordcount';
/** @private */
export const CRM_TOTAL_RECORD_COUNT_LIMIT_EXCEEDED = '@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded';
/** @private */
export const CRM_GLOBAL_METADATA_VERSION = '@Microsoft.Dynamics.CRM.globalmetadataversion';
/**
* DataverseDataOperation provides functionality for performing CRUD operations
* against the Dataverse data source using the XRM WebApi or runtime metadata client.
* @private
*/
export class DataverseDataOperationExecutor {
// Static identifiers for services and actions
// Used to identify specific services and actions within the PowerApps environment
_clientProvider;
_dataSourceService;
_databaseReferences;
constructor(clientProvider, dataSourceService) {
this._clientProvider = clientProvider;
this._dataSourceService = dataSourceService;
}
/**
* Creates a new record in Dataverse
* @param tableName - The name of the table
* @param data - The record data to create
* @returns Promise resolving to operation result
*/
async createRecordAsync(tableName, data) {
return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName), async (dataClient, requestUrl, dataSourceInfo) => {
const dataverseResponse = await dataClient.createDataAsync(requestUrl, DataSources.Dataverse, // Use environment name for Dataverse authentication
tableName, data, {
operationName: DataverseOperationName.CreateRecord,
datasetName: dataSourceInfo.datasetName,
isDataVerseOperation: true,
});
const returnValue = {
success: dataverseResponse.success,
data: dataverseResponse.data,
error: dataverseResponse.error,
};
return returnValue;
}, DataOperationErrorMessages.CreateFailed);
}
/**
* Updates an existing record in Dataverse
* @param tableName - The name of the table
* @param id - The record identifier
* @param data - The updated record data
* @returns Promise resolving to operation result
*/
async updateRecordAsync(tableName, id, data) {
return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, `(${id})`), async (dataClient, requestUrl, dataSourceInfo) => {
const dataverseResponse = await dataClient.updateDataAsync(requestUrl, DataSources.Dataverse, tableName, data, {
operationName: DataverseOperationName.UpdateRecord,
datasetName: dataSourceInfo.datasetName,
isDataVerseOperation: true,
});
const returnValue = {
success: dataverseResponse.success,
data: dataverseResponse.data,
error: dataverseResponse.error,
};
return returnValue;
}, DataOperationErrorMessages.UpdateFailed);
}
/**
* Uploads a record with binary data to Dataverse
* @param tableName - The name of the table
* @param id - The record identifier
* @param columnName - The name of the file column
* @param fileName - The name of the file (used for Dataverse file columns)
* @param data - The binary data to upload
* @returns Promise resolving to operation result
*/
async uploadFileToRecord(tableName, id, columnName, fileName, data) {
return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, `(${id})/${columnName}`), async (dataClient, requestUrl, dataSourceInfo) => {
const dataverseResponse = await dataClient.uploadDataAsync(requestUrl, DataSources.Dataverse, tableName, data, {
operationName: DataverseOperationName.UploadRecord,
datasetName: dataSourceInfo.datasetName,
isDataVerseOperation: true,
fileName,
});
const returnValue = {
success: dataverseResponse.success,
data: dataverseResponse.data,
error: dataverseResponse.error,
};
return returnValue;
}, DataOperationErrorMessages.UploadFailed);
}
/**
* Downloads binary data from a file column in Dataverse
* @param tableName - The name of the table
* @param id - The record identifier
* @param columnName - The name of the file column
* @returns Promise resolving to operation result with file contents as binary data (Uint8Array)
*/
async downloadFileFromRecord(tableName, id, columnName) {
return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, `(${id})/${columnName}/$value`), async (dataClient, requestUrl, dataSourceInfo) => {
const dataverseResponse = await dataClient.retrieveDataAsync(requestUrl, DataSources.Dataverse, tableName, HttpMethod.GET, { Accept: 'application/octet-stream' }, undefined, {
operationName: DataverseOperationName.DownloadRecord,
datasetName: dataSourceInfo.datasetName,
isDataVerseOperation: true,
skipBatch: true,
});
const returnValue = {
success: dataverseResponse.success,
data: dataverseResponse.data,
error: dataverseResponse.error,
fileName: dataverseResponse.fileName,
};
return returnValue;
}, DataOperationErrorMessages.DownloadFailed);
}
/**
* Downloads an image from a Dataverse image column via the Web API $value endpoint.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The identifier of the record.
* @param columnName - The name of the image column.
*/
async downloadImageFromRecord(tableName, recordId, columnName, fullSize = false) {
const urlSuffix = `(${recordId})/${columnName}/$value${fullSize ? '?size=full' : ''}`;
return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, urlSuffix), async (dataClient, requestUrl, dataSourceInfo) => {
const dataverseResponse = await dataClient.retrieveDataAsync(requestUrl, DataSources.Dataverse, tableName, HttpMethod.GET, { Accept: 'application/octet-stream' }, undefined, {
operationName: DataverseOperationName.DownloadRecord,
datasetName: dataSourceInfo.datasetName,
isDataVerseOperation: true,
skipBatch: true,
});
return {
success: dataverseResponse.success,
data: dataverseResponse.data,
error: dataverseResponse.error,
fileName: deriveImageFileName(columnName, dataverseResponse.data),
};
}, DataOperationErrorMessages.DownloadFailed);
}
/**
* Deletes a record from Dataverse
* @param tableName - The name of the table
* @param id - The record identifier
* @returns Promise resolving to operation result
*/
async deleteRecordAsync(tableName, id) {
return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, `(${id})`), async (dataClient, requestUrl, dataSourceInfo) => {
const dataverseResponse = await dataClient.deleteDataAsync(requestUrl, DataSources.Dataverse, tableName, {
operationName: DataverseOperationName.DeleteRecord,
datasetName: dataSourceInfo.datasetName,
isDataVerseOperation: true,
});
const returnValue = {
success: dataverseResponse.success,
data: dataverseResponse.data,
error: dataverseResponse.error,
};
return returnValue;
}, DataOperationErrorMessages.DeleteFailed);
}
/**
* Deletes the file or image data stored in a file/image column of an existing record.
* Sends a DELETE request to `/<tableName>(<recordId>)/<columnName>`.
* Only applicable to Dataverse data sources.
* @param tableName - The logical name of the Dataverse table.
* @param recordId - The identifier of the record.
* @param columnName - The name of the file or image column whose data should be deleted.
*/
async deleteFileOrImageFromRecord(tableName, recordId, columnName) {
return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, `(${recordId})/${columnName}`), async (dataClient, requestUrl, dataSourceInfo) => {
const dataverseResponse = await dataClient.deleteDataAsync(requestUrl, DataSources.Dataverse, tableName, {
operationName: DataverseOperationName.DeleteFileOrImageRecord,
datasetName: dataSourceInfo.datasetName,
isDataVerseOperation: true,
});
return {
success: dataverseResponse.success,
data: dataverseResponse.data,
error: dataverseResponse.error,
};
}, DataOperationErrorMessages.DeleteFileOrImageFailed);
}
/**
* Retrieves a single record from Dataverse
* @param tableName - The name of the table
* @param id - The record identifier
* @param options - The retrieval options
* @returns Promise resolving to operation result
*/
async retrieveRecordAsync(tableName, id, options) {
const { maxPageSize = 500, ...rest } = options || {};
const optionsString = convertOptionsToQueryString(rest);
// Build Prefer header with updated maxPageSize
const headers = { Prefer: `odata.maxpagesize=${maxPageSize},odata.include-annotations=*` };
return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, `(${id})${optionsString}`), async (dataClient, requestUrl, dataSourceInfo) => {
const dataverseResponse = await dataClient.retrieveDataAsync(requestUrl, DataSources.Dataverse, tableName, HttpMethod.GET, headers, undefined, // No body for GET requests
{
operationName: DataverseOperationName.RetrieveRecord,
datasetName: dataSourceInfo.datasetName,
isDataVerseOperation: true,
});
const returnValue = {
success: dataverseResponse.success,
data: dataverseResponse.data,
error: dataverseResponse.error,
};
return returnValue;
}, DataOperationErrorMessages.RetrieveFailed);
}
/**
* Retrieves multiple records from Dataverse
* @param tableName - The name of the table
* @param options - The retrieval options
* @param maxPageSize - Optional maximum page size
* @returns Promise resolving to operation result
*/
async retrieveMultipleRecordsAsync(tableName, options) {
const { maxPageSize = 500, ...rest } = options || {};
const optionsString = convertOptionsToQueryString(rest);
// Build Prefer header with updated maxPageSize
const headers = { Prefer: `odata.maxpagesize=${maxPageSize},odata.include-annotations=*` };
return this._executeNativeDataverseOperation(tableName, (dataSourceInfo, tblName) => this._getDataverseRequestUrl(dataSourceInfo, tblName, optionsString), async (dataClient, requestUrl, dataSourceInfo) => {
const dataverseResponse = await dataClient.retrieveDataAsync(requestUrl, DataSources.Dataverse, tableName, HttpMethod.GET, headers, undefined, // No body for GET requests
{
operationName: DataverseOperationName.RetrieveMultipleRecords,
datasetName: dataSourceInfo.datasetName,
isDataVerseOperation: true,
});
const returnValue = {
success: dataverseResponse.success,
data: dataverseResponse?.data?.value || [],
skipToken: extractSkipToken(dataverseResponse?.data?.[ODATA_NEXT_LINK]),
error: dataverseResponse.error,
};
return returnValue;
}, DataOperationErrorMessages.RetrieveMultipleFailed);
}
/**
* Executes a custom Dataverse operation
* @param operation - The operation to execute
* @returns Promise resolving to operation result
*/
async executeAsync(operation) {
const { dataverseRequest } = operation;
if (!dataverseRequest) {
return {
success: false,
data: null,
error: { message: 'Dataverse request details are required for Dataverse operations.' },
};
}
const { action, parameters } = dataverseRequest;
switch (action) {
// Future custom actions can be handled here
case 'getEntityMetadata': {
const { tableName, options } = parameters;
if (!tableName) {
return {
success: false,
data: null,
error: { message: 'Table name is required for getEntityMetadata action.' },
};
}
return this._getEntityMetadata(tableName, options ?? {});
}
case 'customapi': {
const { operationName, tableName, body } = parameters;
const dataSourceInfo = await this._dataSourceService.getDataSource(tableName);
const apiDef = dataSourceInfo.apis[operationName];
if (!apiDef) {
return {
success: false,
data: null,
error: {
message: `Operation '${operationName}' not found in data source '${tableName}'.`,
},
};
}
const dvInfo = await this._getDefaultDataverseEnvironmentInfo();
const instanceUrl = this._getInstanceUrl(dvInfo);
const bodyRecord = (body ?? {});
// Substitute path parameters into the pre-built OData path
// Collect body params (actions) and OData function params (functions, in: 'query')
let resolvedPath = apiDef.path;
const requestBody = {};
const functionParams = [];
for (const param of apiDef.parameters) {
if (param.in === 'path') {
resolvedPath = resolvedPath.replace(`{${param.name}}`, encodeURIComponent(String(bodyRecord[param.name] ?? '')));
}
else if (param.in === 'body') {
if (param.name in bodyRecord) {
requestBody[param.name] = bodyRecord[param.name];
}
}
else if (param.in === 'query') {
// Dataverse functions pass parameters as OData function params: FunctionName(p1=v1,p2=v2)
if (param.name in bodyRecord) {
functionParams.push(`${param.name}=${toODataLiteral(bodyRecord[param.name], param.type)}`);
}
}
}
if (functionParams.length > 0) {
resolvedPath += `(${functionParams.join(',')})`;
}
const requestUrl = `${instanceUrl}${resolvedPath.startsWith('/') ? resolvedPath.slice(1) : resolvedPath}`;
const dataClient = await this._getDataClient();
const isGet = apiDef.method.toUpperCase() === HttpMethod.GET;
const response = isGet
? await dataClient.retrieveDataAsync(requestUrl, DataSources.Dataverse, operationName, HttpMethod.GET, undefined, undefined, {
operationName: DataverseOperationName.ExecuteCustomApi,
datasetName: dvInfo.datasetName,
isDataVerseOperation: true,
})
: await dataClient.createDataAsync(requestUrl, DataSources.Dataverse, operationName, requestBody, {
operationName: DataverseOperationName.ExecuteCustomApi,
datasetName: dvInfo.datasetName,
isDataVerseOperation: true,
});
return { success: response.success, data: response.data, error: response.error };
}
default:
Log.trackEvent('DataverseDataOperation.UnsupportedAction', {
message: `Unsupported Dataverse action: ${action}`,
});
return {
success: false,
data: null,
error: { message: `Unsupported Dataverse action: "${action}"` },
};
}
}
async _getEntityMetadata(tableName, options) {
const client = await this._getDataClient();
const dataSourceInfo = await this._getDataverseDataSourceInfo(tableName);
const url = this._generateMetadataRequestUrl(dataSourceInfo, options);
return client.retrieveDataAsync(url, DataSources.Dataverse, 'EntityDefinitions', HttpMethod.GET, {
Consistency: 'Strong', // Force CDS to return latest metadata
}, undefined, {
operationName: DataverseOperationName.RetrieveRecord,
datasetName: dataSourceInfo.datasetName,
isDataVerseOperation: true,
});
}
/**
* Returns the database references for Dataverse, grouped by environment/database.
* These come from the launch app response via runtime metadata client.
*/
async getDatabaseReferences() {
if (this._databaseReferences) {
return this._databaseReferences;
}
// Get database references from runtime metadata (launch app response)
// This is the authoritative source containing the complete linkedEnvironmentMetadata
const runtimeDatabaseReferences = await this._loadDatabaseReferencesFromRuntime();
if (runtimeDatabaseReferences && Object.keys(runtimeDatabaseReferences).length > 0) {
this._databaseReferences = runtimeDatabaseReferences;
return this._databaseReferences;
}
throw new PowerDataRuntimeError(ErrorCodes.DataSourceNotFound, 'Failed to load Dataverse database references from runtime.');
}
/**
* Loads database references from runtime metadata client (launch app response).
*/
async _loadDatabaseReferencesFromRuntime() {
try {
const metadataClient = await this._getMetadataClient();
// Get CDS data source configs from runtime metadata
const response = await metadataClient.getAppDataSourceConfigsAsync();
if (!response.success || !response.data) {
return undefined;
}
const cdsDataSources = Object.values(response.data);
if (cdsDataSources.length === 0) {
return undefined;
}
// Build database references from runtime CDS data source configs
const databaseReferences = {};
for (const cdsDataSource of cdsDataSources) {
// Type assertion for CDS data source config
const cdsConfig = cdsDataSource;
// Extract instance URL and other metadata from runtime URL
const instanceUrl = this._extractInstanceUrlFromRuntimeUrl(cdsConfig.runtimeUrl);
// Use a standard environment name for CDS
const envName = 'default.cds';
if (!databaseReferences[envName]) {
databaseReferences[envName] = {
databaseDetails: {
referenceType: 'Environmental',
environmentName: envName,
overrideValues: {
status: 'NotSpecified',
environmentVariableName: '',
},
linkedEnvironmentMetadata: {
resourceId: '', // This would be available in the full app info
friendlyName: '',
uniqueName: '',
domainName: '',
version: cdsConfig.version || '9.2',
instanceUrl,
instanceApiUrl: cdsConfig.runtimeUrl,
baseLanguage: 1033,
instanceState: 'Ready',
createdTime: '',
platformSku: '',
},
},
dataSources: {},
};
}
// Add the data source
const dataSourceName = cdsConfig.entitySetName || cdsConfig.logicalName;
databaseReferences[envName].dataSources[dataSourceName] = {
entitySetName: cdsConfig.entitySetName,
logicalName: cdsConfig.logicalName,
isHidden: false,
};
}
return databaseReferences;
}
catch (error) {
// Info-level logging for tracing errors loading from runtime
Log.trackEvent('DataverseDataOperation.FailedToLoadDatabaseReferences', {
message: '[DataverseDataOperation] Failed to load database references from runtime',
error,
});
// Silently fail and return undefined if there's any error loading from runtime
return undefined;
}
}
_extractInstanceUrlFromRuntimeUrl(runtimeUrl) {
try {
// Runtime URL format: https://org.crm.dynamics.com/api/data/v9.2/
// Extract: https://org.crm.dynamics.com
// Using a simpler approach to avoid URL import issues
const matches = runtimeUrl.match(/^(https?:\/\/[^/]+)/);
return matches ? matches[1] : runtimeUrl;
}
catch (error) {
Log.trackEvent('DataverseDataOperation.FailedToExtractInstanceUrl', {
message: '[DataverseDataOperation] Failed to extract instance URL from runtime URL',
error,
});
// Fallback to original URL on error
return runtimeUrl;
}
}
/**
* Helper to get a native data client and database reference
*/
async _getDataClient() {
const dataClient = await this._clientProvider.getDataClientAsync();
if (!dataClient) {
Log.trackEvent('DataverseDataOperation.DataClientNotAvailable', {
message: '[DataverseDataOperation] Data client is not available',
});
throw new PowerDataRuntimeError(ErrorCodes.DataClientNotAvailable, 'Data client is not available.');
}
return dataClient;
}
/**
* Gets the metadata client instance
*/
async _getMetadataClient() {
const metadataClient = await this._clientProvider.getMetadataClientAsync();
if (!metadataClient) {
Log.trackEvent('DataverseDataOperation.MetadataClientNotAvailable', {
message: '[DataverseDataOperation] Metadata client is not available',
});
throw new PowerDataRuntimeError(ErrorCodes.MetadataClientNotAvailable);
}
return metadataClient;
}
/**
* Template method for connector-style CRUD operations to reduce duplication.
* Handles client, dataSourceInfo, requestUrl, and error handling.
*/
async _executeNativeDataverseOperation(tableName, buildUrl, operation, errorMessage) {
try {
const dataClient = await this._getDataClient();
const dataSourceInfo = await this._getDataverseDataSourceInfo(tableName);
const requestUrl = buildUrl(dataSourceInfo, tableName);
return operation(dataClient, requestUrl, dataSourceInfo);
}
catch (error) {
return createErrorResponse(error, errorMessage);
}
}
/**
* Helper to get the Dataverse datasourceinfo from databaseReferences
*/
async _getDataverseDataSourceInfo(tableName) {
let dbRefs;
// Separate try-catch for getting database references
try {
dbRefs = await this.getDatabaseReferences();
}
catch (error) {
Log.trackEvent('DataverseDataOperation.GetDataSourceInfoFailed', {
message: '[DataverseDataOperation] Failed to get database references',
tableName,
error,
});
const errorMessage = error instanceof Error ? error.message : String(error);
throw new PowerDataRuntimeError(ErrorCodes.DataSourceNotFound, `Failed to get Dataverse data source info for table '${tableName}': ${errorMessage}`);
}
// Find the environment/database that contains this table
for (const dbKey of Object.keys(dbRefs)) {
const db = dbRefs[dbKey];
if (db.dataSources[tableName]) {
const ds = db.dataSources[tableName];
return {
datasetName: db.databaseDetails?.environmentName,
referenceType: db.databaseDetails?.referenceType,
linkedEnvironmentMetadata: db.databaseDetails?.linkedEnvironmentMetadata,
entitySetName: ds?.entitySetName,
logicalName: ds?.logicalName,
isHidden: ds?.isHidden,
tableId: ds?.logicalName,
apis: {},
};
}
}
// Table not found - this will now throw without being caught
const notFoundMsg = `No Dataverse data source found for table: ${tableName}`;
Log.trackEvent('DataverseDataOperation.DataSourceNotFound', {
message: notFoundMsg,
tableName,
});
throw new PowerDataRuntimeError(ErrorCodes.DataSourceNotFound, notFoundMsg);
}
/**
* Returns the Dataverse environment info from the default CDS database reference.
* Used for custom API operations where the data source name is not an entity table.
*/
async _getDefaultDataverseEnvironmentInfo() {
const dbRefs = await this.getDatabaseReferences();
const db = dbRefs['default.cds'];
if (!db?.databaseDetails?.linkedEnvironmentMetadata?.instanceUrl) {
throw new PowerDataRuntimeError(ErrorCodes.DataSourceNotFound, 'No Dataverse environment found at default.cds database reference.');
}
return {
datasetName: db.databaseDetails.environmentName,
referenceType: db.databaseDetails.referenceType,
linkedEnvironmentMetadata: db.databaseDetails.linkedEnvironmentMetadata,
tableId: '',
apis: {},
};
}
_getInstanceUrl(dataSourceInfo) {
const instanceUrl = dataSourceInfo.linkedEnvironmentMetadata?.instanceUrl;
if (!instanceUrl) {
throw new PowerDataRuntimeError(ErrorCodes.DataClientInitFailed, 'No instanceUrl found for Dataverse table.');
}
// Ensure instanceUrl ends with a slash and construct proper URL
const baseUrl = instanceUrl.endsWith('/') ? instanceUrl : `${instanceUrl}/`;
return baseUrl;
}
_getDataverseRequestUrl(dataSourceInfo, tableName, urlPath = '') {
const baseUrl = this._getInstanceUrl(dataSourceInfo);
return `${baseUrl}api/data/v9.0/${tableName}${urlPath}`;
}
/**
* Constructs GET request URL for fetching metadata using options object.
* @param dataSourceInfo - The data source information for the Dataverse table.
* @param options - The options for the metadata request.
* @returns The constructed metadata request URL.
*/
_generateMetadataRequestUrl(dataSourceInfo, options) {
const { logicalName } = dataSourceInfo;
if (!logicalName) {
throw new PowerDataRuntimeError(ErrorCodes.DataClientInitFailed, 'No logicalName found for Dataverse table.');
}
const url = new URL(`${this._getInstanceUrl(dataSourceInfo)}api/data/v9.0/EntityDefinitions(LogicalName='${logicalName}')`);
const { metadata, schema } = options;
const selects = new Set(Array.isArray(metadata) ? metadata : []);
selects.add('LogicalName');
const expands = [];
if (schema?.manyToOne) {
expands.push('ManyToOneRelationships');
}
if (schema?.oneToMany) {
expands.push('OneToManyRelationships');
}
if (schema?.manyToMany) {
expands.push('ManyToManyRelationships');
}
if (schema?.columns === 'all') {
// request all attributes
expands.push('Attributes');
}
else if (schema && Array.isArray(schema.columns) && schema.columns.length > 0) {
// If specific columns are requested, include only those
const attributesCollection = schema.columns.map((a) => `'${a}'`).join(',');
expands.push(`Attributes($filter=Microsoft.Dynamics.CRM.In(PropertyName='LogicalName',PropertyValues=[${attributesCollection}]))`);
}
// otherwise don't include any attributes
url.search = new URLSearchParams({
$select: [...selects].join(','),
$expand: expands.join(','),
}).toString();
return url.toString();
}
}
/**
* Extracts the skip token from the next link URL.
* @param nextLink - The @odata.nextLink URL containing the skip token
* @returns The extracted skip token or undefined if not found.
*/
export function extractSkipToken(nextLink) {
if (!nextLink?.trim()) {
return undefined;
}
const match = nextLink.match(/[?&]\$?skiptoken=([^&#]+)/i);
return match ? decodeURIComponent(match[1]) : undefined;
}
/**
* Detects the image format from the magic bytes at the start of the binary data.
* This is necessary because Dataverse image columns do not provide file extension or MIME type information.
* The use of download url companion column (e.g: columnName_url) is not possible due to CORS, so we have to rely on the binary data sniff to determine the extension. This is a standard technique.
* Referring: https://learn.microsoft.com/en-us/power-apps/developer/data-platform/image-column-data?tabs=sdk#download-url
* Sniffing the magic bytes allows us to derive a file extension for the downloaded image, which can be used when saving the file or setting the correct MIME type for display.
* Docs: https://en.wikipedia.org/wiki/List_of_file_signatures
* Dataverse image columns support only GIF, JPEG, BMP, and PNG.
* The function checks for these formats and returns the corresponding extension.
* See: https://learn.microsoft.com/en-us/power-apps/developer/data-platform/image-column-data?tabs=sdk#image-file-types
* Returns a file extension string, or "png" as a fallback if the format is unrecognized.
*/
function sniffImageExtension(data) {
if (data.length >= 3 && data[0] === 0xff && data[1] === 0xd8 && data[2] === 0xff) {
return 'jpg';
}
if (data.length >= 8 &&
data[0] === 0x89 &&
data[1] === 0x50 &&
data[2] === 0x4e &&
data[3] === 0x47 &&
data[4] === 0x0d &&
data[5] === 0x0a &&
data[6] === 0x1a &&
data[7] === 0x0a) {
return 'png';
}
if (data.length >= 4 &&
data[0] === 0x47 &&
data[1] === 0x49 &&
data[2] === 0x46 &&
data[3] === 0x38) {
return 'gif';
}
if (data.length >= 2 && data[0] === 0x42 && data[1] === 0x4d) {
return 'bmp';
}
return 'png';
}
/**
* Derives a filename for a downloaded image by sniffing the magic bytes of the binary data.
* Falls back to "png" if the format is unrecognized, as PNG is the most common Dataverse image format.
*/
export function deriveImageFileName(columnName, data) {
const ext = data ? sniffImageExtension(data) : 'png';
return `${columnName}.${ext}`;
}
/**
* Converts a JavaScript value to an OData primitive literal string for use in function call URLs.
* Strings are single-quoted with internal single quotes escaped by doubling.
* Numbers and booleans are serialized as-is. Null/undefined becomes 'null'.
*/
export function toODataLiteral(value, type) {
if (value === null || value === undefined) {
return 'null';
}
if (type === 'string') {
return `'${String(value).replace(/'/g, "''")}'`;
}
return String(value);
}
//# sourceMappingURL=dataverseDataOperationExecutor.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,5 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
export { createMockDataExecutor, type MockDataStore } from './mockDataOperationExecutor';
//# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/data/core/data/executors/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,5 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
export { createMockDataExecutor } from './mockDataOperationExecutor';
//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/internal/data/core/data/executors/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAsB,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,25 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { IDataOperation, IDataOperationExecutor, IOperationOptions, IOperationResult } from '../../types';
export type MockDataStore<TRecord = unknown> = {
[tableName: string]: {
[id: string]: TRecord;
};
};
export declare class MockDataOperationExecutor implements IDataOperationExecutor {
private _dataStore;
constructor(data: MockDataStore);
createRecordAsync<TRequest, TResponse>(_tableName: string, _data: TRequest): Promise<IOperationResult<TResponse>>;
updateRecordAsync<TRequest, TResponse>(_tableName: string, _id: string, _data: TRequest): Promise<IOperationResult<TResponse>>;
uploadFileToRecord<TRequest extends string | Uint8Array | ArrayBuffer | Blob>(tableName: string, id: string, columnName: string, fileName: string, data: TRequest): Promise<IOperationResult<void>>;
downloadFileFromRecord(tableName: string, id: string, columnName: string): Promise<IOperationResult<Uint8Array>>;
deleteFileOrImageFromRecord(_tableName: string, _recordId: string, _columnName: string): Promise<IOperationResult<void>>;
downloadImageFromRecord(tableName: string, recordId: string, columnName: string, _fullSize?: boolean): Promise<IOperationResult<Uint8Array>>;
deleteRecordAsync(_tableName: string, _id: string): Promise<IOperationResult<void>>;
retrieveRecordAsync<TResponse>(tableName: string, id: string, _options?: IOperationOptions): Promise<IOperationResult<TResponse>>;
retrieveMultipleRecordsAsync<TResponse>(tableName: string, _options?: IOperationOptions): Promise<IOperationResult<TResponse[]>>;
executeAsync<TRequest, TResponse>(_operation: IDataOperation<TRequest>): Promise<IOperationResult<TResponse>>;
}
export declare function createMockDataExecutor(data: MockDataStore): MockDataOperationExecutor;
//# sourceMappingURL=mockDataOperationExecutor.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"mockDataOperationExecutor.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/data/core/data/executors/mockDataOperationExecutor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,aAAa,CAAC,OAAO,GAAG,OAAO,IAAI;IAC7C,CAAC,SAAS,EAAE,MAAM,GAAG;QACnB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;KACvB,CAAC;CACH,CAAC;AAEF,qBAAa,yBAA0B,YAAW,sBAAsB;IACtE,OAAO,CAAC,UAAU,CAAgB;gBAEtB,IAAI,EAAE,aAAa;IAIlB,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAChD,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAO1B,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAChD,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,QAAQ,GACd,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAO1B,kBAAkB,CAAC,QAAQ,SAAS,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,EACvF,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IASrB,sBAAsB,CACjC,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAU3B,2BAA2B,CACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAUrB,uBAAuB,CAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAS3B,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAOnF,mBAAmB,CAAC,SAAS,EACxC,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,QAAQ,CAAC,EAAE,iBAAiB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAqB1B,4BAA4B,CAAC,SAAS,EACjD,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,iBAAiB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC;IAa5B,YAAY,CAAC,QAAQ,EAAE,SAAS,EAC3C,UAAU,EAAE,cAAc,CAAC,QAAQ,CAAC,GACnC,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;CAOxC;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,aAAa,GAAG,yBAAyB,CAErF"}
@@ -0,0 +1,111 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
export class MockDataOperationExecutor {
_dataStore;
constructor(data) {
this._dataStore = data;
}
async createRecordAsync(_tableName, _data) {
return {
success: false,
error: { message: 'createRecordAsync is not supported by MockDataOperationExecutor' },
data: null,
};
}
async updateRecordAsync(_tableName, _id, _data) {
return {
success: false,
error: { message: 'updateRecordAsync is not supported by MockDataOperationExecutor' },
data: null,
};
}
async uploadFileToRecord(tableName, id, columnName, fileName, data) {
return {
success: false,
error: {
message: `uploadFileToRecord is not supported by MockDataOperationExecutor, ${tableName}, ${columnName}, ${fileName}, ${id}, ${JSON.stringify(data)}`,
},
data: undefined,
};
}
async downloadFileFromRecord(tableName, id, columnName) {
return {
success: false,
error: {
message: `downloadFileFromRecord is not supported by MockDataOperationExecutor, ${tableName}, ${columnName}, ${id}`,
},
data: new Uint8Array(0),
};
}
async deleteFileOrImageFromRecord(_tableName, _recordId, _columnName) {
return {
success: false,
error: {
message: 'deleteFileOrImageFromRecord is not supported by MockDataOperationExecutor',
},
data: undefined,
};
}
async downloadImageFromRecord(tableName, recordId, columnName, _fullSize) {
return {
success: false,
error: {
message: `downloadImageFromRecord is not supported by MockDataOperationExecutor, ${tableName}, ${columnName}, ${recordId}`,
},
data: new Uint8Array(0),
};
}
async deleteRecordAsync(_tableName, _id) {
return {
success: false,
error: { message: 'deleteRecordAsync is not supported by MockDataOperationExecutor' },
data: undefined,
};
}
async retrieveRecordAsync(tableName, id, _options) {
if (!this._dataStore[tableName]) {
return {
success: false,
error: { message: `table <${tableName}> not found` },
data: null,
};
}
const record = this._dataStore[tableName][id];
if (!record) {
return {
success: false,
error: { message: `record with id "${id}" not found in table <${tableName}>` },
data: null,
};
}
return {
success: true,
data: record,
};
}
async retrieveMultipleRecordsAsync(tableName, _options) {
if (!this._dataStore[tableName]) {
return {
success: false,
error: { message: `table <${tableName}> not found` },
data: [],
};
}
return {
success: true,
data: Object.values(this._dataStore[tableName]),
};
}
async executeAsync(_operation) {
return {
success: false,
error: { message: 'executeAsync is not supported by MockDataOperationExecutor' },
data: null,
};
}
}
export function createMockDataExecutor(data) {
return new MockDataOperationExecutor(data);
}
//# sourceMappingURL=mockDataOperationExecutor.js.map
@@ -0,0 +1 @@
{"version":3,"file":"mockDataOperationExecutor.js","sourceRoot":"","sources":["../../../../../../src/internal/data/core/data/executors/mockDataOperationExecutor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,MAAM,OAAO,yBAAyB;IAC5B,UAAU,CAAgB;IAElC,YAAY,IAAmB;QAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,iBAAiB,CAC5B,UAAkB,EAClB,KAAe;QAEf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,EAAE,OAAO,EAAE,iEAAiE,EAAE;YACrF,IAAI,EAAE,IAAiB;SACxB,CAAC;IACJ,CAAC;IACM,KAAK,CAAC,iBAAiB,CAC5B,UAAkB,EAClB,GAAW,EACX,KAAe;QAEf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,EAAE,OAAO,EAAE,iEAAiE,EAAE;YACrF,IAAI,EAAE,IAAiB;SACxB,CAAC;IACJ,CAAC;IACM,KAAK,CAAC,kBAAkB,CAC7B,SAAiB,EACjB,EAAU,EACV,UAAkB,EAClB,QAAgB,EAChB,IAAc;QAEd,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE;gBACL,OAAO,EAAE,qEAAqE,SAAS,KAAK,UAAU,KAAK,QAAQ,KAAK,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;aACtJ;YACD,IAAI,EAAE,SAAS;SAChB,CAAC;IACJ,CAAC;IACM,KAAK,CAAC,sBAAsB,CACjC,SAAiB,EACjB,EAAU,EACV,UAAkB;QAElB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE;gBACL,OAAO,EAAE,yEAAyE,SAAS,KAAK,UAAU,KAAK,EAAE,EAAE;aACpH;YACD,IAAI,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC;SACxB,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,2BAA2B,CACtC,UAAkB,EAClB,SAAiB,EACjB,WAAmB;QAEnB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE;gBACL,OAAO,EAAE,2EAA2E;aACrF;YACD,IAAI,EAAE,SAAS;SAChB,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,uBAAuB,CAClC,SAAiB,EACjB,QAAgB,EAChB,UAAkB,EAClB,SAAmB;QAEnB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE;gBACL,OAAO,EAAE,0EAA0E,SAAS,KAAK,UAAU,KAAK,QAAQ,EAAE;aAC3H;YACD,IAAI,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC;SACxB,CAAC;IACJ,CAAC;IACM,KAAK,CAAC,iBAAiB,CAAC,UAAkB,EAAE,GAAW;QAC5D,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,EAAE,OAAO,EAAE,iEAAiE,EAAE;YACrF,IAAI,EAAE,SAAS;SAChB,CAAC;IACJ,CAAC;IACM,KAAK,CAAC,mBAAmB,CAC9B,SAAiB,EACjB,EAAU,EACV,QAA4B;QAE5B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,SAAS,aAAa,EAAE;gBACpD,IAAI,EAAE,IAAiB;aACxB,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,SAAS,GAAG,EAAE;gBAC9E,IAAI,EAAE,IAAiB;aACxB,CAAC;QACJ,CAAC;QACD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,MAAmB;SAC1B,CAAC;IACJ,CAAC;IACM,KAAK,CAAC,4BAA4B,CACvC,SAAiB,EACjB,QAA4B;QAE5B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,EAAE,OAAO,EAAE,UAAU,SAAS,aAAa,EAAE;gBACpD,IAAI,EAAE,EAAE;aACT,CAAC;QACJ,CAAC;QACD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAgB;SAC/D,CAAC;IACJ,CAAC;IACM,KAAK,CAAC,YAAY,CACvB,UAAoC;QAEpC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,EAAE,OAAO,EAAE,4DAA4D,EAAE;YAChF,IAAI,EAAE,IAAiB;SACxB,CAAC;IACJ,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAmB;IACxD,OAAO,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,12 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { IOperationOptions } from '../../../types';
/**
* Converts operation options to a query string format.
* @param options - The operation options to convert.
* @returns The formatted query string.
* @private
*/
export declare function convertOptionsToQueryString(options?: IOperationOptions): string;
//# sourceMappingURL=stringQueryOptions.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"stringQueryOptions.d.ts","sourceRoot":"","sources":["../../../../../../../src/internal/data/core/data/executors/shared/stringQueryOptions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM,CA8C/E"}
@@ -0,0 +1,41 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
/**
* Converts operation options to a query string format.
* @param options - The operation options to convert.
* @returns The formatted query string.
* @private
*/
export function convertOptionsToQueryString(options) {
if (!options) {
return '';
}
const parts = [];
if (options.select && options.select.length > 0) {
parts.push(`$select=${encodeURIComponent(options.select.map((s) => s.trim().replace(/%20/g, '+').replace(/'/g, '%27')).join(','))}`);
}
if (options.filter) {
const encodedFilter = encodeURIComponent(options.filter.trim())
.replace(/%20/g, '+')
.replace(/'/g, '%27');
parts.push(`$filter=${encodedFilter}`);
}
if (options.orderBy && options.orderBy.length > 0) {
parts.push(`$orderby=${encodeURIComponent(options.orderBy.map((s) => s.trim().replace(/%20/g, '+').replace(/'/g, '%27')).join(','))}`);
}
if (options.top !== undefined && options.top !== null) {
parts.push(`$top=${options.top}`);
}
if (options.skip !== undefined && options.skip !== null) {
parts.push(`$skip=${options.skip}`);
}
if (options.count !== undefined && options.count !== null) {
parts.push(`$count=${options.count}`);
}
if (options.skipToken && options.skipToken.trim() !== '') {
parts.push(`$skiptoken=${encodeURIComponent(options.skipToken.trim())}`);
}
return parts.length ? `?${parts.join('&')}` : '';
}
//# sourceMappingURL=stringQueryOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"stringQueryOptions.js","sourceRoot":"","sources":["../../../../../../../src/internal/data/core/data/executors/shared/stringQueryOptions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CAAC,OAA2B;IACrE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CACR,WAAW,kBAAkB,CAC3B,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CACxF,EAAE,CACJ,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;aAC5D,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;aACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,WAAW,aAAa,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,KAAK,CAAC,IAAI,CACR,YAAY,kBAAkB,CAC5B,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CACzF,EAAE,CACJ,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACtD,KAAK,CAAC,IAAI,CAAC,QAAQ,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1D,KAAK,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,cAAc,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACnD,CAAC"}
@@ -0,0 +1,32 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
/**
* Error types specific to DataRuntime
* @private
*/
export declare enum ErrorCodes {
InitializationFailed = "PDR_INIT_FAILED",
InvalidXrmInfo = "INVALID_XRM_INFO",
OperationsNotInitialized = "OPS_NOT_INITIALIZED",
InvalidOperationExecutor = "INVALID_OPERATION_EXECUTOR",
DataSourceNotFound = "CONNECTION_NOT_FOUND",
DuplicateDataSource = "DUPLICATE_DATA_SOURCE",
InitializationError = "RDSS_INIT_ERROR",
InvalidDataSource = "INVALID_DATA_SOURCE",
DataSourcesInfoNotFound = "DATA_SOURCES_INFO_NOT_FOUND",
DataClientInitFailed = "DATA_CLIENT_INIT_FAILED",
DataClientNotInitialized = "DATA_CLIENT_NOT_INITIALIZED",
MetadataClientInitFailed = "METADATA_CLIENT_INIT_FAILED",
MetadataClientNotInitialized = "METADATA_CLIENT_NOT_INITIALIZED",
ClientProviderNotAvailable = "CLIENT_PROVIDER_NOT_AVAILABLE",
ConnectionReferenceNotFound = "CONNECTION_REFERENCE_NOT_FOUND",
DataClientNotAvailable = "DATA_CLIENT_NOT_AVAILABLE",
DataSourceServiceNotAvailable = "DATA_SOURCE_SERVICE_NOT_AVAILABLE",
MetadataClientNotAvailable = "METADATA_CLIENT_NOT_AVAILABLE",
ConnectionConfigFetchFailed = "CONNECTION_CONFIG_FETCH_FAILED",
DataSourceConfigFetchFailed = "DATA_SOURCE_CONFIG_FETCH_FAILED",
InvalidMetadataResponse = "INVALID_METADATA_RESPONSE",
TokenAcquisitionFailed = "TOKEN_ACQUISITION_FAILED"
}
//# sourceMappingURL=codes.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"codes.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/error/codes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,oBAAY,UAAU;IAEpB,oBAAoB,oBAAoB;IACxC,cAAc,qBAAqB;IACnC,wBAAwB,wBAAwB;IAChD,wBAAwB,+BAA+B;IAGvD,kBAAkB,yBAAyB;IAC3C,mBAAmB,0BAA0B;IAC7C,mBAAmB,oBAAoB;IACvC,iBAAiB,wBAAwB;IAGzC,uBAAuB,gCAAgC;IAGvD,oBAAoB,4BAA4B;IAChD,wBAAwB,gCAAgC;IACxD,wBAAwB,gCAAgC;IACxD,4BAA4B,oCAAoC;IAGhE,0BAA0B,kCAAkC;IAC5D,2BAA2B,mCAAmC;IAC9D,sBAAsB,8BAA8B;IACpD,6BAA6B,sCAAsC;IACnE,0BAA0B,kCAAkC;IAG5D,2BAA2B,mCAAmC;IAC9D,2BAA2B,oCAAoC;IAC/D,uBAAuB,8BAA8B;IAGrD,sBAAsB,6BAA6B;CACpD"}
@@ -0,0 +1,40 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
/**
* Error types specific to DataRuntime
* @private
*/
export var ErrorCodes;
(function (ErrorCodes) {
// PowerDataRuntime specific errors
ErrorCodes["InitializationFailed"] = "PDR_INIT_FAILED";
ErrorCodes["InvalidXrmInfo"] = "INVALID_XRM_INFO";
ErrorCodes["OperationsNotInitialized"] = "OPS_NOT_INITIALIZED";
ErrorCodes["InvalidOperationExecutor"] = "INVALID_OPERATION_EXECUTOR";
// RuntimeDataSourceService specific errors
ErrorCodes["DataSourceNotFound"] = "CONNECTION_NOT_FOUND";
ErrorCodes["DuplicateDataSource"] = "DUPLICATE_DATA_SOURCE";
ErrorCodes["InitializationError"] = "RDSS_INIT_ERROR";
ErrorCodes["InvalidDataSource"] = "INVALID_DATA_SOURCE";
// PowerDataSourcesInfoProvider specific errors
ErrorCodes["DataSourcesInfoNotFound"] = "DATA_SOURCES_INFO_NOT_FOUND";
// DataClientProvider specific errors
ErrorCodes["DataClientInitFailed"] = "DATA_CLIENT_INIT_FAILED";
ErrorCodes["DataClientNotInitialized"] = "DATA_CLIENT_NOT_INITIALIZED";
ErrorCodes["MetadataClientInitFailed"] = "METADATA_CLIENT_INIT_FAILED";
ErrorCodes["MetadataClientNotInitialized"] = "METADATA_CLIENT_NOT_INITIALIZED";
// DataOperation specific errors
ErrorCodes["ClientProviderNotAvailable"] = "CLIENT_PROVIDER_NOT_AVAILABLE";
ErrorCodes["ConnectionReferenceNotFound"] = "CONNECTION_REFERENCE_NOT_FOUND";
ErrorCodes["DataClientNotAvailable"] = "DATA_CLIENT_NOT_AVAILABLE";
ErrorCodes["DataSourceServiceNotAvailable"] = "DATA_SOURCE_SERVICE_NOT_AVAILABLE";
ErrorCodes["MetadataClientNotAvailable"] = "METADATA_CLIENT_NOT_AVAILABLE";
// MetadataClient specific errors
ErrorCodes["ConnectionConfigFetchFailed"] = "CONNECTION_CONFIG_FETCH_FAILED";
ErrorCodes["DataSourceConfigFetchFailed"] = "DATA_SOURCE_CONFIG_FETCH_FAILED";
ErrorCodes["InvalidMetadataResponse"] = "INVALID_METADATA_RESPONSE";
// RuntimeDataClient specific errors
ErrorCodes["TokenAcquisitionFailed"] = "TOKEN_ACQUISITION_FAILED";
})(ErrorCodes || (ErrorCodes = {}));
//# sourceMappingURL=codes.js.map
@@ -0,0 +1 @@
{"version":3,"file":"codes.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/error/codes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,CAAN,IAAY,UAoCX;AApCD,WAAY,UAAU;IACpB,mCAAmC;IACnC,sDAAwC,CAAA;IACxC,iDAAmC,CAAA;IACnC,8DAAgD,CAAA;IAChD,qEAAuD,CAAA;IAEvD,2CAA2C;IAC3C,yDAA2C,CAAA;IAC3C,2DAA6C,CAAA;IAC7C,qDAAuC,CAAA;IACvC,uDAAyC,CAAA;IAEzC,+CAA+C;IAC/C,qEAAuD,CAAA;IAEvD,qCAAqC;IACrC,8DAAgD,CAAA;IAChD,sEAAwD,CAAA;IACxD,sEAAwD,CAAA;IACxD,8EAAgE,CAAA;IAEhE,gCAAgC;IAChC,0EAA4D,CAAA;IAC5D,4EAA8D,CAAA;IAC9D,kEAAoD,CAAA;IACpD,iFAAmE,CAAA;IACnE,0EAA4D,CAAA;IAE5D,iCAAiC;IACjC,4EAA8D,CAAA;IAC9D,6EAA+D,CAAA;IAC/D,mEAAqD,CAAA;IAErD,oCAAoC;IACpC,iEAAmD,CAAA;AACrD,CAAC,EApCW,UAAU,KAAV,UAAU,QAoCrB"}
@@ -0,0 +1,37 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
/** @private */
export declare enum HeaderNames {
/**
* The name of the header used to specify the request ID.
*/
RequestId = "x-ms-client-request-id"
}
/**
* Enum for DataverseDataOperation operation names.
* @private
*/
export declare enum DataverseOperationName {
CreateRecord = "dataverseDataOperation.createRecordAsync",
UpdateRecord = "dataverseDataOperation.updateRecordAsync",
UploadRecord = "dataverseDataOperation.uploadFileToRecord",
DownloadRecord = "dataverseDataOperation.downloadFileFromRecord",
DeleteRecord = "dataverseDataOperation.deleteRecordAsync",
DeleteFileOrImageRecord = "dataverseDataOperation.deleteFileOrImageFromRecord",
RetrieveRecord = "dataverseDataOperation.retrieveRecordAsync",
RetrieveMultipleRecords = "dataverseDataOperation.retrieveMultipleRecordsAsync",
ExecuteCustomApi = "dataverseDataOperation.executeCustomApi"
}
/**
* Enum for ConnectorDataOperation operation names.
* @private
*/
export declare enum ConnectorOperationName {
CreateRecord = "connectorDataOperation.createRecordAsync",
UpdateRecord = "connectorDataOperation.updateRecordAsync",
DeleteRecord = "connectorDataOperation.deleteRecordAsync",
RetrieveRecord = "connectorDataOperation.retrieveRecordAsync",
RetrieveMultipleRecords = "connectorDataOperation.retrieveMultipleRecordsAsync"
}
//# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/error/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAe;AACf,oBAAY,WAAW;IACrB;;OAEG;IACH,SAAS,2BAA2B;CACrC;AAED;;;GAGG;AACH,oBAAY,sBAAsB;IAChC,YAAY,6CAA6C;IACzD,YAAY,6CAA6C;IACzD,YAAY,8CAA8C;IAC1D,cAAc,kDAAkD;IAChE,YAAY,6CAA6C;IACzD,uBAAuB,uDAAuD;IAC9E,cAAc,+CAA+C;IAC7D,uBAAuB,wDAAwD;IAC/E,gBAAgB,4CAA4C;CAC7D;AAED;;;GAGG;AACH,oBAAY,sBAAsB;IAChC,YAAY,6CAA6C;IACzD,YAAY,6CAA6C;IACzD,YAAY,6CAA6C;IACzD,cAAc,+CAA+C;IAC7D,uBAAuB,wDAAwD;CAChF"}
@@ -0,0 +1,40 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
/** @private */
export var HeaderNames;
(function (HeaderNames) {
/**
* The name of the header used to specify the request ID.
*/
HeaderNames["RequestId"] = "x-ms-client-request-id";
})(HeaderNames || (HeaderNames = {}));
/**
* Enum for DataverseDataOperation operation names.
* @private
*/
export var DataverseOperationName;
(function (DataverseOperationName) {
DataverseOperationName["CreateRecord"] = "dataverseDataOperation.createRecordAsync";
DataverseOperationName["UpdateRecord"] = "dataverseDataOperation.updateRecordAsync";
DataverseOperationName["UploadRecord"] = "dataverseDataOperation.uploadFileToRecord";
DataverseOperationName["DownloadRecord"] = "dataverseDataOperation.downloadFileFromRecord";
DataverseOperationName["DeleteRecord"] = "dataverseDataOperation.deleteRecordAsync";
DataverseOperationName["DeleteFileOrImageRecord"] = "dataverseDataOperation.deleteFileOrImageFromRecord";
DataverseOperationName["RetrieveRecord"] = "dataverseDataOperation.retrieveRecordAsync";
DataverseOperationName["RetrieveMultipleRecords"] = "dataverseDataOperation.retrieveMultipleRecordsAsync";
DataverseOperationName["ExecuteCustomApi"] = "dataverseDataOperation.executeCustomApi";
})(DataverseOperationName || (DataverseOperationName = {}));
/**
* Enum for ConnectorDataOperation operation names.
* @private
*/
export var ConnectorOperationName;
(function (ConnectorOperationName) {
ConnectorOperationName["CreateRecord"] = "connectorDataOperation.createRecordAsync";
ConnectorOperationName["UpdateRecord"] = "connectorDataOperation.updateRecordAsync";
ConnectorOperationName["DeleteRecord"] = "connectorDataOperation.deleteRecordAsync";
ConnectorOperationName["RetrieveRecord"] = "connectorDataOperation.retrieveRecordAsync";
ConnectorOperationName["RetrieveMultipleRecords"] = "connectorDataOperation.retrieveMultipleRecordsAsync";
})(ConnectorOperationName || (ConnectorOperationName = {}));
//# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/error/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAe;AACf,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB;;OAEG;IACH,mDAAoC,CAAA;AACtC,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,sBAUX;AAVD,WAAY,sBAAsB;IAChC,mFAAyD,CAAA;IACzD,mFAAyD,CAAA;IACzD,oFAA0D,CAAA;IAC1D,0FAAgE,CAAA;IAChE,mFAAyD,CAAA;IACzD,wGAA8E,CAAA;IAC9E,uFAA6D,CAAA;IAC7D,yGAA+E,CAAA;IAC/E,sFAA4D,CAAA;AAC9D,CAAC,EAVW,sBAAsB,KAAtB,sBAAsB,QAUjC;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,sBAMX;AAND,WAAY,sBAAsB;IAChC,mFAAyD,CAAA;IACzD,mFAAyD,CAAA;IACzD,mFAAyD,CAAA;IACzD,uFAA6D,CAAA;IAC7D,yGAA+E,CAAA;AACjF,CAAC,EANW,sBAAsB,KAAtB,sBAAsB,QAMjC"}
@@ -0,0 +1,8 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
export * from './codes';
export * from './messages';
export * from './types';
export * from './util';
//# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/error/error.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,8 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
export * from './codes';
export * from './messages';
export * from './types';
export * from './util';
//# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/error/error.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,31 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { ErrorCodes } from './codes';
/** @private */
export declare const UnknownErrorMessage = "An unknown error occurred";
/** @private */
export declare const ErrorMessages: {
[key in ErrorCodes]?: string;
};
/** @private */
export declare enum DataOperationErrorMessages {
CreateFailed = "Create operation failure",
DeleteFailed = "Delete operation failure",
ExecuteFailed = "Execute operation failure",
InvalidOperationParameters = "Invalid operation parameters",
InvalidRequest = "Invalid request",
InvalidResponse = "Invalid response format",
MissingConnectorOperation = "Connector operation is required",
MissingDataverseRequest = "Dataverse request is required",
MissingOperationName = "Operation name is required",
MissingRequestBody = "Request body is required",
RetrieveFailed = "Retrieve operation failure",
RetrieveMultipleFailed = "Retrieve multiple records operation failure",
UpdateFailed = "Update operation failure",
UploadFailed = "Upload operation failure",
DownloadFailed = "Download operation failure",
DeleteFileOrImageFailed = "Delete file or image operation failure",
MissingFileData = "File data is required"
}
//# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/error/messages.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,eAAe;AACf,eAAO,MAAM,mBAAmB,8BAA8B,CAAC;AAE/D,eAAe;AACf,eAAO,MAAM,aAAa,EAAE;KAAG,GAAG,IAAI,UAAU,CAAC,CAAC,EAAE,MAAM;CAoCzD,CAAC;AAKF,eAAe;AACf,oBAAY,0BAA0B;IACpC,YAAY,6BAA6B;IACzC,YAAY,6BAA6B;IACzC,aAAa,8BAA8B;IAC3C,0BAA0B,iCAAiC;IAC3D,cAAc,oBAAoB;IAClC,eAAe,4BAA4B;IAC3C,yBAAyB,oCAAoC;IAC7D,uBAAuB,kCAAkC;IACzD,oBAAoB,+BAA+B;IACnD,kBAAkB,6BAA6B;IAC/C,cAAc,+BAA+B;IAC7C,sBAAsB,gDAAgD;IACtE,YAAY,6BAA6B;IACzC,YAAY,6BAA6B;IACzC,cAAc,+BAA+B;IAC7C,uBAAuB,2CAA2C;IAClE,eAAe,0BAA0B;CAC1C"}
@@ -0,0 +1,62 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { ErrorCodes } from './codes';
/** @private */
export const UnknownErrorMessage = 'An unknown error occurred';
/** @private */
export const ErrorMessages = {
// PowerDataRuntime specific errors
[ErrorCodes.InitializationFailed]: 'Failed to initialize PowerDataRuntime',
[ErrorCodes.InvalidXrmInfo]: 'Xrm info is required',
[ErrorCodes.OperationsNotInitialized]: 'PowerDataRuntime is not initialized',
// RuntimeDataSourceService specific errors
[ErrorCodes.DataSourceNotFound]: 'Data source not found',
[ErrorCodes.DuplicateDataSource]: 'Duplicate data source',
[ErrorCodes.InitializationError]: 'Failed to initialize RuntimeDataSourceService',
[ErrorCodes.InvalidDataSource]: 'Invalid data source',
// PowerDataSourcesInfoProvider specific errors
[ErrorCodes.DataSourcesInfoNotFound]: 'DataSourcesInfo must be provided to initialize the singleton instance.',
// DataClientProvider specific errors
[ErrorCodes.DataClientInitFailed]: 'Failed to initialize PowerDataClient',
[ErrorCodes.DataClientNotInitialized]: 'PowerDataClient is not initialized',
[ErrorCodes.MetadataClientInitFailed]: 'Failed to initialize PowerMetadataClient',
[ErrorCodes.MetadataClientNotInitialized]: 'PowerMetadataClient is not initialized',
// DataOperation specific errors
[ErrorCodes.ClientProviderNotAvailable]: 'Client provider is not available',
[ErrorCodes.ConnectionReferenceNotFound]: 'Connection reference not found',
[ErrorCodes.DataClientNotAvailable]: 'PowerDataClient is not available',
[ErrorCodes.DataSourceServiceNotAvailable]: 'Data source service is not available',
[ErrorCodes.MetadataClientNotAvailable]: 'PowerMetadataClient is not available',
// MetadataClient specific errors
[ErrorCodes.ConnectionConfigFetchFailed]: 'Failed to fetch connection configurations',
[ErrorCodes.DataSourceConfigFetchFailed]: 'Failed to fetch data source configurations',
[ErrorCodes.InvalidMetadataResponse]: 'Invalid metadata response format',
// RuntimeDataClient specific errors
[ErrorCodes.TokenAcquisitionFailed]: 'Failed to acquire access token',
};
// The following error messages are returned to the client whenever a data
// operation fails. They are not explicitly logged to telemetry as exceptions,
// but are logged as part of the http pipeline.
/** @private */
export var DataOperationErrorMessages;
(function (DataOperationErrorMessages) {
DataOperationErrorMessages["CreateFailed"] = "Create operation failure";
DataOperationErrorMessages["DeleteFailed"] = "Delete operation failure";
DataOperationErrorMessages["ExecuteFailed"] = "Execute operation failure";
DataOperationErrorMessages["InvalidOperationParameters"] = "Invalid operation parameters";
DataOperationErrorMessages["InvalidRequest"] = "Invalid request";
DataOperationErrorMessages["InvalidResponse"] = "Invalid response format";
DataOperationErrorMessages["MissingConnectorOperation"] = "Connector operation is required";
DataOperationErrorMessages["MissingDataverseRequest"] = "Dataverse request is required";
DataOperationErrorMessages["MissingOperationName"] = "Operation name is required";
DataOperationErrorMessages["MissingRequestBody"] = "Request body is required";
DataOperationErrorMessages["RetrieveFailed"] = "Retrieve operation failure";
DataOperationErrorMessages["RetrieveMultipleFailed"] = "Retrieve multiple records operation failure";
DataOperationErrorMessages["UpdateFailed"] = "Update operation failure";
DataOperationErrorMessages["UploadFailed"] = "Upload operation failure";
DataOperationErrorMessages["DownloadFailed"] = "Download operation failure";
DataOperationErrorMessages["DeleteFileOrImageFailed"] = "Delete file or image operation failure";
DataOperationErrorMessages["MissingFileData"] = "File data is required";
})(DataOperationErrorMessages || (DataOperationErrorMessages = {}));
//# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/error/messages.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,eAAe;AACf,MAAM,CAAC,MAAM,mBAAmB,GAAG,2BAA2B,CAAC;AAE/D,eAAe;AACf,MAAM,CAAC,MAAM,aAAa,GAAqC;IAC7D,mCAAmC;IACnC,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,uCAAuC;IAC1E,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,sBAAsB;IACnD,CAAC,UAAU,CAAC,wBAAwB,CAAC,EAAE,qCAAqC;IAE5E,2CAA2C;IAC3C,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,uBAAuB;IACxD,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,uBAAuB;IACzD,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,+CAA+C;IACjF,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,qBAAqB;IAErD,+CAA+C;IAC/C,CAAC,UAAU,CAAC,uBAAuB,CAAC,EAClC,wEAAwE;IAE1E,qCAAqC;IACrC,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,sCAAsC;IACzE,CAAC,UAAU,CAAC,wBAAwB,CAAC,EAAE,oCAAoC;IAC3E,CAAC,UAAU,CAAC,wBAAwB,CAAC,EAAE,0CAA0C;IACjF,CAAC,UAAU,CAAC,4BAA4B,CAAC,EAAE,wCAAwC;IAEnF,gCAAgC;IAChC,CAAC,UAAU,CAAC,0BAA0B,CAAC,EAAE,kCAAkC;IAC3E,CAAC,UAAU,CAAC,2BAA2B,CAAC,EAAE,gCAAgC;IAC1E,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,kCAAkC;IACvE,CAAC,UAAU,CAAC,6BAA6B,CAAC,EAAE,sCAAsC;IAClF,CAAC,UAAU,CAAC,0BAA0B,CAAC,EAAE,sCAAsC;IAE/E,iCAAiC;IACjC,CAAC,UAAU,CAAC,2BAA2B,CAAC,EAAE,2CAA2C;IACrF,CAAC,UAAU,CAAC,2BAA2B,CAAC,EAAE,4CAA4C;IACtF,CAAC,UAAU,CAAC,uBAAuB,CAAC,EAAE,kCAAkC;IAExE,oCAAoC;IACpC,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,gCAAgC;CACtE,CAAC;AAEF,0EAA0E;AAC1E,8EAA8E;AAC9E,+CAA+C;AAC/C,eAAe;AACf,MAAM,CAAN,IAAY,0BAkBX;AAlBD,WAAY,0BAA0B;IACpC,uEAAyC,CAAA;IACzC,uEAAyC,CAAA;IACzC,yEAA2C,CAAA;IAC3C,yFAA2D,CAAA;IAC3D,gEAAkC,CAAA;IAClC,yEAA2C,CAAA;IAC3C,2FAA6D,CAAA;IAC7D,uFAAyD,CAAA;IACzD,iFAAmD,CAAA;IACnD,6EAA+C,CAAA;IAC/C,2EAA6C,CAAA;IAC7C,oGAAsE,CAAA;IACtE,uEAAyC,CAAA;IACzC,uEAAyC,CAAA;IACzC,2EAA6C,CAAA;IAC7C,gGAAkE,CAAA;IAClE,uEAAyC,CAAA;AAC3C,CAAC,EAlBW,0BAA0B,KAA1B,0BAA0B,QAkBrC"}
@@ -0,0 +1,33 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import type { ErrorCodes } from './codes';
/**
* Base error class for PowerDataRuntime operations
* @private
*/
export declare class PowerDataRuntimeError extends Error {
readonly code: ErrorCodes;
/**
* Creates an instance of PowerDataRuntimeError.
* @param code - The error code associated with the error.
* @param additionalInfo - Optional additional information to include in the error message.
* @param messageOverride - Optional override for the default error message.
*/
constructor(code: ErrorCodes, additionalInfo?: string, messageOverride?: string);
}
/** @private */
export interface PowerDataRuntimeHttpError {
message: string;
status?: number;
requestId?: string;
stack?: string;
}
/** @private */
export interface HttpErrorResponse {
status?: number;
headers?: {
[key: string]: string;
};
}
//# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/internal/data/core/error/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;aAQ5B,IAAI,EAAE,UAAU;IAPlC;;;;;OAKG;gBAEe,IAAI,EAAE,UAAU,EAChC,cAAc,CAAC,EAAE,MAAM,EACvB,eAAe,CAAC,EAAE,MAAM;CAU3B;AAED,eAAe;AACf,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAe;AACf,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE;QACR,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;CACH"}
@@ -0,0 +1,29 @@
/*!
* Copyright (C) Microsoft Corporation. All rights reserved.
*/
import { Log } from '../telemetry/log';
import { ErrorMessages, UnknownErrorMessage } from './messages';
/**
* Base error class for PowerDataRuntime operations
* @private
*/
export class PowerDataRuntimeError extends Error {
code;
/**
* Creates an instance of PowerDataRuntimeError.
* @param code - The error code associated with the error.
* @param additionalInfo - Optional additional information to include in the error message.
* @param messageOverride - Optional override for the default error message.
*/
constructor(code, additionalInfo, messageOverride) {
let message = messageOverride || ErrorMessages[code] || UnknownErrorMessage;
if (additionalInfo) {
message += `: ${additionalInfo}`;
}
super(message);
this.code = code;
this.name = 'PowerDataRuntimeError';
Log.trackException(this);
}
}
//# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/internal/data/core/error/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEhE;;;GAGG;AACH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAQ5B;IAPlB;;;;;OAKG;IACH,YACkB,IAAgB,EAChC,cAAuB,EACvB,eAAwB;QAExB,IAAI,OAAO,GAAG,eAAe,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC;QAC5E,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,IAAI,KAAK,cAAc,EAAE,CAAC;QACnC,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,CAAC;QARC,SAAI,GAAJ,IAAI,CAAY;QAShC,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;CACF"}

Some files were not shown because too many files have changed in this diff Show More