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-accb89e4 to 0.0.0-main-afbec52b

dist/src/metadataDirectives.d.ts

10

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

@@ -16,6 +16,5 @@ "bin": "dist/src/cli.js",

"format": "prettier . --write",
"lint": "eslint src/**/*.ts && prettier . --check"
"lint": "eslint . && prettier . --check"
},
"dependencies": {
"@graphql-tools/utils": "^9.2.1",
"commander": "^10.0.0",

@@ -26,3 +25,5 @@ "graphql": "^16.6.0",

"devDependencies": {
"@graphql-tools/utils": "^9.2.1",
"@types/node": "^18.14.6",
"@types/semver": "^7.5.6",
"@typescript-eslint/eslint-plugin": "^5.55.0",

@@ -36,2 +37,3 @@ "@typescript-eslint/parser": "^5.55.0",

"process": "^0.11.10",
"semver": "^7.5.4",
"ts-node": "^10.9.1"

@@ -42,3 +44,3 @@ },

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

@@ -45,0 +47,0 @@ "node": ">=16 <=21",

98

dist/src/cli.js

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

exports.formatLoc = void 0;
var graphql_1 = require("graphql");
var _1 = require("./");

@@ -52,2 +51,3 @@ var lib_1 = require("./lib");

var ts = require("typescript");
var DiagnosticError_1 = require("./utils/DiagnosticError");
var program = new commander_1.Command();

@@ -59,7 +59,13 @@ program

.option("--tsconfig <TSCONFIG>", "Path to tsconfig.json. Defaults to auto-detecting based on the current working directory")
.option("--watch", "Watch for changes and rebuild schema files as needed")
.action(function (_a) {
var tsconfig = _a.tsconfig;
var tsconfig = _a.tsconfig, watch = _a.watch;
return __awaiter(void 0, void 0, void 0, function () {
return __generator(this, function (_b) {
build(tsconfig);
if (watch) {
startWatchMode(tsconfig);
}
else {
runBuild(tsconfig);
}
return [2 /*return*/];

@@ -75,9 +81,9 @@ });

var tsconfig = _a.tsconfig;
var optionsResult = (0, _1.getParsedTsConfig)(tsconfig);
if (optionsResult.kind === "ERROR") {
throw new Error("TODO");
var config = getTsConfigOrReportAndExit(tsconfig).config;
var schemaResult = (0, lib_1.buildSchemaResult)(config);
if (schemaResult.kind === "ERROR") {
console.error(schemaResult.err.formatDiagnosticsWithColorAndContext());
process.exit(1);
}
var options = optionsResult.value;
var schema = buildSchema(options);
var loc = (0, Locate_1.locate)(schema, entity);
var loc = (0, Locate_1.locate)(schemaResult.value, entity);
if (loc.kind === "ERROR") {

@@ -90,32 +96,64 @@ console.error(loc.err);

program.parse();
function build(tsconfig) {
var configFile = tsconfig || ts.findConfigFile(process.cwd(), ts.sys.fileExists);
if (configFile == null) {
throw new Error("Grats: Could not find tsconfig.json");
}
var optionsResult = (0, _1.getParsedTsConfig)(configFile);
if (optionsResult.kind === "ERROR") {
console.error(optionsResult.err.formatDiagnosticsWithColorAndContext());
/**
* Run the compiler in watch mode.
*/
function startWatchMode(tsconfig) {
var _a = getTsConfigOrReportAndExit(tsconfig), config = _a.config, configPath = _a.configPath;
var watchHost = ts.createWatchCompilerHost(configPath, {}, ts.sys, ts.createSemanticDiagnosticsBuilderProgram, function (diagnostic) { return reportDiagnostics([diagnostic]); }, function (diagnostic) { return reportDiagnostics([diagnostic]); });
watchHost.afterProgramCreate = function (program) {
// For now we just rebuild the schema on every change.
var schemaResult = (0, lib_1.extractSchema)(config, program.getProgram());
if (schemaResult.kind === "ERROR") {
reportDiagnostics(schemaResult.err);
return;
}
writeSchemaFilesAndReport(schemaResult.value, config, configPath);
};
ts.createWatchProgram(watchHost);
}
/**
* Run the compiler performing a single build.
*/
function runBuild(tsconfig) {
var _a = getTsConfigOrReportAndExit(tsconfig), config = _a.config, configPath = _a.configPath;
var schemaResult = (0, lib_1.buildSchemaResult)(config);
if (schemaResult.kind === "ERROR") {
console.error(schemaResult.err.formatDiagnosticsWithColorAndContext());
process.exit(1);
}
var options = optionsResult.value;
var config = options.raw.grats;
var schema = buildSchema(options);
var dest = (0, path_1.resolve)((0, path_1.dirname)(configFile), config.tsSchema);
var code = (0, printSchema_1.printExecutableSchema)(schema, config, dest);
writeSchemaFilesAndReport(schemaResult.value, config, configPath);
}
/**
* Serializes the SDL and TypeScript schema to disk and reports to the console.
*/
function writeSchemaFilesAndReport(schema, config, configPath) {
var gratsOptions = config.raw.grats;
var dest = (0, path_1.resolve)((0, path_1.dirname)(configPath), gratsOptions.tsSchema);
var code = (0, printSchema_1.printExecutableSchema)(schema, gratsOptions, dest);
(0, fs_1.writeFileSync)(dest, code);
console.error("Grats: Wrote TypeScript schema to `".concat(dest, "`."));
var sortedSchema = (0, graphql_1.lexicographicSortSchema)(schema);
var schemaStr = (0, printSchema_1.printGratsSDL)(sortedSchema, config);
var absOutput = (0, path_1.resolve)((0, path_1.dirname)(configFile), config.graphqlSchema);
var schemaStr = (0, printSchema_1.printGratsSDL)(schema, 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, "`."));
}
function buildSchema(options) {
var schemaResult = (0, lib_1.buildSchemaResult)(options);
if (schemaResult.kind === "ERROR") {
console.error(schemaResult.err.formatDiagnosticsWithColorAndContext());
/**
* Utility function to report diagnostics to the console.
*/
function reportDiagnostics(diagnostics) {
var reportable = DiagnosticError_1.ReportableDiagnostics.fromDiagnostics(diagnostics);
console.error(reportable.formatDiagnosticsWithColorAndContext());
}
// Locate and read the tsconfig.json file
function getTsConfigOrReportAndExit(tsconfig) {
var configPath = tsconfig || ts.findConfigFile(process.cwd(), ts.sys.fileExists);
if (configPath == null) {
throw new Error("Grats: Could not find tsconfig.json");
}
var optionsResult = (0, _1.getParsedTsConfig)(configPath);
if (optionsResult.kind === "ERROR") {
console.error(optionsResult.err.formatDiagnosticsWithColorAndContext());
process.exit(1);
}
return schemaResult.value;
return { configPath: configPath, config: optionsResult.value };
}

@@ -122,0 +160,0 @@ // Format a location for printing to the console. Tools like VS Code and iTerm

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

var path = require("path");
var serverDirectives_1 = require("./serverDirectives");
var metadataDirectives_1 = require("./metadataDirectives");
var gratsRoot_1 = require("./gratsRoot");

@@ -40,4 +40,3 @@ var F = ts.factory;

var codegen = new Codegen(schema, destination);
codegen.schemaDeclaration();
codegen.schemaExport();
codegen.schemaDeclarationExport();
return codegen.print();

@@ -55,2 +54,10 @@ }

}
Codegen.prototype.createBlockWithScope = function (closure) {
var initialStatements = this._statements;
this._statements = [];
closure();
var block = F.createBlock(this._statements, true);
this._statements = initialStatements;
return block;
};
Codegen.prototype.graphQLImport = function (name) {

@@ -60,10 +67,11 @@ this._graphQLImports.add(name);

};
Codegen.prototype.schemaDeclaration = function () {
this.constDeclaration("schema", F.createNewExpression(this.graphQLImport("GraphQLSchema"), [], [this.schemaConfig()]));
Codegen.prototype.graphQLTypeImport = function (name) {
this._graphQLImports.add(name);
return F.createTypeReferenceNode(name);
};
Codegen.prototype.schemaExport = function () {
this._statements.push(F.createExportDeclaration(undefined, // [F.createModifier(ts.SyntaxKind.DefaultKeyword)],
false, F.createNamedExports([
F.createExportSpecifier(false, undefined, F.createIdentifier("schema")),
])));
Codegen.prototype.schemaDeclarationExport = function () {
var _this = this;
this.functionDeclaration("getSchema", [F.createModifier(ts.SyntaxKind.ExportKeyword)], this.graphQLTypeImport("GraphQLSchema"), this.createBlockWithScope(function () {
_this._statements.push(F.createReturnStatement(F.createNewExpression(_this.graphQLImport("GraphQLSchema"), [], [_this.schemaConfig()])));
}));
};

@@ -146,7 +154,8 @@ Codegen.prototype.schemaConfig = function () {

var args = ["source", "args", "context", "info"];
var exported = fieldDirective(field, serverDirectives_1.EXPORTED_DIRECTIVE);
var exported = fieldDirective(field, metadataDirectives_1.EXPORTED_DIRECTIVE);
if (exported != null) {
var module_1 = assertDirectiveStringArg(exported, serverDirectives_1.TS_MODULE_PATH_ARG);
var funcName = assertDirectiveStringArg(exported, serverDirectives_1.EXPORTED_FUNCTION_NAME_ARG);
var argCount = assertDirectiveIntArg(exported, serverDirectives_1.ARG_COUNT);
var exportedMetadata = (0, metadataDirectives_1.parseExportedDirective)(exported);
var module_1 = exportedMetadata.tsModulePath;
var funcName = exportedMetadata.exportedFunctionName;
var argCount = exportedMetadata.argCount;
var abs = (0, gratsRoot_1.resolveRelativePath)(module_1);

@@ -165,5 +174,5 @@ var relative = stripExt(path.relative(path.dirname(this._destination), abs));

}
var propertyName = fieldDirective(field, serverDirectives_1.METHOD_NAME_DIRECTIVE);
var propertyName = fieldDirective(field, metadataDirectives_1.FIELD_NAME_DIRECTIVE);
if (propertyName != null) {
var name = assertDirectiveStringArg(propertyName, serverDirectives_1.METHOD_NAME_ARG);
var name = (0, metadataDirectives_1.parsePropertyNameDirective)(propertyName).name;
var prop = F.createPropertyAccessExpression(F.createIdentifier("source"), F.createIdentifier(name));

@@ -301,3 +310,3 @@ var callExpression = F.createCallExpression(prop, undefined, args.map(function (name) {

Codegen.prototype.fieldMethods = function (field, parentTypeName) {
var asyncIterable = fieldDirective(field, serverDirectives_1.ASYNC_ITERABLE_TYPE_DIRECTIVE);
var asyncIterable = fieldDirective(field, metadataDirectives_1.ASYNC_ITERABLE_TYPE_DIRECTIVE);
if (asyncIterable == null) {

@@ -441,2 +450,5 @@ return [this.resolveMethod(field, "resolve", parentTypeName)];

};
Codegen.prototype.functionDeclaration = function (name, modifiers, type, body) {
this._statements.push(F.createFunctionDeclaration(modifiers, undefined, name, undefined, [], type, body));
};
// Helper to allow for nullable elements.

@@ -477,18 +489,2 @@ Codegen.prototype.objectLiteral = function (properties) {

}
function assertDirectiveStringArg(directive, name) {
var _a, _b;
var module = (_b = (_a = directive.arguments) === null || _a === void 0 ? void 0 : _a.find(function (a) { return a.name.value === name; })) === null || _b === void 0 ? void 0 : _b.value;
if ((module === null || module === void 0 ? void 0 : module.kind) !== graphql_1.Kind.STRING) {
throw new Error("Expected string argument");
}
return module.value;
}
function assertDirectiveIntArg(directive, name) {
var _a, _b;
var module = (_b = (_a = directive.arguments) === null || _a === void 0 ? void 0 : _a.find(function (a) { return a.name.value === name; })) === null || _b === void 0 ? void 0 : _b.value;
if ((module === null || module === void 0 ? void 0 : module.kind) !== graphql_1.Kind.INT) {
throw new Error("Expected int argument");
}
return Number(module.value);
}
function stripExt(filePath) {

@@ -495,0 +491,0 @@ var ext = path.extname(filePath);

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

export declare const ISSUE_URL = "https://github.com/captbaritone/grats/issues";
/**

@@ -53,3 +54,3 @@ * Error messages for Grats

export declare function methodMissingType(): string;
export declare function promiseMissingTypeArg(): string;
export declare function wrapperMissingTypeArg(): string;
export declare function cannotResolveSymbolForDescription(): string;

@@ -66,8 +67,7 @@ export declare function propertyFieldMissingType(): string;

export declare function pluralTypeMissingParameter(): string;
export declare function expectedIdentifier(): string;
export declare function expectedNameIdentifier(): 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 implementsTagMissingValue(): string;
export declare function mergedInterfaces(): string;
export declare function implementsTagOnClass(): string;

@@ -74,0 +74,0 @@ export declare function implementsTagOnInterface(): string;

"use strict";
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;
exports.defaultArgElementIsNotAssignment = exports.defaultValueIsNotLiteral = exports.ambiguousNumberType = exports.expectedOneNonNullishType = exports.propertyFieldMissingType = exports.cannotResolveSymbolForDescription = exports.wrapperMissingTypeArg = 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 = exports.ISSUE_URL = 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.mergedInterfaces = exports.nonNullTypeCannotBeOptional = exports.killsParentOnExceptionOnNullable = exports.killsParentOnExceptionWithWrongConfig = exports.expectedNameIdentifier = exports.pluralTypeMissingParameter = exports.unknownGraphQLType = exports.unsupportedTypeLiteral = exports.defaultArgPropertyMissingInitializer = exports.defaultArgPropertyMissingName = void 0;
var Extractor_1 = require("./Extractor");
exports.ISSUE_URL = "https://github.com/captbaritone/grats/issues";
// TODO: Move these to short URLS that are easier to keep from breaking.

@@ -39,31 +40,31 @@ var DOC_URLS = {

function invalidTypeTagUsage() {
return "`@".concat(Extractor_1.TYPE_TAG, "` can only be used on class or interface declarations.");
return "`@".concat(Extractor_1.TYPE_TAG, "` can only be used on class, interface or type declarations. e.g. `class MyType {}`");
}
exports.invalidTypeTagUsage = invalidTypeTagUsage;
function invalidScalarTagUsage() {
return "`@".concat(Extractor_1.SCALAR_TAG, "` can only be used on type alias declarations.");
return "`@".concat(Extractor_1.SCALAR_TAG, "` can only be used on type alias declarations. e.g. `type MyScalar = string`");
}
exports.invalidScalarTagUsage = invalidScalarTagUsage;
function invalidInterfaceTagUsage() {
return "`@".concat(Extractor_1.INTERFACE_TAG, "` can only be used on interface declarations.");
return "`@".concat(Extractor_1.INTERFACE_TAG, "` can only be used on interface declarations. e.g. `interface MyInterface {}`");
}
exports.invalidInterfaceTagUsage = invalidInterfaceTagUsage;
function invalidEnumTagUsage() {
return "`@".concat(Extractor_1.ENUM_TAG, "` can only be used on enum declarations or TypeScript unions.");
return "`@".concat(Extractor_1.ENUM_TAG, "` can only be used on enum declarations or TypeScript unions. e.g. `enum MyEnum {}` or `type MyEnum = \"foo\" | \"bar\"`");
}
exports.invalidEnumTagUsage = invalidEnumTagUsage;
function invalidInputTagUsage() {
return "`@".concat(Extractor_1.INPUT_TAG, "` can only be used on type alias declarations.");
return "`@".concat(Extractor_1.INPUT_TAG, "` can only be used on type alias declarations. e.g. `type MyInput = { foo: string }`");
}
exports.invalidInputTagUsage = invalidInputTagUsage;
function invalidUnionTagUsage() {
return "`@".concat(Extractor_1.UNION_TAG, "` can only be used on type alias declarations.");
return "`@".concat(Extractor_1.UNION_TAG, "` can only be used on type alias declarations. e.g. `type MyUnion = TypeA | TypeB`");
}
exports.invalidUnionTagUsage = invalidUnionTagUsage;
function expectedUnionTypeNode() {
return "Expected a TypeScript union. `@".concat(Extractor_1.UNION_TAG, "` can only be used on TypeScript unions.");
return "Expected a TypeScript union. `@".concat(Extractor_1.UNION_TAG, "` can only be used on TypeScript unions. e.g. `type MyUnion = TypeA | TypeB`");
}
exports.expectedUnionTypeNode = expectedUnionTypeNode;
function expectedUnionTypeReference() {
return "Expected `@".concat(Extractor_1.UNION_TAG, "` union members to be type references.");
return "Expected `@".concat(Extractor_1.UNION_TAG, "` union members to be type references. Grats expects union members to be references to something annotated with `@gqlType`.");
}

@@ -76,43 +77,44 @@ exports.expectedUnionTypeReference = expectedUnionTypeReference;

function invalidReturnTypeForFunctionField() {
return "Expected GraphQL field to have an explicit return type.";
return 'Expected GraphQL field to have an explicit return type. This is needed to allow Grats to "see" the type of the field.';
}
exports.invalidReturnTypeForFunctionField = invalidReturnTypeForFunctionField;
function functionFieldNotTopLevel() {
return "Expected `@".concat(Extractor_1.FIELD_TAG, "` function to be a top-level declaration.");
return "Expected `@".concat(Extractor_1.FIELD_TAG, "` function to be a top-level declaration. Grats needs to import resolver functions into it's generated schema module, so the resolver function must be an exported.");
}
exports.functionFieldNotTopLevel = functionFieldNotTopLevel;
var FUNCTION_PARENT_TYPE_CONTEXT = "Grats treats the first argument as the parent object of the field. Therefore Grats needs to see the _type_ of the first argument in order to know to which type/interface this field should be added.";
function functionFieldParentTypeMissing() {
return "Expected first argument of a `@".concat(Extractor_1.FIELD_TAG, "` function to have an explicit type annotation.");
return "Expected first argument of a `@".concat(Extractor_1.FIELD_TAG, "` function to have an explicit type annotation. ").concat(FUNCTION_PARENT_TYPE_CONTEXT);
}
exports.functionFieldParentTypeMissing = functionFieldParentTypeMissing;
function functionFieldParentTypeNotValid() {
return "Expected first argument of a `@".concat(Extractor_1.FIELD_TAG, "` function to be typed as a `@").concat(Extractor_1.TYPE_TAG, "` type.");
return "Expected first argument of a `@".concat(Extractor_1.FIELD_TAG, "` function to be typed as a type reference. ").concat(FUNCTION_PARENT_TYPE_CONTEXT);
}
exports.functionFieldParentTypeNotValid = functionFieldParentTypeNotValid;
function functionFieldNotNamed() {
return "Expected `@".concat(Extractor_1.FIELD_TAG, "` function to be named.");
return "Expected `@".concat(Extractor_1.FIELD_TAG, "` function to be named. Grats uses the name of the function to derive the name of the GraphQL field. Additionally, Grats needs to import resolver functions into it's generated schema module, so the resolver function must be a named export.");
}
exports.functionFieldNotNamed = functionFieldNotNamed;
function functionFieldDefaultExport() {
return "Expected a `@".concat(Extractor_1.FIELD_TAG, "` function to be a named export, not a default export.");
return "Expected a `@".concat(Extractor_1.FIELD_TAG, "` function to be a named export, not a default export. Grats needs to import resolver functions into it's generated schema module, so the resolver function must be a named export.");
}
exports.functionFieldDefaultExport = functionFieldDefaultExport;
function functionFieldNotNamedExport() {
return "Expected a `@".concat(Extractor_1.FIELD_TAG, "` function to be a named export.");
return "Expected a `@".concat(Extractor_1.FIELD_TAG, "` function to be a named export. Grats needs to import resolver functions into it's generated schema module, so the resolver function must be a named export.");
}
exports.functionFieldNotNamedExport = functionFieldNotNamedExport;
function inputTypeNotLiteral() {
return "`@".concat(Extractor_1.INPUT_TAG, "` can only be used on type literals.");
return "`@".concat(Extractor_1.INPUT_TAG, "` can only be used on type literals. e.g. `type MyInput = { foo: string }`");
}
exports.inputTypeNotLiteral = inputTypeNotLiteral;
function inputTypeFieldNotProperty() {
return "`@".concat(Extractor_1.INPUT_TAG, "` types only support property signature members.");
return "`@".concat(Extractor_1.INPUT_TAG, "` types only support property signature members. e.g. `type MyInput = { foo: string }`");
}
exports.inputTypeFieldNotProperty = inputTypeFieldNotProperty;
function inputFieldUntyped() {
return "Input field must have a type annotation.";
return 'Input field must have an explicit type annotation. Grats uses the type annotation to determine the type of the field, so it must be explicit in order for Grats to "see" the type.';
}
exports.inputFieldUntyped = inputFieldUntyped;
function typeTagOnUnnamedClass() {
return "Unexpected `@".concat(Extractor_1.TYPE_TAG, "` annotation on unnamed class declaration.");
return "Unexpected `@".concat(Extractor_1.TYPE_TAG, "` annotation on unnamed class declaration. Grats uses the name of the class to derive the name of the GraphQL type. Consider naming the class.");
}

@@ -125,83 +127,84 @@ exports.typeTagOnUnnamedClass = typeTagOnUnnamedClass;

function typeNameNotDeclaration() {
return "Expected `__typename` to be a property declaration.";
return "Expected `__typename` to be a property declaration. For example: `__typename: \"MyType\"`.";
}
exports.typeNameNotDeclaration = typeNameNotDeclaration;
var TYPENAME_CONTEXT = "This lets Grats know that the GraphQL executor will be able to derive the type of the object at runtime.";
function typeNameMissingInitializer() {
return "Expected `__typename` property to have an initializer or a string literal type. For example: `__typename = \"MyType\"` or `__typename: \"MyType\";`.";
return "Expected `__typename` property to have an initializer or a string literal type. For example: `__typename = \"MyType\"` or `__typename: \"MyType\";`. ".concat(TYPENAME_CONTEXT);
}
exports.typeNameMissingInitializer = typeNameMissingInitializer;
function typeNameInitializeNotString() {
return "Expected `__typename` property initializer to be a string literal. For example: `__typename = \"MyType\"` or `__typename: \"MyType\";`.";
return "Expected `__typename` property initializer to be a string literal. For example: `__typename = \"MyType\"` or `__typename: \"MyType\";`. ".concat(TYPENAME_CONTEXT);
}
exports.typeNameInitializeNotString = typeNameInitializeNotString;
function typeNameInitializerWrong(expected, actual) {
return "Expected `__typename` property initializer to be `\"".concat(expected, "\"`, found `\"").concat(actual, "\"`.");
return "Expected `__typename` property initializer to be `\"".concat(expected, "\"`, found `\"").concat(actual, "\"`. ").concat(TYPENAME_CONTEXT);
}
exports.typeNameInitializerWrong = typeNameInitializerWrong;
function typeNameMissingTypeAnnotation(expected) {
return "Expected `__typename` property signature to specify the typename as a string literal string type. For example `__typename: \"".concat(expected, "\";`");
return "Expected `__typename` property signature to specify the typename as a string literal string type. For example `__typename: \"".concat(expected, "\";`. ").concat(TYPENAME_CONTEXT);
}
exports.typeNameMissingTypeAnnotation = typeNameMissingTypeAnnotation;
function typeNameTypeNotStringLiteral(expected) {
return "Expected `__typename` property signature to specify the typename as a string literal string type. For example `__typename: \"".concat(expected, "\";`");
return "Expected `__typename` property signature to specify the typename as a string literal string type. For example `__typename: \"".concat(expected, "\";`. ").concat(TYPENAME_CONTEXT);
}
exports.typeNameTypeNotStringLiteral = typeNameTypeNotStringLiteral;
function typeNameDoesNotMatchExpected(expected) {
return "Expected `__typename` property to be `\"".concat(expected, "\"`");
return "Expected `__typename` property to be `\"".concat(expected, "\"`. ").concat(TYPENAME_CONTEXT);
}
exports.typeNameDoesNotMatchExpected = typeNameDoesNotMatchExpected;
function argumentParamIsMissingType() {
return "Expected GraphQL field arguments to have a TypeScript type. If there are no arguments, you can use `args: unknown`.";
return "Expected GraphQL field arguments to have an explicit type annotation. If there are no arguments, you can use `args: unknown`. Grats needs to be able to see the type of the arguments to generate a GraphQL schema.";
}
exports.argumentParamIsMissingType = argumentParamIsMissingType;
function argumentParamIsNotObject() {
return "Expected GraphQL field arguments to be typed using a literal object: `{someField: string}`. If there are no arguments, you can use `args: unknown`.";
return "Expected GraphQL field arguments to be typed using an inline literal object: `{someField: string}`. If there are no arguments, you can use `args: unknown`. Grats needs to be able to see the type of the arguments to generate a GraphQL schema.";
}
exports.argumentParamIsNotObject = argumentParamIsNotObject;
function argIsNotProperty() {
return "Expected GraphQL field argument type to be a property signature.";
return "Expected GraphQL field argument type to be a property signature. For example: `{ someField: string }`. Grats needs to be able to see the type of the arguments to generate a GraphQL schema.";
}
exports.argIsNotProperty = argIsNotProperty;
function argNameNotLiteral() {
return "Expected GraphQL field argument names to be a literal.";
return "Expected GraphQL field argument names to be a literal. For example: `{ someField: string }`. Grats needs to be able to see the type of the arguments to generate a GraphQL schema.";
}
exports.argNameNotLiteral = argNameNotLiteral;
function argNotTyped() {
return "Expected GraphQL field argument to have a type.";
return "Expected GraphQL field argument to have an explicit type annotation. For example: `{ someField: string }`. Grats needs to be able to see the type of the arguments to generate a GraphQL schema.";
}
exports.argNotTyped = argNotTyped;
function enumTagOnInvalidNode() {
return "Expected `@".concat(Extractor_1.ENUM_TAG, "` to be a union type, or a string literal in the edge case of a single value enum.");
return "Expected `@".concat(Extractor_1.ENUM_TAG, "` to be a union type, or a string literal in the edge case of a single value enum. For example: `type MyEnum = \"foo\" | \"bar\"` or `type MyEnum = \"foo\"`.");
}
exports.enumTagOnInvalidNode = enumTagOnInvalidNode;
function enumVariantNotStringLiteral() {
return "Expected `@".concat(Extractor_1.ENUM_TAG, "` enum members to be string literal types. For example: `'foo'`.");
return "Expected `@".concat(Extractor_1.ENUM_TAG, "` enum members to be string literal types. For example: `'foo'`. Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema.");
}
exports.enumVariantNotStringLiteral = enumVariantNotStringLiteral;
function enumVariantMissingInitializer() {
return "Expected `@".concat(Extractor_1.ENUM_TAG, "` enum members to have string literal initializers. For example: `FOO = 'foo'`.");
return "Expected `@".concat(Extractor_1.ENUM_TAG, "` enum members to have string literal initializers. For example: `FOO = 'foo'`. In GraphQL enum values are strings, and Grats needs to be able to see the concrete value of the enum member to generate the GraphQL schema.");
}
exports.enumVariantMissingInitializer = enumVariantMissingInitializer;
function gqlEntityMissingName() {
return "Expected GraphQL entity to have a name.";
return "Expected GraphQL entity to have a name. Grats uses the name of the entity to derive the name of the GraphQL construct.";
}
exports.gqlEntityMissingName = gqlEntityMissingName;
function methodMissingType() {
return "Expected GraphQL field to have a type.";
return "Expected GraphQL field methods to have an explicitly defined return type. Grats needs to be able to see the type of the field to generate its type in the GraphQL schema.";
}
exports.methodMissingType = methodMissingType;
function promiseMissingTypeArg() {
return "Expected type reference to have type arguments.";
function wrapperMissingTypeArg() {
return "Expected wrapper type reference to have type arguments. Grats needs to be able to see the return type in order to generate a GraphQL schema.";
}
exports.promiseMissingTypeArg = promiseMissingTypeArg;
exports.wrapperMissingTypeArg = wrapperMissingTypeArg;
function cannotResolveSymbolForDescription() {
return "Expected TypeScript to be able to resolve this GraphQL entity to a symbol.";
return "Expected TypeScript to be able to resolve this GraphQL entity to a symbol. Is it possible that this type is not defined in this file? Grats needs to follow type references to their declaration in order to determine which GraphQL name is being referenced.";
}
exports.cannotResolveSymbolForDescription = cannotResolveSymbolForDescription;
function propertyFieldMissingType() {
return "Expected GraphQL field to have a type.";
return "Expected GraphQL field to have an explicitly defined type annotation. Grats needs to be able to see the type of the field to generate a field's type in the GraphQL schema.";
}
exports.propertyFieldMissingType = propertyFieldMissingType;
function expectedOneNonNullishType() {
return "Expected exactly one non-nullish type.";
return "Expected exactly one non-nullish type. GraphQL does not support fields returning an arbitrary union of types. Consider defining an explicit `@".concat(Extractor_1.UNION_TAG, "` union type and returning that.");
}

@@ -214,48 +217,48 @@ exports.expectedOneNonNullishType = expectedOneNonNullishType;

function defaultValueIsNotLiteral() {
return "Expected GraphQL field argument default values to be a literal.";
return 'Expected GraphQL field argument default values to be a literal. Grats interprets argument defaults as GraphQL default values, which must be literals. For example: `10` or `"foo"`.';
}
exports.defaultValueIsNotLiteral = defaultValueIsNotLiteral;
function defaultArgElementIsNotAssignment() {
return "Expected object literal property to be a property assignment.";
return "Expected property to be a default assignment. For example: `{ first = 10}`. Grats needs to extract a literal GraphQL value here, and that requires Grats being able to see the literal value in the source code.";
}
exports.defaultArgElementIsNotAssignment = defaultArgElementIsNotAssignment;
function defaultArgPropertyMissingName() {
return "Expected object literal property to have a name.";
return "Expected object literal property to have a name. Grats needs to extract a literal value here, and that requires Grats being able to see the literal value and its field name in the source code.";
}
exports.defaultArgPropertyMissingName = defaultArgPropertyMissingName;
function defaultArgPropertyMissingInitializer() {
return "Expected object literal property to have an initializer. For example: `{ offset = 10}`.";
return "Expected object literal property to have an initializer. For example: `{ offset = 10}`. Grats needs to extract a literal GraphQL value here, and that requires Grats being able to see the literal value in the source code.";
}
exports.defaultArgPropertyMissingInitializer = defaultArgPropertyMissingInitializer;
function unsupportedTypeLiteral() {
return "Unexpected type literal. You may want to define a named GraphQL type elsewhere and reference it here.";
return "Unexpected type literal. Grats expects types in GraphQL positions to be scalar types, or reference a named GraphQL type directly. You may want to define a named GraphQL type elsewhere and reference it here.";
}
exports.unsupportedTypeLiteral = unsupportedTypeLiteral;
function unknownGraphQLType() {
return "Unknown GraphQL type.";
return "Unknown GraphQL type. Grats doe not know how to map this type to a GraphQL type. You may want to define a named GraphQL type elsewhere and reference it here. If you think Grats should be able to infer a GraphQL type from this type, please file an issue.";
}
exports.unknownGraphQLType = unknownGraphQLType;
function pluralTypeMissingParameter() {
return "Expected type reference to have type arguments.";
return "Expected wrapper type reference to have type arguments. Grats needs to be able to see the return type in order to generate a GraphQL schema.";
}
exports.pluralTypeMissingParameter = pluralTypeMissingParameter;
function expectedIdentifier() {
return "Expected an identifier.";
function expectedNameIdentifier() {
return "Expected an name identifier. Grats expected to find a name here which it could use to derive the GraphQL name.";
}
exports.expectedIdentifier = expectedIdentifier;
exports.expectedNameIdentifier = expectedNameIdentifier;
function killsParentOnExceptionWithWrongConfig() {
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.");
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 option `nullableByDefault` is enabled in your `tsconfig.json`.");
}
exports.killsParentOnExceptionWithWrongConfig = killsParentOnExceptionWithWrongConfig;
function killsParentOnExceptionOnNullable() {
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.");
return "Unexpected `@".concat(Extractor_1.KILLS_PARENT_ON_EXCEPTION_TAG, "` tag on field typed as nullable. `@").concat(Extractor_1.KILLS_PARENT_ON_EXCEPTION_TAG, "` will force a field to appear as non-nullable in the schema, so it's implementation must also be non-nullable. .");
}
exports.killsParentOnExceptionOnNullable = killsParentOnExceptionOnNullable;
function nonNullTypeCannotBeOptional() {
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`.";
return "Unexpected optional argument that does not also accept `null`. Optional arguments in GraphQL may get passed an explicit `null` value by the GraphQL executor. This means optional arguments must be typed to also accept `null`. Consider adding `| null` to the end of the argument type.";
}
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.",

@@ -268,6 +271,2 @@ "To avoid ambiguity Grats does not support using merged interfaces as GraphQL interfaces.",

exports.mergedInterfaces = mergedInterfaces;
function implementsTagMissingValue() {
return "Expected `@".concat(Extractor_1.IMPLEMENTS_TAG_DEPRECATED, "` to be followed by one or more interface names.");
}
exports.implementsTagMissingValue = implementsTagMissingValue;
function implementsTagOnClass() {

@@ -308,3 +307,3 @@ return "`@".concat(Extractor_1.IMPLEMENTS_TAG_DEPRECATED, "` has been deprecated. Instead use `class MyType implements MyInterface`.");

function parameterPropertyMissingType() {
return "Expected `@".concat(Extractor_1.FIELD_TAG, "` parameter property to have a type annotation.");
return "Expected `@".concat(Extractor_1.FIELD_TAG, "` parameter property to have an explicit type annotation. Grats needs to be able to see the type of the parameter property to generate a GraphQL schema.");
}

@@ -317,11 +316,11 @@ exports.parameterPropertyMissingType = parameterPropertyMissingType;

function unresolvedTypeReference() {
return "This type is not a valid GraphQL type. Did you mean to annotate it's definition with a `/** @gql */` tag such as `/** @gqlType */` or `/** @gqlInput **/`?";
return "Unable to resolve type reference. In order to generate a GraphQL schema, Grats needs to determine which GraphQL type is being referenced. This requires being able to resolve type references to their `@gql` annotated declaration. However this reference could not be resolved. Is it possible that this type is not defined in this file?";
}
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.";
return "Expected context parameter to have an explicit type annotation. Grats validates that your context parameter is type-safe by checking that 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.";
return "Expected context parameter's type to be a type reference. Grats validates that your context parameter is type-safe by checking that all context values reference the same type declaration.";
}

@@ -332,3 +331,3 @@ exports.expectedTypeAnnotationOfReferenceOnContext = expectedTypeAnnotationOfReferenceOnContext;

// 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.";
return "Unable to resolve context parameter type. Grats validates that your context parameter is type-safe by checking that all context values reference the same type declaration.";
}

@@ -341,3 +340,3 @@ exports.expectedTypeAnnotationOnContextToBeResolvable = expectedTypeAnnotationOnContextToBeResolvable;

function unexpectedParamSpreadForContextParam() {
return "Unexpected spread parameter in context parameter position. Grats expects the context parameter to be a single, explicitly typed, argument.";
return "Unexpected spread parameter in context parameter position. Grats expects the context parameter to be a single, explicitly-typed argument.";
}

@@ -358,16 +357,16 @@ exports.unexpectedParamSpreadForContextParam = unexpectedParamSpreadForContextParam;

function subscriptionFieldNotAsyncIterable() {
return "Expected fields on `Subscription` to return an AsyncIterable.";
return "Expected fields on `Subscription` to return an `AsyncIterable`. Fields on `Subscription` model a subscription, which is a stream of events. Grats expects fields on `Subscription` to return an `AsyncIterable` which can be used to model this stream.";
}
exports.subscriptionFieldNotAsyncIterable = subscriptionFieldNotAsyncIterable;
function nonSubscriptionFieldAsyncIterable() {
return "Unexpected AsyncIterable. Only fields on `Subscription` should return an AsyncIterable.";
return "Unexpected AsyncIterable. Only fields on `Subscription` should return an `AsyncIterable`. Non-subscription fields are only expected to return a single value.";
}
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`.";
return "Operation types `Query`, `Mutation`, and `Subscription` must be defined as type aliases of `unknown`. E.g. `type Query = unknown`. This is because GraphQL servers do not have an agreed upon way to produce root values, and Grats errs on the side of safety. If you are trying to implement dependency injection, consider using the `context` argument passed to each resolver instead. If you have a strong use case for a concrete root value, please file an issue.";
}
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.";
return "Expected nullable argument to _also_ be optional (`?`). graphql-js may omit properties on the argument object where an undefined GraphQL variable is passed, or if the argument is omitted in the operation text. To ensure your resolver is capable of handing this scenario, add a `?` to the end of the argument name to make it optional. e.g. `{greeting?: string | null}`";
}
exports.expectedNullableArgumentToBeOptional = expectedNullableArgumentToBeOptional;

@@ -1,10 +0,8 @@

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 { ConfigOptions } from "./lib";
import { GraphQLConstructor } from "./GraphQLConstructor";
import { NameDefinition } from "./TypeContext";
import { GratsDefinitionNode } from "./GraphQLConstructor";
export declare const LIBRARY_IMPORT_NAME = "grats";
export declare const LIBRARY_NAME = "Grats";
export declare const ISSUE_URL = "https://github.com/captbaritone/grats/issues";
export declare const TYPE_TAG = "gqlType";

@@ -20,3 +18,10 @@ export declare const FIELD_TAG = "gqlField";

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 typesWithTypename: Set<string>;
readonly interfaceDeclarations: Array<ts.InterfaceDeclaration>;
};
/**

@@ -32,84 +37,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;
validateOperationTypes(node: ts.Node, name: string): void;
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;
collectObjectLiteral(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;
validateContextParameter(node: ts.ParameterDeclaration): null | undefined;
methodDeclaration(node: ts.MethodDeclaration | ts.MethodSignature): FieldDefinitionNode | null;
collectReturnType(node: ts.TypeNode): {
type: TypeNode;
isStream: boolean;
} | null;
collectPropertyType(node: ts.TypeNode): TypeNode | null;
maybeUnwrapPromise(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, jsModulePath: string, tsModulePath: string, functionName: string, argCount: number): ConstDirectiveNode;
fieldNameDirective(nameNode: ts.Node, name: string): ConstDirectiveNode;
}
export {};
export declare function extract(sourceFile: ts.SourceFile): DiagnosticsResult<ExtractionSnapshot>;

@@ -30,5 +30,6 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: 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;
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.LIBRARY_NAME = exports.LIBRARY_IMPORT_NAME = void 0;
var graphql_1 = require("graphql");
var DiagnosticError_1 = require("./utils/DiagnosticError");
var Result_1 = require("./utils/Result");
var ts = require("typescript");

@@ -39,6 +40,6 @@ var TypeContext_1 = require("./TypeContext");

var GraphQLConstructor_1 = require("./GraphQLConstructor");
var serverDirectives_1 = require("./serverDirectives");
var gratsRoot_1 = require("./gratsRoot");
var Errors_1 = require("./Errors");
exports.LIBRARY_IMPORT_NAME = "grats";
exports.LIBRARY_NAME = "Grats";
exports.ISSUE_URL = "https://github.com/captbaritone/grats/issues";
exports.TYPE_TAG = "gqlType";

@@ -75,11 +76,25 @@ exports.FIELD_TAG = "gqlField";

*/
function extract(sourceFile) {
var extractor = new Extractor();
return extractor.extract(sourceFile);
}
exports.extract = extract;
var Extractor = /** @class */ (function () {
function Extractor(sourceFile, ctx, buildOptions) {
function Extractor() {
this.definitions = [];
// Snapshot data
this.unresolvedNames = new Map();
this.nameDefinitions = new Map();
this.contextReferences = [];
this.typesWithTypename = 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 +104,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;

@@ -119,2 +134,3 @@ switch (tag.tagName.text) {

ts.isMethodDeclaration(node) ||
ts.isGetAccessorDeclaration(node) ||
ts.isPropertyDeclaration(node) ||

@@ -164,5 +180,12 @@ ts.isMethodSignature(node) ||

if (this.errors.length > 0) {
return (0, DiagnosticError_1.err)(this.errors);
return (0, Result_1.err)(this.errors);
}
return (0, DiagnosticError_1.ok)(this.definitions);
return (0, Result_1.ok)({
definitions: this.definitions,
unresolvedNames: this.unresolvedNames,
nameDefinitions: this.nameDefinitions,
contextReferences: this.contextReferences,
typesWithTypename: this.typesWithTypename,
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;

@@ -245,21 +258,6 @@ };

Extractor.prototype.reportUnhandled = function (node, positionKind, message, relatedInformation) {
var suggestion = "If you think ".concat(exports.LIBRARY_NAME, " should be able to infer this ").concat(positionKind, ", please report an issue at ").concat(exports.ISSUE_URL, ".");
var suggestion = "If you think ".concat(exports.LIBRARY_NAME, " should be able to infer this ").concat(positionKind, ", please report an issue at ").concat(Errors_1.ISSUE_URL, ".");
var completedMessage = "".concat(message, "\n\n").concat(suggestion);
return this.report(node, completedMessage, relatedInformation);
};
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);

@@ -296,3 +294,3 @@ }

}
this.ctx.recordTypeName(node.name, name, "UNION");
this.recordTypeName(node.name, name, "UNION");
this.definitions.push(this.gql.unionTypeDefinition(node, name, types, description));

@@ -330,3 +328,3 @@ };

}
var description = this.collectDescription(funcName);
var description = this.collectDescription(node);
if (!ts.isSourceFile(node.parent)) {

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

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

@@ -348,3 +350,7 @@ var deprecated = this.collectDeprecated(node);

}
var field = this.gql.fieldDefinition(node, name, this.handleErrorBubbling(node, type), args, directives, description);
var killsParentOnExceptionDirective = this.killsParentOnExceptionDirective(node);
if (killsParentOnExceptionDirective != null) {
directives.push(killsParentOnExceptionDirective);
}
var field = this.gql.fieldDefinition(node, name, type, args, directives, description);
this.definitions.push(this.gql.abstractFieldDefinition(node, typeName, field));

@@ -361,3 +367,3 @@ };

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

@@ -389,4 +395,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));

@@ -398,4 +404,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);

@@ -433,3 +439,3 @@ var deprecatedDirective = this.collectDeprecated(node);

Extractor.prototype.collectInputField = function (node) {
var id = this.expectIdentifier(node.name);
var id = this.expectNameIdentifier(node.name);
if (id == null)

@@ -444,3 +450,3 @@ return null;

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);

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

this.validateOperationTypes(node.name, name.value);
var description = this.collectDescription(node.name);
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);

@@ -477,6 +483,6 @@ this.definitions.push(this.gql.objectTypeDefinition(node, name, fields, interfaces, description));

this.validateOperationTypes(node.name, name.value);
var description = this.collectDescription(node.name);
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);

@@ -505,4 +511,4 @@ this.definitions.push(this.gql.objectTypeDefinition(node, name, fields, interfaces, description));

}
var description = this.collectDescription(node.name);
this.ctx.recordTypeName(node.name, name, "TYPE");
var description = this.collectDescription(node);
this.recordTypeName(node.name, name, "TYPE");
this.definitions.push(this.gql.objectTypeDefinition(node, name, fields, interfaces, description));

@@ -516,3 +522,3 @@ };

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

@@ -611,6 +617,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;

@@ -625,11 +630,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) {

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

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

@@ -647,23 +642,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));

@@ -696,3 +675,5 @@ };

}
if (ts.isMethodDeclaration(node) || ts.isMethodSignature(node)) {
if (ts.isMethodDeclaration(node) ||
ts.isMethodSignature(node) ||
ts.isGetAccessorDeclaration(node)) {
var field = _this.methodDeclaration(node);

@@ -751,3 +732,5 @@ if (field != null) {

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

@@ -761,4 +744,8 @@ var type = this.collectType(node.type);

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

@@ -911,3 +898,3 @@ Extractor.prototype.collectArgs = function (argsParam) {

}
var name = this.expectIdentifier(node.name);
var name = this.expectNameIdentifier(node.name);
if (name == null)

@@ -956,3 +943,3 @@ return null;

}
var description = this.collectDescription(node.name);
var description = this.collectDescription(node);
var defaultValue = null;

@@ -973,5 +960,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));

@@ -987,4 +974,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));

@@ -994,3 +981,2 @@ };

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

