@@ -6,10 +6,32 @@ const path = require('path')
6
6
const minimist = require ( 'minimist' ) ;
7
7
const compareVersions = require ( 'compare-versions' ) ;
8
8
9
+ let DEBUG = false ;
9
10
let COMPILED = { } ;
11
+ let SHORTCUTS = [
12
+ 'card4l-sar-nrb' ,
13
+ 'checksum' ,
14
+ 'collection-assets' ,
15
+ 'datacube' ,
16
+ 'eo' ,
17
+ 'item-assets' ,
18
+ 'label' ,
19
+ 'pointcloud' ,
20
+ 'projection' ,
21
+ 'sar' ,
22
+ 'sat' ,
23
+ 'scientific' ,
24
+ 'single-file-stac' ,
25
+ 'tiled-assets' ,
26
+ 'timestamps' ,
27
+ 'version' ,
28
+ 'view'
29
+ ] ;
10
30
let ajv = new Ajv ( {
11
31
allErrors : true ,
12
- missingRefs : "ignore"
32
+ missingRefs : "ignore" ,
33
+ addUsedSchema : false ,
34
+ logger : DEBUG ? console : false
13
35
} ) ;
14
36
15
37
async function run ( ) {
@@ -143,7 +165,7 @@ async function run() {
143
165
console . warn ( validate . errors ) ;
144
166
console . log ( "\n" ) ;
145
167
fileValid = false ;
146
- if ( schema === 'core' ) {
168
+ if ( schema === 'core' && ! DEBUG ) {
147
169
console . info ( "--- Validation error in core, skipping extension validation" ) ;
148
170
break ;
149
171
}
@@ -154,6 +176,9 @@ async function run() {
154
176
} catch ( error ) {
155
177
fileValid = false ;
156
178
console . error ( '---- ' + schema + ": " + error . message ) ;
179
+ if ( DEBUG ) {
180
+ console . trace ( error ) ;
181
+ }
157
182
}
158
183
}
159
184
console . log ( "\n" ) ;
@@ -201,13 +226,22 @@ async function loadSchema(baseUrl = null, version = null, shortcut = null) {
201
226
if ( typeof baseUrl !== 'string' ) {
202
227
baseUrl = "https://schemas.stacspec.org/" + version ;
203
228
}
229
+ else {
230
+ baseUrl = baseUrl . replace ( / \\ / g, '/' ) . replace ( / \/ $ / , "" ) ;
231
+ }
204
232
205
233
let url ;
234
+ let isExtension = false ;
206
235
if ( shortcut === 'item' || shortcut === 'catalog' || shortcut === 'collection' ) {
207
236
url = baseUrl + "/" + shortcut + "-spec/json-schema/" + shortcut + ".json" ;
208
237
}
209
238
else if ( typeof shortcut === 'string' ) {
239
+ if ( shortcut === 'proj' ) {
240
+ // Capture a very common mistake and give a better explanation (see #4)
241
+ throw new Error ( "'stac_extensions' must contain 'projection instead of 'proj'." ) ;
242
+ }
210
243
url = baseUrl + "/extensions/" + shortcut + "/json-schema/schema.json" ;
244
+ isExtension = true ;
211
245
}
212
246
else {
213
247
url = baseUrl ;
@@ -217,13 +251,32 @@ async function loadSchema(baseUrl = null, version = null, shortcut = null) {
217
251
return COMPILED [ url ] ;
218
252
}
219
253
else {
220
- let fullSchema = await $RefParser . dereference ( url , {
221
- dereference : {
222
- circular : "ignore"
254
+ try {
255
+ let parser = new $RefParser ( ) ;
256
+ let fullSchema = await parser . dereference ( url , {
257
+ dereference : {
258
+ circular : 'ignore'
259
+ }
260
+ } ) ;
261
+ COMPILED [ url ] = ajv . compile ( fullSchema ) ;
262
+ if ( parser . $refs . circular ) {
263
+ console . log ( `Schema ${ url } is circular, which is not supported by the library. Some properties may not get validated.` ) ;
223
264
}
224
- } ) ;
225
- COMPILED [ url ] = ajv . compile ( fullSchema ) ;
226
- return COMPILED [ url ] ;
265
+ return COMPILED [ url ] ;
266
+ } catch ( error ) {
267
+ // Convert error to string, both for Error objects and strings
268
+ let msg = "" + error ;
269
+ // Give better error message for (likely) invalid shortcuts
270
+ if ( isExtension && ! SHORTCUTS . includes ( shortcut ) && ( msg . includes ( "Error downloading" ) || msg . includes ( "Error opening file" ) ) ) {
271
+ if ( DEBUG ) {
272
+ console . trace ( error ) ;
273
+ }
274
+ throw new Error ( `Schema at '${ url } ' not found. Please ensure all entries in 'stac_extensions' are valid. ${ hint } ` ) ;
275
+ }
276
+ else {
277
+ throw error ;
278
+ }
279
+ }
227
280
}
228
281
}
229
282
0 commit comments