ortfodb 1.4.1 → 1.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14c03de3d328180d569b9a5b199e51527d337e8c7da107d6f4615272190f9ffe
4
- data.tar.gz: 58414173953c5c279e36c987983522c3b0e7c4b9b602836987b37cf6b62895c7
3
+ metadata.gz: dfdb5e23f5915036479e7ddb21929c3612369d72491679f435387dafe64e0332
4
+ data.tar.gz: 1bd20725c89cebcba8be97922d0ec994506efaa4d77dae3a11c1915b741ec903
5
5
  SHA512:
6
- metadata.gz: 225c011268f5fc27be85a6fbafb4bf2fc4893f33944676ebaf4cead5fc344effac33cafe3ca220fa419e7093e5398ca90bc3c37b435878a1e7cdb01fcde3c4fb
7
- data.tar.gz: 1ab876a11eb09f2d4e2f9fb6035febec9819ce69e451758d3dc1e5a8af4789c1d183017d559d2bda5b6d8e9c6a1bb688637eeed9f24f4c50ab7abcb87b67f65c
6
+ metadata.gz: 5cdc18ef72d256b60d0485c0688d8fc6536eaa7a4722e6f909cff82c6e13fa6dd872cf266ec5f7182324f4a2f824b269fdf68ebc6887b1780bd3a912c081ce19
7
+ data.tar.gz: 7932d8d198277da4cecd808053f7b6c3405681309472a3c49ca3f1bc2fa8ab8626c67ce26faa0c9936049b8e646ea11fd793d13a65f7cc6832d868d4d8eee716
@@ -4,7 +4,7 @@
4
4
  # To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do:
5
5
  #
6
6
  # configuration = Configuration.from_json! "{…}"
7
- # puts configuration.technologies.repository
7
+ # puts configuration.technologies&.repository
8
8
  #
9
9
  # If from_json! succeeds, the value returned matches the schema.
10
10
 
@@ -22,7 +22,7 @@ module Ortfodb
22
22
  String = Strict::String
23
23
  end
24
24
 
25
- class ExtractColors < Dry::Struct
25
+ class ExtractColorsConfiguration < Dry::Struct
26
26
  attribute :default_files, Types.Array(Types::String)
27
27
  attribute :enabled, Types::Bool
28
28
  attribute :extract, Types.Array(Types::String)
@@ -53,7 +53,7 @@ module Ortfodb
53
53
  end
54
54
  end
55
55
 
56
- class MakeGifs < Dry::Struct
56
+ class MakeGIFSConfiguration < Dry::Struct
57
57
  attribute :enabled, Types::Bool
58
58
  attribute :file_name_template, Types::String
59
59
 
@@ -81,7 +81,7 @@ module Ortfodb
81
81
  end
82
82
  end
83
83
 
84
- class MakeThumbnails < Dry::Struct
84
+ class MakeThumbnailsConfiguration < Dry::Struct
85
85
  attribute :enabled, Types::Bool
86
86
  attribute :file_name_template, Types::String
87
87
  attribute :input_file, Types::String
@@ -115,7 +115,9 @@ module Ortfodb
115
115
  end
116
116
  end
117
117
 
118
- class Media < Dry::Struct
118
+ class MediaConfiguration < Dry::Struct
119
+
120
+ # Path to the media directory.
119
121
  attribute :at, Types::String
120
122
 
121
123
  def self.from_dynamic!(d)
@@ -140,7 +142,9 @@ module Ortfodb
140
142
  end
141
143
  end
142
144
 
143
- class Tags < Dry::Struct
145
+ class TagsConfiguration < Dry::Struct
146
+
147
+ # Path to file describing all tags.
144
148
  attribute :repository, Types::String
145
149
 
146
150
  def self.from_dynamic!(d)
@@ -165,7 +169,9 @@ module Ortfodb
165
169
  end
166
170
  end
167
171
 
168
- class Technologies < Dry::Struct
172
+ class TechnologiesConfiguration < Dry::Struct
173
+
174
+ # Path to file describing all technologies.
169
175
  attribute :repository, Types::String
170
176
 
171
177
  def self.from_dynamic!(d)
@@ -192,36 +198,34 @@ module Ortfodb
192
198
 
193
199
  # Configuration represents what the ortfodb.yaml configuration file describes.
194
200
  class Configuration < Dry::Struct
195
- attribute :build_metadata_file, Types::String
196
201
 
197
202
  # Exporter-specific configuration. Maps exporter names to their configuration.
198
203
  attribute :exporters, Types::Hash.meta(of: Types::Hash.meta(of: Types::Any)).optional
199
204
 
200
- attribute :extract_colors, ExtractColors
201
- attribute :make_gifs, MakeGifs
202
- attribute :make_thumbnails, MakeThumbnails
203
- attribute :media, Media
205
+ attribute :extract_colors, ExtractColorsConfiguration.optional
206
+ attribute :make_gifs, MakeGIFSConfiguration.optional
207
+ attribute :make_thumbnails, MakeThumbnailsConfiguration.optional
208
+ attribute :media, MediaConfiguration.optional
204
209
 
205
210
  # Path to the directory containing all projects. Must be absolute.
206
211
  attribute :projects_at, Types::String
207
212
 
208
213
  attribute :scattered_mode_folder, Types::String
209
- attribute :tags, Tags
210
- attribute :technologies, Technologies
214
+ attribute :tags, TagsConfiguration.optional
215
+ attribute :technologies, TechnologiesConfiguration.optional
211
216
 
212
217
  def self.from_dynamic!(d)
213
218
  d = Types::Hash[d]
214
219
  new(
215
- build_metadata_file: d.fetch("build metadata file"),
216
220
  exporters: Types::Hash.optional[d["exporters"]]&.map { |k, v| [k, Types::Hash[v].map { |k, v| [k, Types::Any[v]] }.to_h] }&.to_h,
217
- extract_colors: ExtractColors.from_dynamic!(d.fetch("extract colors")),
218
- make_gifs: MakeGifs.from_dynamic!(d.fetch("make gifs")),
219
- make_thumbnails: MakeThumbnails.from_dynamic!(d.fetch("make thumbnails")),
220
- media: Media.from_dynamic!(d.fetch("media")),
221
+ extract_colors: d["extract colors"] ? ExtractColorsConfiguration.from_dynamic!(d["extract colors"]) : nil,
222
+ make_gifs: d["make gifs"] ? MakeGIFSConfiguration.from_dynamic!(d["make gifs"]) : nil,
223
+ make_thumbnails: d["make thumbnails"] ? MakeThumbnailsConfiguration.from_dynamic!(d["make thumbnails"]) : nil,
224
+ media: d["media"] ? MediaConfiguration.from_dynamic!(d["media"]) : nil,
221
225
  projects_at: d.fetch("projects at"),
222
226
  scattered_mode_folder: d.fetch("scattered mode folder"),
223
- tags: Tags.from_dynamic!(d.fetch("tags")),
224
- technologies: Technologies.from_dynamic!(d.fetch("technologies")),
227
+ tags: d["tags"] ? TagsConfiguration.from_dynamic!(d["tags"]) : nil,
228
+ technologies: d["technologies"] ? TechnologiesConfiguration.from_dynamic!(d["technologies"]) : nil,
225
229
  )
226
230
  end
227
231
 
@@ -231,16 +235,15 @@ module Ortfodb
231
235
 
232
236
  def to_dynamic
233
237
  {
234
- "build metadata file" => build_metadata_file,
235
238
  "exporters" => exporters,
236
- "extract colors" => extract_colors.to_dynamic,
237
- "make gifs" => make_gifs.to_dynamic,
238
- "make thumbnails" => make_thumbnails.to_dynamic,
239
- "media" => media.to_dynamic,
239
+ "extract colors" => extract_colors&.to_dynamic,
240
+ "make gifs" => make_gifs&.to_dynamic,
241
+ "make thumbnails" => make_thumbnails&.to_dynamic,
242
+ "media" => media&.to_dynamic,
240
243
  "projects at" => projects_at,
241
244
  "scattered mode folder" => scattered_mode_folder,
242
- "tags" => tags.to_dynamic,
243
- "technologies" => technologies.to_dynamic,
245
+ "tags" => tags&.to_dynamic,
246
+ "technologies" => technologies&.to_dynamic,
244
247
  }
