Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ const EXAMPLE_CONFIGS = {
},
],
},
"wait-for-callback-submitter-retry-success": {
memorySize: 128,
timeout: 120,
policies: [],
},
};

// Default configuration for Lambda functions
Expand All @@ -45,13 +40,18 @@ function toPascalCase(filename) {
* Get TypeScript files from src/examples directory
*/
function getExampleFiles() {
const examplesDir = path.join(__dirname, "../src/examples");
const catalogPath = path.join(
__dirname,
"../src/utils/examples-catalog.json",
);

if (!fs.existsSync(examplesDir)) {
throw new Error(`Examples directory not found: ${examplesDir}`);
if (!fs.existsSync(catalogPath)) {
throw new Error(`Examples directory not found: ${catalogPath}`);
}

const exampleFiles = [];
const catalog = JSON.parse(fs.readFileSync(catalogPath, "utf8"));

const exampleFiles = catalog.map((example) => example.name);

// Read all directories in examples
const entries = fs.readdirSync(examplesDir, { withFileTypes: true });
Expand Down Expand Up @@ -105,25 +105,25 @@ function getExampleFiles() {
/**
* Create a Lambda function resource configuration
*/
function createFunctionResource(filename, skipVerboseLogging = false) {
const resourceName = toPascalCase(filename);
const config = EXAMPLE_CONFIGS[filename] || DEFAULT_CONFIG;
function createFunctionResource(
resourceName,
catalog,
skipVerboseLogging = false,
) {
const config = EXAMPLE_CONFIGS[resourceName] || DEFAULT_CONFIG;

const functionResource = {
Type: "AWS::Serverless::Function",
Properties: {
FunctionName: `${resourceName}-TypeScript`,
FunctionName: resourceName,
CodeUri: "./dist",
Handler: `${filename}.handler`,
Handler: catalog.handler,
Runtime: "nodejs22.x",
Architectures: ["x86_64"],
MemorySize: config.memorySize,
Timeout: config.timeout,
Role: { "Fn::GetAtt": ["DurableFunctionRole", "Arn"] },
DurableConfig: {
ExecutionTimeout: 3600,
RetentionPeriodInDays: 7,
},
DurableConfig: catalog.durableConfig,
Environment: {
Variables: {
AWS_ENDPOINT_URL_LAMBDA: "http://host.docker.internal:5000",
Expand All @@ -149,9 +149,20 @@ function createFunctionResource(filename, skipVerboseLogging = false) {
* Generate the complete CloudFormation template
*/
function generateTemplate(skipVerboseLogging = false) {
const exampleFiles = getExampleFiles();
const examplesCatalogPath = path.join(
__dirname,
"../src/utils/examples-catalog.json",
);

if (exampleFiles.length === 0) {
if (!fs.existsSync(examplesCatalogPath)) {
throw new Error(`Examples directory not found: ${examplesCatalogPath}`);
}

const examplesCatalog = JSON.parse(
fs.readFileSync(examplesCatalogPath, "utf8"),
);

if (examplesCatalog.length === 0) {
throw new Error("No TypeScript example files found in src/examples");
}

Expand Down Expand Up @@ -202,12 +213,11 @@ function generateTemplate(skipVerboseLogging = false) {
};

// Generate resources for each example file
exampleFiles.forEach((filename) => {
const resourceName = toPascalCase(filename);
template.Resources[resourceName] = createFunctionResource(
filename,
skipVerboseLogging,
);
examplesCatalog.forEach((catalog) => {
const resourceName = catalog.name.replace(/\s/g, "") + `-22x-NodeJS-Local`;
template.Resources[
toPascalCase(catalog.handler.slice(0, -".handler".length))
] = createFunctionResource(resourceName, catalog, skipVerboseLogging);
});

return template;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,19 @@ describe("generate-sam-template", () => {

describe("createFunctionResource", () => {
test("creates default function resource", () => {
const resource = createFunctionResource("hello-world");
const resource = createFunctionResource("hello-world", {
name: "Hello World",
description: "A simple hello world example with no durable operations",
path: "aws-durable-execution-sdk-js/packages/aws-durable-execution-sdk-js-examples/src/examples/hello-world/hello-world.ts",
handler: "hello-world.handler",
durableConfig: {
ExecutionTimeout: 60,
RetentionPeriodInDays: 7,
},
});

expect(resource.Type).toBe("AWS::Serverless::Function");
expect(resource.Properties.FunctionName).toBe("HelloWorld-TypeScript");
expect(resource.Properties.FunctionName).toBe("hello-world");
expect(resource.Properties.Handler).toBe("hello-world.handler");
expect(resource.Properties.Runtime).toBe("nodejs22.x");
expect(resource.Properties.MemorySize).toBe(128);
Expand All @@ -29,11 +38,18 @@ describe("generate-sam-template", () => {
});

test("creates function resource with custom config for steps-with-retry", () => {
const resource = createFunctionResource("steps-with-retry");
const resource = createFunctionResource("steps-with-retry", {
name: "Steps With Retry",
description: "An example demonstrating retry functionality with steps",
path: "aws-durable-execution-sdk-js/packages/aws-durable-execution-sdk-js-examples/src/examples/step/steps-with-retry/steps-with-retry.ts",
handler: "steps-with-retry.handler",
durableConfig: {
ExecutionTimeout: 60,
RetentionPeriodInDays: 7,
},
});

expect(resource.Properties.FunctionName).toBe(
"StepsWithRetry-TypeScript",
);
expect(resource.Properties.FunctionName).toBe("steps-with-retry");
expect(resource.Properties.MemorySize).toBe(256);
expect(resource.Properties.Timeout).toBe(300);
expect(resource.Properties.Policies).toEqual([
Expand All @@ -46,7 +62,7 @@ describe("generate-sam-template", () => {
});

test("includes required environment variables", () => {
const resource = createFunctionResource("hello-world");
const resource = createFunctionResource("hello-world", {});

expect(resource.Properties.Environment.Variables).toEqual({
AWS_ENDPOINT_URL_LAMBDA: "http://host.docker.internal:5000",
Expand Down
Loading
Loading