mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
chore: Lintfix nodes-base (#16877)
This commit is contained in:
@@ -80,13 +80,7 @@ export async function handleListing(
|
|||||||
const itemsKey = toItemsKey(endpoint);
|
const itemsKey = toItemsKey(endpoint);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
responseData = await actionNetworkApiRequest.call(
|
responseData = await actionNetworkApiRequest.call(this, method, endpoint, body, qs);
|
||||||
this,
|
|
||||||
method as IHttpRequestMethods,
|
|
||||||
endpoint,
|
|
||||||
body,
|
|
||||||
qs,
|
|
||||||
);
|
|
||||||
const items = responseData._embedded[itemsKey];
|
const items = responseData._embedded[itemsKey];
|
||||||
returnData.push(...(items as IDataObject[]));
|
returnData.push(...(items as IDataObject[]));
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ export const createMockExecuteFunction = (nodeParameters: IDataObject) => {
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
_itemIndex: number,
|
_itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
return get(nodeParameters, parameter, fallbackValue);
|
return get(nodeParameters, parameter, fallbackValue);
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export async function execute(
|
|||||||
this: IExecuteFunctions,
|
this: IExecuteFunctions,
|
||||||
index: number,
|
index: number,
|
||||||
): Promise<INodeExecutionData[]> {
|
): Promise<INodeExecutionData[]> {
|
||||||
const returnAll = this.getNodeParameter('returnAll', index, false) as boolean;
|
const returnAll = this.getNodeParameter('returnAll', index, false);
|
||||||
const limit = this.getNodeParameter('limit', index, 10);
|
const limit = this.getNodeParameter('limit', index, 10);
|
||||||
const sessionIds = this.getNodeParameter('sessionIds', index, '') as string;
|
const sessionIds = this.getNodeParameter('sessionIds', index, '') as string;
|
||||||
const outputSingleItem = this.getNodeParameter('outputSingleItem', index, true) as boolean;
|
const outputSingleItem = this.getNodeParameter('outputSingleItem', index, true) as boolean;
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ export const createMockExecuteFunction = (nodeParameters: IDataObject) => {
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
_itemIndex: number,
|
_itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
return get(nodeParameters, parameter, fallbackValue);
|
return get(nodeParameters, parameter, fallbackValue);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { NodeApiError } from 'n8n-workflow';
|
import { NodeApiError } from 'n8n-workflow';
|
||||||
|
|
||||||
import { createMockExecuteFunction } from './node/helpers';
|
|
||||||
import { ERROR_MESSAGES, SESSION_STATUS } from '../constants';
|
import { ERROR_MESSAGES, SESSION_STATUS } from '../constants';
|
||||||
import {
|
import {
|
||||||
createSession,
|
createSession,
|
||||||
@@ -18,6 +17,7 @@ import {
|
|||||||
convertScreenshotToBinary,
|
convertScreenshotToBinary,
|
||||||
} from '../GenericFunctions';
|
} from '../GenericFunctions';
|
||||||
import type * as transport from '../transport';
|
import type * as transport from '../transport';
|
||||||
|
import { createMockExecuteFunction } from './node/helpers';
|
||||||
|
|
||||||
const mockCreatedSession = {
|
const mockCreatedSession = {
|
||||||
data: { id: 'new-session-123', status: SESSION_STATUS.RUNNING },
|
data: { id: 'new-session-123', status: SESSION_STATUS.RUNNING },
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export async function asanaApiRequest(
|
|||||||
endpoint: `/${string}`,
|
endpoint: `/${string}`,
|
||||||
body: object,
|
body: object,
|
||||||
query?: IDataObject,
|
query?: IDataObject,
|
||||||
uri?: string | undefined,
|
uri?: string,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const authenticationMethod = this.getNodeParameter('authentication', 0) as string;
|
const authenticationMethod = this.getNodeParameter('authentication', 0) as string;
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export function simplify(item: IAttributeValue): IDataObject {
|
|||||||
for (const [attribute, value] of Object.entries(item)) {
|
for (const [attribute, value] of Object.entries(item)) {
|
||||||
const [type, content] = Object.entries(value)[0] as [AttributeValueType, string];
|
const [type, content] = Object.entries(value)[0] as [AttributeValueType, string];
|
||||||
//nedded as simplify is used in decodeItem
|
//nedded as simplify is used in decodeItem
|
||||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
||||||
output[attribute] = decodeAttribute(type, content);
|
output[attribute] = decodeAttribute(type, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export async function brandfetchApiRequest(
|
|||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
try {
|
try {
|
||||||
let options: IRequestOptions = {
|
let options: IRequestOptions = {
|
||||||
method: method as IHttpRequestMethods,
|
method,
|
||||||
qs,
|
qs,
|
||||||
body,
|
body,
|
||||||
url: uri || `https://api.brandfetch.io/v2${resource}`,
|
url: uri || `https://api.brandfetch.io/v2${resource}`,
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ describe('Cron Node', () => {
|
|||||||
const fakeExecuteFunction = {
|
const fakeExecuteFunction = {
|
||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ export async function getNewEmails(
|
|||||||
dataPropertyAttachmentsPrefixName,
|
dataPropertyAttachmentsPrefixName,
|
||||||
);
|
);
|
||||||
|
|
||||||
(parsedEmail.json as IDataObject).attributes = {
|
parsedEmail.json.attributes = {
|
||||||
uid: message.attributes.uid,
|
uid: message.attributes.uid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -297,7 +297,6 @@ export class Form extends Node {
|
|||||||
],
|
],
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased
|
|
||||||
displayName: 'An n8n Form Trigger node must be set up before this node',
|
displayName: 'An n8n Form Trigger node must be set up before this node',
|
||||||
name: 'triggerNotice',
|
name: 'triggerNotice',
|
||||||
type: 'notice',
|
type: 'notice',
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-loop-func */
|
|
||||||
import type { NodeVMOptions } from '@n8n/vm2';
|
import type { NodeVMOptions } from '@n8n/vm2';
|
||||||
import { NodeVM } from '@n8n/vm2';
|
import { NodeVM } from '@n8n/vm2';
|
||||||
import type {
|
import type {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import type { SchemaField, TableRawData, TableSchema } from './interfaces';
|
|||||||
|
|
||||||
function getFieldValue(schemaField: SchemaField, field: IDataObject, parseTimestamps = false) {
|
function getFieldValue(schemaField: SchemaField, field: IDataObject, parseTimestamps = false) {
|
||||||
if (schemaField.type === 'RECORD') {
|
if (schemaField.type === 'RECORD') {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
||||||
return simplify([field.v as TableRawData], schemaField.fields as unknown as SchemaField[]);
|
return simplify([field.v as TableRawData], schemaField.fields as unknown as SchemaField[]);
|
||||||
} else {
|
} else {
|
||||||
let value = field.v;
|
let value = field.v;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export async function googleApiRequest(
|
|||||||
qs: IDataObject = {},
|
qs: IDataObject = {},
|
||||||
uri?: string,
|
uri?: string,
|
||||||
noCredentials = false,
|
noCredentials = false,
|
||||||
encoding?: null | undefined,
|
encoding?: null,
|
||||||
) {
|
) {
|
||||||
const options: IRequestOptions = {
|
const options: IRequestOptions = {
|
||||||
headers: {
|
headers: {
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ import type {
|
|||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
import { NodeConnectionTypes, NodeApiError } from 'n8n-workflow';
|
import { NodeConnectionTypes, NodeApiError } from 'n8n-workflow';
|
||||||
|
|
||||||
|
import { GOOGLE_DRIVE_FILE_URL_REGEX, GOOGLE_DRIVE_FOLDER_URL_REGEX } from '../constants';
|
||||||
import { extractId, googleApiRequest, googleApiRequestAllItems } from './v1/GenericFunctions';
|
import { extractId, googleApiRequest, googleApiRequestAllItems } from './v1/GenericFunctions';
|
||||||
import { fileSearch, folderSearch } from './v2/methods/listSearch';
|
import { fileSearch, folderSearch } from './v2/methods/listSearch';
|
||||||
import { GOOGLE_DRIVE_FILE_URL_REGEX, GOOGLE_DRIVE_FOLDER_URL_REGEX } from '../constants';
|
|
||||||
|
|
||||||
export class GoogleDriveTrigger implements INodeType {
|
export class GoogleDriveTrigger implements INodeType {
|
||||||
description: INodeTypeDescription = {
|
description: INodeTypeDescription = {
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ export const createMockExecuteFunction = (
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
_itemIndex: number,
|
_itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
return get(nodeParameters, parameter, fallbackValue);
|
return get(nodeParameters, parameter, fallbackValue);
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ export function documentToJson(fields: IDataObject): IDataObject {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const list = value.values as IDataObject[];
|
const list = value.values as IDataObject[];
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return !!list ? list.map((l) => documentToJson(l)) : [];
|
return list ? list.map((l) => documentToJson(l)) : [];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable n8n-nodes-base/node-param-display-name-miscased */
|
|
||||||
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
||||||
import { jsonParse } from 'n8n-workflow';
|
import { jsonParse } from 'n8n-workflow';
|
||||||
import nock from 'nock';
|
import nock from 'nock';
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ import {
|
|||||||
getRevisionFile,
|
getRevisionFile,
|
||||||
sheetBinaryToArrayOfArrays,
|
sheetBinaryToArrayOfArrays,
|
||||||
} from './GoogleSheetsTrigger.utils';
|
} from './GoogleSheetsTrigger.utils';
|
||||||
|
import { GOOGLE_DRIVE_FILE_URL_REGEX, GOOGLE_SHEETS_SHEET_URL_REGEX } from '../constants';
|
||||||
import { GoogleSheet } from './v2/helpers/GoogleSheet';
|
import { GoogleSheet } from './v2/helpers/GoogleSheet';
|
||||||
import type { ResourceLocator, ValueRenderOption } from './v2/helpers/GoogleSheets.types';
|
import type { ResourceLocator, ValueRenderOption } from './v2/helpers/GoogleSheets.types';
|
||||||
import { sheetsSearch, spreadSheetsSearch } from './v2/methods/listSearch';
|
import { sheetsSearch, spreadSheetsSearch } from './v2/methods/listSearch';
|
||||||
import { getSheetHeaderRowAndSkipEmpty } from './v2/methods/loadOptions';
|
import { getSheetHeaderRowAndSkipEmpty } from './v2/methods/loadOptions';
|
||||||
import { apiRequest } from './v2/transport';
|
import { apiRequest } from './v2/transport';
|
||||||
import { GOOGLE_DRIVE_FILE_URL_REGEX, GOOGLE_SHEETS_SHEET_URL_REGEX } from '../constants';
|
|
||||||
|
|
||||||
export const document: INodeProperties = {
|
export const document: INodeProperties = {
|
||||||
displayName: 'Document',
|
displayName: 'Document',
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export class GoogleSheet {
|
|||||||
constructor(
|
constructor(
|
||||||
spreadsheetId: string,
|
spreadsheetId: string,
|
||||||
executeFunctions: IExecuteFunctions | ILoadOptionsFunctions,
|
executeFunctions: IExecuteFunctions | ILoadOptionsFunctions,
|
||||||
options?: ISheetOptions | undefined,
|
options?: ISheetOptions,
|
||||||
) {
|
) {
|
||||||
// options = <SheetOptions>options || {};
|
// options = <SheetOptions>options || {};
|
||||||
if (!options) {
|
if (!options) {
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ export async function execute(
|
|||||||
"At least one value has to be added under 'Values to Send'",
|
"At least one value has to be added under 'Values to Send'",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
||||||
const fields = valuesToSend.reduce((acc, entry) => {
|
const fields = valuesToSend.reduce((acc, entry) => {
|
||||||
if (entry.column === 'newColumn') {
|
if (entry.column === 'newColumn') {
|
||||||
const columnName = entry.columnName as string;
|
const columnName = entry.columnName as string;
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ export async function execute(
|
|||||||
"At least one value has to be added under 'Values to Send'",
|
"At least one value has to be added under 'Values to Send'",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
||||||
const fields = valuesToSend.reduce((acc, entry) => {
|
const fields = valuesToSend.reduce((acc, entry) => {
|
||||||
if (entry.column === 'newColumn') {
|
if (entry.column === 'newColumn') {
|
||||||
const columnName = entry.columnName as string;
|
const columnName = entry.columnName as string;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export async function gotifyApiRequest(
|
|||||||
|
|
||||||
body: any = {},
|
body: any = {},
|
||||||
qs: IDataObject = {},
|
qs: IDataObject = {},
|
||||||
uri?: string | undefined,
|
uri?: string,
|
||||||
_option = {},
|
_option = {},
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const credentials = await this.getCredentials('gotifyApi');
|
const credentials = await this.getCredentials('gotifyApi');
|
||||||
@@ -30,7 +30,7 @@ export async function gotifyApiRequest(
|
|||||||
qs,
|
qs,
|
||||||
uri: uri || `${credentials.url}${path}`,
|
uri: uri || `${credentials.url}${path}`,
|
||||||
json: true,
|
json: true,
|
||||||
rejectUnauthorized: !credentials.ignoreSSLIssues as boolean,
|
rejectUnauthorized: !credentials.ignoreSSLIssues,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
if (Object.keys(body as IDataObject).length === 0) {
|
if (Object.keys(body as IDataObject).length === 0) {
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ export function sanitizeUiMessage(
|
|||||||
sendRequest = {
|
sendRequest = {
|
||||||
...sendRequest,
|
...sendRequest,
|
||||||
[requestProperty]: Object.keys(sendRequest[requestProperty] as object).reduce(
|
[requestProperty]: Object.keys(sendRequest[requestProperty] as object).reduce(
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
||||||
(acc: IDataObject, curr) => {
|
(acc: IDataObject, curr) => {
|
||||||
acc[curr] = authDataKeys[requestProperty].includes(curr)
|
acc[curr] = authDataKeys[requestProperty].includes(curr)
|
||||||
? REDACTED
|
? REDACTED
|
||||||
|
|||||||
@@ -1112,7 +1112,6 @@ export class HttpRequestV1 implements INodeType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.splitIntoItems === true && Array.isArray(response)) {
|
if (options.splitIntoItems === true && Array.isArray(response)) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
||||||
response.forEach((item) =>
|
response.forEach((item) =>
|
||||||
returnItems.push({
|
returnItems.push({
|
||||||
json: item,
|
json: item,
|
||||||
|
|||||||
@@ -1175,7 +1175,6 @@ export class HttpRequestV2 implements INodeType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.splitIntoItems === true && Array.isArray(response)) {
|
if (options.splitIntoItems === true && Array.isArray(response)) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
||||||
response.forEach((item) =>
|
response.forEach((item) =>
|
||||||
returnItems.push({
|
returnItems.push({
|
||||||
json: item,
|
json: item,
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ import type { Readable } from 'stream';
|
|||||||
import { keysToLowercase } from '@utils/utilities';
|
import { keysToLowercase } from '@utils/utilities';
|
||||||
|
|
||||||
import { mainProperties } from './Description';
|
import { mainProperties } from './Description';
|
||||||
import { setFilename } from './utils/binaryData';
|
|
||||||
import { mimeTypeFromResponse } from './utils/parse';
|
|
||||||
import type { BodyParameter, IAuthDataSanitizeKeys } from '../GenericFunctions';
|
import type { BodyParameter, IAuthDataSanitizeKeys } from '../GenericFunctions';
|
||||||
import {
|
import {
|
||||||
binaryContentTypes,
|
binaryContentTypes,
|
||||||
@@ -40,6 +38,8 @@ import {
|
|||||||
sanitizeUiMessage,
|
sanitizeUiMessage,
|
||||||
setAgentOptions,
|
setAgentOptions,
|
||||||
} from '../GenericFunctions';
|
} from '../GenericFunctions';
|
||||||
|
import { setFilename } from './utils/binaryData';
|
||||||
|
import { mimeTypeFromResponse } from './utils/parse';
|
||||||
import { configureResponseOptimizer } from '../shared/optimizeResponse';
|
import { configureResponseOptimizer } from '../shared/optimizeResponse';
|
||||||
|
|
||||||
function toText<T>(data: T) {
|
function toText<T>(data: T) {
|
||||||
@@ -1000,7 +1000,6 @@ export class HttpRequestV3 implements INodeType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(response)) {
|
if (Array.isArray(response)) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
||||||
response.forEach((item) =>
|
response.forEach((item) =>
|
||||||
returnItems.push({
|
returnItems.push({
|
||||||
json: item,
|
json: item,
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ describe('Test IF v2 Node Tests', () => {
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
itemIndex: number,
|
itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export const createClient = async (credentials: MqttCredential): Promise<MqttCli
|
|||||||
|
|
||||||
const onConnect = () => {
|
const onConnect = () => {
|
||||||
client.removeListener('connect', onConnect);
|
client.removeListener('connect', onConnect);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
||||||
client.removeListener('error', onError);
|
client.removeListener('error', onError);
|
||||||
resolve(client);
|
resolve(client);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable n8n-nodes-base/node-param-display-name-miscased-id */
|
|
||||||
/* eslint-disable n8n-nodes-base/node-param-display-name-miscased */
|
/* eslint-disable n8n-nodes-base/node-param-display-name-miscased */
|
||||||
|
|
||||||
export const microsoftEntraApiResponse = {
|
export const microsoftEntraApiResponse = {
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ const fakeExecute = (nodeParameters: IDataObject[]) => {
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
itemIndex: number,
|
itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
return get(nodeParameters[itemIndex], parameter, fallbackValue);
|
return get(nodeParameters[itemIndex], parameter, fallbackValue);
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ describe('Azure Storage Node', () => {
|
|||||||
value: 'mycontainer',
|
value: 'mycontainer',
|
||||||
} as INodeParameterResourceLocator;
|
} as INodeParameterResourceLocator;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line n8n-local-rules/no-plain-errors
|
|
||||||
throw new Error('Unknown parameter');
|
throw new Error('Unknown parameter');
|
||||||
});
|
});
|
||||||
const mockGetCredentials = jest.fn(async (type: string, _itemIndex?: number) => {
|
const mockGetCredentials = jest.fn(async (type: string, _itemIndex?: number) => {
|
||||||
if (type === 'azureStorageSharedKeyApi') {
|
if (type === 'azureStorageSharedKeyApi') {
|
||||||
return credentials.azureStorageSharedKeyApi;
|
return credentials.azureStorageSharedKeyApi;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line n8n-local-rules/no-plain-errors
|
|
||||||
throw new Error('Unknown credentials');
|
throw new Error('Unknown credentials');
|
||||||
});
|
});
|
||||||
const mockContext = {
|
const mockContext = {
|
||||||
@@ -70,14 +70,14 @@ describe('Azure Storage Node', () => {
|
|||||||
if (parameterName === 'authentication') {
|
if (parameterName === 'authentication') {
|
||||||
return 'sharedKey';
|
return 'sharedKey';
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line n8n-local-rules/no-plain-errors
|
|
||||||
throw new Error('Unknown parameter');
|
throw new Error('Unknown parameter');
|
||||||
});
|
});
|
||||||
const mockGetCredentials = jest.fn(async (type: string, _itemIndex?: number) => {
|
const mockGetCredentials = jest.fn(async (type: string, _itemIndex?: number) => {
|
||||||
if (type === 'azureStorageSharedKeyApi') {
|
if (type === 'azureStorageSharedKeyApi') {
|
||||||
return credentials.azureStorageSharedKeyApi;
|
return credentials.azureStorageSharedKeyApi;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line n8n-local-rules/no-plain-errors
|
|
||||||
throw new Error('Unknown credentials');
|
throw new Error('Unknown credentials');
|
||||||
});
|
});
|
||||||
const mockContext = {
|
const mockContext = {
|
||||||
|
|||||||
@@ -311,7 +311,7 @@ export class MicrosoftTeamsTrigger implements INodeType {
|
|||||||
const webhookUrl = this.getNodeWebhookUrl('default');
|
const webhookUrl = this.getNodeWebhookUrl('default');
|
||||||
const webhookData = this.getWorkflowStaticData('node');
|
const webhookData = this.getWorkflowStaticData('node');
|
||||||
|
|
||||||
if (!webhookUrl || !webhookUrl.startsWith('https://')) {
|
if (!webhookUrl?.startsWith('https://')) {
|
||||||
throw new NodeApiError(this.getNode(), {
|
throw new NodeApiError(this.getNode(), {
|
||||||
message: 'Invalid Notification URL',
|
message: 'Invalid Notification URL',
|
||||||
description: `The webhook URL "${webhookUrl}" is invalid. Microsoft Graph requires an HTTPS URL.`,
|
description: `The webhook URL "${webhookUrl}" is invalid. Microsoft Graph requires an HTTPS URL.`,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export async function nasaApiRequest(
|
|||||||
endpoint: string,
|
endpoint: string,
|
||||||
qs: IDataObject,
|
qs: IDataObject,
|
||||||
option: IDataObject = {},
|
option: IDataObject = {},
|
||||||
uri?: string | undefined,
|
uri?: string,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const credentials = await this.getCredentials('nasaApi');
|
const credentials = await this.getCredentials('nasaApi');
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export async function nextCloudApiRequest(
|
|||||||
endpoint: string,
|
endpoint: string,
|
||||||
body: object | string | Buffer,
|
body: object | string | Buffer,
|
||||||
headers?: IDataObject,
|
headers?: IDataObject,
|
||||||
encoding?: null | undefined,
|
encoding?: null,
|
||||||
query?: IDataObject,
|
query?: IDataObject,
|
||||||
) {
|
) {
|
||||||
const resource = this.getNodeParameter('resource', 0);
|
const resource = this.getNodeParameter('resource', 0);
|
||||||
|
|||||||
@@ -1134,7 +1134,6 @@ export class NextCloud implements INodeType {
|
|||||||
endpoint,
|
endpoint,
|
||||||
);
|
);
|
||||||
} else if (['file', 'folder'].includes(resource) && operation === 'share') {
|
} else if (['file', 'folder'].includes(resource) && operation === 'share') {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
||||||
const jsonResponseData: IDataObject = await new Promise((resolve, reject) => {
|
const jsonResponseData: IDataObject = await new Promise((resolve, reject) => {
|
||||||
parseString(responseData as string, { explicitArray: false }, (err, data) => {
|
parseString(responseData as string, { explicitArray: false }, (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -1162,7 +1161,6 @@ export class NextCloud implements INodeType {
|
|||||||
returnData.push(...executionData);
|
returnData.push(...executionData);
|
||||||
} else if (resource === 'user') {
|
} else if (resource === 'user') {
|
||||||
if (operation !== 'getAll') {
|
if (operation !== 'getAll') {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
||||||
const jsonResponseData: IDataObject = await new Promise((resolve, reject) => {
|
const jsonResponseData: IDataObject = await new Promise((resolve, reject) => {
|
||||||
parseString(responseData as string, { explicitArray: false }, (err, data) => {
|
parseString(responseData as string, { explicitArray: false }, (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -1193,7 +1191,6 @@ export class NextCloud implements INodeType {
|
|||||||
|
|
||||||
returnData.push(...executionData);
|
returnData.push(...executionData);
|
||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
||||||
const jsonResponseData: IDataObject[] = await new Promise((resolve, reject) => {
|
const jsonResponseData: IDataObject[] = await new Promise((resolve, reject) => {
|
||||||
parseString(responseData as string, { explicitArray: false }, (err, data) => {
|
parseString(responseData as string, { explicitArray: false }, (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -1219,7 +1216,6 @@ export class NextCloud implements INodeType {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (resource === 'folder' && operation === 'list') {
|
} else if (resource === 'folder' && operation === 'list') {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
|
||||||
const jsonResponseData: IDataObject = await new Promise((resolve, reject) => {
|
const jsonResponseData: IDataObject = await new Promise((resolve, reject) => {
|
||||||
parseString(responseData as string, { explicitArray: false }, (err, data) => {
|
parseString(responseData as string, { explicitArray: false }, (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ const createMockExecuteFunction = (nodeParameters: IDataObject) => {
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
_itemIndex: number,
|
_itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
return get(nodeParameters, parameter, fallbackValue);
|
return get(nodeParameters, parameter, fallbackValue);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export async function pushbulletApiRequest(
|
|||||||
|
|
||||||
body: any = {},
|
body: any = {},
|
||||||
qs: IDataObject = {},
|
qs: IDataObject = {},
|
||||||
uri?: string | undefined,
|
uri?: string,
|
||||||
option = {},
|
option = {},
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const options: IRequestOptions = {
|
const options: IRequestOptions = {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export async function pushcutApiRequest(
|
|||||||
|
|
||||||
body: any = {},
|
body: any = {},
|
||||||
qs: IDataObject = {},
|
qs: IDataObject = {},
|
||||||
uri?: string | undefined,
|
uri?: string,
|
||||||
option = {},
|
option = {},
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const credentials = await this.getCredentials('pushcutApi');
|
const credentials = await this.getCredentials('pushcutApi');
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export async function s3ApiRequest(
|
|||||||
qs: query,
|
qs: query,
|
||||||
uri: endpoint.toString(),
|
uri: endpoint.toString(),
|
||||||
body: signOpts.body,
|
body: signOpts.body,
|
||||||
rejectUnauthorized: !credentials.ignoreSSLIssues as boolean,
|
rejectUnauthorized: !credentials.ignoreSSLIssues,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Object.keys(option).length !== 0) {
|
if (Object.keys(option).length !== 0) {
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export const rowFields: INodeProperties[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
// eslint-disable-next-line n8n-nodes-base/node-param-description-wrong-for-dynamic-options
|
|
||||||
description:
|
description:
|
||||||
'The name of SeaTable table to access. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
'The name of SeaTable table to access. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable n8n-nodes-base/node-param-display-name-miscased */
|
|
||||||
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
import { NodeTestHarness } from '@nodes-testing/node-test-harness';
|
||||||
import nock from 'nock';
|
import nock from 'nock';
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ const createMockExecuteFunction = (
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
_itemIndex: number,
|
_itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
return get(nodeParameters, parameter, fallbackValue);
|
return get(nodeParameters, parameter, fallbackValue);
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ export const createMockExecuteFunction = (nodeParameters: IDataObject) => {
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
_itemIndex: number,
|
_itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
return get(nodeParameters, parameter, fallbackValue);
|
return get(nodeParameters, parameter, fallbackValue);
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export async function shopifyApiRequest(
|
|||||||
|
|
||||||
// Only limit and fields are allowed for page_info links
|
// Only limit and fields are allowed for page_info links
|
||||||
// https://shopify.dev/docs/api/usage/pagination-rest#limitations-and-considerations
|
// https://shopify.dev/docs/api/usage/pagination-rest#limitations-and-considerations
|
||||||
if (uri && uri.includes('page_info')) {
|
if (uri?.includes('page_info')) {
|
||||||
options.qs = {};
|
options.qs = {};
|
||||||
|
|
||||||
if (query.limit) {
|
if (query.limit) {
|
||||||
|
|||||||
@@ -762,7 +762,6 @@ export class SlackV1 implements INodeType {
|
|||||||
} else if (block.type === 'section') {
|
} else if (block.type === 'section') {
|
||||||
const textUi = (blockUi.textUi as IDataObject).textValue as IDataObject;
|
const textUi = (blockUi.textUi as IDataObject).textValue as IDataObject;
|
||||||
if (textUi) {
|
if (textUi) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
||||||
const text: Text = {};
|
const text: Text = {};
|
||||||
if (textUi.type === 'plainText') {
|
if (textUi.type === 'plainText') {
|
||||||
text.type = 'plain_text';
|
text.type = 'plain_text';
|
||||||
@@ -827,7 +826,7 @@ export class SlackV1 implements INodeType {
|
|||||||
const confirm: Confirm = {};
|
const confirm: Confirm = {};
|
||||||
const titleUi = (confirmUi.titleUi as IDataObject)
|
const titleUi = (confirmUi.titleUi as IDataObject)
|
||||||
.titleValue as IDataObject;
|
.titleValue as IDataObject;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
||||||
const textUi = (confirmUi.textUi as IDataObject).textValue as IDataObject;
|
const textUi = (confirmUi.textUi as IDataObject).textValue as IDataObject;
|
||||||
const confirmTextUi = (confirmUi.confirmTextUi as IDataObject)
|
const confirmTextUi = (confirmUi.confirmTextUi as IDataObject)
|
||||||
.confirmValue as IDataObject;
|
.confirmValue as IDataObject;
|
||||||
@@ -979,7 +978,7 @@ export class SlackV1 implements INodeType {
|
|||||||
if (operation === 'getPermalink') {
|
if (operation === 'getPermalink') {
|
||||||
const channel = this.getNodeParameter('channelId', i) as string;
|
const channel = this.getNodeParameter('channelId', i) as string;
|
||||||
const timestamp = this.getNodeParameter('timestamp', i) as string;
|
const timestamp = this.getNodeParameter('timestamp', i) as string;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
||||||
const qs = {
|
const qs = {
|
||||||
channel,
|
channel,
|
||||||
message_ts: timestamp,
|
message_ts: timestamp,
|
||||||
@@ -1270,7 +1269,6 @@ export class SlackV1 implements INodeType {
|
|||||||
|
|
||||||
const additionalFields = this.getNodeParameter('additionalFields', i);
|
const additionalFields = this.getNodeParameter('additionalFields', i);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
||||||
const qs: IDataObject = {};
|
const qs: IDataObject = {};
|
||||||
|
|
||||||
Object.assign(qs, additionalFields);
|
Object.assign(qs, additionalFields);
|
||||||
@@ -1349,7 +1347,6 @@ export class SlackV1 implements INodeType {
|
|||||||
if (operation === 'get') {
|
if (operation === 'get') {
|
||||||
const additionalFields = this.getNodeParameter('additionalFields', i);
|
const additionalFields = this.getNodeParameter('additionalFields', i);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
||||||
const qs: IDataObject = {};
|
const qs: IDataObject = {};
|
||||||
|
|
||||||
Object.assign(qs, additionalFields);
|
Object.assign(qs, additionalFields);
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ export type SnowflakeCredential = Pick<
|
|||||||
);
|
);
|
||||||
|
|
||||||
const extractPrivateKey = (credential: { privateKey: string; passphrase?: string }) => {
|
const extractPrivateKey = (credential: { privateKey: string; passphrase?: string }) => {
|
||||||
const key = formatPrivateKey(credential.privateKey as string);
|
const key = formatPrivateKey(credential.privateKey);
|
||||||
|
|
||||||
if (!credential.passphrase) return key;
|
if (!credential.passphrase) return key;
|
||||||
|
|
||||||
const privateKeyObject = createPrivateKey({
|
const privateKeyObject = createPrivateKey({
|
||||||
key,
|
key,
|
||||||
format: 'pem',
|
format: 'pem',
|
||||||
passphrase: credential.passphrase as string,
|
passphrase: credential.passphrase,
|
||||||
});
|
});
|
||||||
|
|
||||||
return privateKeyObject.export({
|
return privateKeyObject.export({
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ describe('Test Supabase Node', () => {
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
itemIndex: number,
|
itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
const parameterValue = get(nodeParameters, parameter, fallbackValue);
|
const parameterValue = get(nodeParameters, parameter, fallbackValue);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export async function taigaApiRequest(
|
|||||||
resource: string,
|
resource: string,
|
||||||
body = {},
|
body = {},
|
||||||
query = {},
|
query = {},
|
||||||
uri?: string | undefined,
|
uri?: string,
|
||||||
option = {},
|
option = {},
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const credentials = await this.getCredentials('taigaApi');
|
const credentials = await this.getCredentials('taigaApi');
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export async function tapfiliateApiRequest(
|
|||||||
|
|
||||||
body: IDataObject = {},
|
body: IDataObject = {},
|
||||||
qs: IDataObject = {},
|
qs: IDataObject = {},
|
||||||
uri?: string | undefined,
|
uri?: string,
|
||||||
option: IDataObject = {},
|
option: IDataObject = {},
|
||||||
) {
|
) {
|
||||||
const credentials = await this.getCredentials('tapfiliateApi');
|
const credentials = await this.getCredentials('tapfiliateApi');
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ export const createMockExecuteFunction = (nodeParameters: IDataObject) => {
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
_itemIndex: number,
|
_itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
return get(nodeParameters, parameter, fallbackValue);
|
return get(nodeParameters, parameter, fallbackValue);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/dot-notation */
|
|
||||||
import set from 'lodash/set';
|
import set from 'lodash/set';
|
||||||
import {
|
import {
|
||||||
NodeConnectionTypes,
|
NodeConnectionTypes,
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import type {
|
|||||||
INodeTypeDescription,
|
INodeTypeDescription,
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
|
import { getSites, getCollections, getFields } from '../GenericFunctions';
|
||||||
import { router } from './actions/router';
|
import { router } from './actions/router';
|
||||||
import { versionDescription } from './actions/versionDescription';
|
import { versionDescription } from './actions/versionDescription';
|
||||||
import { getSites, getCollections, getFields } from '../GenericFunctions';
|
|
||||||
|
|
||||||
export class WebflowV2 implements INodeType {
|
export class WebflowV2 implements INodeType {
|
||||||
description: INodeTypeDescription;
|
description: INodeTypeDescription;
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export async function execute(
|
|||||||
let responseData;
|
let responseData;
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
try {
|
try {
|
||||||
const returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
const returnAll = this.getNodeParameter('returnAll', i);
|
||||||
const collectionId = this.getNodeParameter('collectionId', i) as string;
|
const collectionId = this.getNodeParameter('collectionId', i) as string;
|
||||||
const qs: IDataObject = {};
|
const qs: IDataObject = {};
|
||||||
|
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ export const isIpWhitelisted = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const address of whitelist) {
|
for (const address of whitelist) {
|
||||||
if (ip && ip.includes(address)) {
|
if (ip?.includes(address)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ export const createMockExecuteFunction = <T = IExecuteFunctions>(
|
|||||||
getNodeParameter(
|
getNodeParameter(
|
||||||
parameterName: string,
|
parameterName: string,
|
||||||
_itemIndex: number,
|
_itemIndex: number,
|
||||||
fallbackValue?: IDataObject | undefined,
|
fallbackValue?: IDataObject,
|
||||||
options?: IGetNodeParameterOptions | undefined,
|
options?: IGetNodeParameterOptions,
|
||||||
) {
|
) {
|
||||||
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
const parameter = options?.extractValue ? `${parameterName}.value` : parameterName;
|
||||||
return get(nodeParameters, parameter, fallbackValue);
|
return get(nodeParameters, parameter, fallbackValue);
|
||||||
|
|||||||
Reference in New Issue
Block a user