Socket
Socket
Sign inDemoInstall

apollo-server-core

Package Overview
Dependencies
Maintainers
6
Versions
314
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apollo-server-core - npm Package Compare versions

Comparing version 1.4.0-alpha.0 to 2.0.0-beta.0

CHANGELOG.md

49

dist/ApolloServer.d.ts

@@ -1,12 +0,39 @@

/// <reference types="@types/node" />
import { Server as HTTPServer } from 'http';
export declare class ApolloServer<Server = HTTPServer> {
server: Server;
constructor(config: any);
private applyMiddleware(server);
private start(config, callback);
/// <reference types="node" />
import { Server as HttpServer } from 'http';
import { GraphQLSchema, GraphQLError, GraphQLResolveInfo, ValidationContext } from 'graphql';
import { LogFunction } from './runQuery';
import { Config, ListenOptions, RegistrationOptions, ServerInfo } from './types';
export declare class ApolloServerBase<Request = RequestInit> {
subscriptions: Config<Request>['subscriptions'];
disableTools: boolean;
private schema;
private context?;
private requestOptions;
private graphqlPath;
private engine;
private engineEnabled;
private http?;
protected getHttp: () => HttpServer;
constructor(config: Config<Request>);
use({getHttp, path}: RegistrationOptions): void;
listen(opts?: ListenOptions): Promise<ServerInfo>;
stop(): Promise<void>;
private createSubscriptionServer(server, config);
private createEngine({engineInRequestPath, engine});
request(request: Request): Promise<{
schema: GraphQLSchema;
formatError: Function | ((e: GraphQLError) => GraphQLError);
rootValue?: any;
context: any;
logFunction?: LogFunction;
formatParams?: Function;
validationRules?: ((context: ValidationContext) => any)[];
formatResponse?: Function;
fieldResolver?: (source: any, args: {
[argName: string]: any;
}, context: any, info: GraphQLResolveInfo) => any;
debug?: boolean;
tracing: boolean;
cacheControl: any;
}>;
}
export declare class ExpressServer extends ApolloServer {
constructor(config: any);
private applyMiddleware(options);
}
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__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;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

@@ -47,45 +45,228 @@ return new (P || (P = Promise))(function (resolve, reject) {

};
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)
t[p[i]] = s[p[i]];
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
var ApolloServer = (function () {
function ApolloServer(config) {
var graphql_tools_1 = require("graphql-tools");
var graphql_1 = require("graphql");
var subscriptions_transport_ws_1 = require("subscriptions-transport-ws");
var errors_1 = require("./errors");
var env = process.env.NODE_ENV;
var isDev = env !== 'production' && env !== 'test';
var NoIntrospection = function (context) { return ({
Field: function (node) {
if (node.name.value === '__schema' || node.name.value === '__type') {
context.reportError(new graphql_1.GraphQLError('GraphQL introspection is not allowed by Apollo Server, but the query containted __schema or __type. To enable introspection, pass enableIntrospection: true to ApolloServer in production', [node]));
}
},
}); };
var ApolloServerBase = (function () {
function ApolloServerBase(config) {
this.disableTools = !isDev;
this.graphqlPath = '/graphql';
this.engineEnabled = false;
var context = config.context, resolvers = config.resolvers, schema = config.schema, schemaDirectives = config.schemaDirectives, subscriptions = config.subscriptions, typeDefs = config.typeDefs, enableIntrospection = config.enableIntrospection, mocks = config.mocks, requestOptions = __rest(config, ["context", "resolvers", "schema", "schemaDirectives", "subscriptions", "typeDefs", "enableIntrospection", "mocks"]);
if (enableIntrospection || isDev)
this.disableTools = false;
if (this.disableTools) {
var noIntro = [NoIntrospection];
requestOptions.validationRules = requestOptions.validationRules
? requestOptions.validationRules.concat(noIntro)
: noIntro;
}
this.requestOptions = requestOptions;
this.context = context;
this.schema = schema
? schema
: graphql_tools_1.makeExecutableSchema({
typeDefs: Array.isArray(typeDefs)
? typeDefs.reduce(function (prev, next) { return prev + '\n' + next; })
: typeDefs,
schemaDirectives: schemaDirectives,
resolvers: resolvers,
});
if (mocks) {
graphql_tools_1.addMockFunctionsToSchema({
schema: this.schema,
preserveResolvers: true,
mocks: typeof mocks === 'boolean' ? {} : mocks,
});
}
this.subscriptions = subscriptions;
}
ApolloServer.prototype.applyMiddleware = function (server) {
return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) {
return [2];
}); });
ApolloServerBase.prototype.use = function (_a) {
var getHttp = _a.getHttp, path = _a.path;
this.getHttp = getHttp;
this.graphqlPath = path;
};
ApolloServer.prototype.start = function (config, callback) { };
return ApolloServer;
}());
exports.ApolloServer = ApolloServer;
var ExpressServer = (function (_super) {
__extends(ExpressServer, _super);
function ExpressServer(config) {
ApolloServerBase.prototype.listen = function (opts) {
var _this = this;
_this.server = config.server;
return _this;
}
ExpressServer.prototype.applyMiddleware = function (options) {
if (opts === void 0) { opts = {}; }
this.http = this.getHttp();
var options = __assign({ port: process.env.PORT || 4000 }, opts);
if (this.subscriptions !== false) {
var config = this.subscriptions === true || typeof this.subscriptions === 'undefined'
? {
path: this.graphqlPath,
}
: this.subscriptions;
this.createSubscriptionServer(this.http, config);
}
if (opts.engine || opts.engineInRequestPath)
this.createEngine(opts);
return new Promise(function (success, fail) {
if (_this.engine) {
_this.engine.listen(Object.assign({}, options.engineLauncherOptions, {
graphqlPaths: [_this.graphqlPath],
port: options.port,
httpServer: _this.http,
}), function () {
_this.engine.engineListeningAddress.url = require('url').resolve(_this.engine.engineListeningAddress.url, _this.graphqlPath);
success(_this.engine.engineListeningAddress);
});
_this.engine.on('error', fail);
return;
}
_this.http.listen({
port: options.port,
host: options.host,
path: options.path,
backlog: options.backlog,
exclusive: options.exclusive,
}, function () {
var la = _this.http.address();
var hostForUrl = la.address;
if (la.address === '' || la.address === '::')
hostForUrl = 'localhost';
la.url = require('url').format({
protocol: 'http',
hostname: hostForUrl,
port: la.port,
pathname: _this.graphqlPath,
});
success(la);
});
});
};
ApolloServerBase.prototype.stop = function () {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
this.server.use(options.endpoint, cors(options.cors), graphqlExpress(function (req) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, {
tracing: true,
cacheControl: true,
schema: makeExecutableSchema({
typeDefs: this.typeDefs,
resolvers: this.resolvers,
}),
}];
});
}); }));
return [2];
switch (_a.label) {
case 0:
if (!this.engine) return [3, 2];
return [4, this.engine.stop()];
case 1:
_a.sent();
_a.label = 2;
case 2:
if (!this.http) return [3, 4];
return [4, new Promise(function (s) { return _this.http.close(s); })];
case 3:
_a.sent();
_a.label = 4;
case 4: return [2];
}
});
});
};
return ExpressServer;
}(ApolloServer));
exports.ExpressServer = ExpressServer;
ApolloServerBase.prototype.createSubscriptionServer = function (server, config) {
var _this = this;
var onDisconnect = config.onDisconnect, onConnect = config.onConnect, keepAlive = config.keepAlive;
subscriptions_transport_ws_1.SubscriptionServer.create({
schema: this.schema,
execute: graphql_1.execute,
subscribe: graphql_1.subscribe,
onConnect: onConnect
? onConnect
: function (connectionParams) { return (__assign({}, connectionParams)); },
onDisconnect: onDisconnect,
onOperation: function (_, connection) { return __awaiter(_this, void 0, void 0, function () {
var context, _a, e_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
connection.formatResponse = function (value) { return (__assign({}, value, { errors: value.errors && value.errors.map(function (err) { return errors_1.internalFormatError(err); }) })); };
context = this.context ? this.context : { connection: connection };
_b.label = 1;
case 1:
_b.trys.push([1, 5, , 6]);
if (!(typeof this.context === 'function')) return [3, 3];
return [4, this.context({ connection: connection })];
case 2:
_a = _b.sent();
return [3, 4];
case 3:
_a = context;
_b.label = 4;
case 4:
context = _a;
return [3, 6];
case 5:
e_1 = _b.sent();
console.error(e_1);
throw e_1;
case 6: return [2, __assign({}, connection, { context: context })];
}
});
}); },
keepAlive: keepAlive,
}, {
server: server,
path: this.graphqlPath,
});
};
ApolloServerBase.prototype.createEngine = function (_a) {
var engineInRequestPath = _a.engineInRequestPath, engine = _a.engine;
var _b = process.env, ENGINE_API_KEY = _b.ENGINE_API_KEY, ENGINE_CONFIG = _b.ENGINE_CONFIG;
if (engine === false && (ENGINE_API_KEY || ENGINE_CONFIG)) {
console.warn('engine is set to false when creating ApolloServer but either ENGINE_CONFIG or ENGINE_API_KEY was found in the environment');
}
var ApolloEngine;
if (engine) {
try {
ApolloEngine = require('apollo-engine').ApolloEngine;
}
catch (e) {
console.warn("ApolloServer was unable to load Apollo Engine yet engine was configured in the options when creating this ApolloServer? To fix this, run the following command:\n\n npm install apollo-engine --save\n");
}
this.engine = new ApolloEngine(typeof engine === 'boolean' ? undefined : engine);
}
if (this.engine || engineInRequestPath)
this.engineEnabled = true;
};
ApolloServerBase.prototype.request = function (request) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
var context, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
context = this.context ? this.context : { request: request };
if (!(typeof this.context === 'function')) return [3, 2];
return [4, this.context({ req: request })];
case 1:
_a = _b.sent();
return [3, 3];
case 2:
_a = context;
_b.label = 3;
case 3:
context = _a;
return [2, __assign({ schema: this.schema, tracing: Boolean(this.engineEnabled), cacheControl: Boolean(this.engineEnabled), formatError: function (e) {
return errors_1.internalFormatError(e, _this.requestOptions.debug);
}, context: context }, this.requestOptions)];
}
});
});
};
return ApolloServerBase;
}());
exports.ApolloServerBase = ApolloServerBase;
//# sourceMappingURL=ApolloServer.js.map
import { GraphQLError } from 'graphql';
export interface IApolloError {
}
export declare class ApolloError extends Error {
extensions: any;
constructor(message: string, code: string, properties?: Record<string, any>);
constructor(message: string, code?: string, properties?: Record<string, any>);
}
export declare function formatError(error: GraphQLError, debug?: boolean): GraphQLError;
export declare function internalFormatError(error: GraphQLError, debug?: boolean): GraphQLError;
export declare function toApolloError(error: Error, code?: string): Error & {
extensions: Record<string, any>;
};
export declare function fromGraphQLError(error: GraphQLError, code?: string): GraphQLError;
export declare class ParseError extends ApolloError {
name: string;
export interface ErrorOptions {
code?: string;
errorClass?: typeof ApolloError;
}
export declare function fromGraphQLError(error: GraphQLError, options?: ErrorOptions): GraphQLError;
export declare class SyntaxError extends ApolloError {
constructor(message: string);
}
export declare class ValidationError extends ApolloError {
name: string;
constructor(message: string);
}
export declare class AuthenticationError extends ApolloError {
name: string;
constructor(message: string);
}
export declare class ForbiddenError extends ApolloError {
constructor(message: string);
}

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

exports.ApolloError = ApolloError;
function formatError(error, debug) {
function internalFormatError(error, debug) {
if (debug === void 0) { debug = false; }
var expanded = __assign({}, error, { extensions: __assign({}, error.extensions, { code: (error.extensions && error.extensions.code) || 'INTERNAL_ERROR', exception: __assign({}, (error.extensions && error.extensions.exception), error.originalError) }) });
var expanded = __assign({ message: error.message, path: error.path, locations: error.locations }, error, { extensions: __assign({}, error.extensions, { code: (error.extensions && error.extensions.code) || 'INTERNAL_SERVER_ERROR', exception: __assign({}, (error.extensions && error.extensions.exception), error.originalError) }) });
delete expanded.extensions.exception.extensions;

@@ -48,5 +48,5 @@ if (debug && !expanded.extensions.exception.stacktrace) {

}
exports.formatError = formatError;
exports.internalFormatError = internalFormatError;
function toApolloError(error, code) {
if (code === void 0) { code = 'INTERNAL_ERROR'; }
if (code === void 0) { code = 'INTERNAL_SERVER_ERROR'; }
var err = error;

@@ -62,6 +62,13 @@ if (err.extensions) {

exports.toApolloError = toApolloError;
function fromGraphQLError(error, code) {
if (code === void 0) { code = 'INTERNAL_ERROR'; }
var copy = __assign({}, error);
copy.extensions = __assign({}, copy.extensions, { code: code });
function fromGraphQLError(error, options) {
var copy = options && options.errorClass
? new options.errorClass(error.message)
: new ApolloError(error.message);
Object.keys(error).forEach(function (key) {
copy[key] = error[key];
});
copy.extensions = __assign({}, copy.extensions, error.extensions);
if (!copy.extensions.code) {
copy.extensions.code = (options && options.code) || 'INTERNAL_SERVER_ERROR';
}
Object.defineProperty(copy, 'originalError', { value: {} });

@@ -74,18 +81,14 @@ Reflect.ownKeys(error).forEach(function (key) {

exports.fromGraphQLError = fromGraphQLError;
var ParseError = (function (_super) {
__extends(ParseError, _super);
function ParseError(message) {
var _this = _super.call(this, message, 'MALFORMED_QUERY') || this;
_this.name = 'MalformedQueryError';
return _this;
var SyntaxError = (function (_super) {
__extends(SyntaxError, _super);
function SyntaxError(message) {
return _super.call(this, message, 'GRAPHQL_PARSE_FAILED') || this;
}
return ParseError;
return SyntaxError;
}(ApolloError));
exports.ParseError = ParseError;
exports.SyntaxError = SyntaxError;
var ValidationError = (function (_super) {
__extends(ValidationError, _super);
function ValidationError(message) {
var _this = _super.call(this, message, 'QUERY_VALIDATION_FAILED') || this;
_this.name = 'ValidationError';
return _this;
return _super.call(this, message, 'GRAPHQL_VALIDATION_FAILED') || this;
}

@@ -98,5 +101,3 @@ return ValidationError;

function AuthenticationError(message) {
var _this = _super.call(this, message, 'UNAUTHORIZED') || this;
_this.name = 'UnauthorizedError';
return _this;
return _super.call(this, message, 'UNAUTHENTICATED') || this;
}

@@ -106,2 +107,10 @@ return AuthenticationError;

exports.AuthenticationError = AuthenticationError;
var ForbiddenError = (function (_super) {
__extends(ForbiddenError, _super);
function ForbiddenError(message) {
return _super.call(this, message, 'FORBIDDEN') || this;
}
return ForbiddenError;
}(ApolloError));
exports.ForbiddenError = ForbiddenError;
//# sourceMappingURL=errors.js.map
import { GraphQLSchema, ValidationContext, GraphQLFieldResolver } from 'graphql';
import { LogFunction } from './runQuery';
import { CacheControlExtensionOptions } from 'apollo-cache-control';
export interface GraphQLServerOptions<TContext = any> {

@@ -16,5 +15,5 @@ schema: GraphQLSchema;

tracing?: boolean;
cacheControl?: boolean | CacheControlExtensionOptions;
cacheControl?: boolean | any;
}
export default GraphQLServerOptions;
export declare function resolveGraphqlOptions(options: GraphQLServerOptions | Function, ...args: any[]): Promise<GraphQLServerOptions>;
export { runQuery, LogFunction, LogMessage, LogStep, LogAction } from './runQuery';
export { runHttpQuery, HttpQueryRequest, HttpQueryError } from './runHttpQuery';
export { default as GraphQLOptions, resolveGraphqlOptions } from './graphqlOptions';
export { ApolloError, toApolloError, ParseError, ValidationError, AuthenticationError, formatError } from './errors';
export { ApolloError, toApolloError, SyntaxError, ValidationError, AuthenticationError, ForbiddenError, internalFormatError } from './errors';
export { ApolloServerBase } from './ApolloServer';
export * from './types';

@@ -15,6 +15,9 @@ "use strict";

exports.toApolloError = errors_1.toApolloError;
exports.ParseError = errors_1.ParseError;
exports.SyntaxError = errors_1.SyntaxError;
exports.ValidationError = errors_1.ValidationError;
exports.AuthenticationError = errors_1.AuthenticationError;
exports.formatError = errors_1.formatError;
exports.ForbiddenError = errors_1.ForbiddenError;
exports.internalFormatError = errors_1.internalFormatError;
var ApolloServer_1 = require("./ApolloServer");
exports.ApolloServerBase = ApolloServer_1.ApolloServerBase;
//# sourceMappingURL=index.js.map

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

case 4:
formatErrorFn = function (error) {
return optionsObject.formatError(errors_1.formatError(error)) || errors_1.formatError;
};
formatErrorFn = optionsObject.formatError
? function (error) { return optionsObject.formatError(errors_1.internalFormatError(error)); }
: errors_1.internalFormatError;
debugDefault = process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test';

@@ -121,2 +121,22 @@ debug = optionsObject.debug !== undefined ? optionsObject.debug : debugDefault;

var query = requestParams.query;
var extensions = requestParams.extensions;
if (isGetRequest && extensions) {
try {
extensions = JSON.parse(extensions);
}
catch (error) {
throw new HttpQueryError(400, 'Extensions are invalid JSON.');
}
}
if (query === undefined && extensions && extensions.persistedQuery) {
throw new HttpQueryError(200, JSON.stringify({
errors: [
{
message: 'PersistedQueryNotSupported',
},
],
}), true, {
'Content-Type': 'application/json',
});
}
if (isGetRequest) {

@@ -161,3 +181,3 @@ if (typeof query === 'string') {

validationRules: optionsObject.validationRules,
formatError: optionsObject.formatError,
formatError: formatErrorFn,
formatResponse: optionsObject.formatResponse,

@@ -164,0 +184,0 @@ fieldResolver: optionsObject.fieldResolver,

import { GraphQLSchema, GraphQLFieldResolver, DocumentNode, GraphQLError, ValidationContext } from 'graphql';
import { CacheControlExtensionOptions } from 'apollo-cache-control';
export interface GraphQLResponse {

@@ -23,3 +22,3 @@ data?: object;

key?: string;
data?: Object;
data?: any;
}

@@ -45,4 +44,4 @@ export interface LogFunction {

tracing?: boolean;
cacheControl?: boolean | CacheControlExtensionOptions;
cacheControl?: boolean | any;
}
export declare function runQuery(options: QueryOptions): Promise<GraphQLResponse>;

@@ -25,8 +25,5 @@ "use strict";

exports.runQuery = runQuery;
function printStackTrace(error) {
console.error(error.stack);
}
function format(errors, options) {
var formatter = options.formatter, debug = options.debug;
return errors.map(function (error) { return errors_1.formatError(error, debug); }).map(function (error) {
return errors.map(function (error) { return errors_1.internalFormatError(error, debug); }).map(function (error) {
if (formatter !== undefined) {

@@ -38,4 +35,4 @@ try {

console.error('Error in formatError function:', err);
var newError = errors_1.fromGraphQLError(new graphql_1.GraphQLError('Internal server error'), 'INTERNAL_ERROR');
return errors_1.formatError(newError, debug);
var newError = errors_1.fromGraphQLError(new graphql_1.GraphQLError('Internal server error'));
return errors_1.internalFormatError(newError, debug);
}

@@ -102,3 +99,7 @@ }

return Promise.resolve({
errors: format([errors_1.fromGraphQLError(syntaxError, 'MALFORMED_QUERY')], {
errors: format([
errors_1.fromGraphQLError(syntaxError, {
errorClass: errors_1.SyntaxError,
}),
], {
formatter: options.formatError,

@@ -123,3 +124,3 @@ debug: debug,

errors: format(validationErrors.map(function (err) {
return errors_1.fromGraphQLError(err, 'QUERY_VALIDATION_FAILED');
return errors_1.fromGraphQLError(err, { errorClass: errors_1.ValidationError });
}), {

@@ -138,3 +139,2 @@ formatter: options.formatError,

logFunction({ action: LogAction.execute, step: LogStep.end });
logFunction({ action: LogAction.request, step: LogStep.end });
var response = {

@@ -148,5 +148,2 @@ data: result.data,

});
if (debug) {
result.errors.map(printStackTrace);
}
}

@@ -161,2 +158,8 @@ if (extensionStack) {

}
logFunction({
action: LogAction.request,
step: LogStep.end,
key: 'response',
data: response,
});
return response;

@@ -169,3 +172,3 @@ });

return Promise.resolve({
errors: format([errors_1.fromGraphQLError(executionError, 'EXECUTION_ERROR')], {
errors: format([errors_1.fromGraphQLError(executionError)], {
formatter: options.formatError,

@@ -172,0 +175,0 @@ debug: debug,

{
"name": "apollo-server-core",
"version": "1.4.0-alpha.0",
"version": "2.0.0-beta.0",
"description": "Core engine for Apollo GraphQL server",

@@ -30,8 +30,11 @@ "main": "dist/index.js",

"@types/graphql": "0.12.7",
"@types/node": "^9.6.1",
"@types/ws": "^4.0.2",
"apollo-engine": "^1.0.6",
"fibers": "1.0.15",
"meteor-promise": "0.8.6",
"typescript": "2.8.1"
"typescript": "2.8.3"
},
"peerDependencies": {
"graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0"
"graphql": "^0.12.0 || ^0.13.0 || ^14.0.0"
},

@@ -43,6 +46,10 @@ "typings": "dist/index.d.ts",

"dependencies": {
"apollo-cache-control": "^0.1.0",
"apollo-cache-control": "^0.1.1",
"apollo-tracing": "^0.1.0",
"graphql-extensions": "^0.0.x"
"graphql-extensions": "^0.0.x",
"graphql-subscriptions": "^0.5.8",
"graphql-tools": "^2.23.1",
"subscriptions-transport-ws": "^0.9.7",
"ws": "^5.1.1"
}
}
import { GraphQLError } from 'graphql';
export interface IApolloError {}
export class ApolloError extends Error {
public extensions;
constructor(message: string, code: string, properties?: Record<string, any>) {
constructor(
message: string,
code?: string,
properties?: Record<string, any>,
) {
super(message);

@@ -12,8 +15,15 @@ this.extensions = { ...properties, code };

export function formatError(error: GraphQLError, debug: boolean = false) {
export function internalFormatError(
error: GraphQLError,
debug: boolean = false,
) {
const expanded: GraphQLError = {
message: error.message,
path: error.path,
locations: error.locations,
...error,
extensions: {
...error.extensions,
code: (error.extensions && error.extensions.code) || 'INTERNAL_ERROR',
code:
(error.extensions && error.extensions.code) || 'INTERNAL_SERVER_ERROR',
exception: {

@@ -48,3 +58,3 @@ ...(error.extensions && error.extensions.exception),

error: Error,
code: string = 'INTERNAL_ERROR',
code: string = 'INTERNAL_SERVER_ERROR',
): Error & { extensions: Record<string, any> } {

@@ -60,14 +70,29 @@ let err: GraphQLError = error;

export function fromGraphQLError(
error: GraphQLError,
code: string = 'INTERNAL_ERROR',
) {
const copy: GraphQLError = {
...error,
};
export interface ErrorOptions {
code?: string;
errorClass?: typeof ApolloError;
}
export function fromGraphQLError(error: GraphQLError, options?: ErrorOptions) {
const copy: GraphQLError =
options && options.errorClass
? new options.errorClass(error.message)
: new ApolloError(error.message);
//copy enumerable keys
Object.keys(error).forEach(key => {
copy[key] = error[key];
});
//extensions are non enumerable, so copy them directly
copy.extensions = {
...copy.extensions,
code,
...error.extensions,
};
//Fallback on default for code
if (!copy.extensions.code) {
copy.extensions.code = (options && options.code) || 'INTERNAL_SERVER_ERROR';
}
//copy the original error, while keeping all values non-enumerable, so they

@@ -83,6 +108,7 @@ //are not printed unless directly referenced

export class ParseError extends ApolloError {
name = 'MalformedQueryError';
export class SyntaxError extends ApolloError {
// TODO make the name nonenumerable
// name = 'SyntaxError';
constructor(message: string) {
super(message, 'MALFORMED_QUERY');
super(message, 'GRAPHQL_PARSE_FAILED');
}

@@ -92,5 +118,6 @@ }

export class ValidationError extends ApolloError {
name = 'ValidationError';
// TODO make the name nonenumerable
// name = 'ValidationError';
constructor(message: string) {
super(message, 'QUERY_VALIDATION_FAILED');
super(message, 'GRAPHQL_VALIDATION_FAILED');
}

@@ -100,6 +127,15 @@ }

export class AuthenticationError extends ApolloError {
name = 'UnauthorizedError';
// TODO make the name nonenumerable
// name = 'AuthenticationError';
constructor(message: string) {
super(message, 'UNAUTHORIZED');
super(message, 'UNAUTHENTICATED');
}
}
export class ForbiddenError extends ApolloError {
// TODO make the name nonenumerable
// name = 'ForbiddenError';
constructor(message: string) {
super(message, 'FORBIDDEN');
}
}

@@ -8,3 +8,2 @@ import {

import { GraphQLExtension } from 'graphql-extensions';
import { CacheControlExtensionOptions } from 'apollo-cache-control';

@@ -38,3 +37,4 @@ /*

tracing?: boolean;
cacheControl?: boolean | CacheControlExtensionOptions;
// cacheControl?: boolean | CacheControlExtensionOptions;
cacheControl?: boolean | any;
}

@@ -41,0 +41,0 @@

@@ -16,6 +16,11 @@ export {

toApolloError,
ParseError,
SyntaxError,
ValidationError,
AuthenticationError,
formatError,
ForbiddenError,
internalFormatError,
} from './errors';
// ApolloServer Base class
export { ApolloServerBase } from './ApolloServer';
export * from './types';

@@ -7,3 +7,3 @@ import { parse, getOperationAST, DocumentNode, ExecutionResult } from 'graphql';

} from './graphqlOptions';
import { formatError } from './errors';
import { internalFormatError } from './errors';

@@ -55,4 +55,5 @@ export interface HttpQueryRequest {

}
const formatErrorFn = error =>
optionsObject.formatError(formatError(error)) || formatError;
const formatErrorFn = optionsObject.formatError
? error => optionsObject.formatError(internalFormatError(error))
: internalFormatError;
const debugDefault =

@@ -106,7 +107,50 @@ process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test';

let query = requestParams.query;
let extensions = requestParams.extensions;
if (isGetRequest && extensions) {
// For GET requests, we have to JSON-parse extensions. (For POST
// requests they get parsed as part of parsing the larger body they're
// inside.)
try {
extensions = JSON.parse(extensions);
} catch (error) {
throw new HttpQueryError(400, 'Extensions are invalid JSON.');
}
}
if (query === undefined && extensions && extensions.persistedQuery) {
// It looks like we've received an Apollo Persisted Query. Apollo Server
// does not support persisted queries out of the box, so we should fail
// fast with a clear error saying that we don't support APQs. (A future
// version of Apollo Server may support APQs directly.)
throw new HttpQueryError(
// Return 200 to simplify processing: we want this to be intepreted by
// the client as data worth interpreting, not an error.
200,
JSON.stringify({
errors: [
{
message: 'PersistedQueryNotSupported',
},
],
}),
true,
{
'Content-Type': 'application/json',
},
);
}
if (isGetRequest) {
if (typeof query === 'string') {
// preparse the query incase of GET so we can assert the operation.
// XXX This makes the type of 'query' in this function confused
// which has led to us accidentally supporting GraphQL AST over
// the wire as a valid query, which confuses users. Refactor to
// not do this. Also, for a GET request, query really shouldn't
// ever be anything other than a string or undefined, so this
// set of conditionals doesn't quite make sense.
query = parse(query);
} else if (!query) {
// Note that we've already thrown a different error if it looks like APQ.
throw new HttpQueryError(400, 'Must provide query string.');

@@ -128,6 +172,9 @@ }

const operationName = requestParams.operationName;
let variables = requestParams.variables;
if (typeof variables === 'string') {
try {
// XXX Really we should only do this for GET requests, but for
// compatibility reasons we'll keep doing this at least for now for
// broken clients that ship variables in a string for no good reason.
variables = JSON.parse(variables);

@@ -158,3 +205,3 @@ } catch (error) {

validationRules: optionsObject.validationRules,
formatError: optionsObject.formatError,
formatError: formatErrorFn,
formatResponse: optionsObject.formatResponse,

@@ -161,0 +208,0 @@ fieldResolver: optionsObject.fieldResolver,

@@ -121,5 +121,4 @@ /* tslint:disable:no-unused-expression */

it('sends stack trace to error if in an error occurs and debug mode is set', () => {
it('does not call console.error if in an error occurs and debug mode is set', () => {
const query = `query { testError }`;
const expected = /at resolveFieldValueOrError/;
const logStub = stub(console, 'error');

@@ -132,8 +131,7 @@ return runQuery({

logStub.restore();
expect(logStub.callCount).to.equal(1);
expect(logStub.getCall(0).args[0]).to.match(expected);
expect(logStub.callCount).to.equal(0);
});
});
it('does not send stack trace if in an error occurs and not in debug mode', () => {
it('does not call console.error if in an error occurs and not in debug mode', () => {
const query = `query { testError }`;

@@ -296,2 +294,6 @@ const logStub = stub(console, 'error');

step: LogStep.end,
key: 'response',
data: {
data: expected,
},
});

@@ -298,0 +300,0 @@ });

@@ -21,9 +21,11 @@ import {

import { TracingExtension } from 'apollo-tracing';
import { CacheControlExtension } from 'apollo-cache-control';
import {
CacheControlExtension,
CacheControlExtensionOptions,
} from 'apollo-cache-control';
fromGraphQLError,
internalFormatError,
ValidationError,
SyntaxError,
} from './errors';
import { fromGraphQLError, formatError } from './errors';
export interface GraphQLResponse {

@@ -52,3 +54,3 @@ data?: object;

key?: string;
data?: Object;
data?: any;
}

@@ -77,3 +79,4 @@

tracing?: boolean;
cacheControl?: boolean | CacheControlExtensionOptions;
// cacheControl?: boolean | CacheControlExtensionOptions;
cacheControl?: boolean | any;
}

@@ -86,6 +89,2 @@

function printStackTrace(error: Error) {
console.error(error.stack);
}
function format(

@@ -99,3 +98,3 @@ errors: Array<Error>,

const { formatter, debug } = options;
return errors.map(error => formatError(error, debug)).map(error => {
return errors.map(error => internalFormatError(error, debug)).map(error => {
if (formatter !== undefined) {

@@ -108,5 +107,4 @@ try {

new GraphQLError('Internal server error'),
'INTERNAL_ERROR',
);
return formatError(newError, debug);
return internalFormatError(newError, debug);
}

@@ -184,6 +182,13 @@ } else {

return Promise.resolve({
errors: format([fromGraphQLError(syntaxError, 'MALFORMED_QUERY')], {
formatter: options.formatError,
debug,
}),
errors: format(
[
fromGraphQLError(syntaxError, {
errorClass: SyntaxError,
}),
],
{
formatter: options.formatError,
debug,
},
),
});

@@ -207,3 +212,3 @@ }

validationErrors.map(err =>
fromGraphQLError(err, 'QUERY_VALIDATION_FAILED'),
fromGraphQLError(err, { errorClass: ValidationError }),
),

@@ -236,3 +241,2 @@ {

logFunction({ action: LogAction.execute, step: LogStep.end });
logFunction({ action: LogAction.request, step: LogStep.end });

@@ -248,5 +252,2 @@ let response: GraphQLResponse = {

});
if (debug) {
result.errors.map(printStackTrace);
}
}

@@ -264,2 +265,9 @@

logFunction({
action: LogAction.request,
step: LogStep.end,
key: 'response',
data: response,
});
return response;

@@ -271,3 +279,9 @@ });

return Promise.resolve({
errors: format([fromGraphQLError(executionError, 'EXECUTION_ERROR')], {
//TODO accurate code for this error, which describes this error, which
// can occur when:
// * variables incorrectly typed/null when nonnullable
// * unknown operation/operation name invalid
// * operation type is unsupported
// Options: PREPROCESSING_FAILED, GRAPHQL_RUNTIME_CHECK_FAILED
errors: format([fromGraphQLError(executionError)], {
formatter: options.formatError,

@@ -274,0 +288,0 @@ debug,

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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