Skip to content

Commit

Permalink
Improve config validation
Browse files Browse the repository at this point in the history
  • Loading branch information
captbaritone committed Feb 6, 2024
1 parent 3be18ba commit 589b9a0
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 16 deletions.
16 changes: 16 additions & 0 deletions src/gratsConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,27 @@ const DEFAULT_TYPESCRIPT_HEADER = `/**
* Do not manually edit. Regenerate by running \`npx grats\`.
*/`;

const VALID_CONFIG_KEYS = new Set([
"graphqlSchema",
"tsSchema",
"nullableByDefault",
"strictSemanticNullability",
"reportTypeScriptTypeErrors",
"schemaHeader",
"tsSchemaHeader",
]);

// TODO: Make this return diagnostics
export function validateGratsOptions(
options: ts.ParsedCommandLine,
): ParsedCommandLineGrats {
const gratsOptions = { ...(options.raw?.grats ?? {}) };
for (const key of Object.keys(gratsOptions)) {
if (!VALID_CONFIG_KEYS.has(key)) {
// TODO: Suggest similar?
throw new Error(`Grats: Unknown Grats config option \`${key}\``);
}
}
if (gratsOptions.nullableByDefault === undefined) {
gratsOptions.nullableByDefault = true;
} else if (typeof gratsOptions.nullableByDefault !== "boolean") {
Expand Down
17 changes: 9 additions & 8 deletions src/printSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ export function applyTypeScriptHeader(
config: ConfigOptions,
code: string,
): string {
if (config.tsSchemaHeader) {
return `${config.tsSchemaHeader}\n${code}`;
}
return code;
return formatHeader(config.tsSchemaHeader, code);
}

/**
Expand All @@ -45,10 +42,7 @@ export function printGratsSDL(
}

export function applySDLHeader(config: ConfigOptions, sdl: string): string {
if (config.schemaHeader) {
return `${config.schemaHeader}\n${sdl}`;
}
return sdl;
return formatHeader(config.schemaHeader, sdl);
}

export function printSDLWithoutMetadata(doc: DocumentNode): string {
Expand All @@ -67,3 +61,10 @@ export function printSDLWithoutMetadata(doc: DocumentNode): string {
});
return print(trimmed);
}

function formatHeader(header: string | string[] | null, code: string): string {
if (header !== null) {
return `${Array.isArray(header) ? header.join("") : header}\n${code}`;
}
return code;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// {"schemaHeader": ["Hello", 1]}
/** @gqlType */
export default class SomeType {
/** @gqlField */
hello: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-----------------
INPUT
-----------------
// {"schemaHeader": ["Hello", 1]}
/** @gqlType */
export default class SomeType {
/** @gqlField */
hello: string;
}

-----------------
OUTPUT
-----------------
Grats: If the Grats config option `schemaHeader` is an array, it must be an array of strings.
6 changes: 6 additions & 0 deletions src/tests/fixtures/configOptions/invalidKey.invalid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// {"invalidKey": "Oops"}
/** @gqlType */
export default class SomeType {
/** @gqlField */
hello: string;
}
14 changes: 14 additions & 0 deletions src/tests/fixtures/configOptions/invalidKey.invalid.ts.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-----------------
INPUT
-----------------
// {"invalidKey": "Oops"}
/** @gqlType */
export default class SomeType {
/** @gqlField */
hello: string;
}

-----------------
OUTPUT
-----------------
Grats: Unknown Grats config option `invalidKey`
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// {"invalidKey": "Oops", "anotherInvalidKey": "Oops"}
/** @gqlType */
export default class SomeType {
/** @gqlField */
hello: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-----------------
INPUT
-----------------
// {"invalidKey": "Oops", "anotherInvalidKey": "Oops"}
/** @gqlType */
export default class SomeType {
/** @gqlField */
hello: string;
}

-----------------
OUTPUT
-----------------
Grats: Unknown Grats config option `invalidKey`
6 changes: 6 additions & 0 deletions src/tests/fixtures/configOptions/nonNullableIsNull.invalid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// {"tsSchema": null}
/** @gqlType */
export default class SomeType {
/** @gqlField */
hello: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
-----------------
INPUT
-----------------
// {"tsSchema": null}
/** @gqlType */
export default class SomeType {
/** @gqlField */
hello: string;
}

-----------------
OUTPUT
-----------------
-- SDL --
type SomeType {
hello: String @metadata
}
-- TypeScript --
import { GraphQLSchema, GraphQLObjectType, GraphQLString } from "graphql";
export function getSchema(): GraphQLSchema {
const SomeTypeType: GraphQLObjectType = new GraphQLObjectType({
name: "SomeType",
fields() {
return {
hello: {
name: "hello",
type: GraphQLString
}
};
}
});
return new GraphQLSchema({
types: [SomeTypeType]
});
}
21 changes: 13 additions & 8 deletions src/tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,19 @@ const testDirs = [
`${fixturesDir}/${fileName}`,
path.join(__dirname, `../Types.ts`),
];
const parsedOptions: ParsedCommandLineGrats = validateGratsOptions({
options: {},
raw: {
grats: options,
},
errors: [],
fileNames: files,
});
let parsedOptions: ParsedCommandLineGrats;
try {
parsedOptions = validateGratsOptions({
options: {},
raw: {
grats: options,
},
errors: [],
fileNames: files,
});
} catch (e) {
return e.message;
}

// https://stackoverflow.com/a/66604532/1263117
const compilerHost = ts.createCompilerHost(
Expand Down

0 comments on commit 589b9a0

Please sign in to comment.