@platformatic/service 1.53.3 → 2.0.0-alpha.10

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.
@@ -14,8 +14,8 @@ async function setupGraphQL (app, opts) {
14
14
  const graphqlOptions = deepmerge({
15
15
  graphiql: true,
16
16
  additionalRouteOptions: {
17
- schema: { hide: true }
18
- }
17
+ schema: { hide: true },
18
+ },
19
19
  }, opts)
20
20
 
21
21
  app.register(mercurius, graphqlOptions)
@@ -10,7 +10,7 @@ async function setupClients (app, opts) {
10
10
  exposeStatusRoute: '/status',
11
11
  healthCheckInterval: healthCheck.interval !== undefined ? healthCheck.interval : 5000,
12
12
  ...healthCheck,
13
- healthCheck: healthCheck.fn
13
+ healthCheck: healthCheck.fn,
14
14
  })
15
15
  }
16
16
 
@@ -13,43 +13,40 @@ const metricsPlugin = fp(async function (app, opts = {}) {
13
13
 
14
14
  const defaultMetrics = opts.defaultMetrics ?? { enabled: true }
15
15
 
16
- if (opts.labels || opts.prefix) {
16
+ if (opts.labels) {
17
17
  const labels = opts.labels ?? {}
18
- if (opts.prefix) {
19
- labels.prefix = opts.prefix
20
- }
21
18
  register.setDefaultLabels(labels)
22
19
  }
23
20
 
24
21
  app.register(require('fastify-metrics'), {
25
22
  defaultMetrics: {
26
23
  ...defaultMetrics,
27
- register
24
+ register,
28
25
  },
29
26
  endpoint: null,
30
27
  name: 'metrics',
31
28
  clearRegisterOnInit: false,
32
29
  promClient: {
33
30
  ...promClient,
34
- register
31
+ register,
35
32
  },
36
33
  routeMetrics: {
37
34
  enabled: true,
38
35
  customLabels: {
39
36
  // TODO: check if this is set in prom
40
- telemetry_id: (req) => req.headers['x-telemetry-id'] ?? 'unknown'
37
+ telemetry_id: (req) => req.headers['x-plt-telemetry-id'] ?? 'unknown',
41
38
  },
42
39
  overrides: {
43
40
  histogram: {
44
41
  name: 'http_request_duration_seconds',
45
- registers: [register]
42
+ registers: [register],
46
43
  },
47
44
  summary: {
48
45
  name: 'http_request_summary_seconds',
49
- registers: [register]
50
- }
51
- }
52
- }
46
+ registers: [register],
47
+ },
48
+ },
49
+ },
53
50
  })
54
51
 
55
52
  app.register(fp(async (app) => {
@@ -59,7 +56,7 @@ const metricsPlugin = fp(async function (app, opts = {}) {
59
56
  collect: () => {
60
57
  process.nextTick(() => httpLatencyMetric.reset())
61
58
  },
62
- registers: [register]
59
+ registers: [register],
63
60
  })
64
61
 
65
62
  const ignoredMethods = ['HEAD', 'OPTIONS', 'TRACE', 'CONNECT']
@@ -78,7 +75,7 @@ const metricsPlugin = fp(async function (app, opts = {}) {
78
75
  }
79
76
  })
80
77
  }, {
81
- encapsulate: false
78
+ encapsulate: false,
82
79
  }))
83
80
 
84
81
  if (defaultMetrics.enabled) {
@@ -93,7 +90,7 @@ const metricsPlugin = fp(async function (app, opts = {}) {
93
90
  eluMetric.set(result)
94
91
  startELU = endELU
95
92
  },
96
- registers: [register]
93
+ registers: [register],
97
94
  })
98
95
  app.metrics.client.register.registerMetric(eluMetric)
99
96
 
@@ -126,7 +123,7 @@ const metricsPlugin = fp(async function (app, opts = {}) {
126
123
  previousIdleTime = idleTime
127
124
  previousTotalTime = totalTime
128
125
  },
129
- registers: [register]
126
+ registers: [register],
130
127
  })
