@platformatic/service 0.22.0 → 0.23.1

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 (38) hide show
  1. package/fixtures/hello-client-ts/platformatic.service.json +2 -1
  2. package/index.js +118 -169
  3. package/lib/load-config.js +6 -1
  4. package/lib/plugins/clients.js +12 -0
  5. package/lib/plugins/cors.js +29 -0
  6. package/lib/plugins/file-watcher.js +44 -0
  7. package/lib/plugins/health-check.js +17 -0
  8. package/lib/plugins/plugins.js +56 -0
  9. package/lib/plugins/typescript.js +46 -0
  10. package/lib/root-endpoint/index.js +1 -0
  11. package/lib/schema.js +8 -1
  12. package/lib/start.mjs +27 -136
  13. package/lib/utils.js +2 -2
  14. package/package.json +9 -8
  15. package/test/autoload.test.js +77 -59
  16. package/test/cli/compile.test.mjs +45 -33
  17. package/test/cli/watch.test.mjs +39 -0
  18. package/test/clients.test.js +24 -17
  19. package/test/config.test.js +58 -86
  20. package/test/cors.test.js +48 -30
  21. package/test/fixtures/bad-typescript-plugin/platformatic.service.json +3 -1
  22. package/test/fixtures/typescript-autoload/platformatic.service.json +3 -1
  23. package/test/fixtures/typescript-plugin/platformatic.service.json +3 -1
  24. package/test/fixtures/typescript-plugin-nocompile/platformatic.service.json +2 -1
  25. package/test/graphql.test.js +18 -14
  26. package/test/healthcheck.test.js +22 -13
  27. package/test/https.test.js +11 -8
  28. package/test/lambda.test.js +103 -0
  29. package/test/load-and-reload-files.test.js +97 -112
  30. package/test/load-plugin.test.js +8 -4
  31. package/test/metrics.test.js +59 -39
  32. package/test/routes.test.js +43 -25
  33. package/test/utils.test.js +2 -2
  34. package/test/watch.test.js +182 -0
  35. /package/lib/{graphql.js → plugins/graphql.js} +0 -0
  36. /package/lib/{metrics-plugin.js → plugins/metrics.js} +0 -0
  37. /package/lib/{openapi.js → plugins/openapi.js} +0 -0
  38. /package/lib/{sandbox-wrapper.js → plugins/sandbox-wrapper.js} +0 -0
@@ -4,7 +4,9 @@
4
4
  "level": "info"
5
5
  },
6
6
  "hostname": "127.0.0.1",
7
- "port": "3042"
7
+ "port": "3042",
8
+ "pluginTimeout": 30000,
9
+ "keepAliveTimeout": 1
8
10
  },
9
11
  "plugins": {
10
12
  "paths": ["plugin.ts"],
@@ -4,7 +4,9 @@
4
4
  "level": "info"
5
5
  },
6
6
  "hostname": "127.0.0.1",
7
- "port": "0"
7
+ "port": "0",
8
+ "pluginTimeout": 60000,
9
+ "keepAliveTimeout": 1
8
10
  },
9
11
  "plugins": {
10
12
  "paths": ["routes"],
@@ -4,7 +4,9 @@
4
4
  "level": "info"
5
5
  },
6
6
  "hostname": "127.0.0.1",
7
- "port": "0"
7
+ "port": "0",
8
+ "pluginTimeout": 60000,
9
+ "keepAliveTimeout": 1
8
10
  },
9
11
  "plugins": {
10
12
  "paths": ["plugin.ts"],
@@ -5,7 +5,8 @@
5
5
  },
6
6
  "hostname": "127.0.0.1",
7
7
  "port": "0",
8
- "pluginTimeout": 60000
8
+ "pluginTimeout": 60000,
9
+ "keepAliveTimeout": 1
9
10
  },
