w3c_api 0.1.3 → 0.1.4

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.
data/lib/w3c_api/hal.rb CHANGED
@@ -1,16 +1,47 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'singleton'
4
+ require 'lutaml/hal'
4
5
  require_relative 'models'
5
6
 
6
7
  module W3cApi
8
+ # Simple parameter class to satisfy lutaml-hal validation requirements
9
+ class SimpleParameter
10
+ attr_reader :name, :location, :required, :default_value
11
+
12
+ def initialize(name, location: :path, required: false, default_value: nil)
13
+ @name = name.to_s
14
+ @location = location
15
+ @required = required
16
+ @default_value = default_value
17
+ end
18
+
19
+ def validate!
20
+ # Simple validation - just ensure name is present
21
+ raise ArgumentError, 'Parameter name cannot be empty' if @name.nil? || @name.empty?
22
+ end
23
+
24
+ def path_parameter?
25
+ @location == :path
26
+ end
27
+
28
+ def query_parameter?
29
+ @location == :query
30
+ end
31
+
32
+ def validate_value(value)
33
+ # Simple validation - accept any non-nil value
34
+ !value.nil?
35
+ end
36
+ end
37
+
7
38
  class Hal
8
39
  include Singleton
9
40
 
10
41
  API_URL = 'https://api.w3.org/'
11
42
 
12
43
  def initialize
13
- setup
44
+ # Don't call setup here - it will be called when register is first accessed
14
45
  end
15
46
 
16
47
  def client
@@ -21,122 +52,185 @@ module W3cApi
21
52
  return @register if @register
22
53
 
23
54
  @register = Lutaml::Hal::ModelRegister.new(name: :w3c_api, client: client)
24
- Lutaml::Hal::GlobalRegister.instance.register(
25
- :w3c_api, @register
26
- )
55
+ Lutaml::Hal::GlobalRegister.instance.register(:w3c_api, @register)
56
+
57
+ # Re-run setup to register all endpoints with the new register
58
+ setup
59
+
27
60
  @register
28
61
  end
29
62
 
63
+ def reset_register
64
+ @register = nil
65
+ end
66
+
30
67
  private
31
68
 
32
- # Common pagination query parameters
33
- PAGINATION_PARAMS = {
34
- 'page' => '{page}',
35
- 'items' => '{items}'
36
- }.freeze
69
+ # Common pagination parameters (simplified without EndpointParameter)
70
+ def pagination_parameters
71
+ [
72
+ SimpleParameter.new('page', location: :query),
73
+ SimpleParameter.new('items', location: :query)
74
+ ]
75
+ end
76
+
77
+ # Parameters for endpoints with embed support (simplified without EndpointParameter)
78
+ def embed_parameters
79
+ [
80
+ SimpleParameter.new('embed', location: :query)
81
+ ] + pagination_parameters
82
+ end
83
+
84
+ # Helper methods for common parameter types (using SimpleParameter)
85
+ def string_path_param(name, _description = nil)
86
+ SimpleParameter.new(name, location: :path)
87
+ end
88
+
89
+ def integer_path_param(name, _description = nil)
90
+ SimpleParameter.new(name, location: :path)
91
+ end
92
+
93
+ def string_query_param(name, _description = nil, required: false)
94
+ SimpleParameter.new(name, location: :query, required: required)
95
+ end
37
96
 
38
97
  # Helper method to add index endpoints with pagination
39
- def add_index_endpoint(id, url, model, query_params = PAGINATION_PARAMS)
98
+ def add_index_endpoint(id, url, model, parameters = pagination_parameters)
40
99
  register.add_endpoint(
41
100
  id: id,
42
101
  type: :index,
43
102
  url: url,
44
103
  model: model,
45
- query_params: query_params
104
+ parameters: parameters
46
105
  )
47
106
  end
48
107
 
49
108
  # Helper method to add resource endpoints
50
- def add_resource_endpoint(id, url, model)
109
+ def add_resource_endpoint(id, url, model, parameters = [])
51
110
  register.add_endpoint(
52
111
  id: id,
53
112
  type: :resource,
54
113
  url: url,
55
- model: model
114
+ model: model,
115
+ parameters: parameters
56
116
  )
57
117
  end
58
118
 
