@platformatic/service 0.17.0 → 0.18.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/help/schema.txt +1 -1
- package/index.js +21 -1
- package/lib/compile.js +2 -2
- package/lib/graphql.js +21 -0
- package/lib/load-config.js +6 -1
- package/lib/openapi-schema-defs.js +1140 -0
- package/lib/openapi.js +42 -0
- package/lib/schema.js +229 -25
- package/lib/utils.js +12 -1
- package/package.json +8 -4
- package/test/cli/compile.test.mjs +55 -33
- package/test/cli/gen-schema.test.mjs +1 -2
- package/test/cli/watch.test.mjs +13 -6
- package/test/config.test.js +2 -1
- package/test/fixtures/bad-typescript-plugin/dist/tsconfig.tsbuildinfo +1 -1
- package/test/fixtures/hello-world-resolver.js +16 -0
- package/test/fixtures/typescript-autoload/platformatic.service.json +13 -0
- package/test/fixtures/typescript-autoload/routes/plugin.ts +5 -0
- package/test/fixtures/typescript-autoload/tsconfig.json +22 -0
- package/test/graphql.test.js +154 -0
- package/test/helper.js +1 -2
- package/test/routes.test.js +123 -5
- package/test/tmp/typescript-plugin-clone-3/dist/tsconfig.tsbuildinfo +1 -1
- package/test/tmp/typescript-plugin-clone-4/dist/tsconfig.tsbuildinfo +1 -1
- package/test/tmp/typescript-plugin-clone-7/inner-folder/dist/plugin.js +18 -0
- package/test/tmp/typescript-plugin-clone-7/inner-folder/dist/plugin.js.map +1 -0
- package/test/tmp/typescript-plugin-clone-7/inner-folder/platformatic.service.json +13 -0
- package/test/tmp/typescript-plugin-clone-7/inner-folder/plugin.ts +5 -0
- package/test/tmp/typescript-plugin-clone-7/inner-folder/tsconfig.json +22 -0
- package/test/tmp/typescript-plugin-clone-8/dist/routes/plugin.js +7 -0
- package/test/tmp/typescript-plugin-clone-8/dist/routes/plugin.js.map +1 -0
- package/test/tmp/typescript-plugin-clone-8/dist/tsconfig.tsbuildinfo +1 -0
- package/test/tmp/typescript-plugin-clone-8/platformatic.service.json +13 -0
- package/test/tmp/typescript-plugin-clone-8/routes/plugin.ts +5 -0
- package/test/tmp/typescript-plugin-clone-8/tsconfig.json +22 -0
package/lib/openapi.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const Swagger = require('@fastify/swagger')
|
|
4
|
+
const SwaggerUI = require('@fastify/swagger-ui')
|
|
5
|
+
const deepmerge = require('@fastify/deepmerge')({ all: true })
|
|
6
|
+
const fp = require('fastify-plugin')
|
|
7
|
+
|
|
8
|
+
// For some unknown reason, c8 is not detecting any of this
|
|
9
|
+
// pf
|
|
10
|
+
// despite being covered by test/routes.test.js
|
|
11
|
+
/* c8 ignore next 33 */
|
|
12
|
+
async function setupOpenAPI (app, opts) {
|
|
13
|
+
const openapiConfig = deepmerge({
|
|
14
|
+
exposeRoute: true,
|
|
15
|
+
info: {
|
|
16
|
+
title: 'Platformatic',
|
|
17
|
+
description: 'This is a service built on top of Platformatic',
|
|
18
|
+
version: '1.0.0'
|
|
19
|
+
}
|
|
20
|
+
}, typeof opts === 'object' ? opts : {})
|
|
21
|
+
app.log.trace({ openapi: openapiConfig })
|
|
22
|
+
await app.register(Swagger, {
|
|
23
|
+
exposeRoute: openapiConfig.exposeRoute,
|
|
24
|
+
openapi: {
|
|
25
|
+
...openapiConfig
|
|
26
|
+
},
|
|
27
|
+
refResolver: {
|
|
28
|
+
buildLocalReference (json, baseUri, fragment, i) {
|
|
29
|
+
// TODO figure out if we need def-${i}
|
|
30
|
+
/* istanbul ignore next */
|
|
31
|
+
return json.$id || `def-${i}`
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
app.register(SwaggerUI, {
|
|
37
|
+
...opts,
|
|
38
|
+
prefix: '/documentation'
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = fp(setupOpenAPI)
|
package/lib/schema.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
const pkg = require('../package.json')
|
|
6
6
|
const version = 'v' + pkg.version
|
|
7
|
+
const openApiDefs = require('./openapi-schema-defs')
|
|
7
8
|
|
|
8
9
|
const cors = {
|
|
9
10
|
type: 'object',
|
|
@@ -123,6 +124,119 @@ const server = {
|
|
|
123
124
|
}
|
|
124
125
|
]
|
|
125
126
|
},
|
|
127
|
+
ignoreTrailingSlash: {
|
|
128
|
+
type: 'boolean'
|
|
129
|
+
},
|
|
130
|
+
ignoreDuplicateSlashes: {
|
|
131
|
+
type: 'boolean'
|
|
132
|
+
},
|
|
133
|
+
connectionTimeout: {
|
|
134
|
+
type: 'integer'
|
|
135
|
+
},
|
|
136
|
+
keepAliveTimeout: {
|
|
137
|
+
type: 'integer'
|
|
138
|
+
},
|
|
139
|
+
maxRequestsPerSocket: {
|
|
140
|
+
type: 'integer'
|
|
141
|
+
},
|
|
142
|
+
forceCloseConnections: {
|
|
143
|
+
anyOf: [
|
|
144
|
+
{ type: 'boolean' },
|
|
145
|
+
{ type: 'string', pattern: '^idle$' }
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
requestTimeout: {
|
|
149
|
+
type: 'integer'
|
|
150
|
+
},
|
|
151
|
+
bodyLimit: {
|
|
152
|
+
type: 'integer'
|
|
153
|
+
},
|
|
154
|
+
maxParamLength: {
|
|
155
|
+
type: 'integer'
|
|
156
|
+
},
|
|
157
|
+
disableRequestLogging: {
|
|
158
|
+
type: 'boolean'
|
|
159
|
+
},
|
|
160
|
+
exposeHeadRoutes: {
|
|
161
|
+
type: 'boolean'
|
|
162
|
+
},
|
|
163
|
+
logger: {
|
|
164
|
+
anyOf: [
|
|
165
|
+
{ type: 'boolean' },
|
|
166
|
+
{
|
|
167
|
+
type: 'object',
|
|
168
|
+
properties: {
|
|
169
|
+
level: {
|
|
170
|
+
type: 'string'
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
additionalProperties: true
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
serializerOpts: {
|
|
178
|
+
type: 'object',
|
|
179
|
+
properties: {
|
|
180
|
+
schema: {
|
|
181
|
+
type: 'object'
|
|
182
|
+
},
|
|
183
|
+
ajv: {
|
|
184
|
+
type: 'object'
|
|
185
|
+
},
|
|
186
|
+
rounding: {
|
|
187
|
+
type: 'string',
|
|
188
|
+
enum: ['floor', 'ceil', 'round', 'trunc'],
|
|
189
|
+
default: 'trunc'
|
|
190
|
+
},
|
|
191
|
+
debugMode: {
|
|
192
|
+
type: 'boolean'
|
|
193
|
+
},
|
|
194
|
+
mode: {
|
|
195
|
+
type: 'string',
|
|
196
|
+
enum: ['debug', 'standalone']
|
|
197
|
+
},
|
|
198
|
+
largeArraySize: {
|
|
199
|
+
anyOf: [
|
|
200
|
+
{ type: 'integer' },
|
|
201
|
+
{ type: 'string' }
|
|
202
|
+
],
|
|
203
|
+
default: 20000
|
|
204
|
+
},
|
|
205
|
+
largeArrayMechanism: {
|
|
206
|
+
type: 'string',
|
|
207
|
+
enum: ['default', 'json-stringify'],
|
|
208
|
+
default: 'default'
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
caseSensitive: {
|
|
213
|
+
type: 'boolean'
|
|
214
|
+
},
|
|
215
|
+
requestIdHeader: {
|
|
216
|
+
anyOf: [
|
|
217
|
+
{ type: 'string' },
|
|
218
|
+
{ type: 'boolean', const: false }
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
requestIdLogLabel: {
|
|
222
|
+
type: 'string'
|
|
223
|
+
},
|
|
224
|
+
jsonShorthand: {
|
|
225
|
+
type: 'boolean'
|
|
226
|
+
},
|
|
227
|
+
trustProxy: {
|
|
228
|
+
anyOf: [
|
|
229
|
+
{ type: 'boolean' },
|
|
230
|
+
{ type: 'string' },
|
|
231
|
+
{
|
|
232
|
+
type: 'array',
|
|
233
|
+
items: {
|
|
234
|
+
type: 'string'
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
{ type: 'integer' }
|
|
238
|
+
]
|
|
239
|
+
},
|
|
126
240
|
cors
|
|
127
241
|
},
|
|
128
242
|
required: ['hostname', 'port']
|
|
@@ -131,28 +245,25 @@ const server = {
|
|
|
131
245
|
const watch = {
|
|
132
246
|
type: 'object',
|
|
133
247
|
properties: {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
type: '
|
|
138
|
-
items: {
|
|
139
|
-
type: 'string'
|
|
140
|
-
},
|
|
141
|
-
minItems: 1,
|
|
142
|
-
nullable: true,
|
|
143
|
-
default: null
|
|
248
|
+
allow: {
|
|
249
|
+
type: 'array',
|
|
250
|
+
items: {
|
|
251
|
+
type: 'string'
|
|
144
252
|
},
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
type: 'string'
|
|
149
|
-
},
|
|
150
|
-
nullable: true,
|
|
151
|
-
default: null
|
|
152
|
-
}
|
|
253
|
+
minItems: 1,
|
|
254
|
+
nullable: true,
|
|
255
|
+
default: null
|
|
153
256
|
},
|
|
154
|
-
|
|
155
|
-
|
|
257
|
+
ignore: {
|
|
258
|
+
type: 'array',
|
|
259
|
+
items: {
|
|
260
|
+
type: 'string'
|
|
261
|
+
},
|
|
262
|
+
nullable: true,
|
|
263
|
+
default: null
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
additionalProperties: false
|
|
156
267
|
}
|
|
157
268
|
|
|
158
269
|
const plugins = {
|
|
@@ -219,15 +330,100 @@ const metrics = {
|
|
|
219
330
|
]
|
|
220
331
|
}
|
|
221
332
|
|
|
333
|
+
const openApiBase = {
|
|
334
|
+
type: 'object',
|
|
335
|
+
properties: {
|
|
336
|
+
info: {
|
|
337
|
+
$ref: '#/$defs/info'
|
|
338
|
+
},
|
|
339
|
+
jsonSchemaDialect: {
|
|
340
|
+
type: 'string',
|
|
341
|
+
|
|
342
|
+
default: 'https://spec.openapis.org/oas/3.1/dialect/base'
|
|
343
|
+
},
|
|
344
|
+
servers: {
|
|
345
|
+
type: 'array',
|
|
346
|
+
items: {
|
|
347
|
+
$ref: '#/$defs/server'
|
|
348
|
+
},
|
|
349
|
+
default: [
|
|
350
|
+
{
|
|
351
|
+
url: '/'
|
|
352
|
+
}
|
|
353
|
+
]
|
|
354
|
+
},
|
|
355
|
+
paths: {
|
|
356
|
+
$ref: '#/$defs/paths'
|
|
357
|
+
},
|
|
358
|
+
webhooks: {
|
|
359
|
+
type: 'object',
|
|
360
|
+
additionalProperties: {
|
|
361
|
+
$ref: '#/$defs/path-item-or-reference'
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
components: {
|
|
365
|
+
$ref: '#/$defs/components'
|
|
366
|
+
},
|
|
367
|
+
security: {
|
|
368
|
+
type: 'array',
|
|
369
|
+
items: {
|
|
370
|
+
$ref: '#/$defs/security-requirement'
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
tags: {
|
|
374
|
+
type: 'array',
|
|
375
|
+
items: {
|
|
376
|
+
$ref: '#/$defs/tag'
|
|
377
|
+
}
|
|
378
|
+
},
|
|
379
|
+
externalDocs: {
|
|
380
|
+
$ref: '#/$defs/external-documentation'
|
|
381
|
+
},
|
|
382
|
+
prefix: {
|
|
383
|
+
type: 'string',
|
|
384
|
+
description: 'Base URL for the OpenAPI'
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const openapi = {
|
|
390
|
+
anyOf: [{
|
|
391
|
+
...openApiBase,
|
|
392
|
+
additionalProperties: false
|
|
393
|
+
}, {
|
|
394
|
+
type: 'boolean'
|
|
395
|
+
}]
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const graphql = {
|
|
399
|
+
anyOf: [{
|
|
400
|
+
type: 'boolean'
|
|
401
|
+
}, {
|
|
402
|
+
type: 'object',
|
|
403
|
+
properties: {
|
|
404
|
+
graphiql: {
|
|
405
|
+
type: 'boolean'
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}]
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const service = {
|
|
412
|
+
type: 'object',
|
|
413
|
+
properties: {
|
|
414
|
+
openapi,
|
|
415
|
+
graphql
|
|
416
|
+
},
|
|
417
|
+
additionalProperties: false
|
|
418
|
+
}
|
|
419
|
+
|
|
222
420
|
const platformaticServiceSchema = {
|
|
223
421
|
$id: `https://platformatic.dev/schemas/${version}/service`,
|
|
224
422
|
type: 'object',
|
|
225
423
|
properties: {
|
|
226
424
|
server,
|
|
227
425
|
plugins,
|
|
228
|
-
metrics
|
|
229
|
-
},
|
|
230
|
-
additionalProperties: {
|
|
426
|
+
metrics,
|
|
231
427
|
watch: {
|
|
232
428
|
anyOf: [watch, {
|
|
233
429
|
type: 'boolean'
|
|
@@ -235,9 +431,15 @@ const platformaticServiceSchema = {
|
|
|
235
431
|
},
|
|
236
432
|
hotReload: {
|
|
237
433
|
type: 'boolean'
|
|
238
|
-
}
|
|
434
|
+
},
|
|
435
|
+
$schema: {
|
|
436
|
+
type: 'string'
|
|
437
|
+
},
|
|
438
|
+
service
|
|
239
439
|
},
|
|
240
|
-
|
|
440
|
+
additionalProperties: false,
|
|
441
|
+
required: ['server'],
|
|
442
|
+
$defs: openApiDefs
|
|
241
443
|
}
|
|
242
444
|
|
|
243
445
|
module.exports.schema = platformaticServiceSchema
|
|
@@ -246,6 +448,8 @@ module.exports.cors = cors
|
|
|
246
448
|
module.exports.server = server
|
|
247
449
|
module.exports.plugins = plugins
|
|
248
450
|
module.exports.watch = watch
|
|
451
|
+
module.exports.openApiDefs = openApiDefs
|
|
452
|
+
module.exports.openApiBase = openApiBase
|
|
249
453
|
|
|
250
454
|
if (require.main === module) {
|
|
251
455
|
console.log(JSON.stringify(platformaticServiceSchema, null, 2))
|
package/lib/utils.js
CHANGED
|
@@ -46,10 +46,21 @@ function getJSPluginPath (configPath, tsPluginPath, compileDir) {
|
|
|
46
46
|
return tsPluginPath
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
const isTs = tsPluginPath.endsWith('ts')
|
|
50
|
+
let newBaseName
|
|
51
|
+
|
|
52
|
+
// TODO: investigate why c8 does not see those
|
|
53
|
+
/* c8 ignore next 5 */
|
|
54
|
+
if (isTs) {
|
|
55
|
+
newBaseName = basename(tsPluginPath, '.ts') + '.js'
|
|
56
|
+
} else {
|
|
57
|
+
newBaseName = basename(tsPluginPath)
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
const tsPluginRelativePath = relative(dirname(configPath), tsPluginPath)
|
|
50
61
|
const jsPluginRelativePath = join(
|
|
51
62
|
dirname(tsPluginRelativePath),
|
|
52
|
-
|
|
63
|
+
newBaseName
|
|
53
64
|
)
|
|
54
65
|
return join(compileDir, jsPluginRelativePath)
|
|
55
66
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/service",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Matteo Collina <hello@matteocollina.com>",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"homepage": "https://github.com/platformatic/platformatic#readme",
|
|
16
16
|
"devDependencies": {
|
|
17
|
+
"@matteo.collina/worker": "^3.0.0",
|
|
17
18
|
"bindings": "^1.5.0",
|
|
18
19
|
"c8": "^7.13.0",
|
|
19
20
|
"snazzy": "^9.0.0",
|
|
@@ -36,7 +37,9 @@
|
|
|
36
37
|
"@fastify/restartable": "^1.4.0",
|
|
37
38
|
"@fastify/static": "^6.9.0",
|
|
38
39
|
"@fastify/swagger": "^8.3.1",
|
|
40
|
+
"@fastify/swagger-ui": "^1.4.0",
|
|
39
41
|
"@fastify/under-pressure": "^8.2.0",
|
|
42
|
+
"@mercuriusjs/federation": "^1.0.1",
|
|
40
43
|
"close-with-grace": "^1.1.0",
|
|
41
44
|
"commist": "^3.2.0",
|
|
42
45
|
"desm": "^1.3.0",
|
|
@@ -49,13 +52,14 @@
|
|
|
49
52
|
"fastify-sandbox": "^0.11.0",
|
|
50
53
|
"graphql": "^16.6.0",
|
|
51
54
|
"help-me": "^4.2.0",
|
|
55
|
+
"mercurius": "^12.2.0",
|
|
52
56
|
"minimist": "^1.2.8",
|
|
53
57
|
"pino": "^8.11.0",
|
|
54
|
-
"pino-pretty": "^
|
|
58
|
+
"pino-pretty": "^10.0.0",
|
|
55
59
|
"rfdc": "^1.3.0",
|
|
56
60
|
"ua-parser-js": "^1.0.33",
|
|
57
|
-
"@platformatic/config": "0.
|
|
58
|
-
"@platformatic/utils": "0.
|
|
61
|
+
"@platformatic/config": "0.18.0",
|
|
62
|
+
"@platformatic/utils": "0.18.0"
|
|
59
63
|
},
|
|
60
64
|
"standard": {
|
|
61
65
|
"ignore": [
|
|
@@ -12,6 +12,20 @@ function urlDirname (url) {
|
|
|
12
12
|
return path.dirname(fileURLToPath(url))
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
function exitOnTeardown (child) {
|
|
16
|
+
return async () => {
|
|
17
|
+
if (os.platform() === 'win32') {
|
|
18
|
+
try {
|
|
19
|
+
await execa('taskkill', ['/pid', child.pid, '/f', '/t'])
|
|
20
|
+
} catch (err) {
|
|
21
|
+
console.error(`Failed to kill process ${child.pid})`)
|
|
22
|
+
}
|
|
23
|
+
} else {
|
|
24
|
+
child.kill('SIGINT')
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
15
29
|
t.test('should compile typescript plugin', async (t) => {
|
|
16
30
|
const testDir = path.join(urlDirname(import.meta.url), '..', 'fixtures', 'typescript-plugin')
|
|
17
31
|
const cwd = path.join(urlDirname(import.meta.url), '..', 'tmp', 'typescript-plugin-clone-1')
|
|
@@ -70,17 +84,7 @@ t.test('should compile typescript plugin with start command', async (t) => {
|
|
|
70
84
|
|
|
71
85
|
const child = execa('node', [cliPath, 'start'], { cwd })
|
|
72
86
|
|
|
73
|
-
t.teardown(
|
|
74
|
-
if (os.platform() === 'win32') {
|
|
75
|
-
try {
|
|
76
|
-
await execa('taskkill', ['/pid', child.pid, '/f', '/t'])
|
|
77
|
-
} catch (err) {
|
|
78
|
-
console.error(`Failed to kill process ${child.pid})`)
|
|
79
|
-
}
|
|
80
|
-
} else {
|
|
81
|
-
child.kill('SIGINT')
|
|
82
|
-
}
|
|
83
|
-
})
|
|
87
|
+
t.teardown(exitOnTeardown(child))
|
|
84
88
|
|
|
85
89
|
const splitter = split()
|
|
86
90
|
child.stdout.pipe(splitter)
|
|
@@ -195,17 +199,7 @@ t.test('start command should not compile typescript if `typescript` is false', a
|
|
|
195
199
|
await cp(testDir, cwd, { recursive: true })
|
|
196
200
|
|
|
197
201
|
const child = execa('node', [cliPath, 'start'], { cwd })
|
|
198
|
-
t.teardown(
|
|
199
|
-
if (os.platform() === 'win32') {
|
|
200
|
-
try {
|
|
201
|
-
await execa('taskkill', ['/pid', child.pid, '/f', '/t'])
|
|
202
|
-
} catch (err) {
|
|
203
|
-
console.error(`Failed to kill process ${child.pid})`)
|
|
204
|
-
}
|
|
205
|
-
} else {
|
|
206
|
-
child.kill('SIGINT')
|
|
207
|
-
}
|
|
208
|
-
})
|
|
202
|
+
t.teardown(exitOnTeardown(child))
|
|
209
203
|
|
|
210
204
|
const jsPluginPath = path.join(cwd, 'dist', 'plugin.js')
|
|
211
205
|
try {
|
|
@@ -227,17 +221,7 @@ t.test('should compile typescript plugin with start command with different cwd',
|
|
|
227
221
|
|
|
228
222
|
const child = execa('node', [cliPath, 'start', '-c', path.join(dest, 'platformatic.service.json')])
|
|
229
223
|
|
|
230
|
-
t.teardown(
|
|
231
|
-
if (os.platform() === 'win32') {
|
|
232
|
-
try {
|
|
233
|
-
await execa('taskkill', ['/pid', child.pid, '/f', '/t'])
|
|
234
|
-
} catch (err) {
|
|
235
|
-
console.error(`Failed to kill process ${child.pid})`)
|
|
236
|
-
}
|
|
237
|
-
} else {
|
|
238
|
-
child.kill('SIGINT')
|
|
239
|
-
}
|
|
240
|
-
})
|
|
224
|
+
t.teardown(exitOnTeardown(child))
|
|
241
225
|
|
|
242
226
|
const splitter = split()
|
|
243
227
|
child.stdout.pipe(splitter)
|
|
@@ -253,3 +237,41 @@ t.test('should compile typescript plugin with start command with different cwd',
|
|
|
253
237
|
}
|
|
254
238
|
t.fail('should compile typescript plugin with start command')
|
|
255
239
|
})
|
|
240
|
+
|
|
241
|
+
t.test('valid tsconfig file inside an inner folder', async (t) => {
|
|
242
|
+
const testDir = path.join(urlDirname(import.meta.url), '..', 'fixtures', 'typescript-plugin')
|
|
243
|
+
const cwd = path.join(urlDirname(import.meta.url), '..', 'tmp', 'typescript-plugin-clone-7/inner-folder')
|
|
244
|
+
|
|
245
|
+
await cp(testDir, cwd, { recursive: true })
|
|
246
|
+
|
|
247
|
+
try {
|
|
248
|
+
await execa('node', [cliPath, 'compile'], { cwd })
|
|
249
|
+
} catch (err) {
|
|
250
|
+
t.fail('should not catch any error')
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
t.pass()
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
t.test('should compile typescript plugin with start command from a folder', async (t) => {
|
|
257
|
+
const testDir = path.join(urlDirname(import.meta.url), '..', 'fixtures', 'typescript-autoload')
|
|
258
|
+
const cwd = path.join(urlDirname(import.meta.url), '..', 'tmp', 'typescript-plugin-clone-8')
|
|
259
|
+
|
|
260
|
+
await cp(testDir, cwd, { recursive: true })
|
|
261
|
+
|
|
262
|
+
const child = execa('node', [cliPath, 'start'], { cwd })
|
|
263
|
+
|
|
264
|
+
t.teardown(exitOnTeardown(child))
|
|
265
|
+
|
|
266
|
+
const splitter = split()
|
|
267
|
+
child.stdout.pipe(splitter)
|
|
268
|
+
|
|
269
|
+
for await (const data of splitter) {
|
|
270
|
+
const sanitized = stripAnsi(data)
|
|
271
|
+
if (sanitized.includes('Typescript plugin loaded')) {
|
|
272
|
+
t.pass()
|
|
273
|
+
return
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
t.fail('should compile typescript plugin with start command')
|
|
277
|
+
})
|
|
@@ -15,9 +15,8 @@ test('generateJsonSchemaConfig generates the file', async (t) => {
|
|
|
15
15
|
|
|
16
16
|
const configSchema = await fs.readFile('platformatic.service.schema.json', 'utf8')
|
|
17
17
|
const schema = JSON.parse(configSchema)
|
|
18
|
-
const { required
|
|
18
|
+
const { required } = schema
|
|
19
19
|
t.has(required, ['server'])
|
|
20
|
-
t.has(additionalProperties, { watch: {} })
|
|
21
20
|
const { $id, type } = schema
|
|
22
21
|
t.equal($id, `https://platformatic.dev/schemas/v${pkg.version}/service`)
|
|
23
22
|
t.equal(type, 'object')
|
package/test/cli/watch.test.mjs
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import os from 'os'
|
|
2
2
|
import { join, basename } from 'path'
|
|
3
3
|
import { writeFile, mkdtemp } from 'fs/promises'
|
|
4
|
-
import { setTimeout as sleep } from 'timers/promises'
|
|
5
4
|
import t, { test } from 'tap'
|
|
6
5
|
import { request } from 'undici'
|
|
6
|
+
import { setTimeout as sleep } from 'timers/promises'
|
|
7
7
|
import { start } from './helper.mjs'
|
|
8
8
|
|
|
9
9
|
t.jobs = 5
|
|
10
10
|
|
|
11
|
-
function createLoggingPlugin (text) {
|
|
11
|
+
function createLoggingPlugin (text, reloaded = false) {
|
|
12
12
|
return `\
|
|
13
13
|
module.exports = async (app) => {
|
|
14
|
+
if (${reloaded}) {
|
|
15
|
+
app.log.info('RELOADED')
|
|
16
|
+
}
|
|
14
17
|
app.get('/version', () => '${text}')
|
|
15
18
|
}
|
|
16
19
|
`
|
|
@@ -43,9 +46,11 @@ test('should watch js files by default', async ({ equal, teardown }) => {
|
|
|
43
46
|
const { child, url } = await start('-c', configFilePath)
|
|
44
47
|
teardown(() => child.kill('SIGINT'))
|
|
45
48
|
|
|
46
|
-
await writeFile(pluginFilePath, createLoggingPlugin('v2'))
|
|
49
|
+
await writeFile(pluginFilePath, createLoggingPlugin('v2', true))
|
|
47
50
|
|
|
48
|
-
await
|
|
51
|
+
for await (const log of child.ndj) {
|
|
52
|
+
if (log.msg === 'RELOADED') break
|
|
53
|
+
}
|
|
49
54
|
|
|
50
55
|
const res = await request(`${url}/version`)
|
|
51
56
|
const version = await res.body.text()
|
|
@@ -128,7 +133,8 @@ test('should not watch ignored file', async ({ teardown, equal }) => {
|
|
|
128
133
|
const { child, url } = await start('-c', configFilePath)
|
|
129
134
|
teardown(() => child.kill('SIGINT'))
|
|
130
135
|
|
|
131
|
-
await writeFile(pluginFilePath, createLoggingPlugin('v2'))
|
|
136
|
+
await writeFile(pluginFilePath, createLoggingPlugin('v2', true))
|
|
137
|
+
|
|
132
138
|
await sleep(5000)
|
|
133
139
|
|
|
134
140
|
const res = await request(`${url}/version`)
|
|
@@ -273,7 +279,8 @@ test('should not hot reload files with `--hot-reload false`', async ({ teardown,
|
|
|
273
279
|
equal(version, 'v1')
|
|
274
280
|
}
|
|
275
281
|
|
|
276
|
-
await writeFile(pluginFilePath, createLoggingPlugin('v2'))
|
|
282
|
+
await writeFile(pluginFilePath, createLoggingPlugin('v2', true))
|
|
283
|
+
|
|
277
284
|
await sleep(5000)
|
|
278
285
|
|
|
279
286
|
{
|
package/test/config.test.js
CHANGED
|
@@ -217,6 +217,7 @@ test('config is adjusted to handle custom loggers', async (t) => {
|
|
|
217
217
|
Object.defineProperty(options.server.logger, 'child', {
|
|
218
218
|
value: function child () {
|
|
219
219
|
called = true
|
|
220
|
+
return this
|
|
220
221
|
},
|
|
221
222
|
enumerable: false
|
|
222
223
|
})
|
|
@@ -284,7 +285,7 @@ test('custom ConfigManager', async ({ teardown, equal, pass, same }) => {
|
|
|
284
285
|
{
|
|
285
286
|
const res = await request(`${server.url}/`)
|
|
286
287
|
equal(res.statusCode, 200, 'add status code')
|
|
287
|
-
same(await res.body.text(), '
|
|
288
|
+
same(await res.body.text(), 'hello', 'response')
|
|
288
289
|
}
|
|
289
290
|
})
|
|
290
291
|
|