cocina-models 0.110.1 → 0.112.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +4 -2
  3. data/.github/pull_request_template.md +0 -5
  4. data/Gemfile.lock +17 -23
  5. data/README.md +17 -10
  6. data/bin/validate-schema +8 -0
  7. data/cocina-models.gemspec +0 -1
  8. data/lib/cocina/generator/generator.rb +4 -4
  9. data/lib/cocina/generator/schema.rb +4 -1
  10. data/lib/cocina/generator/schema_base.rb +2 -0
  11. data/lib/cocina/{open_api_wrapper.rb → json_schema_wrapper.rb} +8 -23
  12. data/lib/cocina/models/admin_policy_access_template.rb +1 -1
  13. data/lib/cocina/models/citation_only_access.rb +1 -1
  14. data/lib/cocina/models/collection_access.rb +1 -1
  15. data/lib/cocina/models/controlled_digital_lending_access.rb +1 -1
  16. data/lib/cocina/models/dark_access.rb +1 -1
  17. data/lib/cocina/models/dro_access.rb +1 -1
  18. data/lib/cocina/models/file.rb +1 -1
  19. data/lib/cocina/models/file_use.rb +1 -1
  20. data/lib/cocina/models/license.rb +1 -1
  21. data/lib/cocina/models/location_based_access.rb +1 -1
  22. data/lib/cocina/models/mapping/from_mods/language_term.rb +1 -1
  23. data/lib/cocina/models/request_file.rb +1 -1
  24. data/lib/cocina/models/stanford_access.rb +1 -1
  25. data/lib/cocina/models/validators/json_schema_validator.rb +39 -0
  26. data/lib/cocina/models/validators/validator.rb +1 -1
  27. data/lib/cocina/models/version.rb +1 -1
  28. data/lib/cocina/models/world_access.rb +1 -1
  29. data/lib/cocina/models.rb +0 -12
  30. data/openapi.yml +0 -199
  31. data/schema.json +2635 -0
  32. metadata +7 -34
  33. data/lib/cocina/models/mapping/from_marc/access.rb +0 -50
  34. data/lib/cocina/models/mapping/from_marc/admin_metadata.rb +0 -77
  35. data/lib/cocina/models/mapping/from_marc/contributor.rb +0 -107
  36. data/lib/cocina/models/mapping/from_marc/description.rb +0 -38
  37. data/lib/cocina/models/mapping/from_marc/description_builder.rb +0 -58
  38. data/lib/cocina/models/mapping/from_marc/event.rb +0 -169
  39. data/lib/cocina/models/mapping/from_marc/form.rb +0 -135
  40. data/lib/cocina/models/mapping/from_marc/geographic.rb +0 -45
  41. data/lib/cocina/models/mapping/from_marc/identifier.rb +0 -101
  42. data/lib/cocina/models/mapping/from_marc/language.rb +0 -49
  43. data/lib/cocina/models/mapping/from_marc/marc_relators.rb +0 -321
  44. data/lib/cocina/models/mapping/from_marc/note.rb +0 -186
  45. data/lib/cocina/models/mapping/from_marc/related_resource.rb +0 -169
  46. data/lib/cocina/models/mapping/from_marc/title.rb +0 -132
  47. data/lib/cocina/models/mapping/from_marc/util.rb +0 -31
  48. data/lib/cocina/models/validators/open_api_validator.rb +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ba030653ba2790a20c4d071881472d3889bb4739c3c4637bb68d11d4c320207
4
- data.tar.gz: 1f5d68d708a345aaf833908dca817af1c5c8499723d7f5194e2b0097817cb3a5
3
+ metadata.gz: 021d53c09f577e12fbfd215fc37bec5acb2b4da9dd6c8b4803153d107c9d9e80
4
+ data.tar.gz: e0e1553f9e8f6e3a3a7bbb032fb6bdb9f9b41c98e71d0c46b1bbe9ef53eab23a
5
5
  SHA512:
6
- metadata.gz: 796ab6c265801899f9b31ff131313d413133fbaf2829e2899dd0535a616345af723201d76aca3cecd4e9efaab5c2afa3151a5281a32cfb3adb46ece694378a13
7
- data.tar.gz: 6ef1fc9300e553734fe55bc59b2cee35d80020e80b6539990ceb81d9c6f809e48449995fe6d0173ac9cf1d2a46d1aa264bfd86afa0c587999b7ae927590e84f9
6
+ metadata.gz: df70b91ae041970111a9a30a299a33e35057a6beaede5894e5a94cf01909072c62e441744dd2c638f05dd19b2634d7dc0fe5ffecbc0d23cfb67a5cc231baa4d3
7
+ data.tar.gz: 6f66fd83a7d8d41b361ef7c7c24600796272f68f41b74161e756519039ae37703e24edc7362c60cfae7c78dec95bae7d9ee2b4eaef36dcc1dc9fd4a83b15262b
data/.circleci/config.yml CHANGED
@@ -4,10 +4,12 @@ orbs:
4
4
  workflows:
5
5
  build:
6
6
  jobs:
7
- - ruby-rails/validate-api:
8
- name: validate
9
7
  - ruby-rails/lint:
10
8
  name: lint
11
9
  - ruby-rails/test-gem:
12
10
  name: test
13
11
  context: dlss
12
+ before-test:
13
+ - run:
14
+ name: validate openapi
15
+ command: bin/validate-schema schema.json
@@ -1,5 +1,3 @@
1
- **NOTE: Changes to openapi.yml require updating openapi.yml for sdr-api and dor-services-app and generating models - see README.**
2
-
3
1
  ## Why was this change made? 🤔
4
2
 
5
3
 
@@ -7,6 +5,3 @@
7
5
  ## How was this change tested? 🤨
8
6
 
