@platformatic/runtime 2.0.0-alpha.9 → 2.0.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/config.d.ts CHANGED
@@ -5,11 +5,12 @@
5
5
  * and run json-schema-to-typescript to regenerate this file.
6
6
  */
7
7
 
8
- export type HttpsSchemasPlatformaticDevPlatformaticRuntime200Alpha9Json = {
8
+ export type HttpsSchemasPlatformaticDevPlatformaticRuntime200Json = {
9
9
  [k: string]: unknown;
10
10
  } & {
11
11
  $schema?: string;
12
12
  preload?: string;
13
+ entrypoint?: string;
13
14
  autoload?: {
14
15
  path: string;
15
16
  exclude?: string[];
@@ -21,87 +22,54 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime200Alpha9Json = {
21
22
  };
22
23
  };
23
24
  };
24
- telemetry?: OpenTelemetry;
25
- server?: {
26
- hostname?: string;
27
- port?: number | string;
28
- pluginTimeout?: number;
29
- healthCheck?:
30
- | boolean
25
+ services?: {
26
+ [k: string]: unknown;
27
+ }[];
28
+ web?: {
29
+ [k: string]: unknown;
30
+ }[];
31
+ logger?: {
32
+ level: (
33
+ | ("fatal" | "error" | "warn" | "info" | "debug" | "trace" | "silent")
31
34
  | {
32
- enabled?: boolean;
33
- interval?: number;
34
35
  [k: string]: unknown;
35
- };
36
- ignoreTrailingSlash?: boolean;
37
- ignoreDuplicateSlashes?: boolean;
38
- connectionTimeout?: number;
39
- keepAliveTimeout?: number;
40
- maxRequestsPerSocket?: number;
41
- forceCloseConnections?: boolean | string;
42
- requestTimeout?: number;
43
- bodyLimit?: number;
44
- maxParamLength?: number;
45
- disableRequestLogging?: boolean;
46
- exposeHeadRoutes?: boolean;
47
- logger?:
48
- | boolean
36
+ }
37
+ ) &
38
+ string;
39
+ transport?:
49
40
  | {
50
- level?: string;
51
- transport?:
52
- | {
53
- target?: string;
54
- options?: {
55
- [k: string]: unknown;
56
- };
57
- }
58
- | {
59
- targets?: {
60
- target?: string;
61
- options?: {
62
- [k: string]: unknown;
63
- };
64
- level?: string;
65
- additionalProperties?: never;
66
- [k: string]: unknown;
67
- }[];
68
- options?: {
69
- [k: string]: unknown;
70
- };
71
- };
72
- pipeline?: {
41
+ target?: string;
42
+ options?: {
43
+ [k: string]: unknown;
44
+ };
45
+ }
46
+ | {
47
+ targets?: {
73
48
  target?: string;
74
49
  options?: {
75
50
  [k: string]: unknown;
76
51
  };
52
+ level?: string;
53
+ additionalProperties?: never;
54
+ [k: string]: unknown;
55
+ }[];
56
+ options?: {
57
+ [k: string]: unknown;
77
58
  };
78
- [k: string]: unknown;
79
59
  };
80
- loggerInstance?: {
81
- [k: string]: unknown;
82
- };
83
- serializerOpts?: {
84
- schema?: {
85
- [k: string]: unknown;
86
- };
87
- ajv?: {
60
+ pipeline?: {
61
+ target?: string;
62
+ options?: {
88
63
  [k: string]: unknown;
89
64
  };
90
- rounding?: "floor" | "ceil" | "round" | "trunc";
91
- debugMode?: boolean;
92
- mode?: "debug" | "standalone";
93
- largeArraySize?: number | string;
94
- largeArrayMechanism?: "default" | "json-stringify";
95
- [k: string]: unknown;
96
65
  };
97
- caseSensitive?: boolean;
98
- requestIdHeader?: string | false;
99
- requestIdLogLabel?: string;
100
- jsonShorthand?: boolean;
101
- trustProxy?: boolean | string | string[] | number;
66
+ [k: string]: unknown;
67
+ };
68
+ server?: {
69
+ hostname?: string;
70
+ port?: number | string;
102
71
  http2?: boolean;
103
72
  https?: {
104
- allowHTTP1?: boolean;
105
73
  key:
106
74
  | string
107
75
  | {
@@ -124,48 +92,9 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime200Alpha9Json = {
124
92
  path?: string;
125
93
  }
126
94
  )[];
127
- requestCert?: boolean;
128
- rejectUnauthorized?: boolean;
129
95
  };
130
- cors?: {
131
- origin?:
132
- | boolean
133
- | string
134
- | (
135
- | string
136
- | {
137
- regexp: string;
138
- [k: string]: unknown;
139
- }
140
- )[]
141
- | {
142
- regexp: string;
143
- [k: string]: unknown;
144
- };
145
- methods?: string[];
146
- /**
147
- * Comma separated string of allowed headers.
148
- */
149
- allowedHeaders?: string;
150
- exposedHeaders?: string[] | string;
151
- credentials?: boolean;
152
- maxAge?: number;
153
- preflightContinue?: boolean;
154
- optionsSuccessStatus?: number;
155
- preflight?: boolean;
156
- strictPreflight?: boolean;
157
- hideOptionsRoute?: boolean;
158
- };
159
- };
160
- entrypoint?: string;
161
- watch?: boolean | string;
162
- inspectorOptions?: {
163
- host?: string;
164
- port?: number;
165
- breakFirstLine?: boolean;
166
- watchDisabled?: boolean;
167
- [k: string]: unknown;
168
96
  };
97
+ restartOnError?: boolean | number;
169
98
  undici?: {
170
99
  agentOptions?: {
171
100
  [k: string]: unknown;
@@ -180,12 +109,13 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime200Alpha9Json = {
180
109
  };
181
110
  [k: string]: unknown;
182
111
  };
112
+ watch?: boolean | string;
183
113
  managementApi?:
184
114
  | boolean
185
115
  | string
186
116
  | {
187
117
  logs?: {
188
- [k: string]: unknown;
118
+ maxSize?: number;
189
119
  };
190
120
  };
191
121
  metrics?:
@@ -202,12 +132,23 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime200Alpha9Json = {
202
132
  [k: string]: string;
203
133
  };
204
134
  };
205
- restartOnError?: boolean | number;
206
- services?: {
135
+ telemetry?: OpenTelemetry;
136
+ inspectorOptions?: {
137
+ host?: string;
138
+ port?: number;
139
+ breakFirstLine?: boolean;
140
+ watchDisabled?: boolean;
207
141
  [k: string]: unknown;
208
- }[];
142
+ };
209
143
  };
210
144
 
145
+ export interface UndiciInterceptor {
146
+ module: string;
147
+ options: {
148
+ [k: string]: unknown;
149
+ };
150
+ [k: string]: unknown;
151
+ }
211
152
  export interface OpenTelemetry {
212
153
  /**
213
154
  * The name of the service. Defaults to the folder name if not specified.
@@ -275,10 +216,3 @@ export interface OpenTelemetry {
275
216
  [k: string]: unknown;
276
217
  };
277
218
  }
278
- export interface UndiciInterceptor {
279
- module: string;
280
- options: {
281
- [k: string]: unknown;
282
- };
283
- [k: string]: unknown;
284
- }
@@ -3,10 +3,7 @@
3
3
  "entrypoint": "db-app",
4
4
  "autoload": {
5
5
  "path": "../monorepo",
6
- "exclude": [
7
- "docs",
8
- "composerApp"
9
- ],
6
+ "exclude": ["docs", "composerApp"],
10
7
  "mappings": {
11
8
  "serviceAppWithLogger": {
12
9
  "id": "with-logger",
@@ -28,5 +25,12 @@
28
25
  "path": "../monorepo/serviceAppWithLogger",
29
26
  "config": "platformatic.service.json"
30
27
  }
28
+ ],
29
+ "web": [
30
+ {
31
+ "id": "with-logger",
32
+ "path": "../monorepo/serviceAppWithLogger",
33
+ "config": "platformatic.service.json"
34
+ }
31
35
  ]
32
36
  }
@@ -20,10 +20,8 @@
20
20
  }
21
21
  }
22
22
  },
23
- "server": {
24
- "logger": {
25
- "level": "trace"
26
- }
23
+ "logger": {
24
+ "level": "trace"
27
25
  },
28
26
  "restartOnError": 1000
29
27
  }
@@ -2,13 +2,15 @@
2
2
  "$schema": "https://schemas.platformatic.dev/@platformatic/service/1.52.0.json",
3
3
  "server": {
4
4
  "logger": {
5
- "level": "warn"
5
+ "level": "info"
6
6
  }
7
7
  },
8
8
  "plugins": {
9
- "paths": [{
10
- "path": "plugin.js",
11
- "encapsulate": false
12
- }]
9
+ "paths": [
10
+ {
11
+ "path": "plugin.js",
12
+ "encapsulate": false
13
+ }
14
+ ]
13
15
  }
14
16
  }
@@ -4,9 +4,12 @@
4
4
  "openapi": true
5
5
  },
6
6
  "plugins": {
7
- "paths": [
8
- "plugin.js"
9
- ]
7
+ "paths": ["plugin.js"]
10
8
  },
11
- "watch": true
9
+ "watch": true,
10
+ "server": {
11
+ "logger": {
12
+ "level": "trace"
13
+ }
14
+ }
12
15
  }
@@ -2,13 +2,15 @@
2
2
  "$schema": "https://schemas.platformatic.dev/@platformatic/service/1.52.0.json",
3
3
  "server": {
4
4
  "logger": {
5
- "level": "warn"
5
+ "level": "info"
6
6
  }
7
7
  },
8
8
  "plugins": {
9
- "paths": [{
10
- "path": "plugin.js",
11
- "encapsulate": false
12
- }]
9
+ "paths": [
10
+ {
11
+ "path": "plugin.js",
12
+ "encapsulate": false
13
+ }
14
+ ]
13
15
  }
14
16
  }
@@ -4,11 +4,11 @@
4
4
  "test": "node --test test/*/*.test.js"
5
5
  },
6
6
  "devDependencies": {
7
- "fastify": "^4.26.0"
7
+ "fastify": "^5.0.0"
8
8
  },
9
9
  "dependencies": {
10
10
  "platformatic": "^1.25.0",
11
- "@fastify/oauth2": "7.9.0"
11
+ "@fastify/oauth2": "8.0.1"
12
12
  },
13
13
  "engines": {
14
14
  "node": ">=20.16.0"
@@ -4,7 +4,7 @@
4
4
  "test": "node --test test/**"
5
5
  },
6
6
  "devDependencies": {
7
- "fastify": "^4.26.0"
7
+ "fastify": "^5.0.0"
8
8
  },
9
9
  "dependencies": {
10
10
  "platformatic": "^1.25.0",
@@ -4,11 +4,11 @@
4
4
  "test": "node --test test/*/*.test.js"
5
5
  },
6
6
  "devDependencies": {
7
- "fastify": "^4.26.0"
7
+ "fastify": "^5.0.0"
8
8
  },
9
9
  "dependencies": {
10
10
  "platformatic": "^1.25.0",
11
- "@fastify/oauth2": "7.9.0"
11
+ "@fastify/oauth2": "8.0.1"
12
12
  },
13
13
  "engines": {
14
14
  "node": ">=20.16.0"
@@ -4,7 +4,7 @@
4
4
  "test": "node --test test/**"
5
5
  },
6
6
  "devDependencies": {
7
- "fastify": "^4.26.0"
7
+ "fastify": "^5.0.0"
8
8
  },
9
9
  "dependencies": {
10
10
  "platformatic": "^1.25.0",
@@ -4,7 +4,7 @@
4
4
  "test": "node --test test/**"
5
5
  },
6
6
  "devDependencies": {
7
- "fastify": "^4.26.0"
7
+ "fastify": "^5.0.0"
8
8
  },
9
9
  "dependencies": {
10
10
  "platformatic": "^1.25.0",
package/index.js CHANGED
@@ -10,6 +10,8 @@ const { buildRuntime, start, startCommand } = require('./lib/start')
10
10
  const symbols = require('./lib/worker/symbols')
11
11
  const { loadConfig, getRuntimeLogsDir } = require('./lib/utils')
12
12
 
13
+ const platformaticVersion = require('./package.json').version
14
+
13
15
  module.exports.buildServer = buildServer
14
16
  module.exports.buildRuntime = buildRuntime
15
17
  module.exports.compile = compile
@@ -24,3 +26,4 @@ module.exports.startCommand = startCommand
24
26
  module.exports.symbols = symbols
25
27
  module.exports.Runtime = Runtime
26
28
  module.exports.wrapConfigInRuntimeConfig = wrapConfigInRuntimeConfig
29
+ module.exports.version = platformaticVersion
package/lib/config.js CHANGED
@@ -8,18 +8,36 @@ const ConfigManager = require('@platformatic/config')
8
8
  const errors = require('./errors')
9
9
  const { schema } = require('./schema')
10
10
  const upgrade = require('./upgrade')
11
+ const { parseArgs } = require('node:util')
11
12
 
12
- const kServicesAutoloaded = Symbol('plt.servicesAutoloaded')
13
-
14
- async function _transformConfig (configManager) {
13
+ async function _transformConfig (configManager, args) {
15
14
  const config = configManager.current
16
- const services = config.services ?? []
17
15
 
18
- if (config.autoload) {
19
- if (config.services && !config.services[kServicesAutoloaded]) {
20
- throw new errors.InvalidAutoloadWithServicesError()
16
+ let services
17
+ if (config.web?.length) {
18
+ if (config.services?.length) {
19
+ throw new errors.InvalidServicesWithWebError()
21
20
  }
22
21
 
22
+ services = config.web
23
+ } else {
24
+ services = config.services ?? []
25
+ }
26
+
27
+ const watchType = typeof config.watch
28
+ if (watchType === 'string') {
29
+ config.watch = config.watch === 'true'
30
+ } else if (watchType === 'undefined') {
31
+ const { values } = parseArgs({
32
+ args,
33
+ strict: false,
34
+ options: { production: { type: 'boolean', short: 'p', default: false } }
35
+ })
36
+
37
+ config.watch = !values.production
38
+ }
39
+
40
+ if (config.autoload) {
23
41
  const { exclude = [], mappings = {} } = config.autoload
24
42
  let { path } = config.autoload
25
43
 
@@ -41,13 +59,13 @@ async function _transformConfig (configManager) {
41
59
  const mapping = mappings[entry.name] ?? {}
42
60
  const id = mapping.id ?? entry.name
43
61
  const entryPath = join(path, entry.name)
44
- const configFilename = mapping.config ?? await ConfigManager.findConfigFile(entryPath)
45
62
 
46
- if (typeof configFilename !== 'string') {
47
- throw new errors.NoConfigFileFoundError(id)
48
- }
63
+ let config
64
+ const configFilename = mapping.config ?? (await ConfigManager.findConfigFile(entryPath))
49
65
 
50
- const config = join(entryPath, configFilename)
66
+ if (typeof configFilename === 'string') {
67
+ config = join(entryPath, configFilename)
68
+ }
51
69
 
52
70
  const service = { id, config, path: entryPath, useHttp: !!mapping.useHttp }
53
71
  const existingServiceId = services.findIndex(service => service.id === id)
@@ -72,11 +90,14 @@ async function _transformConfig (configManager) {
72
90
  service.config = pathResolve(service.path, service.config)
73
91
  }
74
92
  service.entrypoint = service.id === config.entrypoint
75
- service.watch = !!config.watch
76
93
  service.dependencies = []
77
94
  service.localServiceEnvVars = new Map()
78
95
  service.localUrl = `http://${service.id}.plt.local`
79
96
 
97
+ if (typeof service.watch === 'undefined') {
98
+ service.watch = config.watch
99
+ }
100
+
80
101
  if (service.entrypoint) {
81
102
  hasValidEntrypoint = true
82
103
  }
@@ -89,7 +110,7 @@ async function _transformConfig (configManager) {
89
110
  }
90
111
 
91
112
  configManager.current.services = services
92
- configManager.current.services[kServicesAutoloaded] = true
113
+ configManager.current.web = undefined
93
114
 
94
115
  if (configManager.current.restartOnError === true) {
95
116
  configManager.current.restartOnError = 5000
@@ -111,12 +132,12 @@ platformaticRuntime.configManagerConfig = {
111
132
  useDefaults: true,
112
133
  coerceTypes: true,
113
134
  allErrors: true,
114
- strict: false,
135
+ strict: false
115
136
  },
116
- async transformConfig () {
117
- await _transformConfig(this)
137
+ async transformConfig (args) {
138
+ await _transformConfig(this, args)
118
139
  },
119
- upgrade,
140
+ upgrade
120
141
  }
121
142
 
122
143
  async function wrapConfigInRuntimeConfig ({ configManager, args }) {
@@ -140,9 +161,9 @@ async function wrapConfigInRuntimeConfig ({ configManager, args }) {
140
161
  {
141
162
  id: serviceId,
142
163
  path: configManager.dirname,
143
- config: configManager.fullPath,
144
- },
145
- ],
164
+ config: configManager.fullPath
165
+ }
166
+ ]
146
167
  }
147
168
  const cm = new ConfigManager({
148
169
  source: wrapperConfig,
@@ -151,9 +172,11 @@ async function wrapConfigInRuntimeConfig ({ configManager, args }) {
151
172
  useDefaults: true,
152
173
  coerceTypes: true,
153
174
  allErrors: true,
154
- strict: false,
175
+ strict: false
155
176
  },
156
- transformConfig () { return _transformConfig(this) },
177
+ transformConfig (args) {
178
+ return _transformConfig(this, args)
179
+ }
157
180
  })
158
181
 
159
182
  await cm.parseAndValidate()
@@ -205,7 +228,7 @@ function parseInspectorOptions (configManager) {
205
228
  host,
206
229
  port,
207
230
  breakFirstLine: hasInspectBrk,
208
- watchDisabled: !!current.watch,
231
+ watchDisabled: !!current.watch
209
232
  }
210
233
 
211
234
  current.watch = false
@@ -215,5 +238,5 @@ function parseInspectorOptions (configManager) {
215
238
  module.exports = {
216
239
  parseInspectorOptions,
217
240
  platformaticRuntime,
218
- wrapConfigInRuntimeConfig,
241
+ wrapConfigInRuntimeConfig
219
242
  }
package/lib/errors.js CHANGED
@@ -20,7 +20,7 @@ module.exports = {
20
20
  ConfigPathMustBeStringError: createError(`${ERROR_PREFIX}_CONFIG_PATH_MUST_BE_STRING`, 'Config path must be a string'),
21
21
  NoConfigFileFoundError: createError(`${ERROR_PREFIX}_NO_CONFIG_FILE_FOUND`, "No config file found for service '%s'"),
22
22
  InvalidEntrypointError: createError(`${ERROR_PREFIX}_INVALID_ENTRYPOINT`, "Invalid entrypoint: '%s' does not exist"),
23
- InvalidAutoloadWithServicesError: createError(`${ERROR_PREFIX}_INVALID_AUTOLOAD_WITH_SERVICES`, 'Autoload cannot be used when services is defined'),
23
+ InvalidServicesWithWebError: createError(`${ERROR_PREFIX}_INVALID_SERVICES_WITH_WEB`, 'The "services" property cannot be used when the "web" property is also defined'),
24
24
  MissingDependencyError: createError(`${ERROR_PREFIX}_MISSING_DEPENDENCY`, 'Missing dependency: "%s"'),
25
25
  InspectAndInspectBrkError: createError(`${ERROR_PREFIX}_INSPECT_AND_INSPECT_BRK`, '--inspect and --inspect-brk cannot be used together'),
26
26
  InspectorPortError: createError(`${ERROR_PREFIX}_INSPECTOR_PORT`, 'Inspector port must be 0 or in range 1024 to 65535'),
@@ -162,15 +162,15 @@ class RuntimeGenerator extends BaseGenerator {
162
162
  entrypoint: this.entryPoint.name,
163
163
  watch: true,
164
164
  autoload: {
165
- path: 'services',
165
+ path: this.config.autoload || 'services',
166
166
  exclude: ['docs'],
167
167
  },
168
+ logger: {
169
+ level: '{PLT_SERVER_LOGGER_LEVEL}',
170
+ },
168
171
  server: {
169
172
  hostname: '{PLT_SERVER_HOSTNAME}',
170
- port: '{PORT}',
171
- logger: {
172
- level: '{PLT_SERVER_LOGGER_LEVEL}',
173
- },
173
+ port: '{PORT}'
174
174
  },
175
175
  managementApi: '{PLT_MANAGEMENT_API}',
176
176
  }
@@ -254,7 +254,13 @@ class RuntimeGenerator extends BaseGenerator {
254
254
  // set default config
255
255
  service.setConfig()
256
256
  }
257
- service.setTargetDirectory(join(this.targetDirectory, 'services', service.config.serviceName))
257
+ let basePath
258
+ if (this.existingConfig) {
259
+ basePath = this.existingConfig.autoload.path
260
+ } else {
261
+ basePath = join(this.targetDirectory, this.config.autoload || 'services')
262
+ }
263
+ service.setTargetDirectory(join(basePath, service.config.serviceName))
258
264
  })
259
265
  }
260
266
 
package/lib/logger.js CHANGED
@@ -7,7 +7,7 @@ const pino = require('pino')
7
7
  const pretty = require('pino-pretty')
8
8
 
9
9
  function createLogger (config, runtimeLogsDir) {
10
- const loggerConfig = { ...config.server?.logger }
10
+ const loggerConfig = { ...config.logger }
11
11
  const cliStream = isatty(1) ? pretty() : pino.destination(1)
12
12
 
13
13
  if (!config.managementApi) {
@@ -31,7 +31,7 @@ async function managementApiPlugin (app, opts) {
31
31
  })
32
32
 
33
33
  app.get('/env', async () => {
34
- return process.env
34
+ return { ...process.env, ...runtime.getRuntimeEnv() }
35
35
  })
36
36
 
37
37
  app.post('/stop', async () => {
@@ -39,8 +39,8 @@ async function managementApiPlugin (app, opts) {
39
39
  await runtime.close(true)
40
40
  })
41
41
 
42
- app.post('/reload', async () => {
43
- app.log.debug('reload services')
42
+ app.post('/restart', async () => {
43
+ app.log.debug('restart services')
44
44
  await runtime.restart()
45
45
  })
46
46
 
@@ -60,6 +60,12 @@ async function managementApiPlugin (app, opts) {
60
60
  return runtime.getServiceConfig(id)
61
61
  })
62
62
 
63
+ app.get('/services/:id/env', async request => {
64
+ const { id } = request.params
65
+ app.log.debug('get service config', { id })
66
+ return runtime.getServiceEnv(id)
67
+ })
68
+
63
69
  app.get('/services/:id/openapi-schema', async request => {
64
70
  const { id } = request.params
65
71
  app.log.debug('get openapi-schema', { id })
@@ -98,11 +104,14 @@ async function managementApiPlugin (app, opts) {
98
104
  url: requestUrl || '/',
99
105
  headers: request.headers,
100
106
  query: request.query,
101
- body: request.body,
107
+ body: request.body
102
108
  }
103
109
 
104
110
  const res = await runtime.inject(id, injectParams)
105
111
 
112
+ delete res.headers['content-length']
113
+ delete res.headers['transfer-encoding']
114
+
106
115
  reply.code(res.statusCode).headers(res.headers).send(res.body)
107
116
  })
108
117