11#!/usr/bin/env node
22
3- const fs = require ( "fs" ) ;
4- const path = require ( "path" ) ;
5- const yaml = require ( "js-yaml" ) ;
3+ import fs from "fs" ;
4+ import path from "path" ;
5+ import yaml from "js-yaml" ;
66
77// Configuration for different examples that need special settings
8- const EXAMPLE_CONFIGS = {
8+ const EXAMPLE_CONFIGS : Record < string , any > = {
99 "steps-with-retry" : {
1010 memorySize : 256 ,
1111 timeout : 300 ,
@@ -29,90 +29,24 @@ const DEFAULT_CONFIG = {
2929/**
3030 * Convert kebab-case filename to PascalCase resource name
3131 */
32- function toPascalCase ( filename ) {
32+ function toPascalCase ( filename : string ) {
3333 return filename
3434 . split ( "-" )
35- . map ( ( word ) => word . charAt ( 0 ) . toUpperCase ( ) + word . slice ( 1 ) )
35+ . map ( ( word : string ) => word . charAt ( 0 ) . toUpperCase ( ) + word . slice ( 1 ) )
3636 . join ( "" ) ;
3737}
3838
39- /**
40- * Get TypeScript files from src/examples directory
41- */
42- function getExampleFiles ( ) {
43- const catalogPath = path . join (
44- __dirname ,
45- "../src/utils/examples-catalog.json" ,
46- ) ;
47-
48- if ( ! fs . existsSync ( catalogPath ) ) {
49- throw new Error ( `Examples directory not found: ${ catalogPath } ` ) ;
50- }
51-
52- const catalog = JSON . parse ( fs . readFileSync ( catalogPath , "utf8" ) ) ;
53-
54- const exampleFiles = catalog . map ( ( example ) => example . name ) ;
55-
56- // Read all directories in examples
57- const entries = fs . readdirSync ( examplesDir , { withFileTypes : true } ) ;
58-
59- for ( const entry of entries ) {
60- // Skip non-directories and special directories
61- if ( ! entry . isDirectory ( ) || entry . name . startsWith ( "." ) ) {
62- continue ;
63- }
64-
65- const dirPath = path . join ( examplesDir , entry . name ) ;
66- const subEntries = fs . readdirSync ( dirPath , { withFileTypes : true } ) ;
67-
68- // Check if this directory contains TypeScript files directly (standalone examples)
69- const directTsFiles = subEntries . filter (
70- ( dirent ) =>
71- dirent . isFile ( ) &&
72- dirent . name . endsWith ( ".ts" ) &&
73- ! dirent . name . includes ( ".test" ) ,
74- ) ;
75-
76- if ( directTsFiles . length > 0 ) {
77- // Standalone example directory
78- directTsFiles . forEach ( ( file ) => {
79- exampleFiles . push ( path . basename ( file . name , ".ts" ) ) ;
80- } ) ;
81- } else {
82- // Nested structure - scan subdirectories
83- const subDirs = subEntries . filter ( ( dirent ) => dirent . isDirectory ( ) ) ;
84-
85- for ( const subDir of subDirs ) {
86- const subDirPath = path . join ( dirPath , subDir . name ) ;
87- const filesInSubDir = fs . readdirSync ( subDirPath ) ;
88-
89- // Find TypeScript files (excluding test files)
90- const tsFiles = filesInSubDir . filter (
91- ( file ) => file . endsWith ( ".ts" ) && ! file . includes ( ".test." ) ,
92- ) ;
93-
94- // Add each example file (without .ts extension)
95- tsFiles . forEach ( ( file ) => {
96- exampleFiles . push ( path . basename ( file , ".ts" ) ) ;
97- } ) ;
98- }
99- }
100- }
101-
102- return exampleFiles . sort ( ) ; // Sort for consistent output
103- }
104-
10539/**
10640 * Create a Lambda function resource configuration
10741 */
10842function createFunctionResource (
109- resourceName ,
110- catalog ,
43+ resourceName : string ,
44+ catalog : any ,
11145 skipVerboseLogging = false ,
11246) {
11347 const config = EXAMPLE_CONFIGS [ resourceName ] || DEFAULT_CONFIG ;
11448
115- const functionResource = {
49+ const functionResource : Record < string , any > = {
11650 Type : "AWS::Serverless::Function" ,
11751 Properties : {
11852 FunctionName : resourceName ,
@@ -145,10 +79,7 @@ function createFunctionResource(
14579 return functionResource ;
14680}
14781
148- /**
149- * Generate the complete CloudFormation template
150- */
151- function generateTemplate ( skipVerboseLogging = false ) {
82+ function getExamplesCatalogJson ( ) {
15283 const examplesCatalogPath = path . join (
15384 __dirname ,
15485 "../src/utils/examples-catalog.json" ,
@@ -166,7 +97,16 @@ function generateTemplate(skipVerboseLogging = false) {
16697 throw new Error ( "No TypeScript example files found in src/examples" ) ;
16798 }
16899
169- const template = {
100+ return examplesCatalog ;
101+ }
102+
103+ /**
104+ * Generate the complete CloudFormation template
105+ */
106+ function generateTemplate ( skipVerboseLogging = false ) {
107+ const examplesCatalog = getExamplesCatalogJson ( ) ;
108+
109+ const template : Record < string , any > = {
170110 AWSTemplateFormatVersion : "2010-09-09" ,
171111 Description : "Durable Function examples written in TypeScript." ,
172112 Transform : [ "AWS::Serverless-2016-10-31" ] ,
@@ -213,7 +153,7 @@ function generateTemplate(skipVerboseLogging = false) {
213153 } ;
214154
215155 // Generate resources for each example file
216- examplesCatalog . forEach ( ( catalog ) => {
156+ examplesCatalog . forEach ( ( catalog : { name : string ; handler : string } ) => {
217157 const resourceName = catalog . name . replace ( / \s / g, "" ) + `-22x-NodeJS-Local` ;
218158 template . Resources [
219159 toPascalCase ( catalog . handler . slice ( 0 , - ".handler" . length ) )
@@ -262,7 +202,7 @@ function main() {
262202 if ( skipVerboseLogging ) {
263203 console . log ( "🔇 Verbose logging disabled" ) ;
264204 }
265- } catch ( error ) {
205+ } catch ( error : any ) {
266206 console . error ( "❌ Error generating template.yml:" , error . message ) ;
267207 process . exit ( 1 ) ;
268208 }
@@ -273,9 +213,9 @@ if (require.main === module) {
273213 main ( ) ;
274214}
275215
276- module . exports = {
216+ export {
277217 generateTemplate ,
278- getExampleFiles,
279218 toPascalCase ,
280219 createFunctionResource ,
220+ getExamplesCatalogJson ,
281221} ;
0 commit comments