diff --git a/javascriptv3/example_code/bedrock-runtime/scenarios/cli_text_playground.js b/javascriptv3/example_code/bedrock-runtime/scenarios/cli_text_playground.js index 1763022bdb5..1e4747157a1 100644 --- a/javascriptv3/example_code/bedrock-runtime/scenarios/cli_text_playground.js +++ b/javascriptv3/example_code/bedrock-runtime/scenarios/cli_text_playground.js @@ -42,7 +42,6 @@ const printDetails = new ScenarioOutput( * @param {{ model: ModelConfig, prompt: string }} c */ (c) => console.log(`Invoking ${c.model.modelName} with '${c.prompt}'...`), - { slow: false }, ); const invokeModel = new ScenarioAction( @@ -63,7 +62,6 @@ const printResponse = new ScenarioOutput( * @param {{ response: string }} c */ (c) => c.response, - { slow: false }, ); const scenario = new Scenario("Amazon Bedrock Runtime Demo", [ diff --git a/javascriptv3/example_code/cross-services/wkflw-topics-queues/README.md b/javascriptv3/example_code/cross-services/wkflw-topics-queues/README.md index ae8bcc8c056..2e2b2fb5298 100644 --- a/javascriptv3/example_code/cross-services/wkflw-topics-queues/README.md +++ b/javascriptv3/example_code/cross-services/wkflw-topics-queues/README.md @@ -34,8 +34,6 @@ The sample code builds a command line application that asks you for input. This 1. Install dependencies. `npm i` 2. Run the example. `node index.js` -**Note**: By default the prompts in the example will print slowly for readability. To disable this, pass the `--no-logger-delay` option. - ## Tests ⚠ Running tests might result in charges to your AWS account. diff --git a/javascriptv3/example_code/cross-services/wkflw-topics-queues/index.js b/javascriptv3/example_code/cross-services/wkflw-topics-queues/index.js index 3548fa3b98d..755ae9ceb32 100644 --- a/javascriptv3/example_code/cross-services/wkflw-topics-queues/index.js +++ b/javascriptv3/example_code/cross-services/wkflw-topics-queues/index.js @@ -9,14 +9,12 @@ import { SQSClient } from "@aws-sdk/client-sqs"; import { TopicsQueuesWkflw } from "./TopicsQueuesWkflw.js"; import { Prompter } from "@aws-doc-sdk-examples/lib/prompter.js"; -import { SlowLogger } from "@aws-doc-sdk-examples/lib/slow-logger.js"; export const startSnsWorkflow = () => { - const noLoggerDelay = process.argv.find((arg) => arg === "--no-logger-delay"); const snsClient = new SNSClient({}); const sqsClient = new SQSClient({}); const prompter = new Prompter(); - const logger = noLoggerDelay ? console : new SlowLogger(25); + const logger = console; const wkflw = new TopicsQueuesWkflw(snsClient, sqsClient, prompter, logger); diff --git a/javascriptv3/example_code/ec2/scenarios/basic.js b/javascriptv3/example_code/ec2/scenarios/basic.js index 564ff0ea864..8ce78ff296a 100644 --- a/javascriptv3/example_code/ec2/scenarios/basic.js +++ b/javascriptv3/example_code/ec2/scenarios/basic.js @@ -120,23 +120,51 @@ export const ec2Scenario = new Scenario( /** * Run the EC2 introductory scenario. This will make changes * in your AWS account. - * @param {{ confirmAll: boolean, verbose: boolean }} options + * @param {{ confirmAll: boolean, verbose: boolean, noArt: boolean }} options */ -export const main = async ({ confirmAll, verbose }) => { - await ec2Scenario.run({ confirmAll, verbose }); +export const main = async ({ confirmAll, verbose, noArt }) => { + await ec2Scenario.run({ confirmAll, verbose, noArt }); }; -// Call function if run directly. -import { fileURLToPath } from "node:url"; +// Call function if run directly import { parseArgs } from "node:util"; -if (process.argv[1] === fileURLToPath(import.meta.url)) { - const { values } = parseArgs({ - options: { - yes: { - type: "boolean", - short: "y", - }, +import { + isMain, + validateArgs, + printManPage, +} from "@aws-doc-sdk-examples/lib/utils/util-node.js"; + +const loadArgs = () => { + const options = { + help: { + type: "boolean", + }, + confirmAll: { + type: "boolean", + description: "Skip user input.", }, - }); - main({ confirmAll: values.yes }); + noArt: { + type: "boolean", + description: "Do not display ASCII art or text decorations.", + }, + }; + const results = parseArgs({ options }); + const { errors } = validateArgs({ options }, results); + if (results.values.help) { + printManPage(options, { + name: "EC2 Basics", + description: "Learn the basic SDK commands for Amazon EC2.", + synopsis: "node basics.js [OPTIONS]", + }); + } + return { errors, results }; +}; + +if (isMain(import.meta.url)) { + const { errors, results } = loadArgs(); + if (errors) { + console.error(errors.join("\n")); + } else if (!results.values.help) { + main(results.values); + } } diff --git a/javascriptv3/example_code/ec2/scenarios/steps.js b/javascriptv3/example_code/ec2/scenarios/steps.js index acb01402033..ed67c7f2ffd 100644 --- a/javascriptv3/example_code/ec2/scenarios/steps.js +++ b/javascriptv3/example_code/ec2/scenarios/steps.js @@ -82,13 +82,16 @@ export const exitOnNoConfirm = new ScenarioAction( export const greeting = new ScenarioOutput( "greeting", - `Welcome to the Amazon EC2 basic usage scenario. + ` + +Welcome to the Amazon EC2 basic usage scenario. + Before you launch an instances, you'll need to provide a few things: - • A key pair - This is for SSH access to your EC2 instance. You only need to provide the name. - • A security group - This is used for configuring access to your instance. Again, only the name is needed. - • An IP address - Your public IP address will be fetched. - • An Amazon Machine Image (AMI) - • A compatible instance type`, + - A key pair - This is for SSH access to your EC2 instance. You only need to provide the name. + - A security group - This is used for configuring access to your instance. Again, only the name is needed. + - An IP address - Your public IP address will be fetched. + - An Amazon Machine Image (AMI) + - A compatible instance type`, { header: true, preformatted: true, skipWhen: skipWhenErrors }, ); @@ -376,7 +379,7 @@ export const provideImage = new ScenarioInput( type: "select", choices: (/** @type { State } */ state) => state.images.map((image) => ({ - name: `${image.ImageId} - ${image.Description}`, + name: `${image.Description}`, value: image, })), default: (/** @type { State } */ state) => state.images[0], @@ -804,7 +807,7 @@ export const logErrors = new ScenarioOutput( "logErrors", (/** @type {State}*/ state) => { const errorList = state.errors - .map((err) => `• ${err.name}: ${err.message}`) + .map((err) => ` - ${err.name}: ${err.message}`) .join("\n"); return `Scenario errors found:\n${errorList}`; }, diff --git a/javascriptv3/example_code/libs/scenario/scenario.js b/javascriptv3/example_code/libs/scenario/scenario.js index 1dde561f957..05e6cd2daee 100644 --- a/javascriptv3/example_code/libs/scenario/scenario.js +++ b/javascriptv3/example_code/libs/scenario/scenario.js @@ -3,10 +3,9 @@ import { Prompter } from "../prompter.js"; import { Logger } from "../logger.js"; -import { SlowLogger } from "../slow-logger.js"; /** - * @typedef {{ confirmAll: boolean, verbose: boolean }} StepHandlerOptions + * @typedef {{ confirmAll: boolean, verbose: boolean, noArt: boolean }} StepHandlerOptions */ /** @@ -56,7 +55,7 @@ export class Step { } /** - * @typedef {{ slow: boolean, header: boolean, preformatted: boolean }} ScenarioOutputOptions + * @typedef {{ header: boolean, preformatted: boolean }} ScenarioOutputOptions */ /** @@ -68,10 +67,9 @@ export class ScenarioOutput extends Step { * @param {string | (state: Record) => string | false} value * @param {Step['stepOptions']} [scenarioOutputOptions] */ - constructor(name, value, scenarioOutputOptions = { slow: true }) { + constructor(name, value, scenarioOutputOptions = {}) { super(name, scenarioOutputOptions); this.value = value; - this.slowLogger = new SlowLogger(20); this.logger = new Logger(); } @@ -95,14 +93,15 @@ export class ScenarioOutput extends Step { } const paddingTop = "\n"; const paddingBottom = "\n"; - const logger = - this.stepOptions?.slow && !stepHandlerOptions?.confirmAll - ? this.slowLogger - : this.logger; + const logger = this.logger; const message = paddingTop + output + paddingBottom; if (this.stepOptions?.header) { - await this.logger.log(this.logger.box(message)); + if (stepHandlerOptions.noArt === true) { + await this.logger.log(message); + } else { + await this.logger.log(this.logger.box(message)); + } } else { await logger.log(message, this.stepOptions?.preformatted); } diff --git a/javascriptv3/example_code/libs/slow-logger.js b/javascriptv3/example_code/libs/slow-logger.js deleted file mode 100644 index 0da3473ec4b..00000000000 --- a/javascriptv3/example_code/libs/slow-logger.js +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -import { Logger } from "./logger.js"; - -// snippet-start:[javascript.v3.wkflw.topicsandqueues.logger] -export class SlowLogger extends Logger { - constructor(delayInMs) { - super(); - this.delay = delayInMs; - } - - _sleep() { - return new Promise((resolve) => setTimeout(resolve, this.delay)); - } - - /** - * @param {string} message - */ - async _logSlow(message) { - const chars = message.split(""); - for (const c of chars) { - process.stdout.write(c); - await this._sleep(); - } - process.stderr.write("\n"); - } - - /** - * Write a message to the console. Split the message into multiple lines if - * a line would be longer than the max width. Do not split in the middle of - * a word. - * - Generated by CodeWhisperer. - * @param {string} message - * @param {boolean} preformatted Ignore word wrapping if true. Default: false. - * @param {number} maxWidth - */ - async log(message, preformatted = false, maxWidth = 80) { - const words = message.split(" "); - let line = ""; - if (!preformatted) { - for (const word of words) { - if (line.length + word.length > maxWidth) { - await this._logSlow(line); - line = ""; - } - line += `${word} `; - } - } - await this._logSlow(line); - } -} -// snippet-end:[javascript.v3.wkflw.topicsandqueues.logger] diff --git a/javascriptv3/example_code/libs/utils/util-node.js b/javascriptv3/example_code/libs/utils/util-node.js index cb55a8827d0..a0a14ab9997 100644 --- a/javascriptv3/example_code/libs/utils/util-node.js +++ b/javascriptv3/example_code/libs/utils/util-node.js @@ -41,3 +41,33 @@ export const validateArgs = (config, results) => { return { errors }; }; + +/** + * Take a list of options and program info and print a man page. + * @param {Record} options + * @param {{ name: string, synopsis: string, description: string }} programInfo + */ +export const printManPage = (options, programInfo) => { + const { name, synopsis, description } = programInfo; + + console.log("NAME"); + console.log(` ${name}`); + console.log(); + console.log("SYNOPSIS"); + console.log(` ${synopsis}`); + console.log(); + console.log("DESCRIPTION"); + console.log(` ${description}`); + console.log(); + console.log("OPTIONS"); + + const optionPadding = + Math.max(...Object.keys(options).map((key) => key.length)) + 4; + + for (const [key, value] of Object.entries(options)) { + const paddedKey = `--${key}`.padEnd(optionPadding); + console.log( + ` ${paddedKey}${value.type}${(value.description ?? "") && ` - ${value.description}`}`, + ); + } +}; diff --git a/javascriptv3/example_code/medical-imaging/scenarios/health-image-sets/image-frame-steps.js b/javascriptv3/example_code/medical-imaging/scenarios/health-image-sets/image-frame-steps.js index 3584ed76513..8940653d945 100644 --- a/javascriptv3/example_code/medical-imaging/scenarios/health-image-sets/image-frame-steps.js +++ b/javascriptv3/example_code/medical-imaging/scenarios/health-image-sets/image-frame-steps.js @@ -121,5 +121,4 @@ export const outputImageFrameIds = new ScenarioOutput( return output; }, - { slow: false }, ); diff --git a/javascriptv3/example_code/sagemaker/scenarios/wkflw-sagemaker-geospatial-pipeline/index.js b/javascriptv3/example_code/sagemaker/scenarios/wkflw-sagemaker-geospatial-pipeline/index.js index c6c28fa3f5a..e62eba9065d 100644 --- a/javascriptv3/example_code/sagemaker/scenarios/wkflw-sagemaker-geospatial-pipeline/index.js +++ b/javascriptv3/example_code/sagemaker/scenarios/wkflw-sagemaker-geospatial-pipeline/index.js @@ -10,12 +10,11 @@ import { SQSClient } from "@aws-sdk/client-sqs"; import { S3Client } from "@aws-sdk/client-s3"; import { Prompter } from "@aws-doc-sdk-examples/lib/prompter.js"; -import { SlowLogger } from "@aws-doc-sdk-examples/lib/slow-logger.js"; import { SageMakerPipelinesWkflw } from "./SageMakerPipelinesWkflw.js"; const prompter = new Prompter(); -const logger = new SlowLogger(25); +const logger = console; export async function main() { const pipelineWkfw = new SageMakerPipelinesWkflw(prompter, logger, {