@@ -1013,23 +999,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) ||

@@ -1048,3 +1015,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);
}

@@ -1066,3 +1033,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);

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

// Test for leading newlines using the raw text
var hasLeadingNewlines = /\n/.test(tag.getText().trimEnd());
var hasLeadingNewlines = /\n/.test(trimTrailingCommentLines(tag.getText()));
var hasInternalWhitespace = /\s/.test(commentName);

@@ -1114,3 +1081,3 @@ var validationMessage = graphQLNameValidationMessage(commentName);

}
var id = this.expectIdentifier(node.name);
var id = this.expectNameIdentifier(node.name);
if (id == null)

@@ -1138,22 +1105,3 @@ return null;

}
var symbol = this.ctx.checker.getSymbolAtLocation(node.type.typeName);
if (symbol == null) {
return this.report(node.type.typeName, E.expectedTypeAnnotationOnContextToBeResolvable());
}
var declaration = this.ctx.findSymbolDeclaration(symbol);
if (declaration == null) {
return this.report(node.type.typeName, E.expectedTypeAnnotationOnContextToHaveDeclaration());
}
if (this.ctx.gqlContext == null) {
// This is the first typed context value we've seen...
this.ctx.gqlContext = {
declaration: declaration,
firstReference: node.type.typeName,
};
}
else if (this.ctx.gqlContext.declaration !== declaration) {
return this.report(node.type.typeName, E.multipleContextTypes(), [
this.related(this.ctx.gqlContext.firstReference, "A different type reference was used here"),
]);
}
this.contextReferences.push(node.type.typeName);
};

