hereya-cli 0.50.0 → 0.52.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/README.md +44 -42
- package/dist/backend/cloud/cloud-backend.js +7 -0
- package/dist/backend/common.d.ts +5 -0
- package/dist/backend/common.js +1 -0
- package/dist/backend/file.js +1 -0
- package/dist/commands/add/index.js +7 -0
- package/dist/commands/deploy/index.js +7 -0
- package/dist/commands/down/index.js +7 -0
- package/dist/commands/flow/add/index.js +13 -1
- package/dist/commands/flow/down/index.js +13 -1
- package/dist/commands/flow/env/index.js +8 -0
- package/dist/commands/flow/remove/index.js +13 -1
- package/dist/commands/flow/run/index.js +8 -0
- package/dist/commands/flow/up/index.js +13 -1
- package/dist/commands/remove/index.js +7 -0
- package/dist/commands/run/index.js +6 -0
- package/dist/commands/undeploy/index.js +7 -0
- package/dist/commands/up/index.js +7 -0
- package/dist/commands/workspace/create/index.d.ts +1 -0
- package/dist/commands/workspace/create/index.js +2 -0
- package/dist/commands/workspace/list/index.js +7 -3
- package/dist/commands/workspace/set-profile/index.d.ts +1 -0
- package/dist/commands/workspace/set-profile/index.js +20 -3
- package/dist/lib/flow-utils.js +8 -3
- package/dist/lib/workspace-validation.d.ts +17 -0
- package/dist/lib/workspace-validation.js +102 -0
- package/oclif.manifest.json +104 -88
- package/package.json +2 -2
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { getBackend } from '../../../backend/index.js';
|
|
2
3
|
import { getConfigManager } from '../../../lib/config/index.js';
|
|
3
4
|
import { buildFlowWorkspaceName } from '../../../lib/flow-utils.js';
|
|
4
5
|
import { setDebug } from '../../../lib/log.js';
|
|
6
|
+
import { validateFlowCommand } from '../../../lib/workspace-validation.js';
|
|
5
7
|
import Up from '../../up/index.js';
|
|
6
8
|
import WorkspaceCreate from '../../workspace/create/index.js';
|
|
7
9
|
export default class FlowUp extends Command {
|
|
@@ -61,8 +63,18 @@ export default class FlowUp extends Command {
|
|
|
61
63
|
project: loadConfigOutput.config.project,
|
|
62
64
|
projectRootDir,
|
|
63
65
|
});
|
|
66
|
+
// Validate that if workspace exists, it's not a deployment workspace
|
|
67
|
+
const backend = await getBackend();
|
|
68
|
+
const validation = await validateFlowCommand(workspaceName, backend);
|
|
69
|
+
if (!validation.isValid) {
|
|
70
|
+
this.error(validation.message);
|
|
71
|
+
}
|
|
72
|
+
// Import workspace resolution utility
|
|
73
|
+
const { resolveWorkspaceName } = await import('../../../lib/workspace-utils.js');
|
|
74
|
+
// Resolve mirror workspace name with org prefix
|
|
75
|
+
const mirrorWorkspace = resolveWorkspaceName(loadConfigOutput.config.workspace, loadConfigOutput.config.project);
|
|
64
76
|
// Create workspace with mirror
|
|
65
|
-
const createArgs = [workspaceName, '--mirror',
|
|
77
|
+
const createArgs = [workspaceName, '--mirror', mirrorWorkspace];
|
|
66
78
|
if (projectRootDir) {
|
|
67
79
|
createArgs.push('--chdir', projectRootDir);
|
|
68
80
|
}
|
|
@@ -8,6 +8,7 @@ import { getLogger, getLogPath, isDebug, setDebug } from '../../lib/log.js';
|
|
|
8
8
|
import { getParameterManager } from '../../lib/parameter/index.js';
|
|
9
9
|
import { getProfileFromWorkspace } from '../../lib/profile-utils.js';
|
|
10
10
|
import { delay } from '../../lib/shell.js';
|
|
11
|
+
import { validateDevelopmentWorkspace } from '../../lib/workspace-validation.js';
|
|
11
12
|
export default class Remove extends Command {
|
|
12
13
|
static args = {
|
|
13
14
|
package: Args.string({
|
|
@@ -60,6 +61,12 @@ export default class Remove extends Command {
|
|
|
60
61
|
ctx.configOutput = loadConfigOutput;
|
|
61
62
|
// Use workspace from flag if provided, otherwise use config workspace
|
|
62
63
|
ctx.workspace = flags.workspace || loadConfigOutput.config.workspace;
|
|
64
|
+
// Validate that the workspace is a development workspace
|
|
65
|
+
const backend = await getBackend();
|
|
66
|
+
const validation = await validateDevelopmentWorkspace(ctx.workspace, backend, 'remove');
|
|
67
|
+
if (!validation.isValid) {
|
|
68
|
+
throw new Error(validation.message);
|
|
69
|
+
}
|
|
63
70
|
const { config } = loadConfigOutput;
|
|
64
71
|
if (!(ctx.package in (config.packages ?? {})) && !(ctx.package in (config.deploy ?? {}))) {
|
|
65
72
|
throw new Error(`Package ${ctx.package} not found in the project.`);
|
|
@@ -4,6 +4,7 @@ import { getConfigManager } from '../../lib/config/index.js';
|
|
|
4
4
|
import { getEnvManager } from '../../lib/env/index.js';
|
|
5
5
|
import { getProfileFromWorkspace } from '../../lib/profile-utils.js';
|
|
6
6
|
import { runShell } from '../../lib/shell.js';
|
|
7
|
+
import { validateDevelopmentWorkspace } from '../../lib/workspace-validation.js';
|
|
7
8
|
export default class Run extends Command {
|
|
8
9
|
static args = {
|
|
9
10
|
cmd: Args.string({ description: 'command to run', required: true }),
|
|
@@ -43,6 +44,11 @@ export default class Run extends Command {
|
|
|
43
44
|
this.error('you must specify a workspace to run the command in');
|
|
44
45
|
}
|
|
45
46
|
const backend = await getBackend();
|
|
47
|
+
// Validate that the workspace is a development workspace
|
|
48
|
+
const validation = await validateDevelopmentWorkspace(workspace, backend, 'run');
|
|
49
|
+
if (!validation.isValid) {
|
|
50
|
+
this.error(validation.message);
|
|
51
|
+
}
|
|
46
52
|
const profile = await getProfileFromWorkspace(backend, workspace, config.project);
|
|
47
53
|
const envManager = getEnvManager();
|
|
48
54
|
const getProjectEnvOutput = await envManager.getProjectEnv({
|
|
@@ -9,6 +9,7 @@ import { getLogger, getLogPath, isDebug, setDebug } from '../../lib/log.js';
|
|
|
9
9
|
import { getParameterManager } from '../../lib/parameter/index.js';
|
|
10
10
|
import { getProfileFromWorkspace } from '../../lib/profile-utils.js';
|
|
11
11
|
import { delay } from '../../lib/shell.js';
|
|
12
|
+
import { validateDeploymentWorkspace } from '../../lib/workspace-validation.js';
|
|
12
13
|
export default class Undeploy extends Command {
|
|
13
14
|
static description = 'Undeploy a hereya project by removing all resources.';
|
|
14
15
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
@@ -35,6 +36,12 @@ export default class Undeploy extends Command {
|
|
|
35
36
|
const { flags } = await this.parse(Undeploy);
|
|
36
37
|
setDebug(flags.debug);
|
|
37
38
|
const projectRootDir = path.resolve(flags.chdir || process.env.HEREYA_PROJECT_ROOT_DIR || process.cwd());
|
|
39
|
+
// Validate that the workspace is a deployment workspace
|
|
40
|
+
const backend = await getBackend();
|
|
41
|
+
const validation = await validateDeploymentWorkspace(flags.workspace, backend, 'undeploy');
|
|
42
|
+
if (!validation.isValid) {
|
|
43
|
+
this.error(validation.message);
|
|
44
|
+
}
|
|
38
45
|
const myLogger = new ListrLogger({ useIcons: false });
|
|
39
46
|
const task = new Listr([
|
|
40
47
|
{
|
|
@@ -8,6 +8,7 @@ import { getLogger, getLogPath, isDebug, setDebug } from '../../lib/log.js';
|
|
|
8
8
|
import { getParameterManager } from '../../lib/parameter/index.js';
|
|
9
9
|
import { getProfileFromWorkspace } from '../../lib/profile-utils.js';
|
|
10
10
|
import { delay } from '../../lib/shell.js';
|
|
11
|
+
import { validateDevelopmentWorkspace } from '../../lib/workspace-validation.js';
|
|
11
12
|
export default class Up extends Command {
|
|
12
13
|
static description = 'Provision all packages in the project.';
|
|
13
14
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
@@ -58,6 +59,12 @@ export default class Up extends Command {
|
|
|
58
59
|
}
|
|
59
60
|
ctx.configOutput = loadConfigOutput;
|
|
60
61
|
ctx.workspace = flags.workspace || loadConfigOutput.config.workspace;
|
|
62
|
+
// Validate that the workspace is a development workspace
|
|
63
|
+
const backend = await getBackend();
|
|
64
|
+
const validation = await validateDevelopmentWorkspace(ctx.workspace, backend, 'up');
|
|
65
|
+
if (!validation.isValid) {
|
|
66
|
+
throw new Error(validation.message);
|
|
67
|
+
}
|
|
61
68
|
await delay(500);
|
|
62
69
|
},
|
|
63
70
|
title: 'Loading project config',
|
|
@@ -6,6 +6,7 @@ export default class WorkspaceCreate extends Command {
|
|
|
6
6
|
static description: string;
|
|
7
7
|
static examples: string[];
|
|
8
8
|
static flags: {
|
|
9
|
+
deployment: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
10
|
mirror: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
11
|
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
12
|
};
|
|
@@ -7,6 +7,7 @@ export default class WorkspaceCreate extends Command {
|
|
|
7
7
|
static description = 'Create a new workspace if it does not exist.';
|
|
8
8
|
static examples = ['<%= config.bin %> <%= command.id %> dev'];
|
|
9
9
|
static flags = {
|
|
10
|
+
deployment: Flags.boolean({ char: 'd', description: 'mark workspace as a deployment workspace', required: false }),
|
|
10
11
|
mirror: Flags.string({ description: 'workspace to mirror', required: false }),
|
|
11
12
|
profile: Flags.string({ description: 'workspace profile to set (cloud backend only)', required: false }),
|
|
12
13
|
};
|
|
@@ -14,6 +15,7 @@ export default class WorkspaceCreate extends Command {
|
|
|
14
15
|
const { args, flags } = await this.parse(WorkspaceCreate);
|
|
15
16
|
const backend = await getBackend();
|
|
16
17
|
const createWorkspaceOutput = await backend.createWorkspace({
|
|
18
|
+
isDeploy: flags.deployment,
|
|
17
19
|
mirrorOf: flags.mirror,
|
|
18
20
|
name: args.name,
|
|
19
21
|
profile: flags.profile,
|
|
@@ -19,12 +19,14 @@ export default class WorkspaceList extends Command {
|
|
|
19
19
|
const result = await backend.getWorkspace(name);
|
|
20
20
|
if (result.found && !result.hasError) {
|
|
21
21
|
return {
|
|
22
|
+
deployment: result.workspace.isDeploy ? 'Yes' : 'No',
|
|
22
23
|
mirrorOf: result.workspace.mirrorOf || '-',
|
|
23
24
|
name,
|
|
24
25
|
profile: result.workspace.profile || '-',
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
return {
|
|
29
|
+
deployment: 'No',
|
|
28
30
|
mirrorOf: '-',
|
|
29
31
|
name,
|
|
30
32
|
profile: '-',
|
|
@@ -32,6 +34,7 @@ export default class WorkspaceList extends Command {
|
|
|
32
34
|
}
|
|
33
35
|
catch {
|
|
34
36
|
return {
|
|
37
|
+
deployment: 'No',
|
|
35
38
|
mirrorOf: '-',
|
|
36
39
|
name,
|
|
37
40
|
profile: '-',
|
|
@@ -41,13 +44,14 @@ export default class WorkspaceList extends Command {
|
|
|
41
44
|
// Calculate column widths for alignment
|
|
42
45
|
const nameWidth = Math.max(4, ...workspaceDetails.map(w => w.name.length)); // min 4 for "Name"
|
|
43
46
|
const profileWidth = Math.max(7, ...workspaceDetails.map(w => w.profile.length)); // min 7 for "Profile"
|
|
47
|
+
const deploymentWidth = Math.max(10, ...workspaceDetails.map(w => w.deployment.length)); // min 10 for "Deployment"
|
|
44
48
|
const mirrorWidth = Math.max(9, ...workspaceDetails.map(w => w.mirrorOf.length)); // min 9 for "Mirror Of"
|
|
45
49
|
// Display header
|
|
46
|
-
this.log(`${'Name'.padEnd(nameWidth)} ${'Profile'.padEnd(profileWidth)} ${'Mirror Of'.padEnd(mirrorWidth)}`);
|
|
47
|
-
this.log('-'.repeat(nameWidth + profileWidth + mirrorWidth +
|
|
50
|
+
this.log(`${'Name'.padEnd(nameWidth)} ${'Profile'.padEnd(profileWidth)} ${'Deployment'.padEnd(deploymentWidth)} ${'Mirror Of'.padEnd(mirrorWidth)}`);
|
|
51
|
+
this.log('-'.repeat(nameWidth + profileWidth + deploymentWidth + mirrorWidth + 6));
|
|
48
52
|
// Display rows
|
|
49
53
|
for (const workspace of workspaceDetails) {
|
|
50
|
-
this.log(`${workspace.name.padEnd(nameWidth)} ${workspace.profile.padEnd(profileWidth)} ${workspace.mirrorOf.padEnd(mirrorWidth)}`);
|
|
54
|
+
this.log(`${workspace.name.padEnd(nameWidth)} ${workspace.profile.padEnd(profileWidth)} ${workspace.deployment.padEnd(deploymentWidth)} ${workspace.mirrorOf.padEnd(mirrorWidth)}`);
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
catch (error) {
|
|
@@ -6,6 +6,7 @@ export default class WorkspaceSetProfile extends Command {
|
|
|
6
6
|
static description: string;
|
|
7
7
|
static examples: string[];
|
|
8
8
|
static flags: {
|
|
9
|
+
deployment: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
10
|
workspace: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
11
|
};
|
|
11
12
|
run(): Promise<void>;
|
|
@@ -4,21 +4,38 @@ export default class WorkspaceSetProfile extends Command {
|
|
|
4
4
|
static args = {
|
|
5
5
|
profile: Args.string({ description: 'AWS profile name to set for the workspace', required: true }),
|
|
6
6
|
};
|
|
7
|
-
static description = 'Set AWS profile for a workspace (cloud backend only).';
|
|
7
|
+
static description = 'Set AWS profile and deployment status for a workspace (cloud backend only).';
|
|
8
8
|
static examples = ['<%= config.bin %> <%= command.id %> prod-profile -w production'];
|
|
9
9
|
static flags = {
|
|
10
|
+
deployment: Flags.boolean({
|
|
11
|
+
allowNo: true,
|
|
12
|
+
char: 'd',
|
|
13
|
+
description: 'mark workspace as a deployment workspace (use --no-deployment to unset)',
|
|
14
|
+
required: false,
|
|
15
|
+
}),
|
|
10
16
|
workspace: Flags.string({ char: 'w', description: 'workspace name', required: true }),
|
|
11
17
|
};
|
|
12
18
|
async run() {
|
|
13
19
|
const { args, flags } = await this.parse(WorkspaceSetProfile);
|
|
14
20
|
const backend = await getBackend();
|
|
15
21
|
const updateResult = await backend.updateWorkspace({
|
|
22
|
+
isDeploy: flags.deployment,
|
|
16
23
|
name: flags.workspace,
|
|
17
24
|
profile: args.profile,
|
|
18
25
|
});
|
|
19
26
|
if (!updateResult.success) {
|
|
20
|
-
this.error(`Failed to
|
|
27
|
+
this.error(`Failed to update workspace: ${updateResult.reason}`);
|
|
21
28
|
}
|
|
22
|
-
|
|
29
|
+
const messages = [];
|
|
30
|
+
messages.push(`Profile '${args.profile}' set for workspace '${flags.workspace}'`);
|
|
31
|
+
if (flags.deployment !== undefined) {
|
|
32
|
+
if (flags.deployment) {
|
|
33
|
+
messages.push(`Workspace marked as deployment workspace`);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
messages.push(`Workspace unmarked as deployment workspace`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
this.log(messages.join('. ') + '!');
|
|
23
40
|
}
|
|
24
41
|
}
|
package/dist/lib/flow-utils.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { gitUtils } from './git-utils.js';
|
|
2
|
+
import { addOrgPrefix, extractOrgPrefix } from './org-utils.js';
|
|
2
3
|
export async function buildFlowWorkspaceName(options) {
|
|
3
4
|
const { pin, profile, project, projectRootDir } = options;
|
|
5
|
+
// Extract org prefix from project
|
|
6
|
+
const { name: projectName, org } = extractOrgPrefix(project);
|
|
4
7
|
// Get current git branch
|
|
5
8
|
const gitBranch = await gitUtils.getCurrentGitBranch(projectRootDir);
|
|
6
9
|
// Sanitize branch name
|
|
@@ -10,13 +13,15 @@ export async function buildFlowWorkspaceName(options) {
|
|
|
10
13
|
}
|
|
11
14
|
// Get commit SHA if pin is enabled
|
|
12
15
|
const commitSHA = pin ? await gitUtils.getShortCommitSHA(projectRootDir) : null;
|
|
13
|
-
// Build workspace name parts
|
|
14
|
-
const parts = [
|
|
16
|
+
// Build workspace name parts (without org prefix)
|
|
17
|
+
const parts = [projectName, sanitizedBranch];
|
|
15
18
|
if (profile) {
|
|
16
19
|
parts.push(profile);
|
|
17
20
|
}
|
|
18
21
|
if (commitSHA) {
|
|
19
22
|
parts.push(commitSHA);
|
|
20
23
|
}
|
|
21
|
-
|
|
24
|
+
// Join parts and add org prefix if present
|
|
25
|
+
const workspaceName = parts.join('---');
|
|
26
|
+
return addOrgPrefix(org, workspaceName);
|
|
22
27
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Backend } from '../backend/common.js';
|
|
2
|
+
export interface WorkspaceValidationResult {
|
|
3
|
+
isValid: boolean;
|
|
4
|
+
message?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Validates that a workspace exists and is marked as a deployment workspace (isDeploy=true)
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateDeploymentWorkspace(workspaceName: string, backend: Backend, commandName: string): Promise<WorkspaceValidationResult>;
|
|
10
|
+
/**
|
|
11
|
+
* Validates that a workspace exists and is NOT marked as a deployment workspace (isDeploy=false or undefined)
|
|
12
|
+
*/
|
|
13
|
+
export declare function validateDevelopmentWorkspace(workspaceName: string, backend: Backend, commandName: string): Promise<WorkspaceValidationResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Validates that flow commands are not used with deployment workspaces
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateFlowCommand(workspaceName: string | undefined, backend: Backend): Promise<WorkspaceValidationResult>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates that a workspace exists and is marked as a deployment workspace (isDeploy=true)
|
|
3
|
+
*/
|
|
4
|
+
export async function validateDeploymentWorkspace(workspaceName, backend, commandName) {
|
|
5
|
+
const result = await backend.getWorkspace(workspaceName);
|
|
6
|
+
if (!result.found) {
|
|
7
|
+
return {
|
|
8
|
+
isValid: false,
|
|
9
|
+
message: `Workspace '${workspaceName}' not found. Create a deployment workspace with:\n$ hereya workspace:create ${workspaceName} --deployment`,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
if (result.hasError) {
|
|
13
|
+
return {
|
|
14
|
+
isValid: false,
|
|
15
|
+
message: `Error accessing workspace '${workspaceName}': ${result.error}`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const { workspace } = result;
|
|
19
|
+
if (!workspace.isDeploy) {
|
|
20
|
+
return {
|
|
21
|
+
isValid: false,
|
|
22
|
+
message: `Cannot use '${commandName}' with development workspace '${workspaceName}'.
|
|
23
|
+
|
|
24
|
+
The '${commandName}' command requires a deployment workspace. You have two options:
|
|
25
|
+
|
|
26
|
+
1. Create a deployment workspace:
|
|
27
|
+
$ hereya workspace:create prod-deployment --deployment
|
|
28
|
+
|
|
29
|
+
2. Convert existing workspace to deployment (if using cloud backend):
|
|
30
|
+
$ hereya workspace:set-profile ${workspaceName} --deployment
|
|
31
|
+
|
|
32
|
+
Then run: $ hereya ${commandName} -w prod-deployment`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return { isValid: true };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validates that a workspace exists and is NOT marked as a deployment workspace (isDeploy=false or undefined)
|
|
39
|
+
*/
|
|
40
|
+
export async function validateDevelopmentWorkspace(workspaceName, backend, commandName) {
|
|
41
|
+
const result = await backend.getWorkspace(workspaceName);
|
|
42
|
+
if (!result.found) {
|
|
43
|
+
return {
|
|
44
|
+
isValid: false,
|
|
45
|
+
message: `Workspace '${workspaceName}' not found. Create a workspace with:\n$ hereya workspace:create ${workspaceName}`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (result.hasError) {
|
|
49
|
+
return {
|
|
50
|
+
isValid: false,
|
|
51
|
+
message: `Error accessing workspace '${workspaceName}': ${result.error}`,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const { workspace } = result;
|
|
55
|
+
if (workspace.isDeploy === true) {
|
|
56
|
+
return {
|
|
57
|
+
isValid: false,
|
|
58
|
+
message: `Cannot use '${commandName}' with deployment workspace '${workspaceName}'.
|
|
59
|
+
|
|
60
|
+
The '${commandName}' command is for development workspaces only. Deployment workspaces
|
|
61
|
+
should only be managed through 'deploy' and 'undeploy' commands.
|
|
62
|
+
|
|
63
|
+
To work with packages in development:
|
|
64
|
+
1. Use a development workspace: $ hereya ${commandName} <args> -w dev-workspace
|
|
65
|
+
2. Or create a new one: $ hereya workspace:create dev-workspace`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return { isValid: true };
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Validates that flow commands are not used with deployment workspaces
|
|
72
|
+
*/
|
|
73
|
+
export async function validateFlowCommand(workspaceName, backend) {
|
|
74
|
+
if (!workspaceName) {
|
|
75
|
+
// If no workspace specified, flow commands will create their own
|
|
76
|
+
return { isValid: true };
|
|
77
|
+
}
|
|
78
|
+
const result = await backend.getWorkspace(workspaceName);
|
|
79
|
+
if (!result.found) {
|
|
80
|
+
// Workspace doesn't exist, flow command will create it
|
|
81
|
+
return { isValid: true };
|
|
82
|
+
}
|
|
83
|
+
if (result.hasError) {
|
|
84
|
+
return {
|
|
85
|
+
isValid: false,
|
|
86
|
+
message: `Error accessing workspace '${workspaceName}': ${result.error}`,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const { workspace } = result;
|
|
90
|
+
if (workspace.isDeploy === true) {
|
|
91
|
+
return {
|
|
92
|
+
isValid: false,
|
|
93
|
+
message: `Flow commands cannot be used with deployment workspaces.
|
|
94
|
+
|
|
95
|
+
Flow commands are designed for feature branch development workflows.
|
|
96
|
+
For deployment workspaces, use the standard 'deploy' and 'undeploy' commands.
|
|
97
|
+
|
|
98
|
+
Current workspace '${workspaceName}' is marked as a deployment workspace.`,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return { isValid: true };
|
|
102
|
+
}
|