@platformatic/runtime 2.0.0-alpha.2 → 2.0.0-alpha.4

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 (176) hide show
  1. package/config.d.ts +285 -0
  2. package/eslint.config.js +8 -0
  3. package/fixtures/botched-start/platformatic.runtime.json +1 -1
  4. package/fixtures/botched-start/services/a/platformatic.service.json +1 -1
  5. package/fixtures/composerApp/platformatic.composer.json +1 -1
  6. package/fixtures/configs/invalid-autoload-with-services.json +1 -1
  7. package/fixtures/configs/invalid-entrypoint.json +1 -1
  8. package/fixtures/configs/invalid-schema-type.config.json +1 -1
  9. package/fixtures/configs/missing-property.config.json +1 -1
  10. package/fixtures/configs/missing-service-config.json +1 -1
  11. package/fixtures/configs/monorepo-composer-no-autoload.json +2 -2
  12. package/fixtures/configs/monorepo-composer.json +2 -2
  13. package/fixtures/configs/monorepo-create-cycle.json +2 -2
  14. package/fixtures/configs/monorepo-missing-dependencies.json +2 -2
  15. package/fixtures/configs/monorepo-no-cycles.json +2 -2
  16. package/fixtures/configs/monorepo-openapi.json +2 -2
  17. package/fixtures/configs/{monorepo-hotreload-env.json → monorepo-watch-env.json} +2 -2
  18. package/fixtures/configs/monorepo-watch-single.json +12 -0
  19. package/fixtures/configs/monorepo-watch.json +26 -9
  20. package/fixtures/configs/monorepo-with-dependencies.json +2 -2
  21. package/fixtures/configs/monorepo-with-management-api-without-metrics.json +21 -0
  22. package/fixtures/configs/monorepo-with-management-api.json +2 -2
  23. package/fixtures/configs/{monorepo-hotreload.json → monorepo-with-metrics.json} +5 -4
  24. package/fixtures/configs/monorepo.json +2 -2
  25. package/fixtures/configs/no-services.config.json +1 -1
  26. package/fixtures/configs/no-sources.config.json +1 -1
  27. package/fixtures/configs/service-throws-on-start.json +1 -1
  28. package/fixtures/configs/service-with-env-port.json +2 -2
  29. package/fixtures/configs/service-with-stdio.json +12 -0
  30. package/fixtures/configs/{hotreload.json → watch.json} +2 -2
  31. package/fixtures/crash-on-bootstrap/platformatic.runtime.json +15 -0
  32. package/fixtures/crash-on-bootstrap/services/service-1/platformatic.service.json +14 -0
  33. package/fixtures/crash-on-bootstrap/services/service-1/plugin.js +5 -0
  34. package/fixtures/crash-on-bootstrap/services/service-2/platformatic.service.json +14 -0
  35. package/fixtures/crash-on-bootstrap/services/service-2/plugin.js +5 -0
  36. package/fixtures/dbApp/platformatic.db.json +1 -1
  37. package/fixtures/dbAppNoName/platformatic.db.json +1 -1
  38. package/fixtures/dbAppNoPackageJson/platformatic.db.json +1 -1
  39. package/fixtures/dbAppWithMigrationError/platformatic.db.json +1 -1
  40. package/fixtures/do-not-reload-dependencies/platformatic.service.json +1 -1
  41. package/fixtures/do-not-restart-on-crash/platformatic.runtime.json +3 -2
  42. package/fixtures/do-not-restart-on-crash/services/a/platformatic.service.json +1 -1
  43. package/fixtures/express/platformatic.runtime.json +1 -1
  44. package/fixtures/express/services/a/platformatic.service.json +1 -1
  45. package/fixtures/express/services/b/platformatic.service.json +1 -1
  46. package/fixtures/external-client/platformatic.service.json +1 -1
  47. package/fixtures/interceptors/idp.js +2 -2
  48. package/fixtures/interceptors/platformatic.runtime.json +1 -1
  49. package/fixtures/interceptors/services/a/platformatic.service.json +1 -1
  50. package/fixtures/interceptors-2/platformatic.runtime.json +1 -1
  51. package/fixtures/interceptors-2/services/a/platformatic.service.json +1 -1
  52. package/fixtures/leven/platformatic.runtime.json +2 -2
  53. package/fixtures/leven/services/deeply-spittle/platformatic.service.json +1 -1
  54. package/fixtures/leven/services/rainy-empire/platformatic.composer.json +1 -1
  55. package/fixtures/management-api/platformatic.json +3 -3
  56. package/fixtures/management-api/services/service-1/platformatic.json +1 -1
  57. package/fixtures/management-api/services/service-1/plugin.js +4 -3
  58. package/fixtures/management-api/services/service-2/platformatic.json +1 -1
  59. package/fixtures/management-api/services/service-db/platformatic.db.json +1 -1
  60. package/fixtures/management-api-custom-labels/platformatic.json +2 -2
  61. package/fixtures/management-api-custom-labels/services/service-1/platformatic.json +1 -1
  62. package/fixtures/management-api-custom-labels/services/service-1/plugin.js +4 -3
  63. package/fixtures/management-api-custom-labels/services/service-2/platformatic.json +1 -1
  64. package/fixtures/management-api-custom-labels/services/service-db/platformatic.db.json +1 -1
  65. package/fixtures/management-api-without-metrics/platformatic.json +3 -2
  66. package/fixtures/management-api-without-metrics/services/service-1/platformatic.json +1 -1
  67. package/fixtures/monorepo/composerApp/platformatic.composer.json +1 -1
  68. package/fixtures/monorepo/dbApp/platformatic.db.json +1 -1
  69. package/fixtures/monorepo/serviceApp/platformatic.service.json +3 -2
  70. package/fixtures/monorepo/serviceApp/with-logger/with-logger.cjs +2 -2
  71. package/fixtures/monorepo/serviceApp/with-logger/with-logger.d.ts +7 -7
  72. package/fixtures/monorepo/serviceAppWithLogger/platformatic.service.json +1 -1
  73. package/fixtures/monorepo/serviceAppWithLogger/plugin.js +12 -0
  74. package/fixtures/monorepo/serviceAppWithMultiplePlugins/platformatic.service.json +3 -2
  75. package/fixtures/monorepo-missing-dependencies/composer/platformatic.json +1 -1
  76. package/fixtures/monorepo-openapi/serviceAppWithoutOpenapi/platformatic.service.json +1 -1
  77. package/fixtures/monorepo-watch/service1/platformatic.service.json +1 -1
  78. package/fixtures/monorepo-with-dependencies/main/platformatic.json +1 -1
  79. package/fixtures/monorepo-with-dependencies/service-1/platformatic.json +1 -1
  80. package/fixtures/monorepo-with-dependencies/service-2/platformatic.json +1 -1
  81. package/fixtures/no-env.service.json +1 -1
  82. package/fixtures/preload/platformatic.runtime.json +1 -1
  83. package/fixtures/preload/services/a/platformatic.service.json +1 -1
  84. package/fixtures/prom-server/platformatic.json +2 -2
  85. package/fixtures/prom-server/services/service-1/platformatic.json +1 -1
  86. package/fixtures/prom-server/services/service-2/platformatic.json +1 -1
  87. package/fixtures/restart-on-crash/platformatic.runtime.json +1 -1
  88. package/fixtures/restart-on-crash/services/a/platformatic.service.json +1 -1
  89. package/fixtures/sample-runtime/package.json +1 -1
  90. package/fixtures/sample-runtime/platformatic.json +2 -2
  91. package/fixtures/sample-runtime/services/rival/package.json +1 -1
  92. package/fixtures/sample-runtime/services/rival/platformatic.json +1 -1
  93. package/fixtures/sample-runtime-with-2-services/package.json +1 -1
  94. package/fixtures/sample-runtime-with-2-services/platformatic.json +2 -2
  95. package/fixtures/sample-runtime-with-2-services/services/foobar/package.json +1 -1
  96. package/fixtures/sample-runtime-with-2-services/services/foobar/platformatic.json +1 -1
  97. package/fixtures/sample-runtime-with-2-services/services/rival/package.json +1 -1
  98. package/fixtures/sample-runtime-with-2-services/services/rival/platformatic.json +1 -1
  99. package/fixtures/server/logger-transport/platformatic.runtime.json +2 -2
  100. package/fixtures/server/logger-transport/services/echo/platformatic.service.json +1 -1
  101. package/fixtures/server/overrides-service/platformatic.runtime.json +2 -2
  102. package/fixtures/server/overrides-service/services/echo/platformatic.service.json +1 -1
  103. package/fixtures/server/runtime-server/platformatic.runtime.json +2 -2
  104. package/fixtures/server/runtime-server/services/echo/platformatic.service.json +1 -1
  105. package/fixtures/serviceAppThrowsOnStart/platformatic.service.json +1 -1
  106. package/fixtures/stackables/node_modules/foo/foo.js +2 -1
  107. package/fixtures/start-command-in-runtime.js +1 -1
  108. package/fixtures/stdio/platformatic.service.json +6 -0
  109. package/fixtures/stdio/plugin.js +24 -0
  110. package/fixtures/telemetry/platformatic.runtime.json +2 -2
  111. package/fixtures/telemetry/services/echo/platformatic.service.json +1 -1
  112. package/fixtures/telemetry/services/echo/routes/span.js +16 -2
  113. package/fixtures/telemetry/services/service-1/platformatic.service.json +19 -0
  114. package/fixtures/telemetry/services/service-1/routes/echo.js +7 -0
  115. package/fixtures/typescript/platformatic.runtime.json +2 -2
  116. package/fixtures/typescript/services/composer/platformatic.composer.json +1 -1
  117. package/fixtures/typescript/services/movies/global.d.ts +2 -3
  118. package/fixtures/typescript/services/movies/platformatic.db.json +1 -1
  119. package/fixtures/typescript/services/movies/types/Movie.d.ts +3 -3
  120. package/fixtures/typescript/services/movies/types/index.d.ts +6 -6
  121. package/fixtures/typescript/services/titles/client/client.d.ts +35 -35
  122. package/fixtures/typescript/services/titles/platformatic.service.json +1 -1
  123. package/fixtures/typescript-custom-flags/platformatic.runtime.json +2 -2
  124. package/fixtures/typescript-custom-flags/services/composer/platformatic.composer.json +1 -1
  125. package/fixtures/typescript-custom-flags/services/movies/global.d.ts +2 -3
  126. package/fixtures/typescript-custom-flags/services/movies/platformatic.db.json +1 -1
  127. package/fixtures/typescript-custom-flags/services/movies/types/Movie.d.ts +3 -3
  128. package/fixtures/typescript-custom-flags/services/movies/types/index.d.ts +6 -6
  129. package/fixtures/typescript-custom-flags/services/titles/client/client.d.ts +35 -35
  130. package/fixtures/typescript-custom-flags/services/titles/platformatic.service.json +1 -1
  131. package/fixtures/typescript-no-env/platformatic.runtime.json +2 -2
  132. package/fixtures/typescript-no-env/services/composer/platformatic.composer.json +1 -1
  133. package/fixtures/typescript-no-env/services/movies/global.d.ts +2 -3
  134. package/fixtures/typescript-no-env/services/movies/platformatic.db.json +1 -1
  135. package/fixtures/typescript-no-env/services/movies/types/Movie.d.ts +3 -3
  136. package/fixtures/typescript-no-env/services/movies/types/index.d.ts +6 -6
  137. package/fixtures/typescript-no-env/services/titles/client/client.d.ts +35 -35
  138. package/fixtures/typescript-no-env/services/titles/platformatic.service.json +1 -1
  139. package/index.d.ts +7 -8
  140. package/index.js +14 -10
  141. package/index.test-d.ts +10 -12
  142. package/lib/build-server.js +5 -11
  143. package/lib/compile.js +11 -10
  144. package/lib/config.js +21 -14
  145. package/lib/dependencies.js +2 -1
  146. package/lib/errors.js +3 -2
  147. package/lib/generator/errors.js +1 -1
  148. package/lib/generator/runtime-generator.d.ts +15 -15
  149. package/lib/generator/runtime-generator.js +92 -63
  150. package/lib/logger.js +55 -0
  151. package/lib/management-api.js +29 -44
  152. package/lib/prom-server.js +5 -9
  153. package/lib/runtime.js +955 -0
  154. package/lib/schema.js +79 -76
  155. package/lib/start.js +35 -113
  156. package/lib/upgrade.js +4 -3
  157. package/lib/utils.js +49 -1
  158. package/lib/versions/v1.36.0.js +1 -1
  159. package/lib/versions/v1.5.0.js +1 -1
  160. package/lib/versions/v2.0.0.js +17 -0
  161. package/lib/worker/app.js +250 -0
  162. package/lib/worker/default-stackable.js +27 -0
  163. package/lib/worker/itc.js +128 -0
  164. package/lib/worker/main.js +127 -0
  165. package/lib/worker/symbols.js +7 -0
  166. package/package.json +25 -25
  167. package/runtime.mjs +4 -4
  168. package/schema.json +824 -0
  169. package/lib/api-client.js +0 -500
  170. package/lib/api.js +0 -420
  171. package/lib/app.js +0 -397
  172. package/lib/load-config.js +0 -12
  173. package/lib/loader.mjs +0 -103
  174. package/lib/message-port-writable.js +0 -50
  175. package/lib/worker.js +0 -182
  176. /package/lib/{interceptors.js → worker/interceptors.js} +0 -0
