@interopio/gateway-server 0.23.0 → 0.24.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/bin/gateway-server.cjs +289 -118
- package/changelog.md +15 -0
- package/dist/gateway-ent.cjs +1 -1
- package/dist/gateway-ent.cjs.map +3 -3
- package/dist/gateway-ent.js +2 -2
- package/dist/gateway-ent.js.map +3 -3
- package/dist/index.cjs +7 -7
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +7 -7
- package/dist/index.js.map +4 -4
- package/dist/tools.cjs +15 -1
- package/dist/tools.cjs.map +4 -4
- package/dist/tools.js +15 -1
- package/dist/tools.js.map +4 -4
- package/package.json +4 -4
- package/types/build.d.ts +63 -0
- package/types/tools.d.ts +1 -0
package/bin/gateway-server.cjs
CHANGED
|
@@ -8,90 +8,216 @@ const { configure } = require('@interopio/gateway/logging/core');
|
|
|
8
8
|
// import { GatewayServer } from './src/index.ts';
|
|
9
9
|
// import { mkcert, argon2, manage } from './src/tools/index.ts';
|
|
10
10
|
|
|
11
|
-
const { mkcert, argon2, manage } = require('@interopio/gateway-server/tools');
|
|
11
|
+
const { mkcert, argon2, manage, build } = require('@interopio/gateway-server/tools');
|
|
12
12
|
const { GatewayServer } = require('@interopio/gateway-server');
|
|
13
13
|
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Declarative command registry — drives both help text and parseArgs calls
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
const commands = {
|
|
19
|
+
run: {
|
|
20
|
+
description: 'Start the gateway server',
|
|
21
|
+
options: {
|
|
22
|
+
port: { type: 'string', short: 'p', help: 'Port or port range (default: 0 i.e. random)', example: '8385, 8000-8100, 3000,4000-4050' },
|
|
23
|
+
host: { type: 'string', short: 'H', help: 'Network address to bind to', example: 'localhost, 127.0.0.1, 0.0.0.0, ::1' },
|
|
24
|
+
user: { type: 'string', short: 'u', help: 'Enable basic auth and set admin username' },
|
|
25
|
+
auth: { type: 'boolean', help: 'Enable/disable authentication (--no-auth overrides config)' },
|
|
26
|
+
ssl: { type: 'boolean', short: 'S', help: 'Enable HTTPS (auto-generates certs if needed)' },
|
|
27
|
+
tls: { type: 'boolean', help: 'Alias for --ssl' },
|
|
28
|
+
cert: { type: 'string', help: 'SSL/TLS certificate file (default: ./gateway-server.crt)' },
|
|
29
|
+
key: { type: 'string', help: 'SSL/TLS private key file (default: ./gateway-server.key)' },
|
|
30
|
+
ca: { type: 'string', help: 'CA certificate file (default: ./gateway-ca.crt)' },
|
|
31
|
+
'ca-key': { type: 'string', help: 'CA private key file (default: ./gateway-ca.key)' },
|
|
32
|
+
gateway: { type: 'boolean', short: 'g', help: 'Enable/disable gateway endpoint (--no-gateway)' },
|
|
33
|
+
static: { type: 'string', short: 's', multiple: true, help: 'Serve static files from location' },
|
|
34
|
+
config: { type: 'string', short: 'c', help: 'Server configuration file (JSON)' },
|
|
35
|
+
debug: { type: 'boolean', help: 'Enable debug logging (default: info)' },
|
|
36
|
+
},
|
|
37
|
+
allowNegative: true,
|
|
38
|
+
examples: [
|
|
39
|
+
'gateway-server run -p 3000',
|
|
40
|
+
'gateway-server run -u admin --port 8385,8388 --debug',
|
|
41
|
+
'gateway-server run -p 8443 --ssl --user admin --gateway',
|
|
42
|
+
'gateway-server run --port 42443 --tls --ca-key ./ssl/ca.key --host example.com --gateway',
|
|
43
|
+
'gateway-server run -p 3000 --static ./public --config ./server-config.json',
|
|
44
|
+
'gateway-server run --config ./server-config.json --no-gateway --no-ssl --no-auth',
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
build: {
|
|
48
|
+
description: 'Build a Single Executable Application (SEA)',
|
|
49
|
+
positionals: '[entryPoints...]',
|
|
50
|
+
options: {
|
|
51
|
+
'app-name': { type: 'string', help: 'Base name for the executable (default: package.json name)' },
|
|
52
|
+
'app-version': { type: 'string', help: 'App version in output dir name (default: package.json version)' },
|
|
53
|
+
executable: { type: 'string', help: 'Path to the Node.js binary (default: current node)' },
|
|
54
|
+
outdir: { type: 'string', short: 'o', help: 'Output directory for build artifacts (default: ./build)' },
|
|
55
|
+
},
|
|
56
|
+
examples: [
|
|
57
|
+
'gateway-server build',
|
|
58
|
+
'gateway-server build --app-version 1.2.3',
|
|
59
|
+
'gateway-server build ./src/main.cjs --app-name io-bridge --executable /usr/local/bin/node22 --app-version 2.0.0',
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
manage: {
|
|
63
|
+
description: 'Send management commands to a running gateway server',
|
|
64
|
+
positionals: '<command> [key=value... or json]',
|
|
65
|
+
options: {
|
|
66
|
+
path: { type: 'string', help: 'Gateway control socket (named pipe / Unix socket)', example: '\\\\\\\\.\\\\pipe\\\\glue42-gateway-xxx, /tmp/gateway.sock' },
|
|
67
|
+
port: { type: 'string', short: 'p', help: 'TCP port of the management server' },
|
|
68
|
+
timeout: { type: 'string', help: 'Connection timeout in ms (default: 5000)' },
|
|
69
|
+
},
|
|
70
|
+
examples: [
|
|
71
|
+
'gateway-server manage --path \\\\.\\pipe\\glue42-gateway-xxx info',
|
|
72
|
+
'gateway-server manage --path \\\\.\\pipe\\glue42-gateway-xxx shutdown',
|
|
73
|
+
'gateway-server manage --path \\\\.\\pipe\\glue42-gateway-xxx custom-cmd key1=value1 count=42',
|
|
74
|
+
'gateway-server manage --path \\\\.\\pipe\\glue42-gateway-xxx \'{"command":"update-auth","type":"basic"}\'',
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
passwd: {
|
|
78
|
+
description: 'Generate password hash (default: Argon2)',
|
|
79
|
+
options: {
|
|
80
|
+
stdin: { type: 'boolean', help: 'Read password from stdin (for piping)' },
|
|
81
|
+
},
|
|
82
|
+
examples: [
|
|
83
|
+
'gateway-server passwd',
|
|
84
|
+
'echo "mySecret123" | gateway-server passwd --stdin',
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
mkcert: {
|
|
88
|
+
description: 'Generate client/server certificate signed by Dev CA',
|
|
89
|
+
positionals: '[name...]',
|
|
90
|
+
options: {
|
|
91
|
+
client: { type: 'boolean', help: 'Generate client certificate (default: server)' },
|
|
92
|
+
user: { type: 'string', short: 'u', help: 'Common Name (default: dev-user, --client only)' },
|
|
93
|
+
ca: { type: 'string', help: 'CA certificate file (default: ./gateway-ca.crt)' },
|
|
94
|
+
'ca-key': { type: 'string', help: 'CA private key file (default: ./gateway-ca.key)' },
|
|
95
|
+
key: { type: 'string', help: 'Output private key file' },
|
|
96
|
+
cert: { type: 'string', help: 'Output certificate file' },
|
|
97
|
+
},
|
|
98
|
+
examples: [
|
|
99
|
+
'gateway-server mkcert',
|
|
100
|
+
'gateway-server mkcert localhost 127.0.0.1 IP:192.168.1.100',
|
|
101
|
+
'gateway-server mkcert --client EMAIL:john.doe@example.com',
|
|
102
|
+
'gateway-server mkcert example.com *.example.com --key ./gateway-server.key --cert ./gateway-server.crt',
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
// Help text generator
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
|
|
111
|
+
function formatOption(name, opt, negatable, col) {
|
|
112
|
+
const shortFlag = opt.short ? `-${opt.short}, ` : ' ';
|
|
113
|
+
const flag = (opt.type === 'boolean' && negatable) ? `--[no-]${name}` : `--${name}`;
|
|
114
|
+
const argHint = opt.type === 'string' ? ` <${name.replace(/-/g, '_')}>` : '';
|
|
115
|
+
const left = ` ${shortFlag}${flag}${argHint}`;
|
|
116
|
+
const pad = Math.max(2, col - left.length);
|
|
117
|
+
let line = left + ' '.repeat(pad) + (opt.help || '');
|
|
118
|
+
if (opt.example) {
|
|
119
|
+
line += `\n${' '.repeat(col)}examples: ${opt.example}`;
|
|
120
|
+
}
|
|
121
|
+
return line;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Compute column width from a set of options. */
|
|
125
|
+
function optionColumnWidth(options, negatable) {
|
|
126
|
+
let max = 0;
|
|
127
|
+
for (const [name, opt] of Object.entries(options)) {
|
|
128
|
+
const shortFlag = opt.short ? `-X, ` : ' ';
|
|
129
|
+
const flag = (opt.type === 'boolean' && negatable) ? `--[no-]${name}` : `--${name}`;
|
|
130
|
+
const argHint = opt.type === 'string' ? ` <${name.replace(/-/g, '_')}>` : '';
|
|
131
|
+
max = Math.max(max, ` ${shortFlag}${flag}${argHint}`.length);
|
|
132
|
+
}
|
|
133
|
+
return max + 2; // 2 chars minimum padding
|
|
134
|
+
}
|
|
135
|
+
|
|
14
136
|
function showHelp() {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
-
|
|
42
|
-
--
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
`);
|
|
137
|
+
const lines = [
|
|
138
|
+
'',
|
|
139
|
+
'Usage: gateway-server <command> [options]',
|
|
140
|
+
'',
|
|
141
|
+
'Commands:',
|
|
142
|
+
];
|
|
143
|
+
|
|
144
|
+
// Command list
|
|
145
|
+
for (const [name, cmd] of Object.entries(commands)) {
|
|
146
|
+
lines.push(` ${name.padEnd(24)} ${cmd.description}`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Per-command options
|
|
150
|
+
for (const [name, cmd] of Object.entries(commands)) {
|
|
151
|
+
lines.push('');
|
|
152
|
+
const positionals = cmd.positionals ? ` ${cmd.positionals}` : '';
|
|
153
|
+
lines.push(`${name}${positionals} options:`);
|
|
154
|
+
const col = optionColumnWidth(cmd.options, cmd.allowNegative);
|
|
155
|
+
for (const [optName, opt] of Object.entries(cmd.options)) {
|
|
156
|
+
lines.push(formatOption(optName, opt, cmd.allowNegative, col));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Global options
|
|
161
|
+
lines.push('');
|
|
162
|
+
lines.push('Global options:');
|
|
163
|
+
lines.push(' -v, --version Show version information and exit');
|
|
164
|
+
lines.push(' -h, --help Show this help message and exit');
|
|
165
|
+
|
|
166
|
+
// Examples
|
|
167
|
+
lines.push('');
|
|
168
|
+
lines.push('Examples:');
|
|
169
|
+
for (const cmd of Object.values(commands)) {
|
|
170
|
+
for (const ex of (cmd.examples || [])) {
|
|
171
|
+
lines.push(` ${ex}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
console.log(lines.join('\n'));
|
|
176
|
+
process.exit(0);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Extract parseArgs-compatible options from a command definition (strips help/example). */
|
|
180
|
+
function argsOptions(name) {
|
|
181
|
+
const cmd = commands[name];
|
|
182
|
+
const opts = { help: { type: 'boolean', short: 'h' } };
|
|
183
|
+
for (const [k, v] of Object.entries(cmd.options)) {
|
|
184
|
+
const o = { type: v.type };
|
|
185
|
+
if (v.short) o.short = v.short;
|
|
186
|
+
if (v.multiple) o.multiple = true;
|
|
187
|
+
opts[k] = o;
|
|
188
|
+
}
|
|
189
|
+
return opts;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Show help for a single command and exit. */
|
|
193
|
+
function showCommandHelp(name) {
|
|
194
|
+
const cmd = commands[name];
|
|
195
|
+
const positionals = cmd.positionals ? ` ${cmd.positionals}` : '';
|
|
196
|
+
const lines = [
|
|
197
|
+
'',
|
|
198
|
+
`Usage: gateway-server ${name}${positionals} [options]`,
|
|
199
|
+
'',
|
|
200
|
+
cmd.description,
|
|
201
|
+
'',
|
|
202
|
+
'Options:',
|
|
203
|
+
];
|
|
204
|
+
|
|
205
|
+
const col = optionColumnWidth(cmd.options, cmd.allowNegative);
|
|
206
|
+
for (const [optName, opt] of Object.entries(cmd.options)) {
|
|
207
|
+
lines.push(formatOption(optName, opt, cmd.allowNegative, col));
|
|
208
|
+
}
|
|
209
|
+
const helpLeft = ' -h, --help';
|
|
210
|
+
lines.push(helpLeft + ' '.repeat(Math.max(2, col - helpLeft.length)) + 'Show this help message');
|
|
211
|
+
|
|
212
|
+
if (cmd.examples && cmd.examples.length > 0) {
|
|
213
|
+
lines.push('');
|
|
214
|
+
lines.push('Examples:');
|
|
215
|
+
for (const ex of cmd.examples) {
|
|
216
|
+
lines.push(` ${ex}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
console.log(lines.join('\n'));
|
|
95
221
|
process.exit(0);
|
|
96
222
|
}
|
|
97
223
|
|
|
@@ -100,6 +226,22 @@ function showVersion() {
|
|
|
100
226
|
process.exit(0);
|
|
101
227
|
}
|
|
102
228
|
|
|
229
|
+
/** Read the nearest package.json starting from cwd, walking up. */
|
|
230
|
+
function readPackageJson() {
|
|
231
|
+
const { readFileSync } = require('node:fs');
|
|
232
|
+
const { join, dirname } = require('node:path');
|
|
233
|
+
let dir = process.cwd();
|
|
234
|
+
while (true) {
|
|
235
|
+
try {
|
|
236
|
+
return JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
|
|
237
|
+
} catch {
|
|
238
|
+
const parent = dirname(dir);
|
|
239
|
+
if (parent === dir) return {};
|
|
240
|
+
dir = parent;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
103
245
|
// Parse command-line arguments
|
|
104
246
|
const { values: globalValues, positionals } = parseArgs({
|
|
105
247
|
args: process.argv.slice(2),
|
|
@@ -115,7 +257,7 @@ const { values: globalValues, positionals } = parseArgs({
|
|
|
115
257
|
if (globalValues.version) {
|
|
116
258
|
showVersion();
|
|
117
259
|
}
|
|
118
|
-
if (globalValues.help) {
|
|
260
|
+
if (globalValues.help && positionals.length === 0) {
|
|
119
261
|
showHelp();
|
|
120
262
|
}
|
|
121
263
|
|
|
@@ -133,6 +275,9 @@ switch (command) {
|
|
|
133
275
|
case 'run':
|
|
134
276
|
runServer().catch(e => {console.error(e); process.exit(1);});
|
|
135
277
|
break;
|
|
278
|
+
case 'build':
|
|
279
|
+
buildCommand().catch(e => {console.error(e); process.exit(1);});
|
|
280
|
+
break;
|
|
136
281
|
case 'manage':
|
|
137
282
|
manageCommand().catch(e => {console.error(e); process.exit(1);});
|
|
138
283
|
break;
|
|
@@ -148,18 +293,65 @@ switch (command) {
|
|
|
148
293
|
process.exit(1);
|
|
149
294
|
}
|
|
150
295
|
|
|
296
|
+
// Command: build - Build a Single Executable Application (SEA)
|
|
297
|
+
async function buildCommand() {
|
|
298
|
+
const { values, positionals } = parseArgs({
|
|
299
|
+
args: process.argv.slice(3),
|
|
300
|
+
options: argsOptions('build'),
|
|
301
|
+
strict: true,
|
|
302
|
+
allowPositionals: true,
|
|
303
|
+
});
|
|
304
|
+
if (values.help) showCommandHelp('build');
|
|
305
|
+
|
|
306
|
+
// Default app-name and app-version from the nearest package.json
|
|
307
|
+
const pkg = readPackageJson();
|
|
308
|
+
const name = values['app-name'] || (pkg.name ? pkg.name.replace(/^@.*\//, '') : 'gateway-server');
|
|
309
|
+
const entryPoints = positionals.length > 0 ? positionals : [`./bin/${name}.cjs`];
|
|
310
|
+
const executable = values.executable;
|
|
311
|
+
|
|
312
|
+
if (!executable) {
|
|
313
|
+
try {
|
|
314
|
+
if (require('node:sea').isSea()) {
|
|
315
|
+
console.error('Error: --executable is required when running from a single executable application.');
|
|
316
|
+
console.error('Provide the path to a Node.js binary, e.g. --executable /usr/local/bin/node');
|
|
317
|
+
process.exit(1);
|
|
318
|
+
}
|
|
319
|
+
} catch {
|
|
320
|
+
// not a SEA build
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const targetPath = await build.buildSea(name, {
|
|
325
|
+
version: values['app-version'] || pkg.version,
|
|
326
|
+
outDir: values.outdir,
|
|
327
|
+
esbuild: {
|
|
328
|
+
entryPoints,
|
|
329
|
+
define: {
|
|
330
|
+
'process.env.NODE_ENV': '"production"',
|
|
331
|
+
'process.env.WS_NO_UTF_8_VALIDATE': 'true',
|
|
332
|
+
'process.env.WS_NO_BUFFER_UTIL': 'true'
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
config: {
|
|
336
|
+
executable,
|
|
337
|
+
execArgv: ['--experimental-websocket'],
|
|
338
|
+
execArgvExtension: 'cli',
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
console.log(`SEA executable built: ${targetPath}`);
|
|
343
|
+
process.exit(0);
|
|
344
|
+
}
|
|
345
|
+
|
|
151
346
|
// Command: manage - Send management commands to a running gateway server
|
|
152
347
|
async function manageCommand() {
|
|
153
348
|
const { values, positionals } = parseArgs({
|
|
154
|
-
args: process.argv.slice(3),
|
|
155
|
-
options:
|
|
156
|
-
path: { type: 'string' },
|
|
157
|
-
port: { type: 'string', short: 'p' },
|
|
158
|
-
timeout: { type: 'string' },
|
|
159
|
-
},
|
|
349
|
+
args: process.argv.slice(3),
|
|
350
|
+
options: argsOptions('manage'),
|
|
160
351
|
strict: true,
|
|
161
352
|
allowPositionals: true,
|
|
162
353
|
});
|
|
354
|
+
if (values.help) showCommandHelp('manage');
|
|
163
355
|
|
|
164
356
|
const socketPath = values.path;
|
|
165
357
|
const port = values.port ? parseInt(values.port, 10) : undefined;
|
|
@@ -241,13 +433,12 @@ async function manageCommand() {
|
|
|
241
433
|
// Command: passwd - Generate password hash
|
|
242
434
|
async function passwdCommand() {
|
|
243
435
|
const { values } = parseArgs({
|
|
244
|
-
args: process.argv.slice(3),
|
|
245
|
-
options:
|
|
246
|
-
stdin: { type: 'boolean' },
|
|
247
|
-
},
|
|
436
|
+
args: process.argv.slice(3),
|
|
437
|
+
options: argsOptions('passwd'),
|
|
248
438
|
strict: true,
|
|
249
439
|
allowPositionals: false,
|
|
250
440
|
});
|
|
441
|
+
if (values.help) showCommandHelp('passwd');
|
|
251
442
|
|
|
252
443
|
let password/*: string = undefined!*/;
|
|
253
444
|
|
|
@@ -349,18 +540,12 @@ async function promptPassword(prompt/*: string*/) {
|
|
|
349
540
|
// Command: mkcert - Generate client or server certificate
|
|
350
541
|
async function mkcertCommand() {
|
|
351
542
|
const { values, positionals } = parseArgs({
|
|
352
|
-
args: process.argv.slice(3),
|
|
353
|
-
options:
|
|
354
|
-
client: { type: 'boolean' },
|
|
355
|
-
user: { type: 'string', short: 'u' },
|
|
356
|
-
ca: { type: 'string' },
|
|
357
|
-
'ca-key': { type: 'string' },
|
|
358
|
-
key: { type: 'string' },
|
|
359
|
-
cert: { type: 'string' },
|
|
360
|
-
},
|
|
543
|
+
args: process.argv.slice(3),
|
|
544
|
+
options: argsOptions('mkcert'),
|
|
361
545
|
strict: true,
|
|
362
546
|
allowPositionals: true,
|
|
363
547
|
});
|
|
548
|
+
if (values.help) showCommandHelp('mkcert');
|
|
364
549
|
|
|
365
550
|
const isClientCert = values.client || false;
|
|
366
551
|
const user = values.user || 'dev-user';
|
|
@@ -471,27 +656,13 @@ async function mkcertCommand() {
|
|
|
471
656
|
// Command: run - Start the server
|
|
472
657
|
async function runServer() {
|
|
473
658
|
const { values } = parseArgs({
|
|
474
|
-
args: process.argv.slice(3),
|
|
475
|
-
options:
|
|
476
|
-
port: { type: 'string', short: 'p' },
|
|
477
|
-
host: { type: 'string', short: 'H' },
|
|
478
|
-
user: { type: 'string', short: 'u' },
|
|
479
|
-
debug: { type: 'boolean' },
|
|
480
|
-
ssl: { type: 'boolean', short: 'S' },
|
|
481
|
-
tls: { type: 'boolean' },
|
|
482
|
-
cert: { type: 'string' },
|
|
483
|
-
key: { type: 'string' },
|
|
484
|
-
ca: { type: 'string' },
|
|
485
|
-
'ca-key': { type: 'string' },
|
|
486
|
-
config: { type: 'string', short: 'c' },
|
|
487
|
-
gateway: { type: 'boolean', short: 'g' },
|
|
488
|
-
static: { type: 'string', short: 's', multiple: true },
|
|
489
|
-
auth: { type: 'boolean' }
|
|
490
|
-
},
|
|
659
|
+
args: process.argv.slice(3),
|
|
660
|
+
options: argsOptions('run'),
|
|
491
661
|
strict: true,
|
|
492
662
|
allowNegative: true,
|
|
493
663
|
allowPositionals: false,
|
|
494
664
|
});
|
|
665
|
+
if (values.help) showCommandHelp('run');
|
|
495
666
|
|
|
496
667
|
const options = {
|
|
497
668
|
port: values.port,
|
package/changelog.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
# Change Log
|
|
4
4
|
|
|
5
|
+
## 0.24.0 (2026-03-22)
|
|
6
|
+
### Added
|
|
7
|
+
- feat: move build sea as part of the cli (npx @interopio/gateway-server build)###
|
|
8
|
+
### Changed
|
|
9
|
+
- chore: bump @interopio/gateway to 0.25.1
|
|
10
|
+
- chore: bump undici to 7.24.4
|
|
11
|
+
|
|
12
|
+
## 0.23.1 (2026-03-13)
|
|
13
|
+
### Fixed
|
|
14
|
+
- fix: legacy config token-ttl
|
|
15
|
+
- fix: cleanup Unix domain socket on shutdown
|
|
16
|
+
### Changed
|
|
17
|
+
- chore: bump tough-cookie to 6.0.1
|
|
18
|
+
- chore: bump undici to 7.24.0
|
|
19
|
+
|
|
5
20
|
## 0.23.0 (2026-02-23)
|
|
6
21
|
|
|
7
22
|
### Fixed
|
package/dist/gateway-ent.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use strict";var $=Object.create;var c=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var z=Object.getPrototypeOf,A=Object.prototype.hasOwnProperty;var p=(e,t)=>()=>(e&&(t=e(e=0)),t);var m=(e,t)=>{for(var r in t)c(e,r,{get:t[r],enumerable:!0})},h=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of P(t))!A.call(e,n)&&n!==r&&c(e,n,{get:()=>t[n],enumerable:!(i=E(t,n))||i.enumerable});return e};var R=(e,t,r)=>(r=e!=null?$(z(e)):{},h(t||!e||!e.__esModule?c(r,"default",{value:e,enumerable:!0}):r,e)),F=e=>h(c({},"__esModule",{value:!0}),e);function l(e){return v.getLogger(`gateway.server.${e}`)}var v,C=p(()=>{"use strict";v=R(require("@interopio/gateway/logging/core"),1)});var S={};m(S,{default:()=>q});function T(e,t,r){Object.entries(e.nodes).forEach(([i,n])=>{i!==r&&(t.send(d.encode({type:"node-added","node-id":r,"new-node":i})),n.send(d.encode({type:"node-added","node-id":i,"new-node":r})))})}function k(e,t){Object.entries(e.nodes).forEach(([r,i])=>{r!==t&&i.send(d.encode({type:"node-removed","node-id":r,"removed-node":t}))})}function j(e,t){a.info(`${t}connection accepted`)}function B(e,t,r,i){a.info(`${t}connection closed [${r}](${i})`);let n=e.sockets[t];if(n){delete e.sockets[t];for(let s of n)delete e.nodes[s];for(let s of n)k(e,s)}}function N(e,t,r,i){switch(i.type){case"hello":{let n=i["node-id"];e.nodes[n]=t,e.sockets[r]=e.sockets[r]??[],e.sockets[r].push(n),a.info(`[${r}] node ${n} added.`),T(e,t,n);break}case"bye":{let n=i["node-id"];delete e[n],a.info(`[${r}] node ${n} removed.`),k(e,n);break}case"data":{let n=i.from,s=i.to;if(s==="all")Object.entries(e.nodes).forEach(([o,x])=>{o!==n&&x.send(d.encode(i))});else{let o=e.nodes[s];o?o.send(d.encode(i)):a.warn(`unable to send to node ${s} message ${JSON.stringify(i)}`)}break}default:{a.warn(`[${r}] ignoring unknown message ${JSON.stringify(i)}`);break}}}function D(e,t,r,i){try{let n=d.decode(i);a.enabledFor("debug")&&a.debug(`${r}processing msg ${JSON.stringify(n)}`),N(e,t,r,n)}catch(n){a.error(`${r}unable to process message`,n)}}async function J(e){let t={nodes:{},sockets:{}};return a.info("mesh server is listening"),async({socket:r,handshake:i})=>{let n=i.logPrefix;j(t,n),r.on("error",s=>{a.error(`${n}websocket error: ${s}`,s)}),r.on("message",(s,o)=>{Array.isArray(s)&&(s=Buffer.concat(s)),D(t,r,n,s)}),r.on("close",(s,o)=>{B(t,n,s,o)})}}var G,W,a,d,q,L=p(()=>{"use strict";C();G=require("@interopio/gateway"),W=G.IOGateway.Encoding,a=l("mesh.ws.broker");d=W.transit({keywordize:new Map([["/type","*"],["/message/body/type","*"],["/message/origin","*"],["/message/receiver/type","*"],["/message/source/type","*"],["/message/body/type","*"]])});q=J});var Z={};m(Z,{configure_logging:()=>Y,create:()=>X});module.exports=F(Z);var y=require("node:util"),f=class{#e;#t;#r;#i;constructor(t){this.#e=t}parsed(){if(this.#t===void 0){let t,r=this.#e.data;this.#e.data[0]instanceof Error&&(t=this.#e.data[0],r=r.slice(1));let i=(0,y.format)(this.#e.message,...r);this.#t={err:t,msg:i}}return this.#t}get time(){return this.#e.time}get level(){return this.#e.level}get namespace(){return this.#e.name}get file(){}get line(){}get message(){return this.parsed().msg}get stacktrace(){return this.parsed().err}get timestamp(){return this.#r===void 0&&(this.#r=this.time.toISOString()),this.#r}get output(){if(this.#i===void 0){let t=this.parsed().err,r=t?`
|
|
2
|
-
${t.stack??t}`:"";this.#i=`${this.timestamp} ${this.level.toUpperCase()} [${this.namespace}] - ${this.message}${r}`}return this.#i}};function w(e){let t="info";e?.level&&(e.level==="fatal"?t="error":e.level!=="report"&&(t=e.level));let r={level:typeof t=="string"?{gateway:t}:t};e?.disabled_action_groups&&e.disabled_action_groups.forEach(n=>{r.level[`gateway.action.${n}`]="off"});let i=e?.appender;return i&&(r.appender=n=>{i(new f(n))}),r}var b=require("@interopio/gateway-server"),u=class{constructor(t){this.config=t}server;async connect(t){if(!this.server)throw new Error("not started");return await this.server.gateway.connect((i,n)=>t(i,n))}info(){return this.server?.gateway.info()}async start(){return this.server||(this.server=await b.GatewayServer.Factory(this.config)),this}async stop(){return await this.server?.close(),delete this.server,this}};function O(e){if(e){let t=e.publishers.map(i=>({identity:i.publisher,metrics:i.metrics})),r=e["non-matched"];return{publishers:t,non_matched:r}}}function g(e){let t=O(e?.filters),r=H(e?.conflation),i={...e,filters:t,conflation:r};return t||delete i.filters,r||delete i.conflation,i}function H(e){if(e)return{interval:e.interval}}function K(e){let t={publishers:[]};return e?.publishers?.forEach(r=>{if(typeof r=="string"){if(r==="rest"){if(t.publishers.push("rest"),e.rest){let i={...e.rest},n=i["user-agent"];delete i["user-agent"];let s={...i.headers,...n?{"user-agent":n}:{}};delete i.headers,t.rest={endpoint:i.endpoint,headers:s,...g(i)},t.rest.publishFn??="@interopio/gateway-server/metrics/publisher/rest"}}else if(r==="file"&&(t.publishers.push("file"),e.file)){let i={...e.file},n=i["skip-status"]===void 0?!0:!i["skip-status"];delete i["skip-status"],t.file={location:i.location,status:n,...g(i)},t.file.publishFn??="@interopio/gateway/metrics/publisher/file"}}else{let i={...r},n=i["split-size"];delete i["split-size"];let s=r.publisher?.file,o={split_size:n,publisher:{file:s,configuration:r.publisher?.configuration},context:r.context,...g(i)};o.split_size===void 0&&delete o.split_size,t.publishers.push(o)}}),e?.filters&&(t.filters=O(e?.filters)),t}function _(e){return e?.endsWith("/")?e.slice(0,-1):e}function U(e){if(e?.directory){let t=e.directory,r={endpoint:e?.endpoint};if(t.type==="rest"){let i;if(r.endpoint===void 0?r.endpoint=_(t.config?.directory_uri):i={uri:_(t.config?.directory_uri)},t.config?.announce_interval&&(i??={},i.interval=Number(t.config.announce_interval)),i!==void 0&&(r.directory=i,r.directory.metadata??=t.config?.metadata),t.config){let n={...t.config};delete n.directory_uri,delete n.announce_interval,Object.keys(n).length>0&&(r.opts=n)}return r}else if(t.type==="static")return r.directory={members:t.members??[]},r}}function Q(e){let t={auth:{user:null}};if(e?.configuration?.node_id&&(t.node=e.configuration.node_id),e?.configuration?.user&&(t.auth.user=e.configuration?.user),e?.type==="broker"&&(t.broker={endpoint:e.broker?.endpoint??"<unresolved>"}),e?.type==="p2p"){let r=U(e.p2p);r&&(t.cluster=r)}return t}function V(e){let t={available:[]};return e?.default&&(t.default=e.default),(e?.available).forEach(i=>{(i==="basic"||i==="oauth2"||e?.[i]?.authenticator!==void 0)&&(t.available.push(i),e?.[i]!==void 0&&(t[i]=e[i]))}),t}function I(e){let t={route:e.route,maxConnections:e.limits?.max_connections,origins:e.security?.origin_filters,authorize:e.authorize??{access:"permitted"},ping:e.ping,clients:e.clients??{inactive_seconds:0,buffer_size:100},contexts:{lifetime:"retained",visibility:[{context:/___channel___.+/,restrictions:"cluster"},{context:/T42\..+/,restrictions:"local"}]},methods:{visibility:[{method:/T42\..+/,restrictions:"local"}]},peers:{visibility:[{domain:"context",restrictions:"cluster"},{domain:"agm",restrictions:"local"}]},metrics:{publishers:[]}};
|
|
2
|
+
${t.stack??t}`:"";this.#i=`${this.timestamp} ${this.level.toUpperCase()} [${this.namespace}] - ${this.message}${r}`}return this.#i}};function w(e){let t="info";e?.level&&(e.level==="fatal"?t="error":e.level!=="report"&&(t=e.level));let r={level:typeof t=="string"?{gateway:t}:t};e?.disabled_action_groups&&e.disabled_action_groups.forEach(n=>{r.level[`gateway.action.${n}`]="off"});let i=e?.appender;return i&&(r.appender=n=>{i(new f(n))}),r}var b=require("@interopio/gateway-server"),u=class{constructor(t){this.config=t}server;async connect(t){if(!this.server)throw new Error("not started");return await this.server.gateway.connect((i,n)=>t(i,n))}info(){return this.server?.gateway.info()}async start(){return this.server||(this.server=await b.GatewayServer.Factory(this.config)),this}async stop(){return await this.server?.close(),delete this.server,this}};function O(e){if(e){let t=e.publishers.map(i=>({identity:i.publisher,metrics:i.metrics})),r=e["non-matched"];return{publishers:t,non_matched:r}}}function g(e){let t=O(e?.filters),r=H(e?.conflation),i={...e,filters:t,conflation:r};return t||delete i.filters,r||delete i.conflation,i}function H(e){if(e)return{interval:e.interval}}function K(e){let t={publishers:[]};return e?.publishers?.forEach(r=>{if(typeof r=="string"){if(r==="rest"){if(t.publishers.push("rest"),e.rest){let i={...e.rest},n=i["user-agent"];delete i["user-agent"];let s={...i.headers,...n?{"user-agent":n}:{}};delete i.headers,t.rest={endpoint:i.endpoint,headers:s,...g(i)},t.rest.publishFn??="@interopio/gateway-server/metrics/publisher/rest"}}else if(r==="file"&&(t.publishers.push("file"),e.file)){let i={...e.file},n=i["skip-status"]===void 0?!0:!i["skip-status"];delete i["skip-status"],t.file={location:i.location,status:n,...g(i)},t.file.publishFn??="@interopio/gateway/metrics/publisher/file"}}else{let i={...r},n=i["split-size"];delete i["split-size"];let s=r.publisher?.file,o={split_size:n,publisher:{file:s,configuration:r.publisher?.configuration},context:r.context,...g(i)};o.split_size===void 0&&delete o.split_size,t.publishers.push(o)}}),e?.filters&&(t.filters=O(e?.filters)),t}function _(e){return e?.endsWith("/")?e.slice(0,-1):e}function U(e){if(e?.directory){let t=e.directory,r={endpoint:e?.endpoint};if(t.type==="rest"){let i;if(r.endpoint===void 0?r.endpoint=_(t.config?.directory_uri):i={uri:_(t.config?.directory_uri)},t.config?.announce_interval&&(i??={},i.interval=Number(t.config.announce_interval)),i!==void 0&&(r.directory=i,r.directory.metadata??=t.config?.metadata),t.config){let n={...t.config};delete n.directory_uri,delete n.announce_interval,Object.keys(n).length>0&&(r.opts=n)}return r}else if(t.type==="static")return r.directory={members:t.members??[]},r}}function Q(e){let t={auth:{user:null}};if(e?.configuration?.node_id&&(t.node=e.configuration.node_id),e?.configuration?.user&&(t.auth.user=e.configuration?.user),e?.type==="broker"&&(t.broker={endpoint:e.broker?.endpoint??"<unresolved>"}),e?.type==="p2p"){let r=U(e.p2p);r&&(t.cluster=r)}return t}function V(e){let t={available:[]};return e?.default&&(t.default=e.default),(e?.available).forEach(i=>{(i==="basic"||i==="oauth2"||e?.[i]?.authenticator!==void 0)&&(t.available.push(i),e?.[i]!==void 0&&(t[i]=e[i]))}),t}function I(e){let t={route:e.route,maxConnections:e.limits?.max_connections,origins:e.security?.origin_filters,authorize:e.authorize??{access:"permitted"},ping:e.ping,clients:e.clients??{inactive_seconds:0,buffer_size:100},contexts:{lifetime:"retained",visibility:[{context:/___channel___.+/,restrictions:"cluster"},{context:/T42\..+/,restrictions:"local"}]},methods:{visibility:[{method:/T42\..+/,restrictions:"local"}]},peers:{visibility:[{domain:"context",restrictions:"cluster"},{domain:"agm",restrictions:"local"}]},metrics:{publishers:[]}};if(e.authentication!==void 0){let r=e.authentication.token_ttl??e.authentication["token-ttl"];r!==void 0&&(t.token={ttl:r}),(e.authentication.available||e.authentication.default)&&(t.authentication=V(e.authentication))}return e.globals&&(t.globals=e.globals),e.contexts&&(t.contexts=e.contexts),e.methods&&(t.methods=e.methods),e.peers&&(t.peers=e.peers),e.cluster?.enabled&&(t.mesh=Q(e.cluster)),e.metrics?.publishers&&(t.metrics=K(e.metrics)),{port:e.port??3434,host:e.ip??e.host,cors:e.cors===null?void 0:e.cors??!1,memory:e.memory,app:async r=>{e.cluster?.embedded_broker?.enabled===!0&&r.socket({path:e.cluster.embedded_broker.route??"/mesh-broker",options:{authorize:e.cluster.embedded_broker.authorize??{access:"permitted"}},factory:async i=>{t.mesh?.broker?.endpoint==="<unresolved>"&&(t.mesh.broker.endpoint=i.endpoint);let n=(await Promise.resolve().then(()=>(L(),S))).default;return await n(i)}})},gateway:t}}var M=require("@interopio/gateway/logging/core");function X(e){return new u(I(e))}function Y(e){(0,M.configure)(w(e))}0&&(module.exports={configure_logging,create});
|
|
3
3
|
//# sourceMappingURL=gateway-ent.cjs.map
|