Skip to content
Snippets Groups Projects
Commit 9d2a20fa authored by esikkala's avatar esikkala
Browse files

Upgrades to support Node.js 16

- upgrade express-openapi-validator
- recreate package-lock.json
parent daf639e8
No related branches found
No related tags found
No related merge requests found
source diff could not be displayed: it is too large. Options to address this: view the blob.
......@@ -33,7 +33,6 @@
"@nosferatu500/react-sortable-tree": "^3.0.5",
"@shakacode/recompose": "^0.30.3",
"@turf/buffer": "^6.3.0",
"Leaflet.extra-markers": "git+https://github.com/SemanticComputing/Leaflet.ExtraMarkers.git",
"apexcharts": "^3.26.0",
"axios": "^0.21.4",
"buffer": "^6.0.3",
......@@ -43,7 +42,7 @@
"date-fns": "^2.19.0",
"deck.gl": "^8.6.0",
"express": "^4.17.1",
"express-openapi-validator": "^3.12.7",
"express-openapi-validator": "^4.13.2",
"express-static-gzip": "^2.1.1",
"flat": "^5.0.2",
"immutable": "^4.0.0-rc.12",
......@@ -53,6 +52,7 @@
"leaflet-fullscreen": "^1.0.2",
"leaflet-usermarker": "git+https://github.com/SemanticComputing/leaflet-usermarker.git",
"leaflet.control.opacity": "^1.3.0",
"Leaflet.extra-markers": "git+https://github.com/SemanticComputing/Leaflet.ExtraMarkers.git",
"leaflet.locatecontrol": "^0.73.0",
"leaflet.markercluster": "^1.4.1",
"leaflet.zoominfo": "git+https://github.com/SemanticComputing/Leaflet.zoominfo.git",
......
......@@ -17,7 +17,7 @@ import { queryJenaIndex } from './sparql/JenaQuery'
import { getFederatedResults } from './sparql/FederatedSearch'
import { fetchGeoJSONLayer } from './wfs/WFSApi'
import swaggerUi from 'swagger-ui-express'
import { OpenApiValidator } from 'express-openapi-validator'
import * as OpenApiValidator from 'express-openapi-validator'
import yaml from 'js-yaml'
import querystring from 'querystring'
const DEFAULT_PORT = 3001
......@@ -61,330 +61,329 @@ if (!isDevelopment) {
// React app makes requests to these api urls
const apiPath = '/api/v1'
new OpenApiValidator({
const validator = OpenApiValidator.middleware({
apiSpec: swaggerDocument,
validateResponses: true
})
.install(app)
.then(() => {
// https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016
app.post(`${apiPath}/faceted-search/:resultClass/paginated`, async (req, res, next) => {
const { params, body } = req
try {
const data = await getPaginatedResults({
backendSearchConfig,
resultClass: params.resultClass,
page: body.page,
pagesize: parseInt(body.pagesize),
sortBy: body.sortBy,
sortDirection: body.sortDirection,
constraints: body.constraints,
resultFormat: 'json'
})
res.json(data)
} catch (error) {
console.log(error)
next(error)
}
})
app.use(validator)
app.post(`${apiPath}/faceted-search/:resultClass/all`, async (req, res, next) => {
const { params, body } = req
const resultFormat = 'json'
try {
const data = await getAllResults({
backendSearchConfig,
resultClass: params.resultClass,
facetClass: body.facetClass,
uri: body.uri,
constraints: body.constraints,
resultFormat: resultFormat,
limit: body.limit,
optimize: body.optimize,
fromID: body.fromID,
toID: body.toID
})
if (resultFormat === 'csv') {
res.writeHead(200, {
'Content-Type': 'text/csv',
'Content-Disposition': 'attachment; filename=results.csv'
})
res.end(data)
} else {
res.json(data)
}
} catch (error) {
next(error)
}
// https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016
app.post(`${apiPath}/faceted-search/:resultClass/paginated`, async (req, res, next) => {
const { params, body } = req
try {
const data = await getPaginatedResults({
backendSearchConfig,
resultClass: params.resultClass,
page: body.page,
pagesize: parseInt(body.pagesize),
sortBy: body.sortBy,
sortDirection: body.sortDirection,
constraints: body.constraints,
resultFormat: 'json'
})
res.json(data)
} catch (error) {
console.log(error)
next(error)
}
})
// GET endpoint for supporting CSV button
app.get(`${apiPath}/faceted-search/:resultClass/all`, async (req, res, next) => {
try {
const resultFormat = req.query.resultFormat == null ? 'json' : req.query.resultFormat
const data = await getAllResults({
backendSearchConfig,
resultClass: req.params.resultClass,
facetClass: req.query.facetClass || null,
constraints: req.query.constraints == null ? null : req.query.constraints,
resultFormat: resultFormat
})
if (resultFormat === 'csv') {
res.writeHead(200, {
'Content-Type': 'text/csv',
'Content-Disposition': 'attachment; filename=results.csv'
})
res.end(data)
} else {
res.json(data)
}
} catch (error) {
next(error)
}
app.post(`${apiPath}/faceted-search/:resultClass/all`, async (req, res, next) => {
const { params, body } = req
const resultFormat = 'json'
try {
const data = await getAllResults({
backendSearchConfig,
resultClass: params.resultClass,
facetClass: body.facetClass,
uri: body.uri,
constraints: body.constraints,
resultFormat: resultFormat,
limit: body.limit,
optimize: body.optimize,
fromID: body.fromID,
toID: body.toID
})
if (resultFormat === 'csv') {
res.writeHead(200, {
'Content-Type': 'text/csv',
'Content-Disposition': 'attachment; filename=results.csv'
})
res.end(data)
} else {
res.json(data)
}
} catch (error) {
next(error)
}
})
app.post(`${apiPath}/faceted-search/:resultClass/count`, async (req, res, next) => {
const { params, body } = req
try {
const data = await getResultCount({
backendSearchConfig,
resultClass: params.resultClass,
constraints: body.constraints,
resultFormat: 'json'
})
res.json(data)
} catch (error) {
next(error)
}
// GET endpoint for supporting CSV button
app.get(`${apiPath}/faceted-search/:resultClass/all`, async (req, res, next) => {
try {
const resultFormat = req.query.resultFormat == null ? 'json' : req.query.resultFormat
const data = await getAllResults({
backendSearchConfig,
resultClass: req.params.resultClass,
facetClass: req.query.facetClass || null,
constraints: req.query.constraints == null ? null : req.query.constraints,
resultFormat: resultFormat
})
if (resultFormat === 'csv') {
res.writeHead(200, {
'Content-Type': 'text/csv',
'Content-Disposition': 'attachment; filename=results.csv'
})
res.end(data)
} else {
res.json(data)
}
} catch (error) {
next(error)
}
})
app.post(`${apiPath}/:resultClass/page/:uri`, async (req, res, next) => {
const { params, body } = req
try {
const data = await getByURI({
backendSearchConfig,
resultClass: params.resultClass,
uri: params.uri,
facetClass: body.facetClass,
constraints: body.constraints,
resultFormat: 'json'
})
res.json(data)
} catch (error) {
next(error)
}
app.post(`${apiPath}/faceted-search/:resultClass/count`, async (req, res, next) => {
const { params, body } = req
try {
const data = await getResultCount({
backendSearchConfig,
resultClass: params.resultClass,
constraints: body.constraints,
resultFormat: 'json'
})
res.json(data)
} catch (error) {
next(error)
}
})
app.post(`${apiPath}/faceted-search/:facetClass/facet/:id`, async (req, res, next) => {
const { params, body } = req
try {
const data = await getFacet({
backendSearchConfig,
facetClass: params.facetClass,
facetID: params.id,
sortBy: body.sortBy,
sortDirection: body.sortDirection,
constraints: body.constraints,
resultFormat: 'json',
constrainSelf: body.constrainSelf
})
res.json(data)
} catch (error) {
next(error)
}
app.post(`${apiPath}/:resultClass/page/:uri`, async (req, res, next) => {
const { params, body } = req
try {
const data = await getByURI({
backendSearchConfig,
resultClass: params.resultClass,
uri: params.uri,
facetClass: body.facetClass,
constraints: body.constraints,
resultFormat: 'json'
})
res.json(data)
} catch (error) {
next(error)
}
})
app.get(`${apiPath}/full-text-search`, async (req, res, next) => {
try {
const data = await queryJenaIndex({
backendSearchConfig,
queryTerm: req.query.q,
resultClass: 'jenaText',
resultFormat: 'json'
})
res.json(data)
} catch (error) {
next(error)
}
app.post(`${apiPath}/faceted-search/:facetClass/facet/:id`, async (req, res, next) => {
const { params, body } = req
try {
const data = await getFacet({
backendSearchConfig,
facetClass: params.facetClass,
facetID: params.id,
sortBy: body.sortBy,
sortDirection: body.sortDirection,
constraints: body.constraints,
resultFormat: 'json',
constrainSelf: body.constrainSelf
})
res.json(data)
} catch (error) {
next(error)
}
})
app.get(`${apiPath}/federated-search`, async (req, res, next) => {
let queryTerm = ''
let latMin = 0
let longMin = 0
let latMax = 0
let longMax = 0
if (has(req.query, 'q')) {
queryTerm = req.query.q
}
if (has(req.query, 'latMin')) {
latMin = req.query.latMin
longMin = req.query.longMin
latMax = req.query.latMax
longMax = req.query.longMax
}
try {
const data = await getFederatedResults({
federatedSearchDatasets: backendSearchConfig.federatedSearch.datasets,
queryTerm,
latMin,
longMin,
latMax,
longMax,
datasets: castArray(req.query.dataset),
resultFormat: req.query.resultFormat == null ? 'json' : req.query.resultFormat
})
res.json(data)
} catch (error) {
next(error)
}
app.get(`${apiPath}/full-text-search`, async (req, res, next) => {
try {
const data = await queryJenaIndex({
backendSearchConfig,
queryTerm: req.query.q,
resultClass: 'jenaText',
resultFormat: 'json'
})
res.json(data)
} catch (error) {
next(error)
}
})
app.get(`${apiPath}/wfs`, async (req, res, next) => {
const layerIDs = castArray(req.query.layerID)
try {
const data = await Promise.all(layerIDs.map(layerID => fetchGeoJSONLayer({ layerID })))
res.json(data)
} catch (error) {
next(error)
}
app.get(`${apiPath}/federated-search`, async (req, res, next) => {
let queryTerm = ''
let latMin = 0
let longMin = 0
let latMax = 0
let longMax = 0
if (has(req.query, 'q')) {
queryTerm = req.query.q
}
if (has(req.query, 'latMin')) {
latMin = req.query.latMin
longMin = req.query.longMin
latMax = req.query.latMax
longMax = req.query.longMax
}
try {
const data = await getFederatedResults({
federatedSearchDatasets: backendSearchConfig.federatedSearch.datasets,
queryTerm,
latMin,
longMin,
latMax,
longMax,
datasets: castArray(req.query.dataset),
resultFormat: req.query.resultFormat == null ? 'json' : req.query.resultFormat
})
res.json(data)
} catch (error) {
next(error)
}
})
// https://www.maanmittauslaitos.fi/karttakuvapalvelu/tekninen-kuvaus-wmts
app.get(`${apiPath}/nls-wmts`, async (req, res, next) => {
const url = `https://karttakuva.maanmittauslaitos.fi/maasto/wmts/1.0.0/${req.query.layerID}/default/WGS84_Pseudo-Mercator/${req.query.z}/${req.query.y}/${req.query.x}.png`
const headers = {
'Content-Type': 'image/png',
Authorization: `Basic ${process.env.NLS_WMTS_BASIC_AUTH}`
}
try {
const response = await axios({
method: 'get',
url,
responseType: 'arraybuffer',
headers
})
res.end(response.data, 'base64')
} catch (error) {
next(error)
}
})
app.get(`${apiPath}/wfs`, async (req, res, next) => {
const layerIDs = castArray(req.query.layerID)
try {
const data = await Promise.all(layerIDs.map(layerID => fetchGeoJSONLayer({ layerID })))
res.json(data)
} catch (error) {
next(error)
}
})
// https://www.maanmittauslaitos.fi/karttakuvapalvelu/tekninen-kuvaus-wmts
app.get(`${apiPath}/nls-wmts-open`, async (req, res, next) => {
const url = `https://avoin-karttakuva.maanmittauslaitos.fi/avoin/wmts/1.0.0/${req.query.layerID}/default/WGS84_Pseudo-Mercator/${req.query.z}/${req.query.y}/${req.query.x}.png`
const headers = {
'Content-Type': 'image/png',
Authorization: `Basic ${process.env.NLS_API_KEY_BASE64}`
}
try {
const response = await axios({
method: 'get',
url,
responseType: 'arraybuffer',
headers
})
res.end(response.data, 'base64')
} catch (error) {
next(error)
}
// https://www.maanmittauslaitos.fi/karttakuvapalvelu/tekninen-kuvaus-wmts
app.get(`${apiPath}/nls-wmts`, async (req, res, next) => {
const url = `https://karttakuva.maanmittauslaitos.fi/maasto/wmts/1.0.0/${req.query.layerID}/default/WGS84_Pseudo-Mercator/${req.query.z}/${req.query.y}/${req.query.x}.png`
const headers = {
'Content-Type': 'image/png',
Authorization: `Basic ${process.env.NLS_WMTS_BASIC_AUTH}`
}
try {
const response = await axios({
method: 'get',
url,
responseType: 'arraybuffer',
headers
})
res.end(response.data, 'base64')
} catch (error) {
next(error)
}
})
// // https://www.maanmittauslaitos.fi/karttakuvapalvelu/tekninen-kuvaus-vektoritiilet
app.get(`${apiPath}/nls-vectortiles-open`, async (req, res, next) => {
const url = 'https://avoin-karttakuva.maanmittauslaitos.fi/vectortiles/stylejson/v20/taustakartta.json?TileMatrixSet=WGS84_Pseudo-Mercator'
const headers = {
Authorization: `Basic ${process.env.NLS_API_KEY_BASE64}`
}
try {
const response = await axios({
method: 'get',
url,
headers
})
res.json(response.data)
} catch (error) {
next(error)
}
// https://www.maanmittauslaitos.fi/karttakuvapalvelu/tekninen-kuvaus-wmts
app.get(`${apiPath}/nls-wmts-open`, async (req, res, next) => {
const url = `https://avoin-karttakuva.maanmittauslaitos.fi/avoin/wmts/1.0.0/${req.query.layerID}/default/WGS84_Pseudo-Mercator/${req.query.z}/${req.query.y}/${req.query.x}.png`
const headers = {
'Content-Type': 'image/png',
Authorization: `Basic ${process.env.NLS_API_KEY_BASE64}`
}
try {
const response = await axios({
method: 'get',
url,
responseType: 'arraybuffer',
headers
})
res.end(response.data, 'base64')
} catch (error) {
next(error)
}
})
app.get(`${apiPath}/fha-wms`, async (req, res, next) => {
const headers = {
Authorization: `Basic ${process.env.FHA_WMS_BASIC_AUTH}`
}
const { service, request, layers, styles, format, transparent, version, width, height, crs, bbox } = req.query
const mapServerParams = {
service,
request,
layers,
styles,
format,
transparent,
version,
width,
height,
crs,
bbox
}
const url = `http://137.116.207.73/geoserver/ows?${querystring.stringify(mapServerParams)}`
try {
const response = await axios({
method: 'get',
url,
responseType: 'arraybuffer',
headers
})
res.end(response.data, 'base64')
} catch (error) {
console.log(error)
next(error)
}
// // https://www.maanmittauslaitos.fi/karttakuvapalvelu/tekninen-kuvaus-vektoritiilet
app.get(`${apiPath}/nls-vectortiles-open`, async (req, res, next) => {
const url = 'https://avoin-karttakuva.maanmittauslaitos.fi/vectortiles/stylejson/v20/taustakartta.json?TileMatrixSet=WGS84_Pseudo-Mercator'
const headers = {
Authorization: `Basic ${process.env.NLS_API_KEY_BASE64}`
}
try {
const response = await axios({
method: 'get',
url,
headers
})
res.json(response.data)
} catch (error) {
next(error)
}
})
app.get(`${apiPath}/wfs`, async (req, res, next) => {
const layerIDs = castArray(req.query.layerID)
try {
const data = await Promise.all(layerIDs.map(layerID => fetchGeoJSONLayer({ layerID })))
res.json(data)
} catch (error) {
next(error)
}
app.get(`${apiPath}/fha-wms`, async (req, res, next) => {
const headers = {
Authorization: `Basic ${process.env.FHA_WMS_BASIC_AUTH}`
}
const { service, request, layers, styles, format, transparent, version, width, height, crs, bbox } = req.query
const mapServerParams = {
service,
request,
layers,
styles,
format,
transparent,
version,
width,
height,
crs,
bbox
}
const url = `http://137.116.207.73/geoserver/ows?${querystring.stringify(mapServerParams)}`
try {
const response = await axios({
method: 'get',
url,
responseType: 'arraybuffer',
headers
})
res.end(response.data, 'base64')
} catch (error) {
console.log(error)
next(error)
}
})
app.get(`${apiPath}/void/:resultClass`, async (req, res, next) => {
const { params } = req
try {
const data = await getAllResults({
backendSearchConfig,
resultClass: params.resultClass,
resultFormat: 'json'
})
res.json(data)
} catch (error) {
next(error)
}
app.get(`${apiPath}/wfs`, async (req, res, next) => {
const layerIDs = castArray(req.query.layerID)
try {
const data = await Promise.all(layerIDs.map(layerID => fetchGeoJSONLayer({ layerID })))
res.json(data)
} catch (error) {
next(error)
}
})
app.get(`${apiPath}/void/:resultClass`, async (req, res, next) => {
const { params } = req
try {
const data = await getAllResults({
backendSearchConfig,
resultClass: params.resultClass,
resultFormat: 'json'
})
res.json(data)
} catch (error) {
next(error)
}
})
// Express server is used to serve the React app only in production
if (!isDevelopment) {
/* Routes are matched to a url in order of their definition
// Express server is used to serve the React app only in production
if (!isDevelopment) {
/* Routes are matched to a url in order of their definition
Redirect all the the rest for react-router to handle */
app.get('*', function (request, response) {
response.sendFile(path.join(publicPath, 'index.html'))
})
}
app.get('*', function (request, response) {
response.sendFile(path.join(publicPath, 'index.html'))
})
}
const servingInfo = isDevelopment
? 'NODE_ENV=development, so Webpack serves the React app'
: `Static files (e.g. the React app) will be served from ${publicPath}`
const servingInfo = isDevelopment
? 'NODE_ENV=development, so Webpack serves the React app'
: `Static files (e.g. the React app) will be served from ${publicPath}`
const port = app.get('port')
const port = app.get('port')
app.listen(port, () =>
console.log(`
app.listen(port, () =>
console.log(`
Express server listening on port ${port}
API path is ${apiPath}
${servingInfo}
`)
)
})
)
......@@ -191,7 +191,7 @@ paths:
type: object
properties:
data:
type: integer
type: string
sparqlQuery:
type: string
resultClass:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment