@opengis/gis 0.2.167 → 0.2.169

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.
Files changed (249) hide show
  1. package/dist/{CardIcon-golqfa-Y.js → CardIcon-xkRDr3_E.js} +1 -1
  2. package/dist/{EntityTablePage-BhmxePgR.js → EntityTablePage-D1IR5Bmq.js} +1 -1
  3. package/dist/{ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-BFa27smR.js → ExtentOutlineLayer.vue_vue_type_script_setup_true_lang-BJKIgAkD.js} +1 -1
  4. package/dist/{HeaderActions.vue_vue_type_script_setup_true_lang-Dp0MjgnU.js → HeaderActions.vue_vue_type_script_setup_true_lang-BU8__ouG.js} +1 -1
  5. package/dist/{MapSettings-F_DT3xKl.js → MapSettings-DIOlNpt6.js} +1 -1
  6. package/dist/{RastersTablePage-3rXQ0baG.js → RastersTablePage-OD1VqHP8.js} +1 -1
  7. package/dist/{cartocss-CN-UrS7V.js → cartocss-BiamDcNB.js} +5 -5
  8. package/dist/{import-utils-F5ErbNz1.js → import-utils-CvUG1jV0.js} +1 -1
  9. package/dist/{index-CdB0VXro.js → index-C6W8IkTm.js} +1224 -1221
  10. package/dist/index.css +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/index.umd.cjs +53 -40
  13. package/dist/{raster-DWmiWlf7.js → raster-BbIiZGoX.js} +3 -3
  14. package/dist/{register-D1jLD0hK.js → register-Dt2QoLZ3.js} +3 -3
  15. package/dist/service-CdUYntMi.js +3472 -0
  16. package/dist/{vs-datatable-BWItxbtK.js → vs-datatable-BELnJrfM.js} +2 -3
  17. package/module/gis/card/gis.metadata.table/index.yml +22 -22
  18. package/module/gis/card/gis.rasters.table/index.yml +11 -11
  19. package/module/gis/card/gis.registers.table/index.yml +23 -23
  20. package/module/gis/card/gis.services.table/index.yml +25 -25
  21. package/module/gis/cls/bool.yes_no.json +12 -12
  22. package/module/gis/cls/encoding.json +14 -14
  23. package/module/gis/cls/geom_type.json +14 -14
  24. package/module/gis/cls/gis.column_type.json +34 -34
  25. package/module/gis/cls/gis.column_view_type.json +26 -26
  26. package/module/gis/cls/gis.filter_type.json +22 -22
  27. package/module/gis/cls/language.json +10 -10
  28. package/module/gis/cls/meta.service_type.json +42 -42
  29. package/module/gis/cls/ogc.service.json +21 -21
  30. package/module/gis/cls/source_type.json +10 -10
  31. package/module/gis/cls/standarts.json +6 -6
  32. package/module/gis/cls/topic_category.json +106 -106
  33. package/module/gis/cls/update_frequency.json +29 -29
  34. package/module/gis/cls/view.json +21 -21
  35. package/module/gis/form/feedback.answer.form.json +10 -10
  36. package/module/gis/form/gis.cartocss.form.json +64 -64
  37. package/module/gis/form/gis.group_list.form.json +17 -17
  38. package/module/gis/form/gis.maps.form.json +61 -61
  39. package/module/gis/form/gis.metadata.form.json +240 -240
  40. package/module/gis/form/gis.metadata_new.form.json +195 -195
  41. package/module/gis/form/gis.ogc_service.form.json +51 -51
  42. package/module/gis/form/gis.rasters.form.json +76 -76
  43. package/module/gis/form/gis.registers.form.json +124 -124
  44. package/module/gis/form/gis.registers_column.form.json +84 -84
  45. package/module/gis/form/gis.registers_filter.form.json +65 -65
  46. package/module/gis/form/gis.services.form.json +111 -111
  47. package/module/gis/form/gis.services_attributes.form.json +75 -75
  48. package/module/gis/form/gis.services_filter.form.json +65 -65
  49. package/module/gis/menu.json +43 -43
  50. package/module/gis/select/admin.cls.name.sql +9 -9
  51. package/module/gis/select/layer_list.sql +7 -7
  52. package/module/gis/select/layer_list_text.sql +7 -7
  53. package/module/gis/select/pg.column_name.geometry.sql +12 -12
  54. package/module/gis/select/pg.columns.parent.sql +6 -6
  55. package/module/gis/select/pg.table_name.sql +17 -17
  56. package/module/gis/select/service_id.sql +1 -1
  57. package/module/gis/select/srid.sql +7 -7
  58. package/module/gis/table/gis.cartocss.table.json +74 -74
  59. package/module/gis/table/gis.group_list.table.json +58 -58
  60. package/module/gis/table/gis.maps.table.json +110 -110
  61. package/module/gis/table/gis.metadata.table.json +70 -70
  62. package/module/gis/table/gis.metadata_new.table.json +137 -137
  63. package/module/gis/table/gis.ogc_service.table.json +100 -100
  64. package/module/gis/table/gis.rasters.table.json +113 -113
  65. package/module/gis/table/gis.registers.table.json +143 -143
  66. package/module/gis/table/gis.services.table.json +120 -120
  67. package/module/gis/table/site.gis.registers.table.json +88 -88
  68. package/module/gis/table/site.gis.services.table.json +106 -106
  69. package/module/gis/templates/ISO19136_2017_gml_template.xml +330 -330
  70. package/module/gis/tokens.yml +5 -5
  71. package/module/permissions/form/permissions.users.form.json +151 -151
  72. package/module/permissions/table/gis.permissions.table.json +97 -97
  73. package/module/test/map/addr.json +303 -0
  74. package/module/test/map/{addr.yml → addr1.yml} +3 -1
  75. package/module/test/select/address.str_id.sql +3 -0
  76. package/package.json +10 -10
  77. package/plugin.js +21 -12
  78. package/server/plugins/mapnik/funcs/checkRasterFile.js +1 -3
  79. package/server/routes/cartocss/cartocss.route.js +31 -0
  80. package/server/routes/cartocss/cartocss.route.test.js +79 -0
  81. package/server/routes/cartocss/cartocss.schema.js +73 -0
  82. package/server/routes/{gis/cartocss → cartocss/functions}/add.cartocss.js +8 -11
  83. package/server/routes/{gis/cartocss → cartocss/functions}/get.cartocss.js +11 -13
  84. package/server/routes/gis/functions/checkXML.js +107 -0
  85. package/server/routes/gis/functions/dashboard.js +24 -0
  86. package/server/routes/gis/gis.route.js +26 -0
  87. package/server/routes/gis/gis.route.test.js +34 -0
  88. package/server/routes/gis/gis.schema.js +1 -0
  89. package/server/routes/map/{controllers → functions}/clearTiles.js +9 -8
  90. package/server/routes/map/{controllers → functions}/geojson.js +43 -43
  91. package/server/routes/map/{controllers → functions}/gis.convert.js +15 -23
  92. package/server/routes/map/{controllers → functions}/gis.icon.js +23 -10
  93. package/server/routes/map/{controllers → functions}/jsonData.js +72 -71
  94. package/server/routes/map/{controllers → functions}/layerList.js +17 -17
  95. package/server/routes/map/{controllers → functions}/map.js +8 -9
  96. package/server/routes/map/{controllers → functions}/mapCatalog.js +7 -7
  97. package/server/routes/map/functions/mapCatalogAttribute.js +54 -0
  98. package/server/routes/map/{controllers → functions}/mapFeatures.js +22 -18
  99. package/server/routes/map/{controllers → functions}/mapFormat.js +25 -28
  100. package/server/routes/map/{controllers → functions}/mapTiles.js +39 -30
  101. package/server/routes/map/{controllers → functions}/maps.js +3 -3
  102. package/server/routes/map/{controllers → functions}/marker_icon.js +1 -1
  103. package/server/routes/map/{controllers → functions}/parseGeoFile.js +10 -11
  104. package/server/routes/map/{controllers → functions}/pointHeight.js +3 -7
  105. package/server/routes/map/{controllers → functions}/vtile.js +5 -3
  106. package/server/routes/map/{vtile1.js → functions/vtile1.js} +39 -33
  107. package/server/routes/map/map.route.js +280 -0
  108. package/server/routes/map/map.route.test.js +503 -0
  109. package/server/routes/map/map.schema.js +356 -0
  110. package/server/routes/mapnik/{controllers → functions}/clearTiles.js +26 -29
  111. package/server/routes/mapnik/{controllers → functions}/createXml.js +17 -20
  112. package/server/routes/mapnik/{controllers → functions}/createXmlMulti.js +11 -15
  113. package/server/routes/mapnik/{controllers → functions}/fileSearch.js +6 -9
  114. package/server/routes/mapnik/functions/fileStat.js +28 -0
  115. package/server/routes/mapnik/{controllers → functions}/pretile.js +29 -35
  116. package/server/routes/mapnik/{controllers → functions}/rasterInfo.js +19 -10
  117. package/server/routes/mapnik/{controllers → functions}/readDir.js +4 -4
  118. package/server/routes/mapnik/functions/rtile.js +164 -0
  119. package/server/routes/mapnik/{controllers → functions}/uploadRaster.js +19 -24
  120. package/server/routes/mapnik/functions/uploadXML.js +27 -0
  121. package/server/routes/mapnik/mapnik.route.js +102 -0
  122. package/server/routes/mapnik/mapnik.route.test.js +371 -0
  123. package/server/routes/mapnik/mapnik.schema.mjs +190 -0
  124. package/server/routes/mapnik.prefixless/functions/mapnikLogger.js +31 -0
  125. package/server/routes/{mapnik/controllers → mapnik.prefixless/functions}/mapnikStat.js +7 -5
  126. package/server/routes/mapnik.prefixless/mapnik.prefixless.route.js +20 -0
  127. package/server/routes/mapnik.prefixless/mapnik.prefixless.route.test.js +91 -0
  128. package/server/routes/mapnik.prefixless/mapnik.prefixless.schema.mjs +27 -0
  129. package/server/routes/maps/functions/add.map.js +42 -0
  130. package/server/routes/{map/maps → maps/functions}/del.map.js +6 -7
  131. package/server/routes/{map/maps → maps/functions}/get.map.js +12 -11
  132. package/server/routes/maps/maps.route.js +58 -0
  133. package/server/routes/maps/maps.route.test.js +231 -0
  134. package/server/routes/maps/maps.schema.js +10 -0
  135. package/server/routes/metadata/functions/editMetadata.js +35 -0
  136. package/server/routes/metadata/functions/metadataXML.js +19 -0
  137. package/server/routes/metadata/metadata.route.js +26 -0
  138. package/server/routes/metadata/metadata.route.test.js +47 -0
  139. package/server/routes/metadata/metadata.schema.js +53 -0
  140. package/server/routes/{gis/ogc → ogc/functions}/map.info.point.js +22 -29
  141. package/server/routes/ogc/ogc.route.js +21 -0
  142. package/server/routes/ogc/ogc.route.test.js +54 -0
  143. package/server/routes/ogc/ogc.schema.js +16 -0
  144. package/server/routes/permissions/functions/catalog.permissions.edit.js +20 -0
  145. package/server/routes/permissions/functions/catalog.permissions.js +13 -0
  146. package/server/routes/permissions/{controllers → functions}/gis.catalog.js +10 -10
  147. package/server/routes/permissions/permissions.route.js +35 -0
  148. package/server/routes/permissions/permissions.route.test.js +35 -0
  149. package/server/routes/permissions/permissions.schema.js +44 -0
  150. package/server/routes/registers/functions/add.registry.js +37 -0
  151. package/server/routes/{gis/registers/funcs → registers/functions}/classifiers.js +2 -2
  152. package/server/routes/{gis/registers → registers/functions}/del.registry.js +5 -5
  153. package/server/routes/{gis/registers/funcs → registers/functions}/get.info.js +9 -5
  154. package/server/routes/{gis/registers → registers/functions}/gis.export.js +27 -21
  155. package/server/routes/{gis/registers → registers/functions}/gis.registry.js +22 -15
  156. package/server/routes/{gis/registers → registers/functions}/gis.registry.list.js +12 -10
  157. package/server/routes/{gis/registers/funcs → registers/functions}/handleRegistryRequest.js +12 -11
  158. package/server/routes/registers/registers.route.js +80 -0
  159. package/server/routes/registers/registers.route.test.js +145 -0
  160. package/server/routes/registers/registers.schema.js +246 -0
  161. package/server/routes/{gis/services → services/functions}/add.service.js +14 -16
  162. package/server/routes/services/functions/create.route.js +93 -0
  163. package/server/routes/{gis/services → services/functions}/del.service.js +5 -5
  164. package/server/routes/{gis/services → services/functions}/get.service.users.js +15 -13
  165. package/server/routes/services/functions/get.services.col.js +34 -0
  166. package/server/routes/{gis/services → services/functions}/get.services.js +21 -16
  167. package/server/routes/services/services.route.js +76 -0
  168. package/server/routes/services/services.route.test.js +168 -0
  169. package/server/routes/services/services.schema.js +278 -0
  170. package/server/routes/widgets/functions/add.widget.js +39 -0
  171. package/server/routes/widgets/functions/del.widget.js +18 -0
  172. package/server/routes/{map/widgets → widgets/functions}/get.widget.js +12 -11
  173. package/server/routes/widgets/widgets.route.js +61 -0
  174. package/server/routes/widgets/widgets.route.test.js +144 -0
  175. package/server/routes/widgets/widgets.schema.js +25 -0
  176. package/dist/service-JGNtth-y.js +0 -2593
  177. package/module/cls.json +0 -7
  178. package/module/gis/card/gis.metadata.table/main_info.hbs +0 -21
  179. package/module/gis/card/gis.metadata.table/metadata_info.hbs +0 -28
  180. package/module/gis/card/gis.metadata.table/other.hbs +0 -26
  181. package/module/gis/card/gis.rasters.table/main_info.hbs +0 -27
  182. package/module/gis/card/gis.registers.table/cls.hbs +0 -36
  183. package/module/gis/card/gis.registers.table/columns.hbs +0 -89
  184. package/module/gis/card/gis.registers.table/filters.hbs +0 -80
  185. package/module/gis/card/gis.registers.table/main_info.hbs +0 -35
  186. package/module/gis/card/gis.registers.table/source.hbs +0 -45
  187. package/module/gis/card/gis.services.table/attributes.hbs +0 -91
  188. package/module/gis/card/gis.services.table/filters.hbs +0 -83
  189. package/module/gis/card/gis.services.table/main_info.hbs +0 -27
  190. package/module/gis/card/gis.services.table/source.hbs +0 -26
  191. package/module/test/cls/bp_build_type.json +0 -37
  192. package/module/test/cls/doc_status.json +0 -32
  193. package/module/test/cls/ts.temp_status.json +0 -18
  194. package/module/test/cls/ts.temp_structure.ts_class.json +0 -50
  195. package/module/test/cls/ts.temp_type.json +0 -10
  196. package/module/test/layer/bp.json +0 -60
  197. package/module/test/layer/bp1.yml +0 -33
  198. package/module/test/layer/individual.yml +0 -54
  199. package/module/test/layer/ts.linking_passport.yml +0 -56
  200. package/module/test/layer/ts.temp_structure.yml +0 -51
  201. package/module/test/map/bp_myo.json +0 -44
  202. package/module/test/map/bpf.json +0 -44
  203. package/module/test/map/main.json +0 -39
  204. package/module/test/map/mbd.json +0 -92
  205. package/module/test/map/ts.json +0 -53
  206. package/module/test/select/address_id.json +0 -3
  207. package/module/test/select/address_id.sql +0 -8
  208. package/module/test/select/core.user_uid.sql +0 -1
  209. package/module/test/table/data_address.street.table.json +0 -70
  210. package/module/test/table/data_bp_myo.bp.table.json +0 -123
  211. package/server/routes/gis/checkXML.js +0 -117
  212. package/server/routes/gis/dashboard.js +0 -29
  213. package/server/routes/gis/index.mjs +0 -92
  214. package/server/routes/gis/metadata/editMetadata.js +0 -34
  215. package/server/routes/gis/metadata/metadataXML.js +0 -13
  216. package/server/routes/gis/registers/add.registry.js +0 -35
  217. package/server/routes/gis/registers/insert.columns.js +0 -107
  218. package/server/routes/gis/registers/insert.filters.js +0 -110
  219. package/server/routes/gis/services/create.route.js +0 -96
  220. package/server/routes/gis/services/get.services.col.js +0 -33
  221. package/server/routes/map/controllers/mapCatalogAttribute.js +0 -56
  222. package/server/routes/map/index.mjs +0 -259
  223. package/server/routes/map/maps/add.map.js +0 -43
  224. package/server/routes/map/widgets/add.widget.js +0 -39
  225. package/server/routes/map/widgets/del.widget.js +0 -23
  226. package/server/routes/mapnik/controllers/fileStat.js +0 -28
  227. package/server/routes/mapnik/controllers/mapnikLogger.js +0 -29
  228. package/server/routes/mapnik/controllers/rtile.js +0 -167
  229. package/server/routes/mapnik/index.js +0 -40
  230. package/server/routes/permissions/controllers/catalog.permissions.edit.js +0 -22
  231. package/server/routes/permissions/controllers/catalog.permissions.js +0 -8
  232. package/server/routes/permissions/index.mjs +0 -18
  233. /package/server/routes/map/{controllers/pin → pin}/circle1.svg +0 -0
  234. /package/server/routes/map/{controllers/pin → pin}/circle2.svg +0 -0
  235. /package/server/routes/map/{controllers/pin → pin}/none.svg +0 -0
  236. /package/server/routes/map/{controllers/pin → pin}/pin.svg +0 -0
  237. /package/server/routes/map/{controllers/pin → pin}/pin1.svg +0 -0
  238. /package/server/routes/map/{controllers/pin → pin}/pin2.svg +0 -0
  239. /package/server/routes/map/{controllers/pin → pin}/pin3.svg +0 -0
  240. /package/server/routes/map/{controllers/pin → pin}/pin4.svg +0 -0
  241. /package/server/routes/map/{controllers/pin → pin}/pin5.svg +0 -0
  242. /package/server/routes/map/{controllers/pin → pin}/pin6.svg +0 -0
  243. /package/server/routes/map/{controllers/pin → pin}/pin7.svg +0 -0
  244. /package/server/routes/permissions/{controllers/utils → functions}/get.permissions.js +0 -0
  245. /package/server/routes/{gis/registers/funcs → registers/functions}/columns.js +0 -0
  246. /package/server/routes/{gis/registers/funcs → registers/functions}/content.type.js +0 -0
  247. /package/server/routes/{gis/registers → registers/functions}/map.registry.js +0 -0
  248. /package/server/routes/{gis/services → services/functions}/get.layer.geom.js +0 -0
  249. /package/server/routes/{gis/services → services/functions}/legend.auto.js +0 -0
