hyperjump-io / json-schema

JSON Schema Validation, Annotation, and Bundling. Supports Draft 04, 06, 07, 2019-09, 2020-12, OpenAPI 3.0, and OpenAPI 3.1
https://json-schema.hyperjump.io/
MIT License
216 stars 22 forks source link

Add context to a fetch error response when referencing an external schema #27

Closed jeremyfiel closed 1 year ago

jeremyfiel commented 1 year ago

take this schema as an example, it fails validation when fetching geoJSON referencing an external schema

https://github.com/iptc/newsinjson/blob/version1.5version2.1/specification/ninjs-schema_2.1.json

It would be helpful to add more context to this error, either the property where it failed or the url which failed. The error is passed from undici.

https://github.com/hyperjump-io/json-schema/blob/0cef4969ef475ce6877eb6da4052e480fa144f2f/lib/fetch.js#L18

jdesrosiers commented 1 year ago

Can you provide a little more information? What error are you seeing?

jeremyfiel commented 1 year ago

I'm not in front of it now, but I'm fairly certain i used the online validator with the schema provided and it only gives the error text from undici. For sure, it was also the same using the cli. fetch failed

jdesrosiers commented 1 year ago

The error I get is,

Error: https://geojson.org/schema/GeoJSON.json is not a schema. Found a document with media type: application/json

This error comes from my library, not undici, and it means that https://geojson.org/schema/GeoJSON.json is not being served with the proper content type header (application/schema+json). If users want to treat application/json as a schema, they can use addMediaTypePlugin to configure support.

jeremyfiel commented 1 year ago

Ah that's right, copy pasta that schema into the existing schema and that's where the error was

jdesrosiers commented 1 year ago

That exposed a bug related to compound schema documents, but it doesn't have anything to do with fetch or undici.

jdesrosiers commented 1 year ago

I fixed that bug (v1.4.2). Although it doesn't sound like it's related to to problem you're encountering. I still haven't reproduced the issue you've described.

jeremyfiel commented 1 year ago

i tried my best to repro and i can't figure out how I did it..

but i did come across another error TypeError: a.compile is not a function

example schema with error

