@platformatic/runtime 1.23.0 → 1.24.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/fixtures/configs/monorepo-hotreload.json +27 -0
- package/fixtures/management-api/package.json +4 -0
- package/fixtures/management-api/platformatic.json +10 -0
- package/fixtures/management-api/services/service-1/platformatic.json +21 -0
- package/fixtures/management-api/services/service-1/plugin.js +8 -0
- package/fixtures/management-api/services/service-2/platformatic.json +13 -0
- package/fixtures/management-api/services/service-2/plugin.js +8 -0
- package/lib/api-client.js +21 -5
- package/lib/api.js +36 -3
- package/lib/app.js +4 -1
- package/lib/management-api.js +124 -26
- package/lib/start.js +19 -39
- package/lib/worker.js +12 -10
- package/package.json +13 -10
- package/runtime.mjs +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://platformatic.dev/schemas/v0.20.0/runtime",
|
|
3
|
+
"entrypoint": "serviceApp",
|
|
4
|
+
"allowCycles": true,
|
|
5
|
+
"hotReload": true,
|
|
6
|
+
"autoload": {
|
|
7
|
+
"path": "../monorepo",
|
|
8
|
+
"exclude": [
|
|
9
|
+
"docs",
|
|
10
|
+
"composerApp"
|
|
11
|
+
],
|
|
12
|
+
"mappings": {
|
|
13
|
+
"serviceAppWithLogger": {
|
|
14
|
+
"id": "with-logger",
|
|
15
|
+
"config": "platformatic.service.json"
|
|
16
|
+
},
|
|
17
|
+
"serviceAppWithMultiplePlugins": {
|
|
18
|
+
"id": "multi-plugin-service",
|
|
19
|
+
"config": "platformatic.service.json"
|
|
20
|
+
},
|
|
21
|
+
"dbApp": {
|
|
22
|
+
"id": "db-app",
|
|
23
|
+
"config": "platformatic.db.json"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://platformatic.dev/schemas/v1.22.0/service",
|
|
3
|
+
"server": {
|
|
4
|
+
"hostname": "127.0.0.1",
|
|
5
|
+
"port": 0,
|
|
6
|
+
"logger": {
|
|
7
|
+
"name": "service-with-logger",
|
|
8
|
+
"level": "trace"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"service": {
|
|
12
|
+
"openapi": true
|
|
13
|
+
},
|
|
14
|
+
"plugins": {
|
|
15
|
+
"paths": ["plugin.js"]
|
|
16
|
+
},
|
|
17
|
+
"watch": true,
|
|
18
|
+
"metrics": {
|
|
19
|
+
"server": "parent"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/lib/api-client.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { once, EventEmitter } = require('node:events')
|
|
4
4
|
const { randomUUID } = require('node:crypto')
|
|
5
5
|
const errors = require('./errors')
|
|
6
|
+
const { setTimeout: sleep } = require('node:timers/promises')
|
|
6
7
|
|
|
7
8
|
const MAX_LISTENERS_COUNT = 100
|
|
8
9
|
|
|
@@ -27,21 +28,36 @@ class RuntimeApiClient extends EventEmitter {
|
|
|
27
28
|
return this.#sendCommand('plt:start-services')
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
async stop () {
|
|
31
|
-
await this.#sendCommand('plt:stop-services')
|
|
32
|
-
}
|
|
33
|
-
|
|
34
31
|
async close () {
|
|
35
32
|
await this.#sendCommand('plt:stop-services')
|
|
36
33
|
|
|
37
34
|
this.worker.postMessage({ command: 'plt:close' })
|
|
38
|
-
await
|
|
35
|
+
const res = await Promise.race([
|
|
36
|
+
this.#exitPromise,
|
|
37
|
+
// We must kill the worker if it doesn't exit in 10 seconds
|
|
38
|
+
// because it may be stuck in an infinite loop.
|
|
39
|
+
// This is a workaround for
|
|
40
|
+
// https://github.com/nodejs/node/issues/47748
|
|
41
|
+
// https://github.com/nodejs/node/issues/49344
|
|
42
|
+
// Remove once https://github.com/nodejs/node/pull/51290 is released
|
|
43
|
+
// on all lines.
|
|
44
|
+
// Likely to be removed when we drop support for Node.js 18.
|
|
45
|
+
sleep(10000, 'timeout', { ref: false })
|
|
46
|
+
])
|
|
47
|
+
|
|
48
|
+
if (res === 'timeout') {
|
|
49
|
+
this.worker.unref()
|
|
50
|
+
}
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
async restart () {
|
|
42
54
|
return this.#sendCommand('plt:restart-services')
|
|
43
55
|
}
|
|
44
56
|
|
|
57
|
+
async getEntrypointDetails () {
|
|
58
|
+
return this.#sendCommand('plt:get-entrypoint-details')
|
|
59
|
+
}
|
|
60
|
+
|
|
45
61
|
async getServices () {
|
|
46
62
|
return this.#sendCommand('plt:get-services')
|
|
47
63
|
}
|
package/lib/api.js
CHANGED
|
@@ -9,9 +9,11 @@ const { printSchema } = require('graphql')
|
|
|
9
9
|
class RuntimeApi {
|
|
10
10
|
#services
|
|
11
11
|
#dispatcher
|
|
12
|
+
#logger
|
|
12
13
|
|
|
13
14
|
constructor (config, logger, loaderPort) {
|
|
14
15
|
this.#services = new Map()
|
|
16
|
+
this.#logger = logger
|
|
15
17
|
const telemetryConfig = config.telemetry
|
|
16
18
|
|
|
17
19
|
for (let i = 0; i < config.services.length; ++i) {
|
|
@@ -48,8 +50,21 @@ class RuntimeApi {
|
|
|
48
50
|
const command = message?.command
|
|
49
51
|
if (command) {
|
|
50
52
|
if (command === 'plt:close') {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
// We close everything because they might be using
|
|
54
|
+
// a FinalizationRegistry and it may stuck us in an infinite loop.
|
|
55
|
+
// This is a workaround for
|
|
56
|
+
// https://github.com/nodejs/node/issues/47748
|
|
57
|
+
// https://github.com/nodejs/node/issues/49344
|
|
58
|
+
// Remove once https://github.com/nodejs/node/pull/51290 is released
|
|
59
|
+
// on all lines.
|
|
60
|
+
// Likely to be removed when we drop support for Node.js 18.
|
|
61
|
+
if (this.#dispatcher) {
|
|
62
|
+
await this.#dispatcher.close()
|
|
63
|
+
}
|
|
64
|
+
await this.stopServices()
|
|
65
|
+
|
|
66
|
+
setImmediate(process.exit) // Exit the worker thread.
|
|
67
|
+
return
|
|
53
68
|
}
|
|
54
69
|
|
|
55
70
|
const res = await this.#executeCommand(message)
|
|
@@ -97,6 +112,8 @@ class RuntimeApi {
|
|
|
97
112
|
return this.stopServices(params)
|
|
98
113
|
case 'plt:restart-services':
|
|
99
114
|
return this.#restartServices(params)
|
|
115
|
+
case 'plt:get-entrypoint-details':
|
|
116
|
+
return this.#getEntrypointDetails(params)
|
|
100
117
|
case 'plt:get-services':
|
|
101
118
|
return this.#getServices(params)
|
|
102
119
|
case 'plt:get-service-details':
|
|
@@ -162,6 +179,15 @@ class RuntimeApi {
|
|
|
162
179
|
return entrypointUrl
|
|
163
180
|
}
|
|
164
181
|
|
|
182
|
+
#getEntrypointDetails () {
|
|
183
|
+
for (const service of this.#services.values()) {
|
|
184
|
+
if (service.appConfig.entrypoint) {
|
|
185
|
+
return this.#getServiceDetails({ id: service.appConfig.id })
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return null
|
|
189
|
+
}
|
|
190
|
+
|
|
165
191
|
#getServices () {
|
|
166
192
|
const services = { services: [] }
|
|
167
193
|
|
|
@@ -191,8 +217,15 @@ class RuntimeApi {
|
|
|
191
217
|
const service = this.#getServiceById(id)
|
|
192
218
|
const status = service.getStatus()
|
|
193
219
|
|
|
220
|
+
const type = service.config.configType
|
|
194
221
|
const { entrypoint, dependencies, localUrl } = service.appConfig
|
|
195
|
-
|
|
222
|
+
const serviceDetails = { id, type, status, localUrl, entrypoint, dependencies }
|
|
223
|
+
|
|
224
|
+
if (entrypoint) {
|
|
225
|
+
serviceDetails.url = status === 'started' ? service.server.url : null
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return serviceDetails
|
|
196
229
|
}
|
|
197
230
|
|
|
198
231
|
#getServiceConfig ({ id }) {
|
package/lib/app.js
CHANGED
|
@@ -73,7 +73,10 @@ class PlatformaticApp {
|
|
|
73
73
|
this.#setuplogger(this.config.configManager)
|
|
74
74
|
await this.server.restart()
|
|
75
75
|
} catch (err) {
|
|
76
|
-
|
|
76
|
+
// The restart failed. Log the error and
|
|
77
|
+
// wait for another event.
|
|
78
|
+
// The old app is still available
|
|
79
|
+
this.#logger.error({ err })
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
this.#restarting = false
|
package/lib/management-api.js
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { tmpdir, platform } = require('node:os')
|
|
4
|
+
const { join } = require('node:path')
|
|
5
|
+
const { readFile, mkdir, unlink } = require('node:fs/promises')
|
|
3
6
|
const fastify = require('fastify')
|
|
4
|
-
const {
|
|
7
|
+
const { prettyFactory } = require('pino-pretty')
|
|
8
|
+
const errors = require('./errors')
|
|
5
9
|
const platformaticVersion = require('../package.json').version
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
const PLATFORMATIC_TMP_DIR = join(tmpdir(), 'platformatic', 'pids')
|
|
12
|
+
|
|
13
|
+
const pinoLogLevels = {
|
|
14
|
+
fatal: 60,
|
|
15
|
+
error: 50,
|
|
16
|
+
warn: 40,
|
|
17
|
+
info: 30,
|
|
18
|
+
debug: 20,
|
|
19
|
+
trace: 10
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function createManagementApi (configManager, runtimeApiClient, loggingPort) {
|
|
23
|
+
let apiConfig = configManager.current.managementApi
|
|
24
|
+
if (!apiConfig || apiConfig === true) {
|
|
25
|
+
apiConfig = {}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const app = fastify(apiConfig)
|
|
10
29
|
app.log.warn(
|
|
11
30
|
'Runtime Management API is in the experimental stage. ' +
|
|
12
31
|
'The feature is not subject to semantic versioning rules. ' +
|
|
@@ -14,36 +33,57 @@ async function createManagementApi (config, runtimeApiClient) {
|
|
|
14
33
|
'Use of the feature is not recommended in production environments.'
|
|
15
34
|
)
|
|
16
35
|
|
|
36
|
+
async function getRuntimePackageJson (cwd) {
|
|
37
|
+
const packageJsonPath = join(cwd, 'package.json')
|
|
38
|
+
const packageJsonFile = await readFile(packageJsonPath, 'utf8')
|
|
39
|
+
const packageJson = JSON.parse(packageJsonFile)
|
|
40
|
+
return packageJson
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
app.register(require('@fastify/websocket'))
|
|
44
|
+
|
|
17
45
|
app.register(async (app) => {
|
|
18
46
|
app.get('/metadata', async () => {
|
|
47
|
+
const packageJson = await getRuntimePackageJson(configManager.dirname).catch(() => ({}))
|
|
48
|
+
const entrypointDetails = await runtimeApiClient.getEntrypointDetails().catch(() => null)
|
|
49
|
+
|
|
19
50
|
return {
|
|
20
51
|
pid: process.pid,
|
|
21
52
|
cwd: process.cwd(),
|
|
53
|
+
argv: process.argv,
|
|
54
|
+
uptimeSeconds: Math.floor(process.uptime()),
|
|
22
55
|
execPath: process.execPath,
|
|
23
56
|
nodeVersion: process.version,
|
|
57
|
+
projectDir: configManager.dirname,
|
|
58
|
+
packageName: packageJson.name ?? null,
|
|
59
|
+
packageVersion: packageJson.version ?? null,
|
|
60
|
+
url: entrypointDetails?.url ?? null,
|
|
24
61
|
platformaticVersion
|
|
25
62
|
}
|
|
26
63
|
})
|
|
27
64
|
|
|
28
|
-
app.get('/
|
|
29
|
-
return
|
|
65
|
+
app.get('/config', async () => {
|
|
66
|
+
return configManager.current
|
|
30
67
|
})
|
|
31
68
|
|
|
32
|
-
app.
|
|
33
|
-
|
|
34
|
-
await runtimeApiClient.start()
|
|
69
|
+
app.get('/env', async () => {
|
|
70
|
+
return process.env
|
|
35
71
|
})
|
|
36
72
|
|
|
37
|
-
app.post('/
|
|
73
|
+
app.post('/stop', async () => {
|
|
38
74
|
app.log.debug('stop services')
|
|
39
|
-
await runtimeApiClient.
|
|
75
|
+
await runtimeApiClient.close()
|
|
40
76
|
})
|
|
41
77
|
|
|
42
|
-
app.post('/
|
|
43
|
-
app.log.debug('
|
|
78
|
+
app.post('/reload', async () => {
|
|
79
|
+
app.log.debug('reload services')
|
|
44
80
|
await runtimeApiClient.restart()
|
|
45
81
|
})
|
|
46
82
|
|
|
83
|
+
app.get('/services', async () => {
|
|
84
|
+
return runtimeApiClient.getServices()
|
|
85
|
+
})
|
|
86
|
+
|
|
47
87
|
app.get('/services/:id', async (request) => {
|
|
48
88
|
const { id } = request.params
|
|
49
89
|
app.log.debug('get service details', { id })
|
|
@@ -87,27 +127,85 @@ async function createManagementApi (config, runtimeApiClient) {
|
|
|
87
127
|
.headers(res.headers)
|
|
88
128
|
.send(res.body)
|
|
89
129
|
})
|
|
130
|
+
|
|
131
|
+
app.get('/logs', { websocket: true }, async (connection, req) => {
|
|
132
|
+
const logLevel = req.query.level || 'info'
|
|
133
|
+
const pretty = req.query.pretty !== 'false'
|
|
134
|
+
const serviceId = req.query.serviceId || null
|
|
135
|
+
|
|
136
|
+
const logLevelNumber = pinoLogLevels[logLevel]
|
|
137
|
+
const prettify = prettyFactory()
|
|
138
|
+
|
|
139
|
+
const handler = (message) => {
|
|
140
|
+
for (let log of message.logs) {
|
|
141
|
+
try {
|
|
142
|
+
const parsedLog = JSON.parse(log)
|
|
143
|
+
if (parsedLog.level < logLevelNumber) continue
|
|
144
|
+
if (serviceId && parsedLog.name !== serviceId) continue
|
|
145
|
+
if (pretty) {
|
|
146
|
+
log = prettify(parsedLog)
|
|
147
|
+
}
|
|
148
|
+
connection.socket.send(log)
|
|
149
|
+
} catch (err) {
|
|
150
|
+
console.error('Failed to parse log message: ', log, err)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
loggingPort.on('message', handler)
|
|
156
|
+
connection.socket.on('close', () => {
|
|
157
|
+
loggingPort.off('message', handler)
|
|
158
|
+
})
|
|
159
|
+
connection.socket.on('error', () => {
|
|
160
|
+
loggingPort.off('message', handler)
|
|
161
|
+
})
|
|
162
|
+
connection.socket.on('end', () => {
|
|
163
|
+
loggingPort.off('message', handler)
|
|
164
|
+
})
|
|
165
|
+
})
|
|
90
166
|
}, { prefix: '/api' })
|
|
91
167
|
|
|
92
168
|
return app
|
|
93
169
|
}
|
|
94
170
|
|
|
95
|
-
function
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
171
|
+
async function startManagementApi (configManager, runtimeApiClient, loggingPort) {
|
|
172
|
+
const runtimePID = process.pid
|
|
173
|
+
|
|
174
|
+
let socketPath = null
|
|
175
|
+
if (platform() === 'win32') {
|
|
176
|
+
socketPath = '\\\\.\\pipe\\platformatic-' + runtimePID
|
|
177
|
+
} else {
|
|
178
|
+
await mkdir(PLATFORMATIC_TMP_DIR, { recursive: true })
|
|
179
|
+
socketPath = join(PLATFORMATIC_TMP_DIR, `${runtimePID}.sock`)
|
|
103
180
|
}
|
|
104
181
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
182
|
+
try {
|
|
183
|
+
await mkdir(PLATFORMATIC_TMP_DIR, { recursive: true })
|
|
184
|
+
await unlink(socketPath).catch((err) => {
|
|
185
|
+
if (err.code !== 'ENOENT') {
|
|
186
|
+
throw new errors.FailedToUnlinkManagementApiSocket(err.message)
|
|
187
|
+
}
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
const managementApi = await createManagementApi(
|
|
191
|
+
configManager,
|
|
192
|
+
runtimeApiClient,
|
|
193
|
+
loggingPort
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
if (platform() !== 'win32') {
|
|
197
|
+
managementApi.addHook('onClose', async () => {
|
|
198
|
+
await unlink(socketPath).catch(() => {})
|
|
199
|
+
})
|
|
109
200
|
}
|
|
201
|
+
|
|
202
|
+
await managementApi.listen({ path: socketPath })
|
|
203
|
+
return managementApi
|
|
204
|
+
/* c8 ignore next 4 */
|
|
205
|
+
} catch (err) {
|
|
206
|
+
console.error(err)
|
|
207
|
+
process.exit(1)
|
|
110
208
|
}
|
|
111
209
|
}
|
|
112
210
|
|
|
113
|
-
module.exports = { createManagementApi }
|
|
211
|
+
module.exports = { startManagementApi, createManagementApi }
|
package/lib/start.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { tmpdir, platform } = require('node:os')
|
|
4
3
|
const { once } = require('node:events')
|
|
5
4
|
const inspector = require('node:inspector')
|
|
6
5
|
const { join, resolve, dirname } = require('node:path')
|
|
7
|
-
const { writeFile
|
|
6
|
+
const { writeFile } = require('node:fs/promises')
|
|
8
7
|
const { pathToFileURL } = require('node:url')
|
|
9
8
|
const { Worker } = require('node:worker_threads')
|
|
10
9
|
const { start: serviceStart } = require('@platformatic/service')
|
|
11
10
|
const { printConfigValidationErrors } = require('@platformatic/config')
|
|
12
11
|
const closeWithGrace = require('close-with-grace')
|
|
13
12
|
const { loadConfig } = require('./load-config')
|
|
14
|
-
const {
|
|
13
|
+
const { startManagementApi } = require('./management-api')
|
|
15
14
|
const { parseInspectorOptions, wrapConfigInRuntimeConfig } = require('./config')
|
|
16
15
|
const RuntimeApiClient = require('./api-client.js')
|
|
17
16
|
const errors = require('./errors')
|
|
@@ -25,8 +24,6 @@ const kWorkerExecArgv = [
|
|
|
25
24
|
kLoaderFile
|
|
26
25
|
]
|
|
27
26
|
|
|
28
|
-
const PLATFORMATIC_TMP_DIR = join(tmpdir(), 'platformatic', 'pids')
|
|
29
|
-
|
|
30
27
|
async function startWithConfig (configManager, env = process.env) {
|
|
31
28
|
const config = configManager.current
|
|
32
29
|
|
|
@@ -47,10 +44,21 @@ async function startWithConfig (configManager, env = process.env) {
|
|
|
47
44
|
// The configManager cannot be transferred to the worker, so remove it.
|
|
48
45
|
delete config.configManager
|
|
49
46
|
|
|
47
|
+
let mainLoggingPort = null
|
|
48
|
+
let childLoggingPort = config.loggingPort
|
|
49
|
+
|
|
50
|
+
if (!childLoggingPort && config.managementApi) {
|
|
51
|
+
const { port1, port2 } = new MessageChannel()
|
|
52
|
+
mainLoggingPort = port1
|
|
53
|
+
childLoggingPort = port2
|
|
54
|
+
|
|
55
|
+
config.loggingPort = childLoggingPort
|
|
56
|
+
}
|
|
57
|
+
|
|
50
58
|
const worker = new Worker(kWorkerFile, {
|
|
51
59
|
/* c8 ignore next */
|
|
52
60
|
execArgv: config.hotReload ? kWorkerExecArgv : [],
|
|
53
|
-
transferList:
|
|
61
|
+
transferList: childLoggingPort ? [childLoggingPort] : [],
|
|
54
62
|
workerData: { config, dirname },
|
|
55
63
|
env
|
|
56
64
|
})
|
|
@@ -106,7 +114,11 @@ async function startWithConfig (configManager, env = process.env) {
|
|
|
106
114
|
const runtimeApiClient = new RuntimeApiClient(worker)
|
|
107
115
|
|
|
108
116
|
if (config.managementApi) {
|
|
109
|
-
managementApi = await startManagementApi(
|
|
117
|
+
managementApi = await startManagementApi(
|
|
118
|
+
configManager,
|
|
119
|
+
runtimeApiClient,
|
|
120
|
+
mainLoggingPort
|
|
121
|
+
)
|
|
110
122
|
runtimeApiClient.managementApi = managementApi
|
|
111
123
|
}
|
|
112
124
|
|
|
@@ -126,38 +138,6 @@ async function start (args) {
|
|
|
126
138
|
return serviceStart(config.app, args)
|
|
127
139
|
}
|
|
128
140
|
|
|
129
|
-
async function startManagementApi (managementApiConfig, runtimeApiClient) {
|
|
130
|
-
const runtimePID = process.pid
|
|
131
|
-
|
|
132
|
-
let socketPath = null
|
|
133
|
-
if (platform() === 'win32') {
|
|
134
|
-
socketPath = '\\\\.\\pipe\\' + join(PLATFORMATIC_TMP_DIR, `${runtimePID}.sock`)
|
|
135
|
-
} else {
|
|
136
|
-
await mkdir(PLATFORMATIC_TMP_DIR, { recursive: true })
|
|
137
|
-
socketPath = join(PLATFORMATIC_TMP_DIR, `${runtimePID}.sock`)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
try {
|
|
141
|
-
await mkdir(PLATFORMATIC_TMP_DIR, { recursive: true })
|
|
142
|
-
await unlink(socketPath).catch((err) => {
|
|
143
|
-
if (err.code !== 'ENOENT') {
|
|
144
|
-
throw new errors.FailedToUnlinkManagementApiSocket(err.message)
|
|
145
|
-
}
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
const managementApi = await createManagementApi(
|
|
149
|
-
managementApiConfig,
|
|
150
|
-
runtimeApiClient
|
|
151
|
-
)
|
|
152
|
-
await managementApi.listen({ path: socketPath })
|
|
153
|
-
return managementApi
|
|
154
|
-
/* c8 ignore next 4 */
|
|
155
|
-
} catch (err) {
|
|
156
|
-
console.error(err)
|
|
157
|
-
process.exit(1)
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
141
|
async function startCommand (args) {
|
|
162
142
|
try {
|
|
163
143
|
const config = await loadConfig({}, args)
|
package/lib/worker.js
CHANGED
|
@@ -12,6 +12,7 @@ const {
|
|
|
12
12
|
} = require('node:worker_threads')
|
|
13
13
|
const undici = require('undici')
|
|
14
14
|
const pino = require('pino')
|
|
15
|
+
const pretty = require('pino-pretty')
|
|
15
16
|
const { setGlobalDispatcher, Agent } = require('undici')
|
|
16
17
|
const RuntimeApi = require('./api')
|
|
17
18
|
const { MessagePortWritable } = require('./message-port-writable')
|
|
@@ -34,7 +35,6 @@ globalThis.fetch = undici.fetch
|
|
|
34
35
|
const config = workerData.config
|
|
35
36
|
|
|
36
37
|
let loggerConfig = config.server?.logger
|
|
37
|
-
let destination
|
|
38
38
|
|
|
39
39
|
if (loggerConfig) {
|
|
40
40
|
loggerConfig = { ...loggerConfig }
|
|
@@ -42,21 +42,23 @@ if (loggerConfig) {
|
|
|
42
42
|
loggerConfig = {}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
const cliStream = isatty(1) ? pretty() : pino.destination(1)
|
|
46
|
+
|
|
47
|
+
let logger = null
|
|
46
48
|
if (config.loggingPort) {
|
|
47
|
-
|
|
49
|
+
const portStream = new MessagePortWritable({
|
|
48
50
|
metadata: config.loggingMetadata,
|
|
49
51
|
port: config.loggingPort
|
|
50
52
|
})
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
53
|
+
const multiStream = pino.multistream([
|
|
54
|
+
{ stream: portStream, level: 'trace' },
|
|
55
|
+
{ stream: cliStream, level: loggerConfig.level || 'info' }
|
|
56
|
+
])
|
|
57
|
+
logger = pino({ level: 'trace' }, multiStream)
|
|
58
|
+
} else {
|
|
59
|
+
logger = pino(loggerConfig, cliStream)
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
const logger = pino(loggerConfig, destination)
|
|
59
|
-
|
|
60
62
|
if (config.server) {
|
|
61
63
|
config.server.logger = logger
|
|
62
64
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/runtime",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"homepage": "https://github.com/platformatic/platformatic#readme",
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@fastify/express": "^2.3.0",
|
|
21
|
+
"@matteo.collina/tspl": "^0.1.1",
|
|
21
22
|
"borp": "^0.9.0",
|
|
22
23
|
"c8": "^9.1.0",
|
|
23
24
|
"execa": "^8.0.1",
|
|
@@ -30,11 +31,13 @@
|
|
|
30
31
|
"tsd": "^0.30.4",
|
|
31
32
|
"typescript": "^5.3.3",
|
|
32
33
|
"undici-oauth-interceptor": "^0.4.2",
|
|
33
|
-
"
|
|
34
|
-
"@platformatic/sql-
|
|
34
|
+
"ws": "^8.16.0",
|
|
35
|
+
"@platformatic/sql-graphql": "1.24.0",
|
|
36
|
+
"@platformatic/sql-mapper": "1.24.0"
|
|
35
37
|
},
|
|
36
38
|
"dependencies": {
|
|
37
39
|
"@fastify/error": "^3.4.1",
|
|
40
|
+
"@fastify/websocket": "^9.0.0",
|
|
38
41
|
"@hapi/topo": "^6.0.2",
|
|
39
42
|
"boring-name-generator": "^1.0.3",
|
|
40
43
|
"close-with-grace": "^1.2.0",
|
|
@@ -52,13 +55,13 @@
|
|
|
52
55
|
"pino-pretty": "^10.3.1",
|
|
53
56
|
"undici": "^6.6.0",
|
|
54
57
|
"why-is-node-running": "^2.2.2",
|
|
55
|
-
"@platformatic/composer": "1.
|
|
56
|
-
"@platformatic/config": "1.
|
|
57
|
-
"@platformatic/db": "1.
|
|
58
|
-
"@platformatic/
|
|
59
|
-
"@platformatic/
|
|
60
|
-
"@platformatic/telemetry": "1.
|
|
61
|
-
"@platformatic/utils": "1.
|
|
58
|
+
"@platformatic/composer": "1.24.0",
|
|
59
|
+
"@platformatic/config": "1.24.0",
|
|
60
|
+
"@platformatic/db": "1.24.0",
|
|
61
|
+
"@platformatic/generators": "1.24.0",
|
|
62
|
+
"@platformatic/service": "1.24.0",
|
|
63
|
+
"@platformatic/telemetry": "1.24.0",
|
|
64
|
+
"@platformatic/utils": "1.24.0"
|
|
62
65
|
},
|
|
63
66
|
"standard": {
|
|
64
67
|
"ignore": [
|
package/runtime.mjs
CHANGED