@platformatic/control 2.0.0-alpha.15 → 2.0.0-alpha.17

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
@@ -6,6 +6,7 @@ const ERROR_PREFIX = 'PLT_CTR'
6
6
 
7
7
  module.exports = {
8
8
  RuntimeNotFound: createError(`${ERROR_PREFIX}_RUNTIME_NOT_FOUND`, 'Runtime not found.'),
9
+ ServiceNotFound: createError(`${ERROR_PREFIX}_SERVICE_NOT_FOUND`, 'Service not found.'),
9
10
  MissingRuntimeIdentifier: createError(`${ERROR_PREFIX}_MISSING_RUNTIME_IDENTIFIER`, 'Runtime name or PID is required.'),
10
11
  MissingRequestURL: createError(`${ERROR_PREFIX}_MISSING_REQUEST_URL`, 'Request URL is required.'),
11
12
  FailedToGetRuntimeMetadata: createError(`${ERROR_PREFIX}_FAILED_TO_GET_RUNTIME_METADATA`, 'Failed to get runtime metadata %s.'),
@@ -17,6 +18,7 @@ module.exports = {
17
18
  FailedToStopRuntime: createError(`${ERROR_PREFIX}_FAILED_TO_STOP_RUNTIME`, 'Failed to stop the runtime %s.'),
18
19
  FailedToReloadRuntime: createError(`${ERROR_PREFIX}_FAILED_TO_RELOAD_RUNTIME`, 'Failed to reload the runtime %s.'),
19
20
  FailedToGetRuntimeConfig: createError(`${ERROR_PREFIX}_FAILED_TO_GET_RUNTIME_CONFIG`, 'Failed to get runtime config %s.'),
21
+ FailedToGetRuntimeServiceEnv: createError(`${ERROR_PREFIX}_FAILED_TO_GET_RUNTIME_SERVICE_ENV`, 'Failed to get runtime service environment variables %s.'),
20
22
  FailedToGetRuntimeServiceConfig: createError(`${ERROR_PREFIX}_FAILED_TO_GET_RUNTIME_SERVICE_CONFIG`, 'Failed to get runtime service config %s.'),
21
23
  FailedToGetRuntimeHistoryLogs: createError(`${ERROR_PREFIX}_FAILED_TO_GET_HISTORY_LOGS`, 'Failed to get history logs %s.'),
22
24
  FailedToGetRuntimeAllLogs: createError(`${ERROR_PREFIX}_FAILED_TO_GET_RUNTIME_ALL_LOGS`, 'Failed to get runtime all logs %s.'),
package/lib/reload.js CHANGED
@@ -8,16 +8,16 @@ async function reloadRuntimeCommand (argv) {
8
8
  args: argv,
9
9
  options: {
10
10
  pid: { type: 'string', short: 'p' },
11
- name: { type: 'string', short: 'n' },
11
+ name: { type: 'string', short: 'n' }
12
12
  },
13
- strict: false,
13
+ strict: false
14
14
  }).values
15
15
 
16
16
  const client = new RuntimeApiClient()
17
17
  const runtime = await client.getMatchingRuntime(args)
18
18
 
19
- await client.reloadRuntime(runtime.pid)
20
- console.log(`Reloaded runtime "${runtime.packageName}".`)
19
+ const child = await client.reloadRuntime(runtime.pid)
20
+ console.log(`Reloaded runtime "${runtime.packageName}". The new PID is ${child.pid}.`)
21
21
 
22
22
  await client.close()
23
23
  }
