Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .c8rc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"include": ["src/"],
"exclude": [
"src/**/index.ts",
"src/noMultipleVersions.ts",
"src/**/*-fuzz.ts",
"src/jsutils/Maybe.ts",
"src/jsutils/ObjMap.ts",
Expand Down
11 changes: 10 additions & 1 deletion resources/build-npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ assert(
const tsHost = ts.createCompilerHost(tsOptions);
tsHost.writeFile = (filepath, body) => {
fs.mkdirSync(path.dirname(filepath), { recursive: true });
writeGeneratedFile(filepath, body);
let bodyToWrite = body;
const filePath = filepath.split('npmDist')[1];
if (filePath.endsWith('.js') && !filepath.endsWith('noMultipleVersions.js')) {
bodyToWrite =
`import '${
new Array(filePath.split('/').length - 2).fill('..').join('/') || '.'
}/noMultipleVersions.js';\n` + bodyToWrite;
}
writeGeneratedFile(filepath, bodyToWrite);
};

const tsProgram = ts.createProgram(['src/index.ts'], tsOptions, tsHost);
Expand Down Expand Up @@ -109,6 +117,7 @@ function buildPackageJSON() {
// Temporary workaround to allow "internal" imports, no grantees provided
packageJSON.exports['./*.js'] = './*.js';
packageJSON.exports['./*'] = './*.js';
packageJSON.exports['./noMultipleVersions.js'] = null;

// TODO: move to integration tests
const publishTag = packageJSON.publishConfig?.tag;
Expand Down
2 changes: 1 addition & 1 deletion resources/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ interface PackageJSON {
repository?: { url?: string };
scripts?: { [name: string]: string };
type?: string;
exports: { [path: string]: string };
exports: { [path: string]: string | null };
types?: string;
typesVersions: { [ranges: string]: { [path: string]: Array<string> } };
devDependencies?: { [name: string]: string };
Expand Down
9 changes: 9 additions & 0 deletions src/error/GraphQLError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,22 @@ export interface GraphQLErrorOptions {
extensions?: Maybe<GraphQLErrorExtensions>;
}

const isGraphQLErrorSymbol = Symbol.for('GraphQLError');

export function isGraphQLError(error: unknown): error is GraphQLError {
return (
typeof error === 'object' && error != null && isGraphQLErrorSymbol in error
);
}

/**
* A GraphQLError describes an Error found during the parse, validate, or
* execute phases of performing a GraphQL operation. In addition to a message
* and stack trace, it also includes information about the locations in a
* GraphQL document and/or execution result that correspond to the Error.
*/
export class GraphQLError extends Error {
[isGraphQLErrorSymbol]: true = true;
/**
* An array of `{ line, column }` locations within the source GraphQL document
* which correspond to this error.
Expand Down
4 changes: 2 additions & 2 deletions src/execution/subscribe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { isAsyncIterable } from '../jsutils/isAsyncIterable';
import type { Maybe } from '../jsutils/Maybe';
import { addPath, pathToArray } from '../jsutils/Path';

import { GraphQLError } from '../error/GraphQLError';
import { GraphQLError, isGraphQLError } from '../error/GraphQLError';
import { locatedError } from '../error/locatedError';

import type { DocumentNode } from '../language/ast';
Expand Down Expand Up @@ -169,7 +169,7 @@ export async function createSourceEventStream(
} catch (error) {
// If it GraphQLError, report it as an ExecutionResult, containing only errors and no data.
// Otherwise treat the error as a system-class error and re-throw it.
if (error instanceof GraphQLError) {
if (isGraphQLError(error)) {
return { errors: [error] };
}
throw error;
Expand Down
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
* @packageDocumentation
*/

// eslint-disable-next-line import/no-unassigned-import
import './noMultipleVersions';

// The GraphQL.js version info.
export { version, versionInfo } from './version';

Expand Down
79 changes: 0 additions & 79 deletions src/jsutils/__tests__/instanceOf-test.ts

This file was deleted.

54 changes: 0 additions & 54 deletions src/jsutils/instanceOf.ts

This file was deleted.

8 changes: 6 additions & 2 deletions src/language/source.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { devAssert } from '../jsutils/devAssert';
import { inspect } from '../jsutils/inspect';
import { instanceOf } from '../jsutils/instanceOf';

interface Location {
line: number;
column: number;
}

const isSourceSymbol = Symbol.for('Source');

/**
* A representation of source input to GraphQL. The `name` and `locationOffset` parameters are
* optional, but they are useful for clients who store GraphQL documents in source files.
Expand All @@ -15,6 +16,7 @@ interface Location {
* The `line` and `column` properties in `locationOffset` are 1-indexed.
*/
export class Source {
[isSourceSymbol]: true = true;
body: string;
name: string;
locationOffset: Location;
Expand Down Expand Up @@ -53,5 +55,7 @@ export class Source {
* @internal
*/
export function isSource(source: unknown): source is Source {
return instanceOf(source, Source);
return (
typeof source === 'object' && source != null && isSourceSymbol in source
);
}
21 changes: 21 additions & 0 deletions src/noMultipleVersions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { version } from './version';

const graphqlVersionSymbol = Symbol.for('loadedGraphQLVersion');

const currentVersion = (
globalThis as { [graphqlVersionSymbol]?: undefined | string }
)[graphqlVersionSymbol];

if (currentVersion) {
if (currentVersion !== version) {
// eslint-disable-next-line no-console
console.warn(
`Loading GraphQL.js version ${version} while ${currentVersion} has already been loaded.\n` +
'Please consider configuring your package manager or bundler to only install and resolve a single version of GraphQL.',
);
}
} else {
(globalThis as { [graphqlVersionSymbol]?: undefined | string })[
graphqlVersionSymbol
] = version;
}
Loading