@tanstack/start-plugin-core 1.121.0-alpha.26 → 1.121.0-alpha.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/dist/esm/{nitro-plugin/build-sitemap.d.ts → build-sitemap.d.ts} +3 -3
  2. package/dist/esm/{nitro-plugin/build-sitemap.js → build-sitemap.js} +19 -24
  3. package/dist/esm/build-sitemap.js.map +1 -0
  4. package/dist/esm/compilers.d.ts +1 -1
  5. package/dist/esm/compilers.js +6 -9
  6. package/dist/esm/compilers.js.map +1 -1
  7. package/dist/esm/constants.d.ts +6 -2
  8. package/dist/esm/constants.js +7 -4
  9. package/dist/esm/constants.js.map +1 -1
  10. package/dist/esm/debug.js.map +1 -1
  11. package/dist/esm/dev-server-plugin/extract-html-scripts.js.map +1 -1
  12. package/dist/esm/dev-server-plugin/plugin.d.ts +5 -5
  13. package/dist/esm/dev-server-plugin/plugin.js +118 -95
  14. package/dist/esm/dev-server-plugin/plugin.js.map +1 -1
  15. package/dist/esm/index.d.ts +1 -1
  16. package/dist/esm/index.js +0 -4
  17. package/dist/esm/index.js.map +1 -1
  18. package/dist/esm/load-env-plugin/plugin.d.ts +2 -3
  19. package/dist/esm/load-env-plugin/plugin.js +5 -8
  20. package/dist/esm/load-env-plugin/plugin.js.map +1 -1
  21. package/dist/esm/output-directory.d.ts +3 -0
  22. package/dist/esm/output-directory.js +14 -0
  23. package/dist/esm/output-directory.js.map +1 -0
  24. package/dist/esm/plugin.d.ts +11 -286
  25. package/dist/esm/plugin.js +171 -88
  26. package/dist/esm/plugin.js.map +1 -1
  27. package/dist/esm/post-server-build.d.ts +7 -0
  28. package/dist/esm/post-server-build.js +55 -0
  29. package/dist/esm/post-server-build.js.map +1 -0
  30. package/dist/esm/prerender.d.ts +11 -0
  31. package/dist/esm/{nitro-plugin/prerender.js → prerender.js} +88 -68
  32. package/dist/esm/prerender.js.map +1 -0
  33. package/dist/esm/{nitro-plugin/queue.js → queue.js} +7 -10
  34. package/dist/esm/queue.js.map +1 -0
  35. package/dist/esm/resolve-entries.d.ts +8 -0
  36. package/dist/esm/resolve-entries.js +37 -0
  37. package/dist/esm/resolve-entries.js.map +1 -0
  38. package/dist/esm/schema.d.ts +1334 -6585
  39. package/dist/esm/schema.js +54 -86
  40. package/dist/esm/schema.js.map +1 -1
  41. package/dist/esm/start-compiler-plugin.js +7 -3
  42. package/dist/esm/start-compiler-plugin.js.map +1 -1
  43. package/dist/esm/start-manifest-plugin/plugin.d.ts +6 -3
  44. package/dist/esm/start-manifest-plugin/plugin.js +95 -125
  45. package/dist/esm/start-manifest-plugin/plugin.js.map +1 -1
  46. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js +4 -5
  47. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js.map +1 -1
  48. package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.js +2 -4
  49. package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.js.map +1 -1
  50. package/dist/esm/start-router-plugin/plugin.d.ts +1 -1
  51. package/dist/esm/start-router-plugin/plugin.js +26 -2
  52. package/dist/esm/start-router-plugin/plugin.js.map +1 -1
  53. package/dist/esm/start-router-plugin/route-tree-client-plugin.js +2 -1
  54. package/dist/esm/start-router-plugin/route-tree-client-plugin.js.map +1 -1
  55. package/dist/esm/start-router-plugin/virtual-route-tree-plugin.d.ts +0 -1
  56. package/dist/esm/start-router-plugin/virtual-route-tree-plugin.js +3 -4
  57. package/dist/esm/start-router-plugin/virtual-route-tree-plugin.js.map +1 -1
  58. package/dist/esm/utils.js.map +1 -1
  59. package/package.json +14 -18
  60. package/src/{nitro-plugin/build-sitemap.ts → build-sitemap.ts} +8 -8
  61. package/src/compilers.ts +1 -1
  62. package/src/constants.ts +12 -2
  63. package/src/dev-server-plugin/plugin.ts +146 -124
  64. package/src/index.ts +1 -5
  65. package/src/load-env-plugin/plugin.ts +6 -11
  66. package/src/output-directory.ts +18 -0
  67. package/src/plugin.ts +227 -114
  68. package/src/post-server-build.ts +73 -0
  69. package/src/{nitro-plugin/prerender.ts → prerender.ts} +95 -79
  70. package/src/resolve-entries.ts +52 -0
  71. package/src/schema.ts +89 -121
  72. package/src/start-compiler-plugin.ts +4 -0
  73. package/src/start-manifest-plugin/plugin.ts +121 -165
  74. package/src/start-router-plugin/generator-plugins/routes-manifest-plugin.ts +2 -2
  75. package/src/start-router-plugin/plugin.ts +26 -2
  76. package/src/start-router-plugin/route-tree-client-plugin.ts +2 -1
  77. package/src/start-router-plugin/virtual-route-tree-plugin.ts +3 -4
  78. package/dist/cjs/compilers.cjs +0 -416
  79. package/dist/cjs/compilers.cjs.map +0 -1
  80. package/dist/cjs/compilers.d.cts +0 -21
  81. package/dist/cjs/constants.cjs +0 -14
  82. package/dist/cjs/constants.cjs.map +0 -1
  83. package/dist/cjs/constants.d.cts +0 -6
  84. package/dist/cjs/debug.cjs +0 -5
  85. package/dist/cjs/debug.cjs.map +0 -1
  86. package/dist/cjs/debug.d.cts +0 -1
  87. package/dist/cjs/dev-server-plugin/extract-html-scripts.cjs +0 -35
  88. package/dist/cjs/dev-server-plugin/extract-html-scripts.cjs.map +0 -1
  89. package/dist/cjs/dev-server-plugin/extract-html-scripts.d.cts +0 -4
  90. package/dist/cjs/dev-server-plugin/plugin.cjs +0 -136
  91. package/dist/cjs/dev-server-plugin/plugin.cjs.map +0 -1
  92. package/dist/cjs/dev-server-plugin/plugin.d.cts +0 -5
  93. package/dist/cjs/index.cjs +0 -11
  94. package/dist/cjs/index.cjs.map +0 -1
  95. package/dist/cjs/index.d.cts +0 -3
  96. package/dist/cjs/load-env-plugin/plugin.cjs +0 -34
  97. package/dist/cjs/load-env-plugin/plugin.cjs.map +0 -1
  98. package/dist/cjs/load-env-plugin/plugin.d.cts +0 -3
  99. package/dist/cjs/nitro-plugin/build-sitemap.cjs +0 -138
  100. package/dist/cjs/nitro-plugin/build-sitemap.cjs.map +0 -1
  101. package/dist/cjs/nitro-plugin/build-sitemap.d.cts +0 -31
  102. package/dist/cjs/nitro-plugin/plugin.cjs +0 -181
  103. package/dist/cjs/nitro-plugin/plugin.cjs.map +0 -1
  104. package/dist/cjs/nitro-plugin/plugin.d.cts +0 -3
  105. package/dist/cjs/nitro-plugin/prerender.cjs +0 -170
  106. package/dist/cjs/nitro-plugin/prerender.cjs.map +0 -1
  107. package/dist/cjs/nitro-plugin/prerender.d.cts +0 -8
  108. package/dist/cjs/nitro-plugin/queue.cjs +0 -131
  109. package/dist/cjs/nitro-plugin/queue.cjs.map +0 -1
  110. package/dist/cjs/nitro-plugin/queue.d.cts +0 -32
  111. package/dist/cjs/plugin.cjs +0 -191
  112. package/dist/cjs/plugin.cjs.map +0 -1
  113. package/dist/cjs/plugin.d.cts +0 -291
  114. package/dist/cjs/resolve-virtual-entries-plugin/plugin.cjs +0 -66
  115. package/dist/cjs/resolve-virtual-entries-plugin/plugin.cjs.map +0 -1
  116. package/dist/cjs/resolve-virtual-entries-plugin/plugin.d.cts +0 -3
  117. package/dist/cjs/schema.cjs +0 -157
  118. package/dist/cjs/schema.cjs.map +0 -1
  119. package/dist/cjs/schema.d.cts +0 -8779
  120. package/dist/cjs/start-compiler-plugin.cjs +0 -74
  121. package/dist/cjs/start-compiler-plugin.cjs.map +0 -1
  122. package/dist/cjs/start-compiler-plugin.d.cts +0 -13
  123. package/dist/cjs/start-manifest-plugin/plugin.cjs +0 -207
  124. package/dist/cjs/start-manifest-plugin/plugin.cjs.map +0 -1
  125. package/dist/cjs/start-manifest-plugin/plugin.d.cts +0 -3
  126. package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.cjs +0 -39
  127. package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.cjs.map +0 -1
  128. package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.d.cts +0 -6
  129. package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.cjs +0 -121
  130. package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.cjs.map +0 -1
  131. package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.d.cts +0 -2
  132. package/dist/cjs/start-router-plugin/plugin.cjs +0 -21
  133. package/dist/cjs/start-router-plugin/plugin.cjs.map +0 -1
  134. package/dist/cjs/start-router-plugin/plugin.d.cts +0 -3
  135. package/dist/cjs/start-router-plugin/route-tree-client-plugin.cjs +0 -72
  136. package/dist/cjs/start-router-plugin/route-tree-client-plugin.cjs.map +0 -1
  137. package/dist/cjs/start-router-plugin/route-tree-client-plugin.d.cts +0 -6
  138. package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.cjs +0 -30
  139. package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.cjs.map +0 -1
  140. package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.d.cts +0 -4
  141. package/dist/cjs/utils.cjs +0 -18
  142. package/dist/cjs/utils.cjs.map +0 -1
  143. package/dist/cjs/utils.d.cts +0 -8
  144. package/dist/esm/nitro-plugin/build-sitemap.js.map +0 -1
  145. package/dist/esm/nitro-plugin/plugin.d.ts +0 -3
  146. package/dist/esm/nitro-plugin/plugin.js +0 -181
  147. package/dist/esm/nitro-plugin/plugin.js.map +0 -1
  148. package/dist/esm/nitro-plugin/prerender.d.ts +0 -8
  149. package/dist/esm/nitro-plugin/prerender.js.map +0 -1
  150. package/dist/esm/nitro-plugin/queue.js.map +0 -1
  151. package/dist/esm/resolve-virtual-entries-plugin/plugin.d.ts +0 -3
  152. package/dist/esm/resolve-virtual-entries-plugin/plugin.js +0 -49
  153. package/dist/esm/resolve-virtual-entries-plugin/plugin.js.map +0 -1
  154. package/src/nitro-plugin/plugin.ts +0 -244
  155. package/src/resolve-virtual-entries-plugin/plugin.ts +0 -63
  156. /package/dist/esm/{nitro-plugin/queue.d.ts → queue.d.ts} +0 -0
  157. /package/src/{nitro-plugin/queue.ts → queue.ts} +0 -0
