@platformatic/service 2.74.3 → 3.0.0-alpha.2
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/config.d.ts +2 -30
- package/eslint.config.js +4 -6
- package/index.d.ts +55 -47
- package/index.js +44 -199
- package/lib/application.js +35 -0
- package/lib/compile.js +1 -52
- package/lib/generator.js +424 -0
- package/lib/plugins/cors.js +5 -8
- package/lib/plugins/graphql.js +16 -14
- package/lib/plugins/health-check.js +6 -8
- package/lib/plugins/openapi.js +40 -31
- package/lib/plugins/plugins.js +6 -53
- package/lib/{root-endpoint/index.js → plugins/root.js} +9 -8
- package/lib/plugins/sandbox-wrapper.js +62 -55
- package/lib/schema.js +1028 -203
- package/lib/stackable.js +171 -338
- package/lib/upgrade.js +6 -8
- package/lib/utils.js +30 -93
- package/lib/versions/0.16.0.js +14 -15
- package/lib/versions/{from-zero-twenty-eight-to-will-see.js → 0.28.0.js} +3 -6
- package/lib/versions/2.0.0.js +4 -7
- package/lib/versions/3.0.0.js +14 -0
- package/package.json +18 -25
- package/schema.json +10 -155
- package/tsconfig.json +16 -6
- package/.c8rc +0 -6
- package/help/compile.txt +0 -19
- package/help/create.txt +0 -11
- package/help/help.txt +0 -8
- package/help/schema.txt +0 -9
- package/help/start.txt +0 -23
- package/index.test-d.ts +0 -107
- package/lib/create.mjs +0 -85
- package/lib/gen-schema.js +0 -15
- package/lib/gen-types.mjs +0 -38
- package/lib/generator/README.md +0 -31
- package/lib/generator/service-generator.d.ts +0 -11
- package/lib/generator/service-generator.js +0 -126
- package/lib/openapi-schema-defs.js +0 -1108
- package/lib/plugins/clients.js +0 -16
- package/lib/plugins/metrics.js +0 -244
- package/lib/plugins/typescript.js +0 -20
- package/lib/start.js +0 -190
- package/service.mjs +0 -71
- /package/{lib/root-endpoint/public → public}/images/dark_mode.svg +0 -0
- /package/{lib/root-endpoint/public → public}/images/favicon.ico +0 -0
- /package/{lib/root-endpoint/public → public}/images/light_mode.svg +0 -0
- /package/{lib/root-endpoint/public → public}/images/platformatic-logo-dark.svg +0 -0
- /package/{lib/root-endpoint/public → public}/images/platformatic-logo-light.svg +0 -0
- /package/{lib/root-endpoint/public → public}/images/triangle_dark.svg +0 -0
- /package/{lib/root-endpoint/public → public}/images/triangle_light.svg +0 -0
- /package/{lib/root-endpoint/public → public}/index.html +0 -0
package/lib/stackable.js
CHANGED
|
@@ -1,414 +1,229 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
this.
|
|
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 { buildPinoFormatters, buildPinoTimestamp, deepmerge, features, isKeyEnabled } from '@platformatic/foundation'
|
|
3
|
+
import { telemetry } from '@platformatic/telemetry'
|
|
4
|
+
import fastify from 'fastify'
|
|
5
|
+
import { printSchema } from 'graphql'
|
|
6
|
+
import { randomUUID } from 'node:crypto'
|
|
7
|
+
import { hostname } from 'node:os'
|
|
8
|
+
import pino from 'pino'
|
|
9
|
+
import { platformaticService } from './application.js'
|
|
10
|
+
import { setupRoot } from './plugins/root.js'
|
|
11
|
+
import { version } from './schema.js'
|
|
12
|
+
import { sanitizeHTTPSArgument } from './utils.js'
|
|
13
|
+
|
|
14
|
+
export class ServiceStackable extends BaseStackable {
|
|
15
|
+
#app
|
|
16
|
+
#basePath
|
|
17
|
+
|
|
18
|
+
constructor (root, config, context) {
|
|
19
|
+
super('service', version, root, config, context)
|
|
20
|
+
this.applicationFactory = this.context.applicationFactory ?? platformaticService
|
|
61
21
|
}
|
|
62
22
|
|
|
63
23
|
async init () {
|
|
64
|
-
|
|
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()
|
|
24
|
+
await super.init()
|
|
75
25
|
|
|
76
|
-
if (
|
|
77
|
-
await this.app.ready()
|
|
26
|
+
if (this.#app) {
|
|
78
27
|
return
|
|
79
28
|
}
|
|
80
|
-
await this.app.start()
|
|
81
|
-
}
|
|
82
29
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
await this.app.close()
|
|
86
|
-
}
|
|
30
|
+
const config = this.config
|
|
31
|
+
this.#basePath = ensureTrailingSlash(cleanBasePath(config.basePath ?? this.serviceId))
|
|
87
32
|
|
|
88
|
-
|
|
89
|
-
this.#
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
33
|
+
// Create the application
|
|
34
|
+
this.#app = fastify({
|
|
35
|
+
...this.serverConfig,
|
|
36
|
+
...this.fastifyOptions,
|
|
37
|
+
genReqId () {
|
|
38
|
+
return randomUUID()
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// This must be done before loading the plugins, so they can inspect if the
|
|
43
|
+
// openTelemetry decorator exists and then configure accordingly.
|
|
44
|
+
if (isKeyEnabled('telemetry', config)) {
|
|
45
|
+
await this.#app.register(telemetry, config.telemetry)
|
|
96
46
|
}
|
|
97
47
|
|
|
98
|
-
|
|
99
|
-
}
|
|
48
|
+
this.#app.decorate('platformatic', { config: this.config })
|
|
100
49
|
|
|
101
|
-
|
|
102
|
-
return this.app !== null ? this.app.url : null
|
|
103
|
-
}
|
|
50
|
+
await this.#app.register(this.applicationFactory, this)
|
|
104
51
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
52
|
+
if (Array.isArray(this.context.fastifyPlugins)) {
|
|
53
|
+
for (const plugin of this.context.fastifyPlugins) {
|
|
54
|
+
await this.#app.register(plugin)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
110
57
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
58
|
+
if (!this.#app.hasRoute({ url: '/', method: 'GET' }) && !this.#app.hasRoute({ url: '/*', method: 'GET' })) {
|
|
59
|
+
await this.#app.register(setupRoot)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
114
62
|
|
|
115
|
-
|
|
63
|
+
async start (startOptions) {
|
|
64
|
+
// Compatibility with v2 service
|
|
65
|
+
const { listen } = startOptions ?? { listen: true }
|
|
116
66
|
|
|
117
|
-
|
|
118
|
-
|
|
67
|
+
// Make this idempotent
|
|
68
|
+
if (this.url) {
|
|
69
|
+
return this.url
|
|
70
|
+
}
|
|
119
71
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
72
|
+
// Create the application if needed
|
|
73
|
+
if (!this.#app) {
|
|
74
|
+
await this.init()
|
|
75
|
+
await this.#app.ready()
|
|
123
76
|
}
|
|
124
77
|
|
|
125
|
-
|
|
78
|
+
if (listen) {
|
|
79
|
+
await this._listen()
|
|
80
|
+
}
|
|
126
81
|
|
|
127
|
-
|
|
82
|
+
await this._collectMetrics()
|
|
83
|
+
return this.url
|
|
128
84
|
}
|
|
129
85
|
|
|
130
|
-
async
|
|
131
|
-
return this
|
|
86
|
+
async stop () {
|
|
87
|
+
return this.#app?.close()
|
|
132
88
|
}
|
|
133
89
|
|
|
134
|
-
|
|
135
|
-
const
|
|
90
|
+
async inject (injectParams, onInject) {
|
|
91
|
+
const response = await this.#app.inject(injectParams, onInject)
|
|
136
92
|
|
|
137
|
-
|
|
138
|
-
|
|
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]
|
|
93
|
+
if (onInject) {
|
|
94
|
+
return
|
|
146
95
|
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
async getWatchConfig () {
|
|
150
|
-
const config = this.configManager.current
|
|
151
96
|
|
|
152
|
-
const
|
|
97
|
+
const { statusCode, statusMessage, headers, body } = response
|
|
98
|
+
return { statusCode, statusMessage, headers, body }
|
|
99
|
+
}
|
|
153
100
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
path: this.configManager.dirname ?? dirname(this.configManager.fullPath),
|
|
157
|
-
allow: config.watch?.allow,
|
|
158
|
-
ignore: config.watch?.ignore
|
|
159
|
-
}
|
|
101
|
+
getApplication () {
|
|
102
|
+
return this.#app
|
|
160
103
|
}
|
|
161
104
|
|
|
162
105
|
async getDispatchFunc () {
|
|
163
106
|
await this.init()
|
|
164
|
-
return this
|
|
107
|
+
return this.#app
|
|
165
108
|
}
|
|
166
109
|
|
|
167
|
-
async
|
|
168
|
-
|
|
169
|
-
|
|
110
|
+
async getConfig (includeMeta = false) {
|
|
111
|
+
let config = await super.getConfig(includeMeta)
|
|
112
|
+
const loggerInstance = this.serverConfig?.loggerInstance
|
|
170
113
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
async getGraphqlSchema () {
|
|
178
|
-
await this.init()
|
|
179
|
-
await this.app.ready()
|
|
180
|
-
return this.app.graphql ? printSchema(this.app.graphql.schema) : null
|
|
181
|
-
}
|
|
114
|
+
if (loggerInstance) {
|
|
115
|
+
config = Object.assign({}, config)
|
|
116
|
+
const { loggerInstance: _, ...serverConfig } = this.serverConfig
|
|
117
|
+
config.server = { ...serverConfig, logger: { level: loggerInstance.level } }
|
|
118
|
+
}
|
|
182
119
|
|
|
183
|
-
|
|
184
|
-
this.customHealthCheck = fn
|
|
120
|
+
return config
|
|
185
121
|
}
|
|
186
122
|
|
|
187
|
-
async
|
|
188
|
-
|
|
189
|
-
return true
|
|
190
|
-
}
|
|
191
|
-
return await this.customHealthCheck()
|
|
192
|
-
}
|
|
123
|
+
async getWatchConfig () {
|
|
124
|
+
const config = this.config
|
|
193
125
|
|
|
194
|
-
|
|
195
|
-
this.customReadinessCheck = fn
|
|
196
|
-
}
|
|
126
|
+
const enabled = config.watch?.enabled !== false && config.plugins !== undefined
|
|
197
127
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
return true
|
|
128
|
+
if (!enabled) {
|
|
129
|
+
return { enabled, path: this.root }
|
|
201
130
|
}
|
|
202
|
-
return await this.customReadinessCheck()
|
|
203
|
-
}
|
|
204
131
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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()
|
|
132
|
+
return {
|
|
133
|
+
enabled,
|
|
134
|
+
path: this.root,
|
|
135
|
+
allow: config.watch?.allow,
|
|
136
|
+
ignore: config.watch?.ignore
|
|
223
137
|
}
|
|
224
138
|
}
|
|
225
139
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
140
|
+
getMeta () {
|
|
141
|
+
return {
|
|
142
|
+
composer: {
|
|
143
|
+
tcp: typeof this.url !== 'undefined',
|
|
144
|
+
url: this.url,
|
|
145
|
+
prefix: this.basePath ?? this.#basePath,
|
|
146
|
+
wantsAbsoluteUrls: false,
|
|
147
|
+
needsRootTrailingSlash: false
|
|
148
|
+
},
|
|
149
|
+
connectionStrings: [this.connectionString]
|
|
150
|
+
}
|
|
229
151
|
}
|
|
230
152
|
|
|
231
|
-
async
|
|
153
|
+
async getOpenapiSchema () {
|
|
232
154
|
await this.init()
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
return { statusCode, statusMessage, headers, body }
|
|
155
|
+
await this.#app.ready()
|
|
156
|
+
return this.#app.swagger ? this.#app.swagger() : null
|
|
236
157
|
}
|
|
237
158
|
|
|
238
|
-
async
|
|
159
|
+
async getGraphqlSchema () {
|
|
239
160
|
await this.init()
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const message = options.message
|
|
244
|
-
if (!message) return
|
|
245
|
-
|
|
246
|
-
this.app.log[logLevel](message)
|
|
161
|
+
await this.#app.ready()
|
|
162
|
+
return this.#app.graphql ? printSchema(this.#app.graphql.schema) : null
|
|
247
163
|
}
|
|
248
164
|
|
|
249
165
|
async updateContext (context) {
|
|
250
|
-
|
|
251
|
-
this.#updateConfig()
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
setOpenapiSchema (schema) {
|
|
255
|
-
this.openapiSchema = schema
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
setGraphqlSchema (schema) {
|
|
259
|
-
this.graphqlSchema = schema
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
setConnectionString (connectionString) {
|
|
263
|
-
this.connectionString = connectionString
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
setBasePath (basePath) {
|
|
267
|
-
this.basePath = basePath
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
registerGlobals (globals) {
|
|
271
|
-
globalThis.platformatic = Object.assign(globalThis.platformatic ?? {}, globals)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
async #invalidateHttpCache (opts = {}) {
|
|
275
|
-
await globalThis[kITC].send('invalidateHttpCache', opts)
|
|
276
|
-
}
|
|
277
|
-
|
|
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
|
-
}
|
|
166
|
+
super.updateContext(context)
|
|
329
167
|
|
|
330
|
-
|
|
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
|
-
}
|
|
339
|
-
|
|
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
|
-
}
|
|
168
|
+
this.context = { ...this.context, ...context }
|
|
349
169
|
|
|
350
|
-
|
|
351
|
-
|
|
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)
|
|
170
|
+
if (!this.context) {
|
|
171
|
+
return
|
|
358
172
|
}
|
|
359
|
-
}
|
|
360
173
|
|
|
361
|
-
|
|
362
|
-
if (!this.context) return
|
|
174
|
+
const { telemetryConfig, serverConfig, isEntrypoint, isProduction, logger } = this.context
|
|
363
175
|
|
|
364
|
-
const
|
|
365
|
-
this.context
|
|
366
|
-
|
|
367
|
-
const config = this.configManager.current
|
|
176
|
+
const config = { ...this.config }
|
|
368
177
|
|
|
369
178
|
if (telemetryConfig) {
|
|
370
179
|
config.telemetry = telemetryConfig
|
|
371
180
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
181
|
+
|
|
182
|
+
const loggerInstance = logger ?? serverConfig?.loggerInstance ?? this.serverConfig?.loggerInstance
|
|
183
|
+
|
|
375
184
|
if (serverConfig) {
|
|
376
|
-
config.server = deepmerge(
|
|
185
|
+
config.server = deepmerge(this.serverConfig, serverConfig ?? {})
|
|
377
186
|
}
|
|
378
187
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
...config.metrics,
|
|
385
|
-
labels: { serviceId, ...labels }
|
|
188
|
+
config.server ??= {}
|
|
189
|
+
|
|
190
|
+
if (isProduction) {
|
|
191
|
+
if (config.plugins) {
|
|
192
|
+
config.plugins.typescript = false
|
|
386
193
|
}
|
|
194
|
+
config.watch = { enabled: false }
|
|
387
195
|
}
|
|
388
196
|
|
|
197
|
+
// Adjust server options
|
|
389
198
|
if (!isEntrypoint) {
|
|
390
|
-
config.server = config.server ?? {}
|
|
391
199
|
config.server.trustProxy = true
|
|
392
200
|
}
|
|
393
201
|
|
|
394
|
-
if (
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}
|
|
398
|
-
config.watch = { enabled: false }
|
|
202
|
+
if (config.server.https) {
|
|
203
|
+
config.server.https.key = await sanitizeHTTPSArgument(config.server.https.key)
|
|
204
|
+
config.server.https.cert = await sanitizeHTTPSArgument(config.server.https.cert)
|
|
399
205
|
}
|
|
400
206
|
|
|
401
|
-
|
|
207
|
+
// Assign the logger instance if it exists
|
|
208
|
+
if (loggerInstance) {
|
|
209
|
+
config.server = { ...config.server }
|
|
210
|
+
config.server.loggerInstance = loggerInstance
|
|
211
|
+
delete config.server.logger
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
this.serverConfig = config.server
|
|
215
|
+
this.config = config
|
|
402
216
|
}
|
|
403
217
|
|
|
404
|
-
|
|
405
|
-
if (this.
|
|
406
|
-
|
|
407
|
-
|
|
218
|
+
_initializeLogger () {
|
|
219
|
+
if (this.context?.logger) {
|
|
220
|
+
return this.context.logger
|
|
221
|
+
} else if (this.config.server?.loggerInstance) {
|
|
222
|
+
return this.config.server?.loggerInstance
|
|
408
223
|
}
|
|
409
224
|
|
|
410
|
-
this.
|
|
411
|
-
this.loggerConfig = deepmerge(this.context.loggerConfig ?? {}, this.
|
|
225
|
+
this.serverConfig ??= {}
|
|
226
|
+
this.loggerConfig = deepmerge(this.context.loggerConfig ?? {}, this.serverConfig?.logger ?? {})
|
|
412
227
|
|
|
413
228
|
const pinoOptions = {
|
|
414
229
|
...(this.loggerConfig ?? {}),
|
|
@@ -436,12 +251,30 @@ class ServiceStackable {
|
|
|
436
251
|
pinoOptions.timestamp = buildPinoTimestamp(this.loggerConfig?.timestamp)
|
|
437
252
|
}
|
|
438
253
|
|
|
439
|
-
|
|
254
|
+
const logger = pino(pinoOptions)
|
|
440
255
|
|
|
441
256
|
// Only one of logger and loggerInstance should be set
|
|
442
|
-
|
|
443
|
-
this.
|
|
257
|
+
this.serverConfig.loggerInstance = logger
|
|
258
|
+
delete this.serverConfig.logger
|
|
259
|
+
|
|
260
|
+
return logger
|
|
444
261
|
}
|
|
445
|
-
}
|
|
446
262
|
|
|
447
|
-
|
|
263
|
+
async _listen () {
|
|
264
|
+
const serverOptions = this.serverConfig
|
|
265
|
+
const listenOptions = { host: serverOptions?.hostname || '127.0.0.1', port: serverOptions?.port || 0 }
|
|
266
|
+
|
|
267
|
+
if (this.isProduction && features.node.reusePort) {
|
|
268
|
+
listenOptions.reusePort = true
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
await this.#app.listen(listenOptions)
|
|
272
|
+
this.url = getServerUrl(this.#app.server)
|
|
273
|
+
|
|
274
|
+
if (this.serverConfig.http2 || this.serverConfig.https?.key) {
|
|
275
|
+
this.url = this.url.replace('http://', 'https://')
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return this.url
|
|
279
|
+
}
|
|
280
|
+
}
|
package/lib/upgrade.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
module.exports = async function upgrade (config, version) {
|
|
6
|
-
const { semgrator } = await import('semgrator')
|
|
1
|
+
import { abstractLogger } from '@platformatic/foundation'
|
|
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:
|
|
8
|
+
path: resolve(import.meta.dirname, 'versions'),
|
|
11
9
|
input: config,
|
|
12
|
-
logger:
|
|
10
|
+
logger: logger?.child({ name: '@platformatic/service' }) ?? abstractLogger
|
|
13
11
|
})
|
|
14
12
|
|
|
15
13
|
let result
|