@sanity/workflow-cli 0.27.0 → 0.29.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/CHANGELOG.md +59 -0
- package/README.md +40 -39
- package/bin/run.js +3 -1
- package/dist/command-ids.d.ts +10 -0
- package/dist/command-ids.js +10 -0
- package/dist/commands/{editorial-workflows → workflows}/abort.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/abort.js +2 -3
- package/dist/commands/{editorial-workflows → workflows}/definition/delete.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/definition/delete.js +3 -4
- package/dist/commands/{editorial-workflows → workflows}/definition/diff.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/definition/diff.js +2 -3
- package/dist/commands/{editorial-workflows → workflows}/definition/list.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/definition/list.js +3 -4
- package/dist/commands/{editorial-workflows → workflows}/definition/show.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/definition/show.js +0 -1
- package/dist/commands/{editorial-workflows → workflows}/deploy.d.ts +4 -3
- package/dist/commands/{editorial-workflows → workflows}/deploy.js +15 -9
- package/dist/commands/{editorial-workflows → workflows}/diagnose.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/diagnose.js +3 -4
- package/dist/commands/{editorial-workflows → workflows}/fire-action.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/fire-action.js +3 -4
- package/dist/commands/{editorial-workflows → workflows}/list.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/list.js +6 -7
- package/dist/commands/{editorial-workflows → workflows}/nuke.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/nuke.js +3 -4
- package/dist/commands/{editorial-workflows → workflows}/reset-activity.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/reset-activity.js +2 -3
- package/dist/commands/{editorial-workflows → workflows}/set-stage.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/set-stage.js +3 -4
- package/dist/commands/{editorial-workflows → workflows}/show.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/show.js +3 -4
- package/dist/commands/{editorial-workflows → workflows}/start.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/start.js +4 -5
- package/dist/commands/{editorial-workflows → workflows}/tail.d.ts +0 -1
- package/dist/commands/{editorial-workflows → workflows}/tail.js +1 -2
- package/dist/help.d.ts +9 -4
- package/dist/help.js +35 -8
- package/dist/hooks/finally/telemetry.d.ts +2 -1
- package/dist/hooks/prerun/telemetry.d.ts +2 -1
- package/dist/hooks/prerun/telemetry.js +7 -0
- package/dist/lib/base-command.d.ts +3 -3
- package/dist/lib/base-command.js +4 -0
- package/dist/lib/context.d.ts +5 -4
- package/dist/lib/context.js +2 -1
- package/dist/lib/select-deployment.js +2 -1
- package/dist/lib/share-definitions.js +2 -1
- package/dist/lib/telemetry.d.ts +1 -3
- package/dist/standalone-argv.d.ts +14 -0
- package/dist/standalone-argv.js +54 -0
- package/oclif.manifest.json +105 -135
- package/package.json +7 -7
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type WorkflowInstance } from '@sanity/workflow-engine';
|
|
2
2
|
import { WorkflowCommand } from '../../lib/base-command.ts';
|
|
3
3
|
export default class Show extends WorkflowCommand {
|
|
4
|
-
static aliases: string[];
|
|
5
4
|
static description: string;
|
|
6
5
|
static examples: string[];
|
|
7
6
|
static args: {
|
|
@@ -7,12 +7,11 @@ import { findInstance, resolveReadTargets } from "../../lib/context.js";
|
|
|
7
7
|
import { jsonFlags, tagFlags } from "../../lib/flags.js";
|
|
8
8
|
import { formatKeyValue, formatTimestamp, sectionHeader, activityIcon } from "../../lib/ui.js";
|
|
9
9
|
export default class Show extends WorkflowCommand {
|
|
10
|
-
static aliases = ['show'];
|
|
11
10
|
static description = 'Show the state, activities, and effects of a workflow instance.';
|
|
12
11
|
static examples = [
|
|
13
|
-
'<%= config.bin %> show wf-instance.abc123',
|
|
14
|
-
'<%= config.bin %> show wf-instance.abc123 --include history',
|
|
15
|
-
'<%= config.bin %> show wf-instance.abc123 --json',
|
|
12
|
+
'<%= config.bin %> workflows show wf-instance.abc123',
|
|
13
|
+
'<%= config.bin %> workflows show wf-instance.abc123 --include history',
|
|
14
|
+
'<%= config.bin %> workflows show wf-instance.abc123 --json',
|
|
16
15
|
];
|
|
17
16
|
static args = {
|
|
18
17
|
instanceId: Args.string({
|
|
@@ -2,7 +2,6 @@ import { StartNotSettledError, type InitialFieldValue, type StartInstanceArgs, t
|
|
|
2
2
|
import { WorkflowCommand } from '../../lib/base-command.ts';
|
|
3
3
|
import { type EngineScope } from '../../lib/operation-args.ts';
|
|
4
4
|
export default class Start extends WorkflowCommand {
|
|
5
|
-
static aliases: string[];
|
|
6
5
|
static description: string;
|
|
7
6
|
static examples: string[];
|
|
8
7
|
static args: {
|
|
@@ -10,14 +10,13 @@ import { baseEngineArgs } from "../../lib/operation-args.js";
|
|
|
10
10
|
import { runWriteVerb } from "../../lib/ops-report.js";
|
|
11
11
|
import { parseParams } from "../../lib/params.js";
|
|
12
12
|
export default class Start extends WorkflowCommand {
|
|
13
|
-
static aliases = ['start'];
|
|
14
13
|
static description = 'Start a workflow instance from a deployed definition. Supply values for the ' +
|
|
15
14
|
"workflow's input-sourced fields with --field (e.g. the subject document ref).";
|
|
16
15
|
static examples = [
|
|
17
|
-
'<%= config.bin %> start productLaunch',
|
|
18
|
-
'<%= config.bin %> start article-review --field subject=\'{"id":"dataset:proj:ds:article-1","type":"article"}\'',
|
|
19
|
-
'<%= config.bin %> start productLaunch --version 2 --tag prod',
|
|
20
|
-
'<%= config.bin %> start productLaunch --instance-id prod.wf-instance.a1b2c3d4e5f6',
|
|
16
|
+
'<%= config.bin %> workflows start productLaunch',
|
|
17
|
+
'<%= config.bin %> workflows start article-review --field subject=\'{"id":"dataset:proj:ds:article-1","type":"article"}\'',
|
|
18
|
+
'<%= config.bin %> workflows start productLaunch --version 2 --tag prod',
|
|
19
|
+
'<%= config.bin %> workflows start productLaunch --instance-id prod.wf-instance.a1b2c3d4e5f6',
|
|
21
20
|
];
|
|
22
21
|
static args = {
|
|
23
22
|
name: Args.string({ required: true, description: 'Workflow definition name.' }),
|
|
@@ -9,9 +9,8 @@ import { tagFlags } from "../../lib/flags.js";
|
|
|
9
9
|
import { formatTimestamp } from "../../lib/ui.js";
|
|
10
10
|
const TAIL_TAG = 'tail';
|
|
11
11
|
export default class Tail extends WorkflowCommand {
|
|
12
|
-
static aliases = ['tail'];
|
|
13
12
|
static description = 'Stream new history entries on a workflow instance as they land in the dataset.';
|
|
14
|
-
static examples = ['<%= config.bin %> tail wf-instance.abc123'];
|
|
13
|
+
static examples = ['<%= config.bin %> workflows tail wf-instance.abc123'];
|
|
15
14
|
static args = {
|
|
16
15
|
instanceId: Args.string({
|
|
17
16
|
required: true,
|
package/dist/help.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import { Help } from '@oclif/core';
|
|
2
|
-
|
|
1
|
+
import { Help, type Command } from '@oclif/core';
|
|
2
|
+
/** Strip the mount topic so standalone root help can list short forms. */
|
|
3
|
+
export declare const standaloneSurfaceId: (id: string) => string | undefined;
|
|
4
|
+
/** Keep the standalone short surface, including oclif's help command. */
|
|
3
5
|
export declare const keepCommandAtRoot: (id: string) => boolean;
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
+
/** Strip the mount topic from an example rendered by standalone help. */
|
|
7
|
+
export declare const standaloneExample: (example: Command.Example) => Command.Example;
|
|
8
|
+
/** Standalone-binary help that lists topic-scoped commands under their short
|
|
9
|
+
* forms (`deploy`, `definition list`) rather than the mount ids. */
|
|
6
10
|
export default class WorkflowHelp extends Help {
|
|
11
|
+
showCommandHelp(command: Command.Loadable): Promise<void>;
|
|
7
12
|
protected showRootHelp(): Promise<void>;
|
|
8
13
|
}
|
package/dist/help.js
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
import { Help } from '@oclif/core';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { WORKFLOWS_TOPIC, WORKFLOWS_TOPIC_PREFIX } from "./command-ids.js";
|
|
3
|
+
const CANONICAL_EXAMPLE_PREFIX = `<%= config.bin %> ${WORKFLOWS_TOPIC} `;
|
|
4
|
+
const STANDALONE_EXAMPLE_PREFIX = '<%= config.bin %> ';
|
|
5
|
+
const HELP_COMMAND_ID = 'help';
|
|
6
|
+
export const standaloneSurfaceId = (id) => {
|
|
7
|
+
if (!id.startsWith(WORKFLOWS_TOPIC_PREFIX))
|
|
8
|
+
return undefined;
|
|
9
|
+
return id.slice(WORKFLOWS_TOPIC_PREFIX.length);
|
|
10
|
+
};
|
|
11
|
+
export const keepCommandAtRoot = (id) => id === HELP_COMMAND_ID || standaloneSurfaceId(id) !== undefined;
|
|
12
|
+
export const standaloneExample = (example) => {
|
|
13
|
+
if (typeof example === 'string') {
|
|
14
|
+
return example.replace(CANONICAL_EXAMPLE_PREFIX, STANDALONE_EXAMPLE_PREFIX);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
...example,
|
|
18
|
+
command: example.command.replace(CANONICAL_EXAMPLE_PREFIX, STANDALONE_EXAMPLE_PREFIX),
|
|
19
|
+
};
|
|
20
|
+
};
|
|
4
21
|
export default class WorkflowHelp extends Help {
|
|
22
|
+
async showCommandHelp(command) {
|
|
23
|
+
await super.showCommandHelp(withStandaloneSurface(command));
|
|
24
|
+
}
|
|
5
25
|
async showRootHelp() {
|
|
6
26
|
if (this.opts.all) {
|
|
7
27
|
await super.showRootHelp();
|
|
@@ -9,15 +29,22 @@ export default class WorkflowHelp extends Help {
|
|
|
9
29
|
}
|
|
10
30
|
this.log(this.formatRoot());
|
|
11
31
|
this.log('');
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
this.log('');
|
|
16
|
-
}
|
|
17
|
-
const commands = this.sortedCommands.filter((command) => keepCommandAtRoot(command.id));
|
|
32
|
+
const commands = this.sortedCommands
|
|
33
|
+
.filter((command) => keepCommandAtRoot(command.id))
|
|
34
|
+
.map((command) => withStandaloneSurface(command));
|
|
18
35
|
if (commands.length > 0) {
|
|
19
36
|
this.log(this.formatCommands(commands));
|
|
20
37
|
this.log('');
|
|
21
38
|
}
|
|
22
39
|
}
|
|
23
40
|
}
|
|
41
|
+
function withStandaloneSurface(command) {
|
|
42
|
+
const shortId = standaloneSurfaceId(command.id);
|
|
43
|
+
if (shortId === undefined)
|
|
44
|
+
return command;
|
|
45
|
+
return {
|
|
46
|
+
...command,
|
|
47
|
+
id: shortId,
|
|
48
|
+
examples: command.examples?.map((example) => standaloneExample(example)),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -2,7 +2,8 @@ import type { Hook } from '@oclif/core';
|
|
|
2
2
|
/**
|
|
3
3
|
* Completes the command trace — command id, declared-flag names, success —
|
|
4
4
|
* and flushes the final batch. Runs on success and on error alike (oclif's
|
|
5
|
-
* `finally`); an invocation the prerun hook left with telemetry off no-ops
|
|
5
|
+
* `finally`); an invocation the prerun hook left with telemetry off no-ops,
|
|
6
|
+
* which is what keeps host commands outside the `workflows` topic silent.
|
|
6
7
|
*/
|
|
7
8
|
declare const hook: Hook<'finally'>;
|
|
8
9
|
export default hook;
|
|
@@ -4,6 +4,7 @@ import type { Hook } from '@oclif/core';
|
|
|
4
4
|
* A deploy that may share definitions—flagless by default or explicitly
|
|
5
5
|
* enabled—forces the store to send despite CI / `DO_NOT_TRACK`. This is
|
|
6
6
|
* resolved from raw argv because the store is built before oclif parses
|
|
7
|
-
* flags.
|
|
7
|
+
* flags. Skips non-workflows commands when this package is mounted as a
|
|
8
|
+
* host plugin so `sanity dataset list` does not inherit the shell. */
|
|
8
9
|
declare const hook: Hook<'prerun'>;
|
|
9
10
|
export default hook;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import { shouldRunWorkflowCliTelemetry } from "../../command-ids.js";
|
|
1
2
|
import { shouldForceShareTelemetry } from "../../lib/share-definitions.js";
|
|
2
3
|
import { setupCliTelemetry } from "../../lib/telemetry-setup.js";
|
|
3
4
|
const hook = async function ({ config, Command, argv }) {
|
|
5
|
+
if (!shouldRunWorkflowCliTelemetry({
|
|
6
|
+
bin: config.bin,
|
|
7
|
+
commandId: Command?.id,
|
|
8
|
+
})) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
4
11
|
await setupCliTelemetry({
|
|
5
12
|
cliVersion: config.version,
|
|
6
13
|
forceSend: shouldForceShareTelemetry({ commandId: Command?.id, argv }),
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
/**
|
|
3
3
|
* Base for workflow commands: prompt interrupts exit with the conventional
|
|
4
|
-
* SIGINT code and no stack
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* SIGINT code and no stack; an auth rejection and a reader-floor
|
|
5
|
+
* acknowledgement failure — both expected, user-fixable — render through the
|
|
6
|
+
* clean {@link fail} path. Every other error propagates to oclif unchanged.
|
|
7
7
|
*/
|
|
8
8
|
export declare abstract class WorkflowCommand extends Command {
|
|
9
9
|
protected catch(err: Error & {
|
package/dist/lib/base-command.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
2
|
import { Command } from '@oclif/core';
|
|
3
3
|
import { exitCodes } from '@sanity/cli-core';
|
|
4
|
+
import { ReaderModelAcknowledgementError } from '@sanity/workflow-engine';
|
|
4
5
|
import { fail, failureDetail, isAuthRejection } from "./fail.js";
|
|
5
6
|
export class WorkflowCommand extends Command {
|
|
6
7
|
async catch(err) {
|
|
@@ -11,6 +12,9 @@ export class WorkflowCommand extends Command {
|
|
|
11
12
|
if (isAuthRejection(err)) {
|
|
12
13
|
fail('Authentication failed:', failureDetail(err));
|
|
13
14
|
}
|
|
15
|
+
if (err instanceof ReaderModelAcknowledgementError) {
|
|
16
|
+
fail('Reader-floor acknowledgement:', err.message);
|
|
17
|
+
}
|
|
14
18
|
return super.catch(err);
|
|
15
19
|
}
|
|
16
20
|
}
|
package/dist/lib/context.d.ts
CHANGED
|
@@ -17,10 +17,11 @@ export interface InstanceContext {
|
|
|
17
17
|
instance: WorkflowInstance;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
* The resolution a
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* The resolution a deployment-scoped command shares (`start`, `definition
|
|
21
|
+
* delete`, `definition diff`): discover the config, pick the deployment for
|
|
22
|
+
* `--deployment` or `--tag` (or the sole one), assert that deployment's
|
|
23
|
+
* reader-floor acknowledgement, and build an authenticated client for its
|
|
24
|
+
* resource. Instance-id commands resolve elsewhere and do not gate here.
|
|
24
25
|
*/
|
|
25
26
|
export declare function resolveContext(flags: {
|
|
26
27
|
deployment?: string | undefined;
|
package/dist/lib/context.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertReadableModel, resourceGdr, } from '@sanity/workflow-engine';
|
|
1
|
+
import { assertReadableModel, assertReaderModelAcknowledgement, resourceGdr, } from '@sanity/workflow-engine';
|
|
2
2
|
import { clientFor, resolveTokenOrFail } from "./client.js";
|
|
3
3
|
import { fail } from "./fail.js";
|
|
4
4
|
import { loadWorkflowConfig } from "./load-config.js";
|
|
@@ -7,6 +7,7 @@ import { resourceLabel } from "./ui.js";
|
|
|
7
7
|
export async function resolveContext(flags) {
|
|
8
8
|
const config = await loadWorkflowConfig();
|
|
9
9
|
const deployment = await selectDeployment(config, { name: flags.deployment, tag: flags.tag });
|
|
10
|
+
assertReaderModelAcknowledgement(deployment.expectedMinReaderModel, `Deployment ${deployment.name}`);
|
|
10
11
|
return { deployment, client: clientFor(deployment.workflowResource, await resolveTokenOrFail()) };
|
|
11
12
|
}
|
|
12
13
|
function targetsFor(resources, token) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resourceAliasesToMap, } from '@sanity/workflow-engine';
|
|
1
|
+
import { assertReaderModelAcknowledgement, resourceAliasesToMap, } from '@sanity/workflow-engine';
|
|
2
2
|
import { fail } from "./fail.js";
|
|
3
3
|
import { canPromptOnStderr, selectOnStderr } from "./prompt.js";
|
|
4
4
|
export function deploymentLabel({ name, tag }) {
|
|
@@ -70,6 +70,7 @@ function availableDeployments(config, deployments = config.deployments) {
|
|
|
70
70
|
return `Available deployments: ${deployments.map(deploymentLabel).join(', ')}`;
|
|
71
71
|
}
|
|
72
72
|
export function deploymentToTarget(deployment) {
|
|
73
|
+
assertReaderModelAcknowledgement(deployment.expectedMinReaderModel, `Deployment ${deployment.name}`);
|
|
73
74
|
return {
|
|
74
75
|
expectedMinReaderModel: deployment.expectedMinReaderModel,
|
|
75
76
|
tag: deployment.tag,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
2
|
import { getUserConfig } from '@sanity/cli-core';
|
|
3
3
|
import { assertReadableModel, definitionDeployedData, errorMessage, } from '@sanity/workflow-engine';
|
|
4
|
+
import { WORKFLOWS_DEPLOY_COMMAND_ID } from "../command-ids.js";
|
|
4
5
|
import { buildDefinitionShowQuery } from "./definitions.js";
|
|
5
6
|
import { canPromptOnStderr } from "./prompt.js";
|
|
6
7
|
import { cliTelemetry, WorkflowDefinitionShared, WorkflowDefinitionSharingDecided, } from "./telemetry.js";
|
|
@@ -28,7 +29,7 @@ export function definitionShareMarker(args) {
|
|
|
28
29
|
}
|
|
29
30
|
export function shouldForceShareTelemetry(args) {
|
|
30
31
|
const { commandId, argv } = args;
|
|
31
|
-
if (commandId !==
|
|
32
|
+
if (commandId !== WORKFLOWS_DEPLOY_COMMAND_ID) {
|
|
32
33
|
return false;
|
|
33
34
|
}
|
|
34
35
|
const terminator = argv.indexOf('--');
|
package/dist/lib/telemetry.d.ts
CHANGED
|
@@ -117,9 +117,7 @@ export declare function raceWithDeadline<T>(work: Promise<T>, deadlineMs: number
|
|
|
117
117
|
export declare function finishCliTelemetry(data: WorkflowCliCommandData): Promise<void>;
|
|
118
118
|
/**
|
|
119
119
|
* The command id a trace reports: the resolved class's canonical id when
|
|
120
|
-
* oclif supplies it, else the id
|
|
121
|
-
* under the same name as the canonical form — one command, one telemetry
|
|
122
|
-
* identity.
|
|
120
|
+
* oclif supplies it, else the unresolved id from the hook.
|
|
123
121
|
*/
|
|
124
122
|
export declare function traceCommandId(options: {
|
|
125
123
|
id: string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* First argv tokens that belong under {@link WORKFLOWS_TOPIC}.
|
|
3
|
+
* Keep in sync with `src/commands/workflows/` (top-level command
|
|
4
|
+
* files plus the `definition` subtopic directory).
|
|
5
|
+
*/
|
|
6
|
+
export declare const STANDALONE_ROOT_COMMANDS: readonly ["abort", "definition", "deploy", "diagnose", "fire-action", "list", "nuke", "reset-activity", "set-stage", "show", "start", "tail"];
|
|
7
|
+
/** Index of the first argv token that is not a flag (and not `--`). */
|
|
8
|
+
export declare function firstPositionalIndex(args: string[]): number;
|
|
9
|
+
/**
|
|
10
|
+
* Rewrite standalone CLI args so short forms resolve to topic-scoped command
|
|
11
|
+
* ids. Idempotent when the topic is already present. Unknown first tokens are
|
|
12
|
+
* left alone so oclif's own "command not found" path still runs.
|
|
13
|
+
*/
|
|
14
|
+
export declare function rewriteStandaloneArgv(args: string[]): string[];
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { WORKFLOWS_TOPIC } from "./command-ids.js";
|
|
2
|
+
export const STANDALONE_ROOT_COMMANDS = [
|
|
3
|
+
'abort',
|
|
4
|
+
'definition',
|
|
5
|
+
'deploy',
|
|
6
|
+
'diagnose',
|
|
7
|
+
'fire-action',
|
|
8
|
+
'list',
|
|
9
|
+
'nuke',
|
|
10
|
+
'reset-activity',
|
|
11
|
+
'set-stage',
|
|
12
|
+
'show',
|
|
13
|
+
'start',
|
|
14
|
+
'tail',
|
|
15
|
+
];
|
|
16
|
+
const rootCommandSet = new Set(STANDALONE_ROOT_COMMANDS);
|
|
17
|
+
export function firstPositionalIndex(args) {
|
|
18
|
+
for (let i = 0; i < args.length; i++) {
|
|
19
|
+
const token = args[i];
|
|
20
|
+
if (token === undefined)
|
|
21
|
+
continue;
|
|
22
|
+
if (token === '--')
|
|
23
|
+
return i + 1 < args.length ? i + 1 : -1;
|
|
24
|
+
if (!token.startsWith('-'))
|
|
25
|
+
return i;
|
|
26
|
+
}
|
|
27
|
+
return -1;
|
|
28
|
+
}
|
|
29
|
+
function stripScriptArgSeparator(args) {
|
|
30
|
+
return args[0] === '--' ? args.slice(1) : args;
|
|
31
|
+
}
|
|
32
|
+
export function rewriteStandaloneArgv(args) {
|
|
33
|
+
const normalized = stripScriptArgSeparator(args);
|
|
34
|
+
const i = firstPositionalIndex(normalized);
|
|
35
|
+
if (i === -1)
|
|
36
|
+
return normalized;
|
|
37
|
+
const first = normalized[i];
|
|
38
|
+
if (first === undefined || first === WORKFLOWS_TOPIC)
|
|
39
|
+
return normalized;
|
|
40
|
+
if (first === 'help') {
|
|
41
|
+
const commandIndex = firstPositionalIndex(normalized.slice(i + 1));
|
|
42
|
+
if (commandIndex === -1)
|
|
43
|
+
return normalized;
|
|
44
|
+
const absolute = i + 1 + commandIndex;
|
|
45
|
+
const command = normalized[absolute];
|
|
46
|
+
if (command === undefined || command === WORKFLOWS_TOPIC || !rootCommandSet.has(command)) {
|
|
47
|
+
return normalized;
|
|
48
|
+
}
|
|
49
|
+
return [...normalized.slice(0, absolute), WORKFLOWS_TOPIC, ...normalized.slice(absolute)];
|
|
50
|
+
}
|
|
51
|
+
if (!rootCommandSet.has(first))
|
|
52
|
+
return normalized;
|
|
53
|
+
return [...normalized.slice(0, i), WORKFLOWS_TOPIC, ...normalized.slice(i)];
|
|
54
|
+
}
|