Merge pull request #968 from quicktype/additional-schemas
Allow adding additional schemas for $id. Fixes #967
This commit is contained in:
Коммит
f73c63229a
|
@ -56,6 +56,7 @@ export interface CLIOptions {
|
|||
src: string[];
|
||||
srcUrls?: string;
|
||||
srcLang: string;
|
||||
additionalSchema: string[];
|
||||
graphqlSchema?: string;
|
||||
graphqlIntrospect?: string;
|
||||
httpHeader?: string[];
|
||||
|
@ -275,6 +276,7 @@ function inferCLIOptions(opts: Partial<CLIOptions>, targetLanguage: TargetLangua
|
|||
version: opts.version || false,
|
||||
out: opts.out,
|
||||
buildMarkovChain: opts.buildMarkovChain,
|
||||
additionalSchema: opts.additionalSchema || [],
|
||||
graphqlSchema: opts.graphqlSchema,
|
||||
graphqlIntrospect: opts.graphqlIntrospect,
|
||||
httpMethod: opts.httpMethod,
|
||||
|
@ -397,6 +399,14 @@ function makeOptionDefinitions(targetLanguages: TargetLanguage[]): OptionDefinit
|
|||
typeLabel: "HEADER",
|
||||
description: "HTTP header for the GraphQL introspection query."
|
||||
},
|
||||
{
|
||||
name: "additional-schema",
|
||||
alias: "S",
|
||||
type: String,
|
||||
multiple: true,
|
||||
typeLabel: "FILE",
|
||||
description: "Register the $id's of additional JSON Schema files."
|
||||
},
|
||||
{
|
||||
name: "no-render",
|
||||
type: Boolean,
|
||||
|
@ -644,7 +654,11 @@ function makeTypeScriptSource(fileNames: string[]): SchemaTypeSource {
|
|||
return Object.assign({ kind: "schema" }, schemaForTypeScriptSources(sources)) as SchemaTypeSource;
|
||||
}
|
||||
|
||||
async function makeInputData(sources: TypeSource[], targetLanguage: TargetLanguage): Promise<InputData> {
|
||||
async function makeInputData(
|
||||
sources: TypeSource[],
|
||||
targetLanguage: TargetLanguage,
|
||||
additionalSchemaAddresses: ReadonlyArray<string>
|
||||
): Promise<InputData> {
|
||||
const inputData = new InputData();
|
||||
|
||||
for (const source of sources) {
|
||||
|
@ -656,7 +670,11 @@ async function makeInputData(sources: TypeSource[], targetLanguage: TargetLangua
|
|||
await inputData.addSource("json", source, () => jsonInputForTargetLanguage(targetLanguage));
|
||||
break;
|
||||
case "schema":
|
||||
await inputData.addSource("schema", source, () => new JSONSchemaInput(new FetchingJSONSchemaStore()));
|
||||
await inputData.addSource(
|
||||
"schema",
|
||||
source,
|
||||
() => new JSONSchemaInput(new FetchingJSONSchemaStore(), [], additionalSchemaAddresses)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
return assertNever(source);
|
||||
|
@ -800,7 +818,7 @@ export async function makeQuicktypeOptions(
|
|||
return messageError("DriverUnknownOutputLanguage", { lang: options.lang });
|
||||
}
|
||||
|
||||
const inputData = await makeInputData(sources, lang);
|
||||
const inputData = await makeInputData(sources, lang, options.additionalSchema);
|
||||
|
||||
const quicktypeOptions: Partial<Options> = {
|
||||
lang,
|
||||
|
|
|
@ -39,6 +39,7 @@ export type ErrorProperties =
|
|||
| { kind: "SchemaKeyNotInObject"; properties: { key: string; ref: Ref } }
|
||||
| { kind: "SchemaFetchError"; properties: { address: string; base: Ref } }
|
||||
| { kind: "SchemaFetchErrorTopLevel"; properties: { address: string } }
|
||||
| { kind: "SchemaFetchErrorAdditional"; properties: { address: string } }
|
||||
|
||||
// GraphQL input
|
||||
| { kind: "GraphQLNoQueriesDefined"; properties: {} }
|
||||
|
@ -110,8 +111,9 @@ const errorMessages: ErrorMessages = {
|
|||
"Trying to index array in schema with key that is not a number, but is ${actual} at ${ref}",
|
||||
SchemaIndexNotInArray: "Index ${index} out of range of schema array at ${ref}",
|
||||
SchemaKeyNotInObject: "Key ${key} not in schema object at ${ref}",
|
||||
SchemaFetchError: "Could not fetch schema ${address}, referred to from ${base}: ${error}",
|
||||
SchemaFetchErrorTopLevel: "Could not fetch top-level schema ${address}: ${error}",
|
||||
SchemaFetchError: "Could not fetch schema ${address}, referred to from ${base}",
|
||||
SchemaFetchErrorTopLevel: "Could not fetch top-level schema ${address}",
|
||||
SchemaFetchErrorAdditional: "Could not fetch additional schema ${address}",
|
||||
|
||||
// GraphQL input
|
||||
GraphQLNoQueriesDefined: "GraphQL file doesn't have any queries defined.",
|
||||
|
|
|
@ -161,7 +161,6 @@ export class JSONSchemaInput implements Input<JSONSchemaSourceData> {
|
|||
readonly kind: string = "schema";
|
||||
readonly needSchemaProcessing: boolean = true;
|
||||
|
||||
private _schemaStore: JSONSchemaStore | undefined = undefined;
|
||||
private readonly _attributeProducers: JSONSchemaAttributeProducer[];
|
||||
|
||||
private readonly _schemaInputs: Map<string, StringInput> = new Map();
|
||||
|
@ -172,10 +171,10 @@ export class JSONSchemaInput implements Input<JSONSchemaSourceData> {
|
|||
private _needIR: boolean = false;
|
||||
|
||||
constructor(
|
||||
givenSchemaStore: JSONSchemaStore | undefined,
|
||||
additionalAttributeProducers: JSONSchemaAttributeProducer[] = []
|
||||
private _schemaStore: JSONSchemaStore | undefined,
|
||||
additionalAttributeProducers: JSONSchemaAttributeProducer[] = [],
|
||||
private readonly _additionalSchemaAddresses: ReadonlyArray<string> = []
|
||||
) {
|
||||
this._schemaStore = givenSchemaStore;
|
||||
this._attributeProducers = [descriptionAttributeProducer, accessorNamesAttributeProducer].concat(
|
||||
additionalAttributeProducers
|
||||
);
|
||||
|
@ -190,7 +189,14 @@ export class JSONSchemaInput implements Input<JSONSchemaSourceData> {
|
|||
}
|
||||
|
||||
async addTypes(ctx: RunContext, typeBuilder: TypeBuilder): Promise<void> {
|
||||
await addTypesInSchema(ctx, typeBuilder, defined(this._schemaStore), this._topLevels, this._attributeProducers);
|
||||
await addTypesInSchema(
|
||||
ctx,
|
||||
typeBuilder,
|
||||
defined(this._schemaStore),
|
||||
this._topLevels,
|
||||
this._attributeProducers,
|
||||
this._additionalSchemaAddresses
|
||||
);
|
||||
}
|
||||
|
||||
async addSource(schemaSource: JSONSchemaSourceData): Promise<void> {
|
||||
|
|
|
@ -493,7 +493,8 @@ export async function addTypesInSchema(
|
|||
typeBuilder: TypeBuilder,
|
||||
store: JSONSchemaStore,
|
||||
references: ReadonlyMap<string, Ref>,
|
||||
attributeProducers: JSONSchemaAttributeProducer[]
|
||||
attributeProducers: JSONSchemaAttributeProducer[],
|
||||
additionalSchemaAddresses: ReadonlyArray<string>
|
||||
): Promise<void> {
|
||||
const canonizer = new Canonizer(ctx);
|
||||
|
||||
|
@ -894,6 +895,14 @@ export async function addTypesInSchema(
|
|||
return result;
|
||||
}
|
||||
|
||||
for (const address of additionalSchemaAddresses) {
|
||||
const schema = await store.get(address, ctx.debugPrintSchemaResolving);
|
||||
if (schema === undefined) {
|
||||
return messageError("SchemaFetchErrorAdditional", { address });
|
||||
}
|
||||
canonizer.addSchema(schema, address);
|
||||
}
|
||||
|
||||
for (const [topLevelName, topLevelRef] of references) {
|
||||
const [target, loc] = await resolveVirtualRef(
|
||||
new Location(new Ref(topLevelRef.addressURI, [])),
|
||||
|
|
Загрузка…
Ссылка в новой задаче