@platformatic/service 0.19.6 → 0.20.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/lib/sandbox-wrapper.js +3 -1
- package/lib/schema.js +7 -0
- package/package.json +4 -4
- package/test/autoload.test.js +54 -0
- package/test/fixtures/nested-directories/modules/catalogue/index.js +11 -0
- package/test/fixtures/nested-directories/modules/catalogue/routes/products.js +14 -0
- package/test/fixtures/nested-directories/modules/inventory/index.js +29 -0
- package/test/fixtures/nested-directories/modules/inventory/routes/product.js +16 -0
- package/test/fixtures/nested-directories/package.json +3 -0
- package/test/fixtures/nested-directories/platformatic.service.json +23 -0
- package/test/fixtures/nested-directories/plugins/handlers.js +17 -0
package/lib/sandbox-wrapper.js
CHANGED
|
@@ -7,11 +7,13 @@ const { stat } = require('fs').promises
|
|
|
7
7
|
module.exports = fp(async function (app, opts) {
|
|
8
8
|
for (let plugin of opts.paths) {
|
|
9
9
|
if (typeof plugin === 'string') {
|
|
10
|
-
plugin = { path: plugin }
|
|
10
|
+
plugin = { path: plugin, encapsulate: true }
|
|
11
11
|
}
|
|
12
12
|
if ((await stat(plugin.path)).isDirectory()) {
|
|
13
13
|
app.register(autoload, {
|
|
14
14
|
dir: plugin.path,
|
|
15
|
+
encapsulate: plugin.encapsulate !== false,
|
|
16
|
+
maxDepth: plugin.maxDepth,
|
|
15
17
|
options: plugin.options
|
|
16
18
|
})
|
|
17
19
|
} else {
|
package/lib/schema.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/service",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -63,9 +63,9 @@
|
|
|
63
63
|
"pino-pretty": "^10.0.0",
|
|
64
64
|
"rfdc": "^1.3.0",
|
|
65
65
|
"ua-parser-js": "^1.0.33",
|
|
66
|
-
"@platformatic/config": "0.
|
|
67
|
-
"@platformatic/utils": "0.
|
|
68
|
-
"@platformatic/client": "0.
|
|
66
|
+
"@platformatic/config": "0.20.0",
|
|
67
|
+
"@platformatic/utils": "0.20.0",
|
|
68
|
+
"@platformatic/client": "0.20.0"
|
|
69
69
|
},
|
|
70
70
|
"standard": {
|
|
71
71
|
"ignore": [
|
package/test/autoload.test.js
CHANGED
|
@@ -356,3 +356,57 @@ test('multiple files / watch false / no object', async ({ teardown, equal }) =>
|
|
|
356
356
|
equal(body.hello, 'bar', 'body')
|
|
357
357
|
}
|
|
358
358
|
})
|
|
359
|
+
|
|
360
|
+
test('nested directories', async ({ teardown, equal, same }) => {
|
|
361
|
+
const config = {
|
|
362
|
+
server: {
|
|
363
|
+
hostname: '127.0.0.1',
|
|
364
|
+
port: 0
|
|
365
|
+
},
|
|
366
|
+
service: {
|
|
367
|
+
openapi: true
|
|
368
|
+
},
|
|
369
|
+
plugins: {
|
|
370
|
+
paths: [{
|
|
371
|
+
path: join(__dirname, 'fixtures', 'nested-directories', 'plugins'),
|
|
372
|
+
encapsulate: false
|
|
373
|
+
}, {
|
|
374
|
+
path: join(__dirname, 'fixtures', 'nested-directories', 'modules'),
|
|
375
|
+
encapsulate: false,
|
|
376
|
+
maxDepth: 1
|
|
377
|
+
}]
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const server = await buildServer(config)
|
|
382
|
+
teardown(server.stop)
|
|
383
|
+
await server.listen()
|
|
384
|
+
|
|
385
|
+
{
|
|
386
|
+
const res = await request(`${server.url}/inventory/product/42`)
|
|
387
|
+
equal(res.statusCode, 200, 'status code')
|
|
388
|
+
const body = await res.body.json()
|
|
389
|
+
same(body, { sku: 42, inStore: 2 }, 'body')
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
{
|
|
393
|
+
const res = await request(`${server.url}/catalogue/products`)
|
|
394
|
+
equal(res.statusCode, 200, 'status code')
|
|
395
|
+
const body = await res.body.json()
|
|
396
|
+
same(body, [{ sku: 42, name: 'foo', inStore: 2 }, { sku: 43, name: 'bar', inStore: 0 }], 'body')
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
{
|
|
400
|
+
const res = await request(`${server.url}/foo/baz`)
|
|
401
|
+
equal(res.statusCode, 404, 'status code')
|
|
402
|
+
const body = await res.body.text()
|
|
403
|
+
equal(body, 'I\'m sorry, I couldn\'t find what you were looking for.')
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
{
|
|
407
|
+
const res = await request(`${server.url}/catalogue/error`)
|
|
408
|
+
equal(res.statusCode, 500, 'status code')
|
|
409
|
+
const body = await res.body.text()
|
|
410
|
+
equal(body, 'I\'m sorry, there was an error processing your request.')
|
|
411
|
+
}
|
|
412
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export default async function (fastify, opts) {
|
|
2
|
+
fastify.get('/products', async (request, reply) => {
|
|
3
|
+
const data = [{ sku: 42, name: 'foo' }, { sku: 43, name: 'bar' }]
|
|
4
|
+
// Currently slow and inefficient, but ok for the demo
|
|
5
|
+
for (const product of data) {
|
|
6
|
+
product.inStore = await fastify.inventory.howManyInStore(product.sku)
|
|
7
|
+
}
|
|
8
|
+
return data
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
fastify.get('/error', async (request, reply) => {
|
|
12
|
+
throw new Error('This is an error')
|
|
13
|
+
})
|
|
14
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import fp from 'fastify-plugin'
|
|
2
|
+
import autoload from '@fastify/autoload'
|
|
3
|
+
import { join } from 'desm'
|
|
4
|
+
|
|
5
|
+
class Inventory {
|
|
6
|
+
async howManyInStore (sku) {
|
|
7
|
+
if (sku === 42) {
|
|
8
|
+
return 2
|
|
9
|
+
} else {
|
|
10
|
+
return 0
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function inventory (fastify, opts) {
|
|
16
|
+
// This will be published to the root fastify instance
|
|
17
|
+
// it could also be extracted to a separate plugin
|
|
18
|
+
fastify.decorate('inventory', new Inventory())
|
|
19
|
+
|
|
20
|
+
// These routes would be created in their own child instances
|
|
21
|
+
fastify.register(autoload, {
|
|
22
|
+
dir: join(import.meta.url, 'routes'),
|
|
23
|
+
options: {
|
|
24
|
+
prefix: opts.prefix
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default fp(inventory)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
export default async function (fastify, opts) {
|
|
3
|
+
fastify.get('/product/:sku', {
|
|
4
|
+
schema: {
|
|
5
|
+
params: {
|
|
6
|
+
type: 'object',
|
|
7
|
+
properties: {
|
|
8
|
+
sku: { type: 'number' }
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}, async (request, reply) => {
|
|
13
|
+
const sku = request.params.sku
|
|
14
|
+
return { sku, inStore: await fastify.inventory.howManyInStore(sku) }
|
|
15
|
+
})
|
|
16
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://platformatic.dev/schemas/v0.19.7/service",
|
|
3
|
+
"server": {
|
|
4
|
+
"hostname": "{PLT_SERVER_HOSTNAME}",
|
|
5
|
+
"port": "{PORT}",
|
|
6
|
+
"logger": {
|
|
7
|
+
"level": "{PLT_SERVER_LOGGER_LEVEL}"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"service": {
|
|
11
|
+
"openapi": true
|
|
12
|
+
},
|
|
13
|
+
"plugins": {
|
|
14
|
+
"paths": [{
|
|
15
|
+
"path": "plugins",
|
|
16
|
+
"encapsulate": false
|
|
17
|
+
}, {
|
|
18
|
+
"path": "modules",
|
|
19
|
+
"encapsulate": false,
|
|
20
|
+
"maxDepth": 1
|
|
21
|
+
}]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export default async function (app, opts) {
|
|
2
|
+
app.setErrorHandler(async (err, request, reply) => {
|
|
3
|
+
if (err.validation) {
|
|
4
|
+
reply.code(403)
|
|
5
|
+
return err.message
|
|
6
|
+
}
|
|
7
|
+
request.log.error({ err })
|
|
8
|
+
reply.code(err.statusCode || 500)
|
|
9
|
+
|
|
10
|
+
return "I'm sorry, there was an error processing your request."
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
app.setNotFoundHandler(async (request, reply) => {
|
|
14
|
+
reply.code(404)
|
|
15
|
+
return "I'm sorry, I couldn't find what you were looking for."
|
|
16
|
+
})
|
|
17
|
+
}
|