cwd option creates invalid path
McBen opened this issue · 12 comments
(on windows) looks like it adds the process path to the CWD option.
worked fine in 11.0.3
with 12.0 I got:
ResolverError: Error opening file "E:\myproject\node_modules\@bcherny\json-schema-ref-parser\E:\myproject\src\api\v2\schema\index.schema"
[...]
at ReadFileContext.callback (E:\myproject\node_modules\@bcherny\json-schema-ref-parser\cjs\resolvers\file.js:96:32)
at FSReqCallback.readFileAfterOpen [as oncomplete] (node:fs:314:13) {
my code:
const fs = require("fs");
const path = require("path");
const json2ts = require("json-schema-to-typescript");
const fileToCompile = "src/api/v2/schema/index.schema"
json2ts.compileFromFile(fileToCompile, {
unknownAny: false,
cwd: path.join(process.cwd(), path.dirname(fileToCompile)), // <- process.cwd added to express the problem
style: { tabWidth: 4 }
})
.then(ts => fs.writeFileSync(path.join(path.dirname(fileToCompile), "compiled.ts"), ts));
}
We're seeing this too, with or without the CWD option set, via the CLI
Affects 12.0.0, 11.0.5, 11.0.4 - 11.0.3 - 11.01 seem fine
👍🏼 on this
$~> json2ts --cwd "C:/Users/xyz/Desktop/schemas/quicktype_example/schemas" schemas/bridgeRequest.schema.json foo.ts
[
{
stack: 'ResolverError: Error opening file "C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\node_modules\\@bcherny\\json-schema-ref-parser\\C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\schemas\\appIdentifier.schema.json" \n' +
"ENOENT: no such file or directory, open 'C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\node_modules\\@bcherny\\json-schema-ref-parser\\C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\schemas\\appIdentifier.schema.json'\n" +
' at ReadFileContext.callback (C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\node_modules\\@bcherny\\json-schema-ref-parser\\cjs\\resolvers\\file.js:96:32)\n' +
' at FSReqCallback.readFileAfterOpen [as oncomplete] (node:fs:324:13)',
code: 'ERESOLVER',
message: 'Error opening file "C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\node_modules\\@bcherny\\json-schema-ref-parser\\C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\schemas\\appIdentifier.schema.json" \n' +
"ENOENT: no such file or directory, open 'C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\node_modules\\@bcherny\\json-schema-ref-parser\\C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\schemas\\appIdentifier.schema.json'",
source: 'C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\node_modules\\@bcherny\\json-schema-ref-parser\\C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\schemas\\appIdentifier.schema.json',
path: null,
toJSON: [Function: toJSON],
ioErrorCode: 'ENOENT',
name: 'ResolverError',
footprint: 'null+C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\node_modules\\@bcherny\\json-schema-ref-parser\\C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\schemas\\appIdentifier.schema.json+ERESOLVER+Error opening file "C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\node_modules\\@bcherny\\json-schema-ref-parser\\C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\schemas\\appIdentifier.schema.json" \n' +
"ENOENT: no such file or directory, open 'C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\node_modules\\@bcherny\\json-schema-ref-parser\\C:\\Users\\xyz\\Desktop\\schemas\\quicktype_example\\schemas\\appIdentifier.schema.json'",
toString: [Function: toString]
}
]
This is coming from the json-schema-ref-parser library.
Someone has reported it there as well: APIDevTools/json-schema-ref-parser#311
I put together a PR to fix it: APIDevTools/json-schema-ref-parser#315 not sure how quickly a maintainer will get to it.
This library technically uses a fork of that, so maybe can also pull over my PR into the fork.
same here:
node:internal/process/promises:288
triggerUncaughtException(err, true /* fromPromise */);
^
ResolverError: Error opening file "C:\Users\55119\Elucidário.art\elucidario\node_modules\@bcherny\json-schema-ref-parser\C:\Users\55119\Elucidário.art\elucidario\packages\md-to-gdoc\src\presets\abnt\schemas\referencias\autor.json"
ENOENT: no such file or directory, open 'C:\Users\55119\Elucidário.art\elucidario\node_modules\@bcherny\json-schema-ref-parser\C:\Users\55119\Elucidário.art\elucidario\packages\md-to-gdoc\src\presets\abnt\schemas\referencias\autor.json'
at ReadFileContext.callback (c:\Users\55119\Elucid%C3%A1rio.art\elucidario\node_modules\@bcherny\json-schema-ref-parser\cjs\resolvers\file.js:96:32)
at FSReqCallback.readFileAfterOpen [as oncomplete] (node:fs:324:13) {
code: 'ERESOLVER',
source: 'C:\\Users\\55119\\Elucidário.art\\elucidario\\node_modules\\@bcherny\\json-schema-ref-parser\\C:\\Users\\55119\\Elucidário.art\\elucidario\\packages\\md-to-gdoc\\src\\presets\\abnt\\schemas\\referencias\\autor.json',
path: null,
toJSON: [Function: toJSON],
ioErrorCode: 'ENOENT',
[Symbol(nodejs.util.inspect.custom)]: [Function: inspect]
}
Node.js v18.12.1
My current workaround is providing this to options:
{
$refOptions: {
resolve: {
file: {
async read(file: FileInfo): Promise<string> {
if (
process.platform === 'win32' &&
file.url.split(':').length > 1
) {
[, file.url] = file.url.match(/(.:[^:]+)$/) ?? [, 'error'];
}
return await readFile(file.url, 'utf8');
},
},
},
}
@matt1097 PRs for https://github.com/bcherny/json-schema-ref-parser are welcome. I also see a reasonable suggestion on your PR -- could using Node's path
library simplify some of the cross-platform logic?
I'll make a PR.
I believe the reason that library does not use path is because it can work directly in the browser without node
I was just mimicking, existing code style.
@bcherny since you already use path in your library here, i am willing to switch that chunk of code over to using path. the tradeoff being your fork becoming more distant from the original. If you are ok with that, I will take a stab at it.
I'll make a PR. I believe the reason that library does not use path is because it can work directly in the browser without node I was just mimicking, existing code style.
@bcherny since you already use path in your library here, i am willing to switch that chunk of code over to using path. the tradeoff being your fork becoming more distant from the original. If you are ok with that, I will take a stab at it.
Why not use a library like pathe?
https://www.npmjs.com/package/pathe
we experience this issue too
Would love to see this resolved as while meepen's solution worked at first, having a schema reference a file in the same folder causes it to error again.
I'm using pnpm
, nodejs 18
, and package.json "type": "module"
. In summary, I'm in ESM mode with pnpm
as the package manager. It works fine on the CI's Linux and my MacBook, but it doesn't work on my colleague's Windows laptop.
I tried to debug and found some issues in @apidevtools/json-schema-ref-parser/dist/lib/util.js
:
__dirname
is not available in ESM mode (it's used to calculateprojectPath
, but__dirname
is incorrect; it would benode_modules/.pnpm/@apidevtools/json-schema-ref-parser/dist/lib/util/url.js
). From what I can see, it's not needed. I'm not sure about the browser environment, but I think browsers don't have node?- Many checks for the Windows environment are unnecessary. If it's a node environment, using
path.resolve
orjoin
would suffice.
My temporary solution is to use pnpm patch
(or patch-package
if not using pnpm
). I modified @apidevtools/json-schema-ref-parser/dist/lib/util.js
by removing the Windows-related code. This way, it runs on Windows without affecting Linux and Mac. You can also replace it with path.resolve
.
For instance, I encountered an issue with this function:
const path_1 = require("path");
…
function fromFileSystemPath(path) {
// Step 1: On Windows, replace backslashes with forward slashes,
// rather than encoding them as "%5C"
if (isWindows) {
const hasProjectDir = path.toUpperCase().includes(projectDir.replace(/\\/g, "\\").toUpperCase());
const hasProjectUri = path.toUpperCase().includes(projectDir.replace(/\\/g, "/").toUpperCase());
if (hasProjectDir || hasProjectUri) {
path = path.replace(/\\/g, "/");
}
else {
path = `${projectDir}/${path}`.replace(/\\/g, "/");
}
}
// Step 2: `encodeURI` will take care of MOST characters
path = encodeURI(path);
// Step 3: Manually encode characters that are not encoded by `encodeURI`.
// This includes characters such as "#" and "?", which have special meaning in URLs,
// but are just normal characters in a filesystem path.
for (let i = 0; i < urlEncodePatterns.length; i += 2) {
path = path.replace(urlEncodePatterns[i], urlEncodePatterns[i + 1]);
}
return path;
}
exports.fromFileSystemPath = fromFileSystemPath;
I modified it to:
const path_1 = require("path");
…
function fromFileSystemPath(path) {
return path_1.resolve(path);
}
exports.fromFileSystemPath = fromFileSystemPath;
To apply the patch using pnpm
:
pnpm patch @apidevtools/json-schema-ref-parser
// Open the temporary folder and apply the above modifications
pnpm patch-commit tempfile // Refer to pnpm's instructions
@bcherny Is it possible this issue will be fixed if https://github.com/bcherny/json-schema-ref-parser is synced with the latest from https://github.com/APIDevTools/json-schema-ref-parser, currently shows that its 47 commits behind. I see they have since merged in the fixes for Issue #311 in APIDevTools/json-schema-ref-parser#321.