-
Notifications
You must be signed in to change notification settings - Fork 408
Batch mode for generating interfaces for several JSON-schemas at once #16
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
Comments
So how the API may look like? |
Glob syntax sounds good to me. I would separate the work into 2 parts:
|
I like the split 👍. So, for the first step, results would be like
no matter if How do we want to prevent people from specifying output file for multiple inputs? Just throw an error? |
Exactly. Error or warning is probably fine. I agree error might be better to keep the API as strong as possible. |
I expect a little different behavior: It seems I'd need to add a function to generator that returns a dictionary like The tricky part seems to be generating file names (for If that's OK for you I'd start working on a PR providing that. |
@tomekp I'm not convinced that approach is better. Ostensibly if someone has already taken the trouble to put, say, schemas A B and C in JSON-Schema file X and D E and F in JSON-Schema file Y, for their case this is a natural way to modularize and group their schemas. So when we generate TypeScript code from those schemas, it seems natural to put schemas A B and C in X.d.ts and D E and F in Y.d.ts. If a user wanted to generate 1 file per schema, all they would need to do is feed in one file per schema (a trivial refactoring of their JSON-Schemas). On the other hand, under your scheme a user couldn't do the opposite, and generate one file containing several schemas by feeding in one file with several schemas. What do you think? |
This is a kind of related idea. I was just looking at using this and z-schema for the schemas/typings in one of my projects. I think it is handy to support passing schemas as an array to Edit: Having just looked at the dereferencing, it would require a bit of work as well to support passing other schemas to it in an array |
Hi @bytesnz @bcherny, You can take a look to my fork (https://github.com/eweap/json-schema-to-typescript/tree/compile-dir) I think i have partially achieved the part 1 of the solution. I made these modifications urgently in order to be able to use the concatenated output in our projects. But I think it's a good start. I have not made a pull request at the moment for lack of time and because I struggled with the Jest tests (which I had never used) but I think I will finish a day when I will have more time. Below is an overview of how I use compileDir to build final import { outputFileSync } from 'fs-extra';
import { compileFromDir } from 'json-schema-to-typescript';
import { cleanDirectory, compilationOptions } from './utils';
const schemasDir = 'schemas';
const typesDir = 'typings';
const indexFile = 'index.d.ts';
const indexPath = `${typesDir}/${indexFile}`;
const exportFile = 'export.d.ts';
const exportPath = `${typesDir}/${exportFile}`;
export function buildTypes(): Promise<any> {
// Clean the typings directory
cleanDirectory(typesDir);
// When compilation is finished
return compileFromDir(schemasDir, compilationOptions).then(
definitions => {
// Build a global definition files
const globalOutput = definitions.map(definition => definition.definition);
outputFileSync(indexPath, globalOutput.join('\n'));
// Generate an index file
const exportFileOutput = definitions.map(definition => {
// Remove root directory
let exportPath = definition.filepath.replace(schemasDir, '.');
// Remove extension for export
exportPath = exportPath.replace('.json', '');
return `export * from '${exportPath}';`;
});
outputFileSync(exportPath, exportFileOutput.join('\n'));
// Generate the definitions files
return definitions.map(definition => {
let filepath = definition.filepath.replace(`${schemasDir}/`, '');
// Remove extension
filepath = filepath.replace('.json', '.d.ts');
// Retrieve definition output
const definitionOutput = definition.definition;
const definitionPath = `${typesDir}/${filepath}`;
outputFileSync(definitionPath, definitionOutput);
});
},
// Failed
error => console.error(error)
);
} import { existsSync, mkdirSync, removeSync } from 'fs-extra';
import { Options } from 'json-schema-to-typescript';
// Make sure a directory exists and is empty
export function cleanDirectory(dir: string, destructive = true): void {
if (existsSync(dir)) {
if (destructive) {
removeSync(dir);
} else {
throw new Error(`'${dir}' directory exists and should not be deleted (non-destructive call)`);
}
}
mkdirSync(dir);
}
export const compilationOptions: Partial<Options> = {
bannerComment: '',
declareExternallyReferenced: false,
enableConstEnums: true,
style: {
semi: true,
tabWidth: 4,
singleQuote: true,
trailingComma: 'es5',
bracketSpacing: true,
},
unreachableDefinitions: true,
}; Hope it helps (And thx @bcherny for the good work !) |
Hi, Please see following example.
{
"$schema": "http://json-schema.org/schema#",
"id": "Album.schema.json",
"title": "Album",
"required": [
"name"
],
"allOf": [
{ "$ref": "Item.schema.json" },
{
"properties": {
"description": {
"type": "object",
"$ref": "Description.schema.json"
},
"name": { "type": "string" },
"releaseDate": {
"type": "string",
"format": "date-time"
}
}
}
]
} Above one converts to below now (I editted something manually).
export type Album = Item & {
description?: Description;
name?: string;
releaseDate?: string;
[k: string]: any;
};
export interface Item = {
type?: string;
[k: string]: any;
};
export interface Description = {
content?: string;
[k: string]: any;
}; I suggest this form.
import { Item } from 'Item.d.ts';
import { Description } from 'Description.d.ts';
export type Album = Item & {
description?: Description;
name?: string;
releaseDate?: string;
[k: string]: any;
}; Traversing AST one depth only, generate ECMAScript module import statements for type dependency. |
I just opened a PR that should resolve this issue. |
Because of stagnation I've published a npm module that enables this feature, api only for now. https://www.npmjs.com/package/compile-schemas-to-typescript |
To avoid generating the same interface twice.
#15 (comment)
The text was updated successfully, but these errors were encountered: