Skip to content

Commit 73653dd

Browse files
committed
fix: url IDs rules #442
1 parent 01abbae commit 73653dd

File tree

9 files changed

+109
-105
lines changed

9 files changed

+109
-105
lines changed

components/Home/Embedded.vue

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ function onMenuChange(newCategoryId: number) {
150150
menuStore.addSelectedCategoryIds([newCategoryId])
151151
}
152152
153+
// TODO: rely on route params instead of selectedFeature/categgoryIds
153154
function routerPushUrl() {
154155
const categoryIds = selectedCategoryIds.value.join(',')
155156
const id = selectedFeature.value?.properties?.metadata?.id?.toString()

pages/embedded.vue

+34-23
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { mapStore as useMapStore } from '~/stores/map'
99
//
1010
// Composables
1111
//
12-
const { params, query, path } = useRoute()
12+
const route = useRoute()
1313
const siteStore = useSiteStore()
1414
const mapStore = useMapStore()
1515
const { config, settings } = storeToRefs(siteStore)
@@ -20,9 +20,9 @@ const { $trackingInit } = useNuxtApp()
2020
// Data
2121
//
2222
const boundaryGeojson = ref<Polygon | MultiPolygon>()
23-
const categoryIdsJoin = ref<string>()
2423
const poiId = ref<string>()
2524
const categoryIds = ref<number[]>()
25+
const categoryIdsRegex = /^(?:(?<cartocode>cartocode:[a-zA-Z0-9]{2})|(?<reference>ref:[a-z0-9-]+:\d+)|(?<osm>osm:[nwr]\d+)|\d+(?:,\d+)*)$/
2626
2727
//
2828
// Hooks
@@ -31,7 +31,7 @@ onBeforeMount(() => {
3131
$trackingInit(config.value!)
3232
})
3333
34-
const { boundary } = query
34+
const { boundary } = route.query
3535
if (boundary && typeof boundary === 'string' && settings.value!.polygons_extra) {
3636
const boundaryObject = settings.value!.polygons_extra[boundary]
3737
if (boundaryObject) {
@@ -51,33 +51,44 @@ if (boundary && typeof boundary === 'string' && settings.value!.polygons_extra)
5151
}
5252
}
5353
54-
// Workaround Nuxt missing feature to simple respect trialling slash meaning
55-
if (params.poiId) {
56-
categoryIdsJoin.value = params.p1 as string
57-
poiId.value = params.poiId as string
58-
}
59-
else if (path.endsWith('/')) {
60-
categoryIdsJoin.value = params.p1 as string
61-
poiId.value = undefined
54+
// Get category IDs from URL
55+
if (route.params.p1) {
56+
const match = route.params.p1.toString().match(categoryIdsRegex)
57+
58+
if (!match || (!route.path.endsWith('/') && match.groups && (match.groups.cartocode || match.groups.reference || match.groups.osm)))
59+
throw createError({ statusCode: 400, message: `No match for category ID: ${route.params.p1}` })
60+
61+
categoryIds.value = match.input?.split(',').map(id => Number.parseInt(id))
6262
}
63-
else {
64-
categoryIdsJoin.value = undefined
65-
poiId.value = params.p1 as string
63+
64+
// Get POI ID from URL
65+
if (route.name === 'index-p1' && route.path.endsWith('/')) {
66+
poiId.value = route.params.p1?.toString()
67+
categoryIds.value = undefined
6668
}
6769
68-
categoryIds.value = categoryIdsJoin.value?.split(',').map(id => Number.parseInt(id))
70+
if (route.params.poiId)
71+
poiId.value = route.params.poiId.toString()
6972
70-
const { data, error } = await useFetch<ApiPoi>(`${API_ENDPOINT}/${API_PROJECT}/${API_THEME}/poi/${poiId.value}.geojson?geometry_as=bbox&short_description=false`)
73+
// Fetch inital POI
74+
const { data, error, status } = await useFetch<ApiPoi>(
75+
() => `${API_ENDPOINT}/${API_PROJECT}/${API_THEME}/poi/${poiId.value}.geojson`,
76+
{
77+
query: {
78+
geometry_as: 'bbox',
79+
short_description: false,
80+
},
81+
immediate: !!poiId.value,
82+
},
83+
)
7184
72-
if (categoryIds.value && poiId.value) {
73-
if (error.value)
74-
throw createError(error.value)
85+
if (error.value)
86+
createError(error.value)
7587
76-
if (!data.value)
77-
throw createError({ statusCode: 404, message: 'Initial POI not found !' })
88+
if (status.value === 'success' && data.value)
89+
mapStore.setSelectedFeature(data.value)
7890
79-
mapStore.setSelectedFeature(data.value!)
80-
}
91+
// FIXME: In both p1 & poiId this ID is set
8192
</script>
8293

8394
<template>

pages/embedded/[p1].vue

-14
This file was deleted.

pages/embedded/[p1]/[poiId].vue

+10-7
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
// Validators
44
//
55
definePageMeta({
6-
validate({ params }) {
7-
return (
8-
typeof params.p1 === 'string'
9-
&& typeof params.poiId === 'string'
10-
&& /^[0-9,]+$/.test(params.p1)
11-
&& /^[-\w:]+$/.test(params.poiId)
12-
)
6+
validate: ({ params }) => {
7+
const regexForCategoryIds = /^(?:(?<cartocode>cartocode:[a-zA-Z0-9]{2})|(?<reference>ref:[a-z0-9-]+:\d+)|(?<osm>osm:[nwr]\d+)|\d+(?:,\d+)*)$/
8+
const regexForPOIIds = /^(?:cartocode:[a-zA-Z0-9]{2}|ref:[a-z0-9-]+:\d+|\d+)$/
9+
const match = params.p1.toString().match(regexForCategoryIds)
10+
11+
if (match?.groups && (match.groups.cartocode || match.groups.reference || match.groups.osm)) {
12+
return false
13+
}
14+
15+
return regexForCategoryIds.test(params.p1.toString()) && regexForPOIIds.test(params.poiId.toString())
1316
},
1417
})
1518
</script>

pages/embedded/[p1]/index.vue

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
// Validators
44
//
55
definePageMeta({
6-
validate({ params }) {
7-
return (
8-
params.p1 === undefined
9-
|| (typeof params.p1 === 'string' && /^[0-9,]+$/.test(params.p1))
10-
)
6+
validate: ({ params }) => {
7+
const regexForIds = /^(?:cartocode:[a-zA-Z0-9]{2}|ref:[a-z0-9-]+:\d+|\d+(?:,\d+)*)$/
8+
9+
return regexForIds.test(params.p1.toString())
1110
},
1211
})
1312
</script>

pages/index.vue

+46-25
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { mapStore as useMapStore } from '~/stores/map'
99
//
1010
// Composables
1111
//
12-
const { params, query, path } = useRoute()
12+
const route = useRoute()
1313
const siteStore = useSiteStore()
1414
const mapStore = useMapStore()
1515
const { config, settings } = storeToRefs(siteStore)
@@ -20,9 +20,9 @@ const { $trackingInit } = useNuxtApp()
2020
// Data
2121
//
2222
const boundaryGeojson = ref<Polygon | MultiPolygon>()
23-
const categoryIdsJoin = ref<string>()
2423
const poiId = ref<string>()
2524
const categoryIds = ref<number[]>()
25+
const categoryIdsRegex = /^(?:(?<cartocode>cartocode:[a-zA-Z0-9]{2})|(?<reference>ref:[a-z0-9-]+:\d+)|(?<osm>osm:[nwr]\d+)|\d+(?:,\d+)*)$/
2626
2727
//
2828
// Hooks
@@ -31,7 +31,7 @@ onBeforeMount(() => {
3131
$trackingInit(config.value!)
3232
})
3333
34-
const { boundary } = query
34+
const { boundary } = route.query
3535
if (boundary && typeof boundary === 'string' && settings.value!.polygons_extra) {
3636
const boundaryObject = settings.value!.polygons_extra[boundary]
3737
if (boundaryObject) {
@@ -51,43 +51,64 @@ if (boundary && typeof boundary === 'string' && settings.value!.polygons_extra)
5151
}
5252
}
5353
54-
// Workaround Nuxt missing feature to simple respect trialling slash meaning
55-
if (params.poiId) {
56-
categoryIdsJoin.value = params.p1 as string
57-
poiId.value = params.poiId as string
58-
}
59-
else if (path.endsWith('/')) {
60-
categoryIdsJoin.value = params.p1 as string
61-
poiId.value = undefined
54+
// Get category IDs from URL
55+
if (route.params.p1) {
56+
const match = route.params.p1.toString().match(categoryIdsRegex)
57+
58+
if (!match || (!route.path.endsWith('/') && match.groups && (match.groups.cartocode || match.groups.reference || match.groups.osm)))
59+
throw createError({ statusCode: 400, message: `No match for category ID: ${route.params.p1}` })
60+
61+
categoryIds.value = match.input?.split(',').map(id => Number.parseInt(id))
6262
}
63-
else {
64-
categoryIdsJoin.value = undefined
65-
poiId.value = params.p1 as string
63+
64+
// Get POI ID from URL
65+
if (route.name === 'index-p1' && route.path.endsWith('/')) {
66+
poiId.value = route.params.p1?.toString()
67+
categoryIds.value = undefined
6668
}
6769
68-
categoryIds.value = categoryIdsJoin.value?.split(',').map(id => Number.parseInt(id))
70+
if (route.params.poiId)
71+
poiId.value = route.params.poiId.toString()
6972
7073
// Fetch inital POI
71-
const { data, error } = await useFetch<ApiPoi>(`${API_ENDPOINT}/${API_PROJECT}/${API_THEME}/poi/${poiId.value}.geojson?geometry_as=bbox&short_description=true`)
74+
const { data, error, status } = await useFetch<ApiPoi>(
75+
() => `${API_ENDPOINT}/${API_PROJECT}/${API_THEME}/poi/${poiId.value}.geojson`,
76+
{
77+
query: {
78+
geometry_as: 'bbox',
79+
short_description: true,
80+
},
81+
immediate: !!poiId.value,
82+
},
83+
)
7284
73-
if (categoryIds.value && poiId.value) {
74-
if (error.value)
75-
throw createError(error.value)
85+
if (error.value)
86+
createError(error.value)
7687
77-
if (!data.value)
78-
throw createError({ statusCode: 404, message: 'Initial POI not found !' })
88+
if (status.value === 'success' && data.value)
89+
mapStore.setSelectedFeature(data.value)
7990
80-
mapStore.setSelectedFeature(data.value!)
81-
}
91+
// FIXME: In both p1 & poiId this ID is set
8292
</script>
8393

8494
<template>
85-
<VApp>
95+
Hello World
96+
<!-- <VApp>
97+
<VAlert
98+
v-if="error"
99+
:closable="true"
100+
:style="{ zIndex: 999 }"
101+
:text="error.message"
102+
location="top center"
103+
position="fixed"
104+
type="error"
105+
variant="elevated"
106+
/>
86107
<Home
87108
:boundary-area="boundaryGeojson"
88109
:initial-category-ids="categoryIds"
89110
/>
90-
</VApp>
111+
</VApp> -->
91112
</template>
92113

93114
<style scoped>

pages/index/[p1].vue

-18
This file was deleted.

pages/index/[p1]/[poiId].vue

+10-7
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
// Validators
44
//
55
definePageMeta({
6-
validate({ params }) {
7-
return (
8-
typeof params.p1 === 'string'
9-
&& typeof params.poiId === 'string'
10-
&& /^[-\w:,]/.test(params.p1)
11-
&& /^[-\w:]+$/.test(params.poiId)
12-
)
6+
validate: ({ params }) => {
7+
const regexForCategoryIds = /^(?:(?<cartocode>cartocode:[a-zA-Z0-9]{2})|(?<reference>ref:[a-z0-9-]+:\d+)|(?<osm>osm:[nwr]\d+)|\d+(?:,\d+)*)$/
8+
const regexForPOIIds = /^(?:cartocode:[a-zA-Z0-9]{2}|ref:[a-z0-9-]+:\d+|\d+)$/
9+
const match = params.p1.toString().match(regexForCategoryIds)
10+
11+
if (match?.groups && (match.groups.cartocode || match.groups.reference || match.groups.osm)) {
12+
return false
13+
}
14+
15+
return regexForCategoryIds.test(params.p1.toString()) && regexForPOIIds.test(params.poiId.toString())
1316
},
1417
})
1518
</script>

pages/index/[p1]/index.vue

+4-6
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
// Validators
44
//
55
definePageMeta({
6-
validate({ params }) {
7-
return (
8-
params.p1 === undefined
9-
|| (typeof params.p1 === 'string'
10-
&& /^[-\w:,]+$/.test(params.p1))
11-
)
6+
validate: ({ params }) => {
7+
const regexForIds = /^(?:cartocode:[a-zA-Z0-9]{2}|ref:[a-z0-9-]+:\d+|\d+(?:,\d+)*)$/
8+
9+
return regexForIds.test(params.p1.toString())
1210
},
1311
})
1412
</script>

0 commit comments

Comments
 (0)