Repository: bcherny/json-schema-to-typescript

Issue #324: [bug] $ref resolve uses wrong root dir
Created: 2020-07-18T18:56:57Z
So we have project with structure like
project/apidocs/entitity
project/apidocs/response
project/ts-apidocs/entitity
project/ts-apidocs/response
if we launch cli tool like
json2ts -i ./apidocs/response/**/*.json -o ts-apidocs
we have a problem
ResolverError: Error opening file ".../project/entity/Something-2.json" (notice how apidocs folder is missing)
we have a file
./apidocs/response/Something.json
which has reference
"$ref": "../entity/Something-2.json"
During resolvement cli tool uses process.cwd for resolving
https://github.com/bcherny/json-schema-to-typescript/blob/master/src/resolver.ts#L12
but according to docs mentioned at
https://github.com/bcherny/json-schema-to-typescript/blob/master/src/index.ts#L24
https://tools.ietf.org/id/draft-pbryan-zyp-json-ref-03.html#rfc.section.4
If the URI contained in the JSON Reference value is a relative URI, then the base URI resolution MUST be calculated according to [RFC3986], section 5.2. Resolution is performed relative to the referring document.

so it should be relative to referring document (Something.json in my example) and not process.cwd
So our current workaround: we use docs dir as cwd, but it will break as soon as we'll have nested folder structure

Duplicate issue #417: Set Default Working Directory to Schema Root
Created: 2021-10-31T15:11:12Z
Set Default Working Directory to Schema Root
References should be resolved by the directory of the schema itself, not the script/program caller. Currently, the cwd is resetting on every de-reference, thus making it virtually impossible to compile multi-file schemas without first de-referencing them with the $RefParser library. This ruins the ability to reuse definition interfaces, and bloats code. Either way, defaulting to schema root would conform with the RFC, trivially.
I don't think this should be too difficult to change because the $RefParser library does this by default.
Example of Issue (exposition):
Assume a working tree like the following.
schemas
├── bits
│   ├── review_partial.json
│   └── user_partial.json
├── helpers
│   ├── object_id.json
│   └── tokens_wrapper.json
├── review.json
└── user.json

And the file schemas/bits/review_partial.json being:
{
    "$schema": "http://json-schema.org/draft-07/schema",
    "type": "object"
    "properties": {
        "_id": { 
            "$ref": "../helpers/object_id.json"
        }
    }
}
And the file schemas/helpers/object_id.json being:
{
    "$schema": "http://json-schema.org/draft-07/schema",
    "type": "object",
    "properties": {
        "wrapper": {
            "$ref": "./tokens_wrapper.json",
        }
    }
}

Invoking the compiler on schemas/bits/review_partial.json outside the directory (say, at the root), will not result in a schema-relative reference.
If you change the cwd setting to schema/bits, this initial reference will resolve, but the reference in schemas/helpers/object_id.json will ALSO resolve with cwd of schemas/bits, which, it isn't in, and thus the reference fails to resolve to schemas/helpers/token_wrapper.json

$RefParser Library
Note that the parser will auto resolve based on the schema root if invoked on the file. Take the last example: by default, the following will bundle the schema. This is required before passing it to this library, which, as I said ruins the possibility of interface definition re-use, and makes it much more difficult to invoke, especially without experience with JSON references.
console.log(await $RefParser.bundle("./schemas/bits/review_partial.json"));
// logs bundled schema without error

Closing comment (2022-05-22T04:46:39Z): Dup of #324.
Sorry for the delayed response. Feel free to update the PR per requested changes!