New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

grats

Package Overview
Dependencies
Maintainers
1
Versions
240
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

grats - npm Package Compare versions

Comparing version 0.0.0-main-d4ce69ef to 0.0.0-main-d4d43d4b

dist/src/codegen.d.ts

12

dist/package.json
{
"name": "grats",
"version": "0.0.4",
"version": "0.0.10",
"main": "dist/src/index.js",

@@ -15,11 +15,12 @@ "bin": "dist/src/cli.js",

"build": "tsc --build",
"lint": "eslint src/**/*.ts"
"format": "prettier . --write",
"lint": "eslint src/**/*.ts && prettier . --check"
},
"dependencies": {
"@graphql-tools/utils": "^9.2.1",
"commander": "^10.0.0",
"graphql": "^16.6.0",
"typescript": "^4.9.5"
"typescript": "^5.0.2"
},
"devDependencies": {
"@graphql-tools/utils": "^9.2.1",
"@types/node": "^18.14.6",

@@ -32,2 +33,3 @@ "@typescript-eslint/eslint-plugin": "^5.55.0",

"path-browserify": "^1.0.1",
"prettier": "^2.8.7",
"process": "^0.11.10",

@@ -39,3 +41,3 @@ "ts-node": "^10.9.1"

},
"packageManager": "pnpm@8.1.1",
"packageManager": "pnpm@8.12.0",
"engines": {

@@ -42,0 +44,0 @@ "node": ">=16 <=21",

@@ -39,3 +39,3 @@ #!/usr/bin/env node

};
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatLoc = void 0;

@@ -45,3 +45,2 @@ var graphql_1 = require("graphql");

var lib_1 = require("./lib");
var utils_1 = require("@graphql-tools/utils");
var commander_1 = require("commander");

@@ -52,2 +51,4 @@ var fs_1 = require("fs");

var Locate_1 = require("./Locate");
var printSchema_1 = require("./printSchema");
var ts = require("typescript");
var program = new commander_1.Command();

@@ -58,9 +59,8 @@ program

.version(package_json_1.version)
.option("-o, --output <SCHEMA_FILE>", "Where to write the schema file. Defaults to stdout")
.option("--tsconfig <TSCONFIG>", "Path to tsconfig.json. Defaults to auto-detecting based on the current working directory")
.action(function (_a) {
var output = _a.output, tsconfig = _a.tsconfig;
var tsconfig = _a.tsconfig;
return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_b) {
build(output, tsconfig);
build(tsconfig);
return [2 /*return*/];

@@ -76,3 +76,4 @@ });

var tsconfig = _a.tsconfig;
var schema = buildSchema(tsconfig);
var config = getTsConfig(tsconfig).config;
var schema = buildSchema(config);
var loc = (0, Locate_1.locate)(schema, entity);