@@ -62,7 +62,7 @@ class RuntimeApiClient {
62
62
 
63
63
  const { statusCode, body } = await client.request({
64
64
  path: '/api/v1/metadata',
65
- method: 'GET',
65
+ method: 'GET'
66
66
  })
67
67
 
68
68
  if (statusCode !== 200) {
@@ -79,7 +79,7 @@ class RuntimeApiClient {
79
79
 
80
80
  const { statusCode, body } = await client.request({
81
81
  path: '/api/v1/services',
82
- method: 'GET',
82
+ method: 'GET'
83
83
  })
84
84
 
85
85
  if (statusCode !== 200) {
@@ -91,38 +91,49 @@ class RuntimeApiClient {
91
91
  return runtimeServices
92
92
  }
93
93
 
94
- async getRuntimeServiceConfig (pid, serviceId) {
94
+ async getRuntimeConfig (pid) {
95
95
  const client = this.#getUndiciClient(pid)
96
96
 
97
97
  const { statusCode, body } = await client.request({
98
- path: `/api/v1/services/${serviceId}/config`,
99
- method: 'GET',
98
+ path: '/api/v1/config',
99
+ method: 'GET'
100
100
  })
101
101
 
102
102
  if (statusCode !== 200) {
103
103
  const error = await body.text()
104
- throw new errors.FailedToGetRuntimeServiceConfig(error)
104
+ throw new errors.FailedToGetRuntimeConfig(error)
105
105
  }
106
106
 
107
- const serviceConfig = await body.json()
108
- return serviceConfig
107
+ const runtimeConfig = await body.json()
108
+ return runtimeConfig
109
109
  }
110
110
 
111
- async getRuntimeConfig (pid) {
111
+ async getRuntimeServiceConfig (pid, serviceId) {
112
112
  const client = this.#getUndiciClient(pid)
113
113
 
114
114
  const { statusCode, body } = await client.request({
115
- path: '/api/v1/config',
116
- method: 'GET',
115
+ path: `/api/v1/services/${serviceId}/config`,
116
+ method: 'GET'
117
117
  })
118
118
 
119
119
  if (statusCode !== 200) {
120
120
  const error = await body.text()
121
- throw new errors.FailedToGetRuntimeConfig(error)
121
+ let jsonError
122
+ try {
123
+ jsonError = JSON.parse(error)
124
+ } catch {
125
+ // No-op
126
+ }
127
+
128
+ if (jsonError?.code === 'PLT_RUNTIME_SERVICE_NOT_FOUND') {
129
+ throw new errors.ServiceNotFound(error)
130
+ }
131
+
132
+ throw new errors.FailedToGetRuntimeServiceConfig(error)
122
133
  }
123
134
 
124
- const runtimeConfig = await body.json()
125
- return runtimeConfig
135
+ const serviceConfig = await body.json()
136
+ return serviceConfig
126
137
  }
127
138
 
128
139
  async getRuntimeEnv (pid) {
@@ -130,7 +141,7 @@ class RuntimeApiClient {
130
141
 
131
142
  const { statusCode, body } = await client.request({
132
143
  path: '/api/v1/env',
133
- method: 'GET',
144
+ method: 'GET'
134
145
  })
135
146
 
136
147
  if (statusCode !== 200) {
@@ -142,22 +153,57 @@ class RuntimeApiClient {
142
153
  return runtimeEnv
143
154
  }
144
155
 
145
- async restartRuntime (pid, options = {}) {
156
+ async getRuntimeServiceEnv (pid, serviceId) {
157
+ const client = this.#getUndiciClient(pid)
158
+
159
+ const { statusCode, body } = await client.request({
160
+ path: `/api/v1/services/${serviceId}/env`,
161
+ method: 'GET'
162
+ })
163
+
164
+ if (statusCode !== 200) {
165
+ const error = await body.text()
166
+ let jsonError
167
+ try {
168
+ jsonError = JSON.parse(error)
169
+ } catch {
170
+ // No-op
171
+ }
172
+
173
+ if (jsonError?.code === 'PLT_RUNTIME_SERVICE_NOT_FOUND') {
174
+ throw new errors.ServiceNotFound(error)
175
+ }
176
+
177
+ throw new errors.FailedToGetRuntimeServiceEnv(error)
178
+ }
179
+
180
+ const serviceConfig = await body.json()
181
+ return serviceConfig
182
+ }
183
+
184
+ async reloadRuntime (pid, options = {}) {
146
185
  const runtime = await this.getMatchingRuntime({ pid })
147
186
 
148
187
  await this.stopRuntime(pid)
149
188
 
150
189
  const [startCommand, ...startArgs] = runtime.argv
151
- const child = spawn(startCommand, startArgs, { cwd: runtime.cwd, ...options })
190
+ const child = spawn(startCommand, startArgs, { cwd: runtime.cwd, ...options, stdio: 'ignore', detached: true })
191
+
192
+ await new Promise((resolve, reject) => {
193
+ child.on('spawn', resolve)
194
+ child.on('error', reject)
195
+ })
196
+
197
+ child.unref()
152
198
  return child
153
199
  }
154
200
 
155
- async reloadRuntime (pid) {
201
+ async restartRuntime (pid) {
156
202
  const client = this.#getUndiciClient(pid)
157
203
 
158
204
  const { statusCode, body } = await client.request({
159
- path: '/api/v1/reload',
160
- method: 'POST',
205
+ path: '/api/v1/restart',
206
+ method: 'POST'
161
207
  })
162
208
 
163
209
  if (statusCode !== 200) {
@@ -171,7 +217,7 @@ class RuntimeApiClient {
171
217
 
172
218
  const { statusCode, body } = await client.request({
173
219
  path: '/api/v1/stop',
174
- method: 'POST',
220
+ method: 'POST'
175
221
  })
176
222
 
177
223
  if (statusCode !== 200) {
@@ -210,7 +256,7 @@ class RuntimeApiClient {
210
256
  const { statusCode, body } = await client.request({
211
257
  path: '/api/v1/logs/' + logsId,
212
258
  method: 'GET',
213
- query: { pid: runtimePID },
259
+ query: { pid: runtimePID }
214
260
  })
215
261
 
216
262
  if (statusCode !== 200) {
@@ -228,7 +274,7 @@ class RuntimeApiClient {
228
274
  const { statusCode, body } = await client.request({
229
275
  path: '/api/v1/logs/all',
230
276
  method: 'GET',
231
- query: { pid: runtimePID },
277
+ query: { pid: runtimePID }
232
278
  })
233
279
 
234
280
  if (statusCode !== 200) {
@@ -246,7 +292,7 @@ class RuntimeApiClient {
246
292
  const { statusCode, body } = await client.request({
247
293
  path: '/api/v1/logs/indexes',
248
294
  method: 'GET',
249
- query: { all },
295
+ query: { all }
250
296
  })
251
297
 
252
298
  if (statusCode !== 200) {
@@ -268,7 +314,7 @@ class RuntimeApiClient {
268
314
  method: options.method,
269
315
  headers: options.headers,
270
316
  query: options.query,
271
- body: options.body,
317
+ body: options.body
272
318
  })
273
319
  return response
274
320
  }
@@ -289,7 +335,7 @@ class RuntimeApiClient {
289
335
  undiciClient = new Client(
290
336
  {
291
337
  hostname: 'localhost',
292
- protocol: 'http:',
338
+ protocol: 'http:'
293
339
  },
294
340
  { socketPath }
295
341
  )
@@ -312,10 +358,15 @@ class RuntimeApiClient {
312
358
  } catch {
313
359
  return []
314
360
  }
315
- const runtimeDirs = await readdir(PLATFORMATIC_TMP_DIR)
361
+
362
+ const runtimeDirs = await readdir(PLATFORMATIC_TMP_DIR, { withFileTypes: true })
316
363
  const runtimePIDs = []
317
- for (const runtimeDirName of runtimeDirs) {
318
- runtimePIDs.push(parseInt(runtimeDirName))
364
+
365
+ for (const runtimeDir of runtimeDirs) {
366
+ // Only consider directory that can be a PID
367
+ if (runtimeDir.isDirectory() && runtimeDir.name.match(/^\d+$/)) {
368
+ runtimePIDs.push(parseInt(runtimeDir.name))
369
+ }
319
370
  }
320
371
  return runtimePIDs
321
372
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/control",
3
- "version": "2.0.0-alpha.15",
3
+ "version": "2.0.0-alpha.17",
4
4
  "description": "Platformatic Control",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -25,8 +25,8 @@
25
25
  "split2": "^4.2.0",
26
26
  "tsd": "^0.31.0",
27
27
  "typescript": "^5.5.4",
28
- "@platformatic/runtime": "2.0.0-alpha.15",
29
- "@platformatic/service": "2.0.0-alpha.15"
28
+ "@platformatic/service": "2.0.0-alpha.17",
29
+ "@platformatic/runtime": "2.0.0-alpha.17"
30
30
  },
31
31
  "dependencies": {
32
32
  "@fastify/error": "^4.0.0",
@@ -37,7 +37,7 @@
37
37
  "table": "^6.8.1",
38
38
  "undici": "^6.9.0",
39
39
  "ws": "^8.16.0",
40
- "@platformatic/utils": "2.0.0-alpha.15"
40
+ "@platformatic/utils": "2.0.0-alpha.17"
41
41
  },
42
42
  "scripts": {
43
43
  "test": "pnpm run lint && pnpm run unit",