@@ -0,0 +1,371 @@
1
+ import { readFile } from 'fs/promises';
2
+
3
+ import {
4
+ describe, test, expect, beforeAll, afterAll
5
+ } from 'vitest';
6
+
7
+ import { config, getPGAsync, isFileExists, uploadFile } from '@opengis/fastify-table/utils.js';
8
+
9
+ import { build, injectWithHeaders } from '../../../test/helper.js';
10
+
11
+ const user = { uid: '2', type: 'admin' };
12
+
13
+ const testId = 'testRasterId';
14
+
15
+ const rasterRelPath = 'test/files/black1x1.tif';
16
+
17
+ let pg;
18
+
19
+ const cleanUp = async (when) => {
20
+ if (!pg) return;
21
+ const rowCount = await pg.query('delete from gis.rasters where raster_id=$1', [testId]).then(r => r.rowCount);
22
+ console.log(`clean up ${when} finished`, rowCount);
23
+ }
24
+
25
+ beforeAll(async () => {
26
+ await build();
27
+ pg = await getPGAsync();
28
+ expect(pg).toHaveProperty('pk');
29
+ await cleanUp('before');
30
+
31
+ const exists = await isFileExists('/files/temp/black1x1.tif');
32
+ if (!exists && config.s3) {
33
+ // upload raster to s3
34
+ const buffer = await readFile(rasterRelPath);
35
+ await uploadFile('/files/test/black1x1.tif', buffer);
36
+ }
37
+
38
+ await pg.query('insert into gis.rasters (raster_id,name,source_path) values($1,$2,$3)', [testId, 'unit-test', '/files/test/black1x1.tif']).catch(err => console.error(err));
39
+ });
40
+
41
+ afterAll(async () => {
42
+ await cleanUp('after');
43
+ });
44
+
45
+ test('GET /gis-upload-raster/:id (restrict unauthorized)', async () => {
46
+ const res = await injectWithHeaders({
47
+ method: 'GET',
48
+ url: `/api/gis-upload-raster/${testId}`,
49
+ });
50
+ expect(res.statusCode).toBe(403);
51
+ });
52
+
53
+ if (config.s3) {
54
+ describe('upload raster from s3 to mapnik for processing / tile generation', () => {
55
+ test('GET /gis-upload-raster/:id', async () => {
56
+ const res = await injectWithHeaders({
57
+ method: 'GET',
58
+ url: `/api/gis-upload-raster/${testId}`,
59
+ headers: { uid: user.uid, user_type: 'regular' },
60
+ });
61
+ expect(res.statusCode).toBe(200);
62
+ expect(res.body).not.toHaveProperty('error');
63
+ });
64
+ });
65
+ }
66
+
67
+ test('GET /gis-xml/:id', async () => {
68
+ const res = await injectWithHeaders({
69
+ method: 'GET',
70
+ url: `/api/gis-xml/${testId}`,
71
+ query: { nocache: 1 }
72
+ });
73
+ expect(res.statusCode).toBe(200);
74
+ });
75
+
76
+ describe('GET /gis-rtile', async () => {
77
+ test('WEBP from raster', async () => {
78
+ const res = await injectWithHeaders({
79
+ method: 'GET',
80
+ url: `/api/gis-rtile/${testId}/10/523/391.webp`,
81
+ });
82
+
83
+ expect(res.statusCode).toBe(200);
84
+ expect(res.headers['content-type']).toMatch(/image\/webp/);
85
+ expect(res.body.length).toBeGreaterThan(200);
86
+ });
87
+
88
+ const cartocssId = await pg.query('select cartocss_id from gis.cartocss where config is not null and style is not null and source_path is not null and geom is not null and enabled limit 1').then(r => r.rows?.[0]?.cartocss_id);
89
+ expect(cartocssId).toBeTypeOf('string');
90
+
91
+ test('WEBP from cartocss', async () => {
92
+ const res = await injectWithHeaders({
93
+ method: 'GET',
94
+ url: `/api/gis-rtile/${cartocssId}/10/523/391.webp`,
95
+ });
96
+
97
+ expect(res.statusCode).toBe(200);
98
+ expect(res.headers['content-type']).toMatch(/image\/webp/);
99
+ expect(res.body.length).toBeGreaterThan(200);
100
+ });
101
+ });
102
+
103
+ describe('GET /gis-raster/:id', () => {
104
+ test('returns raster metadata', async () => {
105
+ const res = await injectWithHeaders({
106
+ method: 'GET',
107
+ url: `/api/gis-raster/${testId}`,
108
+ });
109
+ expect(res.statusCode).toBe(200);
110
+
111
+ const body = res.json();
112
+
113
+ expect(body).toHaveProperty('total_size');
114
+ expect(typeof body.total_size).toBe('string');
115
+
116
+ expect(body).toHaveProperty('extension');
117
+ expect(typeof body.extension).toBe('string');
118
+
119
+ expect(body).toHaveProperty('srid');
120
+ expect(typeof body.srid).toBe('string');
121
+
122
+ expect(body).toHaveProperty('proj4');
123
+ if (!body.srid) {
124
+ expect(typeof body.proj4).toBe('string');
125
+ }
126
+
127
+ expect(body).toHaveProperty('extent');
128
+ expect(Array.isArray(body.extent)).toBe(true);
129
+ body.extent.forEach(val => expect(typeof val).toBe('number'));
130
+
131
+ expect(body).toHaveProperty('files');
132
+ expect(Array.isArray(body.files)).toBe(true);
133
+ // Optional: check FileItem structure
134
+ if (body.files.length) {
135
+ const fileItem = body.files[0];
136
+ expect(fileItem).toHaveProperty('name');
137
+ expect(fileItem).toHaveProperty('size');
138
+ }
139
+
140
+ expect(body).toHaveProperty('width');
141
+ expect(typeof body.width).toBe('string');
142
+
143
+ expect(body).toHaveProperty('height');
144
+ expect(typeof body.height).toBe('string');
145
+
146
+ expect(body).toHaveProperty('bands_count');
147
+ expect(typeof body.bands_count).toBe('string');
148
+
149
+ expect(body).toHaveProperty('resolution');
150
+ expect(typeof body.resolution).toBe('string');
151
+
152
+ expect(body).toHaveProperty('bands');
153
+ expect(Array.isArray(body.bands)).toBe(true);
154
+ body.bands.forEach(b => expect(typeof b).toBe('string'));
155
+
156
+ expect(body).toHaveProperty('color_depth');
157
+ expect(typeof body.color_depth).toBe('string');
158
+
159
+ expect(body).toHaveProperty('compression');
160
+ expect(typeof body.compression).toBe('string');
161
+ });
162
+ });
163
+
164
+ describe('Create xml for all rasters without existing one', () => {
165
+ test('GET /gis-create-xml/:id? (restrict unauthorized)', async () => {
166
+ const res = await injectWithHeaders({
167
+ method: 'GET',
168
+ url: `/api/gis-create-xml`,
169
+ });
170
+ expect(res.statusCode).toBe(403);
171
+ });
172
+ test('GET /gis-create-xml/:id?', async () => {
173
+ const res = await injectWithHeaders({
174
+ method: 'GET',
175
+ url: `/api/gis-create-xml`,
176
+ headers: { uid: user.uid, user_type: user.type },
177
+ });
178
+ expect(res.statusCode).toBe(200);
179
+ expect(res.body).toBe('all finished');
180
+ });
181
+ });
182
+
183
+ describe('GIS File system API', () => {
184
+ test('lists directory (restrict unauthorized)', async () => {
185
+ const res = await injectWithHeaders({
186
+ method: 'GET',
187
+ url: '/api/gis-files',
188
+ });
189
+ expect(res.statusCode).toBe(403);
190
+ });
191
+
192
+ test('lists directory (restrict non-admin)', async () => {
193
+ const res = await injectWithHeaders({
194
+ method: 'GET',
195
+ url: '/api/gis-files',
196
+ headers: { uid: user.uid, user_type: 'regular' },
197
+ });
198
+ expect(res.statusCode).toBe(403);
199
+ });
200
+
201
+ test('lists directory', async () => {
202
+ const res = await injectWithHeaders({
203
+ method: 'GET',
204
+ url: '/api/gis-files',
205
+ headers: { uid: user.uid, user_type: user.type },
206
+ });
207
+ expect(res.statusCode).toBe(200);
208
+
209
+ const body = res.json();
210
+ expect(body).toHaveProperty('exists');
211
+ expect(body).toHaveProperty('count');
212
+ expect(body).toHaveProperty('data');
213
+ expect(Array.isArray(body.data)).toBe(true);
214
+ expect(body.data[0]).toHaveProperty('name');
215
+ expect(body.data[0]).toHaveProperty('type');
216
+ expect(body.data[0]).toHaveProperty('size');
217
+ });
218
+
219
+ test('search files by key (restrict unauthorized)', async () => {
220
+ const res = await injectWithHeaders({
221
+ method: 'GET',
222
+ url: '/api/gis-file-search?key=tif',
223
+ });
224
+ expect(res.statusCode).toBe(403);
225
+ });
226
+
227
+ test('search files by key (restrict non-admin)', async () => {
228
+ const res = await injectWithHeaders({
229
+ method: 'GET',
230
+ url: '/api/gis-file-search?key=tif',
231
+ headers: { uid: user.uid, user_type: 'regular' },
232
+ });
233
+ expect(res.statusCode).toBe(403);
234
+ });
235
+
236
+ test('search files by key', async () => {
237
+ const res = await injectWithHeaders({
238
+ method: 'GET',
239
+ url: '/api/gis-file-search?key=tif',
240
+ headers: { uid: user.uid, user_type: user.type },
241
+ });
242
+ expect(res.statusCode).toBe(200);
243
+
244
+ const body = res.json();
245
+
246
+ expect(Array.isArray(body.data)).toBe(true);
247
+ });
248
+
249
+ test('gets file info', async () => {
250
+ const res = await injectWithHeaders({
251
+ method: 'GET',
252
+ url: '/api/gis-file-search?key=tif',
253
+ headers: { uid: user.uid, user_type: user.type },
254
+ });
255
+ expect(res.statusCode).toBe(200);
256
+
257
+ const body1 = res.json();
258
+
259
+ const { dir, name: rasterName } = body1.data.find(el => el.name.endsWith('.tif'));
260
+ expect(rasterName).toBeTypeOf('string');
261
+ const rasterPath = [dir, rasterName].filter(Boolean).join('/');
262
+
263
+ // unauthorized
264
+ const res1 = await injectWithHeaders({
265
+ method: 'GET',
266
+ url: '/api/gis-file-info',
267
+ query: {
268
+ path: rasterPath
269
+ }
270
+ });
271
+ expect(res1.statusCode).toBe(403);
272
+
273
+ // non-admin
274
+ const res2 = await injectWithHeaders({
275
+ method: 'GET',
276
+ url: '/api/gis-file-info',
277
+ query: {
278
+ path: rasterPath
279
+ },
280
+ headers: { uid: user.uid, user_type: 'regular' },
281
+ });
282
+ expect(res2.statusCode).toBe(403);
283
+
284
+ const res3 = await injectWithHeaders({
285
+ method: 'GET',
286
+ url: '/api/gis-file-info',
287
+ query: {
288
+ path: rasterPath
289
+ },
290
+ headers: { uid: user.uid, user_type: user.type },
291
+ });
292
+ expect(res3.statusCode).toBe(200);
293
+
294
+ const body = res3.json().data;
295
+
296
+ expect(body).toHaveProperty('exists');
297
+ // expect(body.exists).toBeTruthy();
298
+ expect(body.exists).toBeOneOf([true, false]);
299
+ expect(body).toHaveProperty('size');
300
+ expect(body).toHaveProperty('mdate');
301
+ expect(body).toHaveProperty('adate');
302
+ expect(body).toHaveProperty('cdate');
303
+ expect(body).toHaveProperty('name');
304
+ });
305
+
306
+ test('search files by size', async () => {
307
+ const res = await injectWithHeaders({
308
+ method: 'GET',
309
+ url: '/api/gis-file-search?size=1024',
310
+ headers: { uid: user.uid, user_type: user.type },
311
+ });
312
+
313
+ expect(res.statusCode).toBe(200);
314
+ });
315
+
316
+ test('search files by period', async () => {
317
+ const res = await injectWithHeaders({
318
+ method: 'GET',
319
+ url: '/api/gis-file-search?period=1w',
320
+ headers: { uid: user.uid, user_type: user.type },
321
+ });
322
+
323
+ expect(res.statusCode).toBe(200);
324
+ });
325
+ });
326
+
327
+ test('GET /gis-pretile/:id', async () => {
328
+ // unaunthorized
329
+ const res1 = await injectWithHeaders({
330
+ method: 'GET',
331
+ url: `/api/gis-pretile/${testId}`,
332
+ query: { zoom: 13 }
333
+ });
334
+ expect(res1.statusCode).toBe(403);
335
+
336
+ const res = await injectWithHeaders({
337
+ method: 'GET',
338
+ url: `/api/gis-pretile/${testId}`,
339
+ query: { zoom: 13 },
340
+ headers: { uid: user.uid, user_type: user.type },
341
+ });
342
+ expect(res.statusCode).toBe(200);
343
+ expect(res.body).toBe('OK');
344
+ });
345
+
346
+ test('GET /gis-clear-rtile/:id', async () => {
347
+ // unaunthorized
348
+ const res1 = await injectWithHeaders({
349
+ method: 'GET',
350
+ url: `/api/gis-clear-rtile/${testId}`,
351
+ });
352
+ expect(res1.statusCode).toBe(403);
353
+
354
+ // non-admin
355
+ const res2 = await injectWithHeaders({
356
+ method: 'GET',
357
+ url: `/api/gis-clear-rtile/${testId}`,
358
+ headers: { uid: user.uid, user_type: 'regular' },
359
+ });
360
+ expect(res2.statusCode).toBe(403);
361
+
362
+ const res = await injectWithHeaders({
363
+ method: 'GET',
364
+ url: `/api/gis-clear-rtile/${testId}`,
365
+ headers: { uid: user.uid, user_type: user.type },
366
+ });
367
+ const body = res.json();
368
+
369
+ expect(['ok', 'skip', 'tiles directory not found']).toContain(body.message);
370
+
371
+ });
@@ -0,0 +1,190 @@
1
+ const dirpathSchema = { type: "string", pattern: "^[а-яА-Яa-zA-Z0-9_/\\- ]+$" };
2
+ const filepathSchema = { type: "string", pattern: "^[а-яА-Яa-zA-Z0-9_\/\\-\. ]+$" };
3
+
4
+ // values hardcoded into mapnik
5
+ const periodSchema = {
6
+ type: 'string', enum: ['1w', '1d', '1h', '5m', '1m']
7
+ };
8
+
9
+ export const pretileSchema = {
10
+ params: {
11
+ type: "object",
12
+ properties: {
13
+ id: { type: "string", pattern: '^([\\d\\w]+)$', },
14
+ },
15
+ required: ["id"],
16
+ },
17
+ querystring: {
18
+ type: "object",
19
+ additionalProperties: false,
20
+ properties: {
21
+ zoom: { type: "number", exclusiveMinimum: 0, maximum: 22 },
22
+ max: { type: "number", exclusiveMinimum: 0, maximum: 22 },
23
+ },
24
+ required: ["zoom"],
25
+ },
26
+ };
27
+
28
+ export const uploadRasterSchema = {
29
+ params: {
30
+ type: "object",
31
+ properties: {
32
+ id: { type: "string", pattern: '^([\\d\\w]+)$', },
33
+ },
34
+ required: ["id"],
35
+ },
36
+ }
37
+
38
+ export const gisXmlSchema = {
39
+ params: {
40
+ type: "object",
41
+ properties: {
42
+ id: { type: "string", pattern: '^([\\d\\w]+)$', },
43
+ },
44
+ required: ["id"],
45
+ },
46
+ querystring: {
47
+ type: "object",
48
+ additionalProperties: false,
49
+ properties: {
50
+ sql: { type: "number", minimum: 1, maximum: 1 },
51
+ nocache: { type: "string", enum: ['true', '1'] },
52
+ vrt: { type: "string", enum: ['true', '1'] },
53
+ debug: { type: "number", minimum: 1, maximum: 10 },
54
+ },
55
+ },
56
+ };
57
+
58
+ export const gisRtileSchema = {
59
+ params: {
60
+ type: "object",
61
+ properties: {
62
+ id: { type: "string", pattern: '^([\\d\\w]+)$', },
63
+ z: {
64
+ type: 'number',
65
+ },
66
+ y: {
67
+ type: 'number',
68
+ },
69
+ x: {
70
+ type: 'string',
71
+ pattern: '^\\d+\\.(png|webp)$',
72
+ },
73
+ },
74
+ required: ["id", "z", "y", "x"],
75
+ },
76
+ querystring: {
77
+ type: "object",
78
+ additionalProperties: false,
79
+ properties: {
80
+ nocache: {
81
+ type: 'string', enum: ['1']
82
+ },
83
+ nottl: {
84
+ type: 'string', enum: ['1']
85
+ },
86
+ debug: {
87
+ type: 'number', minimum: 1, maximum: 10
88
+ },
89
+ // random from frontend
90
+ ts: {
91
+ type: 'string'
92
+ },
93
+ },
94
+ },
95
+ };
96
+
97
+ export const gisRasterSchema = {
98
+ params: {
99
+ type: "object",
100
+ properties: {
101
+ id: { type: "string", pattern: '^([\\d\\w]+)$', },
102
+ },
103
+ required: ["id"],
104
+ },
105
+ querystring: {
106
+ type: "object",
107
+ additionalProperties: false,
108
+ properties: {
109
+ debug: { type: "number", minimum: 1, maximum: 10 },
110
+ },
111
+ },
112
+ };
113
+
114
+ export const createXmlMultiSchema = {
115
+ params: {
116
+ type: "object",
117
+ properties: {
118
+ id: { type: "string", pattern: '^([\\d\\w]+)$', },
119
+ },
120
+ },
121
+ querystring: {
122
+ type: "object",
123
+ additionalProperties: false,
124
+ properties: {
125
+ nocache: { type: "number", enum: [1] },
126
+ },
127
+ },
128
+ };
129
+
130
+ export const readDirSchema = {
131
+ querystring: {
132
+ type: "object",
133
+ additionalProperties: false,
134
+ properties: {
135
+ dir: dirpathSchema,
136
+ },
137
+ },
138
+ };
139
+
140
+ export const fileStatSchema = {
141
+ querystring: {
142
+ type: "object",
143
+ additionalProperties: false,
144
+ required: ['path'],
145
+ properties: {
146
+ path: filepathSchema,
147
+ },
148
+ },
149
+ };
150
+
151
+ export const fileSearchSchema = {
152
+ querystring: {
153
+ type: "object",
154
+ additionalProperties: false,
155
+ properties: {
156
+ dir: dirpathSchema,
157
+ key: {
158
+ type: 'string', // filename
159
+ },
160
+ period: periodSchema,
161
+ size: {
162
+ type: 'number', minimum: 1
163
+ },
164
+ page: {
165
+ type: 'number', minimum: 1
166
+ },
167
+ limit: {
168
+ type: 'number', minimum: 1, maximum: 100
169
+ }
170
+ },
171
+ },
172
+ };
173
+
174
+ export const clearTilesSchema = {
175
+ params: {
176
+ type: "object",
177
+ properties: {
178
+ id: { type: "string", pattern: '^([\\d\\w]+)$', },
179
+ },
180
+ },
181
+ querystring: {
182
+ type: "object",
183
+ additionalProperties: false,
184
+ properties: {
185
+ debug: { type: "number", minimum: 1, maximum: 10 },
186
+ },
187
+ },
188
+ };
189
+
190
+ export default null;
@@ -0,0 +1,31 @@
1
+ import { config } from '@opengis/fastify-table/utils.js';
2
+ import { BadRequestError, NotImplementedError } from '@opengis/fastify-table/errors.js';
3
+
4
+ import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
5
+
6
+ export default async function mapnikLogger({
7
+ path: paramsPath,
8
+ }) {
9
+ if (!config.mapnik?.server) {
10
+ throw NotImplementedError('mapnik server address needed');
11
+ }
12
+
13
+ const { GetLogs } = mapnik();
14
+ const { data, links, err } = await GetLogs({ path: paramsPath });
15
+
16
+ if (err) {
17
+ throw BadRequestError(err);
18
+ }
19
+
20
+ if (links) {
21
+ return {
22
+ headers: {
23
+ "Content-Type": "text/html; charset=UTF-8",
24
+ "Content-Security-Policy": "default-src 'none'",
25
+ "X-Content-Type-Options": "nosniff",
26
+ }, data: links.replace(/\/api\/gis-logger/g, '/logger-gis')
27
+ };
28
+ }
29
+
30
+ return { headers: { "Content-type": "text/plain; charset=UTF-8" }, data };
31
+ }
@@ -1,19 +1,21 @@
1
1
  import { config } from '@opengis/fastify-table/utils.js';