131
128
  app.metrics.client.register.registerMetric(cpuMetric)
132
129
  })
@@ -142,20 +139,11 @@ const metricsPlugin = fp(async function (app, opts = {}) {
142
139
  }
143
140
  }
144
141
 
145
- let isRestarting = false
146
- app.addHook('onReady', async () => {
147
- app.addPreRestartHook(async () => {
148
- isRestarting = true
149
- cleanMetrics()
150
- })
151
- })
152
142
  app.addHook('onClose', async () => {
153
- if (!isRestarting) {
154
- cleanMetrics()
155
- }
143
+ cleanMetrics()
156
144
  })
157
145
  }, {
158
- encapsulate: false
146
+ encapsulate: false,
159
147
  })
160
148
 
161
149
  // This is a global httpServer to match global
@@ -182,7 +170,7 @@ async function createMetricsServer (app, hostname, port) {
182
170
  httpServer.on('request', handler)
183
171
  return httpServer
184
172
  },
185
- logger: app.log.child({ name: 'prometheus' })
173
+ loggerInstance: app.log.child({ name: 'prometheus' }),
186
174
  })
187
175
 
188
176
  app.addHook('onClose', async () => {
@@ -226,7 +214,7 @@ module.exports = fp(async function (app, opts) {
226
214
  return reply.code(401).send({ message: 'Unauthorized' })
227
215
  }
228
216
  return done()
229
- }
217
+ },
230
218
  })
231
219
  onRequestHook = metricsServer.basicAuth
232
220
  }
@@ -246,7 +234,7 @@ module.exports = fp(async function (app, opts) {
246
234
  }
247
235
  reply.type('text/plain')
248
236
  return promRegistry.metrics()
249
- }
237
+ },
250
238
  })
251
239
  }
252
240
 
@@ -10,45 +10,34 @@ const fp = require('fastify-plugin')
10
10
  // despite being covered by test/routes.test.js
11
11
  /* c8 ignore next 33 */
12
12
  async function setupOpenAPI (app, opts) {
13
- const { openapi, versions } = opts
13
+ const { openapi } = opts
14
14
  const openapiConfig = deepmerge({
15
15
  exposeRoute: true,
16
16
  info: {
17
17
  title: 'Platformatic',
18
18
  description: 'This is a service built on top of Platformatic',
19
- version: '1.0.0'
20
- }
19
+ version: '1.0.0',
20
+ },
21
21
  }, typeof openapi === 'object' ? openapi : {})
22
22
  app.log.trace({ openapi: openapiConfig })
23
23
  const swaggerOptions = {
24
24
  exposeRoute: openapiConfig.exposeRoute,
25
25
  openapi: {
26
- ...openapiConfig
26
+ ...openapiConfig,
27
27
  },
28
28
  refResolver: {
29
29
  buildLocalReference (json, baseUri, fragment, i) {
30
30
  // TODO figure out if we need def-${i}
31
31
  /* istanbul ignore next */
32
32
  return json.$id || `def-${i}`
33
- }
33
+ },
34
34
  },
35
- transform: ({ schema, url }) => {
36
- // Hide versioned endpoints
37
- for (const version of versions?.configs ?? []) {
38
- if (url.startsWith(version.openapi.prefix)) {
39
- if (!schema) schema = {}
40
- schema.hide = true
41
- break
42
- }
43
- }
44
- return { schema, url }
45
- }
46
35
  }
47
36
 
48
37
  if (openapi.path) {
49
38
  swaggerOptions.mode = 'static'
50
39
  swaggerOptions.specification = {
51
- path: openapi.path
40
+ path: openapi.path,
52
41
  }
53
42
  }
54
43
 
