From 5a2ede181887906ad6ce14a5d06247664ecc3ee9 Mon Sep 17 00:00:00 2001 From: vitaligi <54726763+vitaligi@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:50:04 +0200 Subject: [PATCH 01/10] refactor: additional regex patterns and organize props alphabetically --- src/models/raster/constants.ts | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/models/raster/constants.ts b/src/models/raster/constants.ts index 5e0e203..9976106 100644 --- a/src/models/raster/constants.ts +++ b/src/models/raster/constants.ts @@ -2,13 +2,14 @@ import { zoomLevelToResolutionDeg, zoomLevelToResolutionMeter } from '@map-colonies/mc-utils'; export const VALIDATIONS = { - resolutionMeter: { - min: zoomLevelToResolutionMeter(22), - max: zoomLevelToResolutionMeter(0), + boundingBox: { + pattern: '^-?(0|[1-9]\\d*)(\\.\\d*)?,-?(0|[1-9]\\d*)(\\.\\d*)?,-?(0|[1-9]\\d*)(\\.\\d*)?,-?(0|[1-9]\\d*)(\\.\\d*)?$', }, - resolutionDeg: { - min: zoomLevelToResolutionDeg(22), - max: zoomLevelToResolutionDeg(0), + classification: { + pattern: '^[0-9]$|^[1-9][0-9]$|^(100)$', + }, + fileNames: { + pattern: '^.+.[Gg][Pp][Kk][Gg]$', }, horizontalAccuracyCE90: { min: 0.01, @@ -20,14 +21,19 @@ export const VALIDATIONS = { productVersion: { pattern: '^[1-9]\\d*(\\.(0|[1-9]\\d?))?$', }, - classification: { - pattern: '^[0-9]$|^[1-9][0-9]$|^(100)$', + resolutionDeg: { + min: zoomLevelToResolutionDeg(22), + max: zoomLevelToResolutionDeg(0), + }, + resolutionMeter: { + min: zoomLevelToResolutionMeter(22), + max: zoomLevelToResolutionMeter(0), }, scale: { min: 0, max: 100000000, }, - fileNames: { - pattern: '^.+.[Gg][Pp][Kk][Gg]$', + sensor: { + pattern: '^(?!\\s).+(? Date: Tue, 26 Nov 2024 09:58:44 +0200 Subject: [PATCH 02/10] refactor: use validation pattern --- src/models/raster/ingestion/zod/schemas/partData.schema.ts | 2 +- src/yaml/ingestionTrigger/partData/rasterLayerPartData.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/raster/ingestion/zod/schemas/partData.schema.ts b/src/models/raster/ingestion/zod/schemas/partData.schema.ts index 72325cf..b4d3f94 100644 --- a/src/models/raster/ingestion/zod/schemas/partData.schema.ts +++ b/src/models/raster/ingestion/zod/schemas/partData.schema.ts @@ -23,7 +23,7 @@ export const partSchema = z .min(VALIDATIONS.resolutionMeter.min as number) .max(VALIDATIONS.resolutionMeter.max as number), horizontalAccuracyCE90: z.number().min(VALIDATIONS.horizontalAccuracyCE90.min).max(VALIDATIONS.horizontalAccuracyCE90.max), - sensors: z.array(z.string().regex(new RegExp('^(?! ).+(?(), diff --git a/src/yaml/ingestionTrigger/partData/rasterLayerPartData.yaml b/src/yaml/ingestionTrigger/partData/rasterLayerPartData.yaml index 149f504..f45d936 100644 --- a/src/yaml/ingestionTrigger/partData/rasterLayerPartData.yaml +++ b/src/yaml/ingestionTrigger/partData/rasterLayerPartData.yaml @@ -66,7 +66,7 @@ components: type: array items: type: string - pattern: ^(?! ).+(? Date: Tue, 26 Nov 2024 10:18:55 +0200 Subject: [PATCH 03/10] feat: aggregation zod schema --- .../aggregationLayerMetadata.schema.ts | 92 +++++++++++++++++++ .../raster/ingestion/zod/schemas/index.ts | 3 +- 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts diff --git a/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts b/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts new file mode 100644 index 0000000..4cf333c --- /dev/null +++ b/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts @@ -0,0 +1,92 @@ +import type { MultiPolygon, Polygon } from 'geojson'; +import { z, type ZodType } from 'zod'; +import type { AggregationLayerMetadata } from '../../../../polygonParts/aggregationLayerMetadata'; +import { VALIDATIONS } from '../../../constants'; + +export const aggregationLayerMetadataSchema: ZodType = z + .object( + { + footprint: z.custom(), + imagingTimeBeginUTC: z.coerce.date({ message: 'Aggregation of imaging time begin UTC should be a datetime' }), + imagingTimeEndUTC: z.coerce.date({ message: 'Aggregation of imaging time end UTC should be a datetime' }), + maxHorizontalAccuracyCE90: z + .number({ message: 'Aggregation of max horizontal accuracy CE90 should be a number' }) + .min(VALIDATIONS.horizontalAccuracyCE90.min, { + message: `Aggregation of max horizontal accuracy CE90 should not be less than ${VALIDATIONS.horizontalAccuracyCE90.min}`, + }) + .max(VALIDATIONS.horizontalAccuracyCE90.max, { + message: `Aggregation of max horizontal accuracy CE90 should not be larger than ${VALIDATIONS.horizontalAccuracyCE90.max}`, + }), + maxResolutionDeg: z + .number({ message: 'Aggregation of max resolution degree should be a number' }) + .min(VALIDATIONS.resolutionDeg.min as number, { + message: `Aggregation of max resolution degree should not be less than ${VALIDATIONS.resolutionDeg.min as number}`, + }) + .max(VALIDATIONS.resolutionDeg.max as number, { + message: `Aggregation of max resolution degree should not be larger than ${VALIDATIONS.resolutionDeg.max as number}`, + }), + maxResolutionMeter: z + .number({ message: 'Aggregation of max resolution meter should be a number' }) + .min(VALIDATIONS.resolutionMeter.min as number, { + message: `Aggregation of max resolution meter should not be less than ${VALIDATIONS.resolutionMeter.min as number}`, + }) + .max(VALIDATIONS.resolutionMeter.max as number, { + message: `Aggregation of max resolution meter should not be larger than ${VALIDATIONS.resolutionMeter.max as number}`, + }), + minHorizontalAccuracyCE90: z + .number({ message: 'Aggregation of min horizontal accuracy CE90 should be a number' }) + .min(VALIDATIONS.horizontalAccuracyCE90.min, { + message: `Aggregation of min horizontal accuracy CE90 should not be less than ${VALIDATIONS.horizontalAccuracyCE90.min}`, + }) + .max(VALIDATIONS.horizontalAccuracyCE90.max, { + message: `Aggregation of min horizontal accuracy CE90 should not be larger than ${VALIDATIONS.horizontalAccuracyCE90.max}`, + }), + minResolutionDeg: z + .number({ message: 'Aggregation of min resolution degree should be a number' }) + .min(VALIDATIONS.resolutionDeg.min as number, { + message: `Aggregation of min resolution degree should not be less than ${VALIDATIONS.resolutionDeg.min as number}`, + }) + .max(VALIDATIONS.resolutionDeg.max as number, { + message: `Aggregation of min resolution degree should not be larger than ${VALIDATIONS.resolutionDeg.max as number}`, + }), + minResolutionMeter: z + .number({ message: 'Aggregation of min resolution meter should be a number' }) + .min(VALIDATIONS.resolutionMeter.min as number, { + message: `Aggregation of min resolution meter should not be less than ${VALIDATIONS.resolutionMeter.min as number}`, + }) + .max(VALIDATIONS.resolutionMeter.max as number, { + message: `Aggregation of min resolution meter should not be larger than ${VALIDATIONS.resolutionMeter.max as number}`, + }), + productBoundingBox: z + .string({ message: 'Aggregation of product bounding box should be a string' }) + .regex(new RegExp(VALIDATIONS.boundingBox.pattern), { + message: 'Aggregation of product bounding box must be of the shape min_x,min_y,max_x,max_y', + }), + sensors: z + .array( + z.string({ message: 'Aggregation of sensors should be an array of strings' }).regex(new RegExp(VALIDATIONS.sensor.pattern), { + message: 'Aggregation of sensors should be an array with items not starting or ending with a whitespace', + }), + { message: 'Aggregation of sensors should be an array' } + ) + .min(1, { message: 'Aggregation of sensors should have an array length of at least 1' }), + }, + { message: 'Aggregation of layer metadata should be an object' } + ) + .strict() + .refine( + (aggregationLayerMetadata) => + aggregationLayerMetadata.imagingTimeBeginUTC <= aggregationLayerMetadata.imagingTimeEndUTC && + aggregationLayerMetadata.imagingTimeEndUTC <= new Date(), + { message: 'Aggregation of imaging time begin UTC should be less than or equal to imaging time end UTC and both less than current timestamp' } + ) + .refine((aggregationLayerMetadata) => aggregationLayerMetadata.minHorizontalAccuracyCE90 <= aggregationLayerMetadata.maxHorizontalAccuracyCE90, { + message: 'Aggregation of min horizontal accuracy CE90 should be less than or equal to max horizontal accuracy CE90', + }) + .refine((aggregationLayerMetadata) => aggregationLayerMetadata.minResolutionDeg <= aggregationLayerMetadata.maxResolutionDeg, { + message: 'Aggregation of min resolution degree should be less than or equal to max resolution degree', + }) + .refine((aggregationLayerMetadata) => aggregationLayerMetadata.minResolutionMeter <= aggregationLayerMetadata.maxResolutionMeter, { + message: 'Aggregation of min resolution meter should be less than or equal to max resolution meter', + }) + .describe('aggregationLayerMetadataSchema'); diff --git a/src/models/raster/ingestion/zod/schemas/index.ts b/src/models/raster/ingestion/zod/schemas/index.ts index 33dc810..f09d169 100644 --- a/src/models/raster/ingestion/zod/schemas/index.ts +++ b/src/models/raster/ingestion/zod/schemas/index.ts @@ -1,3 +1,4 @@ -export * from './partData.schema'; +export * from './aggregationLayerMetadata.schema'; export * from './inputFiles.schema'; export * from './metadata.schema'; +export * from './partData.schema'; From cb2f1562c5663655d12ba442c0d086f1839dfcc3 Mon Sep 17 00:00:00 2001 From: vitaligi <54726763+vitaligi@users.noreply.github.com> Date: Tue, 26 Nov 2024 10:27:11 +0200 Subject: [PATCH 04/10] refactor: add time validation between begin, end and current timestamp --- src/models/raster/ingestion/zod/schemas/partData.schema.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/models/raster/ingestion/zod/schemas/partData.schema.ts b/src/models/raster/ingestion/zod/schemas/partData.schema.ts index b4d3f94..0c90c66 100644 --- a/src/models/raster/ingestion/zod/schemas/partData.schema.ts +++ b/src/models/raster/ingestion/zod/schemas/partData.schema.ts @@ -28,4 +28,5 @@ export const partSchema = z cities: z.array(z.string().min(1)).optional(), footprint: z.custom(), }) + .refine((part) => part.imagingTimeBeginUTC <= part.imagingTimeEndUTC && part.imagingTimeEndUTC <= new Date()) .describe('partSchema'); From 6a03c2c152c3d9a65ef0663bceb791acbb8b0f3f Mon Sep 17 00:00:00 2001 From: vitaligi <54726763+vitaligi@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:12:17 +0200 Subject: [PATCH 05/10] fix: openapi sensor regex pattern --- src/yaml/ingestionTrigger/partData/rasterLayerPartData.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yaml/ingestionTrigger/partData/rasterLayerPartData.yaml b/src/yaml/ingestionTrigger/partData/rasterLayerPartData.yaml index f45d936..6ab59bc 100644 --- a/src/yaml/ingestionTrigger/partData/rasterLayerPartData.yaml +++ b/src/yaml/ingestionTrigger/partData/rasterLayerPartData.yaml @@ -66,7 +66,7 @@ components: type: array items: type: string - pattern: ^(?!\\s).+(? Date: Tue, 26 Nov 2024 14:19:10 +0200 Subject: [PATCH 06/10] fix: file name pattern validation --- src/models/raster/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/raster/constants.ts b/src/models/raster/constants.ts index 9976106..bf8c7bf 100644 --- a/src/models/raster/constants.ts +++ b/src/models/raster/constants.ts @@ -9,7 +9,7 @@ export const VALIDATIONS = { pattern: '^[0-9]$|^[1-9][0-9]$|^(100)$', }, fileNames: { - pattern: '^.+.[Gg][Pp][Kk][Gg]$', + pattern: '^.+\\.[Gg][Pp][Kk][Gg]$', }, horizontalAccuracyCE90: { min: 0.01, From 74889ad30e64ffe39b7e45f90015916831ad3635 Mon Sep 17 00:00:00 2001 From: vitaligi <54726763+vitaligi@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:19:33 +0200 Subject: [PATCH 07/10] style: remove extra spaces --- src/yaml/ingestionTrigger/inputFiles/rasterLayerInputFiles.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yaml/ingestionTrigger/inputFiles/rasterLayerInputFiles.yaml b/src/yaml/ingestionTrigger/inputFiles/rasterLayerInputFiles.yaml index 127845b..59a6a62 100644 --- a/src/yaml/ingestionTrigger/inputFiles/rasterLayerInputFiles.yaml +++ b/src/yaml/ingestionTrigger/inputFiles/rasterLayerInputFiles.yaml @@ -21,4 +21,4 @@ components: example: ['example.gpkg'] required: - originDirectory - - fileNames + - fileNames From 4c7c0c537cda1a71ed94eb14881ef9b757359922 Mon Sep 17 00:00:00 2001 From: vitaligi <54726763+vitaligi@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:40:08 +0200 Subject: [PATCH 08/10] refactor: improve error messages --- .../zod/schemas/aggregationLayerMetadata.schema.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts b/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts index 4cf333c..16dacc7 100644 --- a/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts +++ b/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts @@ -65,7 +65,7 @@ export const aggregationLayerMetadataSchema: ZodType = sensors: z .array( z.string({ message: 'Aggregation of sensors should be an array of strings' }).regex(new RegExp(VALIDATIONS.sensor.pattern), { - message: 'Aggregation of sensors should be an array with items not starting or ending with a whitespace', + message: 'Aggregation of sensors should be an array with items not starting or ending with whitespace characters', }), { message: 'Aggregation of sensors should be an array' } ) @@ -78,7 +78,10 @@ export const aggregationLayerMetadataSchema: ZodType = (aggregationLayerMetadata) => aggregationLayerMetadata.imagingTimeBeginUTC <= aggregationLayerMetadata.imagingTimeEndUTC && aggregationLayerMetadata.imagingTimeEndUTC <= new Date(), - { message: 'Aggregation of imaging time begin UTC should be less than or equal to imaging time end UTC and both less than current timestamp' } + { + message: + 'Aggregation of imaging time begin UTC should be less than or equal to imaging time end UTC and both less than or equal to current timestamp', + } ) .refine((aggregationLayerMetadata) => aggregationLayerMetadata.minHorizontalAccuracyCE90 <= aggregationLayerMetadata.maxHorizontalAccuracyCE90, { message: 'Aggregation of min horizontal accuracy CE90 should be less than or equal to max horizontal accuracy CE90', From 84789fe6fdcd9b5fa78a2acdc557fe6ffabd8ce1 Mon Sep 17 00:00:00 2001 From: vitaligi <54726763+vitaligi@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:41:34 +0200 Subject: [PATCH 09/10] refactor: removed prefix of each error message --- .../aggregationLayerMetadata.schema.ts | 67 +++++++++---------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts b/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts index 16dacc7..42a14a3 100644 --- a/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts +++ b/src/models/raster/ingestion/zod/schemas/aggregationLayerMetadata.schema.ts @@ -7,71 +7,69 @@ export const aggregationLayerMetadataSchema: ZodType = .object( { footprint: z.custom(), - imagingTimeBeginUTC: z.coerce.date({ message: 'Aggregation of imaging time begin UTC should be a datetime' }), - imagingTimeEndUTC: z.coerce.date({ message: 'Aggregation of imaging time end UTC should be a datetime' }), + imagingTimeBeginUTC: z.coerce.date({ message: 'Imaging time begin UTC should be a datetime' }), + imagingTimeEndUTC: z.coerce.date({ message: 'Imaging time end UTC should be a datetime' }), maxHorizontalAccuracyCE90: z - .number({ message: 'Aggregation of max horizontal accuracy CE90 should be a number' }) + .number({ message: 'Max horizontal accuracy CE90 should be a number' }) .min(VALIDATIONS.horizontalAccuracyCE90.min, { - message: `Aggregation of max horizontal accuracy CE90 should not be less than ${VALIDATIONS.horizontalAccuracyCE90.min}`, + message: `Max horizontal accuracy CE90 should not be less than ${VALIDATIONS.horizontalAccuracyCE90.min}`, }) .max(VALIDATIONS.horizontalAccuracyCE90.max, { - message: `Aggregation of max horizontal accuracy CE90 should not be larger than ${VALIDATIONS.horizontalAccuracyCE90.max}`, + message: `Max horizontal accuracy CE90 should not be larger than ${VALIDATIONS.horizontalAccuracyCE90.max}`, }), maxResolutionDeg: z - .number({ message: 'Aggregation of max resolution degree should be a number' }) + .number({ message: 'Max resolution degree should be a number' }) .min(VALIDATIONS.resolutionDeg.min as number, { - message: `Aggregation of max resolution degree should not be less than ${VALIDATIONS.resolutionDeg.min as number}`, + message: `Max resolution degree should not be less than ${VALIDATIONS.resolutionDeg.min as number}`, }) .max(VALIDATIONS.resolutionDeg.max as number, { - message: `Aggregation of max resolution degree should not be larger than ${VALIDATIONS.resolutionDeg.max as number}`, + message: `Max resolution degree should not be larger than ${VALIDATIONS.resolutionDeg.max as number}`, }), maxResolutionMeter: z - .number({ message: 'Aggregation of max resolution meter should be a number' }) + .number({ message: 'Max resolution meter should be a number' }) .min(VALIDATIONS.resolutionMeter.min as number, { - message: `Aggregation of max resolution meter should not be less than ${VALIDATIONS.resolutionMeter.min as number}`, + message: `Max resolution meter should not be less than ${VALIDATIONS.resolutionMeter.min as number}`, }) .max(VALIDATIONS.resolutionMeter.max as number, { - message: `Aggregation of max resolution meter should not be larger than ${VALIDATIONS.resolutionMeter.max as number}`, + message: `Max resolution meter should not be larger than ${VALIDATIONS.resolutionMeter.max as number}`, }), minHorizontalAccuracyCE90: z - .number({ message: 'Aggregation of min horizontal accuracy CE90 should be a number' }) + .number({ message: 'Min horizontal accuracy CE90 should be a number' }) .min(VALIDATIONS.horizontalAccuracyCE90.min, { - message: `Aggregation of min horizontal accuracy CE90 should not be less than ${VALIDATIONS.horizontalAccuracyCE90.min}`, + message: `Min horizontal accuracy CE90 should not be less than ${VALIDATIONS.horizontalAccuracyCE90.min}`, }) .max(VALIDATIONS.horizontalAccuracyCE90.max, { - message: `Aggregation of min horizontal accuracy CE90 should not be larger than ${VALIDATIONS.horizontalAccuracyCE90.max}`, + message: `Min horizontal accuracy CE90 should not be larger than ${VALIDATIONS.horizontalAccuracyCE90.max}`, }), minResolutionDeg: z - .number({ message: 'Aggregation of min resolution degree should be a number' }) + .number({ message: 'Min resolution degree should be a number' }) .min(VALIDATIONS.resolutionDeg.min as number, { - message: `Aggregation of min resolution degree should not be less than ${VALIDATIONS.resolutionDeg.min as number}`, + message: `Min resolution degree should not be less than ${VALIDATIONS.resolutionDeg.min as number}`, }) .max(VALIDATIONS.resolutionDeg.max as number, { - message: `Aggregation of min resolution degree should not be larger than ${VALIDATIONS.resolutionDeg.max as number}`, + message: `Min resolution degree should not be larger than ${VALIDATIONS.resolutionDeg.max as number}`, }), minResolutionMeter: z - .number({ message: 'Aggregation of min resolution meter should be a number' }) + .number({ message: 'Min resolution meter should be a number' }) .min(VALIDATIONS.resolutionMeter.min as number, { - message: `Aggregation of min resolution meter should not be less than ${VALIDATIONS.resolutionMeter.min as number}`, + message: `Min resolution meter should not be less than ${VALIDATIONS.resolutionMeter.min as number}`, }) .max(VALIDATIONS.resolutionMeter.max as number, { - message: `Aggregation of min resolution meter should not be larger than ${VALIDATIONS.resolutionMeter.max as number}`, - }), - productBoundingBox: z - .string({ message: 'Aggregation of product bounding box should be a string' }) - .regex(new RegExp(VALIDATIONS.boundingBox.pattern), { - message: 'Aggregation of product bounding box must be of the shape min_x,min_y,max_x,max_y', + message: `Min resolution meter should not be larger than ${VALIDATIONS.resolutionMeter.max as number}`, }), + productBoundingBox: z.string({ message: 'Product bounding box should be a string' }).regex(new RegExp(VALIDATIONS.boundingBox.pattern), { + message: 'Product bounding box must be of the shape min_x,min_y,max_x,max_y', + }), sensors: z .array( - z.string({ message: 'Aggregation of sensors should be an array of strings' }).regex(new RegExp(VALIDATIONS.sensor.pattern), { - message: 'Aggregation of sensors should be an array with items not starting or ending with whitespace characters', + z.string({ message: 'Sensors should be an array of strings' }).regex(new RegExp(VALIDATIONS.sensor.pattern), { + message: 'Sensors should be an array with items not starting or ending with whitespace characters', }), - { message: 'Aggregation of sensors should be an array' } + { message: 'Sensors should be an array' } ) - .min(1, { message: 'Aggregation of sensors should have an array length of at least 1' }), + .min(1, { message: 'Sensors should have an array length of at least 1' }), }, - { message: 'Aggregation of layer metadata should be an object' } + { message: 'Layer metadata should be an object' } ) .strict() .refine( @@ -79,17 +77,16 @@ export const aggregationLayerMetadataSchema: ZodType = aggregationLayerMetadata.imagingTimeBeginUTC <= aggregationLayerMetadata.imagingTimeEndUTC && aggregationLayerMetadata.imagingTimeEndUTC <= new Date(), { - message: - 'Aggregation of imaging time begin UTC should be less than or equal to imaging time end UTC and both less than or equal to current timestamp', + message: 'Imaging time begin UTC should be less than or equal to imaging time end UTC and both less than or equal to current timestamp', } ) .refine((aggregationLayerMetadata) => aggregationLayerMetadata.minHorizontalAccuracyCE90 <= aggregationLayerMetadata.maxHorizontalAccuracyCE90, { - message: 'Aggregation of min horizontal accuracy CE90 should be less than or equal to max horizontal accuracy CE90', + message: 'Min horizontal accuracy CE90 should be less than or equal to max horizontal accuracy CE90', }) .refine((aggregationLayerMetadata) => aggregationLayerMetadata.minResolutionDeg <= aggregationLayerMetadata.maxResolutionDeg, { - message: 'Aggregation of min resolution degree should be less than or equal to max resolution degree', + message: 'Min resolution degree should be less than or equal to max resolution degree', }) .refine((aggregationLayerMetadata) => aggregationLayerMetadata.minResolutionMeter <= aggregationLayerMetadata.maxResolutionMeter, { - message: 'Aggregation of min resolution meter should be less than or equal to max resolution meter', + message: 'Min resolution meter should be less than or equal to max resolution meter', }) .describe('aggregationLayerMetadataSchema'); From 6c9d54defe05cdec34aa601f11fc835b2df77159 Mon Sep 17 00:00:00 2001 From: vitaligi <54726763+vitaligi@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:43:47 +0200 Subject: [PATCH 10/10] refactor: error messages for part data zod schema --- .../ingestion/zod/schemas/partData.schema.ts | 76 ++++++++++++++----- 1 file changed, 56 insertions(+), 20 deletions(-) diff --git a/src/models/raster/ingestion/zod/schemas/partData.schema.ts b/src/models/raster/ingestion/zod/schemas/partData.schema.ts index 0c90c66..8bdc4be 100644 --- a/src/models/raster/ingestion/zod/schemas/partData.schema.ts +++ b/src/models/raster/ingestion/zod/schemas/partData.schema.ts @@ -1,32 +1,68 @@ /* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { Polygon } from 'geojson'; import { z } from 'zod'; -import { Polygon } from 'geojson'; import { VALIDATIONS } from '../../../constants'; export const partSchema = z .object({ - sourceId: z.string().optional(), - sourceName: z.string().min(1), - description: z.string().optional(), - imagingTimeBeginUTC: z.coerce.date(), - imagingTimeEndUTC: z.coerce.date(), + sourceId: z.string({ message: 'Source id should be a string' }).optional(), + sourceName: z.string({ message: 'Source name should be a string' }).min(1, { message: 'Source name should have length of at least 1' }), + description: z.string({ message: 'Description should be a string' }).optional(), + imagingTimeBeginUTC: z.coerce.date({ message: 'Imaging time begin UTC should be a datetime' }), + imagingTimeEndUTC: z.coerce.date({ message: 'Imaging time end UTC should be a datetime' }), resolutionDegree: z - .number() - .min(VALIDATIONS.resolutionDeg.min as number) - .max(VALIDATIONS.resolutionDeg.max as number), + .number({ message: 'Resolution degree should be a number' }) + .min(VALIDATIONS.resolutionDeg.min as number, { + message: `Resolution degree should not be less than ${VALIDATIONS.resolutionDeg.min as number}`, + }) + .max(VALIDATIONS.resolutionDeg.max as number, { + message: `Resolution degree should not be larger than ${VALIDATIONS.resolutionDeg.max as number}`, + }), resolutionMeter: z - .number() - .min(VALIDATIONS.resolutionMeter.min as number) - .max(VALIDATIONS.resolutionMeter.max as number), + .number({ message: 'Resolution meter should be a number' }) + .min(VALIDATIONS.resolutionMeter.min as number, { + message: `Resolution meter should not be less than ${VALIDATIONS.resolutionMeter.min as number}`, + }) + .max(VALIDATIONS.resolutionMeter.max as number, { + message: `Resolution meter should not be larger than ${VALIDATIONS.resolutionMeter.max as number}`, + }), sourceResolutionMeter: z - .number() - .min(VALIDATIONS.resolutionMeter.min as number) - .max(VALIDATIONS.resolutionMeter.max as number), - horizontalAccuracyCE90: z.number().min(VALIDATIONS.horizontalAccuracyCE90.min).max(VALIDATIONS.horizontalAccuracyCE90.max), - sensors: z.array(z.string().regex(new RegExp(VALIDATIONS.sensor.pattern))).min(1), - countries: z.array(z.string().min(1)).optional(), - cities: z.array(z.string().min(1)).optional(), + .number({ message: 'Source resolution meter should be a number' }) + .min(VALIDATIONS.resolutionMeter.min as number, { + message: `Source resolution meter should not be less than ${VALIDATIONS.resolutionMeter.min as number}`, + }) + .max(VALIDATIONS.resolutionMeter.max as number, { + message: `Source resolution meter should not be larger than ${VALIDATIONS.resolutionMeter.max as number}`, + }), + horizontalAccuracyCE90: z + .number({ message: 'Horizontal accuracy CE90 should be a number' }) + .min(VALIDATIONS.horizontalAccuracyCE90.min, { + message: `Horizontal accuracy CE90 should not be less than ${VALIDATIONS.horizontalAccuracyCE90.min}`, + }) + .max(VALIDATIONS.horizontalAccuracyCE90.max, { + message: `Horizontal accuracy CE90 should not be larger than ${VALIDATIONS.horizontalAccuracyCE90.max}`, + }), + sensors: z + .array( + z.string({ message: 'Sensors should be an array of strings' }).regex(new RegExp(VALIDATIONS.sensor.pattern), { + message: 'Sensors should be an array with items not starting or ending with whitespace characters', + }), + { message: 'Sensors should be an array' } + ) + .min(1, { message: 'Sensors should have an array length of at least 1' }), + countries: z + .array(z.string({ message: 'Countries should be an array of strings' }).min(1, { message: 'Countries should have length of at least 1' }), { + message: 'Countries should be an array', + }) + .optional(), + cities: z + .array(z.string({ message: 'Cities should be an array of strings' }).min(1, { message: 'Cities should have length of at least 1' }), { + message: 'Cities should be an array', + }) + .optional(), footprint: z.custom(), }) - .refine((part) => part.imagingTimeBeginUTC <= part.imagingTimeEndUTC && part.imagingTimeEndUTC <= new Date()) + .refine((part) => part.imagingTimeBeginUTC <= part.imagingTimeEndUTC && part.imagingTimeEndUTC <= new Date(), { + message: 'Imaging time begin UTC should be less than or equal to imaging time end UTC and both less than or equal to current timestamp', + }) .describe('partSchema');