59
- # Helper method to add nested index endpoints
60
- def add_nested_index_endpoints(parent_resource, parent_id_param, endpoints)
61
- endpoints.each do |endpoint|
62
- add_index_endpoint(
63
- :"#{parent_resource}_#{endpoint[:name]}_index",
64
- "/#{parent_resource}/#{parent_id_param}/#{endpoint[:path]}",
65
- endpoint[:model]
66
- )
67
- end
68
- end
69
-
70
- # Helper method to add individual nested endpoints
71
- def add_nested_endpoint(parent_resource, parent_id_param, endpoint_name, endpoint_path, model)
72
- add_index_endpoint(
73
- :"#{parent_resource}_#{endpoint_name}_index",
74
- "/#{parent_resource}/#{parent_id_param}/#{endpoint_path}",
75
- model
119
+ # Helper method to add endpoints with path parameters
120
+ def add_endpoint_with_path_params(id, type, url, model, path_params = [], query_params = [])
121
+ parameters = (path_params + query_params).compact
122
+ register.add_endpoint(
123
+ id: id,
124
+ type: type,
125
+ url: url,
126
+ model: model,
127
+ parameters: parameters
76
128
  )
77
129
  end
78
130
 
79
131
  def setup
80
- # Specification endpoints
132
+ # Specification endpoints with embed support
81
133
  add_index_endpoint(
82
134
  :specification_index,
83
135
  '/specifications',
84
- Models::SpecificationIndex
85
- )
86
- add_resource_endpoint(
87
- :specification_resource,
88
- '/specifications/{shortname}',
89
- Models::Specification
136
+ Models::SpecificationIndex,
137
+ embed_parameters
90
138
  )
91
- add_index_endpoint(
139
+
140
+ # Specification by status endpoint
141
+ add_endpoint_with_path_params(
92
142
  :specification_by_status_index,
143
+ :index,
93
144
  '/specifications',
94
145
  Models::SpecificationIndex,
95
- { 'status' => '{status}', **PAGINATION_PARAMS }
146
+ [],
147
+ [string_query_param('status', required: true)] + pagination_parameters
148
+ )
149
+ add_endpoint_with_path_params(
150
+ :specification_resource,
151
+ :resource,
152
+ '/specifications/{shortname}',
153
+ Models::Specification,
154
+ [string_path_param('shortname')]
96
155
  )
97
156
 
98
157
  # Specification version endpoints
99
- add_index_endpoint(
158
+ add_endpoint_with_path_params(
100
159
  :specification_resource_version_index,
160
+ :index,
101
161
  '/specifications/{shortname}/versions',
102
- Models::SpecVersionIndex
162
+ Models::SpecVersionIndex,
163
+ [string_path_param('shortname')],
164
+ pagination_parameters
103
165
  )
104
- add_resource_endpoint(
166
+ add_endpoint_with_path_params(
105
167
  :specification_resource_version_resource,
168
+ :resource,
106
169
  '/specifications/{shortname}/versions/{version}',
107
- Models::SpecVersion
170
+ Models::SpecVersion,
171
+ [
172
+ string_path_param('shortname'),
173
+ string_path_param('version')
174
+ ]
108
175
  )
109
176
 
110
177
  # Specification version editors and deliverers
111
- add_index_endpoint(
178
+ add_endpoint_with_path_params(
112
179
  :specification_version_editors_index,
180
+ :index,
113
181
  '/specifications/{shortname}/versions/{version}/editors',
114
- Models::EditorIndex
115
- )
116
- add_index_endpoint(
182
+ Models::EditorIndex,
183
+ [
184
+ string_path_param('shortname'),
185
+ string_path_param('version')
186
+ ],
187
+ pagination_parameters
188
+ )
189
+ add_endpoint_with_path_params(
117
190
  :specification_version_deliverers_index,
191
+ :index,
118
192
  '/specifications/{shortname}/versions/{version}/deliverers',
119
- Models::DelivererIndex
193
+ Models::DelivererIndex,
194
+ [
195
+ string_path_param('shortname'),
196
+ string_path_param('version')
197
+ ],
198
+ pagination_parameters
120
199
  )
121
200
 
122
201
  # Specification version predecessors and successors
123
- add_index_endpoint(
202
+ add_endpoint_with_path_params(
124
203
  :specification_version_predecessors_index,
204
+ :index,
125
205
  '/specifications/{shortname}/versions/{version}/predecessors',
126
- Models::SpecVersionPredecessorIndex
127
- )
128
- add_index_endpoint(
206
+ Models::SpecVersionPredecessorIndex,
207
+ [
208
+ string_path_param('shortname'),
209
+ string_path_param('version')
210
+ ],
211
+ pagination_parameters
212
+ )
213
+ add_endpoint_with_path_params(
129
214
  :specification_version_successors_index,
215
+ :index,
130
216
  '/specifications/{shortname}/versions/{version}/successors',
131
- Models::SpecVersionSuccessorIndex
217
+ Models::SpecVersionSuccessorIndex,
218
+ [
219
+ string_path_param('shortname'),
220
+ string_path_param('version')
221
+ ],
222
+ pagination_parameters
132
223
  )
133
224
 
134
225
  # Specification related endpoints
135
226
  %w[supersedes superseded_by editors deliverers].each do |relation|
136
- add_index_endpoint(
227
+ add_endpoint_with_path_params(
137
228
  :"specification_#{relation}_index",
229
+ :index,
138
230
  "/specifications/{shortname}/#{relation.tr('_', '-')}",
139
- relation.include?('editor') ? Models::UserIndex : Models::GroupIndex
231
+ relation.include?('editor') ? Models::UserIndex : Models::GroupIndex,
232
+ [string_path_param('shortname')],
233
+ pagination_parameters
140
234
  )
141
235
  end
142
236
 
@@ -148,74 +242,109 @@ module W3cApi
148
242
  # model: Models::SpecificationIndex
149
243
  # )
150
244
 
151
- # Series endpoints
245
+ # Series endpoints with embed support
152
246
  add_index_endpoint(
153
247
  :serie_index,
154
248
  '/specification-series',
155
- Models::SerieIndex
249
+ Models::SerieIndex,
250
+ embed_parameters
156
251
  )
157
- add_resource_endpoint(
252
+ add_endpoint_with_path_params(
158
253
  :serie_resource,
254
+ :resource,
159
255
  '/specification-series/{shortname}',
160
- Models::Serie
256
+ Models::Serie,
257
+ [string_path_param('shortname')]
161
258
  )
162
- add_index_endpoint(
259
+ add_endpoint_with_path_params(
163
260
  :serie_specification_resource,
261
+ :index,
164
262
  '/specification-series/{shortname}/specifications',
165
- Models::SpecificationIndex
263
+ Models::SpecificationIndex,
264
+ [string_path_param('shortname')],
265
+ pagination_parameters
166
266
  )
167
267
 
168
- # Group endpoints
268
+ # Group endpoints with embed support
169
269
  add_index_endpoint(
170
270
  :group_index,
171
271
  '/groups',
172
- Models::GroupIndex
272
+ Models::GroupIndex,
273
+ embed_parameters
173
274
  )
174
- add_resource_endpoint(
275
+ add_endpoint_with_path_params(
175
276
  :group_resource,
277
+ :resource,
176
278
  '/groups/{id}',
177
- Models::Group
279
+ Models::Group,
280
+ [integer_path_param('id')]
178
281
  )
179
- add_resource_endpoint(
282
+ add_endpoint_with_path_params(
180
283
  :group_by_type_shortname_resource,
284
+ :resource,
181
285
  '/groups/{type}/{shortname}',
182
- Models::Group
286
+ Models::Group,
287
+ [
288
+ string_path_param('type'),
289
+ string_path_param('shortname')
290
+ ]
183
291
  )
184
- add_index_endpoint(
292
+ add_endpoint_with_path_params(
185
293
  :group_by_type_index,
294
+ :index,
186
295
  '/groups/{type}',
187
- Models::GroupIndex
296
+ Models::GroupIndex,
297
+ [string_path_param('type')],
298
+ pagination_parameters
188
299
  )
189
300
  # Group nested endpoints
190
- add_index_endpoint(
301
+ add_endpoint_with_path_params(
191
302
  :group_specifications_index,
303
+ :index,
192
304
  '/groups/{id}/specifications',
193
- Models::SpecificationIndex
305
+ Models::SpecificationIndex,
306
+ [integer_path_param('id')],
307
+ pagination_parameters
194
308
  )
195
- add_index_endpoint(
309
+ add_endpoint_with_path_params(
196
310
  :group_users_index,
311
+ :index,
197
312
  '/groups/{id}/users',
198
- Models::UserIndex
313
+ Models::UserIndex,
314
+ [integer_path_param('id')],
315
+ pagination_parameters
199
316
  )
200
- add_index_endpoint(
317
+ add_endpoint_with_path_params(
201
318
  :group_charters_index,
319
+ :index,
202
320
  '/groups/{id}/charters',
203
- Models::CharterIndex
321
+ Models::CharterIndex,
322
+ [integer_path_param('id')],
323
+ pagination_parameters
204
324
  )
205
- add_index_endpoint(
325
+ add_endpoint_with_path_params(
206
326
  :group_chairs_index,
327
+ :index,
207
328
  '/groups/{id}/chairs',
208
- Models::ChairIndex
329
+ Models::ChairIndex,
330
+ [integer_path_param('id')],
331
+ pagination_parameters
209
332
  )
210
- add_index_endpoint(
333
+ add_endpoint_with_path_params(
211
334
  :group_team_contacts_index,
335
+ :index,
212
336
  '/groups/{id}/teamcontacts',
213
- Models::TeamContactIndex
337
+ Models::TeamContactIndex,
338
+ [integer_path_param('id')],
339
+ pagination_parameters
214
340
  )
215
- add_index_endpoint(
341
+ add_endpoint_with_path_params(
216
342
  :group_participations_index,
343
+ :index,
217
344
  '/groups/{id}/participations',
218
- Models::ParticipationIndex
345
+ Models::ParticipationIndex,
346
+ [integer_path_param('id')],
347
+ pagination_parameters
219
348
  )
220
349
 
221
350
  # Translation endpoints
@@ -224,10 +353,12 @@ module W3cApi
224
353
  '/translations',
225
354
  Models::TranslationIndex
226
355
  )
227
- add_resource_endpoint(
356
+ add_endpoint_with_path_params(
228
357
  :translation_resource,
358
+ :resource,
229
359
  '/translations/{id}',
230
- Models::Translation
360
+ Models::Translation,
361
+ [integer_path_param('id')]
231
362
  )
232
363
 
233
364
  # User endpoints
@@ -238,42 +369,62 @@ module W3cApi
238
369
  # url: '/users',
239
370
  # model: Models::UserIndex
240
371
  # )
241
- add_resource_endpoint(
372
+ add_endpoint_with_path_params(
242
373
  :user_resource,
374
+ :resource,
243
375
  '/users/{hash}',
244
- Models::User
376
+ Models::User,
377
+ [string_path_param('hash')]
245
378
  )
246
379
 
247
380
  # User nested endpoints
248
- add_index_endpoint(
381
+ add_endpoint_with_path_params(
249
382
  :user_groups_index,
383
+ :index,
250
384
  '/users/{hash}/groups',
251
- Models::GroupIndex
385
+ Models::GroupIndex,
386
+ [string_path_param('hash')],
387
+ pagination_parameters
252
388
  )
253
- add_index_endpoint(
389
+ add_endpoint_with_path_params(
254
390
  :user_affiliations_index,
391
+ :index,
255
392
  '/users/{hash}/affiliations',
256
- Models::AffiliationIndex
393
+ Models::AffiliationIndex,
394
+ [string_path_param('hash')],
395
+ pagination_parameters
257
396
  )
258
- add_index_endpoint(
397
+ add_endpoint_with_path_params(
259
398
  :user_participations_index,
399
+ :index,
260
400
  '/users/{hash}/participations',
261
- Models::ParticipationIndex
401
+ Models::ParticipationIndex,
402
+ [string_path_param('hash')],
403
+ pagination_parameters
262
404
  )
263
- add_index_endpoint(
405
+ add_endpoint_with_path_params(
264
406
  :user_chair_of_groups_index,
407
+ :index,
265
408
  '/users/{hash}/chair-of-groups',
266
- Models::GroupIndex
409
+ Models::GroupIndex,
410
+ [string_path_param('hash')],
411
+ pagination_parameters
267
412
  )
268
- add_index_endpoint(
413
+ add_endpoint_with_path_params(
269
414
  :user_team_contact_of_groups_index,
415
+ :index,
270
416
  '/users/{hash}/team-contact-of-groups',
271
- Models::GroupIndex
417
+ Models::GroupIndex,
418
+ [string_path_param('hash')],
419
+ pagination_parameters
272
420
  )
273
- add_index_endpoint(
421
+ add_endpoint_with_path_params(
274
422
  :user_specifications_index,
423
+ :index,
275
424
  '/users/{hash}/specifications',
276
- Models::SpecificationIndex
425
+ Models::SpecificationIndex,
426
+ [string_path_param('hash')],
427
+ pagination_parameters
277
428
  )
278
429
 
279
430
  # Affiliation endpoints
@@ -282,22 +433,30 @@ module W3cApi
282
433
  '/affiliations',
283
434
  Models::AffiliationIndex
284
435
  )
285
- add_resource_endpoint(
436
+ add_endpoint_with_path_params(
286
437
  :affiliation_resource,
438
+ :resource,
287
439
  '/affiliations/{id}',
288
- Models::Affiliation
440
+ Models::Affiliation,
441
+ [integer_path_param('id')]
289
442
  )
290
443
 
291
444
  # Affiliation nested endpoints
292
- add_index_endpoint(
445
+ add_endpoint_with_path_params(
293
446
  :affiliation_participants_index,
447
+ :index,
294
448
  '/affiliations/{id}/participants',
295
- Models::ParticipantIndex
449
+ Models::ParticipantIndex,
450
+ [integer_path_param('id')],
451
+ pagination_parameters
296
452
  )
297
- add_index_endpoint(
453
+ add_endpoint_with_path_params(
298
454
  :affiliation_participations_index,
455
+ :index,
299
456
  '/affiliations/{id}/participations',
300
- Models::ParticipationIndex
457
+ Models::ParticipationIndex,
458
+ [integer_path_param('id')],
459
+ pagination_parameters
301
460
  )
302
461
 
303
462
  # Ecosystem endpoints
@@ -306,39 +465,55 @@ module W3cApi
306
465
  '/ecosystems',
307
466
  Models::EcosystemIndex
308
467
  )
309
- add_resource_endpoint(
468
+ add_endpoint_with_path_params(
310
469
  :ecosystem_resource,
470
+ :resource,
311
471
  '/ecosystems/{shortname}',
312
- Models::Ecosystem
472
+ Models::Ecosystem,
473
+ [string_path_param('shortname')]
313
474
  )
314
475
 
315
476
  # Ecosystem nested endpoints
316
- add_index_endpoint(
477
+ add_endpoint_with_path_params(
317
478
  :ecosystem_groups_index,
479
+ :index,
318
480
  '/ecosystems/{shortname}/groups',
319
- Models::GroupIndex
481
+ Models::GroupIndex,
482
+ [string_path_param('shortname')],
483
+ pagination_parameters
320
484
  )
321
- add_index_endpoint(
485
+ add_endpoint_with_path_params(
322
486
  :ecosystem_evangelists_index,
487
+ :index,
323
488
  '/ecosystems/{shortname}/evangelists',
324
- Models::EvangelistIndex
489
+ Models::EvangelistIndex,
490
+ [string_path_param('shortname')],
491
+ pagination_parameters
325
492
  )
326
- add_index_endpoint(
493
+ add_endpoint_with_path_params(
327
494
  :ecosystem_member_organizations_index,
495
+ :index,
328
496
  '/ecosystems/{shortname}/member-organizations',
329
- Models::AffiliationIndex
497
+ Models::AffiliationIndex,
498
+ [string_path_param('shortname')],
499
+ pagination_parameters
330
500
  )
331
501
 
332
502
  # Participation endpoints
333
- add_resource_endpoint(
503
+ add_endpoint_with_path_params(
334
504
  :participation_resource,
505
+ :resource,
335
506
  '/participations/{id}',
336
- Models::Participation
507
+ Models::Participation,
508
+ [integer_path_param('id')]
337
509
  )
338
- add_index_endpoint(
510
+ add_endpoint_with_path_params(
339
511
  :participation_participants_index,
512
+ :index,
340
513
  '/participations/{id}/participants',
341
- Models::ParticipantIndex
514
+ Models::ParticipantIndex,
515
+ [integer_path_param('id')],
516
+ pagination_parameters
342
517
  )
343
518
  end
344
519
  end