@@ -19,6 +19,8 @@ no if "$]" >= 5.033006, feature => 'bareword_filehandles';
1919use JSON::Schema::Modern::Utilities qw( E canonical_uri jsonp is_equal) ;
2020use Carp ' croak' ;
2121use Safe::Isa;
22+ use Digest::MD5 ' md5_hex' ;
23+ use Storable ' dclone' ;
2224use File::ShareDir ' dist_dir' ;
2325use Path::Tiny;
2426use List::Util ' pairs' ;
@@ -50,6 +52,7 @@ has '+evaluator' => (
5052);
5153
5254has ' +metaschema_uri' => (
55+ lazy => 1,
5356 default => DEFAULT_BASE_METASCHEMA,
5457);
5558
@@ -164,6 +167,9 @@ sub traverse ($self, $evaluator, $config_override = {}) {
164167
165168 $state -> @{qw( spec_version vocabularies) } = $check_metaschema_state -> @{qw( spec_version vocabularies) };
166169 $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;
167173 }
168174
169175 # evaluate the document against its metaschema to find any errors, to identify all schema
@@ -414,6 +420,28 @@ sub _traverse_schema ($self, $state) {
414420 }
415421}
416422
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+
417445# FREEZE is defined by parent class
418446
419447# 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
483511
484512See also L</retrieval_uri> .
485513
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-
491514=head2 json_schema_dialect
492515
493516The 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
500523vocabularies and schemas to the implementation yourself. (see C<JSON::Schema::Modern/add_vocabulary >
501524and C<JSON::Schema::Modern/add_schema > ).
502525
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.
508537
509538=head1 METHODS
510539
0 commit comments