@@ -1,113 +1,136 @@
1
- import { createEvent, getHeader, sendWebResponse } from 'h3'
2
1
  import { isRunnableDevEnvironment } from 'vite'
3
- import { VITE_ENVIRONMENT_NAMES } from '../constants'
2
+ import { VIRTUAL_MODULES } from '@tanstack/start-server-core'
3
+ import { NodeRequest, sendNodeResponse } from 'srvx/node'
4
+ import { ENTRY_POINTS, VITE_ENVIRONMENT_NAMES } from '../constants'
5
+ import { resolveViteId } from '../utils'
4
6
  import { extractHtmlScripts } from './extract-html-scripts'
5
- import type { Connect, DevEnvironment, Plugin, ViteDevServer } from 'vite'
6
-
7
- declare global {
8
- // eslint-disable-next-line no-var
9
- var TSS_INJECTED_HEAD_SCRIPTS: string | undefined
10
- }
11
-
12
- export function devServerPlugin(): Plugin {
13
- // let config: UserConfig
7
+ import type { Connect, DevEnvironment, PluginOption } from 'vite'
8
+ import type { TanStackStartOutputConfig } from '../schema'
9
+
10
+ export function devServerPlugin({
11
+ startConfig,
12
+ }: {
13
+ startConfig: TanStackStartOutputConfig
14
+ }): PluginOption {
14
15
  let isTest = false
15
16
 
16
- return {
17
- name: 'start-dev-ssr-plugin',
18
- config(userConfig, { mode }) {
19
- // config = userConfig
20
- isTest = isTest ? isTest : mode === 'test'
21
- },
22
- configureServer(viteDevServer) {
23
- if (isTest) {
24
- return
25
- }
26
-
27
- ;(globalThis as any).viteDevServer = viteDevServer
28
-
29
- return () => {
30
- remove_html_middlewares(viteDevServer.middlewares)
31
- let cachedScripts: string | undefined
32
-
33
- viteDevServer.middlewares.use(async (req, res) => {
34
- // Create an H3Event to have it passed into the server entry
35
- // i.e: event => defineEventHandler(event)
36
- const event = createEvent(req, res)
37
-
17
+ let injectedHeadScripts: string | undefined
18
+
19
+ return [
20
+ {
21
+ name: 'tanstack-start-core:dev-server',
22
+ config(_userConfig, { mode }) {
23
+ isTest = isTest ? isTest : mode === 'test'
24
+ },
25
+ async configureServer(viteDevServer) {
26
+ if (isTest) {
27
+ return
28
+ }
29
+
30
+ // Extract the scripts that Vite plugins would inject into the initial HTML
31
+ const templateHtml = `<html><head></head><body></body></html>`
32
+ const transformedHtml = await viteDevServer.transformIndexHtml(
33
+ '/',
34
+ templateHtml,
35
+ )
36
+ const scripts = extractHtmlScripts(transformedHtml)
37
+ injectedHeadScripts = scripts
38
+ .flatMap((script) => script.content ?? [])
39
+ .join(';')
40
+
41
+ return () => {
38
42
  const serverEnv = viteDevServer.environments[
39
43
  VITE_ENVIRONMENT_NAMES.server
40
44
  ] as DevEnvironment | undefined
41
45
 
42
- try {
43
- if (!serverEnv) {
44
- throw new Error(
45
- `Server environment ${VITE_ENVIRONMENT_NAMES.server} not found`,
46
- )
47
- }
48
-
49
- if (!isRunnableDevEnvironment(serverEnv)) {
50
- throw new Error(
51
- `Expected server environment ${VITE_ENVIRONMENT_NAMES.server} to be a RunnableDevEnvironment. This can be caused by multiple vite versions being installed in the project.`,
52
- )
46
+ if (!serverEnv) {
47
+ throw new Error(
48
+ `Server environment ${VITE_ENVIRONMENT_NAMES.server} not found`,
49
+ )
50
+ }
51
+ const installMiddleware = startConfig.vite?.installDevServerMiddleware
52
+ if (installMiddleware === false) {
53
+ return
54
+ }
55
+ if (installMiddleware == undefined) {
56
+ // do not install middleware in middlewareMode by default
57
+ if (viteDevServer.config.server.middlewareMode) {
58
+ return
53
59
  }
54
60
 
55
- // Extract the scripts that Vite plugins would inject into the initial HTML
56
- if (cachedScripts === undefined) {
57
- const templateHtml = `<html><head></head><body></body></html>`
58
- const transformedHtml = await viteDevServer.transformIndexHtml(
59
- req.url || '/',
60
- templateHtml,
61
- )
62
- const scripts = extractHtmlScripts(transformedHtml)
63
- globalThis.TSS_INJECTED_HEAD_SCRIPTS = scripts
64
- .map((script) => script.content ?? '')
65
- .join(';')
61
+ // do not install middleware if SSR env in case another plugin already did
62
+ if (
63
+ !isRunnableDevEnvironment(serverEnv) ||
64
+ // do not check via `isFetchableDevEnvironment` since nitro does implement the `FetchableDevEnvironment` interface but not via inheritance (which this helper checks)
65
+ 'dispatchFetch' in serverEnv
66
+ ) {
67
+ return
66
68
  }
69
+ }
67
70
 
68
- // Import and resolve the request by running the server entry point
69
- // i.e export default defineEventHandler((event) => { ... })
70
- const serverEntry = await serverEnv.runner.import(
71
- '/~start/server-entry',
71
+ if (!isRunnableDevEnvironment(serverEnv)) {
72
+ throw new Error(
73
+ 'cannot install vite dev server middleware for TanStack Start since the SSR environment is not a RunnableDevEnvironment',
72
74
  )
73
- const response = await serverEntry['default'](event)
74
-
75
- return sendWebResponse(event, response)
76
- } catch (e) {
77
- console.error(e)
78
- viteDevServer.ssrFixStacktrace(e as Error)
75
+ }
79
76
 
80
- if (
81
- getHeader(event, 'content-type')?.includes('application/json')
82
- ) {
83
- return sendWebResponse(
84
- event,
85
- new Response(
86
- JSON.stringify(
77
+ viteDevServer.middlewares.use(async (req, res) => {
78
+ // fix the request URL to match the original URL
79
+ // otherwise, the request URL will '/index.html'
80
+ if (req.originalUrl) {
81
+ req.url = req.originalUrl
82
+ }
83
+ const webReq = new NodeRequest({ req, res })
84
+
85
+ try {
86
+ // Import and resolve the request by running the server request entry point
87
+ // this request entry point must implement the `fetch` API as follows:
88
+ /**
89
+ * export default {
90
+ * fetch(req: Request): Promise<Response>
91
+ * }
92
+ */
93
+ const serverEntry = await serverEnv.runner.import(
94
+ ENTRY_POINTS.server,
95
+ )
96
+ const webRes = await serverEntry['default'].fetch(webReq)
97
+
98
+ return sendNodeResponse(res, webRes)
99
+ } catch (e) {
100
+ console.error(e)
101
+ viteDevServer.ssrFixStacktrace(e as Error)
102
+
103
+ if (
104
+ webReq.headers.get('content-type')?.includes('application/json')
105
+ ) {
106
+ return sendNodeResponse(
107
+ res,
108
+ new Response(
109
+ JSON.stringify(
110
+ {
111
+ status: 500,
112
+ error: 'Internal Server Error',
113
+ message:
114
+ 'An unexpected error occurred. Please try again later.',
115
+ timestamp: new Date().toISOString(),
116
+ },
117
+ null,
118
+ 2,
119
+ ),
87
120
  {
88
121
  status: 500,
89
- error: 'Internal Server Error',
90
- message:
91
- 'An unexpected error occurred. Please try again later.',
92
- timestamp: new Date().toISOString(),
122
+ headers: {
123
+ 'Content-Type': 'application/json',
124
+ },
93
125
  },
94
- null,
95
- 2,
96
126
  ),
97
- {
98
- status: 500,
99
- headers: {
100
- 'Content-Type': 'application/json',
101
- },
102
- },
103
- ),
104
- )
105
- }
127
+ )
128
+ }
106
129
 
107
- return sendWebResponse(
108
- event,
109
- new Response(
110
- `
130
+ return sendNodeResponse(
131
+ res,
132
+ new Response(
133
+ `
111
134
  <!DOCTYPE html>
112
135
  <html lang="en">
113
136
  <head>
@@ -124,42 +147,41 @@ export function devServerPlugin(): Plugin {
124
147
  </body>
125
148
  </html>
126
149
  `,
127
- {
128
- status: 500,
129
- headers: {
130
- 'Content-Type': 'text/html',
150
+ {
151
+ status: 500,
152
+ headers: {
153
+ 'Content-Type': 'text/html',
154
+ },
131
155
  },
132
- },
133
- ),
134
- )
135
- }
136
- })
137
- }
156
+ ),
157
+ )
158
+ }
159
+ })
160
+ }
161
+ },
162
+ },
163
+ {
164
+ name: 'tanstack-start-core:dev-server:injected-head-scripts',
165
+ sharedDuringBuild: true,
166
+ applyToEnvironment: (env) => env.config.consumer === 'server',
167
+ resolveId: {
168
+ filter: { id: new RegExp(VIRTUAL_MODULES.injectedHeadScripts) },
169
+ handler(_id) {
170
+ return resolveViteId(VIRTUAL_MODULES.injectedHeadScripts)
171
+ },
172
+ },
173
+ load: {
174
+ filter: {
175
+ id: new RegExp(resolveViteId(VIRTUAL_MODULES.injectedHeadScripts)),
176
+ },
177
+ handler() {
178
+ const mod = `
179
+ export const injectedHeadScripts = ${JSON.stringify(injectedHeadScripts) || 'undefined'}`
180
+ return mod
181
+ },
182
+ },
138
183
  },
139
- }
140
- }
141
-
142
- /**
143
- * Removes Vite internal middleware
144
- *
145
- * @param server
146
- */
147
- function remove_html_middlewares(server: ViteDevServer['middlewares']) {
148
- const html_middlewares = [
149
- 'viteIndexHtmlMiddleware',
150
- 'vite404Middleware',
151
- 'viteSpaFallbackMiddleware',
152
184
  ]
153
- for (let i = server.stack.length - 1; i > 0; i--) {
154
- if (
155
- html_middlewares.includes(
156
- // @ts-expect-error
157
- server.stack[i].handle.name,
158
- )
159
- ) {
160
- server.stack.splice(i, 1)
161
- }
162
- }
163
185
  }
164
186
 
165
187
  /**
package/src/index.ts CHANGED
@@ -1,8 +1,4 @@
1
- export {
2
- createTanStackConfig,
3
- createTanStackStartOptionsSchema,
4
- pageSchema,
5
- } from './schema'
1
+ export type { TanStackStartInputConfig } from './schema'
6
2
 
7
3
  export { TanStackStartVitePluginCore } from './plugin'
8
4
  export { resolveViteId } from './utils'
@@ -1,17 +1,12 @@
1
- import * as vite from 'vite'
2
- import type { TanStackStartOutputConfig } from '../plugin'
1
+ import { loadEnv } from 'vite'
2
+ import type { Plugin } from 'vite'
3
3
 
4
- export function loadEnvPlugin(
5
- startOpts: TanStackStartOutputConfig,
6
- ): vite.Plugin {
4
+ export function loadEnvPlugin(): Plugin {
7
5
  return {
8
- name: 'tanstack-vite-plugin-nitro-load-env',
6
+ name: 'tanstack-start-core:load-env',
9
7
  enforce: 'pre',
10
- config(userConfig, envConfig) {
11
- Object.assign(
12
- process.env,
13
- vite.loadEnv(envConfig.mode, userConfig.root ?? startOpts.root, ''),
14
- )
8
+ configResolved(config) {
9
+ Object.assign(process.env, loadEnv(config.mode, config.root))
15
10
  },
16
11
  }
17
12
  }
@@ -0,0 +1,18 @@
1
+ import { join } from 'pathe'
2
+ import { VITE_ENVIRONMENT_NAMES } from './constants'
3
+ import type * as vite from 'vite'
4
+
5
+ export function getClientOutputDirectory(userConfig: vite.UserConfig) {
6
+ return (
7
+ userConfig.environments?.[VITE_ENVIRONMENT_NAMES.client]?.build?.outDir ??
8
+ join(getServerOutputDirectory(userConfig), 'public')
9
+ )
10
+ }
11
+
12
+ export function getServerOutputDirectory(userConfig: vite.UserConfig) {
13
+ const rootOutputDirectory = userConfig.build?.outDir ?? 'dist'
14
+ return (
15
+ userConfig.environments?.[VITE_ENVIRONMENT_NAMES.server]?.build?.outDir ??
16
+ rootOutputDirectory
17
+ )
18
+ }