10
11
  "plugins": {
11
12
  "paths": ["plugin.ts"],
@@ -7,7 +7,7 @@ const { request } = require('undici')
7
7
  const { join } = require('path')
8
8
 
9
9
  test('graphql enabled', async ({ teardown, equal, same }) => {
10
- const server = await buildServer(buildConfig({
10
+ const app = await buildServer(buildConfig({
11
11
  server: {
12
12
  hostname: '127.0.0.1',
13
13
  port: 0,
@@ -23,12 +23,14 @@ test('graphql enabled', async ({ teardown, equal, same }) => {
23
23
  paths: [join(__dirname, 'fixtures', 'hello-world-resolver.js')]
24
24
  }
25
25
  }))
26
- teardown(server.stop)
27
26
 
28
- await server.listen()
27
+ teardown(async () => {
28
+ await app.close()
29
+ })
30
+ await app.start()
29
31
 
30
32
  {
31
- const res = await request(`${server.url}/graphql`, {
33
+ const res = await request(`${app.url}/graphql`, {
32
34
  method: 'POST',
33
35
  headers: {
34
36
  'content-type': 'application/json'
@@ -50,14 +52,14 @@ test('graphql enabled', async ({ teardown, equal, same }) => {
50
52
  }
51
53
 
52
54
  {
53
- const res = await request(`${server.url}/graphiql`)
55
+ const res = await request(`${app.url}/graphiql`)
54
56
  equal(res.statusCode, 200, 'graphiql status code')
55
57
  }
56
58
  })
57
59
 
58
60
  test('graphql disabled', async ({ teardown, equal, fail }) => {
59
61
  try {
60
- const server = await buildServer(buildConfig({
62
+ const app = await buildServer(buildConfig({
61
63
  server: {
62
64
  hostname: '127.0.0.1',
63
65
  port: 0,
@@ -73,7 +75,7 @@ test('graphql disabled', async ({ teardown, equal, fail }) => {
73
75
  paths: [join(__dirname, 'fixtures', 'hello-world-resolver.js')]
74
76
  }
75
77
  }))
76
- await server.stop()
78
+ await app.close()
77
79
  fail('should have errored but did not')
78
80
  } catch (err) {
79
81
  equal(err.message, 'Cannot read properties of undefined (reading \'extendSchema\')')
@@ -81,7 +83,7 @@ test('graphql disabled', async ({ teardown, equal, fail }) => {
81
83
  })
82
84
 
83
85
  test('disable graphiql', async ({ teardown, equal, same }) => {
84
- const server = await buildServer(buildConfig({
86
+ const app = await buildServer(buildConfig({
85
87
  server: {
86
88
  hostname: '127.0.0.1',
87
89
  port: 0,
@@ -99,12 +101,14 @@ test('disable graphiql', async ({ teardown, equal, same }) => {
99
101
  paths: [join(__dirname, 'fixtures', 'hello-world-resolver.js')]
100
102
  }
101
103
  }))
102
- teardown(server.stop)
103
104
 
104
- await server.listen()
105
+ teardown(async () => {
106
+ await app.close()
107
+ })
108
+ await app.start()
105
109
 
106
110
  {
107
- const res = await request(`${server.url}/graphql`, {
111
+ const res = await request(`${app.url}/graphql`, {
108
112
  method: 'POST',
109
113
  headers: {
110
114
  'content-type': 'application/json'
@@ -126,14 +130,14 @@ test('disable graphiql', async ({ teardown, equal, same }) => {
126
130
  }
127
131
 
128
132
  {
129
- const res = await request(`${server.url}/graphiql`)
133
+ const res = await request(`${app.url}/graphiql`)
130
134
  equal(res.statusCode, 404, 'graphiql status code')
131
135
  }
132
136
  })
133
137
 
134
138
  test('graphql disabled by default', async ({ teardown, equal, fail }) => {
135
139
  try {
136
- const server = await buildServer(buildConfig({
140
+ const app = await buildServer(buildConfig({
137
141
  server: {
138
142
  hostname: '127.0.0.1',
139
143
  port: 0,
@@ -146,7 +150,7 @@ test('graphql disabled by default', async ({ teardown, equal, fail }) => {
146
150
  paths: [join(__dirname, 'fixtures', 'hello-world-resolver.js')]
147
151
  }
148
152
  }))
149
- await server.stop()
153
+ await app.close()
150
154
  fail('should have errored but did not')
151
155
  } catch (err) {
152
156
  equal(err.message, 'Cannot read properties of undefined (reading \'extendSchema\')')
@@ -7,7 +7,7 @@ const { request } = require('undici')
7
7
 
8
8
  test('healthcheck route enabled with interval', async ({ teardown, equal, same }) => {
9
9
  let check = true
10
- const server = await buildServer({
10
+ const app = await buildServer({
11
11
  server: {
12
12
  hostname: '127.0.0.1',
13
13
  port: 0,
@@ -20,11 +20,14 @@ test('healthcheck route enabled with interval', async ({ teardown, equal, same }
20
20
  },
21
21
  metrics: false
22
22
  })
23
- teardown(server.stop)
24
23
 
25
- await server.listen()
24
+ teardown(async () => {
25
+ await app.close()
26
+ })
27
+ await app.start()
28
+
26
29
  {
27
- const res = await (request(`${server.url}/status`))
30
+ const res = await (request(`${app.url}/status`))
28
31
  equal(res.statusCode, 200)
29
32
  const body = await res.body.json()
30
33
  same(body, { status: 'ok' })
@@ -33,7 +36,7 @@ test('healthcheck route enabled with interval', async ({ teardown, equal, same }
33
36
  check = false
34
37
 
35
38
  {
36
- const res = await (request(`${server.url}/status`))
39
+ const res = await (request(`${app.url}/status`))
37
40
  equal(res.statusCode, 503)
38
41
  const body = await res.body.json()
39
42
  same(body, {
@@ -48,7 +51,7 @@ test('healthcheck route enabled with interval', async ({ teardown, equal, same }
48
51
  })
49
52
 
50
53
  test('healthcheck route enabled without interval', async ({ teardown, equal, same }) => {
51
- const server = await buildServer({
54
+ const app = await buildServer({
52
55
  server: {
53
56
  hostname: '127.0.0.1',
54
57
  port: 0,
@@ -56,11 +59,14 @@ test('healthcheck route enabled without interval', async ({ teardown, equal, sam
56
59
  },
57
60
  metrics: false
58
61
  })
59
- teardown(server.stop)
60
62
 
61
- await server.listen()
63
+ teardown(async () => {
64
+ await app.close()
65
+ })
66
+ await app.start()
67
+
62
68
  {
63
- const res = await (request(`${server.url}/status`))
69
+ const res = await (request(`${app.url}/status`))
64
70
  equal(res.statusCode, 200)
65
71
  const body = await res.body.json()
66
72
  same(body, { status: 'ok' })
@@ -68,16 +74,19 @@ test('healthcheck route enabled without interval', async ({ teardown, equal, sam
68
74
  })
69
75
 
70
76
  test('healthcheck route disabled', async ({ teardown, equal, same }) => {
71
- const server = await buildServer({
77
+ const app = await buildServer({
72
78
  server: {
73
79
  hostname: '127.0.0.1',
74
80
  port: 0
75
81
  },
76
82
  metrics: false
77
83
  })
78
- teardown(server.stop)
79
84
 
80
- await server.listen()
81
- const res = await (request(`${server.url}/status`))
85
+ teardown(async () => {
86
+ await app.close()
87
+ })
88
+ await app.start()
89
+
90
+ const res = await (request(`${app.url}/status`))
82
91
  equal(res.statusCode, 404)
83
92
  })
@@ -31,7 +31,7 @@ test('supports https options', async ({ teardown, equal, same, plan, comment })
31
31
  }
32
32
  }))
33
33
 
34
- const server = await buildServer(buildConfig({
34
+ const app = await buildServer(buildConfig({
35
35
  server: {
36
36
  hostname: '127.0.0.1',
37
37
  port: 0,
@@ -42,19 +42,22 @@ test('supports https options', async ({ teardown, equal, same, plan, comment })
42
42
  }
43
43
  }))
44
44
 
45
- teardown(server.stop)
46
- await server.listen()
45
+ teardown(async () => {
46
+ await app.close()
47
+ })
47
48
 
48
- equal(server.url.startsWith('https://'), true)
49
- let res = await (request(`${server.url}/`))
49
+ await app.start()
50
+
51
+ equal(app.url.startsWith('https://'), true)
52
+ let res = await (request(`${app.url}/`))
50
53
  equal(res.statusCode, 200)
51
54
  let body = await res.body.json()
52
55
  same(body, { message: 'Welcome to Platformatic! Please visit https://oss.platformatic.dev' })
53
56
 
54
- await server.restart()
57
+ await app.restart()
55
58
 
56
- equal(server.url.startsWith('https://'), true)
57
- res = await (request(`${server.url}/`))
59
+ equal(app.url.startsWith('https://'), true)
60
+ res = await (request(`${app.url}/`))
58
61
  equal(res.statusCode, 200)
59
62
  body = await res.body.json()
60
63
  same(body, { message: 'Welcome to Platformatic! Please visit https://oss.platformatic.dev' })
@@ -0,0 +1,103 @@
1
+ 'use strict'
2
+
3
+ const { test } = require('tap')
4
+ const { buildServer } = require('..')
5
+ const { buildConfig } = require('./helper')
6
+ const { join } = require('path')
7
+ const awsLambdaFastify = require('@fastify/aws-lambda')
8
+
9
+ test('should respond 200 on root endpoint', async ({ teardown, equal, same, ok }) => {
10
+ const app = await buildServer(buildConfig({
11
+ server: {
12
+ hostname: '127.0.0.1',
13
+ port: 0,
14
+ healthCheck: {
15
+ enabled: true,
16
+ interval: 2000
17
+ }
18
+ }
19
+ }))
20
+
21
+ teardown(async () => {
22
+ await app.close()
23
+ })
24
+
25
+ const handler = awsLambdaFastify(app)
26
+
27
+ {
28
+ // No browser (i.e. curl)
29
+ const evt = {
30
+ version: '2.0',
31
+ httpMethod: 'GET',
32
+ path: '/',
33
+ headers: {
34
+ },
35
+ cookies: [],
36
+ queryStringParameters: ''
37
+ }
38
+
39
+ const ret = await handler(evt)
40
+
41
+ equal(ret.body, JSON.stringify({ message: 'Welcome to Platformatic! Please visit https://oss.platformatic.dev' }))
42
+ equal(ret.isBase64Encoded, false)
43
+ ok(ret.headers)
44
+ equal(ret.headers['content-type'], 'application/json; charset=utf-8')
45
+ equal(ret.headers['content-length'], '80')
46
+ ok(ret.headers.date)
47
+ equal(ret.headers.connection, 'keep-alive')
48
+ }
49
+
50
+ {
51
+ // browser
52
+ const evt = {
53
+ version: '2.0',
54
+ httpMethod: 'GET',
55
+ path: '/',
56
+ headers: {
57
+ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'
58
+ },
59
+ cookies: [],
60
+ queryStringParameters: ''
61
+ }
62
+
63
+ const ret = await handler(evt)
64
+
65
+ // No browser (i.e. curl)
66
+ equal(ret.isBase64Encoded, false)
67
+ ok(ret.headers)
68
+ equal(ret.headers['content-type'], 'text/html; charset=UTF-8')
69
+ ok(ret.headers.date)
70
+ equal(ret.headers.connection, 'keep-alive')
71
+ }
72
+ })
73
+
74
+ test('from a config file on disk', async ({ teardown, equal, same, ok }) => {
75
+ const app = await buildServer(join(__dirname, '..', 'fixtures', 'hello', 'warn-log.service.json'))
76
+
77
+ teardown(async () => {
78
+ await app.close()
79
+ })
80
+
81
+ const handler = awsLambdaFastify(app)
82
+
83
+ // No browser (i.e. curl)
84
+ const evt = {
85
+ version: '2.0',
86
+ httpMethod: 'GET',
87
+ path: '/',
88
+ headers: {
89
+ },
90
+ cookies: [],
91
+ queryStringParameters: ''
92
+ }
93
+
94
+ const ret = await handler(evt)
95
+
96
+ equal(ret.body, JSON.stringify({ hello: 'world' }))
97
+ equal(ret.isBase64Encoded, false)
98
+ ok(ret.headers)
99
+ equal(ret.headers['content-type'], 'application/json; charset=utf-8')
100
+ equal(ret.headers['content-length'], '17')
101
+ ok(ret.headers.date)
102
+ equal(ret.headers.connection, 'keep-alive')
103
+ })