@platformatic/runtime 2.15.0 → 2.16.0-alpha.1

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 HttpsSchemasPlatformaticDevPlatformaticRuntime2150Json = {
8
+ export type HttpsSchemasPlatformaticDevPlatformaticRuntime2160Alpha1Json = {
9
9
  [k: string]: unknown;
10
10
  } & {
11
11
  $schema?: string;
@@ -165,6 +165,7 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime2150Json = {
165
165
  [k: string]: unknown;
166
166
  };
167
167
  serviceTimeout?: number | string;
168
+ resolvedServicesBasePath?: string;
168
169
  };
169
170
 
170
171
  export interface UndiciInterceptor {
package/lib/config.js CHANGED
@@ -87,8 +87,9 @@ async function _transformConfig (configManager, args) {
87
87
  for (let i = 0; i < services.length; ++i) {
88
88
  const service = services[i]
89
89
 
90
- // We need to have absolut paths here, ot the `loadConfig` will fail
91
- if (!isAbsolute(service.path)) {
90
+ // We need to have absolute paths here, ot the `loadConfig` will fail
91
+ // Make sure we don't resolve if env var was not replaced
92
+ if (service.path && !isAbsolute(service.path) && !service.path.match(/^\{.*\}$/)) {
92
93
  service.path = pathResolve(configManager.dirname, service.path)
93
94
  }
94
95
 
package/lib/errors.js CHANGED
@@ -7,6 +7,7 @@ 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
+ RuntimeAbortedError: createError(`${ERROR_PREFIX}_RUNTIME_ABORT`, 'The runtime aborted the operation'),
10
11
  // The following two use the same code as we only need to differentiate the label
11
12
  ServiceExitedError: createError(`${ERROR_PREFIX}_SERVICE_EXIT`, 'The service "%s" exited prematurely with error code %d'),
12
13
  WorkerExitedError: createError(`${ERROR_PREFIX}_SERVICE_EXIT`, 'The worker %s of the service "%s" exited prematurely with error code %d'),
package/lib/runtime.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { once, EventEmitter } = require('node:events')
4
- const { createReadStream, watch } = require('node:fs')
4
+ const { createReadStream, watch, existsSync } = require('node:fs')
5
5
  const { readdir, readFile, stat, access } = require('node:fs/promises')
6
6
  const { join } = require('node:path')
7
7
  const { setTimeout: sleep } = require('node:timers/promises')
@@ -113,6 +113,31 @@ class Runtime extends EventEmitter {
113
113
 
114
114
  // Create all services, each in is own worker thread
115
115
  for (const serviceConfig of config.services) {
116
+ // If there is no service path, check if the service was resolved
117
+ if (!serviceConfig.path) {
118
+ if (serviceConfig.url) {
119
+ // Try to backfill the path for external services
120
+ serviceConfig.path = join(this.#configManager.dirname, config.resolvedServicesBasePath, serviceConfig.id)
121
+
122
+ if (!existsSync(serviceConfig.path)) {
123
+ const executable = globalThis.platformatic?.executable ?? 'platformatic'
124
+ this.logger.error(
125
+ `The path for service "%s" does not exist. Please run "${executable} resolve" and try again.`,
126
+ serviceConfig.id
127
+ )
128
+
129
+ throw new errors.RuntimeAbortedError()
130
+ }
131
+ } else {
132
+ this.logger.error(
133
+ 'The service "%s" has no path defined. Please check your configuration and try again.',
134
+ serviceConfig.id
135
+ )
136
+
137
+ throw new errors.RuntimeAbortedError()
138
+ }
139
+ }
140
+
116
141
  await this.#setupService(serviceConfig)
117
142
  }
118
143
 
@@ -262,7 +287,7 @@ class Runtime extends EventEmitter {
262
287
  this.#updateStatus('closed')
263
288
  }
264
289
 
265
- async startService (id, silent) {
290
+ async startService (id, silent = false) {
266
291
  // Since when a service is stopped the worker is deleted, we consider a service start if its first service
267
292
  // is no longer in the init phase
268
293
  const firstWorker = this.#workers.get(`${id}:0`)
@@ -284,7 +309,7 @@ class Runtime extends EventEmitter {
284
309
  }
285
310
  }
286
311
 
287
- async stopService (id, silent) {
312
+ async stopService (id, silent = false) {
288
313
  const config = this.#configManager.current
289
314
  const serviceConfig = config.services.find(s => s.id === id)
290
315
 
@@ -721,21 +746,6 @@ class Runtime extends EventEmitter {
721
746
  return createReadStream(filePath)
722
747
  }
723
748
 
724
- async sendCommandToService (id, name, message) {
725
- const service = await this.#getServiceById(id)
726
-
727
- try {
728
- return await sendViaITC(service, name, message)
729
- } catch (e) {
730
- // The service exports no meta, return an empty object
731
- if (e.code === 'PLT_ITC_HANDLER_NOT_FOUND') {
732
- return {}
733
- }
734
-
735
- throw e
736
- }
737
- }
738
-
739
749
  #updateStatus (status) {
740
750
  this.#status = status
741
751
  this.emit(status)
package/lib/schema.js CHANGED
@@ -27,6 +27,8 @@ const services = {
27
27
  },
28
28
  path: {
29
29
  type: 'string',
30
+ // This is required for the resolve command to allow empty paths after environment variable replacement
31
+ allowEmptyPaths: true,
30
32
  resolvePath: true
31
33
  },
32
34
  config: {
@@ -284,6 +286,10 @@ const platformaticRuntimeSchema = {
284
286
  { type: 'string' }
285
287
  ],
286
288
  default: 300000 // 5 minutes
289
+ },
290
+ resolvedServicesBasePath: {
291
+ type: 'string',
292
+ default: 'external'
287
293
  }
288
294
  },
289
295
  anyOf: [{ required: ['autoload'] }, { required: ['services'] }, { required: ['web'] }],
package/lib/start.js CHANGED
@@ -146,7 +146,7 @@ async function startCommand (args, throwAllErrors = false, returnRuntime = false
146
146
 
147
147
  return returnRuntime ? runtime : res
148
148
  } catch (err) {
149
- if (throwAllErrors) {
149
+ if (throwAllErrors && err.code !== 'PLT_RUNTIME_RUNTIME_ABORT') {
150
150
  throw err
151
151
  }
152
152
 
@@ -187,7 +187,9 @@ async function startCommand (args, throwAllErrors = false, returnRuntime = false
187
187
  process.exit(1)
188
188
  }
189
189
 
190
- console.error(err)
190
+ if (err.code !== 'PLT_RUNTIME_RUNTIME_ABORT') {
191
+ console.error(err)
192
+ }
191
193
 
192
194
  process.exit(1)
193
195
  }
@@ -13,7 +13,6 @@ const defaultStackable = {
13
13
  getEnv: () => null,
14
14
  getInfo: () => null,
15
15
  getDispatchFunc: () => null,
16
- getDispatchTarget: () => null,
17
16
  getOpenapiSchema: () => null,
18
17
  getGraphqlSchema: () => null,
19
18
  getMeta: () => ({}),
package/lib/worker/itc.js CHANGED
@@ -72,8 +72,12 @@ function setupITC (app, service, dispatcher) {
72
72
  await app.listen()
73
73
  }
74
74
 
75
- dispatcher.replaceServer(await app.stackable.getDispatchTarget())
76
- return service.entrypoint ? app.stackable.getUrl() : null
75
+ const url = app.stackable.getUrl()
76
+
77
+ const dispatchFunc = await app.stackable.getDispatchFunc()
78
+ dispatcher.replaceServer(url ?? dispatchFunc)
79
+
80
+ return service.entrypoint ? url : null
77
81
  },
78
82
 
79
83
  async stop () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/runtime",
3
- "version": "2.15.0",
3
+ "version": "2.16.0-alpha.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -35,12 +35,12 @@
35
35
  "typescript": "^5.5.4",
36
36
  "undici-oidc-interceptor": "^0.5.0",
37
37
  "why-is-node-running": "^2.2.2",
38
- "@platformatic/db": "2.15.0",
39
- "@platformatic/node": "2.15.0",
40
- "@platformatic/composer": "2.15.0",
41
- "@platformatic/service": "2.15.0",
42
- "@platformatic/sql-graphql": "2.15.0",
43
- "@platformatic/sql-mapper": "2.15.0"
38
+ "@platformatic/composer": "2.16.0-alpha.1",
39
+ "@platformatic/db": "2.16.0-alpha.1",
40
+ "@platformatic/node": "2.16.0-alpha.1",
41
+ "@platformatic/sql-graphql": "2.16.0-alpha.1",
42
+ "@platformatic/sql-mapper": "2.16.0-alpha.1",
43
+ "@platformatic/service": "2.16.0-alpha.1"
44
44
  },
45
45
  "dependencies": {
46
46
  "@fastify/error": "^4.0.0",
@@ -70,13 +70,13 @@
70
70
  "undici": "^6.9.0",
71
71
  "undici-thread-interceptor": "^0.9.0",
72
72
  "ws": "^8.16.0",
73
- "@platformatic/basic": "2.15.0",
74
- "@platformatic/generators": "2.15.0",
75
- "@platformatic/config": "2.15.0",
76
- "@platformatic/ts-compiler": "2.15.0",
77
- "@platformatic/itc": "2.15.0",
78
- "@platformatic/telemetry": "2.15.0",
79
- "@platformatic/utils": "2.15.0"
73
+ "@platformatic/config": "2.16.0-alpha.1",
74
+ "@platformatic/basic": "2.16.0-alpha.1",
75
+ "@platformatic/generators": "2.16.0-alpha.1",
76
+ "@platformatic/itc": "2.16.0-alpha.1",
77
+ "@platformatic/ts-compiler": "2.16.0-alpha.1",
78
+ "@platformatic/telemetry": "2.16.0-alpha.1",
79
+ "@platformatic/utils": "2.16.0-alpha.1"
80
80
  },
81
81
  "scripts": {
82
82
  "test": "npm run lint && borp --concurrency=1 --timeout=300000 && tsd",
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.15.0.json",
2
+ "$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.16.0-alpha.1.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "type": "object",
5
5
  "properties": {
@@ -183,6 +183,7 @@
183
183
  },
184
184
  "path": {
185
185
  "type": "string",
186
+ "allowEmptyPaths": true,
186
187
  "resolvePath": true
187
188
  },
188
189
  "config": {
@@ -335,6 +336,7 @@
335
336
  },
336
337
  "path": {
337
338
  "type": "string",
339
+ "allowEmptyPaths": true,
338
340
  "resolvePath": true
339
341
  },
340
342
  "config": {
@@ -1078,6 +1080,10 @@
1078
1080
  }
1079
1081
  ],
1080
1082
  "default": 300000
1083
+ },
1084
+ "resolvedServicesBasePath": {
1085
+ "type": "string",
1086
+ "default": "external"
1081
1087
  }
1082
1088
  },
1083
1089
  "anyOf": [