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

.schema.json file is not recognized by media type system #23

Closed harrisgilliam closed 1 year ago

harrisgilliam commented 1 year ago

Running on a MacBook, this simple TypeScript program:

import { compile } from '@hyperjump/json-schema/experimental';
import path from 'path';

async function main(): Promise<void> {
  const fullPath = path.resolve('./test.schema.json');

  const compiledSchema = await compile(`file://${fullPath}`);

  console.log(JSON.stringify(compiledSchema, undefined, 2));
}

main()
  .then(() => {
    process.exit(0);
  })
  .catch((error) => {
    console.log(error);
    process.exit(-1);
  });

Produces this error:

Error: file:///Users/hgilliam/git/assure/assure-libs/workspaces/@quil-libs/assure-firestore-data/v2-codegen/test.schema.json is not a schema. Found a document with media type: application/octet-stream

Despite the README stating that when reading from the filesystem a file with the .schema.json suffix would be correctly recognized as a schema file.

Using version 1.2.1 of the package.

harrisgilliam commented 1 year ago

A quick search through the code confirms that the getContentType function as defined in https://github.com/hyperjump-io/json-schema/blob/main/lib/media-types.js is not used anywhere... so any recognition of schema files based on suffixes will never work. The check in parseResponse always uses whatever is returned by the parse function of the "content-type" package. That will never return "application/schema+json" for a file URL.

jdesrosiers commented 1 year ago

The media type plugin for the JSON Schema media type doesn't get loaded until you import support for a JSON Schema version that needs it. Similarly, when you import support for an OpenAPI Schema version the OpenAPI media type is loaded. You need to load at least one JSON Schema version.

import '@hyperjump/json-schema/2020-12';
import { compile } from '@hyperjump/json-schema/experimental';
import path from 'path';

async function main(): Promise<void> {
  const fullPath = path.resolve('./test.schema.json');

  const compiledSchema = await compile(`file://${fullPath}`);

  console.log(JSON.stringify(compiledSchema, undefined, 2));
}

What are you building that you need to use the compile function? It's a pretty low level function, so either you're on the wrong track or doing something very interesting.

harrisgilliam commented 1 year ago

I making my own, very specific, code generator. So my idea was to just compile the schema and iterate through the AST to generate my code.

jdesrosiers commented 1 year ago

Cool! The utilities for that kind of thing aren't well developed at this point, but it's something I very much want to improve and use myself. Let me know if you have any suggestions!

harrisgilliam commented 1 year ago

Another question I have is why did you choose to distribute you library as an ECMAScript module instead of CommonJS? Most of the JS infrastructure is still using CommonJS so using ESM presents some issue when integrating with other stuff.

jdesrosiers commented 1 year ago

It was a tough decision to drop support for CommonJS. In the end, I just don't want to maintain support for both or deal with transpiled deliverables. I was doing all those things in the 0.x versions and it caused more problems than it was worth, so I simplified my world and just picked one. I realize that I'm leaving some people behind, but in the end, I didn't write this for them. I think it's great if other people want to use it, but ultimately I wrote this for me and my experiments, so some of my choices might be selfish.