@platformatic/service 0.7.0 → 0.9.0
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.
- package/index.js +78 -49
- package/lib/autoload-wrapper.js +11 -0
- package/lib/config.js +32 -7
- package/lib/schema.js +61 -31
- package/lib/start.mjs +3 -3
- package/package.json +6 -5
- package/test/autoload.test.js +346 -0
- package/test/cli/start.test.mjs +6 -1
- package/test/cli/watch.test.mjs +18 -22
- package/test/config.test.js +118 -0
- package/test/fixtures/bad-typescript-plugin/platformatic.service.json +2 -2
- package/test/fixtures/directories/platformatic.service.json +13 -0
- package/test/fixtures/directories/plugins/decorator.js +7 -0
- package/test/fixtures/directories/routes/foo/bar.js +11 -0
- package/test/fixtures/directories/routes/foo/baz/index.js +7 -0
- package/test/fixtures/directories/routes/root.js +7 -0
- package/test/fixtures/not-load.js +8 -0
- package/test/fixtures/not-load.service.json +14 -0
- package/test/load-and-reload-files.test.js +5 -13
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { start } = require('@fastify/restartable')
|
|
4
|
+
const autoload = require('@fastify/autoload')
|
|
4
5
|
const sandbox = require('fastify-sandbox')
|
|
5
6
|
const underPressure = require('@fastify/under-pressure')
|
|
6
7
|
const { schema } = require('./lib/schema')
|
|
@@ -9,6 +10,9 @@ const { addLoggerToTheConfig, getJSPluginPath } = require('./lib/utils')
|
|
|
9
10
|
const loadConfig = require('./lib/load-config')
|
|
10
11
|
const { isKeyEnabled, deepmerge } = require('@platformatic/utils')
|
|
11
12
|
const compiler = require('./lib/compile')
|
|
13
|
+
const { stat } = require('fs').promises
|
|
14
|
+
const { join } = require('path')
|
|
15
|
+
const wrapperPath = join(__dirname, 'lib', 'autoload-wrapper.js')
|
|
12
16
|
|
|
13
17
|
function createServerConfig (config) {
|
|
14
18
|
// convert the config file to a new structure
|
|
@@ -46,44 +50,15 @@ async function platformaticService (app, opts, toLoad = []) {
|
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
app.log.debug({ plugin: opts.plugin }, 'loading plugin')
|
|
58
|
-
|
|
59
|
-
// if not defined, we defaults to true (which can happen only if config is set programmatically,
|
|
60
|
-
// that's why we ignore the coverage of the `undefined` case, which cannot be covered in cli tests)
|
|
61
|
-
/* c8 ignore next */
|
|
62
|
-
const hotReload = opts.plugin.watchOptions?.hotReload !== false
|
|
63
|
-
const isWatchEnabled = opts.plugin.watch !== false
|
|
64
|
-
/* c8 ignore next 13 */
|
|
65
|
-
if (isWatchEnabled && hotReload) {
|
|
66
|
-
await app.register(sandbox, {
|
|
67
|
-
...pluginOptions,
|
|
68
|
-
customizeGlobalThis (_globalThis) {
|
|
69
|
-
// Taken from https://github.com/nodejs/undici/blob/fa9fd9066569b6357acacffb806aa804b688c9d8/lib/global.js#L5
|
|
70
|
-
const globalDispatcher = Symbol.for('undici.globalDispatcher.1')
|
|
71
|
-
const dispatcher = globalThis[globalDispatcher]
|
|
72
|
-
/* istanbul ignore else */
|
|
73
|
-
if (dispatcher) {
|
|
74
|
-
_globalThis[globalDispatcher] = dispatcher
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
})
|
|
78
|
-
// c8 fails in reporting the coverage of this else branch, so we ignore it
|
|
79
|
-
/* c8 ignore next 7 */
|
|
80
|
-
} else {
|
|
81
|
-
let plugin = await import(`file://${pluginOptions.path}`)
|
|
82
|
-
if (plugin.__esModule === true) {
|
|
83
|
-
plugin = plugin.default
|
|
84
|
-
}
|
|
85
|
-
await app.register(plugin, pluginOptions.options)
|
|
53
|
+
// TODO apparently c8 is not able to mark
|
|
54
|
+
// this as covered even if it is
|
|
55
|
+
/* c8 ignore next 7 */
|
|
56
|
+
if (Array.isArray(opts.plugin)) {
|
|
57
|
+
for (const plugin of opts.plugin) {
|
|
58
|
+
await loadPlugin(app, opts, plugin)
|
|
86
59
|
}
|
|
60
|
+
} else if (opts.plugin) {
|
|
61
|
+
await loadPlugin(app, opts, opts.plugin)
|
|
87
62
|
}
|
|
88
63
|
|
|
89
64
|
// Enable CORS
|
|
@@ -99,17 +74,69 @@ async function platformaticService (app, opts, toLoad = []) {
|
|
|
99
74
|
}
|
|
100
75
|
}
|
|
101
76
|
|
|
77
|
+
async function loadPlugin (app, config, pluginOptions) {
|
|
78
|
+
/* c8 ignore next 4 */
|
|
79
|
+
if (pluginOptions.typescript !== undefined) {
|
|
80
|
+
const pluginPath = getJSPluginPath(pluginOptions.path, pluginOptions.typescript.outDir)
|
|
81
|
+
pluginOptions = { ...pluginOptions, path: pluginPath }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
app.log.debug({ plugin: pluginOptions }, 'loading plugin')
|
|
85
|
+
|
|
86
|
+
// if not defined, we defaults to true (which can happen only if config is set programmatically,
|
|
87
|
+
// that's why we ignore the coverage of the `undefined` case, which cannot be covered in cli tests)
|
|
88
|
+
/* c8 ignore next 35 */
|
|
89
|
+
const hotReload = pluginOptions.hotReload !== false
|
|
90
|
+
const isWatchEnabled = config.watch !== false
|
|
91
|
+
if (isWatchEnabled && hotReload) {
|
|
92
|
+
let options = pluginOptions
|
|
93
|
+
if ((await stat(pluginOptions.path)).isDirectory()) {
|
|
94
|
+
options = {
|
|
95
|
+
path: wrapperPath,
|
|
96
|
+
options: pluginOptions
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
await app.register(sandbox, {
|
|
100
|
+
...options,
|
|
101
|
+
customizeGlobalThis (_globalThis) {
|
|
102
|
+
// Taken from https://github.com/nodejs/undici/blob/fa9fd9066569b6357acacffb806aa804b688c9d8/lib/global.js#L5
|
|
103
|
+
const globalDispatcher = Symbol.for('undici.globalDispatcher.1')
|
|
104
|
+
const dispatcher = globalThis[globalDispatcher]
|
|
105
|
+
/* istanbul ignore else */
|
|
106
|
+
if (dispatcher) {
|
|
107
|
+
_globalThis[globalDispatcher] = dispatcher
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
// c8 fails in reporting the coverage of this else branch, so we ignore it
|
|
112
|
+
} else {
|
|
113
|
+
if ((await stat(pluginOptions.path)).isDirectory()) {
|
|
114
|
+
const options = {
|
|
115
|
+
...pluginOptions.options,
|
|
116
|
+
dir: pluginOptions.path
|
|
117
|
+
}
|
|
118
|
+
await app.register(autoload, options)
|
|
119
|
+
} else {
|
|
120
|
+
let plugin = await import(`file://${pluginOptions.path}`)
|
|
121
|
+
if (plugin.__esModule === true) {
|
|
122
|
+
plugin = plugin.default
|
|
123
|
+
}
|
|
124
|
+
await app.register(plugin, pluginOptions.options)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
102
129
|
platformaticService[Symbol.for('skip-override')] = true
|
|
103
130
|
|
|
104
131
|
async function buildServer (options, app = platformaticService) {
|
|
105
132
|
if (!options.configManager) {
|
|
106
133
|
// instantiate a new config manager from current options
|
|
107
134
|
const cm = new ConfigManager({
|
|
108
|
-
source:
|
|
135
|
+
source: options,
|
|
109
136
|
schema
|
|
110
137
|
})
|
|
111
138
|
await cm.parseAndValidate()
|
|
112
|
-
options = deepmerge({}, cm.current
|
|
139
|
+
options = deepmerge({}, options, cm.current)
|
|
113
140
|
options.configManager = cm
|
|
114
141
|
}
|
|
115
142
|
const serverConfig = createServerConfig(options)
|
|
@@ -137,25 +164,26 @@ async function buildServer (options, app = platformaticService) {
|
|
|
137
164
|
}
|
|
138
165
|
|
|
139
166
|
addLoggerToTheConfig(opts)
|
|
167
|
+
const configManager = handler.app.platformatic.configManager
|
|
168
|
+
|
|
169
|
+
if (!opts) {
|
|
170
|
+
opts = configManager.current
|
|
171
|
+
}
|
|
140
172
|
|
|
141
173
|
// Ignore because not tested on Windows
|
|
142
174
|
// TODO: remove the ignore, we shoduld be testing
|
|
143
175
|
// this on Windows
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
opts = createServerConfig(opts)
|
|
151
|
-
opts.app = app
|
|
152
|
-
}
|
|
176
|
+
const fileWatcher = handler.app.platformatic.fileWatcher
|
|
177
|
+
opts.fileWatcher = fileWatcher
|
|
178
|
+
opts.configManager = configManager
|
|
179
|
+
opts = createServerConfig(opts)
|
|
180
|
+
opts.app = app
|
|
181
|
+
|
|
153
182
|
debounce = _restart(opts).then(() => {
|
|
154
183
|
handler.app.log.info('restarted')
|
|
155
184
|
}).finally(() => {
|
|
156
185
|
debounce = null
|
|
157
186
|
})
|
|
158
|
-
/* c8 ignore stop */
|
|
159
187
|
return debounce
|
|
160
188
|
}
|
|
161
189
|
|
|
@@ -169,3 +197,4 @@ module.exports.platformaticService = platformaticService
|
|
|
169
197
|
module.exports.addLoggerToTheConfig = addLoggerToTheConfig
|
|
170
198
|
module.exports.loadConfig = loadConfig
|
|
171
199
|
module.exports.tsCompiler = compiler
|
|
200
|
+
module.exports.ConfigManager = ConfigManager
|
package/lib/config.js
CHANGED
|
@@ -9,11 +9,12 @@ class ServiceConfigManager extends ConfigManager {
|
|
|
9
9
|
constructor (opts) {
|
|
10
10
|
super({
|
|
11
11
|
...opts,
|
|
12
|
-
schema,
|
|
12
|
+
schema: opts.schema || schema,
|
|
13
13
|
schemaOptions: {
|
|
14
14
|
useDefaults: true,
|
|
15
15
|
coerceTypes: true,
|
|
16
|
-
allErrors: true
|
|
16
|
+
allErrors: true,
|
|
17
|
+
strict: false
|
|
17
18
|
},
|
|
18
19
|
allowToWatch: ['.env'],
|
|
19
20
|
envWhitelist: ['PORT', ...(opts.envWhitelist || [])]
|
|
@@ -21,10 +22,22 @@ class ServiceConfigManager extends ConfigManager {
|
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
_transformConfig () {
|
|
25
|
+
const fixPluginPath = (plugin) => {
|
|
26
|
+
// for some reasons c8 does not detect these
|
|
27
|
+
/* c8 ignore next 3 */
|
|
28
|
+
if (typeof plugin === 'string') {
|
|
29
|
+
plugin = { path: plugin }
|
|
30
|
+
}
|
|
31
|
+
plugin.path = this._fixRelativePath(plugin.path)
|
|
32
|
+
return plugin
|
|
33
|
+
}
|
|
34
|
+
|
|
24
35
|
// relative-to-absolute plugin path
|
|
25
36
|
/* c8 ignore next 3 */
|
|
26
|
-
if (this.current.plugin) {
|
|
27
|
-
this.current.plugin
|
|
37
|
+
if (Array.isArray(this.current.plugin)) {
|
|
38
|
+
this.current.plugin = this.current.plugin.map(fixPluginPath)
|
|
39
|
+
} else if (this.current.plugin) {
|
|
40
|
+
this.current.plugin = fixPluginPath(this.current.plugin)
|
|
28
41
|
}
|
|
29
42
|
}
|
|
30
43
|
|
|
@@ -32,10 +45,22 @@ class ServiceConfigManager extends ConfigManager {
|
|
|
32
45
|
const sanitizedConfig = clone(this.current)
|
|
33
46
|
const dirOfConfig = dirname(this.fullPath)
|
|
34
47
|
|
|
48
|
+
const fixPluginPath = (plugin) => {
|
|
49
|
+
// for some reasons c8 does not detect these
|
|
50
|
+
/* c8 ignore next 3 */
|
|
51
|
+
if (typeof plugin === 'string') {
|
|
52
|
+
plugin = { path: plugin }
|
|
53
|
+
}
|
|
54
|
+
plugin.path = relative(dirOfConfig, plugin.path)
|
|
55
|
+
return plugin
|
|
56
|
+
}
|
|
57
|
+
|
|
35
58
|
// relative-to-absolute plugin path
|
|
36
|
-
/* c8 ignore next
|
|
37
|
-
if (this.current.plugin) {
|
|
38
|
-
sanitizedConfig.plugin
|
|
59
|
+
/* c8 ignore next 6 */
|
|
60
|
+
if (Array.isArray(this.current.plugin)) {
|
|
61
|
+
sanitizedConfig.plugin = sanitizedConfig.plugin.map(fixPluginPath)
|
|
62
|
+
} else if (this.current.plugin) {
|
|
63
|
+
sanitizedConfig.plugin = fixPluginPath(sanitizedConfig.plugin)
|
|
39
64
|
}
|
|
40
65
|
|
|
41
66
|
return sanitizedConfig
|
package/lib/schema.js
CHANGED
|
@@ -84,6 +84,9 @@ const server = {
|
|
|
84
84
|
{ type: 'string' }
|
|
85
85
|
]
|
|
86
86
|
},
|
|
87
|
+
pluginTimeout: {
|
|
88
|
+
type: 'integer'
|
|
89
|
+
},
|
|
87
90
|
healthCheck: {
|
|
88
91
|
anyOf: [
|
|
89
92
|
{ type: 'boolean' },
|
|
@@ -102,6 +105,34 @@ const server = {
|
|
|
102
105
|
required: ['hostname', 'port']
|
|
103
106
|
}
|
|
104
107
|
|
|
108
|
+
const watch = {
|
|
109
|
+
$id: 'https://schemas.platformatic.dev/service/watch',
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
type: 'object',
|
|
113
|
+
properties: {
|
|
114
|
+
allow: {
|
|
115
|
+
type: 'array',
|
|
116
|
+
items: {
|
|
117
|
+
type: 'string'
|
|
118
|
+
},
|
|
119
|
+
minItems: 1,
|
|
120
|
+
nullable: true,
|
|
121
|
+
default: null
|
|
122
|
+
},
|
|
123
|
+
ignore: {
|
|
124
|
+
type: 'array',
|
|
125
|
+
items: {
|
|
126
|
+
type: 'string'
|
|
127
|
+
},
|
|
128
|
+
nullable: true,
|
|
129
|
+
default: null
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
additionalProperties: false
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
105
136
|
const plugin = {
|
|
106
137
|
$id: 'https://schemas.platformatic.dev/service/plugin',
|
|
107
138
|
type: 'object',
|
|
@@ -122,38 +153,12 @@ const plugin = {
|
|
|
122
153
|
additionalProperties: false,
|
|
123
154
|
required: ['outDir']
|
|
124
155
|
},
|
|
125
|
-
watch: {
|
|
126
|
-
type: 'boolean'
|
|
127
|
-
},
|
|
128
156
|
fallback: {
|
|
129
157
|
type: 'boolean'
|
|
130
158
|
},
|
|
131
|
-
|
|
132
|
-
type: '
|
|
133
|
-
|
|
134
|
-
hotReload: {
|
|
135
|
-
type: 'boolean',
|
|
136
|
-
default: true
|
|
137
|
-
},
|
|
138
|
-
allow: {
|
|
139
|
-
type: 'array',
|
|
140
|
-
items: {
|
|
141
|
-
type: 'string'
|
|
142
|
-
},
|
|
143
|
-
minItems: 1,
|
|
144
|
-
nullable: true,
|
|
145
|
-
default: null
|
|
146
|
-
},
|
|
147
|
-
ignore: {
|
|
148
|
-
type: 'array',
|
|
149
|
-
items: {
|
|
150
|
-
type: 'string'
|
|
151
|
-
},
|
|
152
|
-
nullable: true,
|
|
153
|
-
default: null
|
|
154
|
-
}
|
|
155
|
-
},
|
|
156
|
-
additionalProperties: false
|
|
159
|
+
hotReload: {
|
|
160
|
+
type: 'boolean',
|
|
161
|
+
default: true
|
|
157
162
|
},
|
|
158
163
|
options: {
|
|
159
164
|
type: 'object'
|
|
@@ -190,12 +195,36 @@ const metrics = {
|
|
|
190
195
|
const platformaticServiceSchema = {
|
|
191
196
|
$id: 'https://schemas.platformatic.dev/db',
|
|
192
197
|
type: 'object',
|
|
198
|
+
$defs: {
|
|
199
|
+
plugin
|
|
200
|
+
},
|
|
193
201
|
properties: {
|
|
194
202
|
server,
|
|
195
|
-
plugin
|
|
203
|
+
plugin: {
|
|
204
|
+
anyOf: [{
|
|
205
|
+
type: 'array',
|
|
206
|
+
items: {
|
|
207
|
+
anyOf: [{
|
|
208
|
+
$ref: '#/$defs/plugin'
|
|
209
|
+
}, {
|
|
210
|
+
type: 'string'
|
|
211
|
+
}]
|
|
212
|
+
}
|
|
213
|
+
}, {
|
|
214
|
+
$ref: '#/$defs/plugin'
|
|
215
|
+
}, {
|
|
216
|
+
type: 'string'
|
|
217
|
+
}]
|
|
218
|
+
},
|
|
196
219
|
metrics
|
|
197
220
|
},
|
|
198
|
-
additionalProperties:
|
|
221
|
+
additionalProperties: {
|
|
222
|
+
watch: {
|
|
223
|
+
anyOf: [watch, {
|
|
224
|
+
type: 'boolean'
|
|
225
|
+
}]
|
|
226
|
+
}
|
|
227
|
+
},
|
|
199
228
|
required: ['server']
|
|
200
229
|
}
|
|
201
230
|
|
|
@@ -204,3 +233,4 @@ module.exports.metrics = metrics
|
|
|
204
233
|
module.exports.cors = cors
|
|
205
234
|
module.exports.server = server
|
|
206
235
|
module.exports.plugin = plugin
|
|
236
|
+
module.exports.watch = watch
|
package/lib/start.mjs
CHANGED
|
@@ -40,7 +40,7 @@ async function start (_args) {
|
|
|
40
40
|
|
|
41
41
|
if (
|
|
42
42
|
config.plugin !== undefined &&
|
|
43
|
-
config.
|
|
43
|
+
config.watch !== false
|
|
44
44
|
) {
|
|
45
45
|
await startFileWatching(server)
|
|
46
46
|
}
|
|
@@ -92,8 +92,8 @@ async function startFileWatching (server) {
|
|
|
92
92
|
|
|
93
93
|
const fileWatcher = new FileWatcher({
|
|
94
94
|
path: dirname(configManager.fullPath),
|
|
95
|
-
allowToWatch: config.
|
|
96
|
-
watchIgnore: config.
|
|
95
|
+
allowToWatch: config.watch?.allow,
|
|
96
|
+
watchIgnore: config.watch?.ignore
|
|
97
97
|
})
|
|
98
98
|
fileWatcher.on('update', () => {
|
|
99
99
|
onFilesUpdated(server)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/service",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Matteo Collina <hello@matteocollina.com>",
|
|
@@ -27,15 +27,16 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@fastify/accepts": "^4.0.1",
|
|
30
|
-
"@fastify/
|
|
30
|
+
"@fastify/autoload": "^5.5.0",
|
|
31
|
+
"@fastify/basic-auth": "^5.0.0",
|
|
31
32
|
"@fastify/cors": "^8.0.0",
|
|
32
33
|
"@fastify/deepmerge": "^1.1.0",
|
|
33
34
|
"@fastify/restartable": "^1.3.1",
|
|
34
35
|
"@fastify/static": "^6.5.0",
|
|
35
36
|
"@fastify/swagger": "^8.0.0",
|
|
36
37
|
"@fastify/under-pressure": "^8.0.0",
|
|
37
|
-
"@platformatic/config": "0.
|
|
38
|
-
"@platformatic/utils": "0.
|
|
38
|
+
"@platformatic/config": "0.9.0",
|
|
39
|
+
"@platformatic/utils": "0.9.0",
|
|
39
40
|
"close-with-grace": "^1.1.0",
|
|
40
41
|
"commist": "^3.1.2",
|
|
41
42
|
"desm": "^1.2.0",
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
"fastify": "^4.6.0",
|
|
46
47
|
"fastify-metrics": "^10.0.0",
|
|
47
48
|
"fastify-plugin": "^4.1.0",
|
|
48
|
-
"fastify-sandbox": "^0.
|
|
49
|
+
"fastify-sandbox": "^0.11.0",
|
|
49
50
|
"graphql": "^16.6.0",
|
|
50
51
|
"help-me": "^4.1.0",
|
|
51
52
|
"mercurius": "^11.3.0",
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
require('./helper')
|
|
4
|
+
const { test } = require('tap')
|
|
5
|
+
const { buildServer } = require('..')
|
|
6
|
+
const { request } = require('undici')
|
|
7
|
+
const { join } = require('path')
|
|
8
|
+
|
|
9
|
+
test('autoload & filesystem based routing / watch disabled', async ({ teardown, equal }) => {
|
|
10
|
+
const config = {
|
|
11
|
+
server: {
|
|
12
|
+
hostname: '127.0.0.1',
|
|
13
|
+
port: 0
|
|
14
|
+
},
|
|
15
|
+
plugin: {
|
|
16
|
+
path: join(__dirname, 'fixtures', 'directories', 'routes')
|
|
17
|
+
},
|
|
18
|
+
watch: false,
|
|
19
|
+
metrics: false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const server = await buildServer(config)
|
|
23
|
+
teardown(server.stop)
|
|
24
|
+
await server.listen()
|
|
25
|
+
|
|
26
|
+
{
|
|
27
|
+
const res = await request(`${server.url}/`)
|
|
28
|
+
equal(res.statusCode, 200, 'status code')
|
|
29
|
+
const body = await res.body.json()
|
|
30
|
+
equal(body.hello, 'from root', 'body')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
{
|
|
34
|
+
const res = await request(`${server.url}/foo/bar`)
|
|
35
|
+
equal(res.statusCode, 200, 'status code')
|
|
36
|
+
const body = await res.body.json()
|
|
37
|
+
equal(body.hello, 'from bar', 'body')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
const res = await request(`${server.url}/foo/baz`)
|
|
42
|
+
equal(res.statusCode, 200, 'status code')
|
|
43
|
+
const body = await res.body.json()
|
|
44
|
+
equal(body.hello, 'from baz', 'body')
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test('autoload & filesystem based routing / watch enabled', async ({ teardown, equal }) => {
|
|
49
|
+
const config = {
|
|
50
|
+
server: {
|
|
51
|
+
hostname: '127.0.0.1',
|
|
52
|
+
port: 0
|
|
53
|
+
},
|
|
54
|
+
plugin: {
|
|
55
|
+
path: join(__dirname, 'fixtures', 'directories', 'routes')
|
|
56
|
+
},
|
|
57
|
+
watch: true,
|
|
58
|
+
metrics: false
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const server = await buildServer(config)
|
|
62
|
+
teardown(server.stop)
|
|
63
|
+
await server.listen()
|
|
64
|
+
|
|
65
|
+
{
|
|
66
|
+
const res = await request(`${server.url}/`)
|
|
67
|
+
equal(res.statusCode, 200, 'status code')
|
|
68
|
+
const body = await res.body.json()
|
|
69
|
+
equal(body.hello, 'from root', 'body')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
const res = await request(`${server.url}/foo/bar`)
|
|
74
|
+
equal(res.statusCode, 200, 'status code')
|
|
75
|
+
const body = await res.body.json()
|
|
76
|
+
equal(body.hello, 'from bar', 'body')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
{
|
|
80
|
+
const res = await request(`${server.url}/foo/baz`)
|
|
81
|
+
equal(res.statusCode, 200, 'status code')
|
|
82
|
+
const body = await res.body.json()
|
|
83
|
+
equal(body.hello, 'from baz', 'body')
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test('multiple files', async ({ teardown, equal }) => {
|
|
88
|
+
const config = {
|
|
89
|
+
server: {
|
|
90
|
+
hostname: '127.0.0.1',
|
|
91
|
+
port: 0
|
|
92
|
+
},
|
|
93
|
+
plugin: [{
|
|
94
|
+
path: join(__dirname, 'fixtures', 'directories', 'plugins')
|
|
95
|
+
}, {
|
|
96
|
+
path: join(__dirname, 'fixtures', 'directories', 'routes')
|
|
97
|
+
}],
|
|
98
|
+
watch: true,
|
|
99
|
+
metrics: false
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const server = await buildServer(config)
|
|
103
|
+
teardown(server.stop)
|
|
104
|
+
await server.listen()
|
|
105
|
+
|
|
106
|
+
{
|
|
107
|
+
const res = await request(`${server.url}/`)
|
|
108
|
+
equal(res.statusCode, 200, 'status code')
|
|
109
|
+
const body = await res.body.json()
|
|
110
|
+
equal(body.hello, 'from root', 'body')
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
const res = await request(`${server.url}/foo/bar`)
|
|
115
|
+
equal(res.statusCode, 200, 'status code')
|
|
116
|
+
const body = await res.body.json()
|
|
117
|
+
equal(body.hello, 'from bar', 'body')
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
{
|
|
121
|
+
const res = await request(`${server.url}/foo/baz`)
|
|
122
|
+
equal(res.statusCode, 200, 'status code')
|
|
123
|
+
const body = await res.body.json()
|
|
124
|
+
equal(body.hello, 'from baz', 'body')
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
{
|
|
128
|
+
const res = await request(`${server.url}/foo/with-decorator`)
|
|
129
|
+
equal(res.statusCode, 200, 'status code')
|
|
130
|
+
const body = await res.body.json()
|
|
131
|
+
equal(body.hello, 'bar', 'body')
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
test('multiple files / watch false', async ({ teardown, equal }) => {
|
|
136
|
+
const config = {
|
|
137
|
+
server: {
|
|
138
|
+
hostname: '127.0.0.1',
|
|
139
|
+
port: 0
|
|
140
|
+
},
|
|
141
|
+
plugin: [{
|
|
142
|
+
path: join(__dirname, 'fixtures', 'directories', 'plugins')
|
|
143
|
+
}, {
|
|
144
|
+
path: join(__dirname, 'fixtures', 'directories', 'routes')
|
|
145
|
+
}],
|
|
146
|
+
watch: false,
|
|
147
|
+
metrics: false
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const server = await buildServer(config)
|
|
151
|
+
teardown(server.stop)
|
|
152
|
+
await server.listen()
|
|
153
|
+
|
|
154
|
+
{
|
|
155
|
+
const res = await request(`${server.url}/`)
|
|
156
|
+
equal(res.statusCode, 200, 'status code')
|
|
157
|
+
const body = await res.body.json()
|
|
158
|
+
equal(body.hello, 'from root', 'body')
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
{
|
|
162
|
+
const res = await request(`${server.url}/foo/bar`)
|
|
163
|
+
equal(res.statusCode, 200, 'status code')
|
|
164
|
+
const body = await res.body.json()
|
|
165
|
+
equal(body.hello, 'from bar', 'body')
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
{
|
|
169
|
+
const res = await request(`${server.url}/foo/baz`)
|
|
170
|
+
equal(res.statusCode, 200, 'status code')
|
|
171
|
+
const body = await res.body.json()
|
|
172
|
+
equal(body.hello, 'from baz', 'body')
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
{
|
|
176
|
+
const res = await request(`${server.url}/foo/with-decorator`)
|
|
177
|
+
equal(res.statusCode, 200, 'status code')
|
|
178
|
+
const body = await res.body.json()
|
|
179
|
+
equal(body.hello, 'bar', 'body')
|
|
180
|
+
}
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
test('autoload & filesystem based routing / watch disabled / no object', async ({ teardown, equal }) => {
|
|
184
|
+
const config = {
|
|
185
|
+
server: {
|
|
186
|
+
hostname: '127.0.0.1',
|
|
187
|
+
port: 0
|
|
188
|
+
},
|
|
189
|
+
plugin: join(__dirname, 'fixtures', 'directories', 'routes'),
|
|
190
|
+
watch: false,
|
|
191
|
+
metrics: false
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const server = await buildServer(config)
|
|
195
|
+
teardown(server.stop)
|
|
196
|
+
await server.listen()
|
|
197
|
+
|
|
198
|
+
{
|
|
199
|
+
const res = await request(`${server.url}/`)
|
|
200
|
+
equal(res.statusCode, 200, 'status code')
|
|
201
|
+
const body = await res.body.json()
|
|
202
|
+
equal(body.hello, 'from root', 'body')
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
{
|
|
206
|
+
const res = await request(`${server.url}/foo/bar`)
|
|
207
|
+
equal(res.statusCode, 200, 'status code')
|
|
208
|
+
const body = await res.body.json()
|
|
209
|
+
equal(body.hello, 'from bar', 'body')
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
{
|
|
213
|
+
const res = await request(`${server.url}/foo/baz`)
|
|
214
|
+
equal(res.statusCode, 200, 'status code')
|
|
215
|
+
const body = await res.body.json()
|
|
216
|
+
equal(body.hello, 'from baz', 'body')
|
|
217
|
+
}
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
test('autoload & filesystem based routing / watch enabled / no object', async ({ teardown, equal }) => {
|
|
221
|
+
const config = {
|
|
222
|
+
server: {
|
|
223
|
+
hostname: '127.0.0.1',
|
|
224
|
+
port: 0
|
|
225
|
+
},
|
|
226
|
+
plugin: join(__dirname, 'fixtures', 'directories', 'routes'),
|
|
227
|
+
watch: true,
|
|
228
|
+
metrics: false
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const server = await buildServer(config)
|
|
232
|
+
teardown(server.stop)
|
|
233
|
+
await server.listen()
|
|
234
|
+
|
|
235
|
+
{
|
|
236
|
+
const res = await request(`${server.url}/`)
|
|
237
|
+
equal(res.statusCode, 200, 'status code')
|
|
238
|
+
const body = await res.body.json()
|
|
239
|
+
equal(body.hello, 'from root', 'body')
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
{
|
|
243
|
+
const res = await request(`${server.url}/foo/bar`)
|
|
244
|
+
equal(res.statusCode, 200, 'status code')
|
|
245
|
+
const body = await res.body.json()
|
|
246
|
+
equal(body.hello, 'from bar', 'body')
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
{
|
|
250
|
+
const res = await request(`${server.url}/foo/baz`)
|
|
251
|
+
equal(res.statusCode, 200, 'status code')
|
|
252
|
+
const body = await res.body.json()
|
|
253
|
+
equal(body.hello, 'from baz', 'body')
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
test('multiple files / no object', async ({ teardown, equal }) => {
|
|
258
|
+
const config = {
|
|
259
|
+
server: {
|
|
260
|
+
hostname: '127.0.0.1',
|
|
261
|
+
port: 0
|
|
262
|
+
},
|
|
263
|
+
plugin: [join(__dirname, 'fixtures', 'directories', 'plugins'), join(__dirname, 'fixtures', 'directories', 'routes')],
|
|
264
|
+
watch: true,
|
|
265
|
+
metrics: false
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const server = await buildServer(config)
|
|
269
|
+
teardown(server.stop)
|
|
270
|
+
await server.listen()
|
|
271
|
+
|
|
272
|
+
{
|
|
273
|
+
const res = await request(`${server.url}/`)
|
|
274
|
+
equal(res.statusCode, 200, 'status code')
|
|
275
|
+
const body = await res.body.json()
|
|
276
|
+
equal(body.hello, 'from root', 'body')
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
{
|
|
280
|
+
const res = await request(`${server.url}/foo/bar`)
|
|
281
|
+
equal(res.statusCode, 200, 'status code')
|
|
282
|
+
const body = await res.body.json()
|
|
283
|
+
equal(body.hello, 'from bar', 'body')
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
{
|
|
287
|
+
const res = await request(`${server.url}/foo/baz`)
|
|
288
|
+
equal(res.statusCode, 200, 'status code')
|
|
289
|
+
const body = await res.body.json()
|
|
290
|
+
equal(body.hello, 'from baz', 'body')
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
{
|
|
294
|
+
const res = await request(`${server.url}/foo/with-decorator`)
|
|
295
|
+
equal(res.statusCode, 200, 'status code')
|
|
296
|
+
const body = await res.body.json()
|
|
297
|
+
equal(body.hello, 'bar', 'body')
|
|
298
|
+
}
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
test('multiple files / watch false / no object', async ({ teardown, equal }) => {
|
|
302
|
+
const config = {
|
|
303
|
+
server: {
|
|
304
|
+
hostname: '127.0.0.1',
|
|
305
|
+
port: 0
|
|
306
|
+
},
|
|
307
|
+
plugin: [
|
|
308
|
+
join(__dirname, 'fixtures', 'directories', 'plugins'),
|
|
309
|
+
join(__dirname, 'fixtures', 'directories', 'routes')
|
|
310
|
+
],
|
|
311
|
+
watch: false,
|
|
312
|
+
metrics: false
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const server = await buildServer(config)
|
|
316
|
+
teardown(server.stop)
|
|
317
|
+
await server.listen()
|
|
318
|
+
|
|
319
|
+
{
|
|
320
|
+
const res = await request(`${server.url}/`)
|
|
321
|
+
equal(res.statusCode, 200, 'status code')
|
|
322
|
+
const body = await res.body.json()
|
|
323
|
+
equal(body.hello, 'from root', 'body')
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
{
|
|
327
|
+
const res = await request(`${server.url}/foo/bar`)
|
|
328
|
+
equal(res.statusCode, 200, 'status code')
|
|
329
|
+
const body = await res.body.json()
|
|
330
|
+
equal(body.hello, 'from bar', 'body')
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
{
|
|
334
|
+
const res = await request(`${server.url}/foo/baz`)
|
|
335
|
+
equal(res.statusCode, 200, 'status code')
|
|
336
|
+
const body = await res.body.json()
|
|
337
|
+
equal(body.hello, 'from baz', 'body')
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
{
|
|
341
|
+
const res = await request(`${server.url}/foo/with-decorator`)
|
|
342
|
+
equal(res.statusCode, 200, 'status code')
|
|
343
|
+
const body = await res.body.json()
|
|
344
|
+
equal(body.hello, 'bar', 'body')
|
|
345
|
+
}
|
|
346
|
+
})
|
package/test/cli/start.test.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { start } from './helper.mjs'
|
|
1
|
+
import { start, cliPath } from './helper.mjs'
|
|
2
2
|
import { test } from 'tap'
|
|
3
3
|
import { join } from 'desm'
|
|
4
4
|
import { request } from 'undici'
|
|
5
|
+
import { execa } from 'execa'
|
|
5
6
|
|
|
6
7
|
test('autostart', async ({ equal, same, match, teardown }) => {
|
|
7
8
|
const { child, url } = await start('-c', join(import.meta.url, '..', '..', 'fixtures', 'hello', 'platformatic.service.json'))
|
|
@@ -47,3 +48,7 @@ test('plugin options', async ({ equal, same, match, teardown }) => {
|
|
|
47
48
|
|
|
48
49
|
child.kill('SIGINT')
|
|
49
50
|
})
|
|
51
|
+
|
|
52
|
+
test('not load', async ({ rejects }) => {
|
|
53
|
+
await rejects(execa('node', [cliPath, 'start', '-c', join(import.meta.url, '..', 'fixtures', 'not-load.service.json')]))
|
|
54
|
+
})
|
package/test/cli/watch.test.mjs
CHANGED
|
@@ -29,9 +29,9 @@ test('should watch js files by default', async ({ equal, teardown }) => {
|
|
|
29
29
|
hostname: '127.0.0.1',
|
|
30
30
|
port: 0
|
|
31
31
|
},
|
|
32
|
+
watch: true,
|
|
32
33
|
plugin: {
|
|
33
|
-
path: pluginFilePath
|
|
34
|
-
watch: true
|
|
34
|
+
path: pluginFilePath
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -66,12 +66,11 @@ test('should watch allowed file', async ({ comment, teardown }) => {
|
|
|
66
66
|
hostname: '127.0.0.1',
|
|
67
67
|
port: 0
|
|
68
68
|
},
|
|
69
|
+
watch: {
|
|
70
|
+
allow: ['*.js', '*.json']
|
|
71
|
+
},
|
|
69
72
|
plugin: {
|
|
70
|
-
path: pluginFilePath
|
|
71
|
-
watch: true,
|
|
72
|
-
watchOptions: {
|
|
73
|
-
allow: ['*.js', '*.json']
|
|
74
|
-
}
|
|
73
|
+
path: pluginFilePath
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
76
|
|
|
@@ -113,12 +112,11 @@ test('should not watch ignored file', async ({ teardown, equal }) => {
|
|
|
113
112
|
hostname: '127.0.0.1',
|
|
114
113
|
port: 0
|
|
115
114
|
},
|
|
115
|
+
watch: {
|
|
116
|
+
ignore: [basename(pluginFilePath)]
|
|
117
|
+
},
|
|
116
118
|
plugin: {
|
|
117
|
-
path: pluginFilePath
|
|
118
|
-
watch: true,
|
|
119
|
-
watchOptions: {
|
|
120
|
-
ignore: [basename(pluginFilePath)]
|
|
121
|
-
}
|
|
119
|
+
path: pluginFilePath
|
|
122
120
|
}
|
|
123
121
|
}
|
|
124
122
|
|
|
@@ -151,12 +149,11 @@ test('should not loop forever when doing ESM', { skip: true }, async ({ comment,
|
|
|
151
149
|
hostname: '127.0.0.1',
|
|
152
150
|
port: 0
|
|
153
151
|
},
|
|
152
|
+
watch: {
|
|
153
|
+
ignore: [basename(pluginFilePath)]
|
|
154
|
+
},
|
|
154
155
|
plugin: {
|
|
155
|
-
path: pluginFilePath
|
|
156
|
-
watch: true,
|
|
157
|
-
watchOptions: {
|
|
158
|
-
ignore: [basename(pluginFilePath)]
|
|
159
|
-
}
|
|
156
|
+
path: pluginFilePath
|
|
160
157
|
}
|
|
161
158
|
}
|
|
162
159
|
|
|
@@ -196,12 +193,11 @@ test('should watch config file', async ({ comment, teardown }) => {
|
|
|
196
193
|
hostname: '127.0.0.1',
|
|
197
194
|
port: 0
|
|
198
195
|
},
|
|
196
|
+
watch: {
|
|
197
|
+
allow: ['*.js', '*.json']
|
|
198
|
+
},
|
|
199
199
|
plugin: {
|
|
200
|
-
path: pluginFilePath
|
|
201
|
-
watch: true,
|
|
202
|
-
watchOptions: {
|
|
203
|
-
allow: ['*.js', '*.json']
|
|
204
|
-
}
|
|
200
|
+
path: pluginFilePath
|
|
205
201
|
}
|
|
206
202
|
}
|
|
207
203
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
require('./helper')
|
|
4
|
+
const { test } = require('tap')
|
|
5
|
+
const { buildServer } = require('..')
|
|
6
|
+
const { request } = require('undici')
|
|
7
|
+
const { join } = require('path')
|
|
8
|
+
const os = require('os')
|
|
9
|
+
const { writeFile } = require('fs/promises')
|
|
10
|
+
|
|
11
|
+
test('config reloads', async ({ teardown, equal, pass, same }) => {
|
|
12
|
+
const file = join(os.tmpdir(), `some-plugin-${process.pid}.js`)
|
|
13
|
+
|
|
14
|
+
await writeFile(file, `
|
|
15
|
+
module.exports = async function (app, options) {
|
|
16
|
+
app.get('/', () => options.message)
|
|
17
|
+
}`)
|
|
18
|
+
|
|
19
|
+
const server = await buildServer({
|
|
20
|
+
server: {
|
|
21
|
+
hostname: '127.0.0.1',
|
|
22
|
+
port: 0
|
|
23
|
+
},
|
|
24
|
+
plugin: {
|
|
25
|
+
path: file,
|
|
26
|
+
options: {
|
|
27
|
+
message: 'hello'
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
metrics: false
|
|
31
|
+
})
|
|
32
|
+
teardown(server.stop)
|
|
33
|
+
await server.listen()
|
|
34
|
+
|
|
35
|
+
{
|
|
36
|
+
const res = await request(`${server.url}/`)
|
|
37
|
+
equal(res.statusCode, 200, 'add status code')
|
|
38
|
+
same(await res.body.text(), 'hello', 'response')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
await server.app.platformatic.configManager.update({
|
|
42
|
+
server: {
|
|
43
|
+
hostname: '127.0.0.1',
|
|
44
|
+
port: 0
|
|
45
|
+
},
|
|
46
|
+
plugin: {
|
|
47
|
+
path: file,
|
|
48
|
+
options: {
|
|
49
|
+
message: 'ciao mondo'
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
metrics: false
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
await server.restart()
|
|
56
|
+
|
|
57
|
+
{
|
|
58
|
+
const res = await request(`${server.url}/`)
|
|
59
|
+
equal(res.statusCode, 200, 'add status code')
|
|
60
|
+
same(await res.body.text(), 'ciao mondo', 'response')
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test('config reloads from a written file', async ({ teardown, equal, pass, same }) => {
|
|
65
|
+
const config = join(os.tmpdir(), `some-config-${process.pid}-2.json`)
|
|
66
|
+
const file = join(os.tmpdir(), `some-plugin-${process.pid}-2.js`)
|
|
67
|
+
|
|
68
|
+
await writeFile(config, JSON.stringify({
|
|
69
|
+
server: {
|
|
70
|
+
hostname: '127.0.0.1',
|
|
71
|
+
port: 0
|
|
72
|
+
},
|
|
73
|
+
plugin: {
|
|
74
|
+
path: file,
|
|
75
|
+
options: {
|
|
76
|
+
message: 'hello'
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
metrics: false
|
|
80
|
+
}))
|
|
81
|
+
|
|
82
|
+
await writeFile(file, `
|
|
83
|
+
module.exports = async function (app, options) {
|
|
84
|
+
app.get('/', () => options.message)
|
|
85
|
+
}`)
|
|
86
|
+
|
|
87
|
+
const server = await buildServer(config)
|
|
88
|
+
teardown(server.stop)
|
|
89
|
+
await server.listen()
|
|
90
|
+
|
|
91
|
+
{
|
|
92
|
+
const res = await request(`${server.url}/`)
|
|
93
|
+
equal(res.statusCode, 200, 'add status code')
|
|
94
|
+
same(await res.body.text(), 'hello', 'response')
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
await server.app.platformatic.configManager.update({
|
|
98
|
+
server: {
|
|
99
|
+
hostname: '127.0.0.1',
|
|
100
|
+
port: 0
|
|
101
|
+
},
|
|
102
|
+
plugin: {
|
|
103
|
+
path: file,
|
|
104
|
+
options: {
|
|
105
|
+
message: 'ciao mondo'
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
metrics: false
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
await server.restart()
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
const res = await request(`${server.url}/`)
|
|
115
|
+
equal(res.statusCode, 200, 'add status code')
|
|
116
|
+
same(await res.body.text(), 'ciao mondo', 'response')
|
|
117
|
+
}
|
|
118
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = async function (fastify, opts) {
|
|
4
|
+
fastify.get('/bar', async function (request, reply) {
|
|
5
|
+
return { hello: 'from bar' }
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
fastify.get('/with-decorator', async function (request, reply) {
|
|
9
|
+
return { hello: fastify.foo }
|
|
10
|
+
})
|
|
11
|
+
}
|
|
@@ -303,10 +303,7 @@ test('hot reload disabled, CommonJS', async ({ teardown, equal, pass, same }) =>
|
|
|
303
303
|
},
|
|
304
304
|
plugin: {
|
|
305
305
|
path: file,
|
|
306
|
-
|
|
307
|
-
watchOptions: {
|
|
308
|
-
hotReload: false
|
|
309
|
-
}
|
|
306
|
+
hotReload: false
|
|
310
307
|
}
|
|
311
308
|
})
|
|
312
309
|
teardown(server.stop)
|
|
@@ -359,11 +356,9 @@ test('hot reload disabled, ESM', async ({ teardown, equal, pass, same }) => {
|
|
|
359
356
|
plugin: {
|
|
360
357
|
path: file,
|
|
361
358
|
stopTimeout: 1000,
|
|
362
|
-
|
|
363
|
-
watchOptions: {
|
|
364
|
-
hotReload: false
|
|
365
|
-
}
|
|
359
|
+
hotReload: false
|
|
366
360
|
},
|
|
361
|
+
watch: true,
|
|
367
362
|
metrics: false
|
|
368
363
|
})
|
|
369
364
|
teardown(server.stop)
|
|
@@ -416,11 +411,9 @@ test('hot reload disabled, with default export', async ({ teardown, equal, pass,
|
|
|
416
411
|
plugin: {
|
|
417
412
|
path: file,
|
|
418
413
|
stopTimeout: 1000,
|
|
419
|
-
|
|
420
|
-
watchOptions: {
|
|
421
|
-
hotReload: false
|
|
422
|
-
}
|
|
414
|
+
hotReload: false
|
|
423
415
|
},
|
|
416
|
+
watch: true,
|
|
424
417
|
metrics: false
|
|
425
418
|
})
|
|
426
419
|
teardown(server.stop)
|
|
@@ -430,7 +423,6 @@ test('hot reload disabled, with default export', async ({ teardown, equal, pass,
|
|
|
430
423
|
const res = await request(`${server.url}/test`, {
|
|
431
424
|
method: 'GET'
|
|
432
425
|
})
|
|
433
|
-
equal(res.statusCode, 200)
|
|
434
426
|
same(await res.body.json(), { res: 'plugin, version 1' }, 'get rest plugin')
|
|
435
427
|
}
|
|
436
428
|
|