9
7
  ⚡ ⚠ If this change has cross service impact, ***run [integration tests](https://github.com/sul-dlss/infrastructure-integration-test)*** and/or test in [stage|qa] environment, in addition to specs. ⚡
10
-
11
-
12
-
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cocina-models (0.110.1)
4
+ cocina-models (0.112.0)
5
5
  activesupport
6
6
  deprecation
7
7
  dry-struct (~> 1.0)
@@ -11,7 +11,6 @@ PATH
11
11
  i18n
12
12
  json_schemer (~> 2.0)
13
13
  jsonpath
14
- marc (~> 1.3)
15
14
  nokogiri
16
15
  super_diff
17
16
  thor
@@ -80,8 +79,9 @@ GEM
80
79
  concurrent-ruby (~> 1.0)
81
80
  ice_nine (0.11.2)
82
81
  io-console (0.8.2)
83
- irb (1.16.0)
82
+ irb (1.17.0)
84
83
  pp (>= 0.6.0)
84
+ prism (>= 1.3.0)
85
85
  rdoc (>= 4.0.0)
86
86
  reline (>= 0.4.2)
87
87
  json (2.18.1)
@@ -95,19 +95,16 @@ GEM
95
95
  language_server-protocol (3.17.0.5)
96
96
  lint_roller (1.1.0)
97
97
  logger (1.7.0)
98
- marc (1.4.0)
99
- nokogiri (~> 1.0)
100
- rexml
101
98
  minitest (6.0.1)
102
99
  prism (~> 1.5)
103
100
  multi_json (1.19.1)
104
- nokogiri (1.19.0-arm64-darwin)
101
+ nokogiri (1.19.1-arm64-darwin)
105
102
  racc (~> 1.4)
106
- nokogiri (1.19.0-x86_64-linux-gnu)
103
+ nokogiri (1.19.1-x86_64-linux-gnu)
107
104
  racc (~> 1.4)
108
105
  optimist (3.2.1)
109
106
  parallel (1.27.0)
110
- parser (3.3.10.1)
107
+ parser (3.3.10.2)
111
108
  ast (~> 2.4.1)
112
109
  racc
113
110
  patience_diff (1.2.0)
@@ -122,14 +119,13 @@ GEM
122
119
  racc (1.8.1)
123
120
  rainbow (3.1.1)
124
121
  rake (13.3.1)
125
- rdoc (7.1.0)
122
+ rdoc (7.2.0)
126
123
  erb
127
124
  psych (>= 4.0.0)
128
125
  tsort
129
126
  regexp_parser (2.11.3)
130
127
  reline (0.6.3)
131
128
  io-console (~> 0.5)
132
- rexml (3.4.4)
133
129
  rspec (3.13.2)
134
130
  rspec-core (~> 3.13.0)
135
131
  rspec-expectations (~> 3.13.0)
@@ -145,7 +141,7 @@ GEM
145
141
  rspec-support (3.13.7)
146
142
  rspec_junit_formatter (0.6.0)
147
143
  rspec-core (>= 2, < 4, != 2.12.0)
148
- rubocop (1.84.1)
144
+ rubocop (1.84.2)
149
145
  json (~> 2.3)
150
146
  language_server-protocol (~> 3.17.0.2)
151
147
  lint_roller (~> 1.1.0)
@@ -187,7 +183,7 @@ GEM
187
183
  unicode-emoji (~> 4.1)
188
184
  unicode-emoji (4.2.0)
189
185
  uri (1.1.1)
190
- zeitwerk (2.7.4)
186
+ zeitwerk (2.7.5)
191
187
 
192
188
  PLATFORMS
193
189
  arm64-darwin
@@ -211,7 +207,7 @@ CHECKSUMS
211
207
  attr_extras (7.1.0) sha256=d96fc9a9dd5d85ba2d37762440a816f840093959ae26bb90da994c2d9f1fc827
212
208
  base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
213
209
  bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
214
- cocina-models (0.110.1)
210
+ cocina-models (0.112.0)
215
211
  concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
216
212
  connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
217
213
  date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
@@ -232,21 +228,20 @@ CHECKSUMS
232
228
  i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
233
229
  ice_nine (0.11.2) sha256=5d506a7d2723d5592dc121b9928e4931742730131f22a1a37649df1c1e2e63db
234
230
  io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
235
- irb (1.16.0) sha256=2abe56c9ac947cdcb2f150572904ba798c1e93c890c256f8429981a7675b0806
231
+ irb (1.17.0) sha256=168c4ddb93d8a361a045c41d92b2952c7a118fa73f23fe14e55609eb7a863aae
236
232
  json (2.18.1) sha256=fe112755501b8d0466b5ada6cf50c8c3f41e897fa128ac5d263ec09eedc9f986
237
233
  json_schemer (2.5.0) sha256=2f01fb4cce721a4e08dd068fc2030cffd0702a7f333f1ea2be6e8991f00ae396
238
234
  jsonpath (1.1.5) sha256=29f70467193a2dc93ab864ec3d3326d54267961acc623f487340eb9c34931dbe
239
235
  language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
240
236
  lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
241
237
  logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
242
- marc (1.4.0) sha256=89f31a66c21f5a11e8fcf65fe06d207e121fb45ac6b23abef403f9ce912c7d10
243
238
  minitest (6.0.1) sha256=7854c74f48e2e975969062833adc4013f249a4b212f5e7b9d5c040bf838d54bb
244
239
  multi_json (1.19.1) sha256=7aefeff8f2c854bf739931a238e4aea64592845e0c0395c8a7d2eea7fdd631b7
245
- nokogiri (1.19.0-arm64-darwin) sha256=0811dfd936d5f6dd3f6d32ef790568bf29b2b7bead9ba68866847b33c9cf5810
246
- nokogiri (1.19.0-x86_64-linux-gnu) sha256=f482b95c713d60031d48c44ce14562f8d2ce31e3a9e8dd0ccb131e9e5a68b58c
240
+ nokogiri (1.19.1-arm64-darwin) sha256=dfe2d337e6700eac47290407c289d56bcf85805d128c1b5a6434ddb79731cb9e
241
+ nokogiri (1.19.1-x86_64-linux-gnu) sha256=1a4902842a186b4f901078e692d12257678e6133858d0566152fe29cdb98456a
247
242
  optimist (3.2.1) sha256=8cf8a0fd69f3aa24ab48885d3a666717c27bc3d9edd6e976e18b9d771e72e34e
248
243
  parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
249
- parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688
244
+ parser (3.3.10.2) sha256=6f60c84aa4bdcedb6d1a2434b738fe8a8136807b6adc8f7f53b97da9bc4e9357
250
245
  patience_diff (1.2.0) sha256=f492094486af02fff4a80070fa6b4d0ebbcf4d42fb38bba29d095eef43f6822c
251
246
  pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6
252
247
  prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193
@@ -255,17 +250,16 @@ CHECKSUMS
255
250
  racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
256
251
  rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
257
252
  rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c
258
- rdoc (7.1.0) sha256=494899df0706c178596ca6e1d50f1b7eb285a9b2aae715be5abd742734f17363
253
+ rdoc (7.2.0) sha256=8650f76cd4009c3b54955eb5d7e3a075c60a57276766ebf36f9085e8c9f23192
259
254
  regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4
260
255
  reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
261
- rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142
262
256
  rspec (3.13.2) sha256=206284a08ad798e61f86d7ca3e376718d52c0bc944626b2349266f239f820587
263
257
  rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
264
258
  rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
265
259
  rspec-mocks (3.13.7) sha256=0979034e64b1d7a838aaaddf12bf065ea4dc40ef3d4c39f01f93ae2c66c62b1c
266
260
  rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
267
261
  rspec_junit_formatter (0.6.0) sha256=40dde674e6ae4e6cc0ff560da25497677e34fefd2338cc467a8972f602b62b15
268
- rubocop (1.84.1) sha256=14cc626f355141f5a2ef53c10a68d66b13bb30639b26370a76559096cc6bcc1a
262
+ rubocop (1.84.2) sha256=5692cea54168f3dc8cb79a6fe95c5424b7ea893c707ad7a4307b0585e88dbf5f
269
263
  rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd
270
264
  rubocop-rake (0.7.1) sha256=3797f2b6810c3e9df7376c26d5f44f3475eda59eb1adc38e6f62ecf027cbae4d
271
265
  rubocop-rspec (3.9.0) sha256=8fa70a3619408237d789aeecfb9beef40576acc855173e60939d63332fdb55e2
@@ -283,7 +277,7 @@ CHECKSUMS
283
277
  unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
284
278
  unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
285
279
  uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
286
- zeitwerk (2.7.4) sha256=2bef90f356bdafe9a6c2bd32bcd804f83a4f9b8bc27f3600fff051eb3edcec8b
280
+ zeitwerk (2.7.5) sha256=d8da92128c09ea6ec62c949011b00ed4a20242b255293dd66bf41545398f73dd
287
281
 
288
282
  BUNDLED WITH
289
283
  4.0.6
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  The cocina-models gem is a Ruby implementation of the Stanford Digital Repository (SDR) data model, which we named "Cocina." The data being modeled is oriented around digital repository objects.
9
9
 
10
- The data model is expressed in an OpenAPI specification that lives in this codebase. Expressing the model in such a spec allows for rich validation (using gems such as `OpenAPIParser` and `committee`). The gem provides a set of generators (see below) to generate Ruby classes from the specification, with modeling provided by dry-struct / dry-types. Together, these provide a way for consumers to validate objects against models and to manipulate those objects.
10
+ The data model is expressed in an OpenAPI specification that lives in this codebase. Expressing the model in such a spec allows for rich validation (using gems such as `json_schemer`). The gem provides a set of generators (see below) to generate Ruby classes from the specification, with modeling provided by dry-struct / dry-types. Together, these provide a way for consumers to validate objects against models and to manipulate those objects.
11
11
 
12
12
  Note that the data model encodes properties as camelCase, which the team believes to be consistent with other HTTP APIs and the original design of the Cocina data model. While using camelCase in Ruby code may look and feel wrong, we did explore automagic conversion between camelCase in the model and snake_case in the Ruby context. We ultimately concluded that we have enough representations of the data model in enough codebases to reasonably worry about data inconsistency problems, none of which we need in our work on SDR.
13
13
 
@@ -20,9 +20,9 @@ Set the PURL url base:
20
20
  Cocina::Models::Mapping::Purl.base_url = Settings.release.purl_base_url
21
21
  ```
22
22
 
23
- ## Generate models from openapi.yml
23
+ ## Generate models from schema.json
24
24
 
25
- Note that only a small subset of openapi is supported. If you are using a new openapi feature or pattern, verify that the model will be generated as expected.
25
+ Note that only a small subset of JSON Schema is supported. If you are using a new JSON Schema feature or pattern, verify that the model will be generated as expected.
26
26
 
27
27
  ### All
28
28
  ```
@@ -46,14 +46,16 @@ exe/generator generate_descriptive_docs
46
46
 
47
47
  ## Testing
48
48
 
49
- The generator is tested via its output when run against `openapi.yml`, viz., the Cocina model classes. Thus, `generate` should be run after any changes to `openapi.yml`.
49
+ The generator is tested via its output when run against `schema.json`, viz., the Cocina model classes. Thus, `generate` should be run after any changes to `schema.json`.
50
50
 
51
- Beyond what is necessary to test the generator, the Cocina model classes are not tested, i.e., they are assumed to be as specified in `openapi.yml`.
51
+ Beyond what is necessary to test the generator, the Cocina model classes are not tested, i.e., they are assumed to be as specified in `schema.json`.
52
52
 
53
53
  ## Testing validation changes
54
54
 
55
55
  If there is a possibility that a model, mapping, or validation change will conflict with some existing objects then [validate-cocina](https://github.com/sul-dlss/dor-services-app/blob/main/bin/validate-cocina) should be used for testing. This must be run on the `sdr-infra` VM since it requires deploying a branch of cocina-models.
56
56
 
57
+ For background on object validation, as it relates to migrating versions, see: https://github.com/sul-dlss/dor-services-app/wiki/Migrating-Cocina
58
+
57
59
  1. Create a cocina-models branch containing the proposed change and push to GitHub.
58
60
  2. On the `sdr-infra` VM, while logged in as the `deploy` user, check out `main`, update the `Gemfile` so that cocina-models references the branch, and `bundle install`.
59
61
  3. Select the appropriate environment vars below - they are set to values in puppet. (first 2 lines are the same; last two lines use different variables)
@@ -87,6 +89,13 @@ export DATABASE_PASSWORD=$DOR_SERVICES_DB_PROD_PWD
87
89
  export RUBYOPT='-W:no-deprecated -W:no-experimental'
88
90
  RAILS_ENV=production bin/validate-cocina -p 8
89
91
  ```
92
+
93
+ To run against head_version and latest_closed_version (when the object is open) only, use the `-l` option for `latest_versions_only`
94
+ ```
95
+ export RUBYOPT='-W:no-deprecated -W:no-experimental'
96
+ RAILS_ENV=production bin/validate-cocina -p 8 -l
97
+ ```
98
+
90
99
  5. Check `validate-cocina.csv` for validation errors.
91
100
 
92
101
  ## Running Reports in DSA
@@ -95,7 +104,7 @@ See https://github.com/sul-dlss/dor-services-app/blob/main/README.md#running-rep
95
104
 
96
105
 
97
106
  ## Releasing a patch change
98
- A patch change is a change that (1) does not affect the data model; (2) does not alter the openapi.yml; and more broadly (3) does not matter if some applications have the change and others do not.
107
+ A patch change is a change that (1) does not affect the data model; (2) does not alter the schema.json; and more broadly (3) does not matter if some applications have the change and others do not.
99
108
 
100
109
  A patch change can be released as part of regular dependency updates or selectively released for individual applications.
101
110
 
@@ -146,13 +155,11 @@ This list of services is known to include:
146
155
 
147
156
  **NOTE**: You can skip step 3A if there have not been any changes to the `cocina-models` OpenAPI spec since the prior release.
148
157
 
149
- The cocina-models gem is used in applications that have an API specification that accepts Cocina models. Make sure that the `openapi.yml` for these two applications includes the `openapi.yml` schema changes made in cocina-models.
150
-
151
- Copy and paste the cocina-models schemas to each project's `openapi.yml`. By convention, these schemas are listed first, followed by the application-specific schemas.
158
+ The cocina-models gem is used in applications that have an API specification that accepts Cocina models.
152
159
 
153
160
  #### Step 3B: Bump gems and create the PRs
154
161
 
155
- If you updated the `openapi.yml` in step 3A, use the same PR for step 3B. Why? When [dor-services-app](https://github.com/sul-dlss/dor-services-app), for example, is updated to use the new models (via the auto-update script), these clients should be updated at the same time or there is risk of models produced by dor-services-app not being acceptable to the clients.
162
+ If you updated the `schema.json` in step 3A, use the same PR for step 3B. Why? When [dor-services-app](https://github.com/sul-dlss/dor-services-app), for example, is updated to use the new models (via the auto-update script), these clients should be updated at the same time or there is risk of models produced by dor-services-app not being acceptable to the clients.
156
163
 
157
164
  1. Perform `bundle update --conservative cocina-models dor-services-client` in the services above and make PRs for those repos if they don't already exist. You may first need to update how these gems are pinned in the `Gemfile` in order to bump them.
158
165
  2. Note that sdr-client is not currently used in these applications, but if it were, would also need to be bumped to the latest release.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'cocina/models'
6
+
7
+ filepath = ARGV[0]
8
+ exit(1) unless JSONSchemer.valid_schema?(Pathname.new(filepath))
@@ -33,7 +33,6 @@ Gem::Specification.new do |spec|
33
33
  spec.add_dependency 'i18n' # for validating BCP 47 language tags, according to RFC 4646
34
34
  spec.add_dependency 'jsonpath' # used for date/time validation
35
35
  spec.add_dependency 'json_schemer', '~> 2.0'
36
- spec.add_dependency 'marc', '~> 1.3'
37
36
  spec.add_dependency 'nokogiri'
38
37
  spec.add_dependency 'super_diff'
39
38
  spec.add_dependency 'thor'
@@ -8,7 +8,7 @@ module Cocina
8
8
  class Generator < Thor # rubocop:disable Metrics/ClassLength
9
9
  include Thor::Actions
10
10
 
11
- class_option :openapi, desc: 'Path of openapi.yml', default: 'openapi.yml'
11
+ class_option :schema, desc: 'Path of schema.json', default: 'schema.json'
12
12
  class_option :output, desc: 'Path for output', default: 'lib/cocina/models'
13
13
 
14
14
  def self.source_root
@@ -96,9 +96,9 @@ module Cocina
96
96
  end
97
97
 
98
98
  def schemas
99
- @schemas ||= Cocina::OpenApiWrapper.parse(YAML.load_file(options[:openapi]), strict_reference_validation: true)
100
- .components
101
- .schemas
99
+ file_content = File.read(options[:schema])
100
+ data = JSON.parse(file_content)
101
+ @schemas ||= Cocina::JsonSchemaWrapper.parse(data, strict_reference_validation: true).schemas
102
102
  end
103
103
 
104
104
  def schema_for(schema_name, lite: false)
@@ -8,6 +8,9 @@ module Cocina
8
8
  @schema_properties ||= (properties + all_of_properties + one_of_properties).uniq(&:key)
9
9
  end
10
10
 
11
+ VALIDATE_TYPES = %w[DRO RequestDRO DROWithMetadata Collection RequestCollection CollectionWithMetadata AdminPolicy
12
+ RequestAdminPolicy AdminPolicyWithMetadata Description RequestDescription].freeze
13
+
11
14
  def generate
12
15
  <<~RUBY
13
16
  # frozen_string_literal: true
@@ -71,7 +74,7 @@ module Cocina
71
74
  end
72
75
 
73
76
  def validatable?
74
- !schema_doc.root.paths.path["/validate/#{schema_doc.name}"].nil? && !lite
77
+ VALIDATE_TYPES.include?(name) && !lite
75
78
  end
76
79
 
77
80
  def properties
@@ -40,6 +40,8 @@ module Cocina
40
40
  def quote(item)
41
41
  return item unless schema_doc.type == 'string'
42
42
 
43
+ return 'nil' if item.nil?
44
+
43
45
  "'#{item}'"
44
46
  end
45
47
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cocina
4
- # Wrapper for OpenAPI support using json_schemer
5
- class OpenApiWrapper
4
+ # Wrapper for JSON Schema support using json_schemer
5
+ class JsonSchemaWrapper
6
6
  class OpenApiError < StandardError; end
7
7
  class MissingReferenceError < OpenApiError; end
8
8
 
@@ -18,33 +18,18 @@ module Cocina
18
18
  new(spec_hash, strict_reference_validation:)
19
19
  end
20
20
 
21
- def components
22
- @components ||= ComponentsWrapper.new(self)
23
- end
24
-
25
21
  attr_reader :schemas, :spec
26
22
 
27
23
  private
28
24
 
29
25
  def initialize_schemas
30
- return unless @spec.dig('components', 'schemas')
26
+ return unless @spec.key?('$defs')
31
27
 
32
- spec['components']['schemas'].each do |name, schema|
28
+ spec.fetch('$defs').each do |name, schema|
33
29
  @schemas[name] = SchemaWrapper.new(schema, name, self)
34
30
  end
35
31
  end
36
32
 
37
- # Wrapper for components section
38
- class ComponentsWrapper
39
- def initialize(parent)
40
- @parent = parent
41
- end
42
-
43
- def schemas
44
- @parent.schemas
45
- end
46
- end
47
-
48
33
  # Wrapper for individual schemas
49
34
  class SchemaWrapper
50
35
  attr_reader :name
@@ -65,7 +50,7 @@ module Cocina
65
50
  @schema_def['oneOf'].map do |schema|
66
51
  if schema['$ref']
67
52
  ref_name = schema['$ref'].split('/').last
68
- SchemaWrapper.new(@parent.spec.dig('components', 'schemas', ref_name), ref_name, @parent)
53
+ SchemaWrapper.new(@parent.spec.dig('$defs', ref_name), ref_name, @parent)
69
54
  else
70
55
  SchemaWrapper.new(schema, nil, @parent)
71
56
  end
@@ -78,7 +63,7 @@ module Cocina
78
63
  @schema_def['allOf'].map do |schema|
79
64
  if schema['$ref']
80
65
  ref_name = schema['$ref'].split('/').last
81
- SchemaWrapper.new(@parent.spec.dig('components', 'schemas', ref_name), ref_name, @parent)
66
+ SchemaWrapper.new(@parent.spec.dig('$defs', ref_name), ref_name, @parent)
82
67
  else
83
68
  SchemaWrapper.new(schema, nil, @parent)
84
69
  end
@@ -89,7 +74,7 @@ module Cocina
89
74
  @schema_def['properties']&.transform_values do |schema|
90
75
  if schema['$ref']
91
76
  ref_name = schema['$ref'].split('/').last
92
- SchemaWrapper.new(@parent.spec.dig('components', 'schemas', ref_name), ref_name, @parent)
77
+ SchemaWrapper.new(@parent.spec.dig('$defs', ref_name), ref_name, @parent)
93
78
  else
94
79
  SchemaWrapper.new(schema, nil, @parent)
95
80
  end
@@ -137,7 +122,7 @@ module Cocina
137
122
 
138
123
  if @schema_def['items']['$ref']
139
124
  ref_name = @schema_def['items']['$ref'].split('/').last
140
- SchemaWrapper.new(@parent.spec.dig('components', 'schemas', ref_name), ref_name, @parent)
125
+ SchemaWrapper.new(@parent.spec.dig('$defs', ref_name), ref_name, @parent)
141
126
  else
142
127
  SchemaWrapper.new(@schema_def['items'], Generator::SchemaArray::GENERIC_ITEMS_NAME, @parent)
143
128
  end
@@ -17,7 +17,7 @@ module Cocina
17
17
  attribute? :useAndReproductionStatement, UseAndReproductionStatement.optional
18
18
  # The license governing reuse of the DRO. Should be an IRI for known licenses (i.e.
19
19
  # CC, RightsStatement.org URI, etc.).
20
- attribute? :license, License.optional.enum('https://www.gnu.org/licenses/agpl.txt', 'https://www.apache.org/licenses/LICENSE-2.0', 'https://opensource.org/licenses/BSD-2-Clause', 'https://opensource.org/licenses/BSD-3-Clause', 'https://creativecommons.org/licenses/by/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode', 'https://creativecommons.org/licenses/by-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-sa/4.0/legalcode', 'https://creativecommons.org/publicdomain/zero/1.0/legalcode', 'https://opensource.org/licenses/cddl1', 'https://www.eclipse.org/legal/epl-2.0', 'https://www.gnu.org/licenses/gpl-3.0-standalone.html', 'https://www.isc.org/downloads/software-support-policy/isc-license/', 'https://www.gnu.org/licenses/lgpl-3.0-standalone.html', 'https://opensource.org/licenses/MIT', 'https://www.mozilla.org/MPL/2.0/', 'https://opendatacommons.org/licenses/by/1-0/', 'http://opendatacommons.org/licenses/odbl/1.0/', 'https://opendatacommons.org/licenses/odbl/1-0/', 'https://creativecommons.org/publicdomain/mark/1.0/', 'https://opendatacommons.org/licenses/pddl/1-0/', 'https://creativecommons.org/licenses/by/3.0/legalcode', 'https://creativecommons.org/licenses/by-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nd/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode', 'https://cocina.sul.stanford.edu/licenses/none')
20
+ attribute? :license, License.optional.enum(nil, 'https://www.gnu.org/licenses/agpl.txt', 'https://www.apache.org/licenses/LICENSE-2.0', 'https://opensource.org/licenses/BSD-2-Clause', 'https://opensource.org/licenses/BSD-3-Clause', 'https://creativecommons.org/licenses/by/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode', 'https://creativecommons.org/licenses/by-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-sa/4.0/legalcode', 'https://creativecommons.org/publicdomain/zero/1.0/legalcode', 'https://opensource.org/licenses/cddl1', 'https://www.eclipse.org/legal/epl-2.0', 'https://www.gnu.org/licenses/gpl-3.0-standalone.html', 'https://www.isc.org/downloads/software-support-policy/isc-license/', 'https://www.gnu.org/licenses/lgpl-3.0-standalone.html', 'https://opensource.org/licenses/MIT', 'https://www.mozilla.org/MPL/2.0/', 'https://opendatacommons.org/licenses/by/1-0/', 'http://opendatacommons.org/licenses/odbl/1.0/', 'https://opendatacommons.org/licenses/odbl/1-0/', 'https://creativecommons.org/publicdomain/mark/1.0/', 'https://opendatacommons.org/licenses/pddl/1-0/', 'https://creativecommons.org/licenses/by/3.0/legalcode', 'https://creativecommons.org/licenses/by-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nd/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode', 'https://cocina.sul.stanford.edu/licenses/none')
21
21
  # Access level.
22
22
  # Validation of this property is relaxed. See the openapi for full validation.
23
23
  attribute? :view, Types::Strict::String.optional.default('dark')
@@ -10,7 +10,7 @@ module Cocina
10
10
  # Download access level.
11
11
  attribute :download, Types::Strict::String.enum('none')
12
12
  # Not used for this access type, must be null.
13
- attribute? :location, Types::Strict::String.optional.enum('')
13
+ attribute? :location, Types::Strict::String.optional.enum(nil)
14
14
  attribute? :controlledDigitalLending, Types::Strict::Bool.default(false).enum(false)
15
15
  end
16
16
  end
@@ -17,7 +17,7 @@ module Cocina
17
17
  attribute? :useAndReproductionStatement, UseAndReproductionStatement.optional
18
18
  # The license governing reuse of the DRO. Should be an IRI for known licenses (i.e.
19
19
  # CC, RightsStatement.org URI, etc.).
20
- attribute? :license, License.optional.enum('https://www.gnu.org/licenses/agpl.txt', 'https://www.apache.org/licenses/LICENSE-2.0', 'https://opensource.org/licenses/BSD-2-Clause', 'https://opensource.org/licenses/BSD-3-Clause', 'https://creativecommons.org/licenses/by/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode', 'https://creativecommons.org/licenses/by-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-sa/4.0/legalcode', 'https://creativecommons.org/publicdomain/zero/1.0/legalcode', 'https://opensource.org/licenses/cddl1', 'https://www.eclipse.org/legal/epl-2.0', 'https://www.gnu.org/licenses/gpl-3.0-standalone.html', 'https://www.isc.org/downloads/software-support-policy/isc-license/', 'https://www.gnu.org/licenses/lgpl-3.0-standalone.html', 'https://opensource.org/licenses/MIT', 'https://www.mozilla.org/MPL/2.0/', 'https://opendatacommons.org/licenses/by/1-0/', 'http://opendatacommons.org/licenses/odbl/1.0/', 'https://opendatacommons.org/licenses/odbl/1-0/', 'https://creativecommons.org/publicdomain/mark/1.0/', 'https://opendatacommons.org/licenses/pddl/1-0/', 'https://creativecommons.org/licenses/by/3.0/legalcode', 'https://creativecommons.org/licenses/by-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nd/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode', 'https://cocina.sul.stanford.edu/licenses/none')
20
+ attribute? :license, License.optional.enum(nil, 'https://www.gnu.org/licenses/agpl.txt', 'https://www.apache.org/licenses/LICENSE-2.0', 'https://opensource.org/licenses/BSD-2-Clause', 'https://opensource.org/licenses/BSD-3-Clause', 'https://creativecommons.org/licenses/by/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode', 'https://creativecommons.org/licenses/by-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-sa/4.0/legalcode', 'https://creativecommons.org/publicdomain/zero/1.0/legalcode', 'https://opensource.org/licenses/cddl1', 'https://www.eclipse.org/legal/epl-2.0', 'https://www.gnu.org/licenses/gpl-3.0-standalone.html', 'https://www.isc.org/downloads/software-support-policy/isc-license/', 'https://www.gnu.org/licenses/lgpl-3.0-standalone.html', 'https://opensource.org/licenses/MIT', 'https://www.mozilla.org/MPL/2.0/', 'https://opendatacommons.org/licenses/by/1-0/', 'http://opendatacommons.org/licenses/odbl/1.0/', 'https://opendatacommons.org/licenses/odbl/1-0/', 'https://creativecommons.org/publicdomain/mark/1.0/', 'https://opendatacommons.org/licenses/pddl/1-0/', 'https://creativecommons.org/licenses/by/3.0/legalcode', 'https://creativecommons.org/licenses/by-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nd/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode', 'https://cocina.sul.stanford.edu/licenses/none')
21
21
  end
22
22
  end
23
23
  end
@@ -8,7 +8,7 @@ module Cocina
8
8
  # Download access level.
9
9
  attribute :download, Types::Strict::String.enum('none')
10
10
  # Not used for this access type, must be null.
11
- attribute? :location, Types::Strict::String.optional.enum('')
11
+ attribute? :location, Types::Strict::String.optional.enum(nil)
12
12
  # Available for controlled digital lending.
13
13
  attribute? :controlledDigitalLending, Types::Strict::Bool.default(false)
14
14
  end
@@ -8,7 +8,7 @@ module Cocina
8
8
  # Download access level.
9
9
  attribute? :download, Types::Strict::String.default('none').enum('none')
10
10
  # Not used for this access type, must be null.
11
- attribute? :location, Types::Strict::String.optional.enum('')
11
+ attribute? :location, Types::Strict::String.optional.enum(nil)
12
12
  attribute? :controlledDigitalLending, Types::Strict::Bool.default(false).enum(false)
13
13
  end
14
14
  end
@@ -26,7 +26,7 @@ module Cocina
26
26
  attribute? :useAndReproductionStatement, UseAndReproductionStatement.optional
27
27
  # The license governing reuse of the DRO. Should be an IRI for known licenses (i.e.
28
28
  # CC, RightsStatement.org URI, etc.).
29
- attribute? :license, License.optional.enum('https://www.gnu.org/licenses/agpl.txt', 'https://www.apache.org/licenses/LICENSE-2.0', 'https://opensource.org/licenses/BSD-2-Clause', 'https://opensource.org/licenses/BSD-3-Clause', 'https://creativecommons.org/licenses/by/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode', 'https://creativecommons.org/licenses/by-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-sa/4.0/legalcode', 'https://creativecommons.org/publicdomain/zero/1.0/legalcode', 'https://opensource.org/licenses/cddl1', 'https://www.eclipse.org/legal/epl-2.0', 'https://www.gnu.org/licenses/gpl-3.0-standalone.html', 'https://www.isc.org/downloads/software-support-policy/isc-license/', 'https://www.gnu.org/licenses/lgpl-3.0-standalone.html', 'https://opensource.org/licenses/MIT', 'https://www.mozilla.org/MPL/2.0/', 'https://opendatacommons.org/licenses/by/1-0/', 'http://opendatacommons.org/licenses/odbl/1.0/', 'https://opendatacommons.org/licenses/odbl/1-0/', 'https://creativecommons.org/publicdomain/mark/1.0/', 'https://opendatacommons.org/licenses/pddl/1-0/', 'https://creativecommons.org/licenses/by/3.0/legalcode', 'https://creativecommons.org/licenses/by-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nd/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode', 'https://cocina.sul.stanford.edu/licenses/none')
29
+ attribute? :license, License.optional.enum(nil, 'https://www.gnu.org/licenses/agpl.txt', 'https://www.apache.org/licenses/LICENSE-2.0', 'https://opensource.org/licenses/BSD-2-Clause', 'https://opensource.org/licenses/BSD-3-Clause', 'https://creativecommons.org/licenses/by/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode', 'https://creativecommons.org/licenses/by-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-sa/4.0/legalcode', 'https://creativecommons.org/publicdomain/zero/1.0/legalcode', 'https://opensource.org/licenses/cddl1', 'https://www.eclipse.org/legal/epl-2.0', 'https://www.gnu.org/licenses/gpl-3.0-standalone.html', 'https://www.isc.org/downloads/software-support-policy/isc-license/', 'https://www.gnu.org/licenses/lgpl-3.0-standalone.html', 'https://opensource.org/licenses/MIT', 'https://www.mozilla.org/MPL/2.0/', 'https://opendatacommons.org/licenses/by/1-0/', 'http://opendatacommons.org/licenses/odbl/1.0/', 'https://opendatacommons.org/licenses/odbl/1-0/', 'https://creativecommons.org/publicdomain/mark/1.0/', 'https://opendatacommons.org/licenses/pddl/1-0/', 'https://creativecommons.org/licenses/by/3.0/legalcode', 'https://creativecommons.org/licenses/by-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nd/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode', 'https://cocina.sul.stanford.edu/licenses/none')
30
30
  end
31
31
  end
32
32
  end
@@ -27,7 +27,7 @@ module Cocina
27
27
  # BCP 47 language tag: https://www.rfc-editor.org/rfc/rfc4646.txt -- other applications
28
28
  # (like media players) expect language codes of this format, see e.g. https://videojs.com/guides/text-tracks/#srclang
29
29
  attribute? :languageTag, LanguageTag.optional
30
- # Use for the File (e.g. "transcription" for OCR).
30
+ # Use for the File (e.g. 'transcription' for OCR).
31
31
  attribute? :use, FileUse.optional
32
32
  # Indicates if the text (OCR/captioning) was generated by SDR.
33
33
  attribute? :sdrGeneratedText, Types::Strict::Bool.default(false)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- # Use for the File (e.g. "transcription" for OCR).
5
+ # Use for the File (e.g. 'transcription' for OCR).
6
6
  FileUse = Types::String
7
7
  end
8
8
  end
@@ -4,6 +4,6 @@ module Cocina
4
4
  module Models
5
5
  # The license governing reuse of the DRO. Should be an IRI for known licenses (i.e.
6
6
  # CC, RightsStatement.org URI, etc.).
7
- License = Types::String.enum('https://www.gnu.org/licenses/agpl.txt', 'https://www.apache.org/licenses/LICENSE-2.0', 'https://opensource.org/licenses/BSD-2-Clause', 'https://opensource.org/licenses/BSD-3-Clause', 'https://creativecommons.org/licenses/by/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode', 'https://creativecommons.org/licenses/by-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-sa/4.0/legalcode', 'https://creativecommons.org/publicdomain/zero/1.0/legalcode', 'https://opensource.org/licenses/cddl1', 'https://www.eclipse.org/legal/epl-2.0', 'https://www.gnu.org/licenses/gpl-3.0-standalone.html', 'https://www.isc.org/downloads/software-support-policy/isc-license/', 'https://www.gnu.org/licenses/lgpl-3.0-standalone.html', 'https://opensource.org/licenses/MIT', 'https://www.mozilla.org/MPL/2.0/', 'https://opendatacommons.org/licenses/by/1-0/', 'http://opendatacommons.org/licenses/odbl/1.0/', 'https://opendatacommons.org/licenses/odbl/1-0/', 'https://creativecommons.org/publicdomain/mark/1.0/', 'https://opendatacommons.org/licenses/pddl/1-0/', 'https://creativecommons.org/licenses/by/3.0/legalcode', 'https://creativecommons.org/licenses/by-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nd/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode', 'https://cocina.sul.stanford.edu/licenses/none')
7
+ License = Types::String.enum(nil, 'https://www.gnu.org/licenses/agpl.txt', 'https://www.apache.org/licenses/LICENSE-2.0', 'https://opensource.org/licenses/BSD-2-Clause', 'https://opensource.org/licenses/BSD-3-Clause', 'https://creativecommons.org/licenses/by/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode', 'https://creativecommons.org/licenses/by-nd/4.0/legalcode', 'https://creativecommons.org/licenses/by-sa/4.0/legalcode', 'https://creativecommons.org/publicdomain/zero/1.0/legalcode', 'https://opensource.org/licenses/cddl1', 'https://www.eclipse.org/legal/epl-2.0', 'https://www.gnu.org/licenses/gpl-3.0-standalone.html', 'https://www.isc.org/downloads/software-support-policy/isc-license/', 'https://www.gnu.org/licenses/lgpl-3.0-standalone.html', 'https://opensource.org/licenses/MIT', 'https://www.mozilla.org/MPL/2.0/', 'https://opendatacommons.org/licenses/by/1-0/', 'http://opendatacommons.org/licenses/odbl/1.0/', 'https://opendatacommons.org/licenses/odbl/1-0/', 'https://creativecommons.org/publicdomain/mark/1.0/', 'https://opendatacommons.org/licenses/pddl/1-0/', 'https://creativecommons.org/licenses/by/3.0/legalcode', 'https://creativecommons.org/licenses/by-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nd/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-sa/3.0/legalcode', 'https://creativecommons.org/licenses/by-nc-nd/3.0/legalcode', 'https://cocina.sul.stanford.edu/licenses/none')
8
8
  end
9
9
  end
@@ -7,7 +7,7 @@ module Cocina
7
7
  attribute :view, Types::Strict::String.enum('location-based')
8
8
  # Download access level.
9
9
  attribute :download, Types::Strict::String.enum('location-based', 'none')
10
- # If access or download is "location-based", which location should have access.
10
+ # If access or download is 'location-based', which location should have access.
11
11
  attribute :location, Types::Strict::String.enum('spec', 'music', 'ars', 'art', 'hoover', 'm&m')
12
12
  attribute? :controlledDigitalLending, Types::Strict::Bool.default(false).enum(false)
13
13
  end
@@ -77,7 +77,7 @@ module Cocina
77
77
 
78
78
  def language_applies_to
79
79
  value = language_element['objectPart']
80
- [value: value] if value.present?
80
+ [{value: value}] if value.present?
81
81
  end
82
82
 
83
83
  def language_source_for(code_language_term, text_language_term)
@@ -17,7 +17,7 @@ module Cocina
17
17
  # (like media players) expect language codes of this format, see e.g. https://videojs.com/guides/text-tracks/#srclang
18
18
  attribute? :languageTag, LanguageTag.optional
19
19
  attribute? :externalIdentifier, Types::Strict::String
20
- # Use for the File (e.g. "transcription" for OCR).
20
+ # Use for the File (e.g. 'transcription' for OCR).
21
21
  attribute? :use, FileUse.optional
22
22
  # Indicates if the text (OCR/captioning) was generated by SDR.
23
23
  attribute? :sdrGeneratedText, Types::Strict::Bool.default(false)
@@ -8,7 +8,7 @@ module Cocina
8
8
  # Download access level.
9
9
  attribute :download, Types::Strict::String.enum('stanford')
10
10
  # Not used for this access type, must be null.
11
- attribute? :location, Types::Strict::String.optional.enum('')
11
+ attribute? :location, Types::Strict::String.optional.enum(nil)
12
12
  attribute? :controlledDigitalLending, Types::Strict::Bool.default(false).enum(false)
13
13
  end
14
14
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ module Validators
6
+ # Perform validation against JSON schema
7
+ class JsonSchemaValidator
8
+ def self.validate(clazz, attributes)
9
+ return unless clazz.name
10
+
11
+ method_name = clazz.name.split('::').last
12
+
13
+ attributes['cocinaVersion'] = Cocina::Models::VERSION if %w[DRO RequestDRO AdminPolicy RequestAdminPolicy Collection RequestCollection DROWithMetadata].include? method_name
14
+
15
+ errors = openapi.ref("#/components/schemas/#{method_name}").validate(attributes.as_json).to_a
16
+ return unless errors.any?
17
+
18
+ raise ValidationError, "When validating #{method_name}: " + errors.map { |e| e['error'] }.uniq.join(', ')
19
+ end
20
+
21
+ # @return [Hash] a hash representation of the openapi document
22
+ def self.document
23
+ @document ||= YAML.load_file(openapi_path)
24
+ end
25
+
26
+ # @return [JSONSchemer::OpenAPI]
27
+ def self.openapi
28
+ @openapi ||= JSONSchemer.openapi(YAML.load_file(openapi_path))
29
+ end
30
+ private_class_method :openapi
31
+
32
+ def self.openapi_path
33
+ ::File.expand_path('../../../../openapi.yml', __dir__)
34
+ end
35
+ private_class_method :openapi_path
36
+ end
37
+ end
38
+ end
39
+ end