1- import { typegenAutoConfig } from '@nexus/schema/dist/core'
2- import { stripIndents } from 'common-tags'
31import * as HTTP from 'http'
42import * as Lo from 'lodash'
53import * as Plugin from '../core/plugin'
@@ -19,7 +17,7 @@ type Request = HTTP.IncomingMessage & { log: Logger.Logger }
1917// all places in the framework where the req object is referenced should be
2018// actually referencing the typegen version, so that it reflects the req +
2119// plugin augmentations type
22- type ContextContributor < T extends { } > = ( req : Request ) => T
20+ type ContextContributor < Req , T extends { } = any > = ( req : Req ) => T
2321
2422export type App = {
2523 /**
@@ -28,7 +26,13 @@ export type App = {
2826 * ### todo
2927 */
3028 log : Logger . Logger
31- server : Server . Server
29+ /**
30+ * [API Reference](https://nexus-future.now.sh/#/references/api?id=server) ⌁ [Guide](todo)
31+ *
32+ * ### todo
33+ *
34+ */
35+ server : Server . ServerWithCustomizer
3236 /**
3337 * todo
3438 */
@@ -45,8 +49,8 @@ export type App = {
4549 /**
4650 * todo
4751 */
48- addToContext : < T extends { } > (
49- contextContributor : ContextContributor < T >
52+ addToContext : < Req extends any = Request , T extends { } = any > (
53+ contextContributor : ContextContributor < Req , T >
5054 ) => void
5155 }
5256}
@@ -57,7 +61,7 @@ type SettingsInput = {
5761 server ?: Server . ExtraSettingsInput
5862}
5963
60- type SettingsData = Readonly < {
64+ export type SettingsData = Readonly < {
6165 logger : Logger . SettingsData
6266 schema : Schema . SettingsData
6367 server : Server . ExtraSettingsData
@@ -66,7 +70,7 @@ type SettingsData = Readonly<{
6670/**
6771 * todo
6872 */
69- type Settings = {
73+ export type Settings = {
7074 /**
7175 * todo
7276 */
@@ -85,7 +89,7 @@ type Settings = {
8589 * Crate an app instance
8690 * TODO extract and improve config type
8791 */
88- export function create ( appConfig ?: { types ?: any } ) : App {
92+ export function create ( ) : App {
8993 const plugins : Plugin . RuntimeContributions [ ] = [ ]
9094 // Automatically use all installed plugins
9195 // TODO during build step we should turn this into static imports, not unlike
@@ -94,8 +98,7 @@ export function create(appConfig?: { types?: any }): App {
9498
9599 const contextContributors : ContextContributor < any > [ ] = [ ]
96100
97- let server : Server . Server
98-
101+ const server = Server . create ( )
99102 const schema = Schema . create ( )
100103
101104 const settings : Settings = {
@@ -137,17 +140,14 @@ export function create(appConfig?: { types?: any }): App {
137140 * Start the server. If you do not call this explicitly then nexus will
138141 * for you. You should not normally need to call this function yourself.
139142 */
140- async start ( ) : Promise < void > {
143+ async start ( ) {
141144 // Track the start call so that we can know in entrypoint whether to run
142145 // or not start for the user.
143146 singletonChecks . state . is_was_server_start_called = true
147+
144148 // During development we dynamically import all the schema modules
145- //
146149 // TODO IDEA we have concept of schema module and schema dir
147150 // add a "refactor" command to toggle between them
148- // TODO put behind dev-mode guard
149- // TODO static imports codegen at build time
150- // TODO do not assume root source folder called `server`
151151 // TODO do not assume TS
152152 // TODO refactor and put a system behind this holy mother of...
153153
@@ -158,124 +158,25 @@ export function create(appConfig?: { types?: any }): App {
158158 Layout . schema . importModules ( )
159159 }
160160
161- // todo refactor; this is from before when nexus and framework were
162- // different (e.g. santa). Encapsulate component schema config
163- // into framework schema module.
164- //
165- // Create the NexusSchema config
166- const nexusConfig = Schema . createInternalConfig ( )
167-
168- // Integrate plugin typegenAutoConfig contributions
169- const typegenAutoConfigFromPlugins = { }
170- for ( const p of plugins ) {
171- if ( p . nexus ?. typegenAutoConfig ) {
172- Lo . merge ( typegenAutoConfigFromPlugins , p . nexus . typegenAutoConfig )
173- }
174- }
175-
176- const typegenAutoConfigObject = Lo . merge (
177- { } ,
178- typegenAutoConfigFromPlugins ,
179- nexusConfig . typegenAutoConfig !
180- )
181- nexusConfig . typegenAutoConfig = undefined
182-
183- function contextTypeContribSpecToCode (
184- ctxTypeContribSpec : Record < string , string >
185- ) : string {
186- return stripIndents `
187- interface Context {
188- ${ Object . entries ( ctxTypeContribSpec )
189- . map ( ( [ name , type ] ) => {
190- // Quote key name to handle case of identifier-incompatible key names
191- return `'${ name } ': ${ type } `
192- } )
193- . join ( '\n' ) }
194- }
195- `
196- }
197-
198- // Our use-case of multiple context sources seems to require a custom
199- // handling of typegenConfig. Opened an issue about maybe making our
200- // curreent use-case, fairly basic, integrated into the auto system, here:
201- // https://github.com/prisma-labs/nexus/issues/323
202- nexusConfig . typegenConfig = async ( schema , outputPath ) => {
203- const configurator = await typegenAutoConfig ( typegenAutoConfigObject )
204- const config = await configurator ( schema , outputPath )
205-
206- // Initialize
207- config . imports . push ( 'interface Context {}' )
208- config . contextType = 'Context'
209-
210- // Integrate user's app calls to app.addToContext
211- const addToContextCallResults : string [ ] = process . env
212- . NEXUS_TYPEGEN_ADD_CONTEXT_RESULTS
213- ? JSON . parse ( process . env . NEXUS_TYPEGEN_ADD_CONTEXT_RESULTS )
214- : [ ]
215-
216- const addToContextInterfaces = addToContextCallResults
217- . map ( result => {
218- return stripIndents `
219- interface Context ${ result }
220- `
221- } )
222- . join ( '\n\n' )
223-
224- config . imports . push ( addToContextInterfaces )
225-
226- // Integrate plugin context contributions
227- for ( const p of plugins ) {
228- if ( ! p . context ) continue
229-
230- if ( p . context . typeGen . imports ) {
231- config . imports . push (
232- ...p . context . typeGen . imports . map (
233- im => `import * as ${ im . as } from '${ im . from } '`
234- )
235- )
236- }
237-
238- config . imports . push (
239- contextTypeContribSpecToCode ( p . context . typeGen . fields )
240- )
241- }
242-
243- config . imports . push (
244- "import * as Logger from 'nexus-future/dist/lib/logger'" ,
245- contextTypeContribSpecToCode ( {
246- log : 'Logger.Logger' ,
247- } )
248- )
249-
250- api . log . trace ( 'built up Nexus typegenConfig' , { config } )
251- return config
252- }
253-
254- log . trace ( 'built up schema config' , { nexusConfig } )
255-
256- // Merge the plugin nexus plugins
257- nexusConfig . plugins = nexusConfig . plugins ?? [ ]
258- for ( const plugin of plugins ) {
259- nexusConfig . plugins . push ( ...( plugin . nexus ?. plugins ?? [ ] ) )
260- }
261-
262- if ( appConfig ?. types && appConfig . types . length !== 0 ) {
263- nexusConfig . types . push ( ...appConfig . types )
264- }
161+ const nexusConfig = Schema . createInternalConfig ( plugins )
162+ const compiledSchema = await schema . private . compile ( nexusConfig )
265163
266164 if ( schema . private . types . length === 0 ) {
267165 log . warn ( Layout . schema . emptyExceptionMessage ( ) )
268166 }
269167
270- return Server . create ( {
271- schema : await schema . private . compile ( nexusConfig ) ,
168+ return server . createAndStart ( {
169+ schema : compiledSchema ,
272170 plugins,
273171 contextContributors,
274- ...settings . current . server ,
275- } ) . start ( )
172+ settings,
173+ } )
174+ } ,
175+ stop ( ) {
176+ return server . stop ( )
276177 } ,
277- async stop ( ) {
278- server ?. stop
178+ custom ( customizer ) {
179+ server . setCustomizer ( customizer )
279180 } ,
280181 } ,
281182 }
0 commit comments