hyperjump-io / json-schema-core Goto Github PK
View Code? Open in Web Editor NEWA framework for building JSON Schema validators
License: MIT License
A framework for building JSON Schema validators
License: MIT License
FetchErrro
will be raised if trying to get a local file in windows:
// javascript or typescript code
const schema = await JsonSchema.get('file:///C:/path/to/my/schema/schema.json');
// error
// (node:23068) UnhandledPromiseRejectionWarning: FetchError: Invalid response body while trying to fetch : ENOENT: no such file or directory, open 'C:\C:\path\to\my\schema\schema.json'
// at ReadStream.<anonymous> (D:\Projects\YF1999\easy-projs\node_modules\node-fetch\lib\index.js:399:12)
// at ReadStream.emit (events.js:387:35)
// at internal/fs/streams.js:126:14
// at FSReqCallback.oncomplete (fs.js:180:23)
The reason is that, in fetch.js the path converted from that url is /C:/path/to/my/schema/schema.json
.
I don't know much about URL, but it should be C:/path/to/my/schema/schema.json
.
There’s a “cosnt” in the README.
I’m trying to add the correct line but it’s not obvious how to create an issue from here because GitHub parses and displays it without line numbers. Also I’m on my phone.
I'm trying to load a schema from a file:
import { get } from "@hyperjump/json-schema/lib";
import { join } from "path";
const schema = await get("file://" + join(__dirname, "mySchema.json"));
I expected this to work based on the example in the readme, but I get this error message:
{
"message": "Can't access file resource from network context",
"stack": [
"Error: Can't access file resource from network context",
" at safeResolveUrl (/var/task/node_modules/@hyperjump/json-schema-core/lib/schema.js:184:11)",
" at Object.get (/var/task/node_modules/@hyperjump/json-schema-core/lib/schema.js:135:23)",
" at Resource.doMove (/var/src/api/target-resource.ts:113:26)",
" at Resource.handle (/var/src/api/target-resource.ts:48:21)",
" at Object.handleProxyEvent (/var/src/api/index.ts:11:37)",
" at Runtime.handler (/var/src/application.ts:11:12)",
" at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
]
}
Am I doing something wrong?
I have a short script that loads the schema below from a file, then attempts to validate an instance document against it. If I remove the definition of property "b", then this schema will fail to validate, as expected. The error message is:
request to http://example.com/schema/2 failed, reason: getaddrinfo ENOTFOUND example.com
However, in its full form, I will receive first the error above, followed by an unhandled promise rejection:
(node:219) UnhandledPromiseRejectionWarning: FetchError: request to http://example.com/schema/3 failed, reason: getaddrinfo ENOTFOUND example.com
I believe this is an error, in that the library should either return a single error (for the unresolved $ref) or a single rejection (perhaps with a list of $ref failures). (I have a feeling maybe a Promise.allSettled is missing, but that's just a guess.) Alternatively, it may be that I don't understand the API contract for JsonSchema.validate(), in which case I'd appreciate an explanation. I'm simply using:
const output = await JsonSchema.validate(schema, instanceJSON, JsonSchema.VERBOSE);
For context: I am attempting to apply a set of related schemas that use $id and $ref with schema identifiers that, as in the example below, are not network locations. If a explicitly load the various schemas, everything works. I encountered this when I $ref'ed a schema that hadn't been loaded. That's an error on my part, but one I'd like my script to catch "cleanly" and report.
{ "$schema": "http://json-schema.org/draft-06/schema#", "$id": "http://example.com/schema/1", "properties": { "a": { "$ref": "http://example.com/schema/2" }, "b": { "$ref": "http://example.com/schema/3" } } }
I might be understanding this incorrectly, but it looks like there's support for pulling the schema version out of a Content-Type parameter. For context, we're hosting our json schemas in a web server and trying to validate against them in our frontend. One problem is that our schemas can't have a "$schema" property because they're technically subschemas since they are referenced by some openapi specs. The json schema spec says that "$schema" shouldn't be in subschemas and the library we're using for hosting, Vertx, doesn't like seeing "$schema" in the subschemas. So we went down the route of putting the schema version into a response header.
We thought it'd work since this library seems to support the Content-Type parameters, but we ran into an exception when we attempted a "JsonSchema.get()". It appears that the "JsonSchema.get()" is handling the "defaultDialectId" a bit differently than the "JsonSchema.add()" and the "resolveUrl()" call is throwing an exception before it gets a chance to fall back to the "defaultDialectId".
https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.11.2
json-schema-core/lib/schema.js
Line 206 in eac4635
I think I know the solution, but I'm not entirely sure. We currently have this for the "dialectId" handling in the "JsonSchema.get()":
const [schema, defaultDialectId] = await MediaTypes.parse(response);
// Make sure the meta-schema is loaded if this isn't a known dialect
const dialectId = resolveUrl(schema.$schema, "") || defaultDialectId;
if (id !== dialectId && !(dialectId in dialectJsonSchemaVersion)) {
await get(dialectId);
}
Would this be a possible fix? I'm not sure what the difference between the "defaultDialectId" and the "defaultSchemaVersion" in the "JsonSchema.add()" function are, but maybe this would work? The other option is just doing a check to see if the "$schema" is present or not and fall back to the "defaultDialectId" if it's not present.
const [schema, defaultDialectId] = await MediaTypes.parse(response);
// Make sure the meta-schema is loaded if this isn't a known dialect
const dialectId = resolveUrl(schema["$schema"] || defaultDialectId, "");
if (id !== dialectId && !(dialectId in dialectJsonSchemaVersion)) {
await get(dialectId);
}
I suggest you strictly follow the json-schema spec and not make Content-type: application/schema+json
mandatory when the spec uses SHOULD
and not MUST
.
json-schema-core/lib/schema.js
Lines 172 to 173 in 1feb331
Here's a breaking example that would otherwise work fine:
{
"$id": "https://example.com/geographical-location.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "integer"
},
"warehouse_location": {
"description": "Coordinates of the warehouse with the product",
"$ref": "https://json-schema.org/learn/examples/geographical-location.schema.json"
}
},
"required": ["id"],
"additionalProperties": false
}
This throws: Error: https://json-schema.org/learn/examples/geographical-location.schema.json is not a schema. Found a document with media type: application/json
If you allow the more generic application/json
Content-type, a superset of application/schema+json
, then the above would work instead of throwing a premature error. You do further parsing of the JSON to determine if it really is a schema doc here so there's not much downside in being a forgiving parser:
json-schema-core/lib/schema.js
Lines 32 to 40 in 1feb331
I'm seeing an "undefined" error in a case where the schema is invalid, but I'd expect to get an error message directing me to the error at hand. Here's the invalid schema:
{
"$schema": "http://json-schema.org/draft-06/schema#",
"$id": "http://example.com/test",
"properties": {
"a": { "type": "date-time" }
}
}
If I fix this by changing the type of "a" to "string", then the schema loads and I can validate instance documents. With this error, the schema will load, but when I validate a document, it throws undefined
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.