mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
Added tests and changed name
This commit is contained in:
parent
541f289466
commit
0a57678acc
|
@ -6,14 +6,17 @@ import {
|
||||||
type INodeProperties,
|
type INodeProperties,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import { getAuthorizationTokenUsingMasterKey } from '../nodes/Microsoft/AzureCosmosDB/GenericFunctions';
|
import {
|
||||||
|
getAuthorizationTokenUsingMasterKey,
|
||||||
|
HeaderConstants,
|
||||||
|
} from '../nodes/Microsoft/CosmosDB/GenericFunctions';
|
||||||
|
|
||||||
export class AzureCosmosDbSharedKeyApi implements ICredentialType {
|
export class MicrosoftCosmosDbSharedKeyApi implements ICredentialType {
|
||||||
name = 'azureCosmosDbSharedKeyApi';
|
name = 'microsoftCosmosDbSharedKeyApi';
|
||||||
|
|
||||||
displayName = 'Azure Cosmos DB API';
|
displayName = 'Azure Cosmos DB API';
|
||||||
|
|
||||||
documentationUrl = 'azureCosmosDb';
|
documentationUrl = 'microsoftCosmosDb';
|
||||||
|
|
||||||
properties: INodeProperties[] = [
|
properties: INodeProperties[] = [
|
||||||
{
|
{
|
||||||
|
@ -75,8 +78,9 @@ export class AzureCosmosDbSharedKeyApi implements ICredentialType {
|
||||||
}
|
}
|
||||||
|
|
||||||
let resourceType = '';
|
let resourceType = '';
|
||||||
const resourceLink = requestOptions.url;
|
const resourceLink = '/dbs/first_database_1' + requestOptions.url;
|
||||||
|
|
||||||
|
console.log('Link', resourceLink);
|
||||||
if (resourceLink.includes('/colls')) {
|
if (resourceLink.includes('/colls')) {
|
||||||
resourceType = 'colls';
|
resourceType = 'colls';
|
||||||
} else if (resourceLink.includes('/docs')) {
|
} else if (resourceLink.includes('/docs')) {
|
||||||
|
@ -86,6 +90,7 @@ export class AzureCosmosDbSharedKeyApi implements ICredentialType {
|
||||||
} else {
|
} else {
|
||||||
throw new ApplicationError('Unable to determine resourceType');
|
throw new ApplicationError('Unable to determine resourceType');
|
||||||
}
|
}
|
||||||
|
console.log('Type', resourceType);
|
||||||
|
|
||||||
if (requestOptions.method) {
|
if (requestOptions.method) {
|
||||||
const authToken = getAuthorizationTokenUsingMasterKey(
|
const authToken = getAuthorizationTokenUsingMasterKey(
|
||||||
|
@ -96,10 +101,10 @@ export class AzureCosmosDbSharedKeyApi implements ICredentialType {
|
||||||
credentials.key as string,
|
credentials.key as string,
|
||||||
);
|
);
|
||||||
|
|
||||||
requestOptions.headers.Authorization = authToken;
|
requestOptions.headers[HeaderConstants.AUTHORIZATION] = authToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Final requestOptions headers:', requestOptions.headers);
|
console.log('Final requestOptions:', requestOptions);
|
||||||
|
|
||||||
return requestOptions;
|
return requestOptions;
|
||||||
}
|
}
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
@ -7,8 +7,8 @@ import { searchCollections } from './GenericFunctions';
|
||||||
|
|
||||||
export class AzureCosmosDb implements INodeType {
|
export class AzureCosmosDb implements INodeType {
|
||||||
description: INodeTypeDescription = {
|
description: INodeTypeDescription = {
|
||||||
displayName: 'Azure Cosmos DB',
|
displayName: 'Cosmos DB',
|
||||||
name: 'azureCosmosDb',
|
name: 'cosmosDb',
|
||||||
icon: {
|
icon: {
|
||||||
light: 'file:CosmosDB.svg',
|
light: 'file:CosmosDB.svg',
|
||||||
dark: 'file:CosmosDB.svg',
|
dark: 'file:CosmosDB.svg',
|
||||||
|
@ -24,7 +24,7 @@ export class AzureCosmosDb implements INodeType {
|
||||||
outputs: [NodeConnectionType.Main],
|
outputs: [NodeConnectionType.Main],
|
||||||
credentials: [
|
credentials: [
|
||||||
{
|
{
|
||||||
name: 'azureCosmosDbSharedKeyApi',
|
name: 'microsoftCosmosDbSharedKeyApi',
|
||||||
required: true,
|
required: true,
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
|
@ -11,34 +11,34 @@ import type {
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { ApplicationError } from 'n8n-workflow';
|
import { ApplicationError } from 'n8n-workflow';
|
||||||
|
|
||||||
// export const HeaderConstants = {
|
export const HeaderConstants = {
|
||||||
// // Required
|
// Required
|
||||||
// AUTHORIZATION: 'Authorization',
|
AUTHORIZATION: 'Authorization',
|
||||||
// CONTENT_TYPE: 'Content-Type',
|
CONTENT_TYPE: 'Content-Type',
|
||||||
// X_MS_DATE: 'x-ms-date',
|
X_MS_DATE: 'x-ms-date',
|
||||||
// X_MS_VERSION: 'x-ms-version',
|
X_MS_VERSION: 'x-ms-version',
|
||||||
|
|
||||||
// //Required - for session consistency only
|
//Required - for session consistency only
|
||||||
// X_MS_SESSION_TOKEN: 'x-ms-session-token',
|
X_MS_SESSION_TOKEN: 'x-ms-session-token',
|
||||||
|
|
||||||
// // Optional
|
// Optional
|
||||||
// IF_MATCH: 'If-Match',
|
IF_MATCH: 'If-Match',
|
||||||
// IF_NONE_MATCH: 'If-None-Match',
|
IF_NONE_MATCH: 'If-None-Match',
|
||||||
// IF_MODIFIED_SINCE: 'If-Modified-Since',
|
IF_MODIFIED_SINCE: 'If-Modified-Since',
|
||||||
// USER_AGENT: 'User-Agent',
|
USER_AGENT: 'User-Agent',
|
||||||
// X_MS_ACTIVITY_ID: 'x-ms-activity-id',
|
X_MS_ACTIVITY_ID: 'x-ms-activity-id',
|
||||||
// X_MS_CONSISTENCY_LEVEL: 'x-ms-consistency-level',
|
X_MS_CONSISTENCY_LEVEL: 'x-ms-consistency-level',
|
||||||
// X_MS_CONTINUATION: 'x-ms-continuation',
|
X_MS_CONTINUATION: 'x-ms-continuation',
|
||||||
// X_MS_MAX_ITEM_COUNT: 'x-ms-max-item-count',
|
X_MS_MAX_ITEM_COUNT: 'x-ms-max-item-count',
|
||||||
// X_MS_DOCUMENTDB_PARTITIONKEY: 'x-ms-documentdb-partitionkey',
|
X_MS_DOCUMENTDB_PARTITIONKEY: 'x-ms-documentdb-partitionkey',
|
||||||
// X_MS_DOCUMENTDB_ISQUERY: 'x-ms-documentdb-isquery',
|
X_MS_DOCUMENTDB_ISQUERY: 'x-ms-documentdb-isquery',
|
||||||
// X_MS_DOCUMENTDB_QUERY_ENABLECROSSPARTITION: 'x-ms-documentdb-query-enablecrosspartition',
|
X_MS_DOCUMENTDB_QUERY_ENABLECROSSPARTITION: 'x-ms-documentdb-query-enablecrosspartition',
|
||||||
// A_IM: 'A-IM',
|
A_IM: 'A-IM',
|
||||||
// X_MS_DOCUMENTDB_PARTITIONKEYRANGEID: 'x-ms-documentdb-partitionkeyrangeid',
|
X_MS_DOCUMENTDB_PARTITIONKEYRANGEID: 'x-ms-documentdb-partitionkeyrangeid',
|
||||||
// X_MS_COSMOS_ALLOW_TENTATIVE_WRITES: 'x-ms-cosmos-allow-tentative-writes',
|
X_MS_COSMOS_ALLOW_TENTATIVE_WRITES: 'x-ms-cosmos-allow-tentative-writes',
|
||||||
|
|
||||||
// PREFIX_FOR_STORAGE: 'x-ms-',
|
PREFIX_FOR_STORAGE: 'x-ms-',
|
||||||
// };
|
};
|
||||||
|
|
||||||
export function getAuthorizationTokenUsingMasterKey(
|
export function getAuthorizationTokenUsingMasterKey(
|
||||||
verb: string,
|
verb: string,
|
||||||
|
@ -52,15 +52,13 @@ export function getAuthorizationTokenUsingMasterKey(
|
||||||
`${verb.toLowerCase()}\n` +
|
`${verb.toLowerCase()}\n` +
|
||||||
`${resourceType.toLowerCase()}\n` +
|
`${resourceType.toLowerCase()}\n` +
|
||||||
`${resourceLink}\n` +
|
`${resourceLink}\n` +
|
||||||
`${date.toLowerCase()}\n` +
|
`${date}\n` +
|
||||||
'\n';
|
'\n';
|
||||||
|
|
||||||
const hmacSha256 = crypto.createHmac('sha256', key);
|
const hmacSha256 = crypto.createHmac('sha256', key);
|
||||||
const hashPayload = hmacSha256.update(payload, 'utf8').digest('base64');
|
const hashPayload = hmacSha256.update(payload, 'utf8').digest('base64');
|
||||||
|
|
||||||
const authorizationString = `type=master&ver=1.0&sig=${hashPayload}`;
|
return encodeURIComponent('type=master&ver=1.0&sig=' + hashPayload);
|
||||||
|
|
||||||
return authorizationString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function handlePagination(
|
export async function handlePagination(
|
||||||
|
@ -118,11 +116,11 @@ export async function handlePagination(
|
||||||
return aggregatedResult.map((result) => ({ json: result }));
|
return aggregatedResult.map((result) => ({ json: result }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function azureCosmosDbRequest(
|
export async function microsoftCosmosDbRequest(
|
||||||
this: ILoadOptionsFunctions,
|
this: ILoadOptionsFunctions,
|
||||||
opts: IHttpRequestOptions,
|
opts: IHttpRequestOptions,
|
||||||
): Promise<IDataObject> {
|
): Promise<IDataObject> {
|
||||||
const credentials = await this.getCredentials('azureCosmosDbSharedKeyApi');
|
const credentials = await this.getCredentials('microsoftCosmosDbSharedKeyApi');
|
||||||
const databaseAccount = credentials?.account;
|
const databaseAccount = credentials?.account;
|
||||||
|
|
||||||
if (!databaseAccount) {
|
if (!databaseAccount) {
|
||||||
|
@ -131,7 +129,7 @@ export async function azureCosmosDbRequest(
|
||||||
|
|
||||||
const requestOptions: IHttpRequestOptions = {
|
const requestOptions: IHttpRequestOptions = {
|
||||||
...opts,
|
...opts,
|
||||||
baseURL: `https://${databaseAccount}.documents.azure.com`,
|
baseURL: `${credentials.baseUrl}`,
|
||||||
headers: {
|
headers: {
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
@ -156,7 +154,7 @@ export async function azureCosmosDbRequest(
|
||||||
|
|
||||||
return (await this.helpers.requestWithAuthentication.call(
|
return (await this.helpers.requestWithAuthentication.call(
|
||||||
this,
|
this,
|
||||||
'azureCosmosDbSharedKeyApi',
|
'microsoftCosmosDbSharedKeyApi',
|
||||||
requestOptions,
|
requestOptions,
|
||||||
)) as IDataObject;
|
)) as IDataObject;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -197,7 +195,7 @@ export async function searchCollections(
|
||||||
url: '/colls',
|
url: '/colls',
|
||||||
};
|
};
|
||||||
|
|
||||||
const responseData: IDataObject = await azureCosmosDbRequest.call(this, opts);
|
const responseData: IDataObject = await microsoftCosmosDbRequest.call(this, opts);
|
||||||
|
|
||||||
const responseBody = responseData as {
|
const responseBody = responseData as {
|
||||||
DocumentCollections: IDataObject[];
|
DocumentCollections: IDataObject[];
|
||||||
|
@ -220,37 +218,3 @@ export async function searchCollections(
|
||||||
results,
|
results,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// export async function searchDatabases(
|
|
||||||
// this: ILoadOptionsFunctions,
|
|
||||||
// filter?: string,
|
|
||||||
// ): Promise<INodeListSearchResult> {
|
|
||||||
|
|
||||||
// const opts: IHttpRequestOptions = {
|
|
||||||
// method: 'GET',
|
|
||||||
// url: '/dbs',
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const responseData: IDataObject = await azureCosmosDbRequest.call(this, opts);
|
|
||||||
// console.log('Got this response', responseData)
|
|
||||||
// const responseBody = responseData as {
|
|
||||||
// Databases: IDataObject[];
|
|
||||||
// };
|
|
||||||
// const databases = responseBody.Databases;
|
|
||||||
|
|
||||||
// if (!databases) {
|
|
||||||
// return { results: [] };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const results: INodeListSearchItems[] = databases
|
|
||||||
// .map((database) => ({
|
|
||||||
// name: String(database.id),
|
|
||||||
// value: String(database.id),
|
|
||||||
// }))
|
|
||||||
// .filter((database) => !filter || database.name.includes(filter))
|
|
||||||
// .sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
|
|
||||||
// return {
|
|
||||||
// results,
|
|
||||||
// };
|
|
||||||
// }
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { azureCosmosDbRequest } from '../GenericFunctions';
|
import { microsoftCosmosDbRequest } from '../GenericFunctions';
|
||||||
|
|
||||||
describe('GenericFunctions - azureCosmosDbRequest', () => {
|
describe('GenericFunctions - microsoftCosmosDbRequest', () => {
|
||||||
let mockContext: any;
|
let mockContext: any;
|
||||||
let mockRequestWithAuthentication: jest.Mock;
|
let mockRequestWithAuthentication: jest.Mock;
|
||||||
|
|
||||||
|
@ -17,6 +17,12 @@ describe('GenericFunctions - azureCosmosDbRequest', () => {
|
||||||
test('should make a successful request with correct options', async () => {
|
test('should make a successful request with correct options', async () => {
|
||||||
mockRequestWithAuthentication.mockResolvedValueOnce({ success: true });
|
mockRequestWithAuthentication.mockResolvedValueOnce({ success: true });
|
||||||
(mockContext.getCredentials as jest.Mock).mockResolvedValueOnce({ account: 'us-east-1' });
|
(mockContext.getCredentials as jest.Mock).mockResolvedValueOnce({ account: 'us-east-1' });
|
||||||
|
(mockContext.getCredentials as jest.Mock).mockResolvedValueOnce({
|
||||||
|
database: 'first_database_1',
|
||||||
|
});
|
||||||
|
(mockContext.getCredentials as jest.Mock).mockResolvedValueOnce({
|
||||||
|
baseUrl: 'https://us-east-1.documents.azure.com/dbs',
|
||||||
|
});
|
||||||
|
|
||||||
const requestOptions = {
|
const requestOptions = {
|
||||||
method: 'GET' as const,
|
method: 'GET' as const,
|
||||||
|
@ -26,13 +32,13 @@ describe('GenericFunctions - azureCosmosDbRequest', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await azureCosmosDbRequest.call(mockContext, requestOptions);
|
const result = await microsoftCosmosDbRequest.call(mockContext, requestOptions);
|
||||||
|
|
||||||
expect(mockRequestWithAuthentication).toHaveBeenCalledWith(
|
expect(mockRequestWithAuthentication).toHaveBeenCalledWith(
|
||||||
'azureCosmosDbSharedKeyApi',
|
'microsoftCosmosDbSharedKeyApi',
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
baseURL: 'https://us-east-1.documents.azure.com',
|
baseURL: 'https://us-east-1.documents.azure.com/dbs/first_database_1',
|
||||||
url: '/example-endpoint',
|
url: '/example-endpoint',
|
||||||
headers: expect.objectContaining({
|
headers: expect.objectContaining({
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
@ -55,7 +61,7 @@ describe('GenericFunctions - azureCosmosDbRequest', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await expect(azureCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
await expect(microsoftCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
||||||
'Database account not found in credentials!',
|
'Database account not found in credentials!',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -81,7 +87,7 @@ describe('GenericFunctions - azureCosmosDbRequest', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await expect(azureCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
await expect(microsoftCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
||||||
'The Cosmos DB credentials are not valid!',
|
'The Cosmos DB credentials are not valid!',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -107,7 +113,7 @@ describe('GenericFunctions - azureCosmosDbRequest', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await expect(azureCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
await expect(microsoftCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
||||||
'The Cosmos DB credentials are not valid!',
|
'The Cosmos DB credentials are not valid!',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -133,7 +139,7 @@ describe('GenericFunctions - azureCosmosDbRequest', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await expect(azureCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
await expect(microsoftCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
||||||
'The requested resource was not found!',
|
'The requested resource was not found!',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -155,7 +161,7 @@ describe('GenericFunctions - azureCosmosDbRequest', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await expect(azureCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
await expect(microsoftCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
||||||
'Cosmos DB error response [500]: Internal Server Error',
|
'Cosmos DB error response [500]: Internal Server Error',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -176,7 +182,7 @@ describe('GenericFunctions - azureCosmosDbRequest', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await expect(azureCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
await expect(microsoftCosmosDbRequest.call(mockContext, requestOptions)).rejects.toThrow(
|
||||||
'Cosmos DB error response [undefined]: Unexpected failure',
|
'Cosmos DB error response [undefined]: Unexpected failure',
|
||||||
);
|
);
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
"dist/credentials/AutomizyApi.credentials.js",
|
"dist/credentials/AutomizyApi.credentials.js",
|
||||||
"dist/credentials/AutopilotApi.credentials.js",
|
"dist/credentials/AutopilotApi.credentials.js",
|
||||||
"dist/credentials/Aws.credentials.js",
|
"dist/credentials/Aws.credentials.js",
|
||||||
"dist/credentials/AzureCosmosDbSharedKeyApi.credentials.js",
|
|
||||||
"dist/credentials/BambooHrApi.credentials.js",
|
"dist/credentials/BambooHrApi.credentials.js",
|
||||||
"dist/credentials/BannerbearApi.credentials.js",
|
"dist/credentials/BannerbearApi.credentials.js",
|
||||||
"dist/credentials/BaserowApi.credentials.js",
|
"dist/credentials/BaserowApi.credentials.js",
|
||||||
|
@ -218,6 +217,7 @@
|
||||||
"dist/credentials/MetabaseApi.credentials.js",
|
"dist/credentials/MetabaseApi.credentials.js",
|
||||||
"dist/credentials/MessageBirdApi.credentials.js",
|
"dist/credentials/MessageBirdApi.credentials.js",
|
||||||
"dist/credentials/MetabaseApi.credentials.js",
|
"dist/credentials/MetabaseApi.credentials.js",
|
||||||
|
"dist/credentials/MicrosoftCosmosDbSharedKeyApi.credentials.js",
|
||||||
"dist/credentials/MicrosoftDynamicsOAuth2Api.credentials.js",
|
"dist/credentials/MicrosoftDynamicsOAuth2Api.credentials.js",
|
||||||
"dist/credentials/MicrosoftEntraOAuth2Api.credentials.js",
|
"dist/credentials/MicrosoftEntraOAuth2Api.credentials.js",
|
||||||
"dist/credentials/MicrosoftExcelOAuth2Api.credentials.js",
|
"dist/credentials/MicrosoftExcelOAuth2Api.credentials.js",
|
||||||
|
@ -626,7 +626,7 @@
|
||||||
"dist/nodes/Merge/Merge.node.js",
|
"dist/nodes/Merge/Merge.node.js",
|
||||||
"dist/nodes/MessageBird/MessageBird.node.js",
|
"dist/nodes/MessageBird/MessageBird.node.js",
|
||||||
"dist/nodes/Metabase/Metabase.node.js",
|
"dist/nodes/Metabase/Metabase.node.js",
|
||||||
"dist/nodes/Microsoft/AzureCosmosDB/AzureCosmosDb.node.js",
|
"dist/nodes/Microsoft/CosmosDB/CosmosDb.node.js",
|
||||||
"dist/nodes/Microsoft/Dynamics/MicrosoftDynamicsCrm.node.js",
|
"dist/nodes/Microsoft/Dynamics/MicrosoftDynamicsCrm.node.js",
|
||||||
"dist/nodes/Microsoft/Entra/MicrosoftEntra.node.js",
|
"dist/nodes/Microsoft/Entra/MicrosoftEntra.node.js",
|
||||||
"dist/nodes/Microsoft/Excel/MicrosoftExcel.node.js",
|
"dist/nodes/Microsoft/Excel/MicrosoftExcel.node.js",
|
||||||
|
|
Loading…
Reference in a new issue