@@ -60,11 +49,11 @@ async function setupOpenAPI (app, opts) {
60
49
  /** Serve spec file in yaml and json */
61
50
  app.get(`${routePrefix}/json`, {
62
51
  schema: { hide: true },
63
- logLevel: 'warn'
52
+ logLevel: 'warn',
64
53
  }, async () => app.swagger())
65
54
  app.get(`${routePrefix}/yaml`, {
66
55
  schema: { hide: true },
67
- logLevel: 'warn'
56
+ logLevel: 'warn',
68
57
  }, async () => app.swagger({ yaml: true }))
69
58
 
70
59
  app.register(ScalarApiReference, {
@@ -72,8 +61,8 @@ async function setupOpenAPI (app, opts) {
72
61
  ...openapi,
73
62
  routePrefix,
74
63
  configuration: {
75
- customCss: scalarTheme.theme
76
- }
64
+ customCss: scalarTheme.theme,
65
+ },
77
66
  })
78
67
  }
79
68
 
@@ -7,14 +7,14 @@ const wrapper = require('./sandbox-wrapper')
7
7
 
8
8
  const { getJSPluginPath, isFileAccessible } = require('../utils')
9
9
 
10
- async function loadPlugins (app) {
10
+ async function loadPlugins (app, opts) {
11
11
  const configManager = app.platformatic.configManager
12
12
  const config = configManager.current
13
13
 
14
14
  let isOutDirAccessible = false
15
15
  let outDir = null
16
16
 
17
- const workingDir = configManager.dirname
17
+ const workingDir = opts?.context?.directory ?? configManager.dirname
18
18
  const tsConfigPath = configManager.current.plugins.typescript?.tsConfig || join(workingDir, 'tsconfig.json')
19
19
 
20
20
  // If the tsconfig.json file exists, then we need to adjust the plugin paths
@@ -34,12 +34,19 @@ async function loadPlugins (app) {
34
34
  isOutDirAccessible = await isFileAccessible(outDir)
35
35
  }
36
36
 
37
+ if (opts.context?.isProduction && !isOutDirAccessible) {
38
+ throw new Error(
39
+ `Cannot access directory '${outDir}'. Please run the 'build' command before running in production mode.`
40
+ )
41
+ }
42
+
37
43
  if (config.plugins.paths && isOutDirAccessible) {
38
- config.plugins.paths = config.plugins.paths.map((plugin) => {
44
+ config.plugins.paths = config.plugins.paths.map(plugin => {
39
45
  /* c8 ignore next 3 */
40
- const tmp = typeof plugin === 'string'
41
- ? getJSPluginPath(workingDir, plugin, outDir)
42
- : { ...plugin, path: getJSPluginPath(workingDir, plugin.path, outDir) }
46
+ const tmp =
47
+ typeof plugin === 'string'
48
+ ? getJSPluginPath(workingDir, plugin, outDir)
49
+ : { ...plugin, path: getJSPluginPath(workingDir, plugin.path, outDir) }
43
50
  return tmp
44
51
  })
45
52
  }
@@ -36,7 +36,7 @@ module.exports = fp(async function (app, opts) {
36
36
  forceESM: plugin.forceESM,
37
37
  ignoreFilter: plugin.ignoreFilter,
38
38
  matchFilter: plugin.matchFilter,
39
- ...patternOptions
39
+ ...patternOptions,
40
40
  })
41
41
  } else {
42
42
  let loaded = await import(pathToFileURL(plugin.path))
@@ -71,7 +71,7 @@ function patternOptionsFromPlugin (plugin) {
71
71
  const patternOptionKeys = [
72
72
  'ignorePattern',
73
73
  'indexPattern',
74
- 'autoHooksPattern'
74
+ 'autoHooksPattern',
75
75
  ]
76
76
 
77
77
  for (const key of patternOptionKeys) {
@@ -1,16 +1,20 @@
1
1
  'use strict'
2
2
 
3
3
  const fp = require('fastify-plugin')
4
- const compiler = require('../compile')
5
-
6
- async function setupTsCompiler (app) {
7
- // TODO: move params to opts
4
+ const compiler = require('@platformatic/ts-compiler')
5
+ const { extractTypeScriptCompileOptionsFromConfig } = require('../compile')
8
6
 
7
+ async function setupTsCompiler (app, opts) {
9
8
  const configManager = app.platformatic.configManager
10
9
  const config = configManager.current
11
- const workingDir = configManager.dirname
10
+ const workingDir = opts?.context?.directory ?? configManager.dirname
12
11
 
13
- await compiler.compile(workingDir, config, app.log, { clean: false })
12
+ await compiler.compile({
13
+ ...extractTypeScriptCompileOptionsFromConfig(config),
14
+ cwd: workingDir,
15
+ clean: false,
16
+ logger: app.log,
17
+ })
14
18
  }
15
19
 
16
20
  module.exports = fp(setupTsCompiler)
@@ -5,25 +5,8 @@ const fastifyStatic = require('@fastify/static')
5
5
  const userAgentParser = require('my-ua-parser')
6
6
 
7
7
  module.exports = async (app, opts) => {
8
- const versions = opts.versions || {}
9
-
10
8
  app.register(fastifyStatic, {
11
- root: path.join(__dirname, 'public')
12
- })
13
-
14
- app.route({
15
- method: 'GET',
16
- path: '/_platformatic_versions',
17
- schema: { hide: true },
18
- handler: () => {
19
- const openapiUrls = []
20
- for (const versionConfig of versions?.configs ?? []) {
21
- const name = versionConfig.version
22
- const prefix = versionConfig.openapi.prefix
23
- openapiUrls.push({ name, prefix })
24
- }
25
- return openapiUrls
26
- }
9
+ root: path.join(__dirname, 'public'),
27
10
  })
28
11
 
29
12
  // root endpoint
@@ -40,6 +23,6 @@ module.exports = async (app, opts) => {
40
23
  }
41
24
  }
42
25
  return { message: 'Welcome to Platformatic! Please visit https://docs.platformatic.dev' }
43
- }
26
+ },
44
27
  })
45
28
  }
@@ -197,6 +197,7 @@
197
197
  <div class="button-container">
198
198
  <a href="https://docs.platformatic.dev" target="_blank" class="button-link">Documentation</a>
199
199
  <div class="open-documentation-version buttons-list-container">&nbsp;</div>
200
+ <a id="openapi-link" target="_blank" class="button-link">OpenAPI Documentation</a>
200
201
  <a id="graphql-link" target="_blank" class="button-link">GraphiQL</a>
201
202
  </div>
202
203
  </div>
@@ -205,6 +206,9 @@
205
206
  <script>
206
207
  const currentPath = window.location.pathname
207
208
 
209
+ const openApiLink = document.getElementById('openapi-link')
210
+ openApiLink.href = currentPath + 'documentation'
211
+
208
212
  const graphqlLink = document.getElementById('graphql-link')
209
213
  graphqlLink.href = currentPath + 'graphiql'
210
214
 
@@ -225,27 +229,6 @@
225
229
  document.getElementById('logo').src = 'images/platformatic-logo-dark.svg'
226
230
  }
227
231
  }
228
-
229
- function join (...paths) {
230
- return paths.join('/').replace(/\/+/g, '/')
231
- }
232
-
233
- fetch('/_platformatic_versions')
234
- .then(response => response.json())
235
- .then(versions => {
236
- const sharedOpenapiHref = join(currentPath, 'documentation')
237
- const openapiButtons = [
238
- `<a href="${sharedOpenapiHref}"target="_blank" class="button-link">OpenAPI Documentation</a>`
239
- ]
240
-
241
- for (const version of versions) {
242
- const href = join(currentPath, version.prefix, 'documentation')
243
- openapiButtons.push(`<a href="${href}" target="_blank" class="button-link">OpenAPI Documentation ${version.name}</a>`)
244
- }
245
-
246
- const buttonList = document.getElementsByClassName('open-documentation-version')[0]
247
- buttonList.innerHTML = openapiButtons.join('')
248
- })
249
232
  </script>
250
233
  </body>
251
234
  </html>