1
- import { typegenAutoConfig } from '@nexus/schema/dist/core'
2
- import { stripIndents } from 'common-tags'
3
1
import * as HTTP from 'http'
4
2
import * as Lo from 'lodash'
5
3
import * as Plugin from '../core/plugin'
@@ -19,7 +17,7 @@ type Request = HTTP.IncomingMessage & { log: Logger.Logger }
19
17
// all places in the framework where the req object is referenced should be
20
18
// actually referencing the typegen version, so that it reflects the req +
21
19
// plugin augmentations type
22
- type ContextContributor < T extends { } > = ( req : Request ) => T
20
+ type ContextContributor < Req , T extends { } = any > = ( req : Req ) => T
23
21
24
22
export type App = {
25
23
/**
@@ -28,7 +26,13 @@ export type App = {
28
26
* ### todo
29
27
*/
30
28
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
32
36
/**
33
37
* todo
34
38
*/
@@ -45,8 +49,8 @@ export type App = {
45
49
/**
46
50
* todo
47
51
*/
48
- addToContext : < T extends { } > (
49
- contextContributor : ContextContributor < T >
52
+ addToContext : < Req extends any = Request , T extends { } = any > (
53
+ contextContributor : ContextContributor < Req , T >
50
54
) => void
51
55
}
52
56
}
@@ -57,7 +61,7 @@ type SettingsInput = {
57
61
server ?: Server . ExtraSettingsInput
58
62
}
59
63
60
- type SettingsData = Readonly < {
64
+ export type SettingsData = Readonly < {
61
65
logger : Logger . SettingsData
62
66
schema : Schema . SettingsData
63
67
server : Server . ExtraSettingsData
@@ -66,7 +70,7 @@ type SettingsData = Readonly<{
66
70
/**
67
71
* todo
68
72
*/
69
- type Settings = {
73
+ export type Settings = {
70
74
/**
71
75
* todo
72
76
*/
@@ -85,7 +89,7 @@ type Settings = {
85
89
* Crate an app instance
86
90
* TODO extract and improve config type
87
91
*/
88
- export function create ( appConfig ?: { types ?: any } ) : App {
92
+ export function create ( ) : App {
89
93
const plugins : Plugin . RuntimeContributions [ ] = [ ]
90
94
// Automatically use all installed plugins
91
95
// TODO during build step we should turn this into static imports, not unlike
@@ -94,8 +98,7 @@ export function create(appConfig?: { types?: any }): App {
94
98
95
99
const contextContributors : ContextContributor < any > [ ] = [ ]
96
100
97
- let server : Server . Server
98
-
101
+ const server = Server . create ( )
99
102
const schema = Schema . create ( )
100
103
101
104
const settings : Settings = {
@@ -137,17 +140,14 @@ export function create(appConfig?: { types?: any }): App {
137
140
* Start the server. If you do not call this explicitly then nexus will
138
141
* for you. You should not normally need to call this function yourself.
139
142
*/
140
- async start ( ) : Promise < void > {
143
+ async start ( ) {
141
144
// Track the start call so that we can know in entrypoint whether to run
142
145
// or not start for the user.
143
146
singletonChecks . state . is_was_server_start_called = true
147
+
144
148
// During development we dynamically import all the schema modules
145
- //
146
149
// TODO IDEA we have concept of schema module and schema dir
147
150
// 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`
151
151
// TODO do not assume TS
152
152
// TODO refactor and put a system behind this holy mother of...
153
153
@@ -158,124 +158,25 @@ export function create(appConfig?: { types?: any }): App {
158
158
Layout . schema . importModules ( )
159
159
}
160
160
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 )
265
163
266
164
if ( schema . private . types . length === 0 ) {
267
165
log . warn ( Layout . schema . emptyExceptionMessage ( ) )
268
166
}
269
167
270
- return Server . create ( {
271
- schema : await schema . private . compile ( nexusConfig ) ,
168
+ return server . createAndStart ( {
169
+ schema : compiledSchema ,
272
170
plugins,
273
171
contextContributors,
274
- ...settings . current . server ,
275
- } ) . start ( )
172
+ settings,
173
+ } )
174
+ } ,
175
+ stop ( ) {
176
+ return server . stop ( )
276
177
} ,
277
- async stop ( ) {
278
- server ?. stop
178
+ custom ( customizer ) {
179
+ server . setCustomizer ( customizer )
279
180
} ,
280
181
} ,
281
182
}
0 commit comments