```json { "$schema": "https://json-schema.org/draft/2020-12/schema#", "$id": "http://www.iptc.org/std/ninjs/ninjs-schema_2.1.json#", "type": "object", "title": "IPTC ninjs - News in JSON - version 2.1 (approved at IPTC Standards Committee October 2023)", "description": "A news item as JSON object -- copyright 2023 IPTC - International Press Telecommunications Council - www.iptc.org - This document is published under the Creative Commons Attribution 4.0 license, see http://creativecommons.org/licenses/by/4.0/", "additionalProperties": false, "required": ["uri"], "$defs": { "contactinfoType": { "additionalProperties": false, "properties": { "type": { "description": "Type would be method of communication like phone, mobile, address etc.", "type": "string" }, "role": { "description": "Role refers to type and could be private, office etc", "type": "string" }, "lang": { "description": "If this contactinfo object need to be qualified with what language it is in. The value should follow IETF BCP47.", "type": "string" }, "name": { "description": "Human readable name of the contact method, like name for a web page, name of persons twitter account etc", "type": "string" }, "value": { "description": "Actual phone number, email address, web url etc.", "type": "string" }, "address": { "type": "object", "description": "An array of lines to construct an address. The order is important to construct a correct address.", "additionalProperties": false, "properties": { "lines": { "type": "array", "items": { "type": "string" } }, "locality": { "type": "string" }, "area": { "type": "string" }, "postalcode": { "type": "string" }, "country": { "type": "string" } } } }, "oneOf": [ { "required": ["value"] }, { "required": ["address"] } ] } }, "properties": { "uri": { "title": "Uniform Resource Identifier", "description": "The global unique identifier for this news object. This is the only required property and should identify the ninjs object, not be used for links to external resources etc. nar:newsItem@guid", "type": "string", "format": "uri" }, "type": { "title": "Type", "description": "The generic news type of this news object. (Value 'component' added in version 1.2 as issue #21.). See: http://cv.iptc.org/newscodes/ninature/ nar:itemClass", "type": "string", "enum": [ "text", "audio", "video", "picture", "graphic", "composite", "component" ] }, "representationtype": { "title": "Representation type", "description": "Indicates how complete this representation of a news item is. No mapping to nar. Specific for ninjs.", "type": "string", "enum": [ "full", "partial" ] }, "profile": { "title": "Profile", "description": "An identifier for the structure of the news object. This can be any string but we suggest something identifying the structure of the content such as 'text-only' or 'text-photo'. Profiles are typically provider-specific. nar:profile", "type": "string" }, "version": { "title": "Version", "description": "The version of the news object which is identified by the uri property. nar:newsItem@version", "type": "string" }, "firstcreated": { "title": "First created", "description": "Indicates when the first version of this ninjs object was created. (Added in version 1.2 from issue #5). nar:firstCreated", "type": "string", "format": "date-time" }, "versioncreated": { "title": "Version created", "description": "The date and time when this version of this ninjs object was created. nar:versionCreated", "type": "string", "format": "date-time" }, "contentcreated": { "title": "Content created", "description": "The date and time when the content of this ninjs object was originally created. For example an old photo that is now handled as a ninjs object. nar:contentCreated", "type": "string", "format": "date-time" }, "embargoed": { "title": "Embargoed", "description": "The date and time before which all versions of the news object are embargoed. If absent, this object is not embargoed. nar:embargoed", "type": "string", "format": "date-time" }, "pubstatus": { "title": "Publication status", "description": "The publishing status of the news object, its value is *usable* by default. nar:pubStatus", "type": "string", "enum": [ "usable", "withheld", "canceled" ] }, "urgency": { "title": "Urgency", "description": "The editorial urgency of the content. Values from 1 to 9. 1 represents the highest urgency, 9 the lowest. nar:urgency", "type": "number" }, "copyrightholder": { "title": "Copyright holder", "description": "The person or organisation claiming the intellectual property for the content. nar:copyrightHolder", "type": "string" }, "copyrightnotice": { "title": "Copyright notice", "description": "Any necessary copyright notice for claiming the intellectual property for the content. nar:copyrightNotice", "type": "string" }, "usageterms": { "title": "Usage terms", "description": "A natural-language statement about the usage terms pertaining to the content. nar:usageTerms", "type": "string" }, "ednote": { "title": "Editorial note", "description": "A note that is intended to be read by internal staff at the receiving organisation, but not intended to be published. (Added in version 1.2 from issue #6.). (Consider using this before using the descriptions array.) ednote: nar:edNote", "type": "string" }, "language": { "title": "Language", "description": "The human language used by the content. The value should follow IETF BCP47. nar:language", "type": "string" }, "descriptions": { "title": "Descriptions", "description": "An array of one or more descriptions of the ninjs object. See also ednote for information from provider to reciever. Descriptions are seen as metadata. For a simple description use an array with one object only containing the value property. Role and contenttype are then undefined and it is up to the provider.", "type": "array", "items": { "type": "object", "required": ["value"], "additionalProperties": false, "properties": { "role": { "title": "Role", "description": "The role of this description", "type": "string" }, "contenttype": { "title": "Content Type", "description": "The IANA (Internet Assigned Numbers Authority) media type of the content of this description. Used to be called MIME type.", "type": "string" }, "value": { "title": "Value", "description": "The descriptive text identified with the above role (and contenttype).", "type": "string" } } } }, "bodies": { "title": "Bodies", "description": "An array of body objects with the content as text or with markup. For a simple body use an array with one object only containing the value property. Role and contenttype are then undefined and it is up to the provider.", "type": "array", "items": { "type": "object", "required": ["value"], "additionalProperties": false, "properties": { "role": { "title": "Role", "description": "The role of this body", "type": "string" }, "contenttype": { "title": "Content Type", "description": "The IANA (Internet Assigned Numbers Authority) media type of the content of this body. Used to be called MIME type.", "type": "string" }, "charcount": { "title": "Character count", "description": "The total character count in this body excluding figure captions. (Added in version 1.2 according to issue #27.). nar:charcount", "type": "number" }, "wordcount": { "title": "Word count", "description": "The total number of words in this body excluding figure captions. (Added in version 1.2 according to issue #27.). nar:wordcount", "type": "number" }, "value": { "title": "Value", "description": "The body text identified with the above role and contenttype.", "type": "string" } } } }, "headlines": { "title": "Headlines", "description": "An array of objects containing various types of headlines. For a simple headline use an array with one object only containing the value property. Role and contenttype are then undefined and it is up to the provider.", "type": "array", "items": { "type": "object", "required": ["value"], "additionalProperties": false, "properties": { "role": { "title": "Role", "description": "The role of this headline", "type": "string" }, "contenttype": { "title": "Content Type", "description": "The IANA (Internet Assigned Numbers Authority) media type of the content of this headline. Used to be called MIME type.", "type": "string" }, "value": { "title": "Value", "description": "The headline identified with the above role and contenttype.", "type": "string" } } } }, "people": { "title": "People", "description": "An array of objects describing individual human beings. nar:subject", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of a person", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the person", "type": "string" }, "uri": { "title": "URI", "description": "The identifier for the person as a complete uri with the code.", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the person as a free-text string.", "type": "string" }, "contactinfo": { "type": "array", "items": { "$ref": "#/$defs/contactinfoType" } } } } }, "organisations": { "title": "Organisations", "description": "An array of objects describing administrative and functional structures which may, for example, act as a business, as a political party or not-for-profit party. nar:subject", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the organisation", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the organisation", "type": "string" }, "uri": { "title": "URI", "description": "The identifier of the organisation as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the organisation as a free-text string.", "type": "string" }, "symbols": { "title": "Symbols", "description": "Symbols used for a financial instrument linked to the organisation at a specific market place", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "ticker": { "title": "Ticker", "description": "Ticker symbol used for the financial instrument", "type": "string" }, "exchange": { "title": "Exchange", "description": "Identifier for the marketplace which uses the ticker symbols of the ticker property", "type": "string" }, "symboltype": { "title": "Symbol type uri", "description": "https://cv.iptc.org/newscodes/financialinstrumentsymboltype. Same as type in G2.", "type": "string", "format": "uri" }, "symbol": { "title": "Symbol", "description": "Compare with hasInstrument in NewsML-G2. Same as symbol in G2.", "type": "string" } } } }, "contactinfo": { "type": "array", "items": { "$ref": "#/$defs/contactinfoType" } } } } }, "places": { "title": "Places", "description": "An array of named locations. nar:subject", "additionalProperties": false, "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the place", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the place", "type": "string" }, "uri": { "title": "URI", "description": "The identifier for the place as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the place as a free-text string.", "type": "string" }, "contactinfo": { "type": "array", "items": { "$ref": "#/$defs/contactinfoType" } }, "geojson": { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://geojson.org/schema/GeoJSON.json", "title": "GeoJSON", "oneOf": [ { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON GeometryCollection", "type": "object", "required": [ "type", "geometries" ], "properties": { "type": { "type": "string", "enum": [ "GeometryCollection" ] }, "geometries": { "type": "array", "items": { "oneOf": [ { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Feature", "type": "object", "required": [ "type", "properties", "geometry" ], "properties": { "type": { "type": "string", "enum": [ "Feature" ] }, "id": { "oneOf": [ { "type": "number" }, { "type": "string" } ] }, "properties": { "oneOf": [ { "type": "null" }, { "type": "object" } ] }, "geometry": { "oneOf": [ { "type": "null" }, { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON GeometryCollection", "type": "object", "required": [ "type", "geometries" ], "properties": { "type": { "type": "string", "enum": [ "GeometryCollection" ] }, "geometries": { "type": "array", "items": { "oneOf": [ { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON FeatureCollection", "type": "object", "required": [ "type", "features" ], "properties": { "type": { "type": "string", "enum": [ "FeatureCollection" ] }, "features": { "type": "array", "items": { "title": "GeoJSON Feature", "type": "object", "required": [ "type", "properties", "geometry" ], "properties": { "type": { "type": "string", "enum": [ "Feature" ] }, "id": { "oneOf": [ { "type": "number" }, { "type": "string" } ] }, "properties": { "oneOf": [ { "type": "null" }, { "type": "object" } ] }, "geometry": { "oneOf": [ { "type": "null" }, { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON GeometryCollection", "type": "object", "required": [ "type", "geometries" ], "properties": { "type": { "type": "string", "enum": [ "GeometryCollection" ] }, "geometries": { "type": "array", "items": { "oneOf": [ { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] } } } }, "subjects": { "title": "Subjects", "description": "An array of objects holding concepts with a relationship to the content. nar:subject", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the subject", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the subject", "type": "string" }, "uri": { "title": "URI", "description": "The identifier of the subject as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the subject as a free-text string.", "type": "string" }, "creator": { "title": "Creator", "description": "Specifies which entity (person, organisation or system) that has created or last edited the property.", "type": "string" }, "relevance": { "title": "Relevance", "description": "The relevance of the metadata to the news content to which it is attached.", "type": "integer", "minimum": 0, "maximum": 100 }, "confidence": { "title": "Confidence", "description": "The confidence with which the metadata has been assigned.", "type": "integer", "minimum": 0, "maximum": 100 } } } }, "events": { "title": "Events", "description": "An array of objects describing something which happens in a planned or unplanned manner. nar:?", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the event", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the event", "type": "string" }, "uri": { "title": "URI", "description": "The identifier for the event as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the event as a free-text string.", "type": "string" } } } }, "objects": { "title": "Objects", "description": "An array of objects describing something material, excluding persons. nar:subject", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the object", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the object", "type": "string" }, "uri": { "title": "URI", "description": "The identifier for the object as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the object as a free-text string.", "type": "string" } } } }, "infosources": { "title": "Info sources", "description": "An array of parties (person or organisation) which originated, modified, enhanced, distributed, aggregated or supplied the content or provided some information used to create or enhance the content. (Added in version 1.2 according to issue #15.) . infosource: nar:infoSource", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the infosource", "type": "string" }, "role": { "title": "Role", "description": "The role the infosource in relationship to the content as a uri.", "type": "string", "format": "uri" }, "uri": { "title": "URI", "description": "The identifier of the infosource as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the infosource as a free-text string.", "type": "string" }, "contactinfo": { "type": "array", "items": { "$ref": "#/$defs/contactinfoType" } } } } }, "title": { "title": "Title", "description": "A short natural-language name for the item. Title is metadata, use headlines for publishable headlines. (Added in version 1.2 according to issue #9). nar:itemMeta/title", "type": "string" }, "by": { "title": "By", "description": "A natural-language statement about the creator (author, photographer etc.) of the content. nar:by", "type": "string" }, "slugline": { "title": "Slugline", "description": "A human-readable identifier for the item. (Added in version 1.2 from issue #4.). nar:slugline", "type": "string" }, "located": { "title": "Located", "description": "The name of the location from which the content originates. nar:located", "type": "string" }, "renditions": { "title": "Renditions", "description": "An array of objects with different renditions of the news object. nar:remoteContent", "type": "array", "additionalProperties": false, "items": { "description": "A specific rendition of the content of the news object. (Description changed in version 1.2 according to issue #17.)", "type": "object", "additionalProperties": false, "required": ["name"], "properties": { "name": { "title": "Name", "description": "The name of this object in the array of renditions. For example 'thumbnail'", "type": "string" }, "href": { "title": "href", "description": "The URL for accessing the rendition as a resource. nar:remoteContent@ref", "type": "string", "format": "uri" }, "contenttype": { "title": "Content Type", "description": "A media type which applies to this rendition. nar:remoteContent@contenttype", "type": "string" }, "title": { "title": "Title", "description": "A title for the link to the rendition resource", "type": "string" }, "height": { "title": "Height", "description": "For still and moving images: the height of the display area measured in pixels. nar:remoteContent@height", "type": "number" }, "width": { "title": "Width", "description": "For still and moving images: the width of the display area measured in pixels. nar:remoteContent@width", "type": "number" }, "sizeinbytes": { "title": "Size in bytes", "description": "The size of the rendition resource in bytes", "type": "number" }, "duration": { "title": "Duration", "description": "The total time duration of the content in seconds. (Added in version 1.2. Issue #18). nar:remoteContent@duration", "type": "number" }, "format": { "title": "Format", "description": "A refinement of a generic content type (i.e. IANA media type) by a literal string value. nar:remoteContent@contenttypevariant and nar:remoteContent@format", "type": "string" } } } }, "associations": { "title": "Associations", "description": "An array of objects with content of news objects which are associated with this news object.", "type": "array", "items": { "required": [ "name", "uri" ], "description": "One associated object where each object can use all properties in ninjs.", "type": "object", "anyOf": [ { "properties": { "name": { "type": "string", "description": "The name of this object in the array of associations. For example 'logo'" } } }, { "$ref": "#" } ], "unevaluatedProperties": false } }, "altids": { "title": "Alternative ids", "description": "Alternative identifiers assigned to the content. Each alternative id can have a role and a value. nar:altId issue #3.", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "role": { "title": "Role", "description": "The role of the alternative id", "type": "string" }, "value": { "title": "Value", "description": "The alternative id value", "type": "string" } } } }, "trustindicators": { "title": "Trust indicators", "description": "An array of objects to allow links to documents about trust indicators. issue #44. (Added in version 1.3)", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "role": { "title": "Role", "description": "The role of the trust indicator as a complete uri", "type": "string", "format": "uri" }, "title": { "title": "Title", "description": "The title of the resource being referenced.", "type": "string" }, "href": { "title": "href", "description": "The URL for accessing the trust indicator resource.", "type": "string", "format": "uri" } } } }, "standard": { "title": "Standard", "type": "object", "description": "An object with information about standard, version and schema this instance is valid against. nar:standard, nar:standardversion and xml:schema issue #43. (Added in version 1.3)", "additionalProperties": false, "properties": { "name": { "title": "Name of standard.", "description": "For example ninjs. nar:standard", "type": "string" }, "version": { "title": "Version of standard.", "description": "For example 1.3. nar:standardversion", "type": "string" }, "schema": { "title": "Schema", "description": "The uri of the json schema to use for validation.", "type": "string", "format": "uri" } } }, "genres": { "title": "Genres", "description": "A nature, intellectual or journalistic form of the content. nar:genre. (Added in version 1.3)", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the genre", "type": "string" }, "uri": { "title": "URI", "description": "The identifier of the genre as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the genre as a free-text string.", "type": "string" } } } }, "expires": { "title": "Expires", "description": "The date and time after which the Item is no longer considered editorially relevant by its provider. nar:expires (Added in 2.1)", "type": "string", "format": "date-time" }, "rightsinfo": { "title": "Rights information", "type": "object", "description": "Expression of rights to be applied to content. nar:rightsInfo", "properties": { "langid": { "type": "string", "title": "Language id", "description": "Identifier for the Rights Expression language used. nar:@langid", "format": "uri" }, "linkedrights": { "title": "Linked rights", "description": "A link from the current Item to Web resource with rights related information. nar:link", "type": "string", "format": "uri" }, "encodedrights": { "title": "Encoded Rights", "additionalProperties": false, "type": "string", "description": "Contains a rights expression as defined by a Rights Expression Language. nar:rightsExpressionXML or nar:rightsExpressionData" } }, "oneOf": [ { "required": ["linkedrights"] }, { "required": ["encodedrights"] } ] } } } ```

