mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 04:34:06 -08:00
feat(Slack Node): Add blocks to slack message update (#2182)
* Adding blocks to slack message update * Fixing lint * Adding blocks to slack message update * Fixing lint * ⚡ added toggle to display json inputs in update operation * ⚡ Improvements * feat(Markdown Node): Add new node to covert between Markdown <> HTML (#1728) * ✨ Markdown Node * Tweaked wording * ⬆️ Bump showdown to latest version * ⚡ Small improvement * 👕 Fix linting issue * ⚡ Small improvements * 🔨 added options, added continue on fail, some clean up * ⚡ removed test code * ⚡ added missing semicolumn * 🔨 wip * 🔨 replaced library for converting html to markdown, added options * ⚡ lock file fix * 🔨 clean up Co-authored-by: sirdavidoff <1670123+sirdavidoff@users.noreply.github.com> Co-authored-by: Michael Kret <michael.k@radency.com> Co-authored-by: Michael Kret <michael.k@radency.com> Co-authored-by: ricardo <ricardoespinoza105@gmail.com> Co-authored-by: Ricardo Espinoza <ricardo@n8n.io> Co-authored-by: sirdavidoff <1670123+sirdavidoff@users.noreply.github.com> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
parent
f566569299
commit
b5b60008d6
|
@ -6,7 +6,8 @@
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||||
|
|
||||||
import { Credentials, NodeExecuteFunctions } from 'n8n-core';
|
import { Credentials, NodeExecuteFunctions } from 'n8n-core';
|
||||||
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||||
|
import { get } from 'lodash';
|
||||||
import { NodeVersionedType } from 'n8n-nodes-base';
|
import { NodeVersionedType } from 'n8n-nodes-base';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -633,8 +634,10 @@ export class CredentialsHelper extends ICredentialsHelper {
|
||||||
mode,
|
mode,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let response: INodeExecutionData[][] | null | undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await routingNode.runNode(
|
response = await routingNode.runNode(
|
||||||
inputData,
|
inputData,
|
||||||
runIndex,
|
runIndex,
|
||||||
nodeTypeCopy,
|
nodeTypeCopy,
|
||||||
|
@ -683,6 +686,24 @@ export class CredentialsHelper extends ICredentialsHelper {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
credentialTestFunction.testRequest.rules &&
|
||||||
|
Array.isArray(credentialTestFunction.testRequest.rules)
|
||||||
|
) {
|
||||||
|
// Special testing rules are defined so check all in order
|
||||||
|
for (const rule of credentialTestFunction.testRequest.rules) {
|
||||||
|
if (rule.type === 'responseSuccessBody') {
|
||||||
|
const responseData = response![0][0].json;
|
||||||
|
if (get(responseData, rule.properties.key) === rule.properties.value) {
|
||||||
|
return {
|
||||||
|
status: 'Error',
|
||||||
|
message: rule.properties.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 'OK',
|
status: 'OK',
|
||||||
message: 'Connection successful!',
|
message: 'Connection successful!',
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import {
|
import {
|
||||||
|
IAuthenticateBearer,
|
||||||
|
IAuthenticateQueryAuth,
|
||||||
|
ICredentialTestRequest,
|
||||||
ICredentialType,
|
ICredentialType,
|
||||||
INodeProperties,
|
INodeProperties,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
|
||||||
export class SlackApi implements ICredentialType {
|
export class SlackApi implements ICredentialType {
|
||||||
name = 'slackApi';
|
name = 'slackApi';
|
||||||
displayName = 'Slack API';
|
displayName = 'Slack API';
|
||||||
|
@ -17,4 +19,26 @@ export class SlackApi implements ICredentialType {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
authenticate: IAuthenticateBearer = {
|
||||||
|
type: 'bearer',
|
||||||
|
properties: {
|
||||||
|
tokenPropertyName: 'accessToken',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
test: ICredentialTestRequest = {
|
||||||
|
request: {
|
||||||
|
baseURL: 'https://slack.com',
|
||||||
|
url: '/api/users.profile.get',
|
||||||
|
},
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
type: 'responseSuccessBody',
|
||||||
|
properties: {
|
||||||
|
key: 'ok',
|
||||||
|
value: false,
|
||||||
|
message: 'Invalid access token',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
import {
|
import {
|
||||||
IDataObject,
|
IDataObject,
|
||||||
IOAuth2Options,
|
IOAuth2Options,
|
||||||
|
JsonObject,
|
||||||
NodeApiError,
|
NodeApiError,
|
||||||
NodeOperationError,
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
@ -36,23 +37,16 @@ export async function slackApiRequest(this: IExecuteFunctions | IExecuteSingleFu
|
||||||
if (Object.keys(query).length === 0) {
|
if (Object.keys(query).length === 0) {
|
||||||
delete options.qs;
|
delete options.qs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const oAuth2Options: IOAuth2Options = {
|
||||||
|
tokenType: 'Bearer',
|
||||||
|
property: 'authed_user.access_token',
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let response: any; // tslint:disable-line:no-any
|
let response: any; // tslint:disable-line:no-any
|
||||||
|
const credentialType = authenticationMethod === 'accessToken' ? 'slackApi' : 'slackOAuth2Api';
|
||||||
if (authenticationMethod === 'accessToken') {
|
response = await this.helpers.requestWithAuthentication.call(this, credentialType, options, { oauth2: oAuth2Options });
|
||||||
const credentials = await this.getCredentials('slackApi');
|
|
||||||
options.headers!.Authorization = `Bearer ${credentials.accessToken}`;
|
|
||||||
//@ts-ignore
|
|
||||||
response = await this.helpers.request(options);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
const oAuth2Options: IOAuth2Options = {
|
|
||||||
tokenType: 'Bearer',
|
|
||||||
property: 'authed_user.access_token',
|
|
||||||
};
|
|
||||||
//@ts-ignore
|
|
||||||
response = await this.helpers.requestOAuth2.call(this, 'slackOAuth2Api', options, oAuth2Options);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.ok === false) {
|
if (response.ok === false) {
|
||||||
if (response.error === 'paid_teams_only') {
|
if (response.error === 'paid_teams_only') {
|
||||||
|
@ -66,7 +60,7 @@ export async function slackApiRequest(this: IExecuteFunctions | IExecuteSingleFu
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new NodeApiError(this.getNode(), error);
|
throw new NodeApiError(this.getNode(), error as JsonObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,6 +171,97 @@ export const messageFields: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
name: 'otherOptions',
|
||||||
|
type: 'collection',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'post',
|
||||||
|
'postEphemeral',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'message',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: {},
|
||||||
|
description: 'Other options to set',
|
||||||
|
placeholder: 'Add options',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Icon Emoji',
|
||||||
|
name: 'icon_emoji',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Emoji to use as the icon for this message. Overrides icon_url.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Icon URL',
|
||||||
|
name: 'icon_url',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'URL to an image to use as the icon for this message.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Link Names',
|
||||||
|
name: 'link_names',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Find and link channel names and usernames.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Make Reply',
|
||||||
|
name: 'thread_ts',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'Provide another message\'s ts value to make this message a reply.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Markdown',
|
||||||
|
name: 'mrkdwn',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
description: 'Use Slack Markdown parsing.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Reply Broadcast',
|
||||||
|
name: 'reply_broadcast',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Used in conjunction with thread_ts and indicates whether reply should be made visible to everyone in the channel or conversation.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Unfurl Links',
|
||||||
|
name: 'unfurl_links',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'Pass true to enable unfurling of primarily text-based content.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Unfurl Media',
|
||||||
|
name: 'unfurl_media',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
description: 'Pass false to disable unfurling of media content.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Send as User',
|
||||||
|
name: 'sendAsUser',
|
||||||
|
type: 'string',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
'/authentication': [
|
||||||
|
'accessToken',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: '',
|
||||||
|
description: 'The message will be sent from this username (i.e. as if this individual sent the message).',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Attachments',
|
displayName: 'Attachments',
|
||||||
name: 'attachments',
|
name: 'attachments',
|
||||||
|
@ -367,97 +458,6 @@ export const messageFields: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
displayName: 'Other Options',
|
|
||||||
name: 'otherOptions',
|
|
||||||
type: 'collection',
|
|
||||||
displayOptions: {
|
|
||||||
show: {
|
|
||||||
operation: [
|
|
||||||
'post',
|
|
||||||
'postEphemeral',
|
|
||||||
],
|
|
||||||
resource: [
|
|
||||||
'message',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
default: {},
|
|
||||||
description: 'Other options to set',
|
|
||||||
placeholder: 'Add options',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
displayName: 'Icon Emoji',
|
|
||||||
name: 'icon_emoji',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'Emoji to use as the icon for this message. Overrides icon_url.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Icon URL',
|
|
||||||
name: 'icon_url',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'URL to an image to use as the icon for this message.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Link Names',
|
|
||||||
name: 'link_names',
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
description: 'Find and link channel names and usernames.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Make Reply',
|
|
||||||
name: 'thread_ts',
|
|
||||||
type: 'string',
|
|
||||||
default: '',
|
|
||||||
description: 'Provide another message\'s ts value to make this message a reply.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Markdown',
|
|
||||||
name: 'mrkdwn',
|
|
||||||
type: 'boolean',
|
|
||||||
default: true,
|
|
||||||
description: 'Use Slack Markdown parsing.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Reply Broadcast',
|
|
||||||
name: 'reply_broadcast',
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
description: 'Used in conjunction with thread_ts and indicates whether reply should be made visible to everyone in the channel or conversation.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Unfurl Links',
|
|
||||||
name: 'unfurl_links',
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
description: 'Pass true to enable unfurling of primarily text-based content.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Unfurl Media',
|
|
||||||
name: 'unfurl_media',
|
|
||||||
type: 'boolean',
|
|
||||||
default: true,
|
|
||||||
description: 'Pass false to disable unfurling of media content.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
displayName: 'Send as User',
|
|
||||||
name: 'sendAsUser',
|
|
||||||
type: 'string',
|
|
||||||
displayOptions: {
|
|
||||||
show: {
|
|
||||||
'/authentication': [
|
|
||||||
'accessToken',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
default: '',
|
|
||||||
description: 'The message will be sent from this username (i.e. as if this individual sent the message).',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
/* message:update */
|
/* message:update */
|
||||||
|
@ -487,7 +487,7 @@ export const messageFields: INodeProperties[] = [
|
||||||
displayName: 'Text',
|
displayName: 'Text',
|
||||||
name: 'text',
|
name: 'text',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true,
|
required: false,
|
||||||
default: '',
|
default: '',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
show: {
|
show: {
|
||||||
|
@ -519,6 +519,22 @@ export const messageFields: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
description: `Timestamp of the message to be updated.`,
|
description: `Timestamp of the message to be updated.`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'JSON parameters',
|
||||||
|
name: 'jsonParameters',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
resource: [
|
||||||
|
'message',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Update Fields',
|
displayName: 'Update Fields',
|
||||||
name: 'updateFields',
|
name: 'updateFields',
|
||||||
|
@ -566,6 +582,54 @@ export const messageFields: INodeProperties[] = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Attachments',
|
||||||
|
name: 'attachmentsJson',
|
||||||
|
type: 'json',
|
||||||
|
default: '',
|
||||||
|
required: false,
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'message',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
jsonParameters: [
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'The attachments to add',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Blocks',
|
||||||
|
name: 'blocksJson',
|
||||||
|
type: 'json',
|
||||||
|
default: '',
|
||||||
|
required: false,
|
||||||
|
typeOptions: {
|
||||||
|
alwaysOpenEditWindow: true,
|
||||||
|
},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'message',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'update',
|
||||||
|
],
|
||||||
|
jsonParameters: [
|
||||||
|
true,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'The blocks to add',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Blocks',
|
displayName: 'Blocks',
|
||||||
name: 'blocksUi',
|
name: 'blocksUi',
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { IExecuteFunctions } from 'n8n-core';
|
import {
|
||||||
|
IExecuteFunctions,
|
||||||
|
} from 'n8n-core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ICredentialsDecrypted,
|
ICredentialsDecrypted,
|
||||||
|
@ -10,6 +12,7 @@ import {
|
||||||
INodePropertyOptions,
|
INodePropertyOptions,
|
||||||
INodeType,
|
INodeType,
|
||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
|
JsonObject,
|
||||||
NodeOperationError,
|
NodeOperationError,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
@ -130,7 +133,6 @@ export class Slack implements INodeType {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
testedBy: 'testSlackTokenAuth',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'slackOAuth2Api',
|
name: 'slackOAuth2Api',
|
||||||
|
@ -287,41 +289,6 @@ export class Slack implements INodeType {
|
||||||
return returnData;
|
return returnData;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
credentialTest: {
|
|
||||||
async testSlackTokenAuth(this: ICredentialTestFunctions, credential: ICredentialsDecrypted): Promise<INodeCredentialTestResult> {
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json; charset=utf-8',
|
|
||||||
Authorization: `Bearer ${credential.data!.accessToken}`,
|
|
||||||
},
|
|
||||||
uri: 'https://slack.com/api/users.profile.get',
|
|
||||||
json: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await this.helpers.request(options);
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
return {
|
|
||||||
status: 'Error',
|
|
||||||
message: `${response.error}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
return {
|
|
||||||
status: 'Error',
|
|
||||||
message: `${err.message}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: 'OK',
|
|
||||||
message: 'Connection successful!',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
||||||
|
@ -840,6 +807,28 @@ export class Slack implements INodeType {
|
||||||
}
|
}
|
||||||
body['attachments'] = attachments;
|
body['attachments'] = attachments;
|
||||||
|
|
||||||
|
const jsonParameters = this.getNodeParameter('jsonParameters', i, false) as boolean;
|
||||||
|
if (jsonParameters) {
|
||||||
|
const blocksJson = this.getNodeParameter('blocksJson', i, []) as string;
|
||||||
|
|
||||||
|
if (blocksJson !== '' && validateJSON(blocksJson) === undefined) {
|
||||||
|
throw new NodeOperationError(this.getNode(), 'Blocks it is not a valid json');
|
||||||
|
}
|
||||||
|
if (blocksJson !== '') {
|
||||||
|
body.blocks = blocksJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
const attachmentsJson = this.getNodeParameter('attachmentsJson', i, '') as string;
|
||||||
|
|
||||||
|
if (attachmentsJson !== '' && validateJSON(attachmentsJson) === undefined) {
|
||||||
|
throw new NodeOperationError(this.getNode(), 'Attachments it is not a valid json');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachmentsJson !== '') {
|
||||||
|
body.attachments = attachmentsJson;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add all the other options to the request
|
// Add all the other options to the request
|
||||||
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
|
const updateFields = this.getNodeParameter('updateFields', i) as IDataObject;
|
||||||
Object.assign(body, updateFields);
|
Object.assign(body, updateFields);
|
||||||
|
@ -1189,7 +1178,7 @@ export class Slack implements INodeType {
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (this.continueOnFail()) {
|
if (this.continueOnFail()) {
|
||||||
returnData.push({ error: error.message });
|
returnData.push({ error: (error as JsonObject).message });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
|
|
|
@ -248,9 +248,17 @@ export interface IAuthenticateRuleResponseCode extends IAuthenticateRuleBase {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IAuthenticateRuleResponseSuccessBody extends IAuthenticateRuleBase {
|
||||||
|
type: 'responseSuccessBody';
|
||||||
|
properties: {
|
||||||
|
message: string;
|
||||||
|
key: string;
|
||||||
|
value: any;
|
||||||
|
};
|
||||||
|
}
|
||||||
export interface ICredentialTestRequest {
|
export interface ICredentialTestRequest {
|
||||||
request: IHttpRequestOptions;
|
request: IHttpRequestOptions;
|
||||||
rules?: IAuthenticateRuleResponseCode[];
|
rules?: IAuthenticateRuleResponseCode[] | IAuthenticateRuleResponseSuccessBody[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICredentialTestRequestData {
|
export interface ICredentialTestRequestData {
|
||||||
|
|
Loading…
Reference in a new issue