@@ -1186,4 +1134,4 @@ Extractor.prototype.methodDeclaration = function (node) {

}
var description = this.collectDescription(node.name);
var id = this.expectIdentifier(node.name);
var description = this.collectDescription(node);
var id = this.expectNameIdentifier(node.name);
if (id == null)

@@ -1193,6 +1141,8 @@ return 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.constDirective(node.type, this.gql.name(node.type, serverDirectives_1.ASYNC_ITERABLE_TYPE_DIRECTIVE), null));
directives.push(this.gql.asyncIterableDirective(node.type));
}

@@ -1203,7 +1153,11 @@ var deprecated = this.collectDeprecated(node);

}
return this.gql.fieldDefinition(node, name, this.handleErrorBubbling(node, type), args, directives, description);
var killsParentOnExceptionDirective = this.killsParentOnExceptionDirective(node);
if (killsParentOnExceptionDirective != null) {
directives.push(killsParentOnExceptionDirective);
}
return this.gql.fieldDefinition(node, name, type, args, directives, description);
};
Extractor.prototype.collectReturnType = function (node) {
if (ts.isTypeReferenceNode(node)) {
var identifier = this.expectIdentifier(node.typeName);
var identifier = this.expectNameIdentifier(node.typeName);
if (identifier == null)

@@ -1214,3 +1168,3 @@ return null;

// TODO: Better error?
return this.report(node, E.promiseMissingTypeArg());
return this.report(node, E.wrapperMissingTypeArg());
}

@@ -1240,3 +1194,3 @@ var t_1 = this.collectType(node.typeArguments[0]);

if (ts.isTypeReferenceNode(node)) {
var identifier = this.expectIdentifier(node.typeName);
var identifier = this.expectNameIdentifier(node.typeName);
if (identifier == null)

@@ -1246,3 +1200,3 @@ return null;

if (node.typeArguments == null || node.typeArguments.length === 0) {
return this.report(node, E.promiseMissingTypeArg());
return this.report(node, E.wrapperMissingTypeArg());
}

@@ -1255,11 +1209,12 @@ return node.typeArguments[0];

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.trim(), true);
}
return null;

