geoserver-node-client 0.0.5 → 1.0.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/LICENSE +25 -0
- package/README.md +81 -9
- package/dist/geoserver-rest-client.js +87 -0
- package/dist/package.json +55 -0
- package/dist/src/about.js +145 -0
- package/dist/src/datastore.js +1050 -0
- package/dist/src/imagemosaic.js +297 -0
- package/dist/src/layer.js +1040 -0
- package/dist/src/namespace.js +315 -0
- package/dist/src/security.js +297 -0
- package/dist/src/settings.js +345 -0
- package/dist/src/style.js +597 -0
- package/dist/src/util/geoserver.js +97 -0
- package/dist/src/workspace.js +321 -0
- package/geoserver-rest-client.js +15 -52
- package/package.json +28 -10
- package/src/about.js +59 -0
- package/src/datastore.js +161 -200
- package/src/imagemosaic.js +74 -97
- package/src/layer.js +376 -332
- package/src/namespace.js +84 -83
- package/src/security.js +61 -84
- package/src/settings.js +76 -91
- package/src/style.js +200 -147
- package/src/util/geoserver.js +41 -0
- package/src/workspace.js +89 -81
- package/.eslintrc.json +0 -20
- package/.github/workflows/ci-geoserver-node-client.yml +0 -54
- package/.github/workflows/ci-publish-docs.yml +0 -24
- package/.github/workflows/wait-for.sh +0 -145
- package/DOCS_HOME.md +0 -24
- package/demo/index.js +0 -188
- package/release-it.json +0 -8
- package/test/sample_data/iceland.gpkg +0 -0
- package/test/sample_data/world.geotiff +0 -0
- package/test/test.js +0 -491
package/src/layer.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import fetch from 'node-fetch';
|
|
2
|
+
import { getGeoServerResponseText, GeoServerResponseError } from './util/geoserver.js';
|
|
3
|
+
import AboutClient from './about.js'
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Client for GeoServer layers
|
|
@@ -10,116 +12,125 @@ export default class LayerClient {
|
|
|
10
12
|
* Creates a GeoServer REST LayerClient instance.
|
|
11
13
|
*
|
|
12
14
|
* @param {String} url The URL of the GeoServer REST API endpoint
|
|
13
|
-
* @param {String}
|
|
14
|
-
* @param {String} password The password for the GeoServer REST API
|
|
15
|
+
* @param {String} auth The Basic Authentication string
|
|
15
16
|
*/
|
|
16
|
-
constructor (url,
|
|
17
|
-
this.url = url
|
|
18
|
-
this.
|
|
19
|
-
this.password = password;
|
|
17
|
+
constructor (url, auth) {
|
|
18
|
+
this.url = url;
|
|
19
|
+
this.auth = auth;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* Returns a GeoServer layer by the given
|
|
23
|
+
* Returns a GeoServer layer by the given workspace and layer name,
|
|
24
24
|
* e.g. "myWs:myLayer".
|
|
25
25
|
*
|
|
26
|
-
* @param {String}
|
|
26
|
+
* @param {String} workspace The name of the workspace, can be undefined
|
|
27
|
+
* @param {String} layerName The name of the layer to query
|
|
27
28
|
*
|
|
28
|
-
* @
|
|
29
|
+
* @throws Error if request fails
|
|
30
|
+
*
|
|
31
|
+
* @returns {Object} An object with layer information or undefined if it cannot be found
|
|
29
32
|
*/
|
|
30
|
-
async get (
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
async get (workspace, layerName) {
|
|
34
|
+
let qualifiedName;
|
|
35
|
+
if (workspace) {
|
|
36
|
+
qualifiedName = `${workspace}:${layerName}`;
|
|
37
|
+
} else {
|
|
38
|
+
qualifiedName = layerName;
|
|
39
|
+
}
|
|
40
|
+
const response = await fetch(this.url + 'layers/' + qualifiedName + '.json', {
|
|
41
|
+
credentials: 'include',
|
|
42
|
+
method: 'GET',
|
|
43
|
+
headers: {
|
|
44
|
+
Authorization: this.auth
|
|
45
|
+
}
|
|
46
|
+
});
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
const grc = new AboutClient(this.url, this.auth);
|
|
50
|
+
if (await grc.exists()) {
|
|
51
|
+
// GeoServer exists, but requested item does not exist, we return empty
|
|
52
|
+
return;
|
|
43
53
|
} else {
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
// There was a general problem with GeoServer
|
|
55
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
56
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
46
57
|
}
|
|
47
|
-
} catch (error) {
|
|
48
|
-
return false;
|
|
49
58
|
}
|
|
59
|
+
return response.json();
|
|
50
60
|
}
|
|
51
61
|
|
|
52
62
|
/**
|
|
53
63
|
* Sets the attribution text and link of a layer.
|
|
54
64
|
*
|
|
55
|
-
* @param {String}
|
|
65
|
+
* @param {String} workspace The name of the workspace, can be undefined
|
|
66
|
+
* @param {String} layerName The name of the layer to query
|
|
56
67
|
* @param {String} [attributionText] The attribution text
|
|
57
68
|
* @param {String} [attributionLink] The attribution link
|
|
58
69
|
*
|
|
59
|
-
* @
|
|
70
|
+
* @throws Error if request fails
|
|
60
71
|
*/
|
|
61
|
-
async modifyAttribution (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (attributionLink) {
|
|
71
|
-
jsonBody.layer.attribution.href = attributionLink;
|
|
72
|
-
}
|
|
72
|
+
async modifyAttribution (workspace, layerName, attributionText, attributionLink) {
|
|
73
|
+
let qualifiedName;
|
|
74
|
+
if (workspace) {
|
|
75
|
+
qualifiedName = `${workspace}:${layerName}`;
|
|
76
|
+
} else {
|
|
77
|
+
qualifiedName = layerName;
|
|
78
|
+
}
|
|
79
|
+
// take existing layer properties as template
|
|
80
|
+
const jsonBody = await this.get(workspace, layerName);
|
|
73
81
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
82
|
+
if (!jsonBody || !jsonBody.layer || !jsonBody.layer.attribution) {
|
|
83
|
+
throw new GeoServerResponseError(
|
|
84
|
+
`layer '${workspace}:${layerName}' misses the property 'attribution'`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// set attribution text and link
|
|
89
|
+
if (attributionText) {
|
|
90
|
+
jsonBody.layer.attribution.title = attributionText;
|
|
91
|
+
}
|
|
92
|
+
if (attributionLink) {
|
|
93
|
+
jsonBody.layer.attribution.href = attributionLink;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const url = this.url + 'layers/' + qualifiedName + '.json';
|
|
97
|
+
const response = await fetch(url, {
|
|
98
|
+
credentials: 'include',
|
|
99
|
+
method: 'PUT',
|
|
100
|
+
headers: {
|
|
101
|
+
Authorization: this.auth,
|
|
102
|
+
'Content-Type': 'application/json'
|
|
103
|
+
},
|
|
104
|
+
body: JSON.stringify(jsonBody)
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
109
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
95
110
|
}
|
|
96
111
|
}
|
|
97
112
|
|
|
98
113
|
/**
|
|
99
114
|
* Returns all layers in the GeoServer.
|
|
100
115
|
*
|
|
101
|
-
* @
|
|
116
|
+
* @throws Error if request fails
|
|
117
|
+
*
|
|
118
|
+
* @returns {Object} An object with all layer information
|
|
102
119
|
*/
|
|
103
120
|
async getAll () {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
headers: {
|
|
110
|
-
Authorization: 'Basic ' + auth
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
if (response.status === 200) {
|
|
115
|
-
return await response.json();
|
|
116
|
-
} else {
|
|
117
|
-
console.warn(await response.text());
|
|
118
|
-
return false;
|
|
121
|
+
const response = await fetch(this.url + 'layers.json', {
|
|
122
|
+
credentials: 'include',
|
|
123
|
+
method: 'GET',
|
|
124
|
+
headers: {
|
|
125
|
+
Authorization: this.auth
|
|
119
126
|
}
|
|
120
|
-
}
|
|
121
|
-
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
if (!response.ok) {
|
|
130
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
131
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
122
132
|
}
|
|
133
|
+
return response.json();
|
|
123
134
|
}
|
|
124
135
|
|
|
125
136
|
/**
|
|
@@ -133,40 +144,33 @@ export default class LayerClient {
|
|
|
133
144
|
* @param {String} enabled Flag to enable FeatureType by default
|
|
134
145
|
* @param {String} [abstract] The abstract of the layer
|
|
135
146
|
*
|
|
136
|
-
* @
|
|
147
|
+
* @throws Error if request fails
|
|
137
148
|
*/
|
|
138
149
|
async publishFeatureTypeDefaultDataStore (workspace, nativeName, name, title, srs, enabled, abstract) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
abstract: abstract || ''
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const auth = Buffer.from(this.user + ':' + this.password).toString('base64');
|
|
152
|
-
const response = await fetch(this.url + 'workspaces/' + workspace + '/featuretypes', {
|
|
153
|
-
credentials: 'include',
|
|
154
|
-
method: 'POST',
|
|
155
|
-
headers: {
|
|
156
|
-
Authorization: 'Basic ' + auth,
|
|
157
|
-
'Content-Type': 'application/json'
|
|
158
|
-
},
|
|
159
|
-
body: JSON.stringify(body)
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
if (response.status === 201) {
|
|
163
|
-
return true;
|
|
164
|
-
} else {
|
|
165
|
-
console.warn(await response.text());
|
|
166
|
-
return false;
|
|
150
|
+
const body = {
|
|
151
|
+
featureType: {
|
|
152
|
+
name: name,
|
|
153
|
+
nativeName: nativeName || name,
|
|
154
|
+
title: title || name,
|
|
155
|
+
srs: srs || 'EPSG:4326',
|
|
156
|
+
enabled: enabled,
|
|
157
|
+
abstract: abstract || ''
|
|
167
158
|
}
|
|
168
|
-
}
|
|
169
|
-
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const response = await fetch(this.url + 'workspaces/' + workspace + '/featuretypes', {
|
|
162
|
+
credentials: 'include',
|
|
163
|
+
method: 'POST',
|
|
164
|
+
headers: {
|
|
165
|
+
Authorization: this.auth,
|
|
166
|
+
'Content-Type': 'application/json'
|
|
167
|
+
},
|
|
168
|
+
body: JSON.stringify(body)
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
if (!response.ok) {
|
|
172
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
173
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
170
174
|
}
|
|
171
175
|
}
|
|
172
176
|
|
|
@@ -183,50 +187,78 @@ export default class LayerClient {
|
|
|
183
187
|
* @param {String} [abstract] The abstract of the layer
|
|
184
188
|
* @param {String} [nativeBoundingBox] The native BoundingBox of the FeatureType (has to be set if no data is in store at creation time)
|
|
185
189
|
*
|
|
186
|
-
* @
|
|
190
|
+
* @throws Error if request fails
|
|
187
191
|
*/
|
|
188
192
|
async publishFeatureType (workspace, dataStore, nativeName, name, title, srs, enabled, abstract, nativeBoundingBox) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
$: srs
|
|
195
|
-
}
|
|
193
|
+
// apply CRS info for native BBOX if not provided
|
|
194
|
+
if (nativeBoundingBox && !nativeBoundingBox.crs) {
|
|
195
|
+
nativeBoundingBox.crs = {
|
|
196
|
+
'@class': 'projected',
|
|
197
|
+
$: srs
|
|
196
198
|
}
|
|
199
|
+
}
|
|
197
200
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
201
|
+
const body = {
|
|
202
|
+
featureType: {
|
|
203
|
+
name: name || nativeName,
|
|
204
|
+
nativeName: nativeName,
|
|
205
|
+
title: title || name,
|
|
206
|
+
srs: srs || 'EPSG:4326',
|
|
207
|
+
enabled: enabled,
|
|
208
|
+
abstract: abstract || '',
|
|
209
|
+
nativeBoundingBox: nativeBoundingBox
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const response = await fetch(this.url + 'workspaces/' + workspace + '/datastores/' + dataStore + '/featuretypes', {
|
|
214
|
+
credentials: 'include',
|
|
215
|
+
method: 'POST',
|
|
216
|
+
headers: {
|
|
217
|
+
Authorization: this.auth,
|
|
218
|
+
'Content-Type': 'application/json'
|
|
219
|
+
},
|
|
220
|
+
body: JSON.stringify(body)
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
if (!response.ok) {
|
|
224
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
225
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Get detailed information about a FeatureType.
|
|
231
|
+
*
|
|
232
|
+
* @param {String} workspace The workspace of the FeatureType
|
|
233
|
+
* @param {String} datastore The datastore of the FeatureType
|
|
234
|
+
* @param {String} name The name of the FeatureType
|
|
235
|
+
*
|
|
236
|
+
* @throws Error if request fails
|
|
237
|
+
*
|
|
238
|
+
* @returns {Object} The object of the FeatureType
|
|
239
|
+
*/
|
|
240
|
+
async getFeatureType (workspace, datastore, name) {
|
|
241
|
+
const url = this.url + 'workspaces/' + workspace + '/datastores/' + datastore + '/featuretypes/' + name + '.json';
|
|
242
|
+
const response = await fetch(url, {
|
|
243
|
+
credentials: 'include',
|
|
244
|
+
method: 'GET',
|
|
245
|
+
headers: {
|
|
246
|
+
Authorization: this.auth
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
if (!response.ok) {
|
|
251
|
+
const grc = new AboutClient(this.url, this.auth);
|
|
252
|
+
if (await grc.exists()) {
|
|
253
|
+
// GeoServer exists, but requested item does not exist, we return empty
|
|
254
|
+
return;
|
|
223
255
|
} else {
|
|
224
|
-
|
|
225
|
-
|
|
256
|
+
// There was a general problem with GeoServer
|
|
257
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
258
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
226
259
|
}
|
|
227
|
-
} catch (error) {
|
|
228
|
-
return false;
|
|
229
260
|
}
|
|
261
|
+
return response.json();
|
|
230
262
|
}
|
|
231
263
|
|
|
232
264
|
/**
|
|
@@ -241,40 +273,33 @@ export default class LayerClient {
|
|
|
241
273
|
* @param {String} enabled Flag to enable WMS layer by default
|
|
242
274
|
* @param {String} [abstract] The abstract of the layer
|
|
243
275
|
*
|
|
244
|
-
* @
|
|
276
|
+
* @throws Error if request fails
|
|
245
277
|
*/
|
|
246
278
|
async publishWmsLayer (workspace, dataStore, nativeName, name, title, srs, enabled, abstract) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
abstract: abstract || ''
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
const auth = Buffer.from(this.user + ':' + this.password).toString('base64');
|
|
260
|
-
const response = await fetch(this.url + 'workspaces/' + workspace + '/wmsstores/' + dataStore + '/wmslayers', {
|
|
261
|
-
credentials: 'include',
|
|
262
|
-
method: 'POST',
|
|
263
|
-
headers: {
|
|
264
|
-
Authorization: 'Basic ' + auth,
|
|
265
|
-
'Content-Type': 'application/json'
|
|
266
|
-
},
|
|
267
|
-
body: JSON.stringify(body)
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
if (response.status === 201) {
|
|
271
|
-
return true;
|
|
272
|
-
} else {
|
|
273
|
-
console.warn(await response.text());
|
|
274
|
-
return false;
|
|
279
|
+
const body = {
|
|
280
|
+
wmsLayer: {
|
|
281
|
+
name: name || nativeName,
|
|
282
|
+
nativeName: nativeName,
|
|
283
|
+
title: title || name || nativeName,
|
|
284
|
+
srs: srs || 'EPSG:4326',
|
|
285
|
+
enabled: enabled,
|
|
286
|
+
abstract: abstract || ''
|
|
275
287
|
}
|
|
276
|
-
}
|
|
277
|
-
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const response = await fetch(this.url + 'workspaces/' + workspace + '/wmsstores/' + dataStore + '/wmslayers', {
|
|
291
|
+
credentials: 'include',
|
|
292
|
+
method: 'POST',
|
|
293
|
+
headers: {
|
|
294
|
+
Authorization: this.auth,
|
|
295
|
+
'Content-Type': 'application/json'
|
|
296
|
+
},
|
|
297
|
+
body: JSON.stringify(body)
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
if (!response.ok) {
|
|
301
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
302
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
278
303
|
}
|
|
279
304
|
}
|
|
280
305
|
|
|
@@ -290,39 +315,33 @@ export default class LayerClient {
|
|
|
290
315
|
* @param {String} enabled Flag to enable layer by default
|
|
291
316
|
* @param {String} [abstract] The abstract of the layer
|
|
292
317
|
*
|
|
293
|
-
* @
|
|
318
|
+
* @throws Error if request fails
|
|
294
319
|
*/
|
|
295
320
|
async publishDbRaster (workspace, coverageStore, nativeName, name, title, srs, enabled, abstract) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
abstract: abstract || ''
|
|
305
|
-
}
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
const auth = Buffer.from(this.user + ':' + this.password).toString('base64');
|
|
309
|
-
const response = await fetch(this.url + 'workspaces/' + workspace + '/coveragestores/' + coverageStore + '/coverages', {
|
|
310
|
-
credentials: 'include',
|
|
311
|
-
method: 'POST',
|
|
312
|
-
headers: {
|
|
313
|
-
Authorization: 'Basic ' + auth,
|
|
314
|
-
'Content-Type': 'application/json'
|
|
315
|
-
},
|
|
316
|
-
body: JSON.stringify(body)
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
if (response.status === 201) {
|
|
320
|
-
return true;
|
|
321
|
-
} else {
|
|
322
|
-
return false;
|
|
321
|
+
const body = {
|
|
322
|
+
coverage: {
|
|
323
|
+
name: name || nativeName,
|
|
324
|
+
nativeName: nativeName,
|
|
325
|
+
title: title || name,
|
|
326
|
+
srs: srs,
|
|
327
|
+
enabled: enabled,
|
|
328
|
+
abstract: abstract || ''
|
|
323
329
|
}
|
|
324
|
-
}
|
|
325
|
-
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const response = await fetch(this.url + 'workspaces/' + workspace + '/coveragestores/' + coverageStore + '/coverages', {
|
|
333
|
+
credentials: 'include',
|
|
334
|
+
method: 'POST',
|
|
335
|
+
headers: {
|
|
336
|
+
Authorization: this.auth,
|
|
337
|
+
'Content-Type': 'application/json'
|
|
338
|
+
},
|
|
339
|
+
body: JSON.stringify(body)
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
if (!response.ok) {
|
|
343
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
344
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
326
345
|
}
|
|
327
346
|
}
|
|
328
347
|
|
|
@@ -334,27 +353,20 @@ export default class LayerClient {
|
|
|
334
353
|
* @param {String} name Layer to delete
|
|
335
354
|
* @param {Boolean} recurse Flag to enable recursive deletion
|
|
336
355
|
*
|
|
337
|
-
* @
|
|
356
|
+
* @throws Error if request fails
|
|
338
357
|
*/
|
|
339
358
|
async deleteFeatureType (workspace, datastore, name, recurse) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
headers: {
|
|
346
|
-
Authorization: 'Basic ' + auth
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
if (response.status === 200) {
|
|
351
|
-
return true;
|
|
352
|
-
} else {
|
|
353
|
-
console.warn(await response.text());
|
|
354
|
-
return false;
|
|
359
|
+
const response = await fetch(this.url + 'workspaces/' + workspace + '/datastores/' + datastore + '/featuretypes/' + name + '?recurse=' + recurse, {
|
|
360
|
+
credentials: 'include',
|
|
361
|
+
method: 'DELETE',
|
|
362
|
+
headers: {
|
|
363
|
+
Authorization: this.auth
|
|
355
364
|
}
|
|
356
|
-
}
|
|
357
|
-
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
if (!response.ok) {
|
|
368
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
369
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
358
370
|
}
|
|
359
371
|
}
|
|
360
372
|
|
|
@@ -371,56 +383,46 @@ export default class LayerClient {
|
|
|
371
383
|
* @param {Boolean} [rawNearestMatchEnabled] Enable raw nearest match
|
|
372
384
|
* @param {String} [acceptableInterval] Acceptable interval for nearest match, e.g.'PT30M'
|
|
373
385
|
*
|
|
374
|
-
* @
|
|
386
|
+
* @throws Error if request fails
|
|
375
387
|
*/
|
|
376
388
|
async enableTimeCoverage (workspace, dataStore, name, presentation, resolution, defaultValue, nearestMatchEnabled, rawNearestMatchEnabled, acceptableInterval) {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
rawNearestMatchEnabled: rawNearestMatchEnabled,
|
|
394
|
-
acceptableInterval: acceptableInterval
|
|
395
|
-
}
|
|
389
|
+
const body = {
|
|
390
|
+
coverage: {
|
|
391
|
+
metadata: {
|
|
392
|
+
entry: [
|
|
393
|
+
{
|
|
394
|
+
'@key': 'time',
|
|
395
|
+
dimensionInfo: {
|
|
396
|
+
presentation: presentation || 'DISCRETE_INTERVAL',
|
|
397
|
+
resolution: resolution,
|
|
398
|
+
units: 'ISO8601',
|
|
399
|
+
defaultValue: {
|
|
400
|
+
strategy: defaultValue
|
|
401
|
+
},
|
|
402
|
+
nearestMatchEnabled: nearestMatchEnabled,
|
|
403
|
+
rawNearestMatchEnabled: rawNearestMatchEnabled,
|
|
404
|
+
acceptableInterval: acceptableInterval
|
|
396
405
|
}
|
|
397
|
-
|
|
398
|
-
|
|
406
|
+
}
|
|
407
|
+
]
|
|
399
408
|
}
|
|
400
|
-
};
|
|
401
|
-
|
|
402
|
-
const auth = Buffer.from(this.user + ':' + this.password).toString('base64');
|
|
403
|
-
const url = this.url + 'workspaces/' + workspace + '/coveragestores/' + dataStore + '/coverages/' + name + '.json';
|
|
404
|
-
console.log(url);
|
|
405
|
-
const response = await fetch(url, {
|
|
406
|
-
credentials: 'include',
|
|
407
|
-
method: 'PUT',
|
|
408
|
-
headers: {
|
|
409
|
-
Authorization: 'Basic ' + auth,
|
|
410
|
-
'Content-Type': 'application/json'
|
|
411
|
-
},
|
|
412
|
-
body: JSON.stringify(body)
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
if (response.status === 200) {
|
|
416
|
-
return true;
|
|
417
|
-
} else {
|
|
418
|
-
console.warn(await response.text());
|
|
419
|
-
return false;
|
|
420
409
|
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
const url = this.url + 'workspaces/' + workspace + '/coveragestores/' + dataStore + '/coverages/' + name + '.json';
|
|
413
|
+
const response = await fetch(url, {
|
|
414
|
+
credentials: 'include',
|
|
415
|
+
method: 'PUT',
|
|
416
|
+
headers: {
|
|
417
|
+
Authorization: this.auth,
|
|
418
|
+
'Content-Type': 'application/json'
|
|
419
|
+
},
|
|
420
|
+
body: JSON.stringify(body)
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
if (!response.ok) {
|
|
424
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
425
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
424
426
|
}
|
|
425
427
|
}
|
|
426
428
|
|
|
@@ -436,57 +438,48 @@ export default class LayerClient {
|
|
|
436
438
|
* @param {String} defaultValue The default time value, e.g. 'MINIMUM' or 'MAXIMUM' or 'NEAREST' or 'FIXED'
|
|
437
439
|
* @param {Boolean} [nearestMatchEnabled] Enable nearest match
|
|
438
440
|
* @param {Boolean} [rawNearestMatchEnabled] Enable raw nearest match
|
|
439
|
-
* @param {String} [acceptableInterval] Tolerance interval for nearest mach (e.g. 'PT30M'), only has an effect if 'nearestMatchEnabled' is true
|
|
440
441
|
*
|
|
441
|
-
* @
|
|
442
|
+
* @throws Error if request fails
|
|
442
443
|
*/
|
|
443
444
|
async enableTimeFeatureType (workspace, dataStore, name, attribute, presentation, resolution, defaultValue, nearestMatchEnabled, rawNearestMatchEnabled, acceptableInterval) {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
rawNearestMatchEnabled: rawNearestMatchEnabled,
|
|
462
|
-
acceptableInterval: acceptableInterval
|
|
463
|
-
}
|
|
445
|
+
const body = {
|
|
446
|
+
featureType: {
|
|
447
|
+
metadata: {
|
|
448
|
+
entry: [
|
|
449
|
+
{
|
|
450
|
+
'@key': 'time',
|
|
451
|
+
dimensionInfo: {
|
|
452
|
+
attribute: attribute,
|
|
453
|
+
presentation: presentation,
|
|
454
|
+
resolution: resolution,
|
|
455
|
+
units: 'ISO8601',
|
|
456
|
+
defaultValue: {
|
|
457
|
+
strategy: defaultValue
|
|
458
|
+
},
|
|
459
|
+
nearestMatchEnabled: nearestMatchEnabled,
|
|
460
|
+
rawNearestMatchEnabled: rawNearestMatchEnabled,
|
|
461
|
+
acceptableInterval: acceptableInterval
|
|
464
462
|
}
|
|
465
|
-
|
|
466
|
-
|
|
463
|
+
}
|
|
464
|
+
]
|
|
467
465
|
}
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
const auth = Buffer.from(this.user + ':' + this.password).toString('base64');
|
|
471
|
-
const url = this.url + 'workspaces/' + workspace + '/datastores/' + dataStore + '/featuretypes/' + name + '.json';
|
|
472
|
-
const response = await fetch(url, {
|
|
473
|
-
credentials: 'include',
|
|
474
|
-
method: 'PUT',
|
|
475
|
-
headers: {
|
|
476
|
-
Authorization: 'Basic ' + auth,
|
|
477
|
-
'Content-Type': 'application/json'
|
|
478
|
-
},
|
|
479
|
-
body: JSON.stringify(body)
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
if (response.status === 200) {
|
|
483
|
-
return true;
|
|
484
|
-
} else {
|
|
485
|
-
console.warn(await response.text());
|
|
486
|
-
return false;
|
|
487
466
|
}
|
|
488
|
-
}
|
|
489
|
-
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
const url = this.url + 'workspaces/' + workspace + '/datastores/' + dataStore + '/featuretypes/' + name + '.json';
|
|
470
|
+
const response = await fetch(url, {
|
|
471
|
+
credentials: 'include',
|
|
472
|
+
method: 'PUT',
|
|
473
|
+
headers: {
|
|
474
|
+
Authorization: this.auth,
|
|
475
|
+
'Content-Type': 'application/json'
|
|
476
|
+
},
|
|
477
|
+
body: JSON.stringify(body)
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
if (!response.ok) {
|
|
481
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
482
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
490
483
|
}
|
|
491
484
|
}
|
|
492
485
|
|
|
@@ -497,28 +490,79 @@ export default class LayerClient {
|
|
|
497
490
|
* @param {String} coverageStore The coveragestore containing the coverage
|
|
498
491
|
* @param {String} name Coverage to query
|
|
499
492
|
*
|
|
500
|
-
* @
|
|
493
|
+
* @throws Error if request fails
|
|
494
|
+
*
|
|
495
|
+
* @returns {Object} An object with coverage information or undefined if it cannot be found
|
|
501
496
|
*/
|
|
502
497
|
async getCoverage (workspace, coverageStore, name) {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
}
|
|
512
|
-
});
|
|
498
|
+
const url = this.url + 'workspaces/' + workspace + '/coveragestores/' + coverageStore + '/coverages/' + name + '.json';
|
|
499
|
+
const response = await fetch(url, {
|
|
500
|
+
credentials: 'include',
|
|
501
|
+
method: 'GET',
|
|
502
|
+
headers: {
|
|
503
|
+
Authorization: this.auth
|
|
504
|
+
}
|
|
505
|
+
});
|
|
513
506
|
|
|
514
|
-
|
|
515
|
-
|
|
507
|
+
if (!response.ok) {
|
|
508
|
+
const grc = new AboutClient(this.url, this.auth);
|
|
509
|
+
if (await grc.exists()) {
|
|
510
|
+
// GeoServer exists, but requested item does not exist, we return empty
|
|
511
|
+
return;
|
|
516
512
|
} else {
|
|
517
|
-
|
|
518
|
-
|
|
513
|
+
// There was a general problem with GeoServer
|
|
514
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
515
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
519
516
|
}
|
|
520
|
-
}
|
|
521
|
-
|
|
517
|
+
}
|
|
518
|
+
return response.json();
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Renames the existing bands of a coverage layer.
|
|
523
|
+
*
|
|
524
|
+
* Make sure to provide the same number of bands as existing in the layer.
|
|
525
|
+
*
|
|
526
|
+
* @param {String} workspace Workspace of layer
|
|
527
|
+
* @param {String} datastore The datastore of the layer
|
|
528
|
+
* @param {String} layername The layer name
|
|
529
|
+
* @param {String[]} bandNames An array of the new band names in correct order
|
|
530
|
+
*
|
|
531
|
+
* @throws Error if request fails
|
|
532
|
+
*/
|
|
533
|
+
async renameCoverageBands (workspace, dataStore, layername, bandNames) {
|
|
534
|
+
const body = {
|
|
535
|
+
coverage: {
|
|
536
|
+
dimensions: {
|
|
537
|
+
coverageDimension: [
|
|
538
|
+
]
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
// dynamically create the body
|
|
544
|
+
bandNames.forEach(bandName => {
|
|
545
|
+
body.coverage.dimensions.coverageDimension.push(
|
|
546
|
+
{
|
|
547
|
+
name: bandName
|
|
548
|
+
}
|
|
549
|
+
);
|
|
550
|
+
})
|
|
551
|
+
|
|
552
|
+
const url = this.url + 'workspaces/' + workspace + '/coveragestores/' + dataStore + '/coverages/' + layername + '.json';
|
|
553
|
+
const response = await fetch(url, {
|
|
554
|
+
credentials: 'include',
|
|
555
|
+
method: 'PUT',
|
|
556
|
+
headers: {
|
|
557
|
+
Authorization: this.auth,
|
|
558
|
+
'Content-Type': 'application/json'
|
|
559
|
+
},
|
|
560
|
+
body: JSON.stringify(body)
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
if (!response.ok) {
|
|
564
|
+
const geoServerResponse = await getGeoServerResponseText(response);
|
|
565
|
+
throw new GeoServerResponseError(null, geoServerResponse);
|
|
522
566
|
}
|
|
523
567
|
}
|
|
524
568
|
}
|