From 13d75757cd98781a3d69e1e75ce3e5dc8dc9601d Mon Sep 17 00:00:00 2001 From: Amandeep Date: Mon, 15 Sep 2025 20:34:56 +0530 Subject: [PATCH 1/2] Feat: Complete Js to Ts conversion --- bin/{cli.mjs => cli.ts} | 43 +- bin/commands/{add.mjs => add.ts} | 52 +- bin/commands/clone.mjs | 71 --- bin/commands/clone.ts | 99 ++++ bin/commands/config.mjs | 52 -- bin/commands/config.ts | 61 ++ bin/commands/{construct.mjs => construct.ts} | 19 +- .../{deconstruct.mjs => deconstruct.ts} | 27 +- bin/commands/remove.mjs | 39 -- bin/commands/remove.ts | 64 ++ bin/types.ts | 111 ++++ bin/utils/{constants.mjs => constants.ts} | 13 +- bin/utils/constructor.mjs | 25 - bin/utils/constructor.ts | 46 ++ .../{deconstructor.mjs => deconstructor.ts} | 16 +- bin/utils/helper.mjs | 53 -- bin/utils/helper.ts | 68 +++ package-lock.json | 552 ++++++++++-------- package.json | 18 +- tsconfig.json | 44 ++ 20 files changed, 922 insertions(+), 551 deletions(-) rename bin/{cli.mjs => cli.ts} (79%) rename bin/commands/{add.mjs => add.ts} (63%) delete mode 100644 bin/commands/clone.mjs create mode 100644 bin/commands/clone.ts delete mode 100644 bin/commands/config.mjs create mode 100644 bin/commands/config.ts rename bin/commands/{construct.mjs => construct.ts} (56%) rename bin/commands/{deconstruct.mjs => deconstruct.ts} (57%) delete mode 100644 bin/commands/remove.mjs create mode 100644 bin/commands/remove.ts create mode 100644 bin/types.ts rename bin/utils/{constants.mjs => constants.ts} (92%) delete mode 100644 bin/utils/constructor.mjs create mode 100644 bin/utils/constructor.ts rename bin/utils/{deconstructor.mjs => deconstructor.ts} (60%) delete mode 100644 bin/utils/helper.mjs create mode 100644 bin/utils/helper.ts create mode 100644 tsconfig.json diff --git a/bin/cli.mjs b/bin/cli.ts similarity index 79% rename from bin/cli.mjs rename to bin/cli.ts index 8d96f6c..28a8b86 100755 --- a/bin/cli.mjs +++ b/bin/cli.ts @@ -4,13 +4,21 @@ import inquirer from "inquirer"; import autocompletePrompt from "inquirer-autocomplete-prompt"; import { hideBin } from "yargs/helpers"; -import { deconstruct } from "./commands/deconstruct.mjs"; -import { construct } from "./commands/construct.mjs"; -import { add } from "./commands/add.mjs"; -import { config } from "./commands/config.mjs"; -import { remove } from "./commands/remove.mjs"; -import { clone } from "./commands/clone.mjs"; -import { awsRegions } from "./utils/constants.mjs"; +import { deconstruct } from "./commands/deconstruct.js"; +import { construct } from "./commands/construct.js"; +import { add } from "./commands/add.js"; +import { config } from "./commands/config.js"; +import { remove } from "./commands/remove.js"; +import { clone } from "./commands/clone.js"; +import { awsRegions } from "./utils/constants.js"; +import type { + AddArgs, + CloneArgs, + ConfigArgs, + ConstructArgs, + DeconstructArgs, + RemoveArgs, +} from "./types.js"; // Get the original command from process.argv const command = process.argv.slice(2).join(" "); @@ -34,7 +42,7 @@ yargs(hideBin(process.argv)) }); }, (argv) => { - construct(argv, command); + construct(argv as ConstructArgs); } ) .command( @@ -53,7 +61,7 @@ yargs(hideBin(process.argv)) }); }, (argv) => { - deconstruct(argv, command); + deconstruct(argv as DeconstructArgs); } ) .command( @@ -74,7 +82,7 @@ yargs(hideBin(process.argv)) }); }, (argv) => { - add(argv, command); + add(argv as unknown as AddArgs); } ) .command( @@ -89,7 +97,7 @@ yargs(hideBin(process.argv)) }); }, (argv) => { - remove(argv, command); + remove(argv as unknown as RemoveArgs); } ) .command( @@ -116,7 +124,7 @@ yargs(hideBin(process.argv)) }); }, (argv) => { - clone(argv, command); + clone(argv as unknown as CloneArgs); } ) .command("config", "Configure ShelbySAM", {}, () => { @@ -126,7 +134,10 @@ yargs(hideBin(process.argv)) type: "autocomplete", name: "region", message: "Select your AWS region:", - source: (answers, input) => { + source: ( + answers: Record, + input: string | undefined + ) => { return Promise.resolve( awsRegions.filter((region) => region.includes(input || "")) ); @@ -153,10 +164,10 @@ yargs(hideBin(process.argv)) }, ]) .then((answers) => { - config(answers); + config(answers as ConfigArgs); }); }) - .demandCommand(1, "", null) + .demandCommand(1, "You need to specify a command to run") .version("1.1.5") - .parse() + .parse(); diff --git a/bin/commands/add.mjs b/bin/commands/add.ts similarity index 63% rename from bin/commands/add.mjs rename to bin/commands/add.ts index f36067f..24aa1d3 100644 --- a/bin/commands/add.mjs +++ b/bin/commands/add.ts @@ -1,11 +1,14 @@ #!/usr/bin/env node -import { readJson, readYaml, readConfig } from "../utils/helper.mjs"; +import { readJson, readYaml, readConfig } from "../utils/helper.js"; import fs from "fs"; import yaml from "js-yaml"; -import { markdownSyntax } from "../utils/constants.mjs"; -let templateRegistry = {}; +import { markdownSyntax } from "../utils/constants.js"; +import type { AddArgs, TemplateRegistry, PropertyType } from "../types.js"; -const identifyType = (key, properties, resource) => { + +let templateRegistry: TemplateRegistry = { ResourceTypes: {}, PropertyTypes: {} }; + +const identifyType = (key: string, properties: PropertyType, resource: string): unknown => { // Level 1 processing if (Object.keys(properties).includes("PrimitiveType")) { // directly return the types, no further processing required @@ -22,9 +25,9 @@ const identifyType = (key, properties, resource) => { // Level 2 processing - flex if (Object.keys(properties).includes("Type")) { - let outputTemplate = {}; + let outputTemplate: Record = {}; let outputType = "json"; - let propertyTemplate = {}; + let propertyTemplate: PropertyType | undefined; // sub template definition --> "PropertyTypes" if (Object.keys(properties).includes("ItemType")) { propertyTemplate = @@ -36,10 +39,13 @@ const identifyType = (key, properties, resource) => { outputType = "json"; } - for (const [k, v] of Object.entries(propertyTemplate)) { - if (k === "Properties") { - for (const [kk, vv] of Object.entries(v)) { - outputTemplate[kk] = identifyType(kk, vv, resource); + if (propertyTemplate) { + for (const [k, v] of Object.entries(propertyTemplate)) { + if (k === "Properties") { + const properties = v as Record; + for (const [kk, vv] of Object.entries(properties)) { + outputTemplate[kk] = identifyType(kk, vv, resource); + } } } } @@ -49,34 +55,45 @@ const identifyType = (key, properties, resource) => { }; // Main Function -const add = async (args, command) => { + +const add = async (args: AddArgs): Promise => { try { // read config file const shelbysamConfig = await readConfig(); + if (!shelbysamConfig) { + throw new Error("ShelbySAM configuration not found. Please run 'shelbysam config' first."); + } // get cloudformation registry templateRegistry = await readJson( `.shelbysam/${shelbysamConfig.region}.json` - ); + ) as TemplateRegistry; // read template file const shelbysamTemplate = await readYaml( shelbysamConfig.shelbysam_template_file ); + if (!shelbysamTemplate) { + throw new Error(`Unable to read template file: ${shelbysamConfig.shelbysam_template_file}`); + } // main template definition--> "ResourceTypes" - let outputTemplate = {}; + let outputTemplate: Record = {}; const resourceTemplate = templateRegistry.ResourceTypes[args.type]; + if (!resourceTemplate) { + throw new Error(`Resource type '${args.type}' not found in template registry`); + } + // log document link console.log( - `\n For more information on ${args.type}, visit ${resourceTemplate.Documentation}\n` + `\n For more information on ${args.type}, visit ${resourceTemplate.Documentation || 'N/A'}\n` ); //start processing for (const [k, v] of Object.entries(resourceTemplate)) { if (k === "Properties") { - for (const [kk, vv] of Object.entries(v)) { + for (const [kk, vv] of Object.entries(v as Record)) { outputTemplate[kk] = identifyType(kk, vv, args.type); } } @@ -90,8 +107,11 @@ const add = async (args, command) => { ".yaml"; // add resource to template + if (!shelbysamTemplate.Resources) { + shelbysamTemplate.Resources = {}; + } shelbysamTemplate.Resources[args.lid] = - "${file:" + shelbysamResourcePath + "}"; + "${file:" + shelbysamResourcePath + "}" as string; // write the resource file fs.writeFileSync( diff --git a/bin/commands/clone.mjs b/bin/commands/clone.mjs deleted file mode 100644 index f1666b5..0000000 --- a/bin/commands/clone.mjs +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env node -import { - readYaml, - readConfig, - matchRegex, - writeYaml, -} from "../utils/helper.mjs"; -import fs from "fs"; - -// Main Function -const clone = async (args, command) => { - // read config file - const shelbysamConfig = await readConfig(); - - // read template - const shelbysamTemplate = await readYaml( - shelbysamConfig.shelbysam_template_file - ); - - // match regex for the available declarations - const resource = matchRegex(shelbysamTemplate.Resources[args.slid]); - - const shelbysamSourceResourcePath = resource[1][1]; - const shelbysamDestinationResourcePath = - shelbysamConfig.shelbysam_template_folder + - "/Resources/" + - args.dlid + - ".yaml"; - - // Direct File References - if (resource[0] === "File") { - shelbysamTemplate.Resources[args.dlid] = - "${file:" + shelbysamDestinationResourcePath + "}"; - fs.cpSync(shelbysamSourceResourcePath, shelbysamDestinationResourcePath); - } - // File Object / Group References - else if (resource[0] === "FileObject") { - const sourceResources = await readYaml(shelbysamSourceResourcePath); - - // if group flag is set to true, re-create all resources in the file - if (args.group) { - const destResources = {}; - for (const [k, v] of Object.entries(sourceResources)) { - shelbysamTemplate.Resources[args.dlid + k] = - "${file:" + shelbysamDestinationResourcePath + ":" + k + "}"; - destResources[k] = v; - } - await writeYaml(shelbysamDestinationResourcePath, destResources); - } - // if group flag is set to false, re-create only the specified resource - else { - shelbysamTemplate.Resources[args.dlid] = - "${file:" + shelbysamDestinationResourcePath + "}"; - - console.log(sourceResources[resource[1][2]]); - await writeYaml( - shelbysamDestinationResourcePath, - sourceResources[resource[1][2]] - ); - } - } - - // write the final template - await writeYaml(shelbysamConfig.shelbysam_template_file, shelbysamTemplate); - - return; -}; - -// add support for nested file objects - -export { clone }; diff --git a/bin/commands/clone.ts b/bin/commands/clone.ts new file mode 100644 index 0000000..eefa434 --- /dev/null +++ b/bin/commands/clone.ts @@ -0,0 +1,99 @@ +#!/usr/bin/env node +import { + readYaml, + readConfig, + matchRegex, + writeYaml, +} from "../utils/helper.js"; +import fs from "fs"; +import type { CloneArgs } from "../types.js"; + + +// Main Function +const clone = async (args:CloneArgs): Promise => { + // read config file + const shelbysamConfig = await readConfig(); + if (!shelbysamConfig) { + throw new Error("ShelbySAM configuration not found. Please run 'shelbysam config' first."); + } + + // read template + const shelbysamTemplate = await readYaml( + shelbysamConfig.shelbysam_template_file! + ); + if (!shelbysamTemplate) { + throw new Error(`Unable to read template file: ${shelbysamConfig.shelbysam_template_file}`); + } + + // match regex for the available declarations + if (!shelbysamTemplate.Resources) { + throw new Error("No resources found in template"); + } + const resourceValue = shelbysamTemplate.Resources[args.slid]; + if (!resourceValue || typeof resourceValue !== 'string') { + throw new Error(`Source resource '${args.slid}' not found or invalid format`); + } + const resource = matchRegex(resourceValue); + + const shelbysamSourceResourcePath = (resource[1] as RegExpMatchArray)[1]!; + const shelbysamDestinationResourcePath = + shelbysamConfig.shelbysam_template_folder! + + "/Resources/" + + args.dlid + + ".yaml"; + + // Direct File References + if (resource[0] === "File") { + if (!shelbysamTemplate.Resources) { + shelbysamTemplate.Resources = {}; + } + shelbysamTemplate.Resources[args.dlid] = + "${file:" + shelbysamDestinationResourcePath + "}" as string; + fs.cpSync(shelbysamSourceResourcePath, shelbysamDestinationResourcePath); + } + // File Object / Group References + else if (resource[0] === "FileObject") { + const sourceResources = await readYaml(shelbysamSourceResourcePath); + if (!sourceResources) { + throw new Error(`Unable to read source resource file: ${shelbysamSourceResourcePath}`); + } + + // if group flag is set to true, re-create all resources in the file + if (args.group) { + const destResources: Record = {}; + for (const [k, v] of Object.entries(sourceResources)) { + if (!shelbysamTemplate.Resources) { + shelbysamTemplate.Resources = {}; + } + shelbysamTemplate.Resources[args.dlid + k] = + "${file:" + shelbysamDestinationResourcePath + ":" + k + "}" as string; + destResources[k] = v; + } + await writeYaml(shelbysamDestinationResourcePath, destResources); + } + // if group flag is set to false, re-create only the specified resource + else { + if (!shelbysamTemplate.Resources) { + shelbysamTemplate.Resources = {}; + } + shelbysamTemplate.Resources[args.dlid] = + "${file:" + shelbysamDestinationResourcePath + "}" as string; + + const resourceKey = (resource[1] as RegExpMatchArray)[2] as string; + console.log((sourceResources as Record)[resourceKey]); + await writeYaml( + shelbysamDestinationResourcePath, + (sourceResources as Record)[resourceKey] + ); + } + } + + // write the final template + await writeYaml(shelbysamConfig.shelbysam_template_file!, shelbysamTemplate); + + return; +}; + +// add support for nested file objects + +export { clone }; diff --git a/bin/commands/config.mjs b/bin/commands/config.mjs deleted file mode 100644 index f51cd7c..0000000 --- a/bin/commands/config.mjs +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env node -import fs from "fs"; -import json2toml from "json2toml"; -import { readConfig } from "../utils/helper.mjs"; -import { cfr } from "../utils/constants.mjs"; - -const fetchCF = (region) => { - fetch(cfr[region]) - .then((response) => { - return response.json(); - }) - .then((data) => { - fs.writeFileSync( - ".shelbysam/" + region + ".json", - JSON.stringify(data, null, 4), - { flag: "w" } - ); - }); -}; - -// Main Function -const config = async (args) => { - let configExists = true; - - // Check config file - try { - const shelbysamConfig = await readConfig(); - // future - // replace this with existsSync - } catch (error) { - if ( - error.message === - "ENOENT: no such file or directory, open 'shelbysam-config.toml'" - ) { - // delete .shelbysam folder if exists - const shelbysamFolderExists = fs.existsSync(".shelbysam"); - if (shelbysamFolderExists) fs.rm(".shelbysam", { recursive: true }); - configExists = false; - } - } - // if configuration does not exist, create it - if (!configExists) { - fs.mkdirSync(".shelbysam"); - } - - fs.writeFileSync("shelbysam-config.toml", json2toml(args)); - // Fetch the file to create or update it on config command - fetchCF(args.region); - return; -}; - -export { config }; diff --git a/bin/commands/config.ts b/bin/commands/config.ts new file mode 100644 index 0000000..a2f8007 --- /dev/null +++ b/bin/commands/config.ts @@ -0,0 +1,61 @@ +#!/usr/bin/env node +import fs from "fs"; +import json2toml from "json2toml"; +import { readConfig } from "../utils/helper.js"; +import { cfr } from "../utils/constants.js"; +import type { ConfigArgs } from "../types.js"; + +const fetchCF = (region: string): void => { + const regionUrl = cfr[region]; + if (regionUrl) { + fetch(regionUrl) + .then((response) => { + return response.json(); + }) + .then((data) => { + fs.writeFileSync( + ".shelbysam/" + region + ".json", + JSON.stringify(data, null, 4), + { flag: "w" } + ); + }); + } +}; + +// Main Function +const config = async (args: ConfigArgs): Promise => { + let configExists = true; + + // Check config file + try { + const loadedConfig = await readConfig(); + if (loadedConfig) { + // future + // replace this with existsSync + } else { + // If readConfig returns undefined, treat it as config not existing + configExists = false; + } + } catch (error: unknown) { + if ( + (error as NodeJS.ErrnoException).message === + "ENOENT: no such file or directory, open 'shelbysam-config.toml'" + ) { + // delete .shelbysam folder if exists + const shelbysamFolderExists = fs.existsSync(".shelbysam"); + if (shelbysamFolderExists) fs.rmSync(".shelbysam", { recursive: true }); + configExists = false; + } + } + // if configuration does not exist, create it + if (!configExists) { + fs.mkdirSync(".shelbysam"); + } + + fs.writeFileSync("shelbysam-config.toml", json2toml(args)); + // Fetch the file to create or update it on config command + fetchCF(args.region); + return; +}; + +export { config }; diff --git a/bin/commands/construct.mjs b/bin/commands/construct.ts similarity index 56% rename from bin/commands/construct.mjs rename to bin/commands/construct.ts index e17358f..e7229c4 100644 --- a/bin/commands/construct.mjs +++ b/bin/commands/construct.ts @@ -1,17 +1,23 @@ #!/usr/bin/env node import fs from "fs"; import yaml from "js-yaml"; -import { readYaml, readConfig } from "../utils/helper.mjs"; -import { constructingLoop } from "../utils/constructor.mjs"; +import { readYaml, readConfig } from "../utils/helper.js"; +import { constructingLoop } from "../utils/constructor.js"; +import type { ConstructArgs } from "../types.js"; // Main Function -const construct = async (args, command) => { +const construct = async (args: ConstructArgs) => { const shelbysamConfigExists = fs.existsSync("shelbysam-config.toml"); let shelbysamConfig = { shelbysam_template_file: "shelbysam.yaml", sam_template_file: "template.yaml", }; - if (shelbysamConfigExists) shelbysamConfig = await readConfig(); + if (shelbysamConfigExists) { + const config = await readConfig(); + if (config) { + shelbysamConfig = config; + } + } args.itemplate = args.itemplate ? args.itemplate @@ -22,9 +28,12 @@ const construct = async (args, command) => { // read base file let baseTemplate = await readYaml(args.itemplate); + if (!baseTemplate) { + throw new Error(`Unable to read template file: ${args.itemplate}`); + } // construct template file - baseTemplate = await constructingLoop(baseTemplate); + baseTemplate = await constructingLoop(baseTemplate as Record); // write the output fs.writeFileSync(args.otemplate, yaml.dump(baseTemplate)); diff --git a/bin/commands/deconstruct.mjs b/bin/commands/deconstruct.ts similarity index 57% rename from bin/commands/deconstruct.mjs rename to bin/commands/deconstruct.ts index 93b9b84..73e4bae 100644 --- a/bin/commands/deconstruct.mjs +++ b/bin/commands/deconstruct.ts @@ -2,21 +2,28 @@ import yaml from "js-yaml"; import fs from "fs"; -import { readYaml, readConfig } from "../utils/helper.mjs"; -import { deconstructingLoop } from "../utils/deconstructor.mjs"; +import { readYaml, readConfig } from "../utils/helper.js"; +import { deconstructingLoop } from "../utils/deconstructor.js"; +import type { DeconstructArgs, DeconstructingLoopArgs, CloudFormationTemplate } from "../types.js"; +import type { ConfigArgs } from "../types.js"; const keySeparatorsL1 = ["Globals", "Outputs", "Parameters"]; const keySeparatorsL2 = ["Resources"]; // Main function -const deconstruct = async (args, command) => { +const deconstruct = async (args:DeconstructArgs):Promise => { const shelbysamConfigExists = fs.existsSync("shelbysam-config.toml"); let shelbysamConfig = { sam_template_file: "template.yaml", shelbysam_template_folder: "infra_resources", }; - if (shelbysamConfigExists) shelbysamConfig = await readConfig(); + if (shelbysamConfigExists) { + const config = await readConfig(); + if (config) { + shelbysamConfig = config; + } + } // Switching between args.template and args.name is to enable reusability between init and deconstruct commands args.template = args.template @@ -24,16 +31,24 @@ const deconstruct = async (args, command) => { : shelbysamConfig.sam_template_file; args.path = args.path ? args.path : shelbysamConfig.shelbysam_template_folder; + // check if template file exists + if (!fs.existsSync(args.template)) { + throw new Error(`Template file '${args.template}' not found`); + } + // copy template file fs.cpSync(args.template, "shelbysam.yaml"); // declare template let template = await readYaml("shelbysam.yaml"); + if (!template) { + throw new Error("Unable to read shelbysam.yaml"); + } // create deconstructed files template = await deconstructingLoop( - template, - args, + template as Record,//!TODO: fix this + args as DeconstructingLoopArgs, //!TODO: fix this keySeparatorsL1, keySeparatorsL2 ); diff --git a/bin/commands/remove.mjs b/bin/commands/remove.mjs deleted file mode 100644 index ceb2810..0000000 --- a/bin/commands/remove.mjs +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env node -import { - readYaml, - readConfig, - writeYaml, - matchRegex, -} from "../utils/helper.mjs"; -import fs from "fs"; - -// Main Function -const remove = async (args, command) => { - // read config file - const shelbysamConfig = await readConfig(); - - // read template - const shelbysamTemplate = await readYaml( - shelbysamConfig.shelbysam_template_file - ); - - const resource = matchRegex(shelbysamTemplate.Resources[args.lid]); - - // Direct File References - if (resource[0] === "File") { - fs.rmSync(resource[1][1]); - } - // File Object / Group References - else if (resource[0] === "FileObject") { - const resourceTemplate = await readYaml(resource[1][1]); - delete resourceTemplate[resource[1][2]]; - await writeYaml(resource[1][1], resourceTemplate); - } - - // update shelbysam template - delete shelbysamTemplate.Resources[args.lid]; - await writeYaml(shelbysamConfig.shelbysam_template_file, shelbysamTemplate); - return; -}; - -export { remove }; diff --git a/bin/commands/remove.ts b/bin/commands/remove.ts new file mode 100644 index 0000000..62dbacd --- /dev/null +++ b/bin/commands/remove.ts @@ -0,0 +1,64 @@ +#!/usr/bin/env node +import { + readYaml, + readConfig, + writeYaml, + matchRegex, +} from "../utils/helper.js"; +import fs from "fs"; +import type { RemoveArgs } from "../types.js"; + +// Main Function +const remove = async (args: RemoveArgs):Promise => { + // read config file + const shelbysamConfig = await readConfig(); + if (!shelbysamConfig) { + throw new Error("ShelbySAM configuration not found. Please run 'shelbysam config' first."); + } + + // read template + const shelbysamTemplate = await readYaml( + shelbysamConfig.shelbysam_template_file + ); + if (!shelbysamTemplate) { + throw new Error(`Unable to read template file: ${shelbysamConfig.shelbysam_template_file}`); + } + + if (!shelbysamTemplate.Resources) { + throw new Error("No resources found in template"); + } + const resourceValue = shelbysamTemplate.Resources[args.lid]; + if (!resourceValue || typeof resourceValue !== 'string') { + throw new Error(`Resource '${args.lid}' not found or invalid format`); + } + const resource = matchRegex(resourceValue); + + // Direct File References + if (resource[0] === "File") { + const filePath = (resource[1] as RegExpMatchArray)[1]; + if (filePath) { + fs.rmSync(filePath); + } + } + // File Object / Group References + else if (resource[0] === "FileObject") { + const filePath = (resource[1] as RegExpMatchArray)[1]; + const resourceKey = (resource[1] as RegExpMatchArray)[2]; + if (filePath) { + const resourceTemplate = await readYaml(filePath); + if (resourceTemplate && resourceKey) { + delete (resourceTemplate as Record)[resourceKey]; + await writeYaml(filePath, resourceTemplate); + } + } + } + + // update shelbysam template + if (shelbysamTemplate.Resources) { + delete shelbysamTemplate.Resources[args.lid]; + } + await writeYaml(shelbysamConfig.shelbysam_template_file, shelbysamTemplate); + return; +}; + +export { remove }; diff --git a/bin/types.ts b/bin/types.ts new file mode 100644 index 0000000..a9ff326 --- /dev/null +++ b/bin/types.ts @@ -0,0 +1,111 @@ +interface AddArgs { + type: string; + lid: string; +} +interface CloudFormationTemplate { + AWSTemplateFormatVersion?: string; + Transform?: string; + Description?: string; + Globals?: { + Api?: { + Cors?: { + AllowMethods?: string; + AllowHeaders?: string; + AllowOrigin?: string; + }; + }; + Function?: { + Timeout?: number; + MemorySize?: number; + Runtime?: string; + Architectures?: string[]; + LoggingConfig?: { + LogFormat?: string; + }; + }; + }; + Parameters?: Record; + Resources?: Record; + Metadata?: Record; + }>; + Outputs?: Record; + } + +interface CloneArgs { + slid: string; + dlid: string; + group?: boolean; +} + +interface ConfigArgs { + region: string; + sam_template_file: string; + shelbysam_template_file: string; + shelbysam_template_folder: string; + } + +interface ConstructArgs { + itemplate?: string; + otemplate?: string; +} + +interface DeconstructArgs { + template?: string; + path?: string; +} + +interface DeconstructingLoopArgs { + path: string; +} + +interface RemoveArgs { + lid: string; +} + +interface PropertyType { + PrimitiveType?: string; + PrimitiveItemType?: string; + Type?: string; + ItemType?: string; + Properties?: Record; +} + +interface ResourceType { + Documentation?: string; + Properties?: Record; +} + +interface TemplateRegistry { + ResourceTypes: Record; + PropertyTypes: Record; +} + +interface MatchResult { + type: string; + data: RegExpMatchArray; +} + +export type { + AddArgs, + CloneArgs, + ConfigArgs, + RemoveArgs, + MatchResult, + PropertyType, + ResourceType, + ConstructArgs, + DeconstructArgs, + TemplateRegistry, + DeconstructingLoopArgs, + CloudFormationTemplate +} \ No newline at end of file diff --git a/bin/utils/constants.mjs b/bin/utils/constants.ts similarity index 92% rename from bin/utils/constants.mjs rename to bin/utils/constants.ts index 73af441..a854e31 100644 --- a/bin/utils/constants.mjs +++ b/bin/utils/constants.ts @@ -1,10 +1,10 @@ // Regex -const fileRegex = /\$\{file:(.*?)\}/g; // direct file reference -const fileObjectRegex = /\$\{file:([^:}]+):([^}]+)\}/g; // nested file reference -const markdownSyntax = `/*****************************/\nShelbySAM - About the resource\n/*****************************/` +const fileRegex: RegExp = /\$\{file:(.*?)\}/g; // direct file reference +const fileObjectRegex: RegExp = /\$\{file:([^:}]+):([^}]+)\}/g; // nested file reference +const markdownSyntax: string = `/*****************************/\nShelbySAM - About the resource\n/*****************************/` // AWS Regions -const awsRegions = [ +const awsRegions: string[] = [ "us-east-1", "us-east-2", "us-west-1", @@ -29,7 +29,6 @@ const awsRegions = [ "eu-south-1", "eu-south-2", "eu-west-1", - "eu-west-1", "eu-west-2", "eu-west-3", "me-central-1", @@ -41,7 +40,7 @@ const awsRegions = [ // Cloudformation Registry // https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html -const cfr = { +const cfr: { [region: string]: string } = { "us-east-1": "https://d1uauaxba7bl26.cloudfront.net/latest/gzip/CloudFormationResourceSpecification.json", "us-east-2": @@ -106,4 +105,4 @@ const cfr = { "https://s3.us-gov-west-1.amazonaws.com/cfn-resource-specifications-us-gov-west-1-prod/latest/CloudFormationResourceSpecification.json", }; -export { fileRegex, fileObjectRegex, awsRegions, cfr, markdownSyntax}; +export { fileRegex, fileObjectRegex, awsRegions, cfr, markdownSyntax }; diff --git a/bin/utils/constructor.mjs b/bin/utils/constructor.mjs deleted file mode 100644 index 6693c42..0000000 --- a/bin/utils/constructor.mjs +++ /dev/null @@ -1,25 +0,0 @@ -import { readYaml } from "./helper.mjs"; -import { fileRegex, fileObjectRegex } from "../utils/constants.mjs"; - -// recursive loop to parse shelbysam syntax -const constructingLoop = async (data) => { - for (const [k, v] of Object.entries(data)) { - if (typeof v === "object") { - data[k] = await constructingLoop(v); - } else if (typeof v === "string") { - let matchedRegex1 = [...v.matchAll(fileObjectRegex)]; - if (matchedRegex1 !== null && matchedRegex1.length > 0) { - let temp = await readYaml(matchedRegex1[0][1]); - data[k] = temp[matchedRegex1[0][2]]; - } else { - let matchedRegex2 = [...v.matchAll(fileRegex)]; - if (matchedRegex2 !== null && matchedRegex2.length > 0) { - data[k] = await readYaml(matchedRegex2[0][1]); - } - } - } - } - return data; -}; - -export { constructingLoop }; diff --git a/bin/utils/constructor.ts b/bin/utils/constructor.ts new file mode 100644 index 0000000..fc68c6e --- /dev/null +++ b/bin/utils/constructor.ts @@ -0,0 +1,46 @@ +import { readYaml } from "./helper.js"; +import { fileRegex, fileObjectRegex } from "../utils/constants.js"; + +// recursive loop to parse shelbysam syntax +const constructingLoop = async (data: Record): Promise | undefined> => { + for (const [k, v] of Object.entries(data)) { + if (typeof v === "object" && v !== null) { + const result = await constructingLoop(v as Record); + if (result === undefined) { + // Handle case where nested loop returns undefined, perhaps by skipping or logging + continue; + } + data[k] = result; + } else if (typeof v === "string") { + let matchedRegex1 = [...v.matchAll(fileObjectRegex)]; + if (matchedRegex1 && matchedRegex1.length > 0 && matchedRegex1[0]) { + const filePath = matchedRegex1[0][1]; + const key = matchedRegex1[0][2]; + if (filePath && key) { + let temp = await readYaml(filePath); + if (temp === undefined) { + console.warn(`Warning: Could not read YAML file: ${filePath}`); + continue; + } + data[k] = (temp as Record)[key]; + } else { + let matchedRegex2 = [...v.matchAll(fileRegex)]; + if (matchedRegex2 && matchedRegex2.length > 0 && matchedRegex2[0]) { + const filePath = matchedRegex2[0][1]; + if (filePath) { + const fileData = await readYaml(filePath); + if (fileData === undefined) { + console.warn(`Warning: Could not read YAML file: ${filePath}`); + continue; + } + data[k] = fileData; + } + } + } + } + } + } + return data; +}; + +export { constructingLoop }; diff --git a/bin/utils/deconstructor.mjs b/bin/utils/deconstructor.ts similarity index 60% rename from bin/utils/deconstructor.mjs rename to bin/utils/deconstructor.ts index fcc8c72..7a0ee11 100644 --- a/bin/utils/deconstructor.mjs +++ b/bin/utils/deconstructor.ts @@ -1,16 +1,21 @@ import yaml from "js-yaml"; import fs from "fs/promises"; -import { markdownSyntax } from "./constants.mjs"; +import { markdownSyntax } from "./constants.js"; +import type { CloudFormationTemplate, DeconstructingLoopArgs } from "../types.js"; // deconstructing loop -const deconstructingLoop = async (template, args, keysL1, keysL2) => { +const deconstructingLoop = async ( + template: Record, + args:DeconstructingLoopArgs, + keysL1: string[], + keysL2: string[]) => { //create dir await fs.mkdir(args.path, { recursive: true }); // loop through the template for (const [k, v] of Object.entries(template)) { // create files for the selected keys - l1 if (keysL1.includes(k)) { - const newFileTemplate = (JSON.parse(JSON.stringify(v, null, 4))) + const newFileTemplate: unknown = JSON.parse(JSON.stringify(v, null, 4)); await fs.writeFile( args.path + "/" + k + ".yaml", yaml.dump(newFileTemplate) + markdownSyntax @@ -19,10 +24,11 @@ const deconstructingLoop = async (template, args, keysL1, keysL2) => { } // create files for the selected keys - l2 else if (keysL2.includes(k)) { + const nestedTemplate = template[k] as Record; template[k] = await deconstructingLoop( - template[k], + nestedTemplate, { path: args.path + "/" + k }, - Object.keys(template[k]), + Object.keys(nestedTemplate), [] ); } diff --git a/bin/utils/helper.mjs b/bin/utils/helper.mjs deleted file mode 100644 index e9d7134..0000000 --- a/bin/utils/helper.mjs +++ /dev/null @@ -1,53 +0,0 @@ -import { schema } from "yaml-cfn"; -import yaml from "js-yaml"; -import fs from "fs"; -import toml from "toml"; -import { fileObjectRegex, fileRegex, markdownSyntax} from "./constants.mjs"; - -const readFile = async (filename) => { - const fileString = await fs.readFileSync(filename, "utf8") - const markdownCheck = fileString.split(markdownSyntax) - // TODO: Future implementations using markdown - // if (markdownCheck.length>1){ - // // markdown exists - // } - return markdownCheck[0] -}; - -// helper function to read yaml file and parse it as json -const readYaml = async (filePath) => { - try { - return yaml.load(await readFile(filePath), { schema: schema }); - } catch (error) { - console.error("Unable to parse yaml, check syntax in ", filePath) - } - -}; - -// helper function to read json file and parse it as json -const readJson = async (filePath) => { - return JSON.parse(await readFile(filePath)); -}; - -// helper function to read toml file and parse it as json -const readConfig = async () => { - return toml.parse(await readFile("shelbysam-config.toml")); -}; - -// helper function to match regex between single files and object files -const matchRegex = (string) => { - const matchFileObjectRegex = [...string.matchAll(fileObjectRegex)]; - const matchFileRegex = [...string.matchAll(fileRegex)]; - if (matchFileObjectRegex !== null && matchFileObjectRegex.length > 0) { - return ["FileObject", matchFileObjectRegex[0]]; - } else if (matchFileRegex !== null && matchFileRegex.length > 0) { - return ["File", matchFileRegex[0]]; - }else return ["String", string] -}; - -// helper function to write yaml to file -const writeYaml = async (filepath, content) => { - fs.writeFileSync(`${filepath}`, yaml.dump(content)); -}; - -export { readYaml, readJson, readConfig, matchRegex, writeYaml }; diff --git a/bin/utils/helper.ts b/bin/utils/helper.ts new file mode 100644 index 0000000..8c722fc --- /dev/null +++ b/bin/utils/helper.ts @@ -0,0 +1,68 @@ +import { schema } from "yaml-cfn"; +import yaml from "js-yaml"; +import fs from "fs"; +import toml from "toml"; +import { fileObjectRegex, fileRegex, markdownSyntax } from "./constants.js"; +import type { ConfigArgs, CloudFormationTemplate } from "../types.js"; + +const readFile = async (filename: string): Promise => { + const fileString = fs.readFileSync(filename, "utf8") + const markdownCheck = fileString.split(markdownSyntax) + // TODO: Future implementations using markdown + // if (markdownCheck.length>1){ + // // markdown exists + // } + return markdownCheck[0]; +}; + +// helper function to read yaml file and parse it as json +const readYaml = async (filePath: string): Promise => { + try { + const fileContent = await readFile(filePath); + if (fileContent === undefined) { + console.error("File is empty or not found: ", filePath); + return undefined; + } + return yaml.load(fileContent, { schema: schema }) as CloudFormationTemplate; + } catch (error) { + console.error("Unable to parse yaml, check syntax in ", filePath) + } + +}; + +// helper function to read json file and parse it as json +const readJson = async (filePath: string): Promise => { + const fileContent = await readFile(filePath); + if (fileContent === undefined) { + throw new Error(`File is empty or not found: ${filePath}`); + } + return JSON.parse(fileContent); +}; + +// helper function to read toml file and parse it as json +const readConfig = async (): Promise => { + const fileContent = await readFile("shelbysam-config.toml"); + if (fileContent === undefined) { + console.error("Config file is empty or not found."); + return undefined; + } + return toml.parse(fileContent); +}; + +// helper function to match regex between single files and object files +const matchRegex = (str: string): [string, RegExpMatchArray | string] => { + const matchFileObjectRegex = [...str.matchAll(fileObjectRegex)]; + const matchFileRegex = [...str.matchAll(fileRegex)]; + if (matchFileObjectRegex !== null && matchFileObjectRegex.length > 0) { + return ["FileObject", matchFileObjectRegex[0]!]; + } else if (matchFileRegex !== null && matchFileRegex.length > 0) { + return ["File", matchFileRegex[0]!]; + } else return ["String", str] +}; + +// helper function to write yaml to file +const writeYaml = async (filepath: string, content: unknown): Promise => { + fs.writeFileSync(`${filepath}`, yaml.dump(content)); +}; + +export { readYaml, readJson, readConfig, matchRegex, writeYaml }; diff --git a/package-lock.json b/package-lock.json index 81fdc62..7bab914 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,34 +1,134 @@ { "name": "@antstackio/shelbysam", - "version": "1.1.1", + "version": "1.1.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@antstackio/shelbysam", - "version": "1.1.1", + "version": "1.1.5", "license": "MIT", "dependencies": { + "inquirer": "^9.2.8", + "inquirer-autocomplete-prompt": "^3.0.0", "js-yaml": "^4.1.0", + "json2toml": "^5.0.0", + "toml": "^3.0.0", + "yaml-cfn": "^0.3.2", "yargs": "^17.7.2" }, "bin": { - "shelby": "bin/cli.mjs", - "shelbysam": "bin/cli.mjs" + "shelbysam": "dist/cli.js" }, "devDependencies": { - "inquirer": "^9.2.8", - "inquirer-autocomplete-prompt": "^3.0.0", - "json2toml": "^5.0.0", - "toml": "^3.0.0", - "yaml-cfn": "^0.3.2" + "@types/inquirer-autocomplete-prompt": "^3.0.3", + "@types/js-yaml": "^4.0.9", + "@types/node": "^24.3.0", + "@types/yargs": "^17.0.33", + "json2toml": "^6.1.1", + "typescript": "^5.9.2" } }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", + "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", + "license": "MIT", + "dependencies": { + "chardet": "^2.1.0", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", + "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/inquirer": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.9.tgz", + "integrity": "sha512-/mWx5136gts2Z2e5izdoRCo46lPp5TMs9R15GTSsgg/XnZyxDWVqoVU3R9lWnccKpqwsJLvRoxbCjoJtZB7DSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/through": "*", + "rxjs": "^7.2.0" + } + }, + "node_modules/@types/inquirer-autocomplete-prompt": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/inquirer-autocomplete-prompt/-/inquirer-autocomplete-prompt-3.0.3.tgz", + "integrity": "sha512-OQCW09mEECgvhcppbQRgZSmWskWv58l+WwyUvWB1oxTu3CZj8keYSDZR9U8owUzJ5Zeux5kacN9iVPJLXcoLXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/inquirer": "*" + } + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", + "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.10.0" + } + }, + "node_modules/@types/through": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.33.tgz", + "integrity": "sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -43,6 +143,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -51,6 +152,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -70,7 +172,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -84,13 +185,14 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, + "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -101,7 +203,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -116,34 +217,39 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", + "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", + "license": "MIT" }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, + "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -152,10 +258,10 @@ } }, "node_modules/cli-spinners": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", - "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", - "dev": true, + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -164,10 +270,10 @@ } }, "node_modules/cli-width": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.0.0.tgz", - "integrity": "sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw==", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "license": "ISC", "engines": { "node": ">= 12" } @@ -176,6 +282,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -185,11 +292,28 @@ "node": ">=12" } }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -198,6 +322,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -208,13 +333,14 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, + "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -225,12 +351,14 @@ "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -239,7 +367,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -247,25 +375,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/figures": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", - "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^5.0.0", "is-unicode-supported": "^1.2.0" @@ -277,10 +391,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/figures/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -289,28 +416,31 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -324,45 +454,43 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "license": "ISC" }, "node_modules/inquirer": { - "version": "9.2.8", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.8.tgz", - "integrity": "sha512-SJ0fVfgIzZL1AD6WvFhivlh5/3hN6WeAvpvPrpPXH/8MOcQHeXhinmSm5CDJNRC2Q+sLh9YJ5k8F8/5APMXSfw==", - "dev": true, + "version": "9.3.8", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.3.8.tgz", + "integrity": "sha512-pFGGdaHrmRKMh4WoDDSowddgjT1Vkl90atobmTeSmcPGdYiwikch/m/Ef5wRaiamHejtw0cUUMMerzDUXCci2w==", + "license": "MIT", "dependencies": { + "@inquirer/external-editor": "^1.0.2", + "@inquirer/figures": "^1.0.3", "ansi-escapes": "^4.3.2", - "chalk": "^5.3.0", - "cli-cursor": "^3.1.0", - "cli-width": "^4.0.0", - "external-editor": "^3.0.3", - "figures": "^5.0.0", - "lodash": "^4.17.21", + "cli-width": "^4.1.0", "mute-stream": "1.0.0", "ora": "^5.4.1", "run-async": "^3.0.0", "rxjs": "^7.8.1", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", - "through": "^2.3.6", - "wrap-ansi": "^6.0.1" + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" }, "engines": { - "node": ">=14.18.0" + "node": ">=18" } }, "node_modules/inquirer-autocomplete-prompt": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/inquirer-autocomplete-prompt/-/inquirer-autocomplete-prompt-3.0.0.tgz", - "integrity": "sha512-nsPWllBQB3qhvpVgV1UIJN4xo3yz7Qv8y1+zrNVpJUNPxtUZ7btCum/4UCAs5apPCe/FVhKH1V6Wx0cAwkreyg==", - "dev": true, + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/inquirer-autocomplete-prompt/-/inquirer-autocomplete-prompt-3.0.1.tgz", + "integrity": "sha512-DQBXwX2fVQPVUzu4v4lGgtNgyjcX2+rTyphb2MeSOQh3xUayKAfHAF4y0KgsMi06m6ZiR3xIOdzMZMfQgX2m9w==", + "license": "ISC", "dependencies": { "ansi-escapes": "^6.0.0", "figures": "^5.0.0", @@ -371,20 +499,17 @@ "rxjs": "^7.5.6" }, "engines": { - "node": ">=12" + "node": ">=16" }, "peerDependencies": { "inquirer": "^9.1.0" } }, "node_modules/inquirer-autocomplete-prompt/node_modules/ansi-escapes": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", - "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", - "dev": true, - "dependencies": { - "type-fest": "^3.0.0" - }, + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -396,41 +521,16 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "node_modules/inquirer-autocomplete-prompt/node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inquirer/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } @@ -439,18 +539,18 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true, + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -468,26 +568,21 @@ } }, "node_modules/json2toml": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/json2toml/-/json2toml-5.0.0.tgz", - "integrity": "sha512-N7CG5zw1l1s/MItzEFkzzaMlYCziv/nHvG7fP5W9H9BqPzbOXnQw26fCOqfdpdQblXxYkxsukbqZDMMdsGK9Mg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/json2toml/-/json2toml-6.1.1.tgz", + "integrity": "sha512-kv8qBrRbdK7TVUdQuMcyJxw6pmDCYS5WNco23kcZ9foh+Jp4Q/up65wCOizRMT5EoAhcAHD15jDI0dbKEglzEQ==", "dev": true, + "license": "MIT", "dependencies": { "lodash.isdate": "^4.0.1", "lodash.isempty": "^4.4.0", "lodash.isplainobject": "^4.0.6", - "strftime": "^0.10.2" + "strftime": "^0.10.3" }, "engines": { - "node": "16 || 18 || >=20" + "node": "18 || >=20" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "node_modules/lodash.isdate": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isdate/-/lodash.isdate-4.0.1.tgz", @@ -510,7 +605,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -522,39 +617,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -563,7 +630,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true, + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -572,7 +639,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -587,7 +654,7 @@ "version": "5.4.1", "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, + "license": "MIT", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -606,54 +673,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ora/node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -667,6 +697,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -675,7 +706,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -688,7 +719,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -697,7 +728,6 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, "dependencies": { "tslib": "^2.1.0" } @@ -706,7 +736,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -720,25 +749,27 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "license": "MIT" }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "license": "ISC" }, "node_modules/strftime": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.2.tgz", - "integrity": "sha512-Y6IZaTVM80chcMe7j65Gl/0nmlNdtt+KWPle5YeCAjmsBfw+id2qdaJ5MDrxUq+OmHKab+jHe7mUjU/aNMSZZg==", + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.3.tgz", + "integrity": "sha512-DZrDUeIF73eKJ4/GgGuv8UHWcUQPYDYfDeQFj3jrx+JZl6GQE656MbHIpvbo4mEG9a5DgS8GRCc5DxJXD2udDQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.2.0" } @@ -747,7 +778,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -756,6 +787,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -769,6 +801,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -780,7 +813,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -788,41 +821,21 @@ "node": ">=8" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/toml": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", - "dev": true + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==" }, "node_modules/tslib": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", - "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==", - "dev": true + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -830,41 +843,61 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "devOptional": true, + "license": "MIT" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "license": "MIT" }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, + "license": "MIT", "dependencies": { "defaults": "^1.0.3" } }, "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=8" } }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", "engines": { "node": ">=10" } @@ -873,7 +906,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/yaml-cfn/-/yaml-cfn-0.3.2.tgz", "integrity": "sha512-MvrWhv40GKWHFGCliTGGAMwAeqIXf/bzf6WW48+xND9iMp8cTj0R8xkwM0lX/GzNN/EZKr5gP4Hx63Fn+sICoA==", - "dev": true, "dependencies": { "js-yaml": "^4.0.0" }, @@ -885,6 +917,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -902,9 +935,22 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", "engines": { "node": ">=12" } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index ca5d46c..c827fa7 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,13 @@ "name": "@antstackio/shelbysam", "version": "1.1.5", "description": "ShelbySAM is a plugin to ease cloudformation / sam development", - "main": "./bin/cli.mjs", + "main": "./dist/cli.js", + "type": "module", "bin": { - "shelbysam": "./bin/cli.mjs" + "shelbysam": "./dist/cli.js" + }, + "scripts": { + "build": "tsc" }, "repository": { "type": "git", @@ -29,5 +33,13 @@ "serverless", "sam-cli", "aws" - ] + ], + "devDependencies": { + "@types/inquirer-autocomplete-prompt": "^3.0.3", + "@types/js-yaml": "^4.0.9", + "@types/node": "^24.3.0", + "@types/yargs": "^17.0.33", + "json2toml": "^6.1.1", + "typescript": "^5.9.2" + } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5d9357e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,44 @@ +{ + // Visit https://aka.ms/tsconfig to read more about this file + "compilerOptions": { + // File Layout + "rootDir": "./bin", + "outDir": "./dist", + + // Environment Settings + // See also https://aka.ms/tsconfig/module + "module": "nodenext", + "target": "esnext", + "lib": ["esnext"], + "types": ["node"], + // For nodejs: + // "lib": ["esnext"], + // "types": ["node"], + // and npm install -D @types/node + + // Other Outputs + "sourceMap": true, + "declaration": true, + "declarationMap": true, + + // Stricter Typechecking Options + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + + // Style Options + // "noImplicitReturns": true, + // "noImplicitOverride": true, + // "noUnusedLocals": true, + // "noUnusedParameters": true, + // "noFallthroughCasesInSwitch": true, + // "noPropertyAccessFromIndexSignature": true, + + // Recommended Options + "strict": true, + "verbatimModuleSyntax": true, + "isolatedModules": true, + "noUncheckedSideEffectImports": true, + "moduleDetection": "force", + "skipLibCheck": true, + } +} From 1cda6478d60a2b98b86412d0768883b895e5122c Mon Sep 17 00:00:00 2001 From: Amandeep Date: Tue, 7 Oct 2025 16:59:38 +0530 Subject: [PATCH 2/2] Refractor: removing unnecessary comments --- bin/commands/deconstruct.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/commands/deconstruct.ts b/bin/commands/deconstruct.ts index 73e4bae..06aa40d 100644 --- a/bin/commands/deconstruct.ts +++ b/bin/commands/deconstruct.ts @@ -47,8 +47,8 @@ const deconstruct = async (args:DeconstructArgs):Promise => { // create deconstructed files template = await deconstructingLoop( - template as Record,//!TODO: fix this - args as DeconstructingLoopArgs, //!TODO: fix this + template as Record, + args as DeconstructingLoopArgs, keySeparatorsL1, keySeparatorsL2 );