2
2
 
3
+ import { NotImplementedError } from '@opengis/fastify-table/errors.js';
4
+
3
5
  import mapnik from '../../../plugins/mapnik/funcs/mapnik.js';
4
6
 
5
7
  const { GetStat } = mapnik();
6
8
 
7
9
  export default async function mapnikStat({
8
- params,
9
- }, reply) {
10
+ period,
11
+ }) {
10
12
  if (!config.mapnik?.server) {
11
- return reply.status(400).send({ error: 'mapnik server address needed', code: 400 });
13
+ throw NotImplementedError('mapnik server address needed');
12
14
  }
13
15
 
14
16
  const stat = await GetStat({
15
- period: params.period,
17
+ period,
16
18
  });
17
19
 
18
- return reply.status(200).send(stat);
20
+ return stat;
19
21
  }
@@ -0,0 +1,20 @@
1
+ import mapnikLogger from './functions/mapnikLogger.js';
2
+ import mapnikStat from './functions/mapnikStat.js';
3
+
4
+ import {
5
+ mapnikLoggerSchema,
6
+ mapnikStatSchema,
7
+ } from './mapnik.prefixless.schema.mjs';
8
+
9
+ const adminParams = { config: { role: 'admin' }, package: 'gis' };
10
+
11
+ export default function route(app) {
12
+ app.get('/logger-gis/stat', { ...adminParams, schema: mapnikStatSchema }, async ({ query }) => {
13
+ const result = await mapnikStat({ period: query.period });
14
+ return result;
15
+ });
16
+ app.get('/logger-gis/*', { ...adminParams, schema: mapnikLoggerSchema }, async ({ params }, reply) => {
17
+ const result = await mapnikLogger({ path: params['*'] });
18
+ return reply.headers(result.headers).send(result.data);
19
+ });
20
+ }