Comparing version 0.0.0-main-7bba6033 to 0.0.0-main-7da2858f
{ | ||
"name": "grats", | ||
"version": "0.0.5", | ||
"version": "0.0.7", | ||
"main": "dist/src/index.js", | ||
@@ -5,0 +5,0 @@ "bin": "dist/src/cli.js", |
@@ -89,1 +89,3 @@ /** | ||
export declare function graphQLTagNameHasWhitespace(tagName: string): string; | ||
export declare function subscriptionFieldNotAsyncIterable(): string; | ||
export declare function nonSubscriptionFieldAsyncIterable(): string; |
"use strict"; | ||
exports.__esModule = true; | ||
exports.defaultArgPropertyMissingName = exports.defaultArgElementIsNotAssignment = exports.defaultValueIsNotLiteral = exports.ambiguousNumberType = exports.expectedOneNonNullishType = exports.propertyFieldMissingType = exports.cannotResolveSymbolForDescription = exports.promiseMissingTypeArg = exports.methodMissingType = exports.gqlEntityMissingName = exports.enumVariantMissingInitializer = exports.enumVariantNotStringLiteral = exports.enumTagOnInvalidNode = exports.argNotTyped = exports.argNameNotLiteral = exports.argIsNotProperty = exports.argumentParamIsNotObject = exports.argumentParamIsMissingType = exports.typeNameDoesNotMatchExpected = exports.typeNameTypeNotStringLiteral = exports.typeNameMissingTypeAnnotation = exports.typeNameInitializerWrong = exports.typeNameInitializeNotString = exports.typeNameMissingInitializer = exports.typeNameNotDeclaration = exports.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.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.nonSubscriptionFieldAsyncIterable = exports.subscriptionFieldNotAsyncIterable = exports.graphQLTagNameHasWhitespace = exports.graphQLNameHasLeadingNewlines = exports.multipleContextTypes = exports.unexpectedParamSpreadForContextParam = exports.expectedTypeAnnotationOnContextToHaveDeclaration = exports.expectedTypeAnnotationOnContextToBeResolvable = exports.expectedTypeAnnotationOfReferenceOnContext = exports.expectedTypeAnnotationOnContext = exports.unresolvedTypeReference = exports.invalidTypePassedToFieldFunction = exports.parameterPropertyMissingType = exports.parameterPropertyNotPublic = exports.parameterWithoutModifiers = exports.duplicateInterfaceTag = exports.duplicateTag = exports.implementsTagOnTypeAlias = exports.implementsTagOnInterface = exports.implementsTagOnClass = exports.implementsTagMissingValue = exports.mergedInterfaces = exports.nonNullTypeCannotBeOptional = exports.killsParentOnExceptionOnNullable = exports.killsParentOnExceptionWithWrongConfig = exports.expectedIdentifier = exports.pluralTypeMissingParameter = exports.unknownGraphQLType = exports.unsupportedTypeLiteral = exports.defaultArgPropertyMissingInitializer = void 0; | ||
var Extractor_1 = require("./Extractor"); | ||
@@ -349,1 +349,9 @@ // TODO: Move these to short URLS that are easier to keep from breaking. | ||
exports.graphQLTagNameHasWhitespace = graphQLTagNameHasWhitespace; | ||
function subscriptionFieldNotAsyncIterable() { | ||
return "Expected fields on `Subscription` to return an AsyncIterable."; | ||
} | ||
exports.subscriptionFieldNotAsyncIterable = subscriptionFieldNotAsyncIterable; | ||
function nonSubscriptionFieldAsyncIterable() { | ||
return "Unexpected AsyncIterable. Only fields on `Subscription` should return an AsyncIterable."; | ||
} | ||
exports.nonSubscriptionFieldAsyncIterable = nonSubscriptionFieldAsyncIterable; |
@@ -94,3 +94,6 @@ import { FieldDefinitionNode, InputValueDefinitionNode, NamedTypeNode, NameNode, TypeNode, StringValueNode, ConstValueNode, ConstDirectiveNode, EnumValueDefinitionNode, ConstObjectFieldNode, ConstObjectValueNode, ConstListValueNode } from "graphql"; | ||
methodDeclaration(node: ts.MethodDeclaration | ts.MethodSignature): FieldDefinitionNode | null; | ||
collectMethodType(node: ts.TypeNode): TypeNode | null; | ||
collectReturnType(node: ts.TypeNode): { | ||
type: TypeNode; | ||
isStream: boolean; | ||
} | null; | ||
collectPropertyType(node: ts.TypeNode): TypeNode | null; | ||
@@ -107,5 +110,5 @@ maybeUnwrapPromise(node: ts.TypeNode): ts.TypeNode | null; | ||
handleErrorBubbling(parentNode: ts.Node, type: TypeNode): TypeNode; | ||
exportDirective(nameNode: ts.Node, filename: string, functionName: string): ConstDirectiveNode; | ||
exportDirective(nameNode: ts.Node, jsModulePath: string, tsModulePath: string, functionName: string): ConstDirectiveNode; | ||
fieldNameDirective(nameNode: ts.Node, name: string): ConstDirectiveNode; | ||
} | ||
export {}; |
@@ -305,5 +305,6 @@ "use strict"; | ||
} | ||
var type = this.collectMethodType(node.type); | ||
if (type == null) | ||
var returnType = this.collectReturnType(node.type); | ||
if (returnType == null) | ||
return null; | ||
var type = returnType.type, isStream = returnType.isStream; | ||
var args = null; | ||
@@ -323,8 +324,8 @@ var argsParam = node.parameters[1]; | ||
// TODO: Does this work in the browser? | ||
var filename = this.ctx.getDestFilePath(node.parent); | ||
var _a = this.ctx.getDestFilePath(node.parent), jsModulePath = _a.jsModulePath, tsModulePath = _a.tsModulePath; | ||
var directives = [ | ||
this.exportDirective(funcName, filename, funcName.text), | ||
this.exportDirective(funcName, jsModulePath, tsModulePath, funcName.text), | ||
]; | ||
if (funcName.text !== name.value) { | ||
directives.push(this.fieldNameDirective(funcName, funcName.text)); | ||
if (isStream) { | ||
directives.push(this.gql.constDirective(node.type, this.gql.name(node.type, serverDirectives_1.ASYNC_ITERABLE_TYPE_DIRECTIVE), null)); | ||
} | ||
@@ -1111,3 +1112,6 @@ var deprecated = this.collectDeprecated(node); | ||
} | ||
var type = this.collectMethodType(node.type); | ||
var returnType = this.collectReturnType(node.type); | ||
if (returnType == null) | ||
return null; | ||
var type = returnType.type, isStream = returnType.isStream; | ||
// We already reported an error | ||
@@ -1133,2 +1137,5 @@ if (type == null) | ||
} | ||
if (isStream) { | ||
directives.push(this.gql.constDirective(node.type, this.gql.name(node.type, serverDirectives_1.ASYNC_ITERABLE_TYPE_DIRECTIVE), null)); | ||
} | ||
var deprecated = this.collectDeprecated(node); | ||
@@ -1140,7 +1147,25 @@ if (deprecated != null) { | ||
}; | ||
Extractor.prototype.collectMethodType = function (node) { | ||
Extractor.prototype.collectReturnType = function (node) { | ||
if (ts.isTypeReferenceNode(node)) { | ||
var identifier = this.expectIdentifier(node.typeName); | ||
if (identifier == null) | ||
return null; | ||
if (identifier.text == "AsyncIterable") { | ||
if (node.typeArguments == null || node.typeArguments.length === 0) { | ||
// TODO: Better error? | ||
return this.report(node, E.promiseMissingTypeArg()); | ||
} | ||
var t_1 = this.collectType(node.typeArguments[0]); | ||
if (t_1 == null) | ||
return null; | ||
return { type: t_1, isStream: true }; | ||
} | ||
} | ||
var inner = this.maybeUnwrapPromise(node); | ||
if (inner == null) | ||
return null; | ||
return this.collectType(inner); | ||
var t = this.collectType(inner); | ||
if (t == null) | ||
return null; | ||
return { type: t, isStream: false }; | ||
}; | ||
@@ -1160,3 +1185,3 @@ Extractor.prototype.collectPropertyType = function (node) { | ||
if (identifier.text === "Promise") { | ||
if (node.typeArguments == null) { | ||
if (node.typeArguments == null || node.typeArguments.length === 0) { | ||
return this.report(node, E.promiseMissingTypeArg()); | ||
@@ -1348,3 +1373,3 @@ } | ||
// It is a GraphQL best practice to model all fields as nullable. This allows | ||
// the server to handle field level exections by simply returning null for | ||
// the server to handle field level executions by simply returning null for | ||
// that field. | ||
@@ -1370,5 +1395,6 @@ // https://graphql.org/learn/best-practices/#nullability | ||
/* Grats directives */ | ||
Extractor.prototype.exportDirective = function (nameNode, filename, functionName) { | ||
Extractor.prototype.exportDirective = function (nameNode, jsModulePath, tsModulePath, functionName) { | ||
return this.gql.constDirective(nameNode, this.gql.name(nameNode, serverDirectives_1.EXPORTED_DIRECTIVE), [ | ||
this.gql.constArgument(nameNode, this.gql.name(nameNode, serverDirectives_1.EXPORTED_FILENAME_ARG), this.gql.string(nameNode, filename)), | ||
this.gql.constArgument(nameNode, this.gql.name(nameNode, serverDirectives_1.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)), | ||
@@ -1375,0 +1401,0 @@ ]); |
import * as ts from "typescript"; | ||
export declare function getRelativeOutputPath(options: ts.ParsedCommandLine, sourceFile: ts.SourceFile): string; | ||
export declare function getRelativeOutputPath(options: ts.ParsedCommandLine, sourceFile: ts.SourceFile): { | ||
jsModulePath: string; | ||
tsModulePath: string; | ||
}; | ||
export declare function resolveRelativePath(relativePath: string): string; |
@@ -13,3 +13,3 @@ "use strict"; | ||
// step and the runtime can agree on. This path is that thing. | ||
var gratsRoot = __dirname; | ||
var gratsRoot = (0, path_1.join)(__dirname, "../.."); | ||
function getRelativeOutputPath(options, sourceFile) { | ||
@@ -25,3 +25,5 @@ var fileNames = ts.getOutputFileNames(options, sourceFile.fileName, true); | ||
} | ||
return (0, path_1.relative)(gratsRoot, fileNames[0]); | ||
var jsModulePath = (0, path_1.relative)(gratsRoot, fileNames[0]); | ||
var tsModulePath = (0, path_1.relative)(gratsRoot, sourceFile.fileName); | ||
return { jsModulePath: jsModulePath, tsModulePath: tsModulePath }; | ||
} | ||
@@ -28,0 +30,0 @@ exports.getRelativeOutputPath = getRelativeOutputPath; |
@@ -163,2 +163,6 @@ "use strict"; | ||
var doc = docResult.value; | ||
var subscriptionsValidationResult = ctx.validateAsyncIterableFields(doc); | ||
if (subscriptionsValidationResult.kind === "ERROR") { | ||
return subscriptionsValidationResult; | ||
} | ||
// TODO: Currently this does not detect definitions that shadow builtins | ||
@@ -165,0 +169,0 @@ // (`String`, `Int`, etc). However, if we pass a second param (extending an |
@@ -5,5 +5,7 @@ import { DocumentNode, GraphQLSchema } from "graphql"; | ||
export declare const EXPORTED_DIRECTIVE = "exported"; | ||
export declare const EXPORTED_FILENAME_ARG = "filename"; | ||
export declare const JS_MODULE_PATH_ARG = "jsModulePath"; | ||
export declare const TS_MODULE_PATH_ARG = "tsModulePath"; | ||
export declare const EXPORTED_FUNCTION_NAME_ARG = "functionName"; | ||
export declare const ASYNC_ITERABLE_TYPE_DIRECTIVE = "asyncIterable"; | ||
export declare const DIRECTIVES_AST: DocumentNode; | ||
export declare function applyServerDirectives(schema: GraphQLSchema): GraphQLSchema; |
@@ -50,3 +50,3 @@ "use strict"; | ||
exports.__esModule = true; | ||
exports.applyServerDirectives = exports.DIRECTIVES_AST = exports.EXPORTED_FUNCTION_NAME_ARG = exports.EXPORTED_FILENAME_ARG = exports.EXPORTED_DIRECTIVE = exports.METHOD_NAME_ARG = exports.METHOD_NAME_DIRECTIVE = void 0; | ||
exports.applyServerDirectives = exports.DIRECTIVES_AST = exports.ASYNC_ITERABLE_TYPE_DIRECTIVE = exports.EXPORTED_FUNCTION_NAME_ARG = exports.TS_MODULE_PATH_ARG = exports.JS_MODULE_PATH_ARG = exports.EXPORTED_DIRECTIVE = exports.METHOD_NAME_ARG = exports.METHOD_NAME_DIRECTIVE = void 0; | ||
var utils_1 = require("@graphql-tools/utils"); | ||
@@ -59,6 +59,9 @@ var graphql_1 = require("graphql"); | ||
exports.EXPORTED_DIRECTIVE = "exported"; | ||
exports.EXPORTED_FILENAME_ARG = "filename"; | ||
exports.JS_MODULE_PATH_ARG = "jsModulePath"; | ||
exports.TS_MODULE_PATH_ARG = "tsModulePath"; | ||
exports.EXPORTED_FUNCTION_NAME_ARG = "functionName"; | ||
exports.DIRECTIVES_AST = (0, graphql_1.parse)("\n directive @".concat(exports.METHOD_NAME_DIRECTIVE, "(").concat(exports.METHOD_NAME_ARG, ": String!) on FIELD_DEFINITION\n directive @").concat(exports.EXPORTED_DIRECTIVE, "(\n ").concat(exports.EXPORTED_FILENAME_ARG, ": String!,\n ").concat(exports.EXPORTED_FUNCTION_NAME_ARG, ": String!\n ) on FIELD_DEFINITION\n")); | ||
exports.ASYNC_ITERABLE_TYPE_DIRECTIVE = "asyncIterable"; | ||
exports.DIRECTIVES_AST = (0, graphql_1.parse)("\n directive @".concat(exports.ASYNC_ITERABLE_TYPE_DIRECTIVE, " on FIELD_DEFINITION\n directive @").concat(exports.METHOD_NAME_DIRECTIVE, "(").concat(exports.METHOD_NAME_ARG, ": String!) on FIELD_DEFINITION\n directive @").concat(exports.EXPORTED_DIRECTIVE, "(\n ").concat(exports.JS_MODULE_PATH_ARG, ": String!,\n ").concat(exports.TS_MODULE_PATH_ARG, ": String!,\n ").concat(exports.EXPORTED_FUNCTION_NAME_ARG, ": String!\n ) on FIELD_DEFINITION\n")); | ||
function applyServerDirectives(schema) { | ||
// TODO: Throw if the schema is missing our directives! | ||
var _a; | ||
@@ -69,3 +72,3 @@ // TODO: Do we really need all of mapSchema here or can we create our own | ||
_a[utils_1.MapperKind.OBJECT_FIELD] = function (fieldConfig) { | ||
var _a, _b; | ||
var _a, _b, _c; | ||
var newFieldConfig = fieldConfig; | ||
@@ -80,2 +83,6 @@ var methodNameDirective = (_a = (0, utils_1.getDirective)(schema, fieldConfig, exports.METHOD_NAME_DIRECTIVE)) === null || _a === void 0 ? void 0 : _a[0]; | ||
} | ||
var asyncIterableDirective = (_c = (0, utils_1.getDirective)(schema, fieldConfig, exports.ASYNC_ITERABLE_TYPE_DIRECTIVE)) === null || _c === void 0 ? void 0 : _c[0]; | ||
if (asyncIterableDirective != null) { | ||
newFieldConfig = __assign(__assign({}, newFieldConfig), { subscribe: newFieldConfig.resolve, resolve: function (payload) { return payload; } }); | ||
} | ||
return newFieldConfig; | ||
@@ -111,16 +118,21 @@ }, | ||
// TODO: Does this work in the browser? | ||
var filename = (0, gratsRoot_1.resolveRelativePath)(methodNameDirective[exports.EXPORTED_FILENAME_ARG]); | ||
var jsModulePath = (0, gratsRoot_1.resolveRelativePath)(methodNameDirective[exports.JS_MODULE_PATH_ARG]); | ||
var tsModulePath = (0, gratsRoot_1.resolveRelativePath)(methodNameDirective[exports.TS_MODULE_PATH_ARG]); | ||
var functionName = methodNameDirective[exports.EXPORTED_FUNCTION_NAME_ARG]; | ||
var mod = undefined; | ||
var modPromise = undefined; | ||
return __assign(__assign({}, fieldConfig), { resolve: function (source, args, context, info) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var mod, e_1, resolve; | ||
var e_1, resolve; | ||
return __generator(this, function (_a) { | ||
var _b; | ||
switch (_a.label) { | ||
case 0: | ||
mod = {}; | ||
if (modPromise == null) { | ||
modPromise = importWithFallback(jsModulePath, tsModulePath); | ||
} | ||
if (!(mod == null)) return [3 /*break*/, 4]; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, (_b = filename, Promise.resolve().then(function () { return require(_b); }))]; | ||
return [4 /*yield*/, modPromise]; | ||
case 2: | ||
@@ -131,3 +143,3 @@ mod = _a.sent(); | ||
e_1 = _a.sent(); | ||
console.error("Grats Error: Failed to import module `".concat(filename, "`. You may need to rerun Grats.")); | ||
console.error(loadModuleErrorMessage(jsModulePath, tsModulePath)); | ||
throw e_1; | ||
@@ -137,3 +149,4 @@ case 4: | ||
if (typeof resolve !== "function") { | ||
throw new Error("Grats Error: Expected `".concat(filename, "` to have a named export `").concat(functionName, "` that is a function, but it was `").concat(typeof resolve, "`. You may need to rerun Grats.")); | ||
// TODO: Better error message that indicates if it was loaded from JS or TS. | ||
throw new Error("Grats Error: Expected `".concat(tsModulePath, "` to have a named export `").concat(functionName, "` that is a function, but it was `").concat(typeof resolve, "`. You may need to rerun Grats or regenerate the JavaScript version of your module by rerunning the TypeScript compiler.")); | ||
} | ||
@@ -146,1 +159,33 @@ return [2 /*return*/, resolve(source, args, context, info)]; | ||
} | ||
// When people use Grats with loaders like `esbuild-register` or `ts-node`, the | ||
// compiled JavaScript version of the file may not exist on disk. In these specific | ||
// cases, esbuild or ts-node can load the file via its TypeScript source, so we try | ||
// falling back to that. | ||
function importWithFallback(jsModulePath, tsModulePath) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var e_2; | ||
return __generator(this, function (_a) { | ||
var _b, _c; | ||
switch (_a.label) { | ||
case 0: | ||
_a.trys.push([0, 2, , 4]); | ||
return [4 /*yield*/, (_b = tsModulePath, Promise.resolve().then(function () { return require(_b); }))]; | ||
case 1: | ||
// We start with the .ts version because if both exist, and can be loaded, the .ts version is | ||
// going to be more up to date. The downside is that this causes some extra work to be done in | ||
// in prod. This should be manageable since we cache the loaded module for each field. | ||
// It's important that we await here so that we catch the error if the module doesn't exist or | ||
// cannot be parsed. | ||
return [2 /*return*/, _a.sent()]; | ||
case 2: | ||
e_2 = _a.sent(); | ||
return [4 /*yield*/, (_c = jsModulePath, Promise.resolve().then(function () { return require(_c); }))]; | ||
case 3: return [2 /*return*/, _a.sent()]; | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
} | ||
function loadModuleErrorMessage(jsPath, tsPath) { | ||
return "Grats Error: Failed to import module. Tried loading from two locations:\n* `".concat(jsPath, "`\n* `").concat(tsPath, "`\n\nThis can happen for a few reasons:\n\n* You resolver has moved and you need to rerun Grats to regenerate your schema.\n* Your TypeScript code has changed and you need to rerun `tsc` to generate the JavaScript variant of the file.\n* You compiled your TypeScript with a different TSConfig than what you ran Grats with.\n* The Grats NPM module moved between when you ran Grats and when you ran your server."); | ||
} |
import { Int } from "../../Types"; | ||
/** @gqlType */ | ||
export declare class Query { | ||
/** @gqlField */ | ||
firstHundredIntegers(args: { | ||
first: Int | null; | ||
after: string | null; | ||
}): FirstHundredIntegersConnection; | ||
} | ||
type Query = unknown; | ||
/** @gqlField */ | ||
export declare function firstHundredIntegers(_: Query, args: { | ||
first: Int | null; | ||
after: string | null; | ||
}): FirstHundredIntegersConnection; | ||
/** @gqlType */ | ||
@@ -11,0 +10,0 @@ declare class FirstHundredIntegersConnection { |
@@ -7,15 +7,9 @@ "use strict"; | ||
exports.__esModule = true; | ||
exports.query = exports.Query = void 0; | ||
exports.query = exports.firstHundredIntegers = void 0; | ||
/** @gqlField */ | ||
function firstHundredIntegers(_, args) { | ||
return new FirstHundredIntegersConnection(args.first, args.after); | ||
} | ||
exports.firstHundredIntegers = firstHundredIntegers; | ||
/** @gqlType */ | ||
var Query = /** @class */ (function () { | ||
function Query() { | ||
} | ||
/** @gqlField */ | ||
Query.prototype.firstHundredIntegers = function (args) { | ||
return new FirstHundredIntegersConnection(args.first, args.after); | ||
}; | ||
return Query; | ||
}()); | ||
exports.Query = Query; | ||
/** @gqlType */ | ||
var FirstHundredIntegersConnection = /** @class */ (function () { | ||
@@ -22,0 +16,0 @@ function FirstHundredIntegersConnection(first, after) { |
/** @gqlType */ | ||
export declare class Query { | ||
/** @gqlField */ | ||
me(): User; | ||
} | ||
type Query = unknown; | ||
/** @gqlField */ | ||
export declare function me(_: Query): User; | ||
/** @gqlType */ | ||
@@ -7,0 +6,0 @@ declare class User { |
"use strict"; | ||
exports.__esModule = true; | ||
exports.query = exports.Query = void 0; | ||
exports.query = exports.me = void 0; | ||
/** @gqlField */ | ||
function me(_) { | ||
return new User(); | ||
} | ||
exports.me = me; | ||
/** @gqlType */ | ||
var Query = /** @class */ (function () { | ||
function Query() { | ||
} | ||
/** @gqlField */ | ||
Query.prototype.me = function () { | ||
return new User(); | ||
}; | ||
return Query; | ||
}()); | ||
exports.Query = Query; | ||
/** @gqlType */ | ||
var User = /** @class */ (function () { | ||
@@ -17,0 +11,0 @@ function User() { |
/** @gqlType */ | ||
export declare class Query { | ||
/** | ||
* @gqlField | ||
* @killsParentOnException | ||
*/ | ||
alwaysThrowsKillsParentOnException(): string; | ||
/** @gqlField */ | ||
hello: string; | ||
} | ||
type Query = unknown; | ||
/** | ||
* @gqlField | ||
* @killsParentOnException | ||
*/ | ||
export declare function alwaysThrowsKillsParentOnException(_: Query): string; | ||
/** @gqlField */ | ||
export declare function hello(_: Query): string; | ||
export declare const query = "\n query {\n alwaysThrowsKillsParentOnException\n hello\n }\n"; | ||
export {}; |
"use strict"; | ||
exports.__esModule = true; | ||
exports.query = exports.Query = void 0; | ||
/** @gqlType */ | ||
var Query = /** @class */ (function () { | ||
function Query() { | ||
/** @gqlField */ | ||
this.hello = "Hello Worl"; | ||
} | ||
/** | ||
* @gqlField | ||
* @killsParentOnException | ||
*/ | ||
Query.prototype.alwaysThrowsKillsParentOnException = function () { | ||
throw new Error("This error should kill Query"); | ||
}; | ||
return Query; | ||
}()); | ||
exports.Query = Query; | ||
exports.query = exports.hello = exports.alwaysThrowsKillsParentOnException = void 0; | ||
/** | ||
* @gqlField | ||
* @killsParentOnException | ||
*/ | ||
function alwaysThrowsKillsParentOnException(_) { | ||
throw new Error("This error should kill Query"); | ||
} | ||
exports.alwaysThrowsKillsParentOnException = alwaysThrowsKillsParentOnException; | ||
/** @gqlField */ | ||
function hello(_) { | ||
return "Hello Worl"; | ||
} | ||
exports.hello = hello; | ||
exports.query = "\n query {\n alwaysThrowsKillsParentOnException\n hello\n }\n"; |
/** @gqlType */ | ||
export declare class Query { | ||
type Query = unknown; | ||
/** @gqlField */ | ||
export declare function me(_: Query): User; | ||
/** @gqlType */ | ||
declare class User { | ||
/** @gqlField hello */ | ||
@@ -9,2 +13,3 @@ NOT_THIS: string; | ||
} | ||
export declare const query = "\n query {\n hello\n }\n"; | ||
export declare const query = "\n query {\n me {\n hello\n }\n }\n"; | ||
export {}; |
"use strict"; | ||
exports.__esModule = true; | ||
exports.query = exports.Query = void 0; | ||
exports.query = exports.me = void 0; | ||
/** @gqlField */ | ||
function me(_) { | ||
return new User(); | ||
} | ||
exports.me = me; | ||
/** @gqlType */ | ||
var Query = /** @class */ (function () { | ||
function Query( | ||
var User = /** @class */ (function () { | ||
function User( | ||
/** @gqlField hello */ | ||
@@ -12,5 +17,4 @@ NOT_THIS) { | ||
} | ||
return Query; | ||
return User; | ||
}()); | ||
exports.Query = Query; | ||
exports.query = "\n query {\n hello\n }\n"; | ||
exports.query = "\n query {\n me {\n hello\n }\n }\n"; |
/** @gqlType */ | ||
export declare class Query { | ||
/** @gqlField */ | ||
alwaysThrows(): string; | ||
} | ||
type Query = unknown; | ||
/** @gqlField */ | ||
export declare function alwaysThrows(_: Query): string; | ||
export declare const query = "\n query {\n alwaysThrows\n }\n"; | ||
export {}; |
"use strict"; | ||
exports.__esModule = true; | ||
exports.query = exports.Query = void 0; | ||
/** @gqlType */ | ||
var Query = /** @class */ (function () { | ||
function Query() { | ||
} | ||
/** @gqlField */ | ||
Query.prototype.alwaysThrows = function () { | ||
throw new Error("This should null out the field"); | ||
}; | ||
return Query; | ||
}()); | ||
exports.Query = Query; | ||
exports.query = exports.alwaysThrows = void 0; | ||
/** @gqlField */ | ||
function alwaysThrows(_) { | ||
throw new Error("This should null out the field"); | ||
} | ||
exports.alwaysThrows = alwaysThrows; | ||
exports.query = "\n query {\n alwaysThrows\n }\n"; |
@@ -212,4 +212,3 @@ "use strict"; | ||
schema: schema, | ||
source: server.query, | ||
rootValue: server.Query != null ? new server.Query() : null | ||
source: server.query | ||
})]; | ||
@@ -216,0 +215,0 @@ case 2: |
@@ -1,2 +0,2 @@ | ||
import { DefinitionNode, DocumentNode, FieldDefinitionNode, Location, NameNode } from "graphql"; | ||
import { DefinitionNode, DocumentNode, FieldDefinitionNode, InterfaceTypeDefinitionNode, InterfaceTypeExtensionNode, Location, NameNode, ObjectTypeDefinitionNode, ObjectTypeExtensionNode } from "graphql"; | ||
import * as ts from "typescript"; | ||
@@ -52,2 +52,4 @@ import { DiagnosticResult, DiagnosticsResult } from "./utils/DiagnosticError"; | ||
resolveTypes(doc: DocumentNode): DiagnosticsResult<DocumentNode>; | ||
validateAsyncIterableFields(doc: DocumentNode): DiagnosticsResult<void>; | ||
validateField(t: ObjectTypeDefinitionNode | ObjectTypeExtensionNode | InterfaceTypeDefinitionNode | InterfaceTypeExtensionNode): ts.Diagnostic | void; | ||
handleAbstractDefinitions(docs: GratsDefinitionNode[]): DiagnosticsResult<DefinitionNode[]>; | ||
@@ -58,5 +60,7 @@ addAbstractFieldDefinition(doc: AbstractFieldDefinitionNode, interfaceGraph: InterfaceMap): DiagnosticsResult<DefinitionNode[]>; | ||
relatedInformation(loc: Location, message: string): ts.DiagnosticRelatedInformation; | ||
validateInterfaceImplementorsHaveTypenameField(): DiagnosticResult<null>; | ||
getDestFilePath(sourceFile: ts.SourceFile): string; | ||
getDestFilePath(sourceFile: ts.SourceFile): { | ||
jsModulePath: string; | ||
tsModulePath: string; | ||
}; | ||
} | ||
export {}; |
@@ -122,4 +122,65 @@ "use strict"; | ||
}; | ||
// 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); | ||
} | ||
}; | ||
(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, 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()); | ||
} | ||
} | ||
} | ||
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; } | ||
} | ||
}; | ||
// TODO: Is this still used? | ||
TypeContext.prototype.handleAbstractDefinitions = function (docs) { | ||
var e_1, _a; | ||
var e_2, _a; | ||
var newDocs = []; | ||
@@ -149,3 +210,3 @@ var errors = []; | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
@@ -155,3 +216,3 @@ try { | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
@@ -166,3 +227,3 @@ if (errors.length > 0) { | ||
TypeContext.prototype.addAbstractFieldDefinition = function (doc, interfaceGraph) { | ||
var e_2, _a; | ||
var e_3, _a; | ||
var _b; | ||
@@ -235,3 +296,3 @@ var newDocs = []; | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
catch (e_3_1) { e_3 = { error: e_3_1 }; } | ||
finally { | ||
@@ -241,3 +302,3 @@ try { | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
finally { if (e_3) throw e_3.error; } | ||
} | ||
@@ -304,5 +365,2 @@ break; | ||
}; | ||
TypeContext.prototype.validateInterfaceImplementorsHaveTypenameField = function () { | ||
return (0, DiagnosticError_1.ok)(null); | ||
}; | ||
TypeContext.prototype.getDestFilePath = function (sourceFile) { | ||
@@ -309,0 +367,0 @@ return (0, gratsRoot_1.getRelativeOutputPath)(this._options, sourceFile); |
{ | ||
"name": "grats", | ||
"version": "0.0.0-main-7bba6033", | ||
"version": "0.0.0-main-7da2858f", | ||
"main": "dist/src/index.js", | ||
@@ -5,0 +5,0 @@ "bin": "dist/src/cli.js", |
# -=[ ALPHA SOFTWARE ]=- | ||
**Grats is still experimental. Feel free to try it out and give feedback, but they api is still in flux** | ||
**Grats is still experimental. Feel free to try it out and give feedback, but the api is still in flux** | ||
@@ -5,0 +5,0 @@ # Grats: Implementation-First GraphQL for TypeScript |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
220744
682
51
4525
81
7