UNPKG

@koopjs/featureserver

Version:

*An open source implementation of the GeoServices specification*

235 lines (189 loc) 5.56 kB
const _ = require('lodash'); const joi = require('joi'); const defaults = require('../metadata-defaults'); const logManager = require('../log-manager'); const { LayerFields } = require('./fields'); const supportedQueryFormatsArraySchema = joi .array() .items(joi.string().allow('JSON', 'geojson', 'PBF')) .has(joi.string().valid('JSON')) .message('must contain "JSON"'); const supportedQueryFormatsSchema = joi .alternatives() .try(supportedQueryFormatsArraySchema, joi.string()); class TableLayerMetadata { static create(geojson, options = {}) { const { geojson: normalizedGeojson, options: normalizedOptions } = TableLayerMetadata.normalizeInput(geojson, options); const tableMetadata = new TableLayerMetadata(); return tableMetadata.mixinOverrides(normalizedGeojson, normalizedOptions); } static normalizeInput(geojson, req) { const { metadata = {}, capabilities, ...normalizedGeojson } = geojson; const { params: { layer: reqLayer } = {}, query = {} } = req; const layerId = reqLayer != null ? reqLayer : req.layerId; // TODO: deprecate req.app.locals.config usage const { currentVersion, description } = _.get(req, 'app.locals.config.featureServer', {}); const normalizedOptions = _.pickBy( { currentVersion, description, layerId, ...query, ...metadata, capabilities: normalizeCapabilities(capabilities, metadata.capabilities), }, (value) => value, ); if (!normalizedGeojson.features) { normalizedGeojson.features = []; } return { geojson: normalizedGeojson, options: normalizedOptions, }; } constructor() { Object.assign(this, defaults.tableLayerDefaults()); } mixinOverrides(geojson = {}, options = {}) { const { id, idField = 'OBJECTID', displayField, capabilities, layerId, hasStaticData, supportsPagination, hasAttachments, supportedQueryFormats, } = options; this._setFields(geojson, options); this._setId(layerId, id); this._setDisplayField(displayField, idField); this._setHasStaticData(hasStaticData); this._setCapabilities(capabilities); this._setUniqueIdField(idField); this._setPagination(supportsPagination); this._setDirectOverrides(options); this._setHasAttachments(hasAttachments); this.#setSupportedQueryFormats(supportedQueryFormats); return this; } _setFields(data, options) { const fields = LayerFields.create({ ...data, ...options }); if (fields) { this.fields = fields; } } _setId(layerId, metadataId) { const requestPathLayerId = parseInt(layerId); const id = !isNaN(requestPathLayerId) ? requestPathLayerId : metadataId; if (id) { this.id = id; } } _setDisplayField(displayField, idField) { const overrideDisplayField = displayField || idField; if (overrideDisplayField) { this.displayField = overrideDisplayField; } } _setHasStaticData(hasStaticData) { if (typeof hasStaticData === 'boolean') { this.hasStaticData = hasStaticData; } } _setCapabilities(capabilities) { if (!capabilities) { return; } if (capabilities.list) { this.capabilities = capabilities.list; return; } if (_.has(capabilities, 'extract') && !this.capabilities.includes('Extract')) { this.capabilities = `${this.capabilities},Extract`; } } _setUniqueIdField(idField) { if (idField) { this.uniqueIdField.name = idField; } } _setPagination(supportsPagination) { if (typeof supportsPagination === 'boolean') { this.advancedQueryCapabilities.supportsPagination = supportsPagination; } } _setHasAttachments(hasAttachments) { if (hasAttachments != null && typeof hasAttachments === 'boolean') { this.hasAttachments = hasAttachments; } } _setDirectOverrides(options) { const { name, relationships, description, copyrightText, templates, idField, timeInfo, maxRecordCount, defaultVisibility, currentVersion, hasZ, } = options; _.merge(this, { name, relationships, description, copyrightText, templates, objectIdField: idField, timeInfo, maxRecordCount, defaultVisibility, currentVersion, hasZ, }); } #setSupportedQueryFormats(supportedQueryFormats) { if (!supportedQueryFormats) { return; } try { validateQueryFormatsArray(supportedQueryFormats); if (Array.isArray(supportedQueryFormats)) { this.supportedQueryFormats = supportedQueryFormats.join(','); return; } validateQueryFormatsArray(supportedQueryFormats.split(',').map((val) => val.trim())); this.supportedQueryFormats = supportedQueryFormats; } catch (error) { logManager.logger.error(error.message); } } } function normalizeCapabilities(capabilities, metadataCapabilites) { if (_.isString(metadataCapabilites)) { return { ...capabilities, list: metadataCapabilites, }; } return { ...(metadataCapabilites || {}), ...capabilities, }; } function validateQueryFormatsArray(arr) { const { error } = supportedQueryFormatsSchema.validate(arr); if (error) { throw new Error( `"supportedQueryFormats" override is invalid; ${error.message}. skipping override`, ); } } module.exports = TableLayerMetadata;