jdesrosiers commented 1 year ago

That's the bug I just fixed. Update to the latest version and that should go away.

jeremyfiel commented 1 year ago

Oh ok. I was using the online valdiator. Let me try to refresh

On Tue, Mar 28, 2023, 12:36 Jason Desrosiers @.***> wrote:

That's the bug I just fixed. Update to the latest version and that should go away.

— Reply to this email directly, view it on GitHub https://github.com/hyperjump-io/json-schema/issues/27#issuecomment-1487256536, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHU7MTMZAUIDYZ4BRIZYYXLW6MHQJANCNFSM6AAAAAAWFVNPXM . You are receiving this because you authored the thread.Message ID: @.***>

jdesrosiers commented 1 year ago

Ah, sorry, I haven't updated the online validator yet.

jdesrosiers commented 1 year ago

Ok, the website has been updated.

jeremyfiel commented 1 year ago

i'm still getting keywordHandler.compile is not a function after updating the package locally.

i'm on 1.4.2 node 18.5

example schema with error

import { addSchema, validate } from '@hyperjump/json-schema/draft-2020-12' import "@hyperjump/json-schema/draft-04" let instance= { "uri": "http://tt.se/test/123456", "version": "1", "title": "test", "associations": [ { "uri": "http://tt.se/association", "name": "hej", "type": "graphic", "versioncreated": "2013-07-31T15:32:00Z", "renditions": [ {"name": "test"} ] } ] } let schema = { "$schema": "https://json-schema.org/draft/2020-12/schema#", "$id": "http://www.iptc.org/std/ninjs/ninjs-schema_2.1.json#", "type": "object", "title": "IPTC ninjs - News in JSON - version 2.1 (approved at IPTC Standards Committee October 2023)", "description": "A news item as JSON object -- copyright 2023 IPTC - International Press Telecommunications Council - www.iptc.org - This document is published under the Creative Commons Attribution 4.0 license, see http://creativecommons.org/licenses/by/4.0/", "additionalProperties": false, "required": ["uri"], "$defs": { "contactinfoType": { "additionalProperties": false, "properties": { "type": { "description": "Type would be method of communication like phone, mobile, address etc.", "type": "string" }, "role": { "description": "Role refers to type and could be private, office etc", "type": "string" }, "lang": { "description": "If this contactinfo object need to be qualified with what language it is in. The value should follow IETF BCP47.", "type": "string" }, "name": { "description": "Human readable name of the contact method, like name for a web page, name of persons twitter account etc", "type": "string" }, "value": { "description": "Actual phone number, email address, web url etc.", "type": "string" }, "address": { "type": "object", "description": "An array of lines to construct an address. The order is important to construct a correct address.", "additionalProperties": false, "properties": { "lines": { "type": "array", "items": { "type": "string" } }, "locality": { "type": "string" }, "area": { "type": "string" }, "postalcode": { "type": "string" }, "country": { "type": "string" } } } }, "oneOf": [ { "required": ["value"] }, { "required": ["address"] } ] } }, "properties": { "uri": { "title": "Uniform Resource Identifier", "description": "The global unique identifier for this news object. This is the only required property and should identify the ninjs object, not be used for links to external resources etc. nar:newsItem@guid", "type": "string", "format": "uri" }, "type": { "title": "Type", "description": "The generic news type of this news object. (Value 'component' added in version 1.2 as issue #21.). See: http://cv.iptc.org/newscodes/ninature/ nar:itemClass", "type": "string", "enum": [ "text", "audio", "video", "picture", "graphic", "composite", "component" ] }, "representationtype": { "title": "Representation type", "description": "Indicates how complete this representation of a news item is. No mapping to nar. Specific for ninjs.", "type": "string", "enum": [ "full", "partial" ] }, "profile": { "title": "Profile", "description": "An identifier for the structure of the news object. This can be any string but we suggest something identifying the structure of the content such as 'text-only' or 'text-photo'. Profiles are typically provider-specific. nar:profile", "type": "string" }, "version": { "title": "Version", "description": "The version of the news object which is identified by the uri property. nar:newsItem@version", "type": "string" }, "firstcreated": { "title": "First created", "description": "Indicates when the first version of this ninjs object was created. (Added in version 1.2 from issue #5). nar:firstCreated", "type": "string", "format": "date-time" }, "versioncreated": { "title": "Version created", "description": "The date and time when this version of this ninjs object was created. nar:versionCreated", "type": "string", "format": "date-time" }, "contentcreated": { "title": "Content created", "description": "The date and time when the content of this ninjs object was originally created. For example an old photo that is now handled as a ninjs object. nar:contentCreated", "type": "string", "format": "date-time" }, "embargoed": { "title": "Embargoed", "description": "The date and time before which all versions of the news object are embargoed. If absent, this object is not embargoed. nar:embargoed", "type": "string", "format": "date-time" }, "pubstatus": { "title": "Publication status", "description": "The publishing status of the news object, its value is *usable* by default. nar:pubStatus", "type": "string", "enum": [ "usable", "withheld", "canceled" ] }, "urgency": { "title": "Urgency", "description": "The editorial urgency of the content. Values from 1 to 9. 1 represents the highest urgency, 9 the lowest. nar:urgency", "type": "number" }, "copyrightholder": { "title": "Copyright holder", "description": "The person or organisation claiming the intellectual property for the content. nar:copyrightHolder", "type": "string" }, "copyrightnotice": { "title": "Copyright notice", "description": "Any necessary copyright notice for claiming the intellectual property for the content. nar:copyrightNotice", "type": "string" }, "usageterms": { "title": "Usage terms", "description": "A natural-language statement about the usage terms pertaining to the content. nar:usageTerms", "type": "string" }, "ednote": { "title": "Editorial note", "description": "A note that is intended to be read by internal staff at the receiving organisation, but not intended to be published. (Added in version 1.2 from issue #6.). (Consider using this before using the descriptions array.) ednote: nar:edNote", "type": "string" }, "language": { "title": "Language", "description": "The human language used by the content. The value should follow IETF BCP47. nar:language", "type": "string" }, "descriptions": { "title": "Descriptions", "description": "An array of one or more descriptions of the ninjs object. See also ednote for information from provider to reciever. Descriptions are seen as metadata. For a simple description use an array with one object only containing the value property. Role and contenttype are then undefined and it is up to the provider.", "type": "array", "items": { "type": "object", "required": ["value"], "additionalProperties": false, "properties": { "role": { "title": "Role", "description": "The role of this description", "type": "string" }, "contenttype": { "title": "Content Type", "description": "The IANA (Internet Assigned Numbers Authority) media type of the content of this description. Used to be called MIME type.", "type": "string" }, "value": { "title": "Value", "description": "The descriptive text identified with the above role (and contenttype).", "type": "string" } } } }, "bodies": { "title": "Bodies", "description": "An array of body objects with the content as text or with markup. For a simple body use an array with one object only containing the value property. Role and contenttype are then undefined and it is up to the provider.", "type": "array", "items": { "type": "object", "required": ["value"], "additionalProperties": false, "properties": { "role": { "title": "Role", "description": "The role of this body", "type": "string" }, "contenttype": { "title": "Content Type", "description": "The IANA (Internet Assigned Numbers Authority) media type of the content of this body. Used to be called MIME type.", "type": "string" }, "charcount": { "title": "Character count", "description": "The total character count in this body excluding figure captions. (Added in version 1.2 according to issue #27.). nar:charcount", "type": "number" }, "wordcount": { "title": "Word count", "description": "The total number of words in this body excluding figure captions. (Added in version 1.2 according to issue #27.). nar:wordcount", "type": "number" }, "value": { "title": "Value", "description": "The body text identified with the above role and contenttype.", "type": "string" } } } }, "headlines": { "title": "Headlines", "description": "An array of objects containing various types of headlines. For a simple headline use an array with one object only containing the value property. Role and contenttype are then undefined and it is up to the provider.", "type": "array", "items": { "type": "object", "required": ["value"], "additionalProperties": false, "properties": { "role": { "title": "Role", "description": "The role of this headline", "type": "string" }, "contenttype": { "title": "Content Type", "description": "The IANA (Internet Assigned Numbers Authority) media type of the content of this headline. Used to be called MIME type.", "type": "string" }, "value": { "title": "Value", "description": "The headline identified with the above role and contenttype.", "type": "string" } } } }, "people": { "title": "People", "description": "An array of objects describing individual human beings. nar:subject", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of a person", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the person", "type": "string" }, "uri": { "title": "URI", "description": "The identifier for the person as a complete uri with the code.", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the person as a free-text string.", "type": "string" }, "contactinfo": { "type": "array", "items": { "$ref": "#/$defs/contactinfoType" } } } } }, "organisations": { "title": "Organisations", "description": "An array of objects describing administrative and functional structures which may, for example, act as a business, as a political party or not-for-profit party. nar:subject", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the organisation", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the organisation", "type": "string" }, "uri": { "title": "URI", "description": "The identifier of the organisation as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the organisation as a free-text string.", "type": "string" }, "symbols": { "title": "Symbols", "description": "Symbols used for a financial instrument linked to the organisation at a specific market place", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "ticker": { "title": "Ticker", "description": "Ticker symbol used for the financial instrument", "type": "string" }, "exchange": { "title": "Exchange", "description": "Identifier for the marketplace which uses the ticker symbols of the ticker property", "type": "string" }, "symboltype": { "title": "Symbol type uri", "description": "https://cv.iptc.org/newscodes/financialinstrumentsymboltype. Same as type in G2.", "type": "string", "format": "uri" }, "symbol": { "title": "Symbol", "description": "Compare with hasInstrument in NewsML-G2. Same as symbol in G2.", "type": "string" } } } }, "contactinfo": { "type": "array", "items": { "$ref": "#/$defs/contactinfoType" } } } } }, "places": { "title": "Places", "description": "An array of named locations. nar:subject", "additionalProperties": false, "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the place", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the place", "type": "string" }, "uri": { "title": "URI", "description": "The identifier for the place as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the place as a free-text string.", "type": "string" }, "contactinfo": { "type": "array", "items": { "$ref": "#/$defs/contactinfoType" } }, "geojson": { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://geojson.org/schema/GeoJSON.json", "title": "GeoJSON", "oneOf": [ { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON GeometryCollection", "type": "object", "required": [ "type", "geometries" ], "properties": { "type": { "type": "string", "enum": [ "GeometryCollection" ] }, "geometries": { "type": "array", "items": { "oneOf": [ { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Feature", "type": "object", "required": [ "type", "properties", "geometry" ], "properties": { "type": { "type": "string", "enum": [ "Feature" ] }, "id": { "oneOf": [ { "type": "number" }, { "type": "string" } ] }, "properties": { "oneOf": [ { "type": "null" }, { "type": "object" } ] }, "geometry": { "oneOf": [ { "type": "null" }, { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON GeometryCollection", "type": "object", "required": [ "type", "geometries" ], "properties": { "type": { "type": "string", "enum": [ "GeometryCollection" ] }, "geometries": { "type": "array", "items": { "oneOf": [ { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON FeatureCollection", "type": "object", "required": [ "type", "features" ], "properties": { "type": { "type": "string", "enum": [ "FeatureCollection" ] }, "features": { "type": "array", "items": { "title": "GeoJSON Feature", "type": "object", "required": [ "type", "properties", "geometry" ], "properties": { "type": { "type": "string", "enum": [ "Feature" ] }, "id": { "oneOf": [ { "type": "number" }, { "type": "string" } ] }, "properties": { "oneOf": [ { "type": "null" }, { "type": "object" } ] }, "geometry": { "oneOf": [ { "type": "null" }, { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON GeometryCollection", "type": "object", "required": [ "type", "geometries" ], "properties": { "type": { "type": "string", "enum": [ "GeometryCollection" ] }, "geometries": { "type": "array", "items": { "oneOf": [ { "title": "GeoJSON Point", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Point" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "number" } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON LineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "LineString" ] }, "coordinates": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON Polygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "Polygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPoint", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPoint" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiLineString", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiLineString" ] }, "coordinates": { "type": "array", "items": { "type": "array", "minItems": 2, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } }, { "title": "GeoJSON MultiPolygon", "type": "object", "required": [ "type", "coordinates" ], "properties": { "type": { "type": "string", "enum": [ "MultiPolygon" ] }, "coordinates": { "type": "array", "items": { "type": "array", "items": { "type": "array", "minItems": 4, "items": { "type": "array", "minItems": 2, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } }, "bbox": { "type": "array", "minItems": 4, "items": { "type": "number" } } } } ] } } } }, "subjects": { "title": "Subjects", "description": "An array of objects holding concepts with a relationship to the content. nar:subject", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the subject", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the subject", "type": "string" }, "uri": { "title": "URI", "description": "The identifier of the subject as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the subject as a free-text string.", "type": "string" }, "creator": { "title": "Creator", "description": "Specifies which entity (person, organisation or system) that has created or last edited the property.", "type": "string" }, "relevance": { "title": "Relevance", "description": "The relevance of the metadata to the news content to which it is attached.", "type": "integer", "minimum": 0, "maximum": 100 }, "confidence": { "title": "Confidence", "description": "The confidence with which the metadata has been assigned.", "type": "integer", "minimum": 0, "maximum": 100 } } } }, "events": { "title": "Events", "description": "An array of objects describing something which happens in a planned or unplanned manner. nar:?", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the event", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the event", "type": "string" }, "uri": { "title": "URI", "description": "The identifier for the event as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the event as a free-text string.", "type": "string" } } } }, "objects": { "title": "Objects", "description": "An array of objects describing something material, excluding persons. nar:subject", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the object", "type": "string" }, "rel": { "title": "Relationship", "description": "The relationship of the content of the news object to the object", "type": "string" }, "uri": { "title": "URI", "description": "The identifier for the object as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the object as a free-text string.", "type": "string" } } } }, "infosources": { "title": "Info sources", "description": "An array of parties (person or organisation) which originated, modified, enhanced, distributed, aggregated or supplied the content or provided some information used to create or enhance the content. (Added in version 1.2 according to issue #15.) . infosource: nar:infoSource", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the infosource", "type": "string" }, "role": { "title": "Role", "description": "The role the infosource in relationship to the content as a uri.", "type": "string", "format": "uri" }, "uri": { "title": "URI", "description": "The identifier of the infosource as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the infosource as a free-text string.", "type": "string" }, "contactinfo": { "type": "array", "items": { "$ref": "#/$defs/contactinfoType" } } } } }, "title": { "title": "Title", "description": "A short natural-language name for the item. Title is metadata, use headlines for publishable headlines. (Added in version 1.2 according to issue #9). nar:itemMeta/title", "type": "string" }, "by": { "title": "By", "description": "A natural-language statement about the creator (author, photographer etc.) of the content. nar:by", "type": "string" }, "slugline": { "title": "Slugline", "description": "A human-readable identifier for the item. (Added in version 1.2 from issue #4.). nar:slugline", "type": "string" }, "located": { "title": "Located", "description": "The name of the location from which the content originates. nar:located", "type": "string" }, "renditions": { "title": "Renditions", "description": "An array of objects with different renditions of the news object. nar:remoteContent", "type": "array", "additionalProperties": false, "items": { "description": "A specific rendition of the content of the news object. (Description changed in version 1.2 according to issue #17.)", "type": "object", "additionalProperties": false, "required": ["name"], "properties": { "name": { "title": "Name", "description": "The name of this object in the array of renditions. For example 'thumbnail'", "type": "string" }, "href": { "title": "href", "description": "The URL for accessing the rendition as a resource. nar:remoteContent@ref", "type": "string", "format": "uri" }, "contenttype": { "title": "Content Type", "description": "A media type which applies to this rendition. nar:remoteContent@contenttype", "type": "string" }, "title": { "title": "Title", "description": "A title for the link to the rendition resource", "type": "string" }, "height": { "title": "Height", "description": "For still and moving images: the height of the display area measured in pixels. nar:remoteContent@height", "type": "number" }, "width": { "title": "Width", "description": "For still and moving images: the width of the display area measured in pixels. nar:remoteContent@width", "type": "number" }, "sizeinbytes": { "title": "Size in bytes", "description": "The size of the rendition resource in bytes", "type": "number" }, "duration": { "title": "Duration", "description": "The total time duration of the content in seconds. (Added in version 1.2. Issue #18). nar:remoteContent@duration", "type": "number" }, "format": { "title": "Format", "description": "A refinement of a generic content type (i.e. IANA media type) by a literal string value. nar:remoteContent@contenttypevariant and nar:remoteContent@format", "type": "string" } } } }, "associations": { "title": "Associations", "description": "An array of objects with content of news objects which are associated with this news object.", "type": "array", "items": { "required": [ "name", "uri" ], "description": "One associated object where each object can use all properties in ninjs.", "type": "object", "anyOf": [ { "properties": { "name": { "type": "string", "description": "The name of this object in the array of associations. For example 'logo'" } } }, { "$ref": "#" } ], "unevaluatedProperties": false } }, "altids": { "title": "Alternative ids", "description": "Alternative identifiers assigned to the content. Each alternative id can have a role and a value. nar:altId issue #3.", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "role": { "title": "Role", "description": "The role of the alternative id", "type": "string" }, "value": { "title": "Value", "description": "The alternative id value", "type": "string" } } } }, "trustindicators": { "title": "Trust indicators", "description": "An array of objects to allow links to documents about trust indicators. issue #44. (Added in version 1.3)", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "role": { "title": "Role", "description": "The role of the trust indicator as a complete uri", "type": "string", "format": "uri" }, "title": { "title": "Title", "description": "The title of the resource being referenced.", "type": "string" }, "href": { "title": "href", "description": "The URL for accessing the trust indicator resource.", "type": "string", "format": "uri" } } } }, "standard": { "title": "Standard", "type": "object", "description": "An object with information about standard, version and schema this instance is valid against. nar:standard, nar:standardversion and xml:schema issue #43. (Added in version 1.3)", "additionalProperties": false, "properties": { "name": { "title": "Name of standard.", "description": "For example ninjs. nar:standard", "type": "string" }, "version": { "title": "Version of standard.", "description": "For example 1.3. nar:standardversion", "type": "string" }, "schema": { "title": "Schema", "description": "The uri of the json schema to use for validation.", "type": "string", "format": "uri" } } }, "genres": { "title": "Genres", "description": "A nature, intellectual or journalistic form of the content. nar:genre. (Added in version 1.3)", "type": "array", "items": { "type": "object", "additionalProperties": false, "properties": { "name": { "title": "Name", "description": "The name of the genre", "type": "string" }, "uri": { "title": "URI", "description": "The identifier of the genre as a complete uri", "type": "string", "format": "uri" }, "literal": { "title": "Literal", "description": "An identifier for the genre as a free-text string.", "type": "string" } } } }, "expires": { "title": "Expires", "description": "The date and time after which the Item is no longer considered editorially relevant by its provider. nar:expires (Added in 2.1)", "type": "string", "format": "date-time" }, "rightsinfo": { "title": "Rights information", "type": "object", "description": "Expression of rights to be applied to content. nar:rightsInfo", "properties": { "langid": { "type": "string", "title": "Language id", "description": "Identifier for the Rights Expression language used. nar:@langid", "format": "uri" }, "linkedrights": { "title": "Linked rights", "description": "A link from the current Item to Web resource with rights related information. nar:link", "type": "string", "format": "uri" }, "encodedrights": { "title": "Encoded Rights", "additionalProperties": false, "type": "string", "description": "Contains a rights expression as defined by a Rights Expression Language. nar:rightsExpressionXML or nar:rightsExpressionData" } }, "oneOf": [ { "required": ["linkedrights"] }, { "required": ["encodedrights"] } ] } } } try { addSchema(schema, `http://www.example.com/test`) let valid = await validate(`http://www.example.com/test`, instance, "BASIC") console.log(valid) } catch (err) { console.error(err.message) }

jdesrosiers commented 1 year ago

You haven't loaded support for the dialects needed for this schema.

import { addSchema, validate } from '@hyperjump/json-schema/draft-2020-12'
import "@hyperjump/json-schema/draft-04" 

You need to load support for draft-07 because that's what the GeoJSON schema uses. There's supposed to be an error that tells you that, but apparently that isn't working for embedded schemas.

jdesrosiers commented 1 year ago

I appreciate you exposing bugs, but embedding the GeoJSON schema into the parent schema isn't really a good idea. Especially the concept of embedding an older dialect in a modern one. My library supports that kind of thing, but I haven't heard of any others that do, so you shouldn't expect that to necessarily work in another validator.

jeremyfiel commented 1 year ago

why wouldn't that be a good idea? isn't that behavior similar to the OAS jsonSchemaDialect keyword? it allows using different drafts and each subschema to be validated against the defined metaschema

this is off-topic but my use case would be upgrading to OAS 3.1 and still using draft-04 external schemas for everything.

jdesrosiers commented 1 year ago

It's mainly not a good idea because supporting embedded schemas is not required in older (pre-2020-12) versions of the JSON Schema specification. If you expect to distribute these schemas where it might be used with other validators, you should stick to functionality that is likely to be supported by a wide range of implementations.

The other thing I had in mind is just that there's generally better ways to deal with external references than embedding. I would have just loaded each schema separately,

addSchema(ninjs);
addSchema(geoJson);

or, if the external schemas are on the web (served properly) or filesystem you don't even need to load anything, just reference them.

This is much simpler and avoids the complexity and compatibility issues involved with embedding.

isn't that behavior similar to the OAS jsonSchemaDialect keyword?

I'm missing your point here, sorry.

my use case would be upgrading to OAS 3.1 and still using draft-04 external schemas for everything.

That's what I'm suggesting. Just let your external schemas be external. They don't need to be bundled unless you're working with tooling that can't handle external schemas.

jdesrosiers commented 1 year ago

You should now (v1.4.3) see the same helpful message for missing dialect support when in an embedded schema than you would for a root schema.

jeremyfiel commented 1 year ago

It's mainly not a good idea because supporting embedded schemas is not required in older (pre-2020-12) versions of the JSON Schema specification. If you expect to distribute these schemas where it might be used with other validators, you should stick to functionality that is likely to be supported by a wide range of implementations.

The other thing I had in mind is just that there's generally better ways to deal with external references than embedding. I would have just loaded each schema separately,

addSchema(ninjs);
addSchema(geoJson);

or, if the external schemas are on the web (served properly) or filesystem you don't even need to load anything, just reference them.

This is much simpler and avoids the complexity and compatibility issues involved with embedding.

I guess my question is why would an embedded schema behave differently than an external schema? Ultimately, it seems like the same behavior. when an external schema is loaded, it parses the full schema in the same way (i assume) it would parse an embedded one. When a new dialect in an embedded schema is reached, the validator uses the proper metaschema.

jdesrosiers commented 1 year ago

why would an embedded schema behave differently than an external schema?

It does now (as of 2020-12), but that hasn't always been the case. Previously, an $id in a sub-schema just meant a change in base URI in the same schema, not an embedded schema. The concept of $id representing an embedded schema was introduced in 2019-09, but there was an unfortunate line in the spec that said that the dialect of an embedded schema had to match the dialect of the parent schema. It wasn't until 2020-12 that embedding and external references became the same thing. Therefore, it's a bit ambiguous/undefined what happens when you embed a pre-2020-12 schema because the concept was different.