Skip to content

Commit 834137a

Browse files
committed
missing code
1 parent 26f0940 commit 834137a

6 files changed

Lines changed: 842 additions & 0 deletions

File tree

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
import {Args, Flags, ux} from '@oclif/core';
2+
import cliui from 'cliui';
3+
import {MrtCommand} from '@salesforce/b2c-tooling/cli';
4+
import {createEnv, type MrtEnvironment} from '@salesforce/b2c-tooling/operations/mrt';
5+
import {t} from '../../../i18n/index.js';
6+
7+
/**
8+
* Print environment details in a formatted table.
9+
*/
10+
function printEnvDetails(env: MrtEnvironment, project: string): void {
11+
const ui = cliui({width: process.stdout.columns || 80});
12+
const labelWidth = 18;
13+
14+
ui.div('');
15+
ui.div({text: 'Slug:', width: labelWidth}, {text: env.slug ?? ''});
16+
ui.div({text: 'Name:', width: labelWidth}, {text: env.name});
17+
ui.div({text: 'Project:', width: labelWidth}, {text: project});
18+
ui.div({text: 'State:', width: labelWidth}, {text: env.state ?? 'unknown'});
19+
ui.div({text: 'Production:', width: labelWidth}, {text: env.is_production ? 'Yes' : 'No'});
20+
21+
if (env.ssr_region) {
22+
ui.div({text: 'Region:', width: labelWidth}, {text: env.ssr_region});
23+
}
24+
25+
if (env.hostname) {
26+
ui.div({text: 'Hostname:', width: labelWidth}, {text: env.hostname});
27+
}
28+
29+
if (env.ssr_external_hostname) {
30+
ui.div({text: 'External Host:', width: labelWidth}, {text: env.ssr_external_hostname});
31+
}
32+
33+
if (env.ssr_external_domain) {
34+
ui.div({text: 'External Domain:', width: labelWidth}, {text: env.ssr_external_domain});
35+
}
36+
37+
if (env.allow_cookies) {
38+
ui.div({text: 'Allow Cookies:', width: labelWidth}, {text: 'Yes'});
39+
}
40+
41+
if (env.enable_source_maps) {
42+
ui.div({text: 'Source Maps:', width: labelWidth}, {text: 'Yes'});
43+
}
44+
45+
if (env.log_level) {
46+
ui.div({text: 'Log Level:', width: labelWidth}, {text: env.log_level});
47+
}
48+
49+
ux.stdout(ui.toString());
50+
}
51+
52+
/**
53+
* Valid AWS regions for MRT environments.
54+
*/
55+
const SSR_REGIONS = [
56+
'us-east-1',
57+
'us-east-2',
58+
'us-west-1',
59+
'us-west-2',
60+
'ap-south-1',
61+
'ap-south-2',
62+
'ap-northeast-2',
63+
'ap-southeast-1',
64+
'ap-southeast-2',
65+
'ap-southeast-3',
66+
'ap-northeast-1',
67+
'ap-northeast-3',
68+
'ca-central-1',
69+
'eu-central-1',
70+
'eu-central-2',
71+
'eu-west-1',
72+
'eu-west-2',
73+
'eu-west-3',
74+
'eu-north-1',
75+
'eu-south-1',
76+
'il-central-1',
77+
'me-central-1',
78+
'sa-east-1',
79+
] as const;
80+
81+
type SsrRegion = (typeof SSR_REGIONS)[number];
82+
83+
/**
84+
* Create a new environment (target) in a Managed Runtime project.
85+
*/
86+
export default class MrtEnvCreate extends MrtCommand<typeof MrtEnvCreate> {
87+
static args = {
88+
slug: Args.string({
89+
description: 'Environment slug/identifier (e.g., staging, production)',
90+
required: true,
91+
}),
92+
};
93+
94+
static description = t('commands.mrt.env.create.description', 'Create a new Managed Runtime environment');
95+
96+
static enableJsonFlag = true;
97+
98+
static examples = [
99+
'<%= config.bin %> <%= command.id %> staging --project my-storefront --name "Staging Environment"',
100+
'<%= config.bin %> <%= command.id %> production --project my-storefront --name "Production" --production',
101+
'<%= config.bin %> <%= command.id %> feature-test -p my-storefront -n "Feature Test" --region eu-west-1',
102+
];
103+
104+
static flags = {
105+
...MrtCommand.baseFlags,
106+
name: Flags.string({
107+
char: 'n',
108+
description: 'Display name for the environment',
109+
required: true,
110+
}),
111+
region: Flags.string({
112+
char: 'r',
113+
description: 'AWS region for SSR deployment',
114+
options: SSR_REGIONS as unknown as string[],
115+
}),
116+
production: Flags.boolean({
117+
description: 'Mark as a production environment',
118+
default: false,
119+
}),
120+
hostname: Flags.string({
121+
description: 'Hostname pattern for V8 Tag loading',
122+
}),
123+
'external-hostname': Flags.string({
124+
description: 'Full external hostname (e.g., www.example.com)',
125+
}),
126+
'external-domain': Flags.string({
127+
description: 'External domain for Universal PWA SSR (e.g., example.com)',
128+
}),
129+
'allow-cookies': Flags.boolean({
130+
description: 'Forward HTTP cookies to origin',
131+
default: false,
132+
allowNo: true,
133+
}),
134+
'enable-source-maps': Flags.boolean({
135+
description: 'Enable source map support in the environment',
136+
default: false,
137+
allowNo: true,
138+
}),
139+
};
140+
141+
async run(): Promise<MrtEnvironment> {
142+
this.requireMrtCredentials();
143+
144+
const {slug} = this.args;
145+
const {mrtProject: project} = this.resolvedConfig;
146+
147+
if (!project) {
148+
this.error(
149+
'MRT project is required. Provide --project flag, set SFCC_MRT_PROJECT, or set mrtProject in dw.json.',
150+
);
151+
}
152+
153+
const {
154+
name,
155+
region,
156+
production: isProduction,
157+
hostname,
158+
'external-hostname': externalHostname,
159+
'external-domain': externalDomain,
160+
'allow-cookies': allowCookies,
161+
'enable-source-maps': enableSourceMaps,
162+
} = this.flags;
163+
164+
this.log(
165+
t('commands.mrt.env.create.creating', 'Creating environment "{{slug}}" in {{project}}...', {slug, project}),
166+
);
167+
168+
try {
169+
const result = await createEnv(
170+
{
171+
projectSlug: project,
172+
slug,
173+
name,
174+
region: region as SsrRegion | undefined,
175+
isProduction,
176+
hostname,
177+
externalHostname,
178+
externalDomain,
179+
allowCookies: allowCookies || undefined,
180+
enableSourceMaps: enableSourceMaps || undefined,
181+
},
182+
this.getMrtAuth(),
183+
);
184+
185+
if (this.jsonEnabled()) {
186+
return result;
187+
}
188+
189+
// Human-readable output
190+
this.log(t('commands.mrt.env.create.success', 'Environment created successfully.'));
191+
192+
printEnvDetails(result, project);
193+
194+
return result;
195+
} catch (error) {
196+
if (error instanceof Error) {
197+
this.error(
198+
t('commands.mrt.env.create.failed', 'Failed to create environment: {{message}}', {message: error.message}),
199+
);
200+
}
201+
throw error;
202+
}
203+
}
204+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import * as readline from 'node:readline';
2+
import {Args, Flags} from '@oclif/core';
3+
import {MrtCommand} from '@salesforce/b2c-tooling/cli';
4+
import {deleteEnv} from '@salesforce/b2c-tooling/operations/mrt';
5+
import {t} from '../../../i18n/index.js';
6+
7+
/**
8+
* Simple confirmation prompt.
9+
*/
10+
async function confirm(message: string): Promise<boolean> {
11+
const rl = readline.createInterface({
12+
input: process.stdin,
13+
output: process.stderr,
14+
});
15+
16+
return new Promise((resolve) => {
17+
rl.question(`${message} `, (answer) => {
18+
rl.close();
19+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
20+
});
21+
});
22+
}
23+
24+
/**
25+
* Delete an environment (target) from a Managed Runtime project.
26+
*/
27+
export default class MrtEnvDelete extends MrtCommand<typeof MrtEnvDelete> {
28+
static args = {
29+
slug: Args.string({
30+
description: 'Environment slug/identifier to delete',
31+
required: true,
32+
}),
33+
};
34+
35+
static description = t('commands.mrt.env.delete.description', 'Delete a Managed Runtime environment');
36+
37+
static enableJsonFlag = true;
38+
39+
static examples = [
40+
'<%= config.bin %> <%= command.id %> feature-test --project my-storefront',
41+
'<%= config.bin %> <%= command.id %> old-staging -p my-storefront --force',
42+
];
43+
44+
static flags = {
45+
...MrtCommand.baseFlags,
46+
force: Flags.boolean({
47+
char: 'f',
48+
description: 'Skip confirmation prompt',
49+
default: false,
50+
}),
51+
};
52+
53+
async run(): Promise<{slug: string; project: string}> {
54+
this.requireMrtCredentials();
55+
56+
const {slug} = this.args;
57+
const {mrtProject: project} = this.resolvedConfig;
58+
59+
if (!project) {
60+
this.error(
61+
'MRT project is required. Provide --project flag, set SFCC_MRT_PROJECT, or set mrtProject in dw.json.',
62+
);
63+
}
64+
65+
const {force} = this.flags;
66+
67+
// Confirm deletion unless --force is used
68+
if (!force && !this.jsonEnabled()) {
69+
const confirmed = await confirm(
70+
t(
71+
'commands.mrt.env.delete.confirm',
72+
'Are you sure you want to delete environment "{{slug}}" from {{project}}? (y/n)',
73+
{
74+
slug,
75+
project,
76+
},
77+
),
78+
);
79+
80+
if (!confirmed) {
81+
this.log(t('commands.mrt.env.delete.cancelled', 'Deletion cancelled.'));
82+
return {slug, project};
83+
}
84+
}
85+
86+
if (!this.jsonEnabled()) {
87+
this.log(
88+
t('commands.mrt.env.delete.deleting', 'Deleting environment "{{slug}}" from {{project}}...', {slug, project}),
89+
);
90+
}
91+
92+
try {
93+
await deleteEnv(
94+
{
95+
projectSlug: project,
96+
slug,
97+
},
98+
this.getMrtAuth(),
99+
);
100+
101+
if (!this.jsonEnabled()) {
102+
this.log(
103+
t('commands.mrt.env.delete.success', 'Environment "{{slug}}" deleted from {{project}}.', {
104+
slug,
105+
project,
106+
}),
107+
);
108+
}
109+
110+
return {slug, project};
111+
} catch (error) {
112+
if (error instanceof Error) {
113+
this.error(
114+
t('commands.mrt.env.delete.failed', 'Failed to delete environment: {{message}}', {message: error.message}),
115+
);
116+
}
117+
throw error;
118+
}
119+
}
120+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import {Args} from '@oclif/core';
2+
import {MrtCommand} from '@salesforce/b2c-tooling/cli';
3+
import {deleteEnvVar} from '@salesforce/b2c-tooling/operations/mrt';
4+
import {t} from '../../../../i18n/index.js';
5+
6+
/**
7+
* Delete an environment variable from an MRT project environment.
8+
*/
9+
export default class MrtEnvVarDelete extends MrtCommand<typeof MrtEnvVarDelete> {
10+
static args = {
11+
key: Args.string({
12+
description: 'Environment variable name',
13+
required: true,
14+
}),
15+
};
16+
17+
static description = t(
18+
'commands.mrt.env.var.delete.description',
19+
'Delete an environment variable from a Managed Runtime environment',
20+
);
21+
22+
static enableJsonFlag = true;
23+
24+
static examples = [
25+
'<%= config.bin %> <%= command.id %> MY_VAR --project acme-storefront --environment production',
26+
'<%= config.bin %> <%= command.id %> OLD_API_KEY -p my-project -e staging',
27+
];
28+
29+
static flags = {
30+
...MrtCommand.baseFlags,
31+
};
32+
33+
async run(): Promise<{key: string; project: string; environment: string}> {
34+
this.requireMrtCredentials();
35+
36+
const {key} = this.args;
37+
const {mrtProject: project, mrtEnvironment: environment} = this.resolvedConfig;
38+
39+
if (!project) {
40+
this.error(
41+
'MRT project is required. Provide --project flag, set SFCC_MRT_PROJECT, or set mrtProject in dw.json.',
42+
);
43+
}
44+
if (!environment) {
45+
this.error(
46+
'MRT environment is required. Provide --environment flag, set SFCC_MRT_ENVIRONMENT, or set mrtEnvironment in dw.json.',
47+
);
48+
}
49+
50+
await deleteEnvVar(
51+
{
52+
projectSlug: project,
53+
environment,
54+
key,
55+
},
56+
this.getMrtAuth(),
57+
);
58+
59+
this.log(
60+
t('commands.mrt.env.var.delete.success', 'Deleted {{key}} from {{project}}/{{environment}}', {
61+
key,
62+
project,
63+
environment,
64+
}),
65+
);
66+
67+
return {key, project, environment};
68+
}
69+
}

0 commit comments

Comments
 (0)