wattpm 3.26.0 → 3.28.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/index.js CHANGED
@@ -13,6 +13,7 @@ import { logsCommand } from './lib/commands/logs.js'
13
13
  import { applicationsCommand, configCommand, envCommand, psCommand } from './lib/commands/management.js'
14
14
  import { metricsCommand } from './lib/commands/metrics.js'
15
15
  import { pprofCommand } from './lib/commands/pprof.js'
16
+ import { replCommand } from './lib/commands/repl.js'
16
17
  import { version } from './lib/schema.js'
17
18
 
18
19
  export * from './lib/schema.js'
@@ -106,6 +107,9 @@ export async function main () {
106
107
  case 'pprof':
107
108
  command = pprofCommand
108
109
  break
110
+ case 'repl':
111
+ command = replCommand
112
+ break
109
113
  case 'applications:add':
110
114
  command = applicationsAddCommand
111
115
  break
@@ -19,7 +19,8 @@ async function loadCommands () {
19
19
  'logs',
20
20
  'inject',
21
21
  'metrics',
22
- 'pprof'
22
+ 'pprof',
23
+ 'repl'
23
24
  ]) {
24
25
  const category = await import(`./${file}.js`)
25
26
  Object.assign(commands, category.help)
@@ -0,0 +1,107 @@
1
+ import { getMatchingRuntime, RuntimeApiClient } from '@platformatic/control'
2
+ import { ensureLoggableError, logFatalError, parseArgs } from '@platformatic/foundation'
3
+ import { createInterface } from 'node:readline'
4
+
5
+ export async function replCommand (logger, args) {
6
+ const { positionals: allPositionals } = parseArgs(args, {}, false)
7
+
8
+ const client = new RuntimeApiClient()
9
+ try {
10
+ const [runtime, positionals] = await getMatchingRuntime(client, allPositionals)
11
+ let application = positionals[0]
12
+
13
+ if (!application) {
14
+ const applicationsInfo = await client.getRuntimeApplications(runtime.pid)
15
+ application = applicationsInfo.entrypoint
16
+ }
17
+
18
+ const ws = client.getRuntimeApplicationRepl(runtime.pid, application)
19
+
20
+ await new Promise((resolve, reject) => {
21
+ ws.on('open', resolve)
22
+ ws.on('error', reject)
23
+ })
24
+
25
+ // Set up readline for stdin
26
+ const rl = createInterface({
27
+ input: process.stdin,
28
+ output: process.stdout,
29
+ terminal: process.stdin.isTTY
30
+ })
31
+
32
+ // Forward stdin to WebSocket
33
+ rl.on('line', (line) => {
34
+ ws.send(line + '\n')
35
+ })
36
+
37
+ // Forward WebSocket output to stdout
38
+ ws.on('message', (data) => {
39
+ process.stdout.write(data.toString())
40
+ })
41
+
42
+ // Handle cleanup
43
+ function onClose () {
44
+ rl.close()
45
+ ws.close()
46
+ client.close()
47
+ process.exit(0)
48
+ }
49
+
50
+ process.on('SIGINT', onClose)
51
+ process.on('SIGTERM', onClose)
52
+
53
+ ws.on('close', () => {
54
+ rl.close()
55
+ client.close()
56
+ process.exit(0)
57
+ })
58
+
59
+ ws.on('error', (error) => {
60
+ logger.error({ error: ensureLoggableError(error) }, 'WebSocket error')
61
+ rl.close()
62
+ client.close()
63
+ process.exit(1)
64
+ })
65
+ } catch (error) {
66
+ if (error.code === 'PLT_CTR_RUNTIME_NOT_FOUND') {
67
+ return logFatalError(logger, 'Cannot find a matching runtime.')
68
+ } else if (error.code === 'PLT_CTR_APPLICATION_NOT_FOUND') {
69
+ return logFatalError(logger, 'Cannot find a matching application.')
70
+ } else {
71
+ return logFatalError(
72
+ logger,
73
+ { error: ensureLoggableError(error) },
74
+ `Cannot start REPL: ${error.message}`
75
+ )
76
+ }
77
+ }
78
+ }
79
+
80
+ export const help = {
81
+ repl: {
82
+ usage: 'repl [id] [application]',
83
+ description: 'Starts a REPL session inside a running application',
84
+ args: [
85
+ {
86
+ name: 'id',
87
+ description:
88
+ 'The process ID or the name of the application (it can be omitted only if there is a single application running)'
89
+ },
90
+ {
91
+ name: 'application',
92
+ description: 'The application name (the default is the entrypoint)'
93
+ }
94
+ ],
95
+ footer: `
96
+ The REPL session runs inside the worker thread of the specified application.
97
+ You have access to:
98
+ - app: The Fastify application instance (for service-based apps)
99
+ - capability: The application capability object with configuration and methods
100
+ - platformatic: The global platformatic object
101
+ - config: The application configuration
102
+ - logger: The application logger
103
+
104
+ Press Ctrl+C or type .exit to exit the REPL.
105
+ `
106
+ }
107
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wattpm",
3
- "version": "3.26.0",
3
+ "version": "3.28.0-alpha.1",
4
4
  "description": "The Node.js Application Server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -29,9 +29,9 @@
29
29
  "pino-pretty": "^13.0.0",
30
30
  "split2": "^4.2.0",
31
31
  "table": "^6.8.2",
32
- "@platformatic/control": "3.26.0",
33
- "@platformatic/runtime": "3.26.0",
34
- "@platformatic/foundation": "3.26.0"
32
+ "@platformatic/control": "3.28.0-alpha.1",
33
+ "@platformatic/foundation": "3.28.0-alpha.1",
34
+ "@platformatic/runtime": "3.28.0-alpha.1"
35
35
  },
36
36
  "devDependencies": {
37
37
  "cleaner-spec-reporter": "^0.5.0",
@@ -42,7 +42,7 @@
42
42
  "neostandard": "^0.12.0",
43
43
  "typescript": "^5.5.4",
44
44
  "undici": "^7.0.0",
45
- "@platformatic/node": "3.26.0"
45
+ "@platformatic/node": "3.28.0-alpha.1"
46
46
  },
47
47
  "engines": {
48
48
  "node": ">=22.19.0"
package/schema.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$id": "https://schemas.platformatic.dev/wattpm/3.26.0.json",
2
+ "$id": "https://schemas.platformatic.dev/wattpm/3.28.0-alpha.1.json",
3
3
  "$schema": "http://json-schema.org/draft-07/schema#",
4
4
  "title": "Platformatic Runtime Config",
5
5
  "type": "object",