@@ -1297,5 +1252,5 @@ };

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

@@ -1308,5 +1263,11 @@ return null;

if (id.text !== name.value) {
directives = [this.fieldNameDirective(node.name, id.text)];
directives = [
this.gql.propertyNameDirective(node.name, { name: id.text }),
];
}
return this.gql.fieldDefinition(node, name, this.handleErrorBubbling(node, type), null, directives, description);
var killsParentOnExceptionDirective = this.killsParentOnExceptionDirective(node);
if (killsParentOnExceptionDirective != null) {
directives.push(killsParentOnExceptionDirective);
}
return this.gql.fieldDefinition(node, name, type, null, directives, description);
};

@@ -1341,3 +1302,3 @@ // TODO: Support separate modes for input and output types

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

@@ -1348,3 +1309,3 @@ this.report(first, E.expectedOneNonNullishType(), incompatibleVariants);

if (node.types.length > 1) {
return this.gql.nullableType(type);
return this.gql.withLocation(node, this.gql.nullableType(type));
}

@@ -1373,3 +1334,3 @@ return this.gql.nonNullType(node, type);

Extractor.prototype.typeReference = function (node) {
var identifier = this.expectIdentifier(node.typeName);
var identifier = this.expectNameIdentifier(node.typeName);
if (identifier == null)

@@ -1396,3 +1357,3 @@ return null;

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);

