Skip to content

Commit

Permalink
✨ Added support for more types in validation
Browse files Browse the repository at this point in the history
  • Loading branch information
MiloradFilipovic committed May 8, 2023
1 parent 91a442c commit 3743981
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import type { IUpdateInformation } from '@/Interface';
import type {
FieldType,
INodeIssues,
INodeParameters,
INodeProperties,
Expand Down Expand Up @@ -30,6 +31,7 @@ interface Props {
}
const props = defineProps<Props>();
const FORCE_TEXT_INPUT_FOR_TYPES: FieldType[] = ['time', 'object'];
const emit = defineEmits<{
(event: 'fieldValueChanged', value: IUpdateInformation): void;
Expand All @@ -48,7 +50,7 @@ const fieldsUi = computed<INodeProperties[]>(() => {
displayName: getFieldLabel(field),
// Set part of the path to each param name so value can be fetched properly by input parameter list component
name: `value["${field.id}"]`,
type: (field.type as NodePropertyTypes) || 'string',
type: getParamType(field),
default: field.type === 'boolean' ? false : '',
required: field.required,
description: getFieldDescription(field),
Expand Down Expand Up @@ -218,6 +220,13 @@ function getFieldIssues(field: INodeProperties): string[] {
return fieldIssues;
}
function getParamType(field: ResourceMapperField): NodePropertyTypes {
if (field.type && !FORCE_TEXT_INPUT_FOR_TYPES.includes(field.type)) {
return field.type as NodePropertyTypes;
}
return 'string';
}
function onValueChanged(value: IUpdateInformation): void {
emit('fieldValueChanged', value);
}
Expand Down
19 changes: 9 additions & 10 deletions packages/nodes-base/nodes/Postgres/v2/methods/resourceMapping.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import type {
ILoadOptionsFunctions,
ResourceMapperFields,
ResourceMapperFieldType,
} from 'n8n-workflow';
import type { ILoadOptionsFunctions, ResourceMapperFields, FieldType } from 'n8n-workflow';
import { getTableSchema, isColumnUnique } from '../helpers/utils';
import { Connections } from '../transport';
import type { ConnectionsData } from '../helpers/interfaces';

const fieldTypeMapping: Record<ResourceMapperFieldType, string[]> = {
const fieldTypeMapping: Record<FieldType, string[]> = {
string: ['text', 'varchar', 'character varying', 'character', 'char'],
number: [
'integer',
Expand All @@ -29,15 +25,18 @@ const fieldTypeMapping: Record<ResourceMapperFieldType, string[]> = {
'timestamp without time zone',
'timestamp with time zone',
],
time: ['time', 'time without time zone', 'time with time zone'],
object: ['json', 'jsonb'],
array: [],
};

function mapPostgresType(postgresType: string): ResourceMapperFieldType {
let mappedType: ResourceMapperFieldType = 'string';
function mapPostgresType(postgresType: string): FieldType {
let mappedType: FieldType = 'string';

for (const t of Object.keys(fieldTypeMapping)) {
const postgresTypes = fieldTypeMapping[t as ResourceMapperFieldType];
const postgresTypes = fieldTypeMapping[t as FieldType];
if (postgresTypes.includes(postgresType)) {
mappedType = t as ResourceMapperFieldType;
mappedType = t as FieldType;
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/workflow/src/Interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1960,11 +1960,11 @@ export interface ResourceMapperField {
canBeUsedToMatch?: boolean;
required: boolean;
display: boolean;
type?: ResourceMapperFieldType;
type?: FieldType;
removed?: boolean;
}

export type ResourceMapperFieldType = 'string' | 'number' | 'dateTime' | 'boolean';
export type FieldType = 'string' | 'number' | 'dateTime' | 'boolean' | 'time' | 'array' | 'object';

export type ResourceMapperValue = {
mappingMode: string;
Expand Down
14 changes: 13 additions & 1 deletion packages/workflow/src/NodeHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,15 @@ import type {
IWorkflowExecuteAdditionalData,
NodeParameterValue,
WebhookHttpMethod,
FieldType,
} from './Interfaces';
import {
isBoolean,
isDateTime,
isNumeric,
isObject,
isResourceMapperValue,
isTime,
isValidResourceLocatorParameterValue,
} from './type-guards';
import { deepCopy } from './utils';
Expand Down Expand Up @@ -1103,7 +1106,7 @@ export function nodeIssuesToString(issues: INodeIssues, node?: INode): string[]
return nodeIssues;
}

export const validateFieldType = (value: unknown, type: string): boolean => {
export const validateFieldType = (value: unknown, type: FieldType): boolean => {
if (value === null || value === undefined) return true;
switch (type.toLocaleLowerCase()) {
case 'number': {
Expand All @@ -1115,6 +1118,15 @@ export const validateFieldType = (value: unknown, type: string): boolean => {
case 'datetime': {
return isDateTime(value);
}
case 'time': {
return isTime(value);
}
case 'object': {
return isObject(value);
}
case 'array': {
return Array.isArray(value);
}
default: {
return true;
}
Expand Down
34 changes: 32 additions & 2 deletions packages/workflow/src/type-guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,15 @@ export const isBoolean = (value: unknown): value is boolean => {
if (typeof value === 'boolean') {
return true;
}
// TODO: Extend this to more types/values if needed
if (typeof value === 'string') {
return ['true', 'false'].includes(value.toLowerCase());
const num = Number(value);
if (num === 0) {
return false;
} else if (num === 1) {
return true;
} else {
return ['true', 'false'].includes(value.toLowerCase());
}
}
return false;
};
Expand All @@ -74,3 +80,27 @@ export const isDateTime = (value: unknown): value is Date => {
const d = new Date(String(value));
return d instanceof Date && !isNaN(d.valueOf());
};

export const isTime = (value: unknown): value is string => {
return /\d{2}:\d{2}(:\d{2})?(\-|\+\d{4})?/s.test(String(value));
};

export const isArray = (value: unknown): value is unknown[] => {
try {
return Array.isArray(JSON.parse(`[${String(value)}]`));
} catch (e) {
return false;
}
};

export const isObject = (value: unknown): value is object => {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const o = JSON.parse(String(value));

if (o && typeof o === 'object' && !isArray(o)) {
return true;
}
} catch (e) {}
return false;
};

0 comments on commit 3743981

Please sign in to comment.