245
248
  end
246
249
 
@@ -24,7 +24,7 @@ module Ortfodb
24
24
  end
25
25
 
26
26
  # MediaAttributes stores which HTML attributes should be added to the media.
27
- class Attributes < Dry::Struct
27
+ class MediaAttributes < Dry::Struct
28
28
 
29
29
  # Controlled with attribute character > (adds)
30
30
  attribute :autoplay, Types::Bool
@@ -33,7 +33,7 @@ module Ortfodb
33
33
  attribute :controls, Types::Bool
34
34
 
35
35
  # Controlled with attribute character ~ (adds)
36
- attribute :attributes_loop, Types::Bool
36
+ attribute :media_attributes_loop, Types::Bool
37
37
 
38
38
  # Controlled with attribute character > (adds)
39
39
  attribute :muted, Types::Bool
@@ -44,11 +44,11 @@ module Ortfodb
44
44
  def self.from_dynamic!(d)
45
45
  d = Types::Hash[d]
46
46
  new(
47
- autoplay: d.fetch("autoplay"),
48
- controls: d.fetch("controls"),
49
- attributes_loop: d.fetch("loop"),
50
- muted: d.fetch("muted"),
51
- playsinline: d.fetch("playsinline"),
47
+ autoplay: d.fetch("autoplay"),
48
+ controls: d.fetch("controls"),
49
+ media_attributes_loop: d.fetch("loop"),
50
+ muted: d.fetch("muted"),
51
+ playsinline: d.fetch("playsinline"),
52
52
  )
53
53
  end
54
54
 
@@ -60,7 +60,7 @@ module Ortfodb
60
60
  {
61
61
  "autoplay" => autoplay,
62
62
  "controls" => controls,
63
- "loop" => attributes_loop,
63
+ "loop" => media_attributes_loop,
64
64
  "muted" => muted,
65
65
  "playsinline" => playsinline,
66
66
  }
@@ -72,7 +72,7 @@ module Ortfodb
72
72
  end
73
73
 
74
74
  # ColorPalette reprensents the object in a Work's metadata.colors.
75
- class Colors < Dry::Struct
75
+ class ColorPalette < Dry::Struct
76
76
  attribute :primary, Types::String
77
77
  attribute :secondary, Types::String
78
78
  attribute :tertiary, Types::String
@@ -104,7 +104,7 @@ module Ortfodb
104
104
  end
105
105
 
106
106
  # ImageDimensions represents metadata about a media as it's extracted from its file.
107
- class Dimensions < Dry::Struct
107
+ class ImageDimensions < Dry::Struct
108
108
 
109
109
  # width / height
110
110
  attribute :aspect_ratio, Types::Double
@@ -141,7 +141,7 @@ module Ortfodb
141
141
  end
142
142
  end
143
143
 
144
- class Thumbnails < Dry::Struct
144
+ class ThumbnailsMap < Dry::Struct
145
145
 
146
146
  def self.from_dynamic!(d)
147
147
  d = Types::Hash[d]
@@ -163,27 +163,32 @@ module Ortfodb
163
163
  end
164
164
  end
165
165
 
166
- class BlockElement < Dry::Struct
166
+ class ContentBlock < Dry::Struct
167
167
  attribute :alt, Types::String
168
168
 
169
169
  # whether the media has been analyzed
170
170
  attribute :analyzed, Types::Bool
171
171
 
172
172
  attribute :anchor, Types::String
173
- attribute :attributes, Attributes
173
+ attribute :attributes, MediaAttributes
174
174
  attribute :caption, Types::String
175
- attribute :colors, Colors
175
+ attribute :colors, ColorPalette
176
176
 
177
177
  # html
178
178
  attribute :content, Types::String
179
179
 
180
180
  attribute :content_type, Types::String
