diff --git a/.eslintrc.json b/.eslintrc.json index 64b68cd2..caa53a4e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,5 +3,9 @@ "extends": ["@map-colonies/eslint-config/jest", "@map-colonies/eslint-config/ts-base"], "parserOptions": { "project": "./tsconfig.lint.json" + }, + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": ["off"] } } diff --git a/src/models/common/index.ts b/src/models/common/index.ts index b15a511d..23884055 100644 --- a/src/models/common/index.ts +++ b/src/models/common/index.ts @@ -1,5 +1,4 @@ export * from '../layerMetadata/link'; -export * from '../layerMetadata/discreteOrder'; export * from './decorators/graphQL/graphql.decorator'; export * from './decorators/graphQL/classGraphql.decorator'; export * from './interfaces/ormCatalog.interface'; diff --git a/src/models/layerMetadata/bestMetadata.ts b/src/models/layerMetadata/bestMetadata.ts deleted file mode 100644 index 5601f034..00000000 --- a/src/models/layerMetadata/bestMetadata.ts +++ /dev/null @@ -1,833 +0,0 @@ -import { GeoJSON } from 'geojson'; -import { IPropCatalogDBMapping } from '../common/interfaces/propCatalogDBMapping.interface'; -import { graphql } from '../common/decorators/graphQL/graphql.decorator'; -import { - FieldCategory, - fieldConfig, - getFieldConfig, - IFieldConfigInfo, - IPropFieldConfigInfo, -} from '../common/decorators/fieldConfig/fieldConfig.decorator'; -import { RecordType } from '../pycsw/coreEnums'; -import { IMetadataCommonModel } from './interfaces/metadataCommonModel'; -import { getPyCSWMapping, IPYCSWMapping, pycsw } from './decorators/property/csw.decorator'; -import { getInputDataMapping, IDataMapping, DataFileType, inputDataMapping, IPropSHPMapping } from './decorators/property/shp.decorator'; -import { getCatalogDBMapping, ICatalogDBMapping, catalogDB } from './decorators/property/catalogDB.decorator'; -import { getTsTypesMapping, tsTypes, TsTypes } from './decorators/property/tsTypes.decorator'; -import { ProductType } from './enums'; -import { DiscreteOrder } from './discreteOrder'; - -export interface IBestMetadata { - srsId: string | undefined; - productVersion: string | undefined; - maxResolutionDeg: number | undefined; - rms: number | undefined; - scale: number | undefined; - discretes: DiscreteOrder[] | undefined; - sourceDateStart: Date | undefined; - sourceDateEnd: Date | undefined; - updateDate: Date | undefined; -} - -export interface IPropPYCSWMapping extends IPYCSWMapping { - prop: string; -} - -export class BestMetadata implements IBestMetadata, IMetadataCommonModel { - //#region COMMON FIELDS - //#region COMMON: type - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:type', - queryableField: 'mc:type', - pycswField: 'pycsw:Type', - }) - @catalogDB({ - column: { - name: 'type', - type: 'text', - nullable: true, - }, - }) - @tsTypes({ - mappingType: TsTypes.RECORDTYPE, - }) - @graphql({ - nullable: true, - }) - //#endregion - public type: RecordType | undefined = RecordType.RECORD_RASTER; - - //#region COMMON: classification - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:classification', - queryableField: 'mc:classification', - pycswField: 'pycsw:Classification', - }) - @catalogDB({ - column: { - name: 'classification', - type: 'text', - nullable: false, - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql({ - nullable: false, - }) - @fieldConfig({ - category: FieldCategory.GENERAL, - isAutoGenerated: true, - infoMsgCode: ['info-general-tooltip.required'], - lookupTable: 'classification', - validation: [ - { - errorMsgCode: 'validation-general.required', - required: true, - }, - ], - isLifecycleEnvolved: true, - }) - //#endregion - public classification: string | undefined = undefined; - - //#region COMMON: productName - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:productName', - queryableField: 'mc:productName', - pycswField: 'pycsw:Title', - }) - @catalogDB({ - column: { - name: 'product_name', - type: 'text', - nullable: true, - }, - }) - @inputDataMapping({ - dataFile: DataFileType.SHAPE_METADATA, - valuePath: 'features[0].properties.SourceName', - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql() - @fieldConfig({ - category: FieldCategory.MAIN, - isManuallyEditable: true, - }) - //#endregion - public productName: string | undefined = undefined; - - //#region COMMON: description - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:description', - queryableField: 'mc:description', - pycswField: 'pycsw:Abstract', - }) - @catalogDB({ - column: { - name: 'description', - type: 'text', - nullable: true, - }, - }) - @inputDataMapping({ - dataFile: DataFileType.SHAPE_METADATA, - valuePath: 'features[0].properties.Dsc', - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.GENERAL, - isManuallyEditable: true, - }) - //#endregion - public description: string | undefined = undefined; - - //#region COMMON: srsId - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:SRS', - queryableField: 'mc:SRS', - pycswField: 'pycsw:CRS', - }) - @catalogDB({ - column: { - name: 'srs', - type: 'text', - nullable: false, - default: '4326', - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql({ - nullable: false, - }) - @fieldConfig({ - category: FieldCategory.GEO_INFO, - isAutoGenerated: true, - default: '4326', - }) - //#endregion - public srsId: string | undefined = undefined; - - //#region COMMON: producerName - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:producerName', - queryableField: 'mc:producerName', - pycswField: 'pycsw:Creator', - }) - @catalogDB({ - column: { - name: 'producer_name', - type: 'text', - default: 'IDFMU', - nullable: true, - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql({ - nullable: false, - }) - //#endregion - public producerName: string | undefined = 'IDFMU'; - - //#region COMMON: creationDate - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:creationDate', - queryableField: 'mc:creationDate', - pycswField: 'pycsw:CreationDate', - }) - @catalogDB({ - column: { - name: 'creation_date', - type: 'timestamp without time zone', - }, - }) - @tsTypes({ - mappingType: TsTypes.DATE, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.GENERAL, - isAutoGenerated: true, - isLifecycleEnvolved: true, - }) - //#endregion - public creationDate: Date | undefined = undefined; - - //#region COMMON: ingestionDate - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:ingestionDate', - queryableField: 'mc:ingestionDate', - pycswField: 'pycsw:IngestionDate', - }) - @catalogDB({ - column: { - name: 'ingestion_date', - type: 'timestamp without time zone', - }, - }) - @tsTypes({ - mappingType: TsTypes.DATE, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.MAIN, - isAutoGenerated: true, - }) - //#endregion - public ingestionDate: Date | undefined = undefined; - - //#region COMMON: updateDate - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:updateDate', - queryableField: 'mc:updateDate', - pycswField: 'pycsw:UpdateDate', - }) - @catalogDB({ - column: { - name: 'update_date', - type: 'timestamp without time zone', - }, - }) - @inputDataMapping({ - isCustomLogic: true, - dataFile: DataFileType.SHAPE_METADATA, - valuePath: '***max(features[].properties.UpdateDate)***', - }) - @tsTypes({ - mappingType: TsTypes.DATE, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.MAIN, - isAutoGenerated: true, - isLifecycleEnvolved: true, - }) - //#endregion - public updateDate: Date | undefined = undefined; - - //#region COMMON: sourceDateStart - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:imagingTime_begin', - queryableField: 'mc:imagingTime_begin', - pycswField: 'pycsw:TempExtent_begin', - }) - @catalogDB({ - column: { - name: 'source_start_date', - type: 'timestamp without time zone', - nullable: false, - }, - }) - @inputDataMapping({ - isCustomLogic: true, - dataFile: DataFileType.SHAPE_METADATA, - valuePath: '***min(features[].properties.UpdateDate)***', - }) - @tsTypes({ - mappingType: TsTypes.DATE, - }) - @graphql({ - nullable: false, - }) - @fieldConfig({ - category: FieldCategory.GENERAL, - isAutoGenerated: true, - isLifecycleEnvolved: true, - }) - //#endregion - public sourceDateStart: Date | undefined = undefined; - - //#region COMMON: sourceDateEnd - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:imagingTime_end', - queryableField: 'mc:imagingTime_end', - pycswField: 'pycsw:TempExtent_end', - }) - @catalogDB({ - column: { - name: 'source_end_date', - type: 'timestamp without time zone', - nullable: false, - }, - }) - @inputDataMapping({ - isCustomLogic: true, - dataFile: DataFileType.SHAPE_METADATA, - valuePath: '***max(features[].properties.UpdateDate)***', - }) - @tsTypes({ - mappingType: TsTypes.DATE, - }) - @graphql({ - nullable: false, - }) - @fieldConfig({ - category: FieldCategory.GENERAL, - isAutoGenerated: true, - isLifecycleEnvolved: true, - }) - //#endregion - public sourceDateEnd: Date | undefined = undefined; - - //#region COMMON: accuracyCE90 - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:minHorizontalAccuracyCE90', - queryableField: 'mc:minHorizontalAccuracyCE90', - pycswField: 'pycsw:horizontalAccuracyCE90', - }) - @catalogDB({ - column: { - name: 'min_horizontal_accuracy_ce_90', - type: 'real', - }, - }) - @inputDataMapping({ - dataFile: DataFileType.SHAPE_METADATA, - valuePath: 'features[0].properties.Ep90', - }) - @tsTypes({ - mappingType: TsTypes.NUMBER, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.GEO_INFO, - isAutoGenerated: true, - isLifecycleEnvolved: true, - }) - //#endregion - public minHorizontalAccuracyCE90: number | undefined = undefined; - - //#region COMMON: sensors - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:sensorType', - queryableField: 'mc:sensorType', - pycswField: 'pycsw:sensorType', - }) - @catalogDB({ - column: { - name: 'sensor_type', - type: 'text', - }, - field: { - overrideType: TsTypes.STRING, - }, - }) - @inputDataMapping({ - isCustomLogic: true, - dataFile: DataFileType.SHAPE_METADATA, - valuePath: '***features[].properties.SensorType***', - }) - @tsTypes({ - mappingType: TsTypes.STRING_ARRAY, - }) - @graphql({ - nullable: false, - }) - @fieldConfig({ - category: FieldCategory.GENERAL, - isManuallyEditable: true, - isAutoGenerated: true, - infoMsgCode: ['info-field-tooltip.sensors.tooltip'], - isLifecycleEnvolved: true, - }) - //#endregion - public sensors: string[] | undefined = undefined; - - //#region COMMON: region - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:region', - queryableField: 'mc:region', - pycswField: 'pycsw:Region', - }) - @catalogDB({ - column: { - name: 'region', - type: 'text', - }, - field: { - overrideType: TsTypes.STRING, - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING_ARRAY, - }) - @graphql({ - nullable: false, - }) - @fieldConfig({ - category: FieldCategory.GENERAL, - isLifecycleEnvolved: true, - }) - //#endregion - public region: string[] | undefined = undefined; - - //#region COMMON: productId - @pycsw({ - profile: 'mc_raster', - xmlElement: 'mc:productId', - queryableField: 'mc:productId', - pycswField: 'pycsw:ProductId', - }) - @catalogDB({ - column: { - name: 'product_id', - type: 'text', - nullable: false, - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.MAIN, - infoMsgCode: ['info-general-tooltip.required'], - validation: [ - { - errorMsgCode: 'validation-general.required', - required: true, - }, - { - errorMsgCode: 'validation-field.productId.pattern', - valueType: 'value', - pattern: '^[A-Za-z]{1}[A-Za-z0-9_]{0,62}$', - }, - ], - }) - //#endregion - public productId: string | undefined = 'UNKNOWN'; - //#endregion - - //#region BEST SPECIFIC FIELDS - //#region BEST: productVersion - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:productVersion', - queryableField: 'mc:productVersion', - pycswField: 'pycsw:ProductVersion', - }) - @catalogDB({ - column: { - name: 'product_version', - type: 'text', - nullable: true, - }, - }) - @inputDataMapping({ - isCustomLogic: true, - dataFile: DataFileType.SHAPE_METADATA, - valuePath: '***features[0].properties.Source.Split(-)[1]***', - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.MAIN, - isAutoGenerated: true, - isLifecycleEnvolved: true, - }) - //#endregion - public productVersion: string | undefined = undefined; - - //#region BEST: productType - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:productType', - queryableField: 'mc:productType', - pycswField: 'pycsw:ProductType', - }) - @catalogDB({ - column: { - name: 'product_type', - type: 'text', - nullable: true, - }, - }) - @inputDataMapping({ - dataFile: DataFileType.PRODUCT, - valuePath: 'features[0].properties.Type', - }) - @tsTypes({ - mappingType: TsTypes.PRODUCTTYPE, - }) - @graphql() - @fieldConfig({ - category: FieldCategory.MAIN, - isAutoGenerated: true, - }) - //#endregion - public productType: ProductType | undefined = ProductType.ORTHOPHOTO_BEST; - - //#region BEST: srsName - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:SRSName', - queryableField: 'mc:SRSName', - pycswField: 'pycsw:CRSName', - }) - @catalogDB({ - column: { - name: 'srs_name', - type: 'text', - nullable: false, - default: 'WGS84GEO', - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql({ - nullable: false, - }) - @fieldConfig({ - category: FieldCategory.GEO_INFO, - isAutoGenerated: true, - default: 'WGS84GEO', - }) - //#endregion - public srsName: string | undefined = undefined; - - //#region BEST: maxResolutionDeg - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:maxResolutionDeg', - queryableField: 'mc:maxResolutionDeg', - pycswField: 'pycsw:Resolution', - }) - @catalogDB({ - column: { - name: 'max_resolution_deg', - type: 'numeric', - }, - }) - @inputDataMapping({ - dataFile: DataFileType.TFW, - valuePath: '[0]', - }) - @tsTypes({ - mappingType: TsTypes.NUMBER, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.MAIN, - isAutoGenerated: true, - isLifecycleEnvolved: true, - }) - //#endregion - public maxResolutionDeg: number | undefined = undefined; - - //#region BEST: rms - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:RMS', - queryableField: 'mc:RMS', - pycswField: 'pycsw:Rms', - }) - @catalogDB({ - column: { - name: 'rms', - type: 'real', - nullable: true, - }, - }) - @inputDataMapping({ - dataFile: DataFileType.SHAPE_METADATA, - valuePath: 'features[0].properties.Rms', - }) - @tsTypes({ - mappingType: TsTypes.NUMBER, - }) - @graphql({ - nullable: true, - }) - //#endregion - public rms: number | undefined = undefined; - - //#region BEST: scale - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:scale', - queryableField: 'mc:scale', - pycswField: 'pycsw:Scale', - }) - @catalogDB({ - column: { - name: 'scale', - type: 'integer', - nullable: true, - }, - }) - @inputDataMapping({ - dataFile: DataFileType.SHAPE_METADATA, - valuePath: 'features[0].properties.Scale', - }) - @tsTypes({ - mappingType: TsTypes.NUMBER, - }) - @graphql({ - nullable: true, - }) - //#endregion - public scale: number | undefined = undefined; - - //#region BEST: footprint - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:footprint', - queryableField: 'mc:footprint', - pycswField: 'pycsw:footprint', - }) - @catalogDB({ - column: { - name: 'footprint_geojson', - type: 'text', - nullable: false, - }, - }) - @inputDataMapping({ - dataFile: DataFileType.SHAPE_METADATA, - valuePath: 'features[0].geometry', - }) - @tsTypes({ - mappingType: TsTypes.OBJECT, - }) - @graphql({ - nullable: false, - }) - //#endregion - public footprint: GeoJSON | undefined = undefined; - - //#region BEST: layerPolygonParts - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:layerPolygonParts', - queryableField: 'mc:layerPolygonParts', - pycswField: 'pycsw:layerPolygonParts', - }) - @catalogDB({ - column: { - name: 'layer_polygon_parts', - type: 'text', - nullable: true, - }, - }) - @inputDataMapping({ - isCustomLogic: true, - dataFile: DataFileType.SHAPE_METADATA, - valuePath: '***entire geo json feature collection***', - }) - @tsTypes({ - mappingType: TsTypes.OBJECT, - }) - @graphql({ - nullable: true, - }) - //#endregion - public layerPolygonParts: GeoJSON | undefined = undefined; - //#endregion - - //#region BEST: discretes - @pycsw({ - profile: 'mc_best', - xmlElement: 'mc:discretes', - queryableField: 'mc:discretes', - pycswField: 'pycsw:discretes', - }) - @catalogDB({ - column: { - name: 'discretes', - type: 'text', - nullable: true, - }, - }) - @tsTypes({ - mappingType: TsTypes.DISCRETE_ORDERS, - }) - @graphql({ - nullable: true, - }) - //#endregion - public discretes: DiscreteOrder[] | undefined = undefined; - //#endregion - - public static getPyCSWMapping(prop: string): IPYCSWMapping | undefined { - return getPyCSWMapping(new BestMetadata(), prop); - } - - public static getShpMapping(prop: string): IDataMapping | undefined { - return getInputDataMapping(new BestMetadata(), prop); - } - - public static getCatalogDBMapping(prop: string): ICatalogDBMapping | undefined { - return getCatalogDBMapping(new BestMetadata(), prop); - } - - public static getFieldConfig(prop: string): IFieldConfigInfo | undefined { - return getFieldConfig(new BestMetadata(), prop); - } - - public static getPyCSWMappings(): IPropPYCSWMapping[] { - const ret = []; - const layer = new BestMetadata(); - for (const prop in layer) { - const pycswMap = getPyCSWMapping(layer, prop); - if (pycswMap) { - ret.push({ - prop: prop, - ...pycswMap, - }); - } - } - return ret; - } - - public static getCatalogDBMappings(): IPropCatalogDBMapping[] { - const ret = []; - const layer = new BestMetadata(); - for (const prop in layer) { - const catalogDbMap = getCatalogDBMapping(layer, prop); - const tsTypesMap = getTsTypesMapping(layer, prop); - if (catalogDbMap && tsTypesMap) { - ret.push({ - prop: prop, - ...catalogDbMap, - ...tsTypesMap, - }); - } - } - return ret; - } - - public static getShpMappings(includeCustomLogic = false): IPropSHPMapping[] { - const ret = []; - const layer = new BestMetadata(); - for (const prop in layer) { - const shpMap = getInputDataMapping(layer, prop); - const tsTypesMap = getTsTypesMapping(layer, prop); - if (shpMap && tsTypesMap && (includeCustomLogic || shpMap.isCustomLogic === undefined || !shpMap.isCustomLogic)) { - ret.push({ - prop: prop, - ...shpMap, - ...tsTypesMap, - }); - } - } - return ret; - } - - public static getFieldConfigs(): IPropFieldConfigInfo[] { - const ret = []; - const layer = new BestMetadata(); - for (const prop in layer) { - const fieldConfigMap = getFieldConfig(layer, prop); - if (fieldConfigMap) { - ret.push({ - prop: prop, - ...fieldConfigMap, - }); - } - } - return ret; - } -} diff --git a/src/models/layerMetadata/decorators/property/tsTypes.decorator.ts b/src/models/layerMetadata/decorators/property/tsTypes.decorator.ts index 3c18be0c..08a39a74 100644 --- a/src/models/layerMetadata/decorators/property/tsTypes.decorator.ts +++ b/src/models/layerMetadata/decorators/property/tsTypes.decorator.ts @@ -109,14 +109,6 @@ export const TsTypes = { type: PropertiesTypes.ENUM, importFromPackage: '@map-colonies/mc-model-types', }, - DISCRETE_ORDER: { - value: 'DiscreteOrder', - type: PropertiesTypes.CLASS, - }, - DISCRETE_ORDERS: { - value: 'DiscreteOrder', - type: PropertiesTypes.ARRAY, - }, } satisfies Record; /* eslint-enable @typescript-eslint/naming-convention */ diff --git a/src/models/layerMetadata/discreteOrder.ts b/src/models/layerMetadata/discreteOrder.ts deleted file mode 100644 index ea24f39a..00000000 --- a/src/models/layerMetadata/discreteOrder.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { graphqlClass } from '../common/decorators/graphQL/classGraphql.decorator'; -import { graphql } from '../common/decorators/graphQL/graphql.decorator'; -import { TsTypes, tsTypes } from './decorators/property/tsTypes.decorator'; - -@graphqlClass() -export class DiscreteOrder { - //#region FIELD: id - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql() - //#endregion - public id?: string = undefined; - - //#region FIELD: zOrder - @tsTypes({ - mappingType: TsTypes.NUMBER, - }) - @graphql() - //#endregion - public zOrder?: number = undefined; -} diff --git a/src/models/layerMetadata/index.ts b/src/models/layerMetadata/index.ts index 28a2483c..e960f762 100644 --- a/src/models/layerMetadata/index.ts +++ b/src/models/layerMetadata/index.ts @@ -12,7 +12,6 @@ export { IOrmCatalog } from '../common/interfaces/ormCatalog.interface'; export * from './pycswLayerCatalogRecord'; export * from './pycsw3DCatalogRecord'; -export * from './pycswBestCatalogRecord'; export * from './pycswDEMCatalogRecord'; export * from './pycswVectorBestCatalogRecord'; export * from './pycswQuantizedMeshBestCatalogRecord'; diff --git a/src/models/layerMetadata/layerMetadata.ts b/src/models/layerMetadata/layerMetadata.ts index b8f46d77..376c3a64 100644 --- a/src/models/layerMetadata/layerMetadata.ts +++ b/src/models/layerMetadata/layerMetadata.ts @@ -1,6 +1,5 @@ import { GeoJSON } from 'geojson'; import { TilesMimeFormat } from '@map-colonies/types'; -import { zoomLevelToResolutionDeg, zoomLevelToResolutionMeter } from '@map-colonies/mc-utils'; import { IPropCatalogDBMapping } from '../common/interfaces/propCatalogDBMapping.interface'; import { graphql } from '../common/decorators/graphQL/graphql.decorator'; import { @@ -12,6 +11,7 @@ import { } from '../common/decorators/fieldConfig/fieldConfig.decorator'; import { RecordType } from '../pycsw/coreEnums'; import { NewRasterLayerMetadata, UpdateRasterLayerMetadata } from '../raster/ingestion'; +import { VALIDATIONS } from '../raster/constants'; import { IMetadataCommonModel } from './interfaces/metadataCommonModel'; import { getPyCSWMapping, IPYCSWMapping, pycsw } from './decorators/property/csw.decorator'; import { getInputDataMapping, IDataMapping, DataFileType, inputDataMapping, IPropSHPMapping } from './decorators/property/shp.decorator'; @@ -19,8 +19,6 @@ import { getCatalogDBMapping, ICatalogDBMapping, catalogDB, ORMColumnType } from import { getTsTypesMapping, tsTypes, TsTypes } from './decorators/property/tsTypes.decorator'; import { ProductType, Transparency, TileOutputFormat } from './enums'; -export const horizontalAccuracyValidation = { min: 0.01, max: 4000 }; - export interface ILayerMetadata { id: string | undefined; srs: string | undefined; @@ -475,12 +473,12 @@ export class LayerMetadata implements ILayerMetadata, IMetadataCommonModel { { errorMsgCode: 'validation-field.maxHorizontalAccuracyCE90.min', valueType: 'value', - min: horizontalAccuracyValidation.min, + min: VALIDATIONS.horizontalAccuracyCE90.min, }, { errorMsgCode: 'validation-field.maxHorizontalAccuracyCE90.max', valueType: 'value', - max: horizontalAccuracyValidation.max, + max: VALIDATIONS.horizontalAccuracyCE90.max, }, ], isLifecycleEnvolved: true, @@ -522,12 +520,12 @@ export class LayerMetadata implements ILayerMetadata, IMetadataCommonModel { { errorMsgCode: 'validation-field.minHorizontalAccuracyCE90.min', valueType: 'value', - min: horizontalAccuracyValidation.min, + min: VALIDATIONS.horizontalAccuracyCE90.min, }, { errorMsgCode: 'validation-field.minHorizontalAccuracyCE90.max', valueType: 'value', - max: horizontalAccuracyValidation.max, + max: VALIDATIONS.horizontalAccuracyCE90.max, }, ], isLifecycleEnvolved: true, @@ -656,7 +654,7 @@ export class LayerMetadata implements ILayerMetadata, IMetadataCommonModel { { errorMsgCode: 'validation-field.productId.pattern', valueType: 'value', - pattern: '^[A-Za-z]{1}[A-Za-z0-9_]{0,62}$', + pattern: VALIDATIONS.productId.pattern, }, ], }) @@ -699,7 +697,7 @@ export class LayerMetadata implements ILayerMetadata, IMetadataCommonModel { { errorMsgCode: 'validation-field.productVersion.pattern', valueType: 'value', - pattern: '^[1-9]\\d*(\\.(0|[1-9]\\d?))?$', + pattern: VALIDATIONS.productVersion.pattern, }, ], }) @@ -846,12 +844,12 @@ export class LayerMetadata implements ILayerMetadata, IMetadataCommonModel { { errorMsgCode: 'validation-field.maxResolutionDeg.min', valueType: 'value', - min: zoomLevelToResolutionDeg(22), + min: VALIDATIONS.resolutionDeg.min, }, { errorMsgCode: 'validation-field.maxResolutionDeg.max', valueType: 'value', - max: zoomLevelToResolutionDeg(0), + max: VALIDATIONS.resolutionDeg.max, }, ], isLifecycleEnvolved: true, @@ -898,12 +896,12 @@ export class LayerMetadata implements ILayerMetadata, IMetadataCommonModel { { errorMsgCode: 'validation-field.minResolutionDeg.min', valueType: 'value', - min: zoomLevelToResolutionDeg(22), + min: VALIDATIONS.resolutionDeg.min, }, { errorMsgCode: 'validation-field.minResolutionDeg.max', valueType: 'value', - max: zoomLevelToResolutionDeg(0), + max: VALIDATIONS.resolutionDeg.max, }, ], }) @@ -944,12 +942,12 @@ export class LayerMetadata implements ILayerMetadata, IMetadataCommonModel { { errorMsgCode: 'validation-field.maxResolutionMeter.min', valueType: 'value', - min: zoomLevelToResolutionMeter(22), + min: VALIDATIONS.resolutionMeter.min, }, { errorMsgCode: 'validation-field.maxResolutionMeter.max', valueType: 'value', - max: zoomLevelToResolutionMeter(0), + max: VALIDATIONS.resolutionMeter.max, }, ], isLifecycleEnvolved: true, @@ -991,12 +989,12 @@ export class LayerMetadata implements ILayerMetadata, IMetadataCommonModel { { errorMsgCode: 'validation-field.minResolutionMeter.min', valueType: 'value', - min: zoomLevelToResolutionMeter(22), + min: VALIDATIONS.resolutionMeter.min, }, { errorMsgCode: 'validation-field.minResolutionMeter.max', valueType: 'value', - max: zoomLevelToResolutionMeter(0), + max: VALIDATIONS.resolutionMeter.max, }, ], isLifecycleEnvolved: true, diff --git a/src/models/layerMetadata/pycswBestCatalogRecord.ts b/src/models/layerMetadata/pycswBestCatalogRecord.ts deleted file mode 100644 index 18768853..00000000 --- a/src/models/layerMetadata/pycswBestCatalogRecord.ts +++ /dev/null @@ -1,300 +0,0 @@ -import { IPycswCoreModel } from '../pycsw/interfaces/pycswCoreModel'; -import { IPropCatalogDBMapping } from '../common/interfaces/propCatalogDBMapping.interface'; -import { IOrmCatalog } from '../common/interfaces/ormCatalog.interface'; -import { graphql } from '../common/decorators/graphQL/graphql.decorator'; -import { graphqlClass } from '../common/decorators/graphQL/classGraphql.decorator'; -import { FieldCategory, fieldConfig, getFieldConfig, IPropFieldConfigInfo } from '../common/decorators/fieldConfig/fieldConfig.decorator'; -import { getFieldConfigClassInfo } from '../common/decorators/fieldConfig/classFieldConfig.decorator'; -import { Link } from './link'; -import { catalogDB, getCatalogDBMapping } from './decorators/property/catalogDB.decorator'; -import { getTsTypesMapping, TsTypes, tsTypes } from './decorators/property/tsTypes.decorator'; -import { IPropPYCSWMapping, BestMetadata } from './bestMetadata'; -import { getCatalogDBEntityMapping, catalogDBEntity, ICatalogDBEntityMapping } from './decorators/class/catalogDBEntity.decorator'; -import { getPyCSWMapping, pycsw } from './decorators/property/csw.decorator'; -import { IPropSHPMapping } from './decorators/property/shp.decorator'; - -@catalogDBEntity({ - table: 'records', - className: 'BestEntity', -}) -@graphqlClass({ alias: 'BestRecord' }) -export class PycswBestCatalogRecord extends BestMetadata implements IPycswCoreModel, IOrmCatalog { - //#region CORE: id - @pycsw({ - profile: 'mc_raster', - xmlElement: 'mc:id', - queryableField: 'mc:id', - pycswField: 'pycsw:Identifier', - }) - @catalogDB({ - column: { - name: 'identifier', - type: 'text', - nullable: false, - primary: true, - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql() - @fieldConfig({ - category: FieldCategory.MAIN, - isAutoGenerated: true, - }) - //#endregion - public id: string | undefined = undefined; - - //#region CORE: typename - @catalogDB({ - column: { - name: 'typename', - type: 'text', - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - //#endregion - public typeName = 'mc_MCBestRecord'; - - //#region CORE: schema - @catalogDB({ - column: { - name: 'schema', - type: 'text', - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - //#endregion - public schema: string | undefined = 'mc_raster'; - - //#region CORE: mdsource - @catalogDB({ - column: { - name: 'mdsource', - type: 'text', - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - //#endregion - public mdSource: string | undefined = ''; - - //#region CORE: xml - @catalogDB({ - column: { - name: 'xml', - type: 'text', - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - //#endregion - public xml: string | undefined = ''; - - //#region CORE: anytext - @catalogDB({ - column: { - name: 'anytext', - type: 'text', - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - //#endregion - public anyText: string | undefined = undefined; - - //#region CORE: insertDate - @pycsw({ - profile: 'mc_raster', - xmlElement: 'mc:insertDate', - queryableField: 'mc:insertDate', - pycswField: 'pycsw:InsertDate', - }) - @catalogDB({ - column: { - name: 'insert_date', - type: 'timestamp without time zone', - default: 'CURRENT_TIMESTAMP', - }, - }) - @tsTypes({ - mappingType: TsTypes.DATE, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.GENERAL, - isAutoGenerated: true, - }) - //#endregion - public insertDate: Date | undefined = undefined; - - //#region CORE: wktGeometry - @catalogDB({ - column: { - name: 'wkt_geometry', - type: 'text', - nullable: true, - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - //#endregion - public wktGeometry: string | undefined = undefined; - - //#region CORE: wkbGeometry (DD trigger populated) - @catalogDB({ - column: { - name: 'wkb_geometry', - type: 'geometry', - spatialFeatureType: 'Geometry', - srid: 4326, - nullable: true, - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - //#endregion - public wkbGeometry: string | undefined = undefined; - - //#region CORE: keywords - @pycsw({ - profile: 'mc_raster', - xmlElement: 'mc:keywords', - queryableField: 'mc:keywords', - pycswField: 'pycsw:Keywords', - }) - @catalogDB({ - column: { - name: 'keywords', - type: 'text', - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.GENERAL, - isManuallyEditable: true, - }) - //#endregion - public keywords: string | undefined = undefined; - - //#region CORE: anyTextTsvector - @catalogDB({ - column: { - name: 'anytext_tsvector', - type: 'tsvector', - nullable: true, - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - //#endregion - public anyTextTsvector: string | undefined = undefined; - - //#region CORE: links - @pycsw({ - profile: 'mc_raster', - xmlElement: 'mc:links', - queryableField: 'mc:links', - pycswField: 'pycsw:Links', - }) - @catalogDB({ - column: { - name: 'links', - type: 'text', - nullable: true, - }, - field: { - overrideType: TsTypes.STRING, - }, - }) - @tsTypes({ - mappingType: TsTypes.LINKS, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.GENERAL, - complexType: TsTypes.LINKS, - isAutoGenerated: true, - }) - //#endregion - public links: Link[] | undefined = undefined; - - public constructor() { - super(); - } - - public static getPyCSWMappings(): IPropPYCSWMapping[] { - const ret = []; - const layer = new PycswBestCatalogRecord(); - for (const prop in layer) { - const pycswMap = getPyCSWMapping(layer, prop); - if (pycswMap) { - ret.push({ - prop: prop, - ...pycswMap, - }); - } - } - return ret; - } - - public static getFieldConfigs(): IPropFieldConfigInfo[] { - const ret = []; - const layer = new PycswBestCatalogRecord(); - for (const prop in layer) { - const fieldConfigMap = getFieldConfig(layer, prop); - if (fieldConfigMap) { - const fieldConfig = { prop: prop, ...fieldConfigMap }; - if (fieldConfigMap.complexType) { - fieldConfig.subFields = getFieldConfigClassInfo(fieldConfigMap.complexType.value); - } - ret.push(fieldConfig); - } - } - return ret as IPropFieldConfigInfo[]; - } - - public static getShpMappings(includeCustomLogic = false): IPropSHPMapping[] { - return []; - } - - public getORMCatalogMappings(): IPropCatalogDBMapping[] { - const ret = []; - - for (const prop in this) { - const catalogDbMap = getCatalogDBMapping(this, prop); - const tsTypesMap = getTsTypesMapping(this, prop); - if (catalogDbMap && tsTypesMap) { - ret.push({ - prop: prop, - ...catalogDbMap, - ...tsTypesMap, - }); - } - } - return ret; - } - - public getORMCatalogEntityMappings(): ICatalogDBEntityMapping { - return getCatalogDBEntityMapping(PycswBestCatalogRecord); - } -} diff --git a/src/models/polygonParts/polygonPartRecord.ts b/src/models/polygonParts/polygonPartRecord.ts index a2c1ab77..e7b92d58 100644 --- a/src/models/polygonParts/polygonPartRecord.ts +++ b/src/models/polygonParts/polygonPartRecord.ts @@ -1,13 +1,13 @@ import { Polygon } from 'geojson'; -import { zoomLevelToResolutionDeg, zoomLevelToResolutionMeter } from '@map-colonies/mc-utils'; import { graphql } from '../common/decorators/graphQL/graphql.decorator'; import { FieldCategory, IPropFieldConfigInfo, fieldConfig, getFieldConfig } from '../common/decorators/fieldConfig/fieldConfig.decorator'; import { DataFileType, IPropSHPMapping, getInputDataMapping, inputDataMapping } from '../layerMetadata/decorators/property/shp.decorator'; import { catalogDB, getCatalogDBMapping } from '../layerMetadata/decorators/property/catalogDB.decorator'; import { getTsTypesMapping, tsTypes, TsTypes } from '../layerMetadata/decorators/property/tsTypes.decorator'; -import { ICatalogDBEntityMapping, IOrmCatalog, IPYCSWMapping, ProductType, horizontalAccuracyValidation } from '../layerMetadata'; +import { ICatalogDBEntityMapping, IOrmCatalog, IPYCSWMapping, ProductType } from '../layerMetadata'; import { graphqlClass, IPropCatalogDBMapping } from '../common'; import { getCatalogDBEntityMapping } from '../layerMetadata/decorators/class/catalogDBEntity.decorator'; +import { VALIDATIONS } from '../raster/constants'; interface IPropPYCSWMapping extends IPYCSWMapping { prop: string; @@ -82,7 +82,7 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { { errorMsgCode: 'validation-field.productId.pattern', valueType: 'value', - pattern: '^[A-Za-z]{1}[A-Za-z0-9_]{0,62}$', + pattern: VALIDATIONS.productId.pattern, }, ], }) @@ -228,12 +228,12 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { { errorMsgCode: 'validation-field.minHorizontalAccuracyCE90.min', valueType: 'value', - min: horizontalAccuracyValidation.min, + min: VALIDATIONS.horizontalAccuracyCE90.min, }, { errorMsgCode: 'validation-field.minHorizontalAccuracyCE90.max', valueType: 'value', - max: horizontalAccuracyValidation.max, + max: VALIDATIONS.horizontalAccuracyCE90.max, }, ], isLifecycleEnvolved: true, @@ -356,12 +356,12 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { { errorMsgCode: 'validation-field.maxResolutionDeg.min', valueType: 'value', - min: zoomLevelToResolutionDeg(22), + min: VALIDATIONS.resolutionDeg.min, }, { errorMsgCode: 'validation-field.maxResolutionDeg.max', valueType: 'value', - max: zoomLevelToResolutionDeg(0), + max: VALIDATIONS.resolutionDeg.max, }, ], }) @@ -387,12 +387,12 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { { errorMsgCode: 'validation-field.maxResolutionMeter.min', valueType: 'value', - min: zoomLevelToResolutionMeter(22), + min: VALIDATIONS.resolutionMeter.min, }, { errorMsgCode: 'validation-field.maxResolutionMeter.max', valueType: 'value', - max: zoomLevelToResolutionMeter(0), + max: VALIDATIONS.resolutionMeter.max, }, ], }) @@ -540,7 +540,7 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { { errorMsgCode: 'validation-field.productVersion.pattern', valueType: 'value', - pattern: '^[1-9]\\d*(\\.(0|[1-9]\\d?))?$', + pattern: VALIDATIONS.productVersion.pattern, }, ], }) diff --git a/src/models/raster/constants.ts b/src/models/raster/constants.ts new file mode 100644 index 00000000..8fad9096 --- /dev/null +++ b/src/models/raster/constants.ts @@ -0,0 +1,23 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import { zoomLevelToResolutionDeg, zoomLevelToResolutionMeter } from '@map-colonies/mc-utils'; + +export const VALIDATIONS = { + resolutionMeter: { + min: zoomLevelToResolutionMeter(22), + max: zoomLevelToResolutionMeter(0), + }, + resolutionDeg: { + min: zoomLevelToResolutionDeg(22), + max: zoomLevelToResolutionDeg(0), + }, + horizontalAccuracyCE90: { + min: 0.01, + max: 4000, + }, + productId: { + pattern: '^[A-Za-z]{1}[A-Za-z0-9_]{0,62}$', + }, + productVersion: { + pattern: '^[1-9]\\d*(\\.(0|[1-9]\\d?))?$', + }, +}; diff --git a/src/models/raster/ingestion/zod/schemas/partData.schema.ts b/src/models/raster/ingestion/zod/schemas/partData.schema.ts index 05c190d3..275d8e2f 100644 --- a/src/models/raster/ingestion/zod/schemas/partData.schema.ts +++ b/src/models/raster/ingestion/zod/schemas/partData.schema.ts @@ -1,11 +1,7 @@ /* eslint-disable @typescript-eslint/no-magic-numbers */ import { z } from 'zod'; -import { zoomLevelToResolutionDeg, zoomLevelToResolutionMeter } from '@map-colonies/mc-utils'; import { Polygon } from 'geojson'; - -const resolutionMeterRange = { min: zoomLevelToResolutionMeter(22), max: zoomLevelToResolutionMeter(0) }; -const resolutionDegRange = { min: zoomLevelToResolutionDeg(22), max: zoomLevelToResolutionDeg(0) }; -const horizontalAccuracyCE90Range = { min: 0.01, max: 4000 }; +import { VALIDATIONS } from '../../../constants'; export const partSchema = z.object({ sourceId: z.string().optional(), @@ -15,17 +11,17 @@ export const partSchema = z.object({ imagingTimeEndUTC: z.coerce.date(), resolutionDegree: z .number() - .min(resolutionDegRange.min as number) - .max(resolutionDegRange.max as number), + .min(VALIDATIONS.resolutionDeg.min as number) + .max(VALIDATIONS.resolutionDeg.max as number), resolutionMeter: z .number() - .min(resolutionMeterRange.min as number) - .max(resolutionMeterRange.max as number), + .min(VALIDATIONS.resolutionMeter.min as number) + .max(VALIDATIONS.resolutionMeter.max as number), sourceResolutionMeter: z .number() - .min(resolutionMeterRange.min as number) - .max(resolutionMeterRange.max as number), - horizontalAccuracyCE90: z.number().min(horizontalAccuracyCE90Range.min).max(horizontalAccuracyCE90Range.max), + .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().min(1)).min(1), countries: z.array(z.string().min(1)).optional(), cities: z.array(z.string().min(1)).optional(),