Initial Save

This commit is contained in:
jackbeeby
2025-03-28 12:30:19 +11:00
parent e381994f19
commit d8773925e8
9910 changed files with 982718 additions and 0 deletions

289
node_modules/apollo-server/src/__tests__/index.test.ts generated vendored Normal file
View File

@@ -0,0 +1,289 @@
import { createConnection } from 'net';
import request from 'request';
import { createApolloFetch } from 'apollo-fetch';
import resolvable from '@josephg/resolvable';
import { gql, ApolloServer } from '../index';
const typeDefs = gql`
type Query {
hello: String
hang: String
}
`;
const resolvers = {
Query: {
hello: () => 'hi',
},
};
describe('apollo-server', () => {
describe('constructor', () => {
it('accepts typeDefs and resolvers', () => {
expect(() => new ApolloServer({ typeDefs, resolvers })).not.toThrow;
});
it('accepts typeDefs and mocks', () => {
expect(() => new ApolloServer({ typeDefs, mocks: true })).not.toThrow;
});
it('runs serverWillStart and serverWillStop', async () => {
const fn = jest.fn();
const beAsync = () => new Promise((res) => res());
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [
{
async serverWillStart() {
fn('a');
await beAsync();
fn('b');
return {
async serverWillStop() {
fn('c');
await beAsync();
fn('d');
},
};
},
},
],
});
await server.listen();
expect(fn.mock.calls).toEqual([['a'], ['b']]);
await server.stop();
expect(fn.mock.calls).toEqual([['a'], ['b'], ['c'], ['d']]);
});
describe('stops even with open HTTP connections', () => {
it('all connections are idle', async () => {
const server = new ApolloServer({
typeDefs,
resolvers,
// Disable killing non-idle connections. This means the test will only
// pass if the fast graceful close of the idle connection works.
stopGracePeriodMillis: Infinity,
});
const { port } = await server.listen({ port: 0 });
// Open a TCP connection to the server, and let it dangle idle
// without starting a request.
const connectionBarrier = resolvable();
createConnection({ host: 'localhost', port: port as number }, () =>
connectionBarrier.resolve(),
);
await connectionBarrier;
// Stop the server. Before, when this was just net.Server.close, this
// would hang. Now that we use stoppable, the idle connection is immediately
// killed.
await server.stop();
});
it('a connection with an active HTTP request', async () => {
const gotToHangBarrier = resolvable();
const hangBarrier = resolvable();
const server = new ApolloServer({
typeDefs,
resolvers: {
...resolvers,
Query: {
...resolvers.Query,
async hang() {
gotToHangBarrier.resolve();
await hangBarrier; // never unblocks
},
},
},
// A short grace period, because we're going to actually let this
// strike.
stopGracePeriodMillis: 10,
});
const { url } = await server.listen({ port: 0 });
// Start an HTTP request that won't ever finish. (Ignore the very
// expected error that happens after the server is stopped.)
const apolloFetch = createApolloFetch({ uri: url });
apolloFetch({ query: '{hang}' }).catch(() => {});
await gotToHangBarrier;
// Stop the server. Before, when this was just net.Server.close, this
// would hang. Now that we use stoppable, the idle connection is immediately
// killed.
await server.stop();
});
});
// These tests are duplicates of ones in apollo-server-integration-testsuite
// We don't actually expect Jest to do much here, the purpose of these
// tests is to make sure our typings are correct, and to trigger a
// compile error if they aren't
describe('context field', () => {
describe('as a function', () => {
it('can accept and return `req`', () => {
expect(
new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => ({ req }),
}),
).not.toThrow;
});
it('can accept nothing and return an empty object', () => {
expect(
new ApolloServer({
typeDefs,
resolvers,
context: () => ({}),
}),
).not.toThrow;
});
});
});
describe('as an object', () => {
it('can be an empty object', () => {
expect(
new ApolloServer({
typeDefs,
resolvers,
context: {},
}),
).not.toThrow;
});
it('can contain arbitrary values', () => {
expect(
new ApolloServer({
typeDefs,
resolvers,
context: { value: 'arbitrary' },
}),
).not.toThrow;
});
});
});
describe('without registerServer', () => {
let server: ApolloServer;
afterEach(async () => {
await server.stop();
});
it('can be queried', async () => {
server = new ApolloServer({
typeDefs,
resolvers,
});
const { url: uri } = await server.listen({ port: 0 });
const apolloFetch = createApolloFetch({ uri });
const result = await apolloFetch({ query: '{hello}' });
expect(result.data).toEqual({ hello: 'hi' });
expect(result.errors).toBeUndefined();
});
it('renders GraphQL playground when browser requests', async () => {
const nodeEnv = process.env.NODE_ENV;
delete process.env.NODE_ENV;
server = new ApolloServer({
typeDefs,
resolvers,
stopOnTerminationSignals: false,
});
const { url } = await server.listen({ port: 0 });
return new Promise((resolve, reject) => {
request(
{
url,
method: 'GET',
headers: {
accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
},
},
(error, response, body) => {
process.env.NODE_ENV = nodeEnv;
if (error) {
reject(error);
} else {
expect(body).toMatch('GraphQLPlayground');
expect(response.statusCode).toEqual(200);
resolve();
}
},
);
});
});
it('configures cors', async () => {
server = new ApolloServer({
typeDefs,
resolvers,
});
const { url: uri } = await server.listen({ port: 0 });
const apolloFetch = createApolloFetch({ uri }).useAfter(
(response, next) => {
expect(
response.response.headers.get('access-control-allow-origin'),
).toEqual('*');
next();
},
);
await apolloFetch({ query: '{hello}' });
});
it('configures cors', async () => {
server = new ApolloServer({
typeDefs,
resolvers,
cors: { origin: 'localhost' },
});
const { url: uri } = await server.listen({ port: 0 });
const apolloFetch = createApolloFetch({ uri }).useAfter(
(response, next) => {
expect(
response.response.headers.get('access-control-allow-origin'),
).toEqual('localhost');
next();
},
);
await apolloFetch({ query: '{hello}' });
});
it('creates a healthcheck endpoint', async () => {
server = new ApolloServer({
typeDefs,
resolvers,
});
const { port } = await server.listen({ port: 0 });
return new Promise((resolve, reject) => {
request(
{
url: `http://localhost:${port}/.well-known/apollo/server-health`,
method: 'GET',
},
(error, response, body) => {
if (error) {
reject(error);
} else {
expect(body).toEqual(JSON.stringify({ status: 'pass' }));
expect(response.statusCode).toEqual(200);
resolve();
}
},
);
});
});
});
});

View File

@@ -0,0 +1,7 @@
{
"extends": "../../../../tsconfig.test.base",
"include": ["**/*"],
"references": [
{ "path": "../../" },
]
}

25
node_modules/apollo-server/src/exports.ts generated vendored Normal file
View File

@@ -0,0 +1,25 @@
export * from 'graphql-tools';
export * from 'graphql-subscriptions';
export {
gql,
GraphQLUpload,
GraphQLOptions,
GraphQLExtension,
Config,
GraphQLSchemaModule,
// Errors
ApolloError,
toApolloError,
SyntaxError,
ValidationError,
AuthenticationError,
ForbiddenError,
UserInputError,
// playground
defaultPlaygroundOptions,
PlaygroundConfig,
PlaygroundRenderPageOptions,
} from 'apollo-server-core';
export { CorsOptions } from 'apollo-server-express';

166
node_modules/apollo-server/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,166 @@
// This is the "batteries-included" version of `apollo-server-express`. It
// handles creating the Express app and HTTP server for you (using whatever
// version of `express` its dependency pulls in). If you need to customize the
// Express app or HTTP server at all, you just use `apollo-server-express`
// instead.
import express from 'express';
import http from 'http';
import stoppable from 'stoppable';
import {
ApolloServer as ApolloServerBase,
CorsOptions,
ApolloServerExpressConfig,
} from 'apollo-server-express';
export * from './exports';
export interface ServerInfo {
address: string;
family: string;
url: string;
subscriptionsUrl: string;
port: number | string;
subscriptionsPath: string;
server: http.Server;
}
export class ApolloServer extends ApolloServerBase {
private httpServer?: stoppable.StoppableServer;
private cors?: CorsOptions | boolean;
private onHealthCheck?: (req: express.Request) => Promise<any>;
private stopGracePeriodMillis: number;
constructor(
config: ApolloServerExpressConfig & {
cors?: CorsOptions | boolean;
onHealthCheck?: (req: express.Request) => Promise<any>;
stopGracePeriodMillis?: number;
},
) {
super(config);
this.cors = config && config.cors;
this.onHealthCheck = config && config.onHealthCheck;
this.stopGracePeriodMillis = config?.stopGracePeriodMillis ?? 10_000;
}
private createServerInfo(
server: http.Server,
subscriptionsPath?: string,
): ServerInfo {
const serverInfo: any = {
// TODO: Once we bump to `@types/node@10` or higher, we can replace cast
// with the `net.AddressInfo` type, rather than this custom interface.
// Unfortunately, prior to the 10.x types, this type existed on `dgram`,
// but not on `net`, and in later types, the `server.address()` signature
// can also be a string.
...(server.address() as {
address: string;
family: string;
port: number;
}),
server,
subscriptionsPath,
};
// Convert IPs which mean "any address" (IPv4 or IPv6) into localhost
// corresponding loopback ip. Note that the url field we're setting is
// primarily for consumption by our test suite. If this heuristic is wrong
// for your use case, explicitly specify a frontend host (in the `host`
// option to ApolloServer.listen).
let hostForUrl = serverInfo.address;
if (serverInfo.address === '' || serverInfo.address === '::')
hostForUrl = 'localhost';
serverInfo.url = require('url').format({
protocol: 'http',
hostname: hostForUrl,
port: serverInfo.port,
pathname: this.graphqlPath,
});
serverInfo.subscriptionsUrl = require('url').format({
protocol: 'ws',
hostname: hostForUrl,
port: serverInfo.port,
slashes: true,
pathname: subscriptionsPath,
});
return serverInfo;
}
public applyMiddleware() {
throw new Error(
'To use Apollo Server with an existing express application, please use apollo-server-express',
);
}
public async start(): Promise<void> {
throw new Error(
"When using the `apollo-server` package, you don't need to call start(); just call listen().",
);
}
// Listen takes the same arguments as http.Server.listen.
public async listen(...opts: Array<any>): Promise<ServerInfo> {
// First start the server and throw if startup fails (eg, schema can't be loaded
// or a serverWillStart plugin throws).
await this._start();
// This class is the easy mode for people who don't create their own express
// object, so we have to create it.
const app = express();
app.disable('x-powered-by');
// provide generous values for the getting started experience
super.applyMiddleware({
app,
path: '/',
bodyParserConfig: { limit: '50mb' },
onHealthCheck: this.onHealthCheck,
cors:
typeof this.cors !== 'undefined'
? this.cors
: {
origin: '*',
},
});
const httpServer = http.createServer(app);
// `stoppable` adds a `.stop()` method which:
// - closes the server (ie, stops listening)
// - closes all connections with no active requests
// - continues to close connections when their active request count drops to
// zero
// - in 10 seconds (configurable), closes all remaining active connections
// - calls its callback once there are no remaining active connections
//
// If you don't like this behavior, use apollo-server-express instead of
// apollo-server.
this.httpServer = stoppable(httpServer, this.stopGracePeriodMillis);
if (this.subscriptionServerOptions) {
this.installSubscriptionHandlers(httpServer);
}
await new Promise((resolve) => {
httpServer.once('listening', resolve);
// If the user passed a callback to listen, it'll get called in addition
// to our resolver. They won't have the ability to get the ServerInfo
// object unless they use our Promise, though.
httpServer.listen(...(opts.length ? opts : [{ port: 4000 }]));
});
return this.createServerInfo(httpServer, this.subscriptionsPath);
}
public async stop() {
if (this.httpServer) {
const httpServer = this.httpServer;
await new Promise<void>((resolve) => httpServer.stop(() => resolve()));
this.httpServer = undefined;
}
await super.stop();
}
}