Skip to content

Commit 56ce30a

Browse files
authored
feat: localstack setup init (#11)
feat: localstack Refs: #10 --------- Signed-off-by: seven <[email protected]>
1 parent d3e4402 commit 56ce30a

File tree

4 files changed

+106
-0
lines changed

4 files changed

+106
-0
lines changed

src/commands/index.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { validate } from './validate';
66
import { deploy } from './deploy';
77
import { template } from './template';
88
import { destroyStack } from './destroy';
9+
import { runLocal } from './local';
910

1011
const program = new Command();
1112

@@ -101,4 +102,20 @@ program
101102
},
102103
);
103104

105+
program
106+
.command('local <stackName>')
107+
.description('run Serverless application locally for debugging')
108+
.option('-s, --stage <stage>', 'specify the stage', 'default')
109+
.option('-p, --port <port>', 'specify the port', '3000')
110+
.option('-d, --debug', 'enable debug mode')
111+
.option('-w, --watch', 'enable file watch', true)
112+
.action(async (stackName, { stage, port, debug, watch }) => {
113+
await runLocal(stackName, {
114+
stage,
115+
port: Number(port) || 3000,
116+
debug: !!debug,
117+
watch: typeof watch === 'boolean' ? watch : true,
118+
});
119+
});
120+
104121
program.parse();

src/commands/local.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { logger, setContext } from '../common';
2+
import { startLocalStack } from '../stack/localStack';
3+
4+
export interface RunLocalOptions {
5+
stage: string;
6+
port: number;
7+
debug: boolean;
8+
watch: boolean;
9+
}
10+
11+
export const runLocal = async (stackName: string, opts: RunLocalOptions) => {
12+
const { stage, port, debug, watch } = opts;
13+
14+
await setContext({ stage });
15+
16+
logger.info(
17+
`run-local starting: stack=${stackName} stage=${stage} port=${port} debug=${debug} watch=${watch}`,
18+
);
19+
20+
await startLocalStack();
21+
22+
// if (watch) {
23+
// const cwd = process.cwd();
24+
// try {
25+
// fs.watch(cwd, { recursive: true }, (eventType, filename) => {
26+
// if (!filename) return;
27+
// const filePath = path.join(cwd, filename);
28+
// logger.info(`file change detected: ${eventType} ${filePath}`);
29+
// });
30+
// logger.info(`watching files under ${process.cwd()}`);
31+
// } catch (err) {
32+
// logger.warn(`file watch not available: ${String(err)}`);
33+
// }
34+
// }
35+
//
36+
// const shutdown = () => {
37+
// logger.info('shutting down run-local server');
38+
// server.close(() => process.exit(0));
39+
// };
40+
// process.on('SIGINT', shutdown);
41+
// process.on('SIGTERM', shutdown);
42+
//
43+
// // return server for tests if needed
44+
// return { server, port, stage, debug, watch };
45+
};

src/stack/localStack/event.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import http from 'node:http';
2+
import { logger } from '../../common';
3+
import { EventDomain, EventTypes } from '../../types';
4+
import { isEmpty } from 'lodash';
5+
6+
const startApiGatewayServer = (event: EventDomain) => {
7+
const server = http.createServer((req, res) => {
8+
const matchedTrigger = event.triggers.find(
9+
(trigger) => trigger.method === req.method && trigger.path === req.url,
10+
);
11+
if (!matchedTrigger) {
12+
res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
13+
res.end('Not Found\n');
14+
logger.warn(`API Gateway Event - ${req.method} ${req.url} -> Not Found`);
15+
return;
16+
}
17+
18+
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
19+
res.end(`Invoked backend: ${matchedTrigger.backend}\n`);
20+
logger.info(`API Gateway Event - ${req.method} ${req.url} -> ${matchedTrigger.backend}`);
21+
});
22+
23+
const port = 3000 + Math.floor(Math.random() * 1000);
24+
server.listen(port, () => {
25+
logger.info(`API Gateway "${event.name}" listening on http://localhost:${port}`);
26+
});
27+
};
28+
29+
export const startEvents = (events: Array<EventDomain> | undefined) => {
30+
const apiGateways = events?.filter((event) => event.type === EventTypes.API_GATEWAY);
31+
if (isEmpty(apiGateways)) {
32+
return;
33+
}
34+
35+
apiGateways!.forEach((gateway) => {
36+
startApiGatewayServer(gateway);
37+
});
38+
};

src/stack/localStack/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export * from './event';
2+
3+
export const startLocalStack = async () => {
4+
// Placeholder for starting local stack logic
5+
console.log('Local stack started');
6+
};

0 commit comments

Comments
 (0)