@platformatic/runtime 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/lib/errors.js CHANGED
@@ -4,113 +4,155 @@ const createError = require('@fastify/error')
4
4
 
5
5
  const ERROR_PREFIX = 'PLT_RUNTIME'
6
6
 
7
- module.exports = {
8
- AddressInUseError: createError(`${ERROR_PREFIX}_EADDR_IN_USE`, 'The current port is in use by another application'),
9
- RuntimeExitedError: createError(`${ERROR_PREFIX}_RUNTIME_EXIT`, 'The runtime exited before the operation completed'),
10
- RuntimeAbortedError: createError(`${ERROR_PREFIX}_RUNTIME_ABORT`, 'The runtime aborted the operation'),
11
- // The following two use the same code as we only need to differentiate the label
12
- ServiceExitedError: createError(
13
- `${ERROR_PREFIX}_SERVICE_EXIT`,
14
- 'The service "%s" exited prematurely with error code %d'
15
- ),
16
- WorkerExitedError: createError(
17
- `${ERROR_PREFIX}_SERVICE_EXIT`,
18
- 'The worker %s of the service "%s" exited prematurely with error code %d'
19
- ),
20
- UnknownRuntimeAPICommandError: createError(
21
- `${ERROR_PREFIX}_UNKNOWN_RUNTIME_API_COMMAND`,
22
- 'Unknown Runtime API command "%s"'
23
- ),
24
- ServiceNotFoundError: createError(
25
- `${ERROR_PREFIX}_SERVICE_NOT_FOUND`,
26
- 'Service %s not found. Available services are: %s'
27
- ),
28
- WorkerNotFoundError: createError(
29
- `${ERROR_PREFIX}_WORKER_NOT_FOUND`,
30
- 'Worker %s of service %s not found. Available services are: %s'
31
- ),
32
- ServiceNotStartedError: createError(`${ERROR_PREFIX}_SERVICE_NOT_STARTED`, "Service with id '%s' is not started"),
33
- ServiceStartTimeoutError: createError(
34
- `${ERROR_PREFIX}_SERVICE_START_TIMEOUT`,
35
- "Service with id '%s' failed to start in %dms."
36
- ),
37
- FailedToRetrieveOpenAPISchemaError: createError(
38
- `${ERROR_PREFIX}_FAILED_TO_RETRIEVE_OPENAPI_SCHEMA`,
39
- 'Failed to retrieve OpenAPI schema for service with id "%s": %s'
40
- ),
41
- FailedToRetrieveGraphQLSchemaError: createError(
42
- `${ERROR_PREFIX}_FAILED_TO_RETRIEVE_GRAPHQL_SCHEMA`,
43
- 'Failed to retrieve GraphQL schema for service with id "%s": %s'
44
- ),
45
- FailedToRetrieveMetaError: createError(
46
- `${ERROR_PREFIX}_FAILED_TO_RETRIEVE_META`,
47
- 'Failed to retrieve metadata for service with id "%s": %s'
48
- ),
49
- FailedToRetrieveMetricsError: createError(
50
- `${ERROR_PREFIX}_FAILED_TO_RETRIEVE_METRICS`,
51
- 'Failed to retrieve metrics for service with id "%s": %s'
52
- ),
53
- FailedToRetrieveHealthError: createError(
54
- `${ERROR_PREFIX}_FAILED_TO_RETRIEVE_HEALTH`,
55
- 'Failed to retrieve health for service with id "%s": %s'
56
- ),
57
- FailedToPerformCustomHealthCheckError: createError(
58
- `${ERROR_PREFIX}_FAILED_TO_PERFORM_CUSTOM_HEALTH_CHECK`,
59
- 'Failed to perform custom healthcheck for service with id "%s": %s'
60
- ),
61
- FailedToPerformCustomReadinessCheckError: createError(
62
- `${ERROR_PREFIX}_FAILED_TO_PERFORM_CUSTOM_READINESS_CHECK`,
63
- 'Failed to perform custom readiness check for service with id "%s": %s'
64
- ),
65
- ApplicationAlreadyStartedError: createError(
66
- `${ERROR_PREFIX}_APPLICATION_ALREADY_STARTED`,
67
- 'Application is already started'
68
- ),
69
- ApplicationNotStartedError: createError(
70
- `${ERROR_PREFIX}_APPLICATION_NOT_STARTED`,
71
- 'Application has not been started'
72
- ),
73
- ConfigPathMustBeStringError: createError(
74
- `${ERROR_PREFIX}_CONFIG_PATH_MUST_BE_STRING`,
75
- 'Config path must be a string'
76
- ),
77
- NoConfigFileFoundError: createError(`${ERROR_PREFIX}_NO_CONFIG_FILE_FOUND`, "No config file found for service '%s'"),
78
- InvalidEntrypointError: createError(`${ERROR_PREFIX}_INVALID_ENTRYPOINT`, "Invalid entrypoint: '%s' does not exist"),
79
- MissingEntrypointError: createError(`${ERROR_PREFIX}_MISSING_ENTRYPOINT`, 'Missing application entrypoint.'),
80
- InvalidServicesWithWebError: createError(
81
- `${ERROR_PREFIX}_INVALID_SERVICES_WITH_WEB`,
82
- 'The "services" property cannot be used when the "web" property is also defined'
83
- ),
84
- MissingDependencyError: createError(`${ERROR_PREFIX}_MISSING_DEPENDENCY`, 'Missing dependency: "%s"'),
85
- InspectAndInspectBrkError: createError(
86
- `${ERROR_PREFIX}_INSPECT_AND_INSPECT_BRK`,
87
- '--inspect and --inspect-brk cannot be used together'
88
- ),
89
- InspectorPortError: createError(
90
- `${ERROR_PREFIX}_INSPECTOR_PORT`,
91
- 'Inspector port must be 0 or in range 1024 to 65535'
92
- ),
93
- InspectorHostError: createError(`${ERROR_PREFIX}_INSPECTOR_HOST`, 'Inspector host cannot be empty'),
94
- CannotMapSpecifierToAbsolutePathError: createError(
95
- `${ERROR_PREFIX}_CANNOT_MAP_SPECIFIER_TO_ABSOLUTE_PATH`,
96
- 'Cannot map "%s" to an absolute path'
97
- ),
98
- NodeInspectorFlagsNotSupportedError: createError(
99
- `${ERROR_PREFIX}_NODE_INSPECTOR_FLAGS_NOT_SUPPORTED`,
100
- "The Node.js inspector flags are not supported. Please use 'platformatic start --inspect' instead."
101
- ),
102
- FailedToUnlinkManagementApiSocket: createError(
103
- `${ERROR_PREFIX}_FAILED_TO_UNLINK_MANAGEMENT_API_SOCKET`,
104
- 'Failed to unlink management API socket "%s"'
105
- ),
106
- LogFileNotFound: createError(`${ERROR_PREFIX}_LOG_FILE_NOT_FOUND`, 'Log file with index %s not found', 404),
107
- WorkerIsRequired: createError(`${ERROR_PREFIX}_REQUIRED_WORKER`, 'The worker parameter is required'),
108
- InvalidArgumentError: createError(`${ERROR_PREFIX}_INVALID_ARGUMENT`, 'Invalid argument: "%s"'),
109
- MessagingError: createError(`${ERROR_PREFIX}_MESSAGING_ERROR`, 'Cannot send a message to service "%s": %s'),
7
+ const AddressInUseError = createError(
8
+ `${ERROR_PREFIX}_EADDR_IN_USE`,
9
+ 'The current port is in use by another application'
10
+ )
11
+ const RuntimeExitedError = createError(
12
+ `${ERROR_PREFIX}_RUNTIME_EXIT`,
13
+ 'The runtime exited before the operation completed'
14
+ )
15
+ const RuntimeAbortedError = createError(`${ERROR_PREFIX}_RUNTIME_ABORT`, 'The runtime aborted the operation')
16
+ // The following two use the same code as we only need to differentiate the label
17
+ const ServiceExitedError = createError(
18
+ `${ERROR_PREFIX}_SERVICE_EXIT`,
19
+ 'The service "%s" exited prematurely with error code %d'
20
+ )
21
+ const WorkerExitedError = createError(
22
+ `${ERROR_PREFIX}_SERVICE_EXIT`,
23
+ 'The worker %s of the service "%s" exited prematurely with error code %d'
24
+ )
25
+ const UnknownRuntimeAPICommandError = createError(
26
+ `${ERROR_PREFIX}_UNKNOWN_RUNTIME_API_COMMAND`,
27
+ 'Unknown Runtime API command "%s"'
28
+ )
29
+ const ServiceNotFoundError = createError(
30
+ `${ERROR_PREFIX}_SERVICE_NOT_FOUND`,
31
+ 'Service %s not found. Available services are: %s'
32
+ )
33
+ const WorkerNotFoundError = createError(
34
+ `${ERROR_PREFIX}_WORKER_NOT_FOUND`,
35
+ 'Worker %s of service %s not found. Available services are: %s'
36
+ )
37
+ const ServiceNotStartedError = createError(`${ERROR_PREFIX}_SERVICE_NOT_STARTED`, "Service with id '%s' is not started")
38
+ const ServiceStartTimeoutError = createError(
39
+ `${ERROR_PREFIX}_SERVICE_START_TIMEOUT`,
40
+ "Service with id '%s' failed to start in %dms."
41
+ )
42
+ const FailedToRetrieveOpenAPISchemaError = createError(
43
+ `${ERROR_PREFIX}_FAILED_TO_RETRIEVE_OPENAPI_SCHEMA`,
44
+ 'Failed to retrieve OpenAPI schema for service with id "%s": %s'
45
+ )
46
+ const FailedToRetrieveGraphQLSchemaError = createError(
47
+ `${ERROR_PREFIX}_FAILED_TO_RETRIEVE_GRAPHQL_SCHEMA`,
48
+ 'Failed to retrieve GraphQL schema for service with id "%s": %s'
49
+ )
50
+ const FailedToRetrieveMetaError = createError(
51
+ `${ERROR_PREFIX}_FAILED_TO_RETRIEVE_META`,
52
+ 'Failed to retrieve metadata for service with id "%s": %s'
53
+ )
54
+ const FailedToRetrieveMetricsError = createError(
55
+ `${ERROR_PREFIX}_FAILED_TO_RETRIEVE_METRICS`,
56
+ 'Failed to retrieve metrics for service with id "%s": %s'
57
+ )
58
+ const FailedToRetrieveHealthError = createError(
59
+ `${ERROR_PREFIX}_FAILED_TO_RETRIEVE_HEALTH`,
60
+ 'Failed to retrieve health for service with id "%s": %s'
61
+ )
62
+ const FailedToPerformCustomHealthCheckError = createError(
63
+ `${ERROR_PREFIX}_FAILED_TO_PERFORM_CUSTOM_HEALTH_CHECK`,
64
+ 'Failed to perform custom healthcheck for service with id "%s": %s'
65
+ )
66
+ const FailedToPerformCustomReadinessCheckError = createError(
67
+ `${ERROR_PREFIX}_FAILED_TO_PERFORM_CUSTOM_READINESS_CHECK`,
68
+ 'Failed to perform custom readiness check for service with id "%s": %s'
69
+ )
70
+ const ApplicationAlreadyStartedError = createError(
71
+ `${ERROR_PREFIX}_APPLICATION_ALREADY_STARTED`,
72
+ 'Application is already started'
73
+ )
74
+ const ApplicationNotStartedError = createError(
75
+ `${ERROR_PREFIX}_APPLICATION_NOT_STARTED`,
76
+ 'Application has not been started'
77
+ )
78
+ const ConfigPathMustBeStringError = createError(
79
+ `${ERROR_PREFIX}_CONFIG_PATH_MUST_BE_STRING`,
80
+ 'Config path must be a string'
81
+ )
82
+ const NoConfigFileFoundError = createError(
83
+ `${ERROR_PREFIX}_NO_CONFIG_FILE_FOUND`,
84
+ "No config file found for service '%s'"
85
+ )
86
+ const InvalidEntrypointError = createError(
87
+ `${ERROR_PREFIX}_INVALID_ENTRYPOINT`,
88
+ "Invalid entrypoint: '%s' does not exist"
89
+ )
90
+ const MissingEntrypointError = createError(`${ERROR_PREFIX}_MISSING_ENTRYPOINT`, 'Missing application entrypoint.')
91
+ const InvalidServicesWithWebError = createError(
92
+ `${ERROR_PREFIX}_INVALID_SERVICES_WITH_WEB`,
93
+ 'The "services" property cannot be used when the "web" property is also defined'
94
+ )
95
+ const MissingDependencyError = createError(`${ERROR_PREFIX}_MISSING_DEPENDENCY`, 'Missing dependency: "%s"')
96
+ const InspectAndInspectBrkError = createError(
97
+ `${ERROR_PREFIX}_INSPECT_AND_INSPECT_BRK`,
98
+ '--inspect and --inspect-brk cannot be used together'
99
+ )
100
+ const InspectorPortError = createError(
101
+ `${ERROR_PREFIX}_INSPECTOR_PORT`,
102
+ 'Inspector port must be 0 or in range 1024 to 65535'
103
+ )
104
+ const InspectorHostError = createError(`${ERROR_PREFIX}_INSPECTOR_HOST`, 'Inspector host cannot be empty')
105
+ const CannotMapSpecifierToAbsolutePathError = createError(
106
+ `${ERROR_PREFIX}_CANNOT_MAP_SPECIFIER_TO_ABSOLUTE_PATH`,
107
+ 'Cannot map "%s" to an absolute path'
108
+ )
109
+ const NodeInspectorFlagsNotSupportedError = createError(
110
+ `${ERROR_PREFIX}_NODE_INSPECTOR_FLAGS_NOT_SUPPORTED`,
111
+ "The Node.js inspector flags are not supported. Please use 'platformatic start --inspect' instead."
112
+ )
113
+ const FailedToUnlinkManagementApiSocket = createError(
114
+ `${ERROR_PREFIX}_FAILED_TO_UNLINK_MANAGEMENT_API_SOCKET`,
115
+ 'Failed to unlink management API socket "%s"'
116
+ )
117
+ const LogFileNotFound = createError(`${ERROR_PREFIX}_LOG_FILE_NOT_FOUND`, 'Log file with index %s not found', 404)
118
+ const WorkerIsRequired = createError(`${ERROR_PREFIX}_REQUIRED_WORKER`, 'The worker parameter is required')
119
+ const InvalidArgumentError = createError(`${ERROR_PREFIX}_INVALID_ARGUMENT`, 'Invalid argument: "%s"')
120
+ const MessagingError = createError(`${ERROR_PREFIX}_MESSAGING_ERROR`, 'Cannot send a message to service "%s": %s')
110
121
 
111
- // TODO: should remove next one as it's not used anymore
112
- CannotRemoveServiceOnUpdateError: createError(
113
- `${ERROR_PREFIX}_CANNOT_REMOVE_SERVICE_ON_UPDATE`,
114
- 'Cannot remove service "%s" when updating a Runtime'
115
- )
122
+ module.exports = {
123
+ AddressInUseError,
124
+ RuntimeExitedError,
125
+ RuntimeAbortedError,
126
+ ServiceExitedError,
127
+ WorkerExitedError,
128
+ UnknownRuntimeAPICommandError,
129
+ ServiceNotFoundError,
130
+ WorkerNotFoundError,
131
+ ServiceNotStartedError,
132
+ ServiceStartTimeoutError,
133
+ FailedToRetrieveOpenAPISchemaError,
134
+ FailedToRetrieveGraphQLSchemaError,
135
+ FailedToRetrieveMetaError,
136
+ FailedToRetrieveMetricsError,
137
+ FailedToRetrieveHealthError,
138
+ FailedToPerformCustomHealthCheckError,
139
+ FailedToPerformCustomReadinessCheckError,
140
+ ApplicationAlreadyStartedError,
141
+ ApplicationNotStartedError,
142
+ ConfigPathMustBeStringError,
143
+ NoConfigFileFoundError,
144
+ InvalidEntrypointError,
145
+ MissingEntrypointError,
146
+ InvalidServicesWithWebError,
147
+ MissingDependencyError,
148
+ InspectAndInspectBrkError,
149
+ InspectorPortError,
150
+ InspectorHostError,
151
+ CannotMapSpecifierToAbsolutePathError,
152
+ NodeInspectorFlagsNotSupportedError,
153
+ FailedToUnlinkManagementApiSocket,
154
+ LogFileNotFound,
155
+ WorkerIsRequired,
156
+ InvalidArgumentError,
157
+ MessagingError
116
158
  }
@@ -1,18 +1,26 @@
1
1
  'use strict'
2
2
 
3
+ const createError = require('@fastify/error')
3
4
  const { BaseGenerator } = require('@platformatic/generators')
4
- const { NoEntryPointError, NoServiceNamedError } = require('./errors')
5
5
  const { existsSync } = require('node:fs')
6
6
  const { join, basename } = require('node:path')
7
7
  const { envObjectToString } = require('@platformatic/generators/lib/utils')
8
8
  const { readFile, readdir, stat } = require('node:fs/promises')
9
- const { ConfigManager } = require('@platformatic/config')
10
- const { platformaticRuntime } = require('../config')
9
+ const { transform } = require('./config')
11
10
  const { getServiceTemplateFromSchemaUrl } = require('@platformatic/generators/lib/utils')
12
11
  const { DotEnvTool } = require('dotenv-tool')
13
- const { getArrayDifference } = require('../utils')
12
+ const { getArrayDifference } = require('./utils')
13
+ const { schema } = require('./schema')
14
14
  const { pathToFileURL } = require('node:url')
15
- const { safeRemove, generateDashedName, DEFAULT_PACKAGE_MANAGER } = require('@platformatic/utils')
15
+ const {
16
+ safeRemove,
17
+ generateDashedName,
18
+ findConfigurationFile,
19
+ loadConfiguration,
20
+ loadConfigurationFile,
21
+ kMetadata,
22
+ defaultPackageManager
23
+ } = require('@platformatic/foundation')
16
24
  const { createRequire } = require('node:module')
17
25
 
18
26
  const wrappableProperties = {
@@ -27,9 +35,17 @@ const wrappableProperties = {
27
35
  }
28
36
 
29
37
  const engines = {
30
- node: '^18.8.0 || >=20.6.0'
38
+ node: '>=22.18.0'
31
39
  }
32
40
 
41
+ const ERROR_PREFIX = 'PLT_RUNTIME_GEN'
42
+
43
+ const NoServiceNamedError = createError(
44
+ `${ERROR_PREFIX}_NO_SERVICE_FOUND`,
45
+ "No service named '%s' has been added to this runtime."
46
+ )
47
+ const NoEntryPointError = createError(`${ERROR_PREFIX}_NO_ENTRYPOINT`, 'No entrypoint had been defined.')
48
+
33
49
  function getRuntimeBaseEnvVars (config) {
34
50
  return {
35
51
  PLT_SERVER_HOSTNAME: '127.0.0.1',
@@ -50,7 +66,7 @@ class RuntimeGenerator extends BaseGenerator {
50
66
  this.services = []
51
67
  this.existingServices = []
52
68
  this.entryPoint = null
53
- this.packageManager = opts.packageManager ?? DEFAULT_PACKAGE_MANAGER
69
+ this.packageManager = opts.packageManager ?? defaultPackageManager
54
70
  }
55
71
 
56
72
  async addService (service, name) {
@@ -70,9 +86,7 @@ class RuntimeGenerator extends BaseGenerator {
70
86
  service
71
87
  })
72
88
 
73
- if (typeof service.setRuntime === 'function') {
74
- service.setRuntime(this)
75
- }
89
+ service.setRuntime(this)
76
90
  }
77
91
 
78
92
  setEntryPoint (entryPoint) {
@@ -108,13 +122,6 @@ class RuntimeGenerator extends BaseGenerator {
108
122
  template.workspaces = [this.servicesFolder + '/*']
109
123
  }
110
124
 
111
- if (this.config.typescript) {
112
- const typescriptVersion = JSON.parse(await readFile(join(__dirname, '..', '..', 'package.json'), 'utf-8'))
113
- .devDependencies.typescript
114
- template.scripts.clean = 'rm -fr ./dist'
115
- template.scripts.build = 'platformatic compile'
116
- template.devDependencies.typescript = typescriptVersion
117
- }
118
125
  return template
119
126
  }
120
127
 
@@ -141,21 +148,19 @@ class RuntimeGenerator extends BaseGenerator {
141
148
  return
142
149
  }
143
150
  this._hasCheckedForExistingConfig = true
144
- const existingConfigFile =
145
- this.runtimeConfig ?? (await ConfigManager.findConfigFile(this.targetDirectory, 'runtime'))
151
+ const existingConfigFile = this.runtimeConfig ?? (await findConfigurationFile(this.targetDirectory, 'runtime'))
146
152
  if (existingConfigFile && existsSync(join(this.targetDirectory, existingConfigFile))) {
147
- const configManager = new ConfigManager({
148
- ...platformaticRuntime.configManagerConfig,
149
- source: join(this.targetDirectory, existingConfigFile)
153
+ this.existingConfigRaw = await loadConfigurationFile(join(this.targetDirectory, existingConfigFile))
154
+ this.existingConfig = await loadConfiguration(join(this.targetDirectory, existingConfigFile), schema, {
155
+ transform,
156
+ ignoreProcessEnv: true
150
157
  })
151
- await configManager.parse()
152
158
 
153
- this.existingConfig = configManager.current
154
- this.existingConfigRaw = configManager.currentRaw
155
- this.config.env = configManager.env
156
- this.config.port = configManager.env.PORT
157
- this.entryPoint = configManager.current.services.find(svc => svc.entrypoint)
158
- this.existingServices = configManager.current.services.map(s => s.id)
159
+ const { PLT_ROOT, ...existingEnvironment } = this.existingConfig[kMetadata].env
160
+ this.config.env = existingEnvironment
161
+ this.config.port = this.config.env.PORT
162
+ this.entryPoint = this.existingConfig.services.find(svc => svc.entrypoint)
163
+ this.existingServices = this.existingConfig.services.map(s => s.id)
159
164
 
160
165
  this.updateRuntimeConfig(this.existingConfigRaw)
161
166
  this.updateRuntimeEnv(await readFile(join(this.targetDirectory, '.env'), 'utf-8'))
@@ -183,7 +188,6 @@ class RuntimeGenerator extends BaseGenerator {
183
188
  // set default config
184
189
  service.setConfig()
185
190
  }
186
- service.config.typescript = this.config.typescript
187
191
  })
188
192
  }
189
193
 
@@ -221,10 +225,6 @@ class RuntimeGenerator extends BaseGenerator {
221
225
  contents: envObjectToString(this.config.defaultEnv)
222
226
  })
223
227
 
224
- if (!this.existingConfig) {
225
- this.addFile({ path: '', file: 'README.md', contents: await readFile(join(__dirname, 'README.md'), 'utf-8') })
226
- }
227
-
228
228
  return {
229
229
  targetDirectory: this.targetDirectory,
230
230
  env: servicesEnv
@@ -252,18 +252,6 @@ class RuntimeGenerator extends BaseGenerator {
252
252
  async prepareQuestions () {
253
253
  await this.populateFromExistingConfig()
254
254
 
255
- // typescript
256
- this.questions.push({
257
- type: 'list',
258
- name: 'typescript',
259
- message: 'Do you want to use TypeScript?',
260
- default: false,
261
- choices: [
262
- { name: 'yes', value: true },
263
- { name: 'no', value: false }
264
- ]
265
- })
266
-
267
255
  if (this.existingConfig) {
268
256
  return
269
257
  }
@@ -307,11 +295,6 @@ class RuntimeGenerator extends BaseGenerator {
307
295
  async prepareServiceFiles () {
308
296
  let servicesEnv = {}
309
297
  for (const svc of this.services) {
310
- // Propagate TypeScript
311
- svc.service.setConfig({
312
- ...svc.service.config,
313
- typescript: this.config.typescript
314
- })
315
298
  const svcEnv = await svc.service.prepare()
316
299
  servicesEnv = {
317
300
  ...servicesEnv,
@@ -362,7 +345,7 @@ class RuntimeGenerator extends BaseGenerator {
362
345
  const dirStat = await stat(currentServicePath)
363
346
  if (dirStat.isDirectory()) {
364
347
  // load the service config
365
- const configFile = await ConfigManager.findConfigFile(currentServicePath)
348
+ const configFile = await findConfigurationFile(currentServicePath)
366
349
  const servicePltJson = JSON.parse(await readFile(join(currentServicePath, configFile), 'utf-8'))
367
350
  // get module to load
368
351
  const template = servicePltJson.module || getServiceTemplateFromSchemaUrl(servicePltJson.$schema)
@@ -410,7 +393,7 @@ class RuntimeGenerator extends BaseGenerator {
410
393
 
411
394
  // delete dependencies
412
395
  const servicePath = join(this.targetDirectory, this.servicesFolder, s.name)
413
- const configFile = await ConfigManager.findConfigFile(servicePath)
396
+ const configFile = await findConfigurationFile(servicePath)
414
397
  const servicePackageJson = JSON.parse(await readFile(join(servicePath, configFile), 'utf-8'))
415
398
  if (servicePackageJson.plugins && servicePackageJson.plugins.packages) {
416
399
  servicePackageJson.plugins.packages.forEach(p => {
package/lib/logger.js CHANGED
@@ -1,11 +1,9 @@
1
1
  'use strict'
2
2
 
3
- const { once } = require('node:events')
4
- const { join } = require('node:path')
5
3
  const { isatty } = require('node:tty')
6
4
  const pino = require('pino')
7
5
  const pretty = require('pino-pretty')
8
- const { buildPinoFormatters, buildPinoTimestamp } = require('@platformatic/utils')
6
+ const { abstractLogger, buildPinoFormatters, buildPinoTimestamp } = require('@platformatic/foundation')
9
7
 
10
8
  const customPrettifiers = {
11
9
  name (name, _, obj) {
@@ -19,26 +17,24 @@ const customPrettifiers = {
19
17
  }
20
18
 
21
19
  // Create the runtime logger
22
- async function createLogger (config, runtimeLogsDir) {
20
+ async function createLogger (config) {
23
21
  const loggerConfig = { ...config.logger, transport: undefined }
24
22
  if (config.logger.base === null) {
25
23
  loggerConfig.base = undefined
26
24
  }
27
25
 
28
- // PLT_RUNTIME_LOGGER_STDOUT is used in test to reduce verbosity
29
- let cliStream = process.env.PLT_RUNTIME_LOGGER_STDOUT
30
- ? pino.destination(process.env.PLT_RUNTIME_LOGGER_STDOUT)
31
- : isatty(1)
32
- ? pretty({ customPrettifiers })
33
- : pino.destination(1)
26
+ let cliStream
34
27
 
35
28
  if (config.logger.transport) {
36
29
  cliStream = pino.transport(config.logger.transport)
30
+ } else {
31
+ cliStream = isatty(1) ? pretty({ customPrettifiers }) : pino.destination(1)
37
32
  }
38
33
 
39
34
  if (loggerConfig.formatters) {
40
35
  loggerConfig.formatters = buildPinoFormatters(loggerConfig.formatters)
41
36
  }
37
+
42
38
  if (loggerConfig.timestamp) {
43
39
  loggerConfig.timestamp = buildPinoTimestamp(loggerConfig.timestamp)
44
40
  }
@@ -57,26 +53,7 @@ async function createLogger (config, runtimeLogsDir) {
57
53
  logsLimitCount = 1
58
54
  }
59
55
 
60
- const pinoRoll = pino.transport({
61
- target: 'pino-roll',
62
- options: {
63
- file: join(runtimeLogsDir, 'logs'),
64
- mode: 0o600,
65
- size: logsFileMb + 'm',
66
- mkdir: true,
67
- fsync: true,
68
- limit: {
69
- count: logsLimitCount
70
- }
71
- }
72
- })
73
-
74
- multiStream.add({ level: loggerConfig.level, stream: pinoRoll })
75
-
76
- // Make sure there is a file before continuing otherwise the management API log endpoint might bail out
77
- await once(pinoRoll, 'ready')
78
-
79
56
  return [pino(loggerConfig, multiStream), multiStream]
80
57
  }
81
58
 
82
- module.exports = { createLogger }
59
+ module.exports = { abstractLogger, createLogger }
@@ -2,14 +2,11 @@
2
2
 
3
3
  const { platform, tmpdir } = require('node:os')
4
4
  const { join } = require('node:path')
5
- const { createDirectory, safeRemove } = require('@platformatic/utils')
5
+ const { createDirectory, safeRemove } = require('@platformatic/foundation')
6
6
 
7
7
  const fastify = require('fastify')
8
8
  const ws = require('ws')
9
9
 
10
- const errors = require('./errors')
11
- const { getRuntimeLogsDir } = require('./utils')
12
-
13
10
  const PLATFORMATIC_TMP_DIR = join(tmpdir(), 'platformatic', 'runtimes')
14
11
 
15
12
  async function managementApiPlugin (app, opts) {
@@ -152,58 +149,11 @@ async function managementApiPlugin (app, opts) {
152
149
  })
153
150
 
154
151
  app.get('/logs/live', { websocket: true }, async (socket, req) => {
155
- const startLogId = req.query.start ? parseInt(req.query.start) : null
156
-
157
- if (startLogId) {
158
- const logIds = await runtime.getLogIds()
159
- if (!logIds.includes(startLogId)) {
160
- throw new errors.LogFileNotFound(startLogId)
161
- }
162
- }
163
-
164
- const stream = ws.createWebSocketStream(socket)
165
- runtime.pipeLogsStream(stream, req.log, startLogId)
166
- })
167
-
168
- app.get('/logs/indexes', async req => {
169
- const returnAllIds = req.query.all === 'true'
170
-
171
- if (returnAllIds) {
172
- const runtimesLogsIds = await runtime.getAllLogIds()
173
- return runtimesLogsIds
174
- }
175
-
176
- const runtimeLogsIds = await runtime.getLogIds()
177
- return { indexes: runtimeLogsIds }
178
- })
179
-
180
- app.get('/logs/all', async (req, reply) => {
181
- const runtimePID = parseInt(req.query.pid) || process.pid
182
-
183
- const logsIds = await runtime.getLogIds(runtimePID)
184
- const startLogId = logsIds.at(0)
185
- const endLogId = logsIds.at(-1)
186
-
187
- reply.hijack()
188
-
189
- runtime.pipeLogsStream(reply.raw, req.log, startLogId, endLogId, runtimePID)
190
- })
191
-
192
- app.get('/logs/:id', async req => {
193
- const logId = parseInt(req.params.id)
194
- const runtimePID = parseInt(req.query.pid) || process.pid
195
-
196
- const logIds = await runtime.getLogIds(runtimePID)
197
- if (!logIds || !logIds.includes(logId)) {
198
- throw new errors.LogFileNotFound(logId)
199
- }
200
-
201
- const logFileStream = await runtime.getLogFileStream(logId, runtimePID)
202
- return logFileStream
152
+ runtime.addLoggerDestination(ws.createWebSocketStream(socket))
203
153
  })
204
154
  }
205
155
 
206
- async function startManagementApi (runtime, configManager) {
156
+ async function startManagementApi (runtime, root) {
207
157
  const runtimePID = process.pid
208
158
 
209
159
  try {
@@ -212,9 +162,6 @@ async function startManagementApi (runtime, configManager) {
212
162
  await createDirectory(runtimePIDDir, true)
213
163
  }
214
164
 
215
- const runtimeLogsDir = getRuntimeLogsDir(configManager.dirname, process.pid)
216
- await createDirectory(runtimeLogsDir, true)
217
-
218
165
  let socketPath = null
219
166
  if (platform() === 'win32') {
220
167
  socketPath = '\\\\.\\pipe\\platformatic-' + runtimePID.toString()
@@ -232,6 +179,9 @@ async function startManagementApi (runtime, configManager) {
232
179
  }
233
180
  })
234
181
 
182
+ // When the runtime closes, close the management API as well
183
+ runtime.on('closed', managementApi.close.bind(managementApi))
184
+
235
185
  await managementApi.listen({ path: socketPath })
236
186
  return managementApi
237
187
  /* c8 ignore next 4 */