-
Notifications
You must be signed in to change notification settings - Fork 413
add support for importing typescript types and deduping imports #662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
node dist/src/cli.js --mirrorDir --declareExternallyReferenced false --outDir=qwer -i test/resources/mirror-dir/ReferencingType.json --cwd test/resources/mirror-dir -o foo.ts
…eferenced false -i test/resources/mirror-dir/ -o mirrorDir
There's some cleanup I need to do here--I left some debugging things in place. I'd welcome thoughts on if this makes sense in the meantime. |
|
||
if (dereferencedName) { | ||
dereferencedPaths.delete(schema) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems less than ideal. I need this elsewhere, and I'm wondering if there's a more natural way to register the source path for this schema without needing to keep all references in this map.
Cleaned it up. Still not sure this is the best implementation of this approach, but here is a stab. |
We're really interested in this functionality for jupytergis. Thanks for implementing @srsudar ! |
@mfisher87 , I've actually changed my approach on this a bit in my own project. I can't remember now if it was because this PR wasn't merged, or if I decided this new approach is better for some reason. Basically what I do now is generate all the files without any imports at all, and then I concatenate them all into a single file. I have a redocly lint rule that forces all my Here are the scripts I'm using. I keep my JSONSchema at From
This is just a small wrapper to use
import { mkdir, readdir, writeFile } from 'fs/promises';
import { compileFromFile } from 'json-schema-to-typescript';
import path from 'path';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import * as chalk from '@/scripts/lib/logWithColor';
async function convertAllSchemasWithJson2Ts({
srcDir,
outDir,
quiet = false,
}: {
srcDir: string;
outDir: string;
quiet: boolean;
}): Promise<void> {
const entries = await readdir(srcDir, { withFileTypes: true });
await mkdir(outDir, { recursive: true });
for (const entry of entries) {
const srcPath = path.join(srcDir, entry.name);
const destPath = path.join(outDir, entry.name.replace(/.json/, '.ts'));
if (entry.isDirectory()) {
await convertAllSchemasWithJson2Ts({
srcDir: srcPath,
outDir: path.join(outDir, entry.name),
quiet,
});
} else if (entry.isFile() && entry.name.endsWith('.json')) {
if (!quiet) {
console.log(` json2ts: converting [${srcPath}] to [${destPath}]`);
}
const outTs = await compileFromFile(srcPath, {
bannerComment: '\n',
// make them human readable
format: true,
// other tools use paths relative to the base jsonschema files
cwd: entry.parentPath,
declareExternallyReferenced: false,
});
await mkdir(path.dirname(destPath), { recursive: true });
await writeFile(destPath, outTs);
}
}
}
const argv = yargs(hideBin(process.argv))
.option('srcDir', {
type: 'string',
demandOption: true,
describe: 'Source directory',
})
.option('outDir', {
type: 'string',
demandOption: true,
describe: 'Output directory',
})
.option('quiet', {
type: 'boolean',
default: true,
describe: 'Suppress output',
})
.strict()
.help()
.parseSync();
chalk.printHeader(' ☀️ ⏳ Generating json2ts typescript libraries...');
console.log('');
console.log(' This takes our JSONSchema ground-truth type definitions and');
console.log(' generates familiar, human-readable typescript types like we');
console.log(' know and love.');
console.log('');
convertAllSchemasWithJson2Ts(argv);
chalk.printHeader(' ☀️ ✅ Done!'); And then I use this script to walk that dir and concatenate everything into a single
|
@srsudar Wow, it's so generous of you to take the time to share this! I really appreciate it 😍 |
Sure thing. Let me know if it doesn't work for some reason. Or if you find an alternative approach. I've been a bit surprised that there isn't an off-the-shelf solution that does what I want, which makes me wonder if I'm missing something... |
Overview
Issue #258 requests a way to deduplicate imports.
I’m unsure how others are avoiding this problem today—pointers welcome—but here’s a concrete approach I’ve implemented.
This PR adds a
--useTypeImports
flag that enables deduplication when targeting a directory. It generates a mirrored output structure, and replaces inline definitions withimport type
statements based on$ref
paths.Instead of:
You get:
Approach
This supports setups where a directory of JSON Schema files reference each other via $ref. For example:
Running:
...currently inlines all referenced types, leading to duplication. You'll see something like:
With the new flag, you can run:
...and you will get:
Any comments on this approach / implementation welcome, of course.