tableschema 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +21 -0
  3. data/.travis.yml +15 -1
  4. data/README.md +164 -129
  5. data/Rakefile +10 -1
  6. data/bin/console +2 -6
  7. data/{etc/schemas → lib/profiles}/geojson.json +0 -1
  8. data/lib/profiles/table-schema.json +1625 -0
  9. data/lib/profiles/topojson.json +311 -0
  10. data/lib/tableschema.rb +5 -3
  11. data/lib/tableschema/constraints/constraints.rb +12 -24
  12. data/lib/tableschema/constraints/enum.rb +6 -2
  13. data/lib/tableschema/constraints/max_length.rb +6 -2
  14. data/lib/tableschema/constraints/maximum.rb +12 -2
  15. data/lib/tableschema/constraints/min_length.rb +6 -2
  16. data/lib/tableschema/constraints/minimum.rb +12 -2
  17. data/lib/tableschema/constraints/pattern.rb +9 -2
  18. data/lib/tableschema/constraints/required.rb +6 -15
  19. data/lib/tableschema/constraints/unique.rb +12 -0
  20. data/lib/tableschema/defaults.rb +9 -0
  21. data/lib/tableschema/exceptions.rb +15 -2
  22. data/lib/tableschema/field.rb +39 -20
  23. data/lib/tableschema/helpers.rb +32 -15
  24. data/lib/tableschema/infer.rb +31 -28
  25. data/lib/tableschema/model.rb +57 -34
  26. data/lib/tableschema/schema.rb +40 -6
  27. data/lib/tableschema/table.rb +75 -26
  28. data/lib/tableschema/types/any.rb +1 -0
  29. data/lib/tableschema/types/array.rb +2 -1
  30. data/lib/tableschema/types/base.rb +9 -21
  31. data/lib/tableschema/types/date.rb +1 -0
  32. data/lib/tableschema/types/datetime.rb +1 -0
  33. data/lib/tableschema/types/duration.rb +31 -0
  34. data/lib/tableschema/types/geojson.rb +27 -5
  35. data/lib/tableschema/types/geopoint.rb +4 -3
  36. data/lib/tableschema/types/integer.rb +1 -0
  37. data/lib/tableschema/types/number.rb +40 -25
  38. data/lib/tableschema/types/object.rb +2 -1
  39. data/lib/tableschema/types/string.rb +8 -0
  40. data/lib/tableschema/types/time.rb +1 -0
  41. data/lib/tableschema/types/year.rb +34 -0
  42. data/lib/tableschema/types/yearmonth.rb +52 -0
  43. data/lib/tableschema/validate.rb +45 -29
  44. data/lib/tableschema/version.rb +1 -1
  45. data/tableschema.gemspec +2 -1
  46. metadata +31 -12
  47. data/etc/schemas/json-table-schema.json +0 -102
  48. data/lib/tableschema/data.rb +0 -60
  49. data/lib/tableschema/types/null.rb +0 -37
data/Rakefile CHANGED
@@ -1,6 +1,15 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require "open-uri"
3
4
 
4
5
  RSpec::Core::RakeTask.new(:spec)
5
6
 