@@ -1414,10 +1375,9 @@ }

};
Extractor.prototype.expectIdentifier = function (node) {
Extractor.prototype.expectNameIdentifier = function (node) {
if (ts.isIdentifier(node)) {
return node;
}
return this.report(node, E.expectedIdentifier());
return this.report(node, E.expectedNameIdentifier());
};
Extractor.prototype.findTag = function (node, tagName) {
var _this = this;
var tags = ts

@@ -1431,8 +1391,5 @@ .getJSDocTags(node)

var additionalTags = tags.slice(1).map(function (tag) {
return _this.related(tag, "Additional tag");
return (0, DiagnosticError_1.tsRelated)(tag, "Additional tag");
});
var message = tagName === exports.IMPLEMENTS_TAG_DEPRECATED
? E.duplicateInterfaceTag()
: E.duplicateTag(tagName);
return this.report(tags[0], message, additionalTags);
return this.report(tags[0], E.duplicateTag(tagName), additionalTags);
}

@@ -1445,36 +1402,12 @@ return tags[0];

// https://graphql.org/learn/best-practices/#nullability
Extractor.prototype.handleErrorBubbling = function (parentNode, type) {
Extractor.prototype.killsParentOnExceptionDirective = function (parentNode) {
var tags = ts.getJSDocTags(parentNode);
var killsParentOnExceptions = tags.find(function (tag) { return tag.tagName.text === exports.KILLS_PARENT_ON_EXCEPTION_TAG; });
if (killsParentOnExceptions) {
if (!this.configOptions.nullableByDefault) {
this.report(killsParentOnExceptions.tagName, E.killsParentOnExceptionWithWrongConfig());
}
if (type.kind !== graphql_1.Kind.NON_NULL_TYPE) {
this.report(killsParentOnExceptions.tagName, E.killsParentOnExceptionOnNullable());
}
return type;
return this.gql.killsParentOnExceptionDirective(killsParentOnExceptions.tagName);
}
if (this.configOptions.nullableByDefault) {
return this.gql.nullableType(type);
}
return type;
return null;
};
/* Grats directives */
Extractor.prototype.exportDirective = function (nameNode, jsModulePath, tsModulePath, functionName, argCount) {
return this.gql.constDirective(nameNode, this.gql.name(nameNode, serverDirectives_1.EXPORTED_DIRECTIVE), [
this.gql.constArgument(nameNode, this.gql.name(nameNode, serverDirectives_1.JS_MODULE_PATH_ARG), this.gql.string(nameNode, jsModulePath)),
this.gql.constArgument(nameNode, this.gql.name(nameNode, serverDirectives_1.TS_MODULE_PATH_ARG), this.gql.string(nameNode, tsModulePath)),
this.gql.constArgument(nameNode, this.gql.name(nameNode, serverDirectives_1.EXPORTED_FUNCTION_NAME_ARG), this.gql.string(nameNode, functionName)),
this.gql.constArgument(nameNode, this.gql.name(nameNode, serverDirectives_1.ARG_COUNT), this.gql.int(nameNode, String(argCount))),
]);
};
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) {

@@ -1489,1 +1422,6 @@ try {

}
// Trims any number of whitespace-only lines including any lines that simply
// contain a `*` surrounded by whitespace.
function trimTrailingCommentLines(text) {
return text.replace(/(\s*\n\s*\*?\s*)+$/, "");
}

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

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, ASTNode } 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;
killsParentOnExceptionDirective(node: ts.Node): ConstDirectiveNode;
unionTypeDefinition(node: ts.Node, name: NameNode, types: NamedTypeNode[], description: StringValueNode | null): UnionTypeDefinitionNode;

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

list(node: ts.Node, values: ConstValueNode[]): ConstListValueNode;
withLocation<T = ASTNode>(node: ts.Node, value: T): T;
constArgument(node: ts.Node, name: NameNode, value: ConstValueNode): ConstArgumentNode;

@@ -35,3 +45,3 @@ constDirective(node: ts.Node, name: NameNode, args: ReadonlyArray<ConstArgumentNode> | null): ConstDirectiveNode;

_loc(node: ts.Node): GraphQLLocation;
_dummyToken(pos: number): Token;
_dummyToken(sourceFile: ts.SourceFile, pos: number): Token;
}
"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);
};
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));
};
GraphQLConstructor.prototype.killsParentOnExceptionDirective = function (node) {
return (0, metadataDirectives_1.makeKillsParentOnExceptionDirective)(this._loc(node));
};
/* Top Level Types */

@@ -147,2 +171,5 @@ GraphQLConstructor.prototype.unionTypeDefinition = function (node, name, types, description) {

};
GraphQLConstructor.prototype.withLocation = function (node, value) {
return __assign(__assign({}, value), { loc: this._loc(node) });
};
GraphQLConstructor.prototype.constArgument = function (node, name, value) {

@@ -184,9 +211,10 @@ return { kind: graphql_1.Kind.ARGUMENT, loc: this._loc(node), name: name, value: value };

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);

@@ -193,0 +221,0 @@ };

