Skip to content

Commit 960575f

Browse files
authored
Cli: check for invalid stages names (#1793)
* Cli: check for invalid stages names * Sync
1 parent 8e039ba commit 960575f

3 files changed

Lines changed: 33 additions & 9 deletions

File tree

‎.changeset/sixty-timers-walk.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@serverless-stack/cli": patch
3+
"@serverless-stack/core": patch
4+
---
5+
6+
Cli: check for invalid stages names

‎packages/cli/bin/scripts.mjs‎

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -261,21 +261,35 @@ async function getStage(argv, config) {
261261

262262
if (process.env.__TEST__ === "true") return DEFAULT_STAGE;
263263

264+
// Generate a suggested stage name as the default
264265
const suggested = await State.suggestStage();
266+
const question = `Please enter a stage name you’d like to use locally. Or hit enter to use the one based on your AWS credentials (${suggested}): `;
267+
268+
// Prompt to enter a stage name
269+
const input = await questionSync(`Look like you’re running sst for the first time in this directory. ${question}`);
270+
let final = input.trim() || suggested;
271+
272+
// Re-prompt if stage name is invalid
273+
while(!State.validateStage(final)) {
274+
logger.error(chalk.red("Stage names must start with a letter, and contain only letters, numbers, and hyphens."));
275+
const input = await questionSync(`\n${question}`);
276+
final = input.trim() || suggested;
277+
}
278+
279+
State.setStage(paths.appPath, final);
280+
return final;
281+
}
282+
283+
function questionSync(question) {
265284
const rl = readline.createInterface({
266285
input: process.stdin,
267286
output: process.stdout,
268287
});
269288
return new Promise((resolve) => {
270-
rl.question(
271-
`Look like you’re running sst for the first time in this directory. Please enter a stage name you’d like to use locally. Or hit enter to use the one based on your AWS credentials (${suggested}): `,
272-
(input) => {
273-
const final = input.trim() || suggested;
274-
State.setStage(paths.appPath, final);
275-
rl.close();
276-
resolve(final);
277-
}
278-
);
289+
rl.question(question, (input) => {
290+
rl.close();
291+
resolve(input);
292+
});
279293
});
280294
}
281295

‎packages/core/src/state/index.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,7 @@ export async function suggestStage() {
5252
.catch(() => os.userInfo().username);
5353
return result.replace(/[^A-Za-z0-9]/g, "-");
5454
}
55+
56+
export function validateStage(stage: string) {
57+
return stage.match(/^[A-Za-z][A-Za-z0-9-]*$/);
58+
}

0 commit comments

Comments
 (0)