diff --git a/src/schemas/core/index.ts b/src/schemas/core/index.ts index 3a73c9e..16b0b2a 100644 --- a/src/schemas/core/index.ts +++ b/src/schemas/core/index.ts @@ -6,3 +6,4 @@ export * from './aggregation.schema'; export * from './callback.schema'; export * from './link.schema'; export * from './file.schema'; +export * from './polygonParts.schema'; diff --git a/src/schemas/core/polygonParts.schema.ts b/src/schemas/core/polygonParts.schema.ts new file mode 100644 index 0000000..7a6d458 --- /dev/null +++ b/src/schemas/core/polygonParts.schema.ts @@ -0,0 +1,90 @@ +import { z } from 'zod'; +import { CORE_VALIDATIONS, INGESTION_VALIDATIONS } from '../../constants'; +import { featureCollectionSchema, featureSchema, multiPolygonSchema, polygonSchema } from './geo.schema'; + +const polygonalGeometrySchema = polygonSchema.or(multiPolygonSchema).describe('polygonalGeometrySchema'); + +export const partSchema = z + .object({ + id: z.string(), + 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({ message: 'Resolution degree should be a number' }) + .min(CORE_VALIDATIONS.resolutionDeg.min, { + message: `Resolution degree should not be less than ${CORE_VALIDATIONS.resolutionDeg.min}`, + }) + .max(CORE_VALIDATIONS.resolutionDeg.max, { + message: `Resolution degree should not be larger than ${CORE_VALIDATIONS.resolutionDeg.max}`, + }), + resolutionMeter: z + .number({ message: 'Resolution meter should be a number' }) + .min(INGESTION_VALIDATIONS.resolutionMeter.min, { + message: `Resolution meter should not be less than ${INGESTION_VALIDATIONS.resolutionMeter.min}`, + }) + .max(INGESTION_VALIDATIONS.resolutionMeter.max, { + message: `Resolution meter should not be larger than ${INGESTION_VALIDATIONS.resolutionMeter.max}`, + }), + sourceResolutionMeter: z + .number({ message: 'Source resolution meter should be a number' }) + .min(INGESTION_VALIDATIONS.resolutionMeter.min, { + message: `Source resolution meter should not be less than ${INGESTION_VALIDATIONS.resolutionMeter.min}`, + }) + .max(INGESTION_VALIDATIONS.resolutionMeter.max, { + message: `Source resolution meter should not be larger than ${INGESTION_VALIDATIONS.resolutionMeter.max}`, + }), + horizontalAccuracyCE90: z + .number({ message: 'Horizontal accuracy CE90 should be a number' }) + .min(INGESTION_VALIDATIONS.horizontalAccuracyCE90.min, { + message: `Horizontal accuracy CE90 should not be less than ${INGESTION_VALIDATIONS.horizontalAccuracyCE90.min}`, + }) + .max(INGESTION_VALIDATIONS.horizontalAccuracyCE90.max, { + message: `Horizontal accuracy CE90 should not be larger than ${INGESTION_VALIDATIONS.horizontalAccuracyCE90.max}`, + }), + sensors: z + .array( + z.string({ message: 'Sensors should be an array of strings' }).regex(new RegExp(INGESTION_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(), + }) + .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'); +export const partsSchema = z.array(partSchema).describe('partsSchema'); + +//#region intersection +export const intersectionFeaturePropertiesSchema = partSchema._def.schema + .pick({ resolutionDegree: true }) + .describe('intersectionFeaturePropertiesSchema'); +export const intersectionFeatureGeometrySchema = polygonalGeometrySchema.describe('intersectionFeatureGeometrySchema'); +export const intersectionFeatureSchema = featureSchema(intersectionFeatureGeometrySchema, intersectionFeaturePropertiesSchema).describe( + 'intersectionFeatureGeometrySchema' +); +export const intersectionFeatureCollectionSchema = featureCollectionSchema(intersectionFeatureSchema) + .and(z.object({ features: intersectionFeatureSchema.array().length(1) })) + .describe('intersectionFeatureCollectionSchema'); + +export const intersectedFeaturePropertiesSchema = z.object({}).strict().describe('intersectedFeaturePropertiesSchema'); +export const intersectedFeatureGeometrySchema = polygonalGeometrySchema.describe('intersectedFeatureGeometrySchema'); +export const intersectedFeatureSchema = featureSchema(intersectedFeatureGeometrySchema, intersectedFeaturePropertiesSchema).describe( + 'intersectedFeatureSchema' +); +export const intersectedFeatureCollectionSchema = featureCollectionSchema(intersectedFeatureSchema).describe('intersectedFeatureCollectionSchema'); +//#endregion diff --git a/src/schemas/ingestion/polygonParts.schema.ts b/src/schemas/ingestion/polygonParts.schema.ts index f7fb3be..5a1cef0 100644 --- a/src/schemas/ingestion/polygonParts.schema.ts +++ b/src/schemas/ingestion/polygonParts.schema.ts @@ -1,6 +1,4 @@ import { z } from 'zod'; -import { CORE_VALIDATIONS } from '../../constants'; -import { INGESTION_VALIDATIONS } from '../../constants/ingestion/constants'; import { featureCollectionSchema, featureSchema, @@ -10,75 +8,10 @@ import { resourceIdSchema, versionSchema, } from '../core'; +import { partSchema } from '../core/polygonParts.schema'; import { ingestionJobTypeSchema } from './job.schema'; import { polygonPartsEntityPatternSchema } from './layerNameFormats.schema'; -export const partSchema = z - .object({ - id: z.string(), - 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({ message: 'Resolution degree should be a number' }) - .min(CORE_VALIDATIONS.resolutionDeg.min, { - message: `Resolution degree should not be less than ${CORE_VALIDATIONS.resolutionDeg.min}`, - }) - .max(CORE_VALIDATIONS.resolutionDeg.max, { - message: `Resolution degree should not be larger than ${CORE_VALIDATIONS.resolutionDeg.max}`, - }), - resolutionMeter: z - .number({ message: 'Resolution meter should be a number' }) - .min(INGESTION_VALIDATIONS.resolutionMeter.min, { - message: `Resolution meter should not be less than ${INGESTION_VALIDATIONS.resolutionMeter.min}`, - }) - .max(INGESTION_VALIDATIONS.resolutionMeter.max, { - message: `Resolution meter should not be larger than ${INGESTION_VALIDATIONS.resolutionMeter.max}`, - }), - sourceResolutionMeter: z - .number({ message: 'Source resolution meter should be a number' }) - .min(INGESTION_VALIDATIONS.resolutionMeter.min, { - message: `Source resolution meter should not be less than ${INGESTION_VALIDATIONS.resolutionMeter.min}`, - }) - .max(INGESTION_VALIDATIONS.resolutionMeter.max, { - message: `Source resolution meter should not be larger than ${INGESTION_VALIDATIONS.resolutionMeter.max}`, - }), - horizontalAccuracyCE90: z - .number({ message: 'Horizontal accuracy CE90 should be a number' }) - .min(INGESTION_VALIDATIONS.horizontalAccuracyCE90.min, { - message: `Horizontal accuracy CE90 should not be less than ${INGESTION_VALIDATIONS.horizontalAccuracyCE90.min}`, - }) - .max(INGESTION_VALIDATIONS.horizontalAccuracyCE90.max, { - message: `Horizontal accuracy CE90 should not be larger than ${INGESTION_VALIDATIONS.horizontalAccuracyCE90.max}`, - }), - sensors: z - .array( - z.string({ message: 'Sensors should be an array of strings' }).regex(new RegExp(INGESTION_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(), - }) - .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'); - -export const partsSchema = z.array(partSchema).describe('partsSchema'); - export const polygonPartsEntityNameSchema = z .object({ polygonPartsEntityName: polygonPartsEntityPatternSchema, diff --git a/src/types/core/index.ts b/src/types/core/index.ts index 044b5f9..8e8f7b8 100644 --- a/src/types/core/index.ts +++ b/src/types/core/index.ts @@ -6,3 +6,4 @@ export * from './part.type'; export * from './link.type'; export * from './file.type'; export * from './callback.type'; +export * from './polygonParts.type'; diff --git a/src/types/core/polygonParts.type.ts b/src/types/core/polygonParts.type.ts new file mode 100644 index 0000000..4cdd8f1 --- /dev/null +++ b/src/types/core/polygonParts.type.ts @@ -0,0 +1,20 @@ +import { z } from 'zod'; +import type { + intersectionFeaturePropertiesSchema, + intersectionFeatureGeometrySchema, + intersectionFeatureSchema, + intersectionFeatureCollectionSchema, + intersectedFeaturePropertiesSchema, + intersectedFeatureGeometrySchema, + intersectedFeatureSchema, + intersectedFeatureCollectionSchema, +} from '../../schemas/core/polygonParts.schema'; + +export type IntersectionFeatureProperties = z.infer; +export type IntersectionFeatureGeometry = z.infer; +export type IntersectionFeature = z.infer; +export type IntersectionFeatureCollection = z.infer; +export type IntersectedFeatureProperties = z.infer; +export type IntersectedFeatureGeometry = z.infer; +export type IntersectedFeature = z.infer; +export type IntersectedFeatureCollection = z.infer;