Skip to content

Commit

Permalink
undoing cdk-wrapper change
Browse files Browse the repository at this point in the history
  • Loading branch information
ljacobsson committed Oct 11, 2023
1 parent 74a856f commit c05c098
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 28 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "samp-cli",
"version": "1.0.61",
"version": "1.0.62",
"description": "CLI tool for extended productivity with AWS Serverless Application Model (SAM)",
"main": "index.js",
"scripts": {
Expand Down
136 changes: 109 additions & 27 deletions src/commands/local/runtime-support/nodejs/cdk/cdk-wrapper.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,127 @@
const cdk = require('aws-cdk-lib');
const fs = require('fs');
const { yamlDump } = require('yaml-cfn');
const cdkDir = `${process.cwd()}/cdk.out`;
const inputUtil = require('../../../../../shared/inputUtil');
const path = require('path');
const jsonpath = require('jsonpath');
const baseDir = `${process.cwd()}/.samp-out`;

const templatePath = `${cdkDir}/${process.env.SAMP_STACKNAME}.template.json`;
for (const file of getAllJsFiles(baseDir)) {
if (file.endsWith('.js')) {
let fileContents = fs.readFileSync(file, 'utf8');
if (fileContents.includes('aws-cdk-lib')) {
fileContents = fileContents.replace(/\.ts"/g, '.js"').replace(/\.ts'/g, ".js'").replace(/\.ts`/g, ".js`");
fs.writeFileSync(file, fileContents);
}
}
}

const TargetStack = require(`${process.cwd()}/${process.argv[2]}`);
const className = Object.keys(TargetStack)[0];

const templatePath = `${process.cwd()}/cdk.out/${process.env.SAMP_STACKNAME}.template.json`;
const synthedTemplate = JSON.parse(fs.readFileSync(templatePath, 'utf8'));

const stack = new TargetStack[className](null, process.env.SAMP_STACKNAME, {});
const resources = stack.node._children;
const mockTemplate = {
AWSTemplateFormatVersion: "2010-09-09",
Transform: ['AWS::Serverless-2016-10-31'], Resources: {}
};
for (const fn of Object.keys(synthedTemplate.Resources)) {
const resource = synthedTemplate.Resources[fn];
if (resource.Type === "AWS::Lambda::Function") {
if (!resource.Properties?.Code?.S3Bucket) continue;
if (!resource.Properties?.Runtime.startsWith("node")) continue;
if (resource.Metadata?.["aws:asset:is-bundled"] === false) continue;
if (resource.Metadata?.['aws:cdk:path'].includes('/Resource')) {
const asset = `${resource.Metadata?.['aws:asset:path']}/index.js`;
const assetFile = fs.readFileSync(`${cdkDir}/${asset}`, 'utf8');
const fileNames = assetFile.match(/\n\/\/.+?\.ts\n/g);
let fileName = null;
if (fileNames && fileNames.length === 1) {
fileName = fileNames[0].replace('// ', '').replace('.ts', '').replace(/\n/g, '');
} else {
const handler = await inputUtil.file("Select handler file", "*.ts");
}
for (const key of Object.keys(resources)) {
const resource = JSON.parse(JSON.stringify(resources[key], getCircularReplacer()));
delete resource.node?._children?._children?._children?.stack;
const fingerprintOptions = findShallowestOccurrence(resource, 'fingerprintOptions').occurrence;

logicalId = fn;
const handler = `${fileName}.${resource.Properties.Handler.split(".")[1]}`;
if (logicalId === null) continue;
const entry = fingerprintOptions?.bundling?.relativeEntryPath || (fingerprintOptions?.path ? `${fingerprintOptions?.path}/` : null);

mockTemplate.Resources[logicalId] = {
Type: "AWS::Serverless::Function",
Properties: {
CodeUri: ".",
Handler: handler
let logicalId = null;
let handler
if (entry) {
for (const fn of Object.keys(synthedTemplate.Resources)) {
const resource = synthedTemplate.Resources[fn];
if (resource.Type === "AWS::Lambda::Function") {
if (!resource.Properties?.Code?.S3Bucket) continue;
if (!resource.Properties?.Runtime.startsWith("node")) continue;
if (resource.Metadata?.["aws:asset:is-bundled"] === false) continue;
if (resource.Metadata?.['aws:cdk:path'].includes(`/${key}/`) && resource.Metadata?.['aws:cdk:path'].includes('/Resource')) {
//get filename from entry

const entryFile = entry.substring(entry.lastIndexOf("/") + 1).split(".")[0];
logicalId = fn;
handler = `${entryFile}.${resource.Properties.Handler.split(".")[1]}`;
break;
}
}
}
if (logicalId === null) continue;

mockTemplate.Resources[logicalId] = {
Type: "AWS::Serverless::Function",
Properties: {
CodeUri: ".",
Handler: `${entry.substring(0, entry.lastIndexOf("/"))}/${handler}`,
}
}
}
}

fs.writeFileSync(".samp-out/mock-template.yaml", yamlDump(mockTemplate));
fs.writeFileSync(".samp-out/stack-dump.json", JSON.stringify(stack.node._children, getCircularReplacer(), 2));
function getCircularReplacer() {
const seen = new WeakSet();
return (key, value) => {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
return "[Circular Reference]";
}
seen.add(value);
}
return value;
};
}

function getAllJsFiles(directory) {
let fileArray = [];

const files = fs.readdirSync(directory);

for (const file of files) {
const filePath = path.join(directory, file);
const fileStats = fs.statSync(filePath);

if (fileStats.isDirectory()) {
const nestedFiles = getAllJsFiles(filePath); // Recursively get files in subdirectory
fileArray = fileArray.concat(nestedFiles);
} else {
if (filePath.endsWith('.js'))
fileArray.push(filePath);
}
}

return fileArray;
}


function findShallowestOccurrence(obj, key, depth = 0) {
let shallowestDepth = Infinity;
let shallowestOccurrence = null;

for (const prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (prop === key) {
if (depth < shallowestDepth) {
shallowestDepth = depth;
shallowestOccurrence = obj[prop];
}
} else if (typeof obj[prop] === 'object') {
const occurrence = findShallowestOccurrence(obj[prop], key, depth + 1);
if (occurrence && occurrence.depth < shallowestDepth) {
shallowestDepth = occurrence.depth;
shallowestOccurrence = occurrence.occurrence;
}
}
}
}

return { occurrence: shallowestOccurrence, depth: shallowestDepth };
}

0 comments on commit c05c098

Please sign in to comment.