@data-fair/catalog-onegeo-suite 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # <img alt="Data FAIR logo" src="https://cdn.jsdelivr.net/gh/data-fair/data-fair@master/ui/public/assets/logo.svg" width="40"> @data-fair/catalog-onegeo-suite
2
+
3
+ A simple OneGeoSuite plugin for the Data Fair catalogs service.
package/index.ts ADDED
@@ -0,0 +1,37 @@
1
+ import type CatalogPlugin from '@data-fair/types-catalogs'
2
+ import { importConfigSchema, configSchema, assertConfigValid, type OneGeoSuiteConfig } from '#types'
3
+ import { type OneGeoCapabilities, capabilities } from './lib/capabilities.ts'
4
+ import i18n from './lib/i18n.ts'
5
+
6
+ // Since the plugin is very frequently imported, each function is imported on demand,
7
+ // instead of loading the entire plugin.
8
+ // This file should not contain any code, but only constants and dynamic imports of functions.
9
+
10
+ const plugin: CatalogPlugin<OneGeoSuiteConfig, OneGeoCapabilities> = {
11
+ async prepare (context) {
12
+ const prepare = (await import('./lib/prepare.ts')).default
13
+ return prepare(context)
14
+ },
15
+
16
+ async list (context) {
17
+ const { list } = await import('./lib/list.ts')
18
+ return list(context)
19
+ },
20
+
21
+ async getResource (context) {
22
+ const { getResource } = await import('./lib/imports.ts')
23
+ return getResource(context)
24
+ },
25
+
26
+ metadata: {
27
+ title: 'OneGeoSuite',
28
+ thumbnailPath: './lib/resources/thumbnail.svg',
29
+ i18n,
30
+ capabilities
31
+ },
32
+
33
+ importConfigSchema,
34
+ configSchema,
35
+ assertConfigValid
36
+ }
37
+ export default plugin
@@ -0,0 +1,19 @@
1
+ import type { Capability } from '@data-fair/types-catalogs'
2
+
3
+ /**
4
+ * The list of capabilities of the plugin.
5
+ * These capabilities define the actions that can be performed with the plugin.
6
+ * The capabilities must satisfy the `Capability` type.
7
+ */
8
+ export const capabilities = [
9
+ 'thumbnail',
10
+ 'search',
11
+ 'pagination',
12
+
13
+ 'import',
14
+ 'importConfig',
15
+
16
+ ] satisfies Capability[]
17
+
18
+ export type OneGeoCapabilities = typeof capabilities
19
+ export default capabilities
package/lib/i18n.ts ADDED
@@ -0,0 +1,52 @@
1
+ import type { Metadata } from '@data-fair/types-catalogs'
2
+
3
+ const i18n: Metadata['i18n'] = {
4
+ en: {
5
+ description: 'This catalog allows testing the service by simulating a folder and file structure.',
6
+ actionLabels: {
7
+ // createFolderInRoot: 'Create folder in root',
8
+ // createFolder: 'Create folder',
9
+ createResource: 'Create file', // Default : Create resource
10
+ // replaceFolder: 'Replace folder',
11
+ replaceResource: 'Replace file' // Default : Replace resource
12
+ },
13
+ actionButtons: {
14
+ // createFolderInRoot: 'Create publication',
15
+ // createFolder: 'Create publication here',
16
+ createResource: 'Create file here', // Default : Create publication here
17
+ // replaceFolder: 'Replace this folder',
18
+ replaceResource: 'Replace file' // Default : Replace this resource
19
+ },
20
+ stepTitles: {
21
+ // createFolder: 'Destination folder selection',
22
+ // createResource: 'Destination folder selection',
23
+ // replaceFolder: 'Folder to replace selection',
24
+ replaceResource: 'File to replace selection' // Default : Resource to replace selection
25
+ }
26
+ },
27
+ fr: {
28
+ description: 'Ce catalogue permet de tester le service en simulant une arborescence de dossiers et de fichiers.',
29
+ actionLabels: {
30
+ // createFolderInRoot: 'Créer un dossier à la racine',
31
+ // createFolder: 'Créer un dossier',
32
+ createResource: 'Créer un fichier', // Défaut : Créer une ressource
33
+ // replaceFolder: 'Écraser un dossier',
34
+ replaceResource: 'Remplacer un fichier' // Défaut : Écraser une ressource
35
+ },
36
+ actionButtons: {
37
+ // createFolderInRoot: 'Créer la publication',
38
+ // createFolder: 'Créer la publication ici',
39
+ createResource: 'Créer le fichier ici', // Défaut : Créer la publication ici
40
+ // replaceFolder: 'Écraser ce dossier',
41
+ replaceResource: 'Remplacer le fichier' // Défaut : Écraser cette ressource
42
+ },
43
+ stepTitles: {
44
+ // createFolder: 'Sélection du dossier de destination',
45
+ // createResource: 'Sélection du dossier de destination',
46
+ // replaceFolder: 'Sélection du dossier à écraser',
47
+ replaceResource: 'Sélection du fichier à remplacer' // Défaut : Sélection de la ressource à écraser
48
+ }
49
+ }
50
+ }
51
+
52
+ export default i18n
package/lib/imports.ts ADDED
@@ -0,0 +1,136 @@
1
+ import type { CatalogPlugin, GetResourceContext } from '@data-fair/types-catalogs'
2
+ import type { OneGeoSuiteConfig, Link } from '#types'
3
+
4
+ import axios from '@data-fair/lib-node/axios.js'
5
+
6
+ export const getResource = async ({ catalogConfig, importConfig, resourceId, tmpDir, log }: GetResourceContext<OneGeoSuiteConfig>): ReturnType<CatalogPlugin['getResource']> => {
7
+ const format: string = importConfig.format
8
+ const service: string = importConfig.service
9
+ const catalog = (await axios.get(new URL(`fr/indexer/elastic/_search/?q=_id:${resourceId}`, catalogConfig.url).href)).data.hits.hits[0]
10
+
11
+ if (!catalog) {
12
+ throw Error(`resource ${service} not found for ${resourceId} in ${catalogConfig.url}`)
13
+ }
14
+
15
+ // filter links by format and service
16
+ const source: Link = catalog._source['metadata-fr'].link.find((x: Link) => {
17
+ return x.service === service || x.url === service
18
+ })
19
+
20
+ // table of format for make AFS url
21
+ const afsTable: Record<string, string> = {
22
+ CSV: 'text/csv',
23
+ JSON: 'application/json',
24
+ GeoJSON: 'application/Geo%2Bjson',
25
+ GML: 'application/gml%2Bxml',
26
+ KML: 'application/vnd.google-earth.kml%2Bxml',
27
+ }
28
+ // table of format for make WFS url
29
+ const wfsTable: Record<string, string> = {
30
+ CSV: 'csv',
31
+ GeoJSON: 'application/json',
32
+ 'Shapefile (zip)': 'SHAPE-ZIP',
33
+ GML: 'GML3',
34
+ KML: 'kml',
35
+ }
36
+ // table of format
37
+ const extensionTable: Record<string, string> = {
38
+ CSV: '.csv',
39
+ GeoJSON: '.geojson',
40
+ JSON: '.json',
41
+ 'Shapefile (zip)': '.zip',
42
+ ZIP: '.zip',
43
+ GML: '.gml',
44
+ KML: '.kml',
45
+ XML: '.xml',
46
+ ODS: '.ods',
47
+ 'Excel non structuré': '.xlsx',
48
+ 'Microsoft Excel': '.xls',
49
+ }
50
+
51
+ let downloadUrl: string
52
+ if (source.service === 'WS') {
53
+ downloadUrl = `${source.url}/${source.name}/all${extensionTable[format]}`
54
+ } else if (source.service === undefined) {
55
+ downloadUrl = `${source.url}`
56
+ } else if (source.service === 'AFS') {
57
+ downloadUrl = `${source.url}${source.name}/items?&crs=${source.projections![0]}&f=${afsTable[format]}&sortby=gid`
58
+ } else if (source.service === 'WFS') {
59
+ downloadUrl = `${source.url}?SERVICE=WFS&VERSION=2.0.0&request=GetFeature&typename=${source.name}&outputFormat=${wfsTable[format]}&startIndex=0&sortby=gid`
60
+ } else {
61
+ downloadUrl = `${source.url}`
62
+ }
63
+
64
+ await log.step(`Downloading the file ${downloadUrl}`)
65
+
66
+ // Download the resource
67
+ const fs = await import('node:fs')
68
+ const path = await import('path')
69
+
70
+ const axiosPortail = axios.create({
71
+ validateStatus: function (status) {
72
+ return status >= 200 && status < 500
73
+ }
74
+ })
75
+
76
+ let portail
77
+ if ([200].includes((await axiosPortail.get(new URL('explorer/fr', catalogConfig.url).href)).status)) {
78
+ portail = 'explorer/fr'
79
+ } else if ([200].includes((await axiosPortail.get(new URL('portail/fr', catalogConfig.url).href)).status)) {
80
+ portail = 'portail/fr'
81
+ }
82
+ const origin = portail ? `${catalogConfig.url}/${portail}/jeux-de-donnees/${catalog._source.slug}/info` : ''
83
+
84
+ let response
85
+ try {
86
+ response = await axios.get(downloadUrl, {
87
+ responseType: 'stream',
88
+ })
89
+ if (response.headers['content-type'] === 'text/html') {
90
+ response = undefined
91
+ throw Error('return HTML page')
92
+ }
93
+
94
+ await log.info(`Get file with ${downloadUrl} successfully! ${response.status}`)
95
+ } catch (e) {
96
+ await log.warning(`Get file fail with this url: ${downloadUrl}; ${e}`)
97
+ }
98
+
99
+ if (!response) {
100
+ throw Error(`Download failed ${origin}`)
101
+ }
102
+
103
+ // Create a filename
104
+ const fileName = catalog._source.slug + extensionTable[format]
105
+ const filePath = path.join(tmpDir, fileName)
106
+ await log.info(`Downloading resource to ${fileName}`)
107
+
108
+ // Create write stream
109
+ const writeStream = fs.createWriteStream(filePath)
110
+ response.data.pipe(writeStream)
111
+
112
+ // Return a promise that resolves with the file path
113
+ await new Promise((resolve, reject) => {
114
+ writeStream.on('finish', () => resolve(filePath))
115
+ writeStream.on('error', (error) => reject(error))
116
+ })
117
+ await log.info(`Resource ${fileName} downloaded successfully!`)
118
+
119
+ return {
120
+ id: resourceId,
121
+ slug: catalog._source.slug,
122
+ title: catalog._source['metadata-fr'].title,
123
+ description: source.description ?? catalog._source['metadata-fr'].abstratc,
124
+ filePath,
125
+ format,
126
+ frequency: catalog._source['metadata-fr'].updateFrequency ?? '',
127
+ license: {
128
+ href: '',
129
+ title: catalog._source['metadata-fr'].license
130
+ },
131
+ keywords: catalog._source['metadata-fr'].keyword,
132
+ updatedAt: catalog._source['metadata-fr'].lastUpdateDate ?? undefined,
133
+ image: catalog._source['metadata-fr'].image.find((x: { type: string, url: string | null }) => { return x.type === 'thumbnail' && !!x.url }),
134
+ origin
135
+ }
136
+ }
package/lib/list.ts ADDED
@@ -0,0 +1,105 @@
1
+ import type { CatalogPlugin, ListContext } from '@data-fair/types-catalogs'
2
+ import type { OneGeoSuiteConfig, Link } from '#types'
3
+ import type { OneGeoCapabilities } from './capabilities.ts'
4
+ import axios from '@data-fair/lib-node/axios.js'
5
+
6
+ type ResourceList = Awaited<ReturnType<CatalogPlugin['list']>>['results']
7
+
8
+ const apiList: Array<string | undefined> = ['WS', 'AFS', 'WFS', undefined]
9
+ const formatsList = [
10
+ 'CSV', 'ODS', 'Excel non structuré', 'Microsoft Excel',
11
+ 'ZIP', 'Shapefile (zip)', 'GeoJSON', 'JSON', 'XML', 'GML', 'KML']
12
+
13
+ const getBestFormat = (formats: string[]) => {
14
+ return [...formats].sort((a, b) =>
15
+ (formatsList.indexOf(a) === -1 ? formatsList.length : formatsList.indexOf(a)) -
16
+ (formatsList.indexOf(b) === -1 ? formatsList.length : formatsList.indexOf(b))
17
+ )
18
+ }
19
+ const baseReqDataset = (input: string = '*', size: number = 100000, from: number = 1) => {
20
+ return {
21
+ from: (from - 1) * size,
22
+ size: Math.min(size, 10000),
23
+ track_total_hits: true,
24
+ query: {
25
+ bool: {
26
+ must: [{
27
+ bool: {
28
+ should: [{
29
+ query_string: {
30
+ query: input,
31
+ fields: ['data_and_metadata', 'metadata-fr.title^5', 'metadata-fr.abstract^3', 'content-fr.title^5', 'content-fr.excerpt^3', 'content-fr.plaintext'],
32
+ analyzer: 'my_search_analyzer',
33
+ fuzziness: 'AUTO',
34
+ minimum_should_match: '90%',
35
+ default_operator: 'AND',
36
+ boost: 5
37
+ }
38
+ }]
39
+ }
40
+ }, { term: { is_metadata: true } }, {
41
+ bool: {
42
+ should: [
43
+ ...apiList.filter((x: any) => { return x }).map((x: any) => { return { term: { 'metadata-fr.link.service.keyword': x } } }),
44
+ ...formatsList.filter((x: any) => { return x }).map((x: any) => { return { term: { 'metadata-fr.link.formats.keyword': x } } })],
45
+ }
46
+ }],
47
+ must_not: [{ term: { 'content-fr.status.keyword': 'draft' } }]
48
+ }
49
+ },
50
+ _source: { exclude: ['_dataset'] },
51
+ collapse: {
52
+ field: 'uuid.keyword'
53
+ },
54
+ post_filter: { terms: { 'type.keyword': ['dataset', 'nonGeographicDataset'] } }
55
+ }
56
+ }
57
+
58
+ export const list = async ({ catalogConfig, params }: ListContext<OneGeoSuiteConfig, OneGeoCapabilities>): ReturnType<CatalogPlugin['list']> => {
59
+ const url = catalogConfig.url
60
+ const listResources = async (params: Record<any, any>) => {
61
+ const catalogs = (await axios.post(new URL('fr/indexer/elastic/_search/', url).href, baseReqDataset(params.q, params.size, params.page))).data.hits.hits
62
+ const res = []
63
+
64
+ for (const catalog of catalogs) {
65
+ const sources: Array<Link> = catalog._source['metadata-fr'].link
66
+
67
+ // sort source by priority (services / format)
68
+ sources.sort((x: Link, y: Link) => {
69
+ const bestFormatX = formatsList.indexOf(getBestFormat(x.formats)[0]) === -1 ? formatsList.length : formatsList.indexOf(getBestFormat(x.formats)[0])
70
+ const bestFormatY = formatsList.indexOf(getBestFormat(y.formats)[0]) === -1 ? formatsList.length : formatsList.indexOf(getBestFormat(y.formats)[0])
71
+
72
+ if (bestFormatX !== bestFormatY) {
73
+ return bestFormatX - bestFormatY
74
+ }
75
+
76
+ return apiList.indexOf(x.service) - apiList.indexOf(y.service)
77
+ })
78
+
79
+ const formats: Array<string> = sources[0].formats
80
+ formats.sort((a: string, b: string) => {
81
+ return (formatsList.indexOf(a) === -1 ? formats.length : formatsList.indexOf(a)) - (formatsList.indexOf(b) === -1 ? formats.length : formatsList.indexOf(b))
82
+ })
83
+
84
+ let title = catalog._source['metadata-fr'].title
85
+ if (sources[0].service) title += ` - ( ${sources[0].service} )`
86
+
87
+ res.push({
88
+ id: `${catalog._id}`,
89
+ title,
90
+ description: sources[0].description,
91
+ format: formats[0],
92
+ type: 'resource'
93
+ } as ResourceList[number])
94
+ }
95
+ return res
96
+ }
97
+ // List datasets
98
+ const resources = await listResources(params)
99
+
100
+ return {
101
+ count: resources.length,
102
+ results: resources,
103
+ path: []
104
+ }
105
+ }
package/lib/prepare.ts ADDED
@@ -0,0 +1,21 @@
1
+ import type { OneGeoSuiteConfig } from '#types'
2
+ import type { OneGeoCapabilities } from './capabilities.ts'
3
+ import type { PrepareContext } from '@data-fair/types-catalogs'
4
+ import axios from '@data-fair/lib-node/axios.js'
5
+
6
+ export default async ({ catalogConfig }: PrepareContext<OneGeoSuiteConfig, OneGeoCapabilities>) => {
7
+ if (!catalogConfig.url) {
8
+ throw new Error('Catalog configuration is missing the "url" property.')
9
+ }
10
+
11
+ try {
12
+ await axios.get(`${catalogConfig.url}/fr/dataset`)
13
+ } catch (error) {
14
+ console.error(`Error connecting to OneGeoSuite API at ${catalogConfig.url}:`, error)
15
+ throw new Error(`Unable to connect to OneGeoSuite API at ${catalogConfig.url}. Please check the URL and your network connection.`)
16
+ }
17
+
18
+ return {
19
+ catalogConfig
20
+ }
21
+ }
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="512" height="512">
3
+ <path d="M0 0 C0.79647949 0.38526855 1.59295898 0.77053711 2.41357422 1.16748047 C24.81002753 12.13055578 43.9816398 26.88788868 62 44 C62.82757813 44.78503906 63.65515625 45.57007812 64.5078125 46.37890625 C106.9685617 87.73005399 130.23101425 148.42030708 131.28540039 207.05566406 C131.59882474 248.33732105 121.93795584 286.42876284 103 323 C102.62875 323.71897461 102.2575 324.43794922 101.875 325.17871094 C74.12278653 378.10846963 23.08672214 417.49108893 -33.35644531 435.43798828 C-93.69706641 453.85207444 -159.00775803 448.49453111 -215.05615234 418.93432617 C-235.27046624 407.87020872 -253.40007319 393.92306944 -270 378 C-271.23556641 376.82630859 -271.23556641 376.82630859 -272.49609375 375.62890625 C-315.0977993 334.20853049 -338.2119083 273.24624342 -339.35351562 214.52685547 C-339.60381785 173.43747055 -329.84205873 135.38604949 -311 99 C-310.62875 98.28102539 -310.2575 97.56205078 -309.875 96.82128906 C-295.86947514 70.10958003 -274.60942399 45.6175378 -251 27 C-249.989375 26.18402344 -248.97875 25.36804688 -247.9375 24.52734375 C-240.05155229 18.22762182 -231.81768276 12.90041285 -223 8 C-222.16178711 7.53303711 -221.32357422 7.06607422 -220.45996094 6.58496094 C-199.17553041 -5.15474472 -177.68298678 -13.54321825 -154 -19 C-153.2997168 -19.16725586 -152.59943359 -19.33451172 -151.87792969 -19.50683594 C-101.16004552 -31.52100615 -46.35553466 -22.54256947 0 0 Z " fill="#FEFEFE" transform="translate(360,45)"/>
4
+ <path d="M0 0 C19.8281058 16.94753396 32.62414399 39.80974347 39.40625 64.8359375 C39.61338623 65.59156982 39.82052246 66.34720215 40.03393555 67.12573242 C42.97489852 78.58346637 42.7350267 90.28871548 42.70727539 102.03198242 C42.70699282 103.71831256 42.70715262 105.40464283 42.7077179 107.0909729 C42.70800313 111.63770811 42.70215085 116.18441659 42.69514394 120.73114562 C42.68886464 125.49437176 42.68830299 130.25759861 42.68711853 135.02082825 C42.68401866 144.02674827 42.67582347 153.03265605 42.66576904 162.0385707 C42.65456605 172.29739556 42.64908693 182.55622102 42.64407361 192.81505048 C42.63363966 213.90535449 42.61531099 234.99564173 42.59375 256.0859375 C19.82375 256.0859375 -2.94625 256.0859375 -26.40625 256.0859375 C-26.4155957 251.00944824 -26.42494141 245.93295898 -26.43457031 240.70263672 C-26.46837743 223.90687266 -26.52374779 207.11123041 -26.59015274 190.31556511 C-26.62987961 180.13501615 -26.66230429 169.95454378 -26.67724609 159.77392578 C-26.69029562 150.8954554 -26.71734414 142.017154 -26.76086307 133.13877881 C-26.78340388 128.44229128 -26.79916513 123.74601159 -26.79813385 119.04946518 C-26.79738285 114.61868132 -26.81550843 110.18835561 -26.84741783 105.75769043 C-26.85585779 104.14135965 -26.85770745 102.52497711 -26.85205269 100.90863419 C-26.80557209 85.56564536 -29.66093065 73.01043601 -38.40625 60.0859375 C-38.84453125 59.43109375 -39.2828125 58.77625 -39.734375 58.1015625 C-47.6490066 47.70764871 -61.75610835 40.37594635 -74.40625 38.0859375 C-92.61294321 36.39217116 -107.56580766 38.80249007 -122.40625 50.0859375 C-133.83917181 59.599906 -141.46757143 73.37212762 -143.40625 88.0859375 C-143.70437324 93.6050686 -143.71794879 99.11787391 -143.72509766 104.64306641 C-143.73441034 106.29969769 -143.74458098 107.95632434 -143.75553894 109.61294556 C-143.78270198 114.08327541 -143.79794747 118.55357399 -143.81096697 123.02396441 C-143.8266578 127.70582167 -143.85342888 132.38761563 -143.8789978 137.06942749 C-143.9256806 145.92306236 -143.96247536 154.77670928 -143.99567068 163.63040388 C-144.03396647 173.71512644 -144.08335699 183.79978528 -144.13365483 193.88445401 C-144.23681846 214.61824052 -144.32466493 235.35205408 -144.40625 256.0859375 C-166.84625 256.0859375 -189.28625 256.0859375 -212.40625 256.0859375 C-212.40625 163.6859375 -212.40625 71.2859375 -212.40625 -23.9140625 C-189.96625 -23.9140625 -167.52625 -23.9140625 -144.40625 -23.9140625 C-144.40625 -21.9340625 -144.40625 -19.9540625 -144.40625 -17.9140625 C-143.29830078 -18.49414062 -143.29830078 -18.49414062 -142.16796875 -19.0859375 C-94.80898774 -43.39728226 -39.86540793 -33.54788588 0 0 Z " fill="#313C4E" transform="translate(339.40625,139.9140625)"/>
5
+ </svg>
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@data-fair/catalog-onegeo-suite",
3
+ "description": "OneGeoSuite plugin for the Data Fair catalogs service.",
4
+ "version": "0.1.0",
5
+ "main": "index.ts",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build-types": "df-build-types ./",
9
+ "check-types": "tsc",
10
+ "lint": "eslint .",
11
+ "prepare": "husky || true",
12
+ "test-base": "cross-env NODE_ENV=test EVENTS_LOG_LEVEL=alert node --disable-warning=ExperimentalWarning --test-force-exit --test-concurrency=1 --test",
13
+ "test-only": "npm run test-base -- --test-only test-it/*.ts",
14
+ "test": "npm run test-base test-it/*.ts",
15
+ "quality": "npm run lint && npm run build-types && npm run check-types && npm run test && npm audit --omit=dev --audit-level=critical",
16
+ "prepublishOnly": "npm run build-types"
17
+ },
18
+ "files": [
19
+ "./lib/**",
20
+ "./types/**",
21
+ "index.ts"
22
+ ],
23
+ "imports": {
24
+ "#types": "./types/index.ts",
25
+ "#type/*": "./types/*"
26
+ },
27
+ "keywords": [
28
+ "data-fair-catalogs-plugin"
29
+ ],
30
+ "license": "MIT",
31
+ "dependencies": {
32
+ "@data-fair/lib-node": "^2.11.0",
33
+ "@data-fair/lib-validation": "^1.0.2",
34
+ "prom-client": "^15.1.3"
35
+ },
36
+ "devDependencies": {
37
+ "@commitlint/cli": "^19.8.0",
38
+ "@commitlint/config-conventional": "^19.8.0",
39
+ "@data-fair/lib-types-builder": "^1.8.0",
40
+ "@data-fair/types-catalogs": "^0.6.0",
41
+ "@types/fs-extra": "^11.0.4",
42
+ "chalk": "^5.4.1",
43
+ "cross-env": "^10.1.0",
44
+ "dayjs": "^1.11.13",
45
+ "draftlog": "^1.0.13",
46
+ "eslint": "^9.25.1",
47
+ "fs-extra": "^11.3.0",
48
+ "husky": "^9.1.7",
49
+ "neostandard": "^0.12.1",
50
+ "typescript": "^5.8.3"
51
+ },
52
+ "relativeDependencies": {
53
+ "@data-fair/types-catalogs": "../../catalogs/types-catalogs"
54
+ }
55
+ }
@@ -0,0 +1,20 @@
1
+
2
+ export const schemaExports: string[]
3
+
4
+ // see https://github.com/bcherny/json-schema-to-typescript/issues/439 if some types are not exported
5
+ /**
6
+ * The url of the catalog
7
+ */
8
+ export type URL = string;
9
+
10
+ export type OneGeoSuiteConfig = {
11
+ url: URL;
12
+ }
13
+
14
+
15
+ export declare function validate(data: any): data is OneGeoSuiteConfig
16
+ export declare function assertValid(data: any, options?: import('@data-fair/lib-validation').AssertValidOptions): asserts data is OneGeoSuiteConfig
17
+ export declare function returnValid(data: any, options?: import('@data-fair/lib-validation').AssertValidOptions): OneGeoSuiteConfig
18
+
19
+ export declare const schema: any
20
+
@@ -0,0 +1,53 @@
1
+ /* eslint-disable */
2
+
3
+
4
+ import validate from './validate.js'
5
+ import { assertValid as assertValidGeneric } from '@data-fair/lib-validation'
6
+
7
+ export const schemaExports = [
8
+ "types",
9
+ "validate",
10
+ "schema"
11
+ ]
12
+
13
+ export { validate } from './validate.js'
14
+ export function assertValid(data, options) {
15
+ assertValidGeneric(validate, data, options)
16
+ }
17
+ export function returnValid(data, options) {
18
+ assertValid(data, options)
19
+ return data
20
+ }
21
+
22
+ export const schema = {
23
+ "$id": "https://github.com/data-fair/catalog-onegeo-suite/catalog-config",
24
+ "x-exports": [
25
+ "types",
26
+ "validate",
27
+ "schema"
28
+ ],
29
+ "title": "OneGeoSuiteConfig",
30
+ "type": "object",
31
+ "additionalProperties": false,
32
+ "required": [
33
+ "url"
34
+ ],
35
+ "properties": {
36
+ "url": {
37
+ "type": "string",
38
+ "title": "URL",
39
+ "description": "The url of the catalog",
40
+ "x-i18n-description": {
41
+ "fr": "L'URL du catalogue"
42
+ },
43
+ "pattern": "^https?://.*[^/]$",
44
+ "errorMessage": "The URL must start with http:// or https:// and must not end with `/`.",
45
+ "x-i18n-errorMessage": {
46
+ "fr": "L'URL doit commencer par http:// ou https:// et ne pas se terminer par `/`."
47
+ },
48
+ "examples": [
49
+ "https://demo.onegeosuite.fr"
50
+ ]
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,102 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+
4
+ "use strict";
5
+ export const validate = validate14;
6
+ export default validate14;
7
+ const schema16 = {"$id":"https://github.com/data-fair/catalog-onegeo-suite/catalog-config","x-exports":["types","validate","schema"],"title":"OneGeoSuiteConfig","type":"object","additionalProperties":false,"required":["url"],"properties":{"url":{"type":"string","title":"URL","description":"The url of the catalog","x-i18n-description":{"fr":"L'URL du catalogue"},"pattern":"^https?://.*[^/]$","errorMessage":"The URL must start with http:// or https:// and must not end with `/`.","x-i18n-errorMessage":{"fr":"L'URL doit commencer par http:// ou https:// et ne pas se terminer par `/`."},"examples":["https://demo.onegeosuite.fr"]}}};
8
+ const pattern0 = new RegExp("^https?://.*[^/]$", "u");
9
+
10
+ function validate14(data, {instancePath="", parentData, parentDataProperty, rootData=data}={}){
11
+ /*# sourceURL="https://github.com/data-fair/catalog-onegeo-suite/catalog-config" */;
12
+ let vErrors = null;
13
+ let errors = 0;
14
+ if(data && typeof data == "object" && !Array.isArray(data)){
15
+ if(data.url === undefined){
16
+ const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "url"},message:"must have required property '"+"url"+"'"};
17
+ if(vErrors === null){
18
+ vErrors = [err0];
19
+ }
20
+ else {
21
+ vErrors.push(err0);
22
+ }
23
+ errors++;
24
+ }
25
+ for(const key0 in data){
26
+ if(!(key0 === "url")){
27
+ const err1 = {instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties"};
28
+ if(vErrors === null){
29
+ vErrors = [err1];
30
+ }
31
+ else {
32
+ vErrors.push(err1);
33
+ }
34
+ errors++;
35
+ }
36
+ }
37
+ if(data.url !== undefined){
38
+ let data0 = data.url;
39
+ if(typeof data0 === "string"){
40
+ if(!pattern0.test(data0)){
41
+ const err2 = {instancePath:instancePath+"/url",schemaPath:"#/properties/url/pattern",keyword:"pattern",params:{pattern: "^https?://.*[^/]$"},message:"must match pattern \""+"^https?://.*[^/]$"+"\""};
42
+ if(vErrors === null){
43
+ vErrors = [err2];
44
+ }
45
+ else {
46
+ vErrors.push(err2);
47
+ }
48
+ errors++;
49
+ }
50
+ }
51
+ else {
52
+ const err3 = {instancePath:instancePath+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type: "string"},message:"must be string"};
53
+ if(vErrors === null){
54
+ vErrors = [err3];
55
+ }
56
+ else {
57
+ vErrors.push(err3);
58
+ }
59
+ errors++;
60
+ }
61
+ if(errors > 0){
62
+ const emErrs0 = [];
63
+ for(const err4 of vErrors){
64
+ if(((((err4.keyword !== "errorMessage") && (!err4.emUsed)) && ((err4.instancePath === instancePath+"/url") || ((err4.instancePath.indexOf(instancePath+"/url") === 0) && (err4.instancePath[instancePath+"/url".length] === "/")))) && (err4.schemaPath.indexOf("#/properties/url") === 0)) && (err4.schemaPath["#/properties/url".length] === "/")){
65
+ emErrs0.push(err4);
66
+ err4.emUsed = true;
67
+ }
68
+ }
69
+ if(emErrs0.length){
70
+ const err5 = {instancePath:instancePath+"/url",schemaPath:"#/properties/url/errorMessage",keyword:"errorMessage",params:{errors: emErrs0},message:"The URL must start with http:// or https:// and must not end with `/`."};
71
+ if(vErrors === null){
72
+ vErrors = [err5];
73
+ }
74
+ else {
75
+ vErrors.push(err5);
76
+ }
77
+ errors++;
78
+ }
79
+ const emErrs1 = [];
80
+ for(const err6 of vErrors){
81
+ if(!err6.emUsed){
82
+ emErrs1.push(err6);
83
+ }
84
+ }
85
+ vErrors = emErrs1;
86
+ errors = emErrs1.length;
87
+ }
88
+ }
89
+ }
90
+ else {
91
+ const err7 = {instancePath,schemaPath:"#/type",keyword:"type",params:{type: "object"},message:"must be object"};
92
+ if(vErrors === null){
93
+ vErrors = [err7];
94
+ }
95
+ else {
96
+ vErrors.push(err7);
97
+ }
98
+ errors++;
99
+ }
100
+ validate14.errors = vErrors;
101
+ return errors === 0;
102
+ }
@@ -0,0 +1 @@
1
+ export * from './.type/index.js'
@@ -0,0 +1,32 @@
1
+ {
2
+ "$id": "https://github.com/data-fair/catalog-onegeo-suite/catalog-config",
3
+ "x-exports": [
4
+ "types",
5
+ "validate",
6
+ "schema"
7
+ ],
8
+ "title": "OneGeoSuiteConfig",
9
+ "type": "object",
10
+ "additionalProperties": false,
11
+ "required": [
12
+ "url"
13
+ ],
14
+ "properties": {
15
+ "url": {
16
+ "type": "string",
17
+ "title": "URL",
18
+ "description": "The url of the catalog",
19
+ "x-i18n-description": {
20
+ "fr": "L'URL du catalogue"
21
+ },
22
+ "pattern": "^https?://.*[^/]$",
23
+ "errorMessage": "The URL must start with http:// or https:// and must not end with `/`.",
24
+ "x-i18n-errorMessage": {
25
+ "fr": "L'URL doit commencer par http:// ou https:// et ne pas se terminer par `/`."
26
+ },
27
+ "examples": [
28
+ "https://demo.onegeosuite.fr"
29
+ ]
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,5 @@
1
+
2
+ export const schemaExports: string[]
3
+
4
+ export declare const schema: any
5
+
@@ -0,0 +1,84 @@
1
+ /* eslint-disable */
2
+
3
+
4
+
5
+ export const schemaExports = [
6
+ "schema"
7
+ ]
8
+
9
+ export const schema = {
10
+ "$id": "https://github.com/data-fair/catalog-onegeo-suite/import-config",
11
+ "x-exports": [
12
+ "schema"
13
+ ],
14
+ "title": "ImportConfig",
15
+ "type": "object",
16
+ "additionalProperties": false,
17
+ "required": [
18
+ "service",
19
+ "format"
20
+ ],
21
+ "properties": {
22
+ "service": {
23
+ "type": "string",
24
+ "title": "Web Service",
25
+ "description": "The source of the resource",
26
+ "properties": {
27
+ "id": {
28
+ "type": "string"
29
+ },
30
+ "name": {
31
+ "type": "string"
32
+ },
33
+ "image_url": {
34
+ "type": "string"
35
+ }
36
+ },
37
+ "layout": {
38
+ "getItems": {
39
+ "url": "${context.catalogConfig.url}/fr/indexer/elastic/_search/?q=_id:${context.resourceId}",
40
+ "itemsResults": "(function() { const links = data.hits.hits[0]._source['metadata-fr'].link; return links.filter(l => l.formats.find(f => ['CSV', 'ODS', 'Excel non structuré', 'Microsoft Excel','ZIP', 'Shapefile (zip)', 'GeoJSON', 'JSON', 'XML', 'GML', 'KML'].includes(f)) || ['WS', 'AFS', 'WFS'].includes(l.service)).map((l, i) => [l, i] ); })()",
41
+ "itemTitle": "item[0].service?? 'Local N°' + (item[1] + 1)",
42
+ "itemValue": "item[0].service?? item[0].url"
43
+ }
44
+ }
45
+ },
46
+ "format": {
47
+ "type": "string",
48
+ "title": "Format",
49
+ "description": "the fomat use",
50
+ "properties": {
51
+ "id": {
52
+ "type": "string"
53
+ },
54
+ "name": {
55
+ "type": "string"
56
+ },
57
+ "image_url": {
58
+ "type": "string"
59
+ }
60
+ },
61
+ "layout": {
62
+ "getItems": {
63
+ "url": "${context.catalogConfig.url}/fr/indexer/elastic/_search/?q=_id:${context.resourceId}",
64
+ "itemsResults": "(function(){return data.hits.hits[0]._source['metadata-fr'].link.find(x => x.service === parent.data.service || x.url === parent.data.service).formats; })()",
65
+ "itemTitle": "item",
66
+ "itemValue": "item"
67
+ }
68
+ }
69
+ }
70
+ },
71
+ "layout": [
72
+ {
73
+ "children": [
74
+ "service"
75
+ ]
76
+ },
77
+ {
78
+ "if": "parent.data.service != null",
79
+ "children": [
80
+ "format"
81
+ ]
82
+ }
83
+ ]
84
+ }
@@ -0,0 +1 @@
1
+ export * from './.type/index.js'
@@ -0,0 +1,76 @@
1
+ {
2
+ "$id": "https://github.com/data-fair/catalog-onegeo-suite/import-config",
3
+ "x-exports": [
4
+ "schema"
5
+ ],
6
+ "title": "ImportConfig",
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "required": [
10
+ "service",
11
+ "format"
12
+ ],
13
+ "properties": {
14
+ "service": {
15
+ "type": "string",
16
+ "title": "Web Service",
17
+ "description": "The source of the resource",
18
+ "properties": {
19
+ "id": {
20
+ "type": "string"
21
+ },
22
+ "name": {
23
+ "type": "string"
24
+ },
25
+ "image_url": {
26
+ "type": "string"
27
+ }
28
+ },
29
+ "layout": {
30
+ "getItems": {
31
+ "url": "${context.catalogConfig.url}/fr/indexer/elastic/_search/?q=_id:${context.resourceId}",
32
+ "itemsResults": "(function() { const links = data.hits.hits[0]._source['metadata-fr'].link; return links.filter(l => l.formats.find(f => ['CSV', 'ODS', 'Excel non structuré', 'Microsoft Excel','ZIP', 'Shapefile (zip)', 'GeoJSON', 'JSON', 'XML', 'GML', 'KML'].includes(f)) || ['WS', 'AFS', 'WFS'].includes(l.service)).map((l, i) => [l, i] ); })()",
33
+ "itemTitle": "item[0].service?? 'Local N°' + (item[1] + 1)",
34
+ "itemValue": "item[0].service?? item[0].url"
35
+ }
36
+ }
37
+ },
38
+ "format": {
39
+ "type": "string",
40
+ "title": "Format",
41
+ "description": "the fomat use",
42
+ "properties": {
43
+ "id": {
44
+ "type": "string"
45
+ },
46
+ "name": {
47
+ "type": "string"
48
+ },
49
+ "image_url": {
50
+ "type": "string"
51
+ }
52
+ },
53
+ "layout": {
54
+ "getItems": {
55
+ "url": "${context.catalogConfig.url}/fr/indexer/elastic/_search/?q=_id:${context.resourceId}",
56
+ "itemsResults": "(function(){return data.hits.hits[0]._source['metadata-fr'].link.find(x => x.service === parent.data.service || x.url === parent.data.service).formats; })()",
57
+ "itemTitle": "item",
58
+ "itemValue": "item"
59
+ }
60
+ }
61
+ }
62
+ },
63
+ "layout": [
64
+ {
65
+ "children": [
66
+ "service"
67
+ ]
68
+ },
69
+ {
70
+ "if": "parent.data.service != null",
71
+ "children": [
72
+ "format"
73
+ ]
74
+ }
75
+ ]
76
+ }
package/types/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ export { schema as configSchema, assertValid as assertConfigValid, type OneGeoSuiteConfig } from './catalogConfig/index.ts'
2
+ export { schema as importConfigSchema } from './importConfig/index.ts'
3
+
4
+ export type Link = {
5
+ _main: boolean,
6
+ name: string,
7
+ description?: string,
8
+ formats: string[],
9
+ service?: string,
10
+ url: string,
11
+ projections?: string[]
12
+ }