6
- task :default => :spec
7
+ task default: :spec
8
+
9
+ task :update_profiles do
10
+ open('https://specs.frictionlessdata.io/schemas/table-schema.json') do |remote_schema|
11
+ File.open('./lib/profiles/table-schema.json', 'w') do |local_schema|
12
+ local_schema << remote_schema.read
13
+ end
14
+ end
15
+ end
data/bin/console CHANGED
@@ -6,9 +6,5 @@ require "tableschema"
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
8
8
 
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start
9
+ require "pry"
10
+ Pry.start
@@ -0,0 +1,1625 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "Table Schema",
4
+ "description": "A Table Schema for this resource, compliant with the [Table Schema](/tableschema/) specification.",
5
+ "type": "object",
6
+ "required": [
7
+ "fields"
8
+ ],
9
+ "properties": {
10
+ "fields": {
11
+ "type": "array",
12
+ "minItems": 1,
13
+ "items": {
14
+ "title": "Table Schema Field",
15
+ "type": "object",
16
+ "anyOf": [
17
+ {
18
+ "type": "object",
19
+ "title": "String Field",
20
+ "description": "The field contains strings, that is, sequences of characters.",
21
+ "required": [
22
+ "name"
23
+ ],
24
+ "properties": {
25
+ "name": {
26
+ "title": "Name",
27
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
28
+ "type": "string",
29
+ "pattern": "^([-a-z0-9._/])+$",
30
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
31
+ "examples": [
32
+ "{\n \"name\": \"my-nice-name\"\n}\n"
33
+ ]
34
+ },
35
+ "title": {
36
+ "title": "Title",
37
+ "description": "A human-readable title.",
38
+ "type": "string",
39
+ "examples": [
40
+ "{\n \"title\": \"My Package Title\"\n}\n"
41
+ ]
42
+ },
43
+ "description": {
44
+ "title": "Description",
45
+ "description": "A text description. Markdown is encouraged.",
46
+ "type": "string",
47
+ "examples": [
48
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
49
+ ]
50
+ },
51
+ "type": {
52
+ "description": "The type keyword, which `MUST` be a value of `string`.",
53
+ "enum": [
54
+ "string"
55
+ ]
56
+ },
57
+ "format": {
58
+ "description": "The format keyword options for `string` are `default`, `email`, `uri`, `binary`, and `uuid`.",
59
+ "context": "The following `format` options are supported:\n * **default**: any valid string.\n * **email**: A valid email address.\n * **uri**: A valid URI.\n * **binary**: A base64 encoded string representing binary data.\n * **uuid**: A string that is a uuid.",
60
+ "enum": [
61
+ "default",
62
+ "email",
63
+ "uri",
64
+ "binary",
65
+ "uuid"
66
+ ],
67
+ "default": "default"
68
+ },
69
+ "constraints": {
70
+ "title": "Constraints",
71
+ "description": "The following constraints are supported for `string` fields.",
72
+ "type": "object",
73
+ "properties": {
74
+ "required": {
75
+ "type": "boolean",
76
+ "description": "Indicates whether a property must have a value for each instance.",
77
+ "context": "An empty string is considered to be a missing value."
78
+ },
79
+ "unique": {
80
+ "type": "boolean",
81
+ "description": "When `true`, each value for the property `MUST` be unique."
82
+ },
83
+ "pattern": {
84
+ "type": "string",
85
+ "description": "A regular expression pattern to test each value of the property against, where a truthy response indicates validity.",
86
+ "context": "Regular expressions `SHOULD` conform to the [XML Schema regular expression syntax](http://www.w3.org/TR/xmlschema-2/#regexs)."
87
+ },
88
+ "enum": {
89
+ "type": "array",
90
+ "minItems": 1,
91
+ "uniqueItems": true,
92
+ "items": {
93
+ "type": "string"
94
+ }
95
+ },
96
+ "minLength": {
97
+ "type": "integer",
98
+ "description": "An integer that specifies the minimum length of a value."
99
+ },
100
+ "maxLength": {
101
+ "type": "integer",
102
+ "description": "An integer that specifies the maximum length of a value."
103
+ }
104
+ }
105
+ },
106
+ "rdfType": {
107
+ "type": "string",
108
+ "description": "The RDF type for this field."
109
+ }
110
+ },
111
+ "examples": [
112
+ "{\n \"name\": \"name\",\n \"type\": \"string\"\n}\n",
113
+ "{\n \"name\": \"name\",\n \"type\": \"string\",\n \"format\": \"email\"\n}\n",
114
+ "{\n \"name\": \"name\",\n \"type\": \"string\",\n \"constraints\": {\n \"minLength\": 3,\n \"maxLength\": 35\n }\n}\n"
115
+ ]
116
+ },
117
+ {
118
+ "type": "object",
119
+ "title": "Number Field",
120
+ "description": "The field contains numbers of any kind including decimals.",
121
+ "context": "The lexical formatting follows that of decimal in [XMLSchema](https://www.w3.org/TR/xmlschema-2/#decimal): a non-empty finite-length sequence of decimal digits separated by a period as a decimal indicator. An optional leading sign is allowed. If the sign is omitted, '+' is assumed. Leading and trailing zeroes are optional. If the fractional part is zero, the period and following zero(es) can be omitted. For example: '-1.23', '12678967.543233', '+100000.00', '210'.\n\nThe following special string values are permitted (case does not need to be respected):\n - NaN: not a number\n - INF: positive infinity\n - -INF: negative infinity\n\nA number `MAY` also have a trailing:\n - exponent: this `MUST` consist of an E followed by an optional + or - sign followed by one or more decimal digits (0-9)\n - percentage: the percentage sign: `%`. In conversion percentages should be divided by 100.\n\nIf both exponent and percentages are present the percentage `MUST` follow the exponent e.g. '53E10%' (equals 5.3).",
122
+ "required": [
123
+ "name"
124
+ ],
125
+ "properties": {
126
+ "name": {
127
+ "title": "Name",
128
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
129
+ "type": "string",
130
+ "pattern": "^([-a-z0-9._/])+$",
131
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
132
+ "examples": [
133
+ "{\n \"name\": \"my-nice-name\"\n}\n"
134
+ ]
135
+ },
136
+ "title": {
137
+ "title": "Title",
138
+ "description": "A human-readable title.",
139
+ "type": "string",
140
+ "examples": [
141
+ "{\n \"title\": \"My Package Title\"\n}\n"
142
+ ]
143
+ },
144
+ "description": {
145
+ "title": "Description",
146
+ "description": "A text description. Markdown is encouraged.",
147
+ "type": "string",
148
+ "examples": [
149
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
150
+ ]
151
+ },
152
+ "type": {
153
+ "description": "The type keyword, which `MUST` be a value of `number`.",
154
+ "enum": [
155
+ "number"
156
+ ]
157
+ },
158
+ "format": {
159
+ "description": "There are no format keyword options for `number`: only `default` is allowed.",
160
+ "enum": [
161
+ "default"
162
+ ],
163
+ "default": "default"
164
+ },
165
+ "decimalChar": {
166
+ "type": "string",
167
+ "description": "A string whose value is used to represent a decimal point within the number. The default value is `.`."
168
+ },
169
+ "groupChar": {
170
+ "type": "string",
171
+ "description": "A string whose value is used to group digits within the number. The default value is `null`. A common value is `,` e.g. '100,000'."
172
+ },
173
+ "currency": {
174
+ "type": "string",
175
+ "description": "A number that may include additional currency symbols."
176
+ },
177
+ "constraints": {
178
+ "title": "Constraints",
179
+ "description": "The following constraints are supported for `number` fields.",
180
+ "type": "object",
181
+ "properties": {
182
+ "required": {
183
+ "type": "boolean",
184
+ "description": "Indicates whether a property must have a value for each instance.",
185
+ "context": "An empty string is considered to be a missing value."
186
+ },
187
+ "unique": {
188
+ "type": "boolean",
189
+ "description": "When `true`, each value for the property `MUST` be unique."
190
+ },
191
+ "pattern": {
192
+ "type": "string",
193
+ "description": "A regular expression pattern to test each value of the property against, where a truthy response indicates validity.",
194
+ "context": "Regular expressions `SHOULD` conform to the [XML Schema regular expression syntax](http://www.w3.org/TR/xmlschema-2/#regexs)."
195
+ },
196
+ "enum": {
197
+ "oneOf": [
198
+ {
199
+ "type": "array",
200
+ "minItems": 1,
201
+ "uniqueItems": true,
202
+ "items": {
203
+ "type": "string"
204
+ }
205
+ },
206
+ {
207
+ "type": "array",
208
+ "minItems": 1,
209
+ "uniqueItems": true,
210
+ "items": {
211
+ "type": "number"
212
+ }
213
+ }
214
+ ]
215
+ },
216
+ "minimum": {
217
+ "oneOf": [
218
+ {
219
+ "type": "string"
220
+ },
221
+ {
222
+ "type": "number"
223
+ }
224
+ ]
225
+ },
226
+ "maximum": {
227
+ "oneOf": [
228
+ {
229
+ "type": "string"
230
+ },
231
+ {
232
+ "type": "number"
233
+ }
234
+ ]
235
+ }
236
+ }
237
+ },
238
+ "rdfType": {
239
+ "type": "string",
240
+ "description": "The RDF type for this field."
241
+ }
242
+ },
243
+ "examples": [
244
+ "{\n \"name\": \"field-name\",\n \"type\": \"number\"\n}\n",
245
+ "{\n \"name\": \"field-name\",\n \"type\": \"number\",\n \"constraints\": {\n \"enum\": [ \"1.00\", \"1.50\", \"2.00\" ]\n }\n}\n"
246
+ ]
247
+ },
248
+ {
249
+ "type": "object",
250
+ "title": "Integer Field",
251
+ "description": "The field contains integers - that is whole numbers.",
252
+ "context": "Integer values are indicated in the standard way for any valid integer.",
253
+ "required": [
254
+ "name",
255
+ "type"
256
+ ],
257
+ "properties": {
258
+ "name": {
259
+ "title": "Name",
260
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
261
+ "type": "string",
262
+ "pattern": "^([-a-z0-9._/])+$",
263
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
264
+ "examples": [
265
+ "{\n \"name\": \"my-nice-name\"\n}\n"
266
+ ]
267
+ },
268
+ "title": {
269
+ "title": "Title",
270
+ "description": "A human-readable title.",
271
+ "type": "string",
272
+ "examples": [
273
+ "{\n \"title\": \"My Package Title\"\n}\n"
274
+ ]
275
+ },
276
+ "description": {
277
+ "title": "Description",
278
+ "description": "A text description. Markdown is encouraged.",
279
+ "type": "string",
280
+ "examples": [
281
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
282
+ ]
283
+ },
284
+ "type": {
285
+ "description": "The type keyword, which `MUST` be a value of `integer`.",
286
+ "enum": [
287
+ "integer"
288
+ ]
289
+ },
290
+ "format": {
291
+ "description": "There are no format keyword options for `integer`: only `default` is allowed.",
292
+ "enum": [
293
+ "default"
294
+ ],
295
+ "default": "default"
296
+ },
297
+ "constraints": {
298
+ "title": "Constraints",
299
+ "description": "The following constraints are supported for `integer` fields.",
300
+ "type": "object",
301
+ "properties": {
302
+ "required": {
303
+ "type": "boolean",
304
+ "description": "Indicates whether a property must have a value for each instance.",
305
+ "context": "An empty string is considered to be a missing value."
306
+ },
307
+ "unique": {
308
+ "type": "boolean",
309
+ "description": "When `true`, each value for the property `MUST` be unique."
310
+ },
311
+ "pattern": {
312
+ "type": "string",
313
+ "description": "A regular expression pattern to test each value of the property against, where a truthy response indicates validity.",
314
+ "context": "Regular expressions `SHOULD` conform to the [XML Schema regular expression syntax](http://www.w3.org/TR/xmlschema-2/#regexs)."
315
+ },
316
+ "enum": {
317
+ "oneOf": [
318
+ {
319
+ "type": "array",
320
+ "minItems": 1,
321
+ "uniqueItems": true,
322
+ "items": {
323
+ "type": "string"
324
+ }
325
+ },
326
+ {
327
+ "type": "array",
328
+ "minItems": 1,
329
+ "uniqueItems": true,
330
+ "items": {
331
+ "type": "integer"
332
+ }
333
+ }
334
+ ]
335
+ },
336
+ "minimum": {
337
+ "oneOf": [
338
+ {
339
+ "type": "string"
340
+ },
341
+ {
342
+ "type": "integer"
343
+ }
344
+ ]
345
+ },
346
+ "maximum": {
347
+ "oneOf": [
348
+ {
349
+ "type": "string"
350
+ },
351
+ {
352
+ "type": "integer"
353
+ }
354
+ ]
355
+ }
356
+ }
357
+ },
358
+ "rdfType": {
359
+ "type": "string",
360
+ "description": "The RDF type for this field."
361
+ }
362
+ },
363
+ "examples": [
364
+ "{\n \"name\": \"age\",\n \"type\": \"integer\",\n \"constraints\": {\n \"unique\": true,\n \"minimum\": 100,\n \"maximum\": 9999\n }\n}\n"
365
+ ]
366
+ },
367
+ {
368
+ "type": "object",
369
+ "title": "Date Field",
370
+ "description": "The field contains temporal date values.",
371
+ "required": [
372
+ "name",
373
+ "type"
374
+ ],
375
+ "properties": {
376
+ "name": {
377
+ "title": "Name",
378
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
379
+ "type": "string",
380
+ "pattern": "^([-a-z0-9._/])+$",
381
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
382
+ "examples": [
383
+ "{\n \"name\": \"my-nice-name\"\n}\n"
384
+ ]
385
+ },
386
+ "title": {
387
+ "title": "Title",
388
+ "description": "A human-readable title.",
389
+ "type": "string",
390
+ "examples": [
391
+ "{\n \"title\": \"My Package Title\"\n}\n"
392
+ ]
393
+ },
394
+ "description": {
395
+ "title": "Description",
396
+ "description": "A text description. Markdown is encouraged.",
397
+ "type": "string",
398
+ "examples": [
399
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
400
+ ]
401
+ },
402
+ "type": {
403
+ "description": "The type keyword, which `MUST` be a value of `date`.",
404
+ "enum": [
405
+ "date"
406
+ ]
407
+ },
408
+ "format": {
409
+ "description": "The format keyword options for `date` are `default`, `any`, and `{PATTERN}`.",
410
+ "context": "The following `format` options are supported:\n * **default**: An ISO8601 format string of YYYY-MM-DD.\n * **any**: Any parsable representation of a date. The implementing library can attempt to parse the datetime via a range of strategies.\n * **{PATTERN}**: The value can be parsed according to `{PATTERN}`, which `MUST` follow the date formatting syntax of C / Python [strftime](http://strftime.org/).",
411
+ "default": "default"
412
+ },
413
+ "constraints": {
414
+ "title": "Constraints",
415
+ "description": "The following constraints are supported for `date` fields.",
416
+ "type": "object",
417
+ "properties": {
418
+ "required": {
419
+ "type": "boolean",
420
+ "description": "Indicates whether a property must have a value for each instance.",
421
+ "context": "An empty string is considered to be a missing value."
422
+ },
423
+ "unique": {
424
+ "type": "boolean",
425
+ "description": "When `true`, each value for the property `MUST` be unique."
426
+ },
427
+ "enum": {
428
+ "type": "array",
429
+ "minItems": 1,
430
+ "uniqueItems": true,
431
+ "items": {
432
+ "type": "string"
433
+ }
434
+ },
435
+ "minimum": {
436
+ "type": "string"
437
+ },
438
+ "maximum": {
439
+ "type": "string"
440
+ }
441
+ }
442
+ },
443
+ "rdfType": {
444
+ "type": "string",
445
+ "description": "The RDF type for this field."
446
+ }
447
+ },
448
+ "examples": [
449
+ "{\n \"name\": \"date_of_birth\",\n \"type\": \"date\"\n}\n",
450
+ "{\n \"name\": \"date_of_birth\",\n \"type\": \"date\",\n \"constraints\": {\n \"minimum\": \"01-01-1900\"\n }\n}\n",
451
+ "{\n \"name\": \"date_of_birth\",\n \"type\": \"date\",\n \"format\": \"MM-DD-YYYY\"\n}\n"
452
+ ]
453
+ },
454
+ {
455
+ "type": "object",
456
+ "title": "Time Field",
457
+ "description": "The field contains temporal time values.",
458
+ "required": [
459
+ "name",
460
+ "type"
461
+ ],
462
+ "properties": {
463
+ "name": {
464
+ "title": "Name",
465
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
466
+ "type": "string",
467
+ "pattern": "^([-a-z0-9._/])+$",
468
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
469
+ "examples": [
470
+ "{\n \"name\": \"my-nice-name\"\n}\n"
471
+ ]
472
+ },
473
+ "title": {
474
+ "title": "Title",
475
+ "description": "A human-readable title.",
476
+ "type": "string",
477
+ "examples": [
478
+ "{\n \"title\": \"My Package Title\"\n}\n"
479
+ ]
480
+ },
481
+ "description": {
482
+ "title": "Description",
483
+ "description": "A text description. Markdown is encouraged.",
484
+ "type": "string",
485
+ "examples": [
486
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
487
+ ]
488
+ },
489
+ "type": {
490
+ "description": "The type keyword, which `MUST` be a value of `time`.",
491
+ "enum": [
492
+ "time"
493
+ ]
494
+ },
495
+ "format": {
496
+ "description": "The format keyword options for `time` are `default`, `any`, and `{PATTERN}`.",
497
+ "context": "The following `format` options are supported:\n * **default**: An ISO8601 format string for time.\n * **any**: Any parsable representation of a date. The implementing library can attempt to parse the datetime via a range of strategies.\n * **{PATTERN}**: The value can be parsed according to `{PATTERN}`, which `MUST` follow the date formatting syntax of C / Python [strftime](http://strftime.org/).",
498
+ "default": "default"
499
+ },
500
+ "constraints": {
501
+ "title": "Constraints",
502
+ "description": "The following constraints are supported for `time` fields.",
503
+ "type": "object",
504
+ "properties": {
505
+ "required": {
506
+ "type": "boolean",
507
+ "description": "Indicates whether a property must have a value for each instance.",
508
+ "context": "An empty string is considered to be a missing value."
509
+ },
510
+ "unique": {
511
+ "type": "boolean",
512
+ "description": "When `true`, each value for the property `MUST` be unique."
513
+ },
514
+ "enum": {
515
+ "type": "array",
516
+ "minItems": 1,
517
+ "uniqueItems": true,
518
+ "items": {
519
+ "type": "string"
520
+ }
521
+ },
522
+ "minimum": {
523
+ "type": "string"
524
+ },
525
+ "maximum": {
526
+ "type": "string"
527
+ }
528
+ }
529
+ },
530
+ "rdfType": {
531
+ "type": "string",
532
+ "description": "The RDF type for this field."
533
+ }
534
+ },
535
+ "examples": [
536
+ "{\n \"name\": \"appointment_start\",\n \"type\": \"time\"\n}\n",
537
+ "{\n \"name\": \"appointment_start\",\n \"type\": \"time\",\n \"format\": \"any\"\n}\n"
538
+ ]
539
+ },
540
+ {
541
+ "type": "object",
542
+ "title": "Date Time Field",
543
+ "description": "The field contains temporal datetime values.",
544
+ "required": [
545
+ "name",
546
+ "type"
547
+ ],
548
+ "properties": {
549
+ "name": {
550
+ "title": "Name",
551
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
552
+ "type": "string",
553
+ "pattern": "^([-a-z0-9._/])+$",
554
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
555
+ "examples": [
556
+ "{\n \"name\": \"my-nice-name\"\n}\n"
557
+ ]
558
+ },
559
+ "title": {
560
+ "title": "Title",
561
+ "description": "A human-readable title.",
562
+ "type": "string",
563
+ "examples": [
564
+ "{\n \"title\": \"My Package Title\"\n}\n"
565
+ ]
566
+ },
567
+ "description": {
568
+ "title": "Description",
569
+ "description": "A text description. Markdown is encouraged.",
570
+ "type": "string",
571
+ "examples": [
572
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
573
+ ]
574
+ },
575
+ "type": {
576
+ "description": "The type keyword, which `MUST` be a value of `datetime`.",
577
+ "enum": [
578
+ "datetime"
579
+ ]
580
+ },
581
+ "format": {
582
+ "description": "The format keyword options for `datetime` are `default`, `any`, and `{PATTERN}`.",
583
+ "context": "The following `format` options are supported:\n * **default**: An ISO8601 format string for datetime.\n * **any**: Any parsable representation of a date. The implementing library can attempt to parse the datetime via a range of strategies.\n * **{PATTERN}**: The value can be parsed according to `{PATTERN}`, which `MUST` follow the date formatting syntax of C / Python [strftime](http://strftime.org/).",
584
+ "default": "default"
585
+ },
586
+ "constraints": {
587
+ "title": "Constraints",
588
+ "description": "The following constraints are supported for `datetime` fields.",
589
+ "type": "object",
590
+ "properties": {
591
+ "required": {
592
+ "type": "boolean",
593
+ "description": "Indicates whether a property must have a value for each instance.",
594
+ "context": "An empty string is considered to be a missing value."
595
+ },
596
+ "unique": {
597
+ "type": "boolean",
598
+ "description": "When `true`, each value for the property `MUST` be unique."
599
+ },
600
+ "enum": {
601
+ "type": "array",
602
+ "minItems": 1,
603
+ "uniqueItems": true,
604
+ "items": {
605
+ "type": "string"
606
+ }
607
+ },
608
+ "minimum": {
609
+ "type": "string"
610
+ },
611
+ "maximum": {
612
+ "type": "string"
613
+ }
614
+ }
615
+ },
616
+ "rdfType": {
617
+ "type": "string",
618
+ "description": "The RDF type for this field."
619
+ }
620
+ },
621
+ "examples": [
622
+ "{\n \"name\": \"timestamp\",\n \"type\": \"datetime\"\n}\n",
623
+ "{\n \"name\": \"timestamp\",\n \"type\": \"datetime\",\n \"format\": \"default\"\n}\n"
624
+ ]
625
+ },
626
+ {
627
+ "type": "object",
628
+ "title": "Year Field",
629
+ "description": "A calendar year, being an integer with 4 digits. Equivalent to [gYear in XML Schema](https://www.w3.org/TR/xmlschema-2/#gYear)",
630
+ "required": [
631
+ "name",
632
+ "type"
633
+ ],
634
+ "properties": {
635
+ "name": {
636
+ "title": "Name",
637
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
638
+ "type": "string",
639
+ "pattern": "^([-a-z0-9._/])+$",
640
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
641
+ "examples": [
642
+ "{\n \"name\": \"my-nice-name\"\n}\n"
643
+ ]
644
+ },
645
+ "title": {
646
+ "title": "Title",
647
+ "description": "A human-readable title.",
648
+ "type": "string",
649
+ "examples": [
650
+ "{\n \"title\": \"My Package Title\"\n}\n"
651
+ ]
652
+ },
653
+ "description": {
654
+ "title": "Description",
655
+ "description": "A text description. Markdown is encouraged.",
656
+ "type": "string",
657
+ "examples": [
658
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
659
+ ]
660
+ },
661
+ "type": {
662
+ "description": "The type keyword, which `MUST` be a value of `year`.",
663
+ "enum": [
664
+ "year"
665
+ ]
666
+ },
667
+ "format": {
668
+ "description": "There are no format keyword options for `year`: only `default` is allowed.",
669
+ "enum": [
670
+ "default"
671
+ ],
672
+ "default": "default"
673
+ },
674
+ "constraints": {
675
+ "title": "Constraints",
676
+ "description": "The following constraints are supported for `year` fields.",
677
+ "type": "object",
678
+ "properties": {
679
+ "required": {
680
+ "type": "boolean",
681
+ "description": "Indicates whether a property must have a value for each instance.",
682
+ "context": "An empty string is considered to be a missing value."
683
+ },
684
+ "unique": {
685
+ "type": "boolean",
686
+ "description": "When `true`, each value for the property `MUST` be unique."
687
+ },
688
+ "enum": {
689
+ "oneOf": [
690
+ {
691
+ "type": "array",
692
+ "minItems": 1,
693
+ "uniqueItems": true,
694
+ "items": {
695
+ "type": "string"
696
+ }
697
+ },
698
+ {
699
+ "type": "array",
700
+ "minItems": 1,
701
+ "uniqueItems": true,
702
+ "items": {
703
+ "type": "integer"
704
+ }
705
+ }
706
+ ]
707
+ },
708
+ "minimum": {
709
+ "oneOf": [
710
+ {
711
+ "type": "string"
712
+ },
713
+ {
714
+ "type": "integer"
715
+ }
716
+ ]
717
+ },
718
+ "maximum": {
719
+ "oneOf": [
720
+ {
721
+ "type": "string"
722
+ },
723
+ {
724
+ "type": "integer"
725
+ }
726
+ ]
727
+ }
728
+ }
729
+ },
730
+ "rdfType": {
731
+ "type": "string",
732
+ "description": "The RDF type for this field."
733
+ }
734
+ },
735
+ "examples": [
736
+ "{\n \"name\": \"year\",\n \"type\": \"year\"\n}\n",
737
+ "{\n \"name\": \"year\",\n \"type\": \"year\",\n \"constraints\": {\n \"minimum\": 1970,\n \"maximum\": 2003\n }\n}\n"
738
+ ]
739
+ },
740
+ {
741
+ "type": "object",
742
+ "title": "Year Month Field",
743
+ "description": "A calendar year month, being an integer with 1 or 2 digits. Equivalent to [gYearMonth in XML Schema](https://www.w3.org/TR/xmlschema-2/#gYearMonth)",
744
+ "required": [
745
+ "name",
746
+ "type"
747
+ ],
748
+ "properties": {
749
+ "name": {
750
+ "title": "Name",
751
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
752
+ "type": "string",
753
+ "pattern": "^([-a-z0-9._/])+$",
754
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
755
+ "examples": [
756
+ "{\n \"name\": \"my-nice-name\"\n}\n"
757
+ ]
758
+ },
759
+ "title": {
760
+ "title": "Title",
761
+ "description": "A human-readable title.",
762
+ "type": "string",
763
+ "examples": [
764
+ "{\n \"title\": \"My Package Title\"\n}\n"
765
+ ]
766
+ },
767
+ "description": {
768
+ "title": "Description",
769
+ "description": "A text description. Markdown is encouraged.",
770
+ "type": "string",
771
+ "examples": [
772
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
773
+ ]
774
+ },
775
+ "type": {
776
+ "description": "The type keyword, which `MUST` be a value of `yearmonth`.",
777
+ "enum": [
778
+ "yearmonth"
779
+ ]
780
+ },
781
+ "format": {
782
+ "description": "There are no format keyword options for `yearmonth`: only `default` is allowed.",
783
+ "enum": [
784
+ "default"
785
+ ],
786
+ "default": "default"
787
+ },
788
+ "constraints": {
789
+ "title": "Constraints",
790
+ "description": "The following constraints are supported for `yearmonth` fields.",
791
+ "type": "object",
792
+ "properties": {
793
+ "required": {
794
+ "type": "boolean",
795
+ "description": "Indicates whether a property must have a value for each instance.",
796
+ "context": "An empty string is considered to be a missing value."
797
+ },
798
+ "unique": {
799
+ "type": "boolean",
800
+ "description": "When `true`, each value for the property `MUST` be unique."
801
+ },
802
+ "pattern": {
803
+ "type": "string",
804
+ "description": "A regular expression pattern to test each value of the property against, where a truthy response indicates validity.",
805
+ "context": "Regular expressions `SHOULD` conform to the [XML Schema regular expression syntax](http://www.w3.org/TR/xmlschema-2/#regexs)."
806
+ },
807
+ "enum": {
808
+ "type": "array",
809
+ "minItems": 1,
810
+ "uniqueItems": true,
811
+ "items": {
812
+ "type": "string"
813
+ }
814
+ },
815
+ "minimum": {
816
+ "type": "string"
817
+ },
818
+ "maximum": {
819
+ "type": "string"
820
+ }
821
+ }
822
+ },
823
+ "rdfType": {
824
+ "type": "string",
825
+ "description": "The RDF type for this field."
826
+ }
827
+ },
828
+ "examples": [
829
+ "{\n \"name\": \"month\",\n \"type\": \"yearmonth\"\n}\n",
830
+ "{\n \"name\": \"month\",\n \"type\": \"yearmonth\",\n \"constraints\": {\n \"minimum\": 1,\n \"maximum\": 6\n }\n}\n"
831
+ ]
832
+ },
833
+ {
834
+ "type": "object",
835
+ "title": "Boolean Field",
836
+ "description": "The field contains boolean (true/false) data.",
837
+ "required": [
838
+ "name",
839
+ "type"
840
+ ],
841
+ "properties": {
842
+ "name": {
843
+ "title": "Name",
844
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
845
+ "type": "string",
846
+ "pattern": "^([-a-z0-9._/])+$",
847
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
848
+ "examples": [
849
+ "{\n \"name\": \"my-nice-name\"\n}\n"
850
+ ]
851
+ },
852
+ "title": {
853
+ "title": "Title",
854
+ "description": "A human-readable title.",
855
+ "type": "string",
856
+ "examples": [
857
+ "{\n \"title\": \"My Package Title\"\n}\n"
858
+ ]
859
+ },
860
+ "description": {
861
+ "title": "Description",
862
+ "description": "A text description. Markdown is encouraged.",
863
+ "type": "string",
864
+ "examples": [
865
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
866
+ ]
867
+ },
868
+ "type": {
869
+ "description": "The type keyword, which `MUST` be a value of `boolean`.",
870
+ "enum": [
871
+ "boolean"
872
+ ]
873
+ },
874
+ "trueValues": {
875
+ "type": "array",
876
+ "minItems": 1,
877
+ "items": {
878
+ "type": "string"
879
+ },
880
+ "default": [
881
+ "true",
882
+ "True",
883
+ "TRUE",
884
+ "1"
885
+ ]
886
+ },
887
+ "falseValues": {
888
+ "type": "array",
889
+ "minItems": 1,
890
+ "items": {
891
+ "type": "string"
892
+ },
893
+ "default": [
894
+ "false",
895
+ "False",
896
+ "FALSE",
897
+ "0"
898
+ ]
899
+ },
900
+ "constraints": {
901
+ "title": "Constraints",
902
+ "description": "The following constraints are supported for `boolean` fields.",
903
+ "type": "object",
904
+ "properties": {
905
+ "required": {
906
+ "type": "boolean",
907
+ "description": "Indicates whether a property must have a value for each instance.",
908
+ "context": "An empty string is considered to be a missing value."
909
+ },
910
+ "enum": {
911
+ "type": "array",
912
+ "minItems": 1,
913
+ "uniqueItems": true,
914
+ "items": {
915
+ "type": "boolean"
916
+ }
917
+ }
918
+ }
919
+ },
920
+ "rdfType": {
921
+ "type": "string",
922
+ "description": "The RDF type for this field."
923
+ }
924
+ },
925
+ "examples": [
926
+ "{\n \"name\": \"registered\",\n \"type\": \"boolean\"\n}\n"
927
+ ]
928
+ },
929
+ {
930
+ "type": "object",
931
+ "title": "Object Field",
932
+ "description": "The field contains data which can be parsed as a valid JSON object.",
933
+ "required": [
934
+ "name",
935
+ "type"
936
+ ],
937
+ "properties": {
938
+ "name": {
939
+ "title": "Name",
940
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
941
+ "type": "string",
942
+ "pattern": "^([-a-z0-9._/])+$",
943
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
944
+ "examples": [
945
+ "{\n \"name\": \"my-nice-name\"\n}\n"
946
+ ]
947
+ },
948
+ "title": {
949
+ "title": "Title",
950
+ "description": "A human-readable title.",
951
+ "type": "string",
952
+ "examples": [
953
+ "{\n \"title\": \"My Package Title\"\n}\n"
954
+ ]
955
+ },
956
+ "description": {
957
+ "title": "Description",
958
+ "description": "A text description. Markdown is encouraged.",
959
+ "type": "string",
960
+ "examples": [
961
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
962
+ ]
963
+ },
964
+ "type": {
965
+ "description": "The type keyword, which `MUST` be a value of `object`.",
966
+ "enum": [
967
+ "object"
968
+ ]
969
+ },
970
+ "format": {
971
+ "description": "There are no format keyword options for `object`: only `default` is allowed.",
972
+ "enum": [
973
+ "default"
974
+ ],
975
+ "default": "default"
976
+ },
977
+ "constraints": {
978
+ "title": "Constraints",
979
+ "description": "The following constraints apply for `object` fields.",
980
+ "type": "object",
981
+ "properties": {
982
+ "required": {
983
+ "type": "boolean",
984
+ "description": "Indicates whether a property must have a value for each instance.",
985
+ "context": "An empty string is considered to be a missing value."
986
+ },
987
+ "unique": {
988
+ "type": "boolean",
989
+ "description": "When `true`, each value for the property `MUST` be unique."
990
+ },
991
+ "enum": {
992
+ "oneOf": [
993
+ {
994
+ "type": "array",
995
+ "minItems": 1,
996
+ "uniqueItems": true,
997
+ "items": {
998
+ "type": "string"
999
+ }
1000
+ },
1001
+ {
1002
+ "type": "array",
1003
+ "minItems": 1,
1004
+ "uniqueItems": true,
1005
+ "items": {
1006
+ "type": "object"
1007
+ }
1008
+ }
1009
+ ]
1010
+ },
1011
+ "minLength": {
1012
+ "type": "integer",
1013
+ "description": "An integer that specifies the minimum length of a value."
1014
+ },
1015
+ "maxLength": {
1016
+ "type": "integer",
1017
+ "description": "An integer that specifies the maximum length of a value."
1018
+ }
1019
+ }
1020
+ },
1021
+ "rdfType": {
1022
+ "type": "string",
1023
+ "description": "The RDF type for this field."
1024
+ }
1025
+ },
1026
+ "examples": [
1027
+ "{\n \"name\": \"extra\"\n \"type\": \"object\"\n}\n"
1028
+ ]
1029
+ },
1030
+ {
1031
+ "type": "object",
1032
+ "title": "GeoPoint Field",
1033
+ "description": "The field contains data describing a geographic point.",
1034
+ "required": [
1035
+ "name",
1036
+ "type"
1037
+ ],
1038
+ "properties": {
1039
+ "name": {
1040
+ "title": "Name",
1041
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
1042
+ "type": "string",
1043
+ "pattern": "^([-a-z0-9._/])+$",
1044
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
1045
+ "examples": [
1046
+ "{\n \"name\": \"my-nice-name\"\n}\n"
1047
+ ]
1048
+ },
1049
+ "title": {
1050
+ "title": "Title",
1051
+ "description": "A human-readable title.",
1052
+ "type": "string",
1053
+ "examples": [
1054
+ "{\n \"title\": \"My Package Title\"\n}\n"
1055
+ ]
1056
+ },
1057
+ "description": {
1058
+ "title": "Description",
1059
+ "description": "A text description. Markdown is encouraged.",
1060
+ "type": "string",
1061
+ "examples": [
1062
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
1063
+ ]
1064
+ },
1065
+ "type": {
1066
+ "description": "The type keyword, which `MUST` be a value of `geopoint`.",
1067
+ "enum": [
1068
+ "geopoint"
1069
+ ]
1070
+ },
1071
+ "format": {
1072
+ "description": "The format keyword options for `geopoint` are `default`,`array`, and `object`.",
1073
+ "context": "The following `format` options are supported:\n * **default**: A string of the pattern 'lon, lat', where `lon` is the longitude and `lat` is the latitude.\n * **array**: An array of exactly two items, where each item is either a number, or a string parsable as a number, and the first item is `lon` and the second item is `lat`.\n * **object**: A JSON object with exactly two keys, `lat` and `lon`",
1074
+ "notes": [
1075
+ "Implementations `MUST` strip all white space in the default format of `lon, lat`."
1076
+ ],
1077
+ "enum": [
1078
+ "default",
1079
+ "array",
1080
+ "object"
1081
+ ],
1082
+ "default": "default"
1083
+ },
1084
+ "constraints": {
1085
+ "title": "Constraints",
1086
+ "description": "The following constraints are supported for `geopoint` fields.",
1087
+ "type": "object",
1088
+ "properties": {
1089
+ "required": {
1090
+ "type": "boolean",
1091
+ "description": "Indicates whether a property must have a value for each instance.",
1092
+ "context": "An empty string is considered to be a missing value."
1093
+ },
1094
+ "unique": {
1095
+ "type": "boolean",
1096
+ "description": "When `true`, each value for the property `MUST` be unique."
1097
+ },
1098
+ "enum": {
1099
+ "oneOf": [
1100
+ {
1101
+ "type": "array",
1102
+ "minItems": 1,
1103
+ "uniqueItems": true,
1104
+ "items": {
1105
+ "type": "string"
1106
+ }
1107
+ },
1108
+ {
1109
+ "type": "array",
1110
+ "minItems": 1,
1111
+ "uniqueItems": true,
1112
+ "items": {
1113
+ "type": "array"
1114
+ }
1115
+ },
1116
+ {
1117
+ "type": "array",
1118
+ "minItems": 1,
1119
+ "uniqueItems": true,
1120
+ "items": {
1121
+ "type": "object"
1122
+ }
1123
+ }
1124
+ ]
1125
+ }
1126
+ }
1127
+ },
1128
+ "rdfType": {
1129
+ "type": "string",
1130
+ "description": "The RDF type for this field."
1131
+ }
1132
+ },
1133
+ "examples": [
1134
+ "{\n \"name\": \"post_office\",\n \"type\": \"geopoint\"\n}\n",
1135
+ "{\n \"name\": \"post_office\",\n \"type\": \"geopoint\",\n \"format\": \"array\"\n}\n"
1136
+ ]
1137
+ },
1138
+ {
1139
+ "type": "object",
1140
+ "title": "GeoJSON Field",
1141
+ "description": "The field contains a JSON object according to GeoJSON or TopoJSON",
1142
+ "required": [
1143
+ "name",
1144
+ "type"
1145
+ ],
1146
+ "properties": {
1147
+ "name": {
1148
+ "title": "Name",
1149
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
1150
+ "type": "string",
1151
+ "pattern": "^([-a-z0-9._/])+$",
1152
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
1153
+ "examples": [
1154
+ "{\n \"name\": \"my-nice-name\"\n}\n"
1155
+ ]
1156
+ },
1157
+ "title": {
1158
+ "title": "Title",
1159
+ "description": "A human-readable title.",
1160
+ "type": "string",
1161
+ "examples": [
1162
+ "{\n \"title\": \"My Package Title\"\n}\n"
1163
+ ]
1164
+ },
1165
+ "description": {
1166
+ "title": "Description",
1167
+ "description": "A text description. Markdown is encouraged.",
1168
+ "type": "string",
1169
+ "examples": [
1170
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
1171
+ ]
1172
+ },
1173
+ "type": {
1174
+ "description": "The type keyword, which `MUST` be a value of `geojson`.",
1175
+ "enum": [
1176
+ "geojson"
1177
+ ]
1178
+ },
1179
+ "format": {
1180
+ "description": "The format keyword options for `geojson` are `default` and `topojson`.",
1181
+ "context": "The following `format` options are supported:\n * **default**: A geojson object as per the [GeoJSON spec](http://geojson.org/).\n * **topojson**: A topojson object as per the [TopoJSON spec](https://github.com/topojson/topojson-specification/blob/master/README.md)",
1182
+ "enum": [
1183
+ "default",
1184
+ "topojson"
1185
+ ],
1186
+ "default": "default"
1187
+ },
1188
+ "constraints": {
1189
+ "title": "Constraints",
1190
+ "description": "The following constraints are supported for `geojson` fields.",
1191
+ "type": "object",
1192
+ "properties": {
1193
+ "required": {
1194
+ "type": "boolean",
1195
+ "description": "Indicates whether a property must have a value for each instance.",
1196
+ "context": "An empty string is considered to be a missing value."
1197
+ },
1198
+ "unique": {
1199
+ "type": "boolean",
1200
+ "description": "When `true`, each value for the property `MUST` be unique."
1201
+ },
1202
+ "enum": {
1203
+ "oneOf": [
1204
+ {
1205
+ "type": "array",
1206
+ "minItems": 1,
1207
+ "uniqueItems": true,
1208
+ "items": {
1209
+ "type": "string"
1210
+ }
1211
+ },
1212
+ {
1213
+ "type": "array",
1214
+ "minItems": 1,
1215
+ "uniqueItems": true,
1216
+ "items": {
1217
+ "type": "object"
1218
+ }
1219
+ }
1220
+ ]
1221
+ },
1222
+ "minLength": {
1223
+ "type": "integer",
1224
+ "description": "An integer that specifies the minimum length of a value."
1225
+ },
1226
+ "maxLength": {
1227
+ "type": "integer",
1228
+ "description": "An integer that specifies the maximum length of a value."
1229
+ }
1230
+ }
1231
+ },
1232
+ "rdfType": {
1233
+ "type": "string",
1234
+ "description": "The RDF type for this field."
1235
+ }
1236
+ },
1237
+ "examples": [
1238
+ "{\n \"name\": \"city_limits\",\n \"type\": \"geojson\"\n}\n",
1239
+ "{\n \"name\": \"city_limits\",\n \"type\": \"geojson\",\n \"format\": \"topojson\"\n}\n"
1240
+ ]
1241
+ },
1242
+ {
1243
+ "type": "object",
1244
+ "title": "Array Field",
1245
+ "description": "The field contains data which can be parsed as a valid JSON array.",
1246
+ "required": [
1247
+ "name",
1248
+ "type"
1249
+ ],
1250
+ "properties": {
1251
+ "name": {
1252
+ "title": "Name",
1253
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
1254
+ "type": "string",
1255
+ "pattern": "^([-a-z0-9._/])+$",
1256
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
1257
+ "examples": [
1258
+ "{\n \"name\": \"my-nice-name\"\n}\n"
1259
+ ]
1260
+ },
1261
+ "title": {
1262
+ "title": "Title",
1263
+ "description": "A human-readable title.",
1264
+ "type": "string",
1265
+ "examples": [
1266
+ "{\n \"title\": \"My Package Title\"\n}\n"
1267
+ ]
1268
+ },
1269
+ "description": {
1270
+ "title": "Description",
1271
+ "description": "A text description. Markdown is encouraged.",
1272
+ "type": "string",
1273
+ "examples": [
1274
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
1275
+ ]
1276
+ },
1277
+ "type": {
1278
+ "description": "The type keyword, which `MUST` be a value of `array`.",
1279
+ "enum": [
1280
+ "array"
1281
+ ]
1282
+ },
1283
+ "format": {
1284
+ "description": "There are no format keyword options for `array`: only `default` is allowed.",
1285
+ "enum": [
1286
+ "default"
1287
+ ],
1288
+ "default": "default"
1289
+ },
1290
+ "constraints": {
1291
+ "title": "Constraints",
1292
+ "description": "The following constraints apply for `array` fields.",
1293
+ "type": "object",
1294
+ "properties": {
1295
+ "required": {
1296
+ "type": "boolean",
1297
+ "description": "Indicates whether a property must have a value for each instance.",
1298
+ "context": "An empty string is considered to be a missing value."
1299
+ },
1300
+ "unique": {
1301
+ "type": "boolean",
1302
+ "description": "When `true`, each value for the property `MUST` be unique."
1303
+ },
1304
+ "enum": {
1305
+ "oneOf": [
1306
+ {
1307
+ "type": "array",
1308
+ "minItems": 1,
1309
+ "uniqueItems": true,
1310
+ "items": {
1311
+ "type": "string"
1312
+ }
1313
+ },
1314
+ {
1315
+ "type": "array",
1316
+ "minItems": 1,
1317
+ "uniqueItems": true,
1318
+ "items": {
1319
+ "type": "array"
1320
+ }
1321
+ }
1322
+ ]
1323
+ },
1324
+ "minLength": {
1325
+ "type": "integer",
1326
+ "description": "An integer that specifies the minimum length of a value."
1327
+ },
1328
+ "maxLength": {
1329
+ "type": "integer",
1330
+ "description": "An integer that specifies the maximum length of a value."
1331
+ }
1332
+ }
1333
+ },
1334
+ "rdfType": {
1335
+ "type": "string",
1336
+ "description": "The RDF type for this field."
1337
+ }
1338
+ },
1339
+ "examples": [
1340
+ "{\n \"name\": \"options\"\n \"type\": \"array\"\n}\n"
1341
+ ]
1342
+ },
1343
+ {
1344
+ "type": "object",
1345
+ "title": "Duration Field",
1346
+ "description": "The field contains a duration of time.",
1347
+ "context": "The lexical representation for duration is the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Durations) extended format `PnYnMnDTnHnMnS`, where `nY` represents the number of years, `nM` the number of months, `nD` the number of days, 'T' is the date/time separator, `nH` the number of hours, `nM` the number of minutes and `nS` the number of seconds. The number of seconds can include decimal digits to arbitrary precision. Date and time elements including their designator may be omitted if their value is zero, and lower order elements may also be omitted for reduced precision. Here we follow the definition of [XML Schema duration datatype](http://www.w3.org/TR/xmlschema-2/#duration) directly and that definition is implicitly inlined here.",
1348
+ "required": [
1349
+ "name",
1350
+ "type"
1351
+ ],
1352
+ "properties": {
1353
+ "name": {
1354
+ "title": "Name",
1355
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
1356
+ "type": "string",
1357
+ "pattern": "^([-a-z0-9._/])+$",
1358
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
1359
+ "examples": [
1360
+ "{\n \"name\": \"my-nice-name\"\n}\n"
1361
+ ]
1362
+ },
1363
+ "title": {
1364
+ "title": "Title",
1365
+ "description": "A human-readable title.",
1366
+ "type": "string",
1367
+ "examples": [
1368
+ "{\n \"title\": \"My Package Title\"\n}\n"
1369
+ ]
1370
+ },
1371
+ "description": {
1372
+ "title": "Description",
1373
+ "description": "A text description. Markdown is encouraged.",
1374
+ "type": "string",
1375
+ "examples": [
1376
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
1377
+ ]
1378
+ },
1379
+ "type": {
1380
+ "description": "The type keyword, which `MUST` be a value of `duration`.",
1381
+ "enum": [
1382
+ "duration"
1383
+ ]
1384
+ },
1385
+ "format": {
1386
+ "description": "There are no format keyword options for `duration`: only `default` is allowed.",
1387
+ "enum": [
1388
+ "default"
1389
+ ],
1390
+ "default": "default"
1391
+ },
1392
+ "constraints": {
1393
+ "title": "Constraints",
1394
+ "description": "The following constraints are supported for `duration` fields.",
1395
+ "type": "object",
1396
+ "properties": {
1397
+ "required": {
1398
+ "type": "boolean",
1399
+ "description": "Indicates whether a property must have a value for each instance.",
1400
+ "context": "An empty string is considered to be a missing value."
1401
+ },
1402
+ "unique": {
1403
+ "type": "boolean",
1404
+ "description": "When `true`, each value for the property `MUST` be unique."
1405
+ },
1406
+ "enum": {
1407
+ "type": "array",
1408
+ "minItems": 1,
1409
+ "uniqueItems": true,
1410
+ "items": {
1411
+ "type": "string"
1412
+ }
1413
+ },
1414
+ "minimum": {
1415
+ "type": "string"
1416
+ },
1417
+ "maximum": {
1418
+ "type": "string"
1419
+ }
1420
+ }
1421
+ },
1422
+ "rdfType": {
1423
+ "type": "string",
1424
+ "description": "The RDF type for this field."
1425
+ }
1426
+ },
1427
+ "examples": [
1428
+ "{\n \"name\": \"period\"\n \"type\": \"duration\"\n}\n"
1429
+ ]
1430
+ },
1431
+ {
1432
+ "type": "object",
1433
+ "title": "Any Field",
1434
+ "description": "Any value is accepted, including values that are not captured by the type/format/constraint requirements of the specification.",
1435
+ "required": [
1436
+ "name",
1437
+ "type"
1438
+ ],
1439
+ "properties": {
1440
+ "name": {
1441
+ "title": "Name",
1442
+ "description": "An identifier string. Lower case characters with `.`, `_`, `-` and `/` are allowed.",
1443
+ "type": "string",
1444
+ "pattern": "^([-a-z0-9._/])+$",
1445
+ "context": "This is ideally a url-usable and human-readable name. Name `SHOULD` be invariant, meaning it `SHOULD NOT` change when its parent descriptor is updated.",
1446
+ "examples": [
1447
+ "{\n \"name\": \"my-nice-name\"\n}\n"
1448
+ ]
1449
+ },
1450
+ "title": {
1451
+ "title": "Title",
1452
+ "description": "A human-readable title.",
1453
+ "type": "string",
1454
+ "examples": [
1455
+ "{\n \"title\": \"My Package Title\"\n}\n"
1456
+ ]
1457
+ },
1458
+ "description": {
1459
+ "title": "Description",
1460
+ "description": "A text description. Markdown is encouraged.",
1461
+ "type": "string",
1462
+ "examples": [
1463
+ "{\n \"description\": \"# My Package description\\nAll about my package.\"\n}\n"
1464
+ ]
1465
+ },
1466
+ "type": {
1467
+ "description": "The type keyword, which `MUST` be a value of `any`.",
1468
+ "enum": [
1469
+ "any"
1470
+ ]
1471
+ },
1472
+ "constraints": {
1473
+ "title": "Constraints",
1474
+ "description": "The following constraints apply to `any` fields.",
1475
+ "type": "object",
1476
+ "properties": {
1477
+ "required": {
1478
+ "type": "boolean",
1479
+ "description": "Indicates whether a property must have a value for each instance.",
1480
+ "context": "An empty string is considered to be a missing value."
1481
+ },
1482
+ "unique": {
1483
+ "type": "boolean",
1484
+ "description": "When `true`, each value for the property `MUST` be unique."
1485
+ },
1486
+ "enum": {
1487
+ "type": "array",
1488
+ "minItems": 1,
1489
+ "uniqueItems": true
1490
+ }
1491
+ }
1492
+ },
1493
+ "rdfType": {
1494
+ "type": "string",
1495
+ "description": "The RDF type for this field."
1496
+ }
1497
+ },
1498
+ "examples": [
1499
+ "{\n \"name\": \"notes\",\n \"type\": \"any\"\n"
1500
+ ]
1501
+ }
1502
+ ]
1503
+ },
1504
+ "description": "An `array` of Table Schema Field objects.",
1505
+ "examples": [
1506
+ "{\n \"fields\": [\n {\n \"name\": \"my-field-name\"\n }\n ]\n}\n",
1507
+ "{\n \"fields\": [\n {\n \"name\": \"my-field-name\",\n \"type\": \"number\"\n },\n {\n \"name\": \"my-field-name-2\",\n \"type\": \"string\",\n \"format\": \"email\"\n }\n ]\n}\n"
1508
+ ]
1509
+ },
1510
+ "primaryKey": {
1511
+ "oneOf": [
1512
+ {
1513
+ "type": "array",
1514
+ "minItems": 1,
1515
+ "uniqueItems": true,
1516
+ "items": {
1517
+ "type": "string"
1518
+ }
1519
+ },
1520
+ {
1521
+ "type": "string"
1522
+ }
1523
+ ],
1524
+ "description": "A primary key is a field name or an array of field names, whose values `MUST` uniquely identify each row in the table.",
1525
+ "context": "Field name in the `primaryKey` `MUST` be unique, and `MUST` match a field name in the associated table. It is acceptable to have an array with a single value, indicating that the value of a single field is the primary key.",
1526
+ "examples": [
1527
+ "{\n \"primaryKey\": [\n \"name\"\n ]\n}\n",
1528
+ "{\n \"primaryKey\": [\n \"first_name\",\n \"last_name\"\n ]\n}\n"
1529
+ ]
1530
+ },
1531
+ "foreignKeys": {
1532
+ "type": "array",
1533
+ "minItems": 1,
1534
+ "items": {
1535
+ "title": "Table Schema Foreign Key",
1536
+ "description": "Table Schema Foreign Key",
1537
+ "type": "object",
1538
+ "required": [
1539
+ "fields",
1540
+ "reference"
1541
+ ],
1542
+ "properties": {
1543
+ "oneOf": [
1544
+ {
1545
+ "fields": {
1546
+ "type": "array",
1547
+ "items": {
1548
+ "type": "string",
1549
+ "minItems": 1,
1550
+ "uniqueItems": true,
1551
+ "description": "Fields that make up the primary key."
1552
+ }
1553
+ },
1554
+ "reference": {
1555
+ "type": "object",
1556
+ "required": [
1557
+ "resource",
1558
+ "fields"
1559
+ ],
1560
+ "properties": {
1561
+ "resource": {
1562
+ "type": "string",
1563
+ "default": ""
1564
+ },
1565
+ "fields": {
1566
+ "type": "array",
1567
+ "items": {
1568
+ "type": "string"
1569
+ },
1570
+ "minItems": 1,
1571
+ "uniqueItems": true
1572
+ }
1573
+ }
1574
+ }
1575
+ },
1576
+ {
1577
+ "fields": {
1578
+ "type": "string",
1579
+ "description": "Fields that make up the primary key."
1580
+ },
1581
+ "reference": {
1582
+ "type": "object",
1583
+ "required": [
1584
+ "resource",
1585
+ "fields"
1586
+ ],
1587
+ "properties": {
1588
+ "resource": {
1589
+ "type": "string",
1590
+ "default": ""
1591
+ },
1592
+ "fields": {
1593
+ "type": "string"
1594
+ }
1595
+ }
1596
+ }
1597
+ }
1598
+ ]
1599
+ }
1600
+ },
1601
+ "examples": [
1602
+ "{\n \"foreignKeys\": [\n {\n \"fields\": \"state\",\n \"reference\": {\n \"resource\": \"the-resource\",\n \"fields\": \"state_id\"\n }\n }\n ]\n}\n",
1603
+ "{\n \"foreignKeys\": [\n {\n \"fields\": \"state\",\n \"reference\": {\n \"resource\": \"\",\n \"fields\": \"id\"\n }\n }\n ]\n}\n"
1604
+ ]
1605
+ },
1606
+ "missingValues": {
1607
+ "type": "array",
1608
+ "minItems": 1,
1609
+ "items": {
1610
+ "type": "string"
1611
+ },
1612
+ "default": [
1613
+ ""
1614
+ ],
1615
+ "description": "Values that when encountered in the source, should be considered as `null`, 'not present', or 'blank' values.",
1616
+ "context": "Many datasets arrive with missing data values, either because a value was not collected or it never existed.\nMissing values may be indicated simply by the value being empty in other cases a special value may have been used e.g. `-`, `NaN`, `0`, `-9999` etc.\nThe `missingValues` property provides a way to indicate that these values should be interpreted as equivalent to null.\n\n`missingValues` are strings rather than being the data type of the particular field. This allows for comparison prior to casting and for fields to have missing value which are not of their type, for example a `number` field to have missing values indicated by `-`.\n\nThe default value of `missingValue` for a non-string type field is the empty string `''`. For string type fields there is no default for `missingValue` (for string fields the empty string `''` is a valid value and need not indicate null).",
1617
+ "examples": [
1618
+ "{\n \"missingValues\": [\n \"-\",\n \"NaN\",\n \"\"\n ]\n}\n"
1619
+ ]
1620
+ }
1621
+ },
1622
+ "examples": [
1623
+ "{\n \"schema\": {\n \"fields\": [\n {\n \"name\": \"first_name\",\n \"type\": \"string\"\n \"constraints\": {\n \"required\": true\n }\n },\n {\n \"name\": \"age\",\n \"type\": \"integer\"\n },\n ],\n \"primaryKey\": [\n \"name\"\n ]\n }\n}\n"
1624
+ ]
1625
+ }