@jacebenson/jsn 4.3.7-dev.28 → 4.3.7-dev.30

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jacebenson/jsn",
3
- "version": "4.3.7-dev.28",
3
+ "version": "4.3.7-dev.30",
4
4
  "description": "A command-line interface for ServiceNow that follows the Unix philosophy: simple, composable, and scriptable.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -147,6 +147,17 @@ export function assertMidServerUp(record) {
147
147
  }
148
148
  }
149
149
 
150
+ export function assertMidServerReady(record) {
151
+ assertMidServerUp(record);
152
+ const name = getStringField(record, 'name') || getStringField(record, 'sys_id') || 'MID Server';
153
+ const validated = getStringField(record, 'validated').toLowerCase();
154
+ if (validated !== 'validated') {
155
+ const error = new Error(`MID Server '${name}' is not validated yet (validation: ${validated || 'unknown'}). Wait for ServiceNow validation to complete before executing a command.`);
156
+ error.code = 'midserver_not_validated';
157
+ throw error;
158
+ }
159
+ }
160
+
150
161
  async function promptMidCredentials(app, argv) {
151
162
  if (!canPrompt()) throw new Error('MID Server installation is interactive. Run it from a terminal.');
152
163
  let username = argv.username || '';
@@ -397,22 +408,48 @@ export function midserversCmd(wrap) {
397
408
  }),
398
409
  })
399
410
  .command({
400
- command: 'execute <identifier>',
411
+ command: 'execute [identifier]',
401
412
  describe: 'Execute a shell command through a MID Server',
402
413
  builder: (b) => b
403
- .option('command', { alias: 'c', type: 'string', demandOption: true, describe: 'Command line to execute on the MID Server host' })
414
+ .option('command', { alias: 'c', type: 'string', describe: 'Command line to execute on the MID Server host' })
404
415
  .option('timeout', { type: 'number', default: DEFAULT_TIMEOUT, describe: 'Response timeout in milliseconds' })
405
416
  .option('interval', { type: 'number', default: DEFAULT_INTERVAL, describe: 'Polling interval in milliseconds' }),
406
417
  handler: wrap(async (argv, app) => {
407
- const record = await resolveMidServer(app.sdk, argv.identifier);
408
- assertMidServerUp(record);
418
+ let record;
419
+ if (argv.identifier) {
420
+ record = await resolveMidServer(app.sdk, argv.identifier);
421
+ } else {
422
+ if (!canPrompt() || app.output.getFormat() !== FormatAuto) {
423
+ throw new Error('An identifier and --command are required outside an interactive terminal');
424
+ }
425
+ record = await interactiveList({
426
+ app,
427
+ table: AGENT_TABLE,
428
+ singular: 'MID Server',
429
+ columns: LIST_FIELDS,
430
+ limit: 50,
431
+ labelField: 'name',
432
+ message: 'Select a MID Server to execute on',
433
+ formatLabel: (candidate) => {
434
+ const name = getStringField(candidate, 'name') || getStringField(candidate, 'sys_id');
435
+ const status = getStringField(candidate, 'status');
436
+ return status ? `${name} [${status}]` : name;
437
+ },
438
+ });
439
+ if (!record) return;
440
+ }
441
+ const command = argv.command || await input({
442
+ message: 'Command to execute:',
443
+ validate: value => value.trim() ? true : 'Command is required',
444
+ });
445
+ assertMidServerReady(record);
409
446
  const agent = agentName(record);
410
447
  const output = await app.sdk.create(QUEUE_TABLE, {
411
448
  agent,
412
449
  topic: 'Command',
413
450
  queue: 'output',
414
- name: argv.command,
415
- payload: buildCommandPayload(argv.command),
451
+ name: command,
452
+ payload: buildCommandPayload(command),
416
453
  });
417
454
  const outputSysId = unwrapSysId(output);
418
455
  if (!outputSysId) throw new Error('ServiceNow did not return the ECC Queue sys_id for the command');
@@ -422,7 +459,7 @@ export function midserversCmd(wrap) {
422
459
  const result = parseCommandResult(queueValue(response.payload));
423
460
  app.ok({
424
461
  mid_server: getStringField(record, 'name'),
425
- command: argv.command,
462
+ command,
426
463
  output: { sys_id: outputSysId, ...output },
427
464
  response: { ...response, ...result },
428
465
  }, { summary: `Executed command on MID Server '${getStringField(record, 'name')}'` });