@platformatic/service 2.71.1-alpha.0 → 3.0.0-alpha.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 (51) hide show
  1. package/config.d.ts +1 -19
  2. package/eslint.config.js +4 -6
  3. package/index.d.ts +51 -47
  4. package/index.js +44 -199
  5. package/lib/application.js +57 -0
  6. package/lib/compile.js +1 -52
  7. package/lib/generator.js +154 -0
  8. package/lib/plugins/clients.js +9 -8
  9. package/lib/plugins/cors.js +5 -8
  10. package/lib/plugins/graphql.js +16 -14
  11. package/lib/plugins/health-check.js +6 -8
  12. package/lib/plugins/openapi.js +40 -31
  13. package/lib/plugins/plugins.js +15 -18
  14. package/lib/{root-endpoint/index.js → plugins/root.js} +9 -8
  15. package/lib/plugins/sandbox-wrapper.js +62 -55
  16. package/lib/plugins/typescript.js +10 -13
  17. package/lib/schema.js +1030 -132
  18. package/lib/stackable.js +180 -337
  19. package/lib/upgrade.js +6 -8
  20. package/lib/utils.js +39 -74
  21. package/lib/versions/0.16.0.js +14 -14
  22. package/lib/versions/{from-zero-twenty-eight-to-will-see.js → 0.28.0.js} +3 -5
  23. package/lib/versions/2.0.0.js +4 -6
  24. package/package.json +17 -22
  25. package/schema.json +3 -74
  26. package/tsconfig.json +16 -6
  27. package/.c8rc +0 -6
  28. package/help/compile.txt +0 -19
  29. package/help/create.txt +0 -11
  30. package/help/help.txt +0 -8
  31. package/help/schema.txt +0 -9
  32. package/help/start.txt +0 -23
  33. package/index.test-d.ts +0 -107
  34. package/lib/create.mjs +0 -85
  35. package/lib/gen-schema.js +0 -15
  36. package/lib/gen-types.mjs +0 -38
  37. package/lib/generator/README.md +0 -31
  38. package/lib/generator/service-generator.d.ts +0 -11
  39. package/lib/generator/service-generator.js +0 -126
  40. package/lib/openapi-schema-defs.js +0 -1108
  41. package/lib/plugins/metrics.js +0 -244
  42. package/lib/start.js +0 -190
  43. package/service.mjs +0 -71
  44. /package/{lib/root-endpoint/public → public}/images/dark_mode.svg +0 -0
  45. /package/{lib/root-endpoint/public → public}/images/favicon.ico +0 -0
  46. /package/{lib/root-endpoint/public → public}/images/light_mode.svg +0 -0
  47. /package/{lib/root-endpoint/public → public}/images/platformatic-logo-dark.svg +0 -0
  48. /package/{lib/root-endpoint/public → public}/images/platformatic-logo-light.svg +0 -0
  49. /package/{lib/root-endpoint/public → public}/images/triangle_dark.svg +0 -0
  50. /package/{lib/root-endpoint/public → public}/images/triangle_light.svg +0 -0
  51. /package/{lib/root-endpoint/public → public}/index.html +0 -0