181
- attribute :dimensions, Dimensions
181
+ attribute :dimensions, ImageDimensions
182
182
  attribute :dist_source, Types::String
183
183
 
184
184
  # in seconds
185
185
  attribute :duration, Types::Double
186
186
 
187
+ # Hash of the media file, used for caching purposes. Could also serve as an integrity
188
+ # check.
189
+ # The value is the MD5 hash, base64-encoded.
190
+ attribute :content_block_hash, Types::String
191
+
187
192
  attribute :has_sound, Types::Bool
188
193
  attribute :id, Types::String
189
194
  attribute :index, Types::Integer
@@ -193,39 +198,40 @@ module Ortfodb
193
198
  # in bytes
194
199
  attribute :size, Types::Integer
195
200
 
196
- attribute :text, Types::String
197
- attribute :thumbnails, Thumbnails
198
- attribute :thumbnails_built_at, Types::String
199
- attribute :title, Types::String
200
- attribute :database_schema_type, Types::String
201
- attribute :url, Types::String
201
+ attribute :text, Types::String
202
+ attribute :thumbnails, ThumbnailsMap
203
+ attribute :thumbnails_built_at, Types::String
204
+ attribute :title, Types::String
205
+ attribute :content_block_type, Types::String
206
+ attribute :url, Types::String
202
207
 
203
208
  def self.from_dynamic!(d)
204
209
  d = Types::Hash[d]
205
210
  new(
206
- alt: d.fetch("alt"),
207
- analyzed: d.fetch("analyzed"),
208
- anchor: d.fetch("anchor"),
209
- attributes: Attributes.from_dynamic!(d.fetch("attributes")),
210
- caption: d.fetch("caption"),
211
- colors: Colors.from_dynamic!(d.fetch("colors")),
212
- content: d.fetch("content"),
213
- content_type: d.fetch("contentType"),
214
- dimensions: Dimensions.from_dynamic!(d.fetch("dimensions")),
215
- dist_source: d.fetch("distSource"),
216
- duration: d.fetch("duration"),
217
- has_sound: d.fetch("hasSound"),
218
- id: d.fetch("id"),
219
- index: d.fetch("index"),
220
- online: d.fetch("online"),
221
- relative_source: d.fetch("relativeSource"),
222
- size: d.fetch("size"),
223
- text: d.fetch("text"),
224
- thumbnails: Thumbnails.from_dynamic!(d.fetch("thumbnails")),
225
- thumbnails_built_at: d.fetch("thumbnailsBuiltAt"),
226
- title: d.fetch("title"),
227
- database_schema_type: d.fetch("type"),
228
- url: d.fetch("url"),
211
+ alt: d.fetch("alt"),
212
+ analyzed: d.fetch("analyzed"),
213
+ anchor: d.fetch("anchor"),
214
+ attributes: MediaAttributes.from_dynamic!(d.fetch("attributes")),
215
+ caption: d.fetch("caption"),
216
+ colors: ColorPalette.from_dynamic!(d.fetch("colors")),
217
+ content: d.fetch("content"),
218
+ content_type: d.fetch("contentType"),
219
+ dimensions: ImageDimensions.from_dynamic!(d.fetch("dimensions")),
220
+ dist_source: d.fetch("distSource"),
221
+ duration: d.fetch("duration"),
222
+ content_block_hash: d.fetch("hash"),
223
+ has_sound: d.fetch("hasSound"),
224
+ id: d.fetch("id"),
225
+ index: d.fetch("index"),
226
+ online: d.fetch("online"),
227
+ relative_source: d.fetch("relativeSource"),
228
+ size: d.fetch("size"),
229
+ text: d.fetch("text"),
230
+ thumbnails: ThumbnailsMap.from_dynamic!(d.fetch("thumbnails")),
231
+ thumbnails_built_at: d.fetch("thumbnailsBuiltAt"),
232
+ title: d.fetch("title"),
233
+ content_block_type: d.fetch("type"),
234
+ url: d.fetch("url"),
229
235
  )
230
236
  end
231
237
 