@@ -86,26 +87,31 @@ if (loc.kind === "ERROR") {

program.parse();
function build(output, tsconfig) {
var schema = buildSchema(tsconfig);
function build(tsconfig) {
var _a = getTsConfig(tsconfig), config = _a.config, configPath = _a.configPath;
var schema = buildSchema(config);
var sortedSchema = (0, graphql_1.lexicographicSortSchema)(schema);
var schemaStr = (0, utils_1.printSchemaWithDirectives)(sortedSchema, {
assumeValid: true
});
if (output) {
var absOutput = (0, path_1.resolve)(process.cwd(), output);
(0, fs_1.writeFileSync)(absOutput, schemaStr);
console.error("Grats: Wrote schema to `".concat(absOutput, "`."));
var gratsOptions = config.raw.grats;
var dest = (0, path_1.resolve)((0, path_1.dirname)(configPath), gratsOptions.tsSchema);
var code = (0, printSchema_1.printExecutableSchema)(sortedSchema, gratsOptions, dest);
(0, fs_1.writeFileSync)(dest, code);
console.error("Grats: Wrote TypeScript schema to `".concat(dest, "`."));
var schemaStr = (0, printSchema_1.printGratsSDL)(sortedSchema, gratsOptions);
var absOutput = (0, path_1.resolve)((0, path_1.dirname)(configPath), gratsOptions.graphqlSchema);
(0, fs_1.writeFileSync)(absOutput, schemaStr);
console.error("Grats: Wrote schema to `".concat(absOutput, "`."));
}
// Locate and read the tsconfig.json file
function getTsConfig(tsconfig) {
var configPath = tsconfig || ts.findConfigFile(process.cwd(), ts.sys.fileExists);
if (configPath == null) {
throw new Error("Grats: Could not find tsconfig.json");
}
else {
console.log(schemaStr);
var optionsResult = (0, _1.getParsedTsConfig)(configPath);
if (optionsResult.kind === "ERROR") {
console.error(optionsResult.err.formatDiagnosticsWithColorAndContext());
process.exit(1);
}
return { configPath: configPath, config: optionsResult.value };
}
function buildSchema(tsconfig) {
if (tsconfig && !(0, fs_1.existsSync)(tsconfig)) {
console.error("Grats: Could not find tsconfig.json at `".concat(tsconfig, "`."));
process.exit(1);
}
var parsed = (0, _1.getParsedTsConfig)(tsconfig);
// FIXME: Validate config!
// https://github.com/tsconfig/bases
var schemaResult = (0, lib_1.buildSchemaResult)(parsed);
function buildSchema(options) {
var schemaResult = (0, lib_1.buildSchemaResult)(options);
if (schemaResult.kind === "ERROR") {

@@ -112,0 +118,0 @@ console.error(schemaResult.err.formatDiagnosticsWithColorAndContext());

@@ -34,4 +34,4 @@ /**

export declare function inputFieldUntyped(): string;
export declare function typeTagOnUnamedClass(): string;
export declare function typeTagOnAliasOfNonObject(): string;
export declare function typeTagOnUnnamedClass(): string;
export declare function typeTagOnAliasOfNonObjectOrUnknown(): string;
export declare function typeNameNotDeclaration(): string;

@@ -66,7 +66,7 @@ export declare function typeNameMissingInitializer(): string;

export declare function pluralTypeMissingParameter(): string;
export declare function expectedIdentifer(): string;
export declare function expectedIdentifier(): string;
export declare function killsParentOnExceptionWithWrongConfig(): string;
export declare function killsParentOnExceptionOnNullable(): string;
export declare function nonNullTypeCannotBeOptional(): string;
export declare function mergedInterfaces(interfaceName: string): string;
export declare function mergedInterfaces(): string;
export declare function implementsTagMissingValue(): string;

@@ -83,1 +83,13 @@ export declare function implementsTagOnClass(): string;

export declare function unresolvedTypeReference(): string;
export declare function expectedTypeAnnotationOnContext(): string;
export declare function expectedTypeAnnotationOfReferenceOnContext(): string;
export declare function expectedTypeAnnotationOnContextToBeResolvable(): string;
export declare function expectedTypeAnnotationOnContextToHaveDeclaration(): string;
export declare function unexpectedParamSpreadForContextParam(): string;
export declare function multipleContextTypes(): string;
export declare function graphQLNameHasLeadingNewlines(name: string, tagName: string): string;
export declare function graphQLTagNameHasWhitespace(tagName: string): string;
export declare function subscriptionFieldNotAsyncIterable(): string;
export declare function nonSubscriptionFieldAsyncIterable(): string;
export declare function operationTypeNotUnknown(): string;
export declare function expectedNullableArgumentToBeOptional(): string;
"use strict";
exports.__esModule = true;
exports.defaultArgPropertyMissingName = exports.defaultArgElementIsNotAssignment = exports.defaultValueIsNotLiteral = exports.ambiguousNumberType = exports.expectedOneNonNullishType = exports.propertyFieldMissingType = exports.cannotResolveSymbolForDescription = exports.promiseMissingTypeArg = exports.methodMissingType = exports.gqlEntityMissingName = exports.enumVariantMissingInitializer = exports.enumVariantNotStringLiteral = exports.enumTagOnInvalidNode = exports.argNotTyped = exports.argNameNotLiteral = exports.argIsNotProperty = exports.argumentParamIsNotObject = exports.argumentParamIsMissingType = exports.typeNameDoesNotMatchExpected = exports.typeNameTypeNotStringLiteral = exports.typeNameMissingTypeAnnotation = exports.typeNameInitializerWrong = exports.typeNameInitializeNotString = exports.typeNameMissingInitializer = exports.typeNameNotDeclaration = exports.typeTagOnAliasOfNonObject = exports.typeTagOnUnamedClass = exports.inputFieldUntyped = exports.inputTypeFieldNotProperty = exports.inputTypeNotLiteral = exports.functionFieldNotNamedExport = exports.functionFieldDefaultExport = exports.functionFieldNotNamed = exports.functionFieldParentTypeNotValid = exports.functionFieldParentTypeMissing = exports.functionFieldNotTopLevel = exports.invalidReturnTypeForFunctionField = exports.invalidParentArgForFunctionField = exports.expectedUnionTypeReference = exports.expectedUnionTypeNode = exports.invalidUnionTagUsage = exports.invalidInputTagUsage = exports.invalidEnumTagUsage = exports.invalidInterfaceTagUsage = exports.invalidScalarTagUsage = exports.invalidTypeTagUsage = exports.invalidGratsTag = exports.wrongCasingForGratsTag = exports.killsParentOnExceptionOnWrongNode = exports.fieldTagOnWrongNode = void 0;
exports.unresolvedTypeReference = exports.invalidTypePassedToFieldFunction = exports.parameterPropertyMissingType = exports.parameterPropertyNotPublic = exports.parameterWithoutModifiers = exports.duplicateInterfaceTag = exports.duplicateTag = exports.implementsTagOnTypeAlias = exports.implementsTagOnInterface = exports.implementsTagOnClass = exports.implementsTagMissingValue = exports.mergedInterfaces = exports.nonNullTypeCannotBeOptional = exports.killsParentOnExceptionOnNullable = exports.killsParentOnExceptionWithWrongConfig = exports.expectedIdentifer = exports.pluralTypeMissingParameter = exports.unknownGraphQLType = exports.unsupportedTypeLiteral = exports.defaultArgPropertyMissingInitializer = void 0;
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultArgPropertyMissingName = exports.defaultArgElementIsNotAssignment = exports.defaultValueIsNotLiteral = exports.ambiguousNumberType = exports.expectedOneNonNullishType = exports.propertyFieldMissingType = exports.cannotResolveSymbolForDescription = exports.promiseMissingTypeArg = exports.methodMissingType = exports.gqlEntityMissingName = exports.enumVariantMissingInitializer = exports.enumVariantNotStringLiteral = exports.enumTagOnInvalidNode = exports.argNotTyped = exports.argNameNotLiteral = exports.argIsNotProperty = exports.argumentParamIsNotObject = exports.argumentParamIsMissingType = exports.typeNameDoesNotMatchExpected = exports.typeNameTypeNotStringLiteral = exports.typeNameMissingTypeAnnotation = exports.typeNameInitializerWrong = exports.typeNameInitializeNotString = exports.typeNameMissingInitializer = exports.typeNameNotDeclaration = exports.typeTagOnAliasOfNonObjectOrUnknown = exports.typeTagOnUnnamedClass = exports.inputFieldUntyped = exports.inputTypeFieldNotProperty = exports.inputTypeNotLiteral = exports.functionFieldNotNamedExport = exports.functionFieldDefaultExport = exports.functionFieldNotNamed = exports.functionFieldParentTypeNotValid = exports.functionFieldParentTypeMissing = exports.functionFieldNotTopLevel = exports.invalidReturnTypeForFunctionField = exports.invalidParentArgForFunctionField = exports.expectedUnionTypeReference = exports.expectedUnionTypeNode = exports.invalidUnionTagUsage = exports.invalidInputTagUsage = exports.invalidEnumTagUsage = exports.invalidInterfaceTagUsage = exports.invalidScalarTagUsage = exports.invalidTypeTagUsage = exports.invalidGratsTag = exports.wrongCasingForGratsTag = exports.killsParentOnExceptionOnWrongNode = exports.fieldTagOnWrongNode = void 0;
exports.expectedNullableArgumentToBeOptional = exports.operationTypeNotUnknown = exports.nonSubscriptionFieldAsyncIterable = exports.subscriptionFieldNotAsyncIterable = exports.graphQLTagNameHasWhitespace = exports.graphQLNameHasLeadingNewlines = exports.multipleContextTypes = exports.unexpectedParamSpreadForContextParam = exports.expectedTypeAnnotationOnContextToHaveDeclaration = exports.expectedTypeAnnotationOnContextToBeResolvable = exports.expectedTypeAnnotationOfReferenceOnContext = exports.expectedTypeAnnotationOnContext = exports.unresolvedTypeReference = exports.invalidTypePassedToFieldFunction = exports.parameterPropertyMissingType = exports.parameterPropertyNotPublic = exports.parameterWithoutModifiers = exports.duplicateInterfaceTag = exports.duplicateTag = exports.implementsTagOnTypeAlias = exports.implementsTagOnInterface = exports.implementsTagOnClass = exports.implementsTagMissingValue = exports.mergedInterfaces = exports.nonNullTypeCannotBeOptional = exports.killsParentOnExceptionOnNullable = exports.killsParentOnExceptionWithWrongConfig = exports.expectedIdentifier = exports.pluralTypeMissingParameter = exports.unknownGraphQLType = exports.unsupportedTypeLiteral = exports.defaultArgPropertyMissingInitializer = void 0;
var Extractor_1 = require("./Extractor");
// TODO: Move these to short URLS that are easier to keep from breaking.
var DOC_URLS = {
mergedInterfaces: "https://grats.capt.dev/docs/dockblock-tags/interfaces/#merged-interfaces",
parameterProperties: "https://grats.capt.dev/docs/dockblock-tags/fields#class-based-fields",
typeImplementsInterface: "TODO"
mergedInterfaces: "https://grats.capt.dev/docs/docblock-tags/interfaces/#merged-interfaces",
parameterProperties: "https://grats.capt.dev/docs/docblock-tags/fields#class-based-fields",
};

@@ -115,10 +114,10 @@ /**

exports.inputFieldUntyped = inputFieldUntyped;
function typeTagOnUnamedClass() {
function typeTagOnUnnamedClass() {
return "Unexpected `@".concat(Extractor_1.TYPE_TAG, "` annotation on unnamed class declaration.");
}
exports.typeTagOnUnamedClass = typeTagOnUnamedClass;
function typeTagOnAliasOfNonObject() {
return "Expected `@".concat(Extractor_1.TYPE_TAG, "` type to be a type literal. For example: `type Foo = { bar: string }`");
exports.typeTagOnUnnamedClass = typeTagOnUnnamedClass;
function typeTagOnAliasOfNonObjectOrUnknown() {
return "Expected `@".concat(Extractor_1.TYPE_TAG, "` type to be an object type literal (`{ }`) or `unknown`. For example: `type Foo = { bar: string }` or `type Query = unknown`.");
}
exports.typeTagOnAliasOfNonObject = typeTagOnAliasOfNonObject;
exports.typeTagOnAliasOfNonObjectOrUnknown = typeTagOnAliasOfNonObjectOrUnknown;
function typeNameNotDeclaration() {

@@ -153,7 +152,7 @@ return "Expected `__typename` to be a property declaration.";

function argumentParamIsMissingType() {
return "Expected GraphQL field arguments to have a TypeScript type. If there are no arguments, you can use `args: never`.";
return "Expected GraphQL field arguments to have a TypeScript type. If there are no arguments, you can use `args: unknown`.";
}
exports.argumentParamIsMissingType = argumentParamIsMissingType;
function argumentParamIsNotObject() {
return "Expected GraphQL field arguments to be typed using a literal object: `{someField: string}`.";
return "Expected GraphQL field arguments to be typed using a literal object: `{someField: string}`. If there are no arguments, you can use `args: unknown`.";
}

@@ -241,6 +240,6 @@ exports.argumentParamIsNotObject = argumentParamIsNotObject;

exports.pluralTypeMissingParameter = pluralTypeMissingParameter;
function expectedIdentifer() {
function expectedIdentifier() {
return "Expected an identifier.";
}
exports.expectedIdentifer = expectedIdentifer;
exports.expectedIdentifier = expectedIdentifier;
function killsParentOnExceptionWithWrongConfig() {

@@ -251,12 +250,12 @@ return "Unexpected `@".concat(Extractor_1.KILLS_PARENT_ON_EXCEPTION_TAG, "` tag. `@").concat(Extractor_1.KILLS_PARENT_ON_EXCEPTION_TAG, "` is only supported when the Grats config `nullableByDefault` is enabled.");

function killsParentOnExceptionOnNullable() {
return "Unexpected `@".concat(Extractor_1.KILLS_PARENT_ON_EXCEPTION_TAG, "` tag. `@").concat(Extractor_1.KILLS_PARENT_ON_EXCEPTION_TAG, "` is unnessesary on fields that are already nullable.");
return "Unexpected `@".concat(Extractor_1.KILLS_PARENT_ON_EXCEPTION_TAG, "` tag. `@").concat(Extractor_1.KILLS_PARENT_ON_EXCEPTION_TAG, "` is unnecessary on fields that are already nullable.");
}
exports.killsParentOnExceptionOnNullable = killsParentOnExceptionOnNullable;
function nonNullTypeCannotBeOptional() {
return "Unexpected optional argument that does not also accept `null`. Optional arguments in GraphQL may get passed an explict `null` value. This means optional arguments must be typed to also accept `null`.";
return "Unexpected optional argument that does not also accept `null`. Optional arguments in GraphQL may get passed an explicit `null` value. This means optional arguments must be typed to also accept `null`.";
}
exports.nonNullTypeCannotBeOptional = nonNullTypeCannotBeOptional;
function mergedInterfaces(interfaceName) {
function mergedInterfaces() {
return [
"Unexpected merged interface `".concat(interfaceName, "`."),
"Unexpected merged interface.",
"If an interface is declared multiple times in a scope, TypeScript merges them.",

@@ -282,3 +281,3 @@ "To avoid ambiguity Grats does not support using merged interfaces as GraphQL interfaces.",

function implementsTagOnTypeAlias() {
return "`@".concat(Extractor_1.IMPLEMENTS_TAG_DEPRECATED, "` has been deprecated. Types which implement GraphQL interfaces should be defined using TypeScript class or interface declarations. Learn more: ").concat(DOC_URLS.typeImplementsInterface, ".");
return "`@".concat(Extractor_1.IMPLEMENTS_TAG_DEPRECATED, "` has been deprecated. Types which implement GraphQL interfaces should be defined using TypeScript class or interface declarations.");
}

@@ -320,1 +319,51 @@ exports.implementsTagOnTypeAlias = implementsTagOnTypeAlias;

exports.unresolvedTypeReference = unresolvedTypeReference;
function expectedTypeAnnotationOnContext() {
return "Expected context parameter to have a type annotation. Grats validates that your context parameter is type-safe by checking all context values reference the same type declaration.";
}
exports.expectedTypeAnnotationOnContext = expectedTypeAnnotationOnContext;
function expectedTypeAnnotationOfReferenceOnContext() {
return "Expected context parameter's type to be a type reference Grats validates that your context parameter is type-safe by checking all context values reference the same type declaration.";
}
exports.expectedTypeAnnotationOfReferenceOnContext = expectedTypeAnnotationOfReferenceOnContext;
function expectedTypeAnnotationOnContextToBeResolvable() {
// TODO: Provide guidance?
// TODO: I don't think we have a test case that triggers this error.
return "Unable to resolve context parameter type. Grats validates that your context parameter is type-safe by checking all context values reference the same type declaration.";
}
exports.expectedTypeAnnotationOnContextToBeResolvable = expectedTypeAnnotationOnContextToBeResolvable;
function expectedTypeAnnotationOnContextToHaveDeclaration() {
return "Unable to locate the declaration of the context parameter's type. Grats validates that your context parameter is type-safe by checking all context values reference the same type declaration. Did you forget to import or define this type?";
}
exports.expectedTypeAnnotationOnContextToHaveDeclaration = expectedTypeAnnotationOnContextToHaveDeclaration;
function unexpectedParamSpreadForContextParam() {
return "Unexpected spread parameter in context parameter position. Grats expects the context parameter to be a single, explicitly typed, argument.";
}
exports.unexpectedParamSpreadForContextParam = unexpectedParamSpreadForContextParam;
function multipleContextTypes() {
return "Context argument's type does not match. Grats expects all resolvers that read the context argument to use the same type for that argument. Did you use the incorrect type in one of your resolvers?";
}
exports.multipleContextTypes = multipleContextTypes;
function graphQLNameHasLeadingNewlines(name, tagName) {
return "Expected the GraphQL name `".concat(name, "` to be on the same line as it's `@").concat(tagName, "` tag.");
}
exports.graphQLNameHasLeadingNewlines = graphQLNameHasLeadingNewlines;
function graphQLTagNameHasWhitespace(tagName) {
return "Expected text following a `@".concat(tagName, "` tag to be a GraphQL name. If you intended this text to be a description, place it at the top of the docblock before any `@tags`.");
}
exports.graphQLTagNameHasWhitespace = graphQLTagNameHasWhitespace;
function subscriptionFieldNotAsyncIterable() {
return "Expected fields on `Subscription` to return an AsyncIterable.";
}
exports.subscriptionFieldNotAsyncIterable = subscriptionFieldNotAsyncIterable;
function nonSubscriptionFieldAsyncIterable() {
return "Unexpected AsyncIterable. Only fields on `Subscription` should return an AsyncIterable.";
}
exports.nonSubscriptionFieldAsyncIterable = nonSubscriptionFieldAsyncIterable;
function operationTypeNotUnknown() {
return "Operation types `Query`, `Mutation`, and `Subscription` must be defined as type aliases of `unknown`. E.g. `type Query = unknown`.";
}
exports.operationTypeNotUnknown = operationTypeNotUnknown;
function expectedNullableArgumentToBeOptional() {
return "Expected nullable argument to be optional. graphql-js may not define properties where an undefined argument is passed. To guard against this add a `?` to the end of the argument name to make it optional.";
}
exports.expectedNullableArgumentToBeOptional = expectedNullableArgumentToBeOptional;

@@ -1,7 +0,7 @@

import { FieldDefinitionNode, InputValueDefinitionNode, NamedTypeNode, NameNode, TypeNode, StringValueNode, ConstValueNode, ConstDirectiveNode, EnumValueDefinitionNode, ConstObjectFieldNode, ConstObjectValueNode, ConstListValueNode } from "graphql";
import { NameNode } from "graphql";
import { DiagnosticsResult } from "./utils/DiagnosticError";
import * as ts from "typescript";
import { GratsDefinitionNode, TypeContext } from "./TypeContext";
import { NameDefinition } from "./TypeContext";
import { ConfigOptions } from "./lib";
import { GraphQLConstructor } from "./GraphQLConstructor";
import { GratsDefinitionNode } from "./GraphQLConstructor";
export declare const LIBRARY_IMPORT_NAME = "grats";

@@ -20,3 +20,10 @@ export declare const LIBRARY_NAME = "Grats";

export declare const ALL_TAGS: string[];
type ArgDefaults = Map<string, ts.Expression>;
export type ExtractionSnapshot = {
readonly definitions: GratsDefinitionNode[];
readonly unresolvedNames: Map<ts.Node, NameNode>;
readonly nameDefinitions: Map<ts.Node, NameDefinition>;
readonly contextReferences: Array<ts.Node>;
readonly typesWithTypenameField: Set<string>;
readonly interfaceDeclarations: Array<ts.InterfaceDeclaration>;
};
/**

@@ -32,79 +39,2 @@ * Extracts GraphQL definitions from TypeScript source code.

*/
export declare class Extractor {
definitions: GratsDefinitionNode[];
sourceFile: ts.SourceFile;
ctx: TypeContext;
configOptions: ConfigOptions;
errors: ts.Diagnostic[];
gql: GraphQLConstructor;
constructor(sourceFile: ts.SourceFile, ctx: TypeContext, buildOptions: ConfigOptions);
extract(): DiagnosticsResult<GratsDefinitionNode[]>;
extractType(node: ts.Node, tag: ts.JSDocTag): void;
extractScalar(node: ts.Node, tag: ts.JSDocTag): void;
extractInterface(node: ts.Node, tag: ts.JSDocTag): void;
extractEnum(node: ts.Node, tag: ts.JSDocTag): void;
extractInput(node: ts.Node, tag: ts.JSDocTag): void;
extractUnion(node: ts.Node, tag: ts.JSDocTag): void;
/** Error handling and location juggling */
report(node: ts.Node, message: string, relatedInformation?: ts.DiagnosticRelatedInformation[]): null;
reportUnhandled(node: ts.Node, positionKind: "type" | "field" | "field type" | "input" | "input field" | "union member" | "constant value" | "union" | "enum value", message: string, relatedInformation?: ts.DiagnosticRelatedInformation[]): null;
related(node: ts.Node, message: string): ts.DiagnosticRelatedInformation;
diagnosticAnnotatedLocation(node: ts.Node): {
start: number;
length: number;
filepath: ts.SourceFile;
};
/** TypeScript traversals */
unionTypeAliasDeclaration(node: ts.TypeAliasDeclaration, tag: ts.JSDocTag): null | undefined;
functionDeclarationExtendType(node: ts.FunctionDeclaration, tag: ts.JSDocTag): null | undefined;
typeReferenceFromParam(typeParam: ts.ParameterDeclaration): NameNode | null;
namedFunctionExportName(node: ts.FunctionDeclaration): ts.Identifier | null;
scalarTypeAliasDeclaration(node: ts.TypeAliasDeclaration, tag: ts.JSDocTag): null | undefined;
inputTypeAliasDeclaration(node: ts.TypeAliasDeclaration, tag: ts.JSDocTag): null | undefined;
collectInputFields(node: ts.TypeAliasDeclaration): Array<InputValueDefinitionNode> | null;
collectInputField(node: ts.PropertySignature): InputValueDefinitionNode | null;
typeClassDeclaration(node: ts.ClassDeclaration, tag: ts.JSDocTag): null | undefined;
typeInterfaceDeclaration(node: ts.InterfaceDeclaration, tag: ts.JSDocTag): null | undefined;
typeTypeAliasDeclaration(node: ts.TypeAliasDeclaration, tag: ts.JSDocTag): null | undefined;
checkForTypenameProperty(node: ts.ClassDeclaration | ts.InterfaceDeclaration | ts.TypeLiteralNode, expectedName: string): void;
isValidTypeNameProperty(member: ts.ClassElement | ts.TypeElement, expectedName: string): boolean;
isValidTypenamePropertyDeclaration(node: ts.PropertyDeclaration, expectedName: string): boolean;
isValidTypenamePropertySignature(node: ts.PropertySignature, expectedName: string): boolean;
isValidTypenamePropertyType(node: ts.TypeNode, expectedName: string): boolean;
collectInterfaces(node: ts.ClassDeclaration | ts.InterfaceDeclaration | ts.TypeAliasDeclaration): Array<NamedTypeNode> | null;
reportTagInterfaces(node: ts.TypeAliasDeclaration | ts.ClassDeclaration | ts.InterfaceDeclaration): null | undefined;
collectHeritageInterfaces(node: ts.ClassDeclaration | ts.InterfaceDeclaration): Array<NamedTypeNode> | null;
symbolHasGqlTag(node: ts.Node): boolean;
hasGqlTag(node: ts.Node): boolean;
interfaceInterfaceDeclaration(node: ts.InterfaceDeclaration, tag: ts.JSDocTag): null | undefined;
collectFields(node: ts.ClassDeclaration | ts.InterfaceDeclaration | ts.TypeLiteralNode): Array<FieldDefinitionNode>;
constructorParam(node: ts.ParameterDeclaration): FieldDefinitionNode | null;
collectArgs(argsParam: ts.ParameterDeclaration): ReadonlyArray<InputValueDefinitionNode> | null;
collectArgDefaults(node: ts.ObjectBindingPattern): ArgDefaults;
collectConstValue(node: ts.Expression): ConstValueNode | null;
collectArrayLiteral(node: ts.ArrayLiteralExpression): ConstListValueNode | null;
cellectObjectLiteral(node: ts.ObjectLiteralExpression): ConstObjectValueNode | null;
collectObjectField(node: ts.ObjectLiteralElementLike): ConstObjectFieldNode | null;
collectArg(node: ts.TypeElement, defaults?: Map<string, ts.Expression> | null): InputValueDefinitionNode | null;
enumEnumDeclaration(node: ts.EnumDeclaration, tag: ts.JSDocTag): void;
enumTypeAliasDeclaration(node: ts.TypeAliasDeclaration, tag: ts.JSDocTag): void;
enumTypeAliasVariants(node: ts.TypeAliasDeclaration): EnumValueDefinitionNode[] | null;
collectEnumValues(node: ts.EnumDeclaration): ReadonlyArray<EnumValueDefinitionNode>;
entityName(node: ts.ClassDeclaration | ts.MethodDeclaration | ts.MethodSignature | ts.PropertyDeclaration | ts.InterfaceDeclaration | ts.PropertySignature | ts.EnumDeclaration | ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.ParameterDeclaration, tag: ts.JSDocTag): NameNode | null;
methodDeclaration(node: ts.MethodDeclaration | ts.MethodSignature): FieldDefinitionNode | null;
collectMethodType(node: ts.TypeNode): TypeNode | null;
collectPropertyType(node: ts.TypeNode): TypeNode | null;
maybeUnwrapePromise(node: ts.TypeNode): ts.TypeNode | null;
collectDescription(node: ts.Node): StringValueNode | null;
collectDeprecated(node: ts.Node): ConstDirectiveNode | null;
property(node: ts.PropertyDeclaration | ts.PropertySignature): FieldDefinitionNode | null;
collectType(node: ts.TypeNode): TypeNode | null;
typeReference(node: ts.TypeReferenceNode): TypeNode | null;
isNullish(node: ts.Node): boolean;
expectIdentifier(node: ts.Node): ts.Identifier | null;
findTag(node: ts.Node, tagName: string): ts.JSDocTag | null;
handleErrorBubbling(parentNode: ts.Node, type: TypeNode): TypeNode;
exportDirective(nameNode: ts.Node, filename: string, functionName: string): ConstDirectiveNode;
fieldNameDirective(nameNode: ts.Node, name: string): ConstDirectiveNode;
}
export {};
export declare function extract(options: ConfigOptions, sourceFile: ts.SourceFile): DiagnosticsResult<ExtractionSnapshot>;

@@ -29,4 +29,4 @@ "use strict";

};
exports.__esModule = true;
exports.Extractor = exports.ALL_TAGS = exports.KILLS_PARENT_ON_EXCEPTION_TAG = exports.IMPLEMENTS_TAG_DEPRECATED = exports.INPUT_TAG = exports.UNION_TAG = exports.ENUM_TAG = exports.INTERFACE_TAG = exports.SCALAR_TAG = exports.FIELD_TAG = exports.TYPE_TAG = exports.ISSUE_URL = exports.LIBRARY_NAME = exports.LIBRARY_IMPORT_NAME = void 0;
Object.defineProperty(exports, "__esModule", { value: true });
exports.extract = exports.ALL_TAGS = exports.KILLS_PARENT_ON_EXCEPTION_TAG = exports.IMPLEMENTS_TAG_DEPRECATED = exports.INPUT_TAG = exports.UNION_TAG = exports.ENUM_TAG = exports.INTERFACE_TAG = exports.SCALAR_TAG = exports.FIELD_TAG = exports.TYPE_TAG = exports.ISSUE_URL = exports.LIBRARY_NAME = exports.LIBRARY_IMPORT_NAME = void 0;
var graphql_1 = require("graphql");

@@ -39,3 +39,3 @@ var DiagnosticError_1 = require("./utils/DiagnosticError");

var GraphQLConstructor_1 = require("./GraphQLConstructor");
var serverDirectives_1 = require("./serverDirectives");
var gratsRoot_1 = require("./gratsRoot");
exports.LIBRARY_IMPORT_NAME = "grats";

@@ -64,2 +64,3 @@ exports.LIBRARY_NAME = "Grats";

var DEPRECATED_TAG = "deprecated";
var OPERATION_TYPES = new Set(["Query", "Mutation", "Subscription"]);
/**

@@ -75,11 +76,26 @@ * Extracts GraphQL definitions from TypeScript source code.

*/
function extract(options, sourceFile) {
var extractor = new Extractor(options);
return extractor.extract(sourceFile);
}
exports.extract = extract;
var Extractor = /** @class */ (function () {
function Extractor(sourceFile, ctx, buildOptions) {
function Extractor(buildOptions) {
this.definitions = [];
// Snapshot data
this.unresolvedNames = new Map();
this.nameDefinitions = new Map();
this.contextReferences = [];
this.typesWithTypenameField = new Set();
this.interfaceDeclarations = [];
this.errors = [];
this.sourceFile = sourceFile;
this.ctx = ctx;
this.configOptions = buildOptions;
this.gql = new GraphQLConstructor_1.GraphQLConstructor(sourceFile);
this.gql = new GraphQLConstructor_1.GraphQLConstructor();
}
Extractor.prototype.markUnresolvedType = function (node, name) {
this.unresolvedNames.set(node, name);
};
Extractor.prototype.recordTypeName = function (node, name, kind) {
this.nameDefinitions.set(node, { name: name, kind: kind });
};
// Traverse all nodes, checking each one for its JSDoc tags.

@@ -89,5 +105,5 @@ // If we find a tag we recognize, we extract the relevant information,

// supported.
Extractor.prototype.extract = function () {
Extractor.prototype.extract = function (sourceFile) {
var _this = this;
(0, JSDoc_1.traverseJSDocTags)(this.sourceFile, function (node, tag) {
(0, JSDoc_1.traverseJSDocTags)(sourceFile, function (node, tag) {
var e_1, _a;

@@ -152,3 +168,3 @@ switch (tag.tagName.text) {

try {
if (ALL_TAGS_1_1 && !ALL_TAGS_1_1.done && (_a = ALL_TAGS_1["return"])) _a.call(ALL_TAGS_1);
if (ALL_TAGS_1_1 && !ALL_TAGS_1_1.done && (_a = ALL_TAGS_1.return)) _a.call(ALL_TAGS_1);
}

@@ -166,3 +182,10 @@ finally { if (e_1) throw e_1.error; }

}
return (0, DiagnosticError_1.ok)(this.definitions);
return (0, DiagnosticError_1.ok)({
definitions: this.definitions,
unresolvedNames: this.unresolvedNames,
nameDefinitions: this.nameDefinitions,
contextReferences: this.contextReferences,
typesWithTypenameField: this.typesWithTypenameField,
interfaceDeclarations: this.interfaceDeclarations,
});
};

@@ -228,13 +251,3 @@ Extractor.prototype.extractType = function (node, tag) {

Extractor.prototype.report = function (node, message, relatedInformation) {
var start = node.getStart();
var length = node.getEnd() - start;
this.errors.push({
messageText: message,
file: this.sourceFile,
code: DiagnosticError_1.FAKE_ERROR_CODE,
category: ts.DiagnosticCategory.Error,
start: start,
length: length,
relatedInformation: relatedInformation
});
this.errors.push((0, DiagnosticError_1.tsErr)(node, message, relatedInformation));
return null;

@@ -249,17 +262,2 @@ };

};
Extractor.prototype.related = function (node, message) {
return {
category: ts.DiagnosticCategory.Message,
code: 0,
file: node.getSourceFile(),
start: node.getStart(),
length: node.getWidth(),
messageText: message
};
};
Extractor.prototype.diagnosticAnnotatedLocation = function (node) {
var start = node.getStart();
var end = node.getEnd();
return { start: start, length: end - start, filepath: this.sourceFile };
};
/** TypeScript traversals */

@@ -274,3 +272,3 @@ Extractor.prototype.unionTypeAliasDeclaration = function (node, tag) {

}
var description = this.collectDescription(node.name);
var description = this.collectDescription(node);
var types = [];

@@ -284,3 +282,3 @@ try {

var namedType = this.gql.namedType(member.typeName, TypeContext_1.UNRESOLVED_REFERENCE_NAME);
this.ctx.markUnresolvedType(member.typeName, namedType.name);
this.markUnresolvedType(member.typeName, namedType.name);
types.push(namedType);

@@ -292,7 +290,7 @@ }

try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
this.ctx.recordTypeName(node.name, name, "UNION");
this.recordTypeName(node.name, name, "UNION");
this.definitions.push(this.gql.unionTypeDefinition(node, name, types, description));

@@ -317,5 +315,6 @@ };

}
var type = this.collectMethodType(node.type);
if (type == null)
var returnType = this.collectReturnType(node.type);
if (returnType == null)
return null;
var type = returnType.type, isStream = returnType.isStream;
var args = null;

@@ -326,3 +325,7 @@ var argsParam = node.parameters[1];

}
var description = this.collectDescription(funcName);
var context = node.parameters[2];
if (context != null) {
this.validateContextParameter(context);
}
var description = this.collectDescription(node);
if (!ts.isSourceFile(node.parent)) {

@@ -332,8 +335,12 @@ return this.report(node, E.functionFieldNotTopLevel());

// TODO: Does this work in the browser?
var filename = this.ctx.getDestFilePath(node.parent);
var tsModulePath = (0, gratsRoot_1.relativePath)(node.getSourceFile().fileName);
var directives = [
this.exportDirective(funcName, filename, funcName.text),
this.gql.exportedDirective(funcName, {
tsModulePath: tsModulePath,
exportedFunctionName: funcName.text,
argCount: node.parameters.length,
}),
];
if (funcName.text !== name.value) {
directives.push(this.fieldNameDirective(funcName, funcName.text));
if (isStream) {
directives.push(this.gql.asyncIterableDirective(node.type));
}

@@ -356,3 +363,3 @@ var deprecated = this.collectDeprecated(node);

var typeName = this.gql.name(nameNode, TypeContext_1.UNRESOLVED_REFERENCE_NAME);
this.ctx.markUnresolvedType(nameNode, typeName);
this.markUnresolvedType(nameNode, typeName);
return typeName;

@@ -384,4 +391,4 @@ };

return null;
var description = this.collectDescription(node.name);
this.ctx.recordTypeName(node.name, name, "SCALAR");
var description = this.collectDescription(node);
this.recordTypeName(node.name, name, "SCALAR");
this.definitions.push(this.gql.scalarTypeDefinition(node, name, description));

@@ -393,4 +400,4 @@ };

return null;
var description = this.collectDescription(node.name);
this.ctx.recordTypeName(node.name, name, "INPUT_OBJECT");
var description = this.collectDescription(node);
this.recordTypeName(node.name, name, "INPUT_OBJECT");
var fields = this.collectInputFields(node);

@@ -421,3 +428,3 @@ var deprecatedDirective = this.collectDeprecated(node);

try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}

@@ -439,3 +446,3 @@ finally { if (e_3) throw e_3.error; }

var type = node.questionToken == null ? inner : this.gql.nullableType(inner);
var description = this.collectDescription(node.name);
var description = this.collectDescription(node);
var deprecatedDirective = this.collectDeprecated(node);

@@ -446,3 +453,3 @@ return this.gql.inputValueDefinition(node, this.gql.name(id, id.text), type, deprecatedDirective == null ? null : [deprecatedDirective], null, description);

if (node.name == null) {
return this.report(node, E.typeTagOnUnamedClass());
return this.report(node, E.typeTagOnUnnamedClass());
}

@@ -452,9 +459,17 @@ var name = this.entityName(node, tag);

return null;
var description = this.collectDescription(node.name);
this.validateOperationTypes(node.name, name.value);
var description = this.collectDescription(node);
var fields = this.collectFields(node);
var interfaces = this.collectInterfaces(node);
this.ctx.recordTypeName(node.name, name, "TYPE");
this.recordTypeName(node.name, name, "TYPE");
this.checkForTypenameProperty(node, name.value);
this.definitions.push(this.gql.objectTypeDefinition(node, name, fields, interfaces, description));
};
Extractor.prototype.validateOperationTypes = function (node, name) {
// TODO: If we start supporting defining operation types using
// non-standard names, we will need to update this logic.
if (OPERATION_TYPES.has(name)) {
this.report(node, E.operationTypeNotUnknown());
}
};
Extractor.prototype.typeInterfaceDeclaration = function (node, tag) {

@@ -464,6 +479,7 @@ var name = this.entityName(node, tag);

return null;
var description = this.collectDescription(node.name);
this.validateOperationTypes(node.name, name.value);
var description = this.collectDescription(node);
var fields = this.collectFields(node);
var interfaces = this.collectInterfaces(node);
this.ctx.recordTypeName(node.name, name, "INTERFACE");
this.recordTypeName(node.name, name, "INTERFACE");
this.checkForTypenameProperty(node, name.value);

@@ -476,11 +492,20 @@ this.definitions.push(this.gql.objectTypeDefinition(node, name, fields, interfaces, description));

return null;
if (!ts.isTypeLiteralNode(node.type)) {
this.reportUnhandled(node.type, "type", E.typeTagOnAliasOfNonObject());
return;
var fields = [];
var interfaces = null;
if (ts.isTypeLiteralNode(node.type)) {
this.validateOperationTypes(node.type, name.value);
fields = this.collectFields(node.type);
interfaces = this.collectInterfaces(node);
this.checkForTypenameProperty(node.type, name.value);
}
var description = this.collectDescription(node.name);
var fields = this.collectFields(node.type);
var interfaces = this.collectInterfaces(node);
this.ctx.recordTypeName(node.name, name, "TYPE");
this.checkForTypenameProperty(node.type, name.value);
else if (node.type.kind === ts.SyntaxKind.UnknownKeyword) {
// This is fine, we just don't know what it is. This should be the expected
// case for operation types such as `Query`, `Mutation`, and `Subscription`
// where there is not strong convention around.
}
else {
return this.report(node.type, E.typeTagOnAliasOfNonObjectOrUnknown());
}
var description = this.collectDescription(node);
this.recordTypeName(node.name, name, "TYPE");
this.definitions.push(this.gql.objectTypeDefinition(node, name, fields, interfaces, description));

@@ -494,3 +519,3 @@ };

if (hasTypename) {
this.ctx.recordHasTypenameField(expectedName);
this.typesWithTypenameField.add(expectedName);
}

@@ -589,6 +614,5 @@ };

.filter(function (expression) { return ts.isIdentifier(expression); })
.filter(function (expression) { return _this.symbolHasGqlTag(expression); })
.map(function (expression) {
var namedType = _this.gql.namedType(expression, TypeContext_1.UNRESOLVED_REFERENCE_NAME);
_this.ctx.markUnresolvedType(expression, namedType.name);
_this.markUnresolvedType(expression, namedType.name);
return namedType;

@@ -603,11 +627,2 @@ });

};
Extractor.prototype.symbolHasGqlTag = function (node) {
var symbol = this.ctx.checker.getSymbolAtLocation(node);
if (symbol == null)
return false;
var declaration = this.ctx.findSymbolDeclaration(symbol);
if (declaration == null)
return false;
return this.hasGqlTag(declaration);
};
Extractor.prototype.hasGqlTag = function (node) {

@@ -619,3 +634,2 @@ return ts.getJSDocTags(node).some(function (tag) {

Extractor.prototype.interfaceInterfaceDeclaration = function (node, tag) {
var _this = this;
var name = this.entityName(node, tag);

@@ -625,23 +639,7 @@ if (name == null || name.value == null) {

}
// Prevent using merged interfaces as GraphQL interfaces.
// https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-interfaces
var symbol = this.ctx.checker.getSymbolAtLocation(node.name);
if (symbol != null &&
symbol.declarations != null &&
symbol.declarations.length > 1) {
var otherLocations = symbol.declarations
.filter(function (d) { return d !== node && ts.isInterfaceDeclaration(d); })
.map(function (d) {
var _a;
var locNode = (_a = ts.getNameOfDeclaration(d)) !== null && _a !== void 0 ? _a : d;
return _this.related(locNode, "Other declaration");
});
if (otherLocations.length > 0) {
return this.report(node.name, E.mergedInterfaces(name.value), otherLocations);
}
}
var description = this.collectDescription(node.name);
this.interfaceDeclarations.push(node);
var description = this.collectDescription(node);
var interfaces = this.collectInterfaces(node);
var fields = this.collectFields(node);
this.ctx.recordTypeName(node.name, name, "INTERFACE");
this.recordTypeName(node.name, name, "INTERFACE");
this.definitions.push(this.gql.interfaceTypeDefinition(node, name, fields, interfaces, description));

@@ -669,3 +667,3 @@ };

try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}

@@ -729,3 +727,5 @@ finally { if (e_4) throw e_4.error; }

if (id.text !== name.value) {
directives = [this.fieldNameDirective(node.name, id.text)];
directives = [
this.gql.propertyNameDirective(node.name, { name: id.text }),
];
}

@@ -739,3 +739,3 @@ var type = this.collectType(node.type);

}
var description = this.collectDescription(node.name);
var description = this.collectDescription(node);
return this.gql.fieldDefinition(node, name, this.handleErrorBubbling(node, type), null, directives, description);

@@ -750,3 +750,3 @@ };

}
if (argsType.kind === ts.SyntaxKind.NeverKeyword) {
if (argsType.kind === ts.SyntaxKind.UnknownKeyword) {
return [];

@@ -773,3 +773,3 @@ }

try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}

@@ -796,3 +796,3 @@ finally { if (e_5) throw e_5.error; }

try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}

@@ -813,3 +813,3 @@ finally { if (e_6) throw e_6.error; }

else if (this.isNullish(node)) {
return this.gql["null"](node);
return this.gql.null(node);
}

@@ -823,3 +823,3 @@ else if (node.kind === ts.SyntaxKind.TrueKeyword) {

else if (ts.isObjectLiteralExpression(node)) {
return this.cellectObjectLiteral(node);
return this.collectObjectLiteral(node);
}

@@ -850,3 +850,3 @@ else if (ts.isArrayLiteralExpression(node)) {

try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}

@@ -860,3 +860,3 @@ finally { if (e_7) throw e_7.error; }

};
Extractor.prototype.cellectObjectLiteral = function (node) {
Extractor.prototype.collectObjectLiteral = function (node) {
var e_8, _a;

@@ -880,3 +880,3 @@ var fields = [];

try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}

@@ -924,12 +924,20 @@ finally { if (e_8) throw e_8.error; }

return null;
if (type.kind !== graphql_1.Kind.NON_NULL_TYPE && !node.questionToken) {
// If a field is passed an argument value, and that argument is not defined in the request,
// `graphql-js` will not define the argument property. Therefore we must ensure the argument
// is not just nullable, but optional.
return this.report(node.name, E.expectedNullableArgumentToBeOptional());
}
if (node.questionToken) {
/*
// TODO: Don't allow args that are optional but don't accept null
if (type.kind === Kind.NON_NULL_TYPE) {
return this.report(node.questionToken, E.nonNullTypeCannotBeOptional());
// Question mark means we can handle the argument being undefined in the
// object literal, but if we are going to type the GraphQL arg as
// optional, the code must also be able to handle an explicit null.
//
// TODO: This will catch { a?: string } but not { a?: string | undefined }.
if (type.kind === graphql_1.Kind.NON_NULL_TYPE) {
return this.report(node.questionToken, E.nonNullTypeCannotBeOptional());
}
*/
type = this.gql.nullableType(type);
}
var description = this.collectDescription(node.name);
var description = this.collectDescription(node);
var defaultValue = null;

@@ -950,5 +958,5 @@ if (defaults != null) {

}
var description = this.collectDescription(node.name);
var description = this.collectDescription(node);
var values = this.collectEnumValues(node);
this.ctx.recordTypeName(node.name, name, "ENUM");
this.recordTypeName(node.name, name, "ENUM");
this.definitions.push(this.gql.enumTypeDefinition(node, name, values, description));

@@ -964,4 +972,4 @@ };

return;
var description = this.collectDescription(node.name);
this.ctx.recordTypeName(node.name, name, "ENUM");
var description = this.collectDescription(node);
this.recordTypeName(node.name, name, "ENUM");
this.definitions.push(this.gql.enumTypeDefinition(node, name, values, description));

@@ -971,3 +979,2 @@ };

var e_9, _a;
var _b;
// Semantically we only support deriving enums from type aliases that

@@ -990,23 +997,4 @@ // are unions of string literals. However, in the edge case of a union

try {
for (var _c = __values(node.type.types), _d = _c.next(); !_d.done; _d = _c.next()) {
var member = _d.value;
// TODO: Complete this feature
if (ts.isTypeReferenceNode(member)) {
if (member.typeName.kind === ts.SyntaxKind.Identifier) {
var symbol = this.ctx.checker.getSymbolAtLocation(member.typeName);
if (((_b = symbol === null || symbol === void 0 ? void 0 : symbol.declarations) === null || _b === void 0 ? void 0 : _b.length) === 1) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
var declaration = symbol.declarations[0];
if (ts.isTypeAliasDeclaration(declaration)) {
if (ts.isLiteralTypeNode(declaration.type) &&
ts.isStringLiteral(declaration.type.literal)) {
var deprecatedDirective = this.collectDeprecated(declaration);
var memberDescription = this.collectDescription(declaration.name);
values.push(this.gql.enumValueDefinition(node, this.gql.name(declaration.type.literal, declaration.type.literal.text), deprecatedDirective ? [deprecatedDirective] : [], memberDescription));
continue;
}
}
}
}
}
for (var _b = __values(node.type.types), _c = _b.next(); !_c.done; _c = _b.next()) {
var member = _c.value;
if (!ts.isLiteralTypeNode(member) ||

@@ -1025,3 +1013,3 @@ !ts.isStringLiteral(member.literal)) {

try {
if (_d && !_d.done && (_a = _c["return"])) _a.call(_c);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}

@@ -1043,3 +1031,3 @@ finally { if (e_9) throw e_9.error; }

}
var description = this.collectDescription(member.name);
var description = this.collectDescription(member);
var deprecated = this.collectDeprecated(member);

@@ -1052,3 +1040,3 @@ values.push(this.gql.enumValueDefinition(member, this.gql.name(member.initializer, member.initializer.text), deprecated ? [deprecated] : undefined, description));

try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}

@@ -1064,3 +1052,24 @@ finally { if (e_10) throw e_10.error; }

// FIXME: Use the _value_'s location not the tag's
return this.gql.name(tag, commentName);
var locNode = tag;
// Test for leading newlines using the raw text
var hasLeadingNewlines = /\n/.test(tag.getText().trimEnd());
var hasInternalWhitespace = /\s/.test(commentName);
var validationMessage = graphQLNameValidationMessage(commentName);
if (hasLeadingNewlines && validationMessage == null) {
// TODO: Offer quick fix.
return this.report(locNode, E.graphQLNameHasLeadingNewlines(commentName, tag.tagName.text));
}
if (hasLeadingNewlines || hasInternalWhitespace) {
return this.report(locNode, E.graphQLTagNameHasWhitespace(tag.tagName.text));
}
// No whitespace, but still invalid. We will assume they meant this to
// be a GraphQL name but didn't provide a valid identifier.
//
// NOTE: We can't let GraphQL validation handle this, because it throws rather
// than returning a validation message. Presumably because it expects token
// validation to be done during lexing/parsing.
if (validationMessage !== null) {
return this.report(locNode, validationMessage);
}
return this.gql.name(locNode, commentName);
}

@@ -1076,2 +1085,22 @@ }

};
// Ensure the type of the ctx param resolves to the declaration
// annotated with `@gqlContext`.
Extractor.prototype.validateContextParameter = function (node) {
if (node.type == null) {
return this.report(node, E.expectedTypeAnnotationOnContext());
}
if (node.type.kind === ts.SyntaxKind.UnknownKeyword) {
// If the user just needs to define the argument to get to a later parameter,
// they can use `ctx: unknown` to safely avoid triggering a Grats error.
return;
}
if (!ts.isTypeReferenceNode(node.type)) {
return this.report(node.type, E.expectedTypeAnnotationOfReferenceOnContext());
}
// Check for ...
if (node.dotDotDotToken != null) {
return this.report(node.dotDotDotToken, E.unexpectedParamSpreadForContextParam());
}
this.contextReferences.push(node.type.typeName);
};
Extractor.prototype.methodDeclaration = function (node) {

@@ -1087,3 +1116,6 @@ var tag = this.findTag(node, exports.FIELD_TAG);

}
var type = this.collectMethodType(node.type);
var returnType = this.collectReturnType(node.type);
if (returnType == null)
return null;
var type = returnType.type, isStream = returnType.isStream;
// We already reported an error

@@ -1097,3 +1129,7 @@ if (type == null)

}
var description = this.collectDescription(node.name);
var context = node.parameters[1];
if (context != null) {
this.validateContextParameter(context);
}
var description = this.collectDescription(node);
var id = this.expectIdentifier(node.name);

@@ -1104,4 +1140,9 @@ if (id == null)

if (id.text !== name.value) {
directives = [this.fieldNameDirective(node.name, id.text)];
directives = [
this.gql.propertyNameDirective(node.name, { name: id.text }),
];
}
if (isStream) {
directives.push(this.gql.asyncIterableDirective(node.type));
}
var deprecated = this.collectDeprecated(node);

@@ -1113,11 +1154,29 @@ if (deprecated != null) {

};
Extractor.prototype.collectMethodType = function (node) {
var inner = this.maybeUnwrapePromise(node);
Extractor.prototype.collectReturnType = function (node) {
if (ts.isTypeReferenceNode(node)) {
var identifier = this.expectIdentifier(node.typeName);
if (identifier == null)
return null;
if (identifier.text == "AsyncIterable") {
if (node.typeArguments == null || node.typeArguments.length === 0) {
// TODO: Better error?
return this.report(node, E.promiseMissingTypeArg());
}
var t_1 = this.collectType(node.typeArguments[0]);
if (t_1 == null)
return null;
return { type: t_1, isStream: true };
}
}
var inner = this.maybeUnwrapPromise(node);
if (inner == null)
return null;
return this.collectType(inner);
var t = this.collectType(inner);
if (t == null)
return null;
return { type: t, isStream: false };
};
Extractor.prototype.collectPropertyType = function (node) {
// TODO: Handle function types here.
var inner = this.maybeUnwrapePromise(node);
var inner = this.maybeUnwrapPromise(node);
if (inner == null)

@@ -1127,3 +1186,3 @@ return null;

};
Extractor.prototype.maybeUnwrapePromise = function (node) {
Extractor.prototype.maybeUnwrapPromise = function (node) {
if (ts.isTypeReferenceNode(node)) {

@@ -1134,3 +1193,3 @@ var identifier = this.expectIdentifier(node.typeName);

if (identifier.text === "Promise") {
if (node.typeArguments == null) {
if (node.typeArguments == null || node.typeArguments.length === 0) {
return this.report(node, E.promiseMissingTypeArg());

@@ -1144,11 +1203,12 @@ }

Extractor.prototype.collectDescription = function (node) {
var symbol = this.ctx.checker.getSymbolAtLocation(node);
if (symbol == null) {
return this.report(node, E.cannotResolveSymbolForDescription());
var docs =
// @ts-ignore Exposed as stable in https://github.com/microsoft/TypeScript/pull/53627
ts.getJSDocCommentsAndTags(node);
var comment = docs
.filter(function (doc) { return doc.kind === ts.SyntaxKind.JSDoc; })
.map(function (doc) { return doc.comment; })
.join("");
if (comment) {
return this.gql.string(node, comment.trim(), true);
}
var doc = symbol.getDocumentationComment(this.ctx.checker);
var description = ts.displayPartsToString(doc);
if (description) {
return this.gql.string(node, description, true);
}
return null;

@@ -1186,3 +1246,3 @@ };

var type = node.questionToken == null ? inner : this.gql.nullableType(inner);
var description = this.collectDescription(node.name);
var description = this.collectDescription(node);
var directives = [];

@@ -1197,3 +1257,5 @@ var id = this.expectIdentifier(node.name);

if (id.text !== name.value) {
directives = [this.fieldNameDirective(node.name, id.text)];
directives = [
this.gql.propertyNameDirective(node.name, { name: id.text }),
];
}

@@ -1230,3 +1292,3 @@ return this.gql.fieldDefinition(node, name, this.handleErrorBubbling(node, type), null, directives, description);

var incompatibleVariants = rest.map(function (tsType) {
return _this.related(tsType, "Other non-nullish type");
return (0, DiagnosticError_1.tsRelated)(tsType, "Other non-nullish type");
});

@@ -1283,3 +1345,3 @@ this.report(first, E.expectedOneNonNullishType(), incompatibleVariants);

var namedType = this.gql.namedType(node, TypeContext_1.UNRESOLVED_REFERENCE_NAME);
this.ctx.markUnresolvedType(node.typeName, namedType.name);
this.markUnresolvedType(node.typeName, namedType.name);
return this.gql.nonNullType(node, namedType);

@@ -1305,6 +1367,5 @@ }

}
return this.report(node, E.expectedIdentifer());
return this.report(node, E.expectedIdentifier());
};
Extractor.prototype.findTag = function (node, tagName) {
var _this = this;
var tags = ts

@@ -1318,3 +1379,3 @@ .getJSDocTags(node)

var additionalTags = tags.slice(1).map(function (tag) {
return _this.related(tag, "Additional tag");
return (0, DiagnosticError_1.tsRelated)(tag, "Additional tag");
});

@@ -1329,3 +1390,3 @@ var message = tagName === exports.IMPLEMENTS_TAG_DEPRECATED

// It is a GraphQL best practice to model all fields as nullable. This allows
// the server to handle field level exections by simply returning null for
// the server to handle field level executions by simply returning null for
// that field.

@@ -1350,16 +1411,12 @@ // https://graphql.org/learn/best-practices/#nullability

};
/* Grats directives */
Extractor.prototype.exportDirective = function (nameNode, filename, functionName) {
return this.gql.constDirective(nameNode, this.gql.name(nameNode, serverDirectives_1.EXPORTED_DIRECTIVE), [
this.gql.constArgument(nameNode, this.gql.name(nameNode, serverDirectives_1.EXPORTED_FILENAME_ARG), this.gql.string(nameNode, filename)),
this.gql.constArgument(nameNode, this.gql.name(nameNode, serverDirectives_1.EXPORTED_FUNCTION_NAME_ARG), this.gql.string(nameNode, functionName)),
]);
};
Extractor.prototype.fieldNameDirective = function (nameNode, name) {
return this.gql.constDirective(nameNode, this.gql.name(nameNode, serverDirectives_1.METHOD_NAME_DIRECTIVE), [
this.gql.constArgument(nameNode, this.gql.name(nameNode, serverDirectives_1.METHOD_NAME_ARG), this.gql.string(nameNode, name)),
]);
};
return Extractor;
}());
exports.Extractor = Extractor;
function graphQLNameValidationMessage(name) {
try {
(0, graphql_1.assertName)(name);
return null;
}
catch (e) {
return e.message;
}
}

@@ -1,7 +0,15 @@

import { ListTypeNode, NamedTypeNode, Location as GraphQLLocation, NameNode, Token, TypeNode, NonNullTypeNode, StringValueNode, ConstValueNode, ConstDirectiveNode, ConstArgumentNode, UnionTypeDefinitionNode, FieldDefinitionNode, InputValueDefinitionNode, FloatValueNode, IntValueNode, NullValueNode, BooleanValueNode, ConstListValueNode, ConstObjectValueNode, ConstObjectFieldNode, ObjectTypeDefinitionNode, EnumValueDefinitionNode, ScalarTypeDefinitionNode, InputObjectTypeDefinitionNode, EnumTypeDefinitionNode, InterfaceTypeDefinitionNode } from "graphql";
import { ListTypeNode, NamedTypeNode, Location as GraphQLLocation, NameNode, Token, TypeNode, NonNullTypeNode, StringValueNode, ConstValueNode, ConstDirectiveNode, ConstArgumentNode, UnionTypeDefinitionNode, FieldDefinitionNode, InputValueDefinitionNode, FloatValueNode, IntValueNode, NullValueNode, BooleanValueNode, ConstListValueNode, ConstObjectValueNode, ConstObjectFieldNode, ObjectTypeDefinitionNode, EnumValueDefinitionNode, ScalarTypeDefinitionNode, InputObjectTypeDefinitionNode, EnumTypeDefinitionNode, InterfaceTypeDefinitionNode, DefinitionNode, Location } from "graphql";
import * as ts from "typescript";
import { AbstractFieldDefinitionNode } from "./TypeContext";
import { ExportedMetadata, PropertyNameMetadata } from "./metadataDirectives";
export type GratsDefinitionNode = DefinitionNode | AbstractFieldDefinitionNode;
export type AbstractFieldDefinitionNode = {
readonly kind: "AbstractFieldDefinition";
readonly loc: Location;
readonly onType: NameNode;
readonly field: FieldDefinitionNode;
};
export declare class GraphQLConstructor {
sourceFile: ts.SourceFile;
constructor(sourceFile: ts.SourceFile);
exportedDirective(node: ts.Node, exported: ExportedMetadata): ConstDirectiveNode;
propertyNameDirective(node: ts.Node, propertyName: PropertyNameMetadata): ConstDirectiveNode;
asyncIterableDirective(node: ts.Node): ConstDirectiveNode;
unionTypeDefinition(node: ts.Node, name: NameNode, types: NamedTypeNode[], description: StringValueNode | null): UnionTypeDefinitionNode;

@@ -34,3 +42,3 @@ objectTypeDefinition(node: ts.Node, name: NameNode, fields: FieldDefinitionNode[], interfaces: NamedTypeNode[] | null, description: StringValueNode | null): ObjectTypeDefinitionNode;

_loc(node: ts.Node): GraphQLLocation;
_dummyToken(pos: number): Token;
_dummyToken(sourceFile: ts.SourceFile, pos: number): Token;
}
"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GraphQLConstructor = void 0;
var graphql_1 = require("graphql");
var metadataDirectives_1 = require("./metadataDirectives");
var GraphQLConstructor = /** @class */ (function () {
function GraphQLConstructor(sourceFile) {
this.sourceFile = sourceFile;
function GraphQLConstructor() {
}
/* Metadata Directives */
GraphQLConstructor.prototype.exportedDirective = function (node, exported) {
return (0, metadataDirectives_1.makeExportedDirective)(this._loc(node), exported);
};
GraphQLConstructor.prototype.propertyNameDirective = function (node, propertyName) {
return (0, metadataDirectives_1.makePropertyNameDirective)(this._loc(node), propertyName);
};
GraphQLConstructor.prototype.asyncIterableDirective = function (node) {
return (0, metadataDirectives_1.makeAsyncIterableDirective)(this._loc(node));
};
/* Top Level Types */

@@ -16,3 +26,3 @@ GraphQLConstructor.prototype.unionTypeDefinition = function (node, name, types, description) {

name: name,
types: types
types: types,
};

@@ -28,3 +38,3 @@ };

fields: fields,
interfaces: interfaces !== null && interfaces !== void 0 ? interfaces : undefined
interfaces: interfaces !== null && interfaces !== void 0 ? interfaces : undefined,
};

@@ -40,3 +50,3 @@ };

fields: fields,
interfaces: interfaces !== null && interfaces !== void 0 ? interfaces : undefined
interfaces: interfaces !== null && interfaces !== void 0 ? interfaces : undefined,
};

@@ -50,3 +60,3 @@ };

name: name,
values: values
values: values,
};

@@ -60,3 +70,3 @@ };

