This commit is contained in:
David Siegel 2018-04-01 12:48:52 -05:00 коммит произвёл David Siegel
Родитель 43b66b5f0c
Коммит 68e6f8577d
4 изменённых файлов: 83 добавлений и 42 удалений

Просмотреть файл

@ -1,6 +1,6 @@
{
"name": "quicktype",
"version": "9.0.0",
"version": "10.0.0",
"license": "Apache-2.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@ -69,9 +69,7 @@
"uglify-js": "^3.0.26",
"watch": "^1.0.2"
},
"files": [
"dist/**"
],
"files": ["dist/**"],
"bin": "dist/cli/index.js",
"jest": {
"transform": {
@ -83,13 +81,6 @@
}
},
"testRegex": "(/__tests__/.*)\\.test\\.(tsx?)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"]
}
}

Просмотреть файл

@ -35,7 +35,7 @@ export function sourcesFromPostmanCollection(
}
}
if (samples.length > 0) {
const source: JSONTypeSource = { name: c.name, samples };
const source: JSONTypeSource = { kind: "json", name: c.name, samples };
const sourceDescription = [c.name];
if (typeof c.request === "object") {

Просмотреть файл

@ -11,14 +11,13 @@ import {
getTargetLanguage,
TypeSource,
GraphQLTypeSource,
isJSONSource,
StringInput,
SchemaTypeSource,
isSchemaSource,
quicktypeMultiFile,
SerializedRenderResult,
TargetLanguage,
languageNamed
languageNamed,
TypeScriptTypeSource
} from "..";
import { OptionDefinition } from "../RendererOptions";
@ -79,7 +78,7 @@ const defaultDefaultTargetLanguageName: string = "go";
async function sourceFromFileOrUrlArray(name: string, filesOrUrls: string[]): Promise<JSONTypeSource> {
const samples = await Promise.all(filesOrUrls.map(readableFromFileOrURL));
return { name, samples };
return { kind: "json", name, samples };
}
function typeNameFromFilename(filename: string): string {
@ -109,14 +108,14 @@ async function samplesFromDirectory(dataDir: string, topLevelRefs: string[] | un
}
if (file.endsWith(".url") || file.endsWith(".json")) {
// FIXME: Why do we include the URI here?
sourcesInDir.push({
kind: "json",
name,
uri: fileOrUrl,
samples: [await readableFromFileOrURL(fileOrUrl)]
});
} else if (file.endsWith(".schema")) {
sourcesInDir.push({
kind: "schema",
name,
uri: fileOrUrl,
topLevelRefs
@ -125,7 +124,12 @@ async function samplesFromDirectory(dataDir: string, topLevelRefs: string[] | un
assert(graphQLSchema === undefined, `More than one GraphQL schema in ${dataDir}`);
graphQLSchema = await readableFromFileOrURL(fileOrUrl);
} else if (file.endsWith(".graphql")) {
graphQLSources.push({ name, schema: undefined, query: await readableFromFileOrURL(fileOrUrl) });
graphQLSources.push({
kind: "graphql",
name,
schema: undefined,
query: await readableFromFileOrURL(fileOrUrl)
});
}
}
@ -152,25 +156,39 @@ async function samplesFromDirectory(dataDir: string, topLevelRefs: string[] | un
let jsonSamples: StringInput[] = [];
const schemaSources: SchemaTypeSource[] = [];
const graphQLSources: GraphQLTypeSource[] = [];
const typeScriptSources: TypeScriptTypeSource[] = [];
for (const source of await readFilesOrURLsInDirectory(dir)) {
// FIXME: We do a type switch here, but we know which types we're putting in
// in the function above. It should separate it right away.
if (isJSONSource(source)) {
jsonSamples = jsonSamples.concat(source.samples);
} else if (isSchemaSource(source)) {
schemaSources.push(source);
} else {
graphQLSources.push(source);
switch (source.kind) {
case "json":
jsonSamples = jsonSamples.concat(source.samples);
break;
case "schema":
schemaSources.push(source);
break;
case "graphql":
graphQLSources.push(source);
break;
case "typescript":
typeScriptSources.push(source);
break;
default:
return panic("Unrecognized source");
}
}
if (jsonSamples.length > 0 && schemaSources.length + graphQLSources.length > 0) {
return panic("Cannot mix JSON samples with JSON Schema or GraphQL in input subdirectory");
if (jsonSamples.length > 0 && schemaSources.length + graphQLSources.length + typeScriptSources.length > 0) {
return panic("Cannot mix JSON samples with JSON Schems, GraphQL, or TypeScript in input subdirectory");
}
if (schemaSources.length > 0 && graphQLSources.length > 0) {
return panic("Cannot mix JSON Schema with GraphQL in an input subdirectory");
const oneUnlessEmpty = (xs: any[]) => Math.sign(xs.length);
if (oneUnlessEmpty(schemaSources) + oneUnlessEmpty(graphQLSources) + oneUnlessEmpty(typeScriptSources) > 1) {
return panic("Cannot mix JSON Schema, GraphQL, and TypeScript in an input subdirectory");
}
if (jsonSamples.length > 0) {
sources.push({
kind: "json",
name: path.basename(dir),
samples: jsonSamples
});
@ -597,7 +615,7 @@ async function typeSourceForURIs(name: string, uris: string[], options: CLIOptio
return await sourceFromFileOrUrlArray(name, uris);
case "schema":
assert(uris.length === 1, `Must have exactly one schema for ${name}`);
return { name, uri: uris[0], topLevelRefs: topLevelRefsForOptions(options) };
return { kind: "schema", name, uri: uris[0], topLevelRefs: topLevelRefsForOptions(options) };
default:
return panic(`typeSourceForURIs must not be called for source language ${options.srcLang}`);
}
@ -682,7 +700,7 @@ export async function makeQuicktypeOptions(
const schema = JSON.parse(schemaString);
const query = await readableFromFileOrURL(queryFile);
const name = numSources === 1 ? options.topLevel : typeNameFromFilename(queryFile);
gqlSources.push({ name, schema, query });
gqlSources.push({ kind: "graphql", name, schema, query });
}
sources = gqlSources;
break;
@ -691,8 +709,10 @@ export async function makeQuicktypeOptions(
sources = await getSources(options);
break;
case "typescript":
// TODO make this a TypeScriptSource
sources = [
{
kind: "schema",
name: options.topLevel,
schema: schemaForTypeScriptSources(options.src),
topLevelRefs: ["/definitions/"]

Просмотреть файл

@ -24,6 +24,7 @@ import { descriptionTypeAttributeKind } from "./TypeAttributes";
import { flattenUnions } from "./FlattenUnions";
import { resolveIntersections } from "./ResolveIntersections";
import { replaceObjectType } from "./ReplaceObjectType";
import { schemaForTypeScriptSources } from "./TypeScriptInput";
// Re-export essential types and functions
export { TargetLanguage } from "./TargetLanguage";
@ -49,16 +50,27 @@ export type RendererOptions = { [name: string]: string };
export type StringInput = string | Readable;
export interface JSONTypeSource {
kind: "json";
name: string;
samples: StringInput[];
description?: string;
}
export function isJSONSource(source: TypeSource): source is JSONTypeSource {
return "samples" in source;
return source.kind === "json";
}
export interface TypeScriptTypeSource {
kind: "typescript";
sources: { [filename: string]: string };
}
export function isTypeScriptSource(source: TypeSource): source is TypeScriptTypeSource {
return source.kind === "typescript";
}
export interface SchemaTypeSource {
kind: "schema";
name: string;
uri?: string;
schema?: StringInput;
@ -66,20 +78,35 @@ export interface SchemaTypeSource {
}
export function isSchemaSource(source: TypeSource): source is SchemaTypeSource {
return !("query" in source) && !("samples" in source);
return source.kind === "schema";
}
export function toSchemaSource(source: TypeSource): SchemaTypeSource | undefined {
if (isSchemaSource(source)) {
return source;
} else if (isTypeScriptSource(source)) {
return {
kind: "schema",
name: "",
schema: schemaForTypeScriptSources(source.sources),
topLevelRefs: ["/definitions/"]
};
}
return undefined;
}
export interface GraphQLTypeSource {
kind: "graphql";
name: string;
schema: any;
query: StringInput;
}
export function isGraphQLSource(source: TypeSource): source is GraphQLTypeSource {
return "query" in source;
return source.kind === "graphql";
}
export type TypeSource = GraphQLTypeSource | JSONTypeSource | SchemaTypeSource;
export type TypeSource = GraphQLTypeSource | JSONTypeSource | SchemaTypeSource | TypeScriptTypeSource;
export interface Options {
lang: string | TargetLanguage;
@ -313,8 +340,11 @@ export class Run {
let schemaInputs: Map<string, StringInput> = Map();
let schemaSources: List<[uri.URI, SchemaTypeSource]> = List();
for (const source of this._options.sources) {
if (!isSchemaSource(source)) continue;
const { uri, schema } = source;
const schemaSource = toSchemaSource(source);
if (schemaSource === undefined) continue;
const { uri, schema } = schemaSource;
let normalizedURI: uri.URI;
if (uri === undefined) {
@ -335,7 +365,7 @@ export class Run {
);
}
schemaSources = schemaSources.push([normalizedURI, source]);
schemaSources = schemaSources.push([normalizedURI, schemaSource]);
}
if (!schemaSources.isEmpty()) {
@ -385,7 +415,7 @@ export class Run {
this._allInputs.samples[name].description = description;
}
}
} else if (!isSchemaSource(source)) {
} else if (!isSchemaSource(source) && !isTypeScriptSource(source)) {
assertNever(source);
}
}