@@ -10,3 +10,3 @@ import * as ts from "typescript";

};
export type ParsedCommandLineGrats = ts.ParsedCommandLine & {
export type ParsedCommandLineGrats = Omit<ts.ParsedCommandLine, "raw"> & {
raw: {

@@ -13,0 +13,0 @@ grats: ConfigOptions;

@@ -1,6 +0,2 @@

import * as ts from "typescript";
export declare function getRelativeOutputPath(options: ts.ParsedCommandLine, sourceFile: ts.SourceFile): {
jsModulePath: string;
tsModulePath: string;
};
export declare function relativePath(absolute: string): string;
export declare function resolveRelativePath(relativePath: string): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveRelativePath = exports.getRelativeOutputPath = void 0;
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

@@ -14,17 +13,6 @@ // named export, Grats needs to be able to import that file during execution.

var gratsRoot = (0, path_1.join)(__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.");
}
var jsModulePath = (0, path_1.relative)(gratsRoot, fileNames[0]);
var tsModulePath = (0, path_1.relative)(gratsRoot, sourceFile.fileName);
return { jsModulePath: jsModulePath, tsModulePath: tsModulePath };
function relativePath(absolute) {
return (0, path_1.relative)(gratsRoot, absolute);
}
exports.getRelativeOutputPath = getRelativeOutputPath;
exports.relativePath = relativePath;
function resolveRelativePath(relativePath) {

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

import { ParsedCommandLineGrats } from "./lib";
import { ReportableDiagnostics, Result } from "./utils/DiagnosticError";
import { ReportableDiagnostics } from "./utils/DiagnosticError";
import { Result } from "./utils/Result";
export { printSDLWithoutDirectives } from "./printSchema";
export * from "./Types";
export * from "./lib";
export { extract } from "./Extractor";
export { codegen } from "./codegen";
export declare function getParsedTsConfig(configFile: string): Result<ParsedCommandLineGrats, ReportableDiagnostics>;

@@ -17,8 +17,14 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getParsedTsConfig = exports.codegen = void 0;
exports.getParsedTsConfig = exports.codegen = exports.extract = exports.printSDLWithoutDirectives = void 0;
var ts = require("typescript");
var lib_1 = require("./lib");
var DiagnosticError_1 = require("./utils/DiagnosticError");
var Result_1 = require("./utils/Result");
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);
// Used by the experimental TypeScript plugin
var Extractor_1 = require("./Extractor");
Object.defineProperty(exports, "extract", { enumerable: true, get: function () { return Extractor_1.extract; } });
var codegen_1 = require("./codegen");

@@ -38,6 +44,6 @@ Object.defineProperty(exports, "codegen", { enumerable: true, get: function () { return codegen_1.codegen; } });

if (parsed.errors.length > 0) {
return (0, DiagnosticError_1.err)(DiagnosticError_1.ReportableDiagnostics.fromDiagnostics(parsed.errors));
return (0, Result_1.err)(DiagnosticError_1.ReportableDiagnostics.fromDiagnostics(parsed.errors));
}
return (0, DiagnosticError_1.ok)((0, lib_1.validateGratsOptions)(parsed));
return (0, Result_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;

@@ -15,3 +15,2 @@ "use strict";

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 {

@@ -91,7 +89,4 @@ for (var docs_1 = __values(docs), docs_1_1 = docs_1.next(); !docs_1_1.done; docs_1_1 = docs_1.next()) {

}
if (errors.length > 0) {
return (0, DiagnosticError_1.err)(errors);
}
return (0, DiagnosticError_1.ok)(graph);
return graph;
}
exports.computeInterfaceMap = computeInterfaceMap;
import { GraphQLSchema } from "graphql";
import { Result, ReportableDiagnostics } from "./utils/DiagnosticError";
import { DiagnosticsWithoutLocationResult, ReportableDiagnostics } from "./utils/DiagnosticError";
import { Result } from "./utils/Result";
import * as ts from "typescript";

@@ -8,1 +9,5 @@ import { ParsedCommandLineGrats } from "./gratsConfig";

export declare function buildSchemaResultWithHost(options: ParsedCommandLineGrats, compilerHost: ts.CompilerHost): Result<GraphQLSchema, ReportableDiagnostics>;
/**
* The core transformation pipeline of Grats.
*/
export declare function extractSchema(options: ParsedCommandLineGrats, program: ts.Program): DiagnosticsWithoutLocationResult<GraphQLSchema>;

@@ -27,12 +27,37 @@ "use strict";

};
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.buildSchemaResultWithHost = exports.buildSchemaResult = void 0;
exports.extractSchema = exports.buildSchemaResultWithHost = exports.buildSchemaResult = void 0;
var graphql_1 = require("graphql");
var DiagnosticError_1 = require("./utils/DiagnosticError");
var Result_1 = require("./utils/Result");
var Result_2 = require("./utils/Result");
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 helpers_1 = require("./utils/helpers");
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 addInterfaceFields_1 = require("./transforms/addInterfaceFields");
var filterNonGqlInterfaces_1 = require("./transforms/filterNonGqlInterfaces");
var resolveTypes_1 = require("./transforms/resolveTypes");
var validateAsyncIterable_1 = require("./validations/validateAsyncIterable");
var applyDefaultNullability_1 = require("./transforms/applyDefaultNullability");
__exportStar(require("./gratsConfig"), exports);

@@ -50,91 +75,54 @@ // Construct a schema, using GraphQL schema language

function buildSchemaResultWithHost(options, 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)(schemaResult.value);
var program = ts.createProgram(options.fileNames, options.options, compilerHost);
return new Result_1.ResultPipe(extractSchema(options, program))
.mapErr(function (e) { return new DiagnosticError_1.ReportableDiagnostics(compilerHost, e); })
.result();
}
exports.buildSchemaResultWithHost = buildSchemaResultWithHost;
function extractSchema(options, host) {
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 errors = [];
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 (options.raw.grats.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) {
(0, helpers_1.extend)(errors, typeErrors);
continue;
}
}
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.
errors.push(syntaxErrors[0]);
continue;
}
}
var extractor = new Extractor_1.Extractor(sourceFile, ctx, options.raw.grats);
var extractedResult = extractor.extract();
if (extractedResult.kind === "ERROR") {
(0, helpers_1.extend)(errors, extractedResult.err);
continue;
}
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; }
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
}
finally { if (e_1) throw e_1.error; }
}
if (errors.length > 0) {
return (0, DiagnosticError_1.err)(errors);
}
// 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);
if (definitionsResult.kind === "ERROR") {
return definitionsResult;
}
var docResult = ctx.resolveTypes({
kind: graphql_1.Kind.DOCUMENT,
definitions: definitionsResult.value,
});
if (docResult.kind === "ERROR")
return docResult;
var doc = docResult.value;
var subscriptionsValidationResult = ctx.validateAsyncIterableFields(doc);
if (subscriptionsValidationResult.kind === "ERROR") {
return subscriptionsValidationResult;
}
/**
* The core transformation pipeline of Grats.
*/
function extractSchema(options, program) {
return new Result_1.ResultPipe((0, snapshotsFromProgram_1.extractSnapshotsFromProgram)(program, options))
.map(function (snapshots) { return combineSnapshots(snapshots); })
.andThen(function (snapshot) {
var typesWithTypename = snapshot.typesWithTypename;
var config = options.raw.grats;
var checker = program.getTypeChecker();
var ctx = TypeContext_1.TypeContext.fromSnapshot(checker, snapshot);
// Collect validation errors
var validationResult = (0, Result_1.concatResults)((0, validateMergedInterfaces_1.validateMergedInterfaces)(checker, snapshot.interfaceDeclarations), (0, validateContextReferences_1.validateContextReferences)(ctx, snapshot.contextReferences));
return (new Result_1.ResultPipe(validationResult)
// Add the metadata directive definitions to definitions
// found in the snapshot.
.map(function () { return (0, metadataDirectives_1.addMetadataDirectives)(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.
.andThen(function (definitions) { return (0, addInterfaceFields_1.addInterfaceFields)(ctx, definitions); })
// Convert the definitions into a DocumentNode
.map(function (definitions) { return ({ kind: graphql_1.Kind.DOCUMENT, definitions: definitions }); })
// Filter out any `implements` clauses that are not GraphQL interfaces.
.map(function (doc) { return (0, filterNonGqlInterfaces_1.filterNonGqlInterfaces)(ctx, doc); })
// Apply default nullability to fields and arguments, and detect any misuse of
// `@killsParentOnException`.
.andThen(function (doc) { return (0, applyDefaultNullability_1.applyDefaultNullability)(doc, config); })
// Resolve TypeScript type references to the GraphQL types they represent (or error).
.andThen(function (doc) { return (0, resolveTypes_1.resolveTypes)(ctx, doc); })
// Ensure all subscription fields, and _only_ subscription fields, return an AsyncIterable.
.andThen(function (doc) { return (0, validateAsyncIterable_1.validateAsyncIterable)(doc); })
// Validate the document node against the GraphQL spec.
// Build and validate the schema with regards to the GraphQL spec.
.andThen(function (doc) { return buildSchemaFromDoc(doc); })
// Ensure that every type which implements an interface or is a member of a
// union has a __typename field.
.andThen(function (schema) { return (0, validateTypenames_1.validateTypenames)(schema, typesWithTypename); })
.map(function (schema) { return (0, graphql_1.lexicographicSortSchema)(schema); })
.result());
})
.result();
}
exports.extractSchema = extractSchema;
// Given a SDL AST, build and validate a GraphQLSchema.
function buildSchemaFromDoc(doc) {
// TODO: Currently this does not detect definitions that shadow builtins

@@ -144,7 +132,5 @@ // (`String`, `Int`, etc). However, if we pass a second param (extending an

// shadow builtins.
var validationErrors = (0, validate_1.validateSDL)(doc).map(function (e) {
return (0, DiagnosticError_1.graphQlErrorToDiagnostic)(e);
});
var validationErrors = (0, validate_1.validateSDL)(doc);
if (validationErrors.length > 0) {
return (0, DiagnosticError_1.err)(validationErrors);
return (0, Result_2.err)(validationErrors.map(DiagnosticError_1.graphQlErrorToDiagnostic));
}

@@ -154,51 +140,110 @@ var schema = (0, graphql_1.buildASTSchema)(doc, { assumeValidSDL: true });

// 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); });
.filter(function (e) { return e.source && e.locations && e.positions; });
if (diagnostics.length > 0) {
return (0, DiagnosticError_1.err)(diagnostics);
return (0, Result_2.err)(diagnostics.map(DiagnosticError_1.graphQlErrorToDiagnostic));
}
var typenameDiagnostics = validateTypename(schema, ctx);
if (typenameDiagnostics.length > 0)
return (0, DiagnosticError_1.err)(typenameDiagnostics);
return (0, DiagnosticError_1.ok)(schema);
return (0, Result_2.ok)(schema);
}
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);
// Given a list of snapshots, merge them into a single snapshot.
function combineSnapshots(snapshots) {
var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f, e_7, _g;
var result = {
definitions: [],
nameDefinitions: new Map(),
unresolvedNames: new Map(),
contextReferences: [],
typesWithTypename: 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_2 = void 0, __values(snapshot.definitions)), _j = _h.next(); !_j.done; _j = _h.next()) {
var definition = _j.value;
result.definitions.push(definition);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_j && !_j.done && (_b = _h.return)) _b.call(_h);
}
finally { if (e_2) throw e_2.error; }
}
try {
for (var _k = (e_3 = 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_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
}
finally { if (e_3) throw e_3.error; }
}
try {
for (var _o = (e_4 = 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_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (typeImplementors_1_1 && !typeImplementors_1_1.done && (_b = typeImplementors_1.return)) _b.call(typeImplementors_1);
if (_p && !_p.done && (_d = _o.return)) _d.call(_o);
}
finally { if (e_4) throw e_4.error; }
}
try {
for (var _r = (e_5 = void 0, __values(snapshot.contextReferences)), _s = _r.next(); !_s.done; _s = _r.next()) {
var contextReference = _s.value;
result.contextReferences.push(contextReference);
}
}
catch (e_5_1) { e_5 = { error: e_5_1 }; }
finally {
try {
if (_s && !_s.done && (_e = _r.return)) _e.call(_r);
}
finally { if (e_5) throw e_5.error; }
}
try {
for (var _t = (e_6 = void 0, __values(snapshot.typesWithTypename)), _u = _t.next(); !_u.done; _u = _t.next()) {
var typeName = _u.value;
result.typesWithTypename.add(typeName);
}
}
catch (e_6_1) { e_6 = { error: e_6_1 }; }
finally {
try {
if (_u && !_u.done && (_f = _t.return)) _f.call(_t);
}
finally { if (e_6) throw e_6.error; }
}
try {
for (var _v = (e_7 = void 0, __values(snapshot.interfaceDeclarations)), _w = _v.next(); !_w.done; _w = _v.next()) {
var interfaceDeclaration = _w.value;
result.interfaceDeclarations.push(interfaceDeclaration);
}
}
catch (e_7_1) { e_7 = { error: e_7_1 }; }
finally {
try {
if (_w && !_w.done && (_g = _v.return)) _g.call(_v);
}
finally { if (e_7) throw e_7.error; }
}
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
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; }
finally { if (e_1) throw e_1.error; }
}
return typenameDiagnostics;
return result;
}
import { GraphQLSchema, Location } from "graphql";
import { Result } from "./utils/DiagnosticError";
import { Result } from "./utils/Result";
/**

@@ -4,0 +4,0 @@ * Given an entity name of the format `ParentType` or `ParentType.fieldName`,

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

var graphql_1 = require("graphql");
var DiagnosticError_1 = require("./utils/DiagnosticError");
var Result_1 = require("./utils/Result");
var helpers_1 = require("./utils/helpers");
/**

@@ -19,9 +20,9 @@ * Given an entity name of the format `ParentType` or `ParentType.fieldName`,

if (type == null) {
return (0, DiagnosticError_1.err)("Cannot locate type `".concat(entity.parent, "`."));
return (0, Result_1.err)("Cannot locate type `".concat(entity.parent, "`."));
}
if (entity.field == null) {
if (type.astNode == null || type.astNode.name.loc == null) {
if (type.astNode == null) {
throw new Error("Grats bug: Cannot find location of type `".concat(entity.parent, "`."));
}
return (0, DiagnosticError_1.ok)(type.astNode.name.loc);
return (0, Result_1.ok)((0, helpers_1.loc)(type.astNode.name));
}

@@ -31,12 +32,12 @@ if (!(type instanceof graphql_1.GraphQLObjectType ||

type instanceof graphql_1.GraphQLInputObjectType)) {
return (0, DiagnosticError_1.err)("Cannot locate field `".concat(entity.field, "` on type `").concat(entity.parent, "`. Only object types, interfaces, and input objects have fields."));
return (0, Result_1.err)("Cannot locate field `".concat(entity.field, "` on type `").concat(entity.parent, "`. Only object types, interfaces, and input objects have fields."));
}
var field = type.getFields()[entity.field];
if (field == null) {
return (0, DiagnosticError_1.err)("Cannot locate field `".concat(entity.field, "` on type `").concat(entity.parent, "`."));
return (0, Result_1.err)("Cannot locate field `".concat(entity.field, "` on type `").concat(entity.parent, "`."));
}
if (field.astNode == null || field.astNode.name.loc == null) {
if (field.astNode == null) {
throw new Error("Grats bug: Cannot find location of field `".concat(entity.field, "` on type `").concat(entity.parent, "`."));
}
return (0, DiagnosticError_1.ok)(field.astNode.name.loc);
return (0, Result_1.ok)((0, helpers_1.loc)(field.astNode.name));
}

@@ -48,7 +49,7 @@ exports.locate = locate;

if (match == null) {
return (0, DiagnosticError_1.err)("Invalid entity name: `".concat(entityName, "`. Expected `ParentType` or `ParentType.fieldName`."));
return (0, Result_1.err)("Invalid entity name: `".concat(entityName, "`. Expected `ParentType` or `ParentType.fieldName`."));
}
var parent = match[1];
var field = match[2] || null;
return (0, DiagnosticError_1.ok)({ parent: parent, field: field });
return (0, Result_1.ok)({ parent: parent, field: field });
}

@@ -15,5 +15,5 @@ "use strict";

exports.printSDLWithoutDirectives = exports.printGratsSDL = exports.printExecutableSchema = void 0;
var utils_1 = require("@graphql-tools/utils");
var graphql_1 = require("graphql");
var codegen_1 = require("./codegen");
var metadataDirectives_1 = require("./metadataDirectives");
/**

@@ -36,6 +36,3 @@ * Prints code for a TypeScript module that exports a GraphQLSchema.

function printGratsSDL(schema, config) {
var includeDirectives = !config.graphqlSchema;
var sdl = includeDirectives
? (0, utils_1.printSchemaWithDirectives)(schema, { assumeValid: true })
: printSDLWithoutDirectives(schema);
var sdl = printSDLWithoutDirectives(schema);
if (config.schemaHeader) {

@@ -48,7 +45,6 @@ return "".concat(config.schemaHeader, "\n").concat(sdl);

function printSDLWithoutDirectives(schema) {
return (0, graphql_1.printSchema)(new graphql_1.GraphQLSchema(__assign(__assign({}, schema.toConfig()), {
// TODO: Only filter out our directives. Note that
// the playground duplicates this logic.
directives: [] })));
return (0, graphql_1.printSchema)(new graphql_1.GraphQLSchema(__assign(__assign({}, schema.toConfig()), { directives: schema.getDirectives().filter(function (directive) {
return !metadataDirectives_1.METADATA_DIRECTIVE_NAMES.has(directive.name);
}) })));
}
exports.printSDLWithoutDirectives = printSDLWithoutDirectives;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var graphql_1 = require("graphql");
var SomeObjType = new graphql_1.GraphQLInputObjectType({
name: "SomeObj",
fields: function () {
return {
a: {
name: "a",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString)
}
};
}
});
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
args: {
someObj: {
name: "someObj",
type: new graphql_1.GraphQLNonNull(SomeObjType),
defaultValue: {
a: "Sup"
function getSchema() {
var SomeObjType = new graphql_1.GraphQLInputObjectType({
name: "SomeObj",
fields: function () {
return {
a: {
name: "a",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString)
}
};
}
});
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
args: {
someObj: {
name: "someObj",
type: new graphql_1.GraphQLNonNull(SomeObjType),
defaultValue: {
a: "Sup"
}
}
},
resolve: function (source, args) {
return (0, index_1.hello)(source, args);
}
},
resolve: function (source, args) {
return (0, index_1.hello)(source, args);
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType, SomeObjType]
});
exports.schema = schema;
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType, SomeObjType]
});
}
exports.getSchema = getSchema;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var graphql_1 = require("graphql");
var FirstHundredIntegersPageInfoType = new graphql_1.GraphQLObjectType({
name: "FirstHundredIntegersPageInfo",
fields: function () {
return {
hasNextPage: {
name: "hasNextPage",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLBoolean)
},
hasPreviousPage: {
name: "hasPreviousPage",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLBoolean)
},
startCursor: {
name: "startCursor",
type: graphql_1.GraphQLString
},
endCursor: {
name: "endCursor",
type: graphql_1.GraphQLString
}
};
}
});
var FirstHundredIntegersEdgeType = new graphql_1.GraphQLObjectType({
name: "FirstHundredIntegersEdge",
fields: function () {
return {
node: {
name: "node",
type: graphql_1.GraphQLInt
},
cursor: {
name: "cursor",
type: graphql_1.GraphQLString
}
};
}
});
var FirstHundredIntegersConnectionType = new graphql_1.GraphQLObjectType({
name: "FirstHundredIntegersConnection",
fields: function () {
return {
pageInfo: {
name: "pageInfo",
type: FirstHundredIntegersPageInfoType
},
edges: {
name: "edges",
type: new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(FirstHundredIntegersEdgeType))
}
};
}
});
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
firstHundredIntegers: {
name: "firstHundredIntegers",
type: FirstHundredIntegersConnectionType,
args: {
first: {
name: "first",
type: graphql_1.GraphQLInt
function getSchema() {
var FirstHundredIntegersEdgeType = new graphql_1.GraphQLObjectType({
name: "FirstHundredIntegersEdge",
fields: function () {
return {
cursor: {
name: "cursor",
type: graphql_1.GraphQLString
},
node: {
name: "node",
type: graphql_1.GraphQLInt
}
};
}
});
var FirstHundredIntegersPageInfoType = new graphql_1.GraphQLObjectType({
name: "FirstHundredIntegersPageInfo",
fields: function () {
return {
endCursor: {
name: "endCursor",
type: graphql_1.GraphQLString
},
hasNextPage: {
name: "hasNextPage",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLBoolean)
},
hasPreviousPage: {
name: "hasPreviousPage",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLBoolean)
},
startCursor: {
name: "startCursor",
type: graphql_1.GraphQLString
}
};
}
});
var FirstHundredIntegersConnectionType = new graphql_1.GraphQLObjectType({
name: "FirstHundredIntegersConnection",
fields: function () {
return {
edges: {
name: "edges",
type: new graphql_1.GraphQLList(new graphql_1.GraphQLNonNull(FirstHundredIntegersEdgeType))
},
pageInfo: {
name: "pageInfo",
type: FirstHundredIntegersPageInfoType
}
};
}
});
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
firstHundredIntegers: {
name: "firstHundredIntegers",
type: FirstHundredIntegersConnectionType,
args: {
after: {
name: "after",
type: graphql_1.GraphQLString
},
first: {
name: "first",
type: graphql_1.GraphQLInt
}
},
after: {
name: "after",
type: graphql_1.GraphQLString
resolve: function (source, args) {
return (0, index_1.firstHundredIntegers)(source, args);
}
},
resolve: function (source, args) {
return (0, index_1.firstHundredIntegers)(source, args);
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType, FirstHundredIntegersConnectionType, FirstHundredIntegersPageInfoType, FirstHundredIntegersEdgeType]
});
exports.schema = schema;
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [FirstHundredIntegersConnectionType, FirstHundredIntegersEdgeType, FirstHundredIntegersPageInfoType, QueryType]
});
}
exports.getSchema = getSchema;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var index_2 = require("./index");
var graphql_1 = require("graphql");
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
deprecationReason: "For reasons",
name: "hello",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_1.hello)(source);
function getSchema() {
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
goodBye: {
deprecationReason: "No longer supported",
name: "goodBye",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_1.goodBye)(source);
}
},
hello: {
deprecationReason: "For reasons",
name: "hello",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_2.hello)(source);
}
}
},
goodBye: {
deprecationReason: "No longer supported",
name: "goodBye",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_2.goodBye)(source);
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
exports.schema = schema;
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
}
exports.getSchema = getSchema;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var graphql_1 = require("graphql");
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
args: {
someArg: {
name: "someArg",
type: graphql_1.GraphQLString,
defaultValue: "Hello"
function getSchema() {
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
args: {
someArg: {
name: "someArg",
type: graphql_1.GraphQLString,
defaultValue: "Hello"
}
},
resolve: function (source, args) {
return (0, index_1.hello)(source, args);
}
},
resolve: function (source, args) {
return (0, index_1.hello)(source, args);
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
exports.schema = schema;
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
}
exports.getSchema = getSchema;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var graphql_1 = require("graphql");
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_1.hello)(source);
function getSchema() {
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_1.hello)(source);
}
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
exports.schema = schema;
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
}
exports.getSchema = getSchema;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var graphql_1 = require("graphql");
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_1.notHello)(source);
function getSchema() {
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_1.notHello)(source);
}
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
exports.schema = schema;
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
}
exports.getSchema = getSchema;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var graphql_1 = require("graphql");
var UserType = new graphql_1.GraphQLObjectType({
name: "User",
fields: function () {
return {
alwaysThrowsKillsParentOnException: {
name: "alwaysThrowsKillsParentOnException",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString)
}
};
}
});
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
me: {
name: "me",
type: UserType,
resolve: function (source) {
return (0, index_1.me)(source);
function getSchema() {
var UserType = new graphql_1.GraphQLObjectType({
name: "User",
fields: function () {
return {
alwaysThrowsKillsParentOnException: {
name: "alwaysThrowsKillsParentOnException",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString)
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType, UserType]
});
exports.schema = schema;
};
}
});
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
me: {
name: "me",
type: UserType,
resolve: function (source) {
return (0, index_1.me)(source);
}
}
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType, UserType]
});
}
exports.getSchema = getSchema;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var index_2 = require("./index");
var graphql_1 = require("graphql");
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
alwaysThrowsKillsParentOnException: {
name: "alwaysThrowsKillsParentOnException",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
resolve: function (source) {
return (0, index_1.alwaysThrowsKillsParentOnException)(source);
function getSchema() {
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
alwaysThrowsKillsParentOnException: {
name: "alwaysThrowsKillsParentOnException",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
resolve: function (source) {
return (0, index_1.alwaysThrowsKillsParentOnException)(source);
}
},
hello: {
name: "hello",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_2.hello)(source);
}
}
},
hello: {
name: "hello",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_2.hello)(source);
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
exports.schema = schema;
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
}
exports.getSchema = getSchema;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var graphql_1 = require("graphql");
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
args: {
someID: {
name: "someID",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID)
function getSchema() {
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
args: {
someID: {
name: "someID",
type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLID)
}
},
resolve: function (source, args) {
return (0, index_1.hello)(source, args);
}
},
resolve: function (source, args) {
return (0, index_1.hello)(source, args);
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
exports.schema = schema;
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
}
exports.getSchema = getSchema;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var graphql_1 = require("graphql");
var UserType = new graphql_1.GraphQLObjectType({
name: "User",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
resolve: function (source, args, context, info) {
return typeof source.NOT_THIS === "function" ? source.NOT_THIS(source, args, context, info) : source.NOT_THIS;
function getSchema() {
var UserType = new graphql_1.GraphQLObjectType({
name: "User",
fields: function () {
return {
hello: {
name: "hello",
type: graphql_1.GraphQLString,
resolve: function (source, args, context, info) {
return typeof source.NOT_THIS === "function" ? source.NOT_THIS(source, args, context, info) : source.NOT_THIS;
}
}
}
};
}
});
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
me: {
name: "me",
type: UserType,
resolve: function (source) {
return (0, index_1.me)(source);
};
}
});
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
me: {
name: "me",
type: UserType,
resolve: function (source) {
return (0, index_1.me)(source);
}
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType, UserType]
});
exports.schema = schema;
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType, UserType]
});
}
exports.getSchema = getSchema;
import { GraphQLSchema } from "graphql";
declare const schema: GraphQLSchema;
export { schema };
export declare function getSchema(): GraphQLSchema;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.schema = void 0;
exports.getSchema = void 0;
var index_1 = require("./index");
var graphql_1 = require("graphql");
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
alwaysThrows: {
name: "alwaysThrows",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_1.alwaysThrows)(source);
function getSchema() {
var QueryType = new graphql_1.GraphQLObjectType({
name: "Query",
fields: function () {
return {
alwaysThrows: {
name: "alwaysThrows",
type: graphql_1.GraphQLString,
resolve: function (source) {
return (0, index_1.alwaysThrows)(source);
}
}
}
};
}
});
var schema = new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
exports.schema = schema;
};
}
});
return new graphql_1.GraphQLSchema({
query: QueryType,
types: [QueryType]
});
}
exports.getSchema = getSchema;

@@ -49,2 +49,13 @@ "use strict";

};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __values = (this && this.__values) || function(o) {

@@ -75,2 +86,5 @@ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;

var printSchema_1 = require("../printSchema");
var metadataDirectives_1 = require("../metadataDirectives");
var semver = require("semver");
var TS_VERSION = ts.version;
var program = new commander_1.Command();

@@ -131,3 +145,2 @@ program

var integrationFixturesDir = path.join(__dirname, "integrationFixtures");
var codegenFixturesDir = path.join(__dirname, "codegenFixtures");
var testDirs = [

@@ -146,6 +159,13 @@ {

var json = firstLine.slice(3);
var testOptions = JSON.parse(json);
var _a = JSON.parse(json), tsVersion = _a.tsVersion, testOptions = __rest(_a, ["tsVersion"]);
if (tsVersion != null && !semver.satisfies(TS_VERSION, tsVersion)) {
console.log("Skipping test because TS version doesn't match", tsVersion, "does not match", TS_VERSION);
return false;
}
options = __assign(__assign({}, options), testOptions);
}
var files = ["".concat(fixturesDir, "/").concat(fileName), "src/Types.ts"];
var files = [
"".concat(fixturesDir, "/").concat(fileName),
path.join(__dirname, "../Types.ts"),
];
var parsedOptions = (0, lib_1.validateGratsOptions)({

@@ -168,3 +188,3 @@ options: {},

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

@@ -178,9 +198,13 @@ 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, {
var sansDirectives = new graphql_1.GraphQLSchema(__assign(__assign({}, schemaResult.value.toConfig()), { directives: schemaResult.value.getDirectives().filter(function (directive) {
return !metadataDirectives_1.METADATA_DIRECTIVE_NAMES.has(directive.name);
}) }));
var sdl = (0, utils_1.printSchemaWithDirectives)(sansDirectives, {
assumeValid: true,
});
return "-- SDL --\n".concat(sdl, "\n-- TypeScript --\n").concat(executableSchema);
}

@@ -194,3 +218,3 @@ },

transformer: function (code, fileName) { return __awaiter(void 0, void 0, void 0, function () {
var filePath, schemaPath, options, files, parsedOptions, schemaResult, tsSchema, server, schemaModule, schemaDiff, data;
var filePath, schemaPath, options, files, parsedOptions, schemaResult, tsSchema, server, schemaModule, actualSchema, schemaDiff, data;
return __generator(this, function (_a) {

@@ -204,3 +228,3 @@ switch (_a.label) {

};
files = [filePath, "src/Types.ts"];
files = [filePath, path.join(__dirname, "../Types.ts")];
parsedOptions = (0, lib_1.validateGratsOptions)({

@@ -234,3 +258,4 @@ options: {

schemaModule = _a.sent();
schemaDiff = compareSchemas(schemaModule.schema, schemaResult.value);
actualSchema = schemaModule.getSchema();
schemaDiff = compareSchemas(actualSchema, schemaResult.value);
if (schemaDiff) {

@@ -242,3 +267,3 @@ console.log(schemaDiff);

return [4 /*yield*/, (0, graphql_1.graphql)({
schema: schemaModule.schema,
schema: actualSchema,
source: server.query,

@@ -254,16 +279,2 @@ variableValues: server.variables,

},
{
fixturesDir: codegenFixturesDir,
testFilePattern: /\.graphql$/,
ignoreFilePattern: null,
transformer: function (code, fileName) { return __awaiter(void 0, void 0, void 0, function () {
var filePath, sdl, schema;
return __generator(this, function (_a) {
filePath = "".concat(codegenFixturesDir, "/").concat(fileName);
sdl = (0, fs_1.readFileSync)(filePath, "utf8");
schema = (0, graphql_1.buildSchema)(sdl);
return [2 /*return*/, (0, codegen_1.codegen)(schema, filePath)];
});
}); },
},
];