package/lib/config.js CHANGED
@@ -1,9 +1,12 @@
1
1
  'use strict'
2
+
2
3
  const { readdir } = require('node:fs/promises')
3
4
  const { join, resolve: pathResolve } = require('node:path')
5
+
4
6
  const ConfigManager = require('@platformatic/config')
5
- const { schema } = require('./schema')
7
+
6
8
  const errors = require('./errors')
9
+ const { schema } = require('./schema')
7
10
  const upgrade = require('./upgrade')
8
11
 
9
12
  const kServicesAutoloaded = Symbol('plt.servicesAutoloaded')
@@ -65,11 +68,11 @@ async function _transformConfig (configManager) {
65
68
  for (let i = 0; i < services.length; ++i) {
66
69
  const service = services[i]
67
70
 
68
- if (configManager._fixPaths) {
71
+ if (configManager._fixPaths && service.config) {
69
72
  service.config = pathResolve(service.path, service.config)
70
73
  }
71
74
  service.entrypoint = service.id === config.entrypoint
72
- service.hotReload = !!config.hotReload
75
+ service.watch = !!config.watch
73
76
  service.dependencies = []
74
77
  service.localServiceEnvVars = new Map()
75
78
  service.localUrl = `http://${service.id}.plt.local`
@@ -87,6 +90,10 @@ async function _transformConfig (configManager) {
87
90
 
88
91
  configManager.current.services = services
89
92
  configManager.current.services[kServicesAutoloaded] = true
93
+
94
+ if (configManager.current.restartOnError === true) {
95
+ configManager.current.restartOnError = 5000
96
+ }
90
97
  }
91
98
 
92
99
  async function platformaticRuntime () {
@@ -104,12 +111,12 @@ platformaticRuntime.configManagerConfig = {
104
111
  useDefaults: true,
105
112
  coerceTypes: true,
106
113
  allErrors: true,
107
- strict: false
114
+ strict: false,
108
115
  },
109
116
  async transformConfig () {
110
117
  await _transformConfig(this)
111
118
  },
112
- upgrade
119
+ upgrade,
113
120
  }
114
121
 
115
122
  async function wrapConfigInRuntimeConfig ({ configManager, args }) {
@@ -128,14 +135,14 @@ async function wrapConfigInRuntimeConfig ({ configManager, args }) {
128
135
  const wrapperConfig = {
129
136
  $schema: schema.$id,
130
137
  entrypoint: serviceId,
131
- hotReload: true,
138
+ watch: true,
132
139
  services: [
133
140
  {
134
141
  id: serviceId,
135
142
  path: configManager.dirname,
136
- config: configManager.fullPath
137
- }
138
- ]
143
+ config: configManager.fullPath,
144
+ },
145
+ ],
139
146
  }
140
147
  const cm = new ConfigManager({
141
148
  source: wrapperConfig,
@@ -144,9 +151,9 @@ async function wrapConfigInRuntimeConfig ({ configManager, args }) {
144
151
  useDefaults: true,
145
152
  coerceTypes: true,
146
153
  allErrors: true,
147
- strict: false
154
+ strict: false,
148
155
  },
149
- transformConfig () { return _transformConfig(this) }
156
+ transformConfig () { return _transformConfig(this) },
150
157
  })
151
158
 
152
159
  await cm.parseAndValidate()
@@ -198,15 +205,15 @@ function parseInspectorOptions (configManager) {
198
205
  host,
199
206
  port,
200
207
  breakFirstLine: hasInspectBrk,
201
- hotReloadDisabled: !!current.hotReload
208
+ watchDisabled: !!current.watch,
202
209
  }
203
210
 
204
- current.hotReload = false
211
+ current.watch = false
205
212
  }
206
213
  }
207
214
 
208
215
  module.exports = {
209
216
  parseInspectorOptions,
210
217
  platformaticRuntime,
211
- wrapConfigInRuntimeConfig
218
+ wrapConfigInRuntimeConfig,
212
219
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  const Topo = require('@hapi/topo')
4
4
  const { closest } = require('fastest-levenshtein')
5
+
5
6
  const errors = require('./errors')
6
7
 
7
8
  function missingDependencyErrorMessage (clientName, service, services) {
@@ -38,7 +39,7 @@ function topologicalSort (services, config) {
38
39
  topo.add(service, {
39
40
  group: service.id,
40
41
  after: localDependencyIds,
41
- manual: true
42
+ manual: true,
42
43
  })
43
44
  }
44
45
 
package/lib/errors.js CHANGED
@@ -7,8 +7,9 @@ const ERROR_PREFIX = 'PLT_RUNTIME'
7
7
  module.exports = {
8
8
  AddressInUseError: createError(`${ERROR_PREFIX}_EADDR_IN_USE`, 'The current port is in use by another application'),
9
9
  RuntimeExitedError: createError(`${ERROR_PREFIX}_RUNTIME_EXIT`, 'The runtime exited before the operation completed'),
10
+ ServiceExitedError: createError(`${ERROR_PREFIX}_SERVICE_EXIT`, 'The service %s exited prematurely with error code %d'),
10
11
  UnknownRuntimeAPICommandError: createError(`${ERROR_PREFIX}_UNKNOWN_RUNTIME_API_COMMAND`, 'Unknown Runtime API command "%s"'),
11
- ServiceNotFoundError: createError(`${ERROR_PREFIX}_SERVICE_NOT_FOUND`, 'Service not found. Available services are: %s'),
12
+ ServiceNotFoundError: createError(`${ERROR_PREFIX}_SERVICE_NOT_FOUND`, 'Service %s not found. Available services are: %s'),
12
13
  ServiceNotStartedError: createError(`${ERROR_PREFIX}_SERVICE_NOT_STARTED`, "Service with id '%s' is not started"),
13
14
  FailedToRetrieveOpenAPISchemaError: createError(`${ERROR_PREFIX}_FAILED_TO_RETRIEVE_OPENAPI_SCHEMA`, 'Failed to retrieve OpenAPI schema for service with id "%s": %s'),
14
15
  FailedToRetrieveGraphQLSchemaError: createError(`${ERROR_PREFIX}_FAILED_TO_RETRIEVE_GRAPHQL_SCHEMA`, 'Failed to retrieve GraphQL schema for service with id "%s": %s'),
@@ -29,5 +30,5 @@ module.exports = {
29
30
  WorkerIsRequired: createError(`${ERROR_PREFIX}_REQUIRED_WORKER`, 'The worker parameter is required'),
30
31
 
31
32
  // TODO: should remove next one as it's not used anymore
32
- CannotRemoveServiceOnUpdateError: createError(`${ERROR_PREFIX}_CANNOT_REMOVE_SERVICE_ON_UPDATE`, 'Cannot remove service "%s" when updating a Runtime')
33
+ CannotRemoveServiceOnUpdateError: createError(`${ERROR_PREFIX}_CANNOT_REMOVE_SERVICE_ON_UPDATE`, 'Cannot remove service "%s" when updating a Runtime'),
33
34
  }
@@ -6,5 +6,5 @@ const ERROR_PREFIX = 'PLT_RUNTIME_GEN'
6
6
 
7
7
  module.exports = {
8
8
  NoServiceNamedError: createError(`${ERROR_PREFIX}_NO_SERVICE_FOUND`, 'No service named \'%s\' has been added to this runtime.'),
9
- NoEntryPointError: createError(`${ERROR_PREFIX}_NO_ENTRYPOINT`, 'No entrypoint had been defined.')
9
+ NoEntryPointError: createError(`${ERROR_PREFIX}_NO_ENTRYPOINT`, 'No entrypoint had been defined.'),
10
10
  }
@@ -1,5 +1,5 @@
1
- import { BaseGenerator } from "@platformatic/generators"
2
- import { FileGenerator } from "@platformatic/generators/lib/file-generator"
1
+ import { BaseGenerator } from '@platformatic/generators'
2
+ import { FileGenerator } from '@platformatic/generators/lib/file-generator'
3
3
 
4
4
  type Service = {
5
5
  config: FileGenerator.FileGenerator | BaseGenerator.BaseGenerator
@@ -13,7 +13,7 @@ type KeyValue = {
13
13
  [key: string]: string
14
14
  }
15
15
 
16
- type RuntimeGeneratorOptions = BaseGenerator.BaseGeneratorOptions & {
16
+ type RuntimeGeneratorOptions = BaseGenerator.BaseGeneratorOptions & {
17
17
  logLevel: string
18
18
  }
19
19
 
@@ -21,17 +21,17 @@ export namespace RuntimeGenerator {
21
21
  export class RuntimeGenerator extends BaseGenerator.BaseGenerator {
22
22
  services: Service[]
23
23
  entryPoint: Service
24
- constructor(opts?: RuntimeGeneratorOptions)
25
-
26
- addService(service: Service, name: string): Promise<void>
27
-
28
- setEntryPoint(entryPoint: string): void
29
-
30
- setServicesDirectory(): void
31
-
32
- setServicesConfig(configToOverride: object): void
33
-
34
- getRuntimeEnv(): KeyValue
35
- writeServicesFiles(): Promise<GeneratorMetadata>
24
+ constructor (opts?: RuntimeGeneratorOptions)
25
+
26
+ addService (service: Service, name: string): Promise<void>
27
+
28
+ setEntryPoint (entryPoint: string): void
29
+
30
+ setServicesDirectory (): void
31
+
32
+ setServicesConfig (configToOverride: object): void
33
+
34
+ getRuntimeEnv (): KeyValue
35
+ writeServicesFiles (): Promise<GeneratorMetadata>
36
36
  }
37
37
  }
@@ -5,7 +5,7 @@ const { NoEntryPointError, NoServiceNamedError } = require('./errors')
5
5
  const generateName = require('boring-name-generator')
6
6
  const { join } = require('node:path')
7
7
  const { envObjectToString } = require('@platformatic/generators/lib/utils')
8
- const { readFile, readdir, stat, rm } = require('node:fs/promises')
8
+ const { readFile, readdir, stat } = require('node:fs/promises')
9
9
  const { ConfigManager } = require('@platformatic/config')
10
10
  const { platformaticRuntime } = require('../config')
11
11
  const { getServiceTemplateFromSchemaUrl } = require('@platformatic/generators/lib/utils')
@@ -13,12 +13,13 @@ const { DotEnvTool } = require('dotenv-tool')
13
13
  const { getArrayDifference } = require('../utils')
14
14
  const { createRequire } = require('node:module')
15
15
  const { pathToFileURL } = require('node:url')
16
+ const { safeRemove } = require('@platformatic/utils')
16
17
 
17
18
  class RuntimeGenerator extends BaseGenerator {
18
19
  constructor (opts) {
19
20
  super({
20
21
  ...opts,
21
- module: '@platformatic/runtime'
22
+ module: '@platformatic/runtime',
22
23
  })
23
24
  this.runtimeName = opts.name
24
25
  this.services = []
@@ -32,14 +33,14 @@ class RuntimeGenerator extends BaseGenerator {
32
33
  const newConfig = {
33
34
  ...originalConfig,
34
35
  isRuntimeContext: true,
35
- serviceName
36
+ serviceName,
36
37
  }
37
38
  // reset all files previously generated by the service
38
39
  service.reset()
39
40
  service.setConfig(newConfig)
40
41
  this.services.push({
41
42
  name: serviceName,
42
- service
43
+ service,
43
44
  })
44
45
 
45
46
  if (typeof service.setRuntime === 'function') {
@@ -48,7 +49,7 @@ class RuntimeGenerator extends BaseGenerator {
48
49
  }
49
50
 
50
51
  setEntryPoint (entryPoint) {
51
- const service = this.services.find((svc) => svc.name === entryPoint)
52
+ const service = this.services.find(svc => svc.name === entryPoint)
52
53
  if (!service) {
53
54
  throw new NoServiceNamedError(entryPoint)
54
55
  }
@@ -60,23 +61,24 @@ class RuntimeGenerator extends BaseGenerator {
60
61
  name: `${this.runtimeName}`,
61
62
  workspaces: ['services/*'],
62
63
  scripts: {
63
- start: 'platformatic start'
64
+ start: 'platformatic start',
64
65
  },
65
66
  devDependencies: {
66
67
  fastify: `^${this.fastifyVersion}`,
67
- borp: `${this.pkgData.devDependencies.borp}`
68
+ borp: `${this.pkgData.devDependencies.borp}`,
68
69
  },
69
70
  dependencies: {
70
71
  '@platformatic/runtime': `^${this.platformaticVersion}`,
71
72
  platformatic: `^${this.platformaticVersion}`,
72
- ...this.config.dependencies
73
+ ...this.config.dependencies,
73
74
  },
74
75
  engines: {
75
- node: '^18.8.0 || >=20.6.0'
76
- }
76
+ node: '^18.8.0 || >=20.6.0',
77
+ },
77
78
  }
78
79
  if (this.config.typescript) {
79
- const typescriptVersion = JSON.parse(await readFile(join(__dirname, '..', '..', 'package.json'), 'utf-8')).devDependencies.typescript
80
+ const typescriptVersion = JSON.parse(await readFile(join(__dirname, '..', '..', 'package.json'), 'utf-8'))
81
+ .devDependencies.typescript
80
82
  template.scripts.clean = 'rm -fr ./dist'
81
83
  template.scripts.build = 'platformatic compile'
82
84
  template.devDependencies.typescript = typescriptVersion
@@ -89,18 +91,21 @@ class RuntimeGenerator extends BaseGenerator {
89
91
  this.setServicesConfigValues()
90
92
  this.addServicesDependencies()
91
93
 
92
- this.addEnvVars({
93
- PLT_SERVER_HOSTNAME: '127.0.0.1',
94
- PORT: this.config.port || 3042,
95
- PLT_SERVER_LOGGER_LEVEL: this.config.logLevel || 'info',
96
- PLT_MANAGEMENT_API: true
97
- }, { overwrite: false, default: true })
94
+ this.addEnvVars(
95
+ {
96
+ PLT_SERVER_HOSTNAME: '127.0.0.1',
97
+ PORT: this.config.port || 3042,
98
+ PLT_SERVER_LOGGER_LEVEL: this.config.logLevel || 'info',
99
+ PLT_MANAGEMENT_API: true,
100
+ },
101
+ { overwrite: false, default: true }
102
+ )
98
103
  }
99
104
 
100
105
  addServicesDependencies () {
101
106
  this.services.forEach(({ service }) => {
102
107
  if (service.config.dependencies) {
103
- Object.entries(service.config.dependencies).forEach((kv) => {
108
+ Object.entries(service.config.dependencies).forEach(kv => {
104
109
  this.config.dependencies[kv[0]] = kv[1]
105
110
  })
106
111
  }
@@ -116,13 +121,13 @@ class RuntimeGenerator extends BaseGenerator {
116
121
  if (existingConfigFile) {
117
122
  const configManager = new ConfigManager({
118
123
  ...platformaticRuntime.configManagerConfig,
119
- source: join(this.targetDirectory, existingConfigFile)
124
+ source: join(this.targetDirectory, existingConfigFile),
120
125
  })
121
126
  await configManager.parse()
122
127
  this.existingConfig = configManager.current
123
128
  this.config.env = configManager.env
124
129
  this.config.port = configManager.env.PORT
125
- this.entryPoint = configManager.current.services.find((svc) => svc.entrypoint)
130
+ this.entryPoint = configManager.current.services.find(svc => svc.entrypoint)
126
131
  }
127
132
  }
128
133
 
@@ -134,7 +139,7 @@ class RuntimeGenerator extends BaseGenerator {
134
139
  await this._afterPrepare()
135
140
  return {
136
141
  env: this.config.env,
137
- targetDirectory: this.targetDirectory
142
+ targetDirectory: this.targetDirectory,
138
143
  }
139
144
  } else {
140
145
  return await super.prepare()
@@ -153,21 +158,21 @@ class RuntimeGenerator extends BaseGenerator {
153
158
 
154
159
  async _getConfigFileContents () {
155
160
  const config = {
156
- $schema: `https://platformatic.dev/schemas/v${this.platformaticVersion}/runtime`,
161
+ $schema: `https://schemas.platformatic.dev/@platformatic/runtime/${this.platformaticVersion}.json`,
157
162
  entrypoint: this.entryPoint.name,
158
- hotReload: true,
163
+ watch: true,
159
164
  autoload: {
160
165
  path: 'services',
161
- exclude: ['docs']
166
+ exclude: ['docs'],
162
167
  },
163
168
  server: {
164
169
  hostname: '{PLT_SERVER_HOSTNAME}',
165
170
  port: '{PORT}',
166
171
  logger: {
167
- level: '{PLT_SERVER_LOGGER_LEVEL}'
168
- }
172
+ level: '{PLT_SERVER_LOGGER_LEVEL}',
173
+ },
169
174
  },
170
- managementApi: '{PLT_MANAGEMENT_API}'
175
+ managementApi: '{PLT_MANAGEMENT_API}',
171
176
  }
172
177
 
173
178
  return config
@@ -181,19 +186,19 @@ class RuntimeGenerator extends BaseGenerator {
181
186
  this.addEnvVars({
182
187
  ...this.config.env,
183
188
  ...this.getRuntimeEnv(),
184
- ...servicesEnv
189
+ ...servicesEnv,
185
190
  })
186
191
 
187
192
  this.addFile({
188
193
  path: '',
189
194
  file: '.env',
190
- contents: envObjectToString(this.config.env)
195
+ contents: envObjectToString(this.config.env),
191
196
  })
192
197
 
193
198
  this.addFile({
194
199
  path: '',
195
200
  file: '.env.sample',
196
- contents: envObjectToString(this.config.env)
201
+ contents: envObjectToString(this.config.env),
197
202
  })
198
203
 
199
204
  if (!this.existingConfig) {
@@ -202,7 +207,7 @@ class RuntimeGenerator extends BaseGenerator {
202
207
 
203
208
  return {
204
209
  targetDirectory: this.targetDirectory,
205
- env: servicesEnv
210
+ env: servicesEnv,
206
211
  }
207
212
  }
208
213
 
@@ -224,7 +229,10 @@ class RuntimeGenerator extends BaseGenerator {
224
229
  name: 'typescript',
225
230
  message: 'Do you want to use TypeScript?',
226
231
  default: false,
227
- choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
232
+ choices: [
233
+ { name: 'yes', value: true },
234
+ { name: 'no', value: false },
235
+ ],
228
236
  })
229
237
 
230
238
  if (this.existingConfig) {
@@ -236,7 +244,7 @@ class RuntimeGenerator extends BaseGenerator {
236
244
  type: 'input',
237
245
  name: 'port',
238
246
  default: 3042,
239
- message: 'What port do you want to use?'
247
+ message: 'What port do you want to use?',
240
248
  })
241
249
  }
242
250
 
@@ -251,11 +259,11 @@ class RuntimeGenerator extends BaseGenerator {
251
259
  }
252
260
 
253
261
  setServicesConfig (configToOverride) {
254
- this.services.forEach((service) => {
262
+ this.services.forEach(service => {
255
263
  const originalConfig = service.config
256
264
  service.setConfig({
257
265
  ...originalConfig,
258
- ...configToOverride
266
+ ...configToOverride,
259
267
  })
260
268
  })
261
269
  }
@@ -266,12 +274,12 @@ class RuntimeGenerator extends BaseGenerator {
266
274
  // Propagate TypeScript
267
275
  svc.service.setConfig({
268
276
  ...svc.service.config,
269
- typescript: this.config.typescript
277
+ typescript: this.config.typescript,
270
278
  })
271
279
  const svcEnv = await svc.service.prepare()
272
280
  servicesEnv = {
273
281
  ...servicesEnv,
274
- ...svcEnv.env
282
+ ...svcEnv.env,
275
283
  }
276
284
  }
277
285
  return servicesEnv
@@ -287,7 +295,7 @@ class RuntimeGenerator extends BaseGenerator {
287
295
 
288
296
  getRuntimeEnv () {
289
297
  return {
290
- PORT: this.config.port
298
+ PORT: this.config.port,
291
299
  }
292
300
  }
293
301
 
@@ -305,9 +313,11 @@ class RuntimeGenerator extends BaseGenerator {
305
313
 
306
314
  async loadFromDir () {
307
315
  const output = {
308
- services: []
316
+ services: [],
309
317
  }
310
- const runtimePkgConfigFileData = JSON.parse(await readFile(join(this.targetDirectory, 'platformatic.json'), 'utf-8'))
318
+ const runtimePkgConfigFileData = JSON.parse(
319
+ await readFile(join(this.targetDirectory, 'platformatic.json'), 'utf-8')
320
+ )
311
321
  const servicesPath = join(this.targetDirectory, runtimePkgConfigFileData.autoload.path)
312
322
 
313
323
  // load all services
@@ -323,7 +333,7 @@ class RuntimeGenerator extends BaseGenerator {
323
333
  const template = servicePltJson.module || getServiceTemplateFromSchemaUrl(servicePltJson.$schema)
324
334
  const Generator = await this._getGeneratorForTemplate(currentServicePath, template)
325
335
  const instance = new Generator({
326
- logger: this.logger
336
+ logger: this.logger,
327
337
  })
328
338
  this.addService(instance, s)
329
339
  output.services.push(await instance.loadFromDir(s, this.targetDirectory))
@@ -340,11 +350,11 @@ class RuntimeGenerator extends BaseGenerator {
340
350
  const currrentPackageJson = JSON.parse(await readFile(join(this.targetDirectory, 'package.json'), 'utf-8'))
341
351
  const currentRuntimeDependencies = currrentPackageJson.dependencies
342
352
  // check all services are present with the same template
343
- const allCurrentServicesNames = this.services.map((s) => s.name)
344
- const allNewServicesNames = newConfig.services.map((s) => s.name)
353
+ const allCurrentServicesNames = this.services.map(s => s.name)
354
+ const allNewServicesNames = newConfig.services.map(s => s.name)
345
355
  // load dotenv tool
346
356
  const envTool = new DotEnvTool({
347
- path: join(this.targetDirectory, '.env')
357
+ path: join(this.targetDirectory, '.env'),
348
358
  })
349
359
 
350
360
  await envTool.load()
@@ -355,24 +365,25 @@ class RuntimeGenerator extends BaseGenerator {
355
365
  // handle service delete
356
366
 
357
367
  // delete env variables
358
- const s = this.services.find((f) => f.name === removedService)
368
+ const s = this.services.find(f => f.name === removedService)
359
369
  const allKeys = envTool.getKeys()
360
- allKeys.forEach((k) => {
370
+ allKeys.forEach(k => {
361
371
  if (k.startsWith(`PLT_${s.service.config.envPrefix}`)) {
362
372
  envTool.deleteKey(k)
363
373
  }
364
374
  })
365
375
 
366
376
  // delete dependencies
367
- const servicePackageJson = JSON.parse(await readFile(join(this.targetDirectory, 'services', s.name, 'platformatic.json')))
377
+ const servicePackageJson = JSON.parse(
378
+ await readFile(join(this.targetDirectory, 'services', s.name, 'platformatic.json'))
379
+ )
368
380
  if (servicePackageJson.plugins && servicePackageJson.plugins.packages) {
369
- servicePackageJson.plugins.packages
370
- .forEach((p) => {
371
- delete (currrentPackageJson.dependencies[p.name])
372
- })
381
+ servicePackageJson.plugins.packages.forEach(p => {
382
+ delete currrentPackageJson.dependencies[p.name]
383
+ })
373
384
  }
374
385
  // delete directory
375
- await rm(join(this.targetDirectory, 'services', s.name), { recursive: true })
386
+ await safeRemove(join(this.targetDirectory, 'services', s.name))
376
387
  }
377
388
  // throw new CannotRemoveServiceOnUpdateError(removedServices.join(', '))
378
389
  }
@@ -380,15 +391,18 @@ class RuntimeGenerator extends BaseGenerator {
380
391
  // handle new services
381
392
  for (const newService of newConfig.services) {
382
393
  // create generator for the service
383
- const ServiceGenerator = await this._getGeneratorForTemplate(join(this.targetDirectory, 'package.json'), newService.template)
394
+ const ServiceGenerator = await this._getGeneratorForTemplate(
395
+ join(this.targetDirectory, 'package.json'),
396
+ newService.template
397
+ )
384
398
  const serviceInstance = new ServiceGenerator({
385
- logger: this.logger
399
+ logger: this.logger,
386
400
  })
387
401
  const baseConfig = {
388
402
  isRuntimeContext: true,
389
403
  targetDirectory: join(this.targetDirectory, 'services', newService.name),
390
404
  serviceName: newService.name,
391
- plugin: true
405
+ plugin: true,
392
406
  }
393
407
  if (allCurrentServicesNames.includes(newService.name)) {
394
408
  // update existing services env values
@@ -397,15 +411,15 @@ class RuntimeGenerator extends BaseGenerator {
397
411
 
398
412
  // handle service's plugin differences
399
413
  const oldServiceMetadata = await serviceInstance.loadFromDir(newService.name, this.targetDirectory)
400
- const oldServicePackages = oldServiceMetadata.plugins.map((meta) => meta.name)
401
- const newServicePackages = newService.plugins.map((meta) => meta.name)
414
+ const oldServicePackages = oldServiceMetadata.plugins.map(meta => meta.name)
415
+ const newServicePackages = newService.plugins.map(meta => meta.name)
402
416
  const pluginsToRemove = getArrayDifference(oldServicePackages, newServicePackages)
403
- pluginsToRemove.forEach((p) => delete currentRuntimeDependencies[p])
417
+ pluginsToRemove.forEach(p => delete currentRuntimeDependencies[p])
404
418
  } else {
405
419
  // add service to the generator
406
420
  this.services.push({
407
421
  name: newService.name,
408
- service: serviceInstance
422
+ service: serviceInstance,
409
423
  })
410
424
  }
411
425
  serviceInstance.setConfig(baseConfig)
@@ -430,7 +444,7 @@ class RuntimeGenerator extends BaseGenerator {
430
444
  await serviceInstance.writeFiles()
431
445
  // cleanup runtime env removing keys not present anymore in service plugins
432
446
  const allKeys = envTool.getKeys()
433
- allKeys.forEach((k) => {
447
+ allKeys.forEach(k => {
434
448
  if (k.startsWith(`${serviceEnvPrefix}_FST_PLUGIN`) && !runtimeAddedEnvKeys.includes(k)) {
435
449
  envTool.deleteKey(k)
436
450
  }
@@ -441,18 +455,33 @@ class RuntimeGenerator extends BaseGenerator {
441
455
  envTool.addKey(key, value)
442
456
  })
443
457
  }
444
-
445
458
  // update runtime package.json dependencies
446
459
  currrentPackageJson.dependencies = {
447
460
  ...currrentPackageJson.dependencies,
448
- ...allServicesDependencies
461
+ ...allServicesDependencies,
449
462
  }
450
463
  this.addFile({
451
464
  path: '',
452
465
  file: 'package.json',
453
- contents: JSON.stringify(currrentPackageJson, null, 2)
466
+ contents: JSON.stringify(currrentPackageJson, null, 2),
454
467
  })
455
468
 
469
+ // set new entrypoint if specified
470
+ const newEntrypoint = newConfig.entrypoint
471
+ if (newEntrypoint) {
472
+ // load platformatic.json runtime config
473
+ const runtimePkgConfigFileData = JSON.parse(
474
+ await readFile(join(this.targetDirectory, 'platformatic.json'), 'utf-8')
475
+ )
476
+
477
+ this.setEntryPoint(newEntrypoint)
478
+ runtimePkgConfigFileData.entrypoint = newEntrypoint
479
+ this.addFile({
480
+ path: '',
481
+ file: 'platformatic.json',
482
+ contents: JSON.stringify(runtimePkgConfigFileData, null, 2),
483
+ })
484
+ }
456
485
  await this.writeFiles()
457
486
  // save new env
458
487
  await envTool.save()
package/lib/logger.js ADDED
@@ -0,0 +1,55 @@
1
+ 'use strict'
2
+
3
+ const { join } = require('node:path')
4
+ const { isatty } = require('node:tty')
5
+
6
+ const pino = require('pino')
7
+ const pretty = require('pino-pretty')
8
+
9
+ function createLogger (config, runtimeLogsDir) {
10
+ const loggerConfig = { ...config.server?.logger }
11
+ const cliStream = isatty(1) ? pretty() : pino.destination(1)
12
+
13
+ if (!config.managementApi) {
14
+ return [pino(loggerConfig, cliStream), cliStream]
15
+ }
16
+
17
+ const multiStream = pino.multistream([
18
+ { stream: cliStream, level: loggerConfig.level || 'info' },
19
+ ])
20
+
21
+ if (loggerConfig.transport) {
22
+ const transport = pino.transport(loggerConfig.transport)
23
+ multiStream.add({ level: loggerConfig.level || 'info', stream: transport })
24
+ }
25
+
26
+ if (config.managementApi) {
27
+ const logsFileMb = 5
28
+ const logsLimitMb = config.managementApi?.logs?.maxSize || 200
29
+
30
+ let logsLimitCount = Math.ceil(logsLimitMb / logsFileMb) - 1
31
+ if (logsLimitCount < 1) {
32
+ logsLimitCount = 1
33
+ }
34
+
35
+ const pinoRoll = pino.transport({
36
+ target: 'pino-roll',
37
+ options: {
38
+ file: join(runtimeLogsDir, 'logs'),
39
+ mode: 0o600,
40
+ size: logsFileMb + 'm',
41
+ mkdir: true,
42
+ fsync: true,
43
+ limit: {
44
+ count: logsLimitCount,
45
+ },
46
+ },
47
+ })
48
+
49
+ multiStream.add({ level: 'trace', stream: pinoRoll })
50
+ }
51
+
52
+ return [pino({ level: 'trace' }, multiStream), multiStream]
53
+ }
54
+
55
+ module.exports = { createLogger }