diff --git a/package-lock.json b/package-lock.json index 49bc5994..95fa81a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7463,20 +7463,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -19718,13 +19704,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", diff --git a/src/models/common/decorators/wfs/wfs.decorator.ts b/src/models/common/decorators/wfs/wfs.decorator.ts index a1e299be..cbb2996b 100644 --- a/src/models/common/decorators/wfs/wfs.decorator.ts +++ b/src/models/common/decorators/wfs/wfs.decorator.ts @@ -13,14 +13,22 @@ export enum JAVA_BINDINGS { } export interface IWFSMapping { - binding: JAVA_BINDINGS; // java type 'java.util.UUID' - name?: string; // property name that will be exposed by WFS service - minOccurs?: number; - maxOccurs?: number; + geoserver?: { + binding: JAVA_BINDINGS; // java type 'java.util.UUID' + name?: string; // property name that will be exposed by WFS service + minOccurs?: number; + maxOccurs?: number; + }; + capabilitiesMapping?: { + xmlElement: string; + }; } export interface IPropWFSMapping extends IWFSMapping { prop: string; // prop name for convinience +} + +export interface IWFSGeoServerMapping extends IWFSMapping, IPropWFSMapping { source: string; // DB column name. IMPORTANT: Will be derived from catalogDB decorator metadata nillable: boolean; // is nullable by DB definitions } diff --git a/src/models/layerMetadata/decorators/property/tsTypes.decorator.ts b/src/models/layerMetadata/decorators/property/tsTypes.decorator.ts index c9a61b06..b6df5b34 100644 --- a/src/models/layerMetadata/decorators/property/tsTypes.decorator.ts +++ b/src/models/layerMetadata/decorators/property/tsTypes.decorator.ts @@ -16,6 +16,9 @@ export interface IDescribeTsType { importFromPackage?: string; } +//****** IMPORTANT: ALL external enums which in use MUST be proxied by mc-models. +//****** In other words, enums MUST be imported in generated code(graphQL) from MC_MODELS ONLY, +//****** in order to be compliant to types package which in use by MC-MODELS /* eslint-disable @typescript-eslint/naming-convention */ export const TsTypes = { STRING: { @@ -59,6 +62,14 @@ export const TsTypes = { value: 'Link', type: PropertiesTypes.ARRAY, }, + FEATURESTRUCTURE: { + value: 'VectorFeatureTypeStructure', + type: PropertiesTypes.CLASS, + }, + FIELDFEATURETYPES: { + value: 'FieldFeatureType', + type: PropertiesTypes.ARRAY, + }, RECORDTYPE: { value: 'RecordType', type: PropertiesTypes.ENUM, @@ -97,12 +108,12 @@ export const TsTypes = { PRODUCTTYPE: { value: 'ProductType', type: PropertiesTypes.ENUM, - importFromPackage: '@map-colonies/types', + importFromPackage: '@map-colonies/mc-model-types', }, TRANSPARENCY: { value: 'Transparency', type: PropertiesTypes.ENUM, - importFromPackage: '@map-colonies/types', + importFromPackage: '@map-colonies/mc-model-types', }, TILE_OUTPUT_FORMAT: { value: 'TileOutputFormat', @@ -112,7 +123,7 @@ export const TsTypes = { RECORD_STATUS: { value: 'RecordStatus', type: PropertiesTypes.ENUM, - importFromPackage: '@map-colonies/types', + importFromPackage: '@map-colonies/mc-model-types', }, } satisfies Record; diff --git a/src/models/layerMetadata/index.ts b/src/models/layerMetadata/index.ts index e6bf6435..6878226b 100644 --- a/src/models/layerMetadata/index.ts +++ b/src/models/layerMetadata/index.ts @@ -13,6 +13,7 @@ export { IOrmCatalog } from '../common/interfaces/ormCatalog.interface'; export * from './pycswLayerCatalogRecord'; export * from './pycsw3DCatalogRecord'; export * from './pycswDEMCatalogRecord'; -export * from './pycswVectorBestCatalogRecord'; +export * from './vectorBestMetadata'; export * from './pycswQuantizedMeshBestCatalogRecord'; +export * from './vectorFeatureTypeStructure'; export * from './enums'; diff --git a/src/models/layerMetadata/pycswVectorBestCatalogRecord.ts b/src/models/layerMetadata/pycswVectorBestCatalogRecord.ts deleted file mode 100644 index 329f3c21..00000000 --- a/src/models/layerMetadata/pycswVectorBestCatalogRecord.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, VectorBestMetadata } from './vectorBestMetadata'; -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: 'VectorBestEntity', -}) -@graphqlClass({ alias: 'VectorBestRecord' }) -export class PycswVectorBestCatalogRecord extends VectorBestMetadata implements IPycswCoreModel, IOrmCatalog { - //#region CORE: id - @pycsw({ - profile: 'mc_vector_best', - 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_MCVectorBestRecord'; - - //#region CORE: schema - @catalogDB({ - column: { - name: 'schema', - type: 'text', - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - //#endregion - public schema: string | undefined = 'mc_vector_best'; - - //#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_vector_best', - 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_vector_best', - 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_vector_best', - 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 PycswVectorBestCatalogRecord(); - 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 PycswVectorBestCatalogRecord(); - 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(): 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(PycswVectorBestCatalogRecord); - } -} diff --git a/src/models/layerMetadata/vectorBestMetadata.ts b/src/models/layerMetadata/vectorBestMetadata.ts index 58e2107f..eeb2cf50 100644 --- a/src/models/layerMetadata/vectorBestMetadata.ts +++ b/src/models/layerMetadata/vectorBestMetadata.ts @@ -1,7 +1,7 @@ import { GeoJSON } from 'geojson'; import { RecordType, ProductType } from '@map-colonies/types'; -import { IPropCatalogDBMapping } from '../common/interfaces/propCatalogDBMapping.interface'; import { graphql } from '../common/decorators/graphQL/graphql.decorator'; +import { getFieldConfigClassInfo } from '../common/decorators/fieldConfig/classFieldConfig.decorator'; import { FieldCategory, fieldConfig, @@ -9,55 +9,76 @@ import { IFieldConfigInfo, IPropFieldConfigInfo, } from '../common/decorators/fieldConfig/fieldConfig.decorator'; -import { getPyCSWMapping, IPYCSWMapping, pycsw } from './decorators/property/csw.decorator'; -import { getCatalogDBMapping, ICatalogDBMapping, catalogDB } from './decorators/property/catalogDB.decorator'; -import { getTsTypesMapping, tsTypes, TsTypes } from './decorators/property/tsTypes.decorator'; +import { getWFSMapping, graphqlClass, IPropWFSMapping, IWFSMapping, Link, wfs } from '../common'; +import { tsTypes, TsTypes } from './decorators/property/tsTypes.decorator'; import { IPropSHPMapping } from './decorators/property/shp.decorator'; +import { IPropPYCSWMapping } from './layerRASTERMetadata'; +import { VectorFeatureTypeStructure } from './vectorFeatureTypeStructure'; -export interface IVectorBestMetadata { - productVersion: string | undefined; - // resolution: number | undefined; - // rms: number | undefined; - scale: string | undefined; +@graphqlClass({ alias: 'VectorBestRecord' }) +export class VectorBestMetadata implements IVectorBestMetadata { + //#region COMMON FIELDS - // PROFILES COMMON FIELDS - type: RecordType | undefined; - classification: string | undefined; - productName: string | undefined; - description: string | undefined; - srsId: string | undefined; - srsName: string | undefined; - producerName: string | undefined; - updateDate: Date | undefined; - // sourceDateStart: Date | undefined; - // sourceDateEnd: Date | undefined; - // sensorType: SensorType[] | undefined; //sensors - region: string[] | undefined; - footprint: GeoJSON | undefined; - // productId: string | undefined; - productType: ProductType | undefined; - creationDate: Date | undefined; - ingestionDate: Date | undefined; -} + //#region CORE: id + @wfs({ + capabilitiesMapping: { + xmlElement: '', + }, + }) + @tsTypes({ + mappingType: TsTypes.STRING, + }) + @graphql() + @fieldConfig({ + category: FieldCategory.MAIN, + isAutoGenerated: true, + }) + //#endregion + public id: string | undefined = undefined; -export interface IPropPYCSWMapping extends IPYCSWMapping { - prop: string; -} + //#region CORE: keywords + @wfs({ + capabilitiesMapping: { + xmlElement: 'keywords', + }, + }) + @tsTypes({ + mappingType: TsTypes.STRING, + }) + @graphql({ + nullable: true, + }) + @fieldConfig({ + category: FieldCategory.GENERAL, + isManuallyEditable: true, + }) + //#endregion + public keywords: string | undefined = undefined; + + //#region CORE: links + @wfs({ + capabilitiesMapping: { + xmlElement: 'name', + }, + }) + @tsTypes({ + mappingType: TsTypes.LINKS, + }) + @graphql({ + nullable: true, + }) + @fieldConfig({ + category: FieldCategory.GENERAL, + complexType: TsTypes.LINKS, + isAutoGenerated: true, + }) + //#endregion + public links: Link[] | undefined = undefined; -export class VectorBestMetadata implements IVectorBestMetadata { - //#region COMMON FIELDS //#region COMMON: type - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:type', - queryableField: 'mc:type', - pycswField: 'pycsw:Type', - }) - @catalogDB({ - column: { - name: 'type', - type: 'text', - nullable: true, + @wfs({ + capabilitiesMapping: { + xmlElement: '', }, }) @tsTypes({ @@ -70,17 +91,9 @@ export class VectorBestMetadata implements IVectorBestMetadata { public type: RecordType | undefined = RecordType.RECORD_RASTER; //#region COMMON: classification - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:classification', - queryableField: 'mc:classification', - pycswField: 'pycsw:Classification', - }) - @catalogDB({ - column: { - name: 'classification', - type: 'text', - nullable: false, + @wfs({ + capabilitiesMapping: { + xmlElement: '', }, }) @tsTypes({ @@ -106,17 +119,9 @@ export class VectorBestMetadata implements IVectorBestMetadata { public classification: string | undefined = undefined; //#region COMMON: productName - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:productName', - queryableField: 'mc:productName', - pycswField: 'pycsw:Title', - }) - @catalogDB({ - column: { - name: 'product_name', - type: 'text', - nullable: true, + @wfs({ + capabilitiesMapping: { + xmlElement: 'name.localPart', }, }) @tsTypes({ @@ -138,17 +143,9 @@ export class VectorBestMetadata implements IVectorBestMetadata { public productName: string | undefined = undefined; //#region COMMON: description - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:description', - queryableField: 'mc:description', - pycswField: 'pycsw:Abstract', - }) - @catalogDB({ - column: { - name: 'description', - type: 'text', - nullable: true, + @wfs({ + capabilitiesMapping: { + xmlElement: '', }, }) @tsTypes({ @@ -165,18 +162,9 @@ export class VectorBestMetadata implements IVectorBestMetadata { public description: string | undefined = undefined; //#region COMMON: srsId - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:SRS', - queryableField: 'mc:SRS', - pycswField: 'pycsw:CRS', - }) - @catalogDB({ - column: { - name: 'srs', - type: 'text', - nullable: false, - default: '4326', + @wfs({ + capabilitiesMapping: { + xmlElement: 'defaultCRS', }, }) @tsTypes({ @@ -194,18 +182,9 @@ export class VectorBestMetadata implements IVectorBestMetadata { public srsId: string | undefined = undefined; //#region COMMON: producerName - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:producerName', - queryableField: 'mc:producerName', - pycswField: 'pycsw:Creator', - }) - @catalogDB({ - column: { - name: 'producer_name', - type: 'text', - default: 'IDFMU', - nullable: true, + @wfs({ + capabilitiesMapping: { + xmlElement: 'name', }, }) @tsTypes({ @@ -229,162 +208,10 @@ export class VectorBestMetadata implements IVectorBestMetadata { //#endregion public producerName: string | undefined = undefined; - //#region COMMON: creationDate - @pycsw({ - profile: 'mc_vector_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, - }) - //#endregion - public creationDate: Date | undefined = undefined; - - //#region COMMON: ingestionDate - @pycsw({ - profile: 'mc_vector_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_vector_best', - xmlElement: 'mc:updateDate', - queryableField: 'mc:updateDate', - pycswField: 'pycsw:UpdateDate', - }) - @catalogDB({ - column: { - name: 'update_date', - type: 'timestamp without time zone', - }, - }) - @tsTypes({ - mappingType: TsTypes.DATE, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.MAIN, - isAutoGenerated: true, - }) - //#endregion - public updateDate: Date | undefined = undefined; - - //#region COMMON: region - @pycsw({ - profile: 'mc_vector_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, - infoMsgCode: ['info-field-tooltip.region.tooltip', 'info-general-tooltip.required'], - isMultiSelection: true, - lookupTable: 'countries', - validation: [ - { - errorMsgCode: 'validation-general.required', - required: true, - }, - ], - }) - //#endregion - public region: string[] | undefined = undefined; - //#endregion - - //#region VECTOR_BEST SPECIFIC FIELDS - //#region VECTOR_BEST: productVersion - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:productVersion', - queryableField: 'mc:productVersion', - pycswField: 'pycsw:ProductVersion', - }) - @catalogDB({ - column: { - name: 'product_version', - type: 'text', - nullable: true, - }, - }) - @tsTypes({ - mappingType: TsTypes.STRING, - }) - @graphql({ - nullable: true, - }) - @fieldConfig({ - category: FieldCategory.MAIN, - isAutoGenerated: true, - }) - //#endregion - public productVersion: string | undefined = undefined; - //#region VECTOR_BEST: productType - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:productType', - queryableField: 'mc:productType', - pycswField: 'pycsw:ProductType', - }) - @catalogDB({ - column: { - name: 'product_type', - type: 'text', - nullable: true, + @wfs({ + capabilitiesMapping: { + xmlElement: '', }, }) @tsTypes({ @@ -399,18 +226,9 @@ export class VectorBestMetadata implements IVectorBestMetadata { public productType: ProductType | undefined = ProductType.RASTER_VECTOR_BEST; //#region VECTOR_BEST: srsName - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:SRSName', - queryableField: 'mc:SRSName', - pycswField: 'pycsw:CRSName', - }) - @catalogDB({ - column: { - name: 'srs_name', - type: 'text', - nullable: false, - default: 'WGS84GEO', + @wfs({ + capabilitiesMapping: { + xmlElement: 'defaultCRS', }, }) @tsTypes({ @@ -433,76 +251,49 @@ export class VectorBestMetadata implements IVectorBestMetadata { //#endregion public srsName: string | undefined = undefined; - //#region VECTOR_BEST: scale - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:scale', - queryableField: 'mc:scale', - pycswField: 'pycsw:Scale', - }) - @catalogDB({ - column: { - name: 'scale', - type: 'text', - nullable: true, + //#region VECTOR_BEST: footprint + @wfs({ + capabilitiesMapping: { + xmlElement: 'wgs84BoundingBox', }, }) @tsTypes({ - mappingType: TsTypes.NUMBER, + mappingType: TsTypes.OBJECT, }) @graphql({ - nullable: true, + nullable: false, }) @fieldConfig({ category: FieldCategory.GEO_INFO, - infoMsgCode: [ - 'info-field-tooltip.scale.tooltip', - 'info-general-tooltip.required', - 'info-field-tooltip.scale.min', - 'info-field-tooltip.scale.max', - ], + infoMsgCode: ['info-general-tooltip.required'], validation: [ { errorMsgCode: 'validation-general.required', required: true, }, { - errorMsgCode: 'validation-field.scale.min', - valueType: 'value', - min: 0, - }, - { - errorMsgCode: 'validation-field.scale.max', - valueType: 'value', - max: 100000000, + errorMsgCode: 'validation-field.footprint.json', + json: true, }, ], }) //#endregion - public scale: string | undefined = undefined; + public footprint: GeoJSON | undefined = undefined; - //#region VECTOR_BEST: footprint - @pycsw({ - profile: 'mc_vector_best', - xmlElement: 'mc:footprint', - queryableField: 'mc:footprint', - pycswField: 'pycsw:footprint', - }) - @catalogDB({ - column: { - name: 'footprint_geojson', - type: 'text', - nullable: false, + //#region VECTOR_BEST: featureStructure + @wfs({ + capabilitiesMapping: { + xmlElement: 'metadataLink', }, }) @tsTypes({ - mappingType: TsTypes.OBJECT, + mappingType: TsTypes.FEATURESTRUCTURE, }) @graphql({ nullable: false, }) @fieldConfig({ - category: FieldCategory.GEO_INFO, + category: FieldCategory.MAIN, infoMsgCode: ['info-general-tooltip.required'], validation: [ { @@ -510,21 +301,17 @@ export class VectorBestMetadata implements IVectorBestMetadata { required: true, }, { - errorMsgCode: 'validation-field.footprint.json', + errorMsgCode: 'validation-field.featureStructure.json', json: true, }, ], }) //#endregion - public footprint: GeoJSON | undefined = undefined; + public featureStructure: VectorFeatureTypeStructure | undefined = undefined; //#endregion - public static getPyCSWMapping(prop: string): IPYCSWMapping | undefined { - return getPyCSWMapping(new VectorBestMetadata(), prop); - } - - public static getCatalogDBMapping(prop: string): ICatalogDBMapping | undefined { - return getCatalogDBMapping(new VectorBestMetadata(), prop); + public static getWFSMapping(prop: string): IWFSMapping | undefined { + return getWFSMapping(new VectorBestMetadata(), prop); } public static getFieldConfig(prop: string): IFieldConfigInfo | undefined { @@ -532,31 +319,18 @@ export class VectorBestMetadata implements IVectorBestMetadata { } public static getPyCSWMappings(): IPropPYCSWMapping[] { - const ret = []; - const layer = new VectorBestMetadata(); - for (const prop in layer) { - const pycswMap = getPyCSWMapping(layer, prop); - if (pycswMap) { - ret.push({ - prop: prop, - ...pycswMap, - }); - } - } - return ret; + return []; } - public static getCatalogDBMappings(): IPropCatalogDBMapping[] { + public static getWFSMappings(): IPropWFSMapping[] { const ret = []; const layer = new VectorBestMetadata(); for (const prop in layer) { - const catalogDbMap = getCatalogDBMapping(layer, prop); - const tsTypesMap = getTsTypesMapping(layer, prop); - if (catalogDbMap && tsTypesMap) { + const wfsMap = getWFSMapping(layer, prop); + if (wfsMap) { ret.push({ prop: prop, - ...catalogDbMap, - ...tsTypesMap, + ...wfsMap, }); } } @@ -569,10 +343,11 @@ export class VectorBestMetadata implements IVectorBestMetadata { for (const prop in layer) { const fieldConfigMap = getFieldConfig(layer, prop); if (fieldConfigMap) { - ret.push({ - prop: prop, - ...fieldConfigMap, - }); + const fieldConfig = { prop: prop, ...fieldConfigMap }; + if (fieldConfigMap.complexType) { + fieldConfig.subFields = getFieldConfigClassInfo(fieldConfigMap.complexType.value); + } + ret.push(fieldConfig); } } return ret; @@ -582,3 +357,19 @@ export class VectorBestMetadata implements IVectorBestMetadata { return []; } } + +export interface IVectorBestMetadata { + id: string | undefined; + keywords: string | undefined; + links: Link[] | undefined; + type: RecordType | undefined; + classification: string | undefined; + productName: string | undefined; + description: string | undefined; + srsId: string | undefined; + srsName: string | undefined; + producerName: string | undefined; + footprint: GeoJSON | undefined; + productType: ProductType | undefined; + featureStructure: VectorFeatureTypeStructure | undefined; +} diff --git a/src/models/layerMetadata/vectorFeatureTypeStructure.ts b/src/models/layerMetadata/vectorFeatureTypeStructure.ts new file mode 100644 index 00000000..ea274560 --- /dev/null +++ b/src/models/layerMetadata/vectorFeatureTypeStructure.ts @@ -0,0 +1,91 @@ +import { graphqlClass } from '../common/decorators/graphQL/classGraphql.decorator'; +import { graphql } from '../common/decorators/graphQL/graphql.decorator'; +import { FieldCategory, fieldConfig } from '../common/decorators/fieldConfig/fieldConfig.decorator'; +import { fieldConfigClass } from '../common/decorators/fieldConfig/classFieldConfig.decorator'; +import { TsTypes, tsTypes } from './decorators/property/tsTypes.decorator'; + +@fieldConfigClass() +@graphqlClass() +export class FieldFeatureType { + //#region FIELD: fieldName + @tsTypes({ + mappingType: TsTypes.STRING, + }) + @graphql({ + nullable: true, + }) + @fieldConfig({ + category: FieldCategory.GENERAL, + }) + //#endregion + public fieldName?: string = undefined; + + //#region FIELD: aliasFieldName + @tsTypes({ + mappingType: TsTypes.STRING, + }) + @graphql({ + nullable: true, + }) + @fieldConfig({ + category: FieldCategory.GENERAL, + }) + //#endregion + public aliasFieldName?: string = undefined; + + //#region FIELD: type + @tsTypes({ + mappingType: TsTypes.STRING, + }) + @graphql({ + nullable: true, + }) + @fieldConfig({ + category: FieldCategory.GENERAL, + }) + //#endregion + public type?: string = undefined; +} + +@fieldConfigClass() +@graphqlClass() +export class VectorFeatureTypeStructure { + //#region FIELD: layerName + @tsTypes({ + mappingType: TsTypes.STRING, + }) + @graphql({ + nullable: true, + }) + @fieldConfig({ + category: FieldCategory.GENERAL, + }) + //#endregion + public layerName?: string = undefined; + + //#region FIELD: aliasLayerName + @tsTypes({ + mappingType: TsTypes.STRING, + }) + @graphql({ + nullable: true, + }) + @fieldConfig({ + category: FieldCategory.GENERAL, + }) + //#endregion + public aliasLayerName?: string = undefined; + + //#region FIELD: fields + @tsTypes({ + mappingType: TsTypes.FIELDFEATURETYPES, + }) + @graphql({ + nullable: true, + }) + @fieldConfig({ + category: FieldCategory.GENERAL, + }) + //#endregion + public fields?: FieldFeatureType[] = undefined; +} diff --git a/src/models/polygonParts/polygonPartRecord.ts b/src/models/polygonParts/polygonPartRecord.ts index e7d316f5..dc339622 100644 --- a/src/models/polygonParts/polygonPartRecord.ts +++ b/src/models/polygonParts/polygonPartRecord.ts @@ -13,7 +13,7 @@ import { import { catalogDB, getCatalogDBMapping, ORMColumnType } from '../layerMetadata/decorators/property/catalogDB.decorator'; import { getTsTypesMapping, tsTypes, TsTypes } from '../layerMetadata/decorators/property/tsTypes.decorator'; import { ICatalogDBEntityMapping, IOrmCatalog, IPYCSWMapping } from '../layerMetadata'; -import { getWFSMapping, graphqlClass, IPropCatalogDBMapping, IPropWFSMapping, JAVA_BINDINGS, wfs } from '../common'; +import { getWFSMapping, graphqlClass, IPropCatalogDBMapping, IWFSGeoServerMapping, JAVA_BINDINGS, wfs } from '../common'; import { VALIDATIONS } from '../raster/constants'; import { camelCaseToSnakeCase } from '../helpers/utils'; import { DBEntity, getDBEntityMapping } from '../layerMetadata/decorators/class/DBEntity.decorator'; @@ -43,7 +43,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.STRING, + geoserver: { + binding: JAVA_BINDINGS.STRING, + }, }) @inputDataMapping([ { @@ -84,7 +86,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.STRING, + geoserver: { + binding: JAVA_BINDINGS.STRING, + }, }) @inputDataMapping([ { @@ -131,7 +135,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { index: {}, }) @wfs({ - binding: JAVA_BINDINGS.STRING, + geoserver: { + binding: JAVA_BINDINGS.STRING, + }, }) @inputDataMapping([ { @@ -196,7 +202,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { index: {}, }) @wfs({ - binding: JAVA_BINDINGS.STRING, + geoserver: { + binding: JAVA_BINDINGS.STRING, + }, }) @tsTypes({ mappingType: TsTypes.PRODUCTTYPE, @@ -218,7 +226,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.STRING, + geoserver: { + binding: JAVA_BINDINGS.STRING, + }, }) @inputDataMapping([ { @@ -259,7 +269,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { index: {}, }) @wfs({ - binding: JAVA_BINDINGS.TIMESTAMP, + geoserver: { + binding: JAVA_BINDINGS.TIMESTAMP, + }, }) @inputDataMapping([ { @@ -315,7 +327,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { index: {}, }) @wfs({ - binding: JAVA_BINDINGS.TIMESTAMP, + geoserver: { + binding: JAVA_BINDINGS.TIMESTAMP, + }, }) @inputDataMapping([ { @@ -365,7 +379,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.FLOAT, + geoserver: { + binding: JAVA_BINDINGS.FLOAT, + }, }) @inputDataMapping([ { @@ -424,7 +440,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.STRING, + geoserver: { + binding: JAVA_BINDINGS.STRING, + }, }) @inputDataMapping([ { @@ -473,7 +491,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.STRING, + geoserver: { + binding: JAVA_BINDINGS.STRING, + }, }) @inputDataMapping([ { @@ -517,7 +537,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.STRING, + geoserver: { + binding: JAVA_BINDINGS.STRING, + }, }) @inputDataMapping([ { @@ -558,7 +580,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { index: {}, }) @wfs({ - binding: JAVA_BINDINGS.BIGDECIMAL, + geoserver: { + binding: JAVA_BINDINGS.BIGDECIMAL, + }, }) @tsTypes({ mappingType: TsTypes.NUMBER, @@ -599,7 +623,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { index: {}, }) @wfs({ - binding: JAVA_BINDINGS.BIGDECIMAL, + geoserver: { + binding: JAVA_BINDINGS.BIGDECIMAL, + }, }) @tsTypes({ mappingType: TsTypes.NUMBER, @@ -634,7 +660,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.BIGDECIMAL, + geoserver: { + binding: JAVA_BINDINGS.BIGDECIMAL, + }, }) @tsTypes({ mappingType: TsTypes.NUMBER, @@ -705,7 +733,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { index: { spatial: true }, }) @wfs({ - binding: JAVA_BINDINGS.POLYGON, + geoserver: { + binding: JAVA_BINDINGS.POLYGON, + }, }) @inputDataMapping([ { @@ -755,7 +785,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.UUID, + geoserver: { + binding: JAVA_BINDINGS.UUID, + }, }) @tsTypes({ mappingType: TsTypes.STRING, @@ -776,7 +808,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.UUID, + geoserver: { + binding: JAVA_BINDINGS.UUID, + }, }) @tsTypes({ mappingType: TsTypes.STRING, @@ -799,7 +833,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { index: {}, }) @wfs({ - binding: JAVA_BINDINGS.UUID, + geoserver: { + binding: JAVA_BINDINGS.UUID, + }, }) @tsTypes({ mappingType: TsTypes.STRING, @@ -821,7 +857,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { }, }) @wfs({ - binding: JAVA_BINDINGS.STRING, + geoserver: { + binding: JAVA_BINDINGS.STRING, + }, }) @tsTypes({ mappingType: TsTypes.STRING, @@ -856,7 +894,9 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { index: {}, }) @wfs({ - binding: JAVA_BINDINGS.TIMESTAMP, + geoserver: { + binding: JAVA_BINDINGS.TIMESTAMP, + }, }) @tsTypes({ mappingType: TsTypes.DATE, @@ -872,20 +912,23 @@ export class PolygonPartRecord implements IPolygonPart, IOrmCatalog { return []; } - public static getWFSMappings(): IPropWFSMapping[] { - const ret: IPropWFSMapping[] = []; + public static getWFSMappings(): IWFSGeoServerMapping[] { + const ret: IWFSGeoServerMapping[] = []; const layer = new PolygonPartRecord(); POLYGON_PARTS_SERVED_KEYS.forEach((prop) => { const catalogDbMap = getCatalogDBMapping(layer, prop); const wfsMap = getWFSMapping(layer, prop); if (catalogDbMap && wfsMap) { - const { name, ...rest } = wfsMap; + const { name, binding, ...rest } = wfsMap.geoserver ?? {}; ret.push({ prop: prop, - name: name ?? prop, source: catalogDbMap.column.name as string, nillable: catalogDbMap.column.nullable ?? false, - ...rest, + geoserver: { + name: name ?? prop, + binding: binding ?? JAVA_BINDINGS.STRING, + ...rest, + }, }); } });