onType: onType,
field: field
field: field,
};

@@ -73,3 +83,3 @@ };

arguments: args !== null && args !== void 0 ? args : undefined,
directives: this._optionalList(directives)
directives: this._optionalList(directives),
};

@@ -88,3 +98,3 @@ };

defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : undefined,
directives: this._optionalList(directives)
directives: this._optionalList(directives),
};

@@ -98,3 +108,3 @@ };

name: name,
directives: directives
directives: directives,
};

@@ -108,3 +118,3 @@ };

name: name,
directives: undefined
directives: undefined,
};

@@ -119,3 +129,3 @@ };

fields: fields !== null && fields !== void 0 ? fields : undefined,
directives: this._optionalList(directives)
directives: this._optionalList(directives),
};

@@ -131,3 +141,3 @@ };

loc: this._loc(node),
name: this.name(node, value)
name: this.name(node, value),
};

@@ -166,3 +176,3 @@ };

name: name,
arguments: this._optionalList(args)
arguments: this._optionalList(args),
};

@@ -179,3 +189,3 @@ };

};
GraphQLConstructor.prototype["null"] = function (node) {
GraphQLConstructor.prototype.null = function (node) {
return { kind: graphql_1.Kind.NULL, loc: this._loc(node) };

@@ -196,9 +206,10 @@ };

GraphQLConstructor.prototype._loc = function (node) {
var source = new graphql_1.Source(this.sourceFile.text, this.sourceFile.fileName);
var startToken = this._dummyToken(node.getStart());
var endToken = this._dummyToken(node.getEnd());
var sourceFile = node.getSourceFile();
var source = new graphql_1.Source(sourceFile.text, sourceFile.fileName);
var startToken = this._dummyToken(sourceFile, node.getStart());
var endToken = this._dummyToken(sourceFile, node.getEnd());
return new graphql_1.Location(startToken, endToken, source);
};
GraphQLConstructor.prototype._dummyToken = function (pos) {
var _a = this.sourceFile.getLineAndCharacterOfPosition(pos), line = _a.line, character = _a.character;
GraphQLConstructor.prototype._dummyToken = function (sourceFile, pos) {
var _a = sourceFile.getLineAndCharacterOfPosition(pos), line = _a.line, character = _a.character;
return new graphql_1.Token(graphql_1.TokenKind.SOF, pos, pos, line, character, undefined);

@@ -205,0 +216,0 @@ };

@@ -1,3 +0,2 @@

import * as ts from "typescript";
export declare function getRelativeOutputPath(options: ts.ParsedCommandLine, sourceFile: ts.SourceFile): string;
export declare function relativePath(absolute: string): string;
export declare function resolveRelativePath(relativePath: string): string;
"use strict";
exports.__esModule = true;
exports.resolveRelativePath = exports.getRelativeOutputPath = void 0;
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveRelativePath = exports.relativePath = void 0;
var path_1 = require("path");
var ts = require("typescript");
// Grats parses TypeScript files and finds resolvers. If the field resolver is a

@@ -13,16 +12,7 @@ // named export, Grats needs to be able to import that file during execution.

// step and the runtime can agree on. This path is that thing.
var gratsRoot = __dirname;
function getRelativeOutputPath(options, sourceFile) {
var fileNames = ts.getOutputFileNames(options, sourceFile.fileName, true);
// ts.getOutputFileNames returns a list of files that includes both the .d.ts
// and .js files.
var jsFileNames = fileNames.filter(function (fileName) { return fileName.endsWith(".js"); });
if (jsFileNames.length !== 1) {
throw new Error("Grats: Expected ts.getOutputFileNames to return exactly one `.js` file. " +
"Found ".concat(jsFileNames.length, "}. This is a bug in Grats. I'd appreciate it if ") +
"you could open an issue.");
}
return (0, path_1.relative)(gratsRoot, fileNames[0]);
var gratsRoot = (0, path_1.join)(__dirname, "../..");
function relativePath(absolute) {
return (0, path_1.relative)(gratsRoot, absolute);
}
exports.getRelativeOutputPath = getRelativeOutputPath;
exports.relativePath = relativePath;
function resolveRelativePath(relativePath) {

@@ -29,0 +19,0 @@ return (0, path_1.resolve)(gratsRoot, relativePath);

@@ -1,10 +0,7 @@

import { GraphQLSchema } from "graphql";
import * as ts from "typescript";
import { ParsedCommandLineGrats } from "./lib";
import { ReportableDiagnostics, Result } from "./utils/DiagnosticError";
export { printSDLWithoutDirectives } from "./printSchema";
export * from "./Types";
export * from "./lib";
type RuntimeOptions = {
emitSchemaFile?: string;
};
export declare function extractGratsSchemaAtRuntime(runtimeOptions: RuntimeOptions): GraphQLSchema;
export declare function buildSchemaFromSDL(sdl: string): GraphQLSchema;
export declare function getParsedTsConfig(configPath?: string): ts.ParsedCommandLine;
export { codegen } from "./codegen";
export declare function getParsedTsConfig(configFile: string): Result<ParsedCommandLineGrats, ReportableDiagnostics>;

@@ -16,39 +16,15 @@ "use strict";

};
exports.__esModule = true;
exports.getParsedTsConfig = exports.buildSchemaFromSDL = exports.extractGratsSchemaAtRuntime = void 0;
var graphql_1 = require("graphql");
var utils_1 = require("@graphql-tools/utils");
var fs = require("fs");
Object.defineProperty(exports, "__esModule", { value: true });
exports.getParsedTsConfig = exports.codegen = exports.printSDLWithoutDirectives = void 0;
var ts = require("typescript");
var lib_1 = require("./lib");
var DiagnosticError_1 = require("./utils/DiagnosticError");
var printSchema_1 = require("./printSchema");
Object.defineProperty(exports, "printSDLWithoutDirectives", { enumerable: true, get: function () { return printSchema_1.printSDLWithoutDirectives; } });
__exportStar(require("./Types"), exports);
__exportStar(require("./lib"), exports);
// Build an executable schema from a set of files. Note that if extraction
// fails, this function will exit the process and print a helpful error
// message.
function extractGratsSchemaAtRuntime(runtimeOptions) {
var parsedTsConfig = getParsedTsConfig();
var schemaResult = (0, lib_1.buildSchemaResult)(parsedTsConfig);
if (schemaResult.kind === "ERROR") {
console.error(schemaResult.err.formatDiagnosticsWithColorAndContext());
process.exit(1);
}
var runtimeSchema = schemaResult.value;
if (runtimeOptions.emitSchemaFile) {
runtimeSchema = (0, graphql_1.lexicographicSortSchema)(runtimeSchema);
var sdl = (0, utils_1.printSchemaWithDirectives)(runtimeSchema, { assumeValid: true });
var filePath = runtimeOptions.emitSchemaFile;
fs.writeFileSync(filePath, sdl);
}
return runtimeSchema;
}
exports.extractGratsSchemaAtRuntime = extractGratsSchemaAtRuntime;
function buildSchemaFromSDL(sdl) {
var schema = (0, graphql_1.buildSchema)(sdl);
return (0, lib_1.applyServerDirectives)(schema);
}
exports.buildSchemaFromSDL = buildSchemaFromSDL;
var codegen_1 = require("./codegen");
Object.defineProperty(exports, "codegen", { enumerable: true, get: function () { return codegen_1.codegen; } });
// #FIXME: Report diagnostics instead of throwing!
function getParsedTsConfig(configPath) {
var configFile = configPath || ts.findConfigFile(process.cwd(), ts.sys.fileExists);
function getParsedTsConfig(configFile) {
if (!configFile) {

@@ -60,7 +36,10 @@ throw new Error("Grats: Could not find tsconfig.json");

var parsed = ts.getParsedCommandLineOfConfigFile(configFile, undefined, configFileHost);
if (!parsed || parsed.errors.length > 0) {
throw new Error("Grats: Could not parse tsconfig.json");
if (!parsed) {
throw new Error("Grats: Could not locate tsconfig.json");
}
return parsed;
if (parsed.errors.length > 0) {
return (0, DiagnosticError_1.err)(DiagnosticError_1.ReportableDiagnostics.fromDiagnostics(parsed.errors));
}
return (0, DiagnosticError_1.ok)((0, lib_1.validateGratsOptions)(parsed));
}
exports.getParsedTsConfig = getParsedTsConfig;

@@ -1,3 +0,3 @@

import { GratsDefinitionNode, TypeContext } from "./TypeContext";
import { DiagnosticsResult } from "./utils/DiagnosticError";
import { GratsDefinitionNode } from "./GraphQLConstructor";
import { TypeContext } from "./TypeContext";
import { DefaultMap } from "./utils/helpers";

@@ -12,2 +12,2 @@ export type InterfaceImplementor = {

*/
export declare function computeInterfaceMap(typeContext: TypeContext, docs: GratsDefinitionNode[]): DiagnosticsResult<InterfaceMap>;
export declare function computeInterfaceMap(typeContext: TypeContext, docs: GratsDefinitionNode[]): InterfaceMap;

@@ -13,5 +13,4 @@ "use strict";

};
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeInterfaceMap = void 0;
var DiagnosticError_1 = require("./utils/DiagnosticError");
var helpers_1 = require("./utils/helpers");

@@ -30,3 +29,2 @@ var graphql_1 = require("graphql");

};
var errors = [];
try {

@@ -48,3 +46,3 @@ for (var docs_1 = __values(docs), docs_1_1 = docs_1.next(); !docs_1_1.done; docs_1_1 = docs_1.next()) {

kind: "INTERFACE",
name: doc.name.value
name: doc.name.value,
});

@@ -56,3 +54,3 @@ }

try {
if (_g && !_g.done && (_b = _f["return"])) _b.call(_f);
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
}

@@ -78,3 +76,3 @@ finally { if (e_2) throw e_2.error; }

try {
if (_j && !_j.done && (_c = _h["return"])) _c.call(_h);
if (_j && !_j.done && (_c = _h.return)) _c.call(_h);
}

@@ -90,11 +88,8 @@ finally { if (e_3) throw e_3.error; }

try {
if (docs_1_1 && !docs_1_1.done && (_a = docs_1["return"])) _a.call(docs_1);
if (docs_1_1 && !docs_1_1.done && (_a = docs_1.return)) _a.call(docs_1);
}
finally { if (e_1) throw e_1.error; }
}
if (errors.length > 0) {
return (0, DiagnosticError_1.err)(errors);
}
return (0, DiagnosticError_1.ok)(graph);
return graph;
}
exports.computeInterfaceMap = computeInterfaceMap;

@@ -1,10 +0,13 @@

import { GraphQLSchema } from "graphql";
import { Result, ReportableDiagnostics } from "./utils/DiagnosticError";
import { DocumentNode, GraphQLSchema } from "graphql";
import { DiagnosticsResult, Result, ReportableDiagnostics } from "./utils/DiagnosticError";
import * as ts from "typescript";
export { applyServerDirectives } from "./serverDirectives";
export type ConfigOptions = {
nullableByDefault?: boolean;
reportTypeScriptTypeErrors?: boolean;
};
export declare function buildSchemaResult(options: ts.ParsedCommandLine): Result<GraphQLSchema, ReportableDiagnostics>;
export declare function buildSchemaResultWithHost(options: ts.ParsedCommandLine, compilerHost: ts.CompilerHost): Result<GraphQLSchema, ReportableDiagnostics>;
import { ExtractionSnapshot } from "./Extractor";
import { ParsedCommandLineGrats } from "./gratsConfig";
export * from "./gratsConfig";
export declare function buildSchemaResult(options: ParsedCommandLineGrats): Result<GraphQLSchema, ReportableDiagnostics>;
export declare function buildSchemaResultWithHost(options: ParsedCommandLineGrats, compilerHost: ts.CompilerHost): Result<GraphQLSchema, ReportableDiagnostics>;
/**
* Given a merged snapshot representing the whole program, construct a GraphQL
* schema document with metadata directives attached.
*/
export declare function docFromSnapshot(program: ts.Program, host: ts.CompilerHost, snapshot: ExtractionSnapshot): DiagnosticsResult<DocumentNode>;
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {

@@ -24,2 +13,5 @@ if (k2 === undefined) k2 = k;

}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __values = (this && this.__values) || function(o) {

@@ -36,13 +28,36 @@ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;

};
exports.__esModule = true;
exports.buildSchemaResultWithHost = exports.buildSchemaResult = exports.applyServerDirectives = void 0;
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.docFromSnapshot = exports.buildSchemaResultWithHost = exports.buildSchemaResult = void 0;
var graphql_1 = require("graphql");
var DiagnosticError_1 = require("./utils/DiagnosticError");
var ts = require("typescript");
var Extractor_1 = require("./Extractor");
var TypeContext_1 = require("./TypeContext");
var validate_1 = require("graphql/validation/validate");
var serverDirectives_1 = require("./serverDirectives");
var serverDirectives_2 = require("./serverDirectives");
__createBinding(exports, serverDirectives_2, "applyServerDirectives");
var validateTypenames_1 = require("./validations/validateTypenames");
var snapshotsFromProgram_1 = require("./transforms/snapshotsFromProgram");
var validateMergedInterfaces_1 = require("./validations/validateMergedInterfaces");
var validateContextReferences_1 = require("./validations/validateContextReferences");
var metadataDirectives_1 = require("./metadataDirectives");
var helpers_1 = require("./utils/helpers");
var addInterfaceFields_1 = require("./transforms/addInterfaceFields");
var filterNonGqlInterfaces_1 = require("./transforms/filterNonGqlInterfaces");
var resolveTypes_1 = require("./transforms/resolveTypes");
var validateAsyncIterable_1 = require("./validations/validateAsyncIterable");
__exportStar(require("./gratsConfig"), exports);
// Construct a schema, using GraphQL schema language

@@ -59,76 +74,65 @@ // Exported for tests that want to intercept diagnostic errors.

function buildSchemaResultWithHost(options, compilerHost) {
var gratsOptions = parseGratsOptions(options);
var schemaResult = extractSchema(options, gratsOptions, compilerHost);
var schemaResult = extractSchema(options, compilerHost);
if (schemaResult.kind === "ERROR") {
return (0, DiagnosticError_1.err)(new DiagnosticError_1.ReportableDiagnostics(compilerHost, schemaResult.err));
}
return (0, DiagnosticError_1.ok)((0, serverDirectives_1.applyServerDirectives)(schemaResult.value));
return (0, DiagnosticError_1.ok)(schemaResult.value);
}
exports.buildSchemaResultWithHost = buildSchemaResultWithHost;
// TODO: Make this return diagnostics
function parseGratsOptions(options) {
var _a, _b;
var gratsOptions = __assign({}, ((_b = (_a = options.raw) === null || _a === void 0 ? void 0 : _a.grats) !== null && _b !== void 0 ? _b : {}));
if (gratsOptions.nullableByDefault === undefined) {
gratsOptions.nullableByDefault = true;
function extractSchema(options, host) {
var program = ts.createProgram(options.fileNames, options.options, host);
var snapshotsResult = (0, snapshotsFromProgram_1.snapshotsFromProgram)(program, options);
if (snapshotsResult.kind === "ERROR") {
return snapshotsResult;
}
else if (typeof gratsOptions.nullableByDefault !== "boolean") {
throw new Error("Grats: The Grats config option `nullableByDefault` must be a boolean if provided.");
var snapshot = reduceSnapshots(snapshotsResult.value);
var docResult = docFromSnapshot(program, host, snapshot);
if (docResult.kind === "ERROR") {
return docResult;
}
if (gratsOptions.reportTypeScriptTypeErrors === undefined) {
gratsOptions.reportTypeScriptTypeErrors = false;
return buildSchemaFromDocumentNode(docResult.value, snapshot.typesWithTypenameField);
}
// Given a SDL AST, build and validate a GraphQLSchema.
function buildSchemaFromDocumentNode(doc, typesWithTypenameField) {
// TODO: Currently this does not detect definitions that shadow builtins
// (`String`, `Int`, etc). However, if we pass a second param (extending an
// existing schema) we do! So, we should find a way to validate that we don't
// shadow builtins.
var validationErrors = (0, validate_1.validateSDL)(doc).map(function (e) {
return (0, DiagnosticError_1.graphQlErrorToDiagnostic)(e);
});
if (validationErrors.length > 0) {
return (0, DiagnosticError_1.err)(validationErrors);
}
else if (typeof gratsOptions.reportTypeScriptTypeErrors !== "boolean") {
throw new Error("Grats: The Grats config option `reportTypeScriptTypeErrors` must be a boolean if provided");
var schema = (0, graphql_1.buildASTSchema)(doc, { assumeValidSDL: true });
var diagnostics = (0, graphql_1.validateSchema)(schema)
// FIXME: Handle case where query is not defined (no location)
.filter(function (e) { return e.source && e.locations && e.positions; })
.map(function (e) { return (0, DiagnosticError_1.graphQlErrorToDiagnostic)(e); });
if (diagnostics.length > 0) {
return (0, DiagnosticError_1.err)(diagnostics);
}
// FIXME: Check for unknown options
return gratsOptions;
var typenameDiagnostics = (0, validateTypenames_1.validateTypenames)(schema, typesWithTypenameField);
if (typenameDiagnostics.length > 0)
return (0, DiagnosticError_1.err)(typenameDiagnostics);
return (0, DiagnosticError_1.ok)(schema);
}
function extractSchema(options, gratsOptions, host) {
/**
* Given a merged snapshot representing the whole program, construct a GraphQL
* schema document with metadata directives attached.
*/
function docFromSnapshot(program, host, snapshot) {
var e_1, _a, e_2, _b;
var program = ts.createProgram(options.fileNames, options.options, host);
var checker = program.getTypeChecker();
var ctx = new TypeContext_1.TypeContext(options, checker, host);
var definitions = Array.from(serverDirectives_1.DIRECTIVES_AST.definitions);
var ctx = new TypeContext_1.TypeContext(checker, host);
// Validate the snapshot
var mergedResult = (0, DiagnosticError_1.combineResults)((0, validateMergedInterfaces_1.validateMergedInterfaces)(checker, snapshot.interfaceDeclarations), (0, validateContextReferences_1.validateContextReferences)(ctx, snapshot.contextReferences));
if (mergedResult.kind === "ERROR") {
return mergedResult;
}
try {
for (var _c = __values(program.getSourceFiles()), _d = _c.next(); !_d.done; _d = _c.next()) {
var sourceFile = _d.value;
// If the file doesn't contain any GraphQL definitions, skip it.
if (!/@gql/i.test(sourceFile.text)) {
continue;
}
if (gratsOptions.reportTypeScriptTypeErrors) {
// If the user asked for us to report TypeScript errors, then we'll report them.
var typeErrors = ts.getPreEmitDiagnostics(program, sourceFile);
if (typeErrors.length > 0) {
return (0, DiagnosticError_1.err)(typeErrors);
}
}
else {
// Otherwise, we will only report syntax errors, since they will prevent us from
// extracting any GraphQL definitions.
var syntaxErrors = program.getSyntacticDiagnostics(sourceFile);
if (syntaxErrors.length > 0) {
// It's not very helpful to report multiple syntax errors, so just report
// the first one.
return (0, DiagnosticError_1.err)([syntaxErrors[0]]);
}
}
var extractor = new Extractor_1.Extractor(sourceFile, ctx, gratsOptions);
var extractedResult = extractor.extract();
if (extractedResult.kind === "ERROR")
return extractedResult;
try {
for (var _e = (e_2 = void 0, __values(extractedResult.value)), _f = _e.next(); !_f.done; _f = _e.next()) {
var definition = _f.value;
definitions.push(definition);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_f && !_f.done && (_b = _e["return"])) _b.call(_e);
}
finally { if (e_2) throw e_2.error; }
}
// Propagate snapshot data to type context
for (var _c = __values(snapshot.unresolvedNames), _d = _c.next(); !_d.done; _d = _c.next()) {
var _e = __read(_d.value, 2), node = _e[0], typeName = _e[1];
ctx.markUnresolvedType(node, typeName);
}

@@ -139,63 +143,62 @@ }

try {
if (_d && !_d.done && (_a = _c["return"])) _a.call(_c);
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
}
finally { if (e_1) throw e_1.error; }
}
try {
for (var _f = __values(snapshot.nameDefinitions), _g = _f.next(); !_g.done; _g = _f.next()) {
var _h = __read(_g.value, 2), node = _h[0], definition = _h[1];
ctx.recordTypeName(node, definition.name, definition.kind);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
}
finally { if (e_2) throw e_2.error; }
}
// Fixup the schema SDL
var definitions = Array.from(metadataDirectives_1.DIRECTIVES_AST.definitions);
(0, helpers_1.extend)(definitions, snapshot.definitions);
// If you define a field on an interface using the functional style, we need to add
// that field to each concrete type as well. This must be done after all types are created,
// but before we validate the schema.
var definitionsResult = ctx.handleAbstractDefinitions(definitions);
var definitionsResult = (0, addInterfaceFields_1.addInterfaceFields)(ctx, definitions);
if (definitionsResult.kind === "ERROR") {
return definitionsResult;
}
var docResult = ctx.resolveTypes({
var filteredDoc = (0, filterNonGqlInterfaces_1.filterNonGqlInterfaces)(ctx, {
kind: graphql_1.Kind.DOCUMENT,
definitions: definitionsResult.value
definitions: definitionsResult.value,
});
var docResult = (0, resolveTypes_1.resolveTypes)(ctx, filteredDoc);
if (docResult.kind === "ERROR")
return docResult;
var doc = docResult.value;
// TODO: Currently this does not detect definitions that shadow builtins
// (`String`, `Int`, etc). However, if we pass a second param (extending an
// existing schema) we do! So, we should find a way to validate that we don't
// shadow builtins.
var validationErrors = (0, validate_1.validateSDL)(doc).map(function (e) {
return (0, DiagnosticError_1.graphQlErrorToDiagnostic)(e);
});
if (validationErrors.length > 0) {
return (0, DiagnosticError_1.err)(validationErrors);
var subscriptionsValidationResult = (0, validateAsyncIterable_1.validateAsyncIterable)(doc);
if (subscriptionsValidationResult.kind === "ERROR") {
return subscriptionsValidationResult;
}
var schema = (0, graphql_1.buildASTSchema)(doc, { assumeValidSDL: true });
var diagnostics = (0, graphql_1.validateSchema)(schema)
// FIXME: Handle case where query is not defined (no location)
.filter(function (e) { return e.source && e.locations && e.positions; })
.map(function (e) { return (0, DiagnosticError_1.graphQlErrorToDiagnostic)(e); });
if (diagnostics.length > 0) {
return (0, DiagnosticError_1.err)(diagnostics);
}
var typenameDiagnostics = validateTypename(schema, ctx);
if (typenameDiagnostics.length > 0)
return (0, DiagnosticError_1.err)(typenameDiagnostics);
return (0, DiagnosticError_1.ok)(schema);
return (0, DiagnosticError_1.ok)(doc);
}
function validateTypename(schema, ctx) {
var e_3, _a, e_4, _b;
var _c, _d;
var typenameDiagnostics = [];
var abstractTypes = Object.values(schema.getTypeMap()).filter(graphql_1.isAbstractType);
exports.docFromSnapshot = docFromSnapshot;
// Given a list of snapshots, merge them into a single snapshot.
function reduceSnapshots(snapshots) {
var e_3, _a, e_4, _b, e_5, _c, e_6, _d, e_7, _e, e_8, _f, e_9, _g;
var result = {
definitions: [],
nameDefinitions: new Map(),
unresolvedNames: new Map(),
contextReferences: [],
typesWithTypenameField: new Set(),
interfaceDeclarations: [],
};
try {
for (var abstractTypes_1 = __values(abstractTypes), abstractTypes_1_1 = abstractTypes_1.next(); !abstractTypes_1_1.done; abstractTypes_1_1 = abstractTypes_1.next()) {
var type = abstractTypes_1_1.value;
// TODO: If we already implement resolveType, we don't need to check implementors
var typeImplementors = schema.getPossibleTypes(type).filter(graphql_1.isType);
for (var snapshots_1 = __values(snapshots), snapshots_1_1 = snapshots_1.next(); !snapshots_1_1.done; snapshots_1_1 = snapshots_1.next()) {
var snapshot = snapshots_1_1.value;
try {
for (var typeImplementors_1 = (e_4 = void 0, __values(typeImplementors)), typeImplementors_1_1 = typeImplementors_1.next(); !typeImplementors_1_1.done; typeImplementors_1_1 = typeImplementors_1.next()) {
var implementor = typeImplementors_1_1.value;
if (!ctx.hasTypename.has(implementor.name)) {
var loc = (_d = (_c = implementor.astNode) === null || _c === void 0 ? void 0 : _c.name) === null || _d === void 0 ? void 0 : _d.loc;
if (loc == null) {
throw new Error("Grats expected the parsed type `".concat(implementor.name, "` to have location information. This is a bug in Grats. Please report it."));
}
typenameDiagnostics.push((0, DiagnosticError_1.diagnosticAtGraphQLLocation)("Missing __typename on `".concat(implementor.name, "`. The type `").concat(type.name, "` is used in a union or interface, so it must have a `__typename` field."), loc));
}
for (var _h = (e_4 = void 0, __values(snapshot.definitions)), _j = _h.next(); !_j.done; _j = _h.next()) {
var definition = _j.value;
result.definitions.push(definition);
}

@@ -206,6 +209,71 @@ }

try {
if (typeImplementors_1_1 && !typeImplementors_1_1.done && (_b = typeImplementors_1["return"])) _b.call(typeImplementors_1);
if (_j && !_j.done && (_b = _h.return)) _b.call(_h);
}
finally { if (e_4) throw e_4.error; }
}
try {
for (var _k = (e_5 = void 0, __values(snapshot.nameDefinitions)), _l = _k.next(); !_l.done; _l = _k.next()) {
var _m = __read(_l.value, 2), node = _m[0], definition = _m[1];
result.nameDefinitions.set(node, definition);
}
}
catch (e_5_1) { e_5 = { error: e_5_1 }; }
finally {
try {
if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
}
finally { if (e_5) throw e_5.error; }
}
try {
for (var _o = (e_6 = void 0, __values(snapshot.unresolvedNames)), _p = _o.next(); !_p.done; _p = _o.next()) {
var _q = __read(_p.value, 2), node = _q[0], typeName = _q[1];
result.unresolvedNames.set(node, typeName);
}
}
catch (e_6_1) { e_6 = { error: e_6_1 }; }
finally {
try {
if (_p && !_p.done && (_d = _o.return)) _d.call(_o);
}
finally { if (e_6) throw e_6.error; }
}
try {
for (var _r = (e_7 = void 0, __values(snapshot.contextReferences)), _s = _r.next(); !_s.done; _s = _r.next()) {
var contextReference = _s.value;
result.contextReferences.push(contextReference);
}
}
catch (e_7_1) { e_7 = { error: e_7_1 }; }
finally {
try {
if (_s && !_s.done && (_e = _r.return)) _e.call(_r);
}
finally { if (e_7) throw e_7.error; }
}
try {
for (var _t = (e_8 = void 0, __values(snapshot.typesWithTypenameField)), _u = _t.next(); !_u.done; _u = _t.next()) {
var typeName = _u.value;
result.typesWithTypenameField.add(typeName);
}
}
catch (e_8_1) { e_8 = { error: e_8_1 }; }
finally {
try {
if (_u && !_u.done && (_f = _t.return)) _f.call(_t);
}
finally { if (e_8) throw e_8.error; }
}
try {
for (var _v = (e_9 = void 0, __values(snapshot.interfaceDeclarations)), _w = _v.next(); !_w.done; _w = _v.next()) {
var interfaceDeclaration = _w.value;
result.interfaceDeclarations.push(interfaceDeclaration);
}
}
catch (e_9_1) { e_9 = { error: e_9_1 }; }
finally {
try {
if (_w && !_w.done && (_g = _v.return)) _g.call(_v);
}
finally { if (e_9) throw e_9.error; }
}
}

@@ -216,7 +284,7 @@ }

try {
if (abstractTypes_1_1 && !abstractTypes_1_1.done && (_a = abstractTypes_1["return"])) _a.call(abstractTypes_1);
if (snapshots_1_1 && !snapshots_1_1.done && (_a = snapshots_1.return)) _a.call(snapshots_1);
}
finally { if (e_3) throw e_3.error; }
}
return typenameDiagnostics;
return result;
}
"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.locate = void 0;

@@ -4,0 +4,0 @@ var graphql_1 = require("graphql");

@@ -60,7 +60,6 @@ "use strict";

};
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var TestRunner_1 = require("./TestRunner");
var lib_1 = require("../lib");
var utils_1 = require("@graphql-tools/utils");
var ts = require("typescript");

@@ -71,2 +70,7 @@ var graphql_1 = require("graphql");

var DiagnosticError_1 = require("../utils/DiagnosticError");
var fs_1 = require("fs");
var codegen_1 = require("../codegen");
var utils_1 = require("@graphql-tools/utils");
var jest_diff_1 = require("jest-diff");
var printSchema_1 = require("../printSchema");
var program = new commander_1.Command();

@@ -81,3 +85,3 @@ program

return __awaiter(void 0, void 0, void 0, function () {
var filterRegex, failures, testDirs_1, testDirs_1_1, _b, fixturesDir_1, transformer, runner, e_1_1;
var filterRegex, failures, testDirs_1, testDirs_1_1, _b, fixturesDir_1, transformer, testFilePattern, ignoreFilePattern, runner, e_1_1;
var e_1, _c;

@@ -96,4 +100,4 @@ return __generator(this, function (_d) {

if (!!testDirs_1_1.done) return [3 /*break*/, 5];
_b = testDirs_1_1.value, fixturesDir_1 = _b.fixturesDir, transformer = _b.transformer;
runner = new TestRunner_1["default"](fixturesDir_1, !!write, filterRegex, transformer);
_b = testDirs_1_1.value, fixturesDir_1 = _b.fixturesDir, transformer = _b.transformer, testFilePattern = _b.testFilePattern, ignoreFilePattern = _b.ignoreFilePattern;
runner = new TestRunner_1.default(fixturesDir_1, !!write, filterRegex, testFilePattern, ignoreFilePattern, transformer);
return [4 /*yield*/, runner.run()];

@@ -113,3 +117,3 @@ case 3:

try {
if (testDirs_1_1 && !testDirs_1_1.done && (_c = testDirs_1["return"])) _c.call(testDirs_1);
if (testDirs_1_1 && !testDirs_1_1.done && (_c = testDirs_1.return)) _c.call(testDirs_1);
}

@@ -127,2 +131,3 @@ finally { if (e_1) throw e_1.error; }

});
var gratsDir = path.join(__dirname, "../..");
var fixturesDir = path.join(__dirname, "fixtures");

@@ -133,6 +138,9 @@ var integrationFixturesDir = path.join(__dirname, "integrationFixtures");

fixturesDir: fixturesDir,
testFilePattern: /\.ts$/,
ignoreFilePattern: null,
transformer: function (code, fileName) {
var firstLine = code.split("\n")[0];
var options = {
nullableByDefault: true
nullableByDefault: true,
schemaHeader: null,
};

@@ -144,11 +152,14 @@ if (firstLine.startsWith("// {")) {

}
var files = ["".concat(fixturesDir, "/").concat(fileName), "src/Types.ts"];
var parsedOptions = {
var files = [
"".concat(fixturesDir, "/").concat(fileName),
path.join(__dirname, "../Types.ts"),
];
var parsedOptions = (0, lib_1.validateGratsOptions)({
options: {},
raw: {
grats: options
grats: options,
},
errors: [],
fileNames: files
};
fileNames: files,
});
// https://stackoverflow.com/a/66604532/1263117

@@ -162,2 +173,4 @@ var compilerHost = ts.createCompilerHost(parsedOptions.options,

}
// We run codegen here just ensure that it doesn't throw.
var executableSchema = (0, codegen_1.codegen)(schemaResult.value, "".concat(fixturesDir, "/").concat(fileName));
var LOCATION_REGEX = /^\/\/ Locate: (.*)/;

@@ -171,42 +184,41 @@ var locationMatch = code.match(LOCATION_REGEX);

return new DiagnosticError_1.ReportableDiagnostics(compilerHost, [
(0, DiagnosticError_1.diagnosticAtGraphQLLocation)("Located here", locResult.value),
(0, DiagnosticError_1.gqlErr)(locResult.value, "Located here"),
]).formatDiagnosticsWithContext();
}
else {
return (0, utils_1.printSchemaWithDirectives)(schemaResult.value, {
assumeValid: true
var sdl = (0, utils_1.printSchemaWithDirectives)(schemaResult.value, {
assumeValid: true,
});
return "-- SDL --\n".concat(sdl, "\n-- TypeScript --\n").concat(executableSchema);
}
}
},
},
{
fixturesDir: integrationFixturesDir,
testFilePattern: /index.ts$/,
ignoreFilePattern: /schema.ts$/,
transformer: function (code, fileName) { return __awaiter(void 0, void 0, void 0, function () {
var filePath, server, options, files, parsedOptions, schemaResult, schema, data;
var filePath, schemaPath, options, files, parsedOptions, schemaResult, tsSchema, server, schemaModule, schemaDiff, data;
return __generator(this, function (_a) {
var _b;
switch (_a.label) {
case 0:
filePath = "".concat(integrationFixturesDir, "/").concat(fileName);
return [4 /*yield*/, (_b = filePath, Promise.resolve().then(function () { return require(_b); }))];
case 1:
server = _a.sent();
if (server.query == null || typeof server.query !== "string") {
throw new Error("Expected `".concat(filePath, "` to export a query text as `query`"));
}
if (server.Query == null || typeof server.Query !== "function") {
throw new Error("Expected `".concat(filePath, "` to export a Query type as `Query`"));
}
schemaPath = path.join(path.dirname(filePath), "schema.ts");
options = {
nullableByDefault: true
nullableByDefault: true,
};
files = [filePath, "src/Types.ts"];
parsedOptions = {
options: {},
files = [filePath, path.join(__dirname, "../Types.ts")];
parsedOptions = (0, lib_1.validateGratsOptions)({
options: {
// Required to enable ts-node to locate function exports
rootDir: gratsDir,
outDir: "dist",
configFilePath: "tsconfig.json",
},
raw: {
grats: options
grats: options,
},
errors: [],
fileNames: files
};
fileNames: files,
});
schemaResult = (0, lib_1.buildSchemaResult)(parsedOptions);

@@ -216,9 +228,25 @@ if (schemaResult.kind === "ERROR") {

}
schema = schemaResult.value;
tsSchema = (0, codegen_1.codegen)(schemaResult.value, schemaPath);
(0, fs_1.writeFileSync)(schemaPath, tsSchema);
return [4 /*yield*/, Promise.resolve("".concat(filePath)).then(function (s) { return require(s); })];
case 1:
server = _a.sent();
if (server.query == null || typeof server.query !== "string") {
throw new Error("Expected `".concat(filePath, "` to export a query text as `query`"));
}
return [4 /*yield*/, Promise.resolve("".concat(schemaPath)).then(function (s) { return require(s); })];
case 2:
schemaModule = _a.sent();
schemaDiff = compareSchemas(schemaModule.schema, schemaResult.value);
if (schemaDiff) {
console.log(schemaDiff);
// TODO: Make this an actual test failure, not an error
throw new Error("The codegen schema does not match the SDL schema.");
}
return [4 /*yield*/, (0, graphql_1.graphql)({
schema: schema,
schema: schemaModule.schema,
source: server.query,
rootValue: new server.Query()
variableValues: server.variables,
})];
case 2:
case 3:
data = _a.sent();

@@ -228,5 +256,14 @@ return [2 /*return*/, JSON.stringify(data, null, 2)];

});
}); }
}); },
},
];
// Returns null if the schemas are equal, otherwise returns a string diff.
function compareSchemas(actual, expected) {
var actualSDL = (0, printSchema_1.printSDLWithoutDirectives)(actual);
var expectedSDL = (0, printSchema_1.printSDLWithoutDirectives)(expected);
if (actualSDL === expectedSDL) {
return null;
}
return (0, jest_diff_1.diff)(expectedSDL, actualSDL);
}
program.parse();

@@ -15,3 +15,3 @@ type Transformer = (code: string, filename: string) => Promise<string> | string;

_transformer: Transformer;
constructor(fixturesDir: string, write: boolean, filter: string | null, transformer: Transformer);
constructor(fixturesDir: string, write: boolean, filter: string | null, testFilePattern: RegExp, ignoreFilePattern: RegExp | null, transformer: Transformer);
run(): Promise<boolean>;

@@ -18,0 +18,0 @@ _testFixture(fixture: string): Promise<void>;

@@ -49,3 +49,3 @@ "use strict";

};
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");

@@ -60,3 +60,3 @@ var path = require("path");

var TestRunner = /** @class */ (function () {
function TestRunner(fixturesDir, write, filter, transformer) {
function TestRunner(fixturesDir, write, filter, testFilePattern, ignoreFilePattern, transformer) {
var e_1, _a;

@@ -74,3 +74,3 @@ this._testFixtures = [];

var fileName = _c.value;
if (fileName.endsWith(".ts")) {
if (testFilePattern.test(fileName)) {
this._testFixtures.push(fileName);

@@ -82,3 +82,3 @@ var filePath = path.join(fixturesDir, fileName);

}
else {
else if (!ignoreFilePattern || !ignoreFilePattern.test(fileName)) {
this._otherFiles.add(fileName);

@@ -91,3 +91,3 @@ }

try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}

@@ -125,3 +125,3 @@ finally { if (e_1) throw e_1.error; }

try {
if (_b && !_b.done && (_g = _a["return"])) _g.call(_a);
if (_b && !_b.done && (_g = _a.return)) _g.call(_a);
}

@@ -151,3 +151,3 @@ finally { if (e_2) throw e_2.error; }

try {
if (_d && !_d.done && (_h = _c["return"])) _h.call(_c);
if (_d && !_d.done && (_h = _c.return)) _h.call(_c);
}

@@ -168,3 +168,3 @@ finally { if (e_3) throw e_3.error; }

try {
if (_f && !_f.done && (_j = _e["return"])) _j.call(_e);
if (_f && !_f.done && (_j = _e.return)) _j.call(_e);
}

@@ -191,3 +191,3 @@ finally { if (e_4) throw e_4.error; }

if (this._otherFiles.has(expectedFileName)) {
this._otherFiles["delete"](expectedFileName);
this._otherFiles.delete(expectedFileName);
}

@@ -247,3 +247,3 @@ else {

}());
exports["default"] = TestRunner;
exports.default = TestRunner;
function readdirSyncRecursive(dir) {

@@ -266,3 +266,3 @@ var e_6, _a, e_7, _b;

try {
if (_f && !_f.done && (_b = _e["return"])) _b.call(_e);
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
}

@@ -280,3 +280,3 @@ finally { if (e_7) throw e_7.error; }

try {
if (_d && !_d.done && (_a = _c["return"])) _a.call(_c);
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
}

@@ -283,0 +283,0 @@ finally { if (e_6) throw e_6.error; }

@@ -1,17 +0,9 @@

import { DefinitionNode, DocumentNode, FieldDefinitionNode, Location, NameNode } from "graphql";
import { NameNode } from "graphql";
import * as ts from "typescript";
import { DiagnosticResult, DiagnosticsResult } from "./utils/DiagnosticError";
import { InterfaceMap } from "./InterfaceGraph";
export declare const UNRESOLVED_REFERENCE_NAME = "__UNRESOLVED_REFERENCE__";
type NameDefinition = {
export type NameDefinition = {
name: NameNode;
kind: "TYPE" | "INTERFACE" | "UNION" | "SCALAR" | "INPUT_OBJECT" | "ENUM";
};
export type GratsDefinitionNode = DefinitionNode | AbstractFieldDefinitionNode;
export type AbstractFieldDefinitionNode = {
readonly kind: "AbstractFieldDefinition";
readonly loc: Location;
readonly onType: NameNode;
readonly field: FieldDefinitionNode;
};
/**

@@ -32,21 +24,12 @@ * Used to track TypeScript references.

host: ts.CompilerHost;
_options: ts.ParsedCommandLine;
_symbolToName: Map<ts.Symbol, NameDefinition>;
_unresolvedTypes: Map<NameNode, ts.Symbol>;
hasTypename: Set<string>;
constructor(options: ts.ParsedCommandLine, checker: ts.TypeChecker, host: ts.CompilerHost);
constructor(checker: ts.TypeChecker, host: ts.CompilerHost);
recordTypeName(node: ts.Node, name: NameNode, kind: NameDefinition["kind"]): void;
recordHasTypenameField(name: string): void;
markUnresolvedType(node: ts.Node, name: NameNode): void;
findSymbolDeclaration(startSymbol: ts.Symbol): ts.Declaration | null;
resolveSymbol(startSymbol: ts.Symbol): ts.Symbol;
resolveTypes(doc: DocumentNode): DiagnosticsResult<DocumentNode>;
handleAbstractDefinitions(docs: GratsDefinitionNode[]): DiagnosticsResult<DefinitionNode[]>;
addAbstractFieldDefinition(doc: AbstractFieldDefinitionNode, interfaceGraph: InterfaceMap): DiagnosticsResult<DefinitionNode[]>;
resolveNamedType(unresolved: NameNode): DiagnosticResult<NameNode>;
err(loc: Location, message: string, relatedInformation?: ts.DiagnosticRelatedInformation[]): ts.Diagnostic;
relatedInformation(loc: Location, message: string): ts.DiagnosticRelatedInformation;
validateInterfaceImplementorsHaveTypenameField(): DiagnosticResult<null>;
getDestFilePath(sourceFile: ts.SourceFile): string;
unresolvedNameIsGraphQL(unresolved: NameNode): boolean;
getNameDefinition(nameNode: NameNode): DiagnosticsResult<NameDefinition>;
}
export {};

@@ -13,24 +13,7 @@ "use strict";

};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypeContext = exports.UNRESOLVED_REFERENCE_NAME = void 0;
var graphql_1 = require("graphql");
var ts = require("typescript");
var DiagnosticError_1 = require("./utils/DiagnosticError");
var gratsRoot_1 = require("./gratsRoot");
var serverDirectives_1 = require("./serverDirectives");
var Extractor_1 = require("./Extractor");
var E = require("./Errors");
var InterfaceGraph_1 = require("./InterfaceGraph");
var helpers_1 = require("./utils/helpers");
exports.UNRESOLVED_REFERENCE_NAME = "__UNRESOLVED_REFERENCE__";

@@ -50,10 +33,10 @@ /**

var TypeContext = /** @class */ (function () {
function TypeContext(options, checker, host) {
function TypeContext(checker, host) {
this._symbolToName = new Map();
this._unresolvedTypes = new Map();
this.hasTypename = new Set();
this._options = options;
this.checker = checker;
this.host = host;
}
// Record that a GraphQL construct of type `kind` with the name `name` is
// declared at `node`.
TypeContext.prototype.recordTypeName = function (node, name, kind) {

@@ -71,5 +54,3 @@ var symbol = this.checker.getSymbolAtLocation(node);

};
TypeContext.prototype.recordHasTypenameField = function (name) {
this.hasTypename.add(name);
};
// Record that a type reference `node`
TypeContext.prototype.markUnresolvedType = function (node, name) {

@@ -103,158 +84,2 @@ var symbol = this.checker.getSymbolAtLocation(node);

};
TypeContext.prototype.resolveTypes = function (doc) {
var _a;
var _this = this;
var errors = [];
var newDoc = (0, graphql_1.visit)(doc, (_a = {},
_a[graphql_1.Kind.NAME] = function (t) {
var namedTypeResult = _this.resolveNamedType(t);
if (namedTypeResult.kind === "ERROR") {
errors.push(namedTypeResult.err);
return t;
}
return namedTypeResult.value;
},
_a));
if (errors.length > 0) {
return (0, DiagnosticError_1.err)(errors);
}
return (0, DiagnosticError_1.ok)(newDoc);
};
TypeContext.prototype.handleAbstractDefinitions = function (docs) {
var e_1, _a;
var newDocs = [];
var errors = [];
var interfaceGraphResult = (0, InterfaceGraph_1.computeInterfaceMap)(this, docs);
if (interfaceGraphResult.kind === "ERROR") {
return interfaceGraphResult;
}
var interfaceGraph = interfaceGraphResult.value;
try {
for (var docs_1 = __values(docs), docs_1_1 = docs_1.next(); !docs_1_1.done; docs_1_1 = docs_1.next()) {
var doc = docs_1_1.value;
if (doc.kind === "AbstractFieldDefinition") {
var abstractDocResults = this.addAbstractFieldDefinition(doc, interfaceGraph);
if (abstractDocResults.kind === "ERROR") {
(0, helpers_1.extend)(errors, abstractDocResults.err);
}
else {
(0, helpers_1.extend)(newDocs, abstractDocResults.value);
}
}
else {
newDocs.push(doc);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (docs_1_1 && !docs_1_1.done && (_a = docs_1["return"])) _a.call(docs_1);
}
finally { if (e_1) throw e_1.error; }
}
if (errors.length > 0) {
return (0, DiagnosticError_1.err)(errors);
}
return (0, DiagnosticError_1.ok)(newDocs);
};
// A field definition may be on a concrete type, or on an interface. If it's on an interface,
// we need to add it to each concrete type that implements the interface.
TypeContext.prototype.addAbstractFieldDefinition = function (doc, interfaceGraph) {
var e_2, _a;
var _b;
var newDocs = [];
var typeNameResult = this.resolveNamedType(doc.onType);
if (typeNameResult.kind === "ERROR") {
return (0, DiagnosticError_1.err)([typeNameResult.err]);
}
var symbol = this._unresolvedTypes.get(doc.onType);
if (symbol == null) {
// This should have already been handled by resolveNamedType
throw new Error("Expected to find unresolved type.");
}
var nameDefinition = this._symbolToName.get(symbol);
if (nameDefinition == null) {
// This should have already been handled by resolveNamedType
throw new Error("Expected to find name definition.");
}
switch (nameDefinition.kind) {
case "TYPE":
// Extending a type, is just adding a field to it.
newDocs.push({
kind: graphql_1.Kind.OBJECT_TYPE_EXTENSION,
name: doc.onType,
fields: [doc.field],
loc: doc.loc
});
break;
case "INTERFACE": {
// Extending an interface is a bit more complicated. We need to add the field
// to the interface, and to each type that implements the interface.
// The interface field definition is not executable, so we don't
// need to annotate it with the details of the implementation.
var directives = (_b = doc.field.directives) === null || _b === void 0 ? void 0 : _b.filter(function (directive) {
return directive.name.value !== serverDirectives_1.EXPORTED_DIRECTIVE;
});
newDocs.push({
kind: graphql_1.Kind.INTERFACE_TYPE_EXTENSION,
name: doc.onType,
fields: [__assign(__assign({}, doc.field), { directives: directives })]
});
try {
for (var _c = __values(interfaceGraph.get(nameDefinition.name.value)), _d = _c.next(); !_d.done; _d = _c.next()) {
var implementor = _d.value;
var name = {
kind: graphql_1.Kind.NAME,
value: implementor.name,
loc: doc.loc
};
switch (implementor.kind) {
case "TYPE":
newDocs.push({
kind: graphql_1.Kind.OBJECT_TYPE_EXTENSION,
name: name,
fields: [doc.field],
loc: doc.loc
});
break;
case "INTERFACE":
newDocs.push({
kind: graphql_1.Kind.INTERFACE_TYPE_EXTENSION,
name: name,
fields: [__assign(__assign({}, doc.field), { directives: directives })],
loc: doc.loc
});
break;
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c["return"])) _a.call(_c);
}
finally { if (e_2) throw e_2.error; }
}
break;
}
default: {
// Extending any other type of definition is not supported.
var loc = doc.onType.loc;
if (loc == null) {
throw new Error("Expected onType to have a location.");
}
var relatedLoc = nameDefinition.name.loc;
if (relatedLoc == null) {
throw new Error("Expected nameDefinition to have a location.");
}
return (0, DiagnosticError_1.err)([
this.err(loc, E.invalidTypePassedToFieldFunction(), [
this.relatedInformation(relatedLoc, "This is the type that was passed to `@".concat(Extractor_1.FIELD_TAG, "`.")),
]),
]);
}
}
return (0, DiagnosticError_1.ok)(newDocs);
};
TypeContext.prototype.resolveNamedType = function (unresolved) {

@@ -274,35 +99,30 @@ var symbol = this._unresolvedTypes.get(unresolved);

}
return (0, DiagnosticError_1.err)(this.err(unresolved.loc, E.unresolvedTypeReference()));
return (0, DiagnosticError_1.err)((0, DiagnosticError_1.gqlErr)(unresolved.loc, E.unresolvedTypeReference()));
}
return (0, DiagnosticError_1.ok)(__assign(__assign({}, unresolved), { value: nameDefinition.name.value }));
};
TypeContext.prototype.err = function (loc, message, relatedInformation) {
return {
messageText: message,
start: loc.start,
length: loc.end - loc.start,
category: ts.DiagnosticCategory.Error,
code: DiagnosticError_1.FAKE_ERROR_CODE,
file: ts.createSourceFile(loc.source.name, loc.source.body, ts.ScriptTarget.Latest),
relatedInformation: relatedInformation
};
TypeContext.prototype.unresolvedNameIsGraphQL = function (unresolved) {
var symbol = this._unresolvedTypes.get(unresolved);
return symbol != null && this._symbolToName.has(symbol);
};
TypeContext.prototype.relatedInformation = function (loc, message) {
return {
category: ts.DiagnosticCategory.Message,
code: DiagnosticError_1.FAKE_ERROR_CODE,
messageText: message,
file: ts.createSourceFile(loc.source.name, loc.source.body, ts.ScriptTarget.Latest),
start: loc.start,
length: loc.end - loc.start
};
// TODO: Merge this with resolveNamedType
TypeContext.prototype.getNameDefinition = function (nameNode) {
var typeNameResult = this.resolveNamedType(nameNode);
if (typeNameResult.kind === "ERROR") {
return (0, DiagnosticError_1.err)([typeNameResult.err]);
}
var symbol = this._unresolvedTypes.get(nameNode);
if (symbol == null) {
// This should have already been handled by resolveNamedType
throw new Error("Expected to find unresolved type.");
}
var nameDefinition = this._symbolToName.get(symbol);
if (nameDefinition == null) {
// This should have already been handled by resolveNamedType
throw new Error("Expected to find name definition.");
}
return (0, DiagnosticError_1.ok)(nameDefinition);
};
TypeContext.prototype.validateInterfaceImplementorsHaveTypenameField = function () {
return (0, DiagnosticError_1.ok)(null);
};
TypeContext.prototype.getDestFilePath = function (sourceFile) {
return (0, gratsRoot_1.getRelativeOutputPath)(this._options, sourceFile);
};
return TypeContext;
}());
exports.TypeContext = TypeContext;
"use strict";
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });

@@ -16,6 +16,9 @@ import { GraphQLError, Location, Source } from "graphql";

export declare function err<E>(err: E): Err<E>;
export declare function collectResults<T>(results: DiagnosticsResult<T>[]): DiagnosticsResult<T[]>;
export declare function combineResults<T, U>(result1: DiagnosticsResult<T>, result2: DiagnosticsResult<U>): DiagnosticsResult<[T, U]>;
export declare class ReportableDiagnostics {
_host: ts.CompilerHost;
_host: ts.FormatDiagnosticsHost;
_diagnostics: ts.Diagnostic[];
constructor(host: ts.CompilerHost, diagnostics: ts.Diagnostic[]);
constructor(host: ts.FormatDiagnosticsHost, diagnostics: ts.Diagnostic[]);
static fromDiagnostics(diagnostics: ts.Diagnostic[]): ReportableDiagnostics;
formatDiagnosticsWithColorAndContext(): string;

@@ -26,4 +29,7 @@ formatDiagnosticsWithContext(): string;

export declare function graphQlErrorToDiagnostic(error: GraphQLError): ts.Diagnostic;
export declare function diagnosticAtGraphQLLocation(message: string, loc: Location): ts.Diagnostic;
export declare function gqlErr(loc: Location, message: string, relatedInformation?: ts.DiagnosticRelatedInformation[]): ts.Diagnostic;
export declare function gqlRelated(loc: Location, message: string): ts.DiagnosticRelatedInformation;
export declare function tsErr(node: ts.Node, message: string, relatedInformation?: ts.DiagnosticRelatedInformation[]): ts.Diagnostic;
export declare function tsRelated(node: ts.Node, message: string): ts.DiagnosticRelatedInformation;
export declare function graphqlSourceToSourceFile(source: Source): ts.SourceFile;
export {};
"use strict";
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __read = (this && this.__read) || function (o, n) {

@@ -18,15 +29,13 @@ var m = typeof Symbol === "function" && o[Symbol.iterator];

};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
return to.concat(ar || Array.prototype.slice.call(from));
};
exports.__esModule = true;
exports.graphqlSourceToSourceFile = exports.diagnosticAtGraphQLLocation = exports.graphQlErrorToDiagnostic = exports.FAKE_ERROR_CODE = exports.ReportableDiagnostics = exports.err = exports.ok = void 0;
Object.defineProperty(exports, "__esModule", { value: true });
exports.graphqlSourceToSourceFile = exports.tsRelated = exports.tsErr = exports.gqlRelated = exports.gqlErr = exports.graphQlErrorToDiagnostic = exports.FAKE_ERROR_CODE = exports.ReportableDiagnostics = exports.combineResults = exports.collectResults = exports.err = exports.ok = void 0;
var ts = require("typescript");

@@ -41,2 +50,43 @@ function ok(value) {

exports.err = err;
function collectResults(results) {
var e_1, _a;
var errors = [];
var values = [];
try {
for (var results_1 = __values(results), results_1_1 = results_1.next(); !results_1_1.done; results_1_1 = results_1.next()) {
var result = results_1_1.value;
if (result.kind === "ERROR") {
errors.push.apply(errors, __spreadArray([], __read(result.err), false));
}
else {
values.push(result.value);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (results_1_1 && !results_1_1.done && (_a = results_1.return)) _a.call(results_1);
}
finally { if (e_1) throw e_1.error; }
}
if (errors.length > 0) {
return err(errors);
}
return ok(values);
}
exports.collectResults = collectResults;
function combineResults(result1, result2) {
if (result1.kind === "ERROR" && result2.kind === "ERROR") {
return err(__spreadArray(__spreadArray([], __read(result1.err), false), __read(result2.err), false));
}
if (result1.kind === "ERROR") {
return result1;
}
if (result2.kind === "ERROR") {
return result2;
}
return ok([result1.value, result2.value]);
}
exports.combineResults = combineResults;
var ReportableDiagnostics = /** @class */ (function () {

@@ -47,2 +97,12 @@ function ReportableDiagnostics(host, diagnostics) {

}
// If you don't have a host, for example if you error while parsing the
// tsconfig, you can use this method and one will be created for you.
ReportableDiagnostics.fromDiagnostics = function (diagnostics) {
var formatHost = {
getCanonicalFileName: function (path) { return path; },
getCurrentDirectory: ts.sys.getCurrentDirectory,
getNewLine: function () { return ts.sys.newLine; },
};
return new ReportableDiagnostics(formatHost, diagnostics);
};
ReportableDiagnostics.prototype.formatDiagnosticsWithColorAndContext = function () {

@@ -61,3 +121,3 @@ var formatted = ts.formatDiagnosticsWithColorAndContext(this._diagnostics, this._host);

exports.ReportableDiagnostics = ReportableDiagnostics;
// A madeup error code that we use to fake a TypeScript error code.
// A made-up error code that we use to fake a TypeScript error code.
// We pick a very random number to avoid collisions with real error messages.

@@ -73,3 +133,3 @@ exports.FAKE_ERROR_CODE = 349389149282;

function graphQlErrorToDiagnostic(error) {
var e_1, _a;
var e_2, _a;
var position = error.positions[0];

@@ -79,3 +139,3 @@ if (position == null) {

}
// Start with baseline location infromation
// Start with baseline location information
var start = position;

@@ -99,18 +159,11 @@ var length = 1;

}
relatedInformation.push({
category: ts.DiagnosticCategory.Message,
code: exports.FAKE_ERROR_CODE,
messageText: "Related location",
file: graphqlSourceToSourceFile(relatedNode.loc.source),
start: relatedNode.loc.start,
length: relatedNode.loc.end - relatedNode.loc.start
});
relatedInformation.push(gqlRelated(relatedNode.loc, "Related location"));
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (rest_1_1 && !rest_1_1.done && (_a = rest_1["return"])) _a.call(rest_1);
if (rest_1_1 && !rest_1_1.done && (_a = rest_1.return)) _a.call(rest_1);
}
finally { if (e_1) throw e_1.error; }
finally { if (e_2) throw e_2.error; }
}

@@ -131,7 +184,7 @@ }

length: length,
relatedInformation: relatedInformation
relatedInformation: relatedInformation,
};
}
exports.graphQlErrorToDiagnostic = graphQlErrorToDiagnostic;
function diagnosticAtGraphQLLocation(message, loc) {
function gqlErr(loc, message, relatedInformation) {
return {

@@ -143,6 +196,44 @@ messageText: message,

start: loc.start,
length: loc.end - loc.start
length: loc.end - loc.start,
relatedInformation: relatedInformation,
};
}
exports.diagnosticAtGraphQLLocation = diagnosticAtGraphQLLocation;
exports.gqlErr = gqlErr;
function gqlRelated(loc, message) {
return {
category: ts.DiagnosticCategory.Message,
code: exports.FAKE_ERROR_CODE,
messageText: message,
file: graphqlSourceToSourceFile(loc.source),
start: loc.start,
length: loc.end - loc.start,
};
}
exports.gqlRelated = gqlRelated;
function tsErr(node, message, relatedInformation) {
var start = node.getStart();
var length = node.getEnd() - start;
var sourceFile = node.getSourceFile();
return {
messageText: message,
file: sourceFile,
code: exports.FAKE_ERROR_CODE,
category: ts.DiagnosticCategory.Error,
start: start,
length: length,
relatedInformation: relatedInformation,
};
}
exports.tsErr = tsErr;
function tsRelated(node, message) {
return {
category: ts.DiagnosticCategory.Message,
code: 0,
file: node.getSourceFile(),
start: node.getStart(),
length: node.getWidth(),
messageText: message,
};
}
exports.tsRelated = tsRelated;
function graphqlSourceToSourceFile(source) {

@@ -149,0 +240,0 @@ return ts.createSourceFile(source.name, source.body, ts.ScriptTarget.Latest);

@@ -7,2 +7,2 @@ export declare class DefaultMap<K, V> {

}
export declare function extend<T>(a: T[], b: T[]): void;
export declare function extend<T>(a: T[], b: readonly T[]): void;

@@ -13,3 +13,3 @@ "use strict";

};
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.extend = exports.DefaultMap = void 0;

@@ -43,3 +43,3 @@ var DefaultMap = /** @class */ (function () {

try {
if (b_1_1 && !b_1_1.done && (_a = b_1["return"])) _a.call(b_1);
if (b_1_1 && !b_1_1.done && (_a = b_1.return)) _a.call(b_1);
}

@@ -46,0 +46,0 @@ finally { if (e_1) throw e_1.error; }

@@ -13,3 +13,3 @@ "use strict";

};
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", { value: true });
exports.traverseJSDocTags = void 0;

@@ -42,3 +42,3 @@ var ts = require("typescript");

try {
if (_c && !_c.done && (_a = _b["return"])) _a.call(_b);
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}

@@ -45,0 +45,0 @@ finally { if (e_1) throw e_1.error; }

{
"name": "grats",
"version": "0.0.0-main-d4ce69ef",
"version": "0.0.0-main-d4d43d4b",
"main": "dist/src/index.js",

@@ -12,8 +12,8 @@ "bin": "dist/src/cli.js",

"dependencies": {
"@graphql-tools/utils": "^9.2.1",
"commander": "^10.0.0",
"graphql": "^16.6.0",
"typescript": "^4.9.5"
"typescript": "^5.0.2"
},
"devDependencies": {
"@graphql-tools/utils": "^9.2.1",
"@types/node": "^18.14.6",

@@ -26,2 +26,3 @@ "@typescript-eslint/eslint-plugin": "^5.55.0",

"path-browserify": "^1.0.1",
"prettier": "^2.8.7",
"process": "^0.11.10",

@@ -33,3 +34,3 @@ "ts-node": "^10.9.1"

},
"packageManager": "pnpm@8.1.1",
"packageManager": "pnpm@8.12.0",
"engines": {

@@ -43,4 +44,5 @@ "node": ">=16 <=21",

"build": "tsc --build",
"lint": "eslint src/**/*.ts"
"format": "prettier . --write",
"lint": "eslint src/**/*.ts && prettier . --check"
}
}

@@ -1,5 +0,1 @@

# -=[ ALPHA SOFTWARE ]=-
**Grats is still experimental. Feel free to try it out and give feedback, but they api is still in flux**
# Grats: Implementation-First GraphQL for TypeScript

@@ -9,2 +5,4 @@

_Beta Software: Grats is largely stable and being used in production in multiple places. If you encounter any issues, dont hesitate to let us know._
**What if building a GraphQL server were as simple as just writing functions?**

@@ -18,7 +16,33 @@

By making your TypeScript implementation the source of truth, you never have to
worry about valuating that your implementation matches your schema. Your
worry about validating that your implementation matches your schema. Your
implementation _is_ your schema!
## Read the docs: https://grats.capt.dev/
## Example
Here's what it looks like to define a User type with a greeting field using Grats:
```ts
/** @gqlType */
class User {
/** @gqlField */
name: string;
/** @gqlField */
greet(args: { greeting: string }): string {
return `${args.greeting}, ${this.name}`;
}
}
```
After running `npx grats`, you'll find a `schema.ts` module that exports an executable schema, and a `schema.graphql` file contins your GraphQL schema definition:
```graphql
type User {
name: String
greet(greeting: String!): String
}
```
That's just the begining! To learn more, **Read the docs: https://grats.capt.dev/**
## Contributing

@@ -25,0 +49,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc