diff --git a/.changeset/old-papayas-switch.md b/.changeset/old-papayas-switch.md new file mode 100644 index 00000000000..ce0ab68af3c --- /dev/null +++ b/.changeset/old-papayas-switch.md @@ -0,0 +1,5 @@ +--- +"@apollo/server": patch +--- + +Use extensions for all imports to accommodate TS users using moduleResolution: "nodenext" diff --git a/cspell-dict.txt b/cspell-dict.txt index 3d0d6353d35..99f3918415b 100644 --- a/cspell-dict.txt +++ b/cspell-dict.txt @@ -115,6 +115,7 @@ mygraph myvariant namespacing nanos +nodenext npmrc nsolid oneof diff --git a/package.json b/package.json index b9696d20fae..0c9a8d716c7 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "test:clean": "jest --clearCache", "test:watch": "jest --verbose --watchAll", "test:smoke": "npm run test:smoke:prepare && npm run test:smoke:run", - "test:smoke:prepare": "npm run compile && smoke-test/prepare.sh", + "test:smoke:prepare": "smoke-test/prepare.sh", "test:smoke:run": "smoke-test/smoke-test.sh", "testonly": "npm test", "test:ci": "npm test -- --ci --maxWorkers=2 --reporters=default --reporters=jest-junit", diff --git a/packages/server/src/ApolloServer.ts b/packages/server/src/ApolloServer.ts index 67e6a0f06c7..920f2410719 100644 --- a/packages/server/src/ApolloServer.ts +++ b/packages/server/src/ApolloServer.ts @@ -43,7 +43,7 @@ import type { HTTPGraphQLHead, ContextThunk, GraphQLRequestContext, -} from './externalTypes'; +} from './externalTypes/index.js'; import { runPotentiallyBatchedHttpQuery } from './httpBatching.js'; import { InternalPluginId, pluginIsInternal } from './internalPlugin.js'; import { @@ -62,7 +62,7 @@ import { SchemaManager } from './utils/schemaManager.js'; import { isDefined } from './utils/isDefined.js'; import { UnreachableCaseError } from './utils/UnreachableCaseError.js'; import type { WithRequired } from '@apollo/utils.withrequired'; -import type { ApolloServerOptionsWithStaticSchema } from './externalTypes/constructor'; +import type { ApolloServerOptionsWithStaticSchema } from './externalTypes/constructor.js'; import type { GatewayExecutor } from '@apollo/server-gateway-interface'; const NoIntrospection = (context: ValidationContext) => ({ diff --git a/packages/server/src/determineApolloConfig.ts b/packages/server/src/determineApolloConfig.ts index 9b004e61a4e..10f67928f60 100644 --- a/packages/server/src/determineApolloConfig.ts +++ b/packages/server/src/determineApolloConfig.ts @@ -1,5 +1,5 @@ import { createHash } from '@apollo/utils.createhash'; -import type { ApolloConfig, ApolloConfigInput } from './externalTypes'; +import type { ApolloConfig, ApolloConfigInput } from './externalTypes/index.js'; // This function combines the `apollo` constructor argument and some environment // variables to come up with a full ApolloConfig. diff --git a/packages/server/src/express4/index.ts b/packages/server/src/express4/index.ts index 33693c01006..f5a4e63a879 100644 --- a/packages/server/src/express4/index.ts +++ b/packages/server/src/express4/index.ts @@ -1,11 +1,11 @@ import type { WithRequired } from '@apollo/utils.withrequired'; import type express from 'express'; -import type { ApolloServer } from '..'; +import type { ApolloServer } from '../index.js'; import type { BaseContext, ContextFunction, HTTPGraphQLRequest, -} from '../externalTypes'; +} from '../externalTypes/index.js'; import { parse as urlParse } from 'url'; export interface ExpressContextFunctionArgument { diff --git a/packages/server/src/externalTypes/constructor.ts b/packages/server/src/externalTypes/constructor.ts index cc173cb720e..deabab471ee 100644 --- a/packages/server/src/externalTypes/constructor.ts +++ b/packages/server/src/externalTypes/constructor.ts @@ -10,8 +10,8 @@ import type { } from 'graphql'; import type { KeyValueCache } from '@apollo/utils.keyvaluecache'; import type { GatewayInterface } from '@apollo/server-gateway-interface'; -import type { BaseContext } from '.'; -import type { ApolloServerPlugin } from './plugins'; +import type { ApolloServerPlugin } from './plugins.js'; +import type { BaseContext } from './index.js'; export type DocumentStore = KeyValueCache; diff --git a/packages/server/src/externalTypes/graphql.ts b/packages/server/src/externalTypes/graphql.ts index a032bfd5228..a71145c5b49 100644 --- a/packages/server/src/externalTypes/graphql.ts +++ b/packages/server/src/externalTypes/graphql.ts @@ -7,8 +7,8 @@ import type { OperationDefinitionNode, } from 'graphql'; import type { CachePolicy } from '@apollo/cache-control-types'; -import type { BaseContext } from './context'; -import type { HTTPGraphQLHead, HTTPGraphQLRequest } from './http'; +import type { BaseContext } from './context.js'; +import type { HTTPGraphQLHead, HTTPGraphQLRequest } from './http.js'; import type { Logger } from '@apollo/utils.logger'; import type { KeyValueCache } from '@apollo/utils.keyvaluecache'; diff --git a/packages/server/src/externalTypes/plugins.ts b/packages/server/src/externalTypes/plugins.ts index bea25f684ab..46207bbb85c 100644 --- a/packages/server/src/externalTypes/plugins.ts +++ b/packages/server/src/externalTypes/plugins.ts @@ -1,9 +1,9 @@ import type { KeyValueCache } from '@apollo/utils.keyvaluecache'; import type { Logger } from '@apollo/utils.logger'; import type { GraphQLResolveInfo, GraphQLSchema } from 'graphql'; -import type { ApolloConfig } from './constructor'; -import type { BaseContext } from './context'; -import type { GraphQLRequestContext, GraphQLResponse } from './graphql'; +import type { ApolloConfig } from './constructor.js'; +import type { BaseContext } from './context.js'; +import type { GraphQLRequestContext, GraphQLResponse } from './graphql.js'; import type { GraphQLRequestContextDidEncounterErrors, GraphQLRequestContextDidResolveOperation, @@ -13,7 +13,7 @@ import type { GraphQLRequestContextResponseForOperation, GraphQLRequestContextValidationDidStart, GraphQLRequestContextWillSendResponse, -} from './requestPipeline'; +} from './requestPipeline.js'; export interface GraphQLServerContext { readonly logger: Logger; diff --git a/packages/server/src/externalTypes/requestPipeline.ts b/packages/server/src/externalTypes/requestPipeline.ts index 28075476e55..6de7d46aa7d 100644 --- a/packages/server/src/externalTypes/requestPipeline.ts +++ b/packages/server/src/externalTypes/requestPipeline.ts @@ -1,6 +1,6 @@ import type { WithRequired } from '@apollo/utils.withrequired'; -import type { BaseContext } from './context'; -import type { GraphQLRequestContext } from './graphql'; +import type { BaseContext } from './context.js'; +import type { GraphQLRequestContext } from './graphql.js'; export type GraphQLRequestContextDidResolveSource< TContext extends BaseContext, diff --git a/packages/server/src/httpBatching.ts b/packages/server/src/httpBatching.ts index 02d50cff827..dbad48a7a0e 100644 --- a/packages/server/src/httpBatching.ts +++ b/packages/server/src/httpBatching.ts @@ -2,7 +2,7 @@ import type { BaseContext, HTTPGraphQLRequest, HTTPGraphQLResponse, -} from './externalTypes'; +} from './externalTypes/index.js'; import type { ApolloServer, ApolloServerInternals, diff --git a/packages/server/src/internalPlugin.ts b/packages/server/src/internalPlugin.ts index d5d92f90db7..410c560c946 100644 --- a/packages/server/src/internalPlugin.ts +++ b/packages/server/src/internalPlugin.ts @@ -1,4 +1,4 @@ -import type { BaseContext, ApolloServerPlugin } from './externalTypes'; +import type { BaseContext, ApolloServerPlugin } from './externalTypes/index.js'; // This file's exports should not be exported from the overall // @apollo/server module. diff --git a/packages/server/src/plugin/cacheControl/index.ts b/packages/server/src/plugin/cacheControl/index.ts index eb8f4494245..cb99442c884 100644 --- a/packages/server/src/plugin/cacheControl/index.ts +++ b/packages/server/src/plugin/cacheControl/index.ts @@ -1,4 +1,4 @@ -import type { ApolloServerPlugin } from '../../externalTypes'; +import type { ApolloServerPlugin } from '../../externalTypes/index.js'; import { DirectiveNode, getNamedType, diff --git a/packages/server/src/plugin/disabled/index.ts b/packages/server/src/plugin/disabled/index.ts index 67327e34b01..4aa18603a43 100644 --- a/packages/server/src/plugin/disabled/index.ts +++ b/packages/server/src/plugin/disabled/index.ts @@ -1,10 +1,10 @@ // TODO(AS4): Document this file // TODO(AS4): Decide where it is imported from. -import type { BaseContext, ApolloServerPlugin } from '../..'; +import type { BaseContext, ApolloServerPlugin } from '../../index.js'; import type { InternalApolloServerPlugin, InternalPluginId, -} from '../../internalPlugin'; +} from '../../internalPlugin.js'; function disabledPlugin(id: InternalPluginId): ApolloServerPlugin { const plugin: InternalApolloServerPlugin = { diff --git a/packages/server/src/plugin/drainHttpServer/index.ts b/packages/server/src/plugin/drainHttpServer/index.ts index 287e71ecd84..4493869f6e2 100644 --- a/packages/server/src/plugin/drainHttpServer/index.ts +++ b/packages/server/src/plugin/drainHttpServer/index.ts @@ -1,5 +1,5 @@ import type http from 'http'; -import type { ApolloServerPlugin } from '../../externalTypes'; +import type { ApolloServerPlugin } from '../../externalTypes/index.js'; import { Stopper } from './stoppable.js'; /** diff --git a/packages/server/src/plugin/inlineTrace/index.ts b/packages/server/src/plugin/inlineTrace/index.ts index ffab54233da..4bb95c0d95d 100644 --- a/packages/server/src/plugin/inlineTrace/index.ts +++ b/packages/server/src/plugin/inlineTrace/index.ts @@ -3,7 +3,7 @@ import { TraceTreeBuilder } from '../traceTreeBuilder.js'; import type { SendErrorsOptions } from '../usageReporting/index.js'; import { internalPlugin } from '../../internalPlugin.js'; import { schemaIsFederated } from '../schemaIsFederated.js'; -import type { ApolloServerPlugin } from '../../externalTypes'; +import type { ApolloServerPlugin } from '../../externalTypes/index.js'; export interface ApolloServerPluginInlineTraceOptions { /** diff --git a/packages/server/src/plugin/landingPage/default/index.ts b/packages/server/src/plugin/landingPage/default/index.ts index 6b80ca367e5..4371f91f93a 100644 --- a/packages/server/src/plugin/landingPage/default/index.ts +++ b/packages/server/src/plugin/landingPage/default/index.ts @@ -1,10 +1,13 @@ -import type { ApolloServerPlugin, BaseContext } from '../../../externalTypes'; -import type { ImplicitlyInstallablePlugin } from '../../../ApolloServer'; +import type { + ApolloServerPlugin, + BaseContext, +} from '../../../externalTypes/index.js'; +import type { ImplicitlyInstallablePlugin } from '../../../ApolloServer.js'; import type { ApolloServerPluginLandingPageLocalDefaultOptions, ApolloServerPluginLandingPageProductionDefaultOptions, LandingPageConfig, -} from './types'; +} from './types.js'; import { getEmbeddedExplorerHTML, getEmbeddedSandboxHTML, diff --git a/packages/server/src/plugin/schemaReporting/index.ts b/packages/server/src/plugin/schemaReporting/index.ts index 8c79ada7d6d..d895740674d 100644 --- a/packages/server/src/plugin/schemaReporting/index.ts +++ b/packages/server/src/plugin/schemaReporting/index.ts @@ -4,8 +4,8 @@ import { v4 as uuidv4 } from 'uuid'; import { printSchema, validateSchema, buildSchema } from 'graphql'; import { SchemaReporter } from './schemaReporter.js'; import { schemaIsFederated } from '../schemaIsFederated.js'; -import type { SchemaReport } from './generated/operations'; -import type { ApolloServerPlugin } from '../../externalTypes'; +import type { SchemaReport } from './generated/operations.js'; +import type { ApolloServerPlugin } from '../../externalTypes/index.js'; import type { Fetcher } from '@apollo/utils.fetcher'; import { packageVersion } from '../../generated/packageVersion.js'; import { computeCoreSchemaHash } from '../../utils/computeCoreSchemaHash.js'; diff --git a/packages/server/src/plugin/schemaReporting/schemaReporter.ts b/packages/server/src/plugin/schemaReporting/schemaReporter.ts index ae7ccdcd8eb..64be468cbff 100644 --- a/packages/server/src/plugin/schemaReporting/schemaReporter.ts +++ b/packages/server/src/plugin/schemaReporting/schemaReporter.ts @@ -1,5 +1,5 @@ import fetch from 'node-fetch'; -import type { GraphQLRequest } from '../../externalTypes'; +import type { GraphQLRequest } from '../../externalTypes/index.js'; import type { Logger } from '@apollo/utils.logger'; import type { SchemaReport, diff --git a/packages/server/src/plugin/usageReporting/options.ts b/packages/server/src/plugin/usageReporting/options.ts index 8dc456d0253..d7383daf0eb 100644 --- a/packages/server/src/plugin/usageReporting/options.ts +++ b/packages/server/src/plugin/usageReporting/options.ts @@ -4,7 +4,7 @@ import type { GraphQLRequestContext, GraphQLRequestContextWillSendResponse, BaseContext, -} from '../../externalTypes'; +} from '../../externalTypes/index.js'; import type { Logger } from '@apollo/utils.logger'; import type { Trace } from '@apollo/usage-reporting-protobuf'; import type { Fetcher } from '@apollo/utils.fetcher'; diff --git a/packages/server/src/plugin/usageReporting/plugin.ts b/packages/server/src/plugin/usageReporting/plugin.ts index d7ceb404f16..fd94dc9ed55 100644 --- a/packages/server/src/plugin/usageReporting/plugin.ts +++ b/packages/server/src/plugin/usageReporting/plugin.ts @@ -19,9 +19,9 @@ import type { GraphQLRequestContextWillSendResponse, GraphQLRequestListener, GraphQLServerListener, -} from '../../externalTypes'; +} from '../../externalTypes/index.js'; import { internalPlugin } from '../../internalPlugin.js'; -import type { HeaderMap } from '../../runHttpQuery'; +import type { HeaderMap } from '../../runHttpQuery.js'; import { dateToProtoTimestamp, TraceTreeBuilder } from '../traceTreeBuilder.js'; import { defaultSendOperationsAsTrace } from './defaultSendOperationsAsTrace.js'; import { @@ -32,7 +32,7 @@ import { import type { ApolloServerPluginUsageReportingOptions, SendValuesBaseOptions, -} from './options'; +} from './options.js'; import { OurReport } from './stats.js'; import { makeTraceDetails } from './traceDetails.js'; import { packageVersion } from '../../generated/packageVersion.js'; diff --git a/packages/server/src/plugin/usageReporting/traceDetails.ts b/packages/server/src/plugin/usageReporting/traceDetails.ts index dace53e0c4d..a61c1ed782f 100644 --- a/packages/server/src/plugin/usageReporting/traceDetails.ts +++ b/packages/server/src/plugin/usageReporting/traceDetails.ts @@ -1,5 +1,5 @@ import { Trace } from '@apollo/usage-reporting-protobuf'; -import type { VariableValueOptions } from './options'; +import type { VariableValueOptions } from './options.js'; // Creates trace details from request variables, given a specification for modifying // values of private or sensitive variables. diff --git a/packages/server/src/requestPipeline.ts b/packages/server/src/requestPipeline.ts index 6a81e117810..c19cdf1cd42 100644 --- a/packages/server/src/requestPipeline.ts +++ b/packages/server/src/requestPipeline.ts @@ -42,7 +42,7 @@ import type { GraphQLRequestExecutionListener, BaseContext, HTTPGraphQLHead, -} from './externalTypes'; +} from './externalTypes/index.js'; import { invokeDidStartHook, @@ -57,7 +57,7 @@ import type { ApolloServer, ApolloServerInternals, SchemaDerivedData, -} from './ApolloServer'; +} from './ApolloServer.js'; import { isDefined } from './utils/isDefined.js'; export const APQ_CACHE_PREFIX = 'apq:'; diff --git a/packages/server/src/runHttpQuery.ts b/packages/server/src/runHttpQuery.ts index d5cef40ffd5..2fe3afe19b1 100644 --- a/packages/server/src/runHttpQuery.ts +++ b/packages/server/src/runHttpQuery.ts @@ -4,7 +4,7 @@ import type { HTTPGraphQLHead, HTTPGraphQLRequest, HTTPGraphQLResponse, -} from './externalTypes'; +} from './externalTypes/index.js'; import { ApolloServer, ApolloServerInternals, diff --git a/packages/server/src/standalone/index.ts b/packages/server/src/standalone/index.ts index 82bfb87adeb..7f50f4f95c0 100644 --- a/packages/server/src/standalone/index.ts +++ b/packages/server/src/standalone/index.ts @@ -4,9 +4,9 @@ import cors from 'cors'; import express from 'express'; import http, { IncomingMessage, ServerResponse } from 'http'; import type { ListenOptions } from 'net'; -import type { ApolloServer } from '../ApolloServer'; +import type { ApolloServer } from '../ApolloServer.js'; import { expressMiddleware } from '../express4/index.js'; -import type { BaseContext, ContextFunction } from '../externalTypes'; +import type { BaseContext, ContextFunction } from '../externalTypes/index.js'; import { ApolloServerPluginDrainHttpServer } from '../plugin/drainHttpServer/index.js'; import { urlForHttpServer } from '../utils/urlForHttpServer.js'; diff --git a/packages/server/src/utils/schemaInstrumentation.ts b/packages/server/src/utils/schemaInstrumentation.ts index 27543e02120..a38a85adc1f 100644 --- a/packages/server/src/utils/schemaInstrumentation.ts +++ b/packages/server/src/utils/schemaInstrumentation.ts @@ -9,7 +9,7 @@ import { import type { BaseContext, GraphQLRequestExecutionListener, -} from '../externalTypes'; +} from '../externalTypes/index.js'; export const symbolExecutionDispatcherWillResolveField = Symbol( 'apolloServerExecutionDispatcherWillResolveField', diff --git a/packages/server/src/utils/schemaManager.ts b/packages/server/src/utils/schemaManager.ts index 7790f3176f9..298eb3a206b 100644 --- a/packages/server/src/utils/schemaManager.ts +++ b/packages/server/src/utils/schemaManager.ts @@ -5,8 +5,11 @@ import type { GatewayInterface, GatewayUnsubscriber, } from '@apollo/server-gateway-interface'; -import type { SchemaDerivedData } from '../ApolloServer'; -import type { ApolloConfig, GraphQLSchemaContext } from '../externalTypes'; +import type { SchemaDerivedData } from '../ApolloServer.js'; +import type { + ApolloConfig, + GraphQLSchemaContext, +} from '../externalTypes/index.js'; type SchemaDerivedDataProvider = ( apiSchema: GraphQLSchema, diff --git a/smoke-test/nodenext/package.json b/smoke-test/nodenext/package.json new file mode 100644 index 00000000000..6057b8fbf26 --- /dev/null +++ b/smoke-test/nodenext/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "module": "./dist/smoke-test.js" +} diff --git a/smoke-test/nodenext/src/smoke-test.ts b/smoke-test/nodenext/src/smoke-test.ts new file mode 100644 index 00000000000..ec849974276 --- /dev/null +++ b/smoke-test/nodenext/src/smoke-test.ts @@ -0,0 +1,53 @@ +import { ApolloServer } from '@apollo/server'; +import { startStandaloneServer } from '@apollo/server/standalone'; +import fetch from 'make-fetch-happen'; +import assert from 'assert'; + +async function validateAllImports() { + await import('@apollo/server'); + await import('@apollo/server/plugin/cacheControl'); + await import('@apollo/server/plugin/disabled'); + await import('@apollo/server/plugin/drainHttpServer'); + await import('@apollo/server/plugin/inlineTrace'); + await import('@apollo/server/plugin/landingPage/default'); + await import('@apollo/server/plugin/schemaReporting'); + await import('@apollo/server/plugin/usageReporting'); + await import('@apollo/server/standalone'); +} + +async function smokeTest() { + await validateAllImports(); + + const s = new ApolloServer({ + typeDefs: 'type Query {hello:String}', + resolvers: { + Query: { + hello() { + return 'world'; + }, + }, + }, + }); + const { url } = await startStandaloneServer(s, { listen: { port: 0 } }); + + const response = await fetch(url, { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body: JSON.stringify({ query: '{hello}' }), + }); + const body = await response.json(); + + assert.strictEqual(body.data.hello, 'world'); + + await s.stop(); +} + +smokeTest() + .then(() => { + console.log('TS-NODENEXT smoke test passed!'); + process.exit(0); + }) + .catch((e) => { + console.error(e); + process.exit(1); + }); diff --git a/smoke-test/nodenext/tsconfig.json b/smoke-test/nodenext/tsconfig.json new file mode 100644 index 00000000000..5ad087a66cb --- /dev/null +++ b/smoke-test/nodenext/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "module": "NodeNext", + "moduleResolution": "nodenext", + "target": "es2020", + "lib": ["es2020"], + "types": ["node"] + } +} diff --git a/smoke-test/prepare.sh b/smoke-test/prepare.sh index 153c90c2447..476d0dff54e 100755 --- a/smoke-test/prepare.sh +++ b/smoke-test/prepare.sh @@ -5,6 +5,8 @@ set -x TARBALL_DIR=$(mktemp -d) +# Ensure build is current. +npm run compile # Make tarballs of all packages. npm pack --pack-destination="$TARBALL_DIR" --workspaces=true diff --git a/smoke-test/smoke-test.sh b/smoke-test/smoke-test.sh index c084965d2cc..dddf51fbf08 100755 --- a/smoke-test/smoke-test.sh +++ b/smoke-test/smoke-test.sh @@ -23,6 +23,15 @@ grep 'function createApplication' "$ROLLUP_OUT_DIR"/bundle.mjs # ... and that the one that doesn't, doesn't. ! grep 'function createApplication' "$ROLLUP_OUT_DIR"/bundle-no-express.mjs +# Nodenext needs its own special folder - for this test to exercise the case +# we're after, we need a package.json using type: module and a bleeding edge +# tsconfig using moduleResolution: nodenext. Let's run it before the others +# since this is the "pickiest" of the tests. +cd nodenext +tsc --build . +node ./dist/smoke-test.js +cd .. + # Ensure basic TypeScript builds work. tsc --build tsconfig.{esm,cjs}.json node generated/tsc/smoke-test.cjs