@@ -246,6 +252,7 @@ module Ortfodb
246
252
  "dimensions" => dimensions.to_dynamic,
247
253
  "distSource" => dist_source,
248
254
  "duration" => duration,
255
+ "hash" => content_block_hash,
249
256
  "hasSound" => has_sound,
250
257
  "id" => id,
251
258
  "index" => index,
@@ -256,7 +263,7 @@ module Ortfodb
256
263
  "thumbnails" => thumbnails.to_dynamic,
257
264
  "thumbnailsBuiltAt" => thumbnails_built_at,
258
265
  "title" => title,
259
- "type" => database_schema_type,
266
+ "type" => content_block_type,
260
267
  "url" => url,
261
268
  }
262
269
  end
@@ -266,19 +273,21 @@ module Ortfodb
266
273
  end
267
274
  end
268
275
 
269
- class ContentValue < Dry::Struct
270
- attribute :blocks, Types.Array(BlockElement)
271
- attribute :footnotes, Types::Hash.meta(of: Types::String)
272
- attribute :layout, Types.Array(Types.Array(Types::String))
273
- attribute :title, Types::String
276
+ class LocalizedContent < Dry::Struct
277
+ attribute :abbreviations, Types::Hash.meta(of: Types::String)
278
+ attribute :blocks, Types.Array(ContentBlock)
279
+ attribute :footnotes, Types::Hash.meta(of: Types::String)
280
+ attribute :layout, Types.Array(Types.Array(Types::String))
281
+ attribute :title, Types::String
274
282
 
275
283
  def self.from_dynamic!(d)
276
284
  d = Types::Hash[d]
277
285
  new(
278
- blocks: d.fetch("blocks").map { |x| BlockElement.from_dynamic!(x) },
279
- footnotes: Types::Hash[d.fetch("footnotes")].map { |k, v| [k, Types::String[v]] }.to_h,
280
- layout: d.fetch("layout"),
281
- title: d.fetch("title"),
286
+ abbreviations: Types::Hash[d.fetch("abbreviations")].map { |k, v| [k, Types::String[v]] }.to_h,
287
+ blocks: d.fetch("blocks").map { |x| ContentBlock.from_dynamic!(x) },
288
+ footnotes: Types::Hash[d.fetch("footnotes")].map { |k, v| [k, Types::String[v]] }.to_h,
289
+ layout: d.fetch("layout"),
290
+ title: d.fetch("title"),
282
291
  )
283
292
  end
284
293
 
@@ -288,10 +297,11 @@ module Ortfodb
288
297
 
289
298
  def to_dynamic
290
299
  {
291
- "blocks" => blocks.map { |x| x.to_dynamic },
292
- "footnotes" => footnotes,
293
- "layout" => layout,
294
- "title" => title,
300
+ "abbreviations" => abbreviations,
301
+ "blocks" => blocks.map { |x| x.to_dynamic },
302
+ "footnotes" => footnotes,
303
+ "layout" => layout,
304
+ "title" => title,
295
305
  }
296
306
  end
297
307
 
@@ -300,7 +310,7 @@ module Ortfodb
300
310
  end
301
311
  end
302
312
 
303
- class DatabaseMetadataClass < Dry::Struct
313
+ class DatabaseMeta < Dry::Struct
304
314
 
305
315
  # Partial is true if the database was not fully built.
306
316
  attribute :partial, Types::Bool
@@ -327,11 +337,11 @@ module Ortfodb
327
337
  end
328
338
  end
329
339
 
330
- class Metadata < Dry::Struct
340
+ class WorkMetadata < Dry::Struct
331
341
  attribute :additional_metadata, Types::Hash.meta(of: Types::Any)
332
342
  attribute :aliases, Types.Array(Types::String)
333
- attribute :colors, Colors
334
- attribute :database_metadata, DatabaseMetadataClass
343
+ attribute :colors, ColorPalette
344
+ attribute :database_metadata, DatabaseMeta
335
345
  attribute :finished, Types::String
336
346
  attribute :made_with, Types.Array(Types::String)
337
347
  attribute :page_background, Types::String
