@platformatic/service 1.15.1 → 1.17.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 CHANGED
@@ -21,13 +21,18 @@ const { addLoggerToTheConfig } = require('./lib/utils')
21
21
  const { start, buildServer } = require('./lib/start')
22
22
  const ServiceGenerator = require('./lib/generator/service-generator.js')
23
23
 
24
- // TODO(mcollina): toLoad is deprecated, remove it in the next major version.
25
- async function platformaticService (app, opts, toLoad) {
24
+ // TODO(mcollina): arugments[2] is deprecated, remove it in the next major version.
25
+ async function platformaticService (app, opts) {
26
26
  const configManager = app.platformatic.configManager
27
27
  const config = configManager.current
28
- const beforePlugins = opts.beforePlugins || toLoad || []
28
+ const beforePlugins = opts.beforePlugins || arguments[2] || []
29
29
 
30
30
  if (isKeyEnabled('metrics', config)) {
31
+ if (config.metrics.server === 'own' && parseInt(config.server.port) === parseInt(config.metrics.port)) {
32
+ app.log.warn('In order to serve metrics on the same port as the core applicaton, set metrics.server to "parent".')
33
+ config.metrics.server = 'parent'
34
+ }
35
+
31
36
  app.register(setupMetrics, config.metrics)
32
37
  }
33
38
 
@@ -8,26 +8,44 @@ const basicAuth = require('@fastify/basic-auth')
8
8
  const fastifyAccepts = require('@fastify/accepts')
9
9
  const Fastify = require('fastify')
10
10
 
11
- // This is a global server to match global
11
+ // This is a global httpServer to match global
12
12
  // prometheus. It's an antipattern, so do
13
13
  // not use it elsewhere.
14
- let server = null
14
+ let httpServer = null
15
15
 
16
16
  module.exports = fp(async function (app, opts) {
17
- let port = 9090
18
- let host = '0.0.0.0'
19
- if (typeof opts === 'object') {
20
- if (undefined !== opts.port) {
21
- port = opts.port
17
+ const server = opts.server ?? 'own'
18
+ const hostname = opts.hostname ?? '0.0.0.0'
19
+ const port = opts.port ?? 9090
20
+ const metricsEndpoint = opts.endpoint ?? '/metrics'
21
+ const auth = opts.auth ?? null
22
+
23
+ let basicAuthValidator = null
24
+ if (auth) {
25
+ const { username, password } = auth
26
+ basicAuthValidator = function (user, pass, req, reply, done) {
27
+ if (username !== user || password !== pass) {
28
+ return reply.code(401).send({ message: 'Unauthorized' })
29
+ }
30
+ return done()
22
31
  }
23
- /* c8 ignore next 3 */
24
- if (undefined !== opts.hostname) {
25
- host = opts.hostname
32
+
33
+ if (server === 'parent') {
34
+ await app.register(basicAuth, {
35
+ validate: basicAuthValidator
36
+ })
37
+
38
+ app.addHook('onRoute', (routeOptions) => {
39
+ if (routeOptions.url === metricsEndpoint) {
40
+ routeOptions.onRequest = app.basicAuth
41
+ }
42
+ })
26
43
  }
27
44
  }
45
+
28
46
  app.register(metricsPlugin, {
29
47
  defaultMetrics: { enabled: true },
30
- endpoint: null,
48
+ endpoint: server === 'parent' ? metricsEndpoint : null,
31
49
  name: 'metrics',
32
50
  routeMetrics: { enabled: true },
33
51
  clearRegisterOnInit: true
@@ -56,24 +74,28 @@ module.exports = fp(async function (app, opts) {
56
74
  app.metrics.client.register.registerMetric(eluMetric)
57
75
  })
58
76
 
59
- if (server && server.address().port !== port) {
60
- await new Promise((resolve) => server.close(resolve))
61
- server = null
77
+ if (httpServer && httpServer.address().port !== port) {
78
+ await new Promise((resolve) => httpServer.close(resolve))
79
+ httpServer = null
80
+ }
81
+
82
+ if (server === 'parent') {
83
+ return
62
84
  }
63
85
 
64
- if (!server) {
65
- server = http.createServer()
66
- server.listen(port, host)
67
- server.unref()
86
+ if (!httpServer) {
87
+ httpServer = http.createServer()
88
+ httpServer.listen(port, hostname)
89
+ httpServer.unref()
68
90
  }
69
91
 
70
92
  const promServer = Fastify({
71
93
  name: 'Prometheus server',
72
94
  serverFactory: (handler) => {
73
- server.removeAllListeners('request')
74
- server.removeAllListeners('clientError')
75
- server.on('request', handler)
76
- return server
95
+ httpServer.removeAllListeners('request')
96
+ httpServer.removeAllListeners('clientError')
97
+ httpServer.on('request', handler)
98
+ return httpServer
77
99
  },
78
100
  logger: app.log.child({ name: 'prometheus' })
79
101
  })
@@ -81,7 +103,7 @@ module.exports = fp(async function (app, opts) {
81
103
  promServer.register(fastifyAccepts)
82
104
 
83
105
  const metricsEndpointOptions = {
84
- url: '/metrics',
106
+ url: metricsEndpoint,
85
107
  method: 'GET',
86
108
  logLevel: 'warn',
87
109
  handler: async (req, reply) => {
@@ -95,15 +117,9 @@ module.exports = fp(async function (app, opts) {
95
117
  }
96
118
  }
97
119
 
98
- if (opts.auth) {
99
- const { username, password } = opts.auth
120
+ if (auth) {
100
121
  await promServer.register(basicAuth, {
101
- validate: function (user, pass, req, reply, done) {
102
- if (username !== user || password !== pass) {
103
- return reply.code(401).send({ message: 'Unauthorized' })
104
- }
105
- return done()
106
- }
122
+ validate: basicAuthValidator
107
123
  })
108
124
  metricsEndpointOptions.onRequest = promServer.basicAuth
109
125
  }
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const Swagger = require('@fastify/swagger')
4
- const SwaggerUI = require('@fastify/swagger-ui')
4
+ const ScalarApiReference = require('@scalar/fastify-api-reference')
5
5
  const deepmerge = require('@fastify/deepmerge')({ all: true })
6
6
  const fp = require('fastify-plugin')
7
7
 
@@ -54,12 +54,20 @@ async function setupOpenAPI (app, opts) {
54
54
 
55
55
  await app.register(Swagger, swaggerOptions)
56
56
 
57
- const { default: theme } = await import('@platformatic/swagger-ui-theme')
58
- app.register(SwaggerUI, {
59
- ...theme,
57
+ const { default: scalarTheme } = await import('@platformatic/scalar-theme')
58
+ const routePrefix = openapi.swaggerPrefix || '/documentation'
59
+
60
+ /** Serve spec file in yaml and json */
61
+ app.get(`${routePrefix}/json`, { schema: { hide: true } }, async () => app.swagger())
62
+ app.get(`${routePrefix}/yaml`, { schema: { hide: true } }, async () => app.swagger({ yaml: true }))
63
+
64
+ app.register(ScalarApiReference, {
65
+ ...opts,
60
66
  ...openapi,
61
- logLevel: 'warn',
62
- prefix: openapi.swaggerPrefix || '/documentation'
67
+ routePrefix,
68
+ configuration: {
69
+ customCss: scalarTheme.theme
70
+ }
63
71
  })
64
72
  }
65
73
 
@@ -13,7 +13,7 @@ const {
13
13
  const wrapperPath = join(__dirname, 'sandbox-wrapper.js')
14
14
 
15
15
  const Swagger = require('@fastify/swagger')
16
- const SwaggerUI = require('@fastify/swagger-ui')
16
+ const ScalarApiReference = require('@scalar/fastify-api-reference')
17
17
 
18
18
  async function loadVersions (app) {
19
19
  const configManager = app.platformatic.configManager
@@ -44,9 +44,12 @@ async function loadVersions (app) {
44
44
  }
45
45
  })
46
46
 
47
- app.register(SwaggerUI, {
47
+ app.get('/documentation/json', { schema: { hide: true } }, async () => app.swagger())
48
+ app.get('/documentation/yaml', { schema: { hide: true } }, async () => app.swagger({ yaml: true }))
49
+
50
+ app.register(ScalarApiReference, {
48
51
  logLevel: 'warn',
49
- prefix: '/documentation'
52
+ routePrefix: '/documentation'
50
53
  })
51
54
 
52
55
  if (latestVersionConfig.plugins) {
@@ -110,9 +113,12 @@ async function loadVersions (app) {
110
113
  }
111
114
  })
112
115
 
113
- app.register(SwaggerUI, {
116
+ app.get('/documentation/json', { schema: { hide: true } }, async () => app.swagger())
117
+ app.get('/documentation/yaml', { schema: { hide: true } }, async () => app.swagger({ yaml: true }))
118
+
119
+ app.register(ScalarApiReference, {
114
120
  logLevel: 'warn',
115
- prefix: '/documentation'
121
+ routePrefix: '/documentation'
116
122
  })
117
123
 
118
124
  const componentSchemas = prevOpenapiSchema.components?.schemas ?? {}
@@ -222,6 +222,9 @@
222
222
  <script>
223
223
  const currentPath = window.location.pathname
224
224
 
225
+ const openApiLink = document.getElementById('openapi-link')
226
+ openApiLink.href = currentPath + 'documentation'
227
+
225
228
  const graphqlLink = document.getElementById('graphql-link')
226
229
  graphqlLink.href = currentPath + 'graphiql'
227
230
 
package/lib/schema.js CHANGED
@@ -555,6 +555,11 @@ const metrics = {
555
555
  ]
556
556
  },
557
557
  hostname: { type: 'string' },
558
+ endpoint: { type: 'string' },
559
+ server: {
560
+ type: 'string',
561
+ enum: ['own', 'parent']
562
+ },
558
563
  auth: {
559
564
  type: 'object',
560
565
  properties: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/service",
3
- "version": "1.15.1",
3
+ "version": "1.17.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -20,7 +20,7 @@
20
20
  "@fastify/aws-lambda": "^3.3.0",
21
21
  "@fastify/compress": "^6.5.0",
22
22
  "bindings": "^1.5.0",
23
- "c8": "^8.0.1",
23
+ "c8": "^9.0.0",
24
24
  "glob": "^10.3.10",
25
25
  "json-schema-to-typescript": "^13.1.1",
26
26
  "openapi-types": "^12.1.3",
@@ -31,7 +31,7 @@
31
31
  "standard": "^17.1.0",
32
32
  "strip-ansi": "^7.1.0",
33
33
  "ts-standard": "^12.0.2",
34
- "tsd": "^0.29.0",
34
+ "tsd": "^0.30.0",
35
35
  "typescript": "^5.2.2",
36
36
  "undici": "^6.0.0",
37
37
  "vscode-json-languageservice": "^5.3.6",
@@ -48,23 +48,23 @@
48
48
  "@fastify/restartable": "^2.1.1",
49
49
  "@fastify/static": "^6.11.2",
50
50
  "@fastify/swagger": "^8.10.1",
51
- "@fastify/swagger-ui": "^2.0.0",
52
51
  "@fastify/under-pressure": "^8.3.0",
53
52
  "@mercuriusjs/federation": "^2.0.0",
53
+ "@scalar/fastify-api-reference": "^1.10.1",
54
54
  "@types/ws": "^8.5.6",
55
55
  "ajv": "^8.12.0",
56
+ "cli-progress": "^3.12.0",
56
57
  "close-with-grace": "^1.2.0",
57
58
  "code-block-writer": "^12.0.0",
58
- "commist": "^3.2.0",
59
59
  "colorette": "^2.0.20",
60
- "cli-progress": "^3.12.0",
60
+ "commist": "^3.2.0",
61
61
  "desm": "^1.3.0",
62
62
  "env-schema": "^5.2.0",
63
63
  "es-main": "^1.3.0",
64
64
  "execa": "^8.0.1",
65
65
  "fastify": "^4.23.2",
66
- "fastify-openapi-glue": "^4.3.3",
67
66
  "fastify-metrics": "^10.3.2",
67
+ "fastify-openapi-glue": "^4.3.3",
68
68
  "fastify-plugin": "^4.5.1",
69
69
  "graphql": "^16.8.1",
70
70
  "help-me": "^5.0.0",
@@ -74,16 +74,16 @@
74
74
  "pino": "^8.15.3",
75
75
  "pino-pretty": "^10.2.0",
76
76
  "rfdc": "^1.3.0",
77
- "undici": "^6.0.0",
78
77
  "ua-parser-js": "^1.0.36",
79
- "@platformatic/authenticate": "1.15.1",
80
- "@platformatic/client": "1.15.1",
81
- "@platformatic/config": "1.15.1",
82
- "@platformatic/generators": "1.15.1",
83
- "@platformatic/swagger-ui-theme": "1.15.1",
84
- "@platformatic/telemetry": "1.15.1",
85
- "@platformatic/utils": "1.15.1",
86
- "@platformatic/metaconfig": "1.15.1"
78
+ "undici": "^6.0.0",
79
+ "@platformatic/authenticate": "1.17.0",
80
+ "@platformatic/client": "1.17.0",
81
+ "@platformatic/config": "1.17.0",
82
+ "@platformatic/generators": "1.17.0",
83
+ "@platformatic/metaconfig": "1.17.0",
84
+ "@platformatic/scalar-theme": "1.17.0",
85
+ "@platformatic/telemetry": "1.17.0",
86
+ "@platformatic/utils": "1.17.0"
87
87
  },
88
88
  "standard": {
89
89
  "ignore": [
@@ -98,7 +98,7 @@
98
98
  ]
99
99
  },
100
100
  "scripts": {
101
- "test": "pnpm run lint && c8 -x fixtures -x test node ./test/runner.js && tsd",
101
+ "test": "pnpm run lint && node ./test/runner.js && tsd",
102
102
  "nocov": "pnpm run lint && node ./test/runner.js && tsd",
103
103
  "build": "node lib/schema.js | json2ts > config.d.ts",
104
104
  "lint": "standard | snazzy && ts-standard | snazzy"
package/.taprc DELETED
@@ -1,2 +0,0 @@
1
- timeout: 500
2
- coverage: false