package/lib/stackable.js CHANGED
@@ -1,414 +1,239 @@
1
- 'use strict'
2
-
3
- const { hostname } = require('node:os')
4
- const { dirname } = require('node:path')
5
- const { pathToFileURL } = require('node:url')
6
- const { workerData } = require('node:worker_threads')
7
- const { printSchema } = require('graphql')
8
- const pino = require('pino')
9
- const { client, collectMetrics } = require('@platformatic/metrics')
10
- const { extractTypeScriptCompileOptionsFromConfig } = require('./compile')
11
- const { compile } = require('@platformatic/ts-compiler')
12
- const { deepmerge, buildPinoFormatters, buildPinoTimestamp } = require('@platformatic/utils')
13
-
14
- const kITC = Symbol.for('plt.runtime.itc')
15
-
16
- class ServiceStackable {
17
- constructor (options) {
18
- this.app = null
19
- this._init = options.init
20
- this.stackable = options.stackable
21
- this.metricsRegistry = new client.Registry()
22
-
23
- this.configManager = options.configManager
24
- this.context = options.context ?? {}
25
- this.context.stackable = this
26
-
27
- this.serviceId = this.context.serviceId
28
- this.context.worker ??= { count: 1, index: 0 }
29
- this.workerId = this.context.worker.count > 1 ? this.context.worker.index : undefined
30
-
31
- this.runtimeConfig = deepmerge(this.context.runtimeConfig ?? {}, workerData?.config ?? {})
32
-
33
- this.customHealthCheck = null
34
-
35
- this.configManager.on('error', err => {
36
- /* c8 ignore next */
37
- this.stackable.log({
38
- message: 'error reloading the configuration' + err,
39
- level: 'error'
40
- })
41
- })
42
-
43
- this.#updateConfig()
44
-
45
- // Setup globals
46
- this.registerGlobals({
47
- serviceId: this.serviceId,
48
- workerId: this.workerId,
49
- // Always use URL to avoid serialization problem in Windows
50
- root: this.context.directory ? pathToFileURL(this.context.directory).toString() : undefined,
51
- setOpenapiSchema: this.setOpenapiSchema.bind(this),
52
- setGraphqlSchema: this.setGraphqlSchema.bind(this),
53
- setConnectionString: this.setConnectionString.bind(this),
54
- setBasePath: this.setBasePath.bind(this),
55
- runtimeBasePath: this.runtimeConfig?.basePath ?? null,
56
- invalidateHttpCache: this.#invalidateHttpCache.bind(this),
57
- prometheus: { client, registry: this.metricsRegistry },
58
- setCustomHealthCheck: this.setCustomHealthCheck.bind(this),
59
- setCustomReadinessCheck: this.setCustomReadinessCheck.bind(this)
60
- })
1
+ import { BaseStackable, cleanBasePath, ensureTrailingSlash, getServerUrl } from '@platformatic/basic'
2
+ import { telemetry } from '@platformatic/telemetry'
3
+ import { compile } from '@platformatic/ts-compiler'
4
+ import { buildPinoFormatters, buildPinoTimestamp, deepmerge, features, isKeyEnabled } from '@platformatic/utils'
5
+ import fastify from 'fastify'
6
+ import { printSchema } from 'graphql'
7
+ import { randomUUID } from 'node:crypto'
8
+ import { hostname } from 'node:os'
9
+ import pino from 'pino'
10
+ import { platformaticService } from './application.js'
11
+ import { setupRoot } from './plugins/root.js'
12
+ import { version } from './schema.js'
13
+ import { sanitizeHTTPSArgument } from './utils.js'
14
+
15
+ export class ServiceStackable extends BaseStackable {
16
+ #app
17
+ #basePath
18
+
19
+ constructor (root, config, context) {
20
+ super('service', version, root, config, context)
21
+ this.applicationFactory = this.context.applicationFactory ?? platformaticService
61
22
  }
62
23
 
63
24
  async init () {
64
- this.#initLogger()
65
-
66
- if (this.app === null) {
67
- this.app = await this._init()
68
- await this.#collectMetrics()
69
- }
70
- return this.app
71
- }
72
-
73
- async start (options = {}) {
74
- await this.init()
25
+ await super.init()
75
26
 
76
- if (options.listen === false) {
77
- await this.app.ready()
27
+ if (this.#app) {
78
28
  return
79
29
  }
80
- await this.app.start()
81
- }
82
-
83
- async stop () {
84
- if (this.app === null) return
85
- await this.app.close()
86
- }
87
-
88
- async build () {
89
- this.#initLogger()
90
- const typeScriptCompileOptions = extractTypeScriptCompileOptionsFromConfig(this.configManager.current)
91
- const cwd = dirname(this.configManager.fullPath)
92
- const compileOptions = {
93
- ...typeScriptCompileOptions,
94
- cwd,
95
- logger: this.logger
96
- }
97
-
98
- await compile(compileOptions)
99
- }
100
30
 
101
- getUrl () {
102
- return this.app !== null ? this.app.url : null
103
- }
31
+ const config = this.config
32
+ this.#basePath = ensureTrailingSlash(cleanBasePath(config.basePath ?? this.serviceId))
104
33
 
105
- async getInfo () {
106
- const type = this.stackable.configType
107
- const version = this.stackable.configManagerConfig.version ?? null
108
- return { type, version }
109
- }
34
+ // Create the application
35
+ this.#app = fastify({
36
+ ...this.serverConfig,
37
+ ...this.fastifyOptions,
38
+ genReqId () {
39
+ return randomUUID()
40
+ }
41
+ })
110
42
 
111
- async getConfig () {
112
- const config = Object.assign({}, this.configManager.current)
113
- config.server = Object.assign({}, config.server)
43
+ // This must be done before loading the plugins, so they can inspect if the
44
+ // openTelemetry decorator exists and then configure accordingly.
45
+ if (isKeyEnabled('telemetry', config)) {
46
+ await this.#app.register(telemetry, config.telemetry)
47
+ }
114
48
 
115
- const logger = config.server.loggerInstance
49
+ this.#app.decorate('platformatic', { config: this.config })
116
50
 
117
- if (logger) {
118
- config.server.logger = {}
51
+ await this.#app.register(this.applicationFactory, this)
119
52
 
120
- if (logger.level) {
121
- config.server.logger.level = logger.level
53
+ if (Array.isArray(this.context.fastifyPlugins)) {
54
+ for (const plugin of this.context.fastifyPlugins) {
55
+ await this.#app.register(plugin)
122
56
  }
123
57
  }
124
58
 
125
- delete config.server.loggerInstance
126
-
127
- return config
128
- }
129
-
130
- async getEnv () {
131
- return this.configManager.env
132
- }
133
-
134
- getMeta () {
135
- const config = this.configManager.current
136
-
137
- return {
138
- composer: {
139
- prefix: config.basePath ?? this.basePath ?? this.context?.serviceId,
140
- wantsAbsoluteUrls: false,
141
- needsRootTrailingSlash: false,
142
- tcp: !!this.app?.url,
143
- url: this.app?.url
144
- },
145
- connectionStrings: [this.connectionString]
59
+ if (!this.#app.hasRoute({ url: '/', method: 'GET' }) && !this.#app.hasRoute({ url: '/*', method: 'GET' })) {
60
+ await this.#app.register(setupRoot)
146
61
  }
147
62
  }
148
63
 
149
- async getWatchConfig () {
150
- const config = this.configManager.current
151
-
152
- const enabled = config.watch?.enabled !== false && config.plugins !== undefined
64
+ async start (startOptions) {
65
+ // Compatibility with v2 service
66
+ const { listen } = startOptions ?? { listen: true }
153
67
 
154
- return {
155
- enabled,
156
- path: this.configManager.dirname ?? dirname(this.configManager.fullPath),
157
- allow: config.watch?.allow,
158
- ignore: config.watch?.ignore
68
+ // Make this idempotent
69
+ if (this.url) {
70
+ return this.url
159
71
  }
160
- }
161
72
 
162
- async getDispatchFunc () {
163
- await this.init()
164
- return this.app
165
- }
166
-
167
- async getDispatchTarget () {
168
- return this.getUrl() ?? (await this.getDispatchFunc())
169
- }
73
+ // Create the application if needed
74
+ if (!this.#app) {
75
+ await this.init()
76
+ await this.#app.ready()
77
+ }
170
78
 
171
- async getOpenapiSchema () {
172
- await this.init()
173
- await this.app.ready()
174
- return this.app.swagger ? this.app.swagger() : null
175
- }
79
+ if (listen) {
80
+ await this._listen()
81
+ }
176
82
 
177
- async getGraphqlSchema () {
178
- await this.init()
179
- await this.app.ready()
180
- return this.app.graphql ? printSchema(this.app.graphql.schema) : null
83
+ await this._collectMetrics()
84
+ return this.url
181
85
  }
182
86
 
183
- setCustomHealthCheck (fn) {
184
- this.customHealthCheck = fn
87
+ async stop () {
88
+ return this.#app?.close()
185
89
  }
186
90
 
187
- async getCustomHealthCheck () {
188
- if (!this.customHealthCheck) {
189
- return true
190
- }
191
- return await this.customHealthCheck()
91
+ async build () {
92
+ return compile({
93
+ tsConfig: this.config.plugins?.typescript?.tsConfig,
94
+ flags: this.config.plugins?.typescript?.flags,
95
+ cwd: this.root,
96
+ logger: this.logger
97
+ })
192
98
  }
193
99
 
194
- setCustomReadinessCheck (fn) {
195
- this.customReadinessCheck = fn
196
- }
100
+ async inject (injectParams, onInject) {
101
+ const response = await this.#app.inject(injectParams, onInject)
197
102
 
198
- async getCustomReadinessCheck () {
199
- if (!this.customReadinessCheck) {
200
- return true
103
+ if (onInject) {
104
+ return
201
105
  }
202
- return await this.customReadinessCheck()
203
- }
204
106
 
205
- // This method is not a part of Stackable interface because we need to register
206
- // fastify metrics before the server is started.
207
- async #collectMetrics () {
208
- const metricsConfig = this.context.metricsConfig
209
-
210
- if (metricsConfig !== false) {
211
- await collectMetrics(
212
- this.serviceId,
213
- this.workerId,
214
- {
215
- defaultMetrics: true,
216
- httpMetrics: true,
217
- ...metricsConfig
218
- },
219
- this.metricsRegistry
220
- )
221
-
222
- this.#setHttpCacheMetrics()
223
- }
107
+ const { statusCode, statusMessage, headers, body } = response
108
+ return { statusCode, statusMessage, headers, body }
224
109
  }
225
110
 
226
- async getMetrics (opts) {
227
- const format = opts?.format
228
- return format === 'json' ? await this.metricsRegistry.getMetricsAsJSON() : await this.metricsRegistry.metrics()
111
+ getApplication () {
112
+ return this.#app
229
113
  }
230
114
 
231
- async inject (injectParams) {
115
+ async getDispatchFunc () {
232
116
  await this.init()
233
-
234
- const { statusCode, statusMessage, headers, body } = await this.app.inject(injectParams)
235
- return { statusCode, statusMessage, headers, body }
117
+ return this.#app
236
118
  }
237
119
 
238
- async log (options = {}) {
239
- await this.init()
120
+ async getConfig (includeMeta = false) {
121
+ let config = await super.getConfig(includeMeta)
122
+ const loggerInstance = this.serverConfig?.loggerInstance
240
123
 
241
- const logLevel = options.level ?? 'info'
242
-
243
- const message = options.message
244
- if (!message) return
124
+ if (loggerInstance) {
125
+ config = Object.assign({}, config)
126
+ const { loggerInstance: _, ...serverConfig } = this.serverConfig
127
+ config.server = { ...serverConfig, logger: { level: loggerInstance.level } }
128
+ }
245
129
 
246
- this.app.log[logLevel](message)
130
+ return config
247
131
  }
248
132
 
249
- async updateContext (context) {
250
- this.context = { ...this.context, ...context }
251
- this.#updateConfig()
252
- }
133
+ async getWatchConfig () {
134
+ const config = this.config
253
135
 
254
- setOpenapiSchema (schema) {
255
- this.openapiSchema = schema
256
- }
136
+ const enabled = config.watch?.enabled !== false && config.plugins !== undefined
257
137
 
258
- setGraphqlSchema (schema) {
259
- this.graphqlSchema = schema
260
- }
138
+ if (!enabled) {
139
+ return { enabled, path: this.root }
140
+ }
261
141
 
262
- setConnectionString (connectionString) {
263
- this.connectionString = connectionString
142
+ return {
143
+ enabled,
144
+ path: this.root,
145
+ allow: config.watch?.allow,
146
+ ignore: config.watch?.ignore
147
+ }
264
148
  }
265
149
 
266
- setBasePath (basePath) {
267
- this.basePath = basePath
150
+ getMeta () {
151
+ return {
152
+ composer: {
153
+ tcp: typeof this.url !== 'undefined',
154
+ url: this.url,
155
+ prefix: this.basePath ?? this.#basePath,
156
+ wantsAbsoluteUrls: false,
157
+ needsRootTrailingSlash: false
158
+ },
159
+ connectionStrings: [this.connectionString]
160
+ }
268
161
  }
269
162
 
270
- registerGlobals (globals) {
271
- globalThis.platformatic = Object.assign(globalThis.platformatic ?? {}, globals)
163
+ async getOpenapiSchema () {
164
+ await this.init()
165
+ await this.#app.ready()
166
+ return this.#app.swagger ? this.#app.swagger() : null
272
167
  }
273
168
 
274
- async #invalidateHttpCache (opts = {}) {
275
- await globalThis[kITC].send('invalidateHttpCache', opts)
169
+ async getGraphqlSchema () {
170
+ await this.init()
171
+ await this.#app.ready()
172
+ return this.#app.graphql ? printSchema(this.#app.graphql.schema) : null
276
173
  }
277
174
 
278
- #setHttpCacheMetrics () {
279
- const { client, registry } = globalThis.platformatic.prometheus
280
-
281
- const cacheHitMetric = new client.Counter({
282
- name: 'http_cache_hit_count',
283
- help: 'Number of http cache hits',
284
- registers: [registry]
285
- })
286
-
287
- const cacheMissMetric = new client.Counter({
288
- name: 'http_cache_miss_count',
289
- help: 'Number of http cache misses',
290
- registers: [registry]
291
- })
292
-
293
- globalThis.platformatic.onHttpCacheHit = () => {
294
- cacheHitMetric.inc()
295
- }
296
- globalThis.platformatic.onHttpCacheMiss = () => {
297
- cacheMissMetric.inc()
298
- }
299
-
300
- const httpStatsFreeMetric = new client.Gauge({
301
- name: 'http_client_stats_free',
302
- help: 'Number of free (idle) http clients (sockets)',
303
- labelNames: ['dispatcher_stats_url'],
304
- registers: [registry]
305
- })
306
- globalThis.platformatic.onHttpStatsFree = (url, val) => {
307
- httpStatsFreeMetric.set({ dispatcher_stats_url: url }, val)
308
- }
309
-
310
- const httpStatsConnectedMetric = new client.Gauge({
311
- name: 'http_client_stats_connected',
312
- help: 'Number of open socket connections',
313
- labelNames: ['dispatcher_stats_url'],
314
- registers: [registry]
315
- })
316
- globalThis.platformatic.onHttpStatsConnected = (url, val) => {
317
- httpStatsConnectedMetric.set({ dispatcher_stats_url: url }, val)
318
- }
319
-
320
- const httpStatsPendingMetric = new client.Gauge({
321
- name: 'http_client_stats_pending',
322
- help: 'Number of pending requests across all clients',
323
- labelNames: ['dispatcher_stats_url'],
324
- registers: [registry]
325
- })
326
- globalThis.platformatic.onHttpStatsPending = (url, val) => {
327
- httpStatsPendingMetric.set({ dispatcher_stats_url: url }, val)
328
- }
329
-
330
- const httpStatsQueuedMetric = new client.Gauge({
331
- name: 'http_client_stats_queued',
332
- help: 'Number of queued requests across all clients',
333
- labelNames: ['dispatcher_stats_url'],
334
- registers: [registry]
335
- })
336
- globalThis.platformatic.onHttpStatsQueued = (url, val) => {
337
- httpStatsQueuedMetric.set({ dispatcher_stats_url: url }, val)
338
- }
175
+ async updateContext (context) {
176
+ super.updateContext(context)
339
177
 
340
- const httpStatsRunningMetric = new client.Gauge({
341
- name: 'http_client_stats_running',
342
- help: 'Number of currently active requests across all clients',
343
- labelNames: ['dispatcher_stats_url'],
344
- registers: [registry]
345
- })
346
- globalThis.platformatic.onHttpStatsRunning = (url, val) => {
347
- httpStatsRunningMetric.set({ dispatcher_stats_url: url }, val)
348
- }
178
+ this.context = { ...this.context, ...context }
349
179
 
350
- const httpStatsSizeMetric = new client.Gauge({
351
- name: 'http_client_stats_size',
352
- help: 'Number of active, pending, or queued requests across all clients',
353
- labelNames: ['dispatcher_stats_url'],
354
- registers: [registry]
355
- })
356
- globalThis.platformatic.onHttpStatsSize = (url, val) => {
357
- httpStatsSizeMetric.set({ dispatcher_stats_url: url }, val)
180
+ if (!this.context) {
181
+ return
358
182
  }
359
- }
360
-
361
- #updateConfig () {
362
- if (!this.context) return
363
183
 
364
- const { serviceId, telemetryConfig, metricsConfig, serverConfig, hasManagementApi, isEntrypoint, isProduction } =
365
- this.context
184
+ const { telemetryConfig, serverConfig, isEntrypoint, isProduction, logger } = this.context
366
185
 
367
- const config = this.configManager.current
186
+ const config = { ...this.config }
368
187
 
369
188
  if (telemetryConfig) {
370
189
  config.telemetry = telemetryConfig
371
190
  }
372
- if (metricsConfig) {
373
- config.metrics = metricsConfig
374
- }
191
+
192
+ const loggerInstance = logger ?? serverConfig?.loggerInstance ?? this.serverConfig?.loggerInstance
193
+
375
194
  if (serverConfig) {
376
- config.server = deepmerge(config.server ?? {}, serverConfig ?? {})
195
+ config.server = deepmerge(this.serverConfig, serverConfig ?? {})
377
196
  }
378
197
 
379
- if ((hasManagementApi && config.metrics === undefined) || config.metrics) {
380
- const labels = config.metrics?.labels || {}
381
- config.metrics = {
382
- server: 'hide',
383
- defaultMetrics: { enabled: isEntrypoint },
384
- ...config.metrics,
385
- labels: { serviceId, ...labels }
198
+ config.server ??= {}
199
+
200
+ if (isProduction) {
201
+ if (config.plugins) {
202
+ config.plugins.typescript = false
386
203
  }
204
+ config.watch = { enabled: false }
387
205
  }
388
206
 
207
+ // Adjust server options
389
208
  if (!isEntrypoint) {
390
- config.server = config.server ?? {}
391
209
  config.server.trustProxy = true
392
210
  }
393
211
 
394
- if (isProduction) {
395
- if (config.plugins) {
396
- config.plugins.typescript = false
397
- }
398
- config.watch = { enabled: false }
212
+ if (config.server.https) {
213
+ config.server.https.key = await sanitizeHTTPSArgument(config.server.https.key)
214
+ config.server.https.cert = await sanitizeHTTPSArgument(config.server.https.cert)
215
+ }
216
+
217
+ // Assign the logger instance if it exists
218
+ if (loggerInstance) {
219
+ config.server = { ...config.server }
220
+ config.server.loggerInstance = loggerInstance
221
+ delete config.server.logger
399
222
  }
400
223
 
401
- this.configManager.update(config)
224
+ this.serverConfig = config.server
225
+ this.config = config
402
226
  }
403
227
 
404
- #initLogger () {
405
- if (this.configManager.current.server?.loggerInstance) {
406
- this.logger = this.configManager.current.server?.loggerInstance
407
- return
228
+ _initializeLogger () {
229
+ if (this.context?.logger) {
230
+ return this.context.logger
231
+ } else if (this.config.server?.loggerInstance) {
232
+ return this.config.server?.loggerInstance
408
233
  }
409
234
 
410
- this.configManager.current.server ??= {}
411
- this.loggerConfig = deepmerge(this.context.loggerConfig ?? {}, this.configManager.current.server?.logger ?? {})
235
+ this.serverConfig ??= {}
236
+ this.loggerConfig = deepmerge(this.context.loggerConfig ?? {}, this.serverConfig?.logger ?? {})
412
237
 
413
238
  const pinoOptions = {
414
239
  ...(this.loggerConfig ?? {}),
@@ -436,12 +261,30 @@ class ServiceStackable {
436
261
  pinoOptions.timestamp = buildPinoTimestamp(this.loggerConfig?.timestamp)
437
262
  }
438
263
 
439
- this.logger = pino(pinoOptions)
264
+ const logger = pino(pinoOptions)
440
265
 
441
266
  // Only one of logger and loggerInstance should be set
442
- delete this.configManager.current.server.logger
443
- this.configManager.current.server.loggerInstance = this.logger
267
+ this.serverConfig.loggerInstance = logger
268
+ delete this.serverConfig.logger
269
+
270
+ return logger
444
271
  }
445
- }
446
272
 
447
- module.exports = { ServiceStackable }
273
+ async _listen () {
274
+ const serverOptions = this.serverConfig
275
+ const listenOptions = { host: serverOptions?.hostname || '127.0.0.1', port: serverOptions?.port || 0 }
276
+
277
+ if (this.isProduction && features.node.reusePort) {
278
+ listenOptions.reusePort = true
279
+ }
280
+
281
+ await this.#app.listen(listenOptions)
282
+ this.url = getServerUrl(this.#app.server)
283
+
284
+ if (this.serverConfig.http2 || this.serverConfig.https?.key) {
285
+ this.url = this.url.replace('http://', 'https://')
286
+ }
287
+
288
+ return this.url
289
+ }
290
+ }
package/lib/upgrade.js CHANGED
@@ -1,15 +1,13 @@
1
- 'use strict'
2
-
3
- const { join } = require('path')
4
-
5
- module.exports = async function upgrade (config, version) {
6
- const { semgrator } = await import('semgrator')
1
+ import { abstractLogger } from '@platformatic/utils'
2
+ import { resolve } from 'node:path'
3
+ import { semgrator } from 'semgrator'
7
4
 
5
+ export async function upgrade (logger, config, version) {
8
6
  const iterator = semgrator({
9
7
  version,
10
- path: join(__dirname, 'versions'),
8
+ path: resolve(import.meta.dirname, 'versions'),
11
9
  input: config,
12
- logger: this.logger.child({ name: '@platformatic/service' }),
10
+ logger: logger?.child({ name: '@platformatic/service' }) ?? abstractLogger
13
11
  })
14
12
 
15
13
  let result