@@ -347,8 +357,8 @@ module Ortfodb
347
357
  new(
348
358
  additional_metadata: Types::Hash[d.fetch("additionalMetadata")].map { |k, v| [k, Types::Any[v]] }.to_h,
349
359
  aliases: d.fetch("aliases"),
350
- colors: Colors.from_dynamic!(d.fetch("colors")),
351
- database_metadata: DatabaseMetadataClass.from_dynamic!(d.fetch("databaseMetadata")),
360
+ colors: ColorPalette.from_dynamic!(d.fetch("colors")),
361
+ database_metadata: DatabaseMeta.from_dynamic!(d.fetch("databaseMetadata")),
352
362
  finished: d.fetch("finished"),
353
363
  made_with: d.fetch("madeWith"),
354
364
  page_background: d.fetch("pageBackground"),
@@ -388,23 +398,23 @@ module Ortfodb
388
398
  end
389
399
  end
390
400
 
391
- # AnalyzedWork represents a complete work, with analyzed mediae.
392
- class DatabaseValue < Dry::Struct
401
+ # Work represents a given work in the database.
402
+ class Work < Dry::Struct
393
403
  attribute :built_at, Types::String
394
- attribute :content, Types::Hash.meta(of: ContentValue)
404
+ attribute :content, Types::Hash.meta(of: LocalizedContent)
395
405
  attribute :description_hash, Types::String
396
406
  attribute :id, Types::String
397
- attribute :metadata, Metadata
407
+ attribute :metadata, WorkMetadata
398
408
  attribute :partial, Types::Bool
399
409
 
400
410
  def self.from_dynamic!(d)
401
411
  d = Types::Hash[d]
402
412
  new(
403
413
  built_at: d.fetch("builtAt"),
404
- content: Types::Hash[d.fetch("content")].map { |k, v| [k, ContentValue.from_dynamic!(v)] }.to_h,
414
+ content: Types::Hash[d.fetch("content")].map { |k, v| [k, LocalizedContent.from_dynamic!(v)] }.to_h,
405
415
  description_hash: d.fetch("descriptionHash"),
406
416
  id: d.fetch("id"),
407
- metadata: Metadata.from_dynamic!(d.fetch("metadata")),
417
+ metadata: WorkMetadata.from_dynamic!(d.fetch("metadata")),
408
418
  partial: d.fetch("Partial"),
409
419
  )
410
420
  end
@@ -432,7 +442,7 @@ module Ortfodb
432
442
  module Ortfodb
433
443
  class Database
434
444
  def self.from_json!(json)
435
- Types::Hash[JSON.parse(json, quirks_mode: true)].map { |k, v| [k, DatabaseValue.from_dynamic!(v)] }.to_h
445
+ Types::Hash[JSON.parse(json, quirks_mode: true)].map { |k, v| [k, Work.from_dynamic!(v)] }.to_h
436
446
  end
437
447
  end
438
448
  end
@@ -21,7 +21,7 @@ module Ortfodb
21
21
  String = Strict::String
22
22
  end
23
23
 
24
- class ExporterSchema < Dry::Struct
24
+ class ExporterCommand < Dry::Struct
25
25
 
26
26
  # Log a message. The first argument is the verb, the second is the color, the third is the
27
27
  # message.
@@ -58,10 +58,10 @@ module Ortfodb
58
58
 
59
59
  # Commands to run after the build finishes. Go text template that receives .Data and
60
60
  # .Database, the built database.
61
- attribute :after, Types.Array(ExporterSchema).optional
61
+ attribute :after, Types.Array(ExporterCommand).optional
62
62
 
63
63
  # Commands to run before the build starts. Go text template that receives .Data
64
- attribute :before, Types.Array(ExporterSchema).optional
64
+ attribute :before, Types.Array(ExporterCommand).optional
65
65
 
66
66
  # Initial data
67
67
  attribute :data, Types::Hash.meta(of: Types::Any).optional
@@ -80,19 +80,19 @@ module Ortfodb
80
80
 
81
81
  # Commands to run during the build, for each work. Go text template that receives .Data and
82
82
  # .Work, the current work.
83
- attribute :work, Types.Array(ExporterSchema).optional
83
+ attribute :work, Types.Array(ExporterCommand).optional
84
84
 
85
85
  def self.from_dynamic!(d)
86
86
  d = Types::Hash[d]
87
87
  new(
88
- after: d["after"]&.map { |x| ExporterSchema.from_dynamic!(x) },
89
- before: d["before"]&.map { |x| ExporterSchema.from_dynamic!(x) },
88
+ after: d["after"]&.map { |x| ExporterCommand.from_dynamic!(x) },
89
+ before: d["before"]&.map { |x| ExporterCommand.from_dynamic!(x) },
90
90
  data: Types::Hash.optional[d["data"]]&.map { |k, v| [k, Types::Any[v]] }&.to_h,
91
91
  description: d.fetch("description"),
92
92
  exporter_name: d.fetch("name"),
93
93
  requires: d["requires"],
94
94
  verbose: d["verbose"],
95
- work: d["work"]&.map { |x| ExporterSchema.from_dynamic!(x) },
95
+ work: d["work"]&.map { |x| ExporterCommand.from_dynamic!(x) },
96
96
  )
97
97
  end
98
98
 
data/lib/ortfodb/tags.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  # To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do:
5
5
  #
6
6
  # tags = Tags.from_json! "[…]"
7
- # puts tags.first.detect.search.first
7
+ # puts tags.first.detect&.search&.first
8
8
  #
9
9
  # If from_json! succeeds, the value returned matches the schema.
10
10
 
@@ -20,17 +20,18 @@ module Ortfodb
20
20
  String = Strict::String
21
21
  end
22
22
 
23
+ # Various ways to automatically detect that a work is tagged with this tag.
23
24
  class Detect < Dry::Struct
24
- attribute :files, Types.Array(Types::String)
25
- attribute :made_with, Types.Array(Types::String)
26
- attribute :search, Types.Array(Types::String)
25
+ attribute :files, Types.Array(Types::String).optional
26
+ attribute :made_with, Types.Array(Types::String).optional
27
+ attribute :search, Types.Array(Types::String).optional
27
28
 
28
29
  def self.from_dynamic!(d)
29
30
  d = Types::Hash[d]
30
31
  new(
31
- files: d.fetch("files"),
32
- made_with: d.fetch("made with"),
33
- search: d.fetch("search"),
32
+ files: d["files"],
33
+ made_with: d["made with"],
34
+ search: d["search"],
34
35
  )
35
36
  end
36
37
 
@@ -51,21 +52,34 @@ module Ortfodb
51
52
  end
52
53
  end
53
54
 
55
+ # Tag represents a category that can be assigned to a work.
54
56
  class Tag < Dry::Struct
55
- attribute :aliases, Types.Array(Types::String)
56
- attribute :description, Types::String
57
- attribute :detect, Detect
58
- attribute :learn_more_at, Types::String
59
- attribute :plural, Types::String
60
- attribute :singular, Types::String
57
+
58
+ # Other singular-form names of tags that refer to this tag. The names mentionned here
59
+ # should not be used to define other tags.
60
+ attribute :aliases, Types.Array(Types::String).optional
61
+
62
+ attribute :description, Types::String.optional
63
+
64
+ # Various ways to automatically detect that a work is tagged with this tag.
65
+ attribute :detect, Detect.optional
66
+
67
+ # URL to a website where more information can be found about this tag.
68
+ attribute :learn_more_at, Types::String.optional
69
+
70
+ # Plural-form name of the tag. For example, "Books".
71
+ attribute :plural, Types::String
72
+
73
+ # Singular-form name of the tag. For example, "Book".
74
+ attribute :singular, Types::String
61
75
 
62
76
  def self.from_dynamic!(d)
63
77
  d = Types::Hash[d]
64
78
  new(
65
- aliases: d.fetch("aliases"),
66
- description: d.fetch("description"),
67
- detect: Detect.from_dynamic!(d.fetch("detect")),
68
- learn_more_at: d.fetch("learn more at"),
79
+ aliases: d["aliases"],
80
+ description: d["description"],
81
+ detect: d["detect"] ? Detect.from_dynamic!(d["detect"]) : nil,
82
+ learn_more_at: d["learn more at"],
69
83
  plural: d.fetch("plural"),
70
84
  singular: d.fetch("singular"),
71
85
  )
@@ -79,7 +93,7 @@ module Ortfodb
79
93
  {
80
94
  "aliases" => aliases,
81
95
  "description" => description,
82
- "detect" => detect.to_dynamic,
96
+ "detect" => detect&.to_dynamic,
83
97
  "learn more at" => learn_more_at,
84
98
  "plural" => plural,
85
99
  "singular" => singular,
@@ -4,7 +4,7 @@
4
4
  # To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do:
5
5
  #
6
6
  # technologies = Technologies.from_json! "[…]"
7
- # puts technologies.first.files.first
7
+ # puts technologies.first.files&.first
8
8
  #
9
9
  # If from_json! succeeds, the value returned matches the schema.
10
10
 
@@ -20,34 +20,48 @@ module Ortfodb
20
20
  String = Strict::String
21
21
  end
22
22
 
23
+ # Technology represents a "technology" (in the very broad sense) that was used to create a
24
+ # work.
23
25
  class Technology < Dry::Struct
24
- attribute :aliases, Types.Array(Types::String)
26
+
27
+ # Other technology slugs that refer to this technology. The slugs mentionned here should
28
+ # not be used in the definition of other technologies.
29
+ attribute :aliases, Types.Array(Types::String).optional
25
30
 
26
31
  # Autodetect contains an expression of the form 'CONTENT in PATH' where CONTENT is a
27
32
  # free-form unquoted string and PATH is a filepath relative to the work folder.
28
33
  # If CONTENT is found in PATH, we consider that technology to be used in the work.
29
- attribute :autodetect, Types.Array(Types::String)
34
+ attribute :autodetect, Types.Array(Types::String).optional
35
+
36
+ # Name of the person or organization that created this technology.
37
+ attribute :by, Types::String.optional
30
38
 
31
- attribute :by, Types::String
32
- attribute :description, Types::String
39
+ attribute :description, Types::String.optional
33
40
 
34
41
  # Files contains a list of gitignore-style patterns. If the work contains any of the
35
42
  # patterns specified, we consider that technology to be used in the work.
36
- attribute :files, Types.Array(Types::String)
43
+ attribute :files, Types.Array(Types::String).optional
44
+
45
+ # URL to a website where more information can be found about this technology.
46
+ attribute :learn_more_at, Types::String.optional
37
47
 
38
- attribute :learn_more_at, Types::String
39
48
  attribute :technology_name, Types::String
40
- attribute :slug, Types::String
49
+
50
+ # The slug is a unique identifier for this technology, that's suitable for use in a
51
+ # website's URL.
52
+ # For example, the page that shows all works using a technology with slug "a" could be at
53
+ # https://example.org/technologies/a.
54
+ attribute :slug, Types::String
41
55
 
42
56
  def self.from_dynamic!(d)
43
57
  d = Types::Hash[d]
44
58
  new(
45
- aliases: d.fetch("aliases"),
46
- autodetect: d.fetch("autodetect"),
47
- by: d.fetch("by"),
48
- description: d.fetch("description"),
49
- files: d.fetch("files"),
50
- learn_more_at: d.fetch("learn more at"),
59
+ aliases: d["aliases"],
60
+ autodetect: d["autodetect"],
61
+ by: d["by"],
62
+ description: d["description"],
63
+ files: d["files"],
64
+ learn_more_at: d["learn more at"],
51
65
  technology_name: d.fetch("name"),
52
66
  slug: d.fetch("slug"),
53
67
  )
@@ -1,3 +1,3 @@
1
1
  module Ortfodb
2
- VERSION = "1.4.1"
2
+ VERSION = "1.6.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ortfodb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ewen Le Bihan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-17 00:00:00.000000000 Z
11
+ date: 2024-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-struct