Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converted to ESModule and Upgraded to serverless v3 #185

Merged
merged 19 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from 18 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
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,15 @@
"contributions": [
"code"
]
},
{
"login": "dsarlo",
"name": "Daniel Sarlo",
"avatar_url": "https://avatars.githubusercontent.com/u/16106087?v=4",
"profile": "https://github.com/dsarlo",
"contributions": [
"code"
]
}
],
"repoType": "github",
Expand Down
8,812 changes: 0 additions & 8,812 deletions package-lock.json

This file was deleted.

59 changes: 33 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "serverless-offline-sns",
"version": "0.76.0",
"version": "0.77.0",
"description": "Serverless plugin to run a local SNS server and call lambdas with events notifications.",
"main": "dist/index.js",
"exports": "./dist/index.js",
"type": "module",
"scripts": {
"build": "tsc -p src",
"watch": "tsc -p src -w",
"test": "nyc ts-mocha \"test/**/*.ts\" --slow 300 -p src/tsconfig.json",
"test": "nyc ts-mocha -r ts-node/register --loader=ts-node/esm --no-warnings=ExperimentalWarning --experimental-specifier-resolution=node \"test/**/*.ts\" -p test/tsconfig.json",
"lint": "tslint -c tslint.json 'src/**/*'",
"prepare": "yarn run lint && yarn test && yarn build",
"prettier": "npx prettier --write src test",
Expand All @@ -33,39 +34,45 @@
},
"homepage": "https://github.com/mj1618/serverless-offline-sns#readme",
"dependencies": {
"aws-sdk": "^2.943.0",
"body-parser": "^1.19.0",
"aws-sdk": "^2.1476.0",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.17.1",
"express": "^4.18.2",
"lodash": "^4.17.21",
"node-fetch": "^2.6.1",
"serverless": "^2.51.2",
"shelljs": "^0.8.4",
"uuid": "^8.3.2",
"node-fetch": "^3.3.2",
"serverless": "^3.35.2",
"shelljs": "^0.8.5",
"uuid": "^9.0.1",
"xml": "^1.0.1"
},
"devDependencies": {
"@types/chai": "^4.2.21",
"@types/express": "^4.17.13",
"@types/mocha": "^8.2.3",
"@types/node": "^16.3.1",
"@types/shelljs": "^0.8.9",
"all-contributors-cli": "^6.20.0",
"aws-sdk-mock": "^5.2.1",
"chai": "^4.3.4",
"handlebars": "4.7.7",
"@types/chai": "^4.3.9",
"@types/cors": "^2.8.15",
"@types/express": "^4.17.20",
"@types/mocha": "^10.0.3",
"@types/node": "^20.8.7",
"@types/node-fetch": "^2.6.7",
"@types/serverless": "^3.12.17",
"@types/shelljs": "^0.8.14",
"@types/sinon": "^10.0.20",
"@types/uuid": "^9.0.6",
"@types/xml": "^1.0.10",
"all-contributors-cli": "^6.26.1",
"aws-sdk-mock": "^5.8.0",
"chai": "^4.3.10",
"handlebars": "4.7.8",
"istanbul": "^0.4.5",
"mocha": "^9.0.2",
"mocha": "^10.2.0",
"nyc": "^15.1.0",
"prettier": "2.3.2",
"sinon": "^11.1.1",
"source-map-support": "^0.5.19",
"ts-loader": "^9.2.3",
"prettier": "3.0.3",
"sinon": "^16.1.1",
"source-map-support": "^0.5.21",
"ts-loader": "^9.5.0",
"ts-mocha": "^10.0.0",
"ts-node": "^10.1.0",
"ts-node": "^10.9.1",
"tslint": "^5.20.1",
"tslint-config-prettier": "^1.18.0",
"typescript": "^4.3.5"
"typescript": "^5.2.2"
},
"nyc": {
"extension": [
Expand Down
2 changes: 1 addition & 1 deletion src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { v4 as uuid } from "uuid";
import { MessageAttributes } from "./types";
import { MessageAttributes } from "./types.js";

export function createAttr() {
return {
Expand Down
91 changes: 33 additions & 58 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import * as shell from "shelljs";

import { SNSAdapter } from "./sns-adapter";
import * as express from "express";
import * as cors from "cors";
import * as bodyParser from "body-parser";
import { ISNSAdapter } from "./types";
import { SNSServer } from "./sns-server";
import * as _ from "lodash";
import * as AWS from "aws-sdk";
import { SNSAdapter } from "./sns-adapter.js";
import express from "express";
import cors from "cors";
import bodyParser from "body-parser";
import { ISNSAdapter } from "./types.js";
import { SNSServer } from "./sns-server.js";
import _ from "lodash";
import AWS from "aws-sdk";
import { resolve } from "path";
import { topicNameFromArn } from "./helpers";
import { topicNameFromArn } from "./helpers.js";
import { spawn } from "child_process";
import { get, has } from "lodash/fp";
import lodashfp from 'lodash/fp.js';
const { get, has } = lodashfp;

import { loadServerlessConfig } from "./sls-config-parser";
import { loadServerlessConfig } from "./sls-config-parser.js";

class ServerlessOfflineSns {
private config: any;
Expand All @@ -33,7 +34,7 @@ class ServerlessOfflineSns {
private servicesDirectory: string;
private autoSubscribe: boolean;

constructor(serverless: any, options: any) {
constructor(serverless: any, options: any = {}) {
this.app = express();
this.app.use(cors());
this.app.use((req, res, next) => {
Expand Down Expand Up @@ -204,7 +205,7 @@ class ServerlessOfflineSns {
await this.unsubscribeAll();
this.debug("subscribing functions");
const subscribePromises: Array<Promise<any>> = [];
if(this.autoSubscribe) {
if (this.autoSubscribe) {
if (this.servicesDirectory) {
shell.cd(this.servicesDirectory);
for (const directory of shell.ls("-d", "*/")) {
Expand All @@ -213,7 +214,7 @@ class ServerlessOfflineSns {
const serverless = await loadServerlessConfig(shell.pwd().toString(), this.debug);
this.debug("Processing subscriptions for ", service);
this.debug("shell.pwd()", shell.pwd());
this.debug("serverless functions", serverless.service.functions);
this.debug("serverless functions", JSON.stringify(serverless.service.functions));
const subscriptions = this.getResourceSubscriptions(serverless);
subscriptions.forEach((subscription) =>
subscribePromises.push(
Expand Down Expand Up @@ -288,9 +289,10 @@ class ServerlessOfflineSns {
);
this.debug("topic: " + JSON.stringify(data));
const fn = this.serverless.service.functions[subscription.fnName];
const handler = await this.createHandler(subscription.fnName, fn, location);
await this.snsAdapter.subscribe(
fn,
this.createHandler(subscription.fnName, fn, location),
handler,
data.TopicArn,
subscription.options
);
Expand Down Expand Up @@ -342,9 +344,10 @@ class ServerlessOfflineSns {
this.log(`Creating topic: "${topicName}" for fn "${fnName}"`);
const data = await this.snsAdapter.createTopic(topicName);
this.debug("topic: " + JSON.stringify(data));
const handler = await this.createHandler(fnName, fn, lambdasLocation);
await this.snsAdapter.subscribe(
fn,
this.createHandler(fnName, fn, lambdasLocation),
handler,
data.TopicArn,
snsConfig
);
Expand Down Expand Up @@ -382,15 +385,15 @@ class ServerlessOfflineSns {
await this.snsAdapter.subscribeQueue(queueUrl, data.TopicArn, snsConfig);
}

public createHandler(fnName, fn, location) {
public async createHandler(fnName, fn, location) {
if (!fn.runtime || fn.runtime.startsWith("nodejs")) {
return this.createJavascriptHandler(fn, location);
return await this.createJavascriptHandler(fn, location);
} else {
return () => this.createProxyHandler(fnName, fn, location);
return async () => await this.createProxyHandler(fnName, fn, location);
}
}

public createProxyHandler(funName, funOptions, location) {
public async createProxyHandler(funName, funOptions, location) {
const options = this.options;
return (event, context) => {
const args = ["invoke", "local", "-f", funName];
Expand Down Expand Up @@ -489,43 +492,15 @@ class ServerlessOfflineSns {
};
}

public createJavascriptHandler(fn, location) {
return () => {
// Options are passed from the command line in the options parameter
// ### OLD: use the main serverless config since this behavior is already supported there
if (
!this.options.skipCacheInvalidation ||
Array.isArray(this.options.skipCacheInvalidation)
) {
for (const key in require.cache) {
// don't invalidate cached modules from node_modules ...
if (key.match(/node_modules/)) {
continue;
}

// if an array is provided to the serverless config, check the entries there too
if (
Array.isArray(this.options.skipCacheInvalidation) &&
this.options.skipCacheInvalidation.find((pattern) =>
new RegExp(pattern).test(key)
)
) {
continue;
}

delete require.cache[key];
}
}

this.debug(process.cwd());
const handlerFnNameIndex = fn.handler.lastIndexOf(".");
const handlerPath = fn.handler.substring(0, handlerFnNameIndex);
const handlerFnName = fn.handler.substring(handlerFnNameIndex + 1);
const fullHandlerPath = resolve(location, handlerPath);
this.debug("require(" + fullHandlerPath + ")[" + handlerFnName + "]");
const handler = require(fullHandlerPath)[handlerFnName];
return handler;
};
public async createJavascriptHandler(fn, location) {
// Options are passed from the command line in the options parameter
this.debug(process.cwd());
const handlerFnNameIndex = fn.handler.lastIndexOf('.');
const handlerPath = fn.handler.substring(0, handlerFnNameIndex);
const handlerFnName = fn.handler.substring(handlerFnNameIndex + 1);
const fullHandlerPath = resolve(location, handlerPath);
const handlers = await import(`${fullHandlerPath}.js`);
return handlers[handlerFnName];
}

public log(msg, prefix = "INFO[serverless-offline-sns]: ") {
Expand Down Expand Up @@ -586,4 +561,4 @@ class ServerlessOfflineSns {
}
}

module.exports = ServerlessOfflineSns;
export default ServerlessOfflineSns;
8 changes: 4 additions & 4 deletions src/sls-config-parser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as fs from "fs";
import * as path from "path";
import * as Serverless from "serverless";
import * as findConfigPath from 'serverless/lib/cli/resolve-configuration-path';
import fs from "fs";
import path from "path";
import Serverless from "serverless";
import findConfigPath from 'serverless/lib/cli/resolve-configuration-path.js';

export async function loadServerlessConfig(cwd = process.cwd(), debug) {
console.log("debug loadServerlessConfig", cwd);
Expand Down
15 changes: 7 additions & 8 deletions src/sns-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as AWS from "aws-sdk";
import AWS from "aws-sdk";
import {
ListSubscriptionsResponse, ListTopicsResponse, MessageAttributeMap
} from "aws-sdk/clients/sns.d";
import * as _ from "lodash";
} from "aws-sdk/clients/sns.d.js";
import _ from "lodash";
import fetch from "node-fetch";
import { createMessageId, createSnsLambdaEvent } from "./helpers";
import { IDebug, ISNSAdapter } from "./types";
import { createMessageId, createSnsLambdaEvent } from "./helpers.js";
import { IDebug, ISNSAdapter } from "./types.js";

export class SNSAdapter implements ISNSAdapter {
private sns: AWS.SNS;
Expand Down Expand Up @@ -156,8 +156,7 @@ export class SNSAdapter implements ISNSAdapter {
if (req.body.SubscribeURL) {
this.debug("Visiting subscribe url: " + req.body.SubscribeURL);
return fetch(req.body.SubscribeURL, {
method: "GET",
timeout: 0,
method: "GET"
}).then((fetchResponse) => this.debug("Subscribed: " + fetchResponse));
}

Expand All @@ -171,7 +170,7 @@ export class SNSAdapter implements ISNSAdapter {
this.sent(response);
}
};
const maybePromise = getHandler()(
const maybePromise = getHandler(
event,
this.createLambdaContext(fn, sendIt),
sendIt
Expand Down
Loading