@@ -19,6 +19,8 @@ no if "$]" >= 5.033006, feature => 'bareword_filehandles';
19
19
use JSON::Schema::Modern::Utilities qw( E canonical_uri jsonp is_equal) ;
20
20
use Carp ' croak' ;
21
21
use Safe::Isa;
22
+ use Digest::MD5 ' md5_hex' ;
23
+ use Storable ' dclone' ;
22
24
use File::ShareDir ' dist_dir' ;
23
25
use Path::Tiny;
24
26
use List::Util ' pairs' ;
@@ -50,6 +52,7 @@ has '+evaluator' => (
50
52
);
51
53
52
54
has ' +metaschema_uri' => (
55
+ lazy => 1,
53
56
default => DEFAULT_BASE_METASCHEMA,
54
57
);
55
58
@@ -164,6 +167,9 @@ sub traverse ($self, $evaluator, $config_override = {}) {
164
167
165
168
$state -> @{qw( spec_version vocabularies) } = $check_metaschema_state -> @{qw( spec_version vocabularies) };
166
169
$self -> _set_json_schema_dialect($json_schema_dialect );
170
+
171
+ $self -> _set_metaschema_uri($self -> _dynamic_metaschema_uri($json_schema_dialect ))
172
+ if not $self -> _has_metaschema_uri and $json_schema_dialect ne DEFAULT_DIALECT;
167
173
}
168
174
169
175
# evaluate the document against its metaschema to find any errors, to identify all schema
@@ -414,6 +420,28 @@ sub _traverse_schema ($self, $state) {
414
420
}
415
421
}
416
422
423
+ # given a jsonSchemaDialect uri, generate a new schema that wraps the standard OAD schema
424
+ # to set the jsonSchemaDialect value for the #meta dynamic reference.
425
+ sub _dynamic_metaschema_uri ($self , $json_schema_dialect ) {
426
+ my $dialect_uri = ' https://custom-dialect.example.com/' . md5_hex($json_schema_dialect );
427
+ return $dialect_uri if $self -> evaluator-> _get_resource($dialect_uri );
428
+
429
+ # we use the definition of share/oas/schema-base.json but swap out the dialect reference.
430
+ my $schema = dclone($self -> evaluator-> _get_resource(DEFAULT_BASE_METASCHEMA)-> {document }-> schema);
431
+ $schema -> {' $id' } = $dialect_uri ;
432
+ $schema -> {' $defs' }{dialect }{const } = $json_schema_dialect ;
433
+ $schema -> {' $defs' }{schema }{' $ref' } = $json_schema_dialect ;
434
+
435
+ $self -> evaluator-> add_document(
436
+ Mojo::URL-> new($dialect_uri ),
437
+ JSON::Schema::Modern::Document-> new(
438
+ schema => $schema ,
439
+ evaluator => $self -> evaluator,
440
+ ));
441
+
442
+ return $dialect_uri ;
443
+ }
444
+
417
445
# FREEZE is defined by parent class
418
446
419
447
# callback hook for Sereal::Decoder
@@ -483,11 +511,6 @@ See L<§4.6/https://spec.openapis.org/oas/v3.1.1#relative-references-in-api-desc
483
511
484
512
See also L</retrieval_uri> .
485
513
486
- =head2 metaschema_uri
487
-
488
- The URI of the schema that describes the OpenAPI document itself. Defaults to
489
- L<https://spec.openapis.org/oas/3.1/schema-base/2024-10-25> .
490
-
491
514
=head2 json_schema_dialect
492
515
493
516
The URI of the metaschema to use for all embedded L<JSON Schemas|https://json-schema.org/> in the
@@ -500,11 +523,17 @@ If you specify your own dialect here or in C<jsonSchemaDialect>, then you need t
500
523
vocabularies and schemas to the implementation yourself. (see C<JSON::Schema::Modern/add_vocabulary >
501
524
and C<JSON::Schema::Modern/add_schema > ).
502
525
503
- Note this is B<NOT > the same as L<JSON::Schema::Modern::Document/metaschema_uri> , which contains the
504
- URI describing the entire document (and is not a metaschema in this case, as the entire document is
505
- not a JSON Schema). Note that you may need to explicitly set that attribute as well if you change
506
- C<json_schema_dialect > , as the default metaschema used by the default C<metaschema_uri > can no
507
- longer be assumed.
526
+ Note this is B<NOT > the same as L<JSON::Schema::Modern::Document/metaschema_uri>
527
+ (and C<metaschema_uri > below), which contains the
528
+ URI of the schema describing the entire document (and is not a metaschema in this case, as the
529
+ entire document is not a JSON Schema).
530
+
531
+ =head2 metaschema_uri
532
+
533
+ The URI of the schema that describes the OpenAPI document itself. Defaults to
534
+ L<https://spec.openapis.org/oas/3.1/schema-base/2024-10-25> when the json schema dialect is not
535
+ changed; otherwise defaults to a dynamically generated metaschema that uses the correct
536
+ value of C<jsonSchemaDialect > , so you don't need to write one yourself.
508
537
509
538
=head1 METHODS
510
539
0 commit comments