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

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 CHANGED
@@ -5,7 +5,7 @@
5
5
  * and run json-schema-to-typescript to regenerate this file.
6
6
  */
7
7
 
8
- export type HttpsSchemasPlatformaticDevPlatformaticRuntime200Alpha4Json = {
8
+ export type HttpsSchemasPlatformaticDevPlatformaticRuntime200Alpha5Json = {
9
9
  [k: string]: unknown;
10
10
  } & {
11
11
  $schema?: string;
@@ -201,10 +201,6 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime200Alpha4Json = {
201
201
  };
202
202
  restartOnError?: boolean | number;
203
203
  services?: {
204
- id: string;
205
- path: string;
206
- config?: string;
207
- useHttp?: boolean;
208
204
  [k: string]: unknown;
209
205
  }[];
210
206
  };
package/lib/errors.js CHANGED
@@ -13,6 +13,7 @@ module.exports = {
13
13
  ServiceNotStartedError: createError(`${ERROR_PREFIX}_SERVICE_NOT_STARTED`, "Service with id '%s' is not started"),
14
14
  FailedToRetrieveOpenAPISchemaError: createError(`${ERROR_PREFIX}_FAILED_TO_RETRIEVE_OPENAPI_SCHEMA`, 'Failed to retrieve OpenAPI schema for service with id "%s": %s'),
15
15
  FailedToRetrieveGraphQLSchemaError: createError(`${ERROR_PREFIX}_FAILED_TO_RETRIEVE_GRAPHQL_SCHEMA`, 'Failed to retrieve GraphQL schema for service with id "%s": %s'),
16
+ FailedToRetrieveMetaError: createError(`${ERROR_PREFIX}_FAILED_TO_RETRIEVE_META`, 'Failed to retrieve metadata for service with id "%s": %s'),
16
17
  ApplicationAlreadyStartedError: createError(`${ERROR_PREFIX}_APPLICATION_ALREADY_STARTED`, 'Application is already started'),
17
18
  ApplicationNotStartedError: createError(`${ERROR_PREFIX}_APPLICATION_NOT_STARTED`, 'Application has not been started'),
18
19
  ConfigPathMustBeStringError: createError(`${ERROR_PREFIX}_CONFIG_PATH_MUST_BE_STRING`, 'Config path must be a string'),
@@ -202,7 +202,7 @@ class RuntimeGenerator extends BaseGenerator {
202
202
  })
203
203
 
204
204
  if (!this.existingConfig) {
205
- this.addFile({ path: '', file: 'README.md', contents: await readFile(join(__dirname, 'README.md')) })
205
+ this.addFile({ path: '', file: 'README.md', contents: await readFile(join(__dirname, 'README.md'), 'utf-8') })
206
206
  }
207
207
 
208
208
  return {
@@ -375,7 +375,7 @@ class RuntimeGenerator extends BaseGenerator {
375
375
 
376
376
  // delete dependencies
377
377
  const servicePackageJson = JSON.parse(
378
- await readFile(join(this.targetDirectory, 'services', s.name, 'platformatic.json'))
378
+ await readFile(join(this.targetDirectory, 'services', s.name, 'platformatic.json'), 'utf-8')
379
379
  )
380
380
  if (servicePackageJson.plugins && servicePackageJson.plugins.packages) {
381
381
  servicePackageJson.plugins.packages.forEach(p => {
@@ -72,6 +72,20 @@ async function managementApiPlugin (app, opts) {
72
72
  return runtime.getServiceGraphqlSchema(id)
73
73
  })
74
74
 
75
+ app.get('/services/:id/connection-strings', async request => {
76
+ const { id } = request.params
77
+ try {
78
+ app.log.debug('get connection strings', { id })
79
+ const meta = await runtime.getServiceMeta(id)
80
+ if (meta.db) {
81
+ return meta.db
82
+ }
83
+ return null
84
+ } catch (err) {
85
+ throw new errors.FailedToRetrieveMetaError(id, err.message)
86
+ }
87
+ })
88
+
75
89
  app.post('/services/:id/start', async request => {
76
90
  const { id } = request.params
77
91
  app.log.debug('start service', { id })
package/lib/runtime.js CHANGED
@@ -240,17 +240,20 @@ class Runtime extends EventEmitter {
240
240
  const config = this.#configManager.current
241
241
  const restartOnError = config.restartOnError
242
242
 
243
+ if (!restartOnError) {
244
+ this.logger.error(`Failed to start service "${id}".`)
245
+ throw error
246
+ }
247
+
243
248
  let bootstrapAttempt = this.#bootstrapAttempts.get(id)
244
249
  if (bootstrapAttempt++ >= MAX_BOOTSTRAP_ATTEMPTS || restartOnError === 0) {
245
- this.logger.error(
246
- `Failed to start service "${id}" after ${MAX_BOOTSTRAP_ATTEMPTS} attempts.`
247
- )
250
+ this.logger.error(`Failed to start service "${id}" after ${MAX_BOOTSTRAP_ATTEMPTS} attempts.`)
248
251
  throw error
249
252
  }
250
253
 
251
254
  this.logger.warn(
252
255
  `Starting a service "${id}" in ${restartOnError}ms. ` +
253
- `Attempt ${bootstrapAttempt} of ${MAX_BOOTSTRAP_ATTEMPTS}...`
256
+ `Attempt ${bootstrapAttempt} of ${MAX_BOOTSTRAP_ATTEMPTS}...`
254
257
  )
255
258
 
256
259
  this.#bootstrapAttempts.set(id, bootstrapAttempt)
@@ -720,7 +723,7 @@ class Runtime extends EventEmitter {
720
723
  if (started && this.#status === 'started') {
721
724
  if (restartOnError > 0) {
722
725
  this.logger.warn(`Restarting a service "${id}" in ${restartOnError}ms...`)
723
- this.#restartCrashedService(id).catch((err) => {
726
+ this.#restartCrashedService(id).catch(err => {
724
727
  this.logger.error({ err }, `Failed to restart service "${id}".`)
725
728
  })
726
729
  } else {
@@ -736,7 +739,7 @@ class Runtime extends EventEmitter {
736
739
  // Setup ITC
737
740
  service[kITC] = new ITC({ port: service })
738
741
  service[kITC].listen()
739
- service[kITC].handle('getServiceMeta', this.#getServiceMeta.bind(this))
742
+ service[kITC].handle('getServiceMeta', this.getServiceMeta.bind(this))
740
743
 
741
744
  // Handle services changes
742
745
  // This is not purposely activated on when this.#configManager.current.watch === true
@@ -838,7 +841,7 @@ class Runtime extends EventEmitter {
838
841
  return service
839
842
  }
840
843
 
841
- async #getServiceMeta (id) {
844
+ async getServiceMeta (id) {
842
845
  const service = this.#services.get(id)
843
846
 
844
847
  if (!service) {
package/lib/schema.js CHANGED
@@ -191,7 +191,10 @@ const platformaticRuntimeSchema = {
191
191
  type: 'array',
192
192
  items: {
193
193
  type: 'object',
194
- required: ['id', 'path'],
194
+ anyOf: [
195
+ { required: ['id', 'path'] },
196
+ { required: ['id', 'url'] },
197
+ ],
195
198
  properties: {
196
199
  id: {
197
200
  type: 'string',
@@ -203,6 +206,9 @@ const platformaticRuntimeSchema = {
203
206
  config: {
204
207
  type: 'string',
205
208
  },
209
+ url: {
210
+ type: 'string',
211
+ },
206
212
  useHttp: {
207
213
  type: 'boolean',
208
214
  },
package/lib/worker/app.js CHANGED
@@ -205,21 +205,14 @@ class PlatformaticApp extends EventEmitter {
205
205
 
206
206
  #logAndExit (err) {
207
207
  // Runtime logs here with console.error because stackable is not initialized
208
- console.error(
209
- JSON.stringify({
210
- msg: err.message,
211
- name: this.appConfig.id,
212
- })
213
- )
208
+ console.error(err.message)
214
209
  process.exit(1)
215
210
  }
216
211
 
217
212
  #wrapStackable (stackable) {
218
213
  const newStackable = {}
219
214
  for (const method of Object.keys(defaultStackable)) {
220
- newStackable[method] = stackable[method]
221
- ? stackable[method].bind(stackable)
222
- : defaultStackable[method]
215
+ newStackable[method] = stackable[method] ? stackable[method].bind(stackable) : defaultStackable[method]
223
216
  }
224
217
  return newStackable
225
218
  }
@@ -240,8 +233,7 @@ class PlatformaticApp extends EventEmitter {
240
233
  }
241
234
  }
242
235
 
243
- const dispatcher = getGlobalDispatcher()
244
- .compose(interceptor)
236
+ const dispatcher = getGlobalDispatcher().compose(interceptor)
245
237
 
246
238
  setGlobalDispatcher(dispatcher)
247
239
  }
@@ -13,6 +13,7 @@ const defaultStackable = {
13
13
  getDispatchFunc: () => null,
14
14
  getOpenapiSchema: () => null,
15
15
  getGraphqlSchema: () => null,
16
+ getMeta: () => ({}),
16
17
  getMetrics: () => null,
17
18
  inject: () => {
18
19
  throw new Error('Stackable inject not implemented')
package/lib/worker/itc.js CHANGED
@@ -110,6 +110,14 @@ function setupITC (app, service, dispatcher) {
110
110
  }
111
111
  })
112
112
 
113
+ itc.handle('getServiceMeta', async () => {
114
+ try {
115
+ return app.stackable.getMeta()
116
+ } catch (err) {
117
+ throw new errors.FailedToRetrieveMetaError(service.id, err.message)
118
+ }
119
+ })
120
+
113
121
  itc.handle('getMetrics', async format => {
114
122
  return app.stackable.getMetrics({ format })
115
123
  })
@@ -38,7 +38,7 @@ function handleUnhandled (type, err) {
38
38
 
39
39
  function createLogger () {
40
40
  const destination = new MessagePortWritable({ port: workerData.loggingPort })
41
- const loggerInstance = pino({ level: 'trace' }, destination)
41
+ const loggerInstance = pino({ level: 'trace', name: workerData.serviceConfig.id }, destination)
42
42
 
43
43
  Reflect.defineProperty(process, 'stdout', { value: createPinoWritable(loggerInstance, 'info') })
44
44
  Reflect.defineProperty(process, 'stderr', { value: createPinoWritable(loggerInstance, 'error') })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/runtime",
3
- "version": "2.0.0-alpha.4",
3
+ "version": "2.0.0-alpha.5",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -34,11 +34,11 @@
34
34
  "typescript": "^5.5.4",
35
35
  "undici-oidc-interceptor": "^0.5.0",
36
36
  "why-is-node-running": "^2.2.2",
37
- "@platformatic/composer": "2.0.0-alpha.4",
38
- "@platformatic/db": "2.0.0-alpha.4",
39
- "@platformatic/service": "2.0.0-alpha.4",
40
- "@platformatic/sql-graphql": "2.0.0-alpha.4",
41
- "@platformatic/sql-mapper": "2.0.0-alpha.4"
37
+ "@platformatic/composer": "2.0.0-alpha.5",
38
+ "@platformatic/db": "2.0.0-alpha.5",
39
+ "@platformatic/sql-graphql": "2.0.0-alpha.5",
40
+ "@platformatic/sql-mapper": "2.0.0-alpha.5",
41
+ "@platformatic/service": "2.0.0-alpha.5"
42
42
  },
43
43
  "dependencies": {
44
44
  "@fastify/error": "^3.4.1",
@@ -46,7 +46,7 @@
46
46
  "@hapi/topo": "^6.0.2",
47
47
  "boring-name-generator": "^1.0.3",
48
48
  "change-case-all": "^2.1.0",
49
- "close-with-grace": "^1.3.0",
49
+ "close-with-grace": "^2.0.0",
50
50
  "commist": "^3.2.0",
51
51
  "debounce": "^2.0.0",
52
52
  "desm": "^1.3.1",
@@ -64,15 +64,15 @@
64
64
  "semgrator": "^0.3.0",
65
65
  "tail-file-stream": "^0.2.0",
66
66
  "undici": "^6.9.0",
67
- "undici-thread-interceptor": "^0.5.0",
67
+ "undici-thread-interceptor": "^0.5.1",
68
68
  "ws": "^8.16.0",
69
- "@platformatic/config": "2.0.0-alpha.4",
70
- "@platformatic/basic": "2.0.0-alpha.4",
71
- "@platformatic/generators": "2.0.0-alpha.4",
72
- "@platformatic/itc": "2.0.0-alpha.4",
73
- "@platformatic/telemetry": "2.0.0-alpha.4",
74
- "@platformatic/ts-compiler": "2.0.0-alpha.4",
75
- "@platformatic/utils": "2.0.0-alpha.4"
69
+ "@platformatic/basic": "2.0.0-alpha.5",
70
+ "@platformatic/itc": "2.0.0-alpha.5",
71
+ "@platformatic/generators": "2.0.0-alpha.5",
72
+ "@platformatic/telemetry": "2.0.0-alpha.5",
73
+ "@platformatic/ts-compiler": "2.0.0-alpha.5",
74
+ "@platformatic/utils": "2.0.0-alpha.5",
75
+ "@platformatic/config": "2.0.0-alpha.5"
76
76
  },
77
77
  "scripts": {
78
78
  "test": "npm run lint && borp --concurrency=1 --timeout=180000 && tsd",
package/runtime.mjs CHANGED
@@ -33,7 +33,7 @@ export async function run (argv) {
33
33
  })
34
34
 
35
35
  if (args.version) {
36
- console.log('v' + JSON.parse(await readFile(join(import.meta.url, 'package.json'))).version)
36
+ console.log('v' + JSON.parse(await readFile(join(import.meta.url, 'package.json'), 'utf-8')).version)
37
37
  process.exit(0)
38
38
  }
39
39
 
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.0.0-alpha.4.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.0.0-alpha.5.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "type": "object",
5
5
  "properties": {
@@ -766,9 +766,19 @@
766
766
  "type": "array",
767
767
  "items": {
768
768
  "type": "object",
769
- "required": [
770
- "id",
771
- "path"
769
+ "anyOf": [
770
+ {
771
+ "required": [
772
+ "id",
773
+ "path"
774
+ ]
775
+ },
776
+ {
777
+ "required": [
778
+ "id",
779
+ "url"
780
+ ]
781
+ }
772
782
  ],
773
783
  "properties": {
774
784
  "id": {
@@ -781,6 +791,9 @@
781
791
  "config": {
782
792
  "type": "string"
783
793
  },
794
+ "url": {
795
+ "type": "string"
796
+ },
784
797
  "useHttp": {
785
798
  "type": "boolean"
786
799
  }