@@ -270,0 +281,0 @@ // Returns null if the schemas are equal, otherwise returns a string diff.

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

type Transformer = (code: string, filename: string) => Promise<string> | string;
type Transformer = (code: string, filename: string) => Promise<string | false> | (string | false);
/**

@@ -18,4 +18,4 @@ * Looks in a fixtures dir for .ts files, transforms them according to the

_testFixture(fixture: string): Promise<void>;
transform(code: string, filename: string): Promise<string>;
transform(code: string, filename: string): Promise<string | false>;
}
export {};

@@ -198,2 +198,7 @@ "use strict";

actual = _a.sent();
if (actual === false) {
console.error("SKIPPING: " + displayName);
this._skip.add(fixture);
return [2 /*return*/];
}
actualOutput = "-----------------\nINPUT\n----------------- \n".concat(fixtureContent, "\n-----------------\nOUTPUT\n-----------------\n").concat(actual);

@@ -200,0 +205,0 @@ if (actualOutput !== expectedContent) {

@@ -1,26 +0,11 @@

import { DefinitionNode, DocumentNode, FieldDefinitionNode, InterfaceTypeDefinitionNode, InterfaceTypeExtensionNode, Location, NameNode, ObjectTypeDefinitionNode, ObjectTypeExtensionNode } from "graphql";
import { NameNode } from "graphql";
import * as ts from "typescript";
import { DiagnosticResult, DiagnosticsResult } from "./utils/DiagnosticError";
import { InterfaceMap } from "./InterfaceGraph";
import { ExtractionSnapshot } from "./Extractor";
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;
};
/**
* Information about the GraphQL context type. We track the first value we see,
* and then validate that any other values we see are the same.
*/
type GqlContext = {
declaration: ts.Node;
firstReference: ts.Node;
};
/**
* Used to track TypeScript references.

@@ -39,27 +24,13 @@ *

checker: ts.TypeChecker;
host: ts.CompilerHost;
_options: ts.ParsedCommandLine;
_symbolToName: Map<ts.Symbol, NameDefinition>;
_unresolvedTypes: Map<NameNode, ts.Symbol>;
gqlContext: GqlContext | null;
hasTypename: Set<string>;
constructor(options: ts.ParsedCommandLine, 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;
static fromSnapshot(checker: ts.TypeChecker, snapshot: ExtractionSnapshot): TypeContext;
constructor(checker: ts.TypeChecker);
_recordTypeName(node: ts.Node, name: NameNode, kind: NameDefinition["kind"]): 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>;
validateAsyncIterableFields(doc: DocumentNode): DiagnosticsResult<void>;
validateField(t: ObjectTypeDefinitionNode | ObjectTypeExtensionNode | InterfaceTypeDefinitionNode | InterfaceTypeExtensionNode): ts.Diagnostic | void;
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;
getDestFilePath(sourceFile: ts.SourceFile): {
jsModulePath: string;
tsModulePath: string;
};
unresolvedNameIsGraphQL(unresolved: NameNode): boolean;
getNameDefinition(nameNode: NameNode): DiagnosticsResult<NameDefinition>;
}
export {};

@@ -24,12 +24,24 @@ "use strict";

};
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.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 Result_1 = require("./utils/Result");
var E = require("./Errors");
var InterfaceGraph_1 = require("./InterfaceGraph");
var helpers_1 = require("./utils/helpers");

@@ -50,14 +62,41 @@ exports.UNRESOLVED_REFERENCE_NAME = "__UNRESOLVED_REFERENCE__";

var TypeContext = /** @class */ (function () {
function TypeContext(options, checker, host) {
function TypeContext(checker) {
this._symbolToName = new Map();
this._unresolvedTypes = new Map();
// The resolver context declaration, if it has been encountered.
// Gets mutated by Extractor.
this.gqlContext = null;
this.hasTypename = new Set();
this._options = options;
this.checker = checker;
this.host = host;
}
TypeContext.prototype.recordTypeName = function (node, name, kind) {
TypeContext.fromSnapshot = function (checker, snapshot) {
var e_1, _a, e_2, _b;
var self = new TypeContext(checker);
try {
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];
self._markUnresolvedType(node, typeName);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
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];
self._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; }
}
return self;
};
// Record that a GraphQL construct of type `kind` with the name `name` is
// declared at `node`.
TypeContext.prototype._recordTypeName = function (node, name, kind) {
var symbol = this.checker.getSymbolAtLocation(node);

@@ -74,6 +113,4 @@ if (symbol == null) {

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

@@ -106,131 +143,28 @@ if (symbol == null) {

};
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);
};
// Ensure that all fields on `Subscription` return an AsyncIterable, and that no other
// fields do.
TypeContext.prototype.validateAsyncIterableFields = function (doc) {
var _a;
var _this = this;
var errors = [];
var visitNode = function (t) {
var validateFieldsResult = _this.validateField(t);
if (validateFieldsResult != null) {
errors.push(validateFieldsResult);
TypeContext.prototype.resolveNamedType = function (unresolved) {
var symbol = this._unresolvedTypes.get(unresolved);
if (symbol == null) {
if (unresolved.value === exports.UNRESOLVED_REFERENCE_NAME) {
// This is a logic error on our side.
throw new Error("Unexpected unresolved reference name.");
}
};
(0, graphql_1.visit)(doc, (_a = {},
_a[graphql_1.Kind.INTERFACE_TYPE_DEFINITION] = visitNode,
_a[graphql_1.Kind.INTERFACE_TYPE_EXTENSION] = visitNode,
_a[graphql_1.Kind.OBJECT_TYPE_DEFINITION] = visitNode,
_a[graphql_1.Kind.OBJECT_TYPE_EXTENSION] = visitNode,
_a));
if (errors.length > 0) {
return (0, DiagnosticError_1.err)(errors);
return (0, Result_1.ok)(unresolved);
}
return (0, DiagnosticError_1.ok)(undefined);
};
TypeContext.prototype.validateField = function (t) {
var e_1, _a;
var _b;
if (t.fields == null)
return;
// Note: We assume the default name is used here. When custom operation types are supported
// we'll need to update this.
var isSubscription = t.name.value === "Subscription" &&
(t.kind === graphql_1.Kind.OBJECT_TYPE_DEFINITION ||
t.kind === graphql_1.Kind.OBJECT_TYPE_EXTENSION);
try {
for (var _c = __values(t.fields), _d = _c.next(); !_d.done; _d = _c.next()) {
var field = _d.value;
var asyncDirective = (_b = field.directives) === null || _b === void 0 ? void 0 : _b.find(function (directive) { return directive.name.value === serverDirectives_1.ASYNC_ITERABLE_TYPE_DIRECTIVE; });
if (isSubscription && asyncDirective == null) {
if (field.type.loc == null) {
throw new Error("Expected field type to have a location.");
}
return this.err(field.type.loc, E.subscriptionFieldNotAsyncIterable());
}
if (!isSubscription && asyncDirective != null) {
if (asyncDirective.loc == null) {
throw new Error("Expected asyncDirective to have a location.");
}
return this.err(asyncDirective.loc, // Directive location is the AsyncIterable type.
E.nonSubscriptionFieldAsyncIterable());
}
}
var nameDefinition = this._symbolToName.get(symbol);
if (nameDefinition == null) {
return (0, Result_1.err)((0, DiagnosticError_1.gqlErr)((0, helpers_1.loc)(unresolved), E.unresolvedTypeReference()));
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
}
finally { if (e_1) throw e_1.error; }
}
return (0, Result_1.ok)(__assign(__assign({}, unresolved), { value: nameDefinition.name.value }));
};
// TODO: Is this still used?
TypeContext.prototype.handleAbstractDefinitions = function (docs) {
var e_2, _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_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (docs_1_1 && !docs_1_1.done && (_a = docs_1.return)) _a.call(docs_1);
}
finally { if (e_2) throw e_2.error; }
}
if (errors.length > 0) {
return (0, DiagnosticError_1.err)(errors);
}
return (0, DiagnosticError_1.ok)(newDocs);
TypeContext.prototype.unresolvedNameIsGraphQL = function (unresolved) {
var symbol = this._unresolvedTypes.get(unresolved);
return symbol != null && this._symbolToName.has(symbol);
};
// 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_3, _a;
var _b;
var newDocs = [];
var typeNameResult = this.resolveNamedType(doc.onType);
// 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]);
return (0, Result_1.err)([typeNameResult.err]);
}
var symbol = this._unresolvedTypes.get(doc.onType);
var symbol = this._unresolvedTypes.get(nameNode);
if (symbol == null) {

@@ -245,125 +179,6 @@ // This should have already been handled by resolveNamedType

}
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, // Bit of a lie, but I don't see a better option.
};
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_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
}
finally { if (e_3) throw e_3.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);
return (0, Result_1.ok)(nameDefinition);
};
TypeContext.prototype.resolveNamedType = function (unresolved) {
var symbol = this._unresolvedTypes.get(unresolved);
if (symbol == null) {
if (unresolved.value === exports.UNRESOLVED_REFERENCE_NAME) {
// This is a logic error on our side.
throw new Error("Unexpected unresolved reference name.");
}
return (0, DiagnosticError_1.ok)(unresolved);
}
var nameDefinition = this._symbolToName.get(symbol);
if (nameDefinition == null) {
if (unresolved.loc == null) {
throw new Error("Expected namedType to have a location.");
}
return (0, DiagnosticError_1.err)(this.err(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.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,
};
};
TypeContext.prototype.getDestFilePath = function (sourceFile) {
return (0, gratsRoot_1.getRelativeOutputPath)(this._options, sourceFile);
};
return TypeContext;
}());
exports.TypeContext = TypeContext;
import { GraphQLError, Location, Source } from "graphql";
import * as ts from "typescript";
type Ok<T> = {
kind: "OK";
value: T;
};
type Err<E> = {
kind: "ERROR";
err: E;
};
export type Result<T, E> = Ok<T> | Err<E>;
export type DiagnosticResult<T> = Result<T, ts.Diagnostic>;
export type DiagnosticsResult<T> = Result<T, ts.Diagnostic[]>;
export declare function ok<T>(value: T): Ok<T>;
export declare function err<E>(err: E): Err<E>;
import { Result } from "./Result";
export type DiagnosticResult<T> = Result<T, ts.DiagnosticWithLocation>;
export type DiagnosticsResult<T> = Result<T, ts.DiagnosticWithLocation[]>;
export type DiagnosticsWithoutLocationResult<T> = Result<T, ts.Diagnostic[]>;
export declare class ReportableDiagnostics {

@@ -26,4 +17,6 @@ _host: ts.FormatDiagnosticsHost;

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.DiagnosticWithLocation;
export declare function gqlRelated(loc: Location, message: string): ts.DiagnosticRelatedInformation;
export declare function tsErr(node: ts.Node, message: string, relatedInformation?: ts.DiagnosticRelatedInformation[]): ts.DiagnosticWithLocation;
export declare function tsRelated(node: ts.Node, message: string): ts.DiagnosticRelatedInformation;
export declare function graphqlSourceToSourceFile(source: Source): ts.SourceFile;
export {};

@@ -30,12 +30,4 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.graphqlSourceToSourceFile = exports.diagnosticAtGraphQLLocation = exports.graphQlErrorToDiagnostic = exports.FAKE_ERROR_CODE = exports.ReportableDiagnostics = exports.err = exports.ok = void 0;
exports.graphqlSourceToSourceFile = exports.tsRelated = exports.tsErr = exports.gqlRelated = exports.gqlErr = exports.graphQlErrorToDiagnostic = exports.FAKE_ERROR_CODE = exports.ReportableDiagnostics = void 0;
var ts = require("typescript");
function ok(value) {
return { kind: "OK", value: value };
}
exports.ok = ok;
function err(err) {
return { kind: "ERROR", err: err };
}
exports.err = err;
var ReportableDiagnostics = /** @class */ (function () {

@@ -69,3 +61,3 @@ function ReportableDiagnostics(host, diagnostics) {

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.

@@ -86,3 +78,3 @@ exports.FAKE_ERROR_CODE = 349389149282;

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

@@ -106,10 +98,3 @@ 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"));
}

@@ -139,6 +124,7 @@ }

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

@@ -151,5 +137,45 @@ messageText: message,

length: loc.end - loc.start,
relatedInformation: relatedInformation,
source: "Grats",
};
}
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,
source: "Grats",
};
}
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) {

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

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

import { Location } from "graphql";
export declare class DefaultMap<K, V> {

@@ -8,1 +9,7 @@ private readonly getDefault;

export declare function extend<T>(a: T[], b: readonly T[]): void;
export declare function loc(item: {
loc?: Location;
}): Location;
export declare function astNode<T>(item: {
astNode?: T | undefined | null;
}): T;

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.extend = exports.DefaultMap = void 0;
exports.astNode = exports.loc = exports.extend = exports.DefaultMap = void 0;
var DefaultMap = /** @class */ (function () {

@@ -49,1 +49,15 @@ function DefaultMap(getDefault) {

exports.extend = extend;
function loc(item) {
if (item.loc == null) {
throw new Error("Expected item to have loc");
}
return item.loc;
}
exports.loc = loc;
function astNode(item) {
if (item.astNode == null) {
throw new Error("Expected item to have astNode");
}
return item.astNode;
}
exports.astNode = astNode;
{
"name": "grats",
"version": "0.0.0-main-accb89e4",
"version": "0.0.0-main-afbec52b",
"main": "dist/src/index.js",

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

"dependencies": {
"@graphql-tools/utils": "^9.2.1",
"commander": "^10.0.0",

@@ -19,3 +18,5 @@ "graphql": "^16.6.0",

"devDependencies": {
"@graphql-tools/utils": "^9.2.1",
"@types/node": "^18.14.6",
"@types/semver": "^7.5.6",
"@typescript-eslint/eslint-plugin": "^5.55.0",

@@ -29,2 +30,3 @@ "@typescript-eslint/parser": "^5.55.0",

"process": "^0.11.10",
"semver": "^7.5.4",
"ts-node": "^10.9.1"

@@ -35,3 +37,3 @@ },

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

@@ -46,4 +48,4 @@ "node": ">=16 <=21",

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

@@ -5,3 +5,3 @@ # Grats: Implementation-First GraphQL for TypeScript

_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._
_Beta Software: Grats is largely stable and being used in production in multiple places. If you encounter any issues, don't hesitate to let us know._

@@ -36,3 +36,3 @@ **What if building a GraphQL server were as simple as just writing functions?**

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:
After running `npx grats`, you'll find a `schema.ts` module that exports an executable schema, and a `schema.graphql` file contains your GraphQL schema definition:

@@ -46,3 +46,3 @@ ```graphql

That's just the begining! To learn more, **Read the docs: https://grats.capt.dev/**
That's just the beginning! To learn more, **Read the docs: https://grats.capt.dev/**

@@ -58,3 +58,3 @@ ## Contributing

- [@bradzacher](https://github.com/bradzacher) for tips on how to handle TypeScript ASTs.
- Everyone who worked on Meta's Hack GraphQL server, the developer experince of which inspired this project.
- Everyone who worked on Meta's Hack GraphQL server, the developer experience of which inspired this project.
- A number of other projects which seem to have explored similar ideas in the past:

@@ -61,0 +61,0 @@ - [ts2gql](